aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/nds/entry.cpp72
-rw-r--r--source/nds/entry.h7
-rw-r--r--source/nds/gui.c162
-rw-r--r--source/nds/gui.h20
-rw-r--r--source/nds/message.h3
5 files changed, 244 insertions, 20 deletions
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,