mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-25 12:06:54 +01:00
Merge branch 'main' into develop-gdb
This commit is contained in:
commit
930e287a08
10
Makefile
10
Makefile
@ -8,7 +8,8 @@ FILESYSTEM_DIR = filesystem
|
|||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
OUTPUT_DIR = output
|
OUTPUT_DIR = output
|
||||||
|
|
||||||
FLAGS += -DMENU_VERSION=\"0.0.1.$(shell date +%Y-%m-%dT%H:%M:%SZ).ALPHA\"
|
MENU_VERSION ?= "Rolling release"
|
||||||
|
BUILD_TIMESTAMP = "$(shell TZ='UTC' date "+%Y-%m-%d %H:%M:%S %:z")"
|
||||||
|
|
||||||
include $(N64_INST)/include/n64.mk
|
include $(N64_INST)/include/n64.mk
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ SRCS = \
|
|||||||
menu/views/fault.c \
|
menu/views/fault.c \
|
||||||
menu/views/file_info.c \
|
menu/views/file_info.c \
|
||||||
menu/views/image_viewer.c \
|
menu/views/image_viewer.c \
|
||||||
|
menu/views/text_viewer.c \
|
||||||
menu/views/load_disk.c \
|
menu/views/load_disk.c \
|
||||||
menu/views/load_emulator.c \
|
menu/views/load_emulator.c \
|
||||||
menu/views/load_rom.c \
|
menu/views/load_rom.c \
|
||||||
@ -63,6 +65,7 @@ SRCS = \
|
|||||||
menu/views/system_info.c \
|
menu/views/system_info.c \
|
||||||
menu/views/settings_editor.c \
|
menu/views/settings_editor.c \
|
||||||
menu/views/rtc.c \
|
menu/views/rtc.c \
|
||||||
|
menu/views/flashcart_info.c \
|
||||||
utils/fs.c
|
utils/fs.c
|
||||||
|
|
||||||
FONTS = \
|
FONTS = \
|
||||||
@ -88,6 +91,9 @@ $(FILESYSTEM_DIR)/%.font64: $(ASSETS_DIR)/%.ttf
|
|||||||
|
|
||||||
$(BUILD_DIR)/$(PROJECT_NAME).dfs: $(FILESYSTEM)
|
$(BUILD_DIR)/$(PROJECT_NAME).dfs: $(FILESYSTEM)
|
||||||
|
|
||||||
|
$(BUILD_DIR)/menu/views/credits.o: .FORCE
|
||||||
|
$(BUILD_DIR)/menu/views/credits.o: FLAGS+=-DMENU_VERSION=\"$(MENU_VERSION)\" -DBUILD_TIMESTAMP=\"$(BUILD_TIMESTAMP)\"
|
||||||
|
|
||||||
$(BUILD_DIR)/$(PROJECT_NAME).elf: $(OBJS)
|
$(BUILD_DIR)/$(PROJECT_NAME).elf: $(OBJS)
|
||||||
|
|
||||||
disassembly: $(BUILD_DIR)/$(PROJECT_NAME).elf
|
disassembly: $(BUILD_DIR)/$(PROJECT_NAME).elf
|
||||||
@ -149,4 +155,6 @@ debug-gdb: $(OUTPUT_DIR)/$(PROJECT_NAME).n64
|
|||||||
# test:
|
# test:
|
||||||
# TODO: run tests
|
# TODO: run tests
|
||||||
|
|
||||||
|
.FORCE:
|
||||||
|
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 6323128d72fdf32dfaa134f40191ba72e5527076
|
Subproject commit 185c4a34f265c90d027f4054024cff1675529d7f
|
@ -102,7 +102,7 @@ cic_type_t cic_detect (uint8_t *ipl3) {
|
|||||||
switch (cic_calculate_ipl3_checksum(ipl3, 0x3F)) {
|
switch (cic_calculate_ipl3_checksum(ipl3, 0x3F)) {
|
||||||
case 0x45CC73EE317AULL: return CIC_6101; // 6101
|
case 0x45CC73EE317AULL: return CIC_6101; // 6101
|
||||||
case 0x44160EC5D9AFULL: return CIC_7102; // 7102
|
case 0x44160EC5D9AFULL: return CIC_7102; // 7102
|
||||||
case 0xA536C0F1D859ULL: return CIC_6102_7101; // 6102 / 7101
|
case 0xA536C0F1D859ULL: return CIC_x102; // 6102 / 7101
|
||||||
}
|
}
|
||||||
switch (cic_calculate_ipl3_checksum(ipl3, 0x78)) {
|
switch (cic_calculate_ipl3_checksum(ipl3, 0x78)) {
|
||||||
case 0x586FD4709867ULL: return CIC_x103; // 6103 / 7103
|
case 0x586FD4709867ULL: return CIC_x103; // 6103 / 7103
|
||||||
@ -133,7 +133,7 @@ uint8_t cic_get_seed (cic_type_t cic_type) {
|
|||||||
case CIC_5167: return 0xDD;
|
case CIC_5167: return 0xDD;
|
||||||
case CIC_6101: return 0x3F;
|
case CIC_6101: return 0x3F;
|
||||||
case CIC_7102: return 0x3F;
|
case CIC_7102: return 0x3F;
|
||||||
case CIC_6102_7101: return 0x3F;
|
case CIC_x102: return 0x3F;
|
||||||
case CIC_x103: return 0x78;
|
case CIC_x103: return 0x78;
|
||||||
case CIC_x105: return 0x91;
|
case CIC_x105: return 0x91;
|
||||||
case CIC_x106: return 0x85;
|
case CIC_x106: return 0x85;
|
||||||
|
@ -13,7 +13,7 @@ typedef enum {
|
|||||||
CIC_5167,
|
CIC_5167,
|
||||||
CIC_6101,
|
CIC_6101,
|
||||||
CIC_7102,
|
CIC_7102,
|
||||||
CIC_6102_7101,
|
CIC_x102,
|
||||||
CIC_x103,
|
CIC_x103,
|
||||||
CIC_x105,
|
CIC_x105,
|
||||||
CIC_x106,
|
CIC_x106,
|
||||||
|
@ -73,6 +73,8 @@ static flashcart_err_t d64_deinit (void) {
|
|||||||
static bool d64_has_feature (flashcart_features_t feature) {
|
static bool d64_has_feature (flashcart_features_t feature) {
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case FLASHCART_FEATURE_64DD: return false;
|
case FLASHCART_FEATURE_64DD: return false;
|
||||||
|
case FLASHCART_FEATURE_RTC: return true;
|
||||||
|
case FLASHCART_FEATURE_USB: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +98,7 @@ static flashcart_err_t d64_load_rom (char *rom_path, flashcart_progress_callback
|
|||||||
|
|
||||||
size_t sdram_size = MiB(64);
|
size_t sdram_size = MiB(64);
|
||||||
|
|
||||||
size_t chunk_size = MiB(1);
|
size_t chunk_size = KiB(128);
|
||||||
for (int offset = 0; offset < sdram_size; offset += chunk_size) {
|
for (int offset = 0; offset < sdram_size; offset += chunk_size) {
|
||||||
size_t block_size = MIN(sdram_size - offset, chunk_size);
|
size_t block_size = MIN(sdram_size - offset, chunk_size);
|
||||||
if (f_read(&fil, (void *) (ROM_ADDRESS + offset), block_size, &br) != FR_OK) {
|
if (f_read(&fil, (void *) (ROM_ADDRESS + offset), block_size, &br) != FR_OK) {
|
||||||
|
@ -27,6 +27,8 @@ typedef enum {
|
|||||||
/** @brief List of optional supported flashcart features */
|
/** @brief List of optional supported flashcart features */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FLASHCART_FEATURE_64DD,
|
FLASHCART_FEATURE_64DD,
|
||||||
|
FLASHCART_FEATURE_RTC,
|
||||||
|
FLASHCART_FEATURE_USB,
|
||||||
} flashcart_features_t;
|
} flashcart_features_t;
|
||||||
|
|
||||||
/** @brief Flashcart save type enumeration */
|
/** @brief Flashcart save type enumeration */
|
||||||
|
@ -260,6 +260,8 @@ static flashcart_err_t sc64_deinit (void) {
|
|||||||
static bool sc64_has_feature (flashcart_features_t feature) {
|
static bool sc64_has_feature (flashcart_features_t feature) {
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case FLASHCART_FEATURE_64DD: return true;
|
case FLASHCART_FEATURE_64DD: return true;
|
||||||
|
case FLASHCART_FEATURE_RTC: return true;
|
||||||
|
case FLASHCART_FEATURE_USB: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,7 +290,7 @@ static flashcart_err_t sc64_load_rom (char *rom_path, flashcart_progress_callbac
|
|||||||
size_t shadow_size = shadow_enabled ? MIN(rom_size - sdram_size, KiB(128)) : 0;
|
size_t shadow_size = shadow_enabled ? MIN(rom_size - sdram_size, KiB(128)) : 0;
|
||||||
size_t extended_size = extended_enabled ? rom_size - MiB(64) : 0;
|
size_t extended_size = extended_enabled ? rom_size - MiB(64) : 0;
|
||||||
|
|
||||||
size_t chunk_size = MiB(1);
|
size_t chunk_size = KiB(128);
|
||||||
for (int offset = 0; offset < sdram_size; offset += chunk_size) {
|
for (int offset = 0; offset < sdram_size; offset += chunk_size) {
|
||||||
size_t block_size = MIN(sdram_size - offset, chunk_size);
|
size_t block_size = MIN(sdram_size - offset, chunk_size);
|
||||||
if (f_read(&fil, (void *) (ROM_ADDRESS + offset), block_size, &br) != FR_OK) {
|
if (f_read(&fil, (void *) (ROM_ADDRESS + offset), block_size, &br) != FR_OK) {
|
||||||
@ -450,7 +452,7 @@ static flashcart_err_t sc64_load_64dd_ipl (char *ipl_path, flashcart_progress_ca
|
|||||||
return FLASHCART_ERR_LOAD;
|
return FLASHCART_ERR_LOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t chunk_size = KiB(256);
|
size_t chunk_size = KiB(128);
|
||||||
for (int offset = 0; offset < ipl_size; offset += chunk_size) {
|
for (int offset = 0; offset < ipl_size; offset += chunk_size) {
|
||||||
size_t block_size = MIN(ipl_size - offset, chunk_size);
|
size_t block_size = MIN(ipl_size - offset, chunk_size);
|
||||||
if (f_read(&fil, (void *) (IPL_ADDRESS + offset), block_size, &br) != FR_OK) {
|
if (f_read(&fil, (void *) (IPL_ADDRESS + offset), block_size, &br) != FR_OK) {
|
||||||
|
@ -45,7 +45,8 @@ typedef struct component_context_menu {
|
|||||||
struct component_context_menu *submenu;
|
struct component_context_menu *submenu;
|
||||||
struct {
|
struct {
|
||||||
const char *text;
|
const char *text;
|
||||||
void (*action) (menu_t *menu);
|
void (*action) (menu_t *menu, void *arg);
|
||||||
|
void *arg;
|
||||||
struct component_context_menu *submenu;
|
struct component_context_menu *submenu;
|
||||||
} list[];
|
} list[];
|
||||||
} component_context_menu_t;
|
} component_context_menu_t;
|
||||||
|
@ -48,7 +48,7 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
|||||||
cm->submenu->selected = 0;
|
cm->submenu->selected = 0;
|
||||||
cm->submenu->parent = cm;
|
cm->submenu->parent = cm;
|
||||||
} else if (cm->list[cm->selected].action) {
|
} else if (cm->list[cm->selected].action) {
|
||||||
cm->list[cm->selected].action(menu);
|
cm->list[cm->selected].action(menu, cm->list[cm->selected].arg);
|
||||||
top->hide_pending = true;
|
top->hide_pending = true;
|
||||||
}
|
}
|
||||||
} else if (menu->actions.go_up) {
|
} else if (menu->actions.go_up) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "views/views.h"
|
#include "views/views.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MENU_DIRECTORY "sd:/menu"
|
||||||
#define CACHE_DIRECTORY "sd:/menu/cache"
|
#define CACHE_DIRECTORY "sd:/menu/cache"
|
||||||
#define BACKGROUND_CACHE "sd:/menu/cache/background.data"
|
#define BACKGROUND_CACHE "sd:/menu/cache/background.data"
|
||||||
|
|
||||||
@ -77,6 +78,8 @@ static void menu_init (boot_params_t *boot_params) {
|
|||||||
|
|
||||||
menu->error_message = NULL;
|
menu->error_message = NULL;
|
||||||
|
|
||||||
|
directory_create(MENU_DIRECTORY);
|
||||||
|
|
||||||
settings_load(&menu->settings);
|
settings_load(&menu->settings);
|
||||||
|
|
||||||
directory_create(CACHE_DIRECTORY);
|
directory_create(CACHE_DIRECTORY);
|
||||||
@ -133,30 +136,41 @@ static void menu_deinit (menu_t *menu) {
|
|||||||
display_close();
|
display_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef const struct {
|
||||||
// NOTE: Keep this array in sync with menu_mode_t
|
menu_mode_t id;
|
||||||
static struct views_s {
|
|
||||||
void (*init) (menu_t *menu);
|
void (*init) (menu_t *menu);
|
||||||
void (*show) (menu_t *menu, surface_t *display);
|
void (*show) (menu_t *menu, surface_t *display);
|
||||||
} views[__MENU_MODE_COUNT] = {
|
} view_t;
|
||||||
{ NULL, NULL }, // MENU_MODE_NONE
|
|
||||||
{ view_startup_init, view_startup_display }, // MENU_MODE_STARTUP
|
static view_t menu_views[] = {
|
||||||
{ view_browser_init, view_browser_display }, // MENU_MODE_BROWSER
|
{ MENU_MODE_STARTUP, view_startup_init, view_startup_display },
|
||||||
{ view_file_info_init, view_file_info_display }, // MENU_MODE_FILE_INFO
|
{ MENU_MODE_BROWSER, view_browser_init, view_browser_display },
|
||||||
{ view_system_info_init, view_system_info_display }, // MENU_MODE_SYSTEM_INFO
|
{ MENU_MODE_FILE_INFO, view_file_info_init, view_file_info_display },
|
||||||
{ view_image_viewer_init, view_image_viewer_display }, // MENU_MODE_IMAGE_VIEWER
|
{ MENU_MODE_SYSTEM_INFO, view_system_info_init, view_system_info_display },
|
||||||
{ view_music_player_init, view_music_player_display }, // MENU_MODE_MUSIC_PLAYER
|
{ MENU_MODE_IMAGE_VIEWER, view_image_viewer_init, view_image_viewer_display },
|
||||||
{ view_credits_init, view_credits_display }, // MENU_MODE_CREDITS
|
{ MENU_MODE_TEXT_VIEWER, view_text_viewer_init, view_text_viewer_display },
|
||||||
{ view_settings_init, view_settings_display }, // MENU_MODE_SETTINGS_EDITOR
|
{ MENU_MODE_MUSIC_PLAYER, view_music_player_init, view_music_player_display },
|
||||||
{ view_rtc_init, view_rtc_display }, // MENU_MODE_RTC
|
{ MENU_MODE_CREDITS, view_credits_init, view_credits_display },
|
||||||
{ view_load_rom_init, view_load_rom_display }, // MENU_MODE_LOAD_ROM
|
{ MENU_MODE_SETTINGS_EDITOR, view_settings_init, view_settings_display },
|
||||||
{ view_load_disk_init, view_load_disk_display }, // MENU_MODE_LOAD_DISK
|
{ MENU_MODE_RTC, view_rtc_init, view_rtc_display },
|
||||||
{ view_load_emulator_init, view_load_emulator_display }, // MENU_MODE_LOAD_EMULATOR
|
{ MENU_MODE_FLASHCART, view_flashcart_info_init, view_flashcart_info_display },
|
||||||
{ view_error_init, view_error_display }, // MENU_MODE_ERROR
|
{ MENU_MODE_LOAD_ROM, view_load_rom_init, view_load_rom_display },
|
||||||
{ view_fault_init, view_fault_display }, // MENU_MODE_FAULT
|
{ MENU_MODE_LOAD_DISK, view_load_disk_init, view_load_disk_display },
|
||||||
{ NULL, NULL }, // MENU_MODE_BOOT
|
{ MENU_MODE_LOAD_EMULATOR, view_load_emulator_init, view_load_emulator_display },
|
||||||
|
{ MENU_MODE_ERROR, view_error_init, view_error_display },
|
||||||
|
{ MENU_MODE_FAULT, view_fault_init, view_fault_display },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static view_t *menu_get_view (menu_mode_t id) {
|
||||||
|
for (int i = 0; i < sizeof(menu_views) / sizeof(view_t); i++) {
|
||||||
|
if (menu_views[i].id == id) {
|
||||||
|
return &menu_views[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void menu_run (boot_params_t *boot_params) {
|
void menu_run (boot_params_t *boot_params) {
|
||||||
menu_init(boot_params);
|
menu_init(boot_params);
|
||||||
|
|
||||||
@ -168,8 +182,9 @@ void menu_run (boot_params_t *boot_params) {
|
|||||||
|
|
||||||
actions_update(menu);
|
actions_update(menu);
|
||||||
|
|
||||||
if (views[menu->mode].show) {
|
view_t *view = menu_get_view(menu->mode);
|
||||||
views[menu->mode].show(menu, display);
|
if (view && view->show) {
|
||||||
|
view->show(menu, display);
|
||||||
} else {
|
} else {
|
||||||
rdpq_attach_clear(display, NULL);
|
rdpq_attach_clear(display, NULL);
|
||||||
rdpq_detach_wait();
|
rdpq_detach_wait();
|
||||||
@ -183,8 +198,9 @@ void menu_run (boot_params_t *boot_params) {
|
|||||||
while (menu->mode != menu->next_mode) {
|
while (menu->mode != menu->next_mode) {
|
||||||
menu->mode = menu->next_mode;
|
menu->mode = menu->next_mode;
|
||||||
|
|
||||||
if (views[menu->mode].init) {
|
view_t *next_view = menu_get_view(menu->next_mode);
|
||||||
views[menu->mode].init(menu);
|
if (next_view && next_view->init) {
|
||||||
|
next_view->init(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,17 +29,18 @@ typedef enum {
|
|||||||
MENU_MODE_FILE_INFO,
|
MENU_MODE_FILE_INFO,
|
||||||
MENU_MODE_SYSTEM_INFO,
|
MENU_MODE_SYSTEM_INFO,
|
||||||
MENU_MODE_IMAGE_VIEWER,
|
MENU_MODE_IMAGE_VIEWER,
|
||||||
|
MENU_MODE_TEXT_VIEWER,
|
||||||
MENU_MODE_MUSIC_PLAYER,
|
MENU_MODE_MUSIC_PLAYER,
|
||||||
MENU_MODE_CREDITS,
|
MENU_MODE_CREDITS,
|
||||||
MENU_MODE_SETTINGS_EDITOR,
|
MENU_MODE_SETTINGS_EDITOR,
|
||||||
MENU_MODE_RTC,
|
MENU_MODE_RTC,
|
||||||
|
MENU_MODE_FLASHCART,
|
||||||
MENU_MODE_LOAD_ROM,
|
MENU_MODE_LOAD_ROM,
|
||||||
MENU_MODE_LOAD_DISK,
|
MENU_MODE_LOAD_DISK,
|
||||||
MENU_MODE_LOAD_EMULATOR,
|
MENU_MODE_LOAD_EMULATOR,
|
||||||
MENU_MODE_ERROR,
|
MENU_MODE_ERROR,
|
||||||
MENU_MODE_FAULT,
|
MENU_MODE_FAULT,
|
||||||
MENU_MODE_BOOT,
|
MENU_MODE_BOOT,
|
||||||
__MENU_MODE_COUNT,
|
|
||||||
} menu_mode_t;
|
} menu_mode_t;
|
||||||
|
|
||||||
/** @brief File entry type enumeration */
|
/** @brief File entry type enumeration */
|
||||||
@ -50,6 +51,7 @@ typedef enum {
|
|||||||
ENTRY_TYPE_EMULATOR,
|
ENTRY_TYPE_EMULATOR,
|
||||||
ENTRY_TYPE_SAVE,
|
ENTRY_TYPE_SAVE,
|
||||||
ENTRY_TYPE_IMAGE,
|
ENTRY_TYPE_IMAGE,
|
||||||
|
ENTRY_TYPE_TEXT,
|
||||||
ENTRY_TYPE_MUSIC,
|
ENTRY_TYPE_MUSIC,
|
||||||
ENTRY_TYPE_OTHER,
|
ENTRY_TYPE_OTHER,
|
||||||
} entry_type_t;
|
} entry_type_t;
|
||||||
|
@ -27,7 +27,7 @@ typedef struct {
|
|||||||
mp3dec_t dec;
|
mp3dec_t dec;
|
||||||
mp3dec_frame_info_t info;
|
mp3dec_frame_info_t info;
|
||||||
|
|
||||||
uint8_t buffer[MAX_FREE_FORMAT_FRAME_SIZE];
|
uint8_t buffer[16 * 1024];
|
||||||
uint8_t *buffer_ptr;
|
uint8_t *buffer_ptr;
|
||||||
size_t buffer_left;
|
size_t buffer_left;
|
||||||
|
|
||||||
@ -54,6 +54,10 @@ static void mp3player_fill_buffer (void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->buffer_left >= ALIGN(MAX_FREE_FORMAT_FRAME_SIZE, FS_SECTOR_SIZE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((p->buffer_ptr != p->buffer) && (p->buffer_left > 0)) {
|
if ((p->buffer_ptr != p->buffer) && (p->buffer_left > 0)) {
|
||||||
memmove(p->buffer, p->buffer_ptr, p->buffer_left);
|
memmove(p->buffer, p->buffer_ptr, p->buffer_left);
|
||||||
p->buffer_ptr = p->buffer;
|
p->buffer_ptr = p->buffer;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "png_decoder.h"
|
#include "png_decoder.h"
|
||||||
#include "utils/fs.h"
|
#include "utils/fs.h"
|
||||||
|
|
||||||
|
|
||||||
/** @brief PNG File Information Structure. */
|
/** @brief PNG File Information Structure. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FIL fil;
|
FIL fil;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <fatfs/ff.h>
|
#include <fatfs/ff.h>
|
||||||
#include <mini.c/src/mini.h>
|
#include <mini.c/src/mini.h>
|
||||||
|
|
||||||
|
#include "boot/cic.h"
|
||||||
#include "rom_info.h"
|
#include "rom_info.h"
|
||||||
#include "utils/fs.h"
|
#include "utils/fs.h"
|
||||||
|
|
||||||
@ -16,6 +17,7 @@
|
|||||||
|
|
||||||
#define CLOCK_RATE_DEFAULT (0x0000000F)
|
#define CLOCK_RATE_DEFAULT (0x0000000F)
|
||||||
|
|
||||||
|
|
||||||
/** @brief ROM File Information Structure. */
|
/** @brief ROM File Information Structure. */
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
uint32_t pi_dom1_config;
|
uint32_t pi_dom1_config;
|
||||||
@ -652,15 +654,34 @@ static match_t find_rom_in_database (rom_header_t *rom_header) {
|
|||||||
return *match;
|
return *match;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t fix_boot_address (cic_type_t cic_type, uint32_t boot_address) {
|
static rom_cic_type_t detect_cic_type (uint8_t *ipl3) {
|
||||||
|
switch (cic_detect(ipl3)) {
|
||||||
|
case CIC_5101: return ROM_CIC_TYPE_5101;
|
||||||
|
case CIC_5167: return ROM_CIC_TYPE_5167;
|
||||||
|
case CIC_6101: return ROM_CIC_TYPE_6101;
|
||||||
|
case CIC_7102: return ROM_CIC_TYPE_7102;
|
||||||
|
case CIC_x102: return ROM_CIC_TYPE_x102;
|
||||||
|
case CIC_x103: return ROM_CIC_TYPE_x103;
|
||||||
|
case CIC_x105: return ROM_CIC_TYPE_x105;
|
||||||
|
case CIC_x106: return ROM_CIC_TYPE_x106;
|
||||||
|
case CIC_8301: return ROM_CIC_TYPE_8301;
|
||||||
|
case CIC_8302: return ROM_CIC_TYPE_8302;
|
||||||
|
case CIC_8303: return ROM_CIC_TYPE_8303;
|
||||||
|
case CIC_8401: return ROM_CIC_TYPE_8401;
|
||||||
|
case CIC_8501: return ROM_CIC_TYPE_8501;
|
||||||
|
default: return ROM_CIC_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t fix_boot_address (rom_cic_type_t cic_type, uint32_t boot_address) {
|
||||||
switch (cic_type) {
|
switch (cic_type) {
|
||||||
case CIC_x103: return (boot_address - 0x100000);
|
case ROM_CIC_TYPE_x103: return (boot_address - 0x100000);
|
||||||
case CIC_x106: return (boot_address - 0x200000);
|
case ROM_CIC_TYPE_x106: return (boot_address - 0x200000);
|
||||||
default: return boot_address;
|
default: return boot_address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rom_tv_type_t determine_tv_type (destination_type_t rom_destination_code) {
|
static rom_tv_type_t determine_tv_type (rom_destination_type_t rom_destination_code) {
|
||||||
// check the market type from the ROM destination_code and return best guess!
|
// check the market type from the ROM destination_code and return best guess!
|
||||||
switch (rom_destination_code) {
|
switch (rom_destination_code) {
|
||||||
case MARKET_NORTH_AMERICA:
|
case MARKET_NORTH_AMERICA:
|
||||||
@ -695,7 +716,7 @@ static rom_tv_type_t determine_tv_type (destination_type_t rom_destination_code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 = detect_cic_type(rom_header->ipl3);
|
||||||
|
|
||||||
if (match->type == MATCH_TYPE_HOMEBREW_HEADER) {
|
if (match->type == MATCH_TYPE_HOMEBREW_HEADER) {
|
||||||
if (rom_header->version & (1 << 0)) {
|
if (rom_header->version & (1 << 0)) {
|
||||||
@ -746,63 +767,72 @@ 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) {
|
static void load_overrides (path_t *path, rom_info_t *rom_info) {
|
||||||
|
path_t *overrides_path = path_clone(path);
|
||||||
|
|
||||||
|
path_ext_replace(overrides_path, "ini");
|
||||||
|
|
||||||
|
mini_t *ini = mini_load(path_get(overrides_path));
|
||||||
|
|
||||||
|
rom_info->override.cic = false;
|
||||||
rom_info->override.save = false;
|
rom_info->override.save = false;
|
||||||
rom_info->override.tv = false;
|
rom_info->override.tv = false;
|
||||||
|
|
||||||
path_t *overrides_path = path_clone(path);
|
if (ini) {
|
||||||
|
rom_info->override.cic_type = mini_get_int(ini, NULL, "cic_type", ROM_CIC_TYPE_AUTOMATIC);
|
||||||
|
if (rom_info->override.cic_type != ROM_CIC_TYPE_AUTOMATIC) {
|
||||||
|
rom_info->override.cic = true;
|
||||||
|
}
|
||||||
|
|
||||||
path_ext_replace(overrides_path, "ini");
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (!file_exists(path_get(overrides_path))) {
|
rom_info->override.tv_type = mini_get_int(ini, NULL, "tv_type", ROM_TV_TYPE_AUTOMATIC);
|
||||||
path_free(overrides_path);
|
if (rom_info->override.tv_type != ROM_TV_TYPE_AUTOMATIC) {
|
||||||
return;
|
rom_info->override.tv = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mini_free(ini);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
path_free(overrides_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rom_err_t save_override (path_t *path, const char *id, int value, int default_value) {
|
||||||
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_t *overrides_path = path_clone(path);
|
||||||
|
|
||||||
path_ext_replace(overrides_path, "ini");
|
path_ext_replace(overrides_path, "ini");
|
||||||
|
|
||||||
mini_t *ini = mini_try_load(path_get(overrides_path));
|
mini_t *ini = mini_try_load(path_get(overrides_path));
|
||||||
|
|
||||||
rom_info->override.save_type = save_type;
|
if (!ini) {
|
||||||
|
return ROM_ERR_IO;
|
||||||
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 (value == default_value) {
|
||||||
|
mini_delete_value(ini, NULL, id);
|
||||||
|
} else {
|
||||||
|
mini_set_int(ini, NULL, id, value);
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty_override_file) {
|
bool empty = mini_empty(ini);
|
||||||
mini_save(ini, MINI_FLAGS_NONE);
|
|
||||||
|
if (!empty) {
|
||||||
|
if (mini_save(ini, MINI_FLAGS_NONE) != MINI_OK) {
|
||||||
|
path_free(overrides_path);
|
||||||
|
mini_free(ini);
|
||||||
|
return ROM_ERR_IO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mini_free(ini);
|
mini_free(ini);
|
||||||
|
|
||||||
if (empty_override_file) {
|
if (empty) {
|
||||||
file_delete(path_get(overrides_path));
|
if (file_delete(path_get(overrides_path))) {
|
||||||
|
path_free(overrides_path);
|
||||||
|
return ROM_ERR_IO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
path_free(overrides_path);
|
path_free(overrides_path);
|
||||||
@ -810,38 +840,45 @@ rom_err_t rom_info_override_save_type (path_t *path, rom_info_t *rom_info, rom_s
|
|||||||
return ROM_OK;
|
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");
|
rom_cic_type_t rom_info_get_cic_type (rom_info_t *rom_info) {
|
||||||
|
if (rom_info->override.cic) {
|
||||||
mini_t *ini = mini_try_load(path_get(overrides_path));
|
return rom_info->override.cic_type;
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
rom_info->override.tv = true;
|
return rom_info->cic_type;
|
||||||
mini_set_int(ini, NULL, "tv_type", rom_info->override.tv_type);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rom_info_get_cic_seed (rom_info_t *rom_info, uint8_t *seed) {
|
||||||
|
cic_type_t cic_type;
|
||||||
|
|
||||||
|
switch (rom_info_get_cic_type(rom_info)) {
|
||||||
|
case ROM_CIC_TYPE_5101: cic_type = CIC_5101; break;
|
||||||
|
case ROM_CIC_TYPE_5167: cic_type = CIC_5167; break;
|
||||||
|
case ROM_CIC_TYPE_6101: cic_type = CIC_6101; break;
|
||||||
|
case ROM_CIC_TYPE_7102: cic_type = CIC_7102; break;
|
||||||
|
case ROM_CIC_TYPE_x102: cic_type = CIC_x102; break;
|
||||||
|
case ROM_CIC_TYPE_x103: cic_type = CIC_x103; break;
|
||||||
|
case ROM_CIC_TYPE_x105: cic_type = CIC_x105; break;
|
||||||
|
case ROM_CIC_TYPE_x106: cic_type = CIC_x106; break;
|
||||||
|
case ROM_CIC_TYPE_8301: cic_type = CIC_8301; break;
|
||||||
|
case ROM_CIC_TYPE_8302: cic_type = CIC_8302; break;
|
||||||
|
case ROM_CIC_TYPE_8303: cic_type = CIC_8303; break;
|
||||||
|
case ROM_CIC_TYPE_8401: cic_type = CIC_8401; break;
|
||||||
|
case ROM_CIC_TYPE_8501: cic_type = CIC_8501; break;
|
||||||
|
default: cic_type = CIC_UNKNOWN; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty_override_file = mini_empty(ini);
|
*seed = cic_get_seed(cic_type);
|
||||||
|
|
||||||
if (!empty_override_file) {
|
return (!rom_info->override.cic);
|
||||||
mini_save(ini, MINI_FLAGS_NONE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mini_free(ini);
|
rom_err_t rom_info_override_cic_type (path_t *path, rom_info_t *rom_info, rom_cic_type_t cic_type) {
|
||||||
|
rom_info->override.cic = (cic_type != ROM_CIC_TYPE_AUTOMATIC);
|
||||||
|
rom_info->override.cic_type = cic_type;
|
||||||
|
|
||||||
if (empty_override_file) {
|
return save_override(path, "cic_type", rom_info->override.cic_type, ROM_CIC_TYPE_AUTOMATIC);
|
||||||
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) {
|
rom_save_type_t rom_info_get_save_type (rom_info_t *rom_info) {
|
||||||
@ -852,6 +889,13 @@ rom_save_type_t rom_info_get_save_type (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_info->override.save = (save_type != SAVE_TYPE_AUTOMATIC);
|
||||||
|
rom_info->override.save_type = save_type;
|
||||||
|
|
||||||
|
return save_override(path, "save_type", rom_info->override.save_type, SAVE_TYPE_AUTOMATIC);
|
||||||
|
}
|
||||||
|
|
||||||
rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info) {
|
rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info) {
|
||||||
if (rom_info->override.tv) {
|
if (rom_info->override.tv) {
|
||||||
return rom_info->override.tv_type;
|
return rom_info->override.tv_type;
|
||||||
@ -860,6 +904,13 @@ rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rom_err_t rom_info_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type) {
|
||||||
|
rom_info->override.tv = (tv_type != ROM_TV_TYPE_AUTOMATIC);
|
||||||
|
rom_info->override.tv_type = tv_type;
|
||||||
|
|
||||||
|
return save_override(path, "tv_type", rom_info->override.tv_type, ROM_TV_TYPE_AUTOMATIC);
|
||||||
|
}
|
||||||
|
|
||||||
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info) {
|
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info) {
|
||||||
FIL fil;
|
FIL fil;
|
||||||
UINT br;
|
UINT br;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file rom_info.h
|
* @file rom_info.h
|
||||||
* @brief N64 ROM Database.
|
* @brief N64 ROM Database.
|
||||||
* @note Only works with N64 ROM's by checking the first 1024 bytes of the file.
|
* @note Only works with N64 ROM's by checking the first 4096 bytes of the file.
|
||||||
* @ingroup menu
|
* @ingroup menu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -12,7 +12,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/cic.h"
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ typedef enum {
|
|||||||
ENDIANNESS_LITTLE,
|
ENDIANNESS_LITTLE,
|
||||||
/** @brief Is Byte Swapped Endian. */
|
/** @brief Is Byte Swapped Endian. */
|
||||||
ENDIANNESS_BYTE_SWAP,
|
ENDIANNESS_BYTE_SWAP,
|
||||||
} endianness_t;
|
} rom_endianness_t;
|
||||||
|
|
||||||
/** @brief ROM media type enumeration. */
|
/** @brief ROM media type enumeration. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -45,7 +44,7 @@ typedef enum {
|
|||||||
N64_DISK_EXPANDABLE = 'E',
|
N64_DISK_EXPANDABLE = 'E',
|
||||||
/** @brief Is an Aleck64 program. */
|
/** @brief Is an Aleck64 program. */
|
||||||
N64_ALECK64 = 'Z'
|
N64_ALECK64 = 'Z'
|
||||||
} category_type_t;
|
} rom_category_type_t;
|
||||||
|
|
||||||
/** @brief ROM market region & language type enumeration. */
|
/** @brief ROM market region & language type enumeration. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -89,27 +88,46 @@ typedef enum {
|
|||||||
MARKET_OTHER_Y = 'Y', // many EU ROM's uses this.
|
MARKET_OTHER_Y = 'Y', // many EU ROM's uses this.
|
||||||
/** @brief The ROM is designed for an undefined region and TBD language(s). */
|
/** @brief The ROM is designed for an undefined region and TBD language(s). */
|
||||||
MARKET_OTHER_Z = 'Z' // no known ROM's use this.
|
MARKET_OTHER_Z = 'Z' // no known ROM's use this.
|
||||||
} destination_type_t;
|
} rom_destination_type_t;
|
||||||
|
|
||||||
|
/** @brief ROM CIC type enumeration. */
|
||||||
|
typedef enum {
|
||||||
|
ROM_CIC_TYPE_UNKNOWN = 0, // No known CIC type detected
|
||||||
|
ROM_CIC_TYPE_5101 = 5101, // Aleck64 CIC-5101
|
||||||
|
ROM_CIC_TYPE_5167 = 5167, // 64DD ROM conversion CIC-5167
|
||||||
|
ROM_CIC_TYPE_6101 = 6101, // NTSC CIC-6101
|
||||||
|
ROM_CIC_TYPE_7102 = 7102, // PAL CIC-7102
|
||||||
|
ROM_CIC_TYPE_x102 = 6102, // NTSC CIC-6102 / PAL CIC-7101
|
||||||
|
ROM_CIC_TYPE_x103 = 6103, // NTSC CIC-6103 / PAL CIC-7103
|
||||||
|
ROM_CIC_TYPE_x105 = 6105, // NTSC CIC-6105 / PAL CIC-7105
|
||||||
|
ROM_CIC_TYPE_x106 = 6106, // NTSC CIC-6106 / PAL CIC-7106
|
||||||
|
ROM_CIC_TYPE_8301 = 8301, // NDDJ0 64DD IPL
|
||||||
|
ROM_CIC_TYPE_8302 = 8302, // NDDJ1 64DD IPL
|
||||||
|
ROM_CIC_TYPE_8303 = 8303, // NDDJ2 64DD IPL
|
||||||
|
ROM_CIC_TYPE_8401 = 8401, // NDXJ0 64DD IPL
|
||||||
|
ROM_CIC_TYPE_8501 = 8501, // NDDE0 64DD IPL
|
||||||
|
ROM_CIC_TYPE_AUTOMATIC = -1, // Guess CIC from IPL3
|
||||||
|
} rom_cic_type_t;
|
||||||
|
|
||||||
/** @brief ROM save type enumeration. */
|
/** @brief ROM save type enumeration. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/** @brief There is no expected save type. */
|
/** @brief There is no expected save type. */
|
||||||
SAVE_TYPE_NONE,
|
SAVE_TYPE_NONE = 0,
|
||||||
SAVE_TYPE_EEPROM_4K,
|
SAVE_TYPE_EEPROM_4K = 1,
|
||||||
SAVE_TYPE_EEPROM_16K,
|
SAVE_TYPE_EEPROM_16K = 2,
|
||||||
SAVE_TYPE_SRAM,
|
SAVE_TYPE_SRAM = 3,
|
||||||
SAVE_TYPE_SRAM_BANKED,
|
SAVE_TYPE_SRAM_BANKED = 4,
|
||||||
SAVE_TYPE_SRAM_128K,
|
SAVE_TYPE_SRAM_128K = 5,
|
||||||
SAVE_TYPE_FLASHRAM,
|
SAVE_TYPE_FLASHRAM = 6,
|
||||||
SAVE_TYPE_FLASHRAM_PKST2,
|
SAVE_TYPE_FLASHRAM_PKST2 = 7,
|
||||||
SAVE_TYPE_AUTOMATIC = -1,
|
SAVE_TYPE_AUTOMATIC = -1,
|
||||||
} rom_save_type_t;
|
} rom_save_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ROM_TV_TYPE_PAL,
|
ROM_TV_TYPE_PAL = 0,
|
||||||
ROM_TV_TYPE_NTSC,
|
ROM_TV_TYPE_NTSC = 1,
|
||||||
ROM_TV_TYPE_MPAL,
|
ROM_TV_TYPE_MPAL = 2,
|
||||||
ROM_TV_TYPE_UNKNOWN,
|
ROM_TV_TYPE_UNKNOWN = 3,
|
||||||
ROM_TV_TYPE_AUTOMATIC = -1,
|
ROM_TV_TYPE_AUTOMATIC = -1,
|
||||||
} rom_tv_type_t;
|
} rom_tv_type_t;
|
||||||
|
|
||||||
@ -129,49 +147,62 @@ typedef enum {
|
|||||||
|
|
||||||
/** @brief The ROM is faulty when using 8MB of memory. */
|
/** @brief The ROM is faulty when using 8MB of memory. */
|
||||||
EXPANSION_PAK_FAULTY,
|
EXPANSION_PAK_FAULTY,
|
||||||
} expansion_pak_t;
|
} rom_expansion_pak_t;
|
||||||
|
|
||||||
/** @brief ROM Information Structure. */
|
/** @brief ROM Information Structure. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** @brief The file endian. */
|
/** @brief The file endian. */
|
||||||
endianness_t endianness;
|
rom_endianness_t endianness;
|
||||||
|
|
||||||
/** @brief The clock rate defined in the ROM's header. */
|
/** @brief The clock rate defined in the ROM's header. */
|
||||||
float clock_rate;
|
float clock_rate;
|
||||||
|
|
||||||
/** @brief The boot address defined in the ROM's header. */
|
/** @brief The boot address defined in the ROM's header. */
|
||||||
uint32_t boot_address;
|
uint32_t boot_address;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/** @brief The SDK version defined in the ROM's header. */
|
/** @brief The SDK version defined in the ROM's header. */
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
/** @brief The SDK revision defined in the ROM's header. */
|
/** @brief The SDK revision defined in the ROM's header. */
|
||||||
char revision;
|
char revision;
|
||||||
} libultra;
|
} libultra;
|
||||||
|
|
||||||
/** @brief The check code defined in the ROM's header. */
|
/** @brief The check code defined in the ROM's header. */
|
||||||
uint64_t check_code;
|
uint64_t check_code;
|
||||||
|
|
||||||
/** @brief The title defined in the ROM's header. */
|
/** @brief The title defined in the ROM's header. */
|
||||||
char title[20];
|
char title[20];
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/** @brief The game code defined in the ROM's header. */
|
/** @brief The game code defined in the ROM's header. */
|
||||||
char game_code[4];
|
char game_code[4];
|
||||||
struct {
|
struct {
|
||||||
/** @brief The game media type. */
|
/** @brief The game media type. */
|
||||||
category_type_t category_code : 8;
|
rom_category_type_t category_code : 8;
|
||||||
/** @brief The game unique identifier. */
|
/** @brief The game unique identifier. */
|
||||||
char unique_code[2];
|
char unique_code[2];
|
||||||
/** @brief The game region and or market. */
|
/** @brief The game region and or market. */
|
||||||
destination_type_t destination_code : 8;
|
rom_destination_type_t destination_code : 8;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief The ROM version defined in the ROM's header. */
|
/** @brief The ROM version defined in the ROM's header. */
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
|
||||||
cic_type_t cic_type;
|
/** @brief The CIC type required by the ROM. */
|
||||||
|
rom_cic_type_t cic_type;
|
||||||
|
|
||||||
/** @brief The save type required by the ROM. */
|
/** @brief The save type required by the ROM. */
|
||||||
rom_save_type_t save_type;
|
rom_save_type_t save_type;
|
||||||
|
|
||||||
|
/** @brief The TV type required by the ROM. */
|
||||||
rom_tv_type_t tv_type;
|
rom_tv_type_t tv_type;
|
||||||
|
|
||||||
|
/** @brief Overrides of auto-detected CIC/save/TV types. */
|
||||||
struct {
|
struct {
|
||||||
|
bool cic;
|
||||||
|
rom_cic_type_t cic_type;
|
||||||
|
|
||||||
bool save;
|
bool save;
|
||||||
rom_save_type_t save_type;
|
rom_save_type_t save_type;
|
||||||
|
|
||||||
@ -188,15 +219,21 @@ typedef struct {
|
|||||||
bool real_time_clock;
|
bool real_time_clock;
|
||||||
bool disk_conversion;
|
bool disk_conversion;
|
||||||
bool combo_rom_disk_game;
|
bool combo_rom_disk_game;
|
||||||
expansion_pak_t expansion_pak;
|
rom_expansion_pak_t expansion_pak;
|
||||||
} features;
|
} features;
|
||||||
} rom_info_t;
|
} rom_info_t;
|
||||||
|
|
||||||
|
|
||||||
rom_err_t rom_info_override_save_type (path_t *path, rom_info_t *rom_info, rom_save_type_t save_type);
|
rom_cic_type_t rom_info_get_cic_type (rom_info_t *rom_info);
|
||||||
rom_err_t rom_info_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type);
|
bool rom_info_get_cic_seed (rom_info_t *rom_info, uint8_t *seed);
|
||||||
|
rom_err_t rom_info_override_cic_type (path_t *path, rom_info_t *rom_info, rom_cic_type_t cic_type);
|
||||||
|
|
||||||
rom_save_type_t rom_info_get_save_type (rom_info_t *rom_info);
|
rom_save_type_t rom_info_get_save_type (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_tv_type_t rom_info_get_tv_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_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type);
|
||||||
|
|
||||||
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info);
|
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info);
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define DEFAULT_FREQUENCY (44100)
|
#define DEFAULT_FREQUENCY (44100)
|
||||||
#define NUM_BUFFERS (2)
|
#define NUM_BUFFERS (4)
|
||||||
#define NUM_CHANNELS (2)
|
#define NUM_CHANNELS (2)
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
|
|
||||||
#define MAX_FILE_SIZE MiB(4)
|
#define MAX_FILE_SIZE MiB(4)
|
||||||
|
|
||||||
|
|
||||||
/** @brief The supported USB commands structure. */
|
/** @brief The supported USB commands structure. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** @brief The command identifier. */
|
/** @brief The command identifier. */
|
||||||
const char *id;
|
const char *id;
|
||||||
|
|
||||||
/** @brief The command operation. */
|
/** @brief The command operation. */
|
||||||
void (*op) (menu_t *menu);
|
void (*op) (menu_t *menu);
|
||||||
} usb_comm_command_t;
|
} usb_comm_command_t;
|
||||||
|
@ -14,6 +14,7 @@ static const char *disk_extensions[] = { "ndd", NULL };
|
|||||||
static const char *emulator_extensions[] = { "nes", "sfc", "smc", "gb", "gbc", "sms", "gg", "sg", NULL };
|
static const char *emulator_extensions[] = { "nes", "sfc", "smc", "gb", "gbc", "sms", "gg", "sg", NULL };
|
||||||
static const char *save_extensions[] = { "sav", NULL }; // TODO: "eep", "sra", "srm", "fla" could be used if transfered from different flashcarts.
|
static const char *save_extensions[] = { "sav", NULL }; // TODO: "eep", "sra", "srm", "fla" could be used if transfered from different flashcarts.
|
||||||
static const char *image_extensions[] = { "png", NULL };
|
static const char *image_extensions[] = { "png", NULL };
|
||||||
|
static const char *text_extensions[] = { "txt", "ini", "yml", "yaml", NULL };
|
||||||
static const char *music_extensions[] = { "mp3", NULL };
|
static const char *music_extensions[] = { "mp3", NULL };
|
||||||
|
|
||||||
|
|
||||||
@ -46,6 +47,10 @@ static int compare_entry (const void *pa, const void *pb) {
|
|||||||
return -1;
|
return -1;
|
||||||
} else if (b->type == ENTRY_TYPE_IMAGE) {
|
} else if (b->type == ENTRY_TYPE_IMAGE) {
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (a->type == ENTRY_TYPE_TEXT) {
|
||||||
|
return -1;
|
||||||
|
} else if (b->type == ENTRY_TYPE_TEXT) {
|
||||||
|
return 1;
|
||||||
} else if (a->type == ENTRY_TYPE_MUSIC) {
|
} else if (a->type == ENTRY_TYPE_MUSIC) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (b->type == ENTRY_TYPE_MUSIC) {
|
} else if (b->type == ENTRY_TYPE_MUSIC) {
|
||||||
@ -110,6 +115,8 @@ static bool load_directory (menu_t *menu) {
|
|||||||
entry->type = ENTRY_TYPE_SAVE;
|
entry->type = ENTRY_TYPE_SAVE;
|
||||||
} else if (file_has_extensions(info.fname, image_extensions)) {
|
} else if (file_has_extensions(info.fname, image_extensions)) {
|
||||||
entry->type = ENTRY_TYPE_IMAGE;
|
entry->type = ENTRY_TYPE_IMAGE;
|
||||||
|
} else if (file_has_extensions(info.fname, text_extensions)) {
|
||||||
|
entry->type = ENTRY_TYPE_TEXT;
|
||||||
} else if (file_has_extensions(info.fname, music_extensions)) {
|
} else if (file_has_extensions(info.fname, music_extensions)) {
|
||||||
entry->type = ENTRY_TYPE_MUSIC;
|
entry->type = ENTRY_TYPE_MUSIC;
|
||||||
} else {
|
} else {
|
||||||
@ -135,6 +142,22 @@ static bool load_directory (menu_t *menu) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool reload_directory (menu_t *menu) {
|
||||||
|
int selected = menu->browser.selected;
|
||||||
|
|
||||||
|
if (load_directory(menu)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool push_directory (menu_t *menu, char *directory) {
|
static bool push_directory (menu_t *menu, char *directory) {
|
||||||
path_t *previous_directory = path_clone(menu->browser.directory);
|
path_t *previous_directory = path_clone(menu->browser.directory);
|
||||||
|
|
||||||
@ -175,13 +198,11 @@ static bool pop_directory (menu_t *menu) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_properties (menu_t *menu) {
|
static void show_properties (menu_t *menu, void *arg) {
|
||||||
menu->next_mode = MENU_MODE_FILE_INFO;
|
menu->next_mode = MENU_MODE_FILE_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void delete_entry (menu_t *menu) {
|
static void delete_entry (menu_t *menu, void *arg) {
|
||||||
int selected = menu->browser.selected;
|
|
||||||
|
|
||||||
path_t *path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
|
path_t *path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
|
||||||
|
|
||||||
if (menu->browser.entry->type == ENTRY_TYPE_DIR) {
|
if (menu->browser.entry->type == ENTRY_TYPE_DIR) {
|
||||||
@ -200,20 +221,13 @@ static void delete_entry (menu_t *menu) {
|
|||||||
|
|
||||||
path_free(path);
|
path_free(path);
|
||||||
|
|
||||||
if (load_directory(menu)) {
|
if (reload_directory(menu)) {
|
||||||
menu->browser.valid = false;
|
menu->browser.valid = false;
|
||||||
menu_show_error(menu, "Couldn't refresh directory contents after delete operation");
|
menu_show_error(menu, "Couldn't refresh directory contents after delete operation");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_default_directory (menu_t *menu) {
|
static void set_default_directory (menu_t *menu, void *arg) {
|
||||||
free(menu->settings.default_directory);
|
free(menu->settings.default_directory);
|
||||||
menu->settings.default_directory = strdup(strip_sd_prefix(path_get(menu->browser.directory)));
|
menu->settings.default_directory = strdup(strip_sd_prefix(path_get(menu->browser.directory)));
|
||||||
settings_save(&menu->settings);
|
settings_save(&menu->settings);
|
||||||
@ -228,28 +242,18 @@ static component_context_menu_t entry_context_menu = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void edit_settings (menu_t *menu) {
|
static void set_menu_next_mode (menu_t *menu, void *arg) {
|
||||||
menu->next_mode = MENU_MODE_SETTINGS_EDITOR;
|
menu_mode_t next_mode = (menu_mode_t) (arg);
|
||||||
}
|
menu->next_mode = next_mode;
|
||||||
|
|
||||||
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 void edit_rtc (menu_t *menu) {
|
|
||||||
menu->next_mode = MENU_MODE_RTC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static component_context_menu_t settings_context_menu = {
|
static component_context_menu_t settings_context_menu = {
|
||||||
.list = {
|
.list = {
|
||||||
{ .text = "Edit settings", .action = edit_settings },
|
{ .text = "Edit settings", .action = set_menu_next_mode, .arg = (void *) (MENU_MODE_SETTINGS_EDITOR) },
|
||||||
{ .text = "Show system info", .action = show_system_info },
|
{ .text = "Show system info", .action = set_menu_next_mode, .arg = (void *) (MENU_MODE_SYSTEM_INFO) },
|
||||||
{ .text = "Show credits", .action = show_credits },
|
{ .text = "Show credits", .action = set_menu_next_mode, .arg = (void *) (MENU_MODE_CREDITS) },
|
||||||
{ .text = "Adjust RTC", .action = edit_rtc },
|
{ .text = "Adjust RTC", .action = set_menu_next_mode, .arg = (void *) (MENU_MODE_RTC) },
|
||||||
|
{ .text = "Show cart info", .action = set_menu_next_mode, .arg = (void *) (MENU_MODE_FLASHCART) },
|
||||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -300,6 +304,9 @@ static void process (menu_t *menu) {
|
|||||||
case ENTRY_TYPE_IMAGE:
|
case ENTRY_TYPE_IMAGE:
|
||||||
menu->next_mode = MENU_MODE_IMAGE_VIEWER;
|
menu->next_mode = MENU_MODE_IMAGE_VIEWER;
|
||||||
break;
|
break;
|
||||||
|
case ENTRY_TYPE_TEXT:
|
||||||
|
menu->next_mode = MENU_MODE_TEXT_VIEWER;
|
||||||
|
break;
|
||||||
case ENTRY_TYPE_MUSIC:
|
case ENTRY_TYPE_MUSIC:
|
||||||
menu->next_mode = MENU_MODE_MUSIC_PLAYER;
|
menu->next_mode = MENU_MODE_MUSIC_PLAYER;
|
||||||
break;
|
break;
|
||||||
@ -337,6 +344,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
case ENTRY_TYPE_ROM: action = "A: Load"; break;
|
case ENTRY_TYPE_ROM: action = "A: Load"; break;
|
||||||
case ENTRY_TYPE_DISK: action = "A: Load"; break;
|
case ENTRY_TYPE_DISK: action = "A: Load"; break;
|
||||||
case ENTRY_TYPE_IMAGE: action = "A: Show"; break;
|
case ENTRY_TYPE_IMAGE: action = "A: Show"; break;
|
||||||
|
case ENTRY_TYPE_TEXT: action = "A: View"; break;
|
||||||
case ENTRY_TYPE_MUSIC: action = "A: Play"; break;
|
case ENTRY_TYPE_MUSIC: action = "A: Play"; break;
|
||||||
default: action = "A: Info"; break;
|
default: action = "A: Info"; break;
|
||||||
}
|
}
|
||||||
@ -386,18 +394,12 @@ void view_browser_init (menu_t *menu) {
|
|||||||
menu->browser.valid = true;
|
menu->browser.valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu->browser.reload) {
|
if (menu->browser.reload) {
|
||||||
menu->browser.reload = false;
|
menu->browser.reload = false;
|
||||||
int selected = menu->browser.selected;
|
if (reload_directory(menu)) {
|
||||||
if (load_directory(menu)) {
|
|
||||||
menu_show_error(menu, "Error while reloading current directory");
|
menu_show_error(menu, "Error while reloading current directory");
|
||||||
menu->browser.valid = false;
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef MENU_VERSION
|
#ifndef MENU_VERSION
|
||||||
#define MENU_VERSION "0.0.0.6.ALPHA"
|
#define MENU_VERSION "Unknown"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUILD_TIMESTAMP
|
||||||
|
#define BUILD_TIMESTAMP "Unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +32,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
ALIGN_LEFT, VALIGN_TOP,
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
"\n"
|
"\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Menu Revision: V%s\n"
|
"Menu version: %s\n"
|
||||||
|
"Build timestamp: %s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Github:\n"
|
"Github:\n"
|
||||||
" https://github.com/Polprzewodnikowy/N64FlashcartMenu\n"
|
" https://github.com/Polprzewodnikowy/N64FlashcartMenu\n"
|
||||||
@ -44,7 +49,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
" mini.c (BSD 2-Clause License)\n"
|
" mini.c (BSD 2-Clause License)\n"
|
||||||
" minimp3 (CC0 1.0 Universal)\n"
|
" minimp3 (CC0 1.0 Universal)\n"
|
||||||
" miniz (MIT License)",
|
" miniz (MIT License)",
|
||||||
MENU_VERSION
|
MENU_VERSION,
|
||||||
|
BUILD_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
component_actions_bar_text_draw(
|
component_actions_bar_text_draw(
|
||||||
|
46
src/menu/views/flashcart_info.c
Normal file
46
src/menu/views/flashcart_info.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "views.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void process (menu_t *menu) {
|
||||||
|
if (menu->actions.back) {
|
||||||
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw (menu_t *menu, surface_t *d) {
|
||||||
|
rdpq_attach(d, NULL);
|
||||||
|
|
||||||
|
component_background_draw();
|
||||||
|
|
||||||
|
component_layout_draw();
|
||||||
|
|
||||||
|
component_main_text_draw(
|
||||||
|
ALIGN_CENTER, VALIGN_TOP,
|
||||||
|
"FLASHCART INFORMATION\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
component_main_text_draw(
|
||||||
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
component_actions_bar_text_draw(
|
||||||
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
|
"\n"
|
||||||
|
"B: Back"
|
||||||
|
);
|
||||||
|
|
||||||
|
rdpq_detach_show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void view_flashcart_info_init (menu_t *menu) {
|
||||||
|
// Nothing to initialize (yet)
|
||||||
|
}
|
||||||
|
|
||||||
|
void view_flashcart_info_display (menu_t *menu, surface_t *display) {
|
||||||
|
process(menu);
|
||||||
|
draw(menu, display);
|
||||||
|
}
|
@ -126,9 +126,21 @@ static void load (menu_t *menu) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
menu->next_mode = MENU_MODE_BOOT;
|
menu->next_mode = MENU_MODE_BOOT;
|
||||||
menu->boot_params->device_type = load_rom ? BOOT_DEVICE_TYPE_ROM : BOOT_DEVICE_TYPE_64DD;
|
|
||||||
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
|
if (load_rom) {
|
||||||
menu->boot_params->detect_cic_seed = true;
|
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)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
menu->boot_params->device_type = BOOT_DEVICE_TYPE_64DD;
|
||||||
|
menu->boot_params->tv_type = BOOT_TV_TYPE_NTSC;
|
||||||
|
menu->boot_params->detect_cic_seed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,15 +8,15 @@ static bool load_pending;
|
|||||||
static component_boxart_t *boxart;
|
static component_boxart_t *boxart;
|
||||||
|
|
||||||
|
|
||||||
static char *convert_error_message (disk_err_t err) {
|
static char *convert_error_message (rom_err_t err) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case ROM_ERR_IO: return "I/O error during loading ROM information";
|
case ROM_ERR_IO: return "I/O error during loading/storing ROM information";
|
||||||
case ROM_ERR_NO_FILE: return "Couldn't open ROM file";
|
case ROM_ERR_NO_FILE: return "Couldn't open ROM file";
|
||||||
default: return "Unknown ROM info load error";
|
default: return "Unknown ROM info load error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *format_rom_endianness (endianness_t endianness) {
|
static const char *format_rom_endianness (rom_endianness_t endianness) {
|
||||||
switch (endianness) {
|
switch (endianness) {
|
||||||
case ENDIANNESS_BIG: return "Big (default)";
|
case ENDIANNESS_BIG: return "Big (default)";
|
||||||
case ENDIANNESS_LITTLE: return "Little (unsupported)";
|
case ENDIANNESS_LITTLE: return "Little (unsupported)";
|
||||||
@ -25,7 +25,7 @@ static const char *format_rom_endianness (endianness_t endianness) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *format_rom_media_type (category_type_t media_type) {
|
static const char *format_rom_media_type (rom_category_type_t media_type) {
|
||||||
switch (media_type) {
|
switch (media_type) {
|
||||||
case N64_CART: return "Cartridge";
|
case N64_CART: return "Cartridge";
|
||||||
case N64_DISK: return "Disk";
|
case N64_DISK: return "Disk";
|
||||||
@ -36,7 +36,7 @@ static const char *format_rom_media_type (category_type_t media_type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *format_rom_destination_market (destination_type_t market_type) {
|
static const char *format_rom_destination_market (rom_destination_type_t market_type) {
|
||||||
// TODO: These are all assumptions and should be corrected if required.
|
// TODO: These are all assumptions and should be corrected if required.
|
||||||
// From http://n64devkit.square7.ch/info/submission/pal/01-01.html
|
// From http://n64devkit.square7.ch/info/submission/pal/01-01.html
|
||||||
switch (market_type) {
|
switch (market_type) {
|
||||||
@ -87,7 +87,7 @@ static const char *format_rom_tv_type (rom_tv_type_t tv_type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *format_rom_expansion_pak_info (expansion_pak_t expansion_pak_info) {
|
static const char *format_rom_expansion_pak_info (rom_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";
|
||||||
case EXPANSION_PAK_RECOMMENDED: return "Recommended";
|
case EXPANSION_PAK_RECOMMENDED: return "Recommended";
|
||||||
@ -97,72 +97,94 @@ static char *format_rom_expansion_pak_info (expansion_pak_t expansion_pak_info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *format_cic_type (cic_type_t cic_type) {
|
static const char *format_cic_type (rom_cic_type_t cic_type) {
|
||||||
switch (cic_type) {
|
switch (cic_type) {
|
||||||
case CIC_5101: return "5101";
|
case ROM_CIC_TYPE_5101: return "5101";
|
||||||
case CIC_5167: return "5167";
|
case ROM_CIC_TYPE_5167: return "5167";
|
||||||
case CIC_6101: return "6101";
|
case ROM_CIC_TYPE_6101: return "6101";
|
||||||
case CIC_7102: return "7102";
|
case ROM_CIC_TYPE_7102: return "7102";
|
||||||
case CIC_6102_7101: return "6102 / 7101";
|
case ROM_CIC_TYPE_x102: return "6102 / 7101";
|
||||||
case CIC_x103: return "6103 / 7103";
|
case ROM_CIC_TYPE_x103: return "6103 / 7103";
|
||||||
case CIC_x105: return "6105 / 7105";
|
case ROM_CIC_TYPE_x105: return "6105 / 7105";
|
||||||
case CIC_x106: return "6106 / 7106";
|
case ROM_CIC_TYPE_x106: return "6106 / 7106";
|
||||||
case CIC_8301: return "8301";
|
case ROM_CIC_TYPE_8301: return "8301";
|
||||||
case CIC_8302: return "8302";
|
case ROM_CIC_TYPE_8302: return "8302";
|
||||||
case CIC_8303: return "8303";
|
case ROM_CIC_TYPE_8303: return "8303";
|
||||||
case CIC_8401: return "8401";
|
case ROM_CIC_TYPE_8401: return "8401";
|
||||||
case CIC_8501: return "8501";
|
case ROM_CIC_TYPE_8501: return "8501";
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_save_type (menu_t *menu, rom_save_type_t save_type) {
|
static void set_cic_type (menu_t *menu, void *arg) {
|
||||||
rom_info_override_save_type(menu->load.rom_path, &menu->load.rom_info, save_type);
|
rom_cic_type_t cic_type = (rom_cic_type_t) (arg);
|
||||||
|
rom_err_t err = rom_info_override_cic_type(menu->load.rom_path, &menu->load.rom_info, cic_type);
|
||||||
|
if (err != ROM_OK) {
|
||||||
|
menu_show_error(menu, convert_error_message(err));
|
||||||
|
}
|
||||||
menu->browser.reload = true;
|
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 (menu_t *menu, void *arg) {
|
||||||
static void set_save_type_none (menu_t *menu) { set_save_type(menu, SAVE_TYPE_NONE); }
|
rom_save_type_t save_type = (rom_save_type_t) (arg);
|
||||||
static void set_save_type_eeprom_4kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_EEPROM_4K); }
|
rom_err_t err = rom_info_override_save_type(menu->load.rom_path, &menu->load.rom_info, save_type);
|
||||||
static void set_save_type_eeprom_16kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_EEPROM_16K); }
|
if (err != ROM_OK) {
|
||||||
static void set_save_type_sram_256kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM); }
|
menu_show_error(menu, convert_error_message(err));
|
||||||
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); }
|
menu->browser.reload = true;
|
||||||
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 = {
|
static void set_tv_type (menu_t *menu, void *arg) {
|
||||||
{ .text = "Automatic", .action = set_save_type_automatic },
|
rom_tv_type_t tv_type = (rom_tv_type_t) (arg);
|
||||||
{ .text = "None", .action = set_save_type_none },
|
rom_err_t err = rom_info_override_tv_type(menu->load.rom_path, &menu->load.rom_info, tv_type);
|
||||||
{ .text = "EEPROM 4kbit", .action = set_save_type_eeprom_4kbit },
|
if (err != ROM_OK) {
|
||||||
{ .text = "EEPROM 16kbit", .action = set_save_type_eeprom_16kbit },
|
menu_show_error(menu, convert_error_message(err));
|
||||||
{ .text = "SRAM 256kbit", .action = set_save_type_sram_256kbit },
|
}
|
||||||
{ .text = "SRAM 768kbit", .action = set_save_type_sram_768kbit },
|
menu->browser.reload = true;
|
||||||
{ .text = "SRAM 1Mbit", .action = set_save_type_sram_1mbit },
|
}
|
||||||
{ .text = "FlashRAM 1Mbit", .action = set_save_type_flash_ram_1mbit },
|
|
||||||
|
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) },
|
||||||
|
{.text = "CIC-7102", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_7102) },
|
||||||
|
{.text = "CIC-6102 / CIC-7101", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_x102) },
|
||||||
|
{.text = "CIC-6103 / CIC-7103", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_x103) },
|
||||||
|
{.text = "CIC-6105 / CIC-7105", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_x105) },
|
||||||
|
{.text = "CIC-6106 / CIC-7106", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_x106) },
|
||||||
|
{.text = "Aleck64 CIC-5101", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_5101) },
|
||||||
|
{.text = "64DD ROM conversion CIC-5167", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_5167) },
|
||||||
|
{.text = "NDDJ0 64DD IPL", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_8301) },
|
||||||
|
{.text = "NDDJ1 64DD IPL", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_8302) },
|
||||||
|
{.text = "NDDJ2 64DD IPL", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_8303) },
|
||||||
|
{.text = "NDXJ0 64DD IPL", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_8401) },
|
||||||
|
{.text = "NDDE0 64DD IPL", .action = set_cic_type, .arg = (void *) (ROM_CIC_TYPE_8501) },
|
||||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static void set_tv_type (menu_t *menu, rom_tv_type_t tv_type) {
|
static component_context_menu_t set_save_type_context_menu = { .list = {
|
||||||
rom_info_override_tv_type(menu->load.rom_path, &menu->load.rom_info, tv_type);
|
{ .text = "Automatic", .action = set_save_type, .arg = (void *) (SAVE_TYPE_AUTOMATIC) },
|
||||||
menu->browser.reload = true;
|
{ .text = "None", .action = set_save_type, .arg = (void *) (SAVE_TYPE_NONE) },
|
||||||
}
|
{ .text = "EEPROM 4kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_EEPROM_4K) },
|
||||||
|
{ .text = "EEPROM 16kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_EEPROM_16K) },
|
||||||
static void set_tv_type_automatic (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_AUTOMATIC); }
|
{ .text = "SRAM 256kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM) },
|
||||||
static void set_tv_type_pal (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_PAL); }
|
{ .text = "SRAM 768kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_BANKED) },
|
||||||
static void set_tv_type_ntsc (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_NTSC); }
|
{ .text = "SRAM 1Mbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_128K) },
|
||||||
static void set_tv_type_mpal (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_MPAL); }
|
{ .text = "FlashRAM 1Mbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_FLASHRAM) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
static component_context_menu_t set_tv_type_context_menu = { .list = {
|
static component_context_menu_t set_tv_type_context_menu = { .list = {
|
||||||
{ .text = "Automatic", .action = set_tv_type_automatic },
|
{ .text = "Automatic", .action = set_tv_type, .arg = (void *) (ROM_TV_TYPE_AUTOMATIC) },
|
||||||
{ .text = "PAL", .action = set_tv_type_pal },
|
{ .text = "PAL", .action = set_tv_type, .arg = (void *) (ROM_TV_TYPE_PAL) },
|
||||||
{ .text = "NTSC", .action = set_tv_type_ntsc },
|
{ .text = "NTSC", .action = set_tv_type, .arg = (void *) (ROM_TV_TYPE_NTSC) },
|
||||||
{ .text = "MPAL", .action = set_tv_type_mpal },
|
{ .text = "MPAL", .action = set_tv_type, .arg = (void *) (ROM_TV_TYPE_MPAL) },
|
||||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static component_context_menu_t options_context_menu = { .list = {
|
static component_context_menu_t options_context_menu = { .list = {
|
||||||
{ .text = "Set save type", .submenu = &set_save_type_context_menu },
|
{ .text = "Set CIC Type", .submenu = &set_cic_type_context_menu },
|
||||||
{ .text = "Set TV type", .submenu = &set_tv_type_context_menu },
|
{ .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,
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@ -230,7 +252,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
format_rom_save_type(rom_info_get_save_type(&menu->load.rom_info)),
|
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_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(rom_info_get_cic_type(&menu->load.rom_info)),
|
||||||
menu->load.rom_info.boot_address,
|
menu->load.rom_info.boot_address,
|
||||||
(menu->load.rom_info.libultra.version / 10.0f), menu->load.rom_info.libultra.revision,
|
(menu->load.rom_info.libultra.version / 10.0f), menu->load.rom_info.libultra.revision,
|
||||||
menu->load.rom_info.clock_rate
|
menu->load.rom_info.clock_rate
|
||||||
@ -281,8 +303,8 @@ 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 = rom_info_get_cic_seed(&menu->load.rom_info, &menu->boot_params->cic_seed);
|
||||||
switch(rom_info_get_tv_type(&menu->load.rom_info)) {
|
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_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_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;
|
case ROM_TV_TYPE_MPAL: menu->boot_params->tv_type = BOOT_TV_TYPE_MPAL; break;
|
||||||
@ -296,18 +318,20 @@ static void deinit (void) {
|
|||||||
|
|
||||||
|
|
||||||
void view_load_rom_init (menu_t *menu) {
|
void view_load_rom_init (menu_t *menu) {
|
||||||
|
load_pending = false;
|
||||||
|
|
||||||
if (menu->load.rom_path) {
|
if (menu->load.rom_path) {
|
||||||
path_free(menu->load.rom_path);
|
path_free(menu->load.rom_path);
|
||||||
menu->load.rom_path = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load_pending = false;
|
|
||||||
|
|
||||||
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);
|
rom_err_t err = rom_info_load(menu->load.rom_path, &menu->load.rom_info);
|
||||||
if (err != ROM_OK) {
|
if (err != ROM_OK) {
|
||||||
|
path_free(menu->load.rom_path);
|
||||||
|
menu->load.rom_path = NULL;
|
||||||
menu_show_error(menu, convert_error_message(err));
|
menu_show_error(menu, convert_error_message(err));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boxart = component_boxart_init(menu->load.rom_info.game_code);
|
boxart = component_boxart_init(menu->load.rom_info.game_code);
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
static char *format_boolean_type (int state) {
|
|
||||||
|
static const char *format_switch (bool state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0: return "Off";
|
case true: return "On";
|
||||||
case 1: return "On";
|
case false: return "Off";
|
||||||
default: return "Unknown";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
@ -40,16 +41,15 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
"bgm_enabled: %s\n"
|
"bgm_enabled: %s\n"
|
||||||
"sound_enabled: %s\n"
|
"sound_enabled: %s\n"
|
||||||
"rumble_enabled: %s\n",
|
"rumble_enabled: %s\n",
|
||||||
format_boolean_type(menu->settings.pal60_enabled),
|
format_switch(menu->settings.pal60_enabled),
|
||||||
format_boolean_type(menu->settings.hidden_files_enabled),
|
format_switch(menu->settings.hidden_files_enabled),
|
||||||
menu->settings.default_directory,
|
menu->settings.default_directory,
|
||||||
format_boolean_type(menu->settings.use_saves_folder),
|
format_switch(menu->settings.use_saves_folder),
|
||||||
format_boolean_type(menu->settings.bgm_enabled),
|
format_switch(menu->settings.bgm_enabled),
|
||||||
format_boolean_type(menu->settings.sound_enabled),
|
format_switch(menu->settings.sound_enabled),
|
||||||
format_boolean_type(menu->settings.rumble_enabled)
|
format_switch(menu->settings.rumble_enabled)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
component_actions_bar_text_draw(
|
component_actions_bar_text_draw(
|
||||||
ALIGN_LEFT, VALIGN_TOP,
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
"\n"
|
"\n"
|
||||||
@ -66,5 +66,6 @@ void view_settings_init (menu_t *menu) {
|
|||||||
|
|
||||||
void view_settings_display (menu_t *menu, surface_t *display) {
|
void view_settings_display (menu_t *menu, surface_t *display) {
|
||||||
process(menu);
|
process(menu);
|
||||||
|
|
||||||
draw(menu, display);
|
draw(menu, display);
|
||||||
}
|
}
|
||||||
|
@ -7,27 +7,25 @@ static int joypad[4];
|
|||||||
static int accessory[4];
|
static int accessory[4];
|
||||||
|
|
||||||
|
|
||||||
static char *format_accessory (int joypad) {
|
static const char *format_accessory (int joypad) {
|
||||||
switch (accessory[joypad]) {
|
switch (accessory[joypad]) {
|
||||||
case JOYPAD_ACCESSORY_TYPE_RUMBLE_PAK:
|
case JOYPAD_ACCESSORY_TYPE_RUMBLE_PAK: return "[Rumble Pak is inserted]";
|
||||||
return "[Rumble Pak is inserted]";
|
case JOYPAD_ACCESSORY_TYPE_CONTROLLER_PAK: return "[Controller Pak is inserted]";
|
||||||
case JOYPAD_ACCESSORY_TYPE_CONTROLLER_PAK:
|
case JOYPAD_ACCESSORY_TYPE_TRANSFER_PAK: return "[Transfer Pak is inserted]";
|
||||||
return "[Controller Pak is inserted]";
|
case JOYPAD_ACCESSORY_TYPE_BIO_SENSOR: return "[BIO Sensor is inserted]";
|
||||||
case JOYPAD_ACCESSORY_TYPE_TRANSFER_PAK:
|
case JOYPAD_ACCESSORY_TYPE_SNAP_STATION: return "[Snap Station is inserted]";
|
||||||
return "[Transfer Pak is inserted]";
|
case JOYPAD_ACCESSORY_TYPE_NONE: return "";
|
||||||
case JOYPAD_ACCESSORY_TYPE_BIO_SENSOR:
|
default: return "[unknown accessory inserted]";
|
||||||
return "[BIO Sensor is inserted]";
|
|
||||||
case JOYPAD_ACCESSORY_TYPE_SNAP_STATION:
|
|
||||||
return "[Snap Station is inserted]";
|
|
||||||
case JOYPAD_ACCESSORY_TYPE_NONE:
|
|
||||||
return "";
|
|
||||||
default:
|
|
||||||
return "[unknown accessory inserted]";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
|
JOYPAD_PORT_FOREACH (port) {
|
||||||
|
joypad[port] = (joypad_get_style(port) != JOYPAD_STYLE_NONE);
|
||||||
|
accessory[port] = joypad_get_accessory_type(port);
|
||||||
|
}
|
||||||
|
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
}
|
}
|
||||||
@ -53,10 +51,10 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
"\n"
|
"\n"
|
||||||
"Expansion PAK is %sinserted\n"
|
"Expansion PAK is %sinserted\n"
|
||||||
"\n"
|
"\n"
|
||||||
"JoyPad 1 is %sconnected %s\n"
|
"Joypad 1 is %sconnected %s\n"
|
||||||
"JoyPad 2 is %sconnected %s\n"
|
"Joypad 2 is %sconnected %s\n"
|
||||||
"JoyPad 3 is %sconnected %s\n"
|
"Joypad 3 is %sconnected %s\n"
|
||||||
"JoyPad 4 is %sconnected %s\n",
|
"Joypad 4 is %sconnected %s\n",
|
||||||
menu->current_time >= 0 ? ctime(&menu->current_time) : "Unknown\n",
|
menu->current_time >= 0 ? ctime(&menu->current_time) : "Unknown\n",
|
||||||
is_memory_expanded() ? "" : "not ",
|
is_memory_expanded() ? "" : "not ",
|
||||||
(joypad[0]) ? "" : "not ", format_accessory(0),
|
(joypad[0]) ? "" : "not ", format_accessory(0),
|
||||||
@ -76,10 +74,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
|
|
||||||
|
|
||||||
void view_system_info_init (menu_t *menu) {
|
void view_system_info_init (menu_t *menu) {
|
||||||
JOYPAD_PORT_FOREACH (port) {
|
// Nothing to initialize (yet)
|
||||||
joypad[port] = (joypad_get_style(port) != JOYPAD_STYLE_NONE);
|
|
||||||
accessory[port] = joypad_get_accessory_type(port);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_system_info_display (menu_t *menu, surface_t *display) {
|
void view_system_info_display (menu_t *menu, surface_t *display) {
|
||||||
|
78
src/menu/views/text_viewer.c
Normal file
78
src/menu/views/text_viewer.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include <fatfs/ff.h>
|
||||||
|
|
||||||
|
#include "utils/fs.h"
|
||||||
|
#include "views.h"
|
||||||
|
|
||||||
|
static char *file_content;
|
||||||
|
|
||||||
|
static void process (menu_t *menu) {
|
||||||
|
if (menu->actions.back) {
|
||||||
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw (menu_t *menu, surface_t *d) {
|
||||||
|
rdpq_attach(d, NULL);
|
||||||
|
|
||||||
|
component_background_draw();
|
||||||
|
|
||||||
|
component_layout_draw();
|
||||||
|
|
||||||
|
component_main_text_draw(
|
||||||
|
ALIGN_CENTER, VALIGN_TOP,
|
||||||
|
"TEXT VIEWER\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
component_main_text_draw(
|
||||||
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"%s\n",
|
||||||
|
file_content
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
component_actions_bar_text_draw(
|
||||||
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
|
"\n"
|
||||||
|
"B: Back"
|
||||||
|
);
|
||||||
|
|
||||||
|
rdpq_detach_show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void view_text_viewer_init (menu_t *menu) {
|
||||||
|
path_t *path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
|
||||||
|
|
||||||
|
uint32_t file_size = file_get_size(path_get(path));
|
||||||
|
|
||||||
|
if (file_size > 1024) { // FIXME: this is just a placeholder until scrolling is implemented.
|
||||||
|
file_size = 1024; // For the moment, we just set it to that, since any more would be a waste.
|
||||||
|
}
|
||||||
|
|
||||||
|
file_content = calloc(file_size, 1);
|
||||||
|
|
||||||
|
// read file content
|
||||||
|
FIL fil;
|
||||||
|
UINT br;
|
||||||
|
|
||||||
|
if (f_open(&fil, strip_sd_prefix(path_get(path)), FA_READ) != FR_OK) {
|
||||||
|
debugf("Error loading file\n");
|
||||||
|
}
|
||||||
|
if (f_read(&fil, file_content, file_size, &br) != FR_OK) {
|
||||||
|
f_close(&fil);
|
||||||
|
debugf("Error loading file content\n");
|
||||||
|
}
|
||||||
|
if (f_close(&fil) != FR_OK) {
|
||||||
|
debugf("Error closing file\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
path_free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void view_text_viewer_display (menu_t *menu, surface_t *display) {
|
||||||
|
process(menu);
|
||||||
|
draw(menu, display);
|
||||||
|
}
|
@ -23,33 +23,39 @@ void view_startup_display (menu_t *menu, surface_t *display);
|
|||||||
void view_browser_init (menu_t *menu);
|
void view_browser_init (menu_t *menu);
|
||||||
void view_browser_display (menu_t *menu, surface_t *display);
|
void view_browser_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_system_info_init (menu_t *menu);
|
|
||||||
void view_system_info_display (menu_t *menu, surface_t *display);
|
|
||||||
|
|
||||||
void view_file_info_init (menu_t *menu);
|
void view_file_info_init (menu_t *menu);
|
||||||
void view_file_info_display (menu_t *menu, surface_t *display);
|
void view_file_info_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
|
void view_system_info_init (menu_t *menu);
|
||||||
|
void view_system_info_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_image_viewer_init (menu_t *menu);
|
void view_image_viewer_init (menu_t *menu);
|
||||||
void view_image_viewer_display (menu_t *menu, surface_t *display);
|
void view_image_viewer_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
|
void view_text_viewer_init (menu_t *menu);
|
||||||
|
void view_text_viewer_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_music_player_init (menu_t *menu);
|
void view_music_player_init (menu_t *menu);
|
||||||
void view_music_player_display (menu_t *menu, surface_t *display);
|
void view_music_player_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_credits_init (menu_t *menu);
|
void view_credits_init (menu_t *menu);
|
||||||
void view_credits_display (menu_t *menu, surface_t *display);
|
void view_credits_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_load_rom_init (menu_t *menu);
|
|
||||||
void view_load_rom_display (menu_t *menu, surface_t *display);
|
|
||||||
|
|
||||||
void view_load_disk_init (menu_t *menu);
|
|
||||||
void view_load_disk_display (menu_t *menu, surface_t *display);
|
|
||||||
|
|
||||||
void view_settings_init (menu_t *menu);
|
void view_settings_init (menu_t *menu);
|
||||||
void view_settings_display (menu_t *menu, surface_t *display);
|
void view_settings_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_rtc_init (menu_t *menu);
|
void view_rtc_init (menu_t *menu);
|
||||||
void view_rtc_display (menu_t *menu, surface_t *display);
|
void view_rtc_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
|
void view_flashcart_info_init (menu_t *menu);
|
||||||
|
void view_flashcart_info_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
|
void view_load_rom_init (menu_t *menu);
|
||||||
|
void view_load_rom_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
|
void view_load_disk_init (menu_t *menu);
|
||||||
|
void view_load_disk_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
void view_load_emulator_init (menu_t *menu);
|
void view_load_emulator_init (menu_t *menu);
|
||||||
void view_load_emulator_display (menu_t *menu, surface_t *display);
|
void view_load_emulator_display (menu_t *menu, surface_t *display);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user