From 71d41d7f62d30fc243cda16602441d52774edb24 Mon Sep 17 00:00:00 2001 From: MeirGavish Date: Tue, 22 Jul 2025 16:30:48 +0300 Subject: [PATCH 1/9] Switched all the code in graphic_utils.c to use se_mat instead of se_mem, it's beautiful --- source/graphic_utils.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/graphic_utils.c b/source/graphic_utils.c index 884d26b..aa7f45b 100644 --- a/source/graphic_utils.c +++ b/source/graphic_utils.c @@ -26,7 +26,7 @@ static void clip_se_rect_to_screenblock(Rect* rect) u16 main_bg_se_get_tile(BG_POINT pos) { - return se_mem[MAIN_BG_SBB][pos.x + SE_ROW_LEN * pos.y]; + return se_mat[MAIN_BG_SBB][pos.y][pos.x]; } // Clips a rect of screenblock entries to be within one step of @@ -55,7 +55,7 @@ void main_bg_se_clear_rect(Rect se_rect) for (int y = se_rect.top; y < se_rect.bottom; y++) { - memset16(&(se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y]), 0x0000, rect_width(&se_rect)); + memset16(&(se_mat[MAIN_BG_SBB][y][se_rect.left]), 0x0000, rect_width(&se_rect)); } } @@ -77,14 +77,14 @@ static void main_bg_se_copy_or_move_rect_1_tile_vert(Rect se_rect, int direction for (int y = start; y != end - direction; y -= direction) { - memcpy16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (y + direction)], - &se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y], + memcpy16(&(se_mat[MAIN_BG_SBB][y + direction][se_rect.left]), + &se_mat[MAIN_BG_SBB][y][se_rect.left], rect_width(&se_rect)); } if (move) { - memset16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (end)], 0x0000, rect_width(&se_rect)); + memset16(&se_mat[MAIN_BG_SBB][end][se_rect.left], 0x0000, rect_width(&se_rect)); } } @@ -124,7 +124,7 @@ void main_bg_se_copy_rect(Rect se_rect, BG_POINT pos) for (int sy = 0; sy < height; sy++) { - memcpy16(&se_mem[MAIN_BG_SBB][pos.x + SE_ROW_LEN * (pos.y + sy)], + memcpy16(&se_mat[MAIN_BG_SBB][pos.y + sy][pos.x], &tile_map[sy][0], width); } @@ -143,7 +143,7 @@ void main_bg_se_copy_tile_to_rect(u16 tile, Rect se_rect) for (int sy = 0; sy < height; sy++) { - memset16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (se_rect.top + sy)], tile, width); + memset16(&se_mat[MAIN_BG_SBB][se_rect.top + sy][se_rect.left], tile, width); } } From 793da72465f7f4831e226cdc0332ee7fc9b48ca7 Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 15:45:29 -0400 Subject: [PATCH 2/9] added co-pilot's fixes --- include/joker.h | 2 +- source/game.c | 11 +++++------ source/joker.c | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/joker.h b/include/joker.h index e791792..3ae1906 100644 --- a/include/joker.h +++ b/include/joker.h @@ -36,7 +36,7 @@ typedef struct u8 modifier; // base, foil, holo, poly, negative u8 value; u8 rarity; - bool proccessed; + bool processed; } Joker; typedef struct // copy of CardObject in card.h diff --git a/source/game.c b/source/game.c index c247a47..1c7c0be 100644 --- a/source/game.c +++ b/source/game.c @@ -30,6 +30,7 @@ static int background = 0; static enum GameState game_state = GAME_BLIND_SELECT; // The current game state, this is used to determine what the game is doing at any given time static enum HandState hand_state = HAND_DRAW; static enum PlayState play_state = PLAY_PLAYING; +static int state = 0; // General state variable, used for switch statements in each game state related function static enum HandType hand_type = NONE; @@ -480,7 +481,7 @@ void change_background(int id) } else if (id == BG_ID_ROUND_END) { - if (background != BG_ID_CARD_SELECTING || background != BG_ID_CARD_PLAYING) + if (background != BG_ID_CARD_SELECTING && background != BG_ID_CARD_PLAYING) { change_background(BG_ID_CARD_SELECTING); background = BG_ID_ROUND_END; @@ -1579,7 +1580,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection for (int k = 0; k <= jokers_top; k++) { - if (jokers[k]->joker->proccessed == false) + if (jokers[k]->joker->processed == false) { IndependentEffect joker_effect = joker_independent_effect(jokers[k]->joker); IndependentEffect zero_effect = {0}; @@ -1618,7 +1619,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection tte_write(score_buffer); - jokers[k]->joker->proccessed = true; // Mark the joker as processed + jokers[k]->joker->processed = true; // Mark the joker as processed joker_object_score(jokers[k], SFX_CARD_SELECT); return; // Returning was just the easiest way to break out of the loop @@ -1630,7 +1631,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection { if (jokers[k] != NULL) { - jokers[k]->joker->proccessed = false; // Reset the joker's processed state for the next round + jokers[k]->joker->processed = false; // Reset the joker's processed state for the next round } } @@ -1871,8 +1872,6 @@ void game_round_end_cleanup() void game_round_end() { - static int state = 0; - static int blind_reward = 0; static int hand_reward = 0; static int interest_reward = 0; diff --git a/source/joker.c b/source/joker.c index a056ea8..888721a 100644 --- a/source/joker.c +++ b/source/joker.c @@ -46,7 +46,7 @@ Joker *joker_new(u8 id) joker->modifier = BASE_EDITION; // TODO: Make this random later joker->value = joker_data_lut[id][1] + edition_price_lut[joker->modifier]; // Base value + edition price joker->rarity = joker_data_lut[id][0]; - joker->proccessed = false; + joker->processed = false; return joker; } From b583755985eb69e1be61cc0bc25bae3261877e1d Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 15:53:49 -0400 Subject: [PATCH 3/9] Refactored background change logic and removed unused static state variables in game functions --- source/game.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/source/game.c b/source/game.c index 1c7c0be..7ecf45d 100644 --- a/source/game.c +++ b/source/game.c @@ -423,12 +423,13 @@ void change_background(int id) } else if (id == BG_ID_CARD_SELECTING) { + tte_erase_rect_wrapper(HAND_SIZE_RECT_PLAYING); + REG_WIN0V = (REG_WIN0V << 8) | 0x80; // Set window 0 top to 128 + if (background == BG_ID_CARD_PLAYING) { int offset = 11; memcpy16(&se_mem[MAIN_BG_SBB][SE_ROW_LEN * offset], &background_gfxMap[SE_ROW_LEN * offset], SE_ROW_LEN * 8); - tte_erase_rect_wrapper(HAND_SIZE_RECT_PLAYING); - REG_WIN0V = (REG_WIN0V << 8) | 0x80; } else { @@ -439,8 +440,6 @@ void change_background(int id) GRIT_CPY(&tile8_mem[MAIN_BG_CBB], background_gfxTiles); // Deadass i have no clue how any of these memory things work but I just messed with them until stuff worked GRIT_CPY(&se_mem[MAIN_BG_SBB], background_gfxMap); - tte_erase_rect_wrapper(HAND_SIZE_RECT_PLAYING); - if (current_blind == BIG_BLIND) // Change text and palette depending on blind type { main_bg_se_copy_rect(BIG_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT); @@ -470,7 +469,7 @@ void change_background(int id) background = BG_ID_CARD_PLAYING; } - REG_WIN0V = (REG_WIN0V << 8) | 0xA0; + REG_WIN0V = (REG_WIN0V << 8) | 0xA0; // Set window 0 bottom to 160 for (int i = 0; i <= 2; i++) { @@ -2126,9 +2125,6 @@ void game_round_end() void game_shop() { change_background(BG_ID_SHOP); - - // TODO: Later move these static variables somewhere else so they can be reused for each game state - static int state = 0; static JokerObject *shop_jokers[MAX_SHOP_JOKERS] = {NULL}; @@ -2391,8 +2387,6 @@ void game_shop() void game_blind_select() { - static int state = 0; - static bool top_row = true; // There's only one row in this game state, but this is here for consistency with the shop state if we make these variables global or something switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer From c48ddee5c45b5bbb880f625c3cbe8c492ab150c9 Mon Sep 17 00:00:00 2001 From: MeirGavish Date: Wed, 23 Jul 2025 00:32:31 +0300 Subject: [PATCH 4/9] Fixed a bug in text overflow case for update_text_rect_to_right_align_num() --- source/graphic_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/graphic_utils.c b/source/graphic_utils.c index aa7f45b..5311711 100644 --- a/source/graphic_utils.c +++ b/source/graphic_utils.c @@ -155,11 +155,11 @@ void tte_erase_rect_wrapper(Rect rect) void update_text_rect_to_right_align_num(Rect* rect, int num, int overflow_direction) { int num_digits = get_digits(num); - if (overflow_direction == OVERFLOW_RIGHT) + if (overflow_direction == OVERFLOW_LEFT) { rect->left = max(0, rect->right - num_digits * TILE_SIZE); } - else if (overflow_direction == OVERFLOW_LEFT) + else if (overflow_direction == OVERFLOW_RIGHT) { int num_fitting_digits = rect_width(rect) / TILE_SIZE; if (num_digits < num_fitting_digits) From c536d78976068963ce9e9596fd16207aa619eaae Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 17:35:52 -0400 Subject: [PATCH 5/9] Minor refactor to avoid the use of variable --- source/game.c | 74 +++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/source/game.c b/source/game.c index 7ecf45d..b881fdf 100644 --- a/source/game.c +++ b/source/game.c @@ -65,7 +65,6 @@ static int cards_drawn = 0; static int hand_selections = 0; static int card_focused = 0; -static int previous_card_focused = 0; static int selection_y = 0; static bool sort_by_suit = false; @@ -1007,6 +1006,8 @@ static void game_playing_process_input_and_state() { if (hand_state == HAND_SELECT) { + static bool discard_button_highlighted = false; // true = play button highlighted, false = discard button highlighted + if (key_hit(KEY_LEFT)) { if (selection_y == 0) @@ -1015,7 +1016,7 @@ static void game_playing_process_input_and_state() } else { - card_focused = -2; // Play button + discard_button_highlighted = false; // Play button } } else if (key_hit(KEY_RIGHT)) @@ -1026,61 +1027,62 @@ static void game_playing_process_input_and_state() } else { - card_focused = -3; // Discard button + discard_button_highlighted = true; // Discard button } } else if (key_hit(KEY_UP) && selection_y != 0) { selection_y = 0; - card_focused = previous_card_focused; } else if (key_hit(KEY_DOWN) && selection_y != 1) { selection_y = 1; - previous_card_focused = card_focused; if (card_focused > hand_top / 2) { - card_focused = -2; // Play button + discard_button_highlighted = false; // Play button } else { - card_focused = -3; // Discard button + discard_button_highlighted = true; // Discard button } } - if (card_focused == -2) // Play button logic + if (selection_y == 1) // On row of play/discard buttons { - memset16(&pal_bg_mem[1], 0xFFFF, 1); - memcpy16(&pal_bg_mem[9], &pal_bg_mem[12], 1); - - if (key_hit(SELECT_CARD) && hands > 0 && hand_play()) + if (discard_button_highlighted == false) // Play button logic { - hand_state = HAND_PLAY; - card_focused = 0; - selection_y = 0; - previous_card_focused = 0; - set_hands(--hands); + memset16(&pal_bg_mem[1], 0xFFFF, 1); + memcpy16(&pal_bg_mem[9], &pal_bg_mem[12], 1); + + if (key_hit(SELECT_CARD) && hands > 0 && hand_play()) + { + hand_state = HAND_PLAY; + card_focused = 0; + selection_y = 0; + previous_card_focused = 0; + set_hands(--hands); + } } - } - else if (card_focused == -3) // Discard button logic - { - memcpy16(&pal_bg_mem[1], &pal_bg_mem[7], 1); - memset16(&pal_bg_mem[9], 0xFFFF, 1); - - if (key_hit(SELECT_CARD) && discards > 0 && hand_discard()) + else // Discard button logic { - hand_state = HAND_DISCARD; - card_focused = 0; - selection_y = 0; - previous_card_focused = 0; - set_hands(--discards); - set_hand(); - tte_printf("#{P:%d,%d; cx:0xE000}%d", DISCARDS_TEXT_RECT.left, DISCARDS_TEXT_RECT.top, discards); + memcpy16(&pal_bg_mem[1], &pal_bg_mem[7], 1); + memset16(&pal_bg_mem[9], 0xFFFF, 1); + + if (key_hit(SELECT_CARD) && discards > 0 && hand_discard()) + { + hand_state = HAND_DISCARD; + card_focused = 0; + selection_y = 0; + previous_card_focused = 0; + set_hands(--discards); + set_hand(); + tte_printf("#{P:%d,%d; cx:0xE000}%d", DISCARDS_TEXT_RECT.left, DISCARDS_TEXT_RECT.top, discards); + } } } - if (card_focused >= 0) + if (selection_y == 0) // On row of cards { memcpy16(&pal_bg_mem[1], &pal_bg_mem[7], 1); // Play button highlight color memcpy16(&pal_bg_mem[9], &pal_bg_mem[12], 1); // Discard button highlight color @@ -1229,15 +1231,17 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top]; break; case HAND_SELECT: - if (i == card_focused && !hand[i]->selected) + bool is_focused = (i == card_focused && selection_y == 0); + + if (is_focused && !hand[i]->selected) { hand_y -= int2fx(10); } - else if (i != card_focused && hand[i]->selected) + else if (!is_focused && hand[i]->selected) { hand_y -= int2fx(15); } - else if (i == card_focused && hand[i]->selected) + else if (is_focused && hand[i]->selected) { hand_y -= int2fx(20); } From e51e08322fb4f16f1b5703fd6e402d6f5c7cc56e Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 17:39:33 -0400 Subject: [PATCH 6/9] Fixed compilation error and removed another static variable --- source/game.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/source/game.c b/source/game.c index b881fdf..6e2b5dd 100644 --- a/source/game.c +++ b/source/game.c @@ -64,7 +64,7 @@ static int hand_size = 8; // Default hand size is 8 static int cards_drawn = 0; static int hand_selections = 0; -static int card_focused = 0; +static int selection_x = 0; static int selection_y = 0; static bool sort_by_suit = false; @@ -805,7 +805,7 @@ void card_draw() void hand_set_focus(int index) { if (index < 0 || index > hand_top || hand_state != HAND_SELECT) return; - card_focused = index; + selection_x = index; mm_sound_effect sfx_focus = {{SFX_CARD_FOCUS}, 1024 + rand() % 512, 0, 255, 128,}; mmEffectEx(&sfx_focus); @@ -813,11 +813,11 @@ void hand_set_focus(int index) void hand_select() { - if (hand_state != HAND_SELECT || hand[card_focused] == NULL) return; + if (hand_state != HAND_SELECT || hand[selection_x] == NULL) return; - if (hand[card_focused]->selected) + if (hand[selection_x]->selected) { - hand[card_focused]->selected = false; + hand[selection_x]->selected = false; hand_selections--; mm_sound_effect sfx_select = {{SFX_CARD_SELECT}, 1024, 0, 255, 128,}; @@ -825,7 +825,7 @@ void hand_select() } else if (hand_selections < MAX_SELECTION_SIZE) { - hand[card_focused]->selected = true; + hand[selection_x]->selected = true; hand_selections++; mm_sound_effect sfx_deselect = {{SFX_CARD_DESELECT}, 1024, 0, 255, 128,}; @@ -1012,7 +1012,7 @@ static void game_playing_process_input_and_state() { if (selection_y == 0) { - hand_set_focus(card_focused + 1); // The reason why this adds 1 is because the hand is drawn from right to left. There is no particular reason for this, it's just how I did it. + hand_set_focus(selection_x + 1); // The reason why this adds 1 is because the hand is drawn from right to left. There is no particular reason for this, it's just how I did it. } else { @@ -1023,7 +1023,7 @@ static void game_playing_process_input_and_state() { if (selection_y == 0) { - hand_set_focus(card_focused - 1); + hand_set_focus(selection_x - 1); } else { @@ -1038,7 +1038,7 @@ static void game_playing_process_input_and_state() { selection_y = 1; - if (card_focused > hand_top / 2) + if (selection_x > hand_top / 2) { discard_button_highlighted = false; // Play button } @@ -1058,9 +1058,8 @@ static void game_playing_process_input_and_state() if (key_hit(SELECT_CARD) && hands > 0 && hand_play()) { hand_state = HAND_PLAY; - card_focused = 0; + selection_x = 0; selection_y = 0; - previous_card_focused = 0; set_hands(--hands); } } @@ -1072,9 +1071,8 @@ static void game_playing_process_input_and_state() if (key_hit(SELECT_CARD) && discards > 0 && hand_discard()) { hand_state = HAND_DISCARD; - card_focused = 0; + selection_x = 0; selection_y = 0; - previous_card_focused = 0; set_hands(--discards); set_hand(); tte_printf("#{P:%d,%d; cx:0xE000}%d", DISCARDS_TEXT_RECT.left, DISCARDS_TEXT_RECT.top, discards); @@ -1231,7 +1229,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top]; break; case HAND_SELECT: - bool is_focused = (i == card_focused && selection_y == 0); + bool is_focused = (i == selection_x && selection_y == 0); if (is_focused && !hand[i]->selected) { @@ -1246,7 +1244,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio hand_y -= int2fx(20); } - if (i != card_focused && hand[i]->y > hand_y) + if (i != selection_x && hand[i]->y > hand_y) { hand[i]->y = hand_y; hand[i]->vy = 0; @@ -2145,7 +2143,6 @@ void game_shop() // these are for controlling the shop menu static bool top_row = true; - static ushort selection_x = 0; // temp variables for future implementation const ushort max_items_top = MAX_SHOP_JOKERS; From 62db2815dd720dcf468a5286ce61bd61a5105887 Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 17:43:52 -0400 Subject: [PATCH 7/9] removed another static variable and improved boss blind selection --- source/game.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/game.c b/source/game.c index 6e2b5dd..72d0045 100644 --- a/source/game.c +++ b/source/game.c @@ -2141,9 +2141,6 @@ void game_shop() const int reroll_base_cost = 5; // Base cost for rerolling the shop items static int reroll_cost = reroll_base_cost; - // these are for controlling the shop menu - static bool top_row = true; - // temp variables for future implementation const ushort max_items_top = MAX_SHOP_JOKERS; const ushort max_items_bottom = 0; @@ -2217,7 +2214,7 @@ void game_shop() // Shop input logic if (key_hit(KEY_UP)) { - top_row = true; + selection_y = 0; if (selection_x > max_items_top) { @@ -2226,7 +2223,7 @@ void game_shop() } else if (key_hit(KEY_DOWN)) { - top_row = false; + selection_y = 1; if (selection_x > max_items_bottom) { @@ -2242,11 +2239,11 @@ void game_shop() } else if (key_hit(KEY_RIGHT)) { - if (top_row && selection_x < max_items_top) + if (selection_y == 0 && selection_x < max_items_top) { selection_x++; } - else if (!top_row && selection_x < max_items_bottom) + else if (selection_y == 1 && selection_x < max_items_bottom) { selection_x++; } @@ -2256,7 +2253,7 @@ void game_shop() memcpy16(&pal_bg_mem[5], &pal_bg_mem[16], 1); // Shop selection logic - if (selection_x == 0 && top_row) + if (selection_x == 0 && selection_y == 0) { memset16(&pal_bg_mem[5], 0xFFFF, 1); @@ -2274,7 +2271,7 @@ void game_shop() // And I don't care enough to fix it right now. } } - else if (selection_x == 0 && !top_row) + else if (selection_x == 0 && selection_y == 1) { memset16(&pal_bg_mem[7], 0xFFFF, 1); @@ -2294,7 +2291,7 @@ void game_shop() { if (shop_jokers[i] != NULL) { - if (i == selection_x - 1 && top_row) + if (i == selection_x - 1 && selection_y == 0) { shop_jokers[i]->ty = int2fx(61); @@ -2372,7 +2369,7 @@ void game_shop() reroll_cost = reroll_base_cost; selection_x = 0; // Reset the selection - top_row = true; // Reset the top row selection + selection_y = 0; // Reset the selection for (int i = 0; i < MAX_SHOP_JOKERS; i++) { @@ -2388,8 +2385,6 @@ void game_shop() void game_blind_select() { - static bool top_row = true; // There's only one row in this game state, but this is here for consistency with the shop state if we make these variables global or something - switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer { case 0: // Intro sequence (menu coming into frame) @@ -2412,18 +2407,23 @@ void game_blind_select() } case 1: // Blind select input and selection { + if (timer == 1 && current_blind == BOSS_BLIND) + { + selection_y = 0; + } + // Blind select input logic if (key_hit(KEY_UP)) { - top_row = true; + selection_y = 0; } - else if (key_hit(KEY_DOWN)) + else if (key_hit(KEY_DOWN) && current_blind != BOSS_BLIND) { - top_row = false; + selection_y = 1; } else if (key_hit(SELECT_CARD)) { - if (top_row) // Blind selected + if (selection_y == 0) // Blind selected { state++; timer = 0; @@ -2451,7 +2451,7 @@ void game_blind_select() } } - if (top_row) + if (selection_y == 0) { memset16(&pal_bg_mem[18], 0xFFFF, 1); memcpy16(&pal_bg_mem[10], &pal_bg_mem[5], 1); @@ -2540,7 +2540,7 @@ void game_blind_select() default: state = 0; timer = 0; - top_row = true; + selection_y = 0; background = UNDEFINED; game_set_state(GAME_PLAYING); break; From 1b4267893d2146bd02d79eba19935b284c3b1075 Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 20:00:05 -0400 Subject: [PATCH 8/9] Added greedy joker and refactor joker system --- graphics/joker_gfx.png | Bin 864 -> 1551 bytes include/card.h | 6 +-- include/joker.h | 17 ++----- source/card.c | 2 +- source/game.c | 100 +++++++++++++++++++---------------------- source/joker.c | 61 ++++++++++++++++++++++--- 6 files changed, 109 insertions(+), 77 deletions(-) diff --git a/graphics/joker_gfx.png b/graphics/joker_gfx.png index 8933e0a41671eafa9adced3be5075d669f2392a2..3fa9161ca241e5257bf1a27916b5f21ac96b7d77 100644 GIT binary patch delta 1459 zcmV;k1x)(j29FFOiBL{Q4GJ0x0000DNk~Le0000$0000W2nGNE0HU3Kgpnaq2><{9 z008+zyMK{dHY5V9F`GebV$yfM z*sE3@xqbRLjGR(pL=5h~U?f= z=#J*P%>`7~dAV?97`LCk!b!D+lWGaKpT5F{E5l80Po&u;!j@%F*L6rz;{dhu>wg3E zj*S2SDD7x`C?r#Wt^<s%<@d1TlI`>q1!75(|aZ!G5d zBq%Q|Gne;!n729$Vf?RezIN0QF*id9{L=M4X7|~b#=2iS++pK*zAW4c?k8S4Ylzr^zdv*l z_lGW`Z>0lE?|QNHt`~hP9ZU}Z&y~BL%b&;-c2_{JK)fFM4d)Noi^yU z9#1k|yUqeRrG$9Cj2jyP0DoZL@q8KaeA%G8u@OK#Uv_*JaO?rJngohpVInDJ(s}g& zzJ#6a=*~#ktDbqo;QkB5^Nr?5JdZj_jm=M5&>Zo+58#2&xR}kLR;#fwwZz)B3*-|Q zfv4S_x${HYUTTui4$?_Ss3ifq1tGew8=9tOz#7*&^Gkwx1w|{%?|k`ry)wJ&uL@Wd zZAp?0TVzp3nZm$tE^yQT=k?T6BocgYg}sWGaIk7@dePJSh5v;BFYgE3yce+3^WPtx z0CM}-#H4Ey{J1?I`~0_64)~;Bj#?dQz38{DJ`vtuvU`Yj%cuBy{9lTM&KP~}v_k*@ N002ovPDHLkV1hc9vPu8| delta 767 zcmVP_XRne!$k7wa&woY|Wz*pL{vJ5zaJxOF3x5A9 z1WYMaYf2I^d)7n=Ivx%(0o-m6Znp_g@5i99b9@q5!)bP%eDg@&qq){UnwTdm|eHIUHe@_3xUggU<@!MTTnl@&IMWo zoZPwqDM6GHqcAwbCL0Q>XfC#szVP<5%}S}5T8fDiy7#g5JO5OB_oAz|&N(#gKGt-B)|F5P2Y{2wtLjVr$>cRQ z#+HQDHq=Q-a0$3hLJ~*|L$R|Unxir6sprite = sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, card_sprite_lut[card_object->card->suit][card_object->card->rank], 0, layer); } -void card_object_score(CardObject *card_object, mm_word sound_id) +void card_object_shake(CardObject *card_object, mm_word sound_id) { card_object->vscale = float2fx(0.3f); // Scale down the card when it's scored card_object->vrotation = float2fx(8.0f); // Rotate the card when it's scored diff --git a/source/game.c b/source/game.c index 72d0045..02577f9 100644 --- a/source/game.c +++ b/source/game.c @@ -1549,82 +1549,70 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection { // So pretend "played_selections" is now called "scored_cards" and it counts the number of cards that have been scored int scored_cards = 0; - for (int j = played_top; j >= 0; j--) + for (int j = 0; j <= played_top; j++) { - if (played[played_top - j]->selected) + tte_erase_rect_wrapper(PLAYED_CARDS_SCORES_RECT); + + if (*played_selections > 0) { - scored_cards++; + for (int k = 0; k <= jokers_top; k++) + { + if (joker_object_score(jokers[k], played[*played_selections - 1]->card, &chips, &mult, NULL, &money, NULL)) // NULLs aren't implemented yet + { + set_chips(chips); + set_mult(mult); + set_money(money); + + return; + } + } + } + + if (played[j]->selected) + { + scored_cards = j + 1; // Count the number of cards that have been scored if (scored_cards > *played_selections) { - tte_erase_rect_wrapper(PLAYED_CARDS_SCORES_RECT); - tte_set_pos(fx2int(played[played_top - j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card + for (int k = 0; k <= jokers_top; k++) + { + if (jokers[k] != NULL) + { + jokers[k]->joker->processed = false; // Reset the joker's processed state for the next score + } + } + + tte_set_pos(fx2int(played[j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card tte_set_special(0xD000); // Set text color to blue from background memory // Write the score to a character buffer variable char score_buffer[5]; // Assuming the maximum score is 99, we need 4 characters (2 digits + null terminator) - 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[j]->card)); tte_write(score_buffer); *played_selections = scored_cards; - card_object_score(played[played_top - j], SFX_CARD_SELECT); + card_object_shake(played[j], SFX_CARD_SELECT); // Relocated card scoring logic here - chips += card_get_value(played[played_top - j]->card); + chips += card_get_value(played[j]->card); set_chips(chips); + break; } } - if (j == 0 && scored_cards == *played_selections) // Check if it's the last card + if (j == played_top && scored_cards == *played_selections) // Check if it's the last card { tte_erase_rect_wrapper(PLAYED_CARDS_SCORES_RECT); - for (int k = 0; k <= jokers_top; k++) + for (int k = 0; k <= jokers_top; k++) // Independent joker scoring loop { - if (jokers[k]->joker->processed == false) - { - IndependentEffect joker_effect = joker_independent_effect(jokers[k]->joker); - IndependentEffect zero_effect = {0}; + if (joker_object_score(jokers[k], NULL, &chips, &mult, NULL, &money, NULL)) // NULLs aren't implemented yet + { + set_chips(chips); + set_mult(mult); + set_money(money); - if (memcmp(&joker_effect, &zero_effect, sizeof(IndependentEffect)) != 0) - { - chips += joker_effect.chips; - set_chips(chips); - mult += joker_effect.mult; - set_mult(mult); - // TODO: XMult - money += joker_effect.money; - set_money(money); - // TODO: Retrigger - - - tte_set_pos(fx2int(jokers[k]->x) + 8, 48); // Offset of 16 pixels to center the text on the card - - char score_buffer[12]; - - if (joker_effect.chips > 0) - { - tte_set_special(0xD000); // Blue - snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.chips); - } - else if (joker_effect.mult > 0) - { - tte_set_special(0xE000); // Red - snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.mult); - } - else if (joker_effect.money > 0) - { - tte_set_special(0xC000); // Yellow - snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.money); - } - - tte_write(score_buffer); - - jokers[k]->joker->processed = true; // Mark the joker as processed - joker_object_score(jokers[k], SFX_CARD_SELECT); - - return; // Returning was just the easiest way to break out of the loop - } + return; // Returning was just the easiest way to break out of the loop } } @@ -1805,7 +1793,9 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time) joker_object_destroy(&shop_jokers[i]); // Destroy the joker object if it exists } - shop_jokers[i] = joker_object_new(joker_new(DEFAULT_JOKER_ID)); + u8 joker_id = random() % MAX_JOKERS; + + shop_jokers[i] = joker_object_new(joker_new(joker_id)); shop_jokers[i]->x = int2fx(120 + i * 32); shop_jokers[i]->y = int2fx(160); shop_jokers[i]->tx = shop_jokers[i]->x; @@ -1818,7 +1808,7 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time) if (first_time == false) { shop_jokers[i]->y = shop_jokers[i]->ty; // If it's not the first time, set the y position to the target position - joker_object_score(shop_jokers[i], UNDEFINED); // Give the joker a little wiggle animation + joker_object_shake(shop_jokers[i], UNDEFINED); // Give the joker a little wiggle animation } sprite_position(shop_jokers[i]->sprite, fx2int(shop_jokers[i]->x), fx2int(shop_jokers[i]->y)); diff --git a/source/joker.c b/source/joker.c index 888721a..8af79c0 100644 --- a/source/joker.c +++ b/source/joker.c @@ -4,9 +4,11 @@ #include "joker_gfx.h" #include "graphic_utils.h" #include "card.h" +#include "soundbank.h" #include #include +#include const static u8 joker_data_lut[MAX_JOKERS][2] = // Rarity, Value { @@ -58,17 +60,21 @@ void joker_destroy(Joker **joker) *joker = NULL; } -IndependentEffect joker_independent_effect(Joker *joker) +JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card) { - IndependentEffect effect = {0}; + JokerEffect effect = {0}; switch (joker->id) { case DEFAULT_JOKER_ID: // Default Joker + if (scored_card != NULL) break; // Joker is independent, no effect effect.mult = 4; break; case GREEDY_JOKER_ID: // Greedy Joker - // Nothing because this joker is a scored type + if (scored_card->suit == DIAMONDS) // If the scored card is a diamond + { + effect.mult = 3; + } break; default: break; @@ -139,8 +145,53 @@ void joker_object_update(JokerObject *joker_object) card_object_update(card_object); } -void joker_object_score(JokerObject *joker_object, mm_word sound_id) // Another derived function of card_object +void joker_object_shake(JokerObject *joker_object, mm_word sound_id) { CardObject *card_object = (CardObject *)joker_object; - card_object_score(card_object, sound_id); + card_object_shake(card_object, sound_id); } + +bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips, int *mult, int *xmult, int *money, bool *retrigger) +{ + if (joker_object->joker->processed == true) return false; // If the joker has already been processed, return false + + JokerEffect joker_effect = joker_get_score_effect(joker_object->joker, scored_card); + + if (memcmp(&joker_effect, &(JokerEffect){0}, sizeof(JokerEffect)) != 0) + { + *chips += joker_effect.chips; + *mult += joker_effect.mult; + // TODO: XMult + *money += joker_effect.money; + // TODO: Retrigger + + tte_set_pos(fx2int(joker_object->x) + 8, 48); // Offset of 16 pixels to center the text on the card + + char score_buffer[12]; + + if (joker_effect.chips > 0) + { + tte_set_special(0xD000); // Blue + snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.chips); + } + else if (joker_effect.mult > 0) + { + tte_set_special(0xE000); // Red + snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.mult); + } + else if (joker_effect.money > 0) + { + tte_set_special(0xC000); // Yellow + snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.money); + } + + tte_write(score_buffer); + + joker_object->joker->processed = true; // Mark the joker as processed + joker_object_shake(joker_object, SFX_CARD_SELECT); // TODO: Add a sound effect for scoring the joker + + return true; + } + + return false; +} \ No newline at end of file From c025d354680248062ae7574dbfa8ae184658a54b Mon Sep 17 00:00:00 2001 From: cellos51 Date: Tue, 22 Jul 2025 20:07:51 -0400 Subject: [PATCH 9/9] null check on greedy joker --- source/joker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/joker.c b/source/joker.c index 8af79c0..b765690 100644 --- a/source/joker.c +++ b/source/joker.c @@ -71,7 +71,7 @@ JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card) effect.mult = 4; break; case GREEDY_JOKER_ID: // Greedy Joker - if (scored_card->suit == DIAMONDS) // If the scored card is a diamond + if (scored_card != NULL && scored_card->suit == DIAMONDS) // If the scored card is a diamond { effect.mult = 3; }