From 51826ee42936071a2f00f8feb124d20f9cfe2cd8 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 9 Dec 2025 11:59:25 -0600 Subject: [PATCH 01/19] zTalkBox: Migrate weak functions from zEntPlayerOOBState --- src/SB/Game/zEntPlayerOOBState.cpp | 16 ---------------- src/SB/Game/zTalkBox.h | 29 ++++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index b3d5360cd..abbd260a4 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -387,22 +387,6 @@ bool oob_state::IsPlayerInControl() return oob_state::shared.control == 0; } -WEAK ztalkbox::callback::callback() -{ -} -WEAK void ztalkbox::callback::on_signal(U32) -{ -} -WEAK void ztalkbox::callback::on_start() -{ -} -WEAK void ztalkbox::callback::on_stop() -{ -} -WEAK void ztalkbox::callback::on_answer(ztalkbox::answer_enum) -{ -} - WEAK F32 xVec2::dot(const xVec2& b) const { return (x * b.x) + (y * b.y); diff --git a/src/SB/Game/zTalkBox.h b/src/SB/Game/zTalkBox.h index 0783208af..3b834aa5a 100644 --- a/src/SB/Game/zTalkBox.h +++ b/src/SB/Game/zTalkBox.h @@ -77,11 +77,30 @@ struct ztalkbox : xBase struct callback { - callback(); - virtual void on_signal(U32); - virtual void on_start(); - virtual void on_stop(); - virtual void on_answer(answer_enum); + callback() + { + + } + + virtual void on_signal(U32) + { + + } + + virtual void on_start() + { + + } + + virtual void on_stop() + { + + } + + virtual void on_answer(answer_enum answer) + { + + } }; struct From 1b9681f3a2633dc9c99e4401864fc1cda8507a94 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 9 Dec 2025 11:59:57 -0600 Subject: [PATCH 02/19] Configure zEntPlayerOOBState.cpp for sym on compiler flags --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index a520d2cca..9abc51445 100644 --- a/configure.py +++ b/configure.py @@ -573,7 +573,7 @@ def MatchingFor(*versions): Object(Matching, "SB/Core/x/xVolume.cpp"), Object(NonMatching, "SB/Core/x/xParEmitterType.cpp"), Object(Matching, "SB/Core/x/xRenderState.cpp"), - Object(NonMatching, "SB/Game/zEntPlayerOOBState.cpp"), + Object(NonMatching, "SB/Game/zEntPlayerOOBState.cpp", extra_cflags=["-sym on"]), Object(Equivalent, "SB/Core/x/xClumpColl.cpp"), Object(NonMatching, "SB/Core/x/xEntBoulder.cpp"), Object(NonMatching, "SB/Core/x/xGrid.cpp"), From 29b77cd3e06b1922008b5fbfe3452541ffeb4fec Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 9 Dec 2025 12:00:31 -0600 Subject: [PATCH 03/19] zEntPlayerOOBState: Initial match for render_model and 100% match for move_up --- src/SB/Game/zEntPlayerOOBState.cpp | 34 ++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index abbd260a4..c9f68415b 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -106,9 +106,39 @@ namespace oob_state zCameraTweakGlobal_Init(); } - static void move_up(xVec3& vec, F32 arg1) + static void render_model(xModelInstance& model, const xVec3& unk_r4, const xVec3& unk_r5, const xVec3& unk_r6) { - xMat4x3Tolocal(&vec, &globals.camera.mat, &vec); + basic_rect screen_rect = { 0.0f, 0.0f, 1.0f, 1.0f }; + screen_rect.x = unk_r4.x; + screen_rect.y = unk_r4.y; + + xVec3 from = { 0.0f, 0.0f, 1.0f }; + + xVec3 to = { 0.0f, 0.0f, 0.0f }; + to.z = -unk_r4.z; + + xMat3x3 scaledMat; + xMat3x3 eulerMat; + xMat4x3 outMat; + xMat3x3ScaleC(&scaledMat, unk_r5.x * (1.0f + unk_r4.z), unk_r5.y * (1.0f + unk_r4.z), 1.0f + unk_r4.z); + xMat3x3Euler(&eulerMat, &unk_r6); + xMat3x3Mul(&outMat, &eulerMat, &scaledMat); + + outMat.pos = 0.0f; + outMat.flags = 0x0; + xModelSetFrame(&model, &outMat); + + xModelRender2D(model, screen_rect, from, to); + } + + static void move_up(xVec3& vec, F32 scale) + { + xMat4x3& camMat = globals.camera.mat; + + xVec3 localCoords; + xMat4x3Tolocal(&localCoords, &camMat, &vec); + + vec += camMat.up * scale * localCoords.z; } static bool assume_player_is_stupid() From 2f552215c69fd4a95b48e54f5243383b23189e13 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 9 Dec 2025 12:12:45 -0600 Subject: [PATCH 04/19] zSurface: Add declaration for zSurfaceGetOutOfBoundsDelay --- src/SB/Game/zSurface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SB/Game/zSurface.h b/src/SB/Game/zSurface.h index 516fb7299..3169292c2 100644 --- a/src/SB/Game/zSurface.h +++ b/src/SB/Game/zSurface.h @@ -137,5 +137,6 @@ void zSurfaceSetup(xSurface* s); void zSurfaceUpdate(xBase* to, xScene*, F32 dt); void zSurfaceGetName(S32 type, char* buffer); xSurface& zSurfaceGetDefault(); +F32 zSurfaceGetOutOfBoundsDelay(const xSurface& surface); #endif From ca879a91f8db417784aa3e66fea88cf56655db20 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 9 Dec 2025 14:05:26 -0600 Subject: [PATCH 05/19] OOBState: Type cleanup in header structs --- src/SB/Game/zEntPlayerOOBState.h | 98 ++++++++++++++++---------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index 1635ece3b..e205af871 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -90,19 +90,19 @@ namespace oob_state substate_enum move_substate; substate_enum fade_substate; xVec3 player_start; - float reorient_time; - float angle_delta; - float delay; - float fade_start_time; - float fade_time; - unsigned int scene_reset; + F32 reorient_time; + F32 angle_delta; + F32 delay; + F32 fade_start_time; + F32 fade_time; + U32 scene_reset; // Todo: this is not in the DWARF, but is required for // tutorial_callback::on_stop to match. Probably // not correct. char pad[4]; - unsigned char finished_tutorial; + U8 finished_tutorial; substate_enum (*updatess)(grab_state_type&, xScene&, float&)[10]; bool update_reorient(xScene&, F32&); @@ -144,30 +144,30 @@ namespace oob_state struct _class_9 { - int flags; + S32 flags; state_type* state; - unsigned char control; + U8 control; state_type* states[4]; - float out_time; - float max_out_time; - float reset_time; + F32 out_time; + F32 max_out_time; + F32 reset_time; xModelInstance* model; xVec2 loc; xVec2 dir; - float fade_alpha; - unsigned char render_hand; - unsigned char vertical; - float vel; - float accel; + F32 fade_alpha; + U8 render_hand; + U8 vertical; + F32 vel; + F32 accel; ztalkbox* tutorial; struct { - float near_d; - float near_h; - float near_pitch; - float far_d; - float far_h; - float far_pitch; + F32 near_d; + F32 near_h; + F32 near_pitch; + F32 far_d; + F32 far_h; + F32 far_pitch; xMat4x3* tgt_mat; xMat4x3* tgt_omat; } cam_data; @@ -175,41 +175,41 @@ namespace oob_state struct tagFixed { - float out_time; - float reset_time; - float cam_dist; - float cam_height; - float cam_pitch; - float reorient_time; + F32 out_time; + F32 reset_time; + F32 cam_dist; + F32 cam_height; + F32 cam_pitch; + F32 reorient_time; char* hand_model; xVec2 in_loc; xVec2 out_loc; struct { - float in_wait_time; - float in_vel; - float in_stop_dist; - float out_wait_time; - float out_vel; - float out_start_dist; - float fade_start_time; - float fade_time; + F32 in_wait_time; + F32 in_vel; + F32 in_stop_dist; + F32 out_wait_time; + F32 out_vel; + F32 out_start_dist; + F32 fade_start_time; + F32 fade_time; } grab; struct { - float in_vel; - float in_stop_dist; - float out_wait_time; - float out_vel; - float out_start_dist; - float fade_start_time; - float fade_time; + F32 in_vel; + F32 in_stop_dist; + F32 out_wait_time; + F32 out_vel; + F32 out_start_dist; + F32 fade_start_time; + F32 fade_time; } drop; - float hand_size_x; - float hand_size_y; - float hand_yaw; - float hand_pitch; - float hand_roll; + F32 hand_size_x; + F32 hand_size_y; + F32 hand_yaw; + F32 hand_pitch; + F32 hand_roll; }; } // namespace From f2df61faa78555024cc4c74d9b702e6eb4c1c32c Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Tue, 9 Dec 2025 22:27:56 -0600 Subject: [PATCH 06/19] OOBState: Drop state function matches --- src/SB/Game/zEntPlayerOOBState.cpp | 265 ++++++++++++++++++++++++++--- src/SB/Game/zEntPlayerOOBState.h | 17 +- 2 files changed, 253 insertions(+), 29 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index c9f68415b..0ab3415a6 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -3,8 +3,11 @@ #include "xMath.h" #include "xMathInlines.h" +#include "zSurface.h" +#include "zRenderState.h" #include +#include bool oob_player_teleported; @@ -106,22 +109,24 @@ namespace oob_state zCameraTweakGlobal_Init(); } - static void render_model(xModelInstance& model, const xVec3& unk_r4, const xVec3& unk_r5, const xVec3& unk_r6) + static void render_model(xModelInstance& model, const xVec3& loc, const xVec3& size, + const xVec3& ypr /*Yaw Pitch Roll*/) { basic_rect screen_rect = { 0.0f, 0.0f, 1.0f, 1.0f }; - screen_rect.x = unk_r4.x; - screen_rect.y = unk_r4.y; + screen_rect.x = loc.x; + screen_rect.y = loc.y; xVec3 from = { 0.0f, 0.0f, 1.0f }; xVec3 to = { 0.0f, 0.0f, 0.0f }; - to.z = -unk_r4.z; + to.z = -loc.z; xMat3x3 scaledMat; xMat3x3 eulerMat; xMat4x3 outMat; - xMat3x3ScaleC(&scaledMat, unk_r5.x * (1.0f + unk_r4.z), unk_r5.y * (1.0f + unk_r4.z), 1.0f + unk_r4.z); - xMat3x3Euler(&eulerMat, &unk_r6); + xMat3x3ScaleC(&scaledMat, size.x * (1.0f + loc.z), size.y * (1.0f + loc.z), + 1.0f + loc.z); + xMat3x3Euler(&eulerMat, &ypr); xMat3x3Mul(&outMat, &eulerMat, &scaledMat); outMat.pos = 0.0f; @@ -141,6 +146,29 @@ namespace oob_state vec += camMat.up * scale * localCoords.z; } + static void move_right(xVec3& vec, F32 scale) + { + xMat4x3& camMat = globals.camera.mat; + + xVec3 localCoords; + xMat4x3Tolocal(&localCoords, &camMat, &vec); + + vec += camMat.right * scale * localCoords.z * (4.0f / 3.0f); + } + + static void update_max_out_time(const xSurface& surface) + { + F32 delay = zSurfaceGetOutOfBoundsDelay(surface); + if (delay < 0.0f) + { + delay = fixed.out_time; + } + + F32 old_max_out_time = shared.max_out_time; + shared.max_out_time = delay; + shared.out_time -= old_max_out_time - delay; + } + static bool assume_player_is_stupid() { shared.tutorial = (ztalkbox*)zSceneFindObject(xStrHash("OUT_OF_BOUNDS_TLKBX")); @@ -167,29 +195,118 @@ namespace oob_state return stupid; } - static void move_hand(float dt /* r29+0x10 */) + static void move_hand(F32 dt) { + F32 old_vel = shared.vel; + + shared.vel = shared.accel * dt + old_vel; + shared.loc += shared.dir * (0.5f * shared.accel * dt * dt + old_vel * dt); } + static void set_rect_verts(rwGameCube2DVertex*, F32, F32, F32, F32, iColor_tag c, F32 nsz, + F32 rcz); + static void set_rect_vert(rwGameCube2DVertex&, F32 x, F32 y, F32 z, iColor_tag c, F32 rcz); static void render_fade() { + iColor_tag color = {}; + color.a = 255.0f * (1.0f - shared.fade_alpha) + 0.5f; + + zRenderState(SDRS_OOBFade); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, NULL); + F32 nsz = 1.0f / ((RwCamera*)RWSRCGLOBAL(curCamera))->farPlane; + F32 rcz = RwIm2DGetFarScreenZ(); + + RwIm2DVertex vert[4]; + set_rect_verts((rwGameCube2DVertex*)vert, 0.0f, 0.0f, 640.0f, 480.0f, color, rcz, nsz); + RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, (RwIm2DVertex*)vert, 4); } - static void set_rect_vert(rwGameCube2DVertex&, F32, F32, F32, iColor_tag, F32) + static void set_rect_verts(rwGameCube2DVertex* verts, F32 x, F32 y, F32 w, F32 h, + iColor_tag c, F32 rcz, F32 nsz) { + set_rect_vert(verts[0], x, y, rcz, c, nsz); + set_rect_vert(verts[1], x, y + h, rcz, c, nsz); + set_rect_vert(verts[2], x + w, y, rcz, c, nsz); + set_rect_vert(verts[3], x + w, y + h, rcz, c, nsz); } - drop_state_type::substate_enum drop_state_type::supdate_fade_in(drop_state_type&, - xScene& scn, F32& unk0) + static void set_rect_vert(rwGameCube2DVertex& vert, F32 x, F32 y, F32 z, iColor_tag c, + F32 rcz) { - return drop_state_type::update_fade_in(); + vert.x = x; + vert.y = y; + vert.z = z; + vert.emissiveColor.red = c.r; + vert.emissiveColor.green = c.g; + vert.emissiveColor.blue = c.b; + vert.emissiveColor.alpha = c.a; } - drop_state_type::substate_enum drop_state_type::update_fade_in(xScene&, float&) + static void render_ghost() { - return SS_MOVING_IN; + xEnt& ent = globals.player.ent; + + iDrawSetFBMSK(-1); + zRenderState(SDRS_OOBPlayerZ); + + xModelInstance* xm = ent.model; + while (xm != NULL) + { + RpAtomic& model = *xm->Data; + + if (xm->Flags & 0x1) + { + iModelRender(&model, xm->Mat); + } + + xm = xm->Next; + } + + iDrawSetFBMSK(0); + zRenderState(SDRS_OOBPlayerAlpha); + xLightKit_Enable(ent.lightKit, globals.currWorld); + + U8 alpha = 255.0f * (1.0f - shared.fade_alpha) + 0.5f; + alpha &= 0xFF; + + xm = ent.model; + while (xm != NULL) + { + RpAtomic& model = *xm->Data; + + if (xm->Flags & 0x1) + { + iModelSetMaterialAlpha(&model, alpha); + iModelRender(&model, xm->Mat); + iModelResetMaterial(&model); + } + + xm = xm->Next; + } + + xLightKit_Enable(NULL, globals.currWorld); } + static void render_hand() + { + zRenderState(SDRS_OOBHand); + + xVec3 modelLoc = { 0.0f, 0.0f, 0.0f }; + xVec3 modelSize = { 0.0f, 0.0f, 1.0f }; + xVec3 modelYpr = { 0.0f, 0.0f, 0.0f }; + + modelLoc.x = shared.loc.x; + modelLoc.y = shared.loc.y; + + modelSize.x = fixed.hand_size_x; + modelSize.y = fixed.hand_size_y; + + modelYpr.x = fixed.hand_yaw; + modelYpr.y = fixed.hand_pitch; + modelYpr.z = fixed.hand_roll; + + render_model(*shared.model, modelLoc, modelSize, modelYpr); + } } // namespace } // namespace oob_state @@ -327,31 +444,125 @@ void oob_state::init() { } -#define TODO_FIX_FLOAT 0.000000000000 +namespace oob_state +{ + namespace + { + drop_state_type::drop_state_type() + { + this->fade_substate; + } + + drop_state_type::substate_enum drop_state_type::supdate_fade_in(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_fade_in(scn, dt); + } + + drop_state_type::substate_enum drop_state_type::update_fade_in(xScene& scn, F32& dt) + { + return SS_FADE_IN; + } + + drop_state_type::substate_enum drop_state_type::supdate_start_fade_in(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_start_fade_in(scn, dt); + } + + drop_state_type::substate_enum drop_state_type::update_start_fade_in(xScene& scn, F32& dt) + { + this->fade_time -= dt; + + if (this->fade_time > 0.0f) + { + return SS_START_FADE_IN; + } + + dt += this->fade_time; + return SS_FADE_IN; + } + + drop_state_type::substate_enum drop_state_type::supdate_moving_out(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_moving_out(scn, dt); + } + + drop_state_type::substate_enum drop_state_type::supdate_starting(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_starting(scn, dt); + } + + drop_state_type::substate_enum drop_state_type::update_starting(xScene& scn, F32& dt) + { + move_hand(dt); + + if (shared.vel > -fixed.drop.out_vel) + { + return SS_STARTING; + } + + shared.vel = -fixed.drop.out_vel; + shared.accel = 0.0f; + return SS_MOVING_OUT; + } + + drop_state_type::substate_enum drop_state_type::supdate_stopped(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_stopped(scn, dt); + } + + drop_state_type::substate_enum drop_state_type::update_stopped(xScene& scn, F32& dt) + { + this->fade_start_time -= dt; + + if (this->fade_start_time > 0.0f) + { + return SS_STOPPED; + } + + dt += this->fade_start_time; + shared.accel = + (-fixed.drop.out_vel * fixed.drop.out_vel) / (2.0f * fixed.drop.out_start_dist); + return SS_STARTING; + } + + drop_state_type::substate_enum drop_state_type::supdate_stopping(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_stopping(scn, dt); + } + + drop_state_type::substate_enum drop_state_type::supdate_moving_in(drop_state_type& gst, + xScene& scn, F32& dt) + { + return gst.update_moving_in(scn, dt); + } + } // namespace +} // namespace oob_state oob_state::grab_state_type::substate_enum oob_state::grab_state_type::update_stopping(xScene& scene, F32& dt) { move_hand(dt); - if (shared.vel > TODO_FIX_FLOAT) + if (shared.vel > 0.0f) { return SS_STOPPING; } shared.loc = fixed.in_loc; - shared.vel = TODO_FIX_FLOAT; - shared.accel = TODO_FIX_FLOAT; + shared.vel = 0.0f; + shared.accel = 0.0f; - // fade_start_time is probably incorrect, due to commented issue down below with cb. - // It's probably supposed to be the variable above this, 'delay' - fade_start_time = fixed.grab.out_wait_time; + this->fade_start_time = fixed.grab.out_wait_time; if (assume_player_is_stupid()) { - // callback 'cb' should be the correct paramater at 0x8 offset. - // right now it's at 0x4 offset, so this will need to be fixed shared.tutorial->start_talk(xStrHash("TODO"), (ztalkbox::callback*)&cb, NULL); return SS_TUTORIAL; } @@ -376,7 +587,7 @@ void oob_state::in_state_type::start() shared.control = 0; }; -void oob_state::in_state_type::stop(){ +void oob_state::in_state_type::stop() { }; @@ -386,15 +597,15 @@ void oob_state::out_state_type::start() shared.reset_time = fixed.reset_time; }; -void oob_state::out_state_type::stop(){ +void oob_state::out_state_type::stop() { }; -void oob_state::state_type::start(){ +void oob_state::state_type::start() { }; -void oob_state::state_type::stop(){ +void oob_state::state_type::stop() { }; @@ -403,7 +614,7 @@ bool oob_state::grab_state_type::update_reorient(xScene&, F32&) return true; }; -void oob_state::grab_state_type::stop(){ +void oob_state::grab_state_type::stop() { }; diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index e205af871..0bf57e889 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -135,11 +135,24 @@ namespace oob_state F32 fade_time; substate_enum (*updatess)(drop_state_type&, xScene&, F32&)[7]; + drop_state_type(); void start(); state_enum update(xScene& s, F32& dt); - substate_enum supdate_fade_in(drop_state_type&, xScene&, F32&); - substate_enum update_fade_in(); + + static substate_enum supdate_fade_in(drop_state_type&, xScene&, F32&); substate_enum update_fade_in(xScene&, F32&); + static substate_enum supdate_start_fade_in(drop_state_type&, xScene&, F32&); + substate_enum update_start_fade_in(xScene&, F32&); + static substate_enum supdate_moving_out(drop_state_type&, xScene&, F32&); + substate_enum update_moving_out(xScene&, F32&); + static substate_enum supdate_starting(drop_state_type&, xScene&, F32&); + substate_enum update_starting(xScene&, F32&); + static substate_enum supdate_stopped(drop_state_type&, xScene&, F32&); + substate_enum update_stopped(xScene&, F32&); + static substate_enum supdate_stopping(drop_state_type&, xScene&, F32&); + substate_enum update_stopping(xScene&, F32&); + static substate_enum supdate_moving_in(drop_state_type&, xScene&, F32&); + substate_enum update_moving_in(xScene&, F32&); }; struct _class_9 From dc45abab55697b0ef2e32ca050daa7d8ca8b466c Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Wed, 10 Dec 2025 20:41:55 -0600 Subject: [PATCH 07/19] xMath2: Correct return type of normal to xVec2 --- src/SB/Core/x/xMath2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SB/Core/x/xMath2.h b/src/SB/Core/x/xMath2.h index 33b1d9f16..95e4fffce 100644 --- a/src/SB/Core/x/xMath2.h +++ b/src/SB/Core/x/xMath2.h @@ -55,7 +55,7 @@ struct xVec2 xVec2& assign(F32 x, F32 y); F32 length() const; F32 length2() const; - F32 normal() const; + xVec2 normal() const; xVec2& normalize(); F32 dot(const xVec2&) const; From 5cb7a0bf59cf225f8cf6dbe3f0544961c9bdf2e4 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Wed, 10 Dec 2025 20:42:16 -0600 Subject: [PATCH 08/19] OOBState: drop_state_type update func matches --- src/SB/Game/zEntPlayerOOBState.cpp | 105 +++++++++++++++++++++++++++-- src/SB/Game/zEntPlayerOOBState.h | 12 ++-- 2 files changed, 105 insertions(+), 12 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index 0ab3415a6..d04fdac81 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -461,7 +461,21 @@ namespace oob_state drop_state_type::substate_enum drop_state_type::update_fade_in(xScene& scn, F32& dt) { - return SS_FADE_IN; + this->fade_time -= dt; + shared.fade_alpha = 1.0f - this->fade_time / fixed.drop.fade_time; + + if (shared.fade_alpha > 1.0f) + { + shared.fade_alpha = 1.0f; + } + + if (this->fade_time > 0.0f) + { + return SS_FADE_IN; + } + + dt += this->fade_time; + return SS_INVALID; } drop_state_type::substate_enum drop_state_type::supdate_start_fade_in(drop_state_type& gst, @@ -472,14 +486,14 @@ namespace oob_state drop_state_type::substate_enum drop_state_type::update_start_fade_in(xScene& scn, F32& dt) { - this->fade_time -= dt; + this->fade_start_time -= dt; - if (this->fade_time > 0.0f) + if (this->fade_start_time > 0.0f) { return SS_START_FADE_IN; } - dt += this->fade_time; + dt += this->fade_start_time; return SS_FADE_IN; } @@ -489,6 +503,20 @@ namespace oob_state return gst.update_moving_out(scn, dt); } + drop_state_type::substate_enum drop_state_type::update_moving_out(xScene& scn, F32& dt) + { + move_hand(dt); + + F32 projection = (shared.loc - fixed.out_loc).dot(shared.dir); + if (projection >= 0.0f) + { + return SS_MOVING_OUT; + } + + dt = 0.0f; + return SS_INVALID; + } + drop_state_type::substate_enum drop_state_type::supdate_starting(drop_state_type& gst, xScene& scn, F32& dt) { @@ -517,14 +545,14 @@ namespace oob_state drop_state_type::substate_enum drop_state_type::update_stopped(xScene& scn, F32& dt) { - this->fade_start_time -= dt; + this->stop_time -= dt; - if (this->fade_start_time > 0.0f) + if (this->stop_time > 0.0f) { return SS_STOPPED; } - dt += this->fade_start_time; + dt += this->stop_time; shared.accel = (-fixed.drop.out_vel * fixed.drop.out_vel) / (2.0f * fixed.drop.out_start_dist); return SS_STARTING; @@ -536,11 +564,53 @@ namespace oob_state return gst.update_stopping(scn, dt); } + drop_state_type::substate_enum drop_state_type::update_stopping(xScene& scn, F32& dt) + { + move_hand(dt); + if (shared.vel > 0.0f) + { + return SS_STOPPING; + } + + shared.loc = fixed.in_loc; + shared.vel = 0.0f; + shared.accel = 0.0f; + this->stop_time = fixed.drop.out_wait_time; + + return SS_STOPPED; + } + drop_state_type::substate_enum drop_state_type::supdate_moving_in(drop_state_type& gst, xScene& scn, F32& dt) { return gst.update_moving_in(scn, dt); } + + drop_state_type::substate_enum drop_state_type::update_moving_in(xScene& scn, F32& dt) + { + move_hand(dt); + + xVec2 in_out_path = fixed.in_loc - fixed.out_loc; + xVec2 norm = in_out_path.normal(); + + F32 projection = norm.dot(fixed.in_loc - shared.loc); + if (projection > fixed.grab.in_stop_dist) + { + return SS_MOVING_IN; + } + else if (projection <= 0.0f) + { + shared.vel = 0.0f; + shared.loc = fixed.in_loc; + shared.accel = 0.0f; + } + else + { + shared.accel = (-shared.vel * shared.vel) / (2.0f * projection); + } + + return SS_STOPPING; + } } // namespace } // namespace oob_state @@ -628,6 +698,27 @@ bool oob_state::IsPlayerInControl() return oob_state::shared.control == 0; } +namespace oob_state +{ + namespace + { + void drop_state_type::start() + { + + } + + void drop_state_type::stop() + { + + } + + state_enum drop_state_type::update(xScene& scene, F32& dt) + { + return STATE_DROP; + } + } +} + WEAK F32 xVec2::dot(const xVec2& b) const { return (x * b.x) + (y * b.y); diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index 0bf57e889..323fbeca4 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -45,8 +45,9 @@ namespace oob_state { state_enum type; - void start(); - void stop(); + virtual void start(); + virtual void stop(); + virtual state_enum update(xScene& scene, F32& dt); }; struct in_state_type : state_type @@ -116,6 +117,7 @@ namespace oob_state { enum substate_enum { + SS_INVALID = -1, SS_MOVING_IN, SS_STOPPING, SS_STOPPED, @@ -124,7 +126,6 @@ namespace oob_state SS_START_FADE_IN, SS_FADE_IN, MAX_SS, - SS_INVALID = 0xffffffff, }; substate_enum move_substate; @@ -136,8 +137,9 @@ namespace oob_state substate_enum (*updatess)(drop_state_type&, xScene&, F32&)[7]; drop_state_type(); - void start(); - state_enum update(xScene& s, F32& dt); + virtual void start(); + virtual void stop(); + virtual state_enum update(xScene& scene, F32& dt); static substate_enum supdate_fade_in(drop_state_type&, xScene&, F32&); substate_enum update_fade_in(xScene&, F32&); From b9f3196074fb1beadabf94e81f1f8c011fa6872a Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Wed, 10 Dec 2025 22:33:24 -0600 Subject: [PATCH 09/19] OOBState: Grab State/Tutorial Callback overhaul and matching --- src/SB/Game/zEntPlayerOOBState.cpp | 90 +++++++++++++++++++----------- src/SB/Game/zEntPlayerOOBState.h | 78 ++++++++++++++++---------- 2 files changed, 106 insertions(+), 62 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index d04fdac81..ddf395319 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -448,9 +448,15 @@ namespace oob_state { namespace { - drop_state_type::drop_state_type() + drop_state_type::drop_state_type() : state_type(STATE_DROP) { - this->fade_substate; + this->updatess[0] = &supdate_moving_in; + this->updatess[1] = &supdate_stopping; + this->updatess[2] = &supdate_stopped; + this->updatess[3] = &supdate_starting; + this->updatess[4] = &supdate_moving_out; + this->updatess[5] = &supdate_start_fade_in; + this->updatess[6] = &supdate_fade_in; } drop_state_type::substate_enum drop_state_type::supdate_fade_in(drop_state_type& gst, @@ -611,34 +617,64 @@ namespace oob_state return SS_STOPPING; } - } // namespace -} // namespace oob_state -oob_state::grab_state_type::substate_enum oob_state::grab_state_type::update_stopping(xScene& scene, + state_type::state_type(state_enum state) + { + this->type = state; + } + + grab_state_type::grab_state_type() : state_type(STATE_GRAB), cb(*this) + { + this->updatess[0] = &supdate_reorient; + this->updatess[1] = &supdate_begin_wait; + this->updatess[2] = &supdate_moving_in; + this->updatess[3] = &supdate_stopping; + this->updatess[4] = &supdate_stopped; + this->updatess[5] = &supdate_tutorial; + this->updatess[6] = &supdate_starting; + this->updatess[7] = &supdate_moving_out; + this->updatess[8] = &supdate_start_fade_out; + this->updatess[9] = &supdate_fade_out; + } + + oob_state::grab_state_type::substate_enum oob_state::grab_state_type::update_stopping(xScene& scene, F32& dt) -{ - move_hand(dt); + { + move_hand(dt); - if (shared.vel > 0.0f) - { - return SS_STOPPING; - } + if (shared.vel > 0.0f) + { + return SS_STOPPING; + } - shared.loc = fixed.in_loc; + shared.loc = fixed.in_loc; - shared.vel = 0.0f; - shared.accel = 0.0f; + shared.vel = 0.0f; + shared.accel = 0.0f; - this->fade_start_time = fixed.grab.out_wait_time; + this->fade_start_time = fixed.grab.out_wait_time; + + if (assume_player_is_stupid()) + { + shared.tutorial->start_talk(xStrHash("TODO"), (ztalkbox::callback*)&cb, NULL); + return SS_TUTORIAL; + } + + return SS_STOPPED; + } + + grab_state_type::substate_enum oob_state::grab_state_type::update_reorient(xScene&, F32&) + { + return SS_REORIENT; + }; + + grab_state_type::tutorial_callback::tutorial_callback(grab_state_type& owner) : owner(owner) + { + } + } // namespace +} // namespace oob_state - if (assume_player_is_stupid()) - { - shared.tutorial->start_talk(xStrHash("TODO"), (ztalkbox::callback*)&cb, NULL); - return SS_TUTORIAL; - } - return SS_STOPPED; -} float oob_state::oob_timer() { @@ -679,20 +715,10 @@ void oob_state::state_type::stop() { }; -bool oob_state::grab_state_type::update_reorient(xScene&, F32&) -{ - return true; -}; - void oob_state::grab_state_type::stop() { }; -void oob_state::grab_state_type::tutorial_callback::on_stop() -{ - owner.finished_tutorial = true; -}; - bool oob_state::IsPlayerInControl() { return oob_state::shared.control == 0; diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index 323fbeca4..b275c8256 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -22,29 +22,25 @@ namespace oob_state bool IsPlayerInControl(); - struct callback - { - virtual void on_stop(); - }; - - enum state_enum - { - STATE_INVALID = -1, - BEGIN_STATE, - STATE_IN = 0, - STATE_OUT, - STATE_GRAB, - STATE_DROP, - END_STATE, - MAX_STATE = 0x4 - }; - namespace { + enum state_enum + { + STATE_INVALID = -1, + BEGIN_STATE, + STATE_IN = 0, + STATE_OUT, + STATE_GRAB, + STATE_DROP, + END_STATE, + MAX_STATE = 0x4 + }; + struct state_type { state_enum type; + state_type(state_enum state); virtual void start(); virtual void stop(); virtual state_enum update(xScene& scene, F32& dt); @@ -80,11 +76,21 @@ namespace oob_state MAX_SS }; - struct tutorial_callback : callback + struct tutorial_callback : ztalkbox::callback { grab_state_type& owner; - void on_stop(); + tutorial_callback(grab_state_type& owner); + + virtual void on_signal(U32) + { + + } + + virtual void on_stop() + { + owner.finished_tutorial = true; + } }; tutorial_callback cb; @@ -97,20 +103,32 @@ namespace oob_state F32 fade_start_time; F32 fade_time; U32 scene_reset; - - // Todo: this is not in the DWARF, but is required for - // tutorial_callback::on_stop to match. Probably - // not correct. - char pad[4]; - U8 finished_tutorial; - substate_enum (*updatess)(grab_state_type&, xScene&, float&)[10]; - bool update_reorient(xScene&, F32&); - substate_enum update_stopping(xScene&, float&); - + substate_enum (*updatess[10])(grab_state_type&, xScene&, float&); + + grab_state_type(); void start(); void stop(); + + static substate_enum supdate_reorient(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_reorient(xScene&, F32&); + static substate_enum supdate_begin_wait(grab_state_type& gst, xScene& scene, F32& dt); + static substate_enum supdate_moving_in(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_moving_in(xScene& scene, F32& dt); + static substate_enum supdate_stopping(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_stopping(xScene& scene, F32& dt); + static substate_enum supdate_stopped(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_stopped(xScene& scene, F32& dt); + static substate_enum supdate_tutorial(grab_state_type& gst, xScene& scene, F32& dt); + static substate_enum supdate_starting(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_starting(xScene& scene, F32& dt); + static substate_enum supdate_moving_out(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_moving_out(xScene& scene, F32& dt); + static substate_enum supdate_start_fade_out(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_start_fade_out(xScene& scene, F32& dt); + static substate_enum supdate_fade_out(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_fade_out(xScene& scene, F32& dt); }; struct drop_state_type : state_type @@ -134,7 +152,7 @@ namespace oob_state F32 stop_time; F32 fade_start_time; F32 fade_time; - substate_enum (*updatess)(drop_state_type&, xScene&, F32&)[7]; + substate_enum (*updatess[7])(drop_state_type&, xScene&, F32&); drop_state_type(); virtual void start(); From 7eacb84eb79be6bc2703e545adf89c0bd7915250 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 12 Dec 2025 18:30:28 -0600 Subject: [PATCH 10/19] OOBState: Match grab_state_type functions and vtable --- src/SB/Game/zEntPlayerOOBState.cpp | 230 ++++++++++++++++++++++++++--- src/SB/Game/zEntPlayerOOBState.h | 7 +- 2 files changed, 216 insertions(+), 21 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index ddf395319..9cfdd8e9d 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -474,7 +474,7 @@ namespace oob_state { shared.fade_alpha = 1.0f; } - + if (this->fade_time > 0.0f) { return SS_FADE_IN; @@ -608,7 +608,7 @@ namespace oob_state { shared.vel = 0.0f; shared.loc = fixed.in_loc; - shared.accel = 0.0f; + shared.accel = 0.0f; } else { @@ -637,8 +637,142 @@ namespace oob_state this->updatess[9] = &supdate_fade_out; } - oob_state::grab_state_type::substate_enum oob_state::grab_state_type::update_stopping(xScene& scene, - F32& dt) + grab_state_type::tutorial_callback::tutorial_callback(grab_state_type& owner) : owner(owner) + { + } + + grab_state_type::substate_enum grab_state_type::supdate_fade_out(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_fade_out(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_fade_out(xScene& scene, F32& dt) + { + this->fade_time -= dt; + shared.fade_alpha = this->fade_time / fixed.grab.fade_time; + + if (shared.fade_alpha < 0.0f) + { + shared.fade_alpha = 0.0f; + } + + if (this->fade_time > 0.0f) + { + return SS_FADE_OUT; + } + + dt += this->fade_time; + return SS_INVALID; + } + + grab_state_type::substate_enum + grab_state_type::supdate_start_fade_out(grab_state_type& gst, xScene& scene, F32& dt) + { + return gst.update_start_fade_out(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_start_fade_out(xScene& scene, + F32& dt) + { + this->fade_start_time -= dt; + + if (this->fade_start_time > 0.0f) + { + return SS_START_FADE_OUT; + } + + dt += this->fade_start_time; + return SS_FADE_OUT; + } + + grab_state_type::substate_enum grab_state_type::supdate_moving_out(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_moving_out(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_moving_out(xScene& scene, F32& dt) + { + move_hand(dt); + + if ((shared.loc - fixed.out_loc).dot(shared.dir) >= 0.0f) + { + return SS_MOVING_OUT; + } + + dt = 0.0f; + return SS_INVALID; + } + + grab_state_type::substate_enum grab_state_type::supdate_starting(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_starting(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_starting(xScene& scene, F32& dt) + { + move_hand(dt); + + if (shared.vel > -fixed.grab.out_vel) + { + return SS_STARTING; + } + + shared.vel = -fixed.grab.out_vel; + shared.accel = 0.0f; + return SS_MOVING_OUT; + } + + grab_state_type::substate_enum grab_state_type::supdate_tutorial(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_tutorial(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_tutorial(xScene& scene, F32& dt) + { + this->delay -= dt; + if (!this->finished_tutorial || this->delay > 0.0f) + { + return SS_TUTORIAL; + } + + dt = 0.0f; + shared.accel = + (-fixed.grab.out_vel * fixed.grab.out_vel) / (2.0f * fixed.grab.out_start_dist); + return SS_STARTING; + } + + grab_state_type::substate_enum grab_state_type::supdate_stopped(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_stopped(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_stopped(xScene& scene, F32& dt) + { + this->delay -= dt; + + if (this->delay > 0.0f) + { + return SS_STOPPED; + } + + dt += this->delay; + shared.accel = + (-fixed.grab.out_vel * fixed.grab.out_vel) / (2.0f * fixed.grab.out_start_dist); + return SS_STARTING; + } + + grab_state_type::substate_enum grab_state_type::supdate_stopping(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_stopping(scene, dt); + } + + grab_state_type::substate_enum grab_state_type::update_stopping(xScene& scene, F32& dt) { move_hand(dt); @@ -652,7 +786,7 @@ namespace oob_state shared.vel = 0.0f; shared.accel = 0.0f; - this->fade_start_time = fixed.grab.out_wait_time; + this->delay = fixed.grab.out_wait_time; if (assume_player_is_stupid()) { @@ -663,18 +797,69 @@ namespace oob_state return SS_STOPPED; } - grab_state_type::substate_enum oob_state::grab_state_type::update_reorient(xScene&, F32&) + grab_state_type::substate_enum grab_state_type::supdate_moving_in(grab_state_type& gst, + xScene& scene, F32& dt) { - return SS_REORIENT; - }; + return gst.update_moving_in(scene, dt); + } - grab_state_type::tutorial_callback::tutorial_callback(grab_state_type& owner) : owner(owner) + grab_state_type::substate_enum grab_state_type::update_moving_in(xScene& scene, F32& dt) + { + move_hand(dt); + + xVec2 in_out_path = fixed.in_loc - fixed.out_loc; + xVec2 norm = in_out_path.normal(); + + F32 projection = norm.dot(fixed.in_loc - shared.loc); + if (projection > fixed.grab.in_stop_dist) + { + return SS_MOVING_IN; + } + else if (projection <= 0.0f) + { + shared.vel = 0.0f; + shared.loc = fixed.in_loc; + shared.accel = 0.0f; + } + else + { + shared.accel = (-shared.vel * shared.vel) / (2.0f * projection); + } + + return SS_STOPPING; + } + + grab_state_type::substate_enum grab_state_type::supdate_begin_wait(grab_state_type& gst, + xScene& scene, F32& dt) { + return gst.update_begin_wait(scene, dt); } - } // namespace -} // namespace oob_state + grab_state_type::substate_enum grab_state_type::update_begin_wait(xScene& scene, F32& dt) + { + this->delay -= dt; + if (this->delay > 0.0f) + { + return SS_BEGIN_WAIT; + } + shared.render_hand = true; + return SS_MOVING_IN; + } + + grab_state_type::substate_enum grab_state_type::supdate_reorient(grab_state_type& gst, + xScene& scene, F32& dt) + { + return gst.update_reorient(scene, dt); + } + + grab_state_type::substate_enum oob_state::grab_state_type::update_reorient(xScene& scene, + F32& dt) + { + return SS_BEGIN_WAIT; + }; + } // namespace +} // namespace oob_state float oob_state::oob_timer() { @@ -715,10 +900,6 @@ void oob_state::state_type::stop() { }; -void oob_state::grab_state_type::stop() { - -}; - bool oob_state::IsPlayerInControl() { return oob_state::shared.control == 0; @@ -728,22 +909,33 @@ namespace oob_state { namespace { - void drop_state_type::start() + void grab_state_type::start() { + } + void grab_state_type::stop() + { } - void drop_state_type::stop() + state_enum grab_state_type::update(xScene& scene, F32& dt) { + return STATE_DROP; + } + void drop_state_type::start() + { + } + + void drop_state_type::stop() + { } state_enum drop_state_type::update(xScene& scene, F32& dt) { return STATE_DROP; } - } -} + } // namespace +} // namespace oob_state WEAK F32 xVec2::dot(const xVec2& b) const { diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index b275c8256..fcd446986 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -108,12 +108,14 @@ namespace oob_state substate_enum (*updatess[10])(grab_state_type&, xScene&, float&); grab_state_type(); - void start(); - void stop(); + virtual void start(); + virtual void stop(); + virtual state_enum update(xScene& scene, F32& dt); static substate_enum supdate_reorient(grab_state_type& gst, xScene& scene, F32& dt); substate_enum update_reorient(xScene&, F32&); static substate_enum supdate_begin_wait(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_begin_wait(xScene&, F32&); static substate_enum supdate_moving_in(grab_state_type& gst, xScene& scene, F32& dt); substate_enum update_moving_in(xScene& scene, F32& dt); static substate_enum supdate_stopping(grab_state_type& gst, xScene& scene, F32& dt); @@ -121,6 +123,7 @@ namespace oob_state static substate_enum supdate_stopped(grab_state_type& gst, xScene& scene, F32& dt); substate_enum update_stopped(xScene& scene, F32& dt); static substate_enum supdate_tutorial(grab_state_type& gst, xScene& scene, F32& dt); + substate_enum update_tutorial(xScene& scene, F32& dt); static substate_enum supdate_starting(grab_state_type& gst, xScene& scene, F32& dt); substate_enum update_starting(xScene& scene, F32& dt); static substate_enum supdate_moving_out(grab_state_type& gst, xScene& scene, F32& dt); From 7b85ab97e99ee7fd65d5615ac27fbf698ed6f6d0 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 12 Dec 2025 20:42:32 -0600 Subject: [PATCH 11/19] OOBState: Additional matches with idiot_level_data fix --- src/SB/Game/zEntPlayerOOBState.cpp | 121 ++++++++++++++++++++++++----- src/SB/Game/zEntPlayerOOBState.h | 17 ++-- 2 files changed, 114 insertions(+), 24 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index 9cfdd8e9d..a2642ca12 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -5,6 +5,7 @@ #include "xMathInlines.h" #include "zSurface.h" #include "zRenderState.h" +#include "zEntPlayerBungeeState.h" #include #include @@ -637,10 +638,6 @@ namespace oob_state this->updatess[9] = &supdate_fade_out; } - grab_state_type::tutorial_callback::tutorial_callback(grab_state_type& owner) : owner(owner) - { - } - grab_state_type::substate_enum grab_state_type::supdate_fade_out(grab_state_type& gst, xScene& scene, F32& dt) { @@ -858,10 +855,35 @@ namespace oob_state { return SS_BEGIN_WAIT; }; + + grab_state_type::tutorial_callback::tutorial_callback(grab_state_type& owner) : owner(owner) + { + } + + out_state_type::out_state_type() : state_type(STATE_OUT) + { + } + + in_state_type::in_state_type() : state_type(STATE_IN) + { + } + + void state_type::start() + { + }; + + void state_type::stop() + { + }; } // namespace } // namespace oob_state -float oob_state::oob_timer() +bool oob_state::IsPlayerInControl() +{ + return oob_state::shared.control == 0; +} + +F32 oob_state::oob_timer() { if (shared.reset_time == fixed.reset_time) { @@ -871,6 +893,82 @@ float oob_state::oob_timer() return -1.0f; } +bool oob_state::render() +{ + if ((shared.flags & 0x3) != 3) + { + return false; + } + + if (!shared.control) + { + return false; + } + + xLightKit_Enable(globals.player.ent.lightKit, globals.currWorld); + xEntRender(&globals.player.ent); + xLightKit_Enable(NULL, globals.currWorld); + + return true; +} + +void oob_state::fx_render() +{ + if ((shared.flags & 0x3) != 3) + { + return; + } + + if (shared.control && shared.fade_alpha < 1.0f) + { + render_fade(); + render_ghost(); + } + + if (shared.render_hand && shared.model != NULL) + { + render_hand(); + } +} + +void oob_state::force_start() +{ + if ((shared.flags & 0x7) == 0x3 && !bungee_state::active()) + { + if (globals.player.ControlOff & 0x8000) + { + shared.flags |= 0x8; + oob_player_teleported = false; + } + else + { + shared.flags &= ~0x8; + shared.state->stop(); + shared.state = shared.states[2]; + shared.state->start(); + } + } +} + +void oob_state::read_persistent(xSerial& s) +{ + for (U32 i = 0; i < 6; i++) + { + S32 val; + s.Read_b1(&val); + + idiot_levels[i].triggered = (bool)val; + } +} + +void oob_state::write_persistent(xSerial& s) +{ + for (U32 i = 0; i < 6; i++) + { + s.Write_b1((bool)idiot_levels[i].triggered); + } +} + void oob_state::in_state_type::start() { shared.reset_time = FLOAT_MAX; @@ -892,19 +990,6 @@ void oob_state::out_state_type::stop() { }; -void oob_state::state_type::start() { - -}; - -void oob_state::state_type::stop() { - -}; - -bool oob_state::IsPlayerInControl() -{ - return oob_state::shared.control == 0; -} - namespace oob_state { namespace diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index fcd446986..b58fc2247 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -13,6 +13,7 @@ namespace oob_state { bool render(); void fx_render(); + void force_start(); void read_persistent(xSerial& s); void write_persistent(xSerial& s); void load_settings(xIniFile& ini); @@ -43,19 +44,23 @@ namespace oob_state state_type(state_enum state); virtual void start(); virtual void stop(); - virtual state_enum update(xScene& scene, F32& dt); + virtual state_enum update(xScene& scene, F32& dt) = 0; }; struct in_state_type : state_type { - void start(); - void stop(); + in_state_type(); + virtual void start(); + virtual void stop(); + virtual state_enum update(xScene& scene, F32& dt); }; struct out_state_type : state_type { - void start(); - void stop(); + out_state_type(); + virtual void start(); + virtual void stop(); + virtual state_enum update(xScene& scene, F32& dt); }; struct grab_state_type : state_type @@ -251,7 +256,7 @@ namespace oob_state struct idiot_level_data { - bool triggered; // offset 0x0, size 0x1 + U8 triggered; // offset 0x0, size 0x1 U32 scene; // offset 0x4, size 0x4 }; From 337469148aee0bee0647bb5bec3fc6c0ca4b2ead Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 12 Dec 2025 22:47:23 -0600 Subject: [PATCH 12/19] zSurface: Declare zSurfaceOutOfBounds from DWARF --- src/SB/Game/zSurface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SB/Game/zSurface.h b/src/SB/Game/zSurface.h index 3169292c2..faf1ff278 100644 --- a/src/SB/Game/zSurface.h +++ b/src/SB/Game/zSurface.h @@ -137,6 +137,7 @@ void zSurfaceSetup(xSurface* s); void zSurfaceUpdate(xBase* to, xScene*, F32 dt); void zSurfaceGetName(S32 type, char* buffer); xSurface& zSurfaceGetDefault(); +U8 zSurfaceOutOfBounds(const xSurface& s); F32 zSurfaceGetOutOfBoundsDelay(const xSurface& surface); #endif From bdfc7c9a2cc21a505bfa1d4937481f83088b4e62 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 12 Dec 2025 22:48:04 -0600 Subject: [PATCH 13/19] OOBState: In & Out callback matches --- src/SB/Game/zEntPlayerOOBState.cpp | 92 ++++++++++++++++++++++++++---- src/SB/Game/zEntPlayerOOBState.h | 12 ++-- 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index a2642ca12..0cee0a9c8 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -969,31 +969,99 @@ void oob_state::write_persistent(xSerial& s) } } -void oob_state::in_state_type::start() +namespace oob_state +{ + namespace + { + void in_state_type::start() { - shared.reset_time = FLOAT_MAX; - shared.out_time = FLOAT_MAX; + shared.reset_time = 0.0f; + shared.out_time = 0.0f; shared.control = 0; }; -void oob_state::in_state_type::stop() { + void in_state_type::stop() + { -}; + }; + + state_enum in_state_type::update(xScene& scene, F32& dt) + { + xSurface* floor_surf = globals.player.floor_surf; + U8 oob = FALSE; + + if (floor_surf != NULL && !(globals.player.ControlOff & 0x8000)) + { + oob = zSurfaceOutOfBounds(*floor_surf); + if (oob) + { + update_max_out_time(*floor_surf); + } + } + + if (!oob) + { + shared.reset_time = 0.0f; + shared.out_time = 0.0f; + shared.control = FALSE; + + return STATE_IN; + } -void oob_state::out_state_type::start() + return STATE_OUT; + }; + + void out_state_type::start() { shared.out_time = shared.max_out_time; shared.reset_time = fixed.reset_time; }; -void oob_state::out_state_type::stop() { + void out_state_type::stop() { -}; + }; + + state_enum out_state_type::update(xScene& scene, F32& dt) + { + xSurface* floor_surf = globals.player.floor_surf; + U8 oob = FALSE; + + if (floor_surf != NULL && !(globals.player.ControlOff & 0x8000)) + { + oob = zSurfaceOutOfBounds(*floor_surf); + if (oob) + { + update_max_out_time(*floor_surf); + } + } + + shared.out_time -= dt; + + if (oob) + { + shared.reset_time = fixed.reset_time; + if (shared.reset_time <= 0.0f) + { + return STATE_GRAB; + } + } + else + { + if (!globals.player.JumpState) + { + shared.reset_time = 0.0f; + } + + shared.reset_time -= dt; + if (shared.reset_time <= 0.0f) + { + return STATE_IN; + } + } + + return STATE_OUT; + }; -namespace oob_state -{ - namespace - { void grab_state_type::start() { } diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index b58fc2247..103c6a3e9 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -28,13 +28,13 @@ namespace oob_state enum state_enum { STATE_INVALID = -1, - BEGIN_STATE, + BEGIN_STATE = 0, STATE_IN = 0, - STATE_OUT, - STATE_GRAB, - STATE_DROP, - END_STATE, - MAX_STATE = 0x4 + STATE_OUT = 1, + STATE_GRAB = 2, + STATE_DROP = 3, + END_STATE = 4, + MAX_STATE = 4, }; struct state_type From 822fddbdd866a6ea1cc4cdb879061ca578f5d180 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 00:53:21 -0600 Subject: [PATCH 14/19] OOBState: Progress on start/stop/update funcs --- src/SB/Game/zEntPlayerOOBState.cpp | 59 ++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index 0cee0a9c8..d3b54e86e 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -6,6 +6,7 @@ #include "zSurface.h" #include "zRenderState.h" #include "zEntPlayerBungeeState.h" +#include "zEntCruiseBubble.h" #include #include @@ -974,11 +975,11 @@ namespace oob_state namespace { void in_state_type::start() -{ + { shared.reset_time = 0.0f; shared.out_time = 0.0f; - shared.control = 0; -}; + shared.control = 0; + }; void in_state_type::stop() { @@ -1012,10 +1013,10 @@ namespace oob_state }; void out_state_type::start() -{ - shared.out_time = shared.max_out_time; - shared.reset_time = fixed.reset_time; -}; + { + shared.out_time = shared.max_out_time; + shared.reset_time = fixed.reset_time; + }; void out_state_type::stop() { @@ -1064,6 +1065,42 @@ namespace oob_state void grab_state_type::start() { + this->finished_tutorial = FALSE; + zEntPlayerControlOff(CONTROL_OWNER_OOB); + + globals.player.ControlOffTimer = FLOAT_MAX; + cruise_bubble::reset(); + + shared.flags |= 0x4; + shared.vertical = FABS(fixed.in_loc.y - fixed.out_loc.y) > 0.01f; + shared.control = TRUE; + + this->move_substate = shared.model != NULL ? SS_REORIENT : SS_INVALID; + this->reorient_time = fixed.reorient_time; + + set_camera(false); + + shared.loc = fixed.out_loc; + shared.dir = (fixed.in_loc - fixed.out_loc).normal(); + shared.vel = fixed.grab.in_vel; + shared.accel = 0.0f; + + this->fade_substate = SS_START_FADE_OUT; + this->fade_start_time = fixed.grab.fade_start_time; + this->fade_time = fixed.grab.fade_time; + + shared.fade_alpha = 1.0f; + this->player_start = globals.player.ent.frame->mat.pos; + + xVec3 eulerOut; + xMat3x3GetEuler(&globals.player.ent.frame->mat, &eulerOut); + globals.player.ent.frame->rot.angle = xrmod(eulerOut.x); + + this->angle_delta = xrmod(PI + (globals.camera.pcur - eulerOut.x)) - PI; + this->angle_delta /= fixed.reorient_time; + + xModelUpdate(globals.player.ent.model, 1.0f / 1000.0f); + this->scene_reset = FALSE; } void grab_state_type::stop() @@ -1081,6 +1118,14 @@ namespace oob_state void drop_state_type::stop() { + zEntPlayerControlOn(CONTROL_OWNER_OOB); + globals.player.ControlOffTimer = 1.0f; + + reset_camera(); + + shared.render_hand = FALSE; + shared.fade_alpha = 1.0f; + shared.flags &= ~0x4; } state_enum drop_state_type::update(xScene& scene, F32& dt) From d8c7e4ee418bcf71d252649da803a673c3ad3eb6 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 19:16:29 -0600 Subject: [PATCH 15/19] zEntPlayer: Add declaration for zEntPlayerUpdateModel --- src/SB/Game/zEntPlayer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SB/Game/zEntPlayer.h b/src/SB/Game/zEntPlayer.h index 6279145d9..ff4df690f 100644 --- a/src/SB/Game/zEntPlayer.h +++ b/src/SB/Game/zEntPlayer.h @@ -411,6 +411,7 @@ void zEntPlayer_Init(xEnt* ent, xEntAsset* asset); void zEntPlayerExit(xEnt*); void zEntPlayerPreReset(); void zEntPlayerReset(xEnt* ent); +void zEntPlayerUpdateModel(); void zEntPlayer_LoadSounds(); void zEntPlayer_UnloadSounds(); void zEntPlayer_ShadowModelEnable(); From dd58967790e0841908b01d6b10d8080b164f635c Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 19:20:20 -0600 Subject: [PATCH 16/19] OOBState: Matches for grab and drop state type update loop functions --- src/SB/Game/zEntPlayerOOBState.cpp | 141 ++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index d3b54e86e..c6050ebf3 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -7,6 +7,8 @@ #include "zRenderState.h" #include "zEntPlayerBungeeState.h" #include "zEntCruiseBubble.h" +#include "zGameState.h" +#include "xScrFx.h" #include #include @@ -1109,11 +1111,100 @@ namespace oob_state state_enum grab_state_type::update(xScene& scene, F32& dt) { - return STATE_DROP; + if (shared.model == NULL) + { + return STATE_DROP; + } + + F32 movedt = dt; + while (this->move_substate != SS_INVALID) + { + substate_enum newstate = this->updatess[this->move_substate](*this, scene, movedt); + if (newstate == this->move_substate) + { + break; + } + + this->move_substate = newstate; + } + + F32 fadedt = dt; + while (this->fade_substate != SS_INVALID) + { + substate_enum newstate = this->updatess[this->fade_substate](*this, scene, fadedt); + if (newstate == this->fade_substate) + { + break; + } + + this->fade_substate = newstate; + } + + if (this->move_substate == SS_INVALID && this->fade_substate == SS_INVALID) + { + if (this->scene_reset) + { + return STATE_DROP; + } + + this->scene_reset = TRUE; + zGameStateSwitch(0x2); + } + + if (this->move_substate == SS_STARTING || this->move_substate == SS_MOVING_OUT) + { + xMat4x3& pm = *(xMat4x3*)globals.player.ent.model->Mat; + pm.pos = this->player_start; + + move_up(pm.pos, fixed.in_loc.y - shared.loc.y); + move_right(pm.pos, fixed.in_loc.x - shared.loc.x); + } + + xModelEval(globals.player.ent.model); + zEntPlayerUpdateModel(); + return STATE_GRAB; } void drop_state_type::start() { + this->player_start = globals.player.cp.pos; + this->move_substate = shared.model != NULL ? SS_MOVING_IN : SS_INVALID; + + shared.vel = fixed.drop.in_vel; + shared.accel = 0.0f; + shared.loc.x = fixed.in_loc.x; + shared.loc.y = fixed.in_loc.y; + + this->fade_substate = SS_START_FADE_IN; + this->fade_start_time = fixed.drop.fade_start_time; + this->fade_time = fixed.drop.fade_time; + + xEnt& p = globals.player.ent; + zEntPlayerReset(&p); + zEntPlayerUpdateModel(); + zEntPlayerControlOff(CONTROL_OWNER_OOB); + globals.player.ControlOffTimer = FLOAT_MAX; + xScrFxStopFade(); + zCameraDisableInput(); + + xModelInstance& m = *p.model; + xEntFrame& f = *p.frame; + + f.rot.axis = g_Y3; + f.rot.angle = globals.player.cp.rot; + f.vel = g_O3; + + xMat3x3Euler(&f.mat, f.rot.angle, 0.0f, 0.0f); + f.mat.pos = globals.player.cp.pos; + *(xMat4x3*)m.Mat = f.mat; + + shared_target.pos = *(xVec3*)&m.Mat->pos; + + set_camera(true); + globals.camera.tgt_mat = &shared_target; + globals.camera.tgt_omat = &shared_target; + xCameraMove(&globals.camera, 0x20, fixed.cam_dist, fixed.cam_height, PI + globals.player.cp.rot, 0.0f, 0.0f, 0.0f); + xCameraLookYPR(&globals.camera, 0x0, globals.player.cp.rot, fixed.cam_pitch, 0.0f, 0.0f, 0.0f, 0.0f); } void drop_state_type::stop() @@ -1130,6 +1221,54 @@ namespace oob_state state_enum drop_state_type::update(xScene& scene, F32& dt) { + if (shared.model == NULL) + { + return STATE_IN; + } + + F32 movedt = dt; + while (this->move_substate != SS_INVALID) + { + substate_enum newstate = this->updatess[this->move_substate](*this, scene, movedt); + if (newstate == this->move_substate) + { + break; + } + + this->move_substate = newstate; + } + + F32 fadedt = dt; + while (this->fade_substate != SS_INVALID) + { + substate_enum newstate = this->updatess[this->fade_substate](*this, scene, fadedt); + if (newstate == this->fade_substate) + { + break; + } + + this->fade_substate = newstate; + } + + if (this->move_substate == SS_INVALID && this->fade_substate == SS_INVALID) + { + return STATE_IN; + } + + if (this->move_substate == SS_MOVING_IN || this->move_substate == SS_STOPPING) + { + xMat4x3& pm = *(xMat4x3*)globals.player.ent.model->Mat; + pm.pos = this->player_start; + + move_up(pm.pos, fixed.in_loc.y - shared.loc.y); + move_right(pm.pos, fixed.in_loc.x - shared.loc.x); + } + + if (shared.control) + { + xModelEval(globals.player.ent.model); + } + return STATE_DROP; } } // namespace From 38ad3df11d114d815a504f70f53ba4462ada3053 Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 19:44:30 -0600 Subject: [PATCH 17/19] OOBState: Match oob_state::update --- src/SB/Game/zEntPlayerOOBState.cpp | 40 ++++++++++++++++++++++++++++++ src/SB/Game/zEntPlayerOOBState.h | 1 + 2 files changed, 41 insertions(+) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index c6050ebf3..eb86f7234 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -9,6 +9,7 @@ #include "zEntCruiseBubble.h" #include "zGameState.h" #include "xScrFx.h" +#include "zSaveLoad.h" #include #include @@ -881,6 +882,45 @@ namespace oob_state } // namespace } // namespace oob_state +U8 oob_state::update(xScene& scene, F32 dt) +{ + if ((shared.flags & 0x3) != 0x3) + { + return FALSE; + } + + if (zSaveLoadGetPreAutoSave()) + { + return FALSE; + } + + if (oob_player_teleported) + { + shared.flags &= ~0x8; + } + + if ((shared.flags & 0x8) && !(globals.player.ControlOff & 0x8000)) + { + force_start(); + } + + while (true) + { + state_enum newtype = shared.state->update(scene, dt); + if (newtype == shared.state->type) + { + break; + } + + shared.state->stop(); + shared.state = shared.states[newtype]; + shared.state->start(); + } + + + return shared.control; +} + bool oob_state::IsPlayerInControl() { return oob_state::shared.control == 0; diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index 103c6a3e9..bd37d8977 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -11,6 +11,7 @@ extern bool oob_player_teleported; namespace oob_state { + U8 update(xScene& scene, F32 dt); bool render(); void fx_render(); void force_start(); From 296fdcd88ac64d95564e25de9bbb9dd378a7abcd Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 20:11:07 -0600 Subject: [PATCH 18/19] OOBState: Match progress for init func --- src/SB/Game/zEntPlayerOOBState.cpp | 120 +++++++++-------------------- 1 file changed, 38 insertions(+), 82 deletions(-) diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index eb86f7234..507f403ab 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -315,88 +315,6 @@ namespace oob_state } // namespace } // namespace oob_state -/* -static class -{ - // total size: 0x70 -public: - signed int flags; // offset 0x0, size 0x4 - class state_type* state; // offset 0x4, size 0x4 - unsigned char control; // offset 0x8, size 0x1 - class state_type* states[4]; // offset 0xC, size 0x10 - float out_time; // offset 0x1C, size 0x4 - float max_out_time; // offset 0x20, size 0x4 - float reset_time; // offset 0x24, size 0x4 - class xModelInstance* model; // offset 0x28, size 0x4 - class xVec2 loc; // offset 0x2C, size 0x8 - class xVec2 dir; // offset 0x34, size 0x8 - float fade_alpha; // offset 0x3C, size 0x4 - unsigned char render_hand; // offset 0x40, size 0x1 - unsigned char vertical; // offset 0x41, size 0x1 - float vel; // offset 0x44, size 0x4 - float accel; // offset 0x48, size 0x4 - class ztalkbox* tutorial; // offset 0x4C, size 0x4 - class - { - // total size: 0x20 - public: - float near_d; // offset 0x0, size 0x4 - float near_h; // offset 0x4, size 0x4 - float near_pitch; // offset 0x8, size 0x4 - float far_d; // offset 0xC, size 0x4 - float far_h; // offset 0x10, size 0x4 - float far_pitch; // offset 0x14, size 0x4 - class xMat4x3* tgt_mat; // offset 0x18, size 0x4 - class xMat4x3* tgt_omat; // offset 0x1C, size 0x4 - } cam_data; // offset 0x50, size 0x20 -} -shared; // size: 0x70, address: 0x4DFA90 -*/ - -/* -static class { - // total size: 0x58 -public: - float bottom_anim_frac; // offset 0x0, size 0x4 - float top_anim_frac; // offset 0x4, size 0x4 - float bottom_anim_time; // offset 0x8, size 0x4 - float top_anim_time; // offset 0xC, size 0x4 - float hit_anim_time; // offset 0x10, size 0x4 - float damage_rot; // offset 0x14, size 0x4 - float death_time; // offset 0x18, size 0x4 - float vel_blur; // offset 0x1C, size 0x4 - float fade_dist; // offset 0x20, size 0x4 - float player_radius; // offset 0x24, size 0x4 - float hook_fade_alpha; // offset 0x28, size 0x4 - float hook_fade_time; // offset 0x2C, size 0x4 - class { - // total size: 0xC - public: - float edge_zone; // offset 0x0, size 0x4 - float sway; // offset 0x4, size 0x4 - float decay; // offset 0x8, size 0x4 - } horizontal; // offset 0x30, size 0xC - class { - // total size: 0x10 - public: - float time; // offset 0x0, size 0x4 - float anim_out_time; // offset 0x4, size 0x4 - float min_dist; // offset 0x8, size 0x4 - float max_dist; // offset 0xC, size 0x4 - } dive; // offset 0x3C, size 0x10 - class { - // total size: 0x4 - public: - float speed; // offset 0x0, size 0x4 - } camera; // offset 0x4C, size 0x4 - class { - // total size: 0x8 - public: - float spring; // offset 0x0, size 0x4 - float decay; // offset 0x4, size 0x4 - } turn; // offset 0x50, size 0x8 -} fixed; // size: 0x58, address: 0x5CDE00 */ - void oob_state::load_settings(xIniFile& ini) { fixed.hand_model = xIniGetString(&ini, "player.state.out_of_bounds.hand_model", "hand"); @@ -447,6 +365,44 @@ void oob_state::load_settings(xIniFile& ini) void oob_state::init() { + if ((shared.flags & 0x1) != 0x1) + { + return; + } + + shared.flags |= 0x2; + + static in_state_type in_state; + shared.states[0] = &in_state; + + static out_state_type out_state; + shared.states[1] = &out_state; + + static grab_state_type grab_state; + shared.states[2] = &grab_state; + + static drop_state_type drop_state; + shared.states[3] = &drop_state; + + shared.max_out_time = fixed.out_time; + shared.fade_alpha = 1.0f; + shared.render_hand = FALSE; + shared.control = FALSE; + + U32 bufsize; + void* info = xSTFindAsset(xStrHash(fixed.hand_model), &bufsize); + + xModelInstance* model; + if (info == NULL) + { + model = NULL; + } + else + { + model = xEntLoadModel(NULL, (RpAtomic*)info); + } + + shared.model = model; } namespace oob_state From 0d8b23fb6adb642b8bde6de81a99cf998793b4bb Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sun, 14 Dec 2025 20:16:11 -0600 Subject: [PATCH 19/19] OOBState: Migrate remaining weak functions --- src/SB/Core/x/xMath2.h | 19 ++++++++++++++++--- src/SB/Game/zEntPlayerOOBState.cpp | 11 ----------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/SB/Core/x/xMath2.h b/src/SB/Core/x/xMath2.h index 95e4fffce..66ac08cae 100644 --- a/src/SB/Core/x/xMath2.h +++ b/src/SB/Core/x/xMath2.h @@ -55,9 +55,22 @@ struct xVec2 xVec2& assign(F32 x, F32 y); F32 length() const; F32 length2() const; - xVec2 normal() const; - xVec2& normalize(); - F32 dot(const xVec2&) const; + xVec2 normal() const + { + xVec2 tmp = *this; + return tmp.normalize(); + } + + xVec2& normalize() + { + *this /= length(); + return *this; + } + + F32 dot(const xVec2& b) const + { + return (x * b.x) + (y * b.y); + } xVec2& operator=(F32); xVec2 operator*(F32) const; diff --git a/src/SB/Game/zEntPlayerOOBState.cpp b/src/SB/Game/zEntPlayerOOBState.cpp index 507f403ab..25dbc47b6 100644 --- a/src/SB/Game/zEntPlayerOOBState.cpp +++ b/src/SB/Game/zEntPlayerOOBState.cpp @@ -1269,14 +1269,3 @@ namespace oob_state } } // namespace } // namespace oob_state - -WEAK F32 xVec2::dot(const xVec2& b) const -{ - return (x * b.x) + (y * b.y); -} - -WEAK xVec2& xVec2::normalize() -{ - *this /= length(); - return *this; -}