* *\r
***************************************************************************/\r
\r
+#include <stddef.h>\r
#include <assert.h>\r
#include "stdafx.h"\r
\r
ADSRInfoEx_orig ADSRX; // next ADSR settings (will be moved to active on sample start)\r
} SPUCHAN_orig;\r
\r
-typedef struct\r
+typedef struct SPUFreeze\r
{\r
char szSPUName[8];\r
uint32_t ulFreezeVersion;\r
uint32_t XARepeat;\r
uint32_t XALastVal;\r
uint32_t last_keyon_cycles;\r
+ uint32_t rvb_sb[2][4];\r
+ int32_t interpolation; // which interpolation's data is in SPUCHAN_orig::SB\r
\r
} SPUOSSFreeze_t;\r
\r
// SPUFREEZE: called by main emu on savestate load/save\r
////////////////////////////////////////////////////////////////////////\r
\r
-long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,\r
- uint32_t cycles)\r
+long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,\r
+ unsigned int cycles)\r
{\r
SPUOSSFreeze_t * pFO = NULL;\r
- int i;\r
+ sample_buf *sb_rvb = &spu.sb[MAXCHAN];\r
+ int i, j;\r
\r
if(!pF) return 0; // first check\r
\r
+#if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
+ sb_rvb = &spu.sb_thread[MAXCHAN];\r
+#endif\r
if(ulFreezeMode) // info or save?\r
{//--------------------------------------------------//\r
int xa_left = 0, cdda_left = 0;\r
pFO->xa_left = xa_left;\r
pFO->cdda_left = cdda_left;\r
pFO->cycles_played = spu.cycles_played;\r
+ pFO->cycles_dma_end = spu.cycles_dma_end;\r
+ pFO->decode_dirty_ch = spu.decode_dirty_ch;\r
+ pFO->dwNoiseVal = spu.dwNoiseVal;\r
+ pFO->dwNoiseCount = spu.dwNoiseCount;\r
+ pFO->XARepeat = spu.XARepeat;\r
+ pFO->XALastVal = spu.XALastVal;\r
+ pFO->last_keyon_cycles = spu.last_keyon_cycles;\r
+ for (i = 0; i < 2; i++)\r
+ memcpy(&pFO->rvb_sb[i], sb_rvb->SB_rvb[i], sizeof(pFO->rvb_sb[i]));\r
+ pFO->interpolation = spu.interpolation;\r
\r
for(i=0;i<MAXCHAN;i++)\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->xaS.nsamples) { // start xa again\r
FeedXA(&pF->xaS);\r
spu.XAPlay = spu.XAFeed - pFO->xa_left;\r
spu.XARepeat = 0;\r
spu.XALastVal = 0;\r
spu.last_keyon_cycles = cycles - 16*786u;\r
- if (pFO && pF->ulFreezeSize >= sizeof(*pF) + sizeof(*pFO)) {\r
+ spu.interpolation = -1;\r
+ if (pFO && pF->ulFreezeSize >= sizeof(*pF) + 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
spu.XALastVal = pFO->XALastVal;\r
spu.last_keyon_cycles = pFO->last_keyon_cycles;\r
}\r
+ if (pFO && pF->ulFreezeSize >= sizeof(*pF) + sizeof(*pFO)) {\r
+ for (i = 0; i < 2; i++)\r
+ for (j = 0; j < 2; j++)\r
+ memcpy(&sb_rvb->SB_rvb[i][j*4], pFO->rvb_sb[i], 4 * sizeof(sb_rvb->SB_rvb[i][0]));\r
+ spu.interpolation = pFO->interpolation;\r
+ }\r
+ for (i = 0; i <= 2; i += 2)\r
+ if (!regAreaGet(H_SPUcmvolL+i) && regAreaGet(H_SPUmvolL+i) < 0x8000u)\r
+ regAreaRef(H_SPUcmvolL+i) = regAreaGet(H_SPUmvolL+i) << 1;\r
\r
// repair some globals\r
for(i=0;i<=62;i+=2)\r
spu.rvb->StartAddr = regAreaGet(H_SPUReverbAddr) << 2;\r
if (spu.rvb->CurrAddr < spu.rvb->StartAddr)\r
spu.rvb->CurrAddr = spu.rvb->StartAddr;\r
- // fix to prevent new interpolations from crashing\r
- spu.interpolation = -1;\r
\r
ClearWorkingState();\r
\r