diff --git a/patches/00006_goweiwen_shorten_ff_and_rewind_messages.patch b/patches/00006_goweiwen_shorten_ff_and_rewind_messages.patch new file mode 100644 index 0000000..8dafa7d --- /dev/null +++ b/patches/00006_goweiwen_shorten_ff_and_rewind_messages.patch @@ -0,0 +1,31 @@ +From d79139d17b6e4b388085dd279a71f067edc02dec Mon Sep 17 00:00:00 2001 +From: Goh Wei Wen +Date: Tue, 27 Jun 2023 11:29:59 +0800 +Subject: [PATCH] feat: shorten ff and rewind messages (>>, <<) + +--- + intl/msg_hash_us.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h +index 6f731a249af..10be15442d0 100644 +--- a/intl/msg_hash_us.h ++++ b/intl/msg_hash_us.h +@@ -13903,7 +13903,7 @@ MSG_HASH( + ) + MSG_HASH( + MSG_REWINDING, +- "Rewinding." ++ "<<" + ) + MSG_HASH( + MSG_REWIND_UNSUPPORTED, +@@ -13979,7 +13979,7 @@ MSG_HASH( + ) + MSG_HASH( + MSG_FAST_FORWARD, +- "Fast-Forward." ++ ">>" + ) + MSG_HASH( + MSG_SLOW_MOTION_REWIND, diff --git a/patches/00007_goweiwen_add_state_disk_slot_commands.patch b/patches/00007_goweiwen_add_state_disk_slot_commands.patch new file mode 100644 index 0000000..dd9fa50 --- /dev/null +++ b/patches/00007_goweiwen_add_state_disk_slot_commands.patch @@ -0,0 +1,204 @@ +From e3643675ef77a6fad3a2f400ffe82102fca196fa Mon Sep 17 00:00:00 2001 +From: Goh Wei Wen +Date: Sat, 8 Jul 2023 23:20:34 +0800 +Subject: [PATCH] feat: add state/disk slot commands + +--- + command.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + command.h | 17 +++++++-- + runloop.c | 12 +++++++ + runloop.h | 4 +++ + 4 files changed, 136 insertions(+), 2 deletions(-) + +diff --git a/command.c b/command.c +index 1f07bdd4eeb..b64f63f08d9 100644 +--- a/command.c ++++ b/command.c +@@ -681,6 +681,114 @@ bool command_show_osd_msg(command_t *cmd, const char* arg) + return true; + } + ++bool command_get_disk_count(command_t *cmd, const char *arg) ++{ ++ char reply[128] = ""; ++ ++ runloop_state_t *runloop_st = runloop_state_get_ptr(); ++ rarch_system_info_t *sys_info = runloop_st ? (rarch_system_info_t*)&runloop_st->system : NULL; ++ if (!sys_info) return false; ++ ++ unsigned int disk = disk_control_get_num_images(&sys_info->disk_control); ++ ++ snprintf(reply, sizeof(reply) - 1, "GET_DISK_COUNT %d", disk); ++ cmd->replier(cmd, reply, strlen(reply)); ++ return true; ++} ++ ++bool command_get_disk_slot(command_t *cmd, const char *arg) ++{ ++ char reply[128] = ""; ++ ++ runloop_state_t *runloop_st = runloop_state_get_ptr(); ++ rarch_system_info_t *sys_info = runloop_st ? (rarch_system_info_t*)&runloop_st->system : NULL; ++ if (!sys_info) return false; ++ ++ unsigned int disk = disk_control_get_image_index(&sys_info->disk_control); ++ ++ snprintf(reply, sizeof(reply) - 1, "GET_DISK_SLOT %d", disk); ++ cmd->replier(cmd, reply, strlen(reply)); ++ return true; ++} ++ ++bool command_set_disk_slot(command_t *cmd, const char *arg) ++{ ++ char reply[128] = ""; ++ ++ runloop_state_t *runloop_st = runloop_state_get_ptr(); ++ rarch_system_info_t *sys_info = runloop_st ? (rarch_system_info_t*)&runloop_st->system : NULL; ++ if (!sys_info) return false; ++ ++ unsigned int disk = (unsigned int)strtoul(arg, NULL, 10); ++ ++ disk_control_set_eject_state(&sys_info->disk_control, true, false); ++ disk_control_set_index(&sys_info->disk_control, disk, true); ++ disk_control_set_eject_state(&sys_info->disk_control, false, false); ++ ++ snprintf(reply, sizeof(reply) - 1, "SET_DISK_SLOT %d", disk); ++ cmd->replier(cmd, reply, strlen(reply)); ++ return true; ++} ++ ++bool command_get_state_slot(command_t *cmd, const char *arg) ++{ ++ char reply[128] = ""; ++ ++ bool savestates_enabled = core_info_current_supports_savestate(); ++ if (!savestates_enabled) return false; ++ ++ unsigned int slot = runloop_get_current_savestate(); ++ ++ snprintf(reply, sizeof(reply) - 1, "GET_STATE_SLOT %d", slot); ++ cmd->replier(cmd, reply, strlen(reply)); ++ return true; ++} ++ ++bool command_set_state_slot(command_t *cmd, const char *arg) ++{ ++ char reply[128] = ""; ++ unsigned int slot = (unsigned int)strtoul(arg, NULL, 10); ++ ++ bool savestates_enabled = core_info_current_supports_savestate(); ++ if (!savestates_enabled) return false; ++ ++ runloop_set_current_savestate(slot); ++ ++ snprintf(reply, sizeof(reply) - 1, "SET_STATE_SLOT %d", slot); ++ cmd->replier(cmd, reply, strlen(reply)); ++ return true; ++} ++ ++bool command_save_state_slot(command_t *cmd, const char *arg) ++{ ++ char state_path[16384]; ++ size_t size; ++ char reply[128] = ""; ++ unsigned int slot = (unsigned int)strtoul(arg, NULL, 10); ++ bool savestates_enabled = core_info_current_supports_savestate(); ++ bool ret = false; ++ state_path[0] = '\0'; ++ snprintf(reply, sizeof(reply) - 1, "SAVE_STATE_SLOT %d", slot); ++ if (savestates_enabled) ++ { ++ runloop_get_savestate_path(state_path, sizeof(state_path), slot); ++ ++ size = core_serialize_size(); ++ savestates_enabled = (size > 0); ++ } ++ if (savestates_enabled) ++ { ++ if (slot == -1) ++ ret = content_auto_save_state(state_path); ++ else ++ ret = content_save_state(state_path, true); ++ } ++ else ++ ret = false; ++ ++ cmd->replier(cmd, reply, strlen(reply)); ++ return ret; ++} + + bool command_load_state_slot(command_t *cmd, const char *arg) + { +diff --git a/command.h b/command.h +index ad3ac3e12eb..416f98062f6 100644 +--- a/command.h ++++ b/command.h +@@ -408,6 +408,12 @@ bool command_version(command_t *cmd, const char* arg); + bool command_get_status(command_t *cmd, const char* arg); + bool command_get_config_param(command_t *cmd, const char* arg); + bool command_show_osd_msg(command_t *cmd, const char* arg); ++bool command_get_disk_count(command_t *cmd, const char *arg); ++bool command_get_disk_slot(command_t *cmd, const char *arg); ++bool command_set_disk_slot(command_t *cmd, const char *arg); ++bool command_get_state_slot(command_t *cmd, const char *arg); ++bool command_set_state_slot(command_t *cmd, const char *arg); ++bool command_save_state_slot(command_t *cmd, const char *arg); + bool command_load_state_slot(command_t *cmd, const char* arg); + bool command_play_replay_slot(command_t *cmd, const char* arg); + #ifdef HAVE_CHEEVOS +@@ -441,8 +447,15 @@ static const struct cmd_action_map action_map[] = { + { "READ_CORE_MEMORY", command_read_memory, "
" }, + { "WRITE_CORE_MEMORY",command_write_memory, "
..." }, + +- { "LOAD_STATE_SLOT",command_load_state_slot, ""}, +- { "PLAY_REPLAY_SLOT",command_play_replay_slot, ""}, ++ { "GET_DISK_COUNT", command_get_disk_count, "No argument" }, ++ { "GET_DISK_SLOT", command_get_disk_slot, "No argument" }, ++ { "SET_DISK_SLOT", command_set_disk_slot, "" }, ++ ++ { "GET_STATE_SLOT", command_get_state_slot, "No argument" }, ++ { "SET_STATE_SLOT", command_set_state_slot, "" }, ++ { "SAVE_STATE_SLOT", command_save_state_slot, "" }, ++ { "LOAD_STATE_SLOT", command_load_state_slot, "" }, ++ { "PLAY_REPLAY_SLOT", command_play_replay_slot, "" }, + }; + + static const struct cmd_map map[] = { +diff --git a/runloop.c b/runloop.c +index 846fbabcd3a..bd8bc2adecf 100644 +--- a/runloop.c ++++ b/runloop.c +@@ -7195,6 +7195,18 @@ void runloop_task_msg_queue_push( + } + + ++uint32_t runloop_get_current_savestate() ++{ ++ settings_t *settings = config_get_ptr(); ++ return settings ? settings->ints.state_slot : 0; ++} ++ ++void runloop_set_current_savestate(int state_slot) ++{ ++ settings_t *settings = config_get_ptr(); ++ settings->ints.state_slot = state_slot; ++} ++ + bool runloop_get_current_savestate_path(char *path, size_t len) + { + settings_t *settings = config_get_ptr(); +diff --git a/runloop.h b/runloop.h +index 3ba255f7ba9..b0f2d5f567b 100644 +--- a/runloop.h ++++ b/runloop.h +@@ -424,6 +424,10 @@ uint32_t runloop_get_flags(void); + + bool runloop_get_entry_state_path(char *path, size_t len, unsigned slot); + ++uint32_t runloop_get_current_savestate(); ++ ++void runloop_set_current_savestate(int state_slot); ++ + bool runloop_get_current_savestate_path(char *path, size_t len); + + bool runloop_get_savestate_path(char *path, size_t len, int slot); diff --git a/patches/00008_goweiwen_add_GET_INFO_command.patch b/patches/00008_goweiwen_add_GET_INFO_command.patch new file mode 100644 index 0000000..edd7265 --- /dev/null +++ b/patches/00008_goweiwen_add_GET_INFO_command.patch @@ -0,0 +1,65 @@ +From 4aeaaf389a9d9323819236cc4fb5990995dad0cd Mon Sep 17 00:00:00 2001 +From: Goh Wei Wen +Date: Mon, 17 Jul 2023 00:23:35 +0800 +Subject: [PATCH] feat: add GET_INFO command + +--- + command.c | 24 ++++++++++++++++++++++++ + command.h | 2 ++ + 2 files changed, 26 insertions(+) + +diff --git a/command.c b/command.c +index 38f0f954de1..e9facea0412 100644 +--- a/command.c ++++ b/command.c +@@ -681,6 +681,30 @@ bool command_show_osd_msg(command_t *cmd, const char* arg) + return true; + } + ++bool command_get_info(command_t *cmd, const char *arg) ++{ ++ char reply[128] = ""; ++ ++ runloop_state_t *runloop_st = runloop_state_get_ptr(); ++ rarch_system_info_t *sys_info = runloop_st ? (rarch_system_info_t*)&runloop_st->system : NULL; ++ if (!sys_info) return false; ++ ++ unsigned int disk_count = disk_control_get_num_images(&sys_info->disk_control); ++ unsigned int disk_slot = disk_control_get_image_index(&sys_info->disk_control); ++ ++ bool savestates_enabled = core_info_current_supports_savestate(); ++ if (savestates_enabled) { ++ unsigned int state_slot = runloop_get_current_savestate(); ++ snprintf(reply, sizeof(reply) - 1, "GET_INFO %d %d %d", disk_count, disk_slot, state_slot); ++ } else { ++ snprintf(reply, sizeof(reply) - 1, "GET_INFO %d %d NO", disk_count, disk_slot); ++ } ++ ++ cmd->replier(cmd, reply, strlen(reply)); ++ return true; ++ ++} ++ + bool command_get_disk_count(command_t *cmd, const char *arg) + { + char reply[128] = ""; +diff --git a/command.h b/command.h +index 416f98062f6..1c57a064f8e 100644 +--- a/command.h ++++ b/command.h +@@ -408,6 +408,7 @@ bool command_version(command_t *cmd, const char* arg); + bool command_get_status(command_t *cmd, const char* arg); + bool command_get_config_param(command_t *cmd, const char* arg); + bool command_show_osd_msg(command_t *cmd, const char* arg); ++bool command_get_info(command_t *cmd, const char* arg); + bool command_get_disk_count(command_t *cmd, const char *arg); + bool command_get_disk_slot(command_t *cmd, const char *arg); + bool command_set_disk_slot(command_t *cmd, const char *arg); +@@ -447,6 +448,7 @@ static const struct cmd_action_map action_map[] = { + { "READ_CORE_MEMORY", command_read_memory, "
" }, + { "WRITE_CORE_MEMORY",command_write_memory, "
..." }, + ++ { "GET_INFO", command_get_info, "No argument" }, + { "GET_DISK_COUNT", command_get_disk_count, "No argument" }, + { "GET_DISK_SLOT", command_get_disk_slot, "No argument" }, + { "SET_DISK_SLOT", command_set_disk_slot, "" }, diff --git a/patches/00009_goweiwen_retain_fast-forward_state_when_pausing.patch b/patches/00009_goweiwen_retain_fast-forward_state_when_pausing.patch new file mode 100644 index 0000000..a118d47 --- /dev/null +++ b/patches/00009_goweiwen_retain_fast-forward_state_when_pausing.patch @@ -0,0 +1,36 @@ +From 32e4be60b8fa8799927f6e0a6f698db0d781b369 Mon Sep 17 00:00:00 2001 +From: Goh Wei Wen +Date: Wed, 19 Jul 2023 19:47:35 +0800 +Subject: [PATCH] feat: retain fast-forward state when pausing + +--- + runloop.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/runloop.c b/runloop.c +index bd8bc2adecf..27f2c8b8048 100644 +--- a/runloop.c ++++ b/runloop.c +@@ -6210,14 +6210,14 @@ static enum runloop_state_enum runloop_check_state( + if (!check2) + check2 = old_hold_button_state != new_hold_button_state; + +- /* Don't allow fastmotion while paused */ +- if (runloop_paused) +- { +- check2 = true; +- new_button_state = false; +- new_hold_button_state = false; +- input_st->flags |= INP_FLAG_NONBLOCKING; +- } ++ // /* Don't allow fastmotion while paused */ ++ // if (runloop_paused) ++ // { ++ // check2 = true; ++ // new_button_state = false; ++ // new_hold_button_state = false; ++ // input_st->flags |= INP_FLAG_NONBLOCKING; ++ // } + + if (check2) + { diff --git a/patches/00010_goweiwen_add_pause_unpause_commands.patch b/patches/00010_goweiwen_add_pause_unpause_commands.patch new file mode 100644 index 0000000..351fece --- /dev/null +++ b/patches/00010_goweiwen_add_pause_unpause_commands.patch @@ -0,0 +1,58 @@ +From dd8fa4c75eec6ddc2675363787f3a40cda793996 Mon Sep 17 00:00:00 2001 +From: Wei Wen Goh +Date: Sun, 23 Jul 2023 01:04:29 +0800 +Subject: [PATCH] feat: add pause, unpause commands + +--- + command.c | 14 ++++++++++++++ + command.h | 5 +++++ + 2 files changed, 19 insertions(+) + +diff --git a/command.c b/command.c +index e9facea0412..248b190caa0 100644 +--- a/command.c ++++ b/command.c +@@ -681,6 +681,20 @@ bool command_show_osd_msg(command_t *cmd, const char* arg) + return true; + } + ++bool command_pause(command_t *cmd, const char* arg) ++{ ++ runloop_state_t *runloop_st = runloop_state_get_ptr(); ++ runloop_st->flags |= RUNLOOP_FLAG_PAUSED; ++ return true; ++} ++ ++bool command_unpause(command_t *cmd, const char* arg) ++{ ++ runloop_state_t *runloop_st = runloop_state_get_ptr(); ++ runloop_st->flags &= ~RUNLOOP_FLAG_PAUSED; ++ return true; ++} ++ + bool command_get_info(command_t *cmd, const char *arg) + { + char reply[128] = ""; +diff --git a/command.h b/command.h +index 1c57a064f8e..88c0b87692d 100644 +--- a/command.h ++++ b/command.h +@@ -408,6 +408,8 @@ bool command_version(command_t *cmd, const char* arg); + bool command_get_status(command_t *cmd, const char* arg); + bool command_get_config_param(command_t *cmd, const char* arg); + bool command_show_osd_msg(command_t *cmd, const char* arg); ++bool command_pause(command_t *cmd, const char* arg); ++bool command_unpause(command_t *cmd, const char* arg); + bool command_get_info(command_t *cmd, const char* arg); + bool command_get_disk_count(command_t *cmd, const char *arg); + bool command_get_disk_slot(command_t *cmd, const char *arg); +@@ -448,6 +450,9 @@ static const struct cmd_action_map action_map[] = { + { "READ_CORE_MEMORY", command_read_memory, "
" }, + { "WRITE_CORE_MEMORY",command_write_memory, "
..." }, + ++ { "PAUSE", command_pause, "No argument" }, ++ { "UNPAUSE", command_unpause, "No argument" }, ++ + { "GET_INFO", command_get_info, "No argument" }, + { "GET_DISK_COUNT", command_get_disk_count, "No argument" }, + { "GET_DISK_SLOT", command_get_disk_slot, "No argument" }, diff --git a/patches/00011_add_GET_PATH_command.patch b/patches/00011_add_GET_PATH_command.patch new file mode 100644 index 0000000..d56a38d --- /dev/null +++ b/patches/00011_add_GET_PATH_command.patch @@ -0,0 +1,73 @@ +diff --git a/command.c b/command.c +--- a/command.c ++++ b/command.c +@@ -947,6 +947,50 @@ bool command_get_status(command_t *cmd, const char* arg) + return true; + } + ++bool command_get_path(command_t *cmd, const char* arg) ++{ ++ size_t _len; ++ char reply[4096]; ++ char state_path[16384]; ++ ++ const char *value = NULL; ++ ++ if (string_is_equal(arg, "core")) ++ value = path_get(RARCH_PATH_CORE); ++ else if (string_is_equal(arg, "config")) ++ value = path_get(RARCH_PATH_CONFIG); ++ else if (string_is_equal(arg, "content")) ++ value = path_get(RARCH_PATH_CONTENT); ++ else if (string_is_equal(arg, "config_append")) ++ value = path_get(RARCH_PATH_CONFIG_APPEND); ++ else if (string_is_equal(arg, "config_override")) ++ value = path_get(RARCH_PATH_CONFIG_OVERRIDE); ++ else if (string_is_equal(arg, "core_options")) ++ value = path_get(RARCH_PATH_CORE_OPTIONS); ++ else if (string_is_equal(arg, "default_shader_preset")) ++ value = path_get(RARCH_PATH_DEFAULT_SHADER_PRESET); ++ else if (string_is_equal(arg, "basename")) ++ value = path_get(RARCH_PATH_BASENAME); ++ else if (string_is_equal(arg, "subsystem")) ++ value = path_get(RARCH_PATH_SUBSYSTEM); ++ else if (string_is_equal(arg, "savestate")) { ++ runloop_get_current_savestate_path(state_path, sizeof(state_path)); ++ value = state_path; ++ } ++ ++ _len = strlcpy(reply, "GET_PATH ", sizeof(reply)); ++ _len += strlcpy(reply + _len, arg, sizeof(reply) - _len); ++ reply[ _len] = ' '; ++ reply[++_len] = '\0'; ++ ++ if (value) ++ _len += strlcpy(reply + _len, value, sizeof(reply) - _len); ++ ++ cmd->replier(cmd, reply, _len); ++ ++ return true; ++} ++ + bool command_read_memory(command_t *cmd, const char *arg) + { + unsigned i; +diff --git a/command.h b/command.h +--- a/command.h ++++ b/command.h +@@ -416,6 +416,7 @@ struct cmd_action_map + bool command_version(command_t *cmd, const char* arg); + bool command_get_status(command_t *cmd, const char* arg); + bool command_get_config_param(command_t *cmd, const char* arg); ++bool command_get_path(command_t *cmd, const char* arg); + bool command_show_osd_msg(command_t *cmd, const char* arg); + bool command_load_state_slot(command_t *cmd, const char* arg); + bool command_play_replay_slot(command_t *cmd, const char* arg); +@@ -433,6 +434,7 @@ static const struct cmd_action_map action_map[] = { + { "VERSION", command_version, "No argument"}, + { "GET_STATUS", command_get_status, "No argument" }, + { "GET_CONFIG_PARAM", command_get_config_param, "" }, ++ { "GET_PATH", command_get_path, "" }, + { "SHOW_MSG", command_show_osd_msg, "No argument" }, + #if defined(HAVE_CHEEVOS) + /* These functions use achievement addresses and only work if a game with achievements is diff --git a/scripts/create_patch.sh b/scripts/create_patch.sh index de44eea..bbce368 100755 --- a/scripts/create_patch.sh +++ b/scripts/create_patch.sh @@ -1,4 +1,6 @@ #!/bin/bash +PWD="$(pwd)" +echo -e "\e[32mCurrent directory: $PWD\e[0m" # Define directories, only if not given as environment variables SUBMODULE_DIR="${SUBMODULE_DIR:-submodules/RetroArch}" @@ -7,14 +9,15 @@ PATCH_DIR="${PATCH_DIR:-patches}" SRC_DIR="${SRC_DIR:-src}" # Create patches directory if it doesn't exist -mkdir -p $PATCH_DIR +mkdir -p "$PATCH_DIR" # Get the last patch number LAST_PATCH=$(ls $PATCH_DIR/*.patch 2> /dev/null | grep -oP '\d{5}' | sort -n | tail -1) if [ -z "$LAST_PATCH" ]; then LAST_PATCH=0 fi -NEW_PATCH_NUM=$(printf "%05d" $((LAST_PATCH + 1))) +# Increment the last patch number +NEW_PATCH_NUM=$(printf "%05d" $((10#$LAST_PATCH + 1))) # Prompt the user for a descriptive filename echo -e "\e[33mEnter a descriptive name for the patch file:\e[0m" @@ -22,17 +25,18 @@ read PATCH_NAME # Create the patch file with the descriptive name PATCH_FILE="$PATCH_DIR/${NEW_PATCH_NUM}_${PATCH_NAME}.patch" +FULL_PATH="$PWD/$PATCH_FILE" -echo -e "\e[32mCreating patch file: $PATCH_FILE\e[0m" +echo -e "\e[32mCreating patch file: $FULL_PATH\e[0m" # Generate the patch cd "$SUBMODULE_DIR" -git diff --no-index --ignore-space-at-eol > $PATCH_FILE 2> /dev/null +git diff --ignore-space-at-eol > "$FULL_PATH" 2> /dev/null # Check if the patch file is empty and delete it if it is -if [ ! -s $PATCH_FILE ]; then - rm $PATCH_FILE +if [ ! -s "$FULL_PATH" ]; then + rm "$FULL_PATH" 2> /dev/null echo -e "\e[31mNo changes detected. Patch file not created.\e[0m" else - echo -e "\e[32mPatch file created: $PATCH_FILE\e[0m" + echo -e "\e[32mPatch file created: $FULL_PATH\e[0m" fi diff --git a/src/gfx/drivers/miyoomini/gfx.c b/src/gfx/drivers/miyoomini/gfx.c index a082a65..b0e8581 100644 --- a/src/gfx/drivers/miyoomini/gfx.c +++ b/src/gfx/drivers/miyoomini/gfx.c @@ -15,7 +15,7 @@ // FREEMMA : force free all allocated MMAs when init & quit #define FREEMMA // CLEARFBATQUIT : clear framebuffer when quit -#define CLEARFBATQUIT +// #define CLEARFBATQUIT // GFX_BLOCKING : limit to 60fps but never skips frames // : in case of clearing all buffers by GFX_Flip()x3, needs to use BLOCKING (or GFX_FlipForce()) // GFX_FLIPWAIT : wait until Blit is done when flip diff --git a/src/gfx/drivers/miyoomini/sdl_miyoomini_gfx.c b/src/gfx/drivers/miyoomini/sdl_miyoomini_gfx.c index 167887c..728a2b4 100644 --- a/src/gfx/drivers/miyoomini/sdl_miyoomini_gfx.c +++ b/src/gfx/drivers/miyoomini/sdl_miyoomini_gfx.c @@ -896,6 +896,11 @@ static bool sdl_miyoomini_gfx_frame(void *data, const void *frame, * core skips a frame) */ if (unlikely(!vid || (!frame && !vid->menu_active))) return true; + /* If pause is active, we don't render anything + * so that we don't draw over the menu */ + runloop_state_t *runloop_st = runloop_state_get_ptr(); + if (unlikely(runloop_st->flags & RUNLOOP_FLAG_PAUSED)) return true; + /* If fast forward is currently active, we may * push frames at an 'unlimited' rate. Since the * display has a fixed refresh rate of 60 Hz, this