From a8c2fcdb2c3fa0211581cc82ea8e2d93d225fd7d Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Thu, 14 Feb 2013 03:02:33 -0500 Subject: Add hotkeys to quickly load from and save to saved state #1, as well as to toggle full-screen (going from mode 3, middle of screen, to mode 4, full-screen smoothed). This commit uses text that has not been validated in some languages. --- source/nds/entry.cpp | 72 ++++++++++++++++++++--- source/nds/entry.h | 7 ++- source/nds/gui.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++- source/nds/gui.h | 20 ++++--- source/nds/message.h | 3 + 5 files changed, 244 insertions(+), 20 deletions(-) (limited to 'source') diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index ec1be4e..042991c 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -33,6 +33,12 @@ void S9xProcessSound (unsigned int); char *rom_filename = NULL; char *SDD1_pack = NULL; +/* + * It is only safe to manipulate saved states between frames. + */ +static bool8 LoadStateNeeded = FALSE; +static bool8 SaveStateNeeded = FALSE; + static u8 Buf[MAX_BUFFER_SIZE]; #define FIXED_POINT 0x10000 @@ -626,16 +632,28 @@ int sfc_main (int argc, char **argv) } else #endif - if (Settings.Paused) { - S9xSetSoundMute (TRUE); - unsigned short screen[256*192]; + if (SaveStateNeeded) { + QuickSaveState (); + SaveStateNeeded = FALSE; + } - copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192); - menu(screen, FirstInvocation); - FirstInvocation = FALSE; - game_disableAudio(); - Settings.Paused = 0; + if (LoadStateNeeded) { + QuickLoadState (); + LoadStateNeeded = FALSE; + } + + if (Settings.Paused) + { + S9xSetSoundMute (TRUE); + unsigned short screen[256*192]; + + copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192); + menu(screen, FirstInvocation); + FirstInvocation = FALSE; + game_disableAudio(); + Settings.Paused = 0; + } } #ifdef JOYSTICK_SUPPORT @@ -658,7 +676,6 @@ void S9xSyncSpeed () { uint32 syncnow; int32 syncdif; - unsigned int LastAutoCPUFrequency = AutoCPUFrequency; #if 0 if (Settings.SoundSync == 2) @@ -1197,6 +1214,9 @@ const unsigned int keymap[12] = { */ static bool8 SoundToggleWasHeld = FALSE; +static bool8 LoadStateWasHeld = FALSE; +static bool8 SaveStateWasHeld = FALSE; +static bool8 ToggleFullScreenWasHeld = FALSE; #ifdef ACCUMULATE_JOYPAD // These are kept as DS key bitfields until it's time to send them to Snes9x. @@ -1252,6 +1272,9 @@ uint32 S9xReadJoypad (int which1) u32 HotkeyReturnToMenu = game_config.HotkeyReturnToMenu != 0 ? game_config.HotkeyReturnToMenu : emu_config.HotkeyReturnToMenu; u32 HotkeyTemporaryFastForward = game_config.HotkeyTemporaryFastForward != 0 ? game_config.HotkeyTemporaryFastForward : emu_config.HotkeyTemporaryFastForward; u32 HotkeyToggleSound = game_config.HotkeyToggleSound != 0 ? game_config.HotkeyToggleSound : emu_config.HotkeyToggleSound; + u32 HotkeyQuickLoadState = game_config.HotkeyQuickLoadState != 0 ? game_config.HotkeyQuickLoadState : emu_config.HotkeyQuickLoadState; + u32 HotkeyQuickSaveState = game_config.HotkeyQuickSaveState != 0 ? game_config.HotkeyQuickSaveState : emu_config.HotkeyQuickSaveState; + u32 HotkeyToggleFullScreen = game_config.HotkeyToggleFullScreen != 0 ? game_config.HotkeyToggleFullScreen : emu_config.HotkeyToggleFullScreen; if(Controls & KEY_TOUCH || (HotkeyReturnToMenu && ((Controls & HotkeyReturnToMenu) == HotkeyReturnToMenu)) @@ -1274,6 +1297,37 @@ uint32 S9xReadJoypad (int which1) SoundToggleWasHeld = SoundToggleIsHeld; + /* It is only safe to load/save a state between frames. + * entry.cpp:sfc_main will pick this up. */ + bool8 LoadStateIsHeld = + (HotkeyQuickLoadState && ((Controls & HotkeyQuickLoadState) == HotkeyQuickLoadState)) + ; + + if (LoadStateIsHeld && !LoadStateWasHeld) + LoadStateNeeded = TRUE; + + LoadStateWasHeld = LoadStateIsHeld; + + bool8 SaveStateIsHeld = + (HotkeyQuickSaveState && ((Controls & HotkeyQuickSaveState) == HotkeyQuickSaveState)) + ; + + if (SaveStateIsHeld && !SaveStateWasHeld) + SaveStateNeeded = TRUE; + + SaveStateWasHeld = SaveStateIsHeld; + + /* Full-screen toggle? */ + bool8 ToggleFullScreenIsHeld = + (HotkeyToggleFullScreen && ((Controls & HotkeyToggleFullScreen) == HotkeyToggleFullScreen)) + ; + + if (ToggleFullScreenIsHeld && !ToggleFullScreenWasHeld) { + ToggleFullScreen (); + } + + ToggleFullScreenWasHeld = ToggleFullScreenIsHeld; + uint32 key = 0x80000000; // Required by Snes9x // DS -> SNES diff --git a/source/nds/entry.h b/source/nds/entry.h index 0728768..e1646fb 100644 --- a/source/nds/entry.h +++ b/source/nds/entry.h @@ -1,6 +1,11 @@ #ifdef __cplusplus extern "C" { #endif + void game_disableAudio(); + void game_set_frameskip(); + void game_set_fluidity(); + void game_set_retro(); + int game_load_state(char* file); int game_save_state(char* file); void S9xAutoSaveSRAM (); @@ -8,8 +13,6 @@ extern "C" { void game_restart(void); int load_gamepak(const char* file); - - extern unsigned int AutoCPUFrequency; #ifdef __cplusplus } #endif diff --git a/source/nds/gui.c b/source/nds/gui.c index 84d5bf6..b7ab69e 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1760,15 +1760,27 @@ u32 menu(u16 *screen, bool8 FirstInvocation) auto void set_global_hotkey_return_to_menu(); auto void set_global_hotkey_temporary_fast_forward(); auto void set_global_hotkey_toggle_sound(); + auto void set_global_hotkey_quick_load_state(); + auto void set_global_hotkey_quick_save_state(); + auto void set_global_hotkey_toggle_full_screen(); auto void set_game_specific_hotkey_return_to_menu(); auto void set_game_specific_hotkey_temporary_fast_forward(); auto void set_game_specific_hotkey_toggle_sound(); + auto void set_game_specific_hotkey_quick_load_state(); + auto void set_game_specific_hotkey_quick_save_state(); + auto void set_game_specific_hotkey_toggle_full_screen(); auto void global_hotkey_return_to_menu_passive(); auto void global_hotkey_temporary_fast_forward_passive(); auto void global_hotkey_toggle_sound_passive(); + auto void global_hotkey_quick_load_state_passive(); + auto void global_hotkey_quick_save_state_passive(); + auto void global_hotkey_toggle_full_screen_passive(); auto void game_specific_hotkey_return_to_menu_passive(); auto void game_specific_hotkey_temporary_fast_forward_passive(); auto void game_specific_hotkey_toggle_sound_passive(); + auto void game_specific_hotkey_quick_load_state_passive(); + auto void game_specific_hotkey_quick_save_state_passive(); + auto void game_specific_hotkey_toggle_full_screen_passive(); auto void load_default_setting(); auto void check_gbaemu_version(); auto void load_lastest_played(); @@ -2934,7 +2946,13 @@ u32 menu(u16 *screen, bool8 FirstInvocation) /* 02 */ ACTION_OPTION(set_global_hotkey_temporary_fast_forward, global_hotkey_temporary_fast_forward_passive, &msg[MSG_HOTKEY_TEMPORARY_FAST_FORWARD], NULL, 2), - /* 03 */ ACTION_OPTION(set_global_hotkey_toggle_sound, global_hotkey_toggle_sound_passive, &msg[MSG_HOTKEY_SOUND_TOGGLE], NULL, 3) + /* 03 */ ACTION_OPTION(set_global_hotkey_toggle_sound, global_hotkey_toggle_sound_passive, &msg[MSG_HOTKEY_SOUND_TOGGLE], NULL, 3), + + /* 04 */ ACTION_OPTION(set_global_hotkey_quick_save_state, global_hotkey_quick_save_state_passive, &msg[MSG_HOTKEY_QUICK_SAVE_STATE], NULL, 4), + + /* 05 */ ACTION_OPTION(set_global_hotkey_quick_load_state, global_hotkey_quick_load_state_passive, &msg[MSG_HOTKEY_QUICK_LOAD_STATE], NULL, 5), + + /* 06 */ ACTION_OPTION(set_global_hotkey_toggle_full_screen, global_hotkey_toggle_full_screen_passive, &msg[MSG_HOTKEY_FULL_SCREEN_TOGGLE], NULL, 6) }; MAKE_MENU(tools_global_hotkeys, NULL, NULL, NULL, NULL, 0, 0); @@ -2950,7 +2968,13 @@ u32 menu(u16 *screen, bool8 FirstInvocation) /* 02 */ ACTION_OPTION(set_game_specific_hotkey_temporary_fast_forward, game_specific_hotkey_temporary_fast_forward_passive, &msg[MSG_HOTKEY_TEMPORARY_FAST_FORWARD], NULL, 2), - /* 03 */ ACTION_OPTION(set_game_specific_hotkey_toggle_sound, game_specific_hotkey_toggle_sound_passive, &msg[MSG_HOTKEY_SOUND_TOGGLE], NULL, 3) + /* 03 */ ACTION_OPTION(set_game_specific_hotkey_toggle_sound, game_specific_hotkey_toggle_sound_passive, &msg[MSG_HOTKEY_SOUND_TOGGLE], NULL, 3), + + /* 04 */ ACTION_OPTION(set_game_specific_hotkey_quick_save_state, game_specific_hotkey_quick_save_state_passive, &msg[MSG_HOTKEY_QUICK_SAVE_STATE], NULL, 4), + + /* 05 */ ACTION_OPTION(set_game_specific_hotkey_quick_load_state, game_specific_hotkey_quick_load_state_passive, &msg[MSG_HOTKEY_QUICK_LOAD_STATE], NULL, 5), + + /* 06 */ ACTION_OPTION(set_game_specific_hotkey_toggle_full_screen, game_specific_hotkey_toggle_full_screen_passive, &msg[MSG_HOTKEY_FULL_SCREEN_TOGGLE], NULL, 6) }; MAKE_MENU(tools_game_specific_hotkeys, NULL, NULL, NULL, NULL, 0, 0); @@ -3263,6 +3287,21 @@ u32 menu(u16 *screen, bool8 FirstInvocation) obtain_hotkey(&emu_config.HotkeyToggleSound); } + void set_global_hotkey_quick_load_state() + { + obtain_hotkey(&emu_config.HotkeyQuickLoadState); + } + + void set_global_hotkey_quick_save_state() + { + obtain_hotkey(&emu_config.HotkeyQuickSaveState); + } + + void set_global_hotkey_toggle_full_screen() + { + obtain_hotkey(&emu_config.HotkeyToggleFullScreen); + } + void set_game_specific_hotkey_return_to_menu() { obtain_hotkey(&game_config.HotkeyReturnToMenu); @@ -3278,6 +3317,21 @@ u32 menu(u16 *screen, bool8 FirstInvocation) obtain_hotkey(&game_config.HotkeyToggleSound); } + void set_game_specific_hotkey_quick_load_state() + { + obtain_hotkey(&game_config.HotkeyQuickLoadState); + } + + void set_game_specific_hotkey_quick_save_state() + { + obtain_hotkey(&game_config.HotkeyQuickSaveState); + } + + void set_game_specific_hotkey_toggle_full_screen() + { + obtain_hotkey(&game_config.HotkeyToggleFullScreen); + } + #define HOTKEY_CONTENT_X 156 void hotkey_option_passive_common(u32 HotkeyBitfield) { @@ -3323,6 +3377,21 @@ u32 menu(u16 *screen, bool8 FirstInvocation) hotkey_option_passive_common(emu_config.HotkeyToggleSound); } + void global_hotkey_quick_load_state_passive() + { + hotkey_option_passive_common(emu_config.HotkeyQuickLoadState); + } + + void global_hotkey_quick_save_state_passive() + { + hotkey_option_passive_common(emu_config.HotkeyQuickSaveState); + } + + void global_hotkey_toggle_full_screen_passive() + { + hotkey_option_passive_common(emu_config.HotkeyToggleFullScreen); + } + void game_specific_hotkey_return_to_menu_passive() { hotkey_option_passive_common(game_config.HotkeyReturnToMenu); @@ -3338,6 +3407,21 @@ u32 menu(u16 *screen, bool8 FirstInvocation) hotkey_option_passive_common(game_config.HotkeyToggleSound); } + void game_specific_hotkey_quick_load_state_passive() + { + hotkey_option_passive_common(game_config.HotkeyQuickLoadState); + } + + void game_specific_hotkey_quick_save_state_passive() + { + hotkey_option_passive_common(game_config.HotkeyQuickSaveState); + } + + void game_specific_hotkey_toggle_full_screen_passive() + { + hotkey_option_passive_common(game_config.HotkeyToggleFullScreen); + } + int lastest_game_menu_scroll_value; void latest_game_menu_init() { @@ -4680,6 +4764,80 @@ void SavedStateCacheInvalidate (void) SavedStateExistenceCached [i] = FALSE; } +void QuickLoadState (void) +{ + char BaseName[MAX_PATH + 1]; + get_savestate_filename(0, BaseName); + + mdelay(100); // needed to avoid ds2_setBacklight crashing + ds2_setBacklight(3); + + ds2_clearScreen(DOWN_SCREEN, RGB15(0, 0, 0)); + draw_message(down_screen_addr, NULL, 28, 31, 227, 165, 0); + draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_PROGRESS_SAVED_STATE_LOADING]); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); + + HighFrequencyCPU(); + int flag = load_state(BaseName); + GameFrequencyCPU(); + if(0 != flag) + { + draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_PROGRESS_SAVED_STATE_LOAD_FAILED]); + mdelay(500); // let the failure show + } + + SavedStateCacheInvalidate (); + + ds2_clearScreen(DOWN_SCREEN, RGB15(0, 0, 0)); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); + + mdelay(100); // needed to avoid ds2_setBacklight crashing + ds2_setBacklight(2); +} + +void QuickSaveState (void) +{ + char BaseName[MAX_PATH + 1]; + get_savestate_filename(0, BaseName); + + mdelay(100); // needed to avoid ds2_setBacklight crashing + ds2_setBacklight(3); + + ds2_clearScreen(DOWN_SCREEN, RGB15(0, 0, 0)); + draw_message(down_screen_addr, NULL, 28, 31, 227, 165, 0); + draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_PROGRESS_SAVED_STATE_CREATING]); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); + + HighFrequencyCPU(); + unsigned short screen[256*192]; + copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192); + int flag = save_state(BaseName, screen); + GameFrequencyCPU(); + if(flag < 0) + { + draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_PROGRESS_SAVED_STATE_CREATION_FAILED]); + mdelay(500); // let the failure show + } + + SavedStateCacheInvalidate (); + + ds2_clearScreen(DOWN_SCREEN, RGB15(0, 0, 0)); + ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD); + + mdelay(100); // needed to avoid ds2_setBacklight crashing + ds2_setBacklight(2); +} + +void ToggleFullScreen (void) +{ + if (game_config.graphic == 0 /* full-screen ugly */ + || game_config.graphic == 4 /* full-screen smoothed */) + game_config.graphic = 3 /* middle of the screen */; + else + game_config.graphic = 4 /* full-screen smoothed */; + save_game_config_file(); +} + void get_newest_savestate(char *name_buffer) { if (latest_save < 0) diff --git a/source/nds/gui.h b/source/nds/gui.h index 9b37462..244df5f 100644 --- a/source/nds/gui.h +++ b/source/nds/gui.h @@ -43,7 +43,10 @@ struct _EMU_CONFIG u32 HotkeyReturnToMenu; u32 HotkeyTemporaryFastForward; u32 HotkeyToggleSound; - u32 Reserved[61]; + u32 HotkeyQuickLoadState; + u32 HotkeyQuickSaveState; + u32 HotkeyToggleFullScreen; + u32 Reserved[58]; }; struct _GAME_CONFIG @@ -73,7 +76,10 @@ struct _GAME_CONFIG */ u32 PreviouslyUsed_20130206_2; u32 RetroSound; - u32 Reserved2[41]; + u32 HotkeyQuickLoadState; + u32 HotkeyQuickSaveState; + u32 HotkeyToggleFullScreen; + u32 Reserved2[38]; }; typedef enum @@ -117,7 +123,6 @@ extern char main_path[MAX_PATH]; extern char rom_path[MAX_PATH]; extern u32 game_enable_audio; -extern u32 clock_speed_number; extern u32 game_fast_forward; extern u32 temporary_fast_forward; @@ -139,13 +144,14 @@ extern GAME_CONFIG game_config; ******************************************************************************/ extern void gui_init(u32 lang_id); extern u32 menu(u16 *original_screen, bool8 FirstInvocation); -extern void game_disableAudio(); -extern void game_set_frameskip(); -extern void game_set_fluidity(); -extern void game_set_retro(); extern void LowFrequencyCPU(); extern void HighFrequencyCPU(); extern void GameFrequencyCPU(); + +extern void QuickSaveState(); +extern void QuickLoadState(); +extern void ToggleFullScreen(); + extern int load_language_msg(char *filename, u32 language); #ifdef __cplusplus diff --git a/source/nds/message.h b/source/nds/message.h index a166528..2799b4e 100644 --- a/source/nds/message.h +++ b/source/nds/message.h @@ -63,6 +63,9 @@ enum MSG MSG_HOTKEY_MAIN_MENU, MSG_HOTKEY_TEMPORARY_FAST_FORWARD, MSG_HOTKEY_SOUND_TOGGLE, + MSG_HOTKEY_QUICK_LOAD_STATE, + MSG_HOTKEY_QUICK_SAVE_STATE, + MSG_HOTKEY_FULL_SCREEN_TOGGLE, MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS, MSG_HOTKEY_DELETE_WITH_A, MSG_HOTKEY_CANCEL_WITH_B, -- cgit v1.2.3