misc: eliminate extra allocs on state save/load
authornotaz <notasas@gmail.com>
Fri, 20 Feb 2026 23:33:20 +0000 (01:33 +0200)
committernotaz <notasas@gmail.com>
Fri, 20 Feb 2026 23:33:20 +0000 (01:33 +0200)
and copying

12 files changed:
frontend/menu.c
frontend/plugin.c
include/psemu_plugin_defs.h
libpcsxcore/gpu.h
libpcsxcore/misc.c
libpcsxcore/plugins.h
plugins/dfsound/freeze.c
plugins/dfsound/spu.c
plugins/dfsound/spu.h
plugins/gpulib/gpu.c
plugins/gpulib/gpu.h
plugins/spunull/spunull.c

index 1e44fae..809e1d4 100644 (file)
@@ -816,15 +816,15 @@ static void draw_savestate_bg(int slot)
                return;
        }
 
-       gpu = malloc(sizeof(*gpu));
+       gpu = malloc(sizeof(*gpu) + 1024*512*2);
        if (gpu == NULL) {
                gzclose(f);
                return;
        }
 
-       ret = gzread(f, gpu, sizeof(*gpu));
+       ret = gzread(f, gpu, sizeof(*gpu) + 1024*512*2);
        gzclose(f);
-       if (ret != sizeof(*gpu)) {
+       if (ret != sizeof(*gpu) + 1024*512*2) {
                fprintf(stderr, "gzread failed\n");
                goto out;
        }
@@ -1815,15 +1815,16 @@ static void draw_frame_debug(GPUFreeze_t *gpuf, int x, int y)
 {
        int w = min(g_menuscreen_w, 1024);
        int h = min(g_menuscreen_h, 512);
-       u16 *d = g_menuscreen_ptr;
-       u16 *s = (u16 *)gpuf->psxVRam + y * 1024 + x;
+       u16 *s, *d = g_menuscreen_ptr;
+       uint16_t *vram = NULL;
        char buff[64];
        int ty = 1;
 
        gpuf->ulFreezeVersion = 1;
        if (GPU_freeze != NULL)
-               GPU_freeze(1, gpuf);
+               GPU_freeze(1, gpuf, &vram);
 
+       s = vram + y * 1024 + x;
        for (; h > 0; h--, d += g_menuscreen_w, s += 1024)
                bgr555_to_rgb565(d, s, w);
 
index 3263ae3..86b8bb9 100644 (file)
@@ -93,7 +93,7 @@ extern uint32_t GPUreadData(void);
 extern void GPUreadDataMem(uint32_t *, int);
 extern long GPUdmaChain(uint32_t *, uint32_t, uint32_t *, int32_t *);
 extern void GPUupdateLace(void);
-extern long GPUfreeze(uint32_t, void *);
+extern long GPUfreeze(uint32_t, void *, uint16_t **);
 extern void GPUvBlank(int, int);
 extern void GPUgetScreenInfo(int *y, int *base_hres);
 extern void GPUrearmedCallbacks(const struct rearmed_cbs *cbs);
index 2003e65..88331f1 100644 (file)
@@ -254,21 +254,17 @@ typedef struct xa_decode {
        short                   pcm[16384];
 } xa_decode_t;
 
-typedef struct {
-       char PluginName[8];
-       unsigned int PluginVersion;
-       unsigned int Size;
-} SPUFreezeHdr_t;
-
 typedef struct SPUFreeze {
        char PluginName[8];
        unsigned int PluginVersion;
        unsigned int Size;
        unsigned char SPUPorts[0x200];
-       unsigned char SPURam[0x80000];
-       xa_decode_t xa;
+       //unsigned char SPURam[0x80000]; // handled separately
+       //xa_decode_t xa;
 } SPUFreeze_t;
 
+#define SPUFREEZE_F2_MAX_SIZE 0xc000
+
 /*         NET PlugIn v2       */
 /* Added by linuzappz@pcsx.net */
 
index 9513253..1018768 100644 (file)
@@ -30,7 +30,7 @@ typedef struct GPUFreeze {
        uint32_t ulFreezeVersion;
        uint32_t ulStatus;
        uint32_t ulControl[256];
-       unsigned char psxVRam[1024*512*2];
+       unsigned char psxVRam[0]; // 1024*512*2 // saved separately
 } GPUFreeze_t;
 
 #define PSXGPU_LCF     (1u<<31)
index fcac1a8..b7eaa93 100644 (file)
@@ -705,12 +705,17 @@ struct misc_save_data {
 int SaveState(const char *file) {
        struct misc_save_data *misc = (void *)(psxRegs.ptrs.psxH + 0xf000);
        struct origin_info oi = { 0, };
-       GPUFreeze_t *gpufP = NULL;
-       SPUFreezeHdr_t spufH;
-       SPUFreeze_t *spufP = NULL;
-       u8 buf[EX_SCREENPIC_SIZE];
-       int result = -1;
-       int Size;
+       union {
+               // save stack space
+               u8 buf[EX_SCREENPIC_SIZE];
+               GPUFreeze_t gpu_hdr;
+               struct {
+                       SPUFreeze_t spu_hdr;
+                       u8 spu_part2[SPUFREEZE_F2_MAX_SIZE];
+               };
+       } u;
+       unsigned short *spuram = NULL;
+       uint16_t *vram = NULL;
        void *f;
 
        assert(!psxRegs.branching);
@@ -748,11 +753,10 @@ int SaveState(const char *file) {
        snprintf(oi.build_info, sizeof(oi.build_info), "%s", get_build_info());
 
        // this was space for ScreenPic
-       assert(sizeof(buf) >= EX_SCREENPIC_SIZE);
        assert(sizeof(oi) - 3 <= EX_SCREENPIC_SIZE);
-       memset(buf, 0, sizeof(buf));
-       memcpy(buf + 3, &oi, sizeof(oi));
-       SaveFuncs.write(f, buf, EX_SCREENPIC_SIZE);
+       memset(u.buf, 0, sizeof(u.buf));
+       memcpy(u.buf + 3, &oi, sizeof(oi));
+       SaveFuncs.write(f, u.buf, sizeof(u.buf));
 
        if (Config.HLE)
                psxBiosFreeze(1);
@@ -764,22 +768,22 @@ int SaveState(const char *file) {
        SaveFuncs.write(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
 
        // gpu
-       gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
-       if (gpufP == NULL) goto cleanup;
-       gpufP->ulFreezeVersion = 1;
-       memset(gpufP->ulControl, 0, sizeof(gpufP->ulControl));
-       GPU_freeze(1, gpufP);
-       SaveFuncs.write(f, gpufP, sizeof(GPUFreeze_t));
-       free(gpufP); gpufP = NULL;
+       u.gpu_hdr.ulFreezeVersion = 1;
+       u.gpu_hdr.ulStatus = 0;
+       memset(u.gpu_hdr.ulControl, 0, sizeof(u.gpu_hdr.ulControl));
+       GPU_freeze(1, &u.gpu_hdr, &vram);
+       SaveFuncs.write(f, &u.gpu_hdr, sizeof(u.gpu_hdr));
+       SaveFuncs.write(f, vram, 1024*512*2);
 
        // spu
-       SPU_freeze(2, (SPUFreeze_t *)&spufH, psxRegs.cycle);
-       Size = spufH.Size; SaveFuncs.write(f, &Size, 4);
-       spufP = (SPUFreeze_t *) malloc(Size);
-       if (spufP == NULL) goto cleanup;
-       SPU_freeze(1, spufP, psxRegs.cycle);
-       SaveFuncs.write(f, spufP, Size);
-       free(spufP); spufP = NULL;
+       SPU_freeze(1, &u.spu_hdr, &spuram, u.spu_part2, psxRegs.cycle);
+       assert(u.spu_hdr.Size > sizeof(u.spu_hdr) + 512*1024);
+       assert(u.spu_hdr.Size <= sizeof(u.spu_hdr) + 512*1024 + sizeof(u.spu_part2));
+       assert(spuram);
+       SaveFuncs.write(f, &u.spu_hdr.Size, 4); // redundant, for compat
+       SaveFuncs.write(f, &u.spu_hdr, sizeof(u.spu_hdr));
+       SaveFuncs.write(f, spuram, 512*1024);
+       SaveFuncs.write(f, &u.spu_part2, u.spu_hdr.Size - sizeof(u.spu_hdr) - 512*1024);
 
        sioFreeze(f, 1);
        cdrFreeze(f, 1);
@@ -789,24 +793,30 @@ int SaveState(const char *file) {
        ndrc_freeze(f, 1);
        padFreeze(f, 1);
 
-       result = 0;
-cleanup:
        memset(misc, 0, sizeof(*misc));
        SaveFuncs.close(f);
-       return result;
+       return 0;
 }
 
 int LoadState(const char *file) {
        struct misc_save_data *misc = (void *)(psxRegs.ptrs.psxH + 0xf000);
        u32 biosBranchCheckOld = psxRegs.biosBranchCheck;
-       void *f;
-       GPUFreeze_t *gpufP = NULL;
-       SPUFreeze_t *spufP = NULL;
+       union {
+               // save stack space
+               GPUFreeze_t gpu_hdr;
+               struct {
+                       SPUFreeze_t spu_hdr;
+                       u8 spu_part2[SPUFREEZE_F2_MAX_SIZE];
+               };
+       } u;
+       unsigned short *spuram = NULL;
+       uint16_t *vram = NULL;
        boolean hle, oldhle;
        int Size;
        char header[32];
        u32 version;
        int result = -1;
+       void *f;
 
        f = SaveFuncs.open(file, "rb");
        if (f == NULL) return -1;
@@ -868,20 +878,29 @@ int LoadState(const char *file) {
                psxBiosFreeze(0);
 
        // gpu
-       gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
-       if (gpufP == NULL) goto cleanup;
-       SaveFuncs.read(f, gpufP, sizeof(GPUFreeze_t));
-       GPU_freeze(0, gpufP);
-       free(gpufP);
+       SaveFuncs.read(f, &u.gpu_hdr, sizeof(u.gpu_hdr));
+       GPU_freeze(0, &u.gpu_hdr, &vram);
+       assert(vram);
+       SaveFuncs.read(f, vram, 1024*512*2);
        gpuSyncPluginSR();
 
        // spu
        SaveFuncs.read(f, &Size, 4);
-       spufP = (SPUFreeze_t *)malloc(Size);
-       if (spufP == NULL) goto cleanup;
-       SaveFuncs.read(f, spufP, Size);
-       SPU_freeze(0, spufP, psxRegs.cycle);
-       free(spufP);
+       if (sizeof(u.spu_hdr) + 512*1024 < Size &&
+           (uint32_t)Size <= sizeof(u.spu_hdr) + 512*1024u + sizeof(u.spu_part2))
+       {
+               SPU_freeze(0, NULL, &spuram, NULL, psxRegs.cycle);
+               assert(spuram);
+               SaveFuncs.read(f, &u.spu_hdr, sizeof(u.spu_hdr));
+               SaveFuncs.read(f, spuram, 512*1024);
+               SaveFuncs.read(f, &u.spu_part2, Size - sizeof(u.spu_hdr) - 512*1024);
+               SPU_freeze(0, &u.spu_hdr, &spuram, u.spu_part2, psxRegs.cycle);
+       }
+       else
+       {
+               SysPrintf("broken spu save size %d, attempting to skip\n", Size);
+               SaveFuncs.seek(f, Size, SEEK_CUR);
+       }
 
        sioFreeze(f, 0);
        cdrFreeze(f, 0);
index 8041757..334899d 100644 (file)
@@ -59,7 +59,7 @@ typedef uint32_t (CALLBACK* GPUreadData)(void);
 typedef void (CALLBACK* GPUreadDataMem)(uint32_t *, int);\r
 typedef long (CALLBACK* GPUdmaChain)(uint32_t *, uint32_t, uint32_t *, int32_t *);\r
 typedef void (CALLBACK* GPUupdateLace)(void);\r
-typedef long (CALLBACK* GPUfreeze)(uint32_t, GPUFreeze_t *);\r
+typedef long (CALLBACK* GPUfreeze)(uint32_t, GPUFreeze_t *, uint16_t **);\r
 typedef void (CALLBACK* GPUvBlank)(int, int);\r
 typedef void (CALLBACK* GPUgetScreenInfo)(int *, int *);\r
 \r
@@ -100,7 +100,8 @@ typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int, unsigned int);
 typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *, unsigned int, int);\r
 typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(int));\r
 typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after));\r
-typedef long (CALLBACK* SPUfreeze)(unsigned int, struct SPUFreeze *, unsigned int);\r
+typedef long (CALLBACK* SPUfreeze)(int ulFreezeMode, SPUFreeze_t * pF,\r
+               unsigned short **ram, void * pF2, unsigned int cycles);\r
 typedef void (CALLBACK* SPUasync)(unsigned int, unsigned int);\r
 typedef int  (CALLBACK* SPUplayCDDAchannel)(short *, int, unsigned int, int);\r
 typedef void (CALLBACK* SPUsetCDvol)(unsigned char, unsigned char, unsigned char, unsigned char, unsigned int);\r
index 7daafb9..be43c2c 100644 (file)
@@ -111,6 +111,8 @@ typedef struct
 \r
 typedef struct\r
 {\r
+ xa_decode_t xa;\r
+\r
  unsigned short  spuIrq;\r
  unsigned short  decode_pos;\r
  uint32_t   pSpuIrq;\r
@@ -136,8 +138,8 @@ typedef struct
 \r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles);\r
-static void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles); // unknown format\r
+static void LoadStateV5(SPUOSSFreeze_t * pFO, uint32_t cycles);\r
+static void LoadStateUnknown(uint32_t cycles); // unknown format\r
 \r
 #define SB_FORMAT_MAGIC 0x73626201\r
 \r
@@ -241,14 +243,19 @@ static void load_register(unsigned long reg, unsigned int cycles)
 // SPUFREEZE: called by main emu on savestate load/save\r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,\r
- unsigned int cycles)\r
+long DoFreeze(int ulFreezeMode, struct SPUFreeze * pF, unsigned short **ram,\r
void * pF2, unsigned int cycles)\r
 {\r
  SPUOSSFreeze_t * pFO = NULL;\r
  sample_buf_rvb *sb_rvb = &spu.sb_rvb;\r
+ unsigned int ossOffset = sizeof(SPUFreeze_t) + 512*1024; // when combined\r
  int i, j;\r
 \r
- if(!pF) return 0;                                     // first check\r
+ assert(sizeof(SPUOSSFreeze_t) <= SPUFREEZE_F2_MAX_SIZE);\r
+ if (ram)\r
+  *ram = spu.spuMem;\r
+ if (!pF || !pF2) return 0;                            // first check\r
+ pFO = pF2;\r
 \r
 #if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
  sb_rvb = (sample_buf_rvb *)&spu.sb_thread[MAXCHAN];\r
@@ -258,18 +265,17 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
    int xa_left = 0, cdda_left = 0;\r
    do_samples(cycles, 1);\r
 \r
-   if(ulFreezeMode==1)                                 \r
-    memset(pF,0,sizeof(SPUFreeze_t)+sizeof(SPUOSSFreeze_t));\r
+   if (ulFreezeMode == 1)\r
+    memset(pF, 0, sizeof(*pF));\r
 \r
    strcpy(pF->PluginName, "PBOSS");\r
    pF->PluginVersion = 5;\r
-   pF->Size = sizeof(SPUFreeze_t)+sizeof(SPUOSSFreeze_t);\r
+   pF->Size = ossOffset + sizeof(SPUOSSFreeze_t);\r
 \r
    if(ulFreezeMode==2) return 1;                       // info mode? ok, bye\r
                                                        // save mode:\r
    regAreaGet(H_SPUctrl) = spu.spuCtrl;\r
    regAreaGet(H_SPUstat) = spu.spuStat;\r
-   memcpy(pF->SPURam, spu.spuMem, 0x80000);            // copy common infos\r
    memcpy(pF->SPUPorts, spu.regArea, 0x200);\r
 \r
    if(spu.xapGlobal && spu.XAPlay!=spu.XAFeed)         // some xa\r
@@ -277,7 +283,7 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
      xa_left = spu.XAFeed - spu.XAPlay;\r
      if (xa_left < 0)\r
       xa_left = spu.XAEnd - spu.XAPlay + spu.XAFeed - spu.XAStart;\r
-     pF->xa = *spu.xapGlobal;\r
+     pFO->xa = *spu.xapGlobal;\r
     }\r
    else if (spu.CDDAPlay != spu.CDDAFeed)\r
     {\r
@@ -286,21 +292,19 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
      cdda_left = spu.CDDAFeed - spu.CDDAPlay;\r
      if (cdda_left < 0)\r
       cdda_left = spu.CDDAEnd - spu.CDDAPlay + spu.CDDAFeed - spu.CDDAStart;\r
-     if (cdda_left > sizeof(pF->xa.pcm) / 4)\r
-      cdda_left = sizeof(pF->xa.pcm) / 4;\r
+     if (cdda_left > sizeof(pFO->xa.pcm) / 4)\r
+      cdda_left = sizeof(pFO->xa.pcm) / 4;\r
      if (p + cdda_left <= spu.CDDAEnd)\r
-      memcpy(pF->xa.pcm, p, cdda_left * 4);\r
+      memcpy(pFO->xa.pcm, p, cdda_left * 4);\r
      else {\r
-      memcpy(pF->xa.pcm, p, (spu.CDDAEnd - p) * 4);\r
-      memcpy((char *)pF->xa.pcm + (spu.CDDAEnd - p) * 4, spu.CDDAStart,\r
+      memcpy(pFO->xa.pcm, p, (spu.CDDAEnd - p) * 4);\r
+      memcpy((char *)pFO->xa.pcm + (spu.CDDAEnd - p) * 4, spu.CDDAStart,\r
              (cdda_left - (spu.CDDAEnd - p)) * 4);\r
      }\r
-     pF->xa.nsamples = 0;\r
+     pFO->xa.nsamples = 0;\r
     }\r
    else\r
-    memset(&pF->xa, 0, sizeof(xa_decode_t));           // or clean xa\r
-\r
-   pFO=(SPUOSSFreeze_t *)(pF+1);                       // store special stuff\r
+    memset(&pFO->xa, 0, sizeof(xa_decode_t));          // or clean xa\r
 \r
    pFO->spuIrq = spu.regArea[(H_SPUirqAddr - 0x0c00) / 2];\r
    if(spu.pSpuIrq) pFO->pSpuIrq = spu.pSpuIrq - spu.spuMemC;\r
@@ -338,27 +342,29 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
                                                        \r
  if(ulFreezeMode!=0) return 0;                         // bad mode? bye\r
 \r
- memcpy(spu.spuMem, pF->SPURam, 0x80000);              // get ram\r
  memcpy(spu.regArea, pF->SPUPorts, 0x200);\r
  spu.bMemDirty = 1;\r
  spu.spuCtrl = regAreaGet(H_SPUctrl);\r
  spu.spuStat = regAreaGet(H_SPUstat);\r
 \r
  if (!strcmp(pF->PluginName, "PBOSS") && pF->PluginVersion == 5)\r
-   pFO = LoadStateV5(pF, cycles);\r
- else LoadStateUnknown(pF, cycles);\r
+   LoadStateV5(pFO, cycles);\r
+ else {\r
+   LoadStateUnknown(cycles);\r
+   pFO = NULL;\r
+ }\r
 \r
  spu.XAPlay = spu.XAFeed = spu.XAStart;\r
  spu.CDDAPlay = spu.CDDAFeed = spu.CDDAStart;\r
  spu.cdClearSamples = 512;\r
- if (pFO && pFO->xa_left && pF->xa.nsamples) {         // start xa again\r
-  FeedXA(&pF->xa);\r
+ if (pFO && pFO->xa_left && pFO->xa.nsamples) {        // start xa again\r
+  FeedXA(&pFO->xa);\r
   spu.XAPlay = spu.XAFeed - pFO->xa_left;\r
   if (spu.XAPlay < spu.XAStart)\r
    spu.XAPlay = spu.XAStart;\r
  }\r
  else if (pFO && pFO->cdda_left) {                     // start cdda again\r
-  FeedCDDA((void *)pF->xa.pcm, pFO->cdda_left * 4);\r
+  FeedCDDA((void *)pFO->xa.pcm, pFO->cdda_left * 4);\r
  }\r
 \r
  // not in old savestates\r
@@ -370,7 +376,7 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
  spu.XALastVal = 0;\r
  spu.last_keyon_cycles = cycles - 16*786u;\r
  spu.interpolation = -1;\r
- if (pFO && pF->Size >= sizeof(*pF) + offsetof(SPUOSSFreeze_t, rvb_sb)) {\r
+ if (pFO && pF->Size >= ossOffset + offsetof(SPUOSSFreeze_t, rvb_sb)) {\r
   spu.cycles_dma_end = pFO->cycles_dma_end;\r
   spu.decode_dirty_ch = pFO->decode_dirty_ch;\r
   spu.dwNoiseVal = pFO->dwNoiseVal;\r
@@ -379,7 +385,7 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
   spu.XALastVal = pFO->XALastVal;\r
   spu.last_keyon_cycles = pFO->last_keyon_cycles;\r
  }\r
- if (pFO && pF->Size >= sizeof(*pF) + sizeof(*pFO)) {\r
+ if (pFO && pF->Size >= ossOffset + sizeof(*pFO)) {\r
   for (i = 0; i < 2; i++)\r
    for (j = 0; j < 2; j++)\r
     memcpy(&sb_rvb->sample[i][j*4], pFO->rvb_sb[i], 4 * sizeof(sb_rvb->sample[i][0]));\r
@@ -413,11 +419,9 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
 \r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles)\r
+static void LoadStateV5(SPUOSSFreeze_t * pFO, uint32_t cycles)\r
 {\r
- int i;SPUOSSFreeze_t * pFO;\r
-\r
- pFO=(SPUOSSFreeze_t *)(pF+1);\r
+ int i;\r
 \r
  spu.pSpuIrq = spu.spuMemC + ((spu.regArea[(H_SPUirqAddr - 0x0c00) / 2] << 3) & ~0xf);\r
 \r
@@ -440,13 +444,11 @@ static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles)
    spu.s_chan[i].pCurr+=(uintptr_t)spu.spuMemC;\r
    spu.s_chan[i].pLoop+=(uintptr_t)spu.spuMemC;\r
   }\r
-\r
- return pFO;\r
 }\r
 \r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-static void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles)\r
+static void LoadStateUnknown(uint32_t cycles)\r
 {\r
  int i;\r
 \r
index e7bff1a..7e7f827 100644 (file)
@@ -1411,12 +1411,12 @@ static void exit_spu_thread(void)
 
 #endif
 
-long CALLBACK SPUfreeze(unsigned int ulFreezeMode, struct SPUFreeze * pF,
- unsigned int cycles)
+long CALLBACK SPUfreeze(int ulFreezeMode, SPUFreeze_t * pF, unsigned short **ram,
void * pF2, unsigned int cycles)
 {
  if (worker != NULL)
   sync_worker_thread(1);
- return DoFreeze(ulFreezeMode, pF, cycles);
+ return DoFreeze(ulFreezeMode, pF, ram, pF2, cycles);
 }
 
 // SPUINIT: this func will be called first by the main emu
index f2aa9a4..45f84e4 100644 (file)
@@ -29,7 +29,8 @@ void CALLBACK SPUwriteRegister(unsigned long, unsigned short, unsigned int);
 unsigned short CALLBACK SPUreadRegister(unsigned long, unsigned int);\r
 void CALLBACK SPUregisterCallback(void (*cb)(int));\r
 void CALLBACK SPUregisterScheduleCb(void (*cb)(unsigned int));\r
-long CALLBACK SPUfreeze(unsigned int, struct SPUFreeze *, unsigned int);\r
+long CALLBACK SPUfreeze(int ulFreezeMode, struct SPUFreeze * pF, unsigned short **ram,\r
+               void * pF2, unsigned int cycles);\r
 void CALLBACK SPUasync(unsigned int, unsigned int);\r
 \r
 void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cycles);\r
@@ -42,6 +43,7 @@ void CALLBACK SPUsetCDvol(unsigned char ll, unsigned char lr,
 \r
 // internal\r
 void ClearWorkingState(void);\r
-long DoFreeze(unsigned int, struct SPUFreeze *, unsigned int);\r
+long DoFreeze(int ulFreezeMode, struct SPUFreeze * pF, unsigned short **ram,\r
+               void * pF2, unsigned int cycles);\r
 \r
 #endif /* __P_SPU_H__ */\r
index adbfad6..271e1c7 100644 (file)
@@ -1061,7 +1061,7 @@ uint32_t GPUreadStatus(void)
   return ret;
 }
 
-long GPUfreeze(uint32_t type, GPUFreeze_t *freeze)
+long GPUfreeze(uint32_t type, GPUFreeze_t *freeze, uint16_t **vram_ptr)
 {
   int i;
 
@@ -1073,14 +1073,12 @@ long GPUfreeze(uint32_t type, GPUFreeze_t *freeze)
       }
 
       sync_renderer(&gpu);
-      memcpy(freeze->psxVRam, gpu.vram, 1024 * 512 * 2);
       memcpy(freeze->ulControl, gpu.regs, sizeof(gpu.regs));
       memcpy(freeze->ulControl + 0xe0, gpu.ex_regs, sizeof(gpu.ex_regs));
       freeze->ulStatus = gpu.status;
       break;
     case 0: // load
       sync_renderer(&gpu);
-      memcpy(gpu.vram, freeze->psxVRam, 1024 * 512 * 2);
       //memcpy(gpu.regs, freeze->ulControl, sizeof(gpu.regs));
       memcpy(gpu.ex_regs, freeze->ulControl + 0xe0, sizeof(gpu.ex_regs));
       gpu.status = freeze->ulStatus;
@@ -1093,6 +1091,7 @@ long GPUfreeze(uint32_t type, GPUFreeze_t *freeze)
       break;
   }
 
+  *vram_ptr = gpu.vram;
   return 1;
 }
 
index 16bfedf..86b1fe6 100644 (file)
@@ -193,7 +193,7 @@ void GPUreadDataMem(uint32_t *mem, int count);
 uint32_t GPUreadData(void);
 uint32_t GPUreadStatus(void);
 void GPUwriteStatus(uint32_t data);
-long GPUfreeze(uint32_t type, struct GPUFreeze *freeze);
+long GPUfreeze(uint32_t type, struct GPUFreeze *freeze, uint16_t **vram_ptr);
 void GPUupdateLace(void);
 long GPUopen(unsigned long *disp, char *cap, char *cfg);
 long GPUclose(void);
index e941fff..35f9a26 100644 (file)
@@ -400,10 +400,13 @@ typedef struct
 
 ////////////////////////////////////////////////////////////////////////\r
 
-long CALLBACK SPUfreeze(unsigned long ulFreezeMode,SPUFreeze_t * pF,unsigned int cycles)
+long DoFreeze(int ulFreezeMode, SPUFreeze_t * pF, unsigned short **ram,
+ void * pF2, unsigned int cycles)
 {
  int i;
 
+ if (ram)
+  *ram = spuMem;
  if(!pF) return 0;
 
  if(ulFreezeMode)
@@ -417,16 +420,12 @@ long CALLBACK SPUfreeze(unsigned long ulFreezeMode,SPUFreeze_t * pF,unsigned int
 
    if(ulFreezeMode==2) return 1;
 
-   memcpy(pF->SPURam, spuMem, 0x80000);
    memcpy(pF->SPUPorts, regArea, 0x200);
-   // dummy:
-   memset(&pF->xa, 0, sizeof(xa_decode_t));
    return 1;
   }
 
  if(ulFreezeMode!=0) return 0;
 
- memcpy(spuMem, pF->SPURam, 0x80000);
  memcpy(regArea, pF->SPUPorts, 0x200);
 
  for(i=0;i<0x100;i++)