4#include "affine_background_gfx.h"
6#include "background_main_menu_gfx.h"
33#include "tonc_memdef.h"
41#define STRAIGHT_AND_FLUSH_SIZE_FOUR_FINGERS 4
42#define STRAIGHT_AND_FLUSH_SIZE_DEFAULT 5
46#define STARTING_ROUND 0
47#define STARTING_ANTE 1
48#define STARTING_MONEY 4
49#define STARTING_SCORE 0
51#define EXPIRE_ANIMATION_FRAME_COUNT 3
60int deck_get_size(
void);
61static int deck_get_max_size(
void);
71static const Rect TEMP_SCORE_RECT = {8, 64, 64, 72 };
72static const Rect SCORE_RECT = {24, 48, 64, 56 };
74static const Rect MONEY_TEXT_RECT = {8, 120, 64, 128 };
75static const Rect CHIPS_TEXT_RECT = {8, 80, 32, 88 };
76static const Rect MULT_TEXT_RECT = {40, 80, 64, 88 };
80static const Rect HANDS_TEXT_RECT = {16, 104, UNDEFINED, UNDEFINED };
81static const Rect DISCARDS_TEXT_RECT = {48, 104, UNDEFINED, UNDEFINED };
82static const Rect DECK_SIZE_RECT = {200, 152, 240, 160 };
83static const Rect ROUND_TEXT_RECT = {48, 144, UNDEFINED, UNDEFINED };
84static const Rect ANTE_TEXT_RECT = {8, 144, UNDEFINED, UNDEFINED };
88#define DEF_STATE_INFO(stateEnum, init_fn, update_fn, exit_fn) \
89 {.on_init = init_fn, .on_update = update_fn, .on_exit = exit_fn},
90#include "../include/def_state_info_table.h"
94static StateMachine game_sm = STATE_MACHINE_DEFINE(state_info, GAME_STATE_MAX);
101 .rng_info = {UNDEFINED, {0}},
103 .round = 0, .ante = 0, .money = 0, .hand_size = DEFAULT_HAND_SIZE,
104 .deck = DECK_TYPE_RED,
106 .best_hand_score = 0, .nb_played_hands = {0},
108 .current_blind = BLIND_TYPE_SMALL,
109 .next_boss_blind = BLIND_TYPE_BIG,
113 BLIND_STATE_UPCOMING,
123 .playing_blind_token = NULL,
124 .round_end_blind_token = NULL,
126 .game_speed = DEFAULT_GAME_SPEED,
127 .music_volume = DEFAULT_MUSIC_VOLUME,
128 .sound_volume = DEFAULT_SOUND_VOLUME,
132static List s_owned_jokers_list;
133static List s_discarded_jokers_list;
134static List s_expired_jokers_list;
137static Card* s_deck[MAX_DECK_SIZE] = {NULL};
138static int s_deck_top = -1;
141static int s_shortcut_joker_count = 0;
143static int s_four_fingers_joker_count = 0;
145void deck_push(
Card* card)
147 if (s_deck_top >= MAX_DECK_SIZE - 1)
149 s_deck[++s_deck_top] = card;
156 return s_deck[s_deck_top--];
159void display_ante(
void)
162 "#{P:%d,%d; cx:0x%X000}%ld#{cx:0x%X000}/%d",
184 g_game_vars.hands = MAX_HANDS;
185 g_game_vars.discards = MAX_DISCARDS;
186 g_game_vars.timer = TM_ZERO;
187 g_game_vars.current_blind = BLIND_TYPE_SMALL;
188 g_game_vars.blinds_states[0] = BLIND_STATE_CURRENT;
189 g_game_vars.blinds_states[1] = BLIND_STATE_UPCOMING;
190 g_game_vars.blinds_states[2] = BLIND_STATE_UPCOMING;
191 g_game_vars.ante = STARTING_ANTE;
192 g_game_vars.money = STARTING_MONEY;
193 g_game_vars.score = STARTING_SCORE;
194 g_game_vars.round = 0;
195 g_game_vars.chips = 0;
196 g_game_vars.mult = 0;
197 g_game_vars.round = STARTING_ROUND;
199 g_game_vars.best_hand_score = 0;
200 for (
int i = 0; i < HAND_TYPE_MAX; i++)
201 g_game_vars.nb_played_hands[i] = 0;
209 remove_owned_joker(0);
210 joker_object_destroy(&joker_object);
229 display_score(g_game_vars.score);
241static inline void discarded_jokers_update_loop(
void)
253 if (joker_object->x == joker_object->tx && joker_object->y == joker_object->ty)
257 joker_object_destroy(&joker_object);
262static inline void held_jokers_update_loop(
void)
264 static const int SPACING_LUT[MAX_JOKERS_HELD_SIZE][MAX_JOKERS_HELD_SIZE] = {
268 {39, 13, -13, -39, 0 },
269 {40, 20, 0, -20, -40}
272 FIXED hand_x = int2fx(HELD_JOKERS_POS.x);
276 int jokers_top =
list_get_len(&s_owned_jokers_list) - 1;
282 joker->tx = hand_x - int2fx(SPACING_LUT[jokers_top][i]);
287bool joker_object_can_acquire(
Item* joker_object)
290 return (
list_get_len(get_jokers_list()) < MAX_JOKERS_HELD_SIZE);
293static inline void expired_jokers_update_loop(
void)
306 if (g_game_vars.timer % FRAMES(EXPIRE_ANIMATION_FRAME_COUNT) == 0)
309 int expired_joker_idx = 0;
312 while ((expired_joker =
list_itr_next(&joker_itr)) && expired_joker != joker_object)
321 remove_owned_joker(expired_joker_idx);
323 joker_object_destroy(&joker_object);
328static inline void jokers_update_loop(
void)
330 held_jokers_update_loop();
331 discarded_jokers_update_loop();
332 expired_jokers_update_loop();
341 jokers_update_loop();
348void game_change_state(
enum GameState new_game_state)
350 g_game_vars.timer = TM_ZERO;
355enum GameState game_get_state(
void)
357 return game_sm.
state;
360bool is_joker_owned(
int joker_id)
367 if (joker->joker->id == joker_id)
375List* get_jokers_list(
void)
377 return &s_owned_jokers_list;
380List* get_expired_jokers_list(
void)
382 return &s_expired_jokers_list;
385List* get_discarded_jokers_list(
void)
387 return &s_discarded_jokers_list;
390bool is_shortcut_joker_active(
void)
392 return s_shortcut_joker_count > 0;
395int get_straight_and_flush_size(
void)
397 return s_four_fingers_joker_count > 0 ? STRAIGHT_AND_FLUSH_SIZE_FOUR_FINGERS
398 : STRAIGHT_AND_FLUSH_SIZE_DEFAULT;
408 if (joker_object->joker->id == FOUR_FINGERS_JOKER_ID)
410 s_four_fingers_joker_count++;
413 if (joker_object->joker->id == SHORTCUT_JOKER_ID)
415 s_shortcut_joker_count++;
419void remove_owned_joker(
int owned_joker_idx)
425 if (joker_object->joker->id == FOUR_FINGERS_JOKER_ID)
427 s_four_fingers_joker_count--;
430 if (joker_object->joker->id == SHORTCUT_JOKER_ID)
432 s_shortcut_joker_count--;
440int get_deck_top(
void)
445int get_num_discards_remaining(
void)
447 return g_game_vars.discards;
450int get_num_hands_remaining(
void)
452 return g_game_vars.hands;
457 Rect money_text_rect = MONEY_TEXT_RECT;
460 char money_str_buff[INT_MAX_DIGITS + 2];
461 snprintf(money_str_buff,
sizeof(money_str_buff),
"$%ld", g_game_vars.money);
467 "#{P:%d,%d; cx:0x%X000}%s",
468 money_text_rect.left,
475void display_chips(
void)
477 Rect chips_text_rect = CHIPS_TEXT_RECT;
480 Rect chips_text_overflow_rect = chips_text_rect;
484 char chips_str_buff[UINT_MAX_DIGITS + 1];
494 "#{P:%d,%d; cx:0x%X000;}%s",
495 chips_text_rect.left,
503void display_mult(
void)
505 Rect mult_text_overflow_rect = MULT_TEXT_RECT;
510 char mult_str_buff[UINT_MAX_DIGITS + 1];
518 "#{P:%d,%d; cx:0x%X000;}%s",
528void display_deck_size_max(
void)
534 "#{P:%d,%d; cx:0x%X000}%d/%d",
544bool card_is_face(
Card* card)
548 card->rank == JACK || card->rank == QUEEN || card->rank == KING ||
549 is_joker_owned(PAREIDOLIA_JOKER_ID)
553void display_temp_score(u32 value)
555 char temp_score_str_buff[UINT_MAX_DIGITS + 1];
556 Rect temp_score_rect = TEMP_SCORE_RECT;
566 "#{P:%d,%d; cx:0x%X000}%s",
567 temp_score_rect.left,
574void erase_temp_score(
void)
579void display_score(u32 value)
581 Rect score_rect = SCORE_RECT;
585 char score_str_buff[UINT_MAX_DIGITS + 1];
591 "#{P:%d,%d; cx:0x%X000}%s",
599void display_round(
void)
603 "#{P:%d,%d; cx:0x%X000}%ld",
604 ROUND_TEXT_RECT.left,
611void display_hands(
void)
614 "#{P:%d,%d; cx:0x%X000}%ld",
615 HANDS_TEXT_RECT.left,
622void display_discards(
void)
625 "#{P:%d,%d; cx:0x%X000}%ld",
626 DISCARDS_TEXT_RECT.left,
627 DISCARDS_TEXT_RECT.top,
633int deck_get_size(
void)
635 return s_deck_top + 1;
638static int deck_get_max_size(
void)
644void deck_shuffle(
void)
646 for (
int i = s_deck_top; i > 0; i--)
648 int j =
rng_get_u32(RNG_SEQ_CARD_SHUFFLE) % (i + 1);
649 Card* temp = s_deck[i];
650 s_deck[i] = s_deck[j];
660 g_game_vars.hands = MAX_HANDS;
661 g_game_vars.discards = MAX_DISCARDS;
665 for (
int suit = 0; suit < NUM_SUITS; suit++)
667 for (
int rank = 0; rank < NUM_RANKS; rank++)
669 Card* card = card_new(suit, rank);
679 "#{P:%d,%d; cx:0x%X000}%d/%d",
688 display_score(g_game_vars.score);
699 game_change_state(GAME_STATE_BLIND_SELECT);
Utilities for affine background on GBA.
@ AFFINE_BG_GAME
Display background for game play.
void affine_background_change_background(enum AffineBackgroundID new_bg)
Update the background id.
void affine_background_load_palette(const u16 *src)
Set the background palette.
Utilities for using maxmod to play sound effects.
void init_unbeaten_blinds_lists(void)
Initialize Boss and Showdown Blinds lists to roll from.
Blind select state functions.
Common functions to render UI elements.
void change_background(enum BackgroundId id, bool force_redraw)
Game Over screen state functions.
Game global game variables struct definition.
Graphic utility functions.
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....
void update_text_rect_to_center_str(Rect *rect, const char *str, enum ScreenHorzDir bias_direction)
Updates a rect so a string is centered within it.
#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.
INLINE int rect_width(const Rect *rect)
Get the width of a rectangle.
Functions relative to manipulating and analyzing the contents of the Hand, a.k.a. the Cards we hold a...
int get_hand_top(void)
Get the position in hand array of the last card obtained.
Functions relative to the handling of Jokers.
void joker_set_rollable(int joker_id, bool rollable)
Set whether a Joker is available to be rolled for the shop, packs, etc.
All the functions used specifically to interact with Jokers. This includes browsing,...
Header of shared rects and points needed for ui.
bool list_is_empty(const List *list)
void * list_get_at_idx(List *list, unsigned int idx)
int list_get_len(const List *list)
void list_clear(List *list)
void list_itr_remove_current_node(ListItr *itr)
void * list_itr_next(ListItr *itr)
bool list_remove_at_idx(List *list, unsigned int idx)
void list_push_back(List *list, void *data)
ListItr list_itr_create(List *list)
Main menu state functions.
Common functions to handle RNG manipulation. Using this interface has three goals:
void rng_update(void)
Accumulates CPU cycles for RNG seed generation, call exaclty once per frame.
u32 rng_get_u32(enum RngSequence key)
Get the next "randomly" generated number in the sequence corresponding to the given type.
API relative to the Rounds we play.
int get_discard_top(void)
Get the index of the last discarded card.
void toggle_flaming_score(void)
Checks whether the score that would result from the current Chips and Mult exceeds the current Blind'...
int get_played_top(void)
Get the index of the last played card.
Round end game state functions.
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.
JokerObject * game_shop_get_description_card(void)
Get a pointer to the Card we are currently showing the description of.
void game_shop_reset(void)
Initialize the shop for a run. Resets all the shop data for the run, needs to be called once per run.
Functions and constants for the splash screen intro.
Sprite system for Gbalatro.
void sprite_object_update_all(void)
Update all SpriteObjects, to be called once per frame in the main update loop.
void sprite_destroy(Sprite **sprite)
Destroy Sprite.
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.
void state_machine_update(void)
Update registered state machines' update functions.
A central location for all game variables.
A generic interface for all items that can appear in the shop or be in the inventory....
int state
The current state of the state machine, the offset into state_infos.
Utilities relating around number string representation and protected arithmatic helper functions.
#define GBAL_RETURN_IF_NULL_RET(param, ret_val)
Checks if param is equal to NULL and prints error message and returns in case it is....
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...