mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-25 12:06:54 +01:00
Added manual override options for save and TV type
This commit is contained in:
parent
ae37f92c7f
commit
621e50cf7b
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user