mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-12-25 01:31:51 +01:00
Merge branch 'develop' into improve-rom-info
This commit is contained in:
commit
2e8fdc2e33
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -113,7 +113,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Doxygen
|
||||
uses: mattnotmitt/doxygen-action@1.9.5
|
||||
uses: mattnotmitt/doxygen-action@v1
|
||||
with:
|
||||
doxyfile-path: './Doxyfile'
|
||||
|
||||
|
@ -26,6 +26,7 @@ An open source menu for N64 flashcarts.
|
||||
* Real Time Clock support.
|
||||
* Music playback (MP3).
|
||||
* Menu sound effects.
|
||||
* N64 ROM autoload.
|
||||
|
||||
|
||||
## Documentation
|
||||
@ -49,6 +50,9 @@ An open source menu for N64 flashcarts.
|
||||
## Experimental features
|
||||
These features are subject to change:
|
||||
|
||||
### N64 ROM autoload
|
||||
To use the autoload function, while on the `N64 ROM information` display, press the `R` button on your joypad and select the `Set ROM to autoload` option. When you restart the console, it will now only load the selected ROM rather than the menu.
|
||||
NOTE: to return to the menu, hold joypad `start` button whilst powering on the console.
|
||||
|
||||
### GamePak sprites
|
||||
To use N64 `GamePak` sprites, place `PNG` files within the `sd:/menu/boxart/` folder.
|
||||
@ -60,7 +64,7 @@ These must be `PNG` files that use the following dimensions:
|
||||
* Japanese N64 GamePak boxart sprites: 112x158
|
||||
* 64DD boxart sprites: 129x112
|
||||
|
||||
They will be loaded by directories using each character of the full 4 character Game Code (as identified in the menus ROM information).
|
||||
They will be loaded by directories using each character (case-sensitive) of the full 4 character Game Code (as identified in the menu ROM information).
|
||||
i.e. for GoldenEye NTSC USA (NGEE), this would be `sd:/menu/boxart/N/G/E/E/boxart_front.png`.
|
||||
i.e. for GoldenEye PAL (NGEP), this would be `sd:/menu/boxart/N/G/E/P/boxart_front.png`.
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9dd994151ae3f3709f1f80224e6b654aac8be6b4
|
||||
Subproject commit e93802aec7e7839710281824ce2e9e4689b3a01d
|
@ -77,6 +77,7 @@ static bool d64_has_feature (flashcart_features_t feature) {
|
||||
case FLASHCART_FEATURE_USB: return true;
|
||||
case FLASHCART_FEATURE_AUTO_CIC: return true;
|
||||
case FLASHCART_FEATURE_AUTO_REGION: return true;
|
||||
case FLASHCART_FEATURE_SAVE_WRITEBACK: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,9 @@ typedef enum {
|
||||
FLASHCART_FEATURE_USB,
|
||||
FLASHCART_FEATURE_AUTO_CIC,
|
||||
FLASHCART_FEATURE_AUTO_REGION,
|
||||
FLASHCART_FEATURE_DIAGNOSTIC_DATA,
|
||||
FLASHCART_FEATURE_BIOS_UPDATE_FROM_MENU,
|
||||
FLASHCART_FEATURE_SAVE_WRITEBACK
|
||||
} flashcart_features_t;
|
||||
|
||||
/** @brief Flashcart save type enumeration */
|
||||
|
@ -256,6 +256,8 @@ static bool sc64_has_feature (flashcart_features_t feature) {
|
||||
case FLASHCART_FEATURE_USB: return true;
|
||||
case FLASHCART_FEATURE_AUTO_CIC: return true;
|
||||
case FLASHCART_FEATURE_AUTO_REGION: return true;
|
||||
case FLASHCART_FEATURE_DIAGNOSTIC_DATA: return true;
|
||||
case FLASHCART_FEATURE_SAVE_WRITEBACK: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
2
src/libs/miniz
vendored
2
src/libs/miniz
vendored
@ -1 +1 @@
|
||||
Subproject commit 1ff82be7d67f5c2f8b5497f538eea247861e0717
|
||||
Subproject commit 35528ad769143b9ed38a95a22d460b963e39f278
|
@ -73,8 +73,8 @@ void component_background_draw (void);
|
||||
void component_file_list_draw (entry_t *list, int entries, int selected);
|
||||
|
||||
typedef struct component_context_menu {
|
||||
int count;
|
||||
int selected;
|
||||
int row_count;
|
||||
int row_selected;
|
||||
bool hide_pending;
|
||||
struct component_context_menu *parent;
|
||||
struct component_context_menu *submenu;
|
||||
|
@ -151,7 +151,7 @@ void component_main_text_draw (rdpq_align_t align, rdpq_valign_t valign, char *f
|
||||
.height = LAYOUT_ACTIONS_SEPARATOR_Y - OVERSCAN_HEIGHT - (TEXT_MARGIN_VERTICAL * 2),
|
||||
.align = align,
|
||||
.valign = valign,
|
||||
.wrap = WRAP_ELLIPSES,
|
||||
.wrap = WRAP_WORD,
|
||||
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||
},
|
||||
FNT_DEFAULT,
|
||||
|
@ -13,22 +13,22 @@ static component_context_menu_t *get_current_submenu (component_context_menu_t *
|
||||
|
||||
|
||||
void component_context_menu_init (component_context_menu_t *cm) {
|
||||
cm->selected = -1;
|
||||
cm->count = 0;
|
||||
cm->row_selected = -1;
|
||||
cm->row_count = 0;
|
||||
cm->hide_pending = false;
|
||||
cm->parent = NULL;
|
||||
for (int i = 0; (cm->list[i].text) != NULL; i++) {
|
||||
cm->count += 1;
|
||||
cm->row_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void component_context_menu_show (component_context_menu_t *cm) {
|
||||
cm->selected = 0;
|
||||
cm->row_selected = 0;
|
||||
cm->submenu = NULL;
|
||||
}
|
||||
|
||||
bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) {
|
||||
if (!cm || (cm->selected < 0)) {
|
||||
if (!cm || (cm->row_selected < 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -44,26 +44,26 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
||||
}
|
||||
sound_play_effect(SFX_EXIT);
|
||||
} else if (menu->actions.enter) {
|
||||
if (cm->list[cm->selected].submenu) {
|
||||
cm->submenu = cm->list[cm->selected].submenu;
|
||||
if (cm->list[cm->row_selected].submenu) {
|
||||
cm->submenu = cm->list[cm->row_selected].submenu;
|
||||
component_context_menu_init(cm->submenu);
|
||||
cm->submenu->selected = 0;
|
||||
cm->submenu->row_selected = 0;
|
||||
cm->submenu->parent = cm;
|
||||
} else if (cm->list[cm->selected].action) {
|
||||
cm->list[cm->selected].action(menu, cm->list[cm->selected].arg);
|
||||
} else if (cm->list[cm->row_selected].action) {
|
||||
cm->list[cm->row_selected].action(menu, cm->list[cm->row_selected].arg);
|
||||
top->hide_pending = true;
|
||||
}
|
||||
sound_play_effect(SFX_ENTER);
|
||||
} else if (menu->actions.go_up) {
|
||||
cm->selected -= 1;
|
||||
if (cm->selected < 0) {
|
||||
cm->selected = 0;
|
||||
cm->row_selected -= 1;
|
||||
if (cm->row_selected < 0) {
|
||||
cm->row_selected = 0;
|
||||
}
|
||||
sound_play_effect(SFX_CURSOR);
|
||||
} else if (menu->actions.go_down) {
|
||||
cm->selected += 1;
|
||||
if (cm->selected >= cm->count) {
|
||||
cm->selected = (cm->count - 1);
|
||||
cm->row_selected += 1;
|
||||
if (cm->row_selected >= cm->row_count) {
|
||||
cm->row_selected = (cm->row_count - 1);
|
||||
}
|
||||
sound_play_effect(SFX_CURSOR);
|
||||
}
|
||||
@ -72,7 +72,7 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
||||
}
|
||||
|
||||
void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
if (!cm || (cm->selected < 0)) {
|
||||
if (!cm || (cm->row_selected < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
NULL
|
||||
);
|
||||
|
||||
for (int i = 0; i < cm->count; i++) {
|
||||
for (int i = 0; i < cm->row_count; i++) {
|
||||
const char *text = cm->list[i].text;
|
||||
rdpq_paragraph_builder_span(text, strlen(text));
|
||||
if (cm->list[i + 1].text != NULL) {
|
||||
@ -110,7 +110,7 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
int highlight_x0 = DISPLAY_CENTER_X - (width / 2);
|
||||
int highlight_x1 = DISPLAY_CENTER_X + (width / 2);
|
||||
int highlight_height = (layout->bbox.y1 - layout->bbox.y0) / layout->nlines;
|
||||
int highlight_y = VISIBLE_AREA_Y0 + layout->bbox.y0 + ((cm->selected) * highlight_height);
|
||||
int highlight_y = VISIBLE_AREA_Y0 + layout->bbox.y0 + ((cm->row_selected) * highlight_height);
|
||||
|
||||
component_box_draw(
|
||||
highlight_x0,
|
||||
@ -126,6 +126,6 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
|
||||
if (top->hide_pending) {
|
||||
top->hide_pending = false;
|
||||
top->selected = -1;
|
||||
top->row_selected = -1;
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,12 @@ typedef struct {
|
||||
path_t *disk_path;
|
||||
disk_info_t disk_info;
|
||||
} load;
|
||||
|
||||
struct {
|
||||
bool rom_file;
|
||||
bool disk_file;
|
||||
bool emulator_file;
|
||||
} boot_pending;
|
||||
} menu_t;
|
||||
|
||||
|
||||
|
@ -14,7 +14,10 @@ static settings_t init = {
|
||||
.default_directory = "/",
|
||||
.use_saves_folder = true,
|
||||
.sound_enabled = true,
|
||||
|
||||
.rom_autoload_enabled = false,
|
||||
.rom_autoload_path = "",
|
||||
.rom_autoload_filename = "",
|
||||
|
||||
/* Beta feature flags (should always init to off) */
|
||||
.bgm_enabled = false,
|
||||
.rumble_enabled = false,
|
||||
@ -41,6 +44,10 @@ void settings_load (settings_t *settings) {
|
||||
settings->use_saves_folder = mini_get_bool(ini, "menu", "use_saves_folder", init.use_saves_folder);
|
||||
settings->sound_enabled = mini_get_bool(ini, "menu", "sound_enabled", init.sound_enabled);
|
||||
|
||||
settings->rom_autoload_enabled = mini_get_bool(ini, "menu", "autoload_rom_enabled", init.rom_autoload_enabled);
|
||||
settings->rom_autoload_path = strdup(mini_get_string(ini, "autoload", "rom_path", init.rom_autoload_path));
|
||||
settings->rom_autoload_filename = strdup(mini_get_string(ini, "autoload", "rom_filename", init.rom_autoload_filename));
|
||||
|
||||
/* 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->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled);
|
||||
@ -56,6 +63,9 @@ void settings_save (settings_t *settings) {
|
||||
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", "sound_enabled", settings->sound_enabled);
|
||||
mini_set_bool(ini, "menu", "autoload_rom_enabled", settings->rom_autoload_enabled);
|
||||
mini_set_string(ini, "autoload", "rom_path", settings->rom_autoload_path);
|
||||
mini_set_string(ini, "autoload", "rom_filename", settings->rom_autoload_filename);
|
||||
|
||||
/* Beta feature flags, they should not save until production ready! */
|
||||
// mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled);
|
||||
|
@ -30,6 +30,16 @@ typedef struct {
|
||||
|
||||
/** @brief Enable rumble feedback */
|
||||
bool rumble_enabled;
|
||||
|
||||
/** @brief Enable the ability to bypass the menu and instantly load a ROM */
|
||||
bool rom_autoload_enabled;
|
||||
|
||||
/** @brief A path to the autoloaded ROM */
|
||||
char *rom_autoload_path;
|
||||
|
||||
/** @brief A filename of the autoloaded ROM */
|
||||
char *rom_autoload_filename;
|
||||
|
||||
} settings_t;
|
||||
|
||||
|
||||
@ -40,5 +50,4 @@ void settings_load (settings_t *settings);
|
||||
/** @brief The settings to save */
|
||||
void settings_save (settings_t *settings);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,10 @@ static bool sfx_enabled = false;
|
||||
|
||||
static void sound_reconfigure (int frequency) {
|
||||
if ((frequency > 0) && (audio_get_frequency() != frequency)) {
|
||||
sound_deinit();
|
||||
if (sound_initialized) {
|
||||
mixer_close();
|
||||
audio_close();
|
||||
}
|
||||
audio_init(frequency, NUM_BUFFERS);
|
||||
mixer_init(NUM_CHANNELS);
|
||||
mp3player_mixer_init();
|
||||
@ -97,9 +100,7 @@ void sound_deinit (void) {
|
||||
}
|
||||
|
||||
void sound_poll (void) {
|
||||
if (sound_initialized && audio_can_write()) {
|
||||
short *audio_buffer = audio_write_begin();
|
||||
mixer_poll(audio_buffer, audio_get_buffer_length());
|
||||
audio_write_end();
|
||||
if (sound_initialized) {
|
||||
mixer_try_play();
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@ static char *format_file_type (char *name, bool is_directory) {
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
S_ISDIR(st.st_mode) ? "Directory" : "File",
|
||||
st.st_mode & S_IWUSR ? "" : "(Read only)",
|
||||
format_file_type(menu->browser.entry->name, S_ISDIR(st.st_mode)),
|
||||
ctime(&st.st_mtim.tv_sec)
|
||||
ctime(&st.st_mtime)
|
||||
);
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
|
@ -1,15 +1,35 @@
|
||||
#include "views.h"
|
||||
#include "../sound.h"
|
||||
#include <libcart/cart.h>
|
||||
|
||||
|
||||
static inline const char *format_boolean_type (bool bool_value) {
|
||||
return bool_value ? "Supported" : "Unsupported";
|
||||
}
|
||||
|
||||
static const char *format_cart_type () {
|
||||
switch (cart_type) {
|
||||
case CART_CI:
|
||||
return "64drive";
|
||||
|
||||
case CART_EDX:
|
||||
return "Series X EverDrive-64";
|
||||
|
||||
case CART_ED:
|
||||
return "Series V EverDrive-64";
|
||||
|
||||
case CART_SC:
|
||||
return "SummerCart64";
|
||||
|
||||
default: // Probably emulator
|
||||
return "Emulator?";
|
||||
}
|
||||
}
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,24 +59,25 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
" Virtual 64DD: %s.\n"
|
||||
" Real Time Clock: %s.\n"
|
||||
" USB Debugging: %s.\n"
|
||||
" CIC Detection: %s.\n"
|
||||
" Automatic CIC: %s.\n"
|
||||
" Region Detection: %s.\n"
|
||||
" Save Writeback: %s.\n"
|
||||
" Update from menu: %s.\n"
|
||||
"\n\n",
|
||||
"SummerCart64",
|
||||
"V?.?.?",
|
||||
format_boolean_type(true),
|
||||
format_boolean_type(true),
|
||||
format_boolean_type(true),
|
||||
format_boolean_type(true),
|
||||
format_boolean_type(true)
|
||||
format_cart_type(),
|
||||
"Not Available", // TODO get cart firmware version(s).
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_64DD)),
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_RTC)),
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_USB)),
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_AUTO_CIC)),
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_AUTO_REGION)),
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_SAVE_WRITEBACK)),
|
||||
format_boolean_type(flashcart_has_feature(FLASHCART_FEATURE_BIOS_UPDATE_FROM_MENU))
|
||||
|
||||
//TODO: display the battery and temperature information (if available).
|
||||
//format_diagnostic_data(flashcart_has_feature(FLASHCART_FEATURE_DIAGNOSTIC_DATA))
|
||||
);
|
||||
|
||||
// FIXME: Display:
|
||||
// * cart_type
|
||||
// * Firmware version
|
||||
// * supported features (flashcart_features_t)
|
||||
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_LEFT, VALIGN_TOP,
|
||||
"\n"
|
||||
|
@ -5,8 +5,7 @@
|
||||
#include "views.h"
|
||||
|
||||
|
||||
static bool load_pending;
|
||||
static bool load_rom;
|
||||
static bool load_disk_with_rom;
|
||||
static component_boxart_t *boxart;
|
||||
|
||||
|
||||
@ -31,15 +30,15 @@ static char *format_disk_region (disk_region_t region) {
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.enter) {
|
||||
load_pending = true;
|
||||
load_rom = false;
|
||||
menu->boot_pending.disk_file = true;
|
||||
load_disk_with_rom = false;
|
||||
} else if (menu->actions.options && menu->load.rom_path) {
|
||||
load_pending = true;
|
||||
load_rom = true;
|
||||
menu->boot_pending.disk_file = true;
|
||||
load_disk_with_rom = true;
|
||||
sound_play_effect(SFX_SETTING);
|
||||
} else if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +47,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_background_draw();
|
||||
|
||||
if (load_pending) {
|
||||
if (menu->boot_pending.disk_file) {
|
||||
component_loader_draw(0.0f);
|
||||
} else {
|
||||
component_layout_draw();
|
||||
@ -119,7 +118,7 @@ static void draw_progress (float progress) {
|
||||
static void load (menu_t *menu) {
|
||||
cart_load_err_t err;
|
||||
|
||||
if (menu->load.rom_path && load_rom) {
|
||||
if (menu->load.rom_path && load_disk_with_rom) {
|
||||
err = cart_load_n64_rom_and_save(menu, draw_progress);
|
||||
if (err != CART_LOAD_OK) {
|
||||
menu_show_error(menu, cart_load_convert_error_message(err));
|
||||
@ -135,7 +134,7 @@ static void load (menu_t *menu) {
|
||||
|
||||
menu->next_mode = MENU_MODE_BOOT;
|
||||
|
||||
if (load_rom) {
|
||||
if (load_disk_with_rom) {
|
||||
menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
|
||||
menu->boot_params->detect_cic_seed = rom_info_get_cic_seed(&menu->load.rom_info, &menu->boot_params->cic_seed);
|
||||
switch (rom_info_get_tv_type(&menu->load.rom_info)) {
|
||||
@ -163,7 +162,7 @@ void view_load_disk_init (menu_t *menu) {
|
||||
menu->load.disk_path = NULL;
|
||||
}
|
||||
|
||||
load_pending = false;
|
||||
menu->boot_pending.disk_file = false;
|
||||
|
||||
menu->load.disk_path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
|
||||
|
||||
@ -180,8 +179,8 @@ void view_load_disk_display (menu_t *menu, surface_t *display) {
|
||||
|
||||
draw(menu, display);
|
||||
|
||||
if (load_pending) {
|
||||
load_pending = false;
|
||||
if (menu->boot_pending.disk_file) {
|
||||
menu->boot_pending.disk_file = false;
|
||||
load(menu);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ static const char *emu_gameboy_rom_extensions[] = { "gb", NULL };
|
||||
static const char *emu_gameboy_color_rom_extensions[] = { "gbc", NULL };
|
||||
static const char *emu_sega_8bit_rom_extensions[] = { "sms", "gg", "sg", NULL };
|
||||
|
||||
static bool load_pending;
|
||||
static cart_load_emu_type_t emu_type;
|
||||
|
||||
static char *format_emulator_name (cart_load_emu_type_t emulator_info) {
|
||||
@ -34,10 +33,10 @@ static char *format_emulator_name (cart_load_emu_type_t emulator_info) {
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.enter) {
|
||||
load_pending = true;
|
||||
menu->boot_pending.emulator_file = true;
|
||||
} else if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +45,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_background_draw();
|
||||
|
||||
if (load_pending) {
|
||||
if (menu->boot_pending.emulator_file) {
|
||||
component_loader_draw(0.0f);
|
||||
} else {
|
||||
component_layout_draw();
|
||||
@ -107,7 +106,7 @@ static void load (menu_t *menu) {
|
||||
|
||||
|
||||
void view_load_emulator_init (menu_t *menu) {
|
||||
load_pending = false;
|
||||
menu->boot_pending.emulator_file = false;
|
||||
|
||||
path_t *path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
|
||||
|
||||
@ -133,8 +132,8 @@ void view_load_emulator_display (menu_t *menu, surface_t *display) {
|
||||
|
||||
draw(menu, display);
|
||||
|
||||
if (load_pending) {
|
||||
load_pending = false;
|
||||
if (menu->boot_pending.emulator_file) {
|
||||
menu->boot_pending.emulator_file = false;
|
||||
load(menu);
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
#include "boot/boot.h"
|
||||
#include "../sound.h"
|
||||
#include "views.h"
|
||||
#include <string.h>
|
||||
#include "utils/fs.h"
|
||||
|
||||
static bool show_extra_info_message = false;
|
||||
static bool load_pending;
|
||||
static component_boxart_t *boxart;
|
||||
|
||||
|
||||
static char *convert_error_message (rom_err_t err) {
|
||||
switch (err) {
|
||||
case ROM_ERR_LOAD_IO: return "I/O error during loading ROM information and/or options";
|
||||
@ -153,6 +153,17 @@ static void set_tv_type (menu_t *menu, void *arg) {
|
||||
menu->browser.reload = true;
|
||||
}
|
||||
|
||||
static void set_autoload_type (menu_t *menu, void *arg) {
|
||||
free(menu->settings.rom_autoload_path);
|
||||
menu->settings.rom_autoload_path = strdup(strip_fs_prefix(path_get(menu->browser.directory)));
|
||||
free(menu->settings.rom_autoload_filename);
|
||||
menu->settings.rom_autoload_filename = strdup(menu->browser.entry->name);
|
||||
// FIXME: add a confirmation box here! (press start on reboot)
|
||||
menu->settings.rom_autoload_enabled = true;
|
||||
settings_save(&menu->settings);
|
||||
menu->browser.reload = true;
|
||||
}
|
||||
|
||||
static component_context_menu_t set_cic_type_context_menu = { .list = {
|
||||
{.text = "Automatic", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_AUTOMATIC) },
|
||||
{.text = "CIC-6101", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_6101) },
|
||||
@ -195,6 +206,7 @@ static component_context_menu_t options_context_menu = { .list = {
|
||||
{ .text = "Set CIC Type", .submenu = &set_cic_type_context_menu },
|
||||
{ .text = "Set Save Type", .submenu = &set_save_type_context_menu },
|
||||
{ .text = "Set TV Type", .submenu = &set_tv_type_context_menu },
|
||||
{ .text = "Set ROM to autoload", .action = set_autoload_type },
|
||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||
}};
|
||||
|
||||
@ -204,10 +216,10 @@ static void process (menu_t *menu) {
|
||||
}
|
||||
|
||||
if (menu->actions.enter) {
|
||||
load_pending = true;
|
||||
menu->boot_pending.rom_file = true;
|
||||
} else if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
} else if (menu->actions.options) {
|
||||
component_context_menu_show(&options_context_menu);
|
||||
sound_play_effect(SFX_SETTING);
|
||||
@ -226,7 +238,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_background_draw();
|
||||
|
||||
if (load_pending) {
|
||||
if (menu->boot_pending.rom_file) {
|
||||
component_loader_draw(0.0f);
|
||||
} else {
|
||||
component_layout_draw();
|
||||
@ -354,14 +366,14 @@ static void deinit (void) {
|
||||
|
||||
|
||||
void view_load_rom_init (menu_t *menu) {
|
||||
load_pending = false;
|
||||
if (!menu->settings.rom_autoload_enabled) {
|
||||
if (menu->load.rom_path) {
|
||||
path_free(menu->load.rom_path);
|
||||
}
|
||||
|
||||
if (menu->load.rom_path) {
|
||||
path_free(menu->load.rom_path);
|
||||
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(menu->load.rom_path, &menu->load.rom_info);
|
||||
if (err != ROM_OK) {
|
||||
path_free(menu->load.rom_path);
|
||||
@ -370,9 +382,10 @@ void view_load_rom_init (menu_t *menu) {
|
||||
return;
|
||||
}
|
||||
|
||||
boxart = component_boxart_init(menu->storage_prefix, menu->load.rom_info.game_code, IMAGE_BOXART_FRONT);
|
||||
|
||||
component_context_menu_init(&options_context_menu);
|
||||
if (!menu->settings.rom_autoload_enabled) {
|
||||
boxart = component_boxart_init(menu->storage_prefix, menu->load.rom_info.game_code, IMAGE_BOXART_FRONT);
|
||||
component_context_menu_init(&options_context_menu);
|
||||
}
|
||||
}
|
||||
|
||||
void view_load_rom_display (menu_t *menu, surface_t *display) {
|
||||
@ -380,8 +393,8 @@ void view_load_rom_display (menu_t *menu, surface_t *display) {
|
||||
|
||||
draw(menu, display);
|
||||
|
||||
if (load_pending) {
|
||||
load_pending = false;
|
||||
if (menu->boot_pending.rom_file) {
|
||||
menu->boot_pending.rom_file = false;
|
||||
load(menu);
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,8 @@ static void process (menu_t *menu) {
|
||||
if (err != MP3PLAYER_OK) {
|
||||
menu_show_error(menu, convert_error_message(err));
|
||||
} else if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
} else if (menu->actions.enter) {
|
||||
err = mp3player_toggle();
|
||||
if (err != MP3PLAYER_OK) {
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,8 +114,8 @@ static void process (menu_t *menu) {
|
||||
component_context_menu_show(&options_context_menu);
|
||||
sound_play_effect(SFX_SETTING);
|
||||
} else if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +136,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
ALIGN_LEFT, VALIGN_TOP,
|
||||
"\n\n"
|
||||
" Default Directory : %s\n\n"
|
||||
" Autoload ROM : %s\n"
|
||||
"To change the following menu settings, press 'A':\n"
|
||||
"* PAL60 Mode : %s\n"
|
||||
" Show Hidden Files : %s\n"
|
||||
@ -145,9 +146,11 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
" Background Music : %s\n"
|
||||
" Rumble Feedback : %s\n"
|
||||
#endif
|
||||
"Note: Certain settings have the following caveats:\n\n"
|
||||
"* Requires a flashcart reboot.\n",
|
||||
"\n\n"
|
||||
"Note: Certain settings have the following caveats:\n"
|
||||
"* Requires rebooting the N64 Console.\n",
|
||||
menu->settings.default_directory,
|
||||
format_switch(menu->settings.rom_autoload_enabled),
|
||||
format_switch(menu->settings.pal60_enabled),
|
||||
format_switch(menu->settings.show_protected_entries),
|
||||
format_switch(menu->settings.use_saves_folder),
|
||||
|
@ -9,6 +9,27 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
|
||||
void view_startup_init (menu_t *menu) {
|
||||
// FIXME: rather than use a controller button, would it be better to use the cart button?
|
||||
JOYPAD_PORT_FOREACH (port) {
|
||||
joypad_poll();
|
||||
joypad_buttons_t b_held = joypad_get_buttons_held(port);
|
||||
|
||||
if (menu->settings.rom_autoload_enabled && b_held.start) {
|
||||
menu->settings.rom_autoload_enabled = false;
|
||||
menu->settings.rom_autoload_path = "";
|
||||
menu->settings.rom_autoload_filename = "";
|
||||
settings_save(&menu->settings);
|
||||
}
|
||||
}
|
||||
if (menu->settings.rom_autoload_enabled) {
|
||||
menu->browser.directory = path_init(menu->storage_prefix, menu->settings.rom_autoload_path);
|
||||
menu->load.rom_path = path_clone_push(menu->browser.directory, menu->settings.rom_autoload_filename);
|
||||
menu->boot_pending.rom_file = true;
|
||||
menu->next_mode = MENU_MODE_LOAD_ROM;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,8 @@ static void process (menu_t *menu) {
|
||||
}
|
||||
|
||||
if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,8 @@ static void perform_vertical_scroll (int lines) {
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
sound_play_effect(SFX_EXIT);
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
} else if (text) {
|
||||
if (menu->actions.go_up) {
|
||||
perform_vertical_scroll(menu->actions.go_fast ? -10 : -1);
|
||||
|
Loading…
Reference in New Issue
Block a user