diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 170726a9..9838cd8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,9 @@ on: jobs: build-menu: runs-on: ubuntu-latest + permissions: + contents: write + packages: write steps: - uses: actions/checkout@v4 @@ -68,14 +71,6 @@ jobs: name: SC64 path: ./output/sc64menu.n64 - # - name: Delete rolling-release tag and release - # uses: dev-drprasad/delete-tag-and-release@v1.0 - # if: github.ref == 'refs/heads/main' - # with: - # github_token: ${{ secrets.GITHUB_TOKEN }} - # tag_name: rolling-release - # continue-on-error: true - - name: Upload rolling release uses: softprops/action-gh-release@v2 if: github.ref == 'refs/heads/main' @@ -91,6 +86,22 @@ jobs: ./output/sc64menu.n64 continue-on-error: true + - name: Upload dev rolling release + uses: softprops/action-gh-release@v2 + if: github.ref == 'refs/heads/develop' + with: + name: 'Rolling dev release-V${{ github.run_id }}' + body: Rolling dev prerelease built from latest commit on `develop` branch. + tag_name: prerelease-dev + prerelease: true + files: | + ./output/N64FlashcartMenu.n64 + ./output/menu.bin + ./output/OS64.v64 + ./output/OS64P.v64 + ./output/sc64menu.n64 + continue-on-error: true + generate-docs: runs-on: ubuntu-latest permissions: diff --git a/.gitignore b/.gitignore index bc2d5ddf..35d81191 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Ignore generated files in the libdragon FS /filesystem/FiraMonoBold.font64 +/filesystem/*.wav64 # Ignore external development tools /tools/* diff --git a/Makefile b/Makefile index 88c21b0e..069c99a8 100644 --- a/Makefile +++ b/Makefile @@ -80,17 +80,27 @@ SRCS = \ FONTS = \ FiraMonoBold.ttf +SOUNDS = \ + cursorsound.wav \ + back.wav \ + enter.wav \ + error.wav \ + settings.wav + OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o,$(basename $(SRCS)))) MINIZ_OBJS = $(filter $(BUILD_DIR)/libs/miniz/%.o,$(OBJS)) SPNG_OBJS = $(filter $(BUILD_DIR)/libs/libspng/%.o,$(OBJS)) DEPS = $(OBJS:.o=.d) FILESYSTEM = \ - $(addprefix $(FILESYSTEM_DIR)/, $(notdir $(FONTS:%.ttf=%.font64))) + $(addprefix $(FILESYSTEM_DIR)/, $(notdir $(FONTS:%.ttf=%.font64))) \ + $(addprefix $(FILESYSTEM_DIR)/, $(notdir $(SOUNDS:%.wav=%.wav64))) $(MINIZ_OBJS): N64_CFLAGS+=-DMINIZ_NO_TIME -fcompare-debug-second $(SPNG_OBJS): N64_CFLAGS+=-isystem $(SOURCE_DIR)/libs/miniz -DSPNG_USE_MINIZ -fcompare-debug-second $(FILESYSTEM_DIR)/FiraMonoBold.font64: MKFONT_FLAGS+=-c 1 --size 16 -r 20-1FF -r 2026-2026 --ellipsis 2026,1 +$(FILESYSTEM_DIR)/%.wav64: AUDIOCONV_FLAGS=--wav-compress 1 + $(@info $(shell mkdir -p ./$(FILESYSTEM_DIR) &> /dev/null)) @@ -98,6 +108,10 @@ $(FILESYSTEM_DIR)/%.font64: $(ASSETS_DIR)/%.ttf @echo " [FONT] $@" @$(N64_MKFONT) $(MKFONT_FLAGS) -o $(FILESYSTEM_DIR) "$<" +$(FILESYSTEM_DIR)/%.wav64: $(ASSETS_DIR)/%.wav + @echo " [AUDIO] $@" + @$(N64_AUDIOCONV) $(AUDIOCONV_FLAGS) -o $(FILESYSTEM_DIR) "$<" + $(BUILD_DIR)/$(PROJECT_NAME).dfs: $(FILESYSTEM) $(BUILD_DIR)/menu/views/credits.o: .FORCE diff --git a/README.md b/README.md index dd3624c5..e993dfdc 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ An open source menu for N64 flashcarts. * Comprehensive ROM information display. * Real Time Clock support. * Music playback (MP3). +* Menu sound effects. ### Video showcase (as of Oct 12 2023) @@ -41,7 +42,7 @@ An open source menu for N64 flashcarts. ## Getting started -Using your PC, insert the SD card and ensure it is formatted for compatibility (We recommend FAT32 in most instances). +Using your PC, insert the SD card and ensure it is formatted for compatibility (We recommend FAT32 in most instances, though EXFAT is fully supported on the SummerCart64). ### Save files By default, all save files (whether `FlashRam`, `SRAM` or `EEPROM`) use the `.sav` extension and match the filename of the ROM. @@ -174,3 +175,9 @@ Once merged, they can be viewed [here](https://polprzewodnikowy.github.io/N64Fla - [mini.c](https://github.com/univrsal/mini.c) (BSD 2-Clause License) - [minimp3](https://github.com/lieff/minimp3) (CC0 1.0 Universal) - [miniz](https://github.com/richgel999/miniz) (MIT License) + +## Sounds +See [License](https://pixabay.com/en/service/license-summary/) for the following sounds: + - [Cursor sound](https://pixabay.com/en/sound-effects/click-buttons-ui-menu-sounds-effects-button-7-203601/) by Skyscraper_seven (Free to use) + - [Actions (Enter, back) sound](https://pixabay.com/en/sound-effects/menu-button-user-interface-pack-190041/) by Liecio (Free to use) + - [Error sound](https://pixabay.com/en/sound-effects/error-call-to-attention-129258/) by Universfield (Free to use) diff --git a/assets/back.wav b/assets/back.wav new file mode 100644 index 00000000..f8d4655e Binary files /dev/null and b/assets/back.wav differ diff --git a/assets/cursorsound.wav b/assets/cursorsound.wav new file mode 100644 index 00000000..e6b2a624 Binary files /dev/null and b/assets/cursorsound.wav differ diff --git a/assets/enter.wav b/assets/enter.wav new file mode 100644 index 00000000..ad88ca23 Binary files /dev/null and b/assets/enter.wav differ diff --git a/assets/error.wav b/assets/error.wav new file mode 100644 index 00000000..5ced329b Binary files /dev/null and b/assets/error.wav differ diff --git a/assets/settings.wav b/assets/settings.wav new file mode 100644 index 00000000..3e9a80f0 Binary files /dev/null and b/assets/settings.wav differ diff --git a/src/flashcart/flashcart_utils.c b/src/flashcart/flashcart_utils.c index 3eb13605..cfc714da 100644 --- a/src/flashcart/flashcart_utils.c +++ b/src/flashcart/flashcart_utils.c @@ -51,7 +51,7 @@ bool fatfs_get_file_sectors (char *path, uint32_t *address, address_type_t type, uint32_t cluster = fil.clust; - if (cluster >= fs->n_fatent) { + if ((cluster < 2) || (cluster >= fs->n_fatent)) { error = true; break; } diff --git a/src/menu/components/common.c b/src/menu/components/common.c index 6bf708f8..d0fce75f 100644 --- a/src/menu/components/common.c +++ b/src/menu/components/common.c @@ -118,7 +118,8 @@ void component_messagebox_draw (char *fmt, ...) { .height = VISIBLE_AREA_HEIGHT, .align = ALIGN_CENTER, .valign = VALIGN_CENTER, - .wrap = WRAP_WORD + .wrap = WRAP_WORD, + .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, formatted, ¶graph_nbytes); if (formatted != buffer) { @@ -151,10 +152,11 @@ void component_main_text_draw (rdpq_align_t align, rdpq_valign_t valign, char *f .align = align, .valign = valign, .wrap = WRAP_ELLIPSES, + .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL, - VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL, + VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL, formatted, nbytes ); @@ -180,10 +182,11 @@ void component_actions_bar_text_draw (rdpq_align_t align, rdpq_valign_t valign, .align = align, .valign = valign, .wrap = WRAP_ELLIPSES, + .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL, - LAYOUT_ACTIONS_SEPARATOR_Y + BORDER_THICKNESS + TEXT_MARGIN_VERTICAL, + LAYOUT_ACTIONS_SEPARATOR_Y + BORDER_THICKNESS + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL, formatted, nbytes ); diff --git a/src/menu/components/constants.h b/src/menu/components/constants.h index f3eb3e39..e4d3eb51 100644 --- a/src/menu/components/constants.h +++ b/src/menu/components/constants.h @@ -65,7 +65,9 @@ #define MESSAGEBOX_MARGIN (32) #define TEXT_MARGIN_HORIZONTAL (10) -#define TEXT_MARGIN_VERTICAL (7) +#define TEXT_MARGIN_VERTICAL (6) +#define TEXT_OFFSET_VERTICAL (1) +#define TEXT_LINE_SPACING_ADJUST (0) /** @brief The boxart picture width. */ #define BOXART_WIDTH (158) @@ -86,7 +88,7 @@ #define LIST_SCROLLBAR_Y (VISIBLE_AREA_Y0) /** @brief The maximum amount of file list entries. */ -#define LIST_ENTRIES (20) +#define LIST_ENTRIES (19) /** @brief The maximum width available for a file list entry. */ #define FILE_LIST_MAX_WIDTH (480) #define FILE_LIST_HIGHLIGHT_WIDTH (VISIBLE_AREA_X1 - VISIBLE_AREA_X0 - LIST_SCROLLBAR_WIDTH) diff --git a/src/menu/components/context_menu.c b/src/menu/components/context_menu.c index f2e32c42..c4d0364a 100644 --- a/src/menu/components/context_menu.c +++ b/src/menu/components/context_menu.c @@ -1,5 +1,6 @@ #include "../components.h" #include "../fonts.h" +#include "../sound.h" #include "constants.h" @@ -41,6 +42,7 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) } else { cm->hide_pending = true; } + sound_play_effect(SFX_EXIT); } else if (menu->actions.enter) { if (cm->list[cm->selected].submenu) { cm->submenu = cm->list[cm->selected].submenu; @@ -51,16 +53,19 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm) cm->list[cm->selected].action(menu, cm->list[cm->selected].arg); top->hide_pending = true; } + sound_play_effect(SFX_ENTER); } else if (menu->actions.go_up) { cm->selected -= 1; if (cm->selected < 0) { cm->selected = 0; } + sound_play_effect(SFX_CURSOR); } else if (menu->actions.go_down) { cm->selected += 1; if (cm->selected >= cm->count) { cm->selected = (cm->count - 1); } + sound_play_effect(SFX_CURSOR); } return true; @@ -81,6 +86,7 @@ void component_context_menu_draw (component_context_menu_t *cm) { .height = VISIBLE_AREA_HEIGHT, .align = ALIGN_CENTER, .valign = VALIGN_CENTER, + .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, NULL diff --git a/src/menu/components/file_list.c b/src/menu/components/file_list.c index b00ef329..7a9835ce 100644 --- a/src/menu/components/file_list.c +++ b/src/menu/components/file_list.c @@ -71,6 +71,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) { .width = FILE_LIST_MAX_WIDTH - (TEXT_MARGIN_HORIZONTAL * 2), .height = LAYOUT_ACTIONS_SEPARATOR_Y - VISIBLE_AREA_Y0 - (TEXT_MARGIN_VERTICAL * 2), .wrap = WRAP_ELLIPSES, + .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, file_list_layout @@ -114,7 +115,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) { layout = rdpq_paragraph_builder_end(); int highlight_height = (layout->bbox.y1 - layout->bbox.y0) / layout->nlines; - int highlight_y = VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + ((selected - starting_position) * highlight_height); + int highlight_y = VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL + ((selected - starting_position) * highlight_height); component_box_draw( FILE_LIST_HIGHLIGHT_X, @@ -127,7 +128,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) { rdpq_paragraph_render( layout, VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL, - VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL ); rdpq_paragraph_free(layout); @@ -138,6 +139,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) { .height = LAYOUT_ACTIONS_SEPARATOR_Y - VISIBLE_AREA_Y0 - (TEXT_MARGIN_VERTICAL * 2), .align = ALIGN_RIGHT, .wrap = WRAP_ELLIPSES, + .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, NULL @@ -164,7 +166,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) { rdpq_paragraph_render( layout, VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL, - VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL ); rdpq_paragraph_free(layout); diff --git a/src/menu/menu.c b/src/menu/menu.c index beef676d..b1e05380 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -115,6 +115,10 @@ static void menu_init (boot_params_t *boot_params) { __boot_tvtype = TV_NTSC; } + if (menu->settings.sound_enabled) { + sound_init_sfx(); + } + display_init(RESOLUTION_640x480, DEPTH_16_BPP, 2, GAMMA_NONE, FILTERS_DISABLED); register_VI_handler(frame_counter_handler); diff --git a/src/menu/rom_info.c b/src/menu/rom_info.c index 14026ee9..a2f50cf1 100644 --- a/src/menu/rom_info.c +++ b/src/menu/rom_info.c @@ -1,3 +1,4 @@ +#include #include #include @@ -832,13 +833,21 @@ static rom_err_t save_override (path_t *path, const char *id, int value, int def mini_t *ini = mini_try_load(path_get(overrides_path)); if (!ini) { - return ROM_ERR_IO; + return ROM_ERR_SAVE_IO; } + int mini_err; + if (value == default_value) { - mini_delete_value(ini, NULL, id); + mini_err = mini_delete_value(ini, NULL, id); } else { - mini_set_int(ini, NULL, id, value); + mini_err = mini_set_int(ini, NULL, id, value); + } + + if ((mini_err != MINI_OK) && (mini_err != MINI_VALUE_NOT_FOUND)) { + path_free(overrides_path); + mini_free(ini); + return ROM_ERR_SAVE_IO; } bool empty = mini_empty(ini); @@ -847,16 +856,16 @@ static rom_err_t save_override (path_t *path, const char *id, int value, int def if (mini_save(ini, MINI_FLAGS_NONE) != MINI_OK) { path_free(overrides_path); mini_free(ini); - return ROM_ERR_IO; + return ROM_ERR_SAVE_IO; } } mini_free(ini); if (empty) { - if (remove(path_get(overrides_path))) { + if (remove(path_get(overrides_path)) && (errno != ENOENT)) { path_free(overrides_path); - return ROM_ERR_IO; + return ROM_ERR_SAVE_IO; } } @@ -946,10 +955,10 @@ rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info) { setbuf(f, NULL); if (fread(&rom_header, sizeof(rom_header), 1, f) != 1) { fclose(f); - return ROM_ERR_IO; + return ROM_ERR_LOAD_IO; } if (fclose(f)) { - return ROM_ERR_IO; + return ROM_ERR_LOAD_IO; } fix_rom_header_endianness(&rom_header, rom_info); diff --git a/src/menu/rom_info.h b/src/menu/rom_info.h index cb241a2e..0308cfc9 100644 --- a/src/menu/rom_info.h +++ b/src/menu/rom_info.h @@ -18,7 +18,8 @@ /** @brief ROM error enumeration. */ typedef enum { ROM_OK, - ROM_ERR_IO, + ROM_ERR_LOAD_IO, + ROM_ERR_SAVE_IO, ROM_ERR_NO_FILE, } rom_err_t; diff --git a/src/menu/settings.c b/src/menu/settings.c index 3e046ed0..0b372531 100644 --- a/src/menu/settings.c +++ b/src/menu/settings.c @@ -13,10 +13,10 @@ static settings_t init = { .show_protected_entries = false, .default_directory = "/", .use_saves_folder = true, + .sound_enabled = true, /* Beta feature flags (should always init to off) */ .bgm_enabled = false, - .sound_enabled = false, .rumble_enabled = false, }; @@ -39,10 +39,10 @@ void settings_load (settings_t *settings) { settings->show_protected_entries = mini_get_bool(ini, "menu", "show_protected_entries", init.show_protected_entries); 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->sound_enabled = mini_get_bool(ini, "menu", "sound_enabled", init.sound_enabled); /* 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); @@ -55,10 +55,10 @@ void settings_save (settings_t *settings) { mini_set_bool(ini, "menu", "show_protected_entries", settings->show_protected_entries); mini_set_string(ini, "menu", "default_directory", settings->default_directory); mini_set_bool(ini, "menu", "use_saves_folder", settings->use_saves_folder); + mini_set_bool(ini, "menu", "sound_enabled", settings->sound_enabled); /* Beta feature flags, they should not save until production ready! */ // mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled); - // mini_set_bool(ini, "menu_beta_flag", "sound_enabled", settings->sound_enabled); // mini_set_bool(ini, "menu_beta_flag", "rumble_enabled", settings->rumble_enabled); mini_save(ini, MINI_FLAGS_SKIP_EMPTY_GROUPS); diff --git a/src/menu/sound.c b/src/menu/sound.c index 9e58d001..bf950d6c 100644 --- a/src/menu/sound.c +++ b/src/menu/sound.c @@ -3,14 +3,18 @@ #include #include "mp3_player.h" +#include "sound.h" #define DEFAULT_FREQUENCY (44100) #define NUM_BUFFERS (4) -#define NUM_CHANNELS (2) +#define NUM_CHANNELS (3) + +static wav64_t sfx_cursor, sfx_error, sfx_enter, sfx_exit, sfx_setting; static bool sound_initialized = false; +static bool sfx_enabled = false; static void sound_reconfigure (int frequency) { @@ -35,6 +39,43 @@ void sound_init_mp3_playback (void) { sound_reconfigure(mp3player_get_samplerate()); } + +void sound_init_sfx (void) { + mixer_ch_set_vol(SOUND_SFX_CHANNEL, 0.5f, 0.5f); + wav64_open(&sfx_cursor, "rom:/cursorsound.wav64"); + wav64_open(&sfx_exit, "rom:/back.wav64"); + wav64_open(&sfx_setting, "rom:/settings.wav64"); + wav64_open(&sfx_enter, "rom:/enter.wav64"); + wav64_open(&sfx_error, "rom:/error.wav64"); + sfx_enabled = true; +} + + +void sound_play_effect(sound_effect_t sfx) { + if(sfx_enabled) { + switch (sfx) { + case SFX_CURSOR: + wav64_play(&sfx_cursor, SOUND_SFX_CHANNEL); + break; + case SFX_EXIT: + wav64_play(&sfx_exit, SOUND_SFX_CHANNEL); + break; + case SFX_SETTING: + wav64_play(&sfx_setting, SOUND_SFX_CHANNEL); + break; + case SFX_ENTER: + wav64_play(&sfx_enter, SOUND_SFX_CHANNEL); + break; + case SFX_ERROR: + wav64_play(&sfx_error, SOUND_SFX_CHANNEL); + break; + default: + break; + } + } +} + + void sound_deinit (void) { if (sound_initialized) { mixer_close(); diff --git a/src/menu/sound.h b/src/menu/sound.h index 44ecf6bc..cf311519 100644 --- a/src/menu/sound.h +++ b/src/menu/sound.h @@ -9,12 +9,22 @@ #define SOUND_MP3_PLAYER_CHANNEL (0) +#define SOUND_SFX_CHANNEL (2) + +typedef enum { + SFX_CURSOR, + SFX_ERROR, + SFX_ENTER, + SFX_EXIT, + SFX_SETTING, +} sound_effect_t; void sound_init_default (void); void sound_init_mp3_playback (void); +void sound_init_sfx (void); +void sound_play_effect(sound_effect_t sfx); void sound_deinit (void); void sound_poll (void); - #endif diff --git a/src/menu/views/browser.c b/src/menu/views/browser.c index bb514b1b..c9a1b7e5 100644 --- a/src/menu/views/browser.c +++ b/src/menu/views/browser.c @@ -1,11 +1,12 @@ +#include #include #include -#include #include #include "../fonts.h" #include "utils/fs.h" #include "views.h" +#include "../sound.h" static const char *rom_extensions[] = { "z64", "n64", "v64", "rom", NULL }; @@ -296,16 +297,19 @@ static void process (menu_t *menu) { if (menu->browser.selected < 0) { menu->browser.selected = 0; } + sound_play_effect(SFX_CURSOR); } else if (menu->actions.go_down) { menu->browser.selected += scroll_speed; if (menu->browser.selected >= menu->browser.entries) { menu->browser.selected = menu->browser.entries - 1; } + sound_play_effect(SFX_CURSOR); } menu->browser.entry = &menu->browser.list[menu->browser.selected]; } if (menu->actions.enter && menu->browser.entry) { + sound_play_effect(SFX_ENTER); switch (menu->browser.entry->type) { case ENTRY_TYPE_DIR: if (push_directory(menu, menu->browser.entry->name)) { @@ -340,10 +344,13 @@ static void process (menu_t *menu) { menu->browser.valid = false; menu_show_error(menu, "Couldn't open last directory"); } + sound_play_effect(SFX_EXIT); } else if (menu->actions.options && menu->browser.entry) { component_context_menu_show(&entry_context_menu); + sound_play_effect(SFX_SETTING); } else if (menu->actions.settings) { component_context_menu_show(&settings_context_menu); + sound_play_effect(SFX_SETTING); } } diff --git a/src/menu/views/credits.c b/src/menu/views/credits.c index dc1d0665..fb068e6b 100644 --- a/src/menu/views/credits.c +++ b/src/menu/views/credits.c @@ -1,5 +1,5 @@ #include "views.h" - +#include "../sound.h" #ifndef MENU_VERSION #define MENU_VERSION "Unknown" @@ -13,6 +13,7 @@ static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/error.c b/src/menu/views/error.c index a5c0b84a..07eb70d4 100644 --- a/src/menu/views/error.c +++ b/src/menu/views/error.c @@ -1,9 +1,11 @@ #include "views.h" +#include "../sound.h" static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } @@ -48,6 +50,7 @@ void view_error_display (menu_t *menu, surface_t *display) { } void menu_show_error (menu_t *menu, char *error_message) { + sound_play_effect(SFX_ERROR); menu->next_mode = MENU_MODE_ERROR; menu->error_message = error_message; } diff --git a/src/menu/views/file_info.c b/src/menu/views/file_info.c index 211f5791..19ee97d4 100644 --- a/src/menu/views/file_info.c +++ b/src/menu/views/file_info.c @@ -1,4 +1,5 @@ #include +#include "../sound.h" #include "utils/fs.h" #include "views.h" @@ -50,6 +51,7 @@ static char *format_file_type (char *name, bool is_directory) { static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/flashcart_info.c b/src/menu/views/flashcart_info.c index 084cc073..41c1f443 100644 --- a/src/menu/views/flashcart_info.c +++ b/src/menu/views/flashcart_info.c @@ -1,9 +1,11 @@ #include "views.h" +#include "../sound.h" static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } @@ -17,8 +19,17 @@ static void draw (menu_t *menu, surface_t *d) { component_main_text_draw( ALIGN_CENTER, VALIGN_TOP, "FLASHCART INFORMATION\n" + "\n" + "\n" + "This feature is not yet supported.\n\n" ); + // FIXME: Display: + // * cart_type + // * Firmware version + // * supported features (flashcart_features_t) + + component_main_text_draw( ALIGN_LEFT, VALIGN_TOP, "\n" diff --git a/src/menu/views/image_viewer.c b/src/menu/views/image_viewer.c index 21c153b3..d58d3743 100644 --- a/src/menu/views/image_viewer.c +++ b/src/menu/views/image_viewer.c @@ -1,4 +1,5 @@ #include +#include "../sound.h" #include "../png_decoder.h" #include "views.h" @@ -40,6 +41,7 @@ static void process (menu_t *menu) { } else { menu->next_mode = MENU_MODE_BROWSER; } + sound_play_effect(SFX_EXIT); } else if (menu->actions.enter && image) { if (show_message) { show_message = false; @@ -48,6 +50,7 @@ static void process (menu_t *menu) { } else { show_message = true; } + sound_play_effect(SFX_ENTER); } } diff --git a/src/menu/views/load_disk.c b/src/menu/views/load_disk.c index 7216e97d..983d052a 100644 --- a/src/menu/views/load_disk.c +++ b/src/menu/views/load_disk.c @@ -1,6 +1,7 @@ #include "../cart_load.h" #include "../disk_info.h" #include "boot/boot.h" +#include "../sound.h" #include "views.h" @@ -34,8 +35,10 @@ static void process (menu_t *menu) { } else if (menu->actions.options && menu->load.rom_path) { load_pending = true; load_rom = true; + sound_play_effect(SFX_SETTING); } else if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/load_emulator.c b/src/menu/views/load_emulator.c index 60f8d114..589a6a59 100644 --- a/src/menu/views/load_emulator.c +++ b/src/menu/views/load_emulator.c @@ -1,6 +1,7 @@ #include "../cart_load.h" #include "boot/boot.h" #include "utils/fs.h" +#include "../sound.h" #include "views.h" @@ -36,6 +37,7 @@ static void process (menu_t *menu) { load_pending = true; } else if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/load_rom.c b/src/menu/views/load_rom.c index 1d4f41be..437a43a3 100644 --- a/src/menu/views/load_rom.c +++ b/src/menu/views/load_rom.c @@ -1,6 +1,7 @@ #include "../cart_load.h" #include "../rom_info.h" #include "boot/boot.h" +#include "../sound.h" #include "views.h" @@ -10,7 +11,8 @@ static component_boxart_t *boxart; static char *convert_error_message (rom_err_t err) { switch (err) { - case ROM_ERR_IO: return "I/O error during loading/storing ROM information"; + case ROM_ERR_LOAD_IO: return "I/O error during loading ROM information and/or options"; + case ROM_ERR_SAVE_IO: return "I/O error during storing ROM options"; case ROM_ERR_NO_FILE: return "Couldn't open ROM file"; default: return "Unknown ROM info load error"; } @@ -197,8 +199,10 @@ static void process (menu_t *menu) { load_pending = true; } else if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } else if (menu->actions.options) { component_context_menu_show(&options_context_menu); + sound_play_effect(SFX_SETTING); } } @@ -236,12 +240,10 @@ static void draw (menu_t *menu, surface_t *d) { " Save type: %s\n" " TV type: %s\n" " Expansion PAK: %s\n" - "\n" - " Extra information:\n" - " CIC: %s\n" - " Boot address: 0x%08lX\n" - " SDK version: %.1f%c\n" - " Clock Rate: %.2fMHz\n", + " CIC: %s\n" + " Boot address: 0x%08lX\n" + " SDK version: %.1f%c\n" + " Clock Rate: %.2fMHz\n", format_rom_endianness(menu->load.rom_info.endianness), menu->load.rom_info.title, menu->load.rom_info.game_code[0], menu->load.rom_info.game_code[1], menu->load.rom_info.game_code[2], menu->load.rom_info.game_code[3], diff --git a/src/menu/views/music_player.c b/src/menu/views/music_player.c index 7b3d9751..4de00756 100644 --- a/src/menu/views/music_player.c +++ b/src/menu/views/music_player.c @@ -42,11 +42,13 @@ static void process (menu_t *menu) { menu_show_error(menu, convert_error_message(err)); } else if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } else if (menu->actions.enter) { err = mp3player_toggle(); if (err != MP3PLAYER_OK) { menu_show_error(menu, convert_error_message(err)); } + sound_play_effect(SFX_ENTER); } else if (menu->actions.go_left || menu->actions.go_right) { int seconds = menu->actions.go_fast ? SEEK_SECONDS_FAST : SEEK_SECONDS; err = mp3player_seek(menu->actions.go_left ? (-seconds) : seconds); diff --git a/src/menu/views/rtc.c b/src/menu/views/rtc.c index caeb9305..d810f382 100644 --- a/src/menu/views/rtc.c +++ b/src/menu/views/rtc.c @@ -1,4 +1,5 @@ #include +#include "../sound.h" #include "views.h" // FIXME: add implementation! @@ -18,6 +19,7 @@ static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/settings_editor.c b/src/menu/views/settings_editor.c index 5e9d1854..badb3696 100644 --- a/src/menu/views/settings_editor.c +++ b/src/menu/views/settings_editor.c @@ -1,3 +1,4 @@ +#include "../sound.h" #include "views.h" @@ -12,6 +13,7 @@ static const char *format_switch (bool state) { static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/system_info.c b/src/menu/views/system_info.c index 02b78f72..74ed4cbd 100644 --- a/src/menu/views/system_info.c +++ b/src/menu/views/system_info.c @@ -1,5 +1,6 @@ #include +#include "../sound.h" #include "views.h" @@ -28,6 +29,7 @@ static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } } diff --git a/src/menu/views/text_viewer.c b/src/menu/views/text_viewer.c index 6b688479..cf8b505f 100644 --- a/src/menu/views/text_viewer.c +++ b/src/menu/views/text_viewer.c @@ -3,6 +3,7 @@ #include "../components/constants.h" #include "../fonts.h" +#include "../sound.h" #include "utils/utils.h" #include "views.h" @@ -55,6 +56,7 @@ static void perform_vertical_scroll (int lines) { static void process (menu_t *menu) { if (menu->actions.back) { menu->next_mode = MENU_MODE_BROWSER; + sound_play_effect(SFX_EXIT); } else if (text) { if (menu->actions.go_up) { perform_vertical_scroll(menu->actions.go_fast ? -10 : -1); diff --git a/src/utils/fs.c b/src/utils/fs.c index 41b69c48..b02b2e2c 100644 --- a/src/utils/fs.c +++ b/src/utils/fs.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include #include "fs.h"