diff options
author | Nebuleon Fumika | 2013-01-07 04:38:35 -0500 |
---|---|---|
committer | Nebuleon Fumika | 2013-01-07 04:38:35 -0500 |
commit | dac11c74ac112728016e51625ac9f2a727152ddd (patch) | |
tree | 9d3253ae2b6c7552befffe5391f99fff5e585ec0 | |
parent | 8447b6304cf261f6219aa9fd4e04d99f6a76305a (diff) | |
download | snesemu-dac11c74ac112728016e51625ac9f2a727152ddd.tar.gz snesemu-dac11c74ac112728016e51625ac9f2a727152ddd.tar.bz2 snesemu-dac11c74ac112728016e51625ac9f2a727152ddd.zip |
Smooth out the automatic frame skipping such that it doesn't go from 1 FPS to 8 FPS right away and constantly. The equivalent frame skip will be 2, 3, 5 or 8 most of the time, depending on the game, and will vary a bit depending on rendering demands.
For example, the frame skipping in Super Mario World is 3 on the map and in graphically simple levels, and 5 in complex levels.
-rw-r--r-- | source/nds/entry.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index bff57b2..63d736f 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -626,7 +626,7 @@ int sfc_main (int argc, char **argv) static unsigned int sync_last= 0; static unsigned int sync_next = 0; -static unsigned int framenum = 0; +static unsigned int auto_equivalent_skip = 0; extern "C" u32 game_fast_forward; @@ -664,6 +664,54 @@ void S9xSyncSpeed () { // 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 > auto_equivalent_skip) + { + skip_rate = 0; + IPPU.RenderThisFrame = TRUE; + // Are we early? + syncdif = sync_next - syncnow; + if (syncdif > 0) + { + // Are we VERY early? Say, 3 entire frames... + if (syncdif >= frame_time * 3) + auto_equivalent_skip -= 2; + // or one + else if (syncdif >= frame_time) + auto_equivalent_skip--; + 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(); + } + else + { + // We're late. + // If we're over half a second late, we were + // paused, so do nothing. + if (syncdif <= -11719 /* 500.0 ms late or more */) + sync_next = syncnow + frame_time * (auto_equivalent_skip + 1); + else if (auto_equivalent_skip < 7) + auto_equivalent_skip++; + } + if (auto_equivalent_skip >= 8) + // If we're skipping loads, rebase time to now. + sync_next = syncnow + frame_time * (auto_equivalent_skip + 1); + else + // Otherwise, keep track of partial-frame + // latencies for a bit more. + sync_next += frame_time * (auto_equivalent_skip + 1); + } + else + { + IPPU.RenderThisFrame = FALSE; + } + +#if 0 + // 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 @@ -729,7 +777,7 @@ void S9xSyncSpeed () IPPU.RenderThisFrame = TRUE; sync_next += frame_time; } -#if 0 +/* if(++framenum >= 60) { syncdif = syncnow - sync_last; @@ -738,6 +786,7 @@ void S9xSyncSpeed () //printf("T %d %d\n", syncdif*42667/1000, realframe); realframe = 0; } +*/ #endif } else /* if (Settings.SkipFrames != AUTO_FRAMERATE && !game_fast_forward) */ |