Ensure number bubbles are always on screen and visible

This commit is contained in:
Lucas S. Vieira 2024-12-22 17:48:02 -03:00
parent 3c906cfcd4
commit b3fe14c15d
3 changed files with 40 additions and 11 deletions

View file

@ -64,6 +64,10 @@ typedef struct {
// XY velocity
int32_t spdx;
int32_t spdy;
// Relative XY position (if needed)
int32_t rx;
int32_t ry;
} ObjectFreePos;
typedef struct {

View file

@ -293,13 +293,21 @@ begin_render_routine:
poly->tpage = getTPage(1, 0, 576, 0);
poly->clut = getClut(0, 481);
sort_prim(poly,
((state->id == OBJ_RING)
|| (state->id == OBJ_SHIELD)
|| (state->id == OBJ_EXPLOSION)
|| (state->id == OBJ_BUBBLE))
? OTZ_LAYER_OBJECTS
: OTZ_LAYER_PLAYER);
uint32_t layer = ((state->id == OBJ_RING)
|| (state->id == OBJ_SHIELD)
|| (state->id == OBJ_EXPLOSION)
|| (state->id == OBJ_BUBBLE))
? OTZ_LAYER_OBJECTS
: OTZ_LAYER_PLAYER;
// NOTABLE EXCEPTION: if this is a bubble object which animation has gone
// beyond the first digit display, it should be rendered on text layer
if((state->id == OBJ_BUBBLE)
&& (state->anim_state.animation >= 3)
&& (state->anim_state.frame >= 5))
layer = OTZ_LAYER_HUD;
sort_prim(poly, layer);
after_render:

View file

@ -760,6 +760,14 @@ _bubble_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
// Start with a 50% chance random direction
state->timer *= ((rand() % 2) * 2) - 1;
// If this is a number bubble, we need to initialize its position
// relative to screen center, because it will hang around at the same
// X and Y position on screen.
if(state->anim_state.animation >= 3) {
state->freepos->rx = state->freepos->vx - camera.pos.vx;
state->freepos->ry = state->freepos->vy - camera.pos.vy;
}
}
// A bubble can be of three diameters: small (8), medium (12) or big (32).
@ -776,7 +784,9 @@ _bubble_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
// on number bubbles before the actual number frames show up
if(!((state->anim_state.animation >= 3) && (state->anim_state.frame >= 5))) {
// Bubbles should always be ascending with a 0.5 speed (-0x800)
state->freepos->vy -= 0x800;
if(state->anim_state.animation < 3)
state->freepos->vy -= 0x800;
else state->freepos->ry -= 0x800;
// Bubbles also sway back-and-forth in a sine-like movement.
// x = initial_x + 8 * sin(timer / 128.0)
@ -785,7 +795,16 @@ _bubble_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
state->freepos->spdx *= -1;
state->timer = 128;
}
state->freepos->vx += state->freepos->spdx;
if(state->anim_state.animation < 3)
state->freepos->vx += state->freepos->spdx;
else state->freepos->rx += state->freepos->spdx;
}
// Again: if this is a stick-around bubble (number bubble), our free position
// should be relative to camera center
if(state->anim_state.animation >= 3) {
state->freepos->vx = state->freepos->rx + camera.pos.vx;
state->freepos->vy = state->freepos->ry + camera.pos.vy;
}
// When a normal bubble's top interact with water surface, destroy it.
@ -820,6 +839,4 @@ _bubble_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
return;
}
}
}