diff --git a/graphics/joker_gfx.grit b/graphics/joker_gfx.grit deleted file mode 100644 index f677be5..0000000 --- a/graphics/joker_gfx.grit +++ /dev/null @@ -1 +0,0 @@ --gB4 -Mw4 -Mh4 -m! \ No newline at end of file diff --git a/graphics/joker_gfx.png b/graphics/joker_gfx.png deleted file mode 100644 index 3de5f1b..0000000 Binary files a/graphics/joker_gfx.png and /dev/null differ diff --git a/graphics/joker_gfx0.grit b/graphics/joker_gfx0.grit new file mode 100644 index 0000000..6a8041e --- /dev/null +++ b/graphics/joker_gfx0.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn16 \ No newline at end of file diff --git a/graphics/joker_gfx0.png b/graphics/joker_gfx0.png new file mode 100644 index 0000000..dcc73ab Binary files /dev/null and b/graphics/joker_gfx0.png differ diff --git a/graphics/joker_gfx1.grit b/graphics/joker_gfx1.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx1.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx1.png b/graphics/joker_gfx1.png new file mode 100644 index 0000000..ad85aa5 Binary files /dev/null and b/graphics/joker_gfx1.png differ diff --git a/graphics/joker_gfx2.grit b/graphics/joker_gfx2.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx2.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx2.png b/graphics/joker_gfx2.png new file mode 100644 index 0000000..b848ff0 Binary files /dev/null and b/graphics/joker_gfx2.png differ diff --git a/graphics/joker_gfx3.grit b/graphics/joker_gfx3.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx3.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx3.png b/graphics/joker_gfx3.png new file mode 100644 index 0000000..673aa12 Binary files /dev/null and b/graphics/joker_gfx3.png differ diff --git a/graphics/joker_gfx4.grit b/graphics/joker_gfx4.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx4.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx4.png b/graphics/joker_gfx4.png new file mode 100644 index 0000000..e2074c6 Binary files /dev/null and b/graphics/joker_gfx4.png differ diff --git a/graphics/joker_gfx5.grit b/graphics/joker_gfx5.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx5.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx5.png b/graphics/joker_gfx5.png new file mode 100644 index 0000000..c220cf3 Binary files /dev/null and b/graphics/joker_gfx5.png differ diff --git a/graphics/joker_gfx6.grit b/graphics/joker_gfx6.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx6.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx6.png b/graphics/joker_gfx6.png new file mode 100644 index 0000000..7620341 Binary files /dev/null and b/graphics/joker_gfx6.png differ diff --git a/graphics/joker_gfx7.grit b/graphics/joker_gfx7.grit new file mode 100644 index 0000000..a8ac3f6 --- /dev/null +++ b/graphics/joker_gfx7.grit @@ -0,0 +1 @@ +-gB4 -Mw4 -Mh4 -m! -pn 16 \ No newline at end of file diff --git a/graphics/joker_gfx7.png b/graphics/joker_gfx7.png new file mode 100644 index 0000000..cb2ae9f Binary files /dev/null and b/graphics/joker_gfx7.png differ diff --git a/include/graphic_utils.h b/include/graphic_utils.h index 8d572ba..6c169c7 100644 --- a/include/graphic_utils.h +++ b/include/graphic_utils.h @@ -22,6 +22,7 @@ #define AFFINE_BG_SBB 2 #define AFFINE_BG_CBB 2 #define PAL_ROW_LEN 16 +#define NUM_PALETTES 16 /* Dimensions for a screenblock. * A 1024 size screenblock is arranged in a grid of 32x32 screen entries diff --git a/include/joker.h b/include/joker.h index a735066..a869ed5 100644 --- a/include/joker.h +++ b/include/joker.h @@ -9,7 +9,7 @@ #define JOKER_TID (MAX_HAND_SIZE + MAX_SELECTION_SIZE) * JOKER_SPRITE_OFFSET // Tile ID for the starting index in the tile memory #define JOKER_SPRITE_OFFSET 16 // Offset for the joker sprites -#define JOKER_PB 4 // Palette bank for the default jokers +#define JOKER_BASE_PB 4 // Palette bank for the default jokers #define JOKER_STARTING_LAYER 27 #define BASE_EDITION 0 diff --git a/include/joker_gfx.h b/include/joker_gfx.h new file mode 100644 index 0000000..c549405 --- /dev/null +++ b/include/joker_gfx.h @@ -0,0 +1,13 @@ +#ifndef JOKER_GFX_H +#define JOKER_GFX_H + +#include "joker_gfx0.h" +#include "joker_gfx1.h" +#include "joker_gfx2.h" +#include "joker_gfx3.h" +#include "joker_gfx4.h" +#include "joker_gfx5.h" +#include "joker_gfx6.h" +#include "joker_gfx7.h" + +#endif \ No newline at end of file diff --git a/include/util.h b/include/util.h index 54edbc1..5b3160e 100644 --- a/include/util.h +++ b/include/util.h @@ -37,4 +37,6 @@ static inline int get_digits_even(int n) #define NUM_ELEM_IN_ARR(arr) (sizeof(arr) / sizeof((arr)[0])) +int int_arr_max(int int_arr[], int size); + #endif // UTIL_H \ No newline at end of file diff --git a/source/joker.c b/source/joker.c index 233769b..02febc5 100644 --- a/source/joker.c +++ b/source/joker.c @@ -5,12 +5,17 @@ #include "graphic_utils.h" #include "card.h" #include "soundbank.h" +#include "util.h" #include #include #include #define JOKER_SCORE_TEXT_Y 48 +#define NUM_JOKERS_PER_SPRITESHEET 2 + +const unsigned int **joker_gfxTiles; +const unsigned short **joker_gfxPal; const static u8 edition_price_lut[MAX_EDITIONS] = { @@ -31,20 +36,99 @@ const static u8 edition_price_lut[MAX_EDITIONS] = static bool used_layers[MAX_JOKER_OBJECTS] = {false}; // Track used layers for joker sprites // TODO: Refactor sorting into SpriteObject? +// Maps the spritesheet index to the palette bank index allocated to it. +// Spritesheets that were not allocated are +static int* joker_spritesheet_pb_map; + +static int get_num_spritesheets() +{ + return (get_joker_registry_size() + NUM_JOKERS_PER_SPRITESHEET - 1) / NUM_JOKERS_PER_SPRITESHEET; +} + +// TODO: This should be generalized so any sprite can have dynamic swapping +static int allocate_pb_if_needed(u8 joker_id) +{ + int joker_spritesheet_idx = joker_id / NUM_JOKERS_PER_SPRITESHEET; + int joker_pb = joker_spritesheet_pb_map[joker_spritesheet_idx]; + if (joker_pb != UNDEFINED) + { + // Already allocated + return joker_pb; + } + + // Allocate a new palette + joker_pb = int_arr_max(joker_spritesheet_pb_map, get_num_spritesheets()); + + if (joker_pb == UNDEFINED) + { + // This is the first palette loaded + joker_pb = JOKER_BASE_PB; + } + else + { + // The new palette bank is a 1 increment of the last allocated one + /* TODO: This doesn't account for removal, we need to address that, + * track sprite usage and remove palettes for unused sprites + */ + joker_pb = joker_pb + 1; + } + + if (joker_pb == NUM_PALETTES) + { + // Ran out of palettes, default to base and pray + joker_pb = JOKER_BASE_PB; + } + else + { + joker_spritesheet_pb_map[joker_spritesheet_idx] = joker_pb; + memcpy16(&pal_obj_mem[PAL_ROW_LEN * joker_pb], joker_gfxPal[joker_spritesheet_idx], NUM_ELEM_IN_ARR(joker_gfx0Pal)); + } + + return joker_pb; +} + void joker_init() { - GRIT_CPY(&pal_obj_mem[PAL_ROW_LEN * JOKER_PB], joker_gfxPal); + // This should init once only so no need to free + int num_spritesheets = get_num_spritesheets(); + joker_gfxTiles = (const unsigned int**)malloc((sizeof(unsigned int*) * num_spritesheets)); + joker_gfxPal = (const unsigned short**)malloc((sizeof(unsigned int*) * num_spritesheets)); + joker_spritesheet_pb_map = (int*)malloc(sizeof(int) * num_spritesheets); + + // TODO: Automate this with the preprocessor somehow? + joker_gfxTiles[0] = joker_gfx0Tiles; + joker_gfxTiles[1] = joker_gfx1Tiles; + joker_gfxTiles[2] = joker_gfx2Tiles; + joker_gfxTiles[3] = joker_gfx3Tiles; + joker_gfxTiles[4] = joker_gfx4Tiles; + joker_gfxTiles[5] = joker_gfx5Tiles; + joker_gfxTiles[6] = joker_gfx6Tiles; + joker_gfxTiles[7] = joker_gfx7Tiles; + + joker_gfxPal[0] = joker_gfx0Pal; + joker_gfxPal[1] = joker_gfx1Pal; + joker_gfxPal[2] = joker_gfx2Pal; + joker_gfxPal[3] = joker_gfx3Pal; + joker_gfxPal[4] = joker_gfx4Pal; + joker_gfxPal[5] = joker_gfx5Pal; + joker_gfxPal[6] = joker_gfx6Pal; + joker_gfxPal[7] = joker_gfx7Pal; + + for (int i = 0; i < num_spritesheets; i++) + { + joker_spritesheet_pb_map[i] = UNDEFINED; + } } Joker *joker_new(u8 id) { if (id >= get_joker_registry_size()) return NULL; - Joker *joker = malloc(sizeof(Joker)); + Joker *joker = (Joker*)malloc(sizeof(Joker)); const JokerInfo *jinfo = get_joker_registry_entry(id); joker->id = id; - joker->modifier = BASE_EDITION; // TODO: Make this random later + joker->modifier = BASE_EDITION; // TODO: Make this a parameter joker->value = jinfo->base_value + edition_price_lut[joker->modifier]; // Base value + edition price joker->rarity = jinfo->rarity; joker->processed = false; @@ -87,7 +171,13 @@ JokerObject *joker_object_new(Joker *joker) joker_object->sprite_object = sprite_object_new(); int tile_index = JOKER_TID + (layer * JOKER_SPRITE_OFFSET); - memcpy32(&tile_mem[4][tile_index], &joker_gfxTiles[joker->id * TILE_SIZE * JOKER_SPRITE_OFFSET], TILE_SIZE * JOKER_SPRITE_OFFSET); + + int joker_spritesheet_idx = joker->id / NUM_JOKERS_PER_SPRITESHEET; + int joker_idx = joker->id % NUM_JOKERS_PER_SPRITESHEET; + int joker_pb = allocate_pb_if_needed(joker->id); + + memcpy32(&tile_mem[4][tile_index], &joker_gfxTiles[joker_spritesheet_idx][joker_idx * TILE_SIZE * JOKER_SPRITE_OFFSET], TILE_SIZE * JOKER_SPRITE_OFFSET); + sprite_object_set_sprite ( joker_object->sprite_object, @@ -96,7 +186,7 @@ JokerObject *joker_object_new(Joker *joker) ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, tile_index, - JOKER_PB, + joker_pb, JOKER_STARTING_LAYER + layer ) ); diff --git a/source/util.c b/source/util.c new file mode 100644 index 0000000..94af7ef --- /dev/null +++ b/source/util.c @@ -0,0 +1,16 @@ +#include "util.h" +#include + +int int_arr_max(int int_arr[], int size) +{ + int max = INT_MIN; + for (int i = 0; i < size; i++) + { + if (int_arr[i] > max) + { + max = int_arr[i]; + } + } + + return max; +}