rg_settings: Store configuration sections in separate files
This will be less prone to corruption and user error. It will also easily allow per-rom config
This commit is contained in:
parent
12736c6b02
commit
6b8447a7ca
14
README.md
14
README.md
@ -77,24 +77,16 @@ Some emulators support loading a BIOS. The files should be placed as follows:
|
||||
|
||||
## Wifi
|
||||
|
||||
To use wifi you will need to add your config to `/retro-go/config/retro-go.json` file.
|
||||
To use wifi you will need to add your config to `/retro-go/config/wifi.json` file.
|
||||
It should look like this:
|
||||
|
||||
````json
|
||||
{
|
||||
"global": {
|
||||
...
|
||||
},
|
||||
"wifi": {
|
||||
"ssid": "my-network",
|
||||
"password": "my-password"
|
||||
}
|
||||
"ssid": "my-network",
|
||||
"password": "my-password"
|
||||
}
|
||||
````
|
||||
|
||||
If you are unfamiliar with JSON syntax you can run your config file [through a validator](https://jsonlint.com/)
|
||||
to confirm that it is correct.
|
||||
|
||||
### Time synchronization
|
||||
Time synchronization happens in the launcher immediately after a successful connection to the network.
|
||||
This is done via NTP by contacting `pool.ntp.org` and cannot be disabled at this time.
|
||||
|
||||
@ -1122,8 +1122,7 @@ int rg_gui_about_menu(const rg_gui_option_t *extra_options)
|
||||
switch (sel)
|
||||
{
|
||||
case 1000:
|
||||
rg_system_set_boot_app(RG_APP_FACTORY);
|
||||
rg_system_restart();
|
||||
rg_system_switch_app(RG_APP_FACTORY, RG_APP_FACTORY, 0, 0);
|
||||
break;
|
||||
case 2000:
|
||||
if (rg_gui_confirm("Reset all settings?", NULL, false)) {
|
||||
@ -1302,7 +1301,7 @@ int rg_gui_game_menu(void)
|
||||
switch (sel)
|
||||
{
|
||||
case 1000: if ((slot = rg_gui_savestate_menu("Save", 0, 0)) >= 0) rg_emu_save_state(slot); break;
|
||||
case 2000: if ((slot = rg_gui_savestate_menu("Save", 0, 0)) >= 0) {rg_emu_save_state(slot); exit(0);} break;
|
||||
case 2000: if ((slot = rg_gui_savestate_menu("Save", 0, 0)) >= 0) {rg_emu_save_state(slot); rg_system_switch_app(RG_APP_LAUNCHER, 0, 0, 0);} break;
|
||||
case 3001: if ((slot = rg_gui_savestate_menu("Load", 0, 0)) >= 0) rg_emu_load_state(slot); break;
|
||||
case 3002: rg_emu_reset(false); break;
|
||||
case 3003: rg_emu_reset(true); break;
|
||||
@ -1311,7 +1310,7 @@ int rg_gui_game_menu(void)
|
||||
#endif
|
||||
case 5500: rg_gui_options_menu(); break;
|
||||
case 6000: rg_gui_about_menu(NULL); break;
|
||||
case 7000: exit(0); break;
|
||||
case 7000: rg_system_switch_app(RG_APP_LAUNCHER, 0, 0, 0); break;
|
||||
}
|
||||
|
||||
rg_audio_set_mute(false);
|
||||
|
||||
@ -6,140 +6,145 @@
|
||||
#include <unistd.h>
|
||||
#include <cJSON.h>
|
||||
|
||||
static const char *config_file_path = RG_BASE_PATH_CONFIG "/retro-go.json";
|
||||
static cJSON *config_root = NULL;
|
||||
static int unsaved_changes = 0;
|
||||
|
||||
|
||||
static cJSON *json_root(const char *name)
|
||||
static FILE *open_config_file(const char *name, const char *mode)
|
||||
{
|
||||
char pathbuf[RG_PATH_MAX];
|
||||
snprintf(pathbuf, RG_PATH_MAX, "%s/%s.json", RG_BASE_PATH_CONFIG, name);
|
||||
RG_LOGI("Opening %s for %s", pathbuf, mode);
|
||||
FILE *fp = fopen(pathbuf, mode);
|
||||
if (!fp)
|
||||
{
|
||||
rg_storage_mkdir(rg_dirname(pathbuf));
|
||||
rg_storage_delete(pathbuf);
|
||||
fp = fopen(pathbuf, mode);
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
static cJSON *json_root(const char *name, bool mode)
|
||||
{
|
||||
RG_ASSERT(config_root, "json_root called before settings were initialized!");
|
||||
|
||||
if (name == NS_GLOBAL)
|
||||
name = "global";
|
||||
else if (name == NS_WIFI)
|
||||
name = "wifi";
|
||||
else if (name == NS_APP)
|
||||
name = rg_system_get_app()->configNs;
|
||||
else if (name == NS_FILE)
|
||||
name = rg_system_get_app()->romPath;
|
||||
name = rg_basename(rg_system_get_app()->romPath);
|
||||
else if (name == NS_WIFI)
|
||||
name = "wifi";
|
||||
else if (name == NS_BOOT)
|
||||
name = "boot";
|
||||
|
||||
cJSON *myroot;
|
||||
|
||||
if (!name)
|
||||
cJSON *branch = cJSON_GetObjectItem(config_root, name);
|
||||
if (!branch)
|
||||
{
|
||||
myroot = config_root;
|
||||
}
|
||||
else if (!(myroot = cJSON_GetObjectItem(config_root, name)))
|
||||
{
|
||||
myroot = cJSON_AddObjectToObject(config_root, name);
|
||||
}
|
||||
else if (!cJSON_IsObject(myroot))
|
||||
{
|
||||
myroot = cJSON_CreateObject();
|
||||
cJSON_ReplaceItemInObject(config_root, name, myroot);
|
||||
branch = cJSON_AddObjectToObject(config_root, name);
|
||||
cJSON_AddStringToObject(branch, "namespace", name);
|
||||
cJSON_AddNumberToObject(branch, "changed", 0);
|
||||
FILE *fp = open_config_file(name, "rb");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long length = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *buffer = calloc(1, length + 1);
|
||||
if (fread(buffer, 1, length, fp))
|
||||
cJSON_AddItemToObject(branch, "values", cJSON_Parse(buffer));
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
return myroot;
|
||||
cJSON *root = cJSON_GetObjectItem(branch, "values");
|
||||
if (!cJSON_IsObject(root))
|
||||
{
|
||||
cJSON_DeleteItemFromObject(branch, "values");
|
||||
root = cJSON_AddObjectToObject(branch, "values");
|
||||
}
|
||||
|
||||
if (mode)
|
||||
{
|
||||
cJSON_SetNumberHelper(cJSON_GetObjectItem(branch, "changed"), 1);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static void update_value(const char *section, const char *key, cJSON *new_value)
|
||||
{
|
||||
cJSON *obj = cJSON_GetObjectItem(json_root(section, 0), key);
|
||||
if (obj == NULL)
|
||||
cJSON_AddItemToObject(json_root(section, 1), key, new_value);
|
||||
else if (!cJSON_Compare(obj, new_value, true))
|
||||
cJSON_ReplaceItemInObject(json_root(section, 1), key, new_value);
|
||||
else
|
||||
cJSON_Delete(new_value);
|
||||
}
|
||||
|
||||
void rg_settings_init(void)
|
||||
{
|
||||
FILE *fp = fopen(config_file_path, "rb");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long length = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *buffer = calloc(1, length + 1);
|
||||
if (fread(buffer, 1, length, fp))
|
||||
config_root = cJSON_Parse(buffer);
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (!config_root)
|
||||
{
|
||||
RG_LOGW("Failed to load settings from %s.\n", config_file_path);
|
||||
config_root = cJSON_CreateObject();
|
||||
return;
|
||||
}
|
||||
|
||||
RG_LOGI("Settings loaded from %s.\n", config_file_path);
|
||||
config_root = cJSON_CreateObject();
|
||||
json_root(NS_GLOBAL, 0);
|
||||
json_root(NS_BOOT, 0);
|
||||
}
|
||||
|
||||
void rg_settings_commit(void)
|
||||
{
|
||||
if (!unsaved_changes)
|
||||
if (!config_root)
|
||||
return;
|
||||
|
||||
RG_LOGI("Saving %d change(s)...\n", unsaved_changes);
|
||||
|
||||
char *buffer = cJSON_Print(config_root);
|
||||
if (!buffer)
|
||||
for (cJSON *branch = config_root->child; branch; branch = branch->next)
|
||||
{
|
||||
RG_LOGE("cJSON_Print() failed.\n");
|
||||
return;
|
||||
char *name = cJSON_GetStringValue(cJSON_GetObjectItem(branch, "namespace"));
|
||||
int changed = cJSON_GetNumberValue(cJSON_GetObjectItem(branch, "changed"));
|
||||
|
||||
if (!changed)
|
||||
continue;
|
||||
|
||||
char *buffer = cJSON_Print(cJSON_GetObjectItem(branch, "values"));
|
||||
if (!buffer)
|
||||
continue;
|
||||
|
||||
FILE *fp = open_config_file(name, "wb");
|
||||
if (fp)
|
||||
{
|
||||
if (fputs(buffer, fp) >= 0)
|
||||
cJSON_SetNumberHelper(cJSON_GetObjectItem(branch, "changed"), 0);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
cJSON_free(buffer);
|
||||
}
|
||||
|
||||
FILE *fp = fopen(config_file_path, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
rg_storage_delete(config_file_path);
|
||||
rg_storage_mkdir(rg_dirname(config_file_path));
|
||||
fp = fopen(config_file_path, "wb");
|
||||
}
|
||||
if (fp)
|
||||
{
|
||||
if (fputs(buffer, fp) >= 0)
|
||||
unsaved_changes = 0;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (unsaved_changes > 0)
|
||||
RG_LOGE("Save failed! %p\n", fp);
|
||||
else
|
||||
rg_storage_commit();
|
||||
|
||||
cJSON_free(buffer);
|
||||
rg_storage_commit();
|
||||
}
|
||||
|
||||
void rg_settings_reset(void)
|
||||
{
|
||||
RG_LOGI("Clearing settings...\n");
|
||||
rg_storage_delete(RG_BASE_PATH_CONFIG);
|
||||
cJSON_Delete(config_root);
|
||||
config_root = cJSON_CreateObject();
|
||||
unsaved_changes++;
|
||||
rg_settings_commit();
|
||||
}
|
||||
|
||||
double rg_settings_get_number(const char *section, const char *key, double default_value)
|
||||
{
|
||||
cJSON *obj = cJSON_GetObjectItem(json_root(section), key);
|
||||
cJSON *obj = cJSON_GetObjectItem(json_root(section, 0), key);
|
||||
return obj ? obj->valuedouble : default_value;
|
||||
}
|
||||
|
||||
void rg_settings_set_number(const char *section, const char *key, double value)
|
||||
{
|
||||
cJSON *root = json_root(section);
|
||||
cJSON *obj = cJSON_GetObjectItem(root, key);
|
||||
|
||||
if (!cJSON_IsNumber(obj))
|
||||
{
|
||||
cJSON_Delete(cJSON_DetachItemViaPointer(root, obj));
|
||||
cJSON_AddNumberToObject(root, key, value);
|
||||
unsaved_changes++;
|
||||
}
|
||||
else if (obj->valuedouble != value)
|
||||
{
|
||||
cJSON_SetNumberHelper(obj, value);
|
||||
unsaved_changes++;
|
||||
}
|
||||
update_value(section, key, cJSON_CreateNumber(value));
|
||||
}
|
||||
|
||||
char *rg_settings_get_string(const char *section, const char *key, const char *default_value)
|
||||
{
|
||||
cJSON *obj = cJSON_GetObjectItem(json_root(section), key);
|
||||
cJSON *obj = cJSON_GetObjectItem(json_root(section, 0), key);
|
||||
if (cJSON_IsString(obj))
|
||||
return strdup(obj->valuestring);
|
||||
return default_value ? strdup(default_value) : NULL;
|
||||
@ -147,32 +152,10 @@ char *rg_settings_get_string(const char *section, const char *key, const char *d
|
||||
|
||||
void rg_settings_set_string(const char *section, const char *key, const char *value)
|
||||
{
|
||||
cJSON *root = json_root(section);
|
||||
cJSON *obj = cJSON_GetObjectItem(root, key);
|
||||
cJSON *newobj = value ? cJSON_CreateString(value) : cJSON_CreateNull();
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
cJSON_AddItemToObject(root, key, newobj);
|
||||
unsaved_changes++;
|
||||
}
|
||||
else if (!cJSON_Compare(obj, newobj, true))
|
||||
{
|
||||
cJSON_ReplaceItemInObject(root, key, newobj);
|
||||
unsaved_changes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON_Delete(newobj);
|
||||
}
|
||||
update_value(section, key, value ? cJSON_CreateString(value) : cJSON_CreateNull());
|
||||
}
|
||||
|
||||
void rg_settings_delete(const char *section, const char *key)
|
||||
{
|
||||
cJSON *root = json_root(section);
|
||||
if (key)
|
||||
cJSON_DeleteItemFromObject(root, key);
|
||||
else if (root != config_root)
|
||||
cJSON_Delete(cJSON_DetachItemViaPointer(config_root, root));
|
||||
unsaved_changes++;
|
||||
cJSON_DeleteItemFromObject(json_root(section, 1), key);
|
||||
}
|
||||
|
||||
@ -4,10 +4,11 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define NS_GLOBAL ((char *)-1)
|
||||
#define NS_APP ((char *)-2)
|
||||
#define NS_FILE ((char *)-3)
|
||||
#define NS_WIFI ((char *)-4)
|
||||
#define NS_GLOBAL ((char *)0)
|
||||
#define NS_APP ((char *)1)
|
||||
#define NS_FILE ((char *)2)
|
||||
#define NS_WIFI ((char *)3)
|
||||
#define NS_BOOT ((char *)4)
|
||||
|
||||
void rg_settings_init(void);
|
||||
void rg_settings_commit(void);
|
||||
|
||||
@ -107,7 +107,7 @@ void rg_system_load_time(void)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((fp = fopen(RG_BASE_PATH_CONFIG "/clock.bin", "rb")))
|
||||
if ((fp = fopen(RG_BASE_PATH_CACHE "/clock.bin", "rb")))
|
||||
{
|
||||
fread(&time_sec, sizeof(time_sec), 1, fp);
|
||||
fclose(fp);
|
||||
@ -125,7 +125,7 @@ void rg_system_save_time(void)
|
||||
time_t time_sec = time(NULL);
|
||||
FILE *fp;
|
||||
// We always save to storage in case the RTC disappears.
|
||||
if ((fp = fopen(RG_BASE_PATH_CONFIG "/clock.bin", "wb")))
|
||||
if ((fp = fopen(RG_BASE_PATH_CACHE "/clock.bin", "wb")))
|
||||
{
|
||||
fwrite(&time_sec, sizeof(time_sec), 1, fp);
|
||||
fclose(fp);
|
||||
@ -150,11 +150,7 @@ static void exit_handler(void)
|
||||
{
|
||||
RG_LOGI("Exit handler called.\n");
|
||||
if (!exitCalled)
|
||||
{
|
||||
exitCalled = true;
|
||||
rg_system_set_boot_app(RG_APP_LAUNCHER);
|
||||
rg_system_restart();
|
||||
}
|
||||
rg_system_switch_app(RG_APP_LAUNCHER, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline void begin_panic_trace(const char *context, const char *message)
|
||||
@ -309,12 +305,10 @@ static void enter_recovery_mode(void)
|
||||
rg_settings_reset();
|
||||
break;
|
||||
case 1:
|
||||
rg_system_set_boot_app(RG_APP_FACTORY);
|
||||
rg_system_restart();
|
||||
rg_system_switch_app(RG_APP_FACTORY, RG_APP_FACTORY, 0, 0);
|
||||
case 2:
|
||||
default:
|
||||
rg_system_set_boot_app(RG_APP_LAUNCHER);
|
||||
rg_system_restart();
|
||||
rg_system_switch_app(RG_APP_FACTORY, RG_APP_LAUNCHER, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -381,7 +375,7 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
|
||||
printf(" built for: %s. aud=%d disp=%d pad=%d sd=%d cfg=%d\n", RG_TARGET_NAME, 0, 0, 0, 0, 0);
|
||||
printf("========================================================\n\n");
|
||||
|
||||
#ifndef RG_TARGET_SDL2
|
||||
#ifndef RG_TARGET_SDL2
|
||||
esp_reset_reason_t r_reason = esp_reset_reason();
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
@ -391,7 +385,7 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
|
||||
app.bootType = RG_RST_PANIC;
|
||||
else if (r_reason == ESP_RST_SW)
|
||||
app.bootType = RG_RST_RESTART;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
update_memory_statistics();
|
||||
RG_LOGI("Internal memory: free=%d, total=%d\n", statistics.freeMemoryInt, statistics.totalMemoryInt);
|
||||
@ -408,9 +402,9 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
|
||||
}
|
||||
else
|
||||
{
|
||||
app.configNs = rg_settings_get_string(NS_GLOBAL, SETTING_BOOT_NAME, app.name);
|
||||
app.bootArgs = rg_settings_get_string(NS_GLOBAL, SETTING_BOOT_ARGS, "");
|
||||
app.bootFlags = rg_settings_get_number(NS_GLOBAL, SETTING_BOOT_FLAGS, 0);
|
||||
app.configNs = rg_settings_get_string(NS_BOOT, SETTING_BOOT_NAME, app.name);
|
||||
app.bootArgs = rg_settings_get_string(NS_BOOT, SETTING_BOOT_ARGS, "");
|
||||
app.bootFlags = rg_settings_get_number(NS_BOOT, SETTING_BOOT_FLAGS, 0);
|
||||
app.saveSlot = (app.bootFlags & RG_BOOT_SLOT_MASK) >> 4;
|
||||
app.romPath = app.bootArgs;
|
||||
}
|
||||
@ -449,13 +443,15 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
|
||||
RG_LOGW("Aborting: panic!\n");
|
||||
rg_display_clear(C_BLUE);
|
||||
rg_gui_alert("System Panic!", message);
|
||||
rg_system_set_boot_app(RG_APP_LAUNCHER);
|
||||
rg_system_restart();
|
||||
rg_system_switch_app(RG_APP_LAUNCHER, 0, 0, 0);
|
||||
}
|
||||
panicTrace.magicWord = 0;
|
||||
|
||||
#ifndef RG_TARGET_SDL2
|
||||
if (app.bootFlags & RG_BOOT_ONCE)
|
||||
rg_system_set_boot_app(RG_APP_LAUNCHER);
|
||||
esp_ota_set_boot_partition(esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, RG_APP_LAUNCHER));
|
||||
#endif
|
||||
|
||||
rg_system_set_timezone(rg_settings_get_string(NS_GLOBAL, SETTING_TIMEZONE, "EST+5"));
|
||||
rg_system_load_time();
|
||||
@ -646,7 +642,7 @@ static void emu_update_save_slot(uint8_t slot)
|
||||
app.bootFlags &= ~RG_BOOT_SLOT_MASK;
|
||||
app.bootFlags |= app.saveSlot << 4;
|
||||
app.bootFlags |= RG_BOOT_RESUME;
|
||||
rg_settings_set_number(NS_GLOBAL, SETTING_BOOT_FLAGS, app.bootFlags);
|
||||
rg_settings_set_number(NS_BOOT, SETTING_BOOT_FLAGS, app.bootFlags);
|
||||
}
|
||||
|
||||
rg_storage_commit();
|
||||
@ -848,6 +844,7 @@ void rg_system_shutdown(void)
|
||||
void rg_system_sleep(void)
|
||||
{
|
||||
RG_LOGI("Going to sleep!\n");
|
||||
exitCalled = true;
|
||||
shutdown_cleanup();
|
||||
rg_task_delay(1000);
|
||||
esp_deep_sleep_start();
|
||||
@ -855,43 +852,40 @@ void rg_system_sleep(void)
|
||||
|
||||
void rg_system_restart(void)
|
||||
{
|
||||
RG_LOGI("Restarting system.\n");
|
||||
exitCalled = true;
|
||||
shutdown_cleanup();
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
void rg_system_start_app(const char *app, const char *name, const char *args, uint32_t flags)
|
||||
void rg_system_switch_app(const char *partition, const char *name, const char *args, uint32_t flags)
|
||||
{
|
||||
rg_settings_set_string(NS_GLOBAL, SETTING_BOOT_NAME, name);
|
||||
rg_settings_set_string(NS_GLOBAL, SETTING_BOOT_ARGS, args);
|
||||
rg_settings_set_number(NS_GLOBAL, SETTING_BOOT_FLAGS, flags);
|
||||
rg_system_save_time();
|
||||
rg_settings_commit();
|
||||
rg_system_set_boot_app(app);
|
||||
rg_system_restart();
|
||||
}
|
||||
RG_LOGI("Switching to app %s (%s)!\n", partition, name ?: "-");
|
||||
exitCalled = true;
|
||||
|
||||
bool rg_system_find_app(const char *app)
|
||||
{
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, app) != NULL;
|
||||
}
|
||||
if (app.initialized)
|
||||
{
|
||||
rg_settings_set_string(NS_BOOT, SETTING_BOOT_NAME, name);
|
||||
rg_settings_set_string(NS_BOOT, SETTING_BOOT_ARGS, args);
|
||||
rg_settings_set_number(NS_BOOT, SETTING_BOOT_FLAGS, flags);
|
||||
rg_system_save_time();
|
||||
rg_settings_commit();
|
||||
}
|
||||
|
||||
void rg_system_set_boot_app(const char *app)
|
||||
{
|
||||
const esp_partition_t* partition = esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, app);
|
||||
|
||||
if (partition == NULL)
|
||||
RG_PANIC("Unable to set boot app: App not found!");
|
||||
|
||||
esp_err_t err = esp_ota_set_boot_partition(partition);
|
||||
esp_err_t err = esp_ota_set_boot_partition(esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, partition));
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
RG_LOGE("esp_ota_set_boot_partition returned 0x%02X!\n", err);
|
||||
RG_PANIC("Unable to set boot app!");
|
||||
}
|
||||
|
||||
RG_LOGI("Boot partition set to %d '%s'\n", partition->subtype, partition->label);
|
||||
rg_system_restart();
|
||||
}
|
||||
|
||||
bool rg_system_have_app(const char *app)
|
||||
{
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, app) != NULL;
|
||||
}
|
||||
|
||||
void rg_system_panic(const char *context, const char *message)
|
||||
|
||||
@ -191,9 +191,8 @@ void rg_system_panic(const char *context, const char *message) __attribute__((no
|
||||
void rg_system_shutdown(void) __attribute__((noreturn));
|
||||
void rg_system_sleep(void) __attribute__((noreturn));
|
||||
void rg_system_restart(void) __attribute__((noreturn));
|
||||
void rg_system_start_app(const char *app, const char *name, const char *args, uint32_t flags) __attribute__((noreturn));
|
||||
void rg_system_set_boot_app(const char *app);
|
||||
bool rg_system_find_app(const char *app);
|
||||
void rg_system_switch_app(const char *part, const char *name, const char *args, uint32_t flags) __attribute__((noreturn));
|
||||
bool rg_system_have_app(const char *app);
|
||||
void rg_system_set_led(int value);
|
||||
int rg_system_get_led(void);
|
||||
void rg_system_tick(int busyTime);
|
||||
|
||||
@ -135,7 +135,7 @@ static void application_start(retro_file_t *file, int load_state)
|
||||
flags |= (load_state << 4) & RG_BOOT_SLOT_MASK;
|
||||
}
|
||||
bookmark_add(BOOK_TYPE_RECENT, file); // This could relocate *file, but we no longer need it
|
||||
rg_system_start_app(part, name, path, flags);
|
||||
rg_system_switch_app(part, name, path, flags);
|
||||
}
|
||||
|
||||
static void crc_cache_init(void)
|
||||
@ -648,7 +648,7 @@ void application_show_file_menu(retro_file_t *file, bool advanced)
|
||||
|
||||
static void application(const char *desc, const char *name, const char *exts, const char *part, uint16_t crc_offset)
|
||||
{
|
||||
if (!rg_system_find_app(part))
|
||||
if (!rg_system_have_app(part))
|
||||
{
|
||||
RG_LOGI("Application '%s' (%s) not present, skipping\n", desc, part);
|
||||
return;
|
||||
@ -667,7 +667,7 @@ static void application(const char *desc, const char *name, const char *exts, co
|
||||
snprintf(app->paths.covers, RG_PATH_MAX, RG_BASE_PATH_COVERS "/%s", app->short_name);
|
||||
snprintf(app->paths.saves, RG_PATH_MAX, RG_BASE_PATH_SAVES "/%s", app->short_name);
|
||||
snprintf(app->paths.roms, RG_PATH_MAX, RG_BASE_PATH_ROMS "/%s", app->short_name);
|
||||
app->available = rg_system_find_app(app->partition);
|
||||
app->available = rg_system_have_app(app->partition);
|
||||
app->files = calloc(10, sizeof(retro_file_t));
|
||||
app->crc_offset = crc_offset;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user