aboutsummaryrefslogtreecommitdiff
path: root/source/nds/entry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/nds/entry.cpp')
-rw-r--r--source/nds/entry.cpp195
1 files changed, 145 insertions, 50 deletions
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp
index 5573f47..58adf49 100644
--- a/source/nds/entry.cpp
+++ b/source/nds/entry.cpp
@@ -343,6 +343,18 @@ void game_disableAudio()
S9xSetSoundMute (TRUE);
}
}
+
+void game_set_frameskip()
+{
+ if( game_config.frameskip_value == 0)
+ {
+ Settings.SkipFrames = AUTO_FRAMERATE;
+ }
+ else
+ {
+ Settings.SkipFrames = game_config.frameskip_value - 1 /* 1 -> 0 and so on */;
+ }
+}
void init_sfc_setting(void)
{
@@ -368,7 +380,6 @@ void init_sfc_setting(void)
Settings.ShutdownMaster = TRUE;
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
- Settings.FrameTime = Settings.FrameTimeNTSC;
Settings.DisableSampleCaching = FALSE;
Settings.DisableMasterVolume = FALSE;
Settings.Mouse = TRUE;
@@ -449,10 +460,12 @@ int load_gamepak(char* file)
game_disableAudio();
CPU.Flags = 0;
- S9xReset ();
// mdelay(50); // Delete this delay
if (!Memory.LoadROM (file))
return -1;
+ S9xReset ();
+
+ Settings.FrameTime = (Settings.PAL ? Settings.FrameTimePAL : Settings.FrameTimeNTSC);
Memory.LoadSRAM (S9xGetFilename (".srm"));
// mdelay(50); // Delete this delay
@@ -611,41 +624,18 @@ int sfc_main (int argc, char **argv)
return (0);
}
+static unsigned int sync_last= 0;
+static unsigned int sync_next = 0;
+static unsigned int framenum = 0;
+
+extern "C" u32 game_fast_forward;
+
+static unsigned int skip_rate= 0;
+
void S9xSyncSpeed ()
{
-#if 0
-#ifdef _NETPLAY_SUPPORT
- if (Settings.NetPlay)
- {
- // XXX: Send joypad position update to server
- // XXX: Wait for heart beat from server
- S9xNetPlaySendJoypadUpdate (joypads [0]);
- if (!S9xNetPlayCheckForHeartBeat ())
- {
- do
- {
- CHECK_SOUND ();
-// S9xProcessEvents (FALSE);
- } while (!S9xNetPlayCheckForHeartBeat ());
- IPPU.RenderThisFrame = TRUE;
- IPPU.SkippedFrames = 0;
- }
- else
- {
- if (IPPU.SkippedFrames < 10)
- {
- IPPU.SkippedFrames++;
- IPPU.RenderThisFrame = FALSE;
- }
- else
- {
- IPPU.RenderThisFrame = TRUE;
- IPPU.SkippedFrames = 0;
- }
- }
- }
- else
-#endif
+ uint32 syncnow;
+ int32 syncdif;
#if 0
if (Settings.SoundSync == 2)
@@ -655,30 +645,135 @@ void S9xSyncSpeed ()
return;
}
#endif
+ syncnow = getSysTime();
+
+ if (game_fast_forward)
+ {
+ sync_last = syncnow;
+ sync_next = syncnow;
+ if(++skip_rate < 10)
+ IPPU.RenderThisFrame = false;
+ else
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = true;
+ }
+ }
+ else if (Settings.SkipFrames == AUTO_FRAMERATE /* && !game_fast_forward */)
+ {
+ // frame_time is in getSysTime units: 42.667 microseconds.
+ uint32 frame_time = Settings.PAL ? 468 /* = 20.0 ms */ : 391 /* = 16.67 ms */;
+ if (sync_last > syncnow) // Overflow occurred! (every 50 hrs)
+ {
+ // Render this frame regardless, set the
+ // sync_next, and get the hell out.
+ IPPU.RenderThisFrame = TRUE;
+ sync_last = syncnow;
+ sync_next = syncnow + frame_time;
+ return;
+ }
+ sync_last = syncnow;
+ // If this is positive, we have syncdif*42.66 microseconds to
+ // spare.
+ // If this is negative, we're late by syncdif*42.66
+ // microseconds.
+ syncdif = sync_next - syncnow;
+ if (syncdif < 0 && syncdif >= -(frame_time / 2))
+ {
+ // We're late, but by less than half a frame. Draw it
+ // anyway. If the next frame is too late, it'll be
+ // skipped.
+ skip_rate = 0;
+ IPPU.RenderThisFrame = true;
+ sync_next += frame_time;
+ }
+ else if(syncdif < 0)
+ {
+ /*
+ * If we're consistently late, delay up to 8 frames.
+ *
+ * That really helps with certain games, such as
+ * Super Mario RPG and Yoshi's Island.
+ */
+ if(++skip_rate < 10)
+ {
+ if(syncdif >= -11719 /* not more than 500.0 ms late */)
+ {
+ IPPU.RenderThisFrame = FALSE;
+ sync_next += frame_time;
+ }
+ else
+ { //lag more than 0.5s, maybe paused
+ IPPU.RenderThisFrame = TRUE;
+ sync_next = syncnow + frame_time;
+ framenum = 0;
+ }
+ }
+ else
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = TRUE;
+ sync_next = syncnow + frame_time;
+ }
+ }
+ else // Early
+ {
+ skip_rate = 0;
+ ds2_setCPUclocklevel(0);
+ if (syncdif > 0)
+ udelay(syncdif * 128 / 3 /* times 42 + 2/3 microseconds */);
+ set_cpu_clock(clock_speed_number);
+ S9xProcessSound (0);
+
+ IPPU.RenderThisFrame = TRUE;
+ sync_next += frame_time;
+ }
#if 0
- if (Settings.TurboMode)
- {
- if(++IPPU.FrameSkip >= Settings.TurboSkipFrames)
- {
- IPPU.FrameSkip = 0;
- IPPU.SkippedFrames = 0;
- IPPU.RenderThisFrame = TRUE;
- }
- else
- {
- ++IPPU.SkippedFrames;
- IPPU.RenderThisFrame = FALSE;
- }
- return;
- }
+ if(++framenum >= 60)
+ {
+ syncdif = syncnow - sync_last;
+ sync_last = syncnow;
+ framenum = 0;
+ //printf("T %d %d\n", syncdif*42667/1000, realframe);
+ realframe = 0;
+ }
#endif
+ }
+ else /* if (Settings.SkipFrames != AUTO_FRAMERATE && !game_fast_forward) */
+ {
+ // frame_time is in getSysTime units: 42.667 microseconds.
+ uint32 frame_time = Settings.PAL ? 468 /* = 20.0 ms */ : 391 /* = 16.67 ms */;
+ sync_last = syncnow;
+ if (++skip_rate > Settings.SkipFrames)
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = TRUE;
+ // Are we early?
+ syncdif = sync_next - syncnow;
+ if (syncdif > 0)
+ {
+ ds2_setCPUclocklevel(0);
+ udelay(syncdif * 128 / 3 /* times 42 + 2/3 microseconds */);
+ set_cpu_clock(clock_speed_number);
+ S9xProcessSound (0);
+ // After that little delay, what time is it?
+ syncnow = getSysTime();
+ }
+ sync_next = syncnow + frame_time * Settings.SkipFrames;
+ }
+ else
+ {
+ IPPU.RenderThisFrame = FALSE;
+ }
+ }
#ifdef __sgi
/* BS: saves on CPU usage */
sginap(1);
#endif
+#if 0
/* Check events */
static struct timeval next1 = {0, 0};