sram bugfix + savestate refactoring
authornotaz <notasas@gmail.com>
Mon, 10 Aug 2009 14:22:50 +0000 (14:22 +0000)
committernotaz <notasas@gmail.com>
Mon, 10 Aug 2009 14:22:50 +0000 (14:22 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@744 be3aeb3a-fb24-0410-a615-afba39da0efa

pico/area.c
pico/pico.h
pico/pico_int.h
platform/common/emu.c
platform/common/emu.h
platform/common/menu.c

index 876320d..8a14d55 100644 (file)
@@ -8,6 +8,7 @@
 \r
 \r
 #include "pico_int.h"\r
+#include <zlib/zlib.h>\r
 \r
 // ym2612\r
 #include "sound/ym2612.h"\r
@@ -32,16 +33,18 @@ void (*PicoLoadStateHook)(void) = NULL;
 \r
 \r
 // Scan one variable and callback\r
-static int ScanVar(void *data,int len,char *name,void *PmovFile,int PmovAction)\r
+static int ScanVar(void *data,int len,char *name,void *PmovFile,int is_write)\r
 {\r
   int ret = 0;\r
-  if ((PmovAction&3)==1) ret = areaWrite(data,1,len,PmovFile);\r
-  if ((PmovAction&3)==2) ret = areaRead (data,1,len,PmovFile);\r
+  if (is_write)\r
+    ret = areaWrite(data,1,len,PmovFile);\r
+  else\r
+    ret = areaRead (data,1,len,PmovFile);\r
   return (ret != len);\r
 }\r
 \r
-#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y,PmovFile,PmovAction);\r
-#define SCANP(x)      ScanVar(&Pico.x,sizeof(Pico.x),#x,PmovFile,PmovAction);\r
+#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y,PmovFile,is_write);\r
+#define SCANP(x)      ScanVar(&Pico.x,sizeof(Pico.x),#x,PmovFile,is_write);\r
 \r
 // Pack the cpu into a common format:\r
 PICO_INTERNAL void PicoAreaPackCpu(unsigned char *cpu, int is_sub)\r
@@ -115,7 +118,7 @@ PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
 }\r
 \r
 // Scan the contents of the virtual machine's memory for saving or loading\r
-static int PicoAreaScan(int PmovAction,unsigned int ver, void *PmovFile)\r
+static int PicoAreaScan(int is_write, unsigned int ver, void *PmovFile)\r
 {\r
   void *ym2612_regs;\r
   unsigned char cpu[0x60];\r
@@ -124,59 +127,57 @@ static int PicoAreaScan(int PmovAction,unsigned int ver, void *PmovFile)
 \r
   memset(&cpu,0,sizeof(cpu));\r
   memset(&cpu_z80,0,sizeof(cpu_z80));\r
+  Pico.m.scanline=0;\r
 \r
   ym2612_regs = YM2612GetRegs();\r
 \r
-  if (PmovAction&4)\r
-  {\r
-    Pico.m.scanline=0;\r
-\r
-    // Scan all the memory areas:\r
-    SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)\r
-\r
-    // Pack, scan and unpack the cpu data:\r
-    if((PmovAction&3)==1) PicoAreaPackCpu(cpu, 0);\r
-    //PicoMemInit();\r
-    SCAN_VAR(cpu,"cpu")\r
-    if((PmovAction&3)==2) PicoAreaUnpackCpu(cpu, 0);\r
-\r
-    SCAN_VAR(Pico.m    ,"misc")\r
-    SCAN_VAR(Pico.video,"video")\r
-\r
-    if (PicoOpt&7) {\r
-      if((PmovAction&3)==1) z80_pack(cpu_z80);\r
-      ret = SCAN_VAR(cpu_z80,"cpu_z80")\r
-      // do not unpack if we fail to load z80 state\r
-      if((PmovAction&3)==2) {\r
-        if(ret) z80_reset();\r
-        else    z80_unpack(cpu_z80);\r
-      }\r
-    }\r
-    if (PicoOpt&3)\r
-      ScanVar(sn76496_regs,28*4,"SN76496state", PmovFile, PmovAction); // regs and other stuff\r
-    if (PicoOpt&1) {\r
-      if((PmovAction&3)==1) ym2612_pack_state();\r
-      ScanVar(ym2612_regs, 0x200+4, "YM2612state", PmovFile, PmovAction); // regs + addr line\r
-      if((PmovAction&3)==2) ym2612_unpack_state(); // reload YM2612 state from it's regs\r
-    }\r
+  // Scan all the memory areas:\r
+  SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram)\r
+\r
+  // Pack, scan and unpack the cpu data:\r
+  if (is_write)\r
+    PicoAreaPackCpu(cpu, 0);\r
+  SCAN_VAR(cpu,"cpu")\r
+  if (!is_write)\r
+    PicoAreaUnpackCpu(cpu, 0);\r
+\r
+  SCAN_VAR(Pico.m    ,"misc")\r
+  SCAN_VAR(Pico.video,"video")\r
+\r
+  if (is_write)\r
+    z80_pack(cpu_z80);\r
+  ret = SCAN_VAR(cpu_z80,"cpu_z80")\r
+  // do not unpack if we fail to load z80 state\r
+  if (!is_write) {\r
+    if (ret) z80_reset();\r
+    else     z80_unpack(cpu_z80);\r
   }\r
 \r
