This commit is contained in:
expected-ingot
2025-06-30 01:03:09 +02:00
5 changed files with 373 additions and 325 deletions
+1
View File
@@ -1,2 +1,3 @@
/.vscode /.vscode
/build /build
/.vs
+3
View File
@@ -10,6 +10,7 @@
#define DIAMONDS 1 #define DIAMONDS 1
#define CLUBS 2 #define CLUBS 2
#define SPADES 3 #define SPADES 3
#define NUM_SUITS 4
// Card ranks // Card ranks
#define TWO 0 #define TWO 0
@@ -25,6 +26,8 @@
#define QUEEN 10 #define QUEEN 10
#define KING 11 #define KING 11
#define ACE 12 #define ACE 12
#define NUM_RANKS 13
#define RANK_OFFSET 2 // Because the first rank is 2 and ranks start at 0
// Card types // Card types
typedef struct typedef struct
+5
View File
@@ -6,6 +6,11 @@
#define MAX_SELECTION_SIZE 5 #define MAX_SELECTION_SIZE 5
#define FRAMES(x) (((x) + game_speed - 1) / game_speed) #define FRAMES(x) (((x) + game_speed - 1) / game_speed)
// TODO: Turn into enum?
#define BG_ID_CARD_SELECTING 1
#define BG_ID_CARD_PLAYING 2
#define BG_ID_ROUND_END 3
enum GameState enum GameState
{ {
GAME_PLAYING, GAME_PLAYING,
+1 -1
View File
@@ -44,7 +44,7 @@ u8 card_get_value(Card *card)
} }
else else
{ {
return card->rank + 2; // 2-10 are worth their rank + 2 (because rank starts at 0) return card->rank + RANK_OFFSET; // 2-10 are worth their rank + RANK_OFFSET
} }
return 0; // Should never reach here, but just in case return 0; // Should never reach here, but just in case
+119 -80
View File
@@ -97,37 +97,48 @@ static inline Card *discard_pop()
} }
// General functions // General functions
void sort_cards() void sort_hand_by_suit()
{ {
if (sort_by_suit)
{
for (int a = 0; a < hand_top; a++) for (int a = 0; a < hand_top; a++)
{ {
for (int b = a + 1; b <= hand_top; b++) for (int b = a + 1; b <= hand_top; b++)
{ {
if (hand[a] == NULL || (hand[b] != NULL && (hand[a]->card->suit > hand[b]->card->suit || (hand[a]->card->suit == hand[b]->card->suit && hand[a]->card->rank > hand[b]->card->rank)))) if (hand[a] == NULL || (hand[b] != NULL && (hand[a]->card->suit > hand[b]->card->suit || (hand[a]->card->suit == hand[b]->card->suit && hand[a]->card->rank > hand[b]->card->rank))))
{ {
CardObject *temp = hand[a]; CardObject* temp = hand[a];
hand[a] = hand[b]; hand[a] = hand[b];
hand[b] = temp; hand[b] = temp;
} }
} }
} }
} }
else
{ void sort_hand_by_rank()
{
for (int a = 0; a < hand_top; a++) for (int a = 0; a < hand_top; a++)
{ {
for (int b = a + 1; b <= hand_top; b++) for (int b = a + 1; b <= hand_top; b++)
{ {
if (hand[a] == NULL || (hand[b] != NULL && hand[a]->card->rank > hand[b]->card->rank)) if (hand[a] == NULL || (hand[b] != NULL && hand[a]->card->rank > hand[b]->card->rank))
{ {
CardObject *temp = hand[a]; CardObject* temp = hand[a];
hand[a] = hand[b]; hand[a] = hand[b];
hand[b] = temp; hand[b] = temp;
} }
} }
} }
}
void sort_cards()
{
if (sort_by_suit)
{
sort_hand_by_suit();
}
else
{
sort_hand_by_rank();
} }
// Update the sprites in the hand by destroying them and creating new ones in the correct order // Update the sprites in the hand by destroying them and creating new ones in the correct order
@@ -162,8 +173,8 @@ enum HandType hand_get_type()
hand_type = HIGH_CARD; hand_type = HIGH_CARD;
u8 suits[4] = {0}; u8 suits[NUM_SUITS] = {0};
u8 ranks[13] = {0}; u8 ranks[NUM_RANKS] = {0};
for (int i = 0; i <= hand_top; i++) for (int i = 0; i <= hand_top; i++)
{ {
@@ -175,7 +186,7 @@ enum HandType hand_get_type()
} }
// Check for flush // Check for flush
for (int i = 0; i < 4; i++) for (int i = 0; i < NUM_SUITS; i++)
{ {
if (suits[i] >= MAX_SELECTION_SIZE) // if i add jokers just MAX_SELECTION_SIZE - 1 for four fingers if (suits[i] >= MAX_SELECTION_SIZE) // if i add jokers just MAX_SELECTION_SIZE - 1 for four fingers
{ {
@@ -233,7 +244,7 @@ enum HandType hand_get_type()
} }
// Check for for of a kind // Check for for of a kind
for (int i = 0; i < 13; i++) for (int i = 0; i < NUM_RANKS; i++)
{ {
if (ranks[i] >= 4) if (ranks[i] >= 4)
{ {
@@ -280,19 +291,19 @@ void change_background(int id)
{ {
return; return;
} }
else if (id == 1) // selecting else if (id == BG_ID_CARD_SELECTING)
{ {
memcpy(&se_mem[31], background_gfxMap, background_gfxMapLen); memcpy(&se_mem[31], background_gfxMap, background_gfxMapLen);
tte_erase_rect(128, 152, 152, 160); tte_erase_rect(128, 152, 152, 160);
} }
else if (id == 2) // playing else if (id == BG_ID_CARD_PLAYING)
{ {
memcpy(&se_mem[31], background_play_gfxMap, background_play_gfxMapLen); memcpy(&se_mem[31], background_play_gfxMap, background_play_gfxMapLen);
tte_erase_rect(128, 128, 152, 136); tte_erase_rect(128, 128, 152, 136);
} }
else if (id == 3) // round end else if (id == BG_ID_ROUND_END)
{ {
REG_DISPCNT &= ~DCNT_WIN0; // Disable window 0 so it doesn't make the cashout menu transparent REG_DISPCNT &= ~DCNT_WIN0; // Disable window 0 so it doesn't make the cashout menu transparent
@@ -539,9 +550,9 @@ void deck_shuffle()
void game_init() void game_init()
{ {
// Fill the deck with all the cards. Later on this can be replaced with a more dynamic system that allows for different decks and card types. // Fill the deck with all the cards. Later on this can be replaced with a more dynamic system that allows for different decks and card types.
for (int suit = 0; suit < 4; suit++) for (int suit = 0; suit < NUM_SUITS; suit++)
{ {
for (int rank = 0; rank < 13; rank++) for (int rank = 0; rank < NUM_RANKS; rank++)
{ {
Card *card = card_new(suit, rank); Card *card = card_new(suit, rank);
deck_push(card); deck_push(card);
@@ -557,7 +568,7 @@ void game_init()
deck[j] = temp; deck[j] = temp;
} }
change_background(1); change_background(BG_ID_CARD_SELECTING);
tte_printf("#{P:128,128; cx:0xF000}%d/%d", hand_get_size(), hand_get_max_size()); // Hand size/max size tte_printf("#{P:128,128; cx:0xF000}%d/%d", hand_get_size(), hand_get_max_size()); // Hand size/max size
tte_printf("#{P:200,152; cx:0xF000}%d/%d", deck_get_size(), deck_get_max_size()); // Deck size/max size tte_printf("#{P:200,152; cx:0xF000}%d/%d", deck_get_size(), deck_get_max_size()); // Deck size/max size
@@ -579,19 +590,8 @@ void game_init()
tte_printf("#{P:8,144; cx:0xC000}%d#{cx:0xF000}/%d", 1, 8); // Ante tte_printf("#{P:8,144; cx:0xC000}%d#{cx:0xF000}/%d", 1, 8); // Ante
} }
void game_playing() static void game_playing_process_input_and_state()
{ {
// Background logic (thissss might be moved to the card'ssss logic later. I'm a sssssnake)
if (hand_state == HAND_DRAW || hand_state == HAND_DISCARD || hand_state == HAND_SELECT)
{
change_background(1);
}
else
{
change_background(2);
}
// Input and state related logic
if (hand_state == HAND_SELECT) if (hand_state == HAND_SELECT)
{ {
if (key_hit(KEY_LEFT)) if (key_hit(KEY_LEFT))
@@ -674,8 +674,10 @@ void game_playing()
tte_printf("#{P:32,48; cx:0xF000}%d", score); // Score tte_printf("#{P:32,48; cx:0xF000}%d", score); // Score
} }
} }
}
// Card logic static void game_playing_process_card_draw()
{
if (hand_state == HAND_DRAW && cards_drawn < hand_size) if (hand_state == HAND_DRAW && cards_drawn < hand_size)
{ {
if (timer % FRAMES(10) == 0) // Draw a card every 10 frames if (timer % FRAMES(10) == 0) // Draw a card every 10 frames
@@ -690,16 +692,14 @@ void game_playing()
cards_drawn = 0; cards_drawn = 0;
timer = 1; timer = 1;
} }
}
static int played_selections = 0; static void game_playing_discarded_cards_loop()
static bool sound_played = false; {
bool discarded_card = false; if (hand_get_size() == 0 && hand_state == HAND_SHUFFLING && discard_top >= -1 && timer > 10)
// Discarded cards loop (mainly for shuffling)
if (hand_get_size() == 0 && hand_state == HAND_SHUFFLING && discard_top >= -1 && timer >= FRAMES(10))
{ {
// We take each discarded card and put it back into the deck with a short animation // We take each discarded card and put it back into the deck with a short animation
static CardObject *discarded_card_object = NULL; static CardObject* discarded_card_object = NULL;
if (discarded_card_object == NULL) if (discarded_card_object == NULL)
{ {
discarded_card_object = card_object_new(discard_pop()); discarded_card_object = card_object_new(discard_pop());
@@ -728,8 +728,8 @@ void game_playing()
card_object_destroy(&discarded_card_object); card_object_destroy(&discarded_card_object);
// play draw sound // play draw sound
const int pitch_lut[MAX_HAND_SIZE] = {1024, 1048, 1072, 1096, 1120, 1144, 1168, 1192, 1216, 1240, 1264, 1288, 1312, 1336, 1360, 1384}; const int pitch_lut[MAX_HAND_SIZE] = { 1024, 1048, 1072, 1096, 1120, 1144, 1168, 1192, 1216, 1240, 1264, 1288, 1312, 1336, 1360, 1384 };
mm_sound_effect sfx_draw = {{SFX_CARD_DRAW}, pitch_lut[2], 0, 255, 128,}; mm_sound_effect sfx_draw = { {SFX_CARD_DRAW}, pitch_lut[2], 0, 255, 128, };
mmEffectEx(&sfx_draw); mmEffectEx(&sfx_draw);
} }
} }
@@ -741,13 +741,15 @@ void game_playing()
timer = 1; // Reset the timer timer = 1; // Reset the timer
} }
} }
}
// Cards in hand update loop static void cards_in_hand_update_loop(bool* discarded_card, int* played_selections, bool* sound_played)
{
for (int i = hand_top + 1; i >= 0; i--) // Start from the end of the hand and work backwards because that's how Balatro does it for (int i = hand_top + 1; i >= 0; i--) // Start from the end of the hand and work backwards because that's how Balatro does it
{ {
if (hand[i] != NULL) if (hand[i] != NULL)
{ {
const int spacing_lut[MAX_HAND_SIZE] = {28, 28, 28, 28, 27, 21, 18, 15, 13, 12, 10, 9, 9, 8, 8, 7}; // This is a stupid way to do this but I don't care const int spacing_lut[MAX_HAND_SIZE] = { 28, 28, 28, 28, 27, 21, 18, 15, 13, 12, 10, 9, 9, 8, 8, 7 }; // This is a stupid way to do this but I don't care
FIXED hand_x = int2fx(120); FIXED hand_x = int2fx(120);
FIXED hand_y = int2fx(90); FIXED hand_y = int2fx(90);
@@ -784,17 +786,17 @@ void game_playing()
case HAND_DISCARD: // TODO: Add sound case HAND_DISCARD: // TODO: Add sound
if (hand[i]->selected || hand_state == HAND_SHUFFLING) if (hand[i]->selected || hand_state == HAND_SHUFFLING)
{ {
if (!discarded_card) if (!*discarded_card)
{ {
hand_x = int2fx(240); hand_x = int2fx(240);
hand_y = int2fx(70); hand_y = int2fx(70);
if (!sound_played) if (!*sound_played)
{ {
const int pitch_lut[MAX_SELECTION_SIZE] = {1024, 960, 896, 832, 768}; const int pitch_lut[MAX_SELECTION_SIZE] = { 1024, 960, 896, 832, 768 };
mm_sound_effect sfx_draw = {{SFX_CARD_DRAW}, pitch_lut[cards_drawn], 0, 255, 128,}; mm_sound_effect sfx_draw = { {SFX_CARD_DRAW}, pitch_lut[cards_drawn], 0, 255, 128, };
mmEffectEx(&sfx_draw); mmEffectEx(&sfx_draw);
sound_played = true; *sound_played = true;
} }
if (hand[i]->x >= hand_x) if (hand[i]->x >= hand_x)
@@ -805,14 +807,14 @@ void game_playing()
hand_top--; hand_top--;
cards_drawn++; // This technically isn't drawing cards, I'm just reusing the variable cards_drawn++; // This technically isn't drawing cards, I'm just reusing the variable
sound_played = false; *sound_played = false;
timer = 1; timer = 1;
hand_y = hand[i]->y; hand_y = hand[i]->y;
hand_x = hand[i]->x; hand_x = hand[i]->x;
} }
discarded_card = true; *discarded_card = true;
} }
else else
{ {
@@ -832,10 +834,10 @@ void game_playing()
hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top]; hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top];
} }
if (i == 0 && discarded_card == false && timer % FRAMES(10) == 0) if (i == 0 && *discarded_card == false && timer % 10 == 0)
{ {
hand_state = HAND_DRAW; hand_state = HAND_DRAW;
sound_played = false; *sound_played = false;
cards_drawn = 0; cards_drawn = 0;
hand_selections = 0; hand_selections = 0;
timer = 1; timer = 1;
@@ -847,7 +849,7 @@ void game_playing()
hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top]; hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top];
hand_y += (24 << FIX_SHIFT); hand_y += (24 << FIX_SHIFT);
if (hand[i]->selected && timer % FRAMES(10) == 0) if (hand[i]->selected && timer % 10 == 0)
{ {
hand[i]->selected = false; hand[i]->selected = false;
played_push(hand[i]); played_push(hand[i]);
@@ -855,8 +857,8 @@ void game_playing()
hand[i] = NULL; hand[i] = NULL;
sort_cards(); sort_cards();
const int pitch_lut[MAX_SELECTION_SIZE] = {1024, 960, 896, 832, 768}; const int pitch_lut[MAX_SELECTION_SIZE] = { 1024, 960, 896, 832, 768 };
mm_sound_effect sfx_draw = {{SFX_CARD_DRAW}, pitch_lut[cards_drawn], 0, 255, 128,}; mm_sound_effect sfx_draw = { {SFX_CARD_DRAW}, pitch_lut[cards_drawn], 0, 255, 128, };
mmEffectEx(&sfx_draw); mmEffectEx(&sfx_draw);
hand_top--; hand_top--;
@@ -866,13 +868,13 @@ void game_playing()
timer = 1; timer = 1;
} }
if (i == 0 && timer % FRAMES(10) == 0) if (i == 0 && timer % 10 == 0)
{ {
hand_state = HAND_PLAYING; hand_state = HAND_PLAYING;
cards_drawn = 0; cards_drawn = 0;
hand_selections = 0; hand_selections = 0;
timer = 1; timer = 1;
played_selections = played_top + 1; *played_selections = played_top + 1;
switch (hand_type) // select the cards that apply to the hand type switch (hand_type) // select the cards that apply to the hand type
{ {
@@ -1030,9 +1032,13 @@ void game_playing()
card_object_update(hand[i]); card_object_update(hand[i]);
} }
} }
}
// Played cards update loop static void played_cards_update_loop(bool* discarded_card, int* played_selections, bool* sound_played)
for (int i = 0; i <= played_top; i++) // So this one is a bit fucking weird because I have to work kinda backwards for everything because of the order of the pushed cards from the hand to the play stack (also crazy that the company that published Balatro is called "Playstack" and this is a play stack, but I digress) {
// So this one is a bit fucking weird because I have to work kinda backwards for everything because of the order of the pushed cards from the hand to the play stack
// (also crazy that the company that published Balatro is called "Playstack" and this is a play stack, but I digress)
for (int i = 0; i <= played_top; i++)
{ {
if (played[i] != NULL) if (played[i] != NULL)
{ {
@@ -1051,18 +1057,18 @@ void game_playing()
switch (play_state) switch (play_state)
{ {
case PLAY_PLAYING: case PLAY_PLAYING:
if (i == 0 && (timer % FRAMES(10) == 0 || played[played_top - played_selections]->selected == false) && timer > FRAMES(40)) if (i == 0 && (timer % 10 == 0 || played[played_top - *played_selections]->selected == false) && timer > 40)
{ {
played_selections--; (*played_selections)--;
if (played_selections == 0) if (*played_selections == 0)
{ {
play_state = PLAY_SCORING; play_state = PLAY_SCORING;
timer = 1; timer = 1;
} }
} }
if (played[i]->selected && played_top - i >= played_selections) if (played[i]->selected && played_top - i >= *played_selections)
{ {
played_y -= (10 << FIX_SHIFT); played_y -= (10 << FIX_SHIFT);
} }
@@ -1077,7 +1083,7 @@ void game_playing()
if (played[played_top - j]->selected) if (played[played_top - j]->selected)
{ {
scored_cards++; scored_cards++;
if (scored_cards > played_selections) if (scored_cards > *played_selections)
{ {
tte_erase_rect(72, 48, 240, 56); tte_erase_rect(72, 48, 240, 56);
tte_set_pos(fx2int(played[played_top - j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card tte_set_pos(fx2int(played[played_top - j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card
@@ -1088,7 +1094,7 @@ void game_playing()
snprintf(score_buffer, sizeof(score_buffer), "+%d", card_get_value(played[played_top - j]->card)); snprintf(score_buffer, sizeof(score_buffer), "+%d", card_get_value(played[played_top - j]->card));
tte_write(score_buffer); tte_write(score_buffer);
played_selections = scored_cards; *played_selections = scored_cards;
//played[j]->vy += (3 << FIX_SHIFT); //played[j]->vy += (3 << FIX_SHIFT);
played[played_top - j]->vscale = float2fx(0.3f); // Scale down the card when it's scored played[played_top - j]->vscale = float2fx(0.3f); // Scale down the card when it's scored
played[played_top - j]->vrotation = float2fx(8.0f); // Rotate the card when it's scored played[played_top - j]->vrotation = float2fx(8.0f); // Rotate the card when it's scored
@@ -1103,12 +1109,12 @@ void game_playing()
} }
} }
if (j == 0 && scored_cards == played_selections) // Check if it's the last card if (j == 0 && scored_cards == *played_selections) // Check if it's the last card
{ {
tte_erase_rect(72, 48, 240, 56); tte_erase_rect(72, 48, 240, 56);
play_state = PLAY_ENDING; play_state = PLAY_ENDING;
timer = 1; timer = 1;
played_selections = played_top + 1; // Reset the played selections to the top of the played stack *played_selections = played_top + 1; // Reset the played selections to the top of the played stack
break; break;
} }
} }
@@ -1120,34 +1126,34 @@ void game_playing()
} }
break; break;
case PLAY_ENDING: // This is the reverse of PLAY_PLAYING. The cards get reset back to their neutral position sequentially case PLAY_ENDING: // This is the reverse of PLAY_PLAYING. The cards get reset back to their neutral position sequentially
if (i == 0 && (timer % FRAMES(10) == 0 || played[played_top - played_selections]->selected == false) && timer > FRAMES(40)) if (i == 0 && (timer % 10 == 0 || played[played_top - *played_selections]->selected == false) && timer > 40)
{ {
played_selections--; (*played_selections)--;
if (played_selections == 0) if (*played_selections == 0)
{ {
play_state = PLAY_ENDED; play_state = PLAY_ENDED;
timer = 1; timer = 1;
} }
} }
if (played[i]->selected && played_top - i <= played_selections - 1) if (played[i]->selected && played_top - i <= *played_selections - 1)
{ {
played_y -= (10 << FIX_SHIFT); played_y -= (10 << FIX_SHIFT);
} }
break; break;
case PLAY_ENDED: // Basically a copy of HAND_DISCARD case PLAY_ENDED: // Basically a copy of HAND_DISCARD
if (!discarded_card && played[i] != NULL && timer > FRAMES(40)) if (!*discarded_card && played[i] != NULL && timer > 40)
{ {
played_x = int2fx(240); played_x = int2fx(240);
played_y = int2fx(70); played_y = int2fx(70);
if (!sound_played) if (!*sound_played)
{ {
const int pitch_lut[MAX_SELECTION_SIZE] = {1024, 960, 896, 832, 768}; const int pitch_lut[MAX_SELECTION_SIZE] = {1024, 960, 896, 832, 768};
mm_sound_effect sfx_draw = {{SFX_CARD_DRAW}, pitch_lut[cards_drawn], 0, 255, 128,}; mm_sound_effect sfx_draw = {{SFX_CARD_DRAW}, pitch_lut[cards_drawn], 0, 255, 128,};
mmEffectEx(&sfx_draw); mmEffectEx(&sfx_draw);
sound_played = true; *sound_played = true;
} }
if (played[i]->x >= played_x) if (played[i]->x >= played_x)
@@ -1157,7 +1163,7 @@ void game_playing()
//played_top--; //played_top--;
cards_drawn++; // This technically isn't drawing cards, I'm just reusing the variable cards_drawn++; // This technically isn't drawing cards, I'm just reusing the variable
sound_played = false; *sound_played = false;
if (i == played_top) if (i == played_top)
{ {
@@ -1173,14 +1179,14 @@ void game_playing()
play_state = PLAY_PLAYING; play_state = PLAY_PLAYING;
cards_drawn = 0; cards_drawn = 0;
hand_selections = 0; hand_selections = 0;
played_selections = 0; *played_selections = 0;
played_top = -1; // Reset the played stack played_top = -1; // Reset the played stack
timer = 1; timer = 1;
break; // Break out of the loop to avoid accessing an invalid index break; // Break out of the loop to avoid accessing an invalid index
} }
} }
discarded_card = true; *discarded_card = true;
} }
break; break;
@@ -1192,18 +1198,20 @@ void game_playing()
card_object_update(played[i]); card_object_update(played[i]);
} }
} }
}
// UI Text update static void game_playing_ui_text_update()
{
static int last_hand_size = 0; static int last_hand_size = 0;
static int last_deck_size = 0; static int last_deck_size = 0;
if (last_hand_size != hand_get_size() || last_deck_size != deck_get_size()) if (last_hand_size != hand_get_size() || last_deck_size != deck_get_size())
{ {
if (background == 1) if (background == BG_ID_CARD_SELECTING)
{ {
tte_printf("#{P:128,128; cx:0xF000}%d/%d", hand_get_size(), hand_get_max_size()); // Hand size/max size tte_printf("#{P:128,128; cx:0xF000}%d/%d", hand_get_size(), hand_get_max_size()); // Hand size/max size
} }
else if (background == 2) else if (background == BG_ID_CARD_PLAYING)
{ {
tte_printf("#{P:128,152; cx:0xF000}%d/%d", hand_get_size(), hand_get_max_size()); // Hand size/max size tte_printf("#{P:128,152; cx:0xF000}%d/%d", hand_get_size(), hand_get_max_size()); // Hand size/max size
} }
@@ -1215,13 +1223,44 @@ void game_playing()
} }
} }
void game_playing()
{
// Background logic (thissss might be moved to the card'ssss logic later. I'm a sssssnake)
if (hand_state == HAND_DRAW || hand_state == HAND_DISCARD || hand_state == HAND_SELECT)
{
change_background(BG_ID_CARD_SELECTING);
}
else
{
change_background(BG_ID_CARD_PLAYING);
}
game_playing_process_input_and_state();
// Card logic
game_playing_process_card_draw();
// Discarded cards loop (mainly for shuffling)
game_playing_discarded_cards_loop();
static int played_selections = 0;
static bool sound_played = false;
bool discarded_card = false;
cards_in_hand_update_loop(&discarded_card, &played_selections, &sound_played);
played_cards_update_loop(&discarded_card, &played_selections, &sound_played);
game_playing_ui_text_update();
}
void game_round_end() void game_round_end()
{ {
const int timer_delay = FRAMES(30); // 30 frames = 500ms const int timer_delay = FRAMES(30); // 30 frames = 500ms
if (timer > timer_delay) if (timer > timer_delay)
{ {
change_background(3); // Change to the round end background change_background(BG_ID_ROUND_END);
int timer_offset = (timer - timer_delay); // Offset the timer to start at 0 int timer_offset = (timer - timer_delay); // Offset the timer to start at 0
if (timer_offset <= 12) if (timer_offset <= 12)