mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2025-02-17 02:26:26 +01:00
Merge branch 'main' into develop-gdb
This commit is contained in:
commit
60764ca6d0
@ -1,5 +1,6 @@
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
ARG SC64_DEPLOYER_VERSION=v2.18.0
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get install build-essential doxygen git python3 wget gdb-multiarch -y && \
|
||||
@ -7,9 +8,9 @@ RUN apt-get update && \
|
||||
wget https://github.com/DragonMinded/libdragon/releases/download/toolchain-continuous-prerelease/gcc-toolchain-mips64-x86_64.deb && \
|
||||
dpkg -i gcc-toolchain-mips64-x86_64.deb && \
|
||||
rm gcc-toolchain-mips64-x86_64.deb && \
|
||||
wget https://github.com/Polprzewodnikowy/SummerCart64/releases/download/v2.17.0/sc64-deployer-linux-v2.17.0.tar.gz && \
|
||||
tar -xf sc64-deployer-linux-v2.17.0.tar.gz -C /usr/local/bin && \
|
||||
rm sc64-deployer-linux-v2.17.0.tar.gz && \
|
||||
wget https://github.com/Polprzewodnikowy/SummerCart64/releases/download/$SC64_DEPLOYER_VERSION/sc64-deployer-linux-$SC64_DEPLOYER_VERSION.tar.gz && \
|
||||
tar -xf sc64-deployer-linux-$SC64_DEPLOYER_VERSION.tar.gz -C /usr/local/bin && \
|
||||
rm sc64-deployer-linux-$SC64_DEPLOYER_VERSION.tar.gz && \
|
||||
# wget https://github.com/buu342/N64-UNFLoader/releases/download/v2.1/UNFLoader-Linux-x64.zip && \
|
||||
# unzip UNFLoader-Linux-x64.zip -d /usr/local/unfloader && \
|
||||
# cp -f "/usr/local/unfloader/UNFLoader" "/usr/local/bin/UNFLoader"
|
||||
|
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -28,8 +28,8 @@ body:
|
||||
- type: input
|
||||
id: menu_version
|
||||
attributes:
|
||||
label: Menu version used
|
||||
description: The menu version used
|
||||
label: Menu revision used
|
||||
description: Press (Start) button on the menu to show the current menu version.
|
||||
placeholder: e.g 1.2.3.456, N/A
|
||||
validations:
|
||||
required: false
|
||||
|
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
@ -13,12 +13,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
FLAGS: -DNDEBUG
|
||||
|
||||
- name: Upload artifact (Standard ROM)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: N64FlashcartMenu
|
||||
path: |
|
||||
@ -45,25 +45,25 @@ jobs:
|
||||
./build/N64FlashcartMenu.elf
|
||||
|
||||
- name: Upload artifact (64drive version)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 64drive
|
||||
path: ./output/menu.bin
|
||||
|
||||
- name: Upload artifact (ED64 version)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ED64
|
||||
path: ./output/OS64.v64
|
||||
|
||||
- name: Upload artifact (ED64P version)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ED64P
|
||||
path: ./output/OS64P.v64
|
||||
|
||||
- name: Upload artifact (SC64 version)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SC64
|
||||
path: ./output/sc64menu.n64
|
||||
@ -97,7 +97,7 @@ jobs:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Doxygen
|
||||
uses: mattnotmitt/doxygen-action@1.9.5
|
||||
|
2
Makefile
2
Makefile
@ -61,6 +61,8 @@ SRCS = \
|
||||
menu/views/music_player.c \
|
||||
menu/views/startup.c \
|
||||
menu/views/system_info.c \
|
||||
menu/views/settings_editor.c \
|
||||
menu/views/rtc.c \
|
||||
utils/fs.c
|
||||
|
||||
FONTS = \
|
||||
|
10
README.md
10
README.md
@ -51,6 +51,10 @@ Menu currently supports the following emulators and associated ROM file names:
|
||||
- **Game Boy** / **GB Color**: [gb64](https://lambertjamesd.github.io/gb64/romwrapper/romwrapper.html) by *lambertjamesd* - `gb.v64` / `gbc.v64`
|
||||
- **Sega Master System** / **Sega Game Gear** / **Sg1000**: [TotalSMS](https://github.com/ITotalJustice/TotalSMS) - `TotalSMS.z64` (Currently broken)
|
||||
|
||||
### Menu Settings
|
||||
The Menu creates a `config.ini` file in `sd:/menu/` which contains various settings that are used by the menu.
|
||||
Currently these are read-only (can be viewed in the menu by pressing `L` on the Joypad).
|
||||
If required, you can manually adjust the file on the SD card using your computer.
|
||||
|
||||
### SC64 Specific
|
||||
- Ensure the cart has the latest [firmware](https://github.com/Polprzewodnikowy/SummerCart64/releases/latest) installed.
|
||||
@ -84,11 +88,11 @@ You can use a dev container in VSCode to ease development.
|
||||
|
||||
## To deploy:
|
||||
### SC64
|
||||
* Download the deployer [here](https://github.com/Polprzewodnikowy/SummerCart64/releases/download/v2.17.0/sc64-deployer-windows-v2.17.0.zip)
|
||||
* Download the deployer [here](https://github.com/Polprzewodnikowy/SummerCart64/releases/download/v2.18.0/sc64-deployer-windows-v2.18.0.zip)
|
||||
* Extract and place `sc64deployer.exe` in the `tools/sc64` directory.
|
||||
|
||||
Make sure that your firmware is compatible (currently v2.17.0+)
|
||||
See: [here](https://github.com/Polprzewodnikowy/SummerCart64/blob/v2.17.0/docs/00_quick_startup_guide.md#firmware-backupupdate)
|
||||
Make sure that your firmware is compatible (currently v2.18.0+)
|
||||
See: [here](https://github.com/Polprzewodnikowy/SummerCart64/blob/v2.18.0/docs/00_quick_startup_guide.md#firmware-backupupdate)
|
||||
|
||||
|
||||
#### From the devcontainer
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 92b4fcd070d7cd726bda4fe79d4ab6f1a78f4e6e
|
||||
Subproject commit 6323128d72fdf32dfaa134f40191ba72e5527076
|
@ -20,7 +20,6 @@ static void actions_clear (menu_t *menu) {
|
||||
menu->actions.enter = false;
|
||||
menu->actions.back = false;
|
||||
menu->actions.options = false;
|
||||
menu->actions.system_info = false;
|
||||
menu->actions.settings = false;
|
||||
}
|
||||
|
||||
@ -90,8 +89,6 @@ static void actions_update_buttons (menu_t *menu) {
|
||||
menu->actions.back = true;
|
||||
} else if (pressed.r) {
|
||||
menu->actions.options = true;
|
||||
} else if (pressed.l) {
|
||||
menu->actions.system_info = true;
|
||||
} else if (pressed.start) {
|
||||
menu->actions.settings = true;
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ static bool create_saves_subdirectory (path_t *path) {
|
||||
return error;
|
||||
}
|
||||
|
||||
static flashcart_save_type_t convert_save_type (rom_info_t *info) {
|
||||
switch (info->save_type) {
|
||||
static flashcart_save_type_t convert_save_type (rom_save_type_t save_type) {
|
||||
switch (save_type) {
|
||||
case SAVE_TYPE_EEPROM_4K: return FLASHCART_SAVE_TYPE_EEPROM_4K;
|
||||
case SAVE_TYPE_EEPROM_16K: return FLASHCART_SAVE_TYPE_EEPROM_16K;
|
||||
case SAVE_TYPE_SRAM: return FLASHCART_SAVE_TYPE_SRAM;
|
||||
@ -71,7 +71,7 @@ cart_load_err_t cart_load_n64_rom_and_save (menu_t *menu, flashcart_progress_cal
|
||||
path_t *path = path_clone(menu->load.rom_path);
|
||||
|
||||
bool byte_swap = (menu->load.rom_info.endianness == ENDIANNESS_BYTE_SWAP);
|
||||
flashcart_save_type_t save_type = convert_save_type(&menu->load.rom_info);
|
||||
flashcart_save_type_t save_type = convert_save_type(rom_info_get_save_type(&menu->load.rom_info));
|
||||
|
||||
menu->flashcart_err = flashcart_load_rom(path_get(path), byte_swap, progress);
|
||||
if (menu->flashcart_err != FLASHCART_OK) {
|
||||
|
@ -37,13 +37,16 @@ void component_background_draw (void);
|
||||
|
||||
void component_file_list_draw (entry_t *list, int entries, int selected);
|
||||
|
||||
typedef struct {
|
||||
typedef struct component_context_menu {
|
||||
int count;
|
||||
int selected;
|
||||
bool hide_pending;
|
||||
struct component_context_menu *parent;
|
||||
struct component_context_menu *submenu;
|
||||
struct {
|
||||
const char *text;
|
||||
void (*action) (menu_t *menu);
|
||||
struct component_context_menu *submenu;
|
||||
} list[];
|
||||
} component_context_menu_t;
|
||||
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "constants.h"
|
||||
#include "utils/fs.h"
|
||||
|
||||
|
||||
#ifndef BOXART_DIRECTORY
|
||||
#define BOXART_DIRECTORY "sd:/menu/boxart"
|
||||
#endif
|
||||
|
||||
|
||||
static void png_decoder_callback (png_err_t err, surface_t *decoded_image, void *callback_data) {
|
||||
|
@ -3,10 +3,19 @@
|
||||
#include "constants.h"
|
||||
|
||||
|
||||
static component_context_menu_t *get_current_submenu (component_context_menu_t *cm) {
|
||||
while (cm->submenu != NULL) {
|
||||
cm = cm->submenu;
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
|
||||
void component_context_menu_init (component_context_menu_t *cm) {
|
||||
cm->selected = -1;
|
||||
cm->count = 0;
|
||||
cm->hide_pending = false;
|
||||
cm->parent = NULL;
|
||||
for (int i = 0; (cm->list[i].text) != NULL; i++) {
|
||||
cm->count += 1;
|
||||
}
|
||||
@ -14,6 +23,7 @@ void component_context_menu_init (component_context_menu_t *cm) {
|
||||
|
||||
void component_context_menu_show (component_context_menu_t *cm) {
|
||||
cm->selected = 0;
|
||||
cm->submenu = NULL;
|
||||
}
|
||||
|
||||
bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) {
|
||||
@ -21,13 +31,26 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
||||
return false;
|
||||
}
|
||||
|
||||
component_context_menu_t *top = cm;
|
||||
|
||||
cm = get_current_submenu(cm);
|
||||
|
||||
if (menu->actions.back) {
|
||||
cm->hide_pending = true;
|
||||
} else if (menu->actions.enter) {
|
||||
if (cm->list[cm->selected].action) {
|
||||
cm->list[cm->selected].action(menu);
|
||||
if (cm->parent) {
|
||||
cm->parent->submenu = NULL;
|
||||
} else {
|
||||
cm->hide_pending = true;
|
||||
}
|
||||
} else if (menu->actions.enter) {
|
||||
if (cm->list[cm->selected].submenu) {
|
||||
cm->submenu = cm->list[cm->selected].submenu;
|
||||
component_context_menu_init(cm->submenu);
|
||||
cm->submenu->selected = 0;
|
||||
cm->submenu->parent = cm;
|
||||
} else if (cm->list[cm->selected].action) {
|
||||
cm->list[cm->selected].action(menu);
|
||||
top->hide_pending = true;
|
||||
}
|
||||
} else if (menu->actions.go_up) {
|
||||
cm->selected -= 1;
|
||||
if (cm->selected < 0) {
|
||||
@ -48,6 +71,10 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
return;
|
||||
}
|
||||
|
||||
component_context_menu_t *top = cm;
|
||||
|
||||
cm = get_current_submenu(cm);
|
||||
|
||||
rdpq_paragraph_builder_begin(
|
||||
&(rdpq_textparms_t) {
|
||||
.width = VISIBLE_AREA_WIDTH,
|
||||
@ -91,8 +118,8 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
||||
|
||||
rdpq_paragraph_free(layout);
|
||||
|
||||
if (cm->hide_pending) {
|
||||
cm->hide_pending = false;
|
||||
cm->selected = -1;
|
||||
if (top->hide_pending) {
|
||||
top->hide_pending = false;
|
||||
top->selected = -1;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ static void menu_init (boot_params_t *boot_params) {
|
||||
char *init_directory = default_directory_exists ? menu->settings.default_directory : "";
|
||||
|
||||
menu->browser.valid = false;
|
||||
menu->browser.reload = false;
|
||||
menu->browser.directory = path_init("sd:/", init_directory);
|
||||
|
||||
menu->load.rom_path = NULL;
|
||||
@ -146,6 +147,8 @@ static struct views_s {
|
||||
{ view_image_viewer_init, view_image_viewer_display }, // MENU_MODE_IMAGE_VIEWER
|
||||
{ view_music_player_init, view_music_player_display }, // MENU_MODE_MUSIC_PLAYER
|
||||
{ view_credits_init, view_credits_display }, // MENU_MODE_CREDITS
|
||||
{ view_settings_init, view_settings_display }, // MENU_MODE_SETTINGS_EDITOR
|
||||
{ view_rtc_init, view_rtc_display }, // MENU_MODE_RTC
|
||||
{ view_load_rom_init, view_load_rom_display }, // MENU_MODE_LOAD_ROM
|
||||
{ view_load_disk_init, view_load_disk_display }, // MENU_MODE_LOAD_DISK
|
||||
{ view_load_emulator_init, view_load_emulator_display }, // MENU_MODE_LOAD_EMULATOR
|
||||
|
@ -31,6 +31,8 @@ typedef enum {
|
||||
MENU_MODE_IMAGE_VIEWER,
|
||||
MENU_MODE_MUSIC_PLAYER,
|
||||
MENU_MODE_CREDITS,
|
||||
MENU_MODE_SETTINGS_EDITOR,
|
||||
MENU_MODE_RTC,
|
||||
MENU_MODE_LOAD_ROM,
|
||||
MENU_MODE_LOAD_DISK,
|
||||
MENU_MODE_LOAD_EMULATOR,
|
||||
@ -82,12 +84,12 @@ typedef struct {
|
||||
bool enter;
|
||||
bool back;
|
||||
bool options;
|
||||
bool system_info;
|
||||
bool settings;
|
||||
} actions;
|
||||
|
||||
struct {
|
||||
bool valid;
|
||||
bool reload;
|
||||
path_t *directory;
|
||||
entry_t list[BROWSER_LIST_SIZE];
|
||||
int entries;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <fatfs/ff.h>
|
||||
#include <mini.c/src/mini.h>
|
||||
|
||||
#include "rom_info.h"
|
||||
#include "utils/fs.h"
|
||||
@ -121,7 +122,7 @@ typedef struct {
|
||||
// Matched game metadata
|
||||
struct {
|
||||
// Save type (only cartridge save types)
|
||||
save_type_t save;
|
||||
rom_save_type_t save;
|
||||
|
||||
// Supported features
|
||||
feat_t feat;
|
||||
@ -659,6 +660,40 @@ static uint32_t fix_boot_address (cic_type_t cic_type, uint32_t boot_address) {
|
||||
}
|
||||
}
|
||||
|
||||
static rom_tv_type_t determine_tv_type (destination_type_t rom_destination_code) {
|
||||
// check the market type from the ROM destination_code and return best guess!
|
||||
switch (rom_destination_code) {
|
||||
case MARKET_NORTH_AMERICA:
|
||||
case MARKET_JAPANESE:
|
||||
case MARKET_JAPANESE_MULTI:
|
||||
case MARKET_GATEWAY64_NTSC:
|
||||
return ROM_TV_TYPE_NTSC;
|
||||
case MARKET_BRAZILIAN:
|
||||
return ROM_TV_TYPE_MPAL;
|
||||
case MARKET_GERMAN:
|
||||
case MARKET_FRENCH:
|
||||
case MARKET_DUTCH:
|
||||
case MARKET_ITALIAN:
|
||||
case MARKET_SPANISH:
|
||||
case MARKET_AUSTRALIAN:
|
||||
case MARKET_SCANDINAVIAN:
|
||||
case MARKET_GATEWAY64_PAL:
|
||||
case MARKET_EUROPEAN_BASIC:
|
||||
// FIXME: There might be some interesting errors with OTHER_X and OTHER_Y (e.g. TGR Asia).
|
||||
// But they are mainly PAL regions.
|
||||
case MARKET_OTHER_X:
|
||||
case MARKET_OTHER_Y:
|
||||
return ROM_TV_TYPE_PAL;
|
||||
// FIXME: We cannot be sure on these markets, so just return the default for the moment!
|
||||
case MARKET_CHINESE:
|
||||
case MARKET_CANADIAN:
|
||||
case MARKET_KOREAN:
|
||||
case MARKET_OTHER_Z:
|
||||
default:
|
||||
return ROM_TV_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info_t *rom_info) {
|
||||
rom_info->cic_type = cic_detect(rom_header->ipl3);
|
||||
|
||||
@ -688,6 +723,7 @@ static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info
|
||||
rom_info->version = rom_header->version;
|
||||
|
||||
rom_info->save_type = match->data.save;
|
||||
rom_info->tv_type = determine_tv_type(rom_info->destination_code);
|
||||
|
||||
rom_info->features.controller_pak = (match->data.feat & FEAT_CPAK);
|
||||
rom_info->features.rumble_pak = (match->data.feat & FEAT_RPAK);
|
||||
@ -709,13 +745,127 @@ static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info
|
||||
}
|
||||
}
|
||||
|
||||
static void load_overrides (path_t *path, rom_info_t *rom_info) {
|
||||
rom_info->override.save = false;
|
||||
rom_info->override.tv = false;
|
||||
|
||||
rom_err_t rom_info_load (char *path, rom_info_t *rom_info) {
|
||||
path_t *overrides_path = path_clone(path);
|
||||
|
||||
path_ext_replace(overrides_path, "ini");
|
||||
|
||||
if (!file_exists(path_get(overrides_path))) {
|
||||
path_free(overrides_path);
|
||||
return;
|
||||
}
|
||||
|
||||
mini_t *ini = mini_try_load(path_get(overrides_path));
|
||||
|
||||
rom_info->override.save_type = mini_get_int(ini, NULL, "save_type", SAVE_TYPE_AUTOMATIC);
|
||||
if (rom_info->override.save_type != SAVE_TYPE_AUTOMATIC) {
|
||||
rom_info->override.save = true;
|
||||
}
|
||||
|
||||
rom_info->override.tv_type = mini_get_int(ini, NULL, "tv_type", ROM_TV_TYPE_AUTOMATIC);
|
||||
if (rom_info->override.tv_type != ROM_TV_TYPE_AUTOMATIC) {
|
||||
rom_info->override.tv = true;
|
||||
}
|
||||
|
||||
mini_free(ini);
|
||||
|
||||
path_free(overrides_path);
|
||||
}
|
||||
|
||||
|
||||
rom_err_t rom_info_override_save_type (path_t *path, rom_info_t *rom_info, rom_save_type_t save_type) {
|
||||
path_t *overrides_path = path_clone(path);
|
||||
|
||||
path_ext_replace(overrides_path, "ini");
|
||||
|
||||
mini_t *ini = mini_try_load(path_get(overrides_path));
|
||||
|
||||
rom_info->override.save_type = save_type;
|
||||
|
||||
if (rom_info->override.save_type == SAVE_TYPE_AUTOMATIC) {
|
||||
rom_info->override.save = false;
|
||||
mini_delete_value(ini, NULL, "save_type");
|
||||
} else {
|
||||
rom_info->override.save = true;
|
||||
mini_set_int(ini, NULL, "save_type", rom_info->override.save_type);
|
||||
}
|
||||
|
||||
bool empty_override_file = mini_empty(ini);
|
||||
|
||||
if (!empty_override_file) {
|
||||
mini_save(ini, MINI_FLAGS_NONE);
|
||||
}
|
||||
|
||||
mini_free(ini);
|
||||
|
||||
if (empty_override_file) {
|
||||
file_delete(path_get(overrides_path));
|
||||
}
|
||||
|
||||
path_free(overrides_path);
|
||||
|
||||
return ROM_OK;
|
||||
}
|
||||
|
||||
rom_err_t rom_info_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type) {
|
||||
path_t *overrides_path = path_clone(path);
|
||||
|
||||
path_ext_replace(overrides_path, "ini");
|
||||
|
||||
mini_t *ini = mini_try_load(path_get(overrides_path));
|
||||
|
||||
rom_info->override.tv_type = tv_type;
|
||||
|
||||
if (rom_info->override.tv_type == ROM_TV_TYPE_AUTOMATIC) {
|
||||
rom_info->override.tv = false;
|
||||
mini_delete_value(ini, NULL, "tv_type");
|
||||
} else {
|
||||
rom_info->override.tv = true;
|
||||
mini_set_int(ini, NULL, "tv_type", rom_info->override.tv_type);
|
||||
}
|
||||
|
||||
bool empty_override_file = mini_empty(ini);
|
||||
|
||||
if (!empty_override_file) {
|
||||
mini_save(ini, MINI_FLAGS_NONE);
|
||||
}
|
||||
|
||||
mini_free(ini);
|
||||
|
||||
if (empty_override_file) {
|
||||
file_delete(path_get(overrides_path));
|
||||
}
|
||||
|
||||
path_free(overrides_path);
|
||||
|
||||
return ROM_OK;
|
||||
}
|
||||
|
||||
rom_save_type_t rom_info_get_save_type (rom_info_t *rom_info) {
|
||||
if (rom_info->override.save) {
|
||||
return rom_info->override.save_type;
|
||||
} else {
|
||||
return rom_info->save_type;
|
||||
}
|
||||
}
|
||||
|
||||
rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info) {
|
||||
if (rom_info->override.tv) {
|
||||
return rom_info->override.tv_type;
|
||||
} else {
|
||||
return rom_info->tv_type;
|
||||
}
|
||||
}
|
||||
|
||||
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info) {
|
||||
FIL fil;
|
||||
UINT br;
|
||||
rom_header_t rom_header;
|
||||
|
||||
if (f_open(&fil, strip_sd_prefix(path), FA_READ) != FR_OK) {
|
||||
if (f_open(&fil, strip_sd_prefix(path_get(path)), FA_READ) != FR_OK) {
|
||||
return ROM_ERR_NO_FILE;
|
||||
}
|
||||
if (f_read(&fil, &rom_header, sizeof(rom_header), &br) != FR_OK) {
|
||||
@ -735,5 +885,7 @@ rom_err_t rom_info_load (char *path, rom_info_t *rom_info) {
|
||||
|
||||
extract_rom_info(&match, &rom_header, rom_info);
|
||||
|
||||
load_overrides(path, rom_info);
|
||||
|
||||
return ROM_OK;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/cic.h"
|
||||
#include "path.h"
|
||||
|
||||
|
||||
/** @brief ROM error enumeration. */
|
||||
typedef enum {
|
||||
@ -100,7 +102,16 @@ typedef enum {
|
||||
SAVE_TYPE_SRAM_128K,
|
||||
SAVE_TYPE_FLASHRAM,
|
||||
SAVE_TYPE_FLASHRAM_PKST2,
|
||||
} save_type_t;
|
||||
SAVE_TYPE_AUTOMATIC = -1,
|
||||
} rom_save_type_t;
|
||||
|
||||
typedef enum {
|
||||
ROM_TV_TYPE_PAL,
|
||||
ROM_TV_TYPE_NTSC,
|
||||
ROM_TV_TYPE_MPAL,
|
||||
ROM_TV_TYPE_UNKNOWN,
|
||||
ROM_TV_TYPE_AUTOMATIC = -1,
|
||||
} rom_tv_type_t;
|
||||
|
||||
/** @brief ROM memory requirements enumeration. */
|
||||
typedef enum {
|
||||
@ -156,7 +167,17 @@ typedef struct {
|
||||
cic_type_t cic_type;
|
||||
|
||||
/** @brief The save type required by the ROM. */
|
||||
save_type_t save_type;
|
||||
rom_save_type_t save_type;
|
||||
|
||||
rom_tv_type_t tv_type;
|
||||
|
||||
struct {
|
||||
bool save;
|
||||
rom_save_type_t save_type;
|
||||
|
||||
bool tv;
|
||||
rom_tv_type_t tv_type;
|
||||
} override;
|
||||
|
||||
/** @brief The supported ROM accessories. */
|
||||
struct {
|
||||
@ -172,7 +193,11 @@ typedef struct {
|
||||
} rom_info_t;
|
||||
|
||||
|
||||
rom_err_t rom_info_load (char *path, rom_info_t *rom_info);
|
||||
rom_err_t rom_info_override_save_type (path_t *path, rom_info_t *rom_info, rom_save_type_t save_type);
|
||||
rom_err_t rom_info_override_tv_type (path_t *path, rom_info_t *rom_info, rom_tv_type_t tv_type);
|
||||
rom_save_type_t rom_info_get_save_type (rom_info_t *rom_info);
|
||||
rom_tv_type_t rom_info_get_tv_type (rom_info_t *rom_info);
|
||||
rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -4,16 +4,17 @@
|
||||
#include "settings.h"
|
||||
#include "utils/fs.h"
|
||||
|
||||
|
||||
#ifndef SETTINGS_FILE_PATH
|
||||
#define SETTINGS_FILE_PATH "sd:/menu/config.ini"
|
||||
#endif
|
||||
|
||||
|
||||
static settings_t init = {
|
||||
.pal60_enabled = false,
|
||||
.hidden_files_enabled = false,
|
||||
.default_directory = "/",
|
||||
.use_saves_folder = true,
|
||||
.autodetect_rom_region = true,
|
||||
|
||||
/* Beta feature flags (should always init to off) */
|
||||
.bgm_enabled = false,
|
||||
@ -33,14 +34,12 @@ void settings_load (settings_t *settings) {
|
||||
settings->hidden_files_enabled = mini_get_bool(ini, "menu", "show_hidden_files", init.hidden_files_enabled);
|
||||
settings->default_directory = strdup(mini_get_string(ini, "menu", "default_directory", init.default_directory));
|
||||
settings->use_saves_folder = mini_get_bool(ini, "menu", "use_saves_folder", init.use_saves_folder);
|
||||
settings->autodetect_rom_region = mini_get_bool(ini, "menu", "autodetect_rom_region", init.autodetect_rom_region);
|
||||
|
||||
/* Beta feature flags, they might not be in the file */
|
||||
settings->bgm_enabled = mini_get_bool(ini, "menu_beta_flag", "bgm_enabled", init.bgm_enabled);
|
||||
settings->sound_enabled = mini_get_bool(ini, "menu_beta_flag", "sound_enabled", init.sound_enabled);
|
||||
settings->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled);
|
||||
|
||||
|
||||
mini_free(ini);
|
||||
}
|
||||
|
||||
@ -51,7 +50,6 @@ void settings_save (settings_t *settings) {
|
||||
mini_set_bool(ini, "menu", "show_hidden_files", settings->hidden_files_enabled);
|
||||
mini_set_string(ini, "menu", "default_directory", settings->default_directory);
|
||||
mini_set_bool(ini, "menu", "use_saves_folder", settings->use_saves_folder);
|
||||
mini_set_bool(ini, "menu", "autodetect_rom_region", settings->autodetect_rom_region);
|
||||
|
||||
/* Beta feature flags, they should not save until production ready! */
|
||||
// mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled);
|
||||
|
@ -22,9 +22,6 @@ typedef struct {
|
||||
/** @brief Put saves into separate directory */
|
||||
bool use_saves_folder;
|
||||
|
||||
/** @brief Enable forcing the (N64 system region) tv type to align with game region when booting the ROM. */
|
||||
bool autodetect_rom_region;
|
||||
|
||||
/** @brief Enable Background music */
|
||||
bool bgm_enabled;
|
||||
|
||||
@ -33,9 +30,9 @@ typedef struct {
|
||||
|
||||
/** @brief Enable rumble feedback */
|
||||
bool rumble_enabled;
|
||||
|
||||
} settings_t;
|
||||
|
||||
|
||||
/** @brief The settings to load */
|
||||
void settings_load (settings_t *settings);
|
||||
/** @brief The settings to save */
|
||||
|
@ -228,11 +228,41 @@ static component_context_menu_t entry_context_menu = {
|
||||
}
|
||||
};
|
||||
|
||||
static void edit_settings (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_SETTINGS_EDITOR;
|
||||
}
|
||||
|
||||
static void show_system_info (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_SYSTEM_INFO;
|
||||
}
|
||||
|
||||
static void show_credits (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_CREDITS;
|
||||
}
|
||||
|
||||
static void edit_rtc (menu_t *menu) {
|
||||
menu->next_mode = MENU_MODE_RTC;
|
||||
}
|
||||
|
||||
static component_context_menu_t settings_context_menu = {
|
||||
.list = {
|
||||
{ .text = "Edit settings", .action = edit_settings },
|
||||
{ .text = "Show system info", .action = show_system_info },
|
||||
{ .text = "Show credits", .action = show_credits },
|
||||
{ .text = "Adjust RTC", .action = edit_rtc },
|
||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||
}
|
||||
};
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (component_context_menu_process(menu, &entry_context_menu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (component_context_menu_process(menu, &settings_context_menu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int scroll_speed = menu->actions.go_fast ? 10 : 1;
|
||||
|
||||
if (menu->browser.entries > 1) {
|
||||
@ -284,10 +314,8 @@ static void process (menu_t *menu) {
|
||||
}
|
||||
} else if (menu->actions.options && menu->browser.entry) {
|
||||
component_context_menu_show(&entry_context_menu);
|
||||
} else if (menu->actions.system_info) {
|
||||
menu->next_mode = MENU_MODE_SYSTEM_INFO;
|
||||
} else if (menu->actions.settings) {
|
||||
menu->next_mode = MENU_MODE_CREDITS;
|
||||
component_context_menu_show(&settings_context_menu);
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,9 +352,9 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_RIGHT, VALIGN_TOP,
|
||||
"%s\n"
|
||||
"L: Settings",
|
||||
menu->browser.entries == 0 ? "" : "R: Options"
|
||||
"Start: Settings\n"
|
||||
"^%02XR: Options^00",
|
||||
menu->browser.entries == 0 ? STL_UNKNOWN : STL_DEFAULT
|
||||
);
|
||||
|
||||
if (menu->current_time >= 0) {
|
||||
@ -340,6 +368,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
|
||||
component_context_menu_draw(&entry_context_menu);
|
||||
|
||||
component_context_menu_draw(&settings_context_menu);
|
||||
|
||||
rdpq_detach_show();
|
||||
}
|
||||
|
||||
@ -347,6 +377,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
void view_browser_init (menu_t *menu) {
|
||||
if (!menu->browser.valid) {
|
||||
component_context_menu_init(&entry_context_menu);
|
||||
component_context_menu_init(&settings_context_menu);
|
||||
if (load_directory(menu)) {
|
||||
path_free(menu->browser.directory);
|
||||
menu->browser.directory = path_init("sd:/", "");
|
||||
@ -355,6 +386,20 @@ void view_browser_init (menu_t *menu) {
|
||||
menu->browser.valid = true;
|
||||
}
|
||||
}
|
||||
if (menu->browser.reload) {
|
||||
menu->browser.reload = false;
|
||||
int selected = menu->browser.selected;
|
||||
if (load_directory(menu)) {
|
||||
menu_show_error(menu, "Error while reloading current directory");
|
||||
menu->browser.valid = false;
|
||||
} else {
|
||||
menu->browser.selected = selected;
|
||||
if (menu->browser.selected >= menu->browser.entries) {
|
||||
menu->browser.selected = menu->browser.entries - 1;
|
||||
}
|
||||
menu->browser.entry = menu->browser.selected >= 0 ? &menu->browser.list[menu->browser.selected] : NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void view_browser_display (menu_t *menu, surface_t *display) {
|
||||
|
@ -33,7 +33,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
"Github:\n"
|
||||
" https://github.com/Polprzewodnikowy/N64FlashcartMenu\n"
|
||||
"Authors:\n"
|
||||
" JonesAlmighty / NetworkFusion\n"
|
||||
" Robin Jones / NetworkFusion\n"
|
||||
" Mateusz Faderewski / Polprzewodnikowy\n"
|
||||
"Credits:\n"
|
||||
" N64Brew / libdragon contributors\n"
|
||||
|
@ -64,7 +64,7 @@ static const char *format_rom_destination_market (destination_type_t market_type
|
||||
}
|
||||
}
|
||||
|
||||
static const char *format_rom_save_type (save_type_t save_type) {
|
||||
static const char *format_rom_save_type (rom_save_type_t save_type) {
|
||||
switch (save_type) {
|
||||
case SAVE_TYPE_NONE: return "None";
|
||||
case SAVE_TYPE_EEPROM_4K: return "EEPROM 4K";
|
||||
@ -78,6 +78,15 @@ static const char *format_rom_save_type (save_type_t save_type) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char *format_rom_tv_type (rom_tv_type_t tv_type) {
|
||||
switch (tv_type) {
|
||||
case ROM_TV_TYPE_PAL: return "PAL";
|
||||
case ROM_TV_TYPE_NTSC: return "NTSC";
|
||||
case ROM_TV_TYPE_MPAL: return "MPAL";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static char *format_rom_expansion_pak_info (expansion_pak_t expansion_pak_info) {
|
||||
switch (expansion_pak_info) {
|
||||
case EXPANSION_PAK_REQUIRED: return "Required";
|
||||
@ -107,46 +116,67 @@ static const char *format_cic_type (cic_type_t cic_type) {
|
||||
}
|
||||
}
|
||||
|
||||
static boot_tv_type_t determine_tv_boot_type (destination_type_t rom_destination_code) {
|
||||
// check the market type from the ROM destination_code and return best guess!
|
||||
switch (rom_destination_code) {
|
||||
case MARKET_NORTH_AMERICA:
|
||||
case MARKET_JAPANESE:
|
||||
case MARKET_JAPANESE_MULTI:
|
||||
case MARKET_GATEWAY64_NTSC:
|
||||
return BOOT_TV_TYPE_NTSC;
|
||||
case MARKET_BRAZILIAN:
|
||||
return BOOT_TV_TYPE_MPAL;
|
||||
case MARKET_GERMAN:
|
||||
case MARKET_FRENCH:
|
||||
case MARKET_DUTCH:
|
||||
case MARKET_ITALIAN:
|
||||
case MARKET_SPANISH:
|
||||
case MARKET_AUSTRALIAN:
|
||||
case MARKET_SCANDINAVIAN:
|
||||
case MARKET_GATEWAY64_PAL:
|
||||
case MARKET_EUROPEAN_BASIC:
|
||||
// FIXME: There might be some interesting errors with OTHER_X and OTHER_Y (e.g. TGR Asia).
|
||||
// But they are mainly PAL regions.
|
||||
case MARKET_OTHER_X:
|
||||
case MARKET_OTHER_Y:
|
||||
return BOOT_TV_TYPE_PAL;
|
||||
// FIXME: We cannot be sure on these markets, so just return the default for the moment!
|
||||
case MARKET_CHINESE:
|
||||
case MARKET_CANADIAN:
|
||||
case MARKET_KOREAN:
|
||||
case MARKET_OTHER_Z:
|
||||
default:
|
||||
return BOOT_TV_TYPE_PASSTHROUGH;
|
||||
}
|
||||
static void set_save_type (menu_t *menu, rom_save_type_t save_type) {
|
||||
rom_info_override_save_type(menu->load.rom_path, &menu->load.rom_info, save_type);
|
||||
menu->browser.reload = true;
|
||||
}
|
||||
|
||||
static void set_save_type_automatic (menu_t *menu) { set_save_type(menu, SAVE_TYPE_AUTOMATIC); }
|
||||
static void set_save_type_none (menu_t *menu) { set_save_type(menu, SAVE_TYPE_NONE); }
|
||||
static void set_save_type_eeprom_4kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_EEPROM_4K); }
|
||||
static void set_save_type_eeprom_16kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_EEPROM_16K); }
|
||||
static void set_save_type_sram_256kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM); }
|
||||
static void set_save_type_sram_768kbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM_BANKED); }
|
||||
static void set_save_type_sram_1mbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_SRAM_128K); }
|
||||
static void set_save_type_flash_ram_1mbit (menu_t *menu) { set_save_type(menu, SAVE_TYPE_FLASHRAM); }
|
||||
|
||||
static component_context_menu_t set_save_type_context_menu = { .list = {
|
||||
{ .text = "Automatic", .action = set_save_type_automatic },
|
||||
{ .text = "None", .action = set_save_type_none },
|
||||
{ .text = "EEPROM 4kbit", .action = set_save_type_eeprom_4kbit },
|
||||
{ .text = "EEPROM 16kbit", .action = set_save_type_eeprom_16kbit },
|
||||
{ .text = "SRAM 256kbit", .action = set_save_type_sram_256kbit },
|
||||
{ .text = "SRAM 768kbit", .action = set_save_type_sram_768kbit },
|
||||
{ .text = "SRAM 1Mbit", .action = set_save_type_sram_1mbit },
|
||||
{ .text = "FlashRAM 1Mbit", .action = set_save_type_flash_ram_1mbit },
|
||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||
}};
|
||||
|
||||
static void set_tv_type (menu_t *menu, rom_tv_type_t tv_type) {
|
||||
rom_info_override_tv_type(menu->load.rom_path, &menu->load.rom_info, tv_type);
|
||||
menu->browser.reload = true;
|
||||
}
|
||||
|
||||
static void set_tv_type_automatic (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_AUTOMATIC); }
|
||||
static void set_tv_type_pal (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_PAL); }
|
||||
static void set_tv_type_ntsc (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_NTSC); }
|
||||
static void set_tv_type_mpal (menu_t *menu) { set_tv_type(menu, ROM_TV_TYPE_MPAL); }
|
||||
|
||||
static component_context_menu_t set_tv_type_context_menu = { .list = {
|
||||
{ .text = "Automatic", .action = set_tv_type_automatic },
|
||||
{ .text = "PAL", .action = set_tv_type_pal },
|
||||
{ .text = "NTSC", .action = set_tv_type_ntsc },
|
||||
{ .text = "MPAL", .action = set_tv_type_mpal },
|
||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||
}};
|
||||
|
||||
static component_context_menu_t options_context_menu = { .list = {
|
||||
{ .text = "Set save type", .submenu = &set_save_type_context_menu },
|
||||
{ .text = "Set TV type", .submenu = &set_tv_type_context_menu },
|
||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||
}};
|
||||
|
||||
static void process (menu_t *menu) {
|
||||
if (component_context_menu_process(menu, &options_context_menu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (menu->actions.enter) {
|
||||
load_pending = true;
|
||||
} else if (menu->actions.back) {
|
||||
menu->next_mode = MENU_MODE_BROWSER;
|
||||
} else if (menu->actions.options) {
|
||||
component_context_menu_show(&options_context_menu);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,6 +212,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
" Version: %hhu\n"
|
||||
" Check code: 0x%016llX\n"
|
||||
" Save type: %s\n"
|
||||
" TV type: %s\n"
|
||||
" Expansion PAK: %s\n"
|
||||
"\n"
|
||||
" Extra information:\n"
|
||||
@ -196,7 +227,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
format_rom_destination_market(menu->load.rom_info.destination_code),
|
||||
menu->load.rom_info.version,
|
||||
menu->load.rom_info.check_code,
|
||||
format_rom_save_type(menu->load.rom_info.save_type),
|
||||
format_rom_save_type(rom_info_get_save_type(&menu->load.rom_info)),
|
||||
format_rom_tv_type(rom_info_get_tv_type(&menu->load.rom_info)),
|
||||
format_rom_expansion_pak_info(menu->load.rom_info.features.expansion_pak),
|
||||
format_cic_type(menu->load.rom_info.cic_type),
|
||||
menu->load.rom_info.boot_address,
|
||||
@ -210,7 +242,15 @@ static void draw (menu_t *menu, surface_t *d) {
|
||||
"B: Exit"
|
||||
);
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_RIGHT, VALIGN_TOP,
|
||||
"\n"
|
||||
"R: Options"
|
||||
);
|
||||
|
||||
component_boxart_draw(boxart);
|
||||
|
||||
component_context_menu_draw(&options_context_menu);
|
||||
}
|
||||
|
||||
rdpq_detach_show();
|
||||
@ -239,14 +279,14 @@ static void load (menu_t *menu) {
|
||||
}
|
||||
|
||||
menu->next_mode = MENU_MODE_BOOT;
|
||||
|
||||
menu->boot_params->device_type = BOOT_DEVICE_TYPE_ROM;
|
||||
menu->boot_params->detect_cic_seed = true;
|
||||
|
||||
if (menu->settings.autodetect_rom_region) {
|
||||
menu->boot_params->tv_type = determine_tv_boot_type(menu->load.rom_info.destination_code);
|
||||
}
|
||||
else {
|
||||
menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH;
|
||||
switch(rom_info_get_tv_type(&menu->load.rom_info)) {
|
||||
case ROM_TV_TYPE_PAL: menu->boot_params->tv_type = BOOT_TV_TYPE_PAL; break;
|
||||
case ROM_TV_TYPE_NTSC: menu->boot_params->tv_type = BOOT_TV_TYPE_NTSC; break;
|
||||
case ROM_TV_TYPE_MPAL: menu->boot_params->tv_type = BOOT_TV_TYPE_MPAL; break;
|
||||
default: menu->boot_params->tv_type = BOOT_TV_TYPE_PASSTHROUGH; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,12 +305,14 @@ void view_load_rom_init (menu_t *menu) {
|
||||
|
||||
menu->load.rom_path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
|
||||
|
||||
rom_err_t err = rom_info_load(path_get(menu->load.rom_path), &menu->load.rom_info);
|
||||
rom_err_t err = rom_info_load(menu->load.rom_path, &menu->load.rom_info);
|
||||
if (err != ROM_OK) {
|
||||
menu_show_error(menu, convert_error_message(err));
|
||||
}
|
||||
|
||||
boxart = component_boxart_init(menu->load.rom_info.game_code);
|
||||
|
||||
component_context_menu_init(&options_context_menu);
|
||||
}
|
||||
|
||||
void view_load_rom_display (menu_t *menu, surface_t *display) {
|
||||
|
66
src/menu/views/rtc.c
Normal file
66
src/menu/views/rtc.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include <time.h>
|
||||
#include "views.h"
|
||||
|
||||
// FIXME: add implementation!
|
||||
// struct {
|
||||
// uint16_t seconds;
|
||||
// uint16_t minutes;
|
||||
// uint16_t hours;
|
||||
// uint16_t day;
|
||||
// uint16_t month;
|
||||
// uint16_t year;
|
||||
// } adjusted_datetime;
|
||||
|
||||
// static void save_adjusted_datetime () {
|
||||
|
||||
// }
|
||||
|
||||
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,
|
||||
"ADJUST REAL TIME CLOCK\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"To set the date and time, please use the PC terminal\n"
|
||||
"application and set via USB.\n\n"
|
||||
"Current date & time: %s\n",
|
||||
menu->current_time >= 0 ? ctime(&menu->current_time) : "Unknown\n"
|
||||
);
|
||||
|
||||
component_main_text_draw(
|
||||
ALIGN_LEFT, VALIGN_TOP,
|
||||
"\n"
|
||||
"\n"
|
||||
);
|
||||
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_LEFT, VALIGN_TOP,
|
||||
"\n" // "A: Save\n"
|
||||
"B: Back"
|
||||
);
|
||||
|
||||
rdpq_detach_show();
|
||||
}
|
||||
|
||||
|
||||
void view_rtc_init (menu_t *menu) {
|
||||
// Nothing to initialize (yet)
|
||||
}
|
||||
|
||||
void view_rtc_display (menu_t *menu, surface_t *display) {
|
||||
process(menu);
|
||||
draw(menu, display);
|
||||
}
|
70
src/menu/views/settings_editor.c
Normal file
70
src/menu/views/settings_editor.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include "views.h"
|
||||
|
||||
static char *format_boolean_type (int state) {
|
||||
switch (state) {
|
||||
case 0: return "Off";
|
||||
case 1: return "On";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
"SETTINGS EDITOR\n"
|
||||
"\n"
|
||||
);
|
||||
|
||||
component_main_text_draw(
|
||||
ALIGN_LEFT, VALIGN_TOP,
|
||||
"\n"
|
||||
"\n"
|
||||
"To change the settings, please adjust them\n"
|
||||
"directly in the 'menu/config.ini' file.\n\n"
|
||||
"pal60_enabled: %s\n"
|
||||
"hidden_files_enabled: %s\n"
|
||||
"default_directory: %s\n"
|
||||
"use_saves_folder: %s\n"
|
||||
"bgm_enabled: %s\n"
|
||||
"sound_enabled: %s\n"
|
||||
"rumble_enabled: %s\n",
|
||||
format_boolean_type(menu->settings.pal60_enabled),
|
||||
format_boolean_type(menu->settings.hidden_files_enabled),
|
||||
menu->settings.default_directory,
|
||||
format_boolean_type(menu->settings.use_saves_folder),
|
||||
format_boolean_type(menu->settings.bgm_enabled),
|
||||
format_boolean_type(menu->settings.sound_enabled),
|
||||
format_boolean_type(menu->settings.rumble_enabled)
|
||||
);
|
||||
|
||||
|
||||
component_actions_bar_text_draw(
|
||||
ALIGN_LEFT, VALIGN_TOP,
|
||||
"\n"
|
||||
"B: Back"
|
||||
);
|
||||
|
||||
rdpq_detach_show();
|
||||
}
|
||||
|
||||
|
||||
void view_settings_init (menu_t *menu) {
|
||||
// Nothing to initialize (yet)
|
||||
}
|
||||
|
||||
void view_settings_display (menu_t *menu, surface_t *display) {
|
||||
process(menu);
|
||||
draw(menu, display);
|
||||
}
|
@ -44,6 +44,12 @@ 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_display (menu_t *menu, surface_t *display);
|
||||
|
||||
void view_rtc_init (menu_t *menu);
|
||||
void view_rtc_display (menu_t *menu, surface_t *display);
|
||||
|
||||
void view_load_emulator_init (menu_t *menu);
|
||||
void view_load_emulator_display (menu_t *menu, surface_t *display);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user