mirror of
https://github.com/cellos51/balatro-gba.git
synced 2026-09-08 17:06:33 -05:00
sprite optimizations + static array fix (#454)
Some checks failed
Build and Deploy Doxygen Docs / docs (push) Has been cancelled
Some checks failed
Build and Deploy Doxygen Docs / docs (push) Has been cancelled
* optimizations * fix prototype * clang-format * changes * fix bug * fix bug that came back after rebase * make is_sprite_object_static more readable * make it not broken * actually make it compile... * clang-format * remove first extra check * remove second extra check * remove third extra check * helper function 1 * second helper function * how did i do this that wrong * seperate epsilon * combine if statements * clarify comment * remove redundant checks * Remove braces around return Co-authored-by: Rickey <ric@rf3.xyz> * Move comment to above Co-authored-by: Rickey <ric@rf3.xyz> * clang-format * simplify using abs() Co-authored-by: Rickey <ric@rf3.xyz> * fix syntax error from suggestion * drop second epsilon + use abs() * update comment * extract sprite_oject_needs_position_sync from is_sprite_object_static * figured out the root cause :) * make it compile --------- Co-authored-by: Rickey <ric@rf3.xyz>
This commit is contained in:
@@ -236,7 +236,7 @@ void sprite_object_reset_transform(SpriteObject* sprite_object);
|
||||
*
|
||||
* @param sprite_object pointer to SpriteObject to update. Cannot be **NULL**.
|
||||
*/
|
||||
void sprite_object_update(SpriteObject* sprite_object);
|
||||
IWRAM_CODE void sprite_object_update(SpriteObject* sprite_object);
|
||||
|
||||
/**
|
||||
* @brief Shake SpriteObject on screen and play a sound
|
||||
|
||||
@@ -561,7 +561,7 @@ static inline void discarded_jokers_update_loop(void)
|
||||
|
||||
static inline void held_jokers_update_loop(void)
|
||||
{
|
||||
const int spacing_lut[MAX_JOKERS_HELD_SIZE][MAX_JOKERS_HELD_SIZE] = {
|
||||
static const int spacing_lut[MAX_JOKERS_HELD_SIZE][MAX_JOKERS_HELD_SIZE] = {
|
||||
{0, 0, 0, 0, 0 },
|
||||
{13, -13, 0, 0, 0 },
|
||||
{26, 0, -26, 0, 0 },
|
||||
@@ -1838,6 +1838,7 @@ static inline void card_draw(void)
|
||||
|
||||
card_object->sprite_object->x = deck_x;
|
||||
card_object->sprite_object->y = deck_y;
|
||||
sprite_position(card_object->sprite_object->sprite, fx2int(deck_x), fx2int(deck_y));
|
||||
|
||||
hand[++hand_top] = card_object;
|
||||
|
||||
@@ -2828,10 +2829,17 @@ static inline void cards_in_hand_update_loop(void)
|
||||
{
|
||||
hand_y -= int2fx(CARD_FOCUSED_SEL_Y);
|
||||
}
|
||||
|
||||
if (i != selected_card_idx && hand[i]->sprite_object->y > hand_y)
|
||||
{
|
||||
hand[i]->sprite_object->y = hand_y;
|
||||
sprite_position(
|
||||
hand[i]->sprite_object->sprite,
|
||||
fx2int(hand[i]->sprite_object->x),
|
||||
fx2int(hand_y)
|
||||
);
|
||||
// Set target y to match y. Ensures target is updated even when vy becomes
|
||||
// 0, preventing immediate snap back.
|
||||
hand[i]->sprite_object->ty = hand_y;
|
||||
hand[i]->sprite_object->vy = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,9 +124,8 @@ void game_main_menu_on_init(void)
|
||||
|
||||
void game_main_menu_on_update(void)
|
||||
{
|
||||
card_object_update(main_menu_ace);
|
||||
main_menu_ace->sprite_object->trotation = lu_sin((g_game_vars.timer << 8) / 2) / 3;
|
||||
main_menu_ace->sprite_object->rotation = main_menu_ace->sprite_object->trotation;
|
||||
card_object_update(main_menu_ace);
|
||||
|
||||
// Seed randomization
|
||||
g_game_vars.rng_seed++;
|
||||
|
||||
@@ -209,8 +209,27 @@ void sprite_object_reset_transform(SpriteObject* sprite_object)
|
||||
sprite_object->vrotation = 0;
|
||||
}
|
||||
|
||||
void sprite_object_update(SpriteObject* sprite_object)
|
||||
static inline bool sprite_object_has_velocity(const SpriteObject* sprite_object)
|
||||
{
|
||||
return sprite_object->vx != 0 || sprite_object->vy != 0 || sprite_object->vscale != 0 ||
|
||||
sprite_object->vrotation != 0;
|
||||
}
|
||||
|
||||
static inline bool sprite_object_at_target(const SpriteObject* s)
|
||||
{
|
||||
return s->x == s->tx && s->y == s->ty && s->scale == s->tscale && s->rotation == s->trotation;
|
||||
}
|
||||
|
||||
static inline bool is_sprite_object_static(const SpriteObject* sprite_object)
|
||||
{
|
||||
return !sprite_object_has_velocity(sprite_object) && sprite_object_at_target(sprite_object);
|
||||
}
|
||||
|
||||
IWRAM_CODE void sprite_object_update(SpriteObject* sprite_object)
|
||||
{
|
||||
if (is_sprite_object_static(sprite_object))
|
||||
return;
|
||||
|
||||
sprite_object->vx += ((sprite_object->tx - sprite_object->x) * g_game_vars.game_speed) / 8;
|
||||
sprite_object->vy += ((sprite_object->ty - sprite_object->y) * g_game_vars.game_speed) / 8;
|
||||
|
||||
@@ -220,10 +239,10 @@ void sprite_object_update(SpriteObject* sprite_object)
|
||||
// Rotate the card when it's played
|
||||
sprite_object->vrotation += (sprite_object->trotation - sprite_object->rotation) / 8;
|
||||
|
||||
// set velocity to 0 if it's close enough to the target
|
||||
const FIXED epsilon = (FIX_ONE >> 6); // = 1/2^6 = 0.015625
|
||||
if (sprite_object->vx < epsilon && sprite_object->vx > -epsilon &&
|
||||
sprite_object->vy < epsilon && sprite_object->vy > -epsilon)
|
||||
|
||||
// Snap to target position when velocity is negligible to avoid infinite approach
|
||||
if (abs(sprite_object->vx) < epsilon && abs(sprite_object->vy) < epsilon)
|
||||
{
|
||||
sprite_object->vx = 0;
|
||||
sprite_object->vy = 0;
|
||||
@@ -243,10 +262,10 @@ void sprite_object_update(SpriteObject* sprite_object)
|
||||
}
|
||||
|
||||
// Set scale to 0 if it's close enough to the target
|
||||
if (sprite_object->vscale < epsilon && sprite_object->vscale > -epsilon)
|
||||
if (abs(sprite_object->vscale) < epsilon)
|
||||
{
|
||||
sprite_object->vscale = 0;
|
||||
sprite_object->scale = sprite_object->tscale; // Set the scale to the target scale
|
||||
sprite_object->scale = sprite_object->tscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -256,14 +275,13 @@ void sprite_object_update(SpriteObject* sprite_object)
|
||||
sprite_object->scale += sprite_object->vscale;
|
||||
}
|
||||
|
||||
// Set rotation to 0 if it's close enough to the target
|
||||
if (sprite_object->vrotation < epsilon && sprite_object->vrotation > -epsilon)
|
||||
// For rotation, prioritize snapping to target if close enough, then zero velocity.
|
||||
if (abs(sprite_object->vrotation) < epsilon)
|
||||
{
|
||||
sprite_object->vrotation = 0;
|
||||
// Set the rotation to the target rotation
|
||||
sprite_object->rotation = sprite_object->trotation;
|
||||
}
|
||||
else
|
||||
else // Apply damping and update rotation if not yet settled
|
||||
{
|
||||
sprite_object->vrotation =
|
||||
(sprite_object->vrotation * SPRING_DAMP_NUMERATOR + SPRING_DAMP_ROUNDING) >>
|
||||
|
||||
Reference in New Issue
Block a user