Implement fix from Mednafen for Fantastic Pinball Kyuutenkai.
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index 93d2fa4..93b3c4f 100644 (file)
@@ -46,6 +46,7 @@
 
 cdrStruct cdr;
 static unsigned char *pTransfer;
+static s16 read_buf[CD_FRAMESIZE_RAW/2];
 
 /* CD-ROM magic numbers */
 #define CdlSync        0
@@ -431,6 +432,10 @@ static void AddIrqQueue(unsigned short irq, unsigned long ecycle) {
 
 static void cdrPlayInterrupt_Autopause()
 {
+       u32 abs_lev_max = 0;
+       boolean abs_lev_chselect;
+       u32 i;
+
        if ((cdr.Mode & MODE_AUTOPAUSE) && cdr.TrackChanged) {
                CDR_LOG( "CDDA STOP\n" );
 
@@ -446,10 +451,20 @@ static void cdrPlayInterrupt_Autopause()
                StopCdda();
        }
        else if (((cdr.Mode & MODE_REPORT) || cdr.FastForward || cdr.FastBackward)) {
-
+               CDR_readCDDA(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], (u8 *)read_buf);
                cdr.Result[0] = cdr.StatP;
                cdr.Result[1] = cdr.subq.Track;
                cdr.Result[2] = cdr.subq.Index;
+               
+               abs_lev_chselect = cdr.subq.Absolute[1] & 0x01;
+               
+               /* 8 is a hack. For accuracy, it should be 588. */
+               for (i = 0; i < 8; i++)
+               {
+                       abs_lev_max = MAX_VALUE(abs_lev_max, abs(read_buf[i * 2 + abs_lev_chselect]));
+               }
+               abs_lev_max = MIN_VALUE(abs_lev_max, 32767);
+               abs_lev_max |= abs_lev_chselect << 15;
 
                if (cdr.subq.Absolute[2] & 0x10) {
                        cdr.Result[3] = cdr.subq.Relative[0];
@@ -462,8 +477,8 @@ static void cdrPlayInterrupt_Autopause()
                        cdr.Result[5] = cdr.subq.Absolute[2];
                }
 
-               cdr.Result[6] = 0;
-               cdr.Result[7] = 0;
+               cdr.Result[6] = abs_lev_max >> 0;
+               cdr.Result[7] = abs_lev_max >> 8;
 
                // Rayman: Logo freeze (resultready + dataready)
                cdr.ResultReady = 1;
@@ -518,6 +533,12 @@ void cdrPlayInterrupt()
                cdrPlayInterrupt_Autopause();
 
        if (!cdr.Play) return;
+       
+       if (CDR_readCDDA && !cdr.Muted && cdr.Mode & MODE_REPORT) {
+               cdrAttenuate(read_buf, CD_FRAMESIZE_RAW / 4, 1);
+               if (SPU_playCDDAchannel)
+                       SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW);
+       }
 
        cdr.SetSectorPlay[2]++;
        if (cdr.SetSectorPlay[2] == 75) {
@@ -642,7 +663,7 @@ void cdrInterrupt() {
                        cdr.TrackChanged = FALSE;
 
                        if (!Config.Cdda)
-                               CDR_play(cdr.SetSectorPlay);
+                               CDR_play();
 
                        // Vib Ribbon: gameplay checks flag
                        cdr.StatP &= ~STATUS_SEEK;
@@ -1566,7 +1587,7 @@ int cdrFreeze(void *f, int Mode) {
 
                        Find_CurTrack(cdr.SetSectorPlay);
                        if (!Config.Cdda)
-                               CDR_play(cdr.SetSectorPlay);
+                               CDR_play();
                }
 
                if ((cdr.freeze_ver & 0xffffff00) != 0x63647200) {