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,
40#define MENU_BUTTON_MAIN_COLOR_PAL_IDX 1
41#define SAVE_BUTTON_MAIN_COLOR_PAL_IDX 3
42#define BACK_BUTTON_MAIN_COLOR_PAL_IDX 4
43#define SPEED_DOWN_BUTTON_OUTLINE_COLOR_PAL_IDX 16
44#define SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX 17
45#define SPEED_UP_BUTTON_OUTLINE_COLOR_PAL_IDX 18
46#define CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX 19
47#define READABLE_BUTTON_OUTLINE_COLOR_PAL_IDX 20
48#define MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX 21
49#define SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX 22
50#define SAVE_BUTTON_OUTLINE_COLOR_PAL_IDX 23
51#define BACK_BUTTON_OUTLINE_COLOR_PAL_IDX 24
55static void game_speed_down_on_pressed(
void);
56static void game_speed_up_on_pressed(
void);
57static void high_contrast_on_pressed(
void);
58static void more_readable_on_pressed(
void);
59static void save_on_pressed(
void);
60static void back_on_pressed(
void);
61static int options_menu_return_upper_rows_size(
void);
62static int options_menu_return_card_sprites_row_size(
void);
63static int options_menu_return_bottom_row_size(
void);
64static void options_menu_row_on_key_transit(
SelectionGrid* selection_grid, Selection* selection);
65static bool game_speed_row_on_selection_changed(
68 const Selection* prev_selection,
69 const Selection* new_selection
71static bool music_volume_row_on_selection_changed(
74 const Selection* prev_selection,
75 const Selection* new_selection
77static bool sound_volume_row_on_selection_changed(
80 const Selection* prev_selection,
81 const Selection* new_selection
83static bool regular_button_row_on_selection_changed(
86 const Selection* prev_selection,
87 const Selection* new_selection
94 options_menu_return_upper_rows_size,
95 game_speed_row_on_selection_changed,
101 HIGH_CONTRAST_ROW_IDX,
102 options_menu_return_card_sprites_row_size,
103 regular_button_row_on_selection_changed,
104 options_menu_row_on_key_transit,
108 MUSIC_VOLUME_ROW_IDX,
109 options_menu_return_upper_rows_size,
110 music_volume_row_on_selection_changed,
115 SOUND_VOLUME_ROW_IDX,
116 options_menu_return_upper_rows_size,
117 sound_volume_row_on_selection_changed,
123 options_menu_return_bottom_row_size,
124 regular_button_row_on_selection_changed,
125 options_menu_row_on_key_transit,
130static Button options_menu_buttons[NB_OPTIONS_ROWS][2] = {
131 {{SPEED_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}},
133 {CONTRAST_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, high_contrast_on_pressed, NULL},
134 {READABLE_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, more_readable_on_pressed, NULL}
136 {{MUSIC_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}},
137 {{SOUND_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, NULL, NULL}},
139 {SAVE_BUTTON_OUTLINE_COLOR_PAL_IDX, SAVE_BUTTON_MAIN_COLOR_PAL_IDX, save_on_pressed, NULL},
140 {BACK_BUTTON_OUTLINE_COLOR_PAL_IDX, BACK_BUTTON_MAIN_COLOR_PAL_IDX, back_on_pressed, NULL},
144static Button game_speed_buttons[] = {
145 {SPEED_DOWN_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, game_speed_down_on_pressed, NULL},
146 {SPEED_UP_BUTTON_OUTLINE_COLOR_PAL_IDX, MENU_BUTTON_MAIN_COLOR_PAL_IDX, game_speed_up_on_pressed, NULL},
150const Selection OPTIONS_MENU_INIT_SEL = {0, 0};
153 options_menu_selection_rows,
155 OPTIONS_MENU_INIT_SEL
162static const Rect OPTIONS_SPEED_DOWN_ACTIVE_BTN_SRC_RECT = { 0, 20, 0, 21};
163static const Rect OPTIONS_SPEED_DOWN_DISABLED_BTN_SRC_RECT = { 6, 22, 6, 23};
164static const BG_POINT OPTIONS_SPEED_DOWN_BTN_DEST_POS = {11, 3};
165static const Rect OPTIONS_SPEED_UP_ACTIVE_BTN_SRC_RECT = { 7, 20, 7, 21};
166static const Rect OPTIONS_SPEED_UP_DISABLED_BTN_SRC_RECT = { 7, 22, 7, 23};
167static const BG_POINT OPTIONS_SPEED_UP_BTN_DEST_POS = {18, 3};
168static const Rect OPTIONS_SPEED_VALUES[GAME_SPEED_MAX] = { { 3, 20, 4, 21},
172static const BG_POINT OPTIONS_SPEED_VALUE_DEST_POS = {14, 3};
174static const Rect OPTIONS_CONTRAST_CHECK_NO_SRC_RECT = { 0, 24, 1, 25};
175static const Rect OPTIONS_CONTRAST_CHECK_YES_SRC_RECT = { 2, 24, 3, 25};
176static const BG_POINT OPTIONS_CONTRAST_CHECK_DEST_POS = {14, 7};
177static const Rect OPTIONS_READABLE_CHECK_NO_SRC_RECT = { 4, 24, 5, 25};
178static const Rect OPTIONS_READABLE_CHECK_YES_SRC_RECT = { 6, 24, 7, 25};
179static const BG_POINT OPTIONS_READABLE_CHECK_DEST_POS = {21, 7};
181static const Rect OPTIONS_MUSIC_SLIDER_FULL_SRC = { 9, 20, 9, 20};
182static const Rect OPTIONS_MUSIC_SLIDER_MID_SRC = {10, 20, 10, 20};
183static const Rect OPTIONS_MUSIC_SLIDER_EMPTY_SRC = {11, 20, 11, 20};
184static const Rect OPTIONS_SOUND_SLIDER_FULL_SRC = { 9, 22, 9, 22};
185static const Rect OPTIONS_SOUND_SLIDER_MID_SRC = {10, 22, 10, 22};
186static const Rect OPTIONS_SOUND_SLIDER_EMPTY_SRC = {11, 22, 11, 22};
187static const BG_POINT OPTIONS_MUSIC_SLIDER_START_POS = { 5, 11};
188static const BG_POINT OPTIONS_SOUND_SLIDER_START_POS = { 5, 14};
189static const BG_POINT OPTIONS_MUSIC_SLIDER_END_POS = {24, 11};
190static const BG_POINT OPTIONS_SOUND_SLIDER_END_POS = {24, 14};
191static const u8 OPTIONS_MUSIC_SLIDER_SEGMENT_LENGTH = (OPTIONS_MUSIC_SLIDER_END_POS.x - OPTIONS_MUSIC_SLIDER_START_POS.x + 1)
193static const u8 OPTIONS_SOUND_SLIDER_SEGMENT_LENGTH = (OPTIONS_SOUND_SLIDER_END_POS.x - OPTIONS_SOUND_SLIDER_START_POS.x + 1)
197static const BG_POINT OPTIONS_GAME_SPEED_TEXT_POS = { 82, 16};
198static const BG_POINT OPTIONS_CARD_SPRITES_TEXT_POS = { 72, 48};
199static const BG_POINT OPTIONS_MUSIC_VOLUME_TEXT_POS = { 56, 80};
200static const BG_POINT OPTIONS_MUSIC_VALUE_TEXT_POS = {160, 80};
201static const BG_POINT OPTIONS_SOUND_VOLUME_TEXT_POS = { 56, 104};
202static const BG_POINT OPTIONS_SOUND_VALUE_TEXT_POS = {160, 104};
203static const BG_POINT OPTIONS_BACK_SAVE_TEXT_POS = { 64, 136};
206#define GAME_SPEED_ARROW_HIGHLIGHT_DURATION 10
207enum OptionSpeedButtons game_speed_arrow_highlight_button = GAME_SPEED_UP_BTN_IDX;
208static s32 game_speed_arrow_highlight_start = UNDEFINED;
210static void disable_all_game_speed_outlines_except_self(
enum OptionSpeedButtons highlighted_btn)
212 for (
int i = 0; i < NB_GAME_SPEED_BUTTONS; i++)
218static void disable_all_outlines_except_self(Selection sel_btn)
221 disable_all_game_speed_outlines_except_self(NB_GAME_SPEED_BUTTONS);
223 for (
int j = 0; j < NB_OPTIONS_ROWS; j++)
225 int nb_buttons_in_row;
229 case HIGH_CONTRAST_ROW_IDX:
230 nb_buttons_in_row = options_menu_return_card_sprites_row_size();
232 case SAVE_BACK_ROW_IDX:
233 nb_buttons_in_row = options_menu_return_bottom_row_size();
236 nb_buttons_in_row = options_menu_return_upper_rows_size();
240 for (
int i = 0; i < nb_buttons_in_row; i++)
247static void update_game_speed_button_graphics()
251 Rect speed_down_btn_tiles = (g_game_vars.game_speed == GAME_SPEED_MIN)
252 ? OPTIONS_SPEED_DOWN_DISABLED_BTN_SRC_RECT
253 : OPTIONS_SPEED_DOWN_ACTIVE_BTN_SRC_RECT;
256 Rect speed_up_btn_tiles = (g_game_vars.game_speed == GAME_SPEED_MAX)
257 ? OPTIONS_SPEED_UP_DISABLED_BTN_SRC_RECT
258 : OPTIONS_SPEED_UP_ACTIVE_BTN_SRC_RECT;
262 OPTIONS_SPEED_VALUES[g_game_vars.game_speed - 1],
263 OPTIONS_SPEED_VALUE_DEST_POS
267static void update_high_contrast_button_graphics(
void)
269 Rect contrast_btn_tiles = (get_cards_high_contrast()) ? OPTIONS_CONTRAST_CHECK_YES_SRC_RECT
270 : OPTIONS_CONTRAST_CHECK_NO_SRC_RECT;
274static void update_more_readable_button_graphics(
void)
276 Rect readable_btn_tiles = (get_cards_more_readable()) ? OPTIONS_READABLE_CHECK_YES_SRC_RECT
277 : OPTIONS_READABLE_CHECK_NO_SRC_RECT;
281static void update_volume_slider_graphics(
enum OptionButtonRows sel_row)
284 BG_POINT slider_segment_dest;
285 int slider_segment_length;
286 Rect slider_segment_full;
287 Rect slider_segment_mid;
288 Rect slider_segment_empty;
289 BG_POINT slider_text_pos;
293 case MUSIC_VOLUME_ROW_IDX:
294 slider_value = g_game_vars.music_volume;
295 slider_segment_dest = OPTIONS_MUSIC_SLIDER_START_POS;
296 slider_segment_length = OPTIONS_MUSIC_SLIDER_SEGMENT_LENGTH;
297 slider_segment_full = OPTIONS_MUSIC_SLIDER_FULL_SRC;
298 slider_segment_mid = OPTIONS_MUSIC_SLIDER_MID_SRC;
299 slider_segment_empty = OPTIONS_MUSIC_SLIDER_EMPTY_SRC;
300 slider_text_pos = OPTIONS_MUSIC_VALUE_TEXT_POS;
302 case SOUND_VOLUME_ROW_IDX:
303 slider_value = g_game_vars.sound_volume;
304 slider_segment_dest = OPTIONS_SOUND_SLIDER_START_POS;
305 slider_segment_length = OPTIONS_SOUND_SLIDER_SEGMENT_LENGTH;
306 slider_segment_full = OPTIONS_SOUND_SLIDER_FULL_SRC;
307 slider_segment_mid = OPTIONS_SOUND_SLIDER_MID_SRC;
308 slider_segment_empty = OPTIONS_SOUND_SLIDER_EMPTY_SRC;
309 slider_text_pos = OPTIONS_SOUND_VALUE_TEXT_POS;
319 for (; i < slider_value * slider_segment_length - 1; i++)
322 slider_segment_dest.x++;
328 if (slider_value == VOLUME_OPTION_MAX)
334 if (slider_value != VOLUME_OPTION_MIN)
339 slider_segment_dest.x++;
343 for (; i < VOLUME_OPTION_MAX * slider_segment_length; i++)
346 slider_segment_dest.x++;
351 "#{P:%d,%d; cx:0x%X000}%3d",
355 (slider_value * VOLUME_OPTION_INCREMENT)
363 GRIT_CPY(pal_bg_mem, background_options_menu_gfxPal);
364 GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_options_menu_gfxTiles);
365 GRIT_CPY(&se_mem[MAIN_BG_SBB], background_options_menu_gfxMap);
368 "#{P:%d,%d; cx:0x%X000}Game Speed",
369 OPTIONS_GAME_SPEED_TEXT_POS.x,
370 OPTIONS_GAME_SPEED_TEXT_POS.y,
374 "#{P:%d,%d; cx:0x%X000}Card Sprites",
375 OPTIONS_CARD_SPRITES_TEXT_POS.x,
376 OPTIONS_CARD_SPRITES_TEXT_POS.y,
380 "#{P:%d,%d; cx:0x%X000}Music Volume",
381 OPTIONS_MUSIC_VOLUME_TEXT_POS.x,
382 OPTIONS_MUSIC_VOLUME_TEXT_POS.y,
386 "#{P:%d,%d; cx:0x%X000}Sound Volume",
387 OPTIONS_SOUND_VOLUME_TEXT_POS.x,
388 OPTIONS_SOUND_VOLUME_TEXT_POS.y,
392 "#{P:%d,%d; cx:0x%X000}Save Cancel",
393 OPTIONS_BACK_SAVE_TEXT_POS.x,
394 OPTIONS_BACK_SAVE_TEXT_POS.y,
404 options_menu_selection_grid.selection = OPTIONS_MENU_INIT_SEL;
405 disable_all_outlines_except_self(OPTIONS_MENU_INIT_SEL);
408 update_game_speed_button_graphics();
409 update_high_contrast_button_graphics();
410 update_more_readable_button_graphics();
411 update_volume_slider_graphics(MUSIC_VOLUME_ROW_IDX);
412 update_volume_slider_graphics(SOUND_VOLUME_ROW_IDX);
420 if (game_speed_arrow_highlight_start != UNDEFINED &&
421 (g_game_vars.timer - game_speed_arrow_highlight_start) >
422 GAME_SPEED_ARROW_HIGHLIGHT_DURATION)
424 game_speed_arrow_highlight_start = UNDEFINED;
434static void game_speed_down_on_pressed(
void)
436 g_game_vars.game_speed--;
437 game_speed_arrow_highlight_start = g_game_vars.timer;
438 game_speed_arrow_highlight_button = GAME_SPEED_DOWN_BTN_IDX;
439 disable_all_game_speed_outlines_except_self(GAME_SPEED_DOWN_BTN_IDX);
440 update_game_speed_button_graphics();
443static void game_speed_up_on_pressed(
void)
445 g_game_vars.game_speed++;
446 game_speed_arrow_highlight_start = g_game_vars.timer;
447 game_speed_arrow_highlight_button = GAME_SPEED_UP_BTN_IDX;
448 disable_all_game_speed_outlines_except_self(GAME_SPEED_UP_BTN_IDX);
449 update_game_speed_button_graphics();
455static void high_contrast_on_pressed(
void)
457 set_cards_high_contrast(!get_cards_high_contrast());
458 update_high_contrast_button_graphics();
464static void more_readable_on_pressed(
void)
466 set_cards_more_readable(!get_cards_more_readable());
467 update_more_readable_button_graphics();
473static void save_on_pressed(
void)
476 game_change_state(GAME_STATE_MAIN_MENU);
482static void back_on_pressed(
void)
485 game_change_state(GAME_STATE_MAIN_MENU);
493static int options_menu_return_upper_rows_size(
void)
503static int options_menu_return_card_sprites_row_size(
void)
513static int options_menu_return_bottom_row_size(
void)
518static void change_button_highlight(
520 const Selection* prev_selection,
521 const Selection* new_selection
524 if (prev_selection->y == row_idx)
529 if (new_selection->y == row_idx)
542static bool game_speed_row_on_selection_changed(
545 const Selection* prev_selection,
546 const Selection* new_selection
549 change_button_highlight(row_idx, prev_selection, new_selection);
550 disable_all_game_speed_outlines_except_self(NB_GAME_SPEED_BUTTONS);
553 if (prev_selection->y != new_selection->y)
556 if (key_hit(KEY_LEFT) && g_game_vars.game_speed > GAME_SPEED_MIN)
558 button_press(&game_speed_buttons[GAME_SPEED_DOWN_BTN_IDX]);
560 else if (key_hit(KEY_RIGHT) && g_game_vars.game_speed < GAME_SPEED_MAX)
562 button_press(&game_speed_buttons[GAME_SPEED_UP_BTN_IDX]);
573static void options_menu_row_on_key_transit(
SelectionGrid* selection_grid, Selection* selection)
575 if (key_hit(SELECT_CARD))
577 button_press(&options_menu_buttons[selection->y][selection->x]);
581static bool regular_button_row_on_selection_changed(
584 const Selection* prev_selection,
585 const Selection* new_selection
588 change_button_highlight(row_idx, prev_selection, new_selection);
592static bool music_volume_row_on_selection_changed(
595 const Selection* prev_selection,
596 const Selection* new_selection
599 change_button_highlight(row_idx, prev_selection, new_selection);
601 if (prev_selection->y != new_selection->y)
604 if (key_hit(KEY_LEFT) && g_game_vars.music_volume > VOLUME_OPTION_MIN)
606 g_game_vars.music_volume--;
608 else if (key_hit(KEY_RIGHT) && g_game_vars.music_volume < VOLUME_OPTION_MAX)
610 g_game_vars.music_volume++;
613 update_volume_slider_graphics(MUSIC_VOLUME_ROW_IDX);
619static bool sound_volume_row_on_selection_changed(
622 const Selection* prev_selection,
623 const Selection* new_selection
626 change_button_highlight(row_idx, prev_selection, new_selection);
628 if (prev_selection->y != new_selection->y)
631 if (key_hit(KEY_LEFT) && g_game_vars.sound_volume > VOLUME_OPTION_MIN)
633 g_game_vars.sound_volume--;
635 else if (key_hit(KEY_RIGHT) && g_game_vars.sound_volume < VOLUME_OPTION_MAX)
637 g_game_vars.sound_volume++;
640 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.