+  ScanVar(sn76496_regs, 28*4, "SN76496state", PmovFile, is_write);\r
+  if (is_write)\r
+    ym2612_pack_state();\r
+  ret = ScanVar(ym2612_regs, 0x200+4, "YM2612state", PmovFile, is_write); // regs + addr line\r
+  if (!is_write && !ret)\r
+    ym2612_unpack_state();\r
+\r
   return 0;\r
 }\r
 \r
 // ---------------------------------------------------------------------------\r
 // Helper code to save/load to a file handle\r
 \r
+// XXX: error checking\r
 // Save or load the state from PmovFile:\r
-int PmovState(int PmovAction, void *PmovFile)\r
+static int PmovState(int is_write, void *PmovFile)\r
 {\r
   int minimum=0;\r
   unsigned char head[32];\r
 \r
   if ((PicoAHW & PAHW_MCD) || carthw_chunks != NULL)\r
   {\r
-    if (PmovAction&1) return PicoCdSaveState(PmovFile);\r
-    if (PmovAction&2) {\r
+    if (is_write)\r
+      return PicoCdSaveState(PmovFile);\r
+    else {\r
       int ret = PicoCdLoadState(PmovFile);\r
       if (PicoLoadStateHook) PicoLoadStateHook();\r
       return ret;\r
@@ -186,7 +187,6 @@ int PmovState(int PmovAction, void *PmovFile)
   memset(head,0,sizeof(head));\r
 \r
   // Find out minimal compatible version:\r
-  //PicoAreaScan(PmovAction&0xc,&minimum);\r
   minimum = 0x0021;\r
 \r
   memcpy(head,"Pico",4);\r
@@ -194,14 +194,106 @@ int PmovState(int PmovAction, void *PmovFile)
   *(unsigned int *)(head+0xc)=minimum;\r
 \r
   // Scan header:\r
-  if (PmovAction&1) areaWrite(head,1,sizeof(head),PmovFile);\r
-  if (PmovAction&2) areaRead (head,1,sizeof(head),PmovFile);\r
+  if (is_write)\r
+    areaWrite(head,1,sizeof(head),PmovFile);\r
+  else\r
+    areaRead (head,1,sizeof(head),PmovFile);\r
 \r
   // Scan memory areas:\r
-  PicoAreaScan(PmovAction, *(unsigned int *)(head+0x8), PmovFile);\r
+  PicoAreaScan(is_write, *(unsigned int *)(head+0x8), PmovFile);\r
+\r
+  if (!is_write && PicoLoadStateHook)\r
+    PicoLoadStateHook();\r
 \r
-  if ((PmovAction&2) && PicoLoadStateHook) PicoLoadStateHook();\r
+  return 0;\r
+}\r
+\r
+static size_t gzRead2(void *p, size_t _size, size_t _n, void *file)\r
+{\r
+  return gzread(file, p, _n);\r
+}\r
 \r
+static size_t gzWrite2(void *p, size_t _size, size_t _n, void *file)\r
+{\r
+  return gzwrite(file, p, _n);\r
+}\r
+\r
+static void set_cbs(int gz)\r
+{\r
+  if (gz) {\r
+    areaRead  = gzRead2;\r
+    areaWrite = gzWrite2;\r
+    areaEof   = (areaeof *) gzeof;\r
+    areaSeek  = (areaseek *) gzseek;\r
+    areaClose = (areaclose *) gzclose;\r
+  } else {\r
+    areaRead  = (arearw *) fread;\r
+    areaWrite = (arearw *) fwrite;\r
+    areaEof   = (areaeof *) feof;\r
+    areaSeek  = (areaseek *) fseek;\r
+    areaClose = (areaclose *) fclose;\r
+  }\r
+}\r
+\r
+int PicoState(const char *fname, int is_save)\r
+{\r
+  void *afile = NULL;\r
+  int ret;\r
+\r
+  if (strcmp(fname + strlen(fname) - 3, ".gz") == 0)\r
+  {\r
+    if ( (afile = gzopen(fname, is_save ? "wb" : "rb")) ) {\r
+      set_cbs(1);\r
+      if (is_save)\r
+        gzsetparams(afile, 9, Z_DEFAULT_STRATEGY);\r
+    }\r
+  }\r
+  else\r
+  {\r
+    if ( (afile = fopen(fname, is_save ? "wb" : "rb")) ) {\r
+      set_cbs(0);\r
+    }\r
+  }\r
+\r
+  if (afile == NULL)\r
+    return -1;\r
+\r
+  ret = PmovState(is_save, afile);\r
+  areaClose(afile);\r
+  if (!is_save)\r
+    Pico.m.dirtyPal=1;\r
+\r
+  return ret;\r
+}\r
+\r
+int PicoStateLoadVDP(const char *fname)\r
+{\r
+  void *afile = NULL;\r
+  if (strcmp(fname + strlen(fname) - 3, ".gz") == 0)\r
+  {\r
+    if ( (afile = gzopen(fname, "rb")) )\r
+      set_cbs(1);\r
+  }\r
+  else\r
+  {\r
+    if ( (afile = fopen(fname, "rb")) )\r
+      set_cbs(0);\r
+  }\r
+  if (afile == NULL)\r
+    return -1;\r
+\r
+  if ((PicoAHW & PAHW_MCD) || carthw_chunks != NULL) {\r
+    PicoCdLoadStateGfx(afile);\r
+  } else {\r
+    areaSeek(afile, 0x10020, SEEK_SET);  // skip header and RAM in state file\r
+    areaRead(Pico.vram, 1, sizeof(Pico.vram), afile);\r
+    areaSeek(afile, 0x2000, SEEK_CUR);\r
+    areaRead(Pico.cram, 1, sizeof(Pico.cram), afile);\r
+    areaRead(Pico.vsram, 1, sizeof(Pico.vsram), afile);\r
+    areaSeek(afile, 0x221a0, SEEK_SET);\r
+    areaRead(&Pico.video, 1, sizeof(Pico.video), afile);\r
+  }\r
+  areaClose(afile);\r
   return 0;\r
 }\r
 \r
index 4940796..ba7349e 100644 (file)
@@ -98,21 +98,12 @@ typedef struct
 } picohw_state;\r
 extern picohw_state PicoPicohw;\r
 \r
-// Area.c\r
-typedef size_t (arearw)(void *p, size_t _size, size_t _n, void *file);\r
-typedef size_t (areaeof)(void *file);\r
-typedef int    (areaseek)(void *file, long offset, int whence);\r
-typedef int    (areaclose)(void *file);\r
-// Save or load the state from PmovFile:\r
-int PmovState(int PmovAction, void *PmovFile); // &1=for reading &2=for writing &4=volatile &8=non-volatile\r
-extern arearw  *areaRead;  // external read and write function pointers for\r
-extern arearw  *areaWrite; // gzip save state ability\r
-extern areaeof *areaEof;\r
-extern areaseek *areaSeek;\r
-extern areaclose *areaClose;\r
+// area.c\r
+int PicoState(const char *fname, int is_save);\r
+int PicoStateLoadVDP(const char *fname);\r
 extern void (*PicoStateProgressCB)(const char *str);\r
 \r
-// cd/Area.c\r
+// cd/area.c\r
 int  PicoCdLoadStateGfx(void *file);\r
 \r
 // cd/buffering.c\r
index 9630399..df3a661 100644 (file)
@@ -388,6 +388,17 @@ typedef struct {
 extern carthw_state_chunk *carthw_chunks;\r
 #define CHUNK_CARTHW 64\r
 \r
+// area.c\r
+typedef size_t (arearw)(void *p, size_t _size, size_t _n, void *file);\r
+typedef size_t (areaeof)(void *file);\r
+typedef int    (areaseek)(void *file, long offset, int whence);\r
+typedef int    (areaclose)(void *file);\r
+extern arearw  *areaRead;  // external read and write function pointers for\r
+extern arearw  *areaWrite; // gzip save state ability\r
+extern areaeof *areaEof;\r
+extern areaseek *areaSeek;\r
+extern areaclose *areaClose;\r
+\r
 // Cart.c\r
 extern void (*PicoCartUnloadHook)(void);\r
 \r
index 2e813d3..08dbe0b 100644 (file)
@@ -1,4 +1,4 @@
-// (c) Copyright 2006-2007 notaz, All rights reserved.\r
+// (c) Copyright 2006-2009 notaz, All rights reserved.\r
 // Free for non-commercial use.\r
 \r
 // For commercial use, separate licencing terms must be obtained.\r
@@ -22,7 +22,6 @@
 #include <pico/pico_int.h>\r
 #include <pico/patch.h>\r
 #include <pico/cd/cue.h>\r
-#include <zlib/zlib.h>\r
 \r
 \r
 #define STATUS_MSG_TIMEOUT 2000\r
@@ -516,13 +515,14 @@ int emu_reload_rom(char *rom_fname)
                emu_status_msg(Pico.m.pal ? "PAL SYSTEM / 50 FPS" : "NTSC SYSTEM / 60 FPS");\r
        }\r
 \r
+       strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1);\r
+       rom_fname_loaded[sizeof(rom_fname_loaded)-1] = 0;\r
+       rom_loaded = 1;\r
+\r
        // load SRAM for this ROM\r
        if (currentConfig.EmuOpt & EOPT_EN_SRAM)\r
                emu_save_load_game(1, 1);\r
 \r
-       strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1);\r
-       rom_fname_loaded[sizeof(rom_fname_loaded)-1] = 0;\r
-       rom_loaded = 1;\r
        return 1;\r
 \r
 fail2:\r
