Update for PR

Readd sprite tracker to not reuse indices
check for capacity when returning pool entries
Update script for printing memory map
This commit is contained in:
Rickey Fehr
2025-10-07 18:41:21 -07:00
parent d499abe2c4
commit 16059ab632
5 changed files with 43 additions and 7 deletions
+4 -3
View File
@@ -10,6 +10,7 @@ typedef struct PoolBitmap {
u32 *w;
u32 nbits;
u32 nwords;
u32 cap;
} PoolBitmap;
void pool_bm_clear_idx(PoolBitmap *bm, int idx);
@@ -20,7 +21,6 @@ int pool_bm_get_free_idx(PoolBitmap *bm);
{ \
PoolBitmap bm; \
type * objects; \
u32 max_entries; \
} type##Pool; \
type *pool_get_##type(); \
void pool_free_##type(type *obj); \
@@ -33,9 +33,10 @@ int pool_bm_get_free_idx(PoolBitmap *bm);
.bm = { \
.w = type##_bitmap_w, \
.nbits = POOL_BITS_PER_WORD, \
.nwords = sizeof(u32)}, \
.nwords = sizeof(u32), \
.cap = capacity, \
}, \
.objects = type##_storage, \
.max_entries = capacity, \
}; \
type * pool_get_##type() \
{ \
+2 -1
View File
@@ -14,6 +14,7 @@ typedef struct
OBJ_ATTR *obj;
OBJ_AFFINE *aff;
POINT pos;
int idx;
} Sprite;
// A sprite object is a sprite that is selectable and movable in animation
@@ -66,4 +67,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
+17 -2
View File
@@ -4,7 +4,7 @@ set -euo pipefail
POOL_DEF_FILE='./include/pools.def'
ELF_FILE="${1-./build/balatro-gba.elf}"
READELF='/opt/devkitpro/devkitARM/bin/arm-none-eabi-readelf'
READELF="${READELF-/opt/devkitpro/devkitARM/bin/arm-none-eabi-readelf}"
TOTAL_BYTES=0
if [ ! -f "$ELF_FILE" ]; then
@@ -14,6 +14,13 @@ if [ ! -f "$ELF_FILE" ]; then
exit 1
fi
if [ ! -x "$READELF" ]; then
echo "ERROR: \"$READELF\" is not an executable file."
echo "You can override the file location for 'arm-none-eabi-readelf' with the READELF env variable."
echo " e.g. $ READELF=\"/my/custom/location/arm-none-eabi-readelf\" $(basename $0) <file>"
exit 1
fi
print_line_break() {
echo "--------------------------------------------------------------------"
}
@@ -41,12 +48,20 @@ for name in $(get_pool_names); do
sed -E 's@ +@ @g; s@^ @@' | \
tr -d '\n' \
)"
output_bm="$( \
"$READELF" -sW "$ELF_FILE" | \
grep -E "${name}_bitmap_w" | \
grep OBJECT | \
sed -E 's@ +@ @g; s@^ @@' | \
tr -d '\n' \
)"
address="$(cut -d ' ' -f 2 <<< $output_pool)"
pool_size="$(cut -d ' ' -f 3 <<< $output_pool)"
func_size="$(cut -d ' ' -f 3 <<< $output_func)"
bm_size=16 #always gonna be 16, 4 * sizeof(u32)
bm_size="$(cut -d ' ' -f 3 <<< $output_bm)"
#bm_size=16 #always gonna be 16, 4 * sizeof(u32)
TOTAL_BYTES=$(( TOTAL_BYTES + pool_size + func_size + bm_size ))
+1 -1
View File
@@ -28,7 +28,7 @@ int pool_bm_get_free_idx(PoolBitmap *bm)
int bit = __builtin_ctz(inv);
bm->w[i] |= ((u32)1 << bit);
int idx = i * POOL_BITS_PER_WORD + bit;
return idx;
return (idx < bm->cap) ? idx : -1;
}
}
+19
View File
@@ -15,11 +15,23 @@
OBJ_ATTR obj_buffer[MAX_SPRITES];
OBJ_AFFINE *obj_aff_buffer = (OBJ_AFFINE*)obj_buffer;
typedef struct
{
bool used;
Sprite* p_sprite;
} _UsedSprite;
static bool free_affines[MAX_AFFINES] = {false};
static _UsedSprite free_sprites[MAX_SPRITES] = {{0}};
// Sprite methods
Sprite *sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, int sprite_index)
{
if(free_sprites[sprite_index].used)
{
return free_sprites[sprite_index].p_sprite;
}
Sprite* sprite = POOL_GET(Sprite);
sprite->obj = NULL;
@@ -41,6 +53,7 @@ Sprite *sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, int sprite_index)
if (aff_index == MAX_AFFINES)
{
POOL_FREE(Sprite, sprite);
return NULL;
}
@@ -57,6 +70,9 @@ Sprite *sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, int sprite_index)
obj_set_attr(sprite->obj, a0, a1, ATTR2_PALBANK(pb) | tid);
}
free_sprites[sprite_index].used = true;
free_sprites[sprite_index].p_sprite = sprite;
sprite->idx = sprite_index;
return sprite;
}
@@ -72,6 +88,9 @@ void sprite_destroy(Sprite **sprite)
free_affines[(*sprite)->aff - obj_aff_buffer] = false;
}
free_sprites[(*sprite)->idx].used = false;
free_sprites[(*sprite)->idx].p_sprite = NULL;
POOL_FREE(Sprite, *sprite);
*sprite = NULL;