mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-28 21:44:15 +01:00
Merge branch 'main' into ed64-basic
This commit is contained in:
commit
4796c52a49
@ -20,9 +20,7 @@ static void actions_clear (menu_t *menu) {
|
||||
menu->actions.enter = false;
|
||||
menu->actions.back = false;
|
||||
menu->actions.options = false;
|
||||
menu->actions.system_info = false;
|
||||
menu->actions.settings = false;
|
||||
menu->actions.credits = false;
|
||||
}
|
||||
|
||||
static void actions_update_direction (menu_t *menu) {
|
||||
@ -91,11 +89,7 @@ static void actions_update_buttons (menu_t *menu) {
|
||||
menu->actions.back = true;
|
||||
} else if (pressed.r) {
|
||||
menu->actions.options = true;
|
||||
} else if (pressed.z) {
|
||||
menu->actions.system_info = true;
|
||||
} else if (pressed.start) {
|
||||
menu->actions.credits = true;
|
||||
} else if (pressed.l) {
|
||||
menu->actions.settings = true;
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ static bool create_saves_subdirectory (path_t *path) {
|
||||
return error;
|
||||
}
|
||||
|
||||
static flashcart_save_type_t convert_save_type (rom_info_t *info) {
|
||||
switch (info->save_type) {
|
||||
static flashcart_save_type_t convert_save_type (rom_save_type_t save_type) {
|
||||
switch (save_type) {
|
||||
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_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);
|
||||
|
||||
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);
|
||||
if (menu->flashcart_err != FLASHCART_OK) {
|
||||
|
@ -37,13 +37,16 @@ void component_background_draw (void);
|
||||
|
||||
void component_file_list_draw (entry_t *list, int entries, int selected);
|
||||
|
||||
typedef struct {
|
||||
typedef struct component_context_menu {
|
||||
int count;
|
||||
int selected;
|
||||
bool hide_pending;
|
||||
struct component_context_menu *parent;
|
||||
struct component_context_menu *submenu;
|
||||
struct {
|
||||
const char *text;
|
||||
void (*action) (menu_t *menu);
|
||||
struct component_context_menu *submenu;
|
||||
} list[];
|
||||
} component_context_menu_t;
|
||||
|
||||
|
@ -3,10 +3,19 @@
|
||||
#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) {
|
||||
cm->selected = -1;
|
||||
cm->count = 0;
|
||||
cm->hide_pending = false;
|
||||
cm->parent = NULL;
|
||||
for (int i = 0; (cm->list[i].text) != NULL; i++) {
|
||||
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) {
|
||||
cm->selected = 0;
|
||||
cm->submenu = NULL;
|
||||
}
|
||||
|
||||
bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) {
|
||||
@ -21,12 +31,25 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
||||
return false;
|
||||
}
|
||||
|
||||
component_context_menu_t *top = cm;
|
||||
|
||||
cm = get_current_submenu(cm);
|
||||
|
||||
if (menu->actions.back) {
|
||||
if (cm->parent) {
|
||||
cm->parent->submenu = NULL;
|
||||
} else {
|
||||
cm->hide_pending = true;
|
||||
}
|
||||
} else if (menu->actions.enter) {
|
||||
if (cm->list[cm->selected].action) {
|
||||
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);
|
||||
cm->hide_pending = true;
|
||||
top->hide_pending = true;
|
||||
}
|
||||
} else if (menu->actions.go_up) {
|
||||
cm->selected -= 1;
|
||||
@ -48,6 +71,10 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
return;
|
||||
}
|
||||
|
||||
component_context_menu_t *top = cm;
|
||||
|
||||
cm = get_current_submenu(cm);
|
||||
|
||||
rdpq_paragraph_builder_begin(
|
||||
&(rdpq_textparms_t) {
|
||||
.width = VISIBLE_AREA_WIDTH,
|
||||
@ -91,8 +118,8 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
|
||||
rdpq_paragraph_free(layout);
|
||||
|
||||
if (cm->hide_pending) {
|
||||
cm->hide_pending = false;
|
||||
cm->selected = -1;
|
||||
if (top->hide_pending) {
|
||||
top->hide_pending = false;
|
||||
top->selected = -1;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ static void menu_init (boot_params_t *boot_params) {
|
||||
char *init_directory = default_directory_exists ? menu->settings.default_directory : "";
|
||||
|
||||
menu->browser.valid = false;
|
||||
menu->browser.reload = false;
|
||||
menu->browser.directory = path_init("sd:/", init_directory);
|
||||
|
||||
menu->load.rom_path = NULL;
|
||||
|
@ -83,13 +83,12 @@ typedef struct {
|
||||
bool enter;
|
||||
bool back;
|
||||
bool options;
|
||||
bool system_info;
|
||||
bool settings;
|
||||
bool credits;
|
||||
} actions;
|
||||
|
||||
struct {
|
||||
bool valid;
|
||||
bool reload;
|
||||
path_t *directory;
|
||||
entry_t list[BROWSER_LIST_SIZE];
|
||||
int entries;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <fatfs/ff.h>
|
||||
#include <mini.c/src/mini.h>
|
||||
|
||||
#include "rom_info.h"
|
||||
#include "utils/fs.h"
|
||||
@ -121,7 +122,7 @@ typedef struct {
|
||||
// Matched game metadata
|
||||
struct {
|
||||
// Save type (only cartridge save types)
|
||||
save_type_t save;
|
||||
rom_save_type_t save;
|
||||
|
||||
// Supported features
|
||||
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) {
|
||||
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->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.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;
|
||||
UINT br;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
load_overrides(path, rom_info);
|
||||
|
||||
return ROM_OK;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/cic.h"
|
||||
#include "path.h"
|
||||
|
||||
|
||||
/** @brief ROM error enumeration. */
|
||||
typedef enum {
|
||||
@ -100,7 +102,16 @@ typedef enum {
|
||||
SAVE_TYPE_SRAM_128K,
|
||||
SAVE_TYPE_FLASHRAM,
|
||||
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. */
|
||||
typedef enum {
|
||||
@ -156,7 +167,17 @@ typedef struct {
|
||||
cic_type_t cic_type;
|
||||
|
||||
/** @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. */
|
||||
struct {
|
||||
@ -172,7 +193,11 @@ typedef struct {
|
||||
} 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
|
||||
|
@ -4,16 +4,17 @@
|
||||
#include "settings.h"
|
||||
#include "utils/fs.h"
|
||||
|
||||
|
||||
#ifndef SETTINGS_FILE_PATH
|
||||
#define SETTINGS_FILE_PATH "sd:/menu/config.ini"
|
||||
#endif
|
||||
|
||||
|
||||
static settings_t init = {
|
||||
.pal60_enabled = false,
|
||||
.hidden_files_enabled = false,
|
||||
.default_directory = "/",
|
||||
.use_saves_folder = true,
|
||||
.autodetect_rom_region = true,
|
||||
|
||||
/* Beta feature flags (should always init to off) */
|
||||
.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->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->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 */
|
||||
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->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled);
|
||||
|
||||
|
||||
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_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", "autodetect_rom_region", settings->autodetect_rom_region);
|
||||
|
||||
/* Beta feature flags, they should not save until production ready! */
|
||||
// mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled);
|
||||
|
@ -22,9 +22,6 @@ typedef struct {
|
||||
/** @brief Put saves into separate directory */
|
||||
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 */
|
||||
bool bgm_enabled;
|
||||
|
||||
@ -33,9 +30,9 @@ typedef struct {
|
||||
|
||||
/** @brief Enable rumble feedback */
|
||||
bool rumble_enabled;
|
||||
|
||||
} settings_t;
|
||||
|
||||
|
||||
/** @brief The settings to load */
|
||||
void settings_load (settings_t *settings);
|
||||
/** @brief The settings to save */
|
||||
|
@ -228,11 +228,36 @@ static component_context_menu_t entry_context_menu = {
|
||||
}
|
||||
};
|
||||
|
||||
static void edit_settings (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_SETTINGS_EDITOR;
|
||||
}
|
||||
|
||||
static void show_system_info (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_SYSTEM_INFO;
|
||||
}
|
||||
|
||||
static void show_credits (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_CREDITS;
|
||||
}
|
||||
|
||||
static component_context_menu_t settings_context_menu = {
|
||||
.list = {
|
||||
{ .text = "Edit settings", .action = edit_settings },
|
||||
{ .text = "Show system info", .action = show_system_info },
|
||||
{ .text = "Show credits", .action = show_credits },
|
||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||
}
|
||||
};
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (component_context_menu_process(menu, &entry_context_menu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (component_context_menu_process(menu, &settings_context_menu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int scroll_speed = menu->actions.go_fast ? 10 : 1;
|
||||
|
||||
if (menu->browser.entries > 1) {
|
||||
@ -284,12 +309,8 @@ static void process (menu_t *menu) {
|
||||
}
|
||||
} else if (menu->actions.options && menu->browser.entry) {
|
||||
component_context_menu_show(&entry_context_menu);
|
||||
} else if (menu->actions.system_info) {
|
||||
menu->next_mode = MENU_MODE_SYSTEM_INFO;
|
||||
} else if (menu->actions.credits) {
|
||||
menu->next_mode = MENU_MODE_CREDITS;
|
||||
} else if (menu->actions.settings) {
|
||||
menu->next_mode = MENU_MODE_SETTINGS_EDITOR;
|
||||
component_context_menu_show(&settings_context_menu);
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,15 +347,15 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_RIGHT, VALIGN_TOP,
|
||||
"%s\n"
|
||||
"L: Settings",
|
||||
menu->browser.entries == 0 ? "" : "R: Options"
|
||||
"Start: Settings\n"
|
||||
"^%02XR: Options^00",
|
||||
menu->browser.entries == 0 ? STL_UNKNOWN : STL_DEFAULT
|
||||
);
|
||||
|
||||
if (menu->current_time >= 0) {
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_CENTER, VALIGN_TOP,
|
||||
"Z: System Info | Start: Credits\n"
|
||||
"\n"
|
||||
"%s",
|
||||
ctime(&menu->current_time)
|
||||
);
|
||||
@ -342,6 +363,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_context_menu_draw(&entry_context_menu);
|
||||
|
||||
component_context_menu_draw(&settings_context_menu);
|
||||
|
||||
rdpq_detach_show();
|
||||
}
|
||||
|
||||
@ -349,6 +372,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
void view_browser_init (menu_t *menu) {
|
||||
if (!menu->browser.valid) {
|
||||
component_context_menu_init(&entry_context_menu);
|
||||
component_context_menu_init(&settings_context_menu);
|
||||
if (load_directory(menu)) {
|
||||
path_free(menu->browser.directory);
|
||||
menu->browser.directory = path_init("sd:/", "");
|
||||
@ -357,6 +381,20 @@ void view_browser_init (menu_t *menu) {
|
||||
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) {
|
||||
|
@ -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) {
|
||||
case SAVE_TYPE_NONE: return "None";
|
||||
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) {
|
||||
switch (expansion_pak_info) {
|
||||
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) {
|
||||
// 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 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 (menu_t *menu, rom_save_type_t save_type) {
|
||||
rom_info_override_save_type(menu->load.rom_path, &menu->load.rom_info, save_type);
|
||||
menu->browser.reload = true;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (component_context_menu_process(menu, &options_context_menu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (menu->actions.enter) {
|
||||
load_pending = true;
|
||||
} else if (menu->actions.back) {
|
||||
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"
|
||||
" Check code: 0x%016llX\n"
|
||||
" Save type: %s\n"
|
||||
" TV type: %s\n"
|
||||
" Expansion PAK: %s\n"
|
||||
"\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),
|
||||
menu->load.rom_info.version,
|
||||
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_cic_type(menu->load.rom_info.cic_type),
|
||||
menu->load.rom_info.boot_address,
|
||||
@ -210,7 +242,15 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
"B: Exit"
|
||||
);
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_RIGHT, VALIGN_TOP,
|
||||
"\n"
|
||||
"R: Options"
|
||||
);
|
||||
|
||||
component_boxart_draw(boxart);
|
||||
|
||||
component_context_menu_draw(&options_context_menu);
|
||||
}
|
||||
|
||||
rdpq_detach_show();
|
||||
@ -239,14 +279,14 @@ static void load (menu_t *menu) {
|
||||
}
|
||||
|
||||
menu->next_mode = MENU_MODE_BOOT;
|
||||
|
||||
menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
|
||||
menu->boot_params->detect_cic_seed = true;
|
||||
|
||||
if (menu->settings.autodetect_rom_region) {
|
||||
menu->boot_params->tv_type = determine_tv_boot_type(menu->load.rom_info.destination_code);
|
||||
}
|
||||
else {
|
||||
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
|
||||
switch(rom_info_get_tv_type(&menu->load.rom_info)) {
|
||||
case ROM_TV_TYPE_PAL: menu->boot_params->tv_type = BOOT_TV_TYPE_PAL; break;
|
||||
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;
|
||||
default: menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
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) {
|
||||
menu_show_error(menu, convert_error_message(err));
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -35,7 +35,6 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
"hidden_files_enabled: %s\n"
|
||||
"default_directory: %s\n"
|
||||
"use_saves_folder: %s\n"
|
||||
"autodetect_rom_region: %s\n"
|
||||
"bgm_enabled: %s\n"
|
||||
"sound_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),
|
||||
menu->settings.default_directory,
|
||||
convert_boolean(menu->settings.use_saves_folder),
|
||||
convert_boolean(menu->settings.autodetect_rom_region),
|
||||
convert_boolean(menu->settings.bgm_enabled),
|
||||
convert_boolean(menu->settings.sound_enabled),
|
||||
convert_boolean(menu->settings.rumble_enabled)
|
||||
|
Loading…
Reference in New Issue
Block a user