Implement boss blind graphics (#352)

* Created sprite bank for all blinds

* progress city, it's a beatiful city that progress city!

* Sprite appears in blind selection screen

* Added all blind colors

* fix magic numbers + disable boss reroll

* Fix boss blind token not moving after a reroll

* fix always rolling the Needle due to choosing too early for the rng seed to be set

* No need for affine sprite for blind tokens, regular is enough

* address Copilot's review 1/2

* address Copilot's review 2/2

* correct Blind Tokens/Types

* Index palette colors into the files instead of code

* Fix blind sprites (flip bug not solved)

* Fix magic number, tile index and Mark colors

* load boss blind palette only when changing spritesheet

* Adressing clang format and ease of modification of the blinds' list

* Removed some magic numbers


---------

Co-authored-by: MathisMartin31 <mathis.martin31@gmail.com>
This commit is contained in:
Geralt
2026-04-16 11:52:39 +03:00
committed by GitHub
co-authored by MathisMartin31
parent a31eccba20
commit db27962623
49 changed files with 483 additions and 184 deletions
-1
View File
@@ -1 +0,0 @@
-gB4 -Mw4 -Mh4 -p!
Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

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

After

Width:  |  Height:  |  Size: 393 B

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

After

Width:  |  Height:  |  Size: 377 B

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

After

Width:  |  Height:  |  Size: 364 B

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

After

Width:  |  Height:  |  Size: 383 B

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

After

Width:  |  Height:  |  Size: 284 B

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

After

Width:  |  Height:  |  Size: 345 B

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

After

Width:  |  Height:  |  Size: 343 B

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

After

Width:  |  Height:  |  Size: 356 B

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

After

Width:  |  Height:  |  Size: 343 B

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

After

Width:  |  Height:  |  Size: 346 B

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

After

Width:  |  Height:  |  Size: 366 B

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

After

Width:  |  Height:  |  Size: 380 B

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

After

Width:  |  Height:  |  Size: 357 B

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

After

Width:  |  Height:  |  Size: 367 B

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

After

Width:  |  Height:  |  Size: 387 B

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

After

Width:  |  Height:  |  Size: 369 B

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

After

Width:  |  Height:  |  Size: 378 B

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

After

Width:  |  Height:  |  Size: 363 B

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

Before

Width:  |  Height:  |  Size: 402 B

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

Before

Width:  |  Height:  |  Size: 423 B

+70 -33
View File
@@ -1,45 +1,86 @@
#ifndef BLIND_H #ifndef BLIND_H
#define BLIND_H #define BLIND_H
#include "game.h"
#include "sprite.h" #include "sprite.h"
// The GBA's max uint value is around 4 billion, so we're going to not add endless mode for // The GBA's max uint value is around 4 billion, so we're going to not add endless mode for
// simplicity's sake // simplicity's sake
#define MAX_ANTE 8 #define MAX_ANTE 8
#define SMALL_BLIND_PB 1 #define NORMAL_BLIND_PB 1
#define BIG_BLIND_PB 2 #define BOSS_BLIND_PB 2
#define BOSS_BLIND_PB 3
#define BLIND_BASE_LAYER (MAX_HAND_SIZE + MAX_SELECTION_SIZE)
#define PLAYING_BLIND_TOKEN_LAYER 0
#define ROUND_END_BLIND_TOKEN_LAYER 1
#define SMALL_BLIND_TOKEN_LAYER 2
#define BIG_BLIND_TOKEN_LAYER 3
#define BOSS_BLIND_TOKEN_LAYER 4
#define BLIND_SPRITE_OFFSET 16 #define BLIND_SPRITE_OFFSET 16
#define BLIND_SPRITE_COPY_SIZE BLIND_SPRITE_OFFSET * 8 // 8 ints per tile #define BLIND_SPRITE_COPY_SIZE (BLIND_SPRITE_OFFSET * TILE_SIZE)
#define SMALL_BLIND_TID 960
#define BIG_BLIND_TID (BLIND_SPRITE_OFFSET + SMALL_BLIND_TID)
#define BOSS_BLIND_TID (BLIND_SPRITE_OFFSET + BIG_BLIND_TID)
#define BLIND_TOKENS_PER_SPRITESHEET 2
#define BLIND_TOKEN_PALETTE_SIZE 8
// Order of the Blind sprites' colors as encoded in the files' palettes with Aseprite
enum BlindColorIndex enum BlindColorIndex
{ {
BLIND_TEXT_COLOR_INDEX = 1, BLIND_TEXT_COLOR_INDEX = 1,
BLIND_SHADOW_COLOR_INDEX = 2, BLIND_SHADOW_COLOR_INDEX,
BLIND_HIGHLIGHT_COLOR_INDEX = 3, BLIND_HIGHLIGHT_COLOR_INDEX,
BLIND_MAIN_COLOR_INDEX = 4, BLIND_MAIN_COLOR_INDEX,
BLIND_BACKGROUND_MAIN_COLOR_INDEX = 5, BLIND_BACKGROUND_MAIN_COLOR_INDEX,
BLIND_BACKGROUND_SECONDARY_COLOR_INDEX = 6, BLIND_BACKGROUND_SECONDARY_COLOR_INDEX,
BLIND_BACKGROUND_SHADOW_COLOR_INDEX = 7, BLIND_BACKGROUND_SHADOW_COLOR_INDEX,
}; };
#define BLIND_TYPE_INFO_TABLE \
BLIND_INFO(SMALL, small, FIX_ONE, 3) \
BLIND_INFO(BIG, big, (FIX_ONE * 3) / 2, 4) \
BLIND_INFO(BOSS, boss, FIX_ONE * 2, 5)
// clang-format off // clang-format off
enum BlindType enum BlindType
{ {
#define BLIND_INFO(NAME, name, multi, reward) \ // Normal Blinds
BLIND_TYPE_##NAME, BLIND_TYPE_SMALL,
BLIND_TYPE_INFO_TABLE BLIND_TYPE_BIG,
#undef BLIND_INFO
BLIND_TYPE_MAX, // Boss Blinds
BLIND_TYPE_BOSS,
BLIND_TYPE_HOOK = BLIND_TYPE_BOSS,
BLIND_TYPE_OX,
BLIND_TYPE_HOUSE,
BLIND_TYPE_WALL,
BLIND_TYPE_WHEEL,
BLIND_TYPE_ARM,
BLIND_TYPE_CLUB,
BLIND_TYPE_FISH,
BLIND_TYPE_PSYCHIC,
BLIND_TYPE_GOAD,
BLIND_TYPE_WATER,
BLIND_TYPE_WINDOW,
BLIND_TYPE_MANACLE,
BLIND_TYPE_EYE,
BLIND_TYPE_MOUTH,
BLIND_TYPE_PLANT,
BLIND_TYPE_SERPENT,
BLIND_TYPE_PILLAR,
BLIND_TYPE_NEEDLE,
BLIND_TYPE_HEAD,
BLIND_TYPE_TOOTH,
BLIND_TYPE_FLINT,
BLIND_TYPE_MARK,
// Showdown Blinds
BLIND_TYPE_SHOWDOWN,
BLIND_TYPE_ACORN = BLIND_TYPE_SHOWDOWN,
BLIND_TYPE_LEAF,
BLIND_TYPE_VESSEL,
BLIND_TYPE_HEART,
BLIND_TYPE_BELL,
// End of Blinds' list
BLIND_TYPE_MAX
}; };
// clang-format on // clang-format on
@@ -52,19 +93,9 @@ enum BlindState
BLIND_STATE_MAX, BLIND_STATE_MAX,
}; };
// TODO: Move this to a common interface for other palettes
typedef struct
{
const unsigned int* tiles;
const u16* palette;
u32 tid;
u32 pb;
} BlindGfxInfo;
typedef struct typedef struct
{ {
enum BlindType type; enum BlindType type;
BlindGfxInfo gfx_info;
FIXED score_req_multipler; FIXED score_req_multipler;
s32 reward; s32 reward;
} Blind; } Blind;
@@ -77,6 +108,12 @@ u32 blind_get_requirement(enum BlindType type, int ante);
int blind_get_reward(enum BlindType type); int blind_get_reward(enum BlindType type);
u16 blind_get_color(enum BlindType type, enum BlindColorIndex index); u16 blind_get_color(enum BlindType type, enum BlindColorIndex index);
void init_unbeaten_blinds_list(bool showdown);
enum BlindType roll_blind_type(bool showdown);
void set_blind_beaten(enum BlindType type);
void apply_blind_colors(enum BlindType type);
void apply_blind_tiles(enum BlindType type, int layer);
Sprite* blind_token_new(enum BlindType type, int x, int y, int sprite_index); Sprite* blind_token_new(enum BlindType type, int x, int y, int sprite_index);
#endif // BLIND_H #endif // BLIND_H
+25
View File
@@ -0,0 +1,25 @@
// clang-format off
#ifndef BLIND_GFX_H
#define BLIND_GFX_H
#include "blind_gfx0.h"
#include "blind_gfx1.h"
#include "blind_gfx2.h"
#include "blind_gfx3.h"
#include "blind_gfx4.h"
#include "blind_gfx5.h"
#include "blind_gfx6.h"
#include "blind_gfx7.h"
#include "blind_gfx8.h"
#include "blind_gfx9.h"
#include "blind_gfx10.h"
#include "blind_gfx11.h"
#include "blind_gfx12.h"
#include "blind_gfx13.h"
#include "blind_gfx14.h"
#include "blind_gfx15.h"
#include "blind_gfx16.h"
#include "blind_gfx17.h"
#endif
// clang-format on
+18
View File
@@ -0,0 +1,18 @@
DEF_BLIND_GFX(0)
DEF_BLIND_GFX(1)
DEF_BLIND_GFX(2)
DEF_BLIND_GFX(3)
DEF_BLIND_GFX(4)
DEF_BLIND_GFX(5)
DEF_BLIND_GFX(6)
DEF_BLIND_GFX(7)
DEF_BLIND_GFX(8)
DEF_BLIND_GFX(9)
DEF_BLIND_GFX(10)
DEF_BLIND_GFX(11)
DEF_BLIND_GFX(12)
DEF_BLIND_GFX(13)
DEF_BLIND_GFX(14)
DEF_BLIND_GFX(15)
DEF_BLIND_GFX(16)
DEF_BLIND_GFX(17)
+4 -5
View File
@@ -14,17 +14,16 @@
#define MAX_DEFINABLE_JOKERS 150 #define MAX_DEFINABLE_JOKERS 150
// Tile ID for the starting index in the tile memory
#define JOKER_TID (MAX_HAND_SIZE + MAX_SELECTION_SIZE) * JOKER_SPRITE_OFFSET
#define JOKER_SPRITE_OFFSET 16 // Offset for the joker sprites #define JOKER_SPRITE_OFFSET 16 // Offset for the joker sprites
#define JOKER_BASE_PB 4 // The starting palette index for the jokers #define JOKER_STARTING_LAYER 26
// Tile ID for the starting index in the tile memory
#define JOKER_TID (JOKER_STARTING_LAYER * JOKER_SPRITE_OFFSET)
#define JOKER_BASE_PB 3 // The starting palette index for the jokers
#define JOKER_LAST_PB (NUM_PALETTES - 1) #define JOKER_LAST_PB (NUM_PALETTES - 1)
// Currently allocating the rest of the palettes for the jokers. // Currently allocating the rest of the palettes for the jokers.
// This number needs to be decreased once we need to allocated palettes for other sprites // This number needs to be decreased once we need to allocated palettes for other sprites
// such as planet cards etc. // such as planet cards etc.
#define JOKER_STARTING_LAYER 27
#define BASE_EDITION 0 #define BASE_EDITION 0
#define FOIL_EDITION 1 #define FOIL_EDITION 1
#define HOLO_EDITION 2 #define HOLO_EDITION 2
+196 -71
View File
@@ -1,72 +1,75 @@
#include "blind.h" #include "blind.h"
#include "big_blind_gfx.h" #include "blind_gfx.h"
#include "boss_blind_gfx.h"
#include "graphic_utils.h" #include "graphic_utils.h"
#include "small_blind_gfx.h" #include "list.h"
#include "stdbool.h"
#include "util.h" #include "util.h"
#include <stdlib.h>
#include <tonc.h> #include <tonc.h>
static const unsigned int* blind_gfxTiles[] = {
#define DEF_BLIND_GFX(idx) blind_gfx##idx##Tiles,
#include "../include/def_blind_gfx_table.h"
#undef DEF_BLIND_GFX
};
static const unsigned short* blind_gfxPal[] = {
#define DEF_BLIND_GFX(idx) blind_gfx##idx##Pal,
#include "../include/def_blind_gfx_table.h"
#undef DEF_BLIND_GFX
};
// Bitfields storing blinds we have yet to beat during the current run
static List unbeaten_boss_blinds;
static List unbeaten_showdown_blinds;
// Maps the ante number to the base blind requirement for that ante. // Maps the ante number to the base blind requirement for that ante.
// The game starts at ante 1 which is at index 1 for base requirement 300. // The game starts at ante 1 which is at index 1 for base requirement 300.
// Ante 0 is also there in case it is ever reached. // Ante 0 is also there in case it is ever reached.
static const u32 ante_lut[] = {100, 300, 800, 2000, 5000, 11000, 20000, 35000, 50000}; static const u32 ante_lut[] = {100, 300, 800, 2000, 5000, 11000, 20000, 35000, 50000};
// Palettes for the blinds (Transparency, Text Color, Shadow, Highlight, Main Color) Use this:
// http://www.budmelvin.com/dev/15bitconverter.html
static const u16 small_blind_token_palette[PAL_ROW_LEN] =
{0x0000, 0x7FFF, 0x34A1, 0x5DCB, 0x5104, 0x55A0, 0x2D01, 0x34E0};
static const u16 big_blind_token_palette[PAL_ROW_LEN] =
{0x0000, 0x2527, 0x15F5, 0x36FC, 0x1E9C, 0x01B4, 0x0D0A, 0x010E};
// This variable is temporary, each boss blind will have its own unique palette
static const u16 boss_blind_token_palette[PAL_ROW_LEN] =
{0x0000, 0x2CC9, 0x3D0D, 0x5E14, 0x5171, 0x4D0F, 0x2CC8, 0x3089};
// clang-format off // clang-format off
static Blind _blind_type_map[BLIND_TYPE_MAX] = { static Blind _blind_type_map[BLIND_TYPE_MAX] = {
#define BLIND_INFO(NAME, name, multi, _reward) \ {BLIND_TYPE_SMALL, FIX_ONE, 3},
{ \ {BLIND_TYPE_BIG, (FIX_ONE * 3) / 2, 4},
.type = BLIND_TYPE_##NAME, \ {BLIND_TYPE_HOOK, FIX_ONE * 2, 5},
.gfx_info = \ {BLIND_TYPE_OX, FIX_ONE * 2, 5},
{ \ {BLIND_TYPE_HOUSE, FIX_ONE * 2, 5},
.tiles = name##_blind_gfxTiles, \ {BLIND_TYPE_WALL, FIX_ONE * 2, 5}, // x4 score requirement will be part of the effect
.palette = name##_blind_token_palette, \ {BLIND_TYPE_WHEEL, FIX_ONE * 2, 5},
.tid = NAME##_BLIND_TID, \ {BLIND_TYPE_ARM, FIX_ONE * 2, 5},
.pb = NAME##_BLIND_PB, \ {BLIND_TYPE_CLUB, FIX_ONE * 2, 5},
}, \ {BLIND_TYPE_FISH, FIX_ONE * 2, 5},
.score_req_multipler = multi, \ {BLIND_TYPE_PSYCHIC, FIX_ONE * 2, 5},
.reward = _reward, \ {BLIND_TYPE_GOAD, FIX_ONE * 2, 5},
}, {BLIND_TYPE_WATER, FIX_ONE * 2, 5},
BLIND_TYPE_INFO_TABLE {BLIND_TYPE_WINDOW, FIX_ONE * 2, 5},
#undef BLIND_INFO {BLIND_TYPE_MANACLE, FIX_ONE * 2, 5},
{BLIND_TYPE_EYE, FIX_ONE * 2, 5},
{BLIND_TYPE_MOUTH, FIX_ONE * 2, 5},
{BLIND_TYPE_PLANT, FIX_ONE * 2, 5},
{BLIND_TYPE_SERPENT, FIX_ONE * 2, 5},
{BLIND_TYPE_PILLAR, FIX_ONE * 2, 5},
{BLIND_TYPE_NEEDLE, FIX_ONE * 2, 5}, // Same as the Wall with normal requirement
{BLIND_TYPE_HEAD, FIX_ONE * 2, 5},
{BLIND_TYPE_TOOTH, FIX_ONE * 2, 5},
{BLIND_TYPE_FLINT, FIX_ONE * 2, 5},
{BLIND_TYPE_MARK, FIX_ONE * 2, 5},
{BLIND_TYPE_ACORN, FIX_ONE * 2, 8},
{BLIND_TYPE_LEAF, FIX_ONE * 2, 8},
{BLIND_TYPE_VESSEL, FIX_ONE * 2, 8}, // Same as the Wall with x6 requirement
{BLIND_TYPE_HEART, FIX_ONE * 2, 8},
{BLIND_TYPE_BELL, FIX_ONE * 2, 8}
}; };
// clang-format on // clang-format on
static void s_blind_gfx_init(enum BlindType type);
GBAL_UNUSED
void blind_set_boss_graphics(const unsigned int* tiles, const u16* palette)
{
// TODO: This function is unused and not fully fleshed out.
// We need to support more boss blind graphics in the future.
// The idea here is that we can call this function to set the boss up to
// render new tiles
//
// This will eventually be in it's own map mapping graphic data to
// boss types.
_blind_type_map[BLIND_TYPE_BOSS].gfx_info.tiles = tiles;
_blind_type_map[BLIND_TYPE_BOSS].gfx_info.palette = palette;
s_blind_gfx_init(BLIND_TYPE_BOSS);
}
void blind_init() void blind_init()
{ {
for (int i = 0; i < BLIND_TYPE_MAX; i++) // Set up the palette used by normal blind tokens.
{ // We will never need to edit it ever again.
s_blind_gfx_init(i); memcpy16(&pal_obj_bank[NORMAL_BLIND_PB], blind_gfxPal[0], NUM_ELEM_IN_ARR(blind_gfx0Pal));
}
return; return;
} }
@@ -85,34 +88,156 @@ int blind_get_reward(enum BlindType type)
return _blind_type_map[type].reward; return _blind_type_map[type].reward;
} }
u16 blind_get_color(enum BlindType type, enum BlindColorIndex index) // Fills the unbeaten boss blinds lists
// This must be called at the beginning of a run
void init_unbeaten_blinds_list(bool showdown)
{ {
return _blind_type_map[type].gfx_info.palette[index]; // create the lists when calling for the first time
static bool init = false;
if (!init)
{
init = true;
unbeaten_showdown_blinds = list_create();
unbeaten_boss_blinds = list_create();
} }
Sprite* blind_token_new(enum BlindType type, int x, int y, int sprite_index) List* p_unbeaten_blinds = showdown ? &unbeaten_showdown_blinds : &unbeaten_boss_blinds;
// empty the list just to be sure
list_clear(p_unbeaten_blinds);
int lower_blind = showdown ? BLIND_TYPE_SHOWDOWN : BLIND_TYPE_BOSS;
int upper_blind = showdown ? BLIND_TYPE_MAX - 1 : BLIND_TYPE_SHOWDOWN - 1;
for (int i = lower_blind; i <= upper_blind; i++)
{ {
u16 a0 = ATTR0_SQUARE | ATTR0_4BPP; list_push_back(p_unbeaten_blinds, &_blind_type_map[i]);
u16 a1 = ATTR1_SIZE_32x32; }
u32 tid = _blind_type_map[type].gfx_info.tid, pb = _blind_type_map[type].gfx_info.pb; }
Sprite* sprite = sprite_new(a0, a1, tid, pb, sprite_index); enum BlindType roll_blind_type(bool showdown)
{
List* p_unbeaten_blinds = showdown ? &unbeaten_showdown_blinds : &unbeaten_boss_blinds;
// Fill the list with all blinds if it is empty
// (happens on startup or if we have beaten all blinds)
if (list_is_empty(p_unbeaten_blinds))
{
init_unbeaten_blinds_list(showdown);
}
// roll a random blind among the unbeaten ones
int random_blind_idx = rand() % list_get_len(p_unbeaten_blinds);
Blind* random_blind = list_get_at_idx(p_unbeaten_blinds, random_blind_idx);
return random_blind->type;
}
void set_blind_beaten(enum BlindType type)
{
bool showdown = (type >= BLIND_TYPE_SHOWDOWN);
List* p_unbeaten_blinds = showdown ? &unbeaten_showdown_blinds : &unbeaten_boss_blinds;
// find the beaten blind idx in the list
int beaten_idx = 0;
Blind* beaten_blind = NULL;
ListItr itr = list_itr_create(p_unbeaten_blinds);
while ((beaten_blind = list_itr_next(&itr)))
{
if (beaten_blind->type == type)
{
break;
}
beaten_idx++;
}
if (beaten_idx < list_get_len(p_unbeaten_blinds))
{
list_remove_at_idx(p_unbeaten_blinds, beaten_idx);
}
}
static u32 get_blind_pb(enum BlindType type)
{
return (type <= BLIND_TYPE_BIG) ? NORMAL_BLIND_PB : BOSS_BLIND_PB;
}
static u32 get_blind_spritesheet_idx(enum BlindType type)
{
// See comment below in blind_get_color why we differenciate before/after the Mark
return (type < BLIND_TYPE_MARK)
? type / BLIND_TOKENS_PER_SPRITESHEET
: BLIND_TYPE_MARK / BLIND_TOKENS_PER_SPRITESHEET + type - BLIND_TYPE_MARK;
}
u16 blind_get_color(enum BlindType type, enum BlindColorIndex index)
{
// Do a little translation of palette idx -> custom array idx
// All blinds before the Mark are arranged in pairs with their palettte split in two
// | XX | 1 | 2 | 3 | 4 | 5 | 6 | 7 | -> first sprite
// | XX | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -> second sprite
// so we need to offset the color indices by 8 for blinds with an odd type
// From the Mark onwards, all sprites are alone in their spritesheet, so no need to offset
u32 color_idx = index + ((type < BLIND_TYPE_MARK)
? BLIND_TOKEN_PALETTE_SIZE * (type % BLIND_TOKENS_PER_SPRITESHEET)
: 0);
return blind_gfxPal[get_blind_spritesheet_idx(type)][color_idx];
}
void apply_blind_colors(enum BlindType type)
{
// keep track of active boss blind spritesheet to copy colors only when changing
static u32 active_boss_spritesheet = BLIND_TYPE_MAX;
u32 new_spritesheet = get_blind_spritesheet_idx(type);
// No need to update normal blind palette
if (type < BLIND_TYPE_BOSS || active_boss_spritesheet == new_spritesheet)
{
return;
}
active_boss_spritesheet = new_spritesheet;
// Just copy the palette as is to the sprite palette bank
memcpy16(
&pal_obj_bank[BOSS_BLIND_PB],
blind_gfxPal[active_boss_spritesheet],
NUM_ELEM_IN_ARR(blind_gfx0Pal)
);
}
static u32 get_layer_tile_index(int layer)
{
// All Blind sprites are stored sequentially and correspond to their IDs
return (BLIND_BASE_LAYER + layer) * BLIND_SPRITE_OFFSET;
}
void apply_blind_tiles(enum BlindType type, int layer)
{
u32 spritesheet_idx = get_blind_spritesheet_idx(type);
u32 sprite_idx = (type < BLIND_TYPE_MARK) ? type % BLIND_TOKENS_PER_SPRITESHEET : 0;
memcpy32(
&tile_mem[TILE_MEM_OBJ_CHARBLOCK0_IDX][get_layer_tile_index(layer)],
&blind_gfxTiles[spritesheet_idx][sprite_idx * BLIND_SPRITE_COPY_SIZE],
BLIND_SPRITE_COPY_SIZE
);
apply_blind_colors(type);
}
Sprite* blind_token_new(enum BlindType type, int x, int y, int layer)
{
apply_blind_tiles(type, layer);
Sprite* sprite = sprite_new(
ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF,
ATTR1_SIZE_32x32,
get_layer_tile_index(layer),
get_blind_pb(type),
BLIND_BASE_LAYER + layer
);
sprite_position(sprite, x, y); sprite_position(sprite, x, y);
return sprite; return sprite;
} }
static void s_blind_gfx_init(enum BlindType type)
{
// TODO: Re-add grit copy. You need to decouple the blind graphics first.
// This will allow this function to change the boss graphics info
// GRIT_CPY(&tile_mem[TILE_MEM_OBJ_CHARBLOCK0_IDX][_blind_type_map[type].pal_info.tid], tiles);
BlindGfxInfo* p_gfx = &_blind_type_map[type].gfx_info;
memcpy32(
&tile_mem[TILE_MEM_OBJ_CHARBLOCK0_IDX][p_gfx->tid],
p_gfx->tiles,
BLIND_SPRITE_COPY_SIZE
);
memcpy16(&pal_obj_bank[p_gfx->pb], p_gfx->palette, PAL_ROW_LEN);
}
+150 -70
View File
@@ -178,6 +178,16 @@ enum BlindSelectStates
BLIND_SELECT_MAX BLIND_SELECT_MAX
}; };
// The sprites that display the blinds when in "GAME_BLIND_SELECT" state
// There are only 3 blinds per Ante, so we don't need more sprites than that
enum BlindTokens
{
SMALL_BLIND,
BIG_BLIND,
BOSS_BLIND,
NUM_BLINDS_PER_ANTE
};
typedef struct typedef struct
{ {
u32 chips; u32 chips;
@@ -223,7 +233,7 @@ static void game_blind_select_start_anim_seq(void);
static void game_blind_select_handle_input(void); static void game_blind_select_handle_input(void);
static void game_blind_select_selected_anim_seq(void); static void game_blind_select_selected_anim_seq(void);
static void game_blind_select_display_blind_panel(void); static void game_blind_select_display_blind_panel(void);
static Rect game_blind_select_get_req_score_rect(enum BlindType blind); static Rect game_blind_select_get_req_score_rect(enum BlindTokens blind);
static void game_blind_select_print_blinds_reqs_and_rewards(void); static void game_blind_select_print_blinds_reqs_and_rewards(void);
static void game_round_end_start(void); static void game_round_end_start(void);
static void game_round_end_start_expand_popup(void); static void game_round_end_start_expand_popup(void);
@@ -565,14 +575,16 @@ static Sprite* playing_blind_token = NULL;
// The sprite that displays the blind when in "GAME_ROUND_END" state // The sprite that displays the blind when in "GAME_ROUND_END" state
static Sprite* round_end_blind_token = NULL; static Sprite* round_end_blind_token = NULL;
// The sprites that display the blinds when in "GAME_BLIND_SELECT" state static Sprite* blind_select_tokens[NUM_BLINDS_PER_ANTE] = {NULL};
static Sprite* blind_select_tokens[BLIND_TYPE_MAX] = {NULL};
static int current_blind = BLIND_TYPE_SMALL; static bool boss_rolled_this_ante = false;
// Will be rolled later, just giving it a valid value
static enum BlindType next_boss_blind = BLIND_TYPE_HOOK;
static enum BlindType current_blind = BLIND_TYPE_SMALL;
// The current state of the blinds, this is used to determine what the game is doing at any given // The current state of the blinds, this is used to determine what the game is doing at any given
// time // time
static enum BlindState blinds_states[BLIND_TYPE_MAX] = { static enum BlindState blinds_states[NUM_BLINDS_PER_ANTE] = {
BLIND_STATE_CURRENT, BLIND_STATE_CURRENT,
BLIND_STATE_UPCOMING, BLIND_STATE_UPCOMING,
BLIND_STATE_UPCOMING BLIND_STATE_UPCOMING
@@ -730,6 +742,49 @@ static inline void jokers_available_to_shop_init(void)
reset_shop_jokers(); reset_shop_jokers();
} }
static void reroll_boss_blind(bool no_tiles)
{
// Showdown blinds only show up on ante 8, 16, etc...
next_boss_blind = roll_blind_type((ante % 8 == 0) && (ante > 0));
if (!no_tiles)
{
apply_blind_tiles(next_boss_blind, BOSS_BLIND_TOKEN_LAYER);
}
}
static void blind_tokens_init()
{
reroll_boss_blind(true);
sprite_destroy(&blind_select_tokens[SMALL_BLIND]);
sprite_destroy(&blind_select_tokens[BIG_BLIND]);
sprite_destroy(&blind_select_tokens[BOSS_BLIND]);
blind_select_tokens[SMALL_BLIND] = blind_token_new(
BLIND_TYPE_SMALL,
CUR_BLIND_TOKEN_POS.x,
CUR_BLIND_TOKEN_POS.y,
SMALL_BLIND_TOKEN_LAYER
);
blind_select_tokens[BIG_BLIND] = blind_token_new(
BLIND_TYPE_BIG,
CUR_BLIND_TOKEN_POS.x,
CUR_BLIND_TOKEN_POS.y,
BIG_BLIND_TOKEN_LAYER
);
blind_select_tokens[BOSS_BLIND] = blind_token_new(
next_boss_blind,
CUR_BLIND_TOKEN_POS.x,
CUR_BLIND_TOKEN_POS.y,
BOSS_BLIND_TOKEN_LAYER
);
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{
obj_hide(blind_select_tokens[i]->obj);
}
}
void game_init() void game_init()
{ {
// Initialize all jokers list once // Initialize all jokers list once
@@ -754,28 +809,12 @@ void game_init()
score = STARTING_SCORE; score = STARTING_SCORE;
round = 0; round = 0;
blind_select_tokens[BLIND_TYPE_SMALL] = blind_token_new( // Initialize/reset unbeaten Boss/Showdown Blinds so they are all available
BLIND_TYPE_SMALL, init_unbeaten_blinds_list(false);
CUR_BLIND_TOKEN_POS.x, init_unbeaten_blinds_list(true);
CUR_BLIND_TOKEN_POS.y, boss_rolled_this_ante = false;
MAX_SELECTION_SIZE + MAX_HAND_SIZE + 3
);
blind_select_tokens[BLIND_TYPE_BIG] = blind_token_new(
BLIND_TYPE_BIG,
CUR_BLIND_TOKEN_POS.x,
CUR_BLIND_TOKEN_POS.y,
MAX_SELECTION_SIZE + MAX_HAND_SIZE + 4
);
blind_select_tokens[BLIND_TYPE_BOSS] = blind_token_new(
BLIND_TYPE_BOSS,
CUR_BLIND_TOKEN_POS.x,
CUR_BLIND_TOKEN_POS.y,
MAX_SELECTION_SIZE + MAX_HAND_SIZE + 5
);
obj_hide(blind_select_tokens[BLIND_TYPE_SMALL]->obj); blind_tokens_init();
obj_hide(blind_select_tokens[BLIND_TYPE_BIG]->obj);
obj_hide(blind_select_tokens[BLIND_TYPE_BOSS]->obj);
} }
static inline void discarded_jokers_update_loop(void) static inline void discarded_jokers_update_loop(void)
@@ -1458,12 +1497,10 @@ void change_background_legacy(enum BackgroundId id)
{ {
main_bg_se_copy_rect(BIG_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT); main_bg_se_copy_rect(BIG_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT);
} }
else if (current_blind == BLIND_TYPE_BOSS) else if (current_blind > BLIND_TYPE_BIG)
{ {
main_bg_se_copy_rect(BOSS_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT); main_bg_se_copy_rect(BOSS_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT);
affine_background_set_color(blind_get_color(current_blind, BLIND_SHADOW_COLOR_INDEX)
affine_background_set_color(
blind_get_color(BLIND_TYPE_BOSS, BLIND_SHADOW_COLOR_INDEX)
); );
} }
@@ -1554,7 +1591,16 @@ void change_background_legacy(enum BackgroundId id)
} }
else if (id == BG_BLIND_SELECT) else if (id == BG_BLIND_SELECT)
{ {
for (int i = 0; i < BLIND_TYPE_MAX; i++) // If this is the first time we see this menu this Ante, roll a boss blind
// This check is there for future safety, if we have any kind of pause menu
// so we don't reroll the boss blind every time this menu is opened
if (!boss_rolled_this_ante)
{
boss_rolled_this_ante = true;
reroll_boss_blind(false);
}
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{ {
obj_unhide(blind_select_tokens[i]->obj, 0); obj_unhide(blind_select_tokens[i]->obj, 0);
} }
@@ -1563,9 +1609,9 @@ void change_background_legacy(enum BackgroundId id)
// is shifted down by // is shifted down by
const int default_y = 89 + (TILE_SIZE * 12); const int default_y = 89 + (TILE_SIZE * 12);
// TODO refactor magic numbers '80/120/160' into a map to loop with // TODO refactor magic numbers '80/120/160' into a map to loop with
sprite_position(blind_select_tokens[BLIND_TYPE_SMALL], 80, default_y); sprite_position(blind_select_tokens[SMALL_BLIND], 80, default_y);
sprite_position(blind_select_tokens[BLIND_TYPE_BIG], 120, default_y); sprite_position(blind_select_tokens[BIG_BLIND], 120, default_y);
sprite_position(blind_select_tokens[BLIND_TYPE_BOSS], 160, default_y); sprite_position(blind_select_tokens[BOSS_BLIND], 160, default_y);
toggle_windows(false, true); toggle_windows(false, true);
@@ -1576,12 +1622,12 @@ void change_background_legacy(enum BackgroundId id)
// Copy boss blind colors to blind select palette // Copy boss blind colors to blind select palette
memset16( memset16(
&pal_bg_mem[1], &pal_bg_mem[1],
blind_get_color(BLIND_TYPE_BOSS, BLIND_BACKGROUND_MAIN_COLOR_INDEX), blind_get_color(next_boss_blind, BLIND_BACKGROUND_MAIN_COLOR_INDEX),
1 1
); );
memset16( memset16(
&pal_bg_mem[7], &pal_bg_mem[7],
blind_get_color(BLIND_TYPE_BOSS, BLIND_BACKGROUND_SHADOW_COLOR_INDEX), blind_get_color(next_boss_blind, BLIND_BACKGROUND_SHADOW_COLOR_INDEX),
1 1
); );
@@ -1602,7 +1648,7 @@ void change_background_legacy(enum BackgroundId id)
1 1
); );
for (int i = 0; i < BLIND_TYPE_MAX; i++) for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{ {
Rect curr_blind_rect = SINGLE_BLIND_SELECT_RECT; Rect curr_blind_rect = SINGLE_BLIND_SELECT_RECT;
@@ -1643,7 +1689,7 @@ void change_background_legacy(enum BackgroundId id)
{ {
y_from = 31; y_from = 31;
} }
else if (i == BLIND_TYPE_BOSS) else if (i > BLIND_TYPE_BIG)
{ {
x_from = x_to; x_from = x_to;
y_from = 30; y_from = 30;
@@ -1888,18 +1934,28 @@ static int deck_get_max_size(void)
static void increment_blind(enum BlindState increment_reason) static void increment_blind(enum BlindState increment_reason)
{ {
current_blind++; // cannot do blind++ anymore, we need to go SMALL->BIG->next_boss->SMALL...
if (current_blind >= BLIND_TYPE_MAX) switch (current_blind)
{ {
current_blind = 0; // defeated small blind: go to big
blinds_states[0] = BLIND_STATE_CURRENT; // Reset the blinds to the first one case BLIND_TYPE_SMALL:
blinds_states[1] = BLIND_STATE_UPCOMING; // Set the next blind to upcoming current_blind = BLIND_TYPE_BIG;
blinds_states[2] = BLIND_STATE_UPCOMING; // Set the next blind to upcoming blinds_states[SMALL_BLIND] = increment_reason;
} blinds_states[BIG_BLIND] = BLIND_STATE_CURRENT;
else break;
{ // defeated big blind: go to next boss
blinds_states[current_blind] = BLIND_STATE_CURRENT; case BLIND_TYPE_BIG:
blinds_states[current_blind - 1] = increment_reason; current_blind = next_boss_blind;
blinds_states[BIG_BLIND] = increment_reason;
blinds_states[BOSS_BLIND] = BLIND_STATE_CURRENT;
break;
// defeated a boss: reset everything
default:
current_blind = BLIND_TYPE_SMALL;
blinds_states[SMALL_BLIND] = BLIND_STATE_CURRENT; // Reset the blinds to the first one
blinds_states[BIG_BLIND] = BLIND_STATE_UPCOMING; // Set the next blind to upcoming
blinds_states[BOSS_BLIND] = BLIND_STATE_UPCOMING; // Set the next blind to upcoming
break;
} }
} }
@@ -1920,22 +1976,24 @@ static void game_round_on_init(GameVariables* vars)
cards_drawn = 0; cards_drawn = 0;
hand_selections = 0; hand_selections = 0;
sprite_destroy(&playing_blind_token);
playing_blind_token = blind_token_new( playing_blind_token = blind_token_new(
current_blind, current_blind,
CUR_BLIND_TOKEN_POS.x, CUR_BLIND_TOKEN_POS.x,
CUR_BLIND_TOKEN_POS.y, CUR_BLIND_TOKEN_POS.y,
MAX_SELECTION_SIZE + MAX_HAND_SIZE + 1 PLAYING_BLIND_TOKEN_LAYER
); // Create the blind token sprite at the top left corner ); // Create the blind token sprite at the top left corner
// TODO: Hide blind token and display it after sliding blind rect animation // TODO: Hide blind token and display it after sliding blind rect animation
// if (playing_blind_token != NULL) // if (playing_blind_token != NULL)
//{ //{
// obj_hide(playing_blind_token->obj); // Hide the blind token sprite for now // obj_hide(playing_blind_token->obj); // Hide the blind token sprite for now
//} //}
sprite_destroy(&round_end_blind_token);
round_end_blind_token = blind_token_new( round_end_blind_token = blind_token_new(
current_blind, current_blind,
81, 81,
86, 86,
MAX_SELECTION_SIZE + MAX_HAND_SIZE + 2 ROUND_END_BLIND_TOKEN_LAYER
); // Create the blind token sprite for round end ); // Create the blind token sprite for round end
if (round_end_blind_token != NULL) if (round_end_blind_token != NULL)
@@ -2364,11 +2422,15 @@ static inline void game_playing_handle_round_over(void)
if (score >= blind_get_requirement(current_blind, ante)) if (score >= blind_get_requirement(current_blind, ante))
{ {
if (current_blind == BLIND_TYPE_BOSS) if (current_blind > BLIND_TYPE_BIG)
{ {
if (ante < MAX_ANTE) if (ante < MAX_ANTE)
{ {
display_ante(++ante); display_ante(++ante);
// mark current boss blind as beaten and allow for reroll
set_blind_beaten(next_boss_blind);
boss_rolled_this_ante = false;
} }
else else
{ {
@@ -3590,7 +3652,7 @@ static void game_round_end_display_finished_blind()
int current_ante = ante; int current_ante = ante;
// Beating the boss blind increases the ante, so we need to display the previous ante value // Beating the boss blind increases the ante, so we need to display the previous ante value
if (current_blind == BLIND_TYPE_BOSS) if (current_blind > BLIND_TYPE_BIG)
current_ante--; current_ante--;
Rect blind_req_rect = ROUND_END_BLIND_REQ_RECT; Rect blind_req_rect = ROUND_END_BLIND_REQ_RECT;
@@ -4559,7 +4621,7 @@ static void game_blind_select_on_update(GameVariables* vars)
static inline void game_blind_select_erase_blind_reqs_and_rewards() static inline void game_blind_select_erase_blind_reqs_and_rewards()
{ {
for (enum BlindType curr_blind = 0; curr_blind < BLIND_TYPE_MAX; curr_blind++) for (enum BlindTokens curr_blind = SMALL_BLIND; curr_blind < NUM_BLINDS_PER_ANTE; curr_blind++)
{ {
Rect blind_req_and_reward_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT; Rect blind_req_and_reward_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT;
@@ -4579,7 +4641,25 @@ static inline void game_blind_select_erase_blind_reqs_and_rewards()
} }
} }
static Rect game_blind_select_get_req_score_rect(enum BlindType blind) static enum BlindType get_blind_type_from_token(enum BlindTokens blind)
{
enum BlindType blind_type;
switch (blind)
{
case SMALL_BLIND:
blind_type = BLIND_TYPE_SMALL;
break;
case BIG_BLIND:
blind_type = BLIND_TYPE_BIG;
break;
default:
blind_type = next_boss_blind;
break;
}
return blind_type;
}
static Rect game_blind_select_get_req_score_rect(enum BlindTokens blind)
{ {
Rect blind_req_score_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT; Rect blind_req_score_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT;
@@ -4596,11 +4676,11 @@ static Rect game_blind_select_get_req_score_rect(enum BlindType blind)
return blind_req_score_rect; return blind_req_score_rect;
} }
static inline void game_blind_select_print_blind_req(enum BlindType blind) static inline void game_blind_select_print_blind_req(enum BlindTokens blind)
{ {
Rect blind_req_score_rect = game_blind_select_get_req_score_rect(blind); Rect blind_req_score_rect = game_blind_select_get_req_score_rect(blind);
u32 blind_req = blind_get_requirement(blind, ante); u32 blind_req = blind_get_requirement(get_blind_type_from_token(blind), ante);
char blind_req_str_buff[UINT_MAX_DIGITS + 1]; char blind_req_str_buff[UINT_MAX_DIGITS + 1];
truncate_uint_to_suffixed_str( truncate_uint_to_suffixed_str(
@@ -4620,9 +4700,9 @@ static inline void game_blind_select_print_blind_req(enum BlindType blind)
); );
} }
static inline void game_blind_select_print_blind_reward(enum BlindType blind) static inline void game_blind_select_print_blind_reward(enum BlindTokens blind)
{ {
int blind_reward = blind_get_reward(blind); int blind_reward = blind_get_reward(get_blind_type_from_token(blind));
Rect blind_reward_rect = game_blind_select_get_req_score_rect(blind); Rect blind_reward_rect = game_blind_select_get_req_score_rect(blind);
// The reward is right below the score. // The reward is right below the score.
@@ -4645,7 +4725,7 @@ static inline void game_blind_select_print_blind_reward(enum BlindType blind)
static void game_blind_select_print_blinds_reqs_and_rewards(void) static void game_blind_select_print_blinds_reqs_and_rewards(void)
{ {
for (enum BlindType curr_blind = 0; curr_blind < BLIND_TYPE_MAX; curr_blind++) for (enum BlindTokens curr_blind = 0; curr_blind < NUM_BLINDS_PER_ANTE; curr_blind++)
{ {
game_blind_select_print_blind_req(curr_blind); game_blind_select_print_blind_req(curr_blind);
game_blind_select_print_blind_reward(curr_blind); game_blind_select_print_blind_reward(curr_blind);
@@ -4656,7 +4736,7 @@ static void game_blind_select_start_anim_seq()
{ {
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP); main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP);
for (int i = 0; i < BLIND_TYPE_MAX; i++) for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{ {
sprite_position( sprite_position(
blind_select_tokens[i], blind_select_tokens[i],
@@ -4675,7 +4755,7 @@ static void game_blind_select_start_anim_seq()
static void game_blind_select_handle_input() static void game_blind_select_handle_input()
{ {
if (timer == TM_BLIND_SELECT_START && current_blind == BLIND_TYPE_BOSS) if (timer == TM_BLIND_SELECT_START && current_blind > BLIND_TYPE_BIG)
{ {
selection_y = 0; selection_y = 0;
} }
@@ -4685,7 +4765,7 @@ static void game_blind_select_handle_input()
{ {
selection_y = 0; selection_y = 0;
} }
else if (key_hit(KEY_DOWN) && current_blind != BLIND_TYPE_BOSS) else if (key_hit(KEY_DOWN) && current_blind <= BLIND_TYPE_BIG)
{ {
selection_y = 1; selection_y = 1;
} }
@@ -4701,7 +4781,7 @@ static void game_blind_select_handle_input()
++round; ++round;
display_round(); display_round();
} }
else if (current_blind != BLIND_TYPE_BOSS) else if (current_blind <= BLIND_TYPE_BIG)
{ {
play_sfx(SFX_BUTTON, MM_BASE_PITCH_RATE, BUTTON_SFX_VOLUME); play_sfx(SFX_BUTTON, MM_BASE_PITCH_RATE, BUTTON_SFX_VOLUME);
increment_blind(BLIND_STATE_SKIPPED); increment_blind(BLIND_STATE_SKIPPED);
@@ -4717,7 +4797,7 @@ static void game_blind_select_handle_input()
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP); main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP);
} }
for (int i = 0; i < BLIND_TYPE_MAX; i++) for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{ {
sprite_position( sprite_position(
blind_select_tokens[i], blind_select_tokens[i],
@@ -4760,7 +4840,7 @@ static void game_blind_select_selected_anim_seq()
blinds_rect.top -= 1; // Because of the raised blind blinds_rect.top -= 1; // Because of the raised blind
main_bg_se_move_rect_1_tile_vert(blinds_rect, SCREEN_DOWN); main_bg_se_move_rect_1_tile_vert(blinds_rect, SCREEN_DOWN);
for (int i = 0; i < BLIND_TYPE_MAX; i++) for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{ {
sprite_position( sprite_position(
blind_select_tokens[i], blind_select_tokens[i],
@@ -4771,7 +4851,7 @@ static void game_blind_select_selected_anim_seq()
} }
else if (timer >= MENU_POP_OUT_ANIM_FRAMES) else if (timer >= MENU_POP_OUT_ANIM_FRAMES)
{ {
for (int i = 0; i < BLIND_TYPE_MAX; i++) for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
{ {
obj_hide(blind_select_tokens[i]->obj); obj_hide(blind_select_tokens[i]->obj);
} }
@@ -4987,9 +5067,9 @@ static void game_over_on_exit(GameVariables* vars)
// show up on the next run. // show up on the next run.
sprite_destroy(&playing_blind_token); sprite_destroy(&playing_blind_token);
sprite_destroy(&round_end_blind_token); sprite_destroy(&round_end_blind_token);
sprite_destroy(&blind_select_tokens[BLIND_TYPE_SMALL]); sprite_destroy(&blind_select_tokens[SMALL_BLIND]);
sprite_destroy(&blind_select_tokens[BLIND_TYPE_BIG]); sprite_destroy(&blind_select_tokens[BIG_BLIND]);
sprite_destroy(&blind_select_tokens[BLIND_TYPE_BOSS]); sprite_destroy(&blind_select_tokens[BOSS_BLIND]);
list_clear(&_owned_jokers_list); list_clear(&_owned_jokers_list);
list_clear(&_discarded_jokers_list); list_clear(&_discarded_jokers_list);
+1 -1
View File
@@ -179,7 +179,7 @@ JokerObject* joker_object_new(Joker* joker)
joker_object->joker = joker; joker_object->joker = joker;
joker_object->sprite_object = sprite_object_new(); joker_object->sprite_object = sprite_object_new();
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 = s_joker_get_sprite_idx_in_sheet(joker->id, joker_spritesheet_idx); int joker_idx = s_joker_get_sprite_idx_in_sheet(joker->id, joker_spritesheet_idx);