diff options
-rw-r--r-- | CATSFC/system/language.msg | 36 | ||||
-rw-r--r-- | source/nds/entry.cpp | 72 | ||||
-rw-r--r-- | source/nds/entry.h | 7 | ||||
-rw-r--r-- | source/nds/gui.c | 162 | ||||
-rw-r--r-- | source/nds/gui.h | 20 | ||||
-rw-r--r-- | source/nds/message.h | 3 |
6 files changed, 280 insertions, 20 deletions
diff --git a/CATSFC/system/language.msg b/CATSFC/system/language.msg index 206e357..af802f3 100644 --- a/CATSFC/system/language.msg +++ b/CATSFC/system/language.msg @@ -112,6 +112,12 @@ Go to main menu Temporary fast-forward #MSG_HOTKEY_SOUND_TOGGLE Toggle sound +#MSG_HOTKEY_QUICK_LOAD_STATE +Load saved state 1 +#MSG_HOTKEY_QUICK_SAVE_STATE +Create saved state 1 +#MSG_HOTKEY_FULL_SCREEN_TOGGLE +Toggle full-screen #MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS Press the buttons you wish to use to perform this action. #MSG_HOTKEY_DELETE_WITH_A @@ -322,6 +328,12 @@ Go to main menu Temporary fast-forward #MSG_HOTKEY_SOUND_TOGGLE Toggle sound +#MSG_HOTKEY_QUICK_LOAD_STATE +Load saved state 1 +#MSG_HOTKEY_QUICK_SAVE_STATE +Create saved state 1 +#MSG_HOTKEY_FULL_SCREEN_TOGGLE +Toggle full-screen #MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS Press the buttons you wish to use to perform this action. #MSG_HOTKEY_DELETE_WITH_A @@ -532,6 +544,12 @@ Menu principal Avance rapide temporaire #MSG_HOTKEY_SOUND_TOGGLE (Dés)activer le son +#MSG_HOTKEY_QUICK_LOAD_STATE +Charger la sauvegarde 1 +#MSG_HOTKEY_QUICK_SAVE_STATE +Créer la sauvegarde 1 +#MSG_HOTKEY_FULL_SCREEN_TOGGLE +(Dés)activer le plein écran #MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS Appuyez sur les boutons que vous voulez utiliser pour effectuer cette action. #MSG_HOTKEY_DELETE_WITH_A @@ -743,6 +761,12 @@ Hauptmenü Temp. Schnellvorlauf #MSG_HOTKEY_SOUND_TOGGLE Audio umschalten +#MSG_HOTKEY_QUICK_LOAD_STATE +Speicherstand 1 laden +#MSG_HOTKEY_QUICK_SAVE_STATE +Speicherstand 1 erstellen +#MSG_HOTKEY_FULL_SCREEN_TOGGLE +Vollbild umschalten #MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS Knöpfe für dieses Ereignis drücken. #MSG_HOTKEY_DELETE_WITH_A @@ -954,6 +978,12 @@ Ga naar het hoofdmenu Tijdelijk vooruitspoelen #MSG_HOTKEY_SOUND_TOGGLE Schakel geluid +#MSG_HOTKEY_QUICK_LOAD_STATE +Laad opgeslagen staat 1 +#MSG_HOTKEY_QUICK_SAVE_STATE +Creëer opgeslagen staat 1 +#MSG_HOTKEY_FULL_SCREEN_TOGGLE +Schakel volledig scherm #MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS Druk op de gewenste knoppencombinatie. #MSG_HOTKEY_DELETE_WITH_A @@ -1165,6 +1195,12 @@ Ir al menú principal Avance rápido temporal #MSG_HOTKEY_SOUND_TOGGLE Encender/apagar sonido +#MSG_HOTKEY_QUICK_LOAD_STATE +Cargar partida 1 +#MSG_HOTKEY_QUICK_SAVE_STATE +Grabar partida 1 +#MSG_HOTKEY_FULL_SCREEN_TOGGLE +Alternar pantalla completa #MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS Presione la tecla para esta acción. #MSG_HOTKEY_DELETE_WITH_A 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 c2f1021..db3bd07 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1761,15 +1761,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(); @@ -2935,7 +2947,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); @@ -2951,7 +2969,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); @@ -3264,6 +3288,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); @@ -3279,6 +3318,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) { @@ -3324,6 +3378,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); @@ -3339,6 +3408,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() { @@ -4685,6 +4769,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 ebbf6e8..73686e8 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, |