GBAlatro
A Demake of Balatro for the GBA
Loading...
Searching...
No Matches
run_setup.c
Go to the documentation of this file.
1
7#include "game/run_setup.h"
8
9#include "background_run_setup_gfx.h"
10#include "button.h"
11#include "card.h"
12#include "game.h"
13#include "game_variables.h"
14#include "graphic_utils.h"
15#include "save.h"
16#include "selection_grid.h"
17#include "sprite.h"
18#include "state_machine.h"
19#include "util.h"
20
21#include <string.h>
22#include <tonc.h>
23
24// Palette Indices
25
26#define CHANGE_DECK_BTN_MAIN_COLOR_PAL_IDX 1
27#define RED_BTN_MAIN_COLOR_PAL_IDX 10
28#define RED_DISABLED_BTN_MAIN_COLOR_PAL_IDX 11
29#define BLUE_BTN_MAIN_COLOR_PAL_IDX 12
30#define BLUE_DISABLED_BTN_MAIN_COLOR_PAL_IDX 13
31#define BACK_BTN_MAIN_COLOR_PAL_IDX 14
32
33#define NEW_RUN_BTN_OUTLINE_COLOR_PAL_IDX 30
34#define RESUME_BTN_OUTLINE_COLOR_PAL_IDX 31
35#define CHANGE_DECK_BTN_OUTLINE_COLOR_PAL_IDX 32
36#define SEED_CHECK_BTN_OUTLINE_COLOR_PAL_IDX 33
37#define SEED_DECK_BTN_OUTLINE_COLOR_PAL_IDX 34
38#define PLAY_BTN_OUTLINE_COLOR_PAL_IDX 35
39#define BACK_BTN_OUTLINE_COLOR_PAL_IDX 36
40
41#define KEYBOARD_1_BTN_OUTLINE_COLOR_PAL_IDX 40
42#define KEYBOARD_2_BTN_OUTLINE_COLOR_PAL_IDX 41
43#define KEYBOARD_3_BTN_OUTLINE_COLOR_PAL_IDX 42
44#define KEYBOARD_4_BTN_OUTLINE_COLOR_PAL_IDX 43
45#define KEYBOARD_5_BTN_OUTLINE_COLOR_PAL_IDX 44
46#define KEYBOARD_6_BTN_OUTLINE_COLOR_PAL_IDX 45
47#define KEYBOARD_7_BTN_OUTLINE_COLOR_PAL_IDX 46
48#define KEYBOARD_8_BTN_OUTLINE_COLOR_PAL_IDX 47
49#define KEYBOARD_9_BTN_OUTLINE_COLOR_PAL_IDX 48
50#define KEYBOARD_0_BTN_OUTLINE_COLOR_PAL_IDX 49
51
52#define KEYBOARD_A_BTN_OUTLINE_COLOR_PAL_IDX 50
53#define KEYBOARD_B_BTN_OUTLINE_COLOR_PAL_IDX 51
54#define KEYBOARD_C_BTN_OUTLINE_COLOR_PAL_IDX 52
55#define KEYBOARD_D_BTN_OUTLINE_COLOR_PAL_IDX 53
56#define KEYBOARD_E_BTN_OUTLINE_COLOR_PAL_IDX 54
57#define KEYBOARD_F_BTN_OUTLINE_COLOR_PAL_IDX 55
58#define KEYBOARD_G_BTN_OUTLINE_COLOR_PAL_IDX 56
59#define KEYBOARD_H_BTN_OUTLINE_COLOR_PAL_IDX 57
60#define KEYBOARD_I_BTN_OUTLINE_COLOR_PAL_IDX 58
61#define KEYBOARD_J_BTN_OUTLINE_COLOR_PAL_IDX 59
62
63#define KEYBOARD_K_BTN_OUTLINE_COLOR_PAL_IDX 60
64#define KEYBOARD_L_BTN_OUTLINE_COLOR_PAL_IDX 61
65#define KEYBOARD_M_BTN_OUTLINE_COLOR_PAL_IDX 62
66#define KEYBOARD_N_BTN_OUTLINE_COLOR_PAL_IDX 63
67#define KEYBOARD_O_BTN_OUTLINE_COLOR_PAL_IDX 64
68#define KEYBOARD_P_BTN_OUTLINE_COLOR_PAL_IDX 65
69#define KEYBOARD_Q_BTN_OUTLINE_COLOR_PAL_IDX 66
70#define KEYBOARD_R_BTN_OUTLINE_COLOR_PAL_IDX 67
71#define KEYBOARD_S_BTN_OUTLINE_COLOR_PAL_IDX 68
72#define KEYBOARD_T_BTN_OUTLINE_COLOR_PAL_IDX 69
73
74#define KEYBOARD_RAND_BTN_OUTLINE_COLOR_PAL_IDX 70
75#define KEYBOARD_U_BTN_OUTLINE_COLOR_PAL_IDX 71
76#define KEYBOARD_V_BTN_OUTLINE_COLOR_PAL_IDX 72
77#define KEYBOARD_W_BTN_OUTLINE_COLOR_PAL_IDX 73
78#define KEYBOARD_X_BTN_OUTLINE_COLOR_PAL_IDX 74
79#define KEYBOARD_Y_BTN_OUTLINE_COLOR_PAL_IDX 75
80#define KEYBOARD_Z_BTN_OUTLINE_COLOR_PAL_IDX 76
81#define KEYBOARD_DEL_BTN_OUTLINE_COLOR_PAL_IDX 77
82
83enum RunSetupSubstate
84{
85 RUN_SETUP_SUBSTATE_CHOOSE_DECK,
86 RUN_SETUP_SUBSTATE_CHOOSE_SEED,
87 RUN_SETUP_SUBSTATE_RESUME,
88 RUN_SETUP_SUBSTATE_MAX
89};
90
91static void choose_deck_substate_init(void);
92static void choose_deck_substate_update(void);
93
94static void seed_keyboard_substate_init(void);
95static void seed_keyboard_substate_update(void);
96
97static void resume_substate_init(void);
98
99// clang-format off
100static StateInfo state_info[] =
101{
102 [RUN_SETUP_SUBSTATE_CHOOSE_DECK] = STATE_INFO_INIT_UPDATE_FN(
105 ),
106 [RUN_SETUP_SUBSTATE_CHOOSE_SEED] = STATE_INFO_INIT_UPDATE_FN(
109 ),
110 [RUN_SETUP_SUBSTATE_RESUME] = STATE_INFO_INIT_UPDATE_FN(
112 noop
113 )
114};
115// clang-format on
116
117static StateMachine run_setup_sm = {
118 .state_infos = &state_info[0],
119 .num_infos = RUN_SETUP_SUBSTATE_MAX,
120};
121
122#pragma region LAYOUT
123/*******************************************************************************
124 * TILES LAYOUT
125 ******************************************************************************/
126
127// clang-format off
128// Uncomment when tab row is re-added
129//static const Rect RUN_SETUP_RESUME_TAB_DISABLED_SRC = {19, 22, 23, 23};
130//static const BG_POINT RUN_SETUP_RESUME_TAB_DISABLED_DEST_POS = {15, 1};
131
132static const BG_POINT RUN_SETUP_FRAME_BG_SE_FILL_SRC_POS = {9 , 31};
133
134static const Rect RUN_SETUP_CHOOSE_DECK_CHOICE_BG_9_PTCH_DEST = {6 , 4 , 23, 13};
135static const NinePatchRect RUN_SETUP_CHOOSE_DECK_CHOICE_BG_9_PTCH_SRC = {
136 { 0 , 21, 7 , 28},
137 { 5 , 3 , 2 , 4 }
138};
139
140static const Rect RUN_SETUP_CHOOSE_DECK_CLEAN_LEFT_DEST = {4 , 6 , 5 , 13};
141static const Rect RUN_SETUP_CHOOSE_DECK_CLEAN_RIGHT_DEST = {24, 6 ,25 , 13};
142
143static const Rect RUN_SETUP_CHOOSE_DECK_USE_SEED_BTN_OFF_SRC = {30, 8 , 31, 10};
144static const Rect RUN_SETUP_CHOOSE_DECK_USE_SEED_BTN_ON_SRC = {30, 11, 31, 13};
145static const BG_POINT RUN_SETUP_CHOOSE_DECK_USE_SEED_BTN_DEST_POS = {17, 14};
146
147static const BG_POINT RUN_SETUP_CHOOSE_DECK_SEED_BTN_3X3_SRC_POS = {0 , 29};
148static const BG_POINT RUN_SETUP_CHOOSE_DECK_SEED_BTN_DISABLED_3X3_SRC_POS = {3 , 29};
149static const Rect RUN_SETUP_CHOOSE_DECK_SEED_BTN_DEST = {19, 14, 24, 16};
150
151static const Rect RUN_SETUP_CHOOSE_SEED_FRAME_CLEAN_DEST = {4 , 3 , 25, 5 };
152static const Rect RUN_SETUP_CHOOSE_SEED_KEYBOARD_SRC = {10, 24, 31, 31};
153static const Rect RUN_SETUP_CHOOSE_SEED_FIELD_SRC = {24, 22, 31, 23};
154static const BG_POINT RUN_SETUP_CHOOSE_SEED_KEYBOARD_DEST_POS = {4 , 6};
155static const BG_POINT RUN_SETUP_CHOOSE_SEED_FIELD_DEST_POS = {11, 4};
156
157static const BG_POINT RUN_SETUP_CHOOSE_SEED_DECK_BTN_3X3_SRC_POS = RUN_SETUP_CHOOSE_DECK_SEED_BTN_3X3_SRC_POS;
158static const Rect RUN_SETUP_CHOOSE_SEED_DECK_BTN_DEST = {17, 14, 24, 16};
159
160// Pixel sizes
161#define RUN_SETUP_DECK_SPRITE_T_X 48
162#define RUN_SETUP_DECK_SPRITE_T_Y 54
163static const BG_POINT RUN_SETUP_DECK_NAME_TEXT_POS = {80 , 40 };
164static const BG_POINT RUN_SETUP_DECK_DESC_TEXT_POS = {80 , 56 };
165static const Rect RUN_SETUP_DECK_NAME_DESC_RECT = {80 , 40 ,176, 96 };
166static const BG_POINT RUN_SETUP_SEED_FIELD_TEXT_POS = {96 , 40 };
167static const BG_POINT RUN_SETUP_SEED_DECK_TEXT_POS = {152, 120};
168static const BG_POINT RUN_SETUP_PLAY_TEXT_POS = {76 , 120};
169static const BG_POINT RUN_SETUP_BACK_TEXT_POS = {104, 136};
170// clang-format on
171
172#pragma endregion
173
174#pragma region TAB BAR
175/*******************************************************************************
176 * TAB BAR BUTTONS
177 *
178 * Part of all substate but not state-dependent, they are always updated the
179 * same way, thus `run_setup_tabs_update()` will always be called.
180 ******************************************************************************/
181
182enum RunSetupTab
183{
184 RUN_SETUP_TAB_NEW_RUN,
185 RUN_SETUP_TAB_RESUME,
186 RUN_SETUP_TAB_MAX
187};
188
189static bool is_saved_game_valid = false;
190
191static void tab_set_highlight(enum RunSetupTab tab_sel);
192static void run_setup_tabs_update(void);
193
194// clang-format off
195static Button tabs_buttons[RUN_SETUP_TAB_MAX] = {
196 {NEW_RUN_BTN_OUTLINE_COLOR_PAL_IDX, RED_BTN_MAIN_COLOR_PAL_IDX, NULL, NULL},
197 {RESUME_BTN_OUTLINE_COLOR_PAL_IDX, RED_BTN_MAIN_COLOR_PAL_IDX, NULL, NULL},
198};
199// clang-format on
200
201#pragma endregion
202
203#pragma region BOTTOM BUTTONS
204/*******************************************************************************
205 * BOTTOM BUTTONS
206 *
207 * Declared before any SubState because they are common to all of them.
208 *
209 * The behaviour and appearance of the Seed/Deck button will change from state
210 * to state so these Buttons can't be defined here. functions related to their
211 * behaviour can, though.
212 *
213 * The Play and Back buttons will always be the same, but Play needs to be
214 * duplicated anyway to be integrated to each SubState's SelectionGrid, since
215 * the row it is on doesn't always have the same number of buttons.
216 ******************************************************************************/
217
218static int back_row_get_size(void);
219static void back_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection);
220
221static inline void toggle_seed_enabled(bool enable);
222static void use_seed_on_pressed(void);
223static void seed_on_pressed(void);
224static void deck_on_pressed(void);
225static void play_on_pressed(void);
226static void back_on_pressed(void);
227
228// clang-format off
229static Button back_button = {
230 BACK_BTN_OUTLINE_COLOR_PAL_IDX, BACK_BTN_MAIN_COLOR_PAL_IDX,
231 back_on_pressed, NULL
232};
233// clang-format on
234
235#pragma endregion
236
237#pragma region CHOOSE DECK
238/*******************************************************************************
239 * CHOOSE DECK SUBSTATE
240 ******************************************************************************/
241
242enum RunSetupDeckRows
243{
244 RUN_SETUP_DECK_ROW_CHANGE_DECK,
245 RUN_SETUP_DECK_ROW_SEED_PLAY,
246 RUN_SETUP_DECK_ROW_BACK,
247 RUN_SETUP_DECK_ROW_MAX
248};
249
250enum RunSetupDeckBottomButtons
251{
252 RUN_SETUP_DECK_BB_PLAY,
253 RUN_SETUP_DECK_BB_USE_SEED,
254 RUN_SETUP_DECK_BB_SEED,
255 RUN_SETUP_DECK_BB_MAX
256};
257
258// CHOOSE DECK SELECTION GRID
259
260static int change_deck_get_row_size(void);
262 SelectionGrid* selection_grid,
263 int row_idx,
264 const Selection* prev_selection,
265 const Selection* new_selection
266);
267static int seed_play_get_row_size(void);
268static void seed_play_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection);
269
270// clang-format off
271static SelectionGridRow choose_deck_rows[RUN_SETUP_DECK_ROW_MAX] = {
272 {
273 RUN_SETUP_DECK_ROW_CHANGE_DECK,
276 NULL,
277 {.wrap = true}
278 }, {
279 RUN_SETUP_DECK_ROW_SEED_PLAY,
283 {.wrap = false}
284 }, {
285 RUN_SETUP_DECK_ROW_BACK,
288 back_row_on_key_transit,
289 {.wrap = false}
290 }
291};
292// clang-format on
293
294static const Selection RUN_SETUP_CHOOSE_DECK_INIT_SEL = {0, 0};
295static const Selection RUN_SETUP_CHOOSE_DECK_SEL_FROM_SEED = {2, 1};
296
297static SelectionGrid choose_deck_selection_grid = {
298 choose_deck_rows,
299 RUN_SETUP_DECK_ROW_MAX,
300 RUN_SETUP_CHOOSE_DECK_INIT_SEL
301};
302
303// CHOOSE DECK BUTTONS
304
305static void change_deck_on_pressed(void);
306
307static Button change_deck_button = {
308 CHANGE_DECK_BTN_OUTLINE_COLOR_PAL_IDX,
309 CHANGE_DECK_BTN_MAIN_COLOR_PAL_IDX,
311 NULL
312};
313
314// clang-format off
315// Seed button is disabled by default but can be enabled by clicking the toggle just next to it
316static Button choose_deck_bottom_buttons[RUN_SETUP_DECK_BB_MAX] = {
317 {
318 PLAY_BTN_OUTLINE_COLOR_PAL_IDX, BLUE_BTN_MAIN_COLOR_PAL_IDX,
319 play_on_pressed, NULL
320 }, {
321 SEED_CHECK_BTN_OUTLINE_COLOR_PAL_IDX, RED_BTN_MAIN_COLOR_PAL_IDX,
323 }, {
324 SEED_DECK_BTN_OUTLINE_COLOR_PAL_IDX, BLUE_DISABLED_BTN_MAIN_COLOR_PAL_IDX,
325 seed_on_pressed, NULL
326 }
327};
328// clang-format on
329
330static bool use_seed = false;
331static CardObject* run_setup_deck = NULL;
332
333#pragma endregion
334
335#pragma region SEED KEYBOARD
336/*******************************************************************************
337 * SEED KEYBOARD SUBSTATE
338 ******************************************************************************/
339
340#define KEYBOARD_WIDTH 10
341#define KEYBOARD_HEIGHT 4
342
343enum RunSetupSeedRows
344{
345 RUN_SETUP_SEED_ROW_KEY0,
346 RUN_SETUP_SEED_ROW_KEY1,
347 RUN_SETUP_SEED_ROW_KEY2,
348 RUN_SETUP_SEED_ROW_KEY3,
349 RUN_SETUP_SEED_ROW_DECK_PLAY,
350 RUN_SETUP_SEED_ROW_BACK,
351 RUN_SETUP_SEED_ROW_MAX
352};
353
354enum RunSetupKeyboardButtons
355{
356 RUN_SETUP_KEYBOARD_BEGIN,
357 // Row 0
358 RUN_SETUP_KEYBOARD_1 = RUN_SETUP_KEYBOARD_BEGIN,
359 RUN_SETUP_KEYBOARD_2,
360 RUN_SETUP_KEYBOARD_3,
361 RUN_SETUP_KEYBOARD_4,
362 RUN_SETUP_KEYBOARD_5,
363 RUN_SETUP_KEYBOARD_6,
364 RUN_SETUP_KEYBOARD_7,
365 RUN_SETUP_KEYBOARD_8,
366 RUN_SETUP_KEYBOARD_9,
367 RUN_SETUP_KEYBOARD_0,
368 // Row 1
369 RUN_SETUP_KEYBOARD_A,
370 RUN_SETUP_KEYBOARD_B,
371 RUN_SETUP_KEYBOARD_C,
372 RUN_SETUP_KEYBOARD_D,
373 RUN_SETUP_KEYBOARD_E,
374 RUN_SETUP_KEYBOARD_F,
375 RUN_SETUP_KEYBOARD_G,
376 RUN_SETUP_KEYBOARD_H,
377 RUN_SETUP_KEYBOARD_I,
378 RUN_SETUP_KEYBOARD_J,
379 // Row 2
380 RUN_SETUP_KEYBOARD_K,
381 RUN_SETUP_KEYBOARD_L,
382 RUN_SETUP_KEYBOARD_M,
383 RUN_SETUP_KEYBOARD_N,
384 RUN_SETUP_KEYBOARD_O,
385 RUN_SETUP_KEYBOARD_P,
386 RUN_SETUP_KEYBOARD_Q,
387 RUN_SETUP_KEYBOARD_R,
388 RUN_SETUP_KEYBOARD_S,
389 RUN_SETUP_KEYBOARD_T,
390 // Row 3
391 RUN_SETUP_KEYBOARD_RAND,
392 RUN_SETUP_KEYBOARD_U,
393 RUN_SETUP_KEYBOARD_V,
394 RUN_SETUP_KEYBOARD_W,
395 RUN_SETUP_KEYBOARD_X,
396 RUN_SETUP_KEYBOARD_Y,
397 RUN_SETUP_KEYBOARD_Z,
398 RUN_SETUP_KEYBOARD_DEL,
399 RUN_SETUP_KEYBOARD_MAX
400};
401
402enum RunSetupSeedBottomButtons
403{
404 RUN_SETUP_SEED_BB_PLAY,
405 RUN_SETUP_SEED_BB_DECK,
406 RUN_SETUP_SEED_BB_MAX
407};
408
409// CHOOSE SEED SELECTION GRID
410
411static int choose_seed_get_keyboard_row_size(void);
413static int choose_seed_get_bottom_row_size(void);
414static void choose_seed_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection);
416 SelectionGrid* selection_grid,
417 int row_idx,
418 const Selection* prev_selection,
419 const Selection* new_selection
420);
421
422// clang-format off
423static SelectionGridRow choose_seed_selection_rows[] = {
424 // First 4 rows are the seed keyboard itself.
425 {
426 RUN_SETUP_SEED_ROW_KEY0,
430 {.wrap = true}
431 }, {
432 RUN_SETUP_SEED_ROW_KEY1,
436 {.wrap = true}
437 }, {
438 RUN_SETUP_SEED_ROW_KEY2,
442 {.wrap = true}
443 }, {
444 RUN_SETUP_SEED_ROW_KEY3,
448 {.wrap = true}
449 },
450 // Then we have the Deck/PLAY and Back rows
451 {
452 RUN_SETUP_SEED_ROW_DECK_PLAY,
456 {.wrap = false}
457 }, {
458 RUN_SETUP_SEED_ROW_BACK,
461 back_row_on_key_transit,
462 {.wrap = false}
463 }
464};
465// clang-format on
466
467static const Selection RUN_SETUP_CHOOSE_SEED_INIT_SEL = {1, 4};
468
469static SelectionGrid choose_seed_selection_grid = {
470 choose_seed_selection_rows,
471 RUN_SETUP_SEED_ROW_MAX,
472 RUN_SETUP_CHOOSE_SEED_INIT_SEL
473};
474
475// CHOOSE SEED BUTTONS
476
477static void keyboard_button_on_pressed(void);
478
479// clang-format off
480
481#define DEF_SEED_KEYBOARD_BUTTON_OBJECT(key) \
482 { \
483 KEYBOARD_##key##_BTN_OUTLINE_COLOR_PAL_IDX, RED_BTN_MAIN_COLOR_PAL_IDX, \
484 keyboard_button_on_pressed, NULL \
485 } \
486
487// Button at [3][0] is there for consistency but is not used since it corresponds to the "Random" key
488static Button keyboard_buttons[KEYBOARD_HEIGHT * KEYBOARD_WIDTH] = {
489 // Row 0
490 DEF_SEED_KEYBOARD_BUTTON_OBJECT(1),
491 DEF_SEED_KEYBOARD_BUTTON_OBJECT(2),
492 DEF_SEED_KEYBOARD_BUTTON_OBJECT(3),
493 DEF_SEED_KEYBOARD_BUTTON_OBJECT(4),
494 DEF_SEED_KEYBOARD_BUTTON_OBJECT(5),
495 DEF_SEED_KEYBOARD_BUTTON_OBJECT(6),
496 DEF_SEED_KEYBOARD_BUTTON_OBJECT(7),
497 DEF_SEED_KEYBOARD_BUTTON_OBJECT(8),
498 DEF_SEED_KEYBOARD_BUTTON_OBJECT(9),
499 DEF_SEED_KEYBOARD_BUTTON_OBJECT(0),
500 // Row 1
501 DEF_SEED_KEYBOARD_BUTTON_OBJECT(A),
502 DEF_SEED_KEYBOARD_BUTTON_OBJECT(B),
503 DEF_SEED_KEYBOARD_BUTTON_OBJECT(C),
504 DEF_SEED_KEYBOARD_BUTTON_OBJECT(D),
505 DEF_SEED_KEYBOARD_BUTTON_OBJECT(E),
506 DEF_SEED_KEYBOARD_BUTTON_OBJECT(F),
507 DEF_SEED_KEYBOARD_BUTTON_OBJECT(G),
508 DEF_SEED_KEYBOARD_BUTTON_OBJECT(H),
509 DEF_SEED_KEYBOARD_BUTTON_OBJECT(I),
510 DEF_SEED_KEYBOARD_BUTTON_OBJECT(J),
511 // Row 2
512 DEF_SEED_KEYBOARD_BUTTON_OBJECT(K),
513 DEF_SEED_KEYBOARD_BUTTON_OBJECT(L),
514 DEF_SEED_KEYBOARD_BUTTON_OBJECT(M),
515 DEF_SEED_KEYBOARD_BUTTON_OBJECT(N),
516 DEF_SEED_KEYBOARD_BUTTON_OBJECT(O),
517 DEF_SEED_KEYBOARD_BUTTON_OBJECT(P),
518 DEF_SEED_KEYBOARD_BUTTON_OBJECT(Q),
519 DEF_SEED_KEYBOARD_BUTTON_OBJECT(R),
520 DEF_SEED_KEYBOARD_BUTTON_OBJECT(S),
521 DEF_SEED_KEYBOARD_BUTTON_OBJECT(T),
522 // Row 3
523 DEF_SEED_KEYBOARD_BUTTON_OBJECT(RAND),
524 DEF_SEED_KEYBOARD_BUTTON_OBJECT(U),
525 DEF_SEED_KEYBOARD_BUTTON_OBJECT(V),
526 DEF_SEED_KEYBOARD_BUTTON_OBJECT(W),
527 DEF_SEED_KEYBOARD_BUTTON_OBJECT(X),
528 DEF_SEED_KEYBOARD_BUTTON_OBJECT(Y),
529 DEF_SEED_KEYBOARD_BUTTON_OBJECT(Z),
530 DEF_SEED_KEYBOARD_BUTTON_OBJECT(DEL)
531};
532
533static Button choose_seed_bottom_buttons[2] = {
534 {
535 PLAY_BTN_OUTLINE_COLOR_PAL_IDX, BLUE_BTN_MAIN_COLOR_PAL_IDX,
536 play_on_pressed, NULL
537 }, {
538 SEED_DECK_BTN_OUTLINE_COLOR_PAL_IDX, BLUE_BTN_MAIN_COLOR_PAL_IDX,
539 deck_on_pressed, NULL
540 }
541};
542
543static const char KEYBOARD_BUTTONS_TO_CHAR[KEYBOARD_HEIGHT * KEYBOARD_WIDTH] = {
544 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
545 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
546 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
547 ' ', 'U', 'V', 'W', 'X', 'Y', 'Z'
548};
549// clang-format on
550
551// Size BASE36_MAX_DIGITS + 1 to always have '\0' at the end
552static char s_seed_str[BASE36_MAX_DIGITS + 1] = {'\0'};
553static u8 s_seed_cursor_pos = 0;
554
555#pragma endregion
556
557#pragma region RESUME
558/*******************************************************************************
559 * RESUME SUBSTATE
560 ******************************************************************************/
561
562enum RunSetupResumeRows
563{
564 RUN_SETUP_RESUME_ROW_PLAY,
565 RUN_SETUP_RESUME_ROW_BACK,
566 RUN_SETUP_RESUME_ROW_MAX
567};
568
569// RESUME SELECTION GRID
570
571// RESUME BUTTONS
572
573#pragma endregion
574
575#pragma region STATE FUNCTIONS
576/*******************************************************************************
577 * STATE FUNCTIONS
578 ******************************************************************************/
579
581{
582 tte_erase_screen();
583 GRIT_CPY(pal_bg_mem, background_run_setup_gfxPal);
584 GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_run_setup_gfxTiles);
585 GRIT_CPY(&se_mem[MAIN_BG_SBB], background_run_setup_gfxMap);
586}
587
589{
590 state_machine_register(&run_setup_sm);
592
593 // Apply the current use_seed value if seed is UNDEFINED
594 if (g_game_vars.rng_info.seed == UNDEFINED)
595 {
596 // Make the string empty instead of showing all zeroes
597 memset(s_seed_str, '\0', BASE36_MAX_DIGITS + 1);
598 s_seed_cursor_pos = 0;
599 }
600 // Or use previous Run's seed if it hasn't been reset
601 else
602 {
603 u32_to_base36(g_game_vars.rng_info.seed, s_seed_str);
604 s_seed_cursor_pos = BASE36_MAX_DIGITS;
605 use_seed = true;
606 }
607 toggle_seed_enabled(use_seed);
608
609 // Rank doesn't matter, won't see it
610 run_setup_deck = card_object_new(card_new(SPADES, ACE));
611
612 // We put it at the same layer as the main menu Ace card, but it's okay because
613 // both cards do not exist at the same time, one is destroyed before the other is created.
614 card_object_set_sprite_face_down(run_setup_deck, g_game_vars.deck, 0);
615
617 (SpriteObject*)run_setup_deck,
618 RUN_SETUP_DECK_SPRITE_T_X,
619 RUN_SETUP_DECK_SPRITE_T_Y
620 );
621
622 /* Uncomment these lines when we figure out how to properly restore a game save
623 is_saved_game_valid = is_game_data_valid();
624 if (is_saved_game_valid)
625 {
626 state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_RESUME);
627 }
628 */
629
630 // Land on the deck swapping button when landing on this state from the Main Menu
631 choose_deck_selection_grid.selection = RUN_SETUP_CHOOSE_DECK_INIT_SEL;
632 state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_CHOOSE_DECK);
633}
634
636{
638}
639
641{
642 state_machine_remove(&run_setup_sm);
643
644 card_destroy(&run_setup_deck->card);
645 card_object_destroy(&run_setup_deck);
646
647 tte_erase_screen();
648}
649
650#pragma endregion
651
652#pragma region IMPLEMENTATION
653/*******************************************************************************
654 * STATIC FUNCTIONS IMPLEMENTATION
655 ******************************************************************************/
656
657// CHOOSE DECK
658
663{
664 // Show Deck sprite, name and TODO: description
665 sprite_object_unhide((SpriteObject*)run_setup_deck);
666 print_deck_name(g_game_vars.deck, RUN_SETUP_DECK_NAME_TEXT_POS);
667 print_deck_description(g_game_vars.deck, RUN_SETUP_DECK_DESC_TEXT_POS);
668
669 // Clean frame and expand 9-patch for the Deck choice background
671 RUN_SETUP_CHOOSE_DECK_CLEAN_LEFT_DEST,
672 RUN_SETUP_FRAME_BG_SE_FILL_SRC_POS
673 );
675 RUN_SETUP_CHOOSE_DECK_CLEAN_RIGHT_DEST,
676 RUN_SETUP_FRAME_BG_SE_FILL_SRC_POS
677 );
679 RUN_SETUP_CHOOSE_DECK_CHOICE_BG_9_PTCH_DEST,
680 &RUN_SETUP_CHOOSE_DECK_CHOICE_BG_9_PTCH_SRC
681 );
682
683 // TODO: add left/right navigation arrows once more decks have been implemented
684
685 // Set Tab to "New Run"
686 // Uncomment when tab row is re-added (clang-format made it ugly, sorry)
687 // main_bg_se_copy_rect(RUN_SETUP_RESUME_TAB_DISABLED_SRC,
688 // RUN_SETUP_RESUME_TAB_DISABLED_DEST_POS); tab_set_highlight(RUN_SETUP_TAB_NEW_RUN);
689
690 // Set button highlights
691 button_set_highlight(&change_deck_button, true);
692 button_set_highlight(&choose_deck_bottom_buttons[RUN_SETUP_DECK_BB_USE_SEED], false);
693 button_set_highlight(&choose_deck_bottom_buttons[RUN_SETUP_DECK_BB_PLAY], false);
694 button_set_highlight(&back_button, false);
695 toggle_seed_enabled(use_seed);
696
697 // Print button text
698 tte_printf(
699 "#{P:%d,%d; cx:0x%X000}%s",
700 RUN_SETUP_PLAY_TEXT_POS.x,
701 RUN_SETUP_PLAY_TEXT_POS.y,
702 TTE_WHITE_PB,
703 "PLAY"
704 );
705 tte_printf(
706 "#{P:%d,%d; cx:0x%X000}%s",
707 RUN_SETUP_BACK_TEXT_POS.x,
708 RUN_SETUP_BACK_TEXT_POS.y,
709 TTE_WHITE_PB,
710 "Back"
711 );
712}
713
719{
720 selection_grid_process_input(&choose_deck_selection_grid);
721}
722
729{
730 return 1;
731}
732
739static inline Button* change_deck_get_button_from_sel(const Selection* sel)
740{
741 switch (sel->y)
742 {
743 case RUN_SETUP_DECK_ROW_CHANGE_DECK:
744 return &change_deck_button;
745
746 case RUN_SETUP_DECK_ROW_SEED_PLAY:
747 if (sel->x >= RUN_SETUP_DECK_BB_MAX)
748 return NULL;
749 return &choose_deck_bottom_buttons[sel->x];
750
751 case RUN_SETUP_DECK_ROW_BACK:
752 return &back_button;
753 }
754 return NULL;
755}
756
767 SelectionGrid* selection_grid,
768 int row_idx,
769 const Selection* prev_selection,
770 const Selection* new_selection
771)
772{
775
776 // TODO: detect left/right press on Change Deck row to allow swapping
777 // Decks need to be implemented for this
778
779 return true;
780}
781
788{
789 return 3;
790}
791
798static void seed_play_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
799{
800 if (key_hit(SELECT_CARD))
801 button_press(&choose_deck_bottom_buttons[selection->x]);
802}
803
804// CHOOSE SEED
805
809static inline void update_seed_text(void)
810{
811 tte_printf(
812 "#{P:%d,%d; cx:0x%X000}%-*s",
813 RUN_SETUP_SEED_FIELD_TEXT_POS.x,
814 RUN_SETUP_SEED_FIELD_TEXT_POS.y,
815 TTE_BLACK_PB,
816 BASE36_MAX_DIGITS + 1,
817 s_seed_str
818 );
819}
820
825{
826 choose_seed_selection_grid.selection = RUN_SETUP_CHOOSE_SEED_INIT_SEL;
827 tte_erase_rect_wrapper(RUN_SETUP_DECK_NAME_DESC_RECT);
828
829 // Hide Deck card sprite
830 sprite_object_hide((SpriteObject*)run_setup_deck);
831
832 // Clean deck swap screen with frame BG color
834 RUN_SETUP_CHOOSE_SEED_FRAME_CLEAN_DEST,
835 RUN_SETUP_FRAME_BG_SE_FILL_SRC_POS
836 );
837
838 // Copy keyboard tiles
840 RUN_SETUP_CHOOSE_SEED_KEYBOARD_SRC,
841 RUN_SETUP_CHOOSE_SEED_KEYBOARD_DEST_POS
842 );
843 main_bg_se_copy_rect(RUN_SETUP_CHOOSE_SEED_FIELD_SRC, RUN_SETUP_CHOOSE_SEED_FIELD_DEST_POS);
844
845 // Replace seed toggle and button by "Deck" button that allows going back to deck substate
847 RUN_SETUP_CHOOSE_SEED_DECK_BTN_DEST,
848 RUN_SETUP_CHOOSE_SEED_DECK_BTN_3X3_SRC_POS
849 );
850 tte_printf(
851 "#{P:%d,%d; cx:0x%X000}%s",
852 RUN_SETUP_SEED_DECK_TEXT_POS.x,
853 RUN_SETUP_SEED_DECK_TEXT_POS.y,
854 TTE_WHITE_PB,
855 "Deck " // extra space after to clean potential "Seed" text
856 );
857
858 // Set buttons highlight
859 for (enum RunSetupKeyboardButtons key = RUN_SETUP_KEYBOARD_BEGIN; key < RUN_SETUP_KEYBOARD_MAX;
860 key++)
861 {
862 button_set_highlight(&keyboard_buttons[key], false);
863 }
864 button_set_highlight(&choose_seed_bottom_buttons[RUN_SETUP_SEED_BB_PLAY], false);
865 button_set_highlight(&choose_seed_bottom_buttons[RUN_SETUP_SEED_BB_DECK], true);
866 button_set_highlight(&back_button, false);
867
868 // Print seed text
870}
871
877{
878 selection_grid_process_input(&choose_seed_selection_grid);
879}
880
887{
888 return KEYBOARD_WIDTH;
889}
890
897{
898 return KEYBOARD_WIDTH - 2;
899}
900
907{
908 return 2;
909}
910
914static inline void reroll_seed_str(void)
915{
916 // Need to roll a new seed and get a "real" random number. Otherwise the seed is still stuck at
917 // 0 and we'll have the same sequence of generated seeds each time.
918 // Also, don't use the shuffled seed as is, or we'll just end up with sequential seeds when
919 // rolling multiple times.
921 u32_to_base36(g_game_vars.rng_info.seed, s_seed_str);
923 s_seed_cursor_pos = BASE36_MAX_DIGITS;
924}
925
929static inline void delete_seed_char(void)
930{
931 if (s_seed_cursor_pos == 0)
932 return;
933
934 s_seed_str[--s_seed_cursor_pos] = '\0';
936}
937
943static inline void type_seed_char(enum RunSetupKeyboardButtons key)
944{
945 if (s_seed_cursor_pos >= BASE36_MAX_DIGITS)
946 return;
947
948 s_seed_str[s_seed_cursor_pos++] = KEYBOARD_BUTTONS_TO_CHAR[key];
950}
951
959static inline enum RunSetupKeyboardButtons get_keyboard_index_from_sel(const Selection* sel)
960{
961 return sel->x + KEYBOARD_WIDTH * sel->y;
962}
963
968{
969 // Type something only if the button pressed in on the keyboard
970 if (choose_seed_selection_grid.selection.y > RUN_SETUP_SEED_ROW_KEY3)
971 return;
972
973 // Type only if the seed string is not full.
974 // The cursor position is unsigned so always positive, but we still need to
975 // ensure it doersn't go out of bounds by more than 1 so that we can always
976 // substract 1 from it when erasing a character from the seed string.
977 if (s_seed_cursor_pos > BASE36_MAX_DIGITS)
978 s_seed_cursor_pos = BASE36_MAX_DIGITS;
979
980 if (key_hit(DESELECT_CARDS))
982
983 else if (key_hit(SELECT_CARD))
984 {
985 // Get keyboard button index from selection
986 enum RunSetupKeyboardButtons key =
987 get_keyboard_index_from_sel(&choose_seed_selection_grid.selection);
988
989 switch (key)
990 {
991 case RUN_SETUP_KEYBOARD_RAND:
993 break;
994
995 // Erase last character
996 case RUN_SETUP_KEYBOARD_DEL:
998 break;
999
1000 default:
1001 type_seed_char(key);
1002 break;
1003 }
1004 }
1005}
1006
1013static inline Button* choose_seed_get_button_from_sel(const Selection* sel)
1014{
1015 switch (sel->y)
1016 {
1017 case RUN_SETUP_SEED_ROW_KEY0:
1018 case RUN_SETUP_SEED_ROW_KEY1:
1019 case RUN_SETUP_SEED_ROW_KEY2:
1020 case RUN_SETUP_SEED_ROW_KEY3:
1021 return &keyboard_buttons[get_keyboard_index_from_sel(sel)];
1022
1023 case RUN_SETUP_SEED_ROW_DECK_PLAY:
1024 return &choose_seed_bottom_buttons[sel->x];
1025
1026 case RUN_SETUP_SEED_ROW_BACK:
1027 return &back_button;
1028 }
1029 return NULL;
1030}
1031
1040static void choose_seed_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
1041{
1042 if (key_hit(SELECT_CARD) ||
1043 (selection->y <= RUN_SETUP_SEED_ROW_KEY3 && key_hit(DESELECT_CARDS)))
1044 {
1046 }
1047}
1048
1059 SelectionGrid* selection_grid,
1060 int row_idx,
1061 const Selection* prev_selection,
1062 const Selection* new_selection
1063)
1064{
1065 // TODO: since some rows don't have the same number of buttons but their widths line up,
1066 // need to find a way to shift selection.x to left or right to keep navigation consistent
1067 bool proceed_selection = true;
1068
1069 if (row_idx == prev_selection->y)
1071
1072 if (row_idx == new_selection->y)
1073 {
1074 Selection shifted_selection = *new_selection;
1075
1076 // From row 3 to 4
1077 if (prev_selection->y == RUN_SETUP_SEED_ROW_KEY2 &&
1078 new_selection->y == RUN_SETUP_SEED_ROW_KEY3 && prev_selection->x >= 5 &&
1079 prev_selection->x <= 8)
1080 {
1081 shifted_selection.x++;
1082 selection_grid->selection = shifted_selection;
1083 proceed_selection = false;
1084 }
1085
1086 // From row 4 to 3
1087 else if (prev_selection->y == RUN_SETUP_SEED_ROW_KEY3 &&
1088 new_selection->y == RUN_SETUP_SEED_ROW_KEY2 && prev_selection->x >= 1 &&
1089 prev_selection->x <= 3)
1090 {
1091 shifted_selection.x++;
1092 selection_grid->selection = shifted_selection;
1093 proceed_selection = false;
1094 }
1095
1096 button_set_highlight(choose_seed_get_button_from_sel(&shifted_selection), true);
1097 }
1098
1099 return proceed_selection;
1100}
1101
1105static void deck_on_pressed(void)
1106{
1107 state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_CHOOSE_DECK);
1108 choose_deck_selection_grid.selection = RUN_SETUP_CHOOSE_DECK_SEL_FROM_SEED;
1109 button_set_highlight(&change_deck_button, false);
1110 button_set_highlight(&choose_deck_bottom_buttons[RUN_SETUP_DECK_BB_SEED], true);
1111}
1112
1113// RESUME GAME
1114
1118static void resume_substate_init(void)
1119{
1120 tab_set_highlight(RUN_SETUP_TAB_RESUME);
1121
1122 // Show Deck card sprite
1123 sprite_object_unhide((SpriteObject*)run_setup_deck);
1124}
1125
1126// COMMON BUTTONS
1127
1135static inline void toggle_seed_enabled(bool enable)
1136{
1137 use_seed = enable;
1138
1139 // Apply right main color to the Button
1140 choose_deck_bottom_buttons[RUN_SETUP_DECK_BB_SEED].button_pal_idx =
1141 use_seed ? BLUE_BTN_MAIN_COLOR_PAL_IDX : BLUE_DISABLED_BTN_MAIN_COLOR_PAL_IDX;
1142 button_set_highlight(&choose_deck_bottom_buttons[RUN_SETUP_DECK_BB_SEED], false);
1143
1144 // Replace Seed button tiles with the disabled one's
1145 BG_POINT button_tiles = use_seed ? RUN_SETUP_CHOOSE_DECK_SEED_BTN_3X3_SRC_POS
1146 : RUN_SETUP_CHOOSE_DECK_SEED_BTN_DISABLED_3X3_SRC_POS;
1147 main_bg_se_copy_expand_3x3_rect(RUN_SETUP_CHOOSE_DECK_SEED_BTN_DEST, button_tiles);
1148
1149 // Print Seed button text with the right color
1150 tte_printf(
1151 "#{P:%d,%d; cx:0x%X000}%s",
1152 RUN_SETUP_SEED_DECK_TEXT_POS.x,
1153 RUN_SETUP_SEED_DECK_TEXT_POS.y,
1154 use_seed ? TTE_WHITE_PB : TTE_BLACK_PB,
1155 " Seed" // Extra space before to clean potential "Deck" text
1156 );
1157
1158 // Replace toggle button tiles with either checkmark of empty circle
1159 Rect toggle_tiles = use_seed ? RUN_SETUP_CHOOSE_DECK_USE_SEED_BTN_ON_SRC
1160 : RUN_SETUP_CHOOSE_DECK_USE_SEED_BTN_OFF_SRC;
1161 main_bg_se_copy_rect(toggle_tiles, RUN_SETUP_CHOOSE_DECK_USE_SEED_BTN_DEST_POS);
1162}
1163
1167static void use_seed_on_pressed(void)
1168{
1169 toggle_seed_enabled(!use_seed);
1170}
1171
1175static void seed_on_pressed(void)
1176{
1177 if (use_seed)
1178 state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_CHOOSE_SEED);
1179}
1180
1184static void play_on_pressed(void)
1185{
1186 // Apply provided Seed if enabled, and if we entered one. This prevents us from always using
1187 // seed "ZZZZZZ" if we enter the Seed menu and hit Play without typing anything.
1188 if (use_seed && strlen(s_seed_str) > 0)
1189 rng_set_seed(base36_to_u32(s_seed_str));
1190 else
1192
1193 use_seed = false;
1194
1195 game_change_state(GAME_STATE_GAME_START);
1196}
1197
1201static void back_on_pressed(void)
1202{
1203 game_change_state(GAME_STATE_MAIN_MENU);
1204}
1205
1209static void change_deck_on_pressed(void)
1210{
1211}
1212
1219static void tab_set_highlight(enum RunSetupTab tab_sel)
1220{
1221 for (enum RunSetupTab tab = 0; tab < RUN_SETUP_TAB_MAX; tab++)
1222 {
1223 button_set_highlight(&tabs_buttons[tab], tab == tab_sel);
1224 }
1225}
1226
1230static void run_setup_tabs_update(void)
1231{
1232 static enum RunSetupTab current_tab = RUN_SETUP_TAB_RESUME;
1233
1234 // Either not pressed anything or there is no saved data, "Resume" tab is left grayed out and
1235 // only one tab is available. Return early to not spend time on tab-changing logic
1236 if (!key_hit(KEY_ANY) || !is_saved_game_valid)
1237 return;
1238
1239 // Not all the way to the right and pressed R
1240 if (key_hit(TAB_RIGHT) && current_tab < RUN_SETUP_TAB_MAX - 1)
1241 {
1242 button_set_highlight(&tabs_buttons[current_tab], false);
1243 current_tab++;
1244 }
1245 // Not all the way to the left and pressed L
1246 else if (key_hit(TAB_LEFT) && current_tab > 0)
1247 {
1248 button_set_highlight(&tabs_buttons[current_tab], false);
1249 current_tab--;
1250 }
1251
1252 button_set_highlight(&tabs_buttons[current_tab], true);
1253
1254 switch (current_tab)
1255 {
1256 case RUN_SETUP_TAB_NEW_RUN:
1257 state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_CHOOSE_DECK);
1258 break;
1259
1260 case RUN_SETUP_TAB_RESUME:
1261 state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_RESUME);
1262 break;
1263
1264 default:
1265 break;
1266 }
1267}
1268
1275{
1276 return 1;
1277}
1278
1279static void back_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
1280{
1281 if (key_hit(SELECT_CARD))
1282 button_press(&back_button);
1283}
1284
1285#pragma endregion
A button structure containing the common button functionalities Including highlight and pressing func...
void button_press(Button *button)
Execute a button press, by calling the button's on_pressed function. This checks the button's can_be_...
Definition button.c:18
void button_set_highlight(Button *button, bool highlight)
Set the button highlight on or off.
Definition button.c:8
void print_deck_name(enum DeckType deck, BG_POINT pos)
Prints the Deck name string to the screen at the given position.
Definition deck_types.c:43
void print_deck_description(enum DeckType deck, BG_POINT pos)
Prints the Deck description string to the screen at the given position.
Definition deck_types.c:48
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).
void main_bg_se_copy_expand_3x3_rect(Rect se_rect_dest, BG_POINT se_rect_src_3x3_top_left)
Copies a 3x3 rect and expands it to fit a passed rect. Special case of the 9-patch.
void tte_erase_rect_wrapper(Rect rect)
A wrapper for tte_erase_rect that would use the rect struct.
void main_bg_se_copy_expand_9_patch(Rect se_dest_rect, const NinePatchRect *src_9_ptch)
Copies a 9-patch and expands it to fit a passed rect.
void main_bg_se_copy_expand_tile(Rect se_rect_dest, BG_POINT se_tile_src)
Copies a tile in the main background at se_tile_src to fill se_rect_dest.
void rng_shuffle_seed(void)
Sets a new randomized seed for the RNG using a source of entropy.
Definition random.c:27
void rng_set_seed(u32 seed)
Set the rng seed to the chosen value, and reset the step counter to 0. The seed will be capped at MAX...
Definition random.c:33
static Button * change_deck_get_button_from_sel(const Selection *sel)
Gets the Button corresponding to the current Selection in choose_deck_selection_grid
Definition run_setup.c:739
static int back_row_get_size(void)
Retuns the width of the Back button's row.
Definition run_setup.c:1274
static void keyboard_button_on_pressed(void)
Keyboard key Button callback.
Definition run_setup.c:967
static void delete_seed_char(void)
Deletes the last char in the seed string base-36 representation.
Definition run_setup.c:929
void run_setup_on_exit(void)
Run Setup menu cleanup.
Definition run_setup.c:640
static void seed_on_pressed(void)
Seed Button Callback. Opens the seed input keyboard.
Definition run_setup.c:1175
static void seed_keyboard_substate_update(void)
Update the Choose Seed substate by handling user inputs though the corresponding choose_seed_selectio...
Definition run_setup.c:876
static void update_seed_text(void)
Prints the string representing the chosen seed in base-36.
Definition run_setup.c:809
void run_setup_change_background(void)
Change to the Run Setup menu background.
Definition run_setup.c:580
static void back_on_pressed(void)
Back Button Callback. Goes back to the Main Menu.
Definition run_setup.c:1201
static enum RunSetupKeyboardButtons get_keyboard_index_from_sel(const Selection *sel)
Get the keyboard key index from a SelectionGrid's Selection. The returned value is valid only if the ...
Definition run_setup.c:959
static void toggle_seed_enabled(bool enable)
Toggle whether or not we will use the seed chosen by the user. Changes the looks of the Seed button t...
Definition run_setup.c:1135
static void play_on_pressed(void)
Play Button Callback. Applies the chosen seed if enabled and starts a new run.
Definition run_setup.c:1184
static Button * choose_seed_get_button_from_sel(const Selection *sel)
Get the Button corresponding to a Selection within choose_seed_selection_grid
Definition run_setup.c:1013
void run_setup_on_update(void)
Run Setup menu state update.
Definition run_setup.c:635
static void tab_set_highlight(enum RunSetupTab tab_sel)
Highlights the tab_sel Tab at the top of the screen, and removes highlight from all the others.
Definition run_setup.c:1219
static void change_deck_on_pressed(void)
Button Callback used for cycling through the Decks.
Definition run_setup.c:1209
void run_setup_on_init(void)
Run Setup menu state initialization.
Definition run_setup.c:588
static int choose_seed_get_bottom_row_size(void)
Returns the width of the Deck/Play buttons' row.
Definition run_setup.c:906
static int choose_seed_get_keyboard_short_row_size(void)
Returns the width of the bottom keyboard row, the shortest one.
Definition run_setup.c:896
static void choose_deck_substate_update(void)
Update the deck changing substate by handling user input though its corresponding SelectionGrid.
Definition run_setup.c:718
static bool choose_seed_row_on_selection_changed(SelectionGrid *selection_grid, int row_idx, const Selection *prev_selection, const Selection *new_selection)
Handle directional imputs in choose_seed_selection_grid
Definition run_setup.c:1058
static void choose_seed_row_on_key_transit(SelectionGrid *selection_grid, Selection *selection)
Handle button imputs in choose_seed_selection_grid
Definition run_setup.c:1040
static void seed_keyboard_substate_init(void)
Initialize the Choose Seed substate.
Definition run_setup.c:824
static void seed_play_row_on_key_transit(SelectionGrid *selection_grid, Selection *selection)
Handle button inputs for choose_deck_selection_grid
Definition run_setup.c:798
static int seed_play_get_row_size(void)
Returns the width of the Seed checkbox/Seed/Play buttons' row.
Definition run_setup.c:787
static void reroll_seed_str(void)
Deletes the last char in the seed string base-36 representation.
Definition run_setup.c:914
static void run_setup_tabs_update(void)
Handle user input in regards to the Tabs. Tabs are cycled through using the L/R buttons.
Definition run_setup.c:1230
static void resume_substate_init(void)
Initialize the "Resume Previous Run" substate.
Definition run_setup.c:1118
static int change_deck_get_row_size(void)
Returns the width of the Change Deck Button's row.
Definition run_setup.c:728
static void deck_on_pressed(void)
Deck Button Callback.
Definition run_setup.c:1105
static void use_seed_on_pressed(void)
Seed checkbox Button Callback. Toggles custom seed usage.
Definition run_setup.c:1167
static void choose_deck_substate_init(void)
Initializes the Deck changing substate.
Definition run_setup.c:662
static void type_seed_char(enum RunSetupKeyboardButtons key)
Add a new char at the end of the seed string.
Definition run_setup.c:943
static int choose_seed_get_keyboard_row_size(void)
Returns the width of the 3 top keyboard rows.
Definition run_setup.c:886
static bool choose_deck_row_on_selection_changed(SelectionGrid *selection_grid, int row_idx, const Selection *prev_selection, const Selection *new_selection)
Handle directional input in choose_deck_selection_grid
Definition run_setup.c:766
Setup Run menu state functions.
Utils functions to save/load data structures from/to the 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.
Sprite system for Gbalatro.
void sprite_object_unhide(SpriteObject *sprite_object)
Unhides the SpriteObject by manipulating ATTR0_HIDE in OAM. The sprite's ATTR0_MODE is maintained fro...
Definition sprite.c:271
INLINE void sprite_object_position(SpriteObject *sprite_object, int x, int y)
Set sprite_object position. Inlined for efficiency.
Definition sprite.h:483
void sprite_object_hide(SpriteObject *sprite_object)
Hides the SpriteObject by manipulating ATTR0_HIDE in OAM.
Definition sprite.c:264
State Machine.
void state_machine_remove(StateMachine *state_machine)
Remove a statemachine's update function.
void state_machine_register(StateMachine *state_machine)
Register a statemachine to run it's update function once per frame.
void noop(void)
no operation
void state_machine_change_state(StateMachine *state_machine, int new_state)
Calls the current state's on_exit, the new state's on_init, and sets the active update fn.
A button representation.
Definition button.h:31
u8 button_pal_idx
Palette index of the color of the button itself, used for the border when not highlighted.
Definition button.h:43
Structure to represent arbitrary-sized 9-patches.
u32 seed
Definition random.h:44
The core selection grid struct, represents the grid itself and its state.
A sprite object is a sprite that is focusable and movable in animation.
Definition sprite.h:86
State machine callbacks.
State machine instance.
StateInfo * state_infos
Array of StateCallbacks , one entry per state.
Utilities relating around number string representation and protected arithmatic helper functions.
uint32_t base36_to_u32(const char b36_str[])
Convert a base-36 string representation to a 32-bit unsigned integer. Since we are dealing with base-...
Definition util.c:260
void u32_to_base36(uint32_t n, char b36_str[])
Convert a 32-bit unsigned integer to its base-36 string representation. This will perform 6 divisions...
Definition util.c:272