frontend: update libpicofe, fix missed callbacks
[pcsx_rearmed.git] / plugins / dfsound / freeze.c
index 32c07db..2b50c1f 100644 (file)
@@ -15,6 +15,7 @@
  *                                                                         *\r
  ***************************************************************************/\r
 \r
+#include <stddef.h>\r
 #include <assert.h>\r
 #include "stdafx.h"\r
 \r
@@ -107,7 +108,7 @@ typedef struct
  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
@@ -137,6 +138,8 @@ typedef struct
  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
@@ -236,14 +239,18 @@ static void load_register(unsigned long reg, unsigned int cycles)
 // 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
@@ -303,6 +310,16 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
    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
@@ -331,6 +348,7 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
 \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
@@ -349,7 +367,8 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
  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
@@ -358,6 +377,15 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
   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
@@ -372,8 +400,6 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
  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