aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CATSFC/system/language.msg36
-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
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,