=================================================================== RCS file: /XXXXXX/athena/common/grfio.c,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- common/grfio.c 2003/06/29 05:49:50 1.2 +++ common/grfio.c 2003/11/10 23:32:44 1.4 @@ -4,7 +4,7 @@ *-------------------------------------------------------------------- * special need library : zlib ********************************************************************* - * $Id: grfio.c,v 1.2 2003/06/29 05:49:50 lemit Exp $ + * $Id: grfio.c,v 1.4 2003/11/10 23:32:44 jmb Exp $ * * 2002/12/18 ... 原版 * 2003/01/23 ... コード修正 @@ -14,6 +14,8 @@ * 2003/02/03 ... grfio_resourcecheck処理時、エントリ追加処理方法を修正 * 2003/02/05 ... grfio_init内処理の変更 * 2003/02/23 ... ローカルファイルチェックをGRFIO_LOCALでスイッチ(デフォを機能Offに) + * 2003/11/10 ... Ready new grf format. + * 2003/11/11 ... version check fix & bug fix */ #include @@ -445,7 +447,7 @@ fseek(in,0,0); // SEEK_SET buf2 = malloc(lentry.declen+1024); if (buf2==NULL) { - printf("file read memory allocate error\n"); + printf("file read memory allocate error : declen\n"); goto errret; } fread(buf2,1,lentry.declen,in); @@ -465,7 +467,7 @@ if (entry!=NULL && entry->gentry>0) { // Archive[GRF] File Read buf = malloc(entry->srclen_aligned+1024); if (buf==NULL) { - printf("file read memory allocate error\n"); + printf("file read memory allocate error : srclen_aligned\n"); goto errret; } gfname = gentry_table[entry->gentry-1]; @@ -482,9 +484,11 @@ printf("file decode memory allocate error\n"); goto errret; } - if(entry->type==1) { + if(entry->type==1 || entry->type==3 || entry->type==5) { uLongf len; - decode_des_etc(buf,entry->srclen_aligned,entry->cycle==0,entry->cycle); + if (entry->cycle>=0) { + decode_des_etc(buf,entry->srclen_aligned,entry->cycle==0,entry->cycle); + } len=entry->declen; decode_zip(buf2,&len,buf,entry->srclen); if(len!=entry->declen) { @@ -540,7 +544,7 @@ FILE *fp; int grf_size,list_size; unsigned char grf_header[0x2e]; - int lop,entry,ofs,num; + int lop,entry,entrys,ofs,grf_version; unsigned char *fname; unsigned char *grf_filelist; @@ -560,65 +564,153 @@ return 2; // 2:file format error } - list_size = grf_size-ftell(fp); - grf_filelist = malloc(list_size); - if(grf_filelist==NULL){ - fclose(fp); - printf("out of memory : grf_filelist\n"); - return 3; // 3:memory alloc error - } - fread(grf_filelist,1,list_size,fp); - fclose(fp); + grf_version = getlong(grf_header+0x2a) >> 8; - // エントリー数検索 - for(lop=0,num=0;lopsizeof(aentry.fn)-1){ - printf("file name too long : %s\n",fname); - exit(1); + if (grf_version==0x01) { //****** Grf version 01xx ****** + list_size = grf_size-ftell(fp); + grf_filelist = malloc(list_size); + if(grf_filelist==NULL){ + fclose(fp); + printf("out of memory : grf_filelist\n"); + return 3; // 3:memory alloc error } - srclen=0; - if((period_ptr=rindex(fname,'.'))!=NULL){ - for(lop=0;lop<4;lop++) { - if(strcasecmp(period_ptr,".gnd\0.gat\0.act\0.str"+lop*5)==0) - break; - } - srclen=getlong(grf_filelist+ofs2)-getlong(grf_filelist+ofs2+8)-715; - if(lop==4) { - for(lop=10,srccount=1;srclen>=lop;lop=lop*10,srccount++); - } else { - srccount=0; + fread(grf_filelist,1,list_size,fp); + fclose(fp); + + entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7; + + // Get an entry + for(entry=0,ofs=0;entrysizeof(aentry.fn)-1){ + printf("file name too long : %s\n",fname); + free(grf_filelist); + exit(1); + } + srclen=0; + if((period_ptr=rindex(fname,'.'))!=NULL){ + for(lop=0;lop<4;lop++) { + if(strcasecmp(period_ptr,".gnd\0.gat\0.act\0.str"+lop*5)==0) + break; + } + srclen=getlong(grf_filelist+ofs2)-getlong(grf_filelist+ofs2+8)-715; + if(lop==4) { + for(lop=10,srccount=1;srclen>=lop;lop=lop*10,srccount++); + } else { + srccount=0; + } + } else { + srccount=0; + } + + aentry.srclen = srclen; + aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579; + aentry.declen = getlong(grf_filelist+ofs2+8); + aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e; + aentry.cycle = srccount; + aentry.type = type; + strncpy(aentry.fn,fname,sizeof(aentry.fn)-1); +#ifdef GRFIO_LOCAL + aentry.gentry = -(gentry+1); // 負数にするのは初回LocalFileCheckをさせるためのFlagとして +#else + aentry.gentry = gentry+1; // 初回LocalFileCheck無し +#endif + filelist_modify(&aentry); } - } else { - srccount=0; + ofs = ofs2 + 17; } - - aentry.srclen = srclen; - aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579; - aentry.declen = getlong(grf_filelist+ofs2+8); - aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e; - aentry.cycle = srccount; - aentry.type = grf_filelist[ofs2+12]; - strncpy(aentry.fn,fname,sizeof(aentry.fn)-1); + free(grf_filelist); + + } else if (grf_version==0x02) { //****** Grf version 02xx ****** + unsigned char eheader[8]; + unsigned char *rBuf; + uLongf rSize,eSize; + + fread(eheader,1,8,fp); + rSize = getlong(eheader); // Read Size + eSize = getlong(eheader+4); // Extend Size + + if (rSize > grf_size-ftell(fp)) { + fclose(fp); + printf("Illegal data format : grf compress entry size\n"); + return 4; + } + + rBuf = malloc( rSize ); // Get a Read Size + if (rBuf==NULL) { + fclose(fp); + printf("out of memory : grf compress entry table buffer\n"); + return 3; + } + grf_filelist = malloc( eSize ); // Get a Extend Size + if (grf_filelist==NULL) { + free(rBuf); + fclose(fp); + printf("out of memory : grf extract entry table buffer\n"); + return 3; + } + fread(rBuf,1,rSize,fp); + fclose(fp); + decode_zip(grf_filelist,&eSize,rBuf,rSize); // Decode function + list_size = eSize; + free(rBuf); + + entrys = getlong(grf_header+0x26) - 7; + + // Get an entry + for(entry=0,ofs=0;entrysizeof(aentry.fn)-1) { + printf("grf : file name too long : %s\n",fname); + free(grf_filelist); + exit(1); + } + ofs2 = ofs+strlen(grf_filelist+ofs)+1; + type = grf_filelist[ofs2+12]; + if(type==1 || type==3 || type==5) { + srclen=getlong(grf_filelist+ofs2); + if (grf_filelist[ofs2+12]==3) { + for(lop=10,srccount=1;srclen>=lop;lop=lop*10,srccount++); + } else if (grf_filelist[ofs2+12]==5) { + srccount = 0; + } else { // if (grf_filelist[ofs2+12]==1) { + srccount = -1; + } + + aentry.srclen = srclen; + aentry.srclen_aligned = getlong(grf_filelist+ofs2+4); + aentry.declen = getlong(grf_filelist+ofs2+8); + aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e; + aentry.cycle = srccount; + aentry.type = type; + strncpy(aentry.fn,fname,sizeof(aentry.fn)-1); #ifdef GRFIO_LOCAL - aentry.gentry = -(gentry+1); // 負数にするのは初回LocalFileCheckをさせるためのFlagとして + aentry.gentry = -(gentry+1); // 負数にするのは初回LocalFileCheckをさせるためのFlagとして #else - aentry.gentry = gentry+1; // 初回LocalFileCheck無し + aentry.gentry = gentry+1; // 初回LocalFileCheck無し #endif - filelist_modify(&aentry); + filelist_modify(&aentry); + } + ofs = ofs2 + 17; + } + free(grf_filelist); + + } else { //****** Grf Other version ****** + fclose(fp); + printf("not support grf versions : %04x\n",getlong(grf_header+0x2a)); + return 4; } - free(grf_filelist); + filelist_adjust(); // filelistの不要エリア解放 return 0; // 0:no error