4#include "affine_background_gfx.h"
12enum GameRoundEndStates
16 DISPLAY_FINISHED_BLIND,
22 DISMISS_ROUND_END_PANEL,
26static const u32 TM_RESET_STATIC_VARS = 30;
27static const u32 TM_END_POP_MENU_ANIM = 13;
28static const u32 TM_START_ROUND_END_REWARDS_ANIM = 1;
29static const u32 TM_END_DISPLAY_FIN_BLIND = 30;
30static const u32 TM_END_DISPLAY_SCORE_MIN = 4;
31static const u32 TM_DISMISS_ROUND_END_TM = 20;
33static const u32 REWARD_PANEL_BORDER_PID = 19;
35static const u32 ROUND_END_BLACK_PANEL_INIT_BOTTOM_SE = 12;
36static const u32 ROUND_END_REWARD_TEXT_X = 88;
37static const u32 ROUND_END_REWARD_AMOUNT_X = 168;
40static const Rect ROUND_END_BLIND_REQ_RECT = {104, 96, 136, UNDEFINED};
41static const Rect ROUND_END_BLIND_REWARD_RECT = {168, 96, UNDEFINED, UNDEFINED};
42static const Rect CASHOUT_DEST_RECT = {10, 8, 23, 10 };
43static const Rect CASHOUT_TEXT_RECT = {88, 72, UNDEFINED, UNDEFINED};
44static const Rect BLIND_TOKEN_TEXT_RECT = {80, 72, 200, 160 };
45static const Rect ROUND_END_MENU_RECT = {9, 7, 24, 20 };
47static const BG_POINT CASHOUT_SRC_3X3_RECT_POS = {5, 29};
50static int blind_reward = 0;
51static int hand_reward = 0;
52static int interest_reward = 0;
53static int interest_to_count = 0;
54static int interest_start_time = UNDEFINED;
56static int calculate_interest_reward(
void);
58static void game_round_end_start(
void);
59static void game_round_end_start_expand_popup(
void);
60static void game_round_end_display_finished_blind(
void);
61static void game_round_end_display_score_min(
void);
62static void game_round_end_update_blind_reward(
void);
63static void game_round_end_panel_exit(
void);
64static void game_round_end_display_rewards(
void);
65static void game_round_end_display_cashout(
void);
66static void game_round_end_dismiss_round_end_panel(
void);
68static void game_round_end_extend_black_panel_down(
int black_panel_bottom);
71 STATE_INFO_UPDATE_FN_ONLY(game_round_end_start),
72 STATE_INFO_UPDATE_FN_ONLY(game_round_end_start_expand_popup),
73 STATE_INFO_UPDATE_FN_ONLY(game_round_end_display_finished_blind),
74 STATE_INFO_UPDATE_FN_ONLY(game_round_end_display_score_min),
75 STATE_INFO_UPDATE_FN_ONLY(game_round_end_update_blind_reward),
76 STATE_INFO_UPDATE_FN_ONLY(game_round_end_panel_exit),
77 STATE_INFO_UPDATE_FN_ONLY(game_round_end_display_rewards),
78 STATE_INFO_UPDATE_FN_ONLY(game_round_end_display_cashout),
79 STATE_INFO_UPDATE_FN_ONLY(game_round_end_dismiss_round_end_panel),
82static StateMachine round_end_sm = STATE_MACHINE_DEFINE(state_info, ROUND_END_STATES_MAX);
84static int calculate_interest_reward(
void)
86 int reward = (g_game_vars.money / 5) * INTEREST_PER_5;
87 if (reward > MAX_INTEREST)
88 reward = MAX_INTEREST;
92static void game_round_end_start(
void)
95 if (g_game_vars.timer == TM_RESET_STATIC_VARS)
99 g_game_vars.timer = TM_ZERO;
101 hand_reward = g_game_vars.hands;
102 interest_reward = calculate_interest_reward();
103 interest_to_count = interest_reward;
104 interest_start_time = UNDEFINED;
108static void game_round_end_start_expand_popup(
void)
112 if (g_game_vars.timer == TM_END_POP_MENU_ANIM)
115 g_game_vars.timer = TM_ZERO;
119static void game_round_end_display_finished_blind(
void)
123 int current_ante = g_game_vars.ante;
126 if (g_game_vars.current_blind > BLIND_TYPE_BIG)
129 Rect blind_req_rect = ROUND_END_BLIND_REQ_RECT;
136 char blind_req_str_buff[UINT_MAX_DIGITS + 1];
137 snprintf(blind_req_str_buff,
sizeof(blind_req_str_buff),
"%lu", blind_req);
142 "#{P:%d,%d; cx:0x%X000}%s",
149 if (g_game_vars.timer == TM_START_ROUND_END_REWARDS_ANIM)
151 game_round_end_extend_black_panel_down(ROUND_END_BLACK_PANEL_INIT_BOTTOM_SE);
154 if (g_game_vars.timer >= TM_END_DISPLAY_FIN_BLIND)
157 g_game_vars.timer = TM_ZERO;
161static void game_round_end_display_score_min(
void)
163 const int timer_offset = g_game_vars.timer - 1;
164 const int x_from = 0;
165 const int y_from = 29;
170 &se_mem[MAIN_BG_SBB][x_to + timer_offset + 32 * y_to],
171 &se_mem[MAIN_BG_SBB][x_from + timer_offset + 32 * y_from],
175 if (g_game_vars.timer >= TM_END_DISPLAY_SCORE_MIN)
178 g_game_vars.timer = TM_ZERO;
182static void game_round_end_update_blind_reward(
void)
184 if (g_game_vars.timer % FRAMES(20) != 0)
189 if (blind_reward > 0)
193 "#{P:%d,%d; cx:0x%X000}$%d",
194 BLIND_REWARD_RECT.left,
195 BLIND_REWARD_RECT.top,
200 "#{P:%d,%d; cx:0x%X000}$%d",
201 ROUND_END_BLIND_REWARD_RECT.left,
202 ROUND_END_BLIND_REWARD_RECT.top,
207 else if (g_game_vars.timer > FRAMES(20))
214 g_game_vars.timer = TM_ZERO;
218static void game_round_end_panel_exit(
void)
222 if (g_game_vars.timer < 8)
226 if (g_game_vars.timer == 1)
230 else if (g_game_vars.timer == 2)
233 memset16(&se_mem[MAIN_BG_SBB][32 * (y - 1)], 0x0001, 1);
234 memset16(&se_mem[MAIN_BG_SBB][1 + 32 * (y - 1)], 0x0002, 7);
235 memset16(&se_mem[MAIN_BG_SBB][8 + 32 * (y - 1)], 0x0401, 1);
238 else if (g_game_vars.timer > FRAMES(20))
240 memset16(&pal_bg_mem[REWARD_PANEL_BORDER_PID], 0x1483, 1);
242 g_game_vars.timer = TM_ZERO;
246static inline void game_round_end_print_separator_ellipsis(
void)
249 (ROUND_END_REWARDS_ELLIPSIS_POS.x + g_game_vars.timer - TM_REWARDS_ELLIPSIS_PRINT_START) *
251 int y = (ROUND_END_REWARDS_ELLIPSIS_POS.y) *
TILE_SIZE;
253 tte_printf(
"#{P:%d,%d; cx:0x%X000}.", x, y, TTE_WHITE_PB);
257static inline void game_round_end_print_hand_reward(
int hand_y_offset)
259 int hand_y = ROUND_END_REWARDS_ELLIPSIS_POS.y + hand_y_offset;
260 if (g_game_vars.timer == TM_DISPLAY_REWARDS_CONT_WAIT)
262 game_round_end_extend_black_panel_down(hand_y);
265 "#{P:%lu,%d; cx:0x%X000}%d #{cx:0x%X000}Hands",
266 ROUND_END_REWARD_TEXT_X,
274 else if (g_game_vars.timer > TM_HAND_REWARD_INCR_WAIT &&
275 g_game_vars.timer % FRAMES(TM_REWARD_INCREMENT_INTERVAL) == 0)
279 "#{P:%lu, %d; cx:0x%X000}$%ld",
280 ROUND_END_REWARD_AMOUNT_X,
283 g_game_vars.hands - hand_reward
285 if (hand_reward == 0)
287 interest_start_time = g_game_vars.timer + TM_REWARD_DISPLAY_INTERVAL;
292static inline void game_round_end_print_interest_reward(
int interest_y_offset)
294 int interest_y = ROUND_END_REWARDS_ELLIPSIS_POS.y + interest_y_offset;
296 if (g_game_vars.timer == interest_start_time)
298 game_round_end_extend_black_panel_down(interest_y);
301 "#{P:%lu,%d; cx:0x%X000}%d #{cx:0x%X000}Interest",
302 ROUND_END_REWARD_TEXT_X,
310 else if (g_game_vars.timer > interest_start_time + TM_REWARD_DISPLAY_INTERVAL &&
311 g_game_vars.timer % FRAMES(TM_REWARD_INCREMENT_INTERVAL) == 0)
315 "#{P:%lu, %d; cx:0x%X000}$%d",
316 ROUND_END_REWARD_AMOUNT_X,
319 interest_reward - interest_to_count
324static void game_round_end_display_rewards(
void)
326 int hand_y_offset = 0;
327 int interest_y_offset = 0;
329 if (g_game_vars.hands > 0)
335 interest_start_time = TM_DISPLAY_REWARDS_CONT_WAIT;
338 if (interest_reward > 0)
340 interest_y_offset = hand_y_offset + 1;
344 if (hand_reward <= 0 && interest_to_count <= 0)
346 g_game_vars.timer = TM_ZERO;
349 else if (g_game_vars.timer == TM_START_ROUND_END_REWARDS_ANIM)
351 game_round_end_extend_black_panel_down(ROUND_END_REWARDS_ELLIPSIS_POS.y);
353 else if (g_game_vars.timer < TM_REWARDS_ELLIPSIS_PRINT_END)
355 game_round_end_print_separator_ellipsis();
357 else if (g_game_vars.timer >= TM_DISPLAY_REWARDS_CONT_WAIT && hand_reward > 0)
359 game_round_end_print_hand_reward(hand_y_offset);
361 else if (interest_start_time != UNDEFINED && g_game_vars.timer >= interest_start_time &&
362 interest_to_count > 0)
364 game_round_end_print_interest_reward(interest_y_offset);
368static inline void game_round_end_cashout(
void)
371 g_game_vars.money += g_game_vars.hands +
blind_get_reward(g_game_vars.current_blind) +
372 calculate_interest_reward();
375 g_game_vars.hands = MAX_HANDS;
376 g_game_vars.discards = MAX_DISCARDS;
381 g_game_vars.score = 0;
382 display_score(g_game_vars.score);
385static void game_round_end_display_cashout()
387 if (g_game_vars.timer == FRAMES(40))
392 int cashout_amount = g_game_vars.hands +
blind_get_reward(g_game_vars.current_blind) +
393 calculate_interest_reward();
395 bool omit_space = cashout_amount >= 10;
397 "#{P:%d, %d; cx:0x%X000}Cash Out:%s$%d",
398 CASHOUT_TEXT_RECT.left,
399 CASHOUT_TEXT_RECT.top,
401 omit_space ?
"" :
" ",
407 else if (g_game_vars.timer > FRAMES(40) && key_hit(SELECT_CARD))
409 game_round_end_cashout();
412 g_game_vars.timer = TM_ZERO;
419static void game_round_end_dismiss_round_end_panel(
void)
421 Rect round_end_down = ROUND_END_MENU_RECT;
422 round_end_down.top--;
425 if (g_game_vars.timer >= TM_DISMISS_ROUND_END_TM)
427 g_game_vars.timer = TM_ZERO;
428 game_change_state(GAME_STATE_SHOP);
432static void game_round_end_extend_black_panel_down(
int black_panel_bottom)
434 Rect single_line_rect = ROUND_END_MENU_RECT;
435 single_line_rect.bottom = black_panel_bottom;
436 single_line_rect.top = single_line_rect.bottom - 1;
451 g_game_vars.timer = 0;
Utilities for affine background on GBA.
void affine_background_load_palette(const u16 *src)
Set the background palette.
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...
int blind_get_reward(enum BlindType type)
Get the amount of money gained from beating a certain Blind.
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.
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_clear_rect(Rect se_rect)
Clears a rect in the main background.
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.
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.
Header of shared rects and points needed for ui.
Round end game state functions.
void game_round_end_on_exit(void)
Round end cleanup.
void game_round_end_on_init(void)
Round end state initialization.
void game_round_end_on_update(void)
Round end state update.
void game_round_end_change_background(void)
Change to the round end background.
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.
Utilities relating around number string representation and protected arithmatic helper functions.