Save current state slot to runtime log

This commit is contained in:
sonninnos 2025-08-02 21:31:00 +03:00
parent dc25b375ed
commit 10f92879a6
4 changed files with 81 additions and 17 deletions

View File

@ -4665,9 +4665,6 @@ bool menu_driver_init(bool video_is_threaded)
settings_t *settings = config_get_ptr();
struct menu_state *menu_st = &menu_driver_state;
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL);
if ( menu_st->driver_data
|| menu_driver_init_internal(
menu_st, p_disp, settings,

View File

@ -655,6 +655,9 @@ static void runloop_update_runtime_log(
/* Update 'last played' entry */
runtime_log_set_last_played_now(runtime_log);
/* Update state slot */
runtime_log->state_slot = config_get_ptr()->ints.state_slot;
/* Save runtime log file */
runtime_log_save(runtime_log);
@ -4376,6 +4379,7 @@ static bool event_init_content(
static void runloop_runtime_log_init(runloop_state_t *runloop_st)
{
settings_t *settings = config_get_ptr();
const char *content_path = path_get(RARCH_PATH_CONTENT);
const char *core_path = path_get(RARCH_PATH_CORE);
@ -4407,6 +4411,19 @@ static void runloop_runtime_log_init(runloop_state_t *runloop_st)
strlcpy(runloop_st->runtime_core_path,
core_path,
sizeof(runloop_st->runtime_core_path));
if ( !settings->bools.content_runtime_log
&& !settings->bools.content_runtime_log_aggregate)
return;
if ( !string_is_empty(content_path)
&& !string_is_empty(core_path))
runtime_log_init(
runloop_st->runtime_content_path,
runloop_st->runtime_core_path,
settings->paths.directory_runtime_log,
settings->paths.directory_playlist,
true);
}
void runloop_set_frame_limit(
@ -4655,16 +4672,9 @@ bool runloop_event_init_core(
float fastforward_ratio = 0.0f;
rarch_system_info_t *sys_info = &runloop_st->system;
#ifdef HAVE_NETWORKING
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL))
{
/* We need this in order for core_info_current_supports_netplay
to work correctly at init_netplay,
called later at event_init_content. */
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL);
}
#endif
/* Init core info files */
command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
command_event(CMD_EVENT_LOAD_CORE_PERSIST, NULL);
/* Load symbols */
if (!runloop_init_libretro_symbols(runloop_st,
@ -4792,7 +4802,12 @@ bool runloop_event_init_core(
runloop_set_frame_limit(&video_st->av_info, fastforward_ratio);
runloop_st->frame_limit_last_time = cpu_features_get_time_usec();
/* Init runtime log and read current state slot */
runloop_runtime_log_init(runloop_st);
if (runloop_st->entry_state_slot > -1)
configuration_set_int(settings, settings->ints.state_slot, runloop_st->entry_state_slot);
return true;
}

View File

@ -55,6 +55,7 @@ typedef struct
char **current_entry_val;
char *runtime_string;
char *last_played_string;
char *state_slot;
} RtlJSONContext;
static bool RtlJSONObjectMemberHandler(void *ctx, const char *s, size_t len)
@ -71,6 +72,8 @@ static bool RtlJSONObjectMemberHandler(void *ctx, const char *s, size_t len)
p_ctx->current_entry_val = &p_ctx->runtime_string;
else if (string_is_equal(s, "last_played"))
p_ctx->current_entry_val = &p_ctx->last_played_string;
else if (string_is_equal(s, "state_slot"))
p_ctx->current_entry_val = &p_ctx->state_slot;
/* Ignore unknown members */
}
@ -113,6 +116,8 @@ static void runtime_log_read_file(runtime_log_t *runtime_log)
unsigned last_played_minute = 0;
unsigned last_played_second = 0;
unsigned state_slot = 0;
RtlJSONContext context = {0};
/* Attempt to open log file */
RFILE *file = filestream_open(runtime_log->path,
@ -193,6 +198,24 @@ static void runtime_log_read_file(runtime_log_t *runtime_log)
}
}
/* State slot */
if (!string_is_empty(context.state_slot))
{
if (sscanf(context.state_slot,
"%04u",
&state_slot) != 1)
{
RARCH_ERR("[Runtime] Invalid \"state slot\" entry detected: \"%s\".\n", runtime_log->path);
goto end;
}
}
if (state_slot > 0)
{
runloop_state_t *runloop_st = runloop_state_get_ptr();
runloop_st->entry_state_slot = state_slot;
}
/* If we reach this point then all is well
* > Assign values to runtime_log object */
runtime_log->runtime.hours = runtime_hours;
@ -206,12 +229,16 @@ static void runtime_log_read_file(runtime_log_t *runtime_log)
runtime_log->last_played.minute = last_played_minute;
runtime_log->last_played.second = last_played_second;
runtime_log->state_slot = state_slot;
end:
/* Clean up leftover strings */
if (context.runtime_string)
free(context.runtime_string);
if (context.last_played_string)
free(context.last_played_string);
if (context.state_slot)
free(context.state_slot);
/* Close log file */
filestream_close(file);
@ -317,8 +344,10 @@ runtime_log_t *runtime_log_init(
* no content is provided, 'content' is simply
* the name of the core itself */
if (supports_no_game)
fill_pathname(content_name, core_name,
".lrtl", sizeof(content_name));
fill_pathname(content_name,
core_name,
FILE_PATH_RUNTIME_EXTENSION,
sizeof(content_name));
}
/* NOTE: TyrQuake requires a specific hack, since all
* content has the same name... */
@ -334,12 +363,16 @@ runtime_log_t *runtime_log_init(
strlcpy(tmp_buf,
content_path, _len * sizeof(char));
fill_pathname(content_name,
path_basename(tmp_buf), ".lrtl", sizeof(content_name));
path_basename(tmp_buf),
FILE_PATH_RUNTIME_EXTENSION,
sizeof(content_name));
}
}
}
else
fill_pathname(content_name, path_basename(content_path), ".lrtl",
fill_pathname(content_name,
path_basename(content_path),
FILE_PATH_RUNTIME_EXTENSION,
sizeof(content_name));
if (string_is_empty(content_name))
@ -369,6 +402,8 @@ runtime_log_t *runtime_log_init(
runtime_log->last_played.minute = 0;
runtime_log->last_played.second = 0;
runtime_log->state_slot = 0;
runtime_log->path[0] = '\0';
strlcpy(runtime_log->path, log_file_path, sizeof(runtime_log->path));
@ -468,6 +503,8 @@ void runtime_log_reset(runtime_log_t *runtime_log)
runtime_log->last_played.hour = 0;
runtime_log->last_played.minute = 0;
runtime_log->last_played.second = 0;
runtime_log->state_slot = 0;
}
/* Getters */
@ -1112,6 +1149,20 @@ void runtime_log_save(runtime_log_t *runtime_log)
rjsonwriter_raw(writer, ":", 1);
rjsonwriter_raw(writer, " ", 1);
rjsonwriter_add_string(writer, value_string);
rjsonwriter_raw(writer, ",", 1);
rjsonwriter_raw(writer, "\n", 1);
/* > Current state slot */
value_string[0] = '\0';
snprintf(value_string, sizeof(value_string),
"%u",
runtime_log->state_slot);
rjsonwriter_add_spaces(writer, 2);
rjsonwriter_add_string(writer, "state_slot");
rjsonwriter_raw(writer, ":", 1);
rjsonwriter_raw(writer, " ", 1);
rjsonwriter_add_string(writer, value_string);
rjsonwriter_raw(writer, "\n", 1);
/* > Finalise */

View File

@ -57,6 +57,7 @@ typedef struct
{
rtl_runtime_t runtime; /* unsigned alignment */
rtl_last_played_t last_played; /* unsigned alignment */
unsigned state_slot;
char path[PATH_MAX_LENGTH];
} runtime_log_t;