5#include "background_options_menu_gfx.h"
21#include <tonc_memdef.h>
26 HIGH_CONTRAST_ROW_IDX,
32enum OptionSpeedButtons
34 GAME_SPEED_DOWN_BTN_IDX,
35 GAME_SPEED_UP_BTN_IDX,
43#define MENU_BUTTON_MAIN_COLOR_PAL_IDX 1
44#define SAVE_BUTTON_MAIN_COLOR_PAL_IDX 3
45#define BACK_BUTTON_MAIN_COLOR_PAL_IDX 4
46#define SPEED_DOWN_BUTTON_OUTLINE_COLOR_PAL_IDX 16
47#define SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX 17
48#define SPEED_UP_BUTTON_OUTLINE_COLOR_PAL_IDX 18
49#define CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX 19
50#define READABLE_BUTTON_OUTLINE_COLOR_PAL_IDX 20
51#define MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX 21
52#define SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX 22
53#define SAVE_BUTTON_OUTLINE_COLOR_PAL_IDX 23
54#define BACK_BUTTON_OUTLINE_COLOR_PAL_IDX 24
58static void game_speed_down_on_pressed(
void);
59static void game_speed_up_on_pressed(
void);
60static void high_contrast_on_pressed(
void);
61static void more_readable_on_pressed(
void);
62static void save_on_pressed(
void);
63static void back_on_pressed(
void);
64static int options_menu_return_upper_rows_size(
void);
65static int options_menu_return_card_sprites_row_size(
void);
66static int options_menu_return_bottom_row_size(
void);
67static void options_menu_row_on_key_transit(
SelectionGrid* selection_grid, Selection* selection);
68static bool game_speed_row_on_selection_changed(
71 const Selection* prev_selection,
72 const Selection* new_selection
74static bool music_volume_row_on_selection_changed(
77 const Selection* prev_selection,
78 const Selection* new_selection
80static bool sound_volume_row_on_selection_changed(
83 const Selection* prev_selection,
84 const Selection* new_selection
86static bool regular_button_row_on_selection_changed(
89 const Selection* prev_selection,
90 const Selection* new_selection
97 options_menu_return_upper_rows_size,
98 game_speed_row_on_selection_changed,
104 HIGH_CONTRAST_ROW_IDX,
105 options_menu_return_card_sprites_row_size,
106 regular_button_row_on_selection_changed,
107 options_menu_row_on_key_transit,
111 MUSIC_VOLUME_ROW_IDX,
112 options_menu_return_upper_rows_size,
113 music_volume_row_on_selection_changed,
118 SOUND_VOLUME_ROW_IDX,
119 options_menu_return_upper_rows_size,
120 sound_volume_row_on_selection_changed,
126 options_menu_return_bottom_row_size,
127 regular_button_row_on_selection_changed,
128 options_menu_row_on_key_transit,
133static Button options_menu_buttons[NB_OPTIONS_ROWS][2] = {
134 {{SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}},
136 {CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, high_contrast_on_pressed, NULL},
137 {READABLE_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, more_readable_on_pressed, NULL}
139 {{MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}},
140 {{SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}},
142 {SAVE_BUTTON_OUTLINE_COLOR_PAL_IDX, SAVE_BUTTON_MAIN_COLOR_PAL_IDX, save_on_pressed, NULL},
143 {BACK_BUTTON_OUTLINE_COLOR_PAL_IDX, BACK_BUTTON_MAIN_COLOR_PAL_IDX, back_on_pressed, NULL},
147static Button game_speed_buttons[] = {
148 {SPEED_DOWN_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, game_speed_down_on_pressed, NULL},
149 {SPEED_UP_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, game_speed_up_on_pressed, NULL},
153const Selection OPTIONS_MENU_INIT_SEL = {0, 0};
156 options_menu_selection_rows,
158 OPTIONS_MENU_INIT_SEL
165static const Rect OPTIONS_SPEED_DOWN_ACTIVE_BTN_SRC_RECT = { 0, 20, 0, 21};
166static const Rect OPTIONS_SPEED_DOWN_DISABLED_BTN_SRC_RECT = { 6, 22, 6, 23};
167static const BG_POINT OPTIONS_SPEED_DOWN_BTN_DEST_POS = {11, 3};
168static const Rect OPTIONS_SPEED_UP_ACTIVE_BTN_SRC_RECT = { 7, 20, 7, 21};
169static const Rect OPTIONS_SPEED_UP_DISABLED_BTN_SRC_RECT = { 7, 22, 7, 23};
170static const BG_POINT OPTIONS_SPEED_UP_BTN_DEST_POS = {18, 3};
171static const Rect OPTIONS_SPEED_VALUES[GAME_SPEED_MAX] = { { 3, 20, 4, 21},
175static const BG_POINT OPTIONS_SPEED_VALUE_DEST_POS = {14, 3};
177static const Rect OPTIONS_CONTRAST_CHECK_NO_SRC_RECT = { 0, 24, 1, 25};
178static const Rect OPTIONS_CONTRAST_CHECK_YES_SRC_RECT = { 2, 24, 3, 25};
179static const BG_POINT OPTIONS_CONTRAST_CHECK_DEST_POS = {14, 7};
180static const Rect OPTIONS_READABLE_CHECK_NO_SRC_RECT = { 4, 24, 5, 25};
181static const Rect OPTIONS_READABLE_CHECK_YES_SRC_RECT = { 6, 24, 7, 25};
182static const BG_POINT OPTIONS_READABLE_CHECK_DEST_POS = {21, 7};
184static const Rect OPTIONS_MUSIC_SLIDER_FULL_SRC = { 9, 20, 9, 20};
185static const Rect OPTIONS_MUSIC_SLIDER_MID_SRC = {10, 20, 10, 20};
186static const Rect OPTIONS_MUSIC_SLIDER_EMPTY_SRC = {11, 20, 11, 20};
187static const Rect OPTIONS_SOUND_SLIDER_FULL_SRC = { 9, 22, 9, 22};
188static const Rect OPTIONS_SOUND_SLIDER_MID_SRC = {10, 22, 10, 22};
189static const Rect OPTIONS_SOUND_SLIDER_EMPTY_SRC = {11, 22, 11, 22};
190static const BG_POINT OPTIONS_MUSIC_SLIDER_START_POS = { 5, 11};
191static const BG_POINT OPTIONS_SOUND_SLIDER_START_POS = { 5, 14};
192static const BG_POINT OPTIONS_MUSIC_SLIDER_END_POS = {24, 11};
193static const BG_POINT OPTIONS_SOUND_SLIDER_END_POS = {24, 14};
194static const u8 OPTIONS_MUSIC_SLIDER_SEGMENT_LENGTH = (OPTIONS_MUSIC_SLIDER_END_POS.x - OPTIONS_MUSIC_SLIDER_START_POS.x + 1)
196static const u8 OPTIONS_SOUND_SLIDER_SEGMENT_LENGTH = (OPTIONS_SOUND_SLIDER_END_POS.x - OPTIONS_SOUND_SLIDER_START_POS.x + 1)
200static const BG_POINT OPTIONS_GAME_SPEED_TEXT_POS = { 82, 16};
201static const BG_POINT OPTIONS_CARD_SPRITES_TEXT_POS = { 72, 48};
202static const BG_POINT OPTIONS_MUSIC_VOLUME_TEXT_POS = { 56, 80};
203static const BG_POINT OPTIONS_MUSIC_VALUE_TEXT_POS = {160, 80};
204static const BG_POINT OPTIONS_SOUND_VOLUME_TEXT_POS = { 56, 104};
205static const BG_POINT OPTIONS_SOUND_VALUE_TEXT_POS = {160, 104};
206static const BG_POINT OPTIONS_BACK_SAVE_TEXT_POS = { 64, 136};
209#define GAME_SPEED_ARROW_HIGHLIGHT_DURATION 10
210enum OptionSpeedButtons game_speed_arrow_highlight_button = GAME_SPEED_UP_BTN_IDX;
211static s32 game_speed_arrow_highlight_start = UNDEFINED;
213static void disable_all_game_speed_outlines_except_self(
enum OptionSpeedButtons highlighted_btn)
215 for (
int i = 0; i < NB_GAME_SPEED_BUTTONS; i++)
221static void disable_all_outlines_except_self(Selection sel_btn)
224 disable_all_game_speed_outlines_except_self(NB_GAME_SPEED_BUTTONS);
226 for (
int j = 0; j < NB_OPTIONS_ROWS; j++)
228 int nb_buttons_in_row;
232 case HIGH_CONTRAST_ROW_IDX:
233 nb_buttons_in_row = options_menu_return_card_sprites_row_size();
235 case SAVE_BACK_ROW_IDX:
236 nb_buttons_in_row = options_menu_return_bottom_row_size();
239 nb_buttons_in_row = options_menu_return_upper_rows_size();
243 for (
int i = 0; i < nb_buttons_in_row; i++)
250static void update_game_speed_button_graphics()
254 Rect speed_down_btn_tiles = (g_game_vars.game_speed == GAME_SPEED_MIN)
255 ? OPTIONS_SPEED_DOWN_DISABLED_BTN_SRC_RECT
256 : OPTIONS_SPEED_DOWN_ACTIVE_BTN_SRC_RECT;
259 Rect speed_up_btn_tiles = (g_game_vars.game_speed == GAME_SPEED_MAX)
260 ? OPTIONS_SPEED_UP_DISABLED_BTN_SRC_RECT
261 : OPTIONS_SPEED_UP_ACTIVE_BTN_SRC_RECT;
265 OPTIONS_SPEED_VALUES[g_game_vars.game_speed - 1],
266 OPTIONS_SPEED_VALUE_DEST_POS
270static void update_high_contrast_button_graphics(
void)
272 Rect contrast_btn_tiles = (get_cards_high_contrast()) ? OPTIONS_CONTRAST_CHECK_YES_SRC_RECT
273 : OPTIONS_CONTRAST_CHECK_NO_SRC_RECT;
277static void update_more_readable_button_graphics(
void)
279 Rect readable_btn_tiles = (get_cards_more_readable()) ? OPTIONS_READABLE_CHECK_YES_SRC_RECT
280 : OPTIONS_READABLE_CHECK_NO_SRC_RECT;
284static void update_volume_slider_graphics(
enum OptionButtonRows sel_row)
287 BG_POINT slider_segment_dest;
288 int slider_segment_length;
289 Rect slider_segment_full;
290 Rect slider_segment_mid;
291 Rect slider_segment_empty;
292 BG_POINT slider_text_pos;
296 case MUSIC_VOLUME_ROW_IDX:
297 slider_value = g_game_vars.music_volume;
298 slider_segment_dest = OPTIONS_MUSIC_SLIDER_START_POS;
299 slider_segment_length = OPTIONS_MUSIC_SLIDER_SEGMENT_LENGTH;
300 slider_segment_full = OPTIONS_MUSIC_SLIDER_FULL_SRC;
301 slider_segment_mid = OPTIONS_MUSIC_SLIDER_MID_SRC;
302 slider_segment_empty = OPTIONS_MUSIC_SLIDER_EMPTY_SRC;
303 slider_text_pos = OPTIONS_MUSIC_VALUE_TEXT_POS;
305 case SOUND_VOLUME_ROW_IDX:
306 slider_value = g_game_vars.sound_volume;
307 slider_segment_dest = OPTIONS_SOUND_SLIDER_START_POS;
308 slider_segment_length = OPTIONS_SOUND_SLIDER_SEGMENT_LENGTH;
309 slider_segment_full = OPTIONS_SOUND_SLIDER_FULL_SRC;
310 slider_segment_mid = OPTIONS_SOUND_SLIDER_MID_SRC;
311 slider_segment_empty = OPTIONS_SOUND_SLIDER_EMPTY_SRC;
312 slider_text_pos = OPTIONS_SOUND_VALUE_TEXT_POS;
322 for (; i < slider_value * slider_segment_length - 1; i++)
325 slider_segment_dest.x++;
331 if (slider_value == VOLUME_OPTION_MAX)
337 if (slider_value != VOLUME_OPTION_MIN)
342 slider_segment_dest.x++;
346 for (; i < VOLUME_OPTION_MAX * slider_segment_length; i++)
349 slider_segment_dest.x++;
354 "#{P:%d,%d; cx:0x%X000}%3d",
358 (slider_value * VOLUME_OPTION_INCREMENT)
366 GRIT_CPY(pal_bg_mem, background_options_menu_gfxPal);
367 GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_options_menu_gfxTiles);
368 GRIT_CPY(&se_mem[MAIN_BG_SBB], background_options_menu_gfxMap);
371 "#{P:%d,%d; cx:0x%X000}Game Speed",
372 OPTIONS_GAME_SPEED_TEXT_POS.x,
373 OPTIONS_GAME_SPEED_TEXT_POS.y,
377 "#{P:%d,%d; cx:0x%X000}Card Sprites",
378 OPTIONS_CARD_SPRITES_TEXT_POS.x,
379 OPTIONS_CARD_SPRITES_TEXT_POS.y,
383 "#{P:%d,%d; cx:0x%X000}Music Volume",
384 OPTIONS_MUSIC_VOLUME_TEXT_POS.x,
385 OPTIONS_MUSIC_VOLUME_TEXT_POS.y,
389 "#{P:%d,%d; cx:0x%X000}Sound Volume",
390 OPTIONS_SOUND_VOLUME_TEXT_POS.x,
391 OPTIONS_SOUND_VOLUME_TEXT_POS.y,
395 "#{P:%d,%d; cx:0x%X000}Save Cancel",
396 OPTIONS_BACK_SAVE_TEXT_POS.x,
397 OPTIONS_BACK_SAVE_TEXT_POS.y,
407 options_menu_selection_grid.selection = OPTIONS_MENU_INIT_SEL;
408 disable_all_outlines_except_self(OPTIONS_MENU_INIT_SEL);
411 update_game_speed_button_graphics();
412 update_high_contrast_button_graphics();
413 update_more_readable_button_graphics();
414 update_volume_slider_graphics(MUSIC_VOLUME_ROW_IDX);
415 update_volume_slider_graphics(SOUND_VOLUME_ROW_IDX);
423 if (game_speed_arrow_highlight_start != UNDEFINED &&
424 (g_game_vars.timer - game_speed_arrow_highlight_start) >
425 GAME_SPEED_ARROW_HIGHLIGHT_DURATION)
427 game_speed_arrow_highlight_start = UNDEFINED;
437static void game_speed_down_on_pressed(
void)
439 g_game_vars.game_speed--;
440 game_speed_arrow_highlight_start = g_game_vars.timer;
441 game_speed_arrow_highlight_button = GAME_SPEED_DOWN_BTN_IDX;
442 disable_all_game_speed_outlines_except_self(GAME_SPEED_DOWN_BTN_IDX);
443 update_game_speed_button_graphics();
446static void game_speed_up_on_pressed(
void)
448 g_game_vars.game_speed++;
449 game_speed_arrow_highlight_start = g_game_vars.timer;
450 game_speed_arrow_highlight_button = GAME_SPEED_UP_BTN_IDX;
451 disable_all_game_speed_outlines_except_self(GAME_SPEED_UP_BTN_IDX);
452 update_game_speed_button_graphics();
458static void high_contrast_on_pressed(
void)
460 set_cards_high_contrast(!get_cards_high_contrast());
461 update_high_contrast_button_graphics();
467static void more_readable_on_pressed(
void)
469 set_cards_more_readable(!get_cards_more_readable());
470 update_more_readable_button_graphics();
476static void save_on_pressed(
void)
479 game_change_state(GAME_STATE_MAIN_MENU);
485static void back_on_pressed(
void)
488 game_change_state(GAME_STATE_MAIN_MENU);
496static int options_menu_return_upper_rows_size(
void)
506static int options_menu_return_card_sprites_row_size(
void)
516static int options_menu_return_bottom_row_size(
void)
521static void change_button_highlight(
523 const Selection* prev_selection,
524 const Selection* new_selection
527 if (prev_selection->y == row_idx)
532 if (new_selection->y == row_idx)
545static bool game_speed_row_on_selection_changed(
548 const Selection* prev_selection,
549 const Selection* new_selection
552 change_button_highlight(row_idx, prev_selection, new_selection);
553 disable_all_game_speed_outlines_except_self(NB_GAME_SPEED_BUTTONS);
556 if (prev_selection->y != new_selection->y)
559 if (key_hit(KEY_LEFT) && g_game_vars.game_speed > GAME_SPEED_MIN)
561 button_press(&game_speed_buttons[GAME_SPEED_DOWN_BTN_IDX]);
563 else if (key_hit(KEY_RIGHT) && g_game_vars.game_speed < GAME_SPEED_MAX)
565 button_press(&game_speed_buttons[GAME_SPEED_UP_BTN_IDX]);
576static void options_menu_row_on_key_transit(
SelectionGrid* selection_grid, Selection* selection)
578 if (key_hit(SELECT_CARD))
580 button_press(&options_menu_buttons[selection->y][selection->x]);
584static bool regular_button_row_on_selection_changed(
587 const Selection* prev_selection,
588 const Selection* new_selection
591 change_button_highlight(row_idx, prev_selection, new_selection);
595static bool music_volume_row_on_selection_changed(
598 const Selection* prev_selection,
599 const Selection* new_selection
602 change_button_highlight(row_idx, prev_selection, new_selection);
604 if (prev_selection->y != new_selection->y)
607 if (key_hit(KEY_LEFT) && g_game_vars.music_volume > VOLUME_OPTION_MIN)
609 g_game_vars.music_volume--;
611 else if (key_hit(KEY_RIGHT) && g_game_vars.music_volume < VOLUME_OPTION_MAX)
613 g_game_vars.music_volume++;
616 update_volume_slider_graphics(MUSIC_VOLUME_ROW_IDX);
622static bool sound_volume_row_on_selection_changed(
625 const Selection* prev_selection,
626 const Selection* new_selection
629 change_button_highlight(row_idx, prev_selection, new_selection);
631 if (prev_selection->y != new_selection->y)
634 if (key_hit(KEY_LEFT) && g_game_vars.sound_volume > VOLUME_OPTION_MIN)
636 g_game_vars.sound_volume--;
638 else if (key_hit(KEY_RIGHT) && g_game_vars.sound_volume < VOLUME_OPTION_MAX)
640 g_game_vars.sound_volume++;
643 update_volume_slider_graphics(SOUND_VOLUME_ROW_IDX);
Utilities for affine background on GBA.
Utilities for using maxmod to play sound effects.
#define MM_BASE_PITCH_RATE
The default pitch rate for the sound effect played.
int volume_module_step_to_val(unsigned char step)
Get MaxMod module audio value from VOLUME_OPTION value.
void play_sfx(mm_word id, mm_word rate, mm_byte volume)
Play a sound effect, wrapper for mmEffectEx() See https://maxmod.org/ref/functions/mm_sound_effect....
Common functions to render UI elements.
void change_background(enum BackgroundId id, bool force_redraw)
Game global game variables struct definition.
Graphic utility functions.
void main_bg_se_copy_rect(Rect se_rect, BG_POINT dest_pos)
Copies a rect in the main background from se_rect to the position (x, y).
Utils functions to save/load data structures from/to the SRAM.
void load_options(void)
Load options values from SRAM.
void save_options(void)
Save options values to SRAM.
An implementation for a selection grid that handles directional selection.
void selection_grid_process_input(SelectionGrid *selection_grid)
Processes user input for the selection grid.
The core selection grid struct, represents the grid itself and its state.
Utilities relating around number string representation and protected arithmatic helper functions.