kind of fixed how game_speed behaves

This commit is contained in:
alex
2025-09-21 23:16:50 -07:00
parent 9dc5f7ccc3
commit 6e60cf5970
7 changed files with 856 additions and 811 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ LIBDIRS := $(LIBGBA) $(LIBTONC)
ifneq ($(BUILD),$(notdir $(CURDIR))) ifneq ($(BUILD),$(notdir $(CURDIR)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(BUILD)/$(TARGET) export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
View File
+4
View File
@@ -98,4 +98,8 @@ int get_deck_top(void);
int get_num_discards_remaining(void); int get_num_discards_remaining(void);
int get_money(void); int get_money(void);
extern int game_speed; // had to do this use this it the sprites animations
// that were not affected by game_speed, like discard
// and draw-to-deck animations.
#endif // GAME_H #endif // GAME_H
+88 -52
View File
@@ -32,7 +32,7 @@
static uint rng_seed = 0; static uint rng_seed = 0;
static uint timer = 0; // This might already exist in libtonc but idk so i'm just making my own static uint timer = 0; // This might already exist in libtonc but idk so i'm just making my own
static int game_speed = 1; int game_speed = 1; // BY DEFAULT IS ON 1, but if changed to 2, should speed up all (or most) of the game aspects that should be sped up by speed, as in the original game.
static int background = 0; static int background = 0;
static enum GameState game_state = GAME_SPLASH_SCREEN; // The current game state, this is used to determine what the game is doing at any given time static enum GameState game_state = GAME_SPLASH_SCREEN; // The current game state, this is used to determine what the game is doing at any given time
@@ -99,48 +99,56 @@ static int discard_top = -1;
// Played stack // Played stack
static inline void played_push(CardObject *card_object) static inline void played_push(CardObject *card_object)
{ {
if (played_top >= MAX_SELECTION_SIZE - 1) return; if (played_top >= MAX_SELECTION_SIZE - 1)
return;
played[++played_top] = card_object; played[++played_top] = card_object;
} }
static inline CardObject *played_pop() static inline CardObject *played_pop()
{ {
if (played_top < 0) return NULL; if (played_top < 0)
return NULL;
return played[played_top--]; return played[played_top--];
} }
// Deck stack // Deck stack
static inline void deck_push(Card *card) static inline void deck_push(Card *card)
{ {
if (deck_top >= MAX_DECK_SIZE - 1) return; if (deck_top >= MAX_DECK_SIZE - 1)
return;
deck[++deck_top] = card; deck[++deck_top] = card;
} }
static inline Card *deck_pop() static inline Card *deck_pop()
{ {
if (deck_top < 0) return NULL; if (deck_top < 0)
return NULL;
return deck[deck_top--]; return deck[deck_top--];
} }
// Discard stack // Discard stack
static inline void discard_push(Card *card) static inline void discard_push(Card *card)
{ {
if (discard_top >= MAX_DECK_SIZE - 1) return; if (discard_top >= MAX_DECK_SIZE - 1)
return;
discard_pile[++discard_top] = card; discard_pile[++discard_top] = card;
} }
static inline Card *discard_pop() static inline Card *discard_pop()
{ {
if (discard_top < 0) return NULL; if (discard_top < 0)
return NULL;
return discard_pile[discard_top--]; return discard_pile[discard_top--];
} }
// get-functions, for other files to view game state (mainly for jokers) // get-functions, for other files to view game state (mainly for jokers)
CardObject **get_hand_array(void) { CardObject **get_hand_array(void)
{
return hand; return hand;
} }
int get_hand_top(void) { int get_hand_top(void)
{
return hand_top; return hand_top;
} }
@@ -149,15 +157,18 @@ int hand_get_size(void)
return hand_top + 1; return hand_top + 1;
} }
CardObject **get_played_array(void) { CardObject **get_played_array(void)
{
return played; return played;
} }
int get_played_top(void) { int get_played_top(void)
{
return played_top; return played_top;
} }
List *get_jokers(void) { List *get_jokers(void)
{
return jokers; return jokers;
} }
@@ -171,19 +182,21 @@ void remove_held_joker(int joker_idx)
list_remove_by_idx(jokers, joker_idx); list_remove_by_idx(jokers, joker_idx);
} }
int get_deck_top(void) { int get_deck_top(void)
{
return deck_top; return deck_top;
} }
int get_num_discards_remaining(void) { int get_num_discards_remaining(void)
{
return discards; return discards;
} }
int get_money(void) { int get_money(void)
{
return money; return money;
} }
// Consts // Consts
// Rects left top right bottom // Rects left top right bottom
@@ -204,7 +217,10 @@ static const Rect HAND_BG_RECT_SELECTING = {9, 11, 24, 17 };
// static const Rect HAND_BG_RECT_PLAYING = {9, 14, 24, 18 }; // static const Rect HAND_BG_RECT_PLAYING = {9, 14, 24, 18 };
static const Rect TOP_LEFT_ITEM_SRC_RECT = {0, 20, 8, 25}; static const Rect TOP_LEFT_ITEM_SRC_RECT = {0, 20, 8, 25};
static const BG_POINT TOP_LEFT_PANEL_POINT = {0, 0, }; static const BG_POINT TOP_LEFT_PANEL_POINT = {
0,
0,
};
static const Rect TOP_LEFT_PANEL_ANIM_RECT = {0, 0, 8, 4}; static const Rect TOP_LEFT_PANEL_ANIM_RECT = {0, 0, 8, 4};
/* Contains the shop icon/current blind etc. /* Contains the shop icon/current blind etc.
* The difference between TOP_LEFT_PANEL_ANIM_RECT and TOP_LEFT_PANEL_RECT * The difference between TOP_LEFT_PANEL_ANIM_RECT and TOP_LEFT_PANEL_RECT
@@ -213,7 +229,10 @@ static const Rect TOP_LEFT_PANEL_ANIM_RECT = {0, 0, 8, 4 };
* TOP_LEFT_PANEL_ANIM_RECT should be used for animations, * TOP_LEFT_PANEL_ANIM_RECT should be used for animations,
* TOP_LEFT_PANEL_RECT for copies etc. but mind the overlap * TOP_LEFT_PANEL_RECT for copies etc. but mind the overlap
*/ */
static const BG_POINT TOP_LEFT_BLIND_TITLE_POINT = {0, 21, }; static const BG_POINT TOP_LEFT_BLIND_TITLE_POINT = {
0,
21,
};
static const Rect BIG_BLIND_TITLE_SRC_RECT = {0, 26, 8, 26}; static const Rect BIG_BLIND_TITLE_SRC_RECT = {0, 26, 8, 26};
static const Rect BOSS_BLIND_TITLE_SRC_RECT = {0, 27, 8, 27}; static const Rect BOSS_BLIND_TITLE_SRC_RECT = {0, 27, 8, 27};
static const BG_POINT GAME_OVER_SRC_RECT_3X3_POS = {25, 29}; static const BG_POINT GAME_OVER_SRC_RECT_3X3_POS = {25, 29};
@@ -372,7 +391,8 @@ enum HandType hand_get_type()
res_hand_type = FLUSH; res_hand_type = FLUSH;
// Check for straight // Check for straight
if (hand_contains_straight(ranks)) { if (hand_contains_straight(ranks))
{
if (res_hand_type == FLUSH) if (res_hand_type == FLUSH)
res_hand_type = STRAIGHT_FLUSH; res_hand_type = STRAIGHT_FLUSH;
else else
@@ -380,7 +400,8 @@ enum HandType hand_get_type()
} }
// Check for royal flush vs regular straight flush // Check for royal flush vs regular straight flush
if (res_hand_type == STRAIGHT_FLUSH) { if (res_hand_type == STRAIGHT_FLUSH)
{
if (ranks[TEN] && ranks[JACK] && ranks[QUEEN] && ranks[KING] && ranks[ACE]) if (ranks[TEN] && ranks[JACK] && ranks[QUEEN] && ranks[KING] && ranks[ACE])
return ROYAL_FLUSH; return ROYAL_FLUSH;
return STRAIGHT_FLUSH; return STRAIGHT_FLUSH;
@@ -389,32 +410,40 @@ enum HandType hand_get_type()
// The following can be optimized better but not sure how much it matters // The following can be optimized better but not sure how much it matters
u8 n_of_a_kind = hand_contains_n_of_a_kind(ranks); u8 n_of_a_kind = hand_contains_n_of_a_kind(ranks);
if (n_of_a_kind >= 5) { if (n_of_a_kind >= 5)
if (res_hand_type == FLUSH) { {
if (res_hand_type == FLUSH)
{
return FLUSH_FIVE; return FLUSH_FIVE;
} }
return FIVE_OF_A_KIND; return FIVE_OF_A_KIND;
} }
if (n_of_a_kind == 4) { if (n_of_a_kind == 4)
{
return FOUR_OF_A_KIND; return FOUR_OF_A_KIND;
} }
if (n_of_a_kind == 3 && hand_contains_full_house(ranks)) { if (n_of_a_kind == 3 && hand_contains_full_house(ranks))
{
return FULL_HOUSE; return FULL_HOUSE;
} }
// Flush is more valuable than the remaining hand types, so return now // Flush is more valuable than the remaining hand types, so return now
if (res_hand_type == FLUSH) { if (res_hand_type == FLUSH)
{
return FLUSH; return FLUSH;
} }
if (n_of_a_kind == 3) { if (n_of_a_kind == 3)
{
return THREE_OF_A_KIND; return THREE_OF_A_KIND;
} }
if (n_of_a_kind == 2) { if (n_of_a_kind == 2)
if (hand_contains_two_pair(ranks)) { {
if (hand_contains_two_pair(ranks))
{
return TWO_PAIR; return TWO_PAIR;
} }
return PAIR; return PAIR;
@@ -831,7 +860,8 @@ void set_hand()
void card_draw() void card_draw()
{ {
if (deck_top < 0 || hand_top >= hand_size - 1 || hand_top >= MAX_HAND_SIZE - 1) return; if (deck_top < 0 || hand_top >= hand_size - 1 || hand_top >= MAX_HAND_SIZE - 1)
return;
CardObject *card_object = card_object_new(deck_pop()); CardObject *card_object = card_object_new(deck_pop());
@@ -851,7 +881,8 @@ void card_draw()
void hand_set_focus(int index) void hand_set_focus(int index)
{ {
if (index < 0 || index > hand_top || hand_state != HAND_SELECT) return; if (index < 0 || index > hand_top || hand_state != HAND_SELECT)
return;
selection_x = index; selection_x = index;
play_sfx(SFX_CARD_FOCUS, MM_BASE_PITCH_RATE + rand() % 512); play_sfx(SFX_CARD_FOCUS, MM_BASE_PITCH_RATE + rand() % 512);
@@ -859,7 +890,8 @@ void hand_set_focus(int index)
void hand_toggle_card_selection() void hand_toggle_card_selection()
{ {
if (hand_state != HAND_SELECT || hand[selection_x] == NULL) return; if (hand_state != HAND_SELECT || hand[selection_x] == NULL)
return;
if (card_object_is_selected(hand[selection_x])) if (card_object_is_selected(hand[selection_x]))
{ {
@@ -907,13 +939,15 @@ int hand_get_max_size()
bool hand_discard() bool hand_discard()
{ {
if (hand_state != HAND_SELECT || hand_selections == 0) return false; if (hand_state != HAND_SELECT || hand_selections == 0)
return false;
return true; return true;
} }
bool hand_play() bool hand_play()
{ {
if (hand_state != HAND_SELECT || hand_selections == 0) return false; if (hand_state != HAND_SELECT || hand_selections == 0)
return false;
return true; return true;
} }
@@ -1030,7 +1064,6 @@ static void game_lose_init()
game_over_init(); game_over_init();
// Using the text color to match the "Game Over" text // Using the text color to match the "Game Over" text
affine_background_set_color(TEXT_CLR_RED); affine_background_set_color(TEXT_CLR_RED);
} }
static void game_win_init() static void game_win_init()
@@ -1095,10 +1128,12 @@ void game_init()
jokers_available_to_shop_init(); jokers_available_to_shop_init();
// Initialize jokers list // Initialize jokers list
if (jokers) list_destroy(&jokers); if (jokers)
list_destroy(&jokers);
jokers = list_new(MAX_JOKERS_HELD_SIZE); jokers = list_new(MAX_JOKERS_HELD_SIZE);
if (discarded_jokers != NULL) list_destroy(&discarded_jokers); if (discarded_jokers != NULL)
list_destroy(&discarded_jokers);
discarded_jokers = list_new(MAX_JOKERS_HELD_SIZE); discarded_jokers = list_new(MAX_JOKERS_HELD_SIZE);
hands = max_hands; hands = max_hands;
@@ -1269,7 +1304,7 @@ static void game_playing_process_input_and_state()
if (mult > 0) if (mult > 0)
{ {
temp_score = chips * mult; temp_score = chips * mult;
lerped_temp_score = int2fx(temp_score); lerped_temp_score = (float)(1.0f / game_speed) * int2fx(temp_score);
lerped_score = int2fx(score); lerped_score = int2fx(score);
display_temp_score(temp_score); display_temp_score(temp_score);
@@ -1519,7 +1554,8 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
case HAND_DISCARD: // TODO: Add sound case HAND_DISCARD: // TODO: Add sound
bool break_loop; bool break_loop;
card_in_hand_loop_handle_discard_and_shuffling(i, discarded_card, &hand_x, &hand_y, sound_played, &break_loop); card_in_hand_loop_handle_discard_and_shuffling(i, discarded_card, &hand_x, &hand_y, sound_played, &break_loop);
if (break_loop) break; if (break_loop)
break;
break; break;
case HAND_PLAY: case HAND_PLAY:
@@ -1581,7 +1617,8 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
} }
} }
if (card_object_is_selected(played[i])) break; if (card_object_is_selected(played[i]))
break;
} }
break; break;
case TWO_PAIR: // find two pairs of cards with the same rank (Requires recursion) case TWO_PAIR: // find two pairs of cards with the same rank (Requires recursion)
@@ -1600,7 +1637,8 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
} }
} }
if (card_object_is_selected(played[i])) break; if (card_object_is_selected(played[i]))
break;
} }
for (; i <= played_top - 1; i++) // Find second pair for (; i <= played_top - 1; i++) // Find second pair
@@ -1639,7 +1677,8 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
} }
} }
if (card_object_is_selected(played[i])) break; if (card_object_is_selected(played[i]))
break;
} }
break; break;
case FOUR_OF_A_KIND: // find four cards with the same rank (requires recursion) case FOUR_OF_A_KIND: // find four cards with the same rank (requires recursion)
@@ -2030,7 +2069,8 @@ void game_round_end()
obj_unhide(round_end_blind_token->obj, 0); obj_unhide(round_end_blind_token->obj, 0);
int current_ante = ante; int current_ante = ante;
if (current_blind == BOSS_BLIND) current_ante--; // Beating the boss blind increases the ante, so we need to display the previous ante value if (current_blind == BOSS_BLIND)
current_ante--; // Beating the boss blind increases the ante, so we need to display the previous ante value
Rect blind_req_rect = ROUND_END_BLIND_REQ_RECT; Rect blind_req_rect = ROUND_END_BLIND_REQ_RECT;
int blind_req = blind_get_requirement(current_blind, current_ante); int blind_req = blind_get_requirement(current_blind, current_ante);
@@ -2074,7 +2114,8 @@ void game_round_end()
} }
case 4: // Every 20 frames, display the blind reward and update the text until it reaches 0 case 4: // Every 20 frames, display the blind reward and update the text until it reaches 0
{ {
if (timer % FRAMES(20) != 0) break; if (timer % FRAMES(20) != 0)
break;
// TODO: Add sound effect here // TODO: Add sound effect here
@@ -2484,9 +2525,7 @@ static void shop_top_row_on_key_hit(SelectionGrid* selection_grid, Selection* se
{ {
int shop_joker_idx = selection->x - 1; // - 1 to account for next round button int shop_joker_idx = selection->x - 1; // - 1 to account for next round button
JokerObject *joker_object = list_get(shop_jokers, shop_joker_idx); JokerObject *joker_object = list_get(shop_jokers, shop_joker_idx);
if (joker_object == NULL if (joker_object == NULL || list_get_size(jokers) >= MAX_JOKERS_HELD_SIZE || money < joker_object->joker->value)
|| list_get_size(jokers) >= MAX_JOKERS_HELD_SIZE
|| money < joker_object->joker->value)
{ {
return; return;
} }
@@ -2564,8 +2603,7 @@ SelectionGridRow shop_selection_rows[] =
{ {
{0, jokers_sel_row_get_size, jokers_sel_row_on_selection_changed, jokers_sel_row_on_key_hit}, {0, jokers_sel_row_get_size, jokers_sel_row_on_selection_changed, jokers_sel_row_on_key_hit},
{1, shop_top_row_get_size, shop_top_row_on_selection_changed, shop_top_row_on_key_hit}, {1, shop_top_row_get_size, shop_top_row_on_selection_changed, shop_top_row_on_key_hit},
{2, shop_reroll_row_get_size, shop_reroll_row_on_selection_changed, shop_reroll_row_on_key_hit} {2, shop_reroll_row_get_size, shop_reroll_row_on_selection_changed, shop_reroll_row_on_key_hit}};
};
static const Selection SHOP_INIT_SEL = {-1, 1}; static const Selection SHOP_INIT_SEL = {-1, 1};
@@ -2939,8 +2977,7 @@ static void discarded_jokers_update_loop()
{ {
JokerObject *joker_object = list_get(discarded_jokers, i); JokerObject *joker_object = list_get(discarded_jokers, i);
joker_object_update(joker_object); joker_object_update(joker_object);
if (joker_object->sprite_object->x == joker_object->sprite_object->tx if (joker_object->sprite_object->x == joker_object->sprite_object->tx && joker_object->sprite_object->y == joker_object->sprite_object->ty)
&& joker_object->sprite_object->y == joker_object->sprite_object->ty)
{ {
list_remove_by_idx(discarded_jokers, i); list_remove_by_idx(discarded_jokers, i);
joker_object_destroy(&joker_object); joker_object_destroy(&joker_object);
@@ -2956,8 +2993,7 @@ static void held_jokers_update_loop()
{13, -13, 0, 0, 0}, {13, -13, 0, 0, 0},
{26, 0, -26, 0, 0}, {26, 0, -26, 0, 0},
{39, 13, -13, -39, 0}, {39, 13, -13, -39, 0},
{40, 20, 0, -20, -40} {40, 20, 0, -20, -40}};
};
FIXED hand_x = int2fx(HELD_JOKERS_POS.x); FIXED hand_x = int2fx(HELD_JOKERS_POS.x);
+11 -6
View File
@@ -1,3 +1,4 @@
#include "game.h"
#include "sprite.h" #include "sprite.h"
#include "util.h" #include "util.h"
#include "audio_utils.h" #include "audio_utils.h"
@@ -73,7 +74,8 @@ Sprite *sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, int sprite_index)
void sprite_destroy(Sprite **sprite) void sprite_destroy(Sprite **sprite)
{ {
if (*sprite == NULL) return; if (*sprite == NULL)
return;
obj_hide((*sprite)->obj); obj_hide((*sprite)->obj);
free_sprites[(*sprite)->obj - obj_buffer] = NULL; free_sprites[(*sprite)->obj - obj_buffer] = NULL;
if ((*sprite)->aff != NULL) if ((*sprite)->aff != NULL)
@@ -86,7 +88,8 @@ void sprite_destroy(Sprite **sprite)
int sprite_get_layer(Sprite *sprite) int sprite_get_layer(Sprite *sprite)
{ {
if (sprite == NULL || sprite->obj == NULL) return -1; if (sprite == NULL || sprite->obj == NULL)
return -1;
return sprite->obj - obj_buffer; return sprite->obj - obj_buffer;
} }
@@ -125,7 +128,8 @@ SpriteObject* sprite_object_new()
void sprite_object_destroy(SpriteObject **sprite_object) void sprite_object_destroy(SpriteObject **sprite_object)
{ {
if (*sprite_object == NULL) return; if (*sprite_object == NULL)
return;
sprite_destroy(&((*sprite_object)->sprite)); sprite_destroy(&((*sprite_object)->sprite));
free(*sprite_object); free(*sprite_object);
*sprite_object = NULL; *sprite_object = NULL;
@@ -157,8 +161,8 @@ void sprite_object_reset_transform(SpriteObject* sprite_object)
void sprite_object_update(SpriteObject *sprite_object) void sprite_object_update(SpriteObject *sprite_object)
{ {
sprite_object->vx += (sprite_object->tx - sprite_object->x) / 8; sprite_object->vx += (sprite_object->tx - sprite_object->x) / (8 / game_speed); // SPEED
sprite_object->vy += (sprite_object->ty - sprite_object->y) / 8; sprite_object->vy += (sprite_object->ty - sprite_object->y) / (8 / game_speed);
sprite_object->vscale += (sprite_object->tscale - sprite_object->scale) / 8; // Scale up the card when it's played sprite_object->vscale += (sprite_object->tscale - sprite_object->scale) / 8; // Scale up the card when it's played
@@ -216,7 +220,8 @@ void sprite_object_shake(SpriteObject* sprite_object, mm_word sound_id)
sprite_object->vscale = float2fx(0.3f); sprite_object->vscale = float2fx(0.3f);
sprite_object->vrotation = float2fx(8.0f); // Rotate the card when it's scored sprite_object->vrotation = float2fx(8.0f); // Rotate the card when it's scored
if (sound_id == UNDEFINED) return; // If no sound ID is provided, do nothing if (sound_id == UNDEFINED)
return; // If no sound ID is provided, do nothing
play_sfx(sound_id, MM_BASE_PITCH_RATE); play_sfx(sound_id, MM_BASE_PITCH_RATE);
} }