@@ -766,18 +766,6 @@ void update_movie(void)
        }\r
 }\r
 \r
-\r
-static size_t gzRead2(void *p, size_t _size, size_t _n, void *file)\r
-{\r
-       return gzread(file, p, _n);\r
-}\r
-\r
-\r
-static size_t gzWrite2(void *p, size_t _size, size_t _n, void *file)\r
-{\r
-       return gzwrite(file, p, _n);\r
-}\r
-\r
 static int try_ropen_file(const char *fname)\r
 {\r
        FILE *f;\r
@@ -842,23 +830,6 @@ int emu_check_save_file(int slot)
        return emu_get_save_fname(1, 0, slot) ? 1 : 0;\r
 }\r
 \r
-void emu_setSaveStateCbs(int gz)\r
-{\r
-       if (gz) {\r
-               areaRead  = gzRead2;\r
-               areaWrite = gzWrite2;\r
-               areaEof   = (areaeof *) gzeof;\r
-               areaSeek  = (areaseek *) gzseek;\r
-               areaClose = (areaclose *) gzclose;\r
-       } else {\r
-               areaRead  = (arearw *) fread;\r
-               areaWrite = (arearw *) fwrite;\r
-               areaEof   = (areaeof *) feof;\r
-               areaSeek  = (areaseek *) fseek;\r
-               areaClose = (areaclose *) fclose;\r
-       }\r
-}\r
-\r
 int emu_save_load_game(int load, int sram)\r
 {\r
        int ret = 0;\r
@@ -929,34 +900,13 @@ int emu_save_load_game(int load, int sram)
        }\r
        else\r
        {\r
-               void *PmovFile = NULL;\r
-               if (strcmp(saveFname + strlen(saveFname) - 3, ".gz") == 0)\r
-               {\r
-                       if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) {\r
-                               emu_setSaveStateCbs(1);\r
-                               if (!load) gzsetparams(PmovFile, 9, Z_DEFAULT_STRATEGY);\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       if( (PmovFile = fopen(saveFname, load ? "rb" : "wb")) ) {\r
-                               emu_setSaveStateCbs(0);\r
-                       }\r
-               }\r
-               if(PmovFile) {\r
-                       ret = PmovState(load ? 6 : 5, PmovFile);\r
-                       areaClose(PmovFile);\r
-                       PmovFile = 0;\r
-                       if (load) Pico.m.dirtyPal=1;\r
+               ret = PicoState(saveFname, !load);\r
+               if (!ret) {\r
 #ifndef NO_SYNC\r
-                       else sync();\r
+                       if (!load) sync();\r
 #endif\r
-               }\r
-               else    ret = -1;\r
-               if (!ret)\r
                        emu_status_msg(load ? "STATE LOADED" : "STATE SAVED");\r
-               else\r
-               {\r
+               } else {\r
                        emu_status_msg(load ? "LOAD FAILED" : "SAVE FAILED");\r
                        ret = -1;\r
                }\r
index f08d12a..59fa7a1 100644 (file)
@@ -113,7 +113,6 @@ int   emu_write_config(int game);
 
 char *emu_get_save_fname(int load, int is_sram, int slot);
 int   emu_check_save_file(int slot);
-void  emu_setSaveStateCbs(int gz);
 
 void  emu_text_out8 (int x, int y, const char *text);
 void  emu_text_out16(int x, int y, const char *text);
index 18c4a3f..a81e1bc 100644 (file)
@@ -20,7 +20,6 @@
 \r
 #include <pico/pico_int.h>\r
 #include <pico/patch.h>\r
-#include <zlib/zlib.h>\r
 \r
 #define array_size(x) (sizeof(x) / sizeof(x[0]))\r
 \r
@@ -971,7 +970,7 @@ static void draw_savestate_bg(int slot)
        struct PicoVideo tmp_pv;\r
        unsigned short tmp_cram[0x40];\r
        unsigned short tmp_vsram[0x40];\r
-       void *tmp_vram, *file;\r
+       void *tmp_vram;\r
        char *fname;\r
 \r
        fname = emu_get_save_fname(1, 0, slot);\r
@@ -985,28 +984,7 @@ static void draw_savestate_bg(int slot)
        memcpy(tmp_vsram, Pico.vsram, sizeof(Pico.vsram));\r
        memcpy(&tmp_pv, &Pico.video, sizeof(Pico.video));\r
 \r
-       if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) {\r
-               file = gzopen(fname, "rb");\r
-               emu_setSaveStateCbs(1);\r
-       } else {\r
-               file = fopen(fname, "rb");\r
-               emu_setSaveStateCbs(0);\r
-       }\r
-\r
-       if (file) {\r
-               if (PicoAHW & PAHW_MCD) {\r
-                       PicoCdLoadStateGfx(file);\r
-               } else {\r
-                       areaSeek(file, 0x10020, SEEK_SET);  // skip header and RAM in state file\r
-                       areaRead(Pico.vram, 1, sizeof(Pico.vram), file);\r
-                       areaSeek(file, 0x2000, SEEK_CUR);\r
-                       areaRead(Pico.cram, 1, sizeof(Pico.cram), file);\r
-                       areaRead(Pico.vsram, 1, sizeof(Pico.vsram), file);\r
-                       areaSeek(file, 0x221a0, SEEK_SET);\r
-                       areaRead(&Pico.video, 1, sizeof(Pico.video), file);\r
-               }\r
-               areaClose(file);\r
-       }\r
+       PicoStateLoadVDP(fname);\r
 \r
        /* do a frame and fetch menu bg */\r
        pemu_forced_frame(POPT_EN_SOFTSCALE);\r