From 3e1dc3436916ddadeeff68ca70450c891d0ec48c Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 24 Feb 2023 14:24:59 +0000 Subject: [PATCH] Split out settings --- .github/workflows/build.yml | 46 +++++----- Makefile | 1 + README.md | 11 +++ src/libs/menu_utils/README.md | 2 + src/libs/menu_utils/src/menu.c | 4 +- src/main.c | 12 ++- src/menu/menu.c | 116 +++--------------------- src/menu/menu.h | 13 +-- src/menu/settings.c | 161 +++++++++++++++++++++++++++++++++ src/menu/settings.h | 38 ++++++++ 10 files changed, 259 insertions(+), 145 deletions(-) create mode 100644 src/menu/settings.c create mode 100644 src/menu/settings.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c07e111..f91e18b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,13 +33,18 @@ jobs: run: | cd ./libdragon # FIXME: this currently also builds the examples which adds to the build time. - ./build.sh # release --force-clean + # ./build.sh + # WORKAROUND: for CI + make -j libdragon + make install + make -j tools + make tools-install + make install-mk - - name: Build rom + - name: Build N64FlashcartMenu ROM run: | - # chmod +x build.sh - # ./build.sh # release --force-clean mkdir build + # TODO: split this to use params for each flashcart type. make -j all - name: Upload artifact @@ -48,9 +53,8 @@ jobs: name: N64FlashcartMenu path: | ./build/N64FlashcartMenu.z64 - if-no-files-found: ignore - finalize: + finalize-sc64-menu: runs-on: ubuntu-latest needs: build @@ -76,30 +80,24 @@ jobs: run: | cd ./build python ../tools/finalize.py N64FlashcartMenu.z64 - continue-on-error: true + continue-on-error: false - name: Upload artifact uses: actions/upload-artifact@v3 with: - name: N64FlashcartMenu + name: SC64-Menu path: | ./build/sc64menu.n64 if-no-files-found: ignore - # - name: Get release - # if: github.event_name == 'release' && github.event.action == 'created' - # id: get_release - # uses: bruceadams/get-release@v1.3.2 - # env: - # GITHUB_TOKEN: ${{ github.token }} - # - name: Upload release asset - # if: github.event_name == 'release' && github.event.action == 'created' - # uses: actions/upload-release-asset@v1 # This will start failing soon due to needing node 12! - # env: - # GITHUB_TOKEN: ${{ github.token }} - # with: - # upload_url: ${{ steps.get_release.outputs.upload_url }} - # asset_path: ./build/sc64menu.n64 - # asset_name: sc64menu - # asset_content_type: application/zip + # release-sc64-menu: + # runs-on: ubuntu-latest + # needs: finalize-sc64-menu + + # steps: + # - name: Generate release + # if: github.event_name == 'release' && github.event.action == 'created' + # run: | + # echo "still release preview. Check actions for build assets." + diff --git a/Makefile b/Makefile index 7c26572b..f28cad1a 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ SRCS = \ flashcart/sc64/sc64_internal.c \ flashcart/sc64/sc64.c \ menu/menu.c \ + menu/settings.c \ utils/fs.c \ libs/toml/toml.c \ libs/menu_utils/src/menu.c \ diff --git a/README.md b/README.md index 1b9ec1d7..d99535f6 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,17 @@ Add the following content, replacing the comments. save_path = "" save_type = auto_load = + save_writeback = false + +[last_state] + auto_load_last_rom = false + current_directory = "sd://" + +[boot_params] + device_type = 0; + reset_type = 1; + detect_tv_type = true; + detect_cic_seed = true; ``` Save it to the root folder on your SD card. diff --git a/src/libs/menu_utils/README.md b/src/libs/menu_utils/README.md index 856c589a..8c92838f 100644 --- a/src/libs/menu_utils/README.md +++ b/src/libs/menu_utils/README.md @@ -9,3 +9,5 @@ Used for generating the menu GUI # Notes It might be preferable to change to a submodule. +Changed rdp_detach_display() to rdp_detach() +Changed rdp_attach_display(disp) to rdp_attach(disp) as per deprecated warnings. \ No newline at end of file diff --git a/src/libs/menu_utils/src/menu.c b/src/libs/menu_utils/src/menu.c index 5daf341a..a438fb56 100644 --- a/src/libs/menu_utils/src/menu.c +++ b/src/libs/menu_utils/src/menu.c @@ -354,7 +354,7 @@ void menu_draw_background_center(display_context_t disp, int top, int left, int rdp_sync(SYNC_PIPE); - rdp_attach_display(disp); + rdp_attach(disp); rdp_enable_blend_fill(); rdp_set_default_clipping(); @@ -363,7 +363,7 @@ void menu_draw_background_center(display_context_t disp, int top, int left, int rdp_draw_filled_triangle(left, top, right, top, right, bottom); rdp_draw_filled_triangle(left, top, left, bottom, right, bottom); - rdp_detach_display(); + rdp_detach(); } void menu_scroll_fix_y(Menu *menu) { diff --git a/src/main.c b/src/main.c index b228d833..4bce174d 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include "boot/boot.h" #include "flashcart/flashcart.h" +#include "menu/settings.h" #include "menu/menu.h" @@ -28,19 +29,22 @@ static void deinit (void) { int main (void) { - menu_t menu; init(); + settings_t settings; + settings_load_default_state(&settings); + settings_load_from_file(&settings); + if (boot_is_warm()) { - menu_restore(&menu); + menu_restore(&settings); } - menu_run(&menu); + menu_run(&settings); deinit(); - boot(&menu.boot_params); + boot(&settings.boot_params); return 1; } diff --git a/src/menu/menu.c b/src/menu/menu.c index 6154a13c..86d2c095 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -7,100 +7,11 @@ #include #include "flashcart/flashcart.h" -#include "libs/toml/toml.h" +#include "settings.h" #include "menu.h" - -#define SC64_CONFIG_FILEPATH "sd://config.sc64.toml.txt" -static toml_datum_t rom_path; -static toml_datum_t save_path; -static flashcart_save_type_t save_type = FLASHCART_SAVE_TYPE_NONE; -static bool save_writeback = false; -static bool auto_load_last_rom = false; - - -static void load_config (void) { - FILE *fp = NULL; - char error_buffer[266]; - - printf("Loading config file %s\n", SC64_CONFIG_FILEPATH); - wait_ms(1000); - - fp = fopen(SC64_CONFIG_FILEPATH, "r"); - if (!fp) { - printf("Error loading config file %s\n", SC64_CONFIG_FILEPATH); - wait_ms(10000); - assertf(!fp, "Couldn't open toml config file: %s", SC64_CONFIG_FILEPATH); - - // TODO: generate a default config file. - } - - toml_table_t* conf = toml_parse_file(fp, error_buffer, sizeof(error_buffer)); - if (!conf) { - printf("Error parsing config: %s\n", error_buffer); - wait_ms(10000); - //assertf(!conf, "Couldn't parse toml config: %s", error_buffer); - } - - fclose(fp); - //assertf(!fclose(fp), "Couldn't close toml config file"); - fp = NULL; - - toml_table_t* last_rom = toml_table_in(conf, "last_rom"); - if (!last_rom) { - printf("Missing '[last_rom]' header in config\n"); - wait_ms(10000); - //assertf(!last_rom, "Missing '[last_rom]' header in config"); - } - - rom_path = toml_string_in(last_rom, "rom_path"); - if (!rom_path.ok) { - printf("Couldn't read 'rom_path' value in config\n"); - wait_ms(10000); - //assertf(!rom_path.ok, "Couldn't read 'rom_path' value in config\n"); - } - else { - printf("Found rom path: %s\n", rom_path.u.s ); - } - - save_path = toml_string_in(last_rom, "save_path"); - if (!save_path.ok) { - printf("Couldn't read 'save_path' value in config\n"); - wait_ms(10000); - //assertf(!save_path.ok, "Couldn't read 'save_path' value in config"); - } - else { - printf("Found save path: %s\n", save_path.u.s ); - } - - toml_datum_t tmp_save_type = toml_int_in(last_rom, "save_type"); - if (!tmp_save_type.ok) { - printf("Couldn't read 'save_type' value in config\n"); - wait_ms(10000); - //assertf(!tmp_save_type.ok, "Couldn't read 'save_type' int value in config"); - } - else { - printf("Found save type: %d\n", (int)tmp_save_type.u.i ); - } - assertf((int)tmp_save_type.u.i < __FLASHCART_SAVE_TYPE_END, "Invalid save type in config file"); - save_type = (int)tmp_save_type.u.i; - - toml_datum_t tmp_auto_load_last_rom = toml_bool_in(last_rom, "auto_load"); - if (!tmp_auto_load_last_rom.ok) { - printf("Couldn't read 'auto_load' value in config\n"); - wait_ms(5000); - } - else { - printf("Found autoload: %s\n", tmp_auto_load_last_rom.u.b ? "true" : "false"); - auto_load_last_rom = tmp_auto_load_last_rom.u.b; - } - - toml_free(conf); - -} - -void menu_restore (menu_t *menu) { +void menu_restore (settings_t *settings) { // TODO: restore last menu state from SD card } @@ -135,35 +46,32 @@ FRESULT scan_files ( return res; } -void menu_run (menu_t *menu) { +void menu_run (settings_t *settings) { // TODO: implement nice user interface here console_init(); console_set_debug(true); - load_config(); + if (settings->last_state.auto_load_last_rom) { // TODO: check if there is a button input to cancel. - if (auto_load_last_rom) { // TODO: check if there is a button input to cancel. + printf("Loading last ROM: %s\n", settings->last_rom.rom_path); + assertf(flashcart_load_rom(settings->last_rom.rom_path) == FLASHCART_OK, "ROM load error"); - printf("Loading last ROM: %s\n", rom_path.u.s); - assertf(flashcart_load_rom(rom_path.u.s) == FLASHCART_OK, "ROM load error"); - - printf("Loading save: %s, type: %d, writeback: %d\n", save_path.u.s, save_type, save_writeback); - assertf(flashcart_load_save(save_path.u.s, save_type, save_writeback) == FLASHCART_OK, "Save load error"); + printf("Loading save: %s, type: %d, writeback: %d\n", settings->last_rom.save_path, settings->last_rom.save_type, settings->last_rom.save_writeback); + assertf(flashcart_load_save(settings->last_rom.save_path, settings->last_rom.save_type, settings->last_rom.save_writeback) == FLASHCART_OK, "Save load error"); } else { printf("N64 Flashcart Menu\n\n"); printf("File list:\n"); char buff[256]; strcpy(buff, "/"); - scan_files(buff); + scan_files(buff); // TODO: use current_directory // TODO: wait for a key input + for (;;) { + wait_ms(1000); + } } // TODO: write menu state to SD card - menu->boot_params.device_type = BOOT_DEVICE_TYPE_ROM; - menu->boot_params.reset_type = BOOT_RESET_TYPE_NMI; - menu->boot_params.detect_tv_type = true; - menu->boot_params.detect_cic_seed = true; } diff --git a/src/menu/menu.h b/src/menu/menu.h index e0b1e98c..804725d3 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -2,16 +2,7 @@ #define MENU_H__ -#include "boot/boot.h" - - -typedef struct { - boot_params_t boot_params; -} menu_t; - - -void menu_restore (menu_t *menu); -void menu_run (menu_t *menu); - +void menu_restore (settings_t *settings); +void menu_run (settings_t *settings); #endif diff --git a/src/menu/settings.c b/src/menu/settings.c new file mode 100644 index 00000000..129f3fd4 --- /dev/null +++ b/src/menu/settings.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include + +#include + +#include "flashcart/flashcart.h" +#include "libs/toml/toml.h" +#include "boot/boot.h" + +#include "settings.h" + + +void settings_load_from_file (settings_t *settings) { + FILE *fp = NULL; + char error_buffer[256]; + + printf("Loading settings file %s\n", SC64_SETTINGS_FILEPATH); + wait_ms(1000); + + fp = fopen(SC64_SETTINGS_FILEPATH, "r"); + if (!fp) { + printf("Error loading config file %s\n", SC64_SETTINGS_FILEPATH); + // generate a default config file. + printf("Creating a new one!"); + wait_ms(10000); + //assertf(!fp, "Couldn't open toml config file: %s", SC64_SETTINGS_FILEPATH); + settings_save_default_state(); + } + + toml_table_t *conf = toml_parse_file(fp, error_buffer, sizeof(error_buffer)); + if (!conf) { + printf("Error parsing config: %s\n", error_buffer); + wait_ms(10000); + printf("Attempt a repair!"); + settings_validate(); + printf("Creating a new one!"); + settings_save_default_state(); + //assertf(!conf, "Couldn't parse toml config: %s", error_buffer); // TODO: work out why and handle appropriately. + } + + fclose(fp); + assertf(!fclose(fp), "Couldn't close toml config file"); // TODO: work out why and handle appropriately. + fp = NULL; + + toml_table_t *last_rom = toml_table_in(conf, "last_rom"); + if (!last_rom) { + printf("Missing '[last_rom]' header in config\n"); + wait_ms(10000); + } + + toml_datum_t rom_path = toml_string_in(last_rom, "rom_path"); + if (!rom_path.ok) { + printf("Couldn't read 'rom_path' value in config\n"); + wait_ms(10000); + } + else { + printf("Found rom path: %s\n", rom_path.u.s); + settings->last_rom.rom_path = rom_path.u.s; + } + + toml_datum_t save_path = toml_string_in(last_rom, "save_path"); + if (!save_path.ok) { + printf("Couldn't read 'save_path' value in config\n"); + wait_ms(10000); + } + else { + printf("Found save path: %s\n", save_path.u.s ); + settings->last_rom.save_path = save_path.u.s; + } + + toml_datum_t tmp_save_type = toml_int_in(last_rom, "save_type"); + if (!tmp_save_type.ok) { + printf("Couldn't read 'save_type' value in config\n"); + wait_ms(10000); + } + else { + assertf((int)tmp_save_type.u.i < __FLASHCART_SAVE_TYPE_END, "Invalid save type in config file"); + printf("Found save type: %d\n", (int)tmp_save_type.u.i ); + settings->last_rom.save_type = (int)tmp_save_type.u.i; + } + + + toml_table_t* last_state = toml_table_in(conf, "last_state"); + if (!last_state) { + printf("Missing '[last_state]' header in config\n"); + wait_ms(10000); + } + + // toml_datum_t current_directory = toml_string_in(last_state, "current_directory"); + // if (!current_directory.ok) { + // printf("Couldn't read 'current_directory' value in config\n"); + // printf("Defaulting to root directory.\n"); + // settings->last_state.current_directory = "sd://"; + // wait_ms(5000); + // } + // else { + // printf("Found current directory: %s\n", current_directory.u.s ); + // settings->last_state.current_directory = current_directory.u.s; + // } + + // toml_datum_t tmp_auto_load_last_rom = toml_bool_in(last_state, "auto_load"); + // if (!tmp_auto_load_last_rom.ok) { + // printf("Couldn't read 'auto_load' value in config\n"); + // printf("Defaulting to false.\n"); + // wait_ms(5000); + // settings->last_state.auto_load_last_rom = false; + // } + // else { + // printf("Found autoload: %s\n", tmp_auto_load_last_rom.u.b ? "true" : "false"); + // settings->last_state.auto_load_last_rom = tmp_auto_load_last_rom.u.b; + // } + + toml_free(conf); + +} + +void settings_save(void) { + // TODO: if there is a failure, validate or write the default state. + FILE *fp = NULL; + printf("Saving settings file %s\n", SC64_SETTINGS_FILEPATH); + wait_ms(1000); + fp = fopen(SC64_SETTINGS_FILEPATH, "w"); + + // TODO: convert and save the state to TOML + + fclose(fp); + assertf(!fclose(fp), "Couldn't close toml settings file"); // TODO: work out why and handle appropriately. + fp = NULL; +} + +void settings_load_default_state(settings_t *settings) { + // Happens on init + // TODO: should also happen as a last resort + // Mainly if the file does not exist, or is corrupted beyond repair. +//#ifdef SETTINGS_SCHEMA_VERSION 1 + settings->last_rom.rom_path = ""; + settings->last_rom.save_path = ""; + settings->last_rom.save_type = FLASHCART_SAVE_TYPE_NONE; + settings->last_rom.save_writeback = false; + + settings->last_state.current_directory = "sd://"; + settings->last_state.auto_load_last_rom = false; + + settings->boot_params.device_type = BOOT_DEVICE_TYPE_ROM; + settings->boot_params.reset_type = BOOT_RESET_TYPE_NMI; + settings->boot_params.detect_tv_type = true; + settings->boot_params.detect_cic_seed = true; +//#endif +} + +void settings_save_default_state(void) { + +} + +void settings_validate(void) { + // TODO: should validate against a file schema. + // Must take into account that the settings will change in future, so should be backwards compatible. +} + diff --git a/src/menu/settings.h b/src/menu/settings.h new file mode 100644 index 00000000..49e89711 --- /dev/null +++ b/src/menu/settings.h @@ -0,0 +1,38 @@ +#ifndef SETTINGS_H__ +#define SETTINGS_H__ + +#include "flashcart/flashcart.h" +#include "libs/toml/toml.h" +#include "boot/boot.h" + +#define SC64_SETTINGS_FILEPATH "sd://config.sc64.toml.txt" +#define SETTINGS_SCHEMA_VERSION 1 + + +typedef struct { + char *rom_path; + char *save_path; + flashcart_save_type_t save_type; //TODO: should this be converted from a string, or use an integer value? + bool save_writeback; // TODO: this is likely SC64 specific. +} settings_last_rom_t; + +typedef struct { + bool auto_load_last_rom; + char* current_directory; +} settings_last_state_t; + +typedef struct { + settings_last_rom_t last_rom; + settings_last_state_t last_state; + boot_params_t boot_params; +} settings_t; + + +void settings_load_from_file (settings_t *settings); +void settings_save (void); +void settings_reset (void); +void settings_load_default_state(settings_t *settings); +void settings_save_default_state(void); +void settings_validate (void); + +#endif