diff options
Diffstat (limited to 'source/nds')
-rw-r--r-- | source/nds/entry.cpp | 195 | ||||
-rw-r--r-- | source/nds/gui.c | 21 | ||||
-rw-r--r-- | source/nds/gui.h | 62 | ||||
-rw-r--r-- | source/nds/message.h | 17 |
4 files changed, 222 insertions, 73 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}; diff --git a/source/nds/gui.c b/source/nds/gui.c index 4ebb224..d198166 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -17,8 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "snes9x.h" - #include <stdio.h> #include <string.h> #include <sys/stat.h> @@ -78,7 +78,7 @@ GAME_CONFIG game_config; //save state file map char savestate_map[SAVE_STATE_SLOT_NUM]; -static unsigned int savestate_index; +static u32 savestate_index; #define MAKE_MENU(name, init_function, passive_function, key_function, end_function, \ focus_option, screen_focus) \ @@ -2776,7 +2776,7 @@ u32 menu(u16 *screen) (char*)&msg[MSG_VIDEO_ASPECT_RATIO_3], (char*)&msg[MSG_VIDEO_ASPECT_RATIO_4]}; - char *frameskip_options[] = { (char*)&msg[MSG_FRAMESKIP_0], (char*)&msg[MSG_FRAMESKIP_1] }; + char *frameskip_options[] = { (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_AUTOMATIC], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_0], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_1], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_2], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_3], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_4], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_5], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_6], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_7], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_8], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_9], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_10] }; char *on_off_options[] = { (char*)&msg[MSG_GENERAL_OFF], (char*)&msg[MSG_GENERAL_ON] }; @@ -2800,7 +2800,10 @@ u32 menu(u16 *screen) &game_fast_forward, 2, NULL, ACTION_TYPE, 2), /* 03 */ STRING_SELECTION_OPTION(game_disableAudio, NULL, &msg[FMT_AUDIO_SOUND], sound_seletion, - &game_enable_audio, 2, NULL, ACTION_TYPE, 3) + &game_enable_audio, 2, NULL, ACTION_TYPE, 3), + + /* 04 */ STRING_SELECTION_OPTION(game_set_frameskip, NULL, &msg[FMT_VIDEO_FRAME_SKIPPING], frameskip_options, + &game_config.frameskip_value, 12 /* auto (0) and 0..10 (1..11) make 12 option values */, NULL, ACTION_TYPE, 4) }; MAKE_MENU(graphics, NULL, NULL, NULL, NULL, 0, 0); @@ -4004,9 +4007,7 @@ void init_game_config(void) game_config.clock_speed_number = 5; // 396 MHz by default clock_speed_number = 5; game_config.graphic = 3; // By default, have a good-looking aspect ratio - - game_config.gamepad_config_menu = BUTTON_ID_TOUCH; - memcpy(game_config.gamepad_config_map, gamepad_config_map_init, sizeof(gamepad_config_map_init)); + game_config.frameskip_value = 0; // Automatic frame skipping game_config.backward = 0; //time backward disable game_config.backward_time = 2; //time backward granularity 1s @@ -4063,9 +4064,8 @@ void load_game_config_file(void) { fread(&game_config, 1, sizeof(GAME_CONFIG), fp); - memcpy(gamepad_config_map, game_config.gamepad_config_map, sizeof(game_config.gamepad_config_map)); - gamepad_config_menu = game_config.gamepad_config_menu; clock_speed_number = game_config.clock_speed_number; + Settings.SkipFrames = (game_config.frameskip_value == 0 ? AUTO_FRAMERATE : game_config.frameskip_value - 1 /* 1 -> 0 and so on */); } fclose(fp); @@ -4113,9 +4113,6 @@ int save_game_config_file(void) if(gamepak_name[0] == 0) return -1; - memcpy(game_config.gamepad_config_map, gamepad_config_map, sizeof(game_config.gamepad_config_map)); - game_config.gamepad_config_menu = gamepad_config_menu; - sprintf(game_config_filename, "%s/%s", DEFAULT_CFG_DIR, gamepak_name); pt = strrchr(game_config_filename, '.'); if(NULL == pt) diff --git a/source/nds/gui.h b/source/nds/gui.h index 5a40979..ec0dd1a 100644 --- a/source/nds/gui.h +++ b/source/nds/gui.h @@ -44,16 +44,63 @@ struct _EMU_CONFIG struct _GAME_CONFIG { - u32 clock_speed_number; - u32 frameskip_type; + u32 clock_speed_number; + u32 Reserved0; u32 frameskip_value; - u32 graphic; - u32 enable_audio; - u32 gamepad_config_menu; + u32 graphic; + u32 enable_audio; + u32 Reserved1; u32 backward; u32 backward_time; - u32 reserve[32]; - u32 gamepad_config_map[MAX_GAMEPAD_MAP]; + u32 Reserved2; + u32 Reserved3; + u32 Reserved4; + u32 Reserved5; + u32 Reserved6; + u32 Reserved7; + u32 Reserved8; + u32 Reserved9; + u32 Reserved10; + u32 Reserved11; + u32 Reserved12; + u32 Reserved13; + u32 Reserved14; + u32 Reserved15; + u32 Reserved16; + u32 Reserved17; + u32 Reserved18; + u32 Reserved19; + u32 Reserved20; + u32 Reserved21; + u32 Reserved22; + u32 Reserved23; + u32 Reserved24; + u32 Reserved25; + u32 Reserved26; + u32 Reserved27; + u32 Reserved28; + u32 Reserved29; + u32 Reserved30; + u32 Reserved31; + u32 Reserved32; + + u32 Reserved33; + u32 Reserved34; + u32 Reserved35; + u32 Reserved36; + u32 Reserved37; + u32 Reserved38; + u32 Reserved39; + u32 Reserved40; + u32 Reserved41; + u32 Reserved42; + u32 Reserved43; + u32 Reserved44; + u32 Reserved45; + u32 Reserved46; + u32 Reserved47; + u32 Reserved48; + u32 Reserved49; }; typedef enum @@ -118,6 +165,7 @@ extern GAME_CONFIG game_config; extern void gui_init(u32 lang_id); extern u32 menu(u16 *original_screen); extern void game_disableAudio(); +extern void game_set_frameskip(); extern void set_cpu_clock(u32 num); #ifdef __cplusplus diff --git a/source/nds/message.h b/source/nds/message.h index ee89acd..09332bc 100644 --- a/source/nds/message.h +++ b/source/nds/message.h @@ -30,8 +30,7 @@ enum MSG MSG_MAIN_MENU_EXIT, FMT_VIDEO_ASPECT_RATIO, FMT_VIDEO_FAST_FORWARD, - FMT_VIDEO_FRAME_SKIP_AUTOMATIC, - FMT_VIDEO_FRAME_SKIP_MANUAL, + FMT_VIDEO_FRAME_SKIPPING, FMT_AUDIO_SOUND, MSG_SAVED_STATE_CREATE, FMT_SAVED_STATE_LOAD, @@ -56,8 +55,18 @@ enum MSG MSG_VIDEO_ASPECT_RATIO_3, MSG_VIDEO_ASPECT_RATIO_4, - MSG_FRAMESKIP_0, // currently unused - MSG_FRAMESKIP_1, // currently unused + MSG_VIDEO_FRAME_SKIPPING_AUTOMATIC, + MSG_VIDEO_FRAME_SKIPPING_0, + MSG_VIDEO_FRAME_SKIPPING_1, + MSG_VIDEO_FRAME_SKIPPING_2, + MSG_VIDEO_FRAME_SKIPPING_3, + MSG_VIDEO_FRAME_SKIPPING_4, + MSG_VIDEO_FRAME_SKIPPING_5, + MSG_VIDEO_FRAME_SKIPPING_6, + MSG_VIDEO_FRAME_SKIPPING_7, + MSG_VIDEO_FRAME_SKIPPING_8, + MSG_VIDEO_FRAME_SKIPPING_9, + MSG_VIDEO_FRAME_SKIPPING_10, MSG_GENERAL_OFF, MSG_GENERAL_ON, |