From b3fe14c15df1d9beac0117131ff74fc2ee0630aa Mon Sep 17 00:00:00 2001 From: "Lucas S. Vieira" Date: Sun, 22 Dec 2024 17:48:02 -0300 Subject: [PATCH] Ensure number bubbles are always on screen and visible --- include/object_state.h | 4 ++++ src/object_state.c | 22 +++++++++++++++------- src/object_state_update.c | 25 +++++++++++++++++++++---- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/include/object_state.h b/include/object_state.h index e678303..0284a9f 100644 --- a/include/object_state.h +++ b/include/object_state.h @@ -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 { diff --git a/src/object_state.c b/src/object_state.c index f52eab8..16dd762 100644 --- a/src/object_state.c +++ b/src/object_state.c @@ -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: diff --git a/src/object_state_update.c b/src/object_state_update.c index 2bff5c0..ffe1be5 100644 --- a/src/object_state_update.c +++ b/src/object_state_update.c @@ -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; } } - - }