Added manual override options for save and TV type

This commit is contained in:
Mateusz Faderewski 2023-12-21 19:58:30 +01:00
parent ae37f92c7f
commit 621e50cf7b
12 changed files with 326 additions and 68 deletions

View File

@ -34,8 +34,8 @@ static bool create_saves_subdirectory (path_t *path) {
return error; return error;
} }
static flashcart_save_type_t convert_save_type (rom_info_t *info) { static flashcart_save_type_t convert_save_type (rom_save_type_t save_type) {
switch (info->save_type) { switch (save_type) {
case SAVE_TYPE_EEPROM_4K: return FLASHCART_SAVE_TYPE_EEPROM_4K; case SAVE_TYPE_EEPROM_4K: return FLASHCART_SAVE_TYPE_EEPROM_4K;
case SAVE_TYPE_EEPROM_16K: return FLASHCART_SAVE_TYPE_EEPROM_16K; case SAVE_TYPE_EEPROM_16K: return FLASHCART_SAVE_TYPE_EEPROM_16K;
case SAVE_TYPE_SRAM: return FLASHCART_SAVE_TYPE_SRAM; case SAVE_TYPE_SRAM: return FLASHCART_SAVE_TYPE_SRAM;
@ -71,7 +71,7 @@ cart_load_err_t cart_load_n64_rom_and_save (menu_t *menu, flashcart_progress_cal
path_t *path = path_clone(menu->load.rom_path); path_t *path = path_clone(menu->load.rom_path);
bool byte_swap = (menu->load.rom_info.endianness == ENDIANNESS_BYTE_SWAP); bool byte_swap = (menu->load.rom_info.endianness == ENDIANNESS_BYTE_SWAP);
flashcart_save_type_t save_type = convert_save_type(&menu->load.rom_info); flashcart_save_type_t save_type = convert_save_type(rom_info_get_save_type(&menu->load.rom_info));
menu->flashcart_err = flashcart_load_rom(path_get(path), byte_swap, progress); menu->flashcart_err = flashcart_load_rom(path_get(path), byte_swap, progress);
if (menu->flashcart_err != FLASHCART_OK) { if (menu->flashcart_err != FLASHCART_OK) {

View File

@ -37,13 +37,16 @@ void component_background_draw (void);
void component_file_list_draw (entry_t *list, int entries, int selected); void component_file_list_draw (entry_t *list, int entries, int selected);
typedef struct { typedef struct component_context_menu {
int count; int count;
int selected; int selected;
bool hide_pending; bool hide_pending;
struct component_context_menu *parent;
struct component_context_menu *submenu;
struct { struct {
const char *text; const char *text;
void (*action) (menu_t *menu); void (*action) (menu_t *menu);
struct component_context_menu *submenu;
} list[]; } list[];
} component_context_menu_t; } component_context_menu_t;

View File

@ -3,10 +3,19 @@
#include "constants.h" #include "constants.h"
static component_context_menu_t *get_current_submenu (component_context_menu_t *cm) {
while (cm->submenu != NULL) {
cm = cm->submenu;
}
return cm;
}
void component_context_menu_init (component_context_menu_t *cm) { void component_context_menu_init (component_context_menu_t *cm) {
cm->selected = -1; cm->selected = -1;
cm->count = 0; cm->count = 0;
cm->hide_pending = false; cm->hide_pending = false;
cm->parent = NULL;
for (int i = 0; (cm->list[i].text) != NULL; i++) { for (int i = 0; (cm->list[i].text) != NULL; i++) {
cm->count += 1; cm->count += 1;
} }
@ -14,6 +23,7 @@ void component_context_menu_init (component_context_menu_t *cm) {
void component_context_menu_show (component_context_menu_t *cm) { void component_context_menu_show (component_context_menu_t *cm) {
cm->selected = 0; cm->selected = 0;
cm->submenu = NULL;
} }
bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) { bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) {
@ -21,13 +31,26 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
return false; return false;
} }
component_context_menu_t *top = cm;
cm = get_current_submenu(cm);
if (menu->actions.back) { if (menu->actions.back) {
cm->hide_pending = true; if (cm->parent) {
} else if (menu->actions.enter) { cm->parent->submenu = NULL;
if (cm->list[cm->selected].action) { } else {
cm->list[cm->selected].action(menu);
cm->hide_pending = true; cm->hide_pending = true;
} }
} else if (menu->actions.enter) {
if (cm->list[cm->selected].submenu) {
cm->submenu = cm->list[cm->selected].submenu;
component_context_menu_init(cm->submenu);
cm->submenu->selected = 0;
cm->submenu->parent = cm;
} else if (cm->list[cm->selected].action) {
cm->list[cm->selected].action(menu);
top->hide_pending = true;
}
} else if (menu->actions.go_up) { } else if (menu->actions.go_up) {
cm->selected -= 1; cm->selected -= 1;
if (cm->selected < 0) { if (cm->selected < 0) {
@ -48,6 +71,10 @@ void component_context_menu_draw (component_context_menu_t *cm) {
return; return;
} }
component_context_menu_t *top = cm;
cm = get_current_submenu(cm);
rdpq_paragraph_builder_begin( rdpq_paragraph_builder_begin(
&(rdpq_textparms_t) { &(rdpq_textparms_t) {
.width = VISIBLE_AREA_WIDTH, .width = VISIBLE_AREA_WIDTH,
@ -91,8 +118,8 @@ void component_context_menu_draw (component_context_menu_t *cm) {
rdpq_paragraph_free(layout); rdpq_paragraph_free(layout);
if (cm->hide_pending) { if (top->hide_pending) {
cm->hide_pending = false; top->hide_pending = false;
cm->selected = -1; top->selected = -1;
} }
} }

View File

@ -89,6 +89,7 @@ static void menu_init (boot_params_t *boot_params) {
char *init_directory = default_directory_exists ? menu->settings.default_directory : ""; char *init_directory = default_directory_exists ? menu->settings.default_directory : "";
menu->browser.valid = false; menu->browser.valid = false;
menu->browser.reload = false;
menu->browser.directory = path_init("sd:/", init_directory); menu->browser.directory = path_init("sd:/", init_directory);
menu->load.rom_path = NULL; menu->load.rom_path = NULL;

View File

@ -90,6 +90,7 @@ typedef struct {
struct { struct {
bool valid; bool valid;
bool reload;
path_t *directory; path_t *directory;
entry_t list[BROWSER_LIST_SIZE]; entry_t list[BROWSER_LIST_SIZE];
int entries; int entries;

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include <fatfs/ff.h> #include <fatfs/ff.h>
#include <mini.c/src/mini.h>
#include "rom_info.h" #include "rom_info.h"
#include "utils/fs.h" #include "utils/fs.h"
@ -121,7 +122,7 @@ typedef struct {
// Matched game metadata // Matched game metadata
struct { struct {
// Save type (only cartridge save types) // Save type (only cartridge save types)
save_type_t save; rom_save_type_t save;
// Supported features // Supported features
feat_t feat; feat_t feat;
@ -659,6 +660,40 @@ static uint32_t fix_boot_address (cic_type_t cic_type, uint32_t boot_address) {
} }
} }
static rom_tv_type_t determine_tv_type (destination_type_t rom_destination_code) {
// check the market type from the ROM destination_code and return best guess!
switch (rom_destination_code) {
case MARKET_NORTH_AMERICA:
case MARKET_JAPANESE:
case MARKET_JAPANESE_MULTI:
case MARKET_GATEWAY64_NTSC:
return ROM_TV_TYPE_NTSC;
case MARKET_BRAZILIAN:
return ROM_TV_TYPE_MPAL;
case MARKET_GERMAN:
case MARKET_FRENCH:
case MARKET_DUTCH:
case MARKET_ITALIAN:
case MARKET_SPANISH:
case MARKET_AUSTRALIAN:
case MARKET_SCANDINAVIAN:
case MARKET_GATEWAY64_PAL:
case MARKET_EUROPEAN_BASIC:
// FIXME: There might be some interesting errors with OTHER_X and OTHER_Y (e.g. TGR Asia).
// But they are mainly PAL regions.
case MARKET_OTHER_X:
case MARKET_OTHER_Y:
return ROM_TV_TYPE_PAL;
// FIXME: We cannot be sure on these markets, so just return the default for the moment!
case MARKET_CHINESE:
case MARKET_CANADIAN:
case MARKET_KOREAN:
case MARKET_OTHER_Z:
default:
return ROM_TV_TYPE_UNKNOWN;
}
}
static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info_t *rom_info) { static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info_t *rom_info) {
rom_info->cic_type = cic_detect(rom_header->ipl3); rom_info->cic_type = cic_detect(rom_header->ipl3);
@ -688,6 +723,7 @@ static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info
rom_info->version = rom_header->version; rom_info->version = rom_header->version;
rom_info->save_type = match->data.save; rom_info->save_type = match->data.save;
rom_info->tv_type = determine_tv_type(rom_info->destination_code);
rom_info->features.controller_pak = (match->data.feat & FEAT_CPAK); rom_info->features.controller_pak = (match->data.feat & FEAT_CPAK);
rom_info->features.rumble_pak = (match->data.feat & FEAT_RPAK); rom_info->features.rumble_pak = (match->data.feat & FEAT_RPAK);
@ -709,13 +745,127 @@ static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info
} }
} }
static void load_overrides (path_t *path, rom_info_t *rom_info) {
rom_info->override.save = false;
rom_info->override.tv = false;
rom_err_t rom_info_load (char *path, rom_info_t *rom_info) { path_t *overrides_path = path_clone(path);
path_ext_replace(overrides_path, "ini");
if (!file_exists(path_get(overrides_path))) {
path_free(overrides_path);
return;
}
mini_t *ini = mini_try_load(path_get(overrides_path));
rom_info->override.save_type = mini_get_int(ini, NULL, "save_type", SAVE_TYPE_AUTOMATIC);
if (rom_info->override.save_type != SAVE_TYPE_AUTOMATIC) {
rom_info->override.save = true;
}
rom_info->override.tv_type = mini_get_int(ini, NULL, "tv_type", ROM_TV_TYPE_AUTOMATIC);
if (rom_info->override.tv_type != ROM_TV_TYPE_AUTOMATIC) {
rom_info->override.tv = true;
}
mini_free(ini);
path_free(overrides_path);
}
rom_err_t rom_info_override_save_type (path_t *path, rom_info_t *rom_info, rom_save_type_t save_type) {
path_t *overrides_path = path_clone(path);
path_ext_replace(overrides_path, "ini");
mini_t *ini = mini_try_load(path_get(overrides_path));
rom_info->override.save_type = save_type;
if (rom_info->override.save_type == SAVE_TYPE_AUTOMATIC) {
rom_info->override.save = false;
mini_delete_value(ini, NULL, "save_type");
} else {
rom_info->override.save = true;
mini_set_int(ini, NULL, "save_type", rom_info->override.save_type);
}
bool empty_override_file = mini_empty(ini);
if (!empty_override_file) {
mini_save(ini, MINI_FLAGS_NONE);
}
mini_free(ini);
if (empty_override_file) {
file_delete(path_get(overrides_path));
}
path_free(overrides_path);
return ROM_OK;
}
rom_err_t rom_info_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type) {
path_t *overrides_path = path_clone(path);
path_ext_replace(overrides_path, "ini");
mini_t *ini = mini_try_load(path_get(overrides_path));
rom_info->override.tv_type = tv_type;
if (rom_info->override.tv_type == ROM_TV_TYPE_AUTOMATIC) {
rom_info->override.tv = false;
mini_delete_value(ini, NULL, "tv_type");
} else {
rom_info->override.tv = true;
mini_set_int(ini, NULL, "tv_type", rom_info->override.tv_type);
}
bool empty_override_file = mini_empty(ini);
if (!empty_override_file) {
mini_save(ini, MINI_FLAGS_NONE);
}
mini_free(ini);
if (empty_override_file) {
file_delete(path_get(overrides_path));
}
path_free(overrides_path);
return ROM_OK;
}
rom_save_type_t rom_info_get_save_type (rom_info_t *rom_info) {
if (rom_info->override.save) {
return rom_info->override.save_type;
} else {
return rom_info->save_type;
}
}
rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info) {
if (rom_info->override.tv) {
return rom_info->override.tv_type;
} else {
return rom_info->tv_type;
}
}
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info) {
FIL fil; FIL fil;
UINT br; UINT br;
rom_header_t rom_header; rom_header_t rom_header;
if (f_open(&fil, strip_sd_prefix(path), FA_READ) != FR_OK) { if (f_open(&fil, strip_sd_prefix(path_get(path)), FA_READ) != FR_OK) {
return ROM_ERR_NO_FILE; return ROM_ERR_NO_FILE;
} }
if (f_read(&fil, &rom_header, sizeof(rom_header), &br) != FR_OK) { if (f_read(&fil, &rom_header, sizeof(rom_header), &br) != FR_OK) {
@ -735,5 +885,7 @@ rom_err_t rom_info_load (char *path, rom_info_t *rom_info) {
extract_rom_info(&match, &rom_header, rom_info); extract_rom_info(&match, &rom_header, rom_info);
load_overrides(path, rom_info);
return ROM_OK; return ROM_OK;
} }

View File

@ -13,6 +13,8 @@
#include <stdint.h> #include <stdint.h>
#include "boot/cic.h" #include "boot/cic.h"
#include "path.h"
/** @brief ROM error enumeration. */ /** @brief ROM error enumeration. */
typedef enum { typedef enum {
@ -100,7 +102,16 @@ typedef enum {
SAVE_TYPE_SRAM_128K, SAVE_TYPE_SRAM_128K,
SAVE_TYPE_FLASHRAM, SAVE_TYPE_FLASHRAM,
SAVE_TYPE_FLASHRAM_PKST2, SAVE_TYPE_FLASHRAM_PKST2,
} save_type_t; SAVE_TYPE_AUTOMATIC = -1,
} rom_save_type_t;
typedef enum {
ROM_TV_TYPE_PAL,
ROM_TV_TYPE_NTSC,
ROM_TV_TYPE_MPAL,
ROM_TV_TYPE_UNKNOWN,
ROM_TV_TYPE_AUTOMATIC = -1,
} rom_tv_type_t;
/** @brief ROM memory requirements enumeration. */ /** @brief ROM memory requirements enumeration. */
typedef enum { typedef enum {
@ -156,7 +167,17 @@ typedef struct {
cic_type_t cic_type; cic_type_t cic_type;
/** @brief The save type required by the ROM. */ /** @brief The save type required by the ROM. */
save_type_t save_type; rom_save_type_t save_type;
rom_tv_type_t tv_type;
struct {
bool save;
rom_save_type_t save_type;
bool tv;
rom_tv_type_t tv_type;
} override;
/** @brief The supported ROM accessories. */ /** @brief The supported ROM accessories. */
struct { struct {
@ -172,7 +193,11 @@ typedef struct {
} rom_info_t; } rom_info_t;
rom_err_t rom_info_load (char *path, rom_info_t *rom_info); rom_err_t rom_info_override_save_type (path_t *path, rom_info_t *rom_info, rom_save_type_t save_type);
rom_err_t rom_info_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type);
rom_save_type_t rom_info_get_save_type (rom_info_t *rom_info);
rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info);
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info);
#endif #endif

View File

@ -4,16 +4,17 @@
#include "settings.h" #include "settings.h"
#include "utils/fs.h" #include "utils/fs.h"
#ifndef SETTINGS_FILE_PATH #ifndef SETTINGS_FILE_PATH
#define SETTINGS_FILE_PATH "sd:/menu/config.ini" #define SETTINGS_FILE_PATH "sd:/menu/config.ini"
#endif #endif
static settings_t init = { static settings_t init = {
.pal60_enabled = false, .pal60_enabled = false,
.hidden_files_enabled = false, .hidden_files_enabled = false,
.default_directory = "/", .default_directory = "/",
.use_saves_folder = true, .use_saves_folder = true,
.autodetect_rom_region = true,
/* Beta feature flags (should always init to off) */ /* Beta feature flags (should always init to off) */
.bgm_enabled = false, .bgm_enabled = false,
@ -33,14 +34,12 @@ void settings_load (settings_t *settings) {
settings->hidden_files_enabled = mini_get_bool(ini, "menu", "show_hidden_files", init.hidden_files_enabled); settings->hidden_files_enabled = mini_get_bool(ini, "menu", "show_hidden_files", init.hidden_files_enabled);
settings->default_directory = strdup(mini_get_string(ini, "menu", "default_directory", init.default_directory)); settings->default_directory = strdup(mini_get_string(ini, "menu", "default_directory", init.default_directory));
settings->use_saves_folder = mini_get_bool(ini, "menu", "use_saves_folder", init.use_saves_folder); settings->use_saves_folder = mini_get_bool(ini, "menu", "use_saves_folder", init.use_saves_folder);
settings->autodetect_rom_region = mini_get_bool(ini, "menu", "autodetect_rom_region", init.autodetect_rom_region);
/* Beta feature flags, they might not be in the file */ /* Beta feature flags, they might not be in the file */
settings->bgm_enabled = mini_get_bool(ini, "menu_beta_flag", "bgm_enabled", init.bgm_enabled); settings->bgm_enabled = mini_get_bool(ini, "menu_beta_flag", "bgm_enabled", init.bgm_enabled);
settings->sound_enabled = mini_get_bool(ini, "menu_beta_flag", "sound_enabled", init.sound_enabled); settings->sound_enabled = mini_get_bool(ini, "menu_beta_flag", "sound_enabled", init.sound_enabled);
settings->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled); settings->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled);
mini_free(ini); mini_free(ini);
} }
@ -51,7 +50,6 @@ void settings_save (settings_t *settings) {
mini_set_bool(ini, "menu", "show_hidden_files", settings->hidden_files_enabled); mini_set_bool(ini, "menu", "show_hidden_files", settings->hidden_files_enabled);
mini_set_string(ini, "menu", "default_directory", settings->default_directory); mini_set_string(ini, "menu", "default_directory", settings->default_directory);
mini_set_bool(ini, "menu", "use_saves_folder", settings->use_saves_folder); mini_set_bool(ini, "menu", "use_saves_folder", settings->use_saves_folder);
mini_set_bool(ini, "menu", "autodetect_rom_region", settings->autodetect_rom_region);
/* Beta feature flags, they should not save until production ready! */ /* Beta feature flags, they should not save until production ready! */
// mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled); // mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled);

View File

@ -22,9 +22,6 @@ typedef struct {
/** @brief Put saves into separate directory */ /** @brief Put saves into separate directory */
bool use_saves_folder; bool use_saves_folder;
/** @brief Enable forcing the (N64 system region) tv type to align with game region when booting the ROM. */
bool autodetect_rom_region;
/** @brief Enable Background music */ /** @brief Enable Background music */
bool bgm_enabled; bool bgm_enabled;
@ -33,9 +30,9 @@ typedef struct {
/** @brief Enable rumble feedback */ /** @brief Enable rumble feedback */
bool rumble_enabled; bool rumble_enabled;
} settings_t; } settings_t;
/** @brief The settings to load */ /** @brief The settings to load */
void settings_load (settings_t *settings); void settings_load (settings_t *settings);
/** @brief The settings to save */ /** @brief The settings to save */

View File

@ -357,6 +357,20 @@ void view_browser_init (menu_t *menu) {
menu->browser.valid = true; menu->browser.valid = true;
} }
} }
if (menu->browser.reload) {
menu->browser.reload = false;
int selected = menu->browser.selected;
if (load_directory(menu)) {
menu_show_error(menu, "Error while reloading current directory");
menu->browser.valid = false;
} else {
menu->browser.selected = selected;
if (menu->browser.selected >= menu->browser.entries) {
menu->browser.selected = menu->browser.entries - 1;
}
menu->browser.entry = menu->browser.selected >= 0 ? &menu->browser.list[menu->browser.selected] : NULL;
}
}
} }
void view_browser_display (menu_t *menu, surface_t *display) { void view_browser_display (menu_t *menu, surface_t *display) {

View File

@ -64,7 +64,7 @@ static const char *format_rom_destination_market (destination_type_t market_type
} }
} }
static const char *format_rom_save_type (save_type_t save_type) { static const char *format_rom_save_type (rom_save_type_t save_type) {
switch (save_type) { switch (save_type) {
case SAVE_TYPE_NONE: return "None"; case SAVE_TYPE_NONE: return "None";
case SAVE_TYPE_EEPROM_4K: return "EEPROM 4K"; case SAVE_TYPE_EEPROM_4K: return "EEPROM 4K";
@ -78,6 +78,15 @@ static const char *format_rom_save_type (save_type_t save_type) {
} }
} }
static const char *format_rom_tv_type (rom_tv_type_t tv_type) {
switch (tv_type) {
case ROM_TV_TYPE_PAL: return "PAL";
case ROM_TV_TYPE_NTSC: return "NTSC";
case ROM_TV_TYPE_MPAL: return "MPAL";
default: return "Unknown";
}
}
static char *format_rom_expansion_pak_info (expansion_pak_t expansion_pak_info) { static char *format_rom_expansion_pak_info (expansion_pak_t expansion_pak_info) {
switch (expansion_pak_info) { switch (expansion_pak_info) {
case EXPANSION_PAK_REQUIRED: return "Required"; case EXPANSION_PAK_REQUIRED: return "Required";
@ -107,46 +116,67 @@ static const char *format_cic_type (cic_type_t cic_type) {
} }
} }
static boot_tv_type_t determine_tv_boot_type (destination_type_t rom_destination_code) { static void set_save_type (menu_t *menu, rom_save_type_t save_type) {
// check the market type from the ROM destination_code and return best guess! rom_info_override_save_type(menu->load.rom_path, &menu->load.rom_info, save_type);
switch (rom_destination_code) { menu->browser.reload = true;
case MARKET_NORTH_AMERICA:
case MARKET_JAPANESE:
case MARKET_JAPANESE_MULTI:
case MARKET_GATEWAY64_NTSC:
return BOOT_TV_TYPE_NTSC;
case MARKET_BRAZILIAN:
return BOOT_TV_TYPE_MPAL;
case MARKET_GERMAN:
case MARKET_FRENCH:
case MARKET_DUTCH:
case MARKET_ITALIAN:
case MARKET_SPANISH:
case MARKET_AUSTRALIAN:
case MARKET_SCANDINAVIAN:
case MARKET_GATEWAY64_PAL:
case MARKET_EUROPEAN_BASIC:
// FIXME: There might be some interesting errors with OTHER_X and OTHER_Y (e.g. TGR Asia).
// But they are mainly PAL regions.
case MARKET_OTHER_X:
case MARKET_OTHER_Y:
return BOOT_TV_TYPE_PAL;
// FIXME: We cannot be sure on these markets, so just return the default for the moment!
case MARKET_CHINESE:
case MARKET_CANADIAN:
case MARKET_KOREAN:
case MARKET_OTHER_Z:
default:
return BOOT_TV_TYPE_PASSTHROUGH;
}
} }
static void set_save_type_automatic (menu_t *menu) { set_save_type(menu, SAVE_TYPE_AUTOMATIC); }
static void set_save_type_none (menu_t *menu) { set_save_type(menu, SAVE_TYPE_NONE); }
static void set_save_type_eeprom_4kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_EEPROM_4K); }
static void set_save_type_eeprom_16kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_EEPROM_16K); }
static void set_save_type_sram_256kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM); }
static void set_save_type_sram_768kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM_BANKED); }
static void set_save_type_sram_1mbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM_128K); }
static void set_save_type_flash_ram_1mbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_FLASHRAM); }
static component_context_menu_t set_save_type_context_menu = { .list = {
{ .text = "Automatic", .action = set_save_type_automatic },
{ .text = "None", .action = set_save_type_none },
{ .text = "EEPROM 4kbit", .action = set_save_type_eeprom_4kbit },
{ .text = "EEPROM 16kbit", .action = set_save_type_eeprom_16kbit },
{ .text = "SRAM 256kbit", .action = set_save_type_sram_256kbit },
{ .text = "SRAM 768kbit", .action = set_save_type_sram_768kbit },
{ .text = "SRAM 1Mbit", .action = set_save_type_sram_1mbit },
{ .text = "FlashRAM 1Mbit", .action = set_save_type_flash_ram_1mbit },
COMPONENT_CONTEXT_MENU_LIST_END,
}};
static void set_tv_type (menu_t *menu, rom_tv_type_t tv_type) {
rom_info_override_tv_type(menu->load.rom_path, &menu->load.rom_info, tv_type);
menu->browser.reload = true;
}
static void set_tv_type_automatic (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_AUTOMATIC); }
static void set_tv_type_pal (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_PAL); }
static void set_tv_type_ntsc (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_NTSC); }
static void set_tv_type_mpal (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_MPAL); }
static component_context_menu_t set_tv_type_context_menu = { .list = {
{ .text = "Automatic", .action = set_tv_type_automatic },
{ .text = "PAL", .action = set_tv_type_pal },
{ .text = "NTSC", .action = set_tv_type_ntsc },
{ .text = "MPAL", .action = set_tv_type_mpal },
COMPONENT_CONTEXT_MENU_LIST_END,
}};
static component_context_menu_t options_context_menu = { .list = {
{ .text = "Set Save Type", .submenu = &set_save_type_context_menu },
{ .text = "Set TV Type", .submenu = &set_tv_type_context_menu },
COMPONENT_CONTEXT_MENU_LIST_END,
}};
static void process (menu_t *menu) { static void process (menu_t *menu) {
if (component_context_menu_process(menu, &options_context_menu)) {
return;
}
if (menu->actions.enter) { if (menu->actions.enter) {
load_pending = true; load_pending = true;
} else if (menu->actions.back) { } else if (menu->actions.back) {
menu->next_mode = MENU_MODE_BROWSER; menu->next_mode = MENU_MODE_BROWSER;
} else if (menu->actions.options) {
component_context_menu_show(&options_context_menu);
} }
} }
@ -182,6 +212,7 @@ static void draw (menu_t *menu, surface_t *d) {
" Version: %hhu\n" " Version: %hhu\n"
" Check code: 0x%016llX\n" " Check code: 0x%016llX\n"
" Save type: %s\n" " Save type: %s\n"
" TV type: %s\n"
" Expansion PAK: %s\n" " Expansion PAK: %s\n"
"\n" "\n"
" Extra information:\n" " Extra information:\n"
@ -196,7 +227,8 @@ static void draw (menu_t *menu, surface_t *d) {
format_rom_destination_market(menu->load.rom_info.destination_code), format_rom_destination_market(menu->load.rom_info.destination_code),
menu->load.rom_info.version, menu->load.rom_info.version,
menu->load.rom_info.check_code, menu->load.rom_info.check_code,
format_rom_save_type(menu->load.rom_info.save_type), format_rom_save_type(rom_info_get_save_type(&menu->load.rom_info)),
format_rom_tv_type(rom_info_get_tv_type(&menu->load.rom_info)),
format_rom_expansion_pak_info(menu->load.rom_info.features.expansion_pak), format_rom_expansion_pak_info(menu->load.rom_info.features.expansion_pak),
format_cic_type(menu->load.rom_info.cic_type), format_cic_type(menu->load.rom_info.cic_type),
menu->load.rom_info.boot_address, menu->load.rom_info.boot_address,
@ -210,7 +242,15 @@ static void draw (menu_t *menu, surface_t *d) {
"B: Exit" "B: Exit"
); );
component_actions_bar_text_draw(
ALIGN_RIGHT, VALIGN_TOP,
"\n"
"R: Options"
);
component_boxart_draw(boxart); component_boxart_draw(boxart);
component_context_menu_draw(&options_context_menu);
} }
rdpq_detach_show(); rdpq_detach_show();
@ -239,14 +279,14 @@ static void load (menu_t *menu) {
} }
menu->next_mode = MENU_MODE_BOOT; menu->next_mode = MENU_MODE_BOOT;
menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM; menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
menu->boot_params->detect_cic_seed = true; menu->boot_params->detect_cic_seed = true;
switch(rom_info_get_tv_type(&menu->load.rom_info)) {
if (menu->settings.autodetect_rom_region) { case ROM_TV_TYPE_PAL: menu->boot_params->tv_type = BOOT_TV_TYPE_PAL; break;
menu->boot_params->tv_type = determine_tv_boot_type(menu->load.rom_info.destination_code); case ROM_TV_TYPE_NTSC: menu->boot_params->tv_type = BOOT_TV_TYPE_NTSC; break;
} case ROM_TV_TYPE_MPAL: menu->boot_params->tv_type = BOOT_TV_TYPE_MPAL; break;
else { default: menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH; break;
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
} }
} }
@ -265,12 +305,14 @@ void view_load_rom_init (menu_t *menu) {
menu->load.rom_path = path_clone_push(menu->browser.directory, menu->browser.entry->name); menu->load.rom_path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
rom_err_t err = rom_info_load(path_get(menu->load.rom_path), &menu->load.rom_info); rom_err_t err = rom_info_load(menu->load.rom_path, &menu->load.rom_info);
if (err != ROM_OK) { if (err != ROM_OK) {
menu_show_error(menu, convert_error_message(err)); menu_show_error(menu, convert_error_message(err));
} }
boxart = component_boxart_init(menu->load.rom_info.game_code); boxart = component_boxart_init(menu->load.rom_info.game_code);
component_context_menu_init(&options_context_menu);
} }
void view_load_rom_display (menu_t *menu, surface_t *display) { void view_load_rom_display (menu_t *menu, surface_t *display) {

View File

@ -35,7 +35,6 @@ static void draw (menu_t *menu, surface_t *d) {
"hidden_files_enabled: %s\n" "hidden_files_enabled: %s\n"
"default_directory: %s\n" "default_directory: %s\n"
"use_saves_folder: %s\n" "use_saves_folder: %s\n"
"autodetect_rom_region: %s\n"
"bgm_enabled: %s\n" "bgm_enabled: %s\n"
"sound_enabled: %s\n" "sound_enabled: %s\n"
"rumble_enabled: %s\n", "rumble_enabled: %s\n",
@ -43,7 +42,6 @@ static void draw (menu_t *menu, surface_t *d) {
convert_boolean(menu->settings.hidden_files_enabled), convert_boolean(menu->settings.hidden_files_enabled),
menu->settings.default_directory, menu->settings.default_directory,
convert_boolean(menu->settings.use_saves_folder), convert_boolean(menu->settings.use_saves_folder),
convert_boolean(menu->settings.autodetect_rom_region),
convert_boolean(menu->settings.bgm_enabled), convert_boolean(menu->settings.bgm_enabled),
convert_boolean(menu->settings.sound_enabled), convert_boolean(menu->settings.sound_enabled),
convert_boolean(menu->settings.rumble_enabled) convert_boolean(menu->settings.rumble_enabled)