grfio.c
来自「CS反恐精英1.6的部分C源代码。」· C语言 代码 · 共 765 行 · 第 1/2 页
C
765 行
/*==========================================
* File List Sub : File Read
*------------------------------------------
*/
static void filelist_adjust(void)
{
if (filelist!=NULL) {
FILELIST *new_filelist = (FILELIST*)realloc((void*)filelist,filelist_entrys*sizeof(FILELIST));
if (new_filelist!=NULL) {
filelist = new_filelist;
filelist_maxentry = filelist_entrys;
} else {
printf("out of memory : filelist\n");
exit(1);
}
}
}
/*==========================================
* File List Sub : File Read
*------------------------------------------
*/
void* grfio_read(char *fname)
{
FILE *in;
unsigned char *buf=NULL,*buf2=NULL;
char *gfname;
FILELIST *entry;
entry = filelist_find(fname);
if (entry==NULL || entry->gentry<=0) { // LocalFileCheck
char lfname[256],*p;
FILELIST lentry;
strncpy(lfname,fname,255);
for(p=&lfname[0];*p!=0;p++) if (*p=='\\') *p = '/'; // only for Unix
in = fopen(lfname,"rb");
if(in!=NULL) {
if (entry!=NULL && entry->gentry==0) {
lentry.declen=entry->declen;
} else {
fseek(in,0,2); // SEEK_END
lentry.declen = ftell(in);
}
fseek(in,0,0); // SEEK_SET
buf2 = malloc(lentry.declen+1024);
if (buf2==NULL) {
fclose(in);
printf("file read memory allocate error\n");
exit(1);
}
fread(buf2,1,lentry.declen,in);
fclose(in);
strcpy(lentry.fn, fname);
lentry.gentry = 0; // 0:LocalFile
entry = filelist_modify(&lentry);
} else {
if (entry!=NULL && entry->gentry<0) {
entry->gentry = -entry->gentry; // local file checked
} else {
printf("%s not found\n", fname);
exit(1);
}
}
}
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");
exit(1);
}
gfname = gentry_table[entry->gentry-1];
in = fopen(gfname,"rb");
if(in==NULL) {
printf("%s not found\n",gfname);
exit(1);
}
fseek(in,entry->srcpos,0);
fread(buf,1,entry->srclen_aligned,in);
fclose(in);
buf2=malloc(entry->declen+1024);
if (buf2==NULL) {
free(buf);
printf("file decode memory allocate error\n");
exit(1);
}
if(entry->type==1) {
uLongf len;
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) {
printf("decode_zip size miss match err: %d != %d\n",(int)len,entry->declen);
exit(1);
}
} else {
memcpy(buf2,buf,entry->declen);
}
free(buf);
}
return buf2;
}
/*==========================================
* File List Sub : Filename Decode
*------------------------------------------
*/
static unsigned char * decode_filename(unsigned char *buf,int len)
{
int lop;
for(lop=0;lop<len;lop+=8) {
NibbleSwap(&buf[lop],8);
BitConvert(&buf[lop],BitSwapTable1);
BitConvert4(&buf[lop]);
BitConvert(&buf[lop],BitSwapTable2);
}
return buf;
}
/*==========================================
* Grfio Entry Read
*------------------------------------------
*/
static int grfio_entryread(char *gfname,int gentry)
{
FILE *fp;
int grf_size,list_size;
unsigned char grf_header[0x2e];
int lop,entry,ofs,num;
unsigned char *fname;
unsigned char *grf_filelist;
fp = fopen(gfname,"rb");
if(fp==NULL) {
printf("%s not found\n",gfname);
return 1; // 1:not found err
}
fseek(fp,0,2); // SEEK_END
grf_size = ftell(fp);
fseek(fp,0,0); // SEEK_SET
fread(grf_header,1,0x2e,fp);
if(strcmp(grf_header,"Master of Magic") || fseek(fp,getlong(grf_header+0x1e),1)){ // SEEK_CUR
printf("%s read error\n",gfname);
exit(2);
}
list_size = grf_size-ftell(fp);
grf_filelist = malloc(list_size);
if(grf_filelist==NULL){
printf("out of memory : grf_filelist\n");
exit(1);
}
fread(grf_filelist,1,list_size,fp);
fclose(fp);
// 僄儞僩儕乕悢専嶕
for(lop=0,num=0;lop<list_size;lop+=21+getlong(grf_filelist+lop))
if(grf_filelist[lop+getlong(grf_filelist+lop)+16]) num++;
for(entry=0,ofs=0;entry<num;entry++,ofs+=21+getlong(grf_filelist+ofs)){
int ofs2,srclen,srccount;
char *period_ptr;
FILELIST aentry;
ofs2 = ofs+getlong(grf_filelist+ofs)+4;
if(grf_filelist[ofs2+12]==0){ // Directory Index ... skip
entry--;
continue;
}
fname = decode_filename(grf_filelist+ofs+6,grf_filelist[ofs]-6);
if(strlen(fname)>=sizeof(filelist[entry].fn)-1){
printf("file name too long : %s\n",fname);
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 = grf_filelist[ofs2+12];
strcpy(aentry.fn,fname);
aentry.gentry = -(gentry+1);
//As for making negative number as a Flag because it can point to the first LocalFileCheck (raw babblefish translation)
filelist_modify(&aentry);
}
free(grf_filelist);
filelist_adjust(); //release unused area from filelist
return 0; // 0:noerr
}
/*==========================================
* Grfio Resource Check
*------------------------------------------
*/
static void grfio_resourcecheck()
{
int lop,lopext,size;
unsigned char *buf,*ptr;
char w1[256],w2[256],src[256],dst[256];
FILELIST *entry;
size=grfio_size("data\\resnametable.txt");
buf=grfio_read("data\\resnametable.txt");
buf[size] = 0;
lopext = filelist_entrys+1024;
for(lop=filelist_entrys,ptr=buf;lop<lopext && ptr-buf<size;lop++){
if(sscanf(ptr,"%[^#]#%[^#]#",w1,w2)==2){
if(strstr(w2,"bmp")){
sprintf(src,"data\\texture\\%s",w1);
sprintf(dst,"data\\texture\\%s",w2);
} else {
sprintf(src,"data\\%s",w1);
sprintf(dst,"data\\%s",w2);
}
entry = filelist_find(dst);
if (entry!=NULL) {
FILELIST fentry;
memcpy( &fentry, entry, sizeof(FILELIST) );
strcpy( fentry.fn ,src );
filelist_add(&fentry);
} else {
//printf("file not found in data.grf : %s < %s\n",dst,src);
lop--;
}
}
ptr = strchr(ptr,'\n');
if (!ptr) break;
ptr++;
}
free(buf);
filelist_adjust(); //release unused area from filelist
}
/*==========================================
* Grfio Resource Add
*------------------------------------------
*/
int grfio_add(char *fname)
{
int len,result;
char *buf;
printf("%s file reading...\n",fname);
if (gentry_entrys>=gentry_maxentry) {
char **new_gentry = (char**)realloc((void*)gentry_table,(gentry_maxentry+16)*sizeof(char*));
if (new_gentry!=NULL) {
int lop;
gentry_table = new_gentry;
gentry_maxentry += 16;
for(lop=gentry_entrys;lop<gentry_maxentry;lop++)
gentry_table[lop] = NULL;
} else {
printf("out of memory : gentry\n");
exit(1);
}
}
len = strlen( fname );
buf = malloc(len+1);
if (buf==NULL) {
printf("out of memory : gentry\n");
exit(1);
}
strcpy( buf, fname );
gentry_table[gentry_entrys++] = buf;
result = grfio_entryread(fname,gentry_entrys-1);
if (result==0) {
//Resource check
grfio_resourcecheck();
}
return result;
}
/*==========================================
* Grfio Finalize
*------------------------------------------
*/
void grfio_final(void)
{
int lop;
if (filelist!=NULL) free(filelist);
filelist = NULL;
filelist_entrys = filelist_maxentry = 0;
if (gentry_table!=NULL) {
for(lop=0;lop<gentry_entrys;lop++) {
if (gentry_table[lop]!=NULL) {
free(gentry_table[lop]);
}
}
free(gentry_table);
}
gentry_table = NULL;
gentry_entrys = gentry_maxentry = 0;
}
/*==========================================
* Grfio Initialize
*------------------------------------------
*/
void grfio_init(void)
{
// ADDED ON 03/31/2003 -----------------
FILE *data_cnf;
char data_file[500] = "data.grf";
char sdata_file[500] = "sdata.grf";
char line[500], w1[500], w2[500];
// END ---------------------------------
hashinit(); // hash table initialization
filelist = NULL; filelist_entrys = filelist_maxentry = 0;
gentry_table = NULL; gentry_entrys = gentry_maxentry = 0;
atexit(grfio_final); //end processing
// ADDED AND CHANGED ON 03/31/2003 -----------------------
// NEW STUFF - GIVE grfio_add FUNCTION WHERE data.grf AND
// sdata.grf ARE, ACCORDING TO data_athena.cnf
data_cnf = fopen("grf-files.txt", "r");
if(data_cnf != NULL)
{
printf("grf-files.txt found.\n");
while(fgets(line, 499, data_cnf))
{
if(sscanf(line, "%[^:]:%s", w1, w2) == 2)
{
if(strcmp(w1, "data") == 0)
{
strcpy(data_file, w2);
}
else if(strcmp(w1, "sdata") == 0)
{
strcpy(sdata_file, w2);
}
}
}
fclose(data_cnf);
}
else
{
printf( "grf-files.txt not found.\n" );
exit(1);
}
//reading entry table
grfio_add(data_file); // Standard data file
grfio_add(sdata_file); // Sakray addon data file
// END -----------------------------------------------------
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?