cdrom: resume cdda on state load
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index c82b6da..d9a3bb3 100644 (file)
@@ -709,11 +709,12 @@ void cdrInterrupt() {
                        Wild 9: skip PREGAP + starting accurate SubQ
                        - plays tracks without retry play
                        */
+                       /* unneeded with correct cdriso?
                        Set_Track();
+                       */
                        Find_CurTrack();
                        ReadTrack( cdr.SetSectorPlay );
 
-
                        // GameShark CD Player: Calls 2x + Play 2x
                        if( cdr.FastBackward || cdr.FastForward ) {
                                if( cdr.FastForward ) cdr.FastForward--;
@@ -1224,6 +1225,7 @@ void cdrInterrupt() {
                        /*
                        Duke Nukem: Land of the Babes - seek then delay read for one frame
                        - fixes cutscenes
+                       C-12 - Final Resistance - doesn't like seek
                        */
 
                        if (!cdr.Seeked) {
@@ -1328,6 +1330,23 @@ void cdrReadInterrupt() {
                        int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector);
 
                        if (!ret) {
+                               // only handle attenuator basic channel switch for now
+                               if (cdr.Xa.stereo) {
+                                       int i;
+                                       if ((cdr.AttenuatorLeft[0] | cdr.AttenuatorLeft[1])
+                                           && !(cdr.AttenuatorRight[0] | cdr.AttenuatorRight[1]))
+                                       {
+                                               for (i = 0; i < cdr.Xa.nsamples; i++)
+                                                       cdr.Xa.pcm[i*2 + 1] = cdr.Xa.pcm[i*2];
+                                       }
+                                       else if (!(cdr.AttenuatorLeft[0] | cdr.AttenuatorLeft[1])
+                                           && (cdr.AttenuatorRight[0] | cdr.AttenuatorRight[1]))
+                                       {
+                                               for (i = 0; i < cdr.Xa.nsamples; i++)
+                                                       cdr.Xa.pcm[i*2] = cdr.Xa.pcm[i*2 + 1];
+                                       }
+                               }
+
                                SPU_playADPCMchannel(&cdr.Xa);
                                cdr.FirstSector = 0;
 
@@ -1455,6 +1474,7 @@ unsigned char cdrRead1(void) {
 }
 
 void cdrWrite1(unsigned char rt) {
+       char set_loc[3];
        int i;
 
 #ifdef CDR_LOG
@@ -1464,7 +1484,7 @@ void cdrWrite1(unsigned char rt) {
 
        // Tekken: CDXA fade-out
        if( (cdr.Ctrl & 3) == 3 ) {
-               //cdr.AttenuatorRight[0] = rt;
+               cdr.AttenuatorRight[0] = rt;
        }
 
 
@@ -1503,9 +1523,12 @@ void cdrWrite1(unsigned char rt) {
 
        case CdlSetloc:
                StopReading();
-               cdr.Seeked = FALSE;
                for (i = 0; i < 3; i++)
-                       cdr.SetSector[i] = btoi(cdr.Param[i]);
+                       set_loc[i] = btoi(cdr.Param[i]);
+               i = abs(msf2sec(cdr.SetSector) - msf2sec(set_loc));
+               if (i > 16)
+                       cdr.Seeked = FALSE;
+               memcpy(cdr.SetSector, set_loc, 3);
                cdr.SetSector[3] = 0;
 
                /*
@@ -1816,10 +1839,10 @@ void cdrWrite2(unsigned char rt) {
 
        // Tekken: CDXA fade-out
        if( (cdr.Ctrl & 3) == 2 ) {
-               //cdr.AttenuatorLeft[0] = rt;
+               cdr.AttenuatorLeft[0] = rt;
        }
        else if( (cdr.Ctrl & 3) == 3 ) {
-               //cdr.AttenuatorRight[1] = rt;
+               cdr.AttenuatorRight[1] = rt;
        }
 
 
@@ -1861,7 +1884,7 @@ void cdrWrite3(unsigned char rt) {
 #ifdef CDR_LOG
        CDR_LOG("cdrWrite3() Log: CD3 write: %x\n", rt);
 #endif
-/*
+
        // Tekken: CDXA fade-out
        if( (cdr.Ctrl & 3) == 2 ) {
                cdr.AttenuatorLeft[1] = rt;
@@ -1873,7 +1896,7 @@ void cdrWrite3(unsigned char rt) {
                        cdr.AttenuatorRight[0], cdr.AttenuatorRight[1] );
 #endif
        }
-*/
+
 
        // GameShark CDX CD Player: Irq timing mania
        if( rt == 0 &&
@@ -1901,9 +1924,14 @@ void cdrWrite3(unsigned char rt) {
                // - Final Fantasy Tactics
                // - various other games
 
-               if (cdr.Irq) // rearmed guesswork hack
                if (cdr.Reading && !cdr.ResultReady) {
-                       CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime);
+                       int left = psxRegs.intCycle[PSXINT_CDREAD].sCycle + psxRegs.intCycle[PSXINT_CDREAD].cycle - psxRegs.cycle;
+                       int time = (cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime;
+                       if (Config.CdrReschedule != 2)
+                       if (left < time / 2 || Config.CdrReschedule) { // rearmed guesswork hack
+                               //printf("-- resched %d -> %d\n", left, time);
+                               CDREAD_INT(time);
+                       }
                }
 
                return;
@@ -1931,6 +1959,7 @@ void cdrWrite3(unsigned char rt) {
 
 void psxDma3(u32 madr, u32 bcr, u32 chcr) {
        u32 cdsize;
+       int size;
        u8 *ptr;
 
 #ifdef CDR_LOG
@@ -1975,15 +2004,12 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                        - CdlPlay
                        - Spams DMA3 and gets buffer overrun
                        */
-
-                       if( (cdr.pTransfer-cdr.Transfer) + cdsize > 2352 )
-                       {
-                               // avoid crash - probably should wrap here
-                               //memcpy(ptr, cdr.pTransfer, cdsize);
-                       }
-                       else
+                       size = CD_FRAMESIZE_RAW - (cdr.pTransfer - cdr.Transfer);
+                       if (size > cdsize)
+                               size = cdsize;
+                       if (size > 0)
                        {
-                               memcpy(ptr, cdr.pTransfer, cdsize);
+                               memcpy(ptr, cdr.pTransfer, size);
                        }
 
                        psxCpu->Clear(madr, cdsize / 4);
@@ -2012,8 +2038,11 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
 
 void cdrDmaInterrupt()
 {
-       HW_DMA3_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(3);
+       if (HW_DMA3_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA3_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(3);
+       }
 }
 
 void cdrReset() {
@@ -2021,6 +2050,12 @@ void cdrReset() {
        cdr.CurTrack = 1;
        cdr.File = 1;
        cdr.Channel = 1;
+
+       // BIOS player - default values
+       cdr.AttenuatorLeft[0] = 0x80;
+       cdr.AttenuatorLeft[1] = 0x00;
+       cdr.AttenuatorRight[0] = 0x80;
+       cdr.AttenuatorRight[1] = 0x00;
 }
 
 int cdrFreeze(gzFile f, int Mode) {
@@ -2038,9 +2073,13 @@ int cdrFreeze(gzFile f, int Mode) {
 
        gzfreeze(&tmp, sizeof(tmp));
 
-       if (Mode == 0)
+       if (Mode == 0) {
                cdr.pTransfer = cdr.Transfer + tmp;
 
+               if (cdr.Play && !Config.Cdda)
+                       CDR_play(cdr.SetSectorPlay);
+       }
+
        return 0;
 }