Optimize bit operations, style fix, cleanup
This commit is contained in:
+17
-14
@@ -4,7 +4,6 @@
|
||||
#include <tonc.h>
|
||||
|
||||
#define POOL_BITS_PER_WORD 32
|
||||
#define POOL_WORD_T u32
|
||||
#define POOL_MAX_CAPACITY 128
|
||||
|
||||
typedef struct PoolBitmap {
|
||||
@@ -13,11 +12,12 @@ typedef struct PoolBitmap {
|
||||
u32 nwords;
|
||||
} PoolBitmap;
|
||||
|
||||
void pool_clear_idx(PoolBitmap *bm, int idx);
|
||||
int pool_get_free_idx(PoolBitmap *bm);
|
||||
void pool_bm_clear_idx(PoolBitmap *bm, int idx);
|
||||
int pool_bm_get_free_idx(PoolBitmap *bm);
|
||||
|
||||
#define DECLARE_POOL_TYPE(type) \
|
||||
typedef struct type##Pool { \
|
||||
#define POOL_DECLARE_TYPE(type) \
|
||||
typedef struct \
|
||||
{ \
|
||||
PoolBitmap bm; \
|
||||
type * objects; \
|
||||
u32 max_entries; \
|
||||
@@ -26,29 +26,32 @@ int pool_get_free_idx(PoolBitmap *bm);
|
||||
void pool_free_##type(type##Pool *pool, type *obj); \
|
||||
void pool_init_##type(type##Pool *pool);
|
||||
|
||||
#define DEFINE_POOL_TYPE(type, capacity) \
|
||||
#define POOL_DEFINE_TYPE(type, capacity) \
|
||||
static type type##_storage[capacity]; \
|
||||
static u32 type##_bitmap_w[sizeof(POOL_WORD_T)] = {0}; \
|
||||
static type##Pool type##_pool = { \
|
||||
static u32 type##_bitmap_w[sizeof(u32)] = {0}; \
|
||||
static type##Pool type##_pool = \
|
||||
{ \
|
||||
.bm = { \
|
||||
.w = type##_bitmap_w, \
|
||||
.nbits = POOL_BITS_PER_WORD, \
|
||||
.nwords = sizeof(POOL_WORD_T)}, \
|
||||
.nwords = sizeof(u32)}, \
|
||||
.objects = type##_storage, \
|
||||
.max_entries = capacity, \
|
||||
}; \
|
||||
type * pool_get_##type(type##Pool *pool) { \
|
||||
int free_offset = pool_get_free_idx(&pool->bm); \
|
||||
type * pool_get_##type(type##Pool *pool) \
|
||||
{ \
|
||||
int free_offset = pool_bm_get_free_idx(&pool->bm); \
|
||||
if(free_offset == -1) return NULL; \
|
||||
return &pool->objects[free_offset]; \
|
||||
} \
|
||||
void pool_free_##type(type##Pool *pool, type *entry) { \
|
||||
void pool_free_##type(type##Pool *pool, type *entry) \
|
||||
{ \
|
||||
if(entry == NULL) return; \
|
||||
int offset = entry - &pool->objects[0]; \
|
||||
pool_clear_idx(&pool->bm, offset); \
|
||||
pool_bm_clear_idx(&pool->bm, offset); \
|
||||
}
|
||||
|
||||
#define POOL_GET(type) pool_get_##type(&type##_pool)
|
||||
#define POOL_FREE(type, obj) pool_free_##type(&type##_pool, obj)
|
||||
|
||||
#endif
|
||||
#endif // POOL_H
|
||||
|
||||
+1
-1
@@ -63,4 +63,4 @@ Sprite* sprite_object_get_sprite(SpriteObject* sprite_object);
|
||||
void sprite_object_set_focus(SpriteObject* sprite_object, bool focus);
|
||||
bool sprite_object_is_focused(SpriteObject* sprite_object);
|
||||
|
||||
#endif // SPRITE_H
|
||||
#endif // SPRITE_H
|
||||
+4
-4
@@ -14,10 +14,10 @@
|
||||
#define MAX_CARDS_PER_HAND (NUM_SUITS * NUM_RANKS)
|
||||
#define MAX_CARDS_ON_SCREEN 16
|
||||
|
||||
DECLARE_POOL_TYPE(Card);
|
||||
DEFINE_POOL_TYPE(Card, MAX_CARDS_PER_HAND);
|
||||
DECLARE_POOL_TYPE(CardObject);
|
||||
DEFINE_POOL_TYPE(CardObject, MAX_CARDS_ON_SCREEN);
|
||||
POOL_DECLARE_TYPE(Card);
|
||||
POOL_DEFINE_TYPE(Card, MAX_CARDS_PER_HAND);
|
||||
POOL_DECLARE_TYPE(CardObject);
|
||||
POOL_DEFINE_TYPE(CardObject, MAX_CARDS_ON_SCREEN);
|
||||
|
||||
// Card sprites lookup table. First index is the suit, second index is the rank. The value is the tile index.
|
||||
const static u16 card_sprite_lut[NUM_SUITS][NUM_RANKS] = {
|
||||
|
||||
+1
-1
@@ -586,7 +586,7 @@ void sort_cards()
|
||||
if (hand[i] != NULL)
|
||||
{
|
||||
// card_object_get_sprite() will not work here since we need the address
|
||||
sprite_destroy(&hand[i]->sprite_object->sprite);
|
||||
sprite_destroy(&(hand[i]->sprite_object->sprite));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -29,13 +29,14 @@ static const unsigned short *joker_gfxPal[] =
|
||||
#undef DEF_JOKER_GFX
|
||||
};
|
||||
|
||||
// Jokers in deck
|
||||
DECLARE_POOL_TYPE(Joker)
|
||||
DEFINE_POOL_TYPE(Joker, 8); // 8 should be fine, we only have a max of 2
|
||||
// This won't be more than the number of jokers in your current deck
|
||||
// plus the amount that can fit in the shop, 8 should be fine. For now...
|
||||
#define MAX_ACTIVE_JOKERS 8
|
||||
|
||||
// Jokers on screen
|
||||
DECLARE_POOL_TYPE(JokerObject)
|
||||
DEFINE_POOL_TYPE(JokerObject, 8) // 8 should be fine here as well, max of 2 from the shop in game.c
|
||||
POOL_DECLARE_TYPE(Joker)
|
||||
POOL_DEFINE_TYPE(Joker, MAX_ACTIVE_JOKERS)
|
||||
POOL_DECLARE_TYPE(JokerObject)
|
||||
POOL_DEFINE_TYPE(JokerObject, MAX_ACTIVE_JOKERS)
|
||||
|
||||
const static u8 edition_price_lut[MAX_EDITIONS] =
|
||||
{
|
||||
|
||||
+15
-9
@@ -1,14 +1,19 @@
|
||||
#include "pool.h"
|
||||
|
||||
void pool_clear_idx(PoolBitmap *bm, int idx) {
|
||||
u32 i = idx / POOL_BITS_PER_WORD; // word offset
|
||||
u32 b = idx % POOL_BITS_PER_WORD; // bit offset
|
||||
bm->w[i] &= ~((POOL_WORD_T)1 << b);
|
||||
void pool_bm_clear_idx(PoolBitmap *bm, int idx)
|
||||
{
|
||||
// Divide by 32 to get the word index
|
||||
u32 i = idx >> 5;
|
||||
// Get last 5-bits, same as a modulo (% 32) operation on positive numbers
|
||||
u32 b = idx & 31;
|
||||
bm->w[i] &= ~((u32)1 << b);
|
||||
}
|
||||
|
||||
int pool_get_free_idx(PoolBitmap *bm) {
|
||||
for (u32 i = 0; i < bm->nwords; i++) {
|
||||
POOL_WORD_T inv = ~bm->w[i];
|
||||
int pool_bm_get_free_idx(PoolBitmap *bm)
|
||||
{
|
||||
for (u32 i = 0; i < bm->nwords; i++)
|
||||
{
|
||||
u32 inv = ~bm->w[i];
|
||||
|
||||
// guard so we don't cal `ctz` with 0, since __builtin_ctz(0) is undefined
|
||||
// https://gcc.gnu.org/onlinedocs/gcc/Bit-Operation-Builtins.html#index-_005f_005fbuiltin_005fctz
|
||||
@@ -18,9 +23,10 @@ int pool_get_free_idx(PoolBitmap *bm) {
|
||||
// than 0 indicates there is a free slot. Then, when counting the trailing 0's, you can test very quickly
|
||||
// where the first free slot is. This operation prevents looping through every bit of filled flags, and
|
||||
// will instead operate only on the first word with free slots.
|
||||
if (inv) {
|
||||
if (inv)
|
||||
{
|
||||
int bit = __builtin_ctz(inv);
|
||||
bm->w[i] |= ((POOL_WORD_T)1 << bit);
|
||||
bm->w[i] |= ((u32)1 << bit);
|
||||
int idx = i * POOL_BITS_PER_WORD + bit;
|
||||
return idx;
|
||||
}
|
||||
|
||||
+4
-4
@@ -16,11 +16,11 @@
|
||||
OBJ_ATTR obj_buffer[MAX_SPRITES];
|
||||
OBJ_AFFINE *obj_aff_buffer = (OBJ_AFFINE*)obj_buffer;
|
||||
|
||||
DECLARE_POOL_TYPE(SpriteObject)
|
||||
DEFINE_POOL_TYPE(SpriteObject, MAX_SPRITES)
|
||||
POOL_DECLARE_TYPE(SpriteObject)
|
||||
POOL_DEFINE_TYPE(SpriteObject, MAX_SPRITES)
|
||||
|
||||
DECLARE_POOL_TYPE(Sprite)
|
||||
DEFINE_POOL_TYPE(Sprite, MAX_SPRITES)
|
||||
POOL_DECLARE_TYPE(Sprite)
|
||||
POOL_DEFINE_TYPE(Sprite, MAX_SPRITES)
|
||||
|
||||
static bool free_affines[MAX_AFFINES] = {false};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user