frontend: update libpicofe, fix missed callbacks
[pcsx_rearmed.git] / libpcsxcore / psxcounters.c
index 02191c7..064c06b 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "psxcounters.h"
+#include "psxevents.h"
 #include "gpu.h"
 //#include "debug.h"
 #define DebugVSync()
@@ -70,17 +71,46 @@ static const u32 HSyncTotal[]     = { 263, 314 };
 #ifdef DRC_DISABLE
 Rcnt rcnts[ CounterQuantity ];
 #endif
-u32 hSyncCount = 0;
-u32 frame_counter = 0;
+unsigned int hSyncCount = 0;
+unsigned int frame_counter = 0;
 static u32 hsync_steps = 0;
 
-u32 psxNextCounter = 0, psxNextsCounter = 0;
-
 /******************************************************************************/
 
+#define FPS_FRACTIONAL_PAL  (53203425/314./3406) // ~49.75
+#define FPS_FRACTIONAL_NTSC (53693175/263./3413) // ~59.81
+
+static inline
+u32 frameCycles(void)
+{
+    int ff = Config.FractionalFramerate >= 0
+        ? Config.FractionalFramerate : Config.hacks.fractional_Framerate;
+    if (ff)
+    {
+        if (Config.PsxType)
+            return (u32)(PSXCLK / FPS_FRACTIONAL_PAL);
+        else
+            return (u32)(PSXCLK / FPS_FRACTIONAL_NTSC);
+    }
+    return Config.PsxType ? (PSXCLK / 50) : (PSXCLK / 60);
+}
+
+// used to inform the frontend about the exact framerate
+double psxGetFps()
+{
+    int ff = Config.FractionalFramerate >= 0
+        ? Config.FractionalFramerate : Config.hacks.fractional_Framerate;
+    if (ff)
+        return Config.PsxType ? FPS_FRACTIONAL_PAL : FPS_FRACTIONAL_NTSC;
+    else
+        return Config.PsxType ? 50.0 : 60.0;
+}
+
+// to inform the frontend about the exact famerate
 static inline
 u32 lineCycles(void)
 {
+    // should be more like above, but our timing is already poor anyway
     if (Config.PsxType)
         return PSXCLK / 50 / HSyncTotal[1];
     else
@@ -117,11 +147,7 @@ void verboseLog( u32 level, const char *str, ... )
 static inline
 void _psxRcntWcount( u32 index, u32 value )
 {
-    if( value > 0xffff )
-    {
-        verboseLog( 1, "[RCNT %i] wcount > 0xffff: %x\n", index, value );
-        value &= 0xffff;
-    }
+    value &= 0xffff;
 
     rcnts[index].cycleStart  = psxRegs.cycle;
     rcnts[index].cycleStart -= value * rcnts[index].rate;
@@ -213,27 +239,26 @@ void psxRcntSet()
     s32 countToUpdate;
     u32 i;
 
-    psxNextsCounter = psxRegs.cycle;
-    psxNextCounter  = 0x7fffffff;
+    psxRegs.psxNextsCounter = psxRegs.cycle;
+    psxRegs.psxNextCounter  = 0x7fffffff;
 
     for( i = 0; i < CounterQuantity; ++i )
     {
-        countToUpdate = rcnts[i].cycle - (psxNextsCounter - rcnts[i].cycleStart);
+        countToUpdate = rcnts[i].cycle - (psxRegs.psxNextsCounter - rcnts[i].cycleStart);
 
         if( countToUpdate < 0 )
         {
-            psxNextCounter = 0;
+            psxRegs.psxNextCounter = 0;
             break;
         }
 
-        if( countToUpdate < (s32)psxNextCounter )
+        if( countToUpdate < (s32)psxRegs.psxNextCounter )
         {
-            psxNextCounter = countToUpdate;
+            psxRegs.psxNextCounter = countToUpdate;
         }
     }
 
-    psxRegs.interrupt |= (1 << PSXINT_RCNT);
-    new_dyna_set_event(PSXINT_RCNT, psxNextCounter);
+    set_event(PSXINT_RCNT, psxRegs.psxNextCounter);
 }
 
 /******************************************************************************/
@@ -312,7 +337,7 @@ static void scheduleRcntBase(void)
 
     if (hSyncCount + hsync_steps == HSyncTotal[Config.PsxType])
     {
-        rcnts[3].cycle = Config.PsxType ? PSXCLK / 50 : PSXCLK / 60;
+        rcnts[3].cycle = frameCycles();
     }
     else
     {
@@ -384,7 +409,7 @@ void psxRcntUpdate()
         if( hSyncCount >= HSyncTotal[Config.PsxType] )
         {
             u32 status, field = 0;
-            rcnts[3].cycleStart += Config.PsxType ? PSXCLK / 50 : PSXCLK / 60;
+            rcnts[3].cycleStart += frameCycles();
             hSyncCount = 0;
             frame_counter++;
 
@@ -397,6 +422,8 @@ void psxRcntUpdate()
             }
             HW_GPU_STATUS = SWAP32(status);
             GPU_vBlank(0, field);
+            if ((s32)(psxRegs.gpuIdleAfter - psxRegs.cycle) < 0)
+                psxRegs.gpuIdleAfter = psxRegs.cycle - 1; // prevent overflow
 
             if ((rcnts[0].mode & 7) == (RcSyncModeEnable | Rc01UnblankReset) ||
                 (rcnts[0].mode & 7) == (RcSyncModeEnable | Rc01UnblankReset2))
@@ -567,8 +594,8 @@ s32 psxRcntFreeze( void *f, s32 Mode )
     gzfreeze( &rcnts, sizeof(Rcnt) * CounterQuantity );
     gzfreeze( &hSyncCount, sizeof(hSyncCount) );
     gzfreeze( &spuSyncCount, sizeof(spuSyncCount) );
-    gzfreeze( &psxNextCounter, sizeof(psxNextCounter) );
-    gzfreeze( &psxNextsCounter, sizeof(psxNextsCounter) );
+    gzfreeze( &psxRegs.psxNextCounter, sizeof(psxRegs.psxNextCounter) );
+    gzfreeze( &psxRegs.psxNextsCounter, sizeof(psxRegs.psxNextsCounter) );
 
     if (Mode == 0)
     {