From 69403f059fa86f772e09abee7f80502bd93d10e9 Mon Sep 17 00:00:00 2001 From: Geralt <84459734+MathisMartin31@users.noreply.github.com> Date: Wed, 20 May 2026 03:10:49 +0200 Subject: [PATCH] Allow to exit the options menu without saving changes made (#484) * Allow exiting options menu without saving * Change "Back" button text to "Cancel" to be more explicit * clang format * fix load_game * use proper existing defines for options default values * fix buttons' array sizes --------- Co-authored-by: MathisMartin31 --- graphics/background_options_menu_gfx.png | Bin 2194 -> 2124 bytes source/game/options_menu.c | 234 +++++++++++------------ source/save.c | 18 +- 3 files changed, 120 insertions(+), 132 deletions(-) diff --git a/graphics/background_options_menu_gfx.png b/graphics/background_options_menu_gfx.png index 2cf5401b5c6567278c3022b11d806e61fa585144..d36c827ebb59f3cab204c6282813c010876a303a 100644 GIT binary patch delta 1030 zcmbOvct&8u9!6${$^R$sVU*Z>k#P?r@8r%hCk6(F1tmd#!3>iZGS8cA$HMN){L$0J zF{EP7+q<`C-BJ*7NZk6>A}HkE|JdKEhK5QK1!XD+qQvKBs@uMacQpx)UE9%d;0w;J((o#uNw|A~_ksh-bY(VCuf3yw zlwk$W0(0 zxr5vT_XQv4my5la&0t^8BE?xh=Ra2o8$wY+9fRsdQMtVd(Dr5o}-{XQOatzrA;et8kwXYcKHpMPFk+j!Jo z{=vNa`i~e-eE-RCe@h+1bKitbSBk5o*FC(pDL-CSP3+(qMx{@8c$p^XI=l(1k0>o( z{V(|&gW>(Dx7WS;`{>+f#zLSQqfMKCF*&^cVD8RuVe!@GVrDJJetw$_+ft8Lm5ZvG zGPYH}o1D0wL4Wu0Ukr1OFPo=sW$sY_GD>{2@PnTdu6%a+zK88j`^)yt`ibHVr7=J~ zo5c=ZWc^?D@)}FRf3H-Azq$A0UY?F;_EgiVlMhgD;JVMXT50>C!u#R|U@KPtyQmjFiCL39>&T086`H~V%*6%iHVIjY)6Y30|Uc?k|4iehRF+==S{X_VRvOQ_jGX# zshIQj?%S$GRw53GrCYA01?>1g`z`as**P3$GjbwcAJ05)bpB=C)rJRKmJ16Cc0PS& z_3KX}>nEG@Q$)iY?*Caj`6HuPY9WJO=+kub_q*19WscG7J@EF;-L-dr)iSCwxE8WB zT=!AcJI2A z7-V=B>@R>5MYF0qFlBzd3>tWV@R>o&FkVN~S~ z77g;Oxtt$9`#ai$Wa^>PE$jvx`HO3fqW6h))ZRV5+&7*_lM5uLpwM8|Xrpn!IQ)jO zN`q5lx<|w1;6%me*EIyn>J}aTw(@V;8_T0kyc&Oxw0~h-7y9)3i~pxDpI*Cv)vcfB z53AXKR{l08Df~BY{N^`h-`-72jsLb;pYg#Safa{urvrH=)Nj9P9`kkzlY=31K&_{= z!@bk@inf0LWZmEJDO<>4QMSYT)O_WFt;YL+an~j0@aLzqnqfoUeo-+8oB4CD;?2d}yoR5y7gP;mSxT8%Ech54bQ?CdA5uFF4EBPZTWv+Y{p+>d=)T>OVN>45 zxbn)p9VfKeegtfEuitLT*V4yoVDUTGU%O2z;Meqdos3^tUVUEmPdmO=>p{@et@5vb zy8rI{w)KFrX2az#dp7;wcfL$gm0^xBtA+2m)wlD@YYv$IDh}Lo{KzdvwO;m^U&WSR zUSIuNF3->xZfnd?_UYH+O{NL6&j0x~6@vd$@?2>?4e?k@lU diff --git a/source/game/options_menu.c b/source/game/options_menu.c index 4fedf16..04719ad 100644 --- a/source/game/options_menu.c +++ b/source/game/options_menu.c @@ -19,15 +19,14 @@ #include #include -// Button indices -enum OptionButtons +enum OptionButtonRows { - GAME_SPEED_BTN_IDX, - HIGH_CONTRAST_BTN_IDX, - MUSIC_VOLUME_BTN_IDX, - SOUND_VOLUME_BTN_IDX, - BACK_BTN_IDX, - NB_OPTIONS_BUTTONS + GAME_SPEED_ROW_IDX, + HIGH_CONTRAST_ROW_IDX, + MUSIC_VOLUME_ROW_IDX, + SOUND_VOLUME_ROW_IDX, + SAVE_BACK_ROW_IDX, + NB_OPTIONS_ROWS }; enum OptionSpeedButtons { @@ -38,22 +37,26 @@ enum OptionSpeedButtons // Color palette indices #define MENU_BUTTON_MAIN_COLOR_PAL_IDX 1 -#define BACK_BUTTON_MAIN_COLOR_PAL_IDX 3 -#define SPEED_DOWN_BUTTON_OUTLINE_COLOR_PAL_IDX 4 -#define SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX 5 -#define SPEED_UP_BUTTON_OUTLINE_COLOR_PAL_IDX 6 -#define CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX 7 -#define MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX 8 -#define SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX 9 -#define BACK_BUTTON_OUTLINE_COLOR_PAL_IDX 10 +#define SAVE_BUTTON_MAIN_COLOR_PAL_IDX 3 +#define BACK_BUTTON_MAIN_COLOR_PAL_IDX 4 +#define SPEED_DOWN_BUTTON_OUTLINE_COLOR_PAL_IDX 5 +#define SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX 6 +#define SPEED_UP_BUTTON_OUTLINE_COLOR_PAL_IDX 7 +#define CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX 8 +#define MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX 9 +#define SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX 10 +#define SAVE_BUTTON_OUTLINE_COLOR_PAL_IDX 11 +#define BACK_BUTTON_OUTLINE_COLOR_PAL_IDX 12 // Define selection grid for the menu buttons static void game_speed_down_on_pressed(void); static void game_speed_up_on_pressed(void); static void high_contrast_on_pressed(void); +static void save_on_pressed(void); static void back_on_pressed(void); -static int options_menu_return_row_size(void); +static int options_menu_return_upper_rows_size(void); +static int options_menu_return_bottom_row_size(void); static void options_menu_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection); static bool game_speed_row_on_selection_changed( SelectionGrid* selection_grid, @@ -83,49 +86,52 @@ static bool regular_button_row_on_selection_changed( // clang-format off static SelectionGridRow options_menu_selection_rows[] = { { - GAME_SPEED_BTN_IDX, - options_menu_return_row_size, + GAME_SPEED_ROW_IDX, + options_menu_return_upper_rows_size, game_speed_row_on_selection_changed, NULL, {.wrap = true} // The wrapping is used to allow button activation with Left/Right arrows by // putting logic into the `game_speed_row_on_selection_changed` function }, { - HIGH_CONTRAST_BTN_IDX, - options_menu_return_row_size, + HIGH_CONTRAST_ROW_IDX, + options_menu_return_upper_rows_size, regular_button_row_on_selection_changed, options_menu_row_on_key_transit, {.wrap = false} }, { - MUSIC_VOLUME_BTN_IDX, - options_menu_return_row_size, + MUSIC_VOLUME_ROW_IDX, + options_menu_return_upper_rows_size, music_volume_row_on_selection_changed, NULL, {.wrap = true} // Same trick as Game Speed button }, { - SOUND_VOLUME_BTN_IDX, - options_menu_return_row_size, + SOUND_VOLUME_ROW_IDX, + options_menu_return_upper_rows_size, sound_volume_row_on_selection_changed, NULL, {.wrap = true} // Same trick as Game Speed button }, { - BACK_BTN_IDX, - options_menu_return_row_size, + SAVE_BACK_ROW_IDX, + options_menu_return_bottom_row_size, regular_button_row_on_selection_changed, options_menu_row_on_key_transit, {.wrap = false} } }; -static Button options_menu_buttons[] = { - {SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}, - {CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, high_contrast_on_pressed, NULL}, - {MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}, - {SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}, - {BACK_BUTTON_OUTLINE_COLOR_PAL_IDX, BACK_BUTTON_MAIN_COLOR_PAL_IDX, back_on_pressed, NULL} +static Button options_menu_buttons[NB_OPTIONS_ROWS][2] = { + {{SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}}, + {{CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, high_contrast_on_pressed, NULL}}, + {{MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}}, + {{SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}}, + { + {SAVE_BUTTON_OUTLINE_COLOR_PAL_IDX, SAVE_BUTTON_MAIN_COLOR_PAL_IDX, save_on_pressed, NULL}, + {BACK_BUTTON_OUTLINE_COLOR_PAL_IDX, BACK_BUTTON_MAIN_COLOR_PAL_IDX, back_on_pressed, NULL}, + } }; static Button game_speed_buttons[] = { @@ -138,7 +144,7 @@ const Selection OPTIONS_MENU_INIT_SEL = {0, 0}; static SelectionGrid options_menu_selection_grid = { options_menu_selection_rows, - NB_OPTIONS_BUTTONS, + NB_OPTIONS_ROWS, OPTIONS_MENU_INIT_SEL }; @@ -146,28 +152,28 @@ static SelectionGrid options_menu_selection_grid = { // clang-format off // Values in tiles -static const Rect OPTIONS_SPEED_DOWN_ACTIVE_BTN_SRC_RECT = { 3, 20, 3, 21}; -static const Rect OPTIONS_SPEED_DOWN_DISABLED_BTN_SRC_RECT = { 9, 22, 9, 23}; +static const Rect OPTIONS_SPEED_DOWN_ACTIVE_BTN_SRC_RECT = { 0, 20, 0, 21}; +static const Rect OPTIONS_SPEED_DOWN_DISABLED_BTN_SRC_RECT = { 6, 22, 6, 23}; static const BG_POINT OPTIONS_SPEED_DOWN_BTN_DEST_POS = {11, 3}; -static const Rect OPTIONS_SPEED_UP_ACTIVE_BTN_SRC_RECT = {10, 20, 10, 21}; -static const Rect OPTIONS_SPEED_UP_DISABLED_BTN_SRC_RECT = {10, 22, 10, 23}; +static const Rect OPTIONS_SPEED_UP_ACTIVE_BTN_SRC_RECT = { 7, 20, 7, 21}; +static const Rect OPTIONS_SPEED_UP_DISABLED_BTN_SRC_RECT = { 7, 22, 7, 23}; static const BG_POINT OPTIONS_SPEED_UP_BTN_DEST_POS = {18, 3}; -static const Rect OPTIONS_SPEED_VALUES[GAME_SPEED_MAX] = { { 6, 20, 7, 21}, - { 3, 22, 4, 23}, - { 5, 22, 6, 23}, - { 7, 22, 8, 23} }; +static const Rect OPTIONS_SPEED_VALUES[GAME_SPEED_MAX] = { { 3, 20, 4, 21}, + { 0, 22, 1, 23}, + { 2, 22, 3, 23}, + { 4, 22, 5, 23} }; static const BG_POINT OPTIONS_SPEED_VALUE_DEST_POS = {14, 3}; -static const Rect OPTIONS_CONTRAST_VALUE_YES_SRC_RECT = { 4, 24, 7, 25}; -static const Rect OPTIONS_CONTRAST_VALUE_NO_SRC_RECT = { 9, 24, 12, 25}; +static const Rect OPTIONS_CONTRAST_VALUE_YES_SRC_RECT = { 1, 24, 4, 25}; +static const Rect OPTIONS_CONTRAST_VALUE_NO_SRC_RECT = { 6, 24, 9, 25}; static const BG_POINT OPTIONS_CONTRAST_VALUE_DEST_POS = {13, 7}; -static const Rect OPTIONS_MUSIC_SLIDER_FULL_SRC = {12, 20, 12, 20}; -static const Rect OPTIONS_MUSIC_SLIDER_MID_SRC = {13, 20, 13, 20}; -static const Rect OPTIONS_MUSIC_SLIDER_EMPTY_SRC = {14, 20, 14, 20}; -static const Rect OPTIONS_SOUND_SLIDER_FULL_SRC = {12, 22, 12, 22}; -static const Rect OPTIONS_SOUND_SLIDER_MID_SRC = {13, 22, 13, 22}; -static const Rect OPTIONS_SOUND_SLIDER_EMPTY_SRC = {14, 22, 14, 22}; +static const Rect OPTIONS_MUSIC_SLIDER_FULL_SRC = { 9, 20, 9, 20}; +static const Rect OPTIONS_MUSIC_SLIDER_MID_SRC = {10, 20, 10, 20}; +static const Rect OPTIONS_MUSIC_SLIDER_EMPTY_SRC = {11, 20, 11, 20}; +static const Rect OPTIONS_SOUND_SLIDER_FULL_SRC = { 9, 22, 9, 22}; +static const Rect OPTIONS_SOUND_SLIDER_MID_SRC = {10, 22, 10, 22}; +static const Rect OPTIONS_SOUND_SLIDER_EMPTY_SRC = {11, 22, 11, 22}; static const BG_POINT OPTIONS_MUSIC_SLIDER_START_POS = { 5, 11}; static const BG_POINT OPTIONS_SOUND_SLIDER_START_POS = { 5, 14}; static const BG_POINT OPTIONS_MUSIC_SLIDER_END_POS = {24, 11}; @@ -184,16 +190,13 @@ static const BG_POINT OPTIONS_MUSIC_VOLUME_TEXT_POS = { 56, 80}; static const BG_POINT OPTIONS_MUSIC_VALUE_TEXT_POS = {160, 80}; static const BG_POINT OPTIONS_SOUND_VOLUME_TEXT_POS = { 56, 104}; static const BG_POINT OPTIONS_SOUND_VALUE_TEXT_POS = {160, 104}; -static const BG_POINT OPTIONS_BACK_SAVE_TEXT_POS = { 72, 136}; +static const BG_POINT OPTIONS_BACK_SAVE_TEXT_POS = { 64, 136}; // clang-format on #define GAME_SPEED_ARROW_HIGHLIGHT_DURATION 10 enum OptionSpeedButtons game_speed_arrow_highlight_button = GAME_SPEED_UP_BTN_IDX; static s32 game_speed_arrow_highlight_start = UNDEFINED; -static bool any_value_changed = false; -static bool back_btn_is_save_state = false; - static void disable_all_game_speed_outlines_except_self(enum OptionSpeedButtons highlighted_btn) { for (int i = 0; i < NB_GAME_SPEED_BUTTONS; i++) @@ -202,14 +205,19 @@ static void disable_all_game_speed_outlines_except_self(enum OptionSpeedButtons } } -static void disable_all_outlines_except_self(enum OptionButtons highlighted_btn) +static void disable_all_outlines_except_self(Selection sel_btn) { // These two get disabled no matter what here disable_all_game_speed_outlines_except_self(NB_GAME_SPEED_BUTTONS); - for (int i = 0; i < NB_OPTIONS_BUTTONS; i++) + for (int j = 0; j < NB_OPTIONS_ROWS; j++) { - button_set_highlight(&options_menu_buttons[i], i == highlighted_btn); + int nb_buttons_in_row = (j == SAVE_BACK_ROW_IDX) ? options_menu_return_bottom_row_size() + : options_menu_return_upper_rows_size(); + for (int i = 0; i < nb_buttons_in_row; i++) + { + button_set_highlight(&options_menu_buttons[j][i], i == sel_btn.x && j == sel_btn.y); + } } } @@ -244,8 +252,6 @@ static void update_game_speed_button_graphics() OPTIONS_SPEED_VALUES[g_game_vars.game_speed - 1], OPTIONS_SPEED_VALUE_DEST_POS ); - - any_value_changed = true; } static void update_high_contrast_button_graphics() @@ -258,11 +264,9 @@ static void update_high_contrast_button_graphics() { main_bg_se_copy_rect(OPTIONS_CONTRAST_VALUE_NO_SRC_RECT, OPTIONS_CONTRAST_VALUE_DEST_POS); } - - any_value_changed = true; } -static void update_volume_slider_graphics(enum OptionButtons slider_idx) +static void update_volume_slider_graphics(enum OptionButtonRows sel_row) { u8 slider_value; BG_POINT slider_segment_dest; @@ -272,9 +276,9 @@ static void update_volume_slider_graphics(enum OptionButtons slider_idx) Rect slider_segment_empty; BG_POINT slider_text_pos; - switch (slider_idx) + switch (sel_row) { - case MUSIC_VOLUME_BTN_IDX: + case MUSIC_VOLUME_ROW_IDX: slider_value = g_game_vars.music_volume; slider_segment_dest = OPTIONS_MUSIC_SLIDER_START_POS; slider_segment_length = OPTIONS_MUSIC_SLIDER_SEGMENT_LENGTH; @@ -283,7 +287,7 @@ static void update_volume_slider_graphics(enum OptionButtons slider_idx) slider_segment_empty = OPTIONS_MUSIC_SLIDER_EMPTY_SRC; slider_text_pos = OPTIONS_MUSIC_VALUE_TEXT_POS; break; - case SOUND_VOLUME_BTN_IDX: + case SOUND_VOLUME_ROW_IDX: slider_value = g_game_vars.sound_volume; slider_segment_dest = OPTIONS_SOUND_SLIDER_START_POS; slider_segment_length = OPTIONS_SOUND_SLIDER_SEGMENT_LENGTH; @@ -338,20 +342,6 @@ static void update_volume_slider_graphics(enum OptionButtons slider_idx) TTE_WHITE_PB, (slider_value * VOLUME_OPTION_INCREMENT) ); - - any_value_changed = true; -} - -static void change_back_save_text(bool is_back) -{ - char* btn_text = is_back ? " Back " : "Save Changes"; - tte_printf( - "#{P:%d,%d; cx:0x%X000}%s", - OPTIONS_BACK_SAVE_TEXT_POS.x, - OPTIONS_BACK_SAVE_TEXT_POS.y, - TTE_WHITE_PB, - btn_text - ); } void game_options_menu_change_background(void) @@ -387,7 +377,12 @@ void game_options_menu_change_background(void) OPTIONS_SOUND_VOLUME_TEXT_POS.y, TTE_WHITE_PB ); - change_back_save_text(true); + tte_printf( + "#{P:%d,%d; cx:0x%X000}Save Cancel", + OPTIONS_BACK_SAVE_TEXT_POS.x, + OPTIONS_BACK_SAVE_TEXT_POS.y, + TTE_WHITE_PB + ); } void game_options_menu_on_init(void) @@ -396,17 +391,13 @@ void game_options_menu_on_init(void) // Select game speed button by default options_menu_selection_grid.selection = OPTIONS_MENU_INIT_SEL; - disable_all_outlines_except_self(GAME_SPEED_BTN_IDX); + disable_all_outlines_except_self(OPTIONS_MENU_INIT_SEL); // Do an update on the first frame update_game_speed_button_graphics(); update_high_contrast_button_graphics(); - update_volume_slider_graphics(MUSIC_VOLUME_BTN_IDX); - update_volume_slider_graphics(SOUND_VOLUME_BTN_IDX); - - // Prevent "Back" button to become "Save Changes" when we first load the data, - // the player hasn't technically changed anything so it would be confusing. - any_value_changed = false; + update_volume_slider_graphics(MUSIC_VOLUME_ROW_IDX); + update_volume_slider_graphics(SOUND_VOLUME_ROW_IDX); } void game_options_menu_on_update(void) @@ -421,17 +412,6 @@ void game_options_menu_on_update(void) game_speed_arrow_highlight_start = UNDEFINED; button_set_highlight(&game_speed_buttons[game_speed_arrow_highlight_button], false); } - - // Except on the first update where it is forced to display the loaded values - // instead of the default ones, if any value was changed, edit the last button - // text to read "Save Changes" instead of "Back" - if (any_value_changed && !back_btn_is_save_state) - { - change_back_save_text(false); - back_btn_is_save_state = true; - } - - any_value_changed = false; } void game_options_menu_on_exit(void) @@ -467,50 +447,58 @@ static void high_contrast_on_pressed(void) } /** - * @brief Handles input for the Back/Save button. + * @brief Handles input for the Save button. */ -static void back_on_pressed(void) +static void save_on_pressed(void) { - if (back_btn_is_save_state) - { - save_options(); - change_back_save_text(true); - back_btn_is_save_state = false; - } - else - { - game_change_state(GAME_STATE_MAIN_MENU); - } + save_options(); + game_change_state(GAME_STATE_MAIN_MENU); } /** - * @brief Gives the width of options menu rows in selection grid. - * - * @returns Always 1, all rows contain only 1 button. Could have been a define - * but I had to make this a function so it could be given to the - * SelectionGrid constructor. + * @brief Handles input for the Back button. */ -static int options_menu_return_row_size(void) +static void back_on_pressed(void) +{ + load_options(); + game_change_state(GAME_STATE_MAIN_MENU); +} + +/** + * @brief Gives the width of upper options menu rows in selection grid. + * + * @returns 1 + */ +static int options_menu_return_upper_rows_size(void) { return 1; } +/** + * @brief Gives the width of the Save and Back buttons' row. + * + * @returns 2 + */ +static int options_menu_return_bottom_row_size(void) +{ + return 2; +} + static void change_button_highlight( int row_idx, const Selection* prev_selection, const Selection* new_selection ) { - if (prev_selection->y == row_idx && prev_selection->x >= 0 && - prev_selection->x < NB_OPTIONS_BUTTONS) + if (prev_selection->y == row_idx) { - button_set_highlight(&options_menu_buttons[row_idx], false); + button_set_highlight(&options_menu_buttons[row_idx][prev_selection->x], false); } if (new_selection->y == row_idx) { play_sfx(SFX_BUTTON, MM_BASE_PITCH_RATE, BUTTON_SFX_VOLUME); - button_set_highlight(&options_menu_buttons[row_idx], true); + button_set_highlight(&options_menu_buttons[row_idx][new_selection->x], true); } } @@ -555,7 +543,7 @@ static void options_menu_row_on_key_transit(SelectionGrid* selection_grid, Selec { if (key_hit(SELECT_CARD)) { - button_press(&options_menu_buttons[selection->y]); + button_press(&options_menu_buttons[selection->y][selection->x]); } } @@ -591,7 +579,7 @@ static bool music_volume_row_on_selection_changed( g_game_vars.music_volume++; } - update_volume_slider_graphics(MUSIC_VOLUME_BTN_IDX); + update_volume_slider_graphics(MUSIC_VOLUME_ROW_IDX); mmSetModuleVolume(MM_MODULE_FULL_VOLUME * g_game_vars.music_volume / VOLUME_OPTION_MAX); return true; @@ -618,7 +606,7 @@ static bool sound_volume_row_on_selection_changed( g_game_vars.sound_volume++; } - update_volume_slider_graphics(SOUND_VOLUME_BTN_IDX); + update_volume_slider_graphics(SOUND_VOLUME_ROW_IDX); return true; } diff --git a/source/save.c b/source/save.c index d637867..3622e27 100644 --- a/source/save.c +++ b/source/save.c @@ -155,10 +155,10 @@ static const SaveHeader SaveHeader_default = { */ static const SaveOptions SaveOptions_default = { .tag_options = "- OPTIONS DATA -", - .game_speed = 0, - .high_contrast = false, - .music_volume = 0, - .sound_volume = 0, + .game_speed = GAME_SPEED_MIN, + .high_contrast = DEFAULT_HIGH_CONTRAST, + .music_volume = VOLUME_OPTION_MAX, + .sound_volume = VOLUME_OPTION_MAX, .padding = {UNDEFINED, UNDEFINED, UNDEFINED}, }; @@ -306,12 +306,12 @@ void save_options(void) void load_options(void) { SaveHeader header; - if (!get_save_header(&header) || !(header.valid_sections & SAVE_SECTION_FLAG_OPTIONS)) - return; - SaveOptions options = SaveOptions_default; - read_sram(OPTIONS_ADDRESS, (u8*)&options, sizeof(options)); + // If options data doesn't exist or is invalid, just don't read from + // SRAM and apply the default values + if (get_save_header(&header) && (header.valid_sections & SAVE_SECTION_FLAG_OPTIONS)) + read_sram(OPTIONS_ADDRESS, (u8*)&options, sizeof(options)); g_game_vars.game_speed = options.game_speed; g_game_vars.high_contrast = options.high_contrast; @@ -362,11 +362,11 @@ void save_game(void) void load_game(void) { SaveHeader header; + if (!get_save_header(&header) || !(header.valid_sections & SAVE_SECTION_FLAG_GAME)) return; SaveGame game = SaveGame_default; - read_sram(GAME_ADDRESS, (u8*)&game, sizeof(game)); g_game_vars.timer = game.timer;