ips patches, 0.4 r162 rel?
[fceu.git] / file.c
diff --git a/file.c b/file.c
index d9d3a52..475b8e4 100644 (file)
--- a/file.c
+++ b/file.c
 #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;