5#include "background_blind_select_gfx.h"
20static const u32 BLIND_SELECT_BTN_PID = 15;
21static const u32 BLIND_SKIP_BTN_PID = 5;
22static const u32 BLIND_SKIP_BTN_SELECTED_BORDER_PID = 10;
23static const u32 BLIND_SELECT_BTN_SELECTED_BORDER_PID = 18;
25static const u32 TM_DISP_BLIND_PANEL_FINISH = 7;
26static const u32 TM_DISP_BLIND_PANEL_START = 1;
30static void game_blind_select_start_anim_seq(
void);
31static void game_blind_select_handle_input(
void);
32static void game_blind_select_selected_anim_seq(
void);
33static void game_blind_select_display_blind_panel(
void);
34static void game_blind_select_exit(
void);
35static Rect game_blind_select_get_req_score_rect(
enum BlindTokens blind);
36static void game_blind_select_print_blinds_reqs_and_rewards(
void);
38static void blind_tokens_init(
void);
44 BLIND_SELECTED_ANIM_SEQ,
52 STATE_INFO_UPDATE_FN_ONLY(game_blind_select_start_anim_seq),
53 STATE_INFO_UPDATE_FN_ONLY(game_blind_select_handle_input),
54 STATE_INFO_UPDATE_FN_ONLY(game_blind_select_selected_anim_seq),
55 STATE_INFO_UPDATE_FN_ONLY(game_blind_select_display_blind_panel),
56 STATE_INFO_UPDATE_FN_ONLY(game_blind_select_exit),
59static StateMachine blind_select_sm = STATE_MACHINE_DEFINE(state_info, BLIND_SELECT_MAX);
63static const BG_POINT TOP_LEFT_PANEL_EMPTY_3W_ROW_POS = {29, 31};
65static const Rect BLIND_SKIP_BTN_GRAY_RECT = {0, 24, 4, 27};
66static const Rect BLIND_SKIP_BTN_PREANIM_DEST_RECT = {9, 29, 19, 31};
67static const Rect SINGLE_BLIND_SEL_REQ_SCORE_RECT = {80, 120, 104, 128};
68static const Rect SINGLE_BLIND_SELECT_RECT = {9, 7, 13, 31};
71static const u32 TM_END_ANIM_SEQ = 12;
72static const u32 TM_BLIND_SELECT_START = 1;
74static const u32 BLIND_LEFT_X = 80;
75static const u32 BLIND_CENTER_X = 120;
76static const u32 BLIND_RIGHT_X = 160;
78static const u32 BLIND_ROW = 0;
79static const u32 SKIP_ROW = 1;
81static int selection_x = 0;
82static int selection_y = 0;
84static Sprite* blind_select_tokens[NUM_BLINDS_PER_ANTE] = {NULL};
86static void game_blind_select_start_anim_seq()
91 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
94 blind_select_tokens[i],
95 blind_select_tokens[i]->pos.x,
100 if (s_timer == TM_END_ANIM_SEQ)
102 game_blind_select_print_blinds_reqs_and_rewards();
108static inline void game_blind_select_erase_blind_reqs_and_rewards()
110 for (
enum BlindTokens curr_blind = SMALL_BLIND; curr_blind < NUM_BLINDS_PER_ANTE; curr_blind++)
112 Rect blind_req_and_reward_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT;
115 blind_req_and_reward_rect.top -=
TILE_SIZE;
116 blind_req_and_reward_rect.bottom +=
TILE_SIZE;
119 blind_req_and_reward_rect.right +=
TILE_SIZE;
121 blind_req_and_reward_rect.left +=
123 blind_req_and_reward_rect.right +=
130void increment_blind(
enum BlindState increment_reason)
132 switch (g_game_vars.current_blind)
135 case BLIND_TYPE_SMALL:
136 g_game_vars.current_blind = BLIND_TYPE_BIG;
137 g_game_vars.blinds_states[SMALL_BLIND] = increment_reason;
138 g_game_vars.blinds_states[BIG_BLIND] = BLIND_STATE_CURRENT;
142 g_game_vars.current_blind = g_game_vars.next_boss_blind;
143 g_game_vars.blinds_states[BIG_BLIND] = increment_reason;
144 g_game_vars.blinds_states[BOSS_BLIND] = BLIND_STATE_CURRENT;
148 g_game_vars.current_blind = BLIND_TYPE_SMALL;
149 g_game_vars.blinds_states[SMALL_BLIND] = BLIND_STATE_CURRENT;
150 g_game_vars.blinds_states[BIG_BLIND] = BLIND_STATE_UPCOMING;
151 g_game_vars.blinds_states[BOSS_BLIND] = BLIND_STATE_UPCOMING;
157static inline void highlight_select_button(
void)
159 memset16(&pal_bg_mem[BLIND_SELECT_BTN_SELECTED_BORDER_PID], 0xFFFF, 1);
160 memcpy16(&pal_bg_mem[BLIND_SKIP_BTN_SELECTED_BORDER_PID], &pal_bg_mem[BLIND_SKIP_BTN_PID], 1);
163static inline void highlight_skip_button(
void)
166 &pal_bg_mem[BLIND_SELECT_BTN_SELECTED_BORDER_PID],
167 &pal_bg_mem[BLIND_SELECT_BTN_PID],
170 memset16(&pal_bg_mem[BLIND_SKIP_BTN_SELECTED_BORDER_PID], 0xFFFF, 1);
173static void game_blind_select_handle_input()
175 if (s_timer == TM_BLIND_SELECT_START && g_game_vars.current_blind == BLIND_TYPE_BOSS)
177 selection_y = BLIND_ROW;
183 selection_y = BLIND_ROW;
184 highlight_select_button();
186 else if (key_hit(KEY_DOWN) && g_game_vars.current_blind <= BLIND_TYPE_BIG)
188 selection_y = SKIP_ROW;
189 highlight_skip_button();
191 else if (key_hit(SELECT_CARD))
193 game_blind_select_erase_blind_reqs_and_rewards();
205 if (g_game_vars.current_blind <= BLIND_TYPE_BIG)
208 increment_blind(BLIND_STATE_SKIPPED);
210 selection_y = BLIND_ROW;
216 for (
int i = 0; i < 12; i++)
221 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
224 blind_select_tokens[i],
225 blind_select_tokens[i]->pos.x,
226 blind_select_tokens[i]->pos.y - (
TILE_SIZE * 12)
230 game_blind_select_print_blinds_reqs_and_rewards();
231 highlight_select_button();
242static void game_blind_select_selected_anim_seq()
246 Rect blinds_rect = POP_MENU_ANIM_RECT;
247 blinds_rect.top -= 1;
250 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
253 blind_select_tokens[i],
254 blind_select_tokens[i]->pos.x,
255 blind_select_tokens[i]->pos.y +
TILE_SIZE
259 else if (s_timer >= MENU_POP_OUT_ANIM_FRAMES)
261 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
271static void game_blind_select_display_blind_panel()
273 if (s_timer >= TM_DISP_BLIND_PANEL_FINISH)
280 if (s_timer == TM_DISP_BLIND_PANEL_START)
289 if (g_game_vars.current_blind >= BLIND_TYPE_BOSS)
298 for (
int y = 0; y < s_timer; y++)
300 int y_from = 26 + y - s_timer;
303 Rect from = {0, y_from, 8, y_from};
304 BG_POINT to = {0, y_to};
310static void game_blind_select_exit(
void)
313 game_change_state(GAME_STATE_ROUND);
316static Rect game_blind_select_get_req_score_rect(
enum BlindTokens blind)
318 Rect blind_req_score_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT;
323 if (g_game_vars.blinds_states[blind] == BLIND_STATE_CURRENT)
327 blind_req_score_rect.bottom -=
TILE_SIZE;
330 return blind_req_score_rect;
339 blind_type = BLIND_TYPE_SMALL;
342 blind_type = BLIND_TYPE_BIG;
345 blind_type = g_game_vars.next_boss_blind;
351static inline void game_blind_select_print_blind_req(
enum BlindTokens blind)
353 Rect blind_req_score_rect = game_blind_select_get_req_score_rect(blind);
357 char blind_req_str_buff[UINT_MAX_DIGITS + 1];
367 "#{P:%d,%d; cx:0x%X000}%s",
368 blind_req_score_rect.left,
369 blind_req_score_rect.top,
375static inline void game_blind_select_print_blind_reward(
enum BlindTokens blind)
378 Rect blind_reward_rect = game_blind_select_get_req_score_rect(blind);
384 char blind_reward_str_buff[UINT_MAX_DIGITS + 2];
385 snprintf(blind_reward_str_buff,
sizeof(blind_reward_str_buff),
"$%d", blind_reward);
390 "#{P:%d,%d; cx:0x%X000}%s",
391 blind_reward_rect.left,
392 blind_reward_rect.top,
394 blind_reward_str_buff
398static void game_blind_select_print_blinds_reqs_and_rewards(
void)
400 for (
enum BlindTokens curr_blind = 0; curr_blind < NUM_BLINDS_PER_ANTE; curr_blind++)
402 game_blind_select_print_blind_req(curr_blind);
403 game_blind_select_print_blind_reward(curr_blind);
407static inline void reroll_boss_blind(
bool no_tiles)
410 g_game_vars.next_boss_blind =
411 roll_blind_type((g_game_vars.ante % 8 == 0) && (g_game_vars.ante > 0));
418static void blind_tokens_init()
420 if (g_game_vars.current_blind == BLIND_TYPE_SMALL)
421 reroll_boss_blind(
true);
429 CUR_BLIND_TOKEN_POS.x,
430 CUR_BLIND_TOKEN_POS.y,
431 SMALL_BLIND_TOKEN_LAYER
435 CUR_BLIND_TOKEN_POS.x,
436 CUR_BLIND_TOKEN_POS.y,
437 BIG_BLIND_TOKEN_LAYER
440 g_game_vars.next_boss_blind,
441 CUR_BLIND_TOKEN_POS.x,
442 CUR_BLIND_TOKEN_POS.y,
443 BOSS_BLIND_TOKEN_LAYER
446 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
468 highlight_select_button();
495 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
502 const int default_y = 89 + (
TILE_SIZE * 12);
504 sprite_position(blind_select_tokens[SMALL_BLIND], BLIND_LEFT_X, default_y);
505 sprite_position(blind_select_tokens[BIG_BLIND], BLIND_CENTER_X, default_y);
506 sprite_position(blind_select_tokens[BOSS_BLIND], BLIND_RIGHT_X, default_y);
510 GRIT_CPY(pal_bg_mem, background_blind_select_gfxPal);
511 GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_blind_select_gfxTiles);
512 GRIT_CPY(&se_mem[MAIN_BG_SBB], background_blind_select_gfxMap);
517 blind_get_color(g_game_vars.next_boss_blind, BLIND_BACKGROUND_MAIN_COLOR_INDEX),
522 blind_get_color(g_game_vars.next_boss_blind, BLIND_BACKGROUND_SHADOW_COLOR_INDEX),
529 &pal_bg_mem[BLIND_SELECT_BTN_SELECTED_BORDER_PID],
530 &pal_bg_mem[BLIND_SELECT_BTN_PID],
537 memcpy16(&pal_bg_mem[BLIND_SKIP_BTN_SELECTED_BORDER_PID], &pal_bg_mem[BLIND_SKIP_BTN_PID], 1);
539 for (
int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
541 Rect curr_blind_rect = SINGLE_BLIND_SELECT_RECT;
544 curr_blind_rect.left += i *
rect_width(&SINGLE_BLIND_SELECT_RECT);
545 curr_blind_rect.right += i *
rect_width(&SINGLE_BLIND_SELECT_RECT);
547 if (g_game_vars.blinds_states[i] != BLIND_STATE_CURRENT &&
548 (i == BLIND_TYPE_SMALL || i == BLIND_TYPE_BIG))
550 BG_POINT skip_blind_btn_pos_dest = {
551 BLIND_SKIP_BTN_PREANIM_DEST_RECT.left,
552 BLIND_SKIP_BTN_PREANIM_DEST_RECT.top
554 skip_blind_btn_pos_dest.x = curr_blind_rect.left;
556 Rect skip_blind_btn_rect_src = BLIND_SKIP_BTN_GRAY_RECT;
557 skip_blind_btn_rect_src.top += i *
rect_height(&BLIND_SKIP_BTN_GRAY_RECT);
558 skip_blind_btn_rect_src.bottom += i *
rect_height(&BLIND_SKIP_BTN_GRAY_RECT);
563 switch (g_game_vars.blinds_states[i])
565 case BLIND_STATE_CURRENT:
573 int x_to = curr_blind_rect.left;
576 if (i == BLIND_TYPE_BIG)
580 else if (i > BLIND_TYPE_BIG)
589 {x_from, y_from, x_from +
rect_width(&SINGLE_BLIND_SELECT_RECT) - 1, y_from};
590 BG_POINT gap_fill_point = {x_to, y_to};
595 blind_select_tokens[i],
596 blind_select_tokens[i]->pos.x,
601 case BLIND_STATE_UPCOMING:
606 int x_to = 10 + (i *
rect_width(&SINGLE_BLIND_SELECT_RECT));
610 &se_mem[MAIN_BG_SBB][x_to + 32 * y_to],
611 &se_mem[MAIN_BG_SBB][x_from + 32 * y_from],
616 case BLIND_STATE_SKIPPED:
621 int x_to = 10 + (i * 5);
625 &se_mem[MAIN_BG_SBB][x_to + 32 * y_to],
626 &se_mem[MAIN_BG_SBB][x_from + 32 * y_from],
631 case BLIND_STATE_DEFEATED:
636 int x_to = 10 + (i * 5);
640 &se_mem[MAIN_BG_SBB][x_to + 32 * y_to],
641 &se_mem[MAIN_BG_SBB][x_from + 32 * y_from],
Utilities for affine background on GBA.
void affine_background_set_color(COLOR color)
Update the affine background color.
Utilities for using maxmod to play sound effects.
#define MM_BASE_PITCH_RATE
The default pitch rate for the sound effect played.
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....
#define SFX_DEFAULT_VOLUME
Default volume for sound effects.
Data structures and functions relative to the behaviour and graphics of Blinds.
void apply_blind_tiles(enum BlindType type, enum BlindTokenLayers layer)
Change the tiles of the BlindToken Sprite at a given layer to that of the given BlindType.
enum BlindType roll_blind_type(bool showdown)
Choose a random Blind among the ones that haven't been beaten yet.
BlindType
All Blind types in the game are listed here.
BlindState
All the possible states an Ante's Blinds can be in when viewed in the "Blind Select" screen.
u16 blind_get_color(enum BlindType type, enum BlindColorIndex index)
Get the color associated with a given Blind.
u32 blind_get_requirement(enum BlindType type, int ante)
Get the score required to beat a certain blind (either the Small, Big, or any Boss/Showdown blind) at...
BlindTokens
The sprites that display the blinds when in "GAME_BLIND_SELECT" state. There are only 3 blinds per An...
Sprite * blind_token_new(enum BlindType type, int x, int y, enum BlindTokenLayers sprite_index)
Create a new BlindToken sprite.
int blind_get_reward(enum BlindType type)
Get the amount of money gained from beating a certain Blind.
Blind select state functions.
void game_blind_select_on_exit(void)
Blind select cleanup.
void game_blind_select_on_update(void)
Blind select state update.
void game_blind_select_on_init(void)
Blind select state initialization.
void game_blind_select_change_background(void)
Change to the blind select background.
void change_background(enum BackgroundId id, bool force_redraw)
void reset_top_left_panel_bottom_row(void)
Restores the bottom row of the top-left panel from the background map.
Game global game variables struct definition.
Graphic utility functions.
void main_bg_se_move_rect_1_tile_vert(Rect se_rect, enum ScreenVertDir direction)
Moves a rect in the main background vertically in direction by a single tile.
INLINE int rect_height(const Rect *rect)
Get the height of a rectangle.
void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, enum ScreenVertDir direction)
Copies a rect in the main background vertically in direction by a single tile.
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 toggle_windows(bool win0, bool win1)
Toggles the visibility of the window layers.
void update_text_rect_to_right_align_str(Rect *rect, const char *str, enum OverflowDir overflow_direction)
Changes rect->left so it fits the digits of num exactly when right aligned to rect->right....
#define TILE_SIZE
Tile size in pixels, both height and width as tiles are square.
#define TTE_CHAR_SIZE
By default TTE characters occupy a single tile.
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_3w_row(Rect se_dest_rect, BG_POINT src_row_left_pnt)
Copies a 3-width SE rect and expands it to fit a passed rect.
INLINE int rect_width(const Rect *rect)
Get the width of a rectangle.
Header of shared rects and points needed for ui.
Sprite system for Gbalatro.
INLINE void sprite_position(Sprite *sprite, int x, int y)
Set sprite position. Inlined for efficiency.
void sprite_destroy(Sprite **sprite)
Destroy Sprite.
void sprite_hide(Sprite *sprite)
Hides the sprite by manipulating ATTR0_HIDE in OAM.
void sprite_unhide(Sprite *sprite)
Unhides the sprite by manipulating ATTR0_HIDE in OAM. The sprite's ATTR0_MODE is maintained from the ...
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 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.
Sprite struct for GBA hardware specifics.
POINT pos
Sprite position on screen in pixels.
Utilities relating around number string representation and protected arithmatic helper functions.
void truncate_uint_to_suffixed_str(uint32_t num, int num_req_chars, char out_str_buff[UINT_MAX_DIGITS+1])
Truncate an unsigned number into a suffixed string representation e.g. 12000 -> "12K" The least signi...