Implement arbitrary-sized joker spritesheets (#285)

* Convert static joker sprites indexes to maps for dynamic spritesheets size

* tmp commit

* reorder Joker spritesheets

* more reordering

* Joker maps, will test later

* More reorders and palette optimizations. Sprites now work

* Fix Joker gfx

* Format joker.c

* Fix rebase error

* Integrate Shoot the Moon art

* format

* format

* removing useless GBAL_UNUSED from photograph Joker effect func

* Tidy up joker.c variables formatting

* Fix magic number

* Add context for map in joker.c

Co-authored-by: Rickey <ric@rf3.xyz>

* Update source/joker.c

Co-authored-by: Rickey <ric@rf3.xyz>

* Apply suggestion from @ricfehr3

Co-authored-by: Rickey <ric@rf3.xyz>

* format

* reduce clutter in joker_effects.c file by defining a macro for forward static declarations of joker effect funcs

* refactored some maps in joker.c to make it more concise

* clang format

* adding back how to mark functions as unused when Jokers don't have a sprite yet

* format

* Remove comment about unused functions for Jokers without art

---------

Co-authored-by: MathisMartin31 <mathis.martin31@gmail.com>
Co-authored-by: Rickey <ric@rf3.xyz>
This commit is contained in:
Geralt
2026-03-28 17:58:05 -07:00
committed by GitHub
co-authored by Rickey MathisMartin31
parent 461584b674
commit 5cf9e2674d
40 changed files with 196 additions and 414 deletions
+1 -1
View File
@@ -1 +1 @@
-gB4 -Mw4 -Mh4 -m! -pn16 -gB4 -Mw4 -Mh4 -m! -pn16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 11 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -m! -pn 16
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1000 B

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 927 B

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1016 B

After

Width:  |  Height:  |  Size: 7.5 KiB

-8
View File
@@ -16,11 +16,3 @@ DEF_JOKER_GFX(14)
DEF_JOKER_GFX(15) DEF_JOKER_GFX(15)
DEF_JOKER_GFX(16) DEF_JOKER_GFX(16)
DEF_JOKER_GFX(17) DEF_JOKER_GFX(17)
DEF_JOKER_GFX(18)
DEF_JOKER_GFX(19)
DEF_JOKER_GFX(20)
DEF_JOKER_GFX(21)
DEF_JOKER_GFX(22)
DEF_JOKER_GFX(23)
DEF_JOKER_GFX(24)
DEF_JOKER_GFX(25)
+7 -7
View File
@@ -85,13 +85,13 @@ enum JokerEvent
// Jokers in the game // Jokers in the game
#define DEFAULT_JOKER_ID 0 #define DEFAULT_JOKER_ID 0
#define GREEDY_JOKER_ID 1 #define STENCIL_JOKER_ID 15
#define STENCIL_JOKER_ID 16 #define GREEDY_JOKER_ID 18
#define SHORTCUT_JOKER_ID 26 #define SHORTCUT_JOKER_ID 38
#define PAREIDOLIA_JOKER_ID 30 #define BRAINSTORM_JOKER_ID 41
#define BLUEPRINT_JOKER_ID 39 #define PAREIDOLIA_JOKER_ID 46
#define BRAINSTORM_JOKER_ID 40 #define FOUR_FINGERS_JOKER_ID 50
#define FOUR_FINGERS_JOKER_ID 48 #define BLUEPRINT_JOKER_ID 52
typedef struct typedef struct
{ {
-8
View File
@@ -20,14 +20,6 @@
#include "joker_gfx15.h" #include "joker_gfx15.h"
#include "joker_gfx16.h" #include "joker_gfx16.h"
#include "joker_gfx17.h" #include "joker_gfx17.h"
#include "joker_gfx18.h"
#include "joker_gfx19.h"
#include "joker_gfx20.h"
#include "joker_gfx21.h"
#include "joker_gfx22.h"
#include "joker_gfx23.h"
#include "joker_gfx24.h"
#include "joker_gfx25.h"
#endif #endif
// clang-format on // clang-format on
+66 -25
View File
@@ -12,17 +12,17 @@
#include <string.h> #include <string.h>
#include <tonc.h> #include <tonc.h>
#define JOKER_SCORE_TEXT_Y 48 #define JOKER_SCORE_TEXT_Y 48
#define HELD_CARD_SCORE_TEXT_Y 108 #define HELD_CARD_SCORE_TEXT_Y 108
#define MAX_CARD_SCORE_STR_LEN 2 #define MAX_CARD_SCORE_STR_LEN 2
#define NUM_JOKERS_PER_SPRITESHEET 2 // what it was before (MAX_DEFINEABLE_JOKERS / JOKERS_PER_SPRITESHEET)
#define MAX_NUM_JOKERS_SPRITESHEETS 75
static const unsigned int* joker_gfxTiles[] = { static const unsigned int* joker_gfxTiles[] = {
#define DEF_JOKER_GFX(idx) joker_gfx##idx##Tiles, #define DEF_JOKER_GFX(idx) joker_gfx##idx##Tiles,
#include "../include/def_joker_gfx_table.h" #include "../include/def_joker_gfx_table.h"
#undef DEF_JOKER_GFX #undef DEF_JOKER_GFX
}; };
static const unsigned short* joker_gfxPal[] = { static const unsigned short* joker_gfxPal[] = {
#define DEF_JOKER_GFX(idx) joker_gfx##idx##Pal, #define DEF_JOKER_GFX(idx) joker_gfx##idx##Pal,
#include "def_joker_gfx_table.h" #include "def_joker_gfx_table.h"
@@ -44,16 +44,53 @@ const static u8 edition_price_lut[MAX_EDITIONS] = {
logic. But I'm going to use a simpler approach for the joker objects since I'm lazy and sorting logic. But I'm going to use a simpler approach for the joker objects since I'm lazy and sorting
them wouldn't look good enough to warrant the effort. them wouldn't look good enough to warrant the effort.
*/ */
static bool _used_layers[MAX_JOKER_OBJECTS] = {false}; // Track used layers for joker sprites static bool used_layers[MAX_JOKER_OBJECTS] = {false}; // Track used layers for joker sprites
// TODO: Refactor sorting into SpriteObject? // TODO: Refactor sorting into SpriteObject?
// Maps the spritesheet index to the palette bank index allocated to it. // Maps the spritesheet index to the palette bank index allocated to it.
// Spritesheets that were not allocated are // Spritesheets that were not allocated are
static int _joker_spritesheet_pb_map[(MAX_DEFINABLE_JOKERS + 1) / NUM_JOKERS_PER_SPRITESHEET]; static int joker_spritesheet_pb_map[MAX_NUM_JOKERS_SPRITESHEETS];
static int _joker_pb_num_sprite_users[JOKER_LAST_PB - JOKER_BASE_PB + 1] = {0}; static int joker_pb_num_sprite_users[JOKER_LAST_PB - JOKER_BASE_PB + 1] = {0};
// See linked issue for context of maps
// https://github.com/GBALATRO/balatro-gba/issues/274#issue-3685075538
// clang-format off
// Map of Joker ID -> Spritesheet idx
static int joker_id_to_sprite_map[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1,
2, 2,
3, 3, 3, 3, 3,
4, 4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7,
8, 8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
};
// Map of Spritesheet idx -> first Joker ID in sheet
// This is used to determine the sprite index of a Joker's sprite
// within its spritesheet by substracting its ID to this starting ID.
// Notice how spritesheets with only one Joker have sequential starting IDs.
static int spritesheet_idx_to_starting_joker_id[] = {
0, 18, 20, 22, 27, 32, 36, 40, 42, 44,
45, 46, 47, 48, 49, 50, 51, 52
};
// clang-format on
static int s_get_num_spritesheets(void); static int s_get_num_spritesheets(void);
static int s_joker_get_spritesheet_idx(u8 joker_id); static int s_joker_get_spritesheet_idx(u8 joker_id);
static int s_joker_get_sprite_idx_in_sheet(u8 joker_id, int spritesheet_idx);
static void s_joker_pb_add_sprite_user(int pb); static void s_joker_pb_add_sprite_user(int pb);
static void s_joker_pb_remove_sprite_user(int pb); static void s_joker_pb_remove_sprite_user(int pb);
static int s_joker_pb_get_num_sprite_users(int joker_pb); static int s_joker_pb_get_num_sprite_users(int joker_pb);
@@ -67,7 +104,7 @@ void joker_init()
for (int i = 0; i < num_spritesheets; i++) for (int i = 0; i < num_spritesheets; i++)
{ {
_joker_spritesheet_pb_map[i] = UNDEFINED; joker_spritesheet_pb_map[i] = UNDEFINED;
} }
} }
@@ -131,10 +168,10 @@ JokerObject* joker_object_new(Joker* joker)
int layer = 0; int layer = 0;
for (int i = 0; i < MAX_JOKER_OBJECTS; i++) for (int i = 0; i < MAX_JOKER_OBJECTS; i++)
{ {
if (!_used_layers[i]) if (!used_layers[i])
{ {
layer = i; layer = i;
_used_layers[i] = true; // Mark this layer as used used_layers[i] = true; // Mark this layer as used
break; break;
} }
} }
@@ -145,7 +182,7 @@ JokerObject* joker_object_new(Joker* joker)
int tile_index = JOKER_TID + (layer * JOKER_SPRITE_OFFSET); int tile_index = JOKER_TID + (layer * JOKER_SPRITE_OFFSET);
int joker_spritesheet_idx = s_joker_get_spritesheet_idx(joker->id); int joker_spritesheet_idx = s_joker_get_spritesheet_idx(joker->id);
int joker_idx = joker->id % NUM_JOKERS_PER_SPRITESHEET; int joker_idx = s_joker_get_sprite_idx_in_sheet(joker->id, joker_spritesheet_idx);
int joker_pb = s_allocate_pb_if_needed(joker->id); int joker_pb = s_allocate_pb_if_needed(joker->id);
s_joker_pb_add_sprite_user(joker_pb); s_joker_pb_add_sprite_user(joker_pb);
@@ -175,12 +212,12 @@ void joker_object_destroy(JokerObject** joker_object)
return; return;
int layer = sprite_get_layer(joker_object_get_sprite(*joker_object)) - JOKER_STARTING_LAYER; int layer = sprite_get_layer(joker_object_get_sprite(*joker_object)) - JOKER_STARTING_LAYER;
_used_layers[layer] = false; used_layers[layer] = false;
s_joker_pb_remove_sprite_user(sprite_get_pb(joker_object_get_sprite(*joker_object))); s_joker_pb_remove_sprite_user(sprite_get_pb(joker_object_get_sprite(*joker_object)));
if (s_joker_pb_get_num_sprite_users((sprite_get_pb(joker_object_get_sprite(*joker_object)))) == if (s_joker_pb_get_num_sprite_users((sprite_get_pb(joker_object_get_sprite(*joker_object)))) ==
0) 0)
{ {
_joker_spritesheet_pb_map[s_joker_get_spritesheet_idx((*joker_object)->joker->id)] = joker_spritesheet_pb_map[s_joker_get_spritesheet_idx((*joker_object)->joker->id)] =
UNDEFINED; UNDEFINED;
} }
@@ -354,36 +391,40 @@ int joker_get_random_rarity()
static int s_get_num_spritesheets() static int s_get_num_spritesheets()
{ {
return (get_joker_registry_size() + NUM_JOKERS_PER_SPRITESHEET - 1) / return MAX_NUM_JOKERS_SPRITESHEETS;
NUM_JOKERS_PER_SPRITESHEET;
} }
static int s_joker_get_spritesheet_idx(u8 joker_id) static int s_joker_get_spritesheet_idx(u8 joker_id)
{ {
return joker_id / NUM_JOKERS_PER_SPRITESHEET; return joker_id_to_sprite_map[joker_id];
}
static int s_joker_get_sprite_idx_in_sheet(u8 joker_id, int spritesheet_idx)
{
return joker_id - spritesheet_idx_to_starting_joker_id[joker_id_to_sprite_map[joker_id]];
} }
static void s_joker_pb_add_sprite_user(int pb) static void s_joker_pb_add_sprite_user(int pb)
{ {
_joker_pb_num_sprite_users[pb - JOKER_BASE_PB]++; joker_pb_num_sprite_users[pb - JOKER_BASE_PB]++;
} }
static void s_joker_pb_remove_sprite_user(int pb) static void s_joker_pb_remove_sprite_user(int pb)
{ {
int num_sprite_users = _joker_pb_num_sprite_users[pb - JOKER_BASE_PB]; int num_sprite_users = joker_pb_num_sprite_users[pb - JOKER_BASE_PB];
_joker_pb_num_sprite_users[pb - JOKER_BASE_PB] = max(0, num_sprite_users - 1); joker_pb_num_sprite_users[pb - JOKER_BASE_PB] = max(0, num_sprite_users - 1);
} }
static int s_joker_pb_get_num_sprite_users(int joker_pb) static int s_joker_pb_get_num_sprite_users(int joker_pb)
{ {
return _joker_pb_num_sprite_users[joker_pb - JOKER_BASE_PB]; return joker_pb_num_sprite_users[joker_pb - JOKER_BASE_PB];
} }
static int s_get_unused_joker_pb() static int s_get_unused_joker_pb()
{ {
for (int i = 0; i < NUM_ELEM_IN_ARR(_joker_pb_num_sprite_users); i++) for (int i = 0; i < NUM_ELEM_IN_ARR(joker_pb_num_sprite_users); i++)
{ {
if (_joker_pb_num_sprite_users[i] == 0) if (joker_pb_num_sprite_users[i] == 0)
{ {
return (i + JOKER_BASE_PB); return (i + JOKER_BASE_PB);
} }
@@ -395,7 +436,7 @@ static int s_get_unused_joker_pb()
static int s_allocate_pb_if_needed(u8 joker_id) static int s_allocate_pb_if_needed(u8 joker_id)
{ {
int joker_spritesheet_idx = s_joker_get_spritesheet_idx(joker_id); int joker_spritesheet_idx = s_joker_get_spritesheet_idx(joker_id);
int joker_pb = _joker_spritesheet_pb_map[joker_spritesheet_idx]; int joker_pb = joker_spritesheet_pb_map[joker_spritesheet_idx];
if (joker_pb != UNDEFINED) if (joker_pb != UNDEFINED)
{ {
// Already allocated // Already allocated
@@ -412,7 +453,7 @@ static int s_allocate_pb_if_needed(u8 joker_id)
} }
else else
{ {
_joker_spritesheet_pb_map[joker_spritesheet_idx] = joker_pb; joker_spritesheet_pb_map[joker_spritesheet_idx] = joker_pb;
memcpy16( memcpy16(
&pal_obj_mem[PAL_ROW_LEN * joker_pb], &pal_obj_mem[PAL_ROW_LEN * joker_pb],
joker_gfxPal[joker_spritesheet_idx], joker_gfxPal[joker_spritesheet_idx],
+122 -357
View File
@@ -23,312 +23,72 @@
static JokerEffect shared_joker_effect = {0}; static JokerEffect shared_joker_effect = {0};
// Joker Effect functions // Joker Effect functions
static u32 joker_effect_noop(
Joker* joker, #define REGISTER_JOKER_EFFECT_FUNC(joker_effect_name) \
Card* scored_card, static u32 joker_effect_name( \
enum JokerEvent joker_event, Joker* joker, \
JokerEffect** joker_effect Card* scored_card, \
); enum JokerEvent joker_event, \
static u32 default_joker_effect( JokerEffect** joker_effect \
Joker* joker, );
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 sinful_joker_effect( static u32 sinful_joker_effect(
Card* scored_card, Card* scored_card,
u8 sinful_suit, u8 sinful_suit,
enum JokerEvent joker_event, enum JokerEvent joker_event,
JokerEffect** joker_effect JokerEffect** joker_effect
); );
static u32 greedy_joker_effect(
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(joker_effect_noop)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(default_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(greedy_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(lusty_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(wrathful_joker_effect)
static u32 lusty_joker_effect( REGISTER_JOKER_EFFECT_FUNC(gluttonous_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(jolly_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(zany_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(mad_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(crazy_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(droll_joker_effect)
static u32 wrathful_joker_effect( REGISTER_JOKER_EFFECT_FUNC(sly_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(wily_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(clever_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(devious_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(crafty_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(half_joker_effect)
static u32 gluttonous_joker_effect( REGISTER_JOKER_EFFECT_FUNC(stencil_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(misprint_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(walkie_talkie_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(fibonnaci_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(banner_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(mystic_summit_joker_effect)
static u32 jolly_joker_effect( REGISTER_JOKER_EFFECT_FUNC(blackboard_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(blue_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(raised_fist_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(reserved_parking_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(business_card_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(scholar_joker_effect)
static u32 zany_joker_effect( REGISTER_JOKER_EFFECT_FUNC(scary_face_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(abstract_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(bull_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(smiley_face_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(even_steven_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(odd_todd_joker_effect)
static u32 mad_joker_effect( REGISTER_JOKER_EFFECT_FUNC(acrobat_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(hanging_chad_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(the_duo_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(the_trio_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(the_family_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(the_order_joker_effect)
static u32 crazy_joker_effect( REGISTER_JOKER_EFFECT_FUNC(the_tribe_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(bootstraps_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(shoot_the_moon_joker_effect)
enum JokerEvent joker_event, REGISTER_JOKER_EFFECT_FUNC(photograph_joker_effect)
JokerEffect** joker_effect REGISTER_JOKER_EFFECT_FUNC(dusk_joker_effect)
); REGISTER_JOKER_EFFECT_FUNC(blueprint_brainstorm_joker_effect)
static u32 droll_joker_effect( REGISTER_JOKER_EFFECT_FUNC(hack_joker_effect)
Joker* joker, REGISTER_JOKER_EFFECT_FUNC(seltzer_joker_effect)
Card* scored_card, REGISTER_JOKER_EFFECT_FUNC(sock_and_buskin_joker_effect)
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 sly_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 wily_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 clever_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 devious_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 crafty_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 half_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 joker_stencil_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 misprint_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 walkie_talkie_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 fibonnaci_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 banner_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 mystic_summit_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 blackboard_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 blue_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 raised_fist_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 reserved_parking_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 business_card_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 scholar_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 scary_face_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 abstract_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 bull_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 smiley_face_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 even_steven_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 odd_todd_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 acrobat_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 hanging_chad_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 the_duo_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 the_trio_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 the_family_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 the_order_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 the_tribe_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 bootstraps_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 shoot_the_moon_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 photograph_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 dusk_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 blueprint_brainstorm_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 hack_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 seltzer_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
static u32 sock_and_buskin_joker_effect(
Joker* joker,
Card* scored_card,
enum JokerEvent joker_event,
JokerEffect** joker_effect
);
// clang-format off // clang-format off
/* The index of a joker in the registry matches its ID. /* The index of a joker in the registry matches its ID.
@@ -340,66 +100,76 @@ static u32 sock_and_buskin_joker_effect(
* (and put together in the matching spritesheet) to share a color palette. * (and put together in the matching spritesheet) to share a color palette.
* Otherwise the order is similar to the wiki. * Otherwise the order is similar to the wiki.
*/ */
// clang-format off
const JokerInfo joker_registry[] = const JokerInfo joker_registry[] =
{ {
// Spritesheet 0
{ COMMON_JOKER, 2, default_joker_effect }, // DEFAULT_JOKER_ID = 0 { COMMON_JOKER, 2, default_joker_effect }, // DEFAULT_JOKER_ID = 0
{ COMMON_JOKER, 5, greedy_joker_effect }, // GREEDY_JOKER_ID = 1 { COMMON_JOKER, 4, abstract_joker_effect }, // 1
{ COMMON_JOKER, 5, lusty_joker_effect }, // etc... 2 { COMMON_JOKER, 5, half_joker_effect }, // 2
{ COMMON_JOKER, 5, wrathful_joker_effect }, // 3 { COMMON_JOKER, 4, misprint_joker_effect }, // 3
{ COMMON_JOKER, 5, gluttonous_joker_effect }, // 4 { COMMON_JOKER, 4, scary_face_joker_effect }, // 4
{ COMMON_JOKER, 3, jolly_joker_effect }, // 5 { UNCOMMON_JOKER, 6, sock_and_buskin_joker_effect }, // 5
{ COMMON_JOKER, 4, zany_joker_effect }, // 6 { UNCOMMON_JOKER, 6, acrobat_joker_effect }, // 6
{ COMMON_JOKER, 4, mad_joker_effect }, // 7 { UNCOMMON_JOKER, 8, fibonnaci_joker_effect }, // 7
{ COMMON_JOKER, 4, crazy_joker_effect }, // 8 { COMMON_JOKER, 4, scholar_joker_effect }, // 8
{ COMMON_JOKER, 4, droll_joker_effect }, // 9 { COMMON_JOKER, 4, droll_joker_effect }, // 9
{ COMMON_JOKER, 3, sly_joker_effect }, // 10 { COMMON_JOKER, 4, crafty_joker_effect }, // 10
{ COMMON_JOKER, 4, wily_joker_effect }, // 11 { COMMON_JOKER, 5, raised_fist_joker_effect }, // 11
{ COMMON_JOKER, 4, clever_joker_effect }, // 12 { COMMON_JOKER, 6, reserved_parking_joker_effect }, // 12
{ COMMON_JOKER, 4, devious_joker_effect }, // 13 { COMMON_JOKER, 4, business_card_joker_effect }, // 13
{ COMMON_JOKER, 4, crafty_joker_effect }, // 14 { COMMON_JOKER, 4, hanging_chad_joker_effect }, // 14
{ COMMON_JOKER, 5, half_joker_effect }, // 15 { UNCOMMON_JOKER, 8, stencil_joker_effect }, // 15
{ UNCOMMON_JOKER, 8, joker_stencil_effect }, // 16 { COMMON_JOKER, 5, banner_joker_effect }, // 16
{ COMMON_JOKER, 5, photograph_joker_effect, }, // 17 { COMMON_JOKER, 5, shoot_the_moon_joker_effect, }, // 17
{ COMMON_JOKER, 4, walkie_talkie_joker_effect }, // 18 // Spritesheet 1
{ COMMON_JOKER, 5, banner_joker_effect }, // 19 { COMMON_JOKER, 5, greedy_joker_effect }, // 18
{ UNCOMMON_JOKER, 6, blackboard_joker_effect }, // 20 { COMMON_JOKER, 5, lusty_joker_effect }, // 19
{ COMMON_JOKER, 5, mystic_summit_joker_effect }, // 21 // Spritesheet 2
{ COMMON_JOKER, 4, misprint_joker_effect }, // 22 { COMMON_JOKER, 5, wrathful_joker_effect }, // 20
{ COMMON_JOKER, 4, even_steven_joker_effect }, // 23 { COMMON_JOKER, 5, gluttonous_joker_effect }, // 21
{ COMMON_JOKER, 5, blue_joker_effect }, // 24 // Spritesheet 3
{ COMMON_JOKER, 4, odd_todd_joker_effect }, // 25 { COMMON_JOKER, 4, crazy_joker_effect }, // 22
{ UNCOMMON_JOKER, 7, joker_effect_noop, }, // 26 Shortcut { COMMON_JOKER, 4, mad_joker_effect }, // 23
{ COMMON_JOKER, 4, business_card_joker_effect }, // 27 { COMMON_JOKER, 4, clever_joker_effect }, // 24
{ COMMON_JOKER, 4, scary_face_joker_effect }, // 28 { COMMON_JOKER, 4, devious_joker_effect }, // 25
{ UNCOMMON_JOKER, 7, bootstraps_joker_effect }, // 29 { COMMON_JOKER, 4, even_steven_joker_effect }, // 26
{ UNCOMMON_JOKER, 5, joker_effect_noop }, // 30 Pareidolia // Spritesheet 4
{ COMMON_JOKER, 6, reserved_parking_joker_effect }, // 31 { UNCOMMON_JOKER, 6, blackboard_joker_effect }, // 27
{ COMMON_JOKER, 4, abstract_joker_effect }, // 32 { COMMON_JOKER, 5, mystic_summit_joker_effect }, // 28
{ UNCOMMON_JOKER, 6, bull_joker_effect }, // 33 { COMMON_JOKER, 4, walkie_talkie_joker_effect }, // 29
{ RARE_JOKER, 8, the_duo_joker_effect }, // 34 { COMMON_JOKER, 4, zany_joker_effect }, // 30
{ RARE_JOKER, 8, the_trio_joker_effect }, // 35 { COMMON_JOKER, 4, wily_joker_effect }, // 31
{ RARE_JOKER, 8, the_family_joker_effect }, // 36 // Spritesheet 5
{ RARE_JOKER, 8, the_order_joker_effect }, // 37 { COMMON_JOKER, 3, sly_joker_effect }, // 32
{ RARE_JOKER, 8, the_tribe_joker_effect }, // 38 { COMMON_JOKER, 3, jolly_joker_effect }, // 33
{ RARE_JOKER, 10, blueprint_brainstorm_joker_effect }, // 39 Blueprint { COMMON_JOKER, 5, blue_joker_effect }, // 34
{ RARE_JOKER, 10, blueprint_brainstorm_joker_effect }, // 40 Brainstorm { COMMON_JOKER, 4, odd_todd_joker_effect }, // 35
{ COMMON_JOKER, 5, raised_fist_joker_effect }, // 41 // Spritesheet 6
{ RARE_JOKER, 8, the_duo_joker_effect }, // 36
{ RARE_JOKER, 8, the_trio_joker_effect }, // 37
{ RARE_JOKER, 8, the_order_joker_effect }, // 38
{ RARE_JOKER, 8, the_tribe_joker_effect }, // 39
// Spritesheet 7
{ RARE_JOKER, 8, the_family_joker_effect }, // 40
{ RARE_JOKER, 10, blueprint_brainstorm_joker_effect }, // 41 Brainstorm
// Spritesheet 8
{ COMMON_JOKER, 4, smiley_face_joker_effect }, // 42 { COMMON_JOKER, 4, smiley_face_joker_effect }, // 42
{ UNCOMMON_JOKER, 6, acrobat_joker_effect }, // 43 { UNCOMMON_JOKER, 6, bull_joker_effect }, // 43
{ UNCOMMON_JOKER, 5, dusk_joker_effect }, // 44 // Individual Jokers (for now :3)
{ UNCOMMON_JOKER, 6, sock_and_buskin_joker_effect }, // 45 { COMMON_JOKER, 5, photograph_joker_effect, }, // 44
{ UNCOMMON_JOKER, 6, hack_joker_effect }, // 46 { UNCOMMON_JOKER, 6, hack_joker_effect }, // 45
{ COMMON_JOKER, 4, hanging_chad_joker_effect }, // 47 { UNCOMMON_JOKER, 5, joker_effect_noop }, // 46 Pareidolia
{ UNCOMMON_JOKER, 7, joker_effect_noop, }, // 48 Four Fingers { UNCOMMON_JOKER, 7, bootstraps_joker_effect }, // 47
{ COMMON_JOKER, 4, scholar_joker_effect }, // 49 { UNCOMMON_JOKER, 7, joker_effect_noop, }, // 48 Shortcut
{ UNCOMMON_JOKER, 8, fibonnaci_joker_effect }, // 50 { UNCOMMON_JOKER, 5, dusk_joker_effect }, // 49
{ UNCOMMON_JOKER, 7, joker_effect_noop, }, // 50 Four Fingers
{ UNCOMMON_JOKER, 6, seltzer_joker_effect, }, // 51 { UNCOMMON_JOKER, 6, seltzer_joker_effect, }, // 51
{ RARE_JOKER, 10, blueprint_brainstorm_joker_effect }, // 52 Blueprint
// The following jokers don't have sprites yet, // The following jokers don't have sprites yet,
// uncomment them when their sprites are added. // uncomment them when their sprites are added.
#if 0 #if 0
{ COMMON_JOKER, 5, shoot_the_moon_joker_effect, },
#endif #endif
}; };
// clang-format on // clang-format on
@@ -749,7 +519,7 @@ static u32 half_joker_effect(
return effect_flags_ret; return effect_flags_ret;
} }
static u32 joker_stencil_effect( static u32 stencil_joker_effect(
Joker* joker, Joker* joker,
Card* scored_card, Card* scored_card,
enum JokerEvent joker_event, enum JokerEvent joker_event,
@@ -1395,10 +1165,6 @@ static u32 bootstraps_joker_effect(
return effect_flags_ret; return effect_flags_ret;
} }
// Using GBAL_UNUSED, aka __attribute__((unused)), for jokers with no sprites yet to avoid warning
// Remove the attribute once they have sprites
// no graphics available but ready to be used if wanted when graphics available
GBAL_UNUSED
static u32 shoot_the_moon_joker_effect( static u32 shoot_the_moon_joker_effect(
Joker* joker, Joker* joker,
Card* scored_card, Card* scored_card,
@@ -1421,7 +1187,6 @@ static u32 shoot_the_moon_joker_effect(
return effect_flags_ret; return effect_flags_ret;
} }
GBAL_UNUSED
static u32 photograph_joker_effect( static u32 photograph_joker_effect(
Joker* joker, Joker* joker,
Card* scored_card, Card* scored_card,