Implement fix from Mednafen for Fantastic Pinball Kyuutenkai. (#206)
authorgameblabla <gameblabla@users.noreply.github.com>
Mon, 30 Aug 2021 22:34:02 +0000 (22:34 +0000)
committerGitHub <noreply@github.com>
Mon, 30 Aug 2021 22:34:02 +0000 (01:34 +0300)
This is taken from the way Mednafen implemented it.
https://github.com/libretro-mirrors/mednafen-git/blob/563b72e377fa8284559df4df0271108d4935c9f1/src/psx/cdc.cpp#L941

This properly fixes the freeze issue in Fantastic Pinball Kyuutenkai.

libpcsxcore/cdrom.c
libpcsxcore/cdrom.h

index 7236179..4e312fd 100644 (file)
@@ -431,6 +431,11 @@ static void AddIrqQueue(unsigned short irq, unsigned long ecycle) {
 
 static void cdrPlayInterrupt_Autopause()
 {
+       u32 abs_lev_max = 0;
+       boolean abs_lev_chselect;
+       u32 i;
+       s16 read_buf[CD_FRAMESIZE_RAW/2];
+       
        if ((cdr.Mode & MODE_AUTOPAUSE) && cdr.TrackChanged) {
                CDR_LOG( "CDDA STOP\n" );
 
@@ -446,10 +451,21 @@ static void cdrPlayInterrupt_Autopause()
                StopCdda();
        }
        else if (cdr.Mode & MODE_REPORT) {
+               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 +478,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;
index a37f6ba..860930b 100644 (file)
@@ -34,6 +34,10 @@ extern "C" {
 #define btoi(b)     ((b) / 16 * 10 + (b) % 16) /* BCD to u_char */
 #define itob(i)     ((i) / 10 * 16 + (i) % 10) /* u_char to BCD */
 
+#define ABS_CD(x) ((x >= 0) ? x : -x)
+#define MIN_VALUE(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
+#define MAX_VALUE(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
+
 #define MSF2SECT(m, s, f)              (((m) * 60 + (s) - 2) * 75 + (f))
 
 #define CD_FRAMESIZE_RAW               2352