X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=file.c;h=475b8e4cdbdf57d1aeba8b2f614b3dc53d345214;hp=d9d3a521cad21bb8c25f54a1996caa1d588a4123;hb=892b1f6c68346fa00dc3029ab8bd31178e730509;hpb=c62d28102c77e19c291c78bf6bf7f0a81abd54b9 diff --git a/file.c b/file.c index d9d3a52..475b8e4 100644 --- a/file.c +++ b/file.c @@ -32,17 +32,129 @@ #include "endian.h" #include "memory.h" #include "driver.h" +#include "svga.h" static void *desctable[8]={0,0,0,0,0,0,0,0}; static int x; -#ifdef ZLIB - +/* +typedef struct { + uint8 *data; + uint32 size; + uint32 location; +} MEMWRAP; +*/ typedef struct { uint8 *data; uint32 size; uint32 location; } ZIPWRAP; +#define MEMWRAP ZIPWRAP + +void ApplyIPS(FILE *ips, int destf) +{ + uint8 header[5]; + uint32 count=0; + MEMWRAP *dest; + + FCEU_printf(" Applying IPS...\n"); + if(!(destf&0x8000)) + { + FCEU_printf("failed (bad destf).\n"); + return; + } + + dest=(MEMWRAP*)desctable[(destf&255)-1]; + + if(fread(header,1,5,ips)!=5) + { + FCEU_printf("failed (bad header).\n"); + fclose(ips); + return; + } + if(memcmp(header,"PATCH",5)) + { + FCEU_printf("failed (bad header).\n"); + fclose(ips); + return; + } + + while(fread(header,1,3,ips)==3) + { + uint32 offset=(header[0]<<16)|(header[1]<<8)|header[2]; + uint16 size; + + if(!memcmp(header,"EOF",3)) + { + FCEU_printf(" IPS EOF: Did %d patches\n\n",count); + fclose(ips); + return; + } + + size=fgetc(ips)<<8; + size|=fgetc(ips); + if(!size) /* RLE */ + { + uint8 *start; + uint8 b; + size=fgetc(ips)<<8; + size|=fgetc(ips); + + //FCEU_printf(" Offset: %8d Size: %5d RLE\n",offset,size); + + if((offset+size)>dest->size) + { + uint8 *tmp; + + // Probably a little slow. + tmp=(uint8 *)realloc(dest->data,offset+size); + if(!tmp) + { + FCEU_printf(" Oops. IPS patch %d(type RLE) goes beyond end of file. Could not allocate memory.\n",count); + fclose(ips); + return; + } + dest->size=offset+size; + dest->data=tmp; + memset(dest->data+dest->size,0,offset+size-dest->size); + } + b=fgetc(ips); + start=dest->data+offset; + do + { + *start=b; + start++; + } while(--size); + } + else /* Normal patch */ + { + //FCEU_printf(" Offset: %8d Size: %5d\n",offset,size); + if((offset+size)>dest->size) + { + uint8 *tmp; + + // Probably a little slow. + tmp=(uint8 *)realloc(dest->data,offset+size); + if(!tmp) + { + FCEU_printf(" Oops. IPS patch %d(type normal) goes beyond end of file. Could not allocate memory.\n",count); + fclose(ips); + return; + } + dest->data=tmp; + memset(dest->data+dest->size,0,offset+size-dest->size); + } + fread(dest->data+offset,1,size,ips); + } + count++; + } + fclose(ips); + FCEU_printf(" Hard IPS end!\n"); +} + + +#ifdef ZLIB + void *MakeZipWrap(void *tz) { @@ -51,8 +163,8 @@ void *MakeZipWrap(void *tz) if(!(tmp=FCEU_malloc(sizeof(ZIPWRAP)))) goto doret; - - unzGetCurrentFileInfo(tz,&ufo,0,0,0,0,0,0); + + unzGetCurrentFileInfo(tz,&ufo,0,0,0,0,0,0); tmp->location=0; tmp->size=ufo.uncompressed_size; @@ -68,7 +180,7 @@ void *MakeZipWrap(void *tz) unzCloseCurrentFile(tz); unzClose(tz); - + return tmp; } #endif @@ -109,13 +221,13 @@ int FASTAPASS(2) FCEU_fopen(char *path, char *mode) break; } if(unzGoToNextFile(tz)!=UNZ_OK) - { + { if(unzGoToFirstFile(tz)!=UNZ_OK) goto zpfail; - break; + break; } } if(unzOpenCurrentFile(tz)!=UNZ_OK) - goto zpfail; + goto zpfail; } else { @@ -171,6 +283,43 @@ int FASTAPASS(2) FCEU_fopen(char *path, char *mode) return 0; } +int FASTAPASS(1) FCEU_fopen_forcemem(char *path) +{ + MEMWRAP *tmp; + long size; + int fp; + + fp=FCEU_fopen(path, "rb"); + if (!fp) return 0; + + if (fp&0x8000) return fp; + + if (!(tmp=FCEU_malloc(sizeof(*tmp)))) + goto retr; + + size=FCEU_fgetsize(fp); + if (size <= 0) goto retr; + tmp->size=size; + tmp->data=FCEU_malloc(size); + if (!tmp->data) goto retr; + FCEU_fread(tmp->data, 1, size, fp); + FCEU_fclose(fp); fp=0; + tmp->location=0; + + for(x=0;x<8;x++) + if(!desctable[x]) + { + desctable[x]=tmp; + return (x+1)|0x8000; + } + + retr: + if (fp) FCEU_fclose(fp); + if (tmp && tmp->data) FCEU_free(tmp->data); + if (tmp) FCEU_free(tmp); + return 0; +} + int FASTAPASS(1) FCEU_fclose(int stream) { #ifdef ZLIB @@ -204,7 +353,7 @@ size_t FASTAPASS(3) FCEU_fread(void *ptr, size_t size, size_t nmemb, int stream) return gzread(desctable[(stream&255)-1],ptr,size*nmemb); } else if(stream&0x8000) - { + { ZIPWRAP *wz; uint32 total=size*nmemb; @@ -242,7 +391,7 @@ size_t FASTAPASS(3) FCEU_fwrite(void *ptr, size_t size, size_t nmemb, int stream return gzwrite(desctable[(stream&255)-1],ptr,size*nmemb); } else if(stream&0x8000) - { + { return 0; } else @@ -256,7 +405,7 @@ int FASTAPASS(3) FCEU_fseek(int stream, long offset, int whence) if(stream&0x4000) { return gzseek(desctable[(stream&255)-1],offset,whence); - } + } else if(stream&0x8000) { ZIPWRAP *wz; @@ -271,7 +420,7 @@ int FASTAPASS(3) FCEU_fseek(int stream, long offset, int whence) return (-1); wz->location+=offset; break; - } + } return 0; } else @@ -287,8 +436,8 @@ long FASTAPASS(1) FCEU_ftell(int stream) return gztell(desctable[(stream&255)-1]); } else if(stream&0x8000) - { - return (((ZIPWRAP *)desctable[(stream&255)-1])->location); + { + return (((ZIPWRAP *)desctable[(stream&255)-1])->location); } else #endif @@ -312,25 +461,25 @@ void FASTAPASS(1)FCEU_rewind(int stream) fseek(desctable[stream-1],0,SEEK_SET); #else rewind(desctable[stream-1]); - #endif + #endif } int FASTAPASS(2) FCEU_read32(void *Bufo, int stream) { #ifdef ZLIB if(stream&0xC000) - { - uint8 t[4]; + { + uint32 t; #ifndef LSB_FIRST uint8 x[4]; #endif if(stream&0x8000) - { + { ZIPWRAP *wz; wz=(ZIPWRAP*)desctable[(stream&255)-1]; if(wz->location+4>wz->size) {return 0;} - *(uint32 *)t=*(uint32 *)(wz->data+wz->location); + memcpy(&t, wz->data+wz->location, 4); wz->location+=4; } else if(stream&0x4000) @@ -342,7 +491,7 @@ int FASTAPASS(2) FCEU_read32(void *Bufo, int stream) x[3]=t[0]; *(uint32*)Bufo=*(uint32*)x; #else - *(uint32*)Bufo=*(uint32*)t; + memcpy(Bufo, &t, 4); #endif return 1; } @@ -357,7 +506,7 @@ int FASTAPASS(1) FCEU_fgetc(int stream) { #ifdef ZLIB if(stream&0x4000) - return gzgetc(desctable[(stream&255)-1]); + return gzgetc(desctable[(stream&255)-1]); else if(stream&0x8000) { ZIPWRAP *wz;