From d7c6199ed6792fbce9b99792063099a67be9e89c Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 21 Feb 2026 01:33:20 +0200 Subject: [PATCH] misc: eliminate extra allocs on state save/load and copying --- frontend/menu.c | 13 ++--- frontend/plugin.c | 2 +- include/psemu_plugin_defs.h | 12 ++--- libpcsxcore/gpu.h | 2 +- libpcsxcore/misc.c | 99 ++++++++++++++++++++++--------------- libpcsxcore/plugins.h | 5 +- plugins/dfsound/freeze.c | 70 +++++++++++++------------- plugins/dfsound/spu.c | 6 +-- plugins/dfsound/spu.h | 6 ++- plugins/gpulib/gpu.c | 5 +- plugins/gpulib/gpu.h | 2 +- plugins/spunull/spunull.c | 9 ++-- 12 files changed, 125 insertions(+), 106 deletions(-) diff --git a/frontend/menu.c b/frontend/menu.c index 1e44fae0..809e1d40 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -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); diff --git a/frontend/plugin.c b/frontend/plugin.c index 3263ae31..86b8bb92 100644 --- a/frontend/plugin.c +++ b/frontend/plugin.c @@ -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); diff --git a/include/psemu_plugin_defs.h b/include/psemu_plugin_defs.h index 2003e65d..88331f13 100644 --- a/include/psemu_plugin_defs.h +++ b/include/psemu_plugin_defs.h @@ -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 */ diff --git a/libpcsxcore/gpu.h b/libpcsxcore/gpu.h index 95132532..10187680 100644 --- a/libpcsxcore/gpu.h +++ b/libpcsxcore/gpu.h @@ -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) diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index fcac1a8b..b7eaa931 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -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); diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h index 80417577..334899d6 100644 --- a/libpcsxcore/plugins.h +++ b/libpcsxcore/plugins.h @@ -59,7 +59,7 @@ typedef uint32_t (CALLBACK* GPUreadData)(void); typedef void (CALLBACK* GPUreadDataMem)(uint32_t *, int); typedef long (CALLBACK* GPUdmaChain)(uint32_t *, uint32_t, uint32_t *, int32_t *); typedef void (CALLBACK* GPUupdateLace)(void); -typedef long (CALLBACK* GPUfreeze)(uint32_t, GPUFreeze_t *); +typedef long (CALLBACK* GPUfreeze)(uint32_t, GPUFreeze_t *, uint16_t **); typedef void (CALLBACK* GPUvBlank)(int, int); typedef void (CALLBACK* GPUgetScreenInfo)(int *, int *); @@ -100,7 +100,8 @@ typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int, unsigned int); typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *, unsigned int, int); typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(int)); typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after)); -typedef long (CALLBACK* SPUfreeze)(unsigned int, struct SPUFreeze *, unsigned int); +typedef long (CALLBACK* SPUfreeze)(int ulFreezeMode, SPUFreeze_t * pF, + unsigned short **ram, void * pF2, unsigned int cycles); typedef void (CALLBACK* SPUasync)(unsigned int, unsigned int); typedef int (CALLBACK* SPUplayCDDAchannel)(short *, int, unsigned int, int); typedef void (CALLBACK* SPUsetCDvol)(unsigned char, unsigned char, unsigned char, unsigned char, unsigned int); diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 7daafb92..be43c2c8 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -111,6 +111,8 @@ typedef struct typedef struct { + xa_decode_t xa; + unsigned short spuIrq; unsigned short decode_pos; uint32_t pSpuIrq; @@ -136,8 +138,8 @@ typedef struct //////////////////////////////////////////////////////////////////////// -static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles); -static void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles); // unknown format +static void LoadStateV5(SPUOSSFreeze_t * pFO, uint32_t cycles); +static void LoadStateUnknown(uint32_t cycles); // unknown format #define SB_FORMAT_MAGIC 0x73626201 @@ -241,14 +243,19 @@ static void load_register(unsigned long reg, unsigned int cycles) // SPUFREEZE: called by main emu on savestate load/save //////////////////////////////////////////////////////////////////////// -long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, - unsigned int cycles) +long DoFreeze(int ulFreezeMode, struct SPUFreeze * pF, unsigned short **ram, + void * pF2, unsigned int cycles) { SPUOSSFreeze_t * pFO = NULL; sample_buf_rvb *sb_rvb = &spu.sb_rvb; + unsigned int ossOffset = sizeof(SPUFreeze_t) + 512*1024; // when combined int i, j; - if(!pF) return 0; // first check + assert(sizeof(SPUOSSFreeze_t) <= SPUFREEZE_F2_MAX_SIZE); + if (ram) + *ram = spu.spuMem; + if (!pF || !pF2) return 0; // first check + pFO = pF2; #if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE) sb_rvb = (sample_buf_rvb *)&spu.sb_thread[MAXCHAN]; @@ -258,18 +265,17 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, int xa_left = 0, cdda_left = 0; do_samples(cycles, 1); - if(ulFreezeMode==1) - memset(pF,0,sizeof(SPUFreeze_t)+sizeof(SPUOSSFreeze_t)); + if (ulFreezeMode == 1) + memset(pF, 0, sizeof(*pF)); strcpy(pF->PluginName, "PBOSS"); pF->PluginVersion = 5; - pF->Size = sizeof(SPUFreeze_t)+sizeof(SPUOSSFreeze_t); + pF->Size = ossOffset + sizeof(SPUOSSFreeze_t); if(ulFreezeMode==2) return 1; // info mode? ok, bye // save mode: regAreaGet(H_SPUctrl) = spu.spuCtrl; regAreaGet(H_SPUstat) = spu.spuStat; - memcpy(pF->SPURam, spu.spuMem, 0x80000); // copy common infos memcpy(pF->SPUPorts, spu.regArea, 0x200); if(spu.xapGlobal && spu.XAPlay!=spu.XAFeed) // some xa @@ -277,7 +283,7 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, xa_left = spu.XAFeed - spu.XAPlay; if (xa_left < 0) xa_left = spu.XAEnd - spu.XAPlay + spu.XAFeed - spu.XAStart; - pF->xa = *spu.xapGlobal; + pFO->xa = *spu.xapGlobal; } else if (spu.CDDAPlay != spu.CDDAFeed) { @@ -286,21 +292,19 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, cdda_left = spu.CDDAFeed - spu.CDDAPlay; if (cdda_left < 0) cdda_left = spu.CDDAEnd - spu.CDDAPlay + spu.CDDAFeed - spu.CDDAStart; - if (cdda_left > sizeof(pF->xa.pcm) / 4) - cdda_left = sizeof(pF->xa.pcm) / 4; + if (cdda_left > sizeof(pFO->xa.pcm) / 4) + cdda_left = sizeof(pFO->xa.pcm) / 4; if (p + cdda_left <= spu.CDDAEnd) - memcpy(pF->xa.pcm, p, cdda_left * 4); + memcpy(pFO->xa.pcm, p, cdda_left * 4); else { - memcpy(pF->xa.pcm, p, (spu.CDDAEnd - p) * 4); - memcpy((char *)pF->xa.pcm + (spu.CDDAEnd - p) * 4, spu.CDDAStart, + memcpy(pFO->xa.pcm, p, (spu.CDDAEnd - p) * 4); + memcpy((char *)pFO->xa.pcm + (spu.CDDAEnd - p) * 4, spu.CDDAStart, (cdda_left - (spu.CDDAEnd - p)) * 4); } - pF->xa.nsamples = 0; + pFO->xa.nsamples = 0; } else - memset(&pF->xa, 0, sizeof(xa_decode_t)); // or clean xa - - pFO=(SPUOSSFreeze_t *)(pF+1); // store special stuff + memset(&pFO->xa, 0, sizeof(xa_decode_t)); // or clean xa pFO->spuIrq = spu.regArea[(H_SPUirqAddr - 0x0c00) / 2]; if(spu.pSpuIrq) pFO->pSpuIrq = spu.pSpuIrq - spu.spuMemC; @@ -338,27 +342,29 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, if(ulFreezeMode!=0) return 0; // bad mode? bye - memcpy(spu.spuMem, pF->SPURam, 0x80000); // get ram memcpy(spu.regArea, pF->SPUPorts, 0x200); spu.bMemDirty = 1; spu.spuCtrl = regAreaGet(H_SPUctrl); spu.spuStat = regAreaGet(H_SPUstat); if (!strcmp(pF->PluginName, "PBOSS") && pF->PluginVersion == 5) - pFO = LoadStateV5(pF, cycles); - else LoadStateUnknown(pF, cycles); + LoadStateV5(pFO, cycles); + else { + LoadStateUnknown(cycles); + pFO = NULL; + } spu.XAPlay = spu.XAFeed = spu.XAStart; spu.CDDAPlay = spu.CDDAFeed = spu.CDDAStart; spu.cdClearSamples = 512; - if (pFO && pFO->xa_left && pF->xa.nsamples) { // start xa again - FeedXA(&pF->xa); + if (pFO && pFO->xa_left && pFO->xa.nsamples) { // start xa again + FeedXA(&pFO->xa); spu.XAPlay = spu.XAFeed - pFO->xa_left; if (spu.XAPlay < spu.XAStart) spu.XAPlay = spu.XAStart; } else if (pFO && pFO->cdda_left) { // start cdda again - FeedCDDA((void *)pF->xa.pcm, pFO->cdda_left * 4); + FeedCDDA((void *)pFO->xa.pcm, pFO->cdda_left * 4); } // not in old savestates @@ -370,7 +376,7 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, spu.XALastVal = 0; spu.last_keyon_cycles = cycles - 16*786u; spu.interpolation = -1; - if (pFO && pF->Size >= sizeof(*pF) + offsetof(SPUOSSFreeze_t, rvb_sb)) { + if (pFO && pF->Size >= ossOffset + offsetof(SPUOSSFreeze_t, rvb_sb)) { spu.cycles_dma_end = pFO->cycles_dma_end; spu.decode_dirty_ch = pFO->decode_dirty_ch; spu.dwNoiseVal = pFO->dwNoiseVal; @@ -379,7 +385,7 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, spu.XALastVal = pFO->XALastVal; spu.last_keyon_cycles = pFO->last_keyon_cycles; } - if (pFO && pF->Size >= sizeof(*pF) + sizeof(*pFO)) { + if (pFO && pF->Size >= ossOffset + sizeof(*pFO)) { for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) memcpy(&sb_rvb->sample[i][j*4], pFO->rvb_sb[i], 4 * sizeof(sb_rvb->sample[i][0])); @@ -413,11 +419,9 @@ long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, //////////////////////////////////////////////////////////////////////// -static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles) +static void LoadStateV5(SPUOSSFreeze_t * pFO, uint32_t cycles) { - int i;SPUOSSFreeze_t * pFO; - - pFO=(SPUOSSFreeze_t *)(pF+1); + int i; spu.pSpuIrq = spu.spuMemC + ((spu.regArea[(H_SPUirqAddr - 0x0c00) / 2] << 3) & ~0xf); @@ -440,13 +444,11 @@ static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles) spu.s_chan[i].pCurr+=(uintptr_t)spu.spuMemC; spu.s_chan[i].pLoop+=(uintptr_t)spu.spuMemC; } - - return pFO; } //////////////////////////////////////////////////////////////////////// -static void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles) +static void LoadStateUnknown(uint32_t cycles) { int i; diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index e7bff1a0..7e7f827b 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -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 diff --git a/plugins/dfsound/spu.h b/plugins/dfsound/spu.h index f2aa9a4e..45f84e48 100644 --- a/plugins/dfsound/spu.h +++ b/plugins/dfsound/spu.h @@ -29,7 +29,8 @@ void CALLBACK SPUwriteRegister(unsigned long, unsigned short, unsigned int); unsigned short CALLBACK SPUreadRegister(unsigned long, unsigned int); void CALLBACK SPUregisterCallback(void (*cb)(int)); void CALLBACK SPUregisterScheduleCb(void (*cb)(unsigned int)); -long CALLBACK SPUfreeze(unsigned int, struct SPUFreeze *, unsigned int); +long CALLBACK SPUfreeze(int ulFreezeMode, struct SPUFreeze * pF, unsigned short **ram, + void * pF2, unsigned int cycles); void CALLBACK SPUasync(unsigned int, unsigned int); void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cycles); @@ -42,6 +43,7 @@ void CALLBACK SPUsetCDvol(unsigned char ll, unsigned char lr, // internal void ClearWorkingState(void); -long DoFreeze(unsigned int, struct SPUFreeze *, unsigned int); +long DoFreeze(int ulFreezeMode, struct SPUFreeze * pF, unsigned short **ram, + void * pF2, unsigned int cycles); #endif /* __P_SPU_H__ */ diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c index adbfad6b..271e1c79 100644 --- a/plugins/gpulib/gpu.c +++ b/plugins/gpulib/gpu.c @@ -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; } diff --git a/plugins/gpulib/gpu.h b/plugins/gpulib/gpu.h index 16bfedf9..86b1fe6a 100644 --- a/plugins/gpulib/gpu.h +++ b/plugins/gpulib/gpu.h @@ -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); diff --git a/plugins/spunull/spunull.c b/plugins/spunull/spunull.c index e941fff1..35f9a26a 100644 --- a/plugins/spunull/spunull.c +++ b/plugins/spunull/spunull.c @@ -400,10 +400,13 @@ typedef struct //////////////////////////////////////////////////////////////////////// -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++) -- 2.47.3