core: different frame limiter implementation
[mupen64plus-pandora.git] / source / mupen64plus-core / src / main / main.c
index 119bd7d..6b7a632 100755 (executable)
@@ -194,6 +194,8 @@ int main_set_core_defaults(void)
     ConfigSetDefaultString(g_CoreConfig, "SaveStatePath", "", "Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserConfigPath}/save will be used");
     ConfigSetDefaultString(g_CoreConfig, "SaveSRAMPath", "", "Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserConfigPath}/save will be used");
     ConfigSetDefaultString(g_CoreConfig, "SharedDataPath", "", "Path to a directory to search when looking for shared data files");
+    ConfigSetDefaultBool(g_CoreConfig, "DelaySI", 0, "Delay interrupt after DMA SI read/write");
+    ConfigSetDefaultInt(g_CoreConfig, "CountPerOp", 2, "Force number of cycles per emulated instruction");
 
     /* handle upgrades */
     if (bUpgrade)
@@ -671,7 +673,7 @@ void new_frame(void)
     }
 }
 
-void new_vi(void)
+void new_vi_(void)
 {
     int Dif;
     unsigned int CurrentFPSTime;
@@ -722,6 +724,62 @@ void new_vi(void)
     end_section(IDLE_SECTION);
 }
 
+#define TOL_FRAMES 3
+
+void new_vi(void)
+{
+    static int prev_vilimit, prev_factor;
+    static float counter, interval;
+    unsigned int now, expect;
+    int diff;
+
+    if (!l_MainSpeedLimit)
+        return;
+
+    if (ROM_PARAMS.vilimit != prev_vilimit || l_SpeedFactor != prev_factor)
+    {
+        double VILimitMilliseconds = 1000.0 / ROM_PARAMS.vilimit;
+        interval = VILimitMilliseconds * 100.0 / l_SpeedFactor;  // adjust for selected emulator speed
+        prev_vilimit = ROM_PARAMS.vilimit;
+        prev_factor = l_SpeedFactor;
+    }
+
+    start_section(IDLE_SECTION);
+
+#ifdef DBG
+    if(g_DebuggerActive) DebuggerCallback(DEBUG_UI_VI, 0);
+#endif
+
+    now = SDL_GetTicks();
+    counter += interval;
+    expect = (int)counter;
+    diff = now - expect;
+
+    if (diff < -200 || diff > 200)
+    {
+        counter = now - 1 * 17;
+        return;
+    }
+
+    if (diff > TOL_FRAMES * 17)
+    {
+        //printf("lim %d\n", diff);
+        counter = now - TOL_FRAMES * 17;
+        return;
+    }
+
+    if (diff < 0)
+    {
+        int time = -diff;
+        time -= time / 4;
+        DebugMessage(M64MSG_VERBOSE, "    new_vi(): Waiting %ims", time);
+        //printf("sleep %2d\n", time);
+        SDL_Delay(time);
+    }
+
+    end_section(IDLE_SECTION);
+}
+
 /*********************************************************************************************************
 * emulation thread - runs the core
 */
@@ -734,8 +792,12 @@ m64p_error main_run(void)
     savestates_set_autoinc_slot(ConfigGetParamBool(g_CoreConfig, "AutoStateSlotIncrement"));
     savestates_select_slot(ConfigGetParamInt(g_CoreConfig, "CurrentStateSlot"));
     no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump");
+       if (delay_si==-1) delay_si = ConfigGetParamBool(g_CoreConfig, "DelaySI");
+    if (count_per_op==-1) count_per_op = ConfigGetParamInt(g_CoreConfig, "CountPerOp");
+    if (count_per_op <= 0)
+        count_per_op = 2;
 
-    // initialize memory, and do byte-swapping if it's not been done yet
+       // initialize memory, and do byte-swapping if it's not been done yet
     if (g_MemHasBeenBSwapped == 0)
     {
         init_memory(1);
@@ -856,12 +918,3 @@ void main_stop(void)
     }
 #endif        
 }
-
-/*********************************************************************************************************
-* main function
-*/
-int main(int argc, char *argv[])
-{
-    return 1;
-}
-