menubg, png, bugfix
[fceu.git] / state.c
diff --git a/state.c b/state.c
index e306eda..c349cff 100644 (file)
--- a/state.c
+++ b/state.c
 #include "memory.h"
 #include "ppu.h"
 
-static SFORMAT SFMDATA[64];
+static void (*SPreSave)(void) = 0;
+static void (*SPostSave)(void) = 0;
+
+#define SFMDATA_SIZE (64)
+static SFORMAT SFMDATA[SFMDATA_SIZE];
 static int SFEXINDEX;
 static int stateversion;
 
@@ -285,6 +289,7 @@ extern int geniestage;
 void SaveState(void)
 {
        FILE *st=NULL;
+       char *fname;
 
        TempAddrT=TempAddr;
        RefreshAddrT=RefreshAddr;
@@ -295,7 +300,9 @@ void SaveState(void)
         return;
         }
 
-        st=fopen(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"wb");
+        fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0);
+        st=fopen(fname,"wb");
+        free(fname);
 
         if(st!=NULL)
         {
@@ -313,7 +320,11 @@ void SaveState(void)
          totalsize+=WriteStateChunk(st,3,FCEUPPU_STATEINFO);
          totalsize+=WriteStateChunk(st,4,FCEUCTRL_STATEINFO);
          totalsize+=WriteStateChunk(st,5,SFSND);
+
+
+         if(SPreSave) SPreSave();
          totalsize+=WriteStateChunk(st,0x10,SFMDATA);
+         if(SPostSave) SPostSave();
 
          fseek(st,4,SEEK_SET);
          write32(totalsize,st);
@@ -378,6 +389,7 @@ int FCEUSS_LoadFP(FILE *st, int make_backup)
 void LoadState(void)
 {
        FILE *st=NULL;
+       char *fname;
 
         if(geniestage==1)
         {
@@ -385,15 +397,24 @@ void LoadState(void)
          return;
         }
 
-       st=fopen(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"rb");
+       fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0);
+       st=fopen(fname,"rb");
+       free(fname);
+
        if (st)
        {
         FCEUSS_LoadFP(st, 0);
         fclose(st);
        }
+       else
+       {
+        FCEU_DispMessage("State %d load error (no file).",CurrentState);
+        SaveStateStatus[CurrentState]=0;
+       }
 }
 
 char SaveStateStatus[10];
+#if 0 // leaks memory
 void CheckStates(void)
 {
        FILE *st=NULL;
@@ -412,33 +433,55 @@ void CheckStates(void)
            SaveStateStatus[ssel]=0;
         }
 }
+#endif
 
 void SaveStateRefresh(void)
 {
  SaveStateStatus[0]=-1;
 }
 
-void ResetExState(void)
+void ResetExState(void (*PreSave)(void), void (*PostSave)(void))
 {
  int x;
  for(x=0;x<SFEXINDEX;x++)
-  free(SFMDATA[x].desc);
+ {
+  if(SFMDATA[x].desc)
+   free(SFMDATA[x].desc);
+ }
+ SPreSave = PreSave;
+ SPostSave = PostSave;
  SFEXINDEX=0;
 }
 
+
 void AddExState(void *v, uint32 s, int type, char *desc)
 {
- SFMDATA[SFEXINDEX].desc=FCEU_malloc(5);
- if(SFMDATA[SFEXINDEX].desc)
+ if(desc)
  {
+  SFMDATA[SFEXINDEX].desc=(char *)FCEU_malloc(5);
   strcpy(SFMDATA[SFEXINDEX].desc,desc);
-  SFMDATA[SFEXINDEX].v=v;
-  SFMDATA[SFEXINDEX].s=s;
-  if(type) SFMDATA[SFEXINDEX].s|=RLSB;
-  if(SFEXINDEX<63) SFEXINDEX++;
  }
+ else
+//  SFMDATA[SFEXINDEX].desc=0;
+  return; // do not support recursive save structures
+ SFMDATA[SFEXINDEX].v=v;
+ SFMDATA[SFEXINDEX].s=s;
+ if(type) SFMDATA[SFEXINDEX].s|=RLSB;
+ if(SFEXINDEX<SFMDATA_SIZE-1)
+        SFEXINDEX++;
+ else
+ {
+        static int once=1;
+        if(once)
+        {
+                once=0;
+                FCEU_PrintError("Error in AddExState: SFEXINDEX overflow.\nSomebody made SFMDATA_SIZE too small.");
+        }
+ }
+ SFMDATA[SFEXINDEX].v=0;               // End marker.
 }
 
+
 /* Old state loading code follows */
 
 uint8 *StateBuffer;