aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core.c7
-rw-r--r--core.h1
-rw-r--r--funkey/fk_instant_play.c61
-rw-r--r--funkey/fk_instant_play.h4
-rw-r--r--main.c70
-rw-r--r--main.h1
-rw-r--r--menu.c43
-rw-r--r--overrides.h2
-rw-r--r--overrides/mame2000.h2
9 files changed, 129 insertions, 62 deletions
diff --git a/core.c b/core.c
index 8dead78..34810a5 100644
--- a/core.c
+++ b/core.c
@@ -715,14 +715,17 @@ const char **core_extensions(void) {
}
void core_unload(void) {
- PA_INFO("Unloading core...\n");
-
if (current_core.initialized) {
core_unload_content();
current_core.retro_deinit();
current_core.initialized = false;
}
+}
+
+void core_close(void) {
+ PA_INFO("Unloading core...\n");
+ core_unload();
string_list_free(extensions);
extensions = NULL;
diff --git a/core.h b/core.h
index 2ec86b5..bc855d4 100644
--- a/core.h
+++ b/core.h
@@ -68,5 +68,6 @@ void core_apply_cheats(struct cheats *cheats);
void core_unload_content(void);
const char **core_extensions(void);
void core_unload(void);
+void core_close(void);
#endif
diff --git a/funkey/fk_instant_play.c b/funkey/fk_instant_play.c
index 8c8fc33..638e0fd 100644
--- a/funkey/fk_instant_play.c
+++ b/funkey/fk_instant_play.c
@@ -41,6 +41,7 @@
#endif
static char *prog_name;
+int instant_play = 0;
/* Handler for SIGUSR1, caused by closing the console */
static void handle_sigusr1(int signal)
@@ -77,12 +78,7 @@ void FK_Suspend(void)
FILE *fp;
char pidcmd[100];
- state_slot = AUTOSAVE_SLOT;
- if(state_write()) {
- printf("Save failed\n");
- state_slot = 0;
- }
-
+ FK_Autosave();
sram_write();
save_config(CONFIG_TYPE_AUTO);
@@ -108,10 +104,61 @@ void FK_Suspend(void)
exit(0);
}
+void FK_LoadNewGame(const char *fname)
+{
+ char prog_path[PATH_MAX];
+ realpath(prog_name, prog_path);
+
+ /* FunKey uses musl libc so dlclose is no-op. If core depends on
+ * all statics being reset, FunKey cannot reload it. Instead,
+ * re-exec with new content. */
+ PA_INFO("Restarting with %s %s %s\n", prog_path, core_path, fname);
+ finish();
+ execl(prog_path, prog_name, core_path, fname, NULL);
+
+ /* Should not be reached */
+ PA_ERROR("Failed to load game\n");
+
+ /* Exit application */
+ exit(0);
+}
+
+void FK_Autosave(void)
+{
+ if (state_allowed()) {
+ int prev_state_slot = state_slot;
+ state_slot = AUTOSAVE_SLOT;
+ state_write();
+ state_slot = prev_state_slot;
+ }
+}
+
+void FK_Resume(void)
+{
+ char autosave_path[MAX_PATH];
+
+ state_file_name(autosave_path, MAX_PATH, AUTOSAVE_SLOT);
+ if (access(autosave_path, F_OK) == 0) {
+ if (instant_play) {
+ resume_slot = AUTOSAVE_SLOT;
+ } else {
+ SDL_Surface *screen = SDL_GetVideoSurface();
+ int resume = FK_RunResumeMenu(screen);
+ if (resume == RESUME_YES) {
+ resume_slot = AUTOSAVE_SLOT;
+ }
+ }
+ }
+
+ instant_play = false;
+ state_resume();
+
+ remove(autosave_path);
+ remove_config(CONFIG_TYPE_AUTO);
+}
void FK_InitInstantPlay(int argc, char **argv)
{
prog_name = argv[0];
signal(SIGUSR1, handle_sigusr1);
}
-
diff --git a/funkey/fk_instant_play.h b/funkey/fk_instant_play.h
index 5185065..2ed3c71 100644
--- a/funkey/fk_instant_play.h
+++ b/funkey/fk_instant_play.h
@@ -39,8 +39,12 @@ extern "C" {
#include <signal.h>
#define AUTOSAVE_SLOT 99
+extern int instant_play;
extern void FK_InitInstantPlay(int argc, char **argv);
+extern void FK_LoadNewGame(const char *fname);
+extern void FK_Autosave(void);
+extern void FK_Resume(void);
extern void FK_Suspend(void);
/* Ends C function definitions when using C++ */
diff --git a/main.c b/main.c
index e59f2fd..b4e19be 100644
--- a/main.c
+++ b/main.c
@@ -25,7 +25,6 @@ char save_template_path[MAX_PATH];
#ifdef FUNKEY_S
#include "funkey/fk_menu.h"
#include "funkey/fk_instant_play.h"
-static bool instant_play = false;
bool should_suspend = false;
#endif
@@ -610,10 +609,6 @@ int state_resume(void) {
int main(int argc, char **argv) {
char content_path[MAX_PATH];
-#ifdef FUNKEY_S
- char autosave_path[MAX_PATH];
-#endif
-
if (argc > 1) {
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
@@ -662,20 +657,6 @@ int main(int argc, char **argv) {
load_config();
core_load();
- if (core_load_content(content)) {
- quit(-1);
- }
-
- load_config_keys();
-
-#ifdef MMENU
-
- mmenu = dlopen("libmmenu.so", RTLD_LAZY);
- if (mmenu) {
- ResumeSlot_t ResumeSlot = (ResumeSlot_t)dlsym(mmenu, "ResumeSlot");
- if (ResumeSlot) resume_slot = ResumeSlot();
- }
-#endif
#ifdef FUNKEY_S
if (IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP) == 0) {
PA_ERROR("Error initializing SDL_Image\n");
@@ -686,30 +667,30 @@ int main(int argc, char **argv) {
PA_ERROR("Error initializing SDL_ttf\n");
quit(-1);
}
- FK_InitMenu();
+#endif
- state_file_name(autosave_path, MAX_PATH, AUTOSAVE_SLOT);
- if (access(autosave_path, F_OK) == 0) {
- if (instant_play) {
- resume_slot = AUTOSAVE_SLOT;
- } else {
- SDL_Surface *screen = SDL_GetVideoSurface();
- int resume = FK_RunResumeMenu(screen);
- if (resume == RESUME_YES) {
- resume_slot = AUTOSAVE_SLOT;
- }
- }
+ if (core_load_content(content)) {
+ quit(-1);
}
- instant_play = false;
- FK_InitInstantPlay(argc, argv);
+ load_config_keys();
+
+#ifdef MMENU
+ mmenu = dlopen("libmmenu.so", RTLD_LAZY);
+ if (mmenu) {
+ ResumeSlot_t ResumeSlot = (ResumeSlot_t)dlsym(mmenu, "ResumeSlot");
+ if (ResumeSlot) resume_slot = ResumeSlot();
+ }
+
+ state_resume();
#endif
+
show_startup_message();
- state_resume();
#ifdef FUNKEY_S
- remove(autosave_path);
- remove_config(CONFIG_TYPE_AUTO);
+ FK_InitMenu();
+ FK_Resume();
+ FK_InitInstantPlay(argc, argv);
#endif
do {
@@ -731,21 +712,20 @@ int main(int argc, char **argv) {
return quit(0);
}
-int quit(int code) {
- menu_finish();
-
+void finish(void) {
#ifdef FUNKEY_S
- if (current_core.initialized && state_allowed()) {
- state_slot = AUTOSAVE_SLOT;
- state_write();
- }
-
+ FK_Autosave();
FK_EndMenu();
TTF_Quit();
IMG_Quit();
#endif
- core_unload();
+ menu_finish();
+ core_close();
plat_finish();
+}
+
+int quit(int code) {
+ finish();
exit(code);
}
diff --git a/main.h b/main.h
index f4fc12a..ca7ac07 100644
--- a/main.h
+++ b/main.h
@@ -65,6 +65,7 @@ int remove_config(config_type config_type);
void handle_emu_action(emu_action action);
void pa_log(enum retro_log_level level, const char *fmt, ...);
void pa_track_render(void);
+void finish(void);
int quit(int code);
#endif /* __MAIN_H__ */
diff --git a/menu.c b/menu.c
index fde7c10..bd00e52 100644
--- a/menu.c
+++ b/menu.c
@@ -8,12 +8,18 @@
#include "scale.h"
#include "util.h"
+#ifdef FUNKEY_S
+#include "funkey/fk_instant_play.h"
+#endif
+
static int drew_alt_bg = 0;
static char cores_path[MAX_PATH];
static struct dirent **corelist = NULL;
static int corelist_len = 0;
+static const char *new_fname = NULL;
+
#define MENU_ALIGN_LEFT 0
#define MENU_X2 0
@@ -306,7 +312,29 @@ static int menu_loop_select_content(int id, int keys) {
if (fname == NULL)
return -1;
- core_unload_content();
+ new_fname = fname;
+
+ return 1;
+}
+
+static void load_new_content(const char *fname) {
+ const struct core_override *override = get_overrides();
+
+ if (!override || override->needs_reopen) {
+#ifdef FUNKEY_S
+ FK_LoadNewGame(fname);
+ /* Does not return */
+#else
+ core_close();
+ core_open(core_path);
+#endif
+ } else {
+#ifdef FUNKEY_S
+ FK_Autosave();
+#endif
+ core_unload();
+ }
+ core_load();
content = content_init(fname);
if (!content) {
@@ -328,7 +356,9 @@ static int menu_loop_select_content(int id, int keys) {
state_resume();
}
- return 1;
+#ifdef FUNKEY_S
+ FK_Resume();
+#endif
}
static int menu_loop_disc(int id, int keys)
@@ -685,7 +715,6 @@ void menu_loop(void)
{
static int sel = 0;
bool needs_disc_ctrl = disc_get_count() > 1;
- const struct core_override *override = get_overrides();
plat_video_menu_enter(1);
@@ -697,9 +726,6 @@ void menu_loop(void)
me_enable(e_menu_main, MA_MAIN_DISC_CTRL, needs_disc_ctrl);
- if (override)
- me_enable(e_menu_main, MA_MAIN_CONTENT_SEL, !override->block_load_content);
-
#ifdef MMENU
if (state_allowed()) {
me_enable(e_menu_main, MA_MAIN_SAVE_STATE, mmenu == NULL);
@@ -712,6 +738,11 @@ void menu_loop(void)
while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
;
+ if (new_fname) {
+ load_new_content(new_fname);
+ new_fname = NULL;
+ }
+
/* Force the hud to clear */
plat_video_set_msg(NULL, 0, 0);
plat_video_menu_leave();
diff --git a/overrides.h b/overrides.h
index fd1f9c2..19efdf3 100644
--- a/overrides.h
+++ b/overrides.h
@@ -35,7 +35,7 @@ struct core_override {
me_bind_action* emu_actions;
const size_t emu_action_size;
const struct core_override_option* options;
- int block_load_content;
+ int needs_reopen;
};
#define CORE_OVERRIDE(override, key, fallback) ((override && override->key) ? (override->key) : (fallback))
diff --git a/overrides/mame2000.h b/overrides/mame2000.h
index 81af3fc..a74da1f 100644
--- a/overrides/mame2000.h
+++ b/overrides/mame2000.h
@@ -80,5 +80,5 @@ const struct core_override_fast_forward mame2000_fast_forward = {
.emu_actions = mame2000_emu_actions, \
.emu_action_size = array_size(mame2000_emu_actions), \
.options = mame2000_core_option_overrides, \
- .block_load_content = 1 \
+ .needs_reopen = 1, \
}