X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=plugins%2Fdfsound%2Ffreeze.c;h=d4898b46a2bb48f03e3310f77c13aef6c014c37e;hb=b34d6a805a50ee4a897b0a53bbc0b89e3eb7f72e;hp=51e9fd77582436cf78c92db10aecc3d853f41160;hpb=dc3178e9ced416632e8b5b5486bb35a561a6b2b9;p=pcsx_rearmed.git diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 51e9fd77..d4898b46 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -122,9 +122,10 @@ typedef struct unsigned short decode_pos; uint32_t pSpuIrq; uint32_t spuAddr; - uint32_t dummy1; - uint32_t dummy2; - uint32_t dummy3; + uint32_t rvb_cur; + uint16_t xa_left; + uint16_t cdda_left; + uint32_t cycles_played; SPUCHAN_orig s_chan[MAXCHAN]; @@ -132,8 +133,8 @@ typedef struct //////////////////////////////////////////////////////////////////////// -void LoadStateV5(SPUFreeze_t * pF); // newest version -void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles); // unknown format +static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles); +static void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles); // unknown format // we want to retain compatibility between versions, // so use original channel struct @@ -228,14 +229,16 @@ static void load_register(unsigned long reg, unsigned int cycles) long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, uint32_t cycles) { - int i;SPUOSSFreeze_t * pFO; + SPUOSSFreeze_t * pFO = NULL; + int i; if(!pF) return 0; // first check - do_samples(cycles, 1); - if(ulFreezeMode) // info or save? {//--------------------------------------------------// + int xa_left = 0, cdda_left = 0; + do_samples(cycles, 1); + if(ulFreezeMode==1) memset(pF,0,sizeof(SPUFreeze_t)+sizeof(SPUOSSFreeze_t)); @@ -250,10 +253,31 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, if(spu.xapGlobal && spu.XAPlay!=spu.XAFeed) // some xa { - pF->xaS=*spu.xapGlobal; + xa_left = spu.XAFeed - spu.XAPlay; + if (xa_left < 0) + xa_left = spu.XAEnd - spu.XAPlay + spu.XAFeed - spu.XAStart; + pF->xaS = *spu.xapGlobal; + } + else if (spu.CDDAPlay != spu.CDDAFeed) + { + // abuse the xa struct to store leftover cdda samples + unsigned int *p = spu.CDDAPlay; + 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->xaS.pcm) / 4) + cdda_left = sizeof(pF->xaS.pcm) / 4; + if (p + cdda_left <= spu.CDDAEnd) + memcpy(pF->xaS.pcm, p, cdda_left * 4); + else { + memcpy(pF->xaS.pcm, p, (spu.CDDAEnd - p) * 4); + memcpy((char *)pF->xaS.pcm + (spu.CDDAEnd - p) * 4, spu.CDDAStart, + (cdda_left - (spu.CDDAEnd - p)) * 4); + } + pF->xaS.nsamples = 0; } - else - memset(&pF->xaS,0,sizeof(xa_decode_t)); // or clean xa + else + memset(&pF->xaS,0,sizeof(xa_decode_t)); // or clean xa pFO=(SPUOSSFreeze_t *)(pF+1); // store special stuff @@ -263,6 +287,10 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, pFO->spuAddr=spu.spuAddr; if(pFO->spuAddr==0) pFO->spuAddr=0xbaadf00d; pFO->decode_pos = spu.decode_pos; + pFO->rvb_cur = spu.rvb->CurrAddr; + pFO->xa_left = xa_left; + pFO->cdda_left = cdda_left; + pFO->cycles_played = spu.cycles_played; for(i=0;icSPUPort,0x200); spu.bMemDirty = 1; - if(pF->xaS.nsamples<=4032) // start xa again - SPUplayADPCMchannel(&pF->xaS, spu.cycles_played, 0); - - spu.xapGlobal=0; - - if(!strcmp(pF->szSPUName,"PBOSS") && pF->ulFreezeVersion==5) - LoadStateV5(pF); + if (!strcmp(pF->szSPUName,"PBOSS") && pF->ulFreezeVersion==5) + pFO = LoadStateV5(pF, cycles); else LoadStateUnknown(pF, cycles); + spu.XAPlay = spu.XAFeed = spu.XAStart; + spu.CDDAPlay = spu.CDDAFeed = spu.CDDAStart; + if (pFO && pFO->xa_left && pF->xaS.nsamples) { // start xa again + FeedXA(&pF->xaS); + 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->xaS.pcm, pFO->cdda_left * 4); + } + // repair some globals for(i=0;i<=62;i+=2) load_register(H_Reverb+i, cycles); @@ -308,7 +343,6 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, for(i=0;ispuAddr & 0x7fffe; } spu.decode_pos = pFO->decode_pos & 0x1ff; + spu.rvb->CurrAddr = pFO->rvb_cur; + spu.cycles_played = pFO->cycles_played ? pFO->cycles_played : cycles; spu.dwNewChannel=0; spu.dwChannelsAudible=0; @@ -343,11 +379,12 @@ void LoadStateV5(SPUFreeze_t * pF) spu.s_chan[i].pCurr+=(uintptr_t)spu.spuMemC; spu.s_chan[i].pLoop+=(uintptr_t)spu.spuMemC; } + return pFO; } //////////////////////////////////////////////////////////////////////// -void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles) +static void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles) { int i; @@ -360,6 +397,7 @@ void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles) spu.dwChannelsAudible=0; spu.dwChannelDead=0; spu.pSpuIrq=spu.spuMemC; + spu.cycles_played = cycles; for(i=0;i<0xc0;i++) { @@ -368,3 +406,4 @@ void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles) } //////////////////////////////////////////////////////////////////////// +// vim:shiftwidth=1:expandtab