diff --git a/src/SB/Core/x/xBase.h b/src/SB/Core/x/xBase.h index c27425f..aa747a7 100644 --- a/src/SB/Core/x/xBase.h +++ b/src/SB/Core/x/xBase.h @@ -20,15 +20,15 @@ typedef S32 (*xBaseEventCB)(xBase*, xBase*, U32, const F32*, xBase*); // Size: 0x10 struct xBase { - U32 id; - U8 baseType; - U8 linkCount; - U16 baseFlags; - xLinkAsset* link; - void (*eventFunc)(xBase*, xBase*, U32, F32*, xBase*, U32); + U32 id; // 0x0 + U8 baseType; // 0x4 + U8 linkCount; // 0x5 + U16 baseFlags; // 0x6 + xLinkAsset* link; // 0x8 + void (*eventFunc)(xBase*, xBase*, U32, F32*, xBase*, U32); // 0xC }; -void xBaseInit(xBase* xb, xBaseAsset* asset); +void xBaseInit(xBase* xb, const xBaseAsset* asset); void xBaseSetup(xBase* xb); void xBaseSave(xBase* ent, xSerial* s); void xBaseLoad(xBase* ent, xSerial* s); diff --git a/src/SB/Core/x/xCamera.cpp b/src/SB/Core/x/xCamera.cpp index ca96ebb..7481da2 100644 --- a/src/SB/Core/x/xCamera.cpp +++ b/src/SB/Core/x/xCamera.cpp @@ -6,6 +6,8 @@ #include "xScene.h" #include "xCollideFast.h" #include "xScrFx.h" +#include "zGlobals.h" +#include "zMain.h" #include "iMath.h" @@ -66,44 +68,6 @@ struct cameraFXTableEntry void (*funcKill)(cameraFX*); }; -extern F32 _764; -extern F32 _765; -extern F32 _766; -extern F32 _785; -extern F32 _786; -extern F32 _787; -extern F32 _788; -extern F32 _789; -extern F32 _790; -extern F32 _830; -extern F32 _831; -extern F32 _873; -extern F32 _874; -extern F32 _880; -extern F32 _888; -extern F32 _895; -extern F32 _1234; -extern F32 _1235; -extern F32 _1236; -extern F32 _1237; -extern F32 _1238; -extern F32 _1239; -extern F32 _1240; -extern F32 _1241; -extern F32 _1242; -extern F32 _1283; -extern F64 _1286; -extern F32 _1404; -extern F32 _1405; -extern F32 _1534; -extern F32 _1584; -extern F32 _1585; -extern F32 _1586; -extern F32 _1757; -extern F32 _1758; -extern F32 _1766; -extern F32 _1772; - extern S32 sCamCollis; extern volatile S32 xcam_collis_owner_disable; extern S32 xcam_do_collis; @@ -124,29 +88,41 @@ F32 xasin(F32 x) void xCameraRotate(xCamera* cam, const xVec3& v, F32 roll, F32 time, F32 accel, F32 decl) { - cam->yaw_goal = xatan2(v.x, v.z); - cam->pitch_goal = -xasin(v.y); + cam->yaw_goal = xAngleClampFast(atan2(v.x, v.z)); + F32 fVar2 = v.y; + + if (v.y > 1.0f) + { + fVar2 = 1.0f; + } + + if (fVar2 < -1.0f) + { + fVar2 = -1.0f; + } + + cam->pitch_goal = -(F32)asin(fVar2); cam->roll_goal = roll; - if (_765 == time) + if (0.0f == time) { cam->yaw_cur = cam->yaw_goal; cam->pitch_cur = cam->pitch_goal; cam->roll_cur = cam->roll_goal; } - cam->flags = cam->flags & ~0xF80 | 0x80; + cam->flags = (cam->flags & ~0xF80) | 0x80; xMat3x3Euler(&cam->mat, cam->yaw_goal, cam->pitch_goal, cam->roll_goal); - if (_765 == time) + if (0.0f == time) { *(xMat3x3*)&cam->omat = *(xMat3x3*)&cam->mat; } - if (_765 == time) + if (0.0f == time) { - cam->ltm_acc = cam->ltm_dec = cam->ltmr = _765; + cam->ltm_acc = cam->ltm_dec = cam->ltmr = 0.0f; } else { @@ -155,7 +131,7 @@ void xCameraRotate(xCamera* cam, const xVec3& v, F32 roll, F32 time, F32 accel, cam->ltmr = time; } - cam->yaw_epv = cam->pitch_epv = cam->roll_epv = _765; + cam->yaw_epv = cam->pitch_epv = cam->roll_epv = 0.0f; } void xCameraRotate(xCamera* cam, const xMat3x3& m, F32 time, F32 accel, F32 decl) @@ -170,7 +146,7 @@ void xCameraRotate(xCamera* cam, const xMat3x3& m, F32 time, F32 accel, F32 decl cam->pitch_goal = eu.y; cam->roll_goal = eu.z; - if (_765 == time) + if (0.0f == time) { cam->yaw_cur = eu.x; cam->pitch_cur = eu.y; @@ -179,14 +155,14 @@ void xCameraRotate(xCamera* cam, const xMat3x3& m, F32 time, F32 accel, F32 decl *(xMat3x3*)&cam->mat = m; - if (_765 == time) + if (0.0f == time) { *(xMat3x3*)&cam->omat = m; } - if (_765 == time) + if (0.0f == time) { - cam->ltm_acc = cam->ltm_dec = cam->ltmr = _765; + cam->ltm_acc = cam->ltm_dec = cam->ltmr = 0.0f; } else { @@ -195,7 +171,7 @@ void xCameraRotate(xCamera* cam, const xMat3x3& m, F32 time, F32 accel, F32 decl cam->ltmr = time; } - cam->yaw_epv = cam->pitch_epv = cam->roll_epv = _765; + cam->yaw_epv = cam->pitch_epv = cam->roll_epv = 0.0f; } void xCameraLookYPR(xCamera* cam, U32 flags, F32 yaw, F32 pitch, F32 roll, F32 tm, F32 tm_acc, @@ -206,7 +182,7 @@ void xCameraLookYPR(xCamera* cam, U32 flags, F32 yaw, F32 pitch, F32 roll, F32 t cam->pitch_goal = pitch; cam->roll_goal = roll; - if (tm <= _765) + if (tm <= 0.0f) { if (cam->tgt_mat) { @@ -226,7 +202,7 @@ void xCameraLookYPR(xCamera* cam, U32 flags, F32 yaw, F32 pitch, F32 roll, F32 t cam->ltm_dec = tm_dec; cam->ltmr = tm; - F32 s = _788 / (tm - _766 * (tm_acc - tm_dec)); + F32 s = 1.0f / (tm - 0.5f * (tm_acc - tm_dec)); cam->yaw_epv = s * xDangleClamp(yaw - cam->yaw_cur); cam->pitch_epv = s * xDangleClamp(pitch - cam->pitch_cur); @@ -237,29 +213,28 @@ void xCameraLookYPR(xCamera* cam, U32 flags, F32 yaw, F32 pitch, F32 roll, F32 t void xCameraFOV(xCamera* cam, F32 fov, F32 maxSpeed, F32 dt) { F32 speed = maxSpeed * dt; - F32 currentFOV = xCameraGetFOV(cam); - if (currentFOV != fov) + if (cam->fov != fov) { - if (speed != _765) + if (speed != 0.0f) { - F32 len = fov - currentFOV; - - if ((F32)iabs(len) > speed) + F32 currentFOV = fov - cam->fov; + if (iabs(currentFOV) > speed) { - len *= speed / len; - xCameraSetFOV(cam, currentFOV + len); + F32 newFOV = currentFOV * (speed / currentFOV); + cam->fov += newFOV; } else { - xCameraSetFOV(cam, fov); + cam->fov = fov; } } else { - xCameraSetFOV(cam, fov); + cam->fov = fov; } } + return; } void xCameraMove(xCamera* cam, const xVec3& loc, F32 maxSpeed) @@ -271,7 +246,7 @@ void xCameraMove(xCamera* cam, const xVec3& loc, F32 maxSpeed) f1 = xVec3Length(&var_28); - if (f1 > maxSpeed) + if (f1 > 0.0f) { xVec3SMul(&var_28, &var_28, maxSpeed / f1); xVec3Add(&cam->mat.pos, &cam->mat.pos, &var_28); @@ -283,14 +258,15 @@ void xCameraMove(xCamera* cam, const xVec3& loc, F32 maxSpeed) cam->omat.pos = cam->mat.pos; cam->flags &= ~0x3E; - cam->tm_acc = cam->tm_dec = cam->tmr = _765; + cam->tm_acc = cam->tm_dec = cam->tmr = 0.0f; } void xCameraMove(xCamera* cam, const xVec3& loc) { + // xVec3::operator= needs to be inlined? And use lwz/stw for some reason? cam->omat.pos = cam->mat.pos = loc; cam->flags &= ~0x3E; - cam->tm_acc = cam->tm_dec = cam->tmr = _765; + cam->tm_acc = cam->tm_dec = cam->tmr = 0.0f; } static void xCam_cyltoworld(xVec3* v, const xMat4x3* tgt_mat, F32 d, F32 h, F32 p, U32 flags) @@ -326,7 +302,7 @@ void xCameraMove(xCamera* cam, U32 flags, F32 dgoal, F32 hgoal, F32 pgoal, F32 t cam->hgoal = hgoal; cam->pgoal = pgoal; - if (tm <= _765) + if (tm <= 0.0f) { if (cam->tgt_mat) { @@ -334,10 +310,29 @@ void xCameraMove(xCamera* cam, U32 flags, F32 dgoal, F32 hgoal, F32 pgoal, F32 t cam->hcur = hgoal; cam->pcur = pgoal; - xCam_cyltoworld(&cam->mat.pos, cam->tgt_mat, dgoal, hgoal, pgoal, cam->flags); - + U32 uVar1 = cam->flags; + xMat4x3* tgt_mat = cam->tgt_mat; + if ((uVar1 & 0x10) != 0) + { + cam->mat.pos.y = hgoal; + } + else + { + cam->mat.pos.y = hgoal + (tgt_mat->pos).y; + } + if ((uVar1 & 0x20) != 0) + { + cam->mat.pos.x = dgoal * isin(pgoal) + tgt_mat->pos.x; + cam->mat.pos.z = dgoal * icos(pgoal) + tgt_mat->pos.z; + } + else + { + F32 angle = xAngleClampFast(atan2(tgt_mat->at.x, tgt_mat->at.z)); + cam->mat.pos.x = dgoal * isin(pgoal + angle) + tgt_mat->pos.x; + cam->mat.pos.z = dgoal * icos(pgoal + angle) + tgt_mat->pos.z; + } cam->omat.pos = cam->mat.pos; - cam->yaw_cur = cam->yaw_goal = cam->pcur + ((cam->pcur >= _786) ? _1534 : _786); + cam->yaw_cur = cam->yaw_goal = cam->pcur + ((cam->pcur >= PI) ? -PI : PI); } } else @@ -347,20 +342,24 @@ void xCameraMove(xCamera* cam, U32 flags, F32 dgoal, F32 hgoal, F32 pgoal, F32 t cam->tm_dec = tm_dec; cam->tmr = tm; - F32 s = _788 / (tm - _766 * (tm_acc - tm_dec)); + F32 s = 1.0f / (tm - 0.5f * (tm_acc - tm_dec)); cam->depv = s * (dgoal - cam->dcur); cam->hepv = s * (hgoal - cam->hcur); - cam->pepv = xDangleClamp(pgoal - cam->pcur) * s * _766 * (dgoal + cam->dcur); + cam->pepv = xDangleClamp(pgoal - cam->pcur) * s * 0.5f * (dgoal + cam->dcur); } } void xCameraDoCollisions(S32 do_collis, S32 owner) { - xcam_collis_owner_disable &= ~(1 << owner); - xcam_collis_owner_disable |= !do_collis << owner; - - xcam_do_collis = (xcam_collis_owner_disable == 0); + S32 temp_r3; + S32 temp_r5; + + temp_r5 = xcam_collis_owner_disable & ~(1 << owner); + temp_r3 = temp_r5 | ((do_collis == 0) << owner); + xcam_collis_owner_disable = temp_r5; + xcam_collis_owner_disable = temp_r3; + xcam_do_collis = (temp_r3 == 0); } void xCameraSetTargetOMatrix(xCamera* cam, xMat4x3* mat) @@ -380,21 +379,16 @@ void xCameraSetScene(xCamera* cam, xScene* sc) iCameraAssignEnv(cam->lo_cam, sc->env->geom); } -static void _xCameraUpdate(xCamera* cam, F32 dt) -{ - // lol nope -} +static void _xCameraUpdate(xCamera* cam, F32 dt); // Inlining issue void xCameraUpdate(xCamera* cam, F32 dt) { S32 i; - S32 num_updates; - F32 sdt; - - num_updates = std::ceilf(_1283 * dt); - - sdt = dt / num_updates; + // num_updates_f doesn't exist in the dwarf but needed to match + F32 num_updates_f = ceil(144.0f * dt); + S32 num_updates = num_updates_f; + F32 sdt = dt / num_updates; for (i = 0; i < num_updates; i++) { @@ -404,6 +398,418 @@ void xCameraUpdate(xCamera* cam, F32 dt) } } +static void _xCameraUpdate(xCamera* cam, F32 dt) +{ + if (!cam->tgt_mat) + return; + + static F32 last_dt = 1.0f / 60; + + //xCam_worldtocyl(cam->dcur, cam->hcur, cam->pcur, cam->tgt_mat, &cam->mat.pos, cam->flags); + + F32 wcvx = cam->mat.pos.x - cam->omat.pos.x; + F32 wcvy = cam->mat.pos.y - cam->omat.pos.y; + F32 wcvz = cam->mat.pos.z - cam->omat.pos.z; + F32 m = 1.0f / last_dt; + wcvx *= m; + wcvy *= m; + wcvz *= m; + + cam->omat.pos = cam->mat.pos; + + //xCam_buildbasis(cam); + + F32 dcv = wcvx * cam->mbasis.at.x + wcvz * cam->mbasis.at.z; + F32 hcv = wcvy; + F32 pcv = wcvx * cam->mbasis.right.x + wcvz * cam->mbasis.right.z; + wcvx *= dt; + wcvy *= dt; + wcvz *= dt; + + cam->mat.pos.x += wcvx; + cam->mat.pos.y += wcvy; + cam->mat.pos.z += wcvz; + + if (cam->flags & 0x1) + { + F32 tnext = cam->tmr - dt; + if (tnext <= 0.0f) + { + cam->flags &= ~0x1; + cam->tmr = 0.0f; + cam->omat.pos = cam->mat.pos; + } + else + { + F32 dtg = cam->dgoal - cam->dcur; + F32 htg = cam->hgoal - cam->hcur; + F32 ptg = (cam->dgoal + cam->dcur) * xDangleClamp(cam->pgoal - cam->pcur) * 0.5f; + F32 dsv, hsv, psv; + if (tnext <= cam->tm_dec) + { + F32 T_inv = 1.0f / cam->tmr; + dsv = (2.0f * dtg - dcv * dt) * T_inv; + hsv = (2.0f * htg - hcv * dt) * T_inv; + psv = (2.0f * ptg - pcv * dt) * T_inv; + } + else if (tnext <= cam->tm_acc) + { + F32 T_inv = 1.0f / (2.0f * cam->tmr - dt - cam->tm_dec); + dsv = (2.0f * dtg - dcv * dt) * T_inv; + hsv = (2.0f * htg - hcv * dt) * T_inv; + psv = (2.0f * ptg - pcv * dt) * T_inv; + } + else + { + F32 it = cam->tm_acc + (cam->tmr - dt) - cam->tm_dec; + F32 ot = 2.0f / (cam->tmr + cam->tm_acc - cam->tm_dec); + F32 T_inv = 1.0f / (cam->tmr - cam->tm_acc); + dsv = (2.0f * dtg - (dtg * ot + cam->depv) * 0.5f * it - dcv * dt) * T_inv; + hsv = (2.0f * htg - (htg * ot + cam->hepv) * 0.5f * it - hcv * dt) * T_inv; + psv = (2.0f * ptg - (ptg * ot + cam->pepv) * 0.5f * it - pcv * dt) * T_inv; + } + F32 dpv = dsv - dcv; + F32 hpv = hsv - hcv; + F32 ppv = psv - pcv; + F32 vax = cam->mbasis.right.x * ppv + cam->mbasis.at.x * dpv; + F32 vay = cam->mbasis.right.y * ppv + hpv; + F32 vaz = cam->mbasis.right.z * ppv + cam->mbasis.at.z * dpv; + vax *= dt; + vay *= dt; + vaz *= dt; + cam->mat.pos.x += vax; + cam->mat.pos.y += vay; + cam->mat.pos.z += vaz; + cam->tmr = tnext; + } + } + else + { + if (cam->flags & 0x2) + { + //if (xeq(cam->dcur / cam->dgoal, 1.0f, 1e-5f)) + { + } + //else + { + F32 dtg = cam->dgoal - cam->dcur; + //xCam_CorrectD(cam, dtg, dcv, dt); + } + } + else if (cam->dmax > cam->dmin) + { + if (cam->dcur < cam->dmin) + { + F32 dtg = cam->dmin - cam->dcur; + //xCam_CorrectD(cam, dtg, dcv, dt); + } + else if (cam->dcur > cam->dmax) + { + F32 dtg = cam->dmax - cam->dcur; + //xCam_CorrectD(cam, dtg, dcv, dt); + } + } + + if (cam->flags & 0x4) + { + //if (xeq(cam->hcur / cam->hgoal, 1.0f, 1e-5f)) + { + } + //else + { + F32 htg = cam->hgoal - cam->hcur; + //xCam_CorrectH(cam, htg, hcv, dt); + } + } + else if (cam->hmax > cam->hmin) + { + if (cam->hcur < cam->hmin) + { + F32 htg = cam->hmin - cam->hcur; + //xCam_CorrectH(cam, htg, hcv, dt); + } + else if (cam->hcur > cam->hmax) + { + F32 htg = cam->hmax - cam->hcur; + //xCam_CorrectH(cam, htg, hcv, dt); + } + } + + if (cam->flags & 0x8) + { + //if (xeq(cam->pcur / cam->pgoal, 1.0f, 1e-5f)) + { + } + //else + { + F32 ptg = cam->dcur * xDangleClamp(cam->pgoal - cam->pcur); + //xCam_CorrectP(cam, ptg, pcv, dt); + } + } + else if (cam->pmax > cam->pmin) + { + F32 dphi = xDangleClamp(cam->pmax - cam->pcur); + F32 dplo = xDangleClamp(cam->pmin - cam->pcur); + if (dplo > 0.0f && (dphi > 0.0f || xabs(dplo) <= xabs(dphi))) + { + F32 ptg = (1e-5f + dplo) * cam->dcur; + //xCam_CorrectP(cam, ptg, pcv, dt); + } + else if (dphi < 0.0f) + { + F32 ptg = (dphi - 1e-5f) * cam->dcur; + //xCam_CorrectP(cam, ptg, pcv, dt); + } + else + { + //xCam_DampP(cam, pcv, dt); + } + } + else + { + //xCam_DampP(cam, pcv, dt); + } + } + + if (cam->flags & 0x80) + { + xVec3 oeu, eu; + xMat3x3GetEuler(&cam->mat, &eu); + xMat3x3GetEuler(&cam->omat, &oeu); + + F32 m = 1.0f / last_dt; + F32 ycv = m * xDangleClamp(eu.x - oeu.x); + F32 pcv = m * xDangleClamp(eu.y - oeu.y); + F32 rcv = m * xDangleClamp(eu.z - oeu.z); + ycv *= cam->yaw_ccv; + pcv *= cam->pitch_ccv; + rcv *= cam->roll_ccv; + + cam->omat = cam->mat; + cam->yaw_cur += ycv * dt; + cam->pitch_cur += pcv * dt; + cam->roll_cur += rcv * dt; + + if (cam->flags & 0x40) + { + F32 tnext = cam->ltmr - dt; + if (tnext <= 0.0f) + { + cam->flags &= ~0x40; + cam->ltmr = 0.0f; + } + else + { + F32 ytg = xDangleClamp(cam->yaw_goal - cam->yaw_cur); + F32 ptg = xDangleClamp(cam->pitch_goal - cam->pitch_cur); + F32 rtg = xDangleClamp(cam->roll_goal - cam->roll_cur); + F32 ysv, psv, rsv; + if (tnext <= cam->ltm_dec) + { + F32 T_inv = 1.0f / cam->ltmr; + ysv = (2.0f * ytg - ycv * dt) * T_inv; + psv = (2.0f * ptg - pcv * dt) * T_inv; + rsv = (2.0f * rtg - rcv * dt) * T_inv; + } + else if (tnext <= cam->ltm_acc) + { + F32 T_inv = 1.0f / (2.0f * cam->ltmr - dt - cam->ltm_dec); + ysv = (2.0f * ytg - ycv * dt) * T_inv; + psv = (2.0f * ptg - pcv * dt) * T_inv; + rsv = (2.0f * rtg - rcv * dt) * T_inv; + } + else + { + F32 it = cam->ltm_acc + (cam->ltmr - dt) - cam->ltm_dec; + F32 ot = 2.0f / (cam->ltmr + cam->ltm_acc - cam->ltm_dec); + F32 T_inv = 1.0f / (cam->ltmr - cam->ltm_acc); + ysv = ((2.0f * ytg - (ytg * ot + cam->yaw_epv) * 0.5f * it) - ycv * dt) * T_inv; + psv = + ((2.0f * ptg - (ptg * ot + cam->pitch_epv) * 0.5f * it) - pcv * dt) * T_inv; + rsv = + ((2.0f * rtg - (rtg * ot + cam->roll_epv) * 0.5f * it) - rcv * dt) * T_inv; + } + F32 ypv = ysv - ycv; + F32 ppv = psv - pcv; + F32 rpv = rsv - rcv; + cam->yaw_cur += ypv * dt; + cam->pitch_cur += ppv * dt; + cam->roll_cur += rpv * dt; + xMat3x3Euler(&cam->mat, cam->yaw_cur, cam->pitch_cur, cam->roll_cur); + cam->ltmr = tnext; + } + } + else + { + //if (xeq(cam->yaw_cur, cam->yaw_goal, 1e-5f)) + { + } + //else + { + F32 ytg = xDangleClamp(cam->yaw_goal - cam->yaw_cur); + //xCam_CorrectYaw(cam, ytg, ycv, dt); + } + + //if (xeq(cam->pitch_cur, cam->pitch_goal, 1e-5f)) + { + } + //else + { + F32 ptg = xDangleClamp(cam->pitch_goal - cam->pitch_cur); + //xCam_CorrectPitch(cam, ptg, pcv, dt); + } + + //if (xeq(cam->roll_cur, cam->roll_goal, 1e-5f)) + { + } + //else + { + F32 rtg = xDangleClamp(cam->roll_goal - cam->roll_cur); + //xCam_CorrectRoll(cam, rtg, rcv, dt); + } + + xMat3x3Euler(&cam->mat, cam->yaw_cur, cam->pitch_cur, cam->roll_cur); + } + } + else + { + xQuatFromMat(&cam->orn_cur, &cam->mat); + + xQuat oq; + xQuatFromMat(&oq, &cam->omat); + + xQuat qdiff_o_c; + xQuatDiff(&qdiff_o_c, &oq, &cam->orn_cur); + + xRot rot_cv; + //xQuatToAxisAngle(&qdiff_o_c, &rot_cv.axis, &rot_cv.angle); + rot_cv.angle *= m; + rot_cv.angle = 0.0f; // lol + + cam->omat = cam->mat; + + xVec3 f; + xMat3x3RMulVec(&f, cam->tgt_mat, &cam->focus); + xVec3AddTo(&f, &cam->tgt_mat->pos); + + xVec3 v; + F32 dist; + //xVec3NormalizeDistXZMacro(&v, &cam->mat.pos, &cam->tgt_mat->pos, &dist); + v.y = 0.0f; + + if (cam->tgt_mat->at.x * v.x + cam->tgt_mat->at.y * v.y + cam->tgt_mat->at.z * v.z < 0.0f) + { + F32 mpx = f.x - cam->tgt_mat->pos.x; + F32 mpy = f.y - cam->tgt_mat->pos.y; + F32 mpz = f.z - cam->tgt_mat->pos.z; + F32 s = (mpx * v.x + mpy * v.y + mpz * v.z) * -2.0f; + mpx = v.x * s; + mpy = v.y * s; + mpz = v.z * s; + f.x += mpx; + f.y += mpy; + f.z += mpz; + } + + xMat3x3 des_mat; + xMat3x3LookAt(&des_mat, &f, &cam->mat.pos); + + xMat3x3 latgt; + xMat3x3LookAt(&latgt, &cam->tgt_mat->pos, &cam->mat.pos); + + F32 ang_dist = xacos(latgt.at.x * des_mat.at.x + latgt.at.y * des_mat.at.y + + latgt.at.z * des_mat.at.z); + + if (ang_dist > DEG2RAD(30.0f)) + { + xQuat a; + xQuatFromMat(&a, &latgt); + + xQuat b; + xQuatFromMat(&b, &des_mat); + + xQuat o; + F32 s = PI - ang_dist; + if (s < DEG2RAD(90.0f)) + { + if (s > DEG2RAD(5.0f)) + { + xQuatSlerp(&o, &a, &b, s / ang_dist); + } + else + { + o = a; + } + } + else + { + xQuatSlerp(&o, &a, &b, DEG2RAD(30.0f) / ang_dist); + } + + xQuatToMat(&o, &des_mat); + } + + xQuat desq; + xQuatFromMat(&desq, &des_mat); + + //xCameraLook(cam, 0, &desq, 0.25f, 0.0f, 0.0f); + + xQuat difq; + xQuatConj(&difq, &cam->orn_cur); + xQuatMul(&difq, &difq, &desq); + + xQuat newq; + xQuatSlerp(&newq, &cam->orn_cur, &desq, 25.5f * dt); + xQuatToMat(&newq, &cam->mat); + } + + while (xcam_do_collis && sCamCollis) + { + xSweptSphere sws; + + xVec3 tgtpos; + tgtpos.x = cam->tgt_mat->pos.x; + tgtpos.y = 0.7f + cam->tgt_mat->pos.y; + tgtpos.z = cam->tgt_mat->pos.z; + + xSweptSpherePrepare(&sws, &tgtpos, &cam->mat.pos, 0.07f); + //xSweptSphereToEnv(&sws, globals.sceneCur->env); + + xRay3 ray; + xVec3Copy(&ray.origin, &sws.start); + xVec3Sub(&ray.dir, &sws.end, &sws.start); + + ray.max_t = xVec3Length(&ray.dir); + + F32 one_len = 1.0f / MAX(ray.max_t, 1e-5f); + xVec3SMul(&ray.dir, &ray.dir, one_len); + + ray.flags = 0x800; + if (!(ray.flags & 0x400)) + { + ray.flags |= 0x400; + ray.min_t = 0.0f; + } + + //xRayHitsGrid(&colls_grid, globals.sceneCur, &ray, SweptSphereHitsCameraEnt, &sws.qcd, &sws); + //xRayHitsGrid(&colls_oso_grid, globals.sceneCur, &ray, SweptSphereHitsCameraEnt, &sws.qcd, &sws); + + if (sws.curdist != sws.dist) + { + F32 stopdist = MAX(sws.curdist, 0.6f); + cam->mat.pos.x = ray.origin.x + stopdist * ray.dir.x; + cam->mat.pos.y = ray.origin.y + stopdist * ray.dir.y; + cam->mat.pos.z = ray.origin.z + stopdist * ray.dir.z; + } + + break; + } + + last_dt = dt; + + iCameraUpdatePos(cam->lo_cam, &cam->mat); +} + void SweptSphereHitsCameraEnt(xScene*, xRay3* ray, xQCData* qcd, xEnt* ent, void* data) { xSweptSphere* sws = (xSweptSphere*)data; @@ -421,12 +827,12 @@ void SweptSphereHitsCameraEnt(xScene*, xRay3* ray, xQCData* qcd, xEnt* ent, void { if (ent->bound.type == XBOUND_TYPE_BOX) { - xSweptSphereToBox(sws, &ent->bound.box.box, NULL); + xSweptSphereToBox(*sws, ent->bound.box.box); return; } else if (ent->bound.type == XBOUND_TYPE_OBB) { - xSweptSphereToBox(sws, &ent->bound.box.box, ent->bound.mat); + xSweptSphereToOBB(sws, &ent->bound.box.box, ent->bound.mat); return; } else @@ -475,7 +881,7 @@ void SweptSphereHitsCameraEnt(xScene*, xRay3* ray, xQCData* qcd, xEnt* ent, void F32 f31 = xVec3Length(&ent->bound.mat->right); xMat3x3Normalize(&mn, ent->bound.mat); - xMat4x3Tolocal(&lr.origin, ent->bound.mat, &ray->origin); + xMat3x3Tolocal(&lr.origin, ent->bound.mat, &ray->origin); xMat3x3Tolocal(&lr.dir, &mn, &ray->dir); lr.max_t = ray->max_t / f31; @@ -508,47 +914,124 @@ static void xCam_buildbasis(xCamera* cam) { if (cam->tgt_mat) { - F32 d2d; F32 dx__ = cam->mat.pos.x - cam->tgt_mat->pos.x; F32 dz__ = cam->mat.pos.z - cam->tgt_mat->pos.z; F32 dist2 = SQR(dx__) + SQR(dz__); F32 dist_inv; + F32 d2d; + S32 iVar7; + U32 uVar5; - if ((F32)iabs(dist2 - _788) <= _830) + if ((F32)iabs(dist2 - 1.0f) <= 0.00001f) { cam->mbasis.at.x = dx__; cam->mbasis.at.z = dz__; - - d2d = _788; + d2d = 1.0f; } - else if ((F32)iabs(dist2) <= _830) + else if ((F32)iabs(dist2) <= 0.00001f) { - cam->mbasis.at.x = _765; - cam->mbasis.at.z = _765; - - d2d = _765; + cam->mbasis.at.x = 0.0f; + cam->mbasis.at.z = 0.0f; + d2d = 0.0f; } else { - d2d = xsqrt(dist2); - dist_inv = _788 / d2d; + if (dist2 > 0.0f) + { + uVar5 = *((U32*)&dist2) & 0x7f800000; + if (uVar5 == 0x7f800000) + { + if ((*((U32*)&dist2) & 0x7fffff) == 0) + iVar7 = 2; + else + iVar7 = 1; + } + else if (uVar5 < 0x7f800000 && uVar5 == 0) + { + if ((*((U32*)&dist2) & 0x7fffff) == 0) + iVar7 = 3; + else + iVar7 = 5; + } + else + { + iVar7 = 4; + } + + if (iVar7 != 2) + { + F32 inv_sqrt = 1.0f / dist2; + inv_sqrt = -(inv_sqrt * inv_sqrt * dist2 - 3.0f) * inv_sqrt * 0.5f; + if (inv_sqrt > 0.00001f) + dist_inv = 1.0f / inv_sqrt; + else + dist_inv = 100000.0f; + } + else + { + dist_inv = 1.0f; + } + } + else + { + dist_inv = 1.0f; + } cam->mbasis.at.x = dx__ * dist_inv; cam->mbasis.at.z = dz__ * dist_inv; + d2d = dist2; } - if (d2d < _830) + if (d2d < 0.00001f) { cam->mbasis.at.x = cam->mat.at.x; cam->mbasis.at.z = cam->mat.at.z; - dist2 = xsqrt(SQR(cam->mbasis.at.x) + SQR(cam->mbasis.at.z)); + dist2 = SQR(cam->mbasis.at.x) + SQR(cam->mbasis.at.z); - if (dist2 > _831) + if (dist2 > 0.001f) { - // non-matching: wrong registers - dist_inv = _788 / dist2; + if (dist2 > 0.0f) + { + uVar5 = *((U32*)&dist2) & 0x7f800000; + if (uVar5 == 0x7f800000) + { + if ((*((U32*)&dist2) & 0x7fffff) == 0) + iVar7 = 2; + else + iVar7 = 1; + } + else if (uVar5 < 0x7f800000 && uVar5 == 0) + { + if ((*((U32*)&dist2) & 0x7fffff) == 0) + iVar7 = 3; + else + iVar7 = 5; + } + else + { + iVar7 = 4; + } + + if (iVar7 != 2) + { + F32 inv_sqrt = 1.0f / dist2; + inv_sqrt = -(inv_sqrt * inv_sqrt * dist2 - 3.0f) * inv_sqrt * 0.5f; + if (inv_sqrt > 0.00001f) + dist_inv = 1.0f / inv_sqrt; + else + dist_inv = 100000.0f; + } + else + { + dist_inv = 1.0f; + } + } + else + { + dist_inv = 1.0f; + } cam->mbasis.at.x *= dist_inv; cam->mbasis.at.z *= dist_inv; @@ -560,12 +1043,12 @@ static void xCam_buildbasis(xCamera* cam) } } - cam->mbasis.at.y = _765; - cam->mbasis.up.x = _765; - cam->mbasis.up.y = _788; - cam->mbasis.up.z = _765; + cam->mbasis.at.y = 0.0f; + cam->mbasis.up.x = 0.0f; + cam->mbasis.up.y = 1.0f; + cam->mbasis.up.z = 0.0f; cam->mbasis.right.x = cam->mbasis.at.z; - cam->mbasis.right.y = _765; + cam->mbasis.right.y = 0.0f; cam->mbasis.right.z = -cam->mbasis.at.x; } } @@ -577,46 +1060,47 @@ void xCameraReset(xCamera* cam, F32 d, F32 h, F32 pitch) xMat4x3Identity(&cam->mat); cam->omat = cam->mat; - cam->focus.x = _765; - cam->focus.y = _765; - cam->focus.z = _785; - cam->tran_accum.x = _765; - cam->tran_accum.y = _765; - cam->tran_accum.z = _765; + cam->focus.x = 0.0f; + cam->focus.y = 0.0f; + cam->focus.z = 10.0f; + cam->tran_accum.x = 0.0f; + cam->tran_accum.y = 0.0f; + cam->tran_accum.z = 0.0f; cam->flags = 0; - F32 goal_p = _786; + F32 goal_p = 3.1415927f; if (cam->tgt_mat) { - goal_p += xatan2(cam->tgt_mat->at.x, cam->tgt_mat->at.z); + goal_p += atan2(cam->tgt_mat->at.x, cam->tgt_mat->at.z); } - xCameraMove(cam, 0x2E, d, h, goal_p, _765, _787, _787); + xCameraMove(cam, 0x2E, d, h, goal_p, 0.0f, 0.66666669f, 0.66666669f); cam->pitch_goal = pitch; cam->pitch_cur = pitch; - cam->roll_cur = _765; + cam->roll_cur = 0.0f; xMat3x3Euler(&cam->mat, cam->yaw_cur, cam->pitch_cur, cam->roll_cur); cam->omat = cam->mat; - cam->yaw_ct = _788; - cam->yaw_cd = _788; - cam->yaw_ccv = _789; - cam->yaw_csv = _788; - cam->pitch_ct = _788; - cam->pitch_cd = _788; - cam->pitch_ccv = _790; - cam->pitch_csv = _788; - cam->roll_ct = _788; - cam->roll_cd = _788; - cam->roll_ccv = _790; - cam->roll_csv = _788; + cam->yaw_ct = 1.0f; + cam->yaw_cd = 1.0f; + cam->yaw_ccv = 0.65f; + cam->yaw_csv = 1.0f; + cam->pitch_ct = 1.0f; + cam->pitch_cd = 1.0f; + cam->pitch_ccv = 0.7f; + cam->pitch_csv = 1.0f; + cam->roll_ct = 1.0f; + cam->roll_cd = 1.0f; + cam->roll_ccv = 0.7f; + cam->roll_csv = 1.0f; cam->flags |= 0x80; xcam_do_collis = 1; xcam_collis_owner_disable = 0; + cam->smoothOutwardSlidePos = 10.0f; } void xCameraExit(xCamera* cam) @@ -630,27 +1114,17 @@ void xCameraExit(xCamera* cam) void xCameraInit(xCamera* cam, U32 width, U32 height) { - xCameraFXInit(); - - cam->lo_cam = iCameraCreate(width, height, 1); - - xCameraSetFOV(cam, _764); - - cam->bound.sph.center.x = _765; - cam->bound.sph.center.y = _765; - cam->bound.sph.center.z = _765; - cam->bound.sph.r = _766; + cam->lo_cam = globals.screen->icam; + cam->fov = 75.0; + cam->bound.sph.center.x = 0.0f; + cam->bound.sph.center.y = 0.0f; + cam->bound.sph.center.z = 0.0f; + cam->bound.sph.r = 0.5f; cam->tgt_mat = NULL; cam->tgt_omat = NULL; cam->tgt_bound = NULL; cam->sc = NULL; - cam->tran_accum.x = _765; - cam->tran_accum.y = _765; - cam->tran_accum.z = _765; - - add_camera_tweaks(); -} - -void add_camera_tweaks() -{ + cam->tran_accum.x = 0.0f; + cam->tran_accum.y = 0.0f; + cam->tran_accum.z = 0.0f; } diff --git a/src/SB/Core/x/xCamera.h b/src/SB/Core/x/xCamera.h index 16212fb..c04b853 100644 --- a/src/SB/Core/x/xCamera.h +++ b/src/SB/Core/x/xCamera.h @@ -191,6 +191,7 @@ struct xCamera : xBase F32 roll_ccv; F32 roll_csv; xVec4 frustplane[12]; + F32 smoothOutwardSlidePos; }; struct xBinaryCamera @@ -293,6 +294,7 @@ struct xCam xCamOrientType orient_type; _class_0 coord; _class_1 orient; + U8 _padding[0x2c]; // until the anonymous union structs above are done xCamConfigCommon cfg_common; S32 group_index; S32 group_flags; diff --git a/src/SB/Core/x/xCollide.h b/src/SB/Core/x/xCollide.h index b6643fd..c54ce26 100644 --- a/src/SB/Core/x/xCollide.h +++ b/src/SB/Core/x/xCollide.h @@ -105,8 +105,9 @@ enum _xCollsIdx struct xScene; void xCollideInit(xScene* sc); -S32 xSweptSphereToBox(xSweptSphere* sws, xBox* box, xMat4x3* mat); -S32 xSweptSphereToModel(xSweptSphere* sws, RpAtomic* model, RwMatrix* mat); +S32 xSweptSphereToOBB(xSweptSphere* sws, const xBox* box, const xMat4x3* mat); +S32 xSweptSphereToBox(xSweptSphere& sws, const xBox& box); +S32 xSweptSphereToModel(xSweptSphere* sws, RpAtomic* model, const RwMatrix* mat); S32 xSweptSphereToScene(xSweptSphere* sws, xScene* sc, xEnt* mover, U8 collType); void xSweptSpherePrepare(xSweptSphere* sws, xVec3* start, xVec3* end, F32 radius); void xSweptSphereGetResults(xSweptSphere* sws); diff --git a/src/SB/Core/x/xEnt.h b/src/SB/Core/x/xEnt.h index 8740fa9..565758c 100644 --- a/src/SB/Core/x/xEnt.h +++ b/src/SB/Core/x/xEnt.h @@ -184,7 +184,7 @@ xMat4x3* xEntGetFrame(const xEnt* ent); void xEntEnable(xEnt* ent); xVec3* xEntGetCenter(const xEnt* ent); xVec3* xEntGetPos(const xEnt* ent); -U32 xEntIsVisible(const xEnt* ent); +inline U32 xEntIsVisible(const xEnt* ent); void xEntHide(xEnt* ent); void xEntShow(xEnt* ent); void xEntInitShadow(xEnt& ent, xEntShadow& shadow); diff --git a/src/SB/Core/x/xLinkAsset.h b/src/SB/Core/x/xLinkAsset.h index 31895de..0963044 100644 --- a/src/SB/Core/x/xLinkAsset.h +++ b/src/SB/Core/x/xLinkAsset.h @@ -5,12 +5,12 @@ struct xLinkAsset { - U16 srcEvent; - U16 dstEvent; - U32 dstAssetID; - F32 param[4]; - U32 paramWidgetAssetID; - U32 chkAssetID; + U16 srcEvent; // 0x0 + U16 dstEvent; // 0x2 + U32 dstAssetID; // 0x4 + F32 param[4]; // 0x8 + U32 paramWidgetAssetID; // 0x18 + U32 chkAssetID; // 0x1C }; #endif diff --git a/src/SB/Core/x/xVec3.h b/src/SB/Core/x/xVec3.h index 725a877..359a782 100644 --- a/src/SB/Core/x/xVec3.h +++ b/src/SB/Core/x/xVec3.h @@ -43,7 +43,7 @@ struct xVec3 } // FIXME: This should not be declared. Declaring it causes the assignment operator for the // anonymous struct "camera" in hook_asset to call it rather than just copy the vec members. - xVec3& operator=(const xVec3&); + //xVec3& operator=(const xVec3& v); xVec3 operator+(const xVec3&) const; xVec3 operator-(const xVec3&) const; xVec3 operator*(F32) const; diff --git a/src/SB/Core/x/xVec3Inlines.h b/src/SB/Core/x/xVec3Inlines.h index a09f848..b99e3d9 100644 --- a/src/SB/Core/x/xVec3Inlines.h +++ b/src/SB/Core/x/xVec3Inlines.h @@ -2,14 +2,33 @@ #define XVEC3INLINES_H #include "xVec3.h" +#include "fake_tgmath.h" -void xVec3Sub(xVec3* o, const xVec3* a, const xVec3* b); +inline void xVec3Sub(xVec3* o, const xVec3* a, const xVec3* b) +{ + o->x = a->x - b->x; + o->y = a->y - b->y; + o->z = a->z - b->z; +} void xVec3Cross(xVec3* o, const xVec3* a, const xVec3* b); void xVec3Inv(xVec3* o, const xVec3* v); void xVec3Copy(xVec3* o, const xVec3* v); -F32 xVec3Length(const xVec3* v); -void xVec3SMul(xVec3* o, const xVec3* v, F32 s); -void xVec3Add(xVec3* o, const xVec3* a, const xVec3* b); +inline F32 xVec3Length(const xVec3* v) +{ + return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); +} +inline void xVec3SMul(xVec3* o, const xVec3* v, F32 s) +{ + o->x = s * v->x; + o->y = s * v->y; + o->z = s * v->z; +} +inline void xVec3Add(xVec3* o, const xVec3* a, const xVec3* b) +{ + o->x = a->x + b->x; + o->y = a->y + b->y; + o->z = a->z + b->z; +} void xVec3Init(xVec3* v, F32 _x, F32 _y, F32 _z); void xVec3AddTo(xVec3* o, const xVec3* v); void xVec3Lerp(xVec3* o, const xVec3* a, const xVec3* b, F32 t); diff --git a/src/SB/Game/zCamera.cpp b/src/SB/Game/zCamera.cpp index e22df66..f7860ba 100644 --- a/src/SB/Game/zCamera.cpp +++ b/src/SB/Game/zCamera.cpp @@ -1,9 +1,16 @@ +#include "xpkrsvc.h" +#include "xScrFx.h" +#include "xstransvc.h" #include "zCamera.h" +#include "zCameraTweak.h" +#include "zGlobals.h" +#include "zMain.h" namespace { WallJumpViewState wall_jump_enabled; bool lassocam_enabled; + F32 lassocam_factor; U32 stop_track; bool input_enabled = true; F32 dMultiplier; @@ -11,8 +18,538 @@ namespace F32 hMultiplier; F32 hOffset; zCamSB* follow_cam; + xVec3 wall_jump_view; } // namespace +void zCameraMinTargetHeightClear() +{ + zcam_mintgtheight = FLOAT_MIN; +} + +void zCameraMinTargetHeightSet(F32 min_height) +{ + zcam_mintgtheight = min_height; +} + +void zCameraSetReward(S32 on) +{ + if (stop_track != 0) + { + zcam_reward = 0; + return; + } + zcam_reward = on; +} + +void zCameraDisableWallJump(xCamera* cam) +{ + if (wall_jump_enabled != WJVS_DISABLED) + { + wall_jump_enabled = WJVS_DISABLING; + } +} + +void zCameraEnableWallJump(xCamera* cam, const xVec3& collNormal) +{ + if (wall_jump_enabled != WJVS_ENABLED) + { + wall_jump_enabled = WJVS_ENABLING; + } + + xVec3 up = { 0.0f, 0.0f, 0.0f }; + + // Missing inline? + xVec3Cross(&wall_jump_view, &collNormal, &up); + xVec3Normalize(&wall_jump_view, &wall_jump_view); + + if (xVec3Dot(&wall_jump_view, &globals.oldSkoolCamera.mat.at) < 0.0f) + { + // Missing inline? + xVec3Sub(&wall_jump_view, &g_O3, &wall_jump_view); + } +} + +void zCameraTranslate(xCamera* cam, F32 x, F32 y, F32 z) +{ + cam->mat.pos.x += x; + cam->mat.pos.y += y; + cam->mat.pos.z += z; + cam->tran_accum.x += x; + cam->tran_accum.y += y; + cam->tran_accum.z += z; +} + +S32 zCameraGetConvers() +{ + return zcam_convers; +} + +F32 zCameraGetLassoCamFactor() +{ + return lassocam_factor; +} + +void zCameraSetLassoCamFactor(F32 new_factor) +{ + lassocam_factor = new_factor; +} + +void zCameraEnableLassoCam() +{ + lassocam_enabled = 1; +} + +void zCameraDisableLassoCam() +{ + lassocam_enabled = 0; +} + +void zCameraEnableInput() +{ + input_enabled = 1; +} + +void zCameraDisableInput() +{ + input_enabled = 0; +} + +U32 zCameraIsTrackingDisabled() +{ + return stop_track; +} + +void zCameraEnableTracking(camera_owner_enum owner) +{ + stop_track &= ~owner; +} + +void zCameraDisableTracking(camera_owner_enum owner) +{ + stop_track |= owner; +} + +void zCameraSetPlayerVel(xVec3* vel) +{ + zcam_playervel = vel; +} + +void zCameraSetHighbounce(S32 lbounce) +{ + if (zcam_longbounce != 0 || zcam_highbounce != lbounce) + { + zcam_lbbounce = 0; + } + + zcam_highbounce = lbounce; + zcam_longbounce = 0; +} + +void zCameraSetLongbounce(S32 lbounce) +{ + if (zcam_highbounce != 0 || zcam_longbounce != lbounce) + { + zcam_lbbounce = 0; + } + + zcam_longbounce = lbounce; + zcam_highbounce = 0; +} + +void zCameraSetBbounce(S32 bbouncing) +{ + zcam_bbounce = bbouncing; +} + +void zCameraUpdate(xCamera* camera, F32 dt) +{ + zcam_near &= 0x1; + + // Missing inline? + zCameraTweakGlobal_Update(dt); +} + +S32 zCameraIsFlyCamRunning() +{ + return zcam_fly; +} + +void zCameraFreeLookSetGoals(xCamera* cam, F32 pitch_s, F32& dgoal, F32& hgoal, F32& pitch_goal, + F32& lktm, F32 dt) +{ + // from the dwarf + F32 s; + // ghidra generated + F32 fVar2; + F32 fVar3; + F32 fVar5; + + if (zcam_bbounce == 0) + { + s = zcam_highbounce_d; + if ((zcam_highbounce == 0) && (s = sCamD, wall_jump_enabled == WJVS_ENABLED)) + { + s = zcam_wall_d; + } + fVar2 = dMultiplier * s + dOffset + 0.0; + s = zcam_highbounce_h; + if ((zcam_highbounce == 0) && (s = sCamH, wall_jump_enabled == WJVS_ENABLED)) + { + s = zcam_wall_h; + } + fVar3 = dMultiplier * s + dOffset + 0.0; + s = sCamPitch; + if (zcam_highbounce != 0) + { + s = zcam_highbounce_pitch; + } + if ((lassocam_enabled == '\0') || (stop_track != 0)) + { + if (0.0 < pitch_s) + { + dgoal = pitch_s * (zcam_below_d - fVar2) + fVar2 + 0.0; + hgoal = pitch_s * (zcam_below_h - fVar3) + fVar3 + 0.0; + pitch_goal = pitch_s * pitch_s * pitch_s * (zcam_below_pitch - s) + s + 0.0; + } + else + { + fVar5 = -pitch_s; + dgoal = fVar5 * (zcam_above_d - fVar2) + fVar2 + 0.0; + hgoal = fVar5 * (zcam_above_h - fVar3) + fVar3 + 0.0; + pitch_goal = fVar5 * (zcam_above_pitch - s) + s + 0.0; + } + if (0.1 < lktm) + { + s = lktm; + lktm = s - dt; + if (s - dt < 0.1) + { + lktm = 0.1; + } + } + else + { + lktm = 0.1; + } + } + else + { + dgoal = lassocam_factor * (fVar2 - zcam_near_d) + zcam_near_d + 0.0; + hgoal = lassocam_factor * (fVar3 - zcam_near_h) + zcam_near_h + 0.0; + pitch_goal = lassocam_factor * (s - zcam_near_pitch) + zcam_near_pitch + 0.0; + } + } + else if (zcam_highbounce == 0) + { + if (zcam_near == 0) + { + s = sCamD; + if (wall_jump_enabled == WJVS_ENABLED) + { + s = zcam_wall_d; + } + dgoal = dMultiplier * s + dOffset + 0.0; + } + else + { + dgoal = 3.5; + } + if (zcam_near == 0) + { + s = zcam_highbounce_h; + if ((zcam_highbounce == 0) && (s = sCamH, wall_jump_enabled == WJVS_ENABLED)) + { + s = zcam_wall_h; + } + hgoal = dMultiplier * s + dOffset + 0.0; + } + else + { + hgoal = 2.4; + } + if (zcam_longbounce == 0) + { + if (zcam_near == 0) + { + pitch_goal = 0.5235988; + } + else + { + pitch_goal = 0.6981317; + } + } + else + { + fVar5 = zcam_playervel->y; + bool bVar1 = zcam_playervel != 0x0; + fVar2 = zcam_playervel->x; + fVar3 = zcam_playervel->z; + s = sqrt(fVar3 * fVar3 + fVar2 * fVar2 + fVar5 * fVar5); + if ((bVar1) && (bVar1 = true, s == 0.0)) + { + bVar1 = false; + } + if (bVar1) + { + s = ((cam->mat).at.z * fVar3 + (cam->mat).at.x * fVar2 + (cam->mat).at.y * fVar5) / + s; + if (0.0 < s) + { + s = -0.0; + } + else + { + s = -s; + } + } + else + { + s = 0.0; + } + if (zcam_near == 0) + { + s = 0.5235988; + } + else + { + s = (s * 20.0 + 20.0) * 0.017453292; + } + pitch_goal = s; + } + } + else + { + s = zcam_highbounce_d; + if ((zcam_highbounce == 0) && (s = sCamD, wall_jump_enabled == WJVS_ENABLED)) + { + s = zcam_wall_d; + } + dgoal = dMultiplier * s + dOffset + 0.0; + s = zcam_highbounce_h; + if ((zcam_highbounce == 0) && (s = sCamH, wall_jump_enabled == WJVS_ENABLED)) + { + s = zcam_wall_h; + } + hgoal = dMultiplier * s + dOffset + 0.0; + s = sCamPitch; + if (zcam_highbounce != 0) + { + s = zcam_highbounce_pitch; + } + pitch_goal = s; + } + return; +} + +// WIP +static void zCameraFlyRestoreBackup(xCamera* backup) +{ + globals.oldSkoolCamera.mat = backup->mat; + globals.oldSkoolCamera.omat = backup->omat; + globals.oldSkoolCamera.mbasis = backup->mbasis; + globals.oldSkoolCamera.bound = backup->bound; + globals.oldSkoolCamera.focus = backup->focus; + + globals.oldSkoolCamera.flags = backup->flags; + globals.oldSkoolCamera.tmr = backup->tmr; + globals.oldSkoolCamera.tm_acc = backup->tm_acc; + globals.oldSkoolCamera.tm_dec = backup->tm_dec; + globals.oldSkoolCamera.ltmr = backup->ltmr; + globals.oldSkoolCamera.ltm_acc = backup->ltm_acc; + globals.oldSkoolCamera.ltm_dec = backup->ltm_dec; + globals.oldSkoolCamera.dmin = backup->dmin; + globals.oldSkoolCamera.dmax = backup->dmax; + globals.oldSkoolCamera.dcur = backup->dcur; + globals.oldSkoolCamera.dgoal = backup->dgoal; + globals.oldSkoolCamera.hmin = backup->hmin; + globals.oldSkoolCamera.hmax = backup->hmax; + globals.oldSkoolCamera.hcur = backup->hcur; + globals.oldSkoolCamera.hgoal = backup->hgoal; + globals.oldSkoolCamera.pmin = backup->pmin; + globals.oldSkoolCamera.pmax = backup->pmax; + globals.oldSkoolCamera.pcur = backup->pcur; + globals.oldSkoolCamera.pgoal = backup->pgoal; + globals.oldSkoolCamera.depv = backup->depv; + globals.oldSkoolCamera.hepv = backup->hepv; + globals.oldSkoolCamera.pepv = backup->pepv; + globals.oldSkoolCamera.orn_epv = backup->orn_epv; + globals.oldSkoolCamera.yaw_epv = backup->yaw_epv; + globals.oldSkoolCamera.pitch_epv = backup->pitch_epv; + globals.oldSkoolCamera.roll_epv = backup->roll_epv; + globals.oldSkoolCamera.orn_cur = backup->orn_cur; + globals.oldSkoolCamera.orn_goal = backup->orn_goal; + globals.oldSkoolCamera.orn_diff = backup->orn_diff; + globals.oldSkoolCamera.yaw_cur = backup->yaw_cur; + globals.oldSkoolCamera.yaw_goal = backup->yaw_goal; + globals.oldSkoolCamera.pitch_cur = backup->pitch_cur; + globals.oldSkoolCamera.pitch_goal = backup->pitch_goal; + globals.oldSkoolCamera.roll_cur = backup->roll_cur; + globals.oldSkoolCamera.roll_goal = backup->roll_goal; + globals.oldSkoolCamera.dct = backup->dct; + globals.oldSkoolCamera.dcd = backup->dcd; + globals.oldSkoolCamera.dccv = backup->dccv; + globals.oldSkoolCamera.dcsv = backup->dcsv; + globals.oldSkoolCamera.hct = backup->hct; + globals.oldSkoolCamera.hcd = backup->hcd; + globals.oldSkoolCamera.hccv = backup->hccv; + globals.oldSkoolCamera.hcsv = backup->hcsv; + globals.oldSkoolCamera.pct = backup->pct; + globals.oldSkoolCamera.pcd = backup->pcd; + globals.oldSkoolCamera.pccv = backup->pccv; + globals.oldSkoolCamera.pcsv = backup->pcsv; + globals.oldSkoolCamera.orn_ct = backup->orn_ct; + globals.oldSkoolCamera.orn_cd = backup->orn_cd; + globals.oldSkoolCamera.orn_ccv = backup->orn_ccv; + globals.oldSkoolCamera.orn_csv = backup->orn_csv; + globals.oldSkoolCamera.yaw_ct = backup->yaw_ct; + globals.oldSkoolCamera.yaw_cd = backup->yaw_cd; + globals.oldSkoolCamera.yaw_ccv = backup->yaw_ccv; + globals.oldSkoolCamera.yaw_csv = backup->yaw_csv; + globals.oldSkoolCamera.pitch_ct = backup->pitch_ct; + globals.oldSkoolCamera.pitch_cd = backup->pitch_cd; + globals.oldSkoolCamera.pitch_ccv = backup->pitch_ccv; + globals.oldSkoolCamera.pitch_csv = backup->pitch_csv; + globals.oldSkoolCamera.roll_ct = backup->roll_ct; + globals.oldSkoolCamera.roll_cd = backup->roll_cd; + globals.oldSkoolCamera.roll_ccv = backup->roll_ccv; + globals.oldSkoolCamera.roll_csv = backup->roll_csv; +} + +void zCameraFlyStart(U32 assetID) +{ + PKRAssetTOCInfo info; + if (xSTGetAssetInfo(assetID, &info) == 0) + { + return; + } + + follow_cam->cfg_common.priority = '\x7f'; + zcam_fly = 1; + zcam_flypaused = 0; + zcam_flydata = info.mempos; + zcam_flysize = info.size; + zcam_flytime = 0.033333335f; + zcam_flyasset_current = assetID; + zcam_flyrate = 1.0f; + + zEntPlayerControlOff(CONTROL_OWNER_FLY_CAM); + xScrFxLetterbox(1); + + zcam_backupcam = globals.oldSkoolCamera; +} + +static S32 zCameraFlyUpdate(xCamera* cam, F32 dt) +{ + S32 i; + S32 flyIdx; + S32 numKeys; + S32 flySize; + F32 flyLerp; + F32 flyFrame; + zFlyKey keys[4]; + F32 matdiff1; + F32 matdiff2; + F32 matdiff3; + xMat3x3 tmpMat; + xQuat quats[2]; + xQuat qresult; + + if ((globals.pad0->pressed & 0x50000) && zcam_flytime > gSkipTimeFlythrough) + { + zcam_flytime = 0.033333335f * zcam_flysize; + } + + flyFrame = 30.0f * zcam_flytime; + numKeys = floor(flyFrame); + flyLerp = flyFrame - floor(flyFrame); + + flySize = (S32)(zcam_flysize >> 6) - 1; + if (!(numKeys < flySize)) + { + return 0; + } + + flyIdx = numKeys; + if (numKeys - 1 >= 0) + { + flyIdx = numKeys - 1; + } + + keys[0] = *((zFlyKey*)zcam_flydata + flyIdx); + keys[1] = *((zFlyKey*)zcam_flydata + numKeys); + keys[2] = *((zFlyKey*)zcam_flydata + (numKeys + 1)); + + flyIdx = numKeys + 1; + if (numKeys + 2 < flySize) + { + flyIdx = numKeys + 2; + } + + keys[3] = *((zFlyKey*)zcam_flydata + flyIdx); + + // Reverses the byte order (endianness) of 64 4-byte blocks + U8* framePtr = (U8*)&keys[0].frame; + for (i = 64; i > 0; i--) + { + S8 tmp1 = *framePtr; + S8 tmp2 = *(framePtr + 1); + *framePtr = *(framePtr + 3); + *(framePtr + 1) = *(framePtr + 2); + *(framePtr + 2) = tmp2; + *(framePtr + 3) = tmp1; + + framePtr += 4; + } + + if (0 < numKeys) + { + //matdiff1 = TranSpeed(&keys[0]); + //matdiff2 = TranSpeed(&keys[1]); + //matdiff3 = TranSpeed(&keys[2]); + + if (matdiff2 > 10.0f && matdiff2 > 5.0f * matdiff1 && matdiff2 > 5.0f * matdiff3) + { + flyLerp = 0.0f; + } + else + { + //matdiff1 = MatrixSpeed(&keys[0]); + //matdiff2 = MatrixSpeed(&keys[1]); + //matdiff3 = MatrixSpeed(&keys[2]); + + if (matdiff2 > 45.0f && matdiff2 > matdiff1 * 5.0f && matdiff2 > matdiff3 * 5.0f) + { + flyLerp = 0.0f; + } + } + } + + for (i = 0; i < 2; i++) + { + tmpMat.right.x = -keys[i + 1].matrix[0]; + tmpMat.right.y = -keys[i + 1].matrix[1]; + tmpMat.right.z = -keys[i + 1].matrix[2]; + + tmpMat.up.x = keys[i + 1].matrix[3]; + tmpMat.up.y = keys[i + 1].matrix[4]; + tmpMat.up.z = keys[i + 1].matrix[5]; + + tmpMat.at.x = -keys[i + 1].matrix[6]; + tmpMat.at.y = -keys[i + 1].matrix[7]; + tmpMat.at.z = -keys[i + 1].matrix[8]; + + xQuatFromMat(&quats[i], &tmpMat); + } + + xQuatSlerp(&qresult, &quats[0], &quats[1], flyLerp); + xQuatToMat(&qresult, &cam->mat); + xVec3Lerp(&cam->mat.pos, (xVec3*)&keys[1].matrix[9], (xVec3*)&keys[2].matrix[9], flyLerp); + + zcam_flytime += dt; + + return 1; +} + void zCameraReset(xCamera* cam) { zcam_mode = 0; @@ -32,7 +569,7 @@ void zCameraReset(xCamera* cam) wall_jump_enabled = WJVS_DISABLED; lassocam_enabled = '\0'; stop_track = 0; - zcam_mintgtheight = -1e+38f; + zcam_mintgtheight = FLOAT_MIN; zcam_centering = '\0'; zcam_lastcentering = '\0'; sNearToggleEnabled = '\0'; diff --git a/src/SB/Game/zCameraFly.cpp b/src/SB/Game/zCameraFly.cpp index 24ff4a1..bc4d2fa 100644 --- a/src/SB/Game/zCameraFly.cpp +++ b/src/SB/Game/zCameraFly.cpp @@ -1 +1,79 @@ +#include "xLinkAsset.h" +#include + +#include "xBase.h" +#include "xEvent.h" +#include "xScene.h" + +#include "zBase.h" #include "zCameraFly.h" +#include "zCamera.h" +#include "zGlobals.h" +#include "zMusic.h" + +extern U32 zcam_flyasset_current; + +void zCameraFlyEventCB(xBase* from, xBase* to, U32 toEvent, F32* toParam, xBase* b3, U32 unknown) +{ + zCameraFly* fly = (zCameraFly*)to; + + switch (toEvent) + { + case eEventEnable: + fly->baseFlags |= 1; + break; + + case eEventDisable: + fly->baseFlags &= ~1; + break; + + case eEventRun: + if (fly->baseFlags & 1) + { + zCameraFlyStart(fly->casset->flyID); + } + break; + + case eEventStop: + break; + + case eEventSceneBegin: + break; + + default: + break; + } +} + +void zCameraFly_Load(zCameraFly* fly, xSerial* s) +{ + xBaseLoad((xBase*)fly, s); +} + +void zCameraFly_Save(zCameraFly* fly, xSerial* s) +{ + xBaseSave((xBase*)fly, s); +} +void zCameraFly_Update(xBase* to, xScene* scene, F32 dt) +{ +} +void zCameraFly_Setup(zCameraFly* fly) +{ + fly->baseFlags |= (U16)2; +} + +void zCameraFly_Init(xBase& data, xDynAsset& asset, size_t) +{ + xBaseInit(&data, &asset); + zCameraFly* fly = (zCameraFly*)&data; + fly->casset = (CameraFly_asset*)&asset; + data.eventFunc = zCameraFlyEventCB; + if (data.linkCount != 0) + { + data.link = (xLinkAsset*)&asset; + } + else + { + data.link = NULL; + } +} diff --git a/src/SB/Game/zCameraFly.h b/src/SB/Game/zCameraFly.h index f860041..979945f 100644 --- a/src/SB/Game/zCameraFly.h +++ b/src/SB/Game/zCameraFly.h @@ -22,8 +22,7 @@ void zCameraFly_Setup(zCameraFly* fly); void zCameraFly_Update(xBase* to, xScene* scene, F32 dt); void zCameraFly_Save(zCameraFly* fly, xSerial* s); void zCameraFly_Load(zCameraFly* fly, xSerial* s); -U32 zCameraFlyProcessStopEvent(); void zCameraFlyStart(U32 id); -S32 zCameraFlyEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* b3); +void zCameraFlyEventCB(xBase* from, xBase* to, U32 toEvent, F32* toParam, xBase* b3, U32 unknown); #endif diff --git a/src/SB/Game/zDispatcher.cpp b/src/SB/Game/zDispatcher.cpp index 256b7e0..cfbca35 100644 --- a/src/SB/Game/zDispatcher.cpp +++ b/src/SB/Game/zDispatcher.cpp @@ -12,6 +12,7 @@ #include "zRumble.h" #include "zVar.h" #include "zGameState.h" +#include "zGlobals.h" #include "xIni.h" extern st_ZDISPATCH_CONTEXT lbl_80254E00; @@ -71,6 +72,7 @@ void zDispatcher_FindWorldTask(U32 sceneID, S32& world, S32& task) // PORTED DIRECTLY FROM BFBB // NEEDS A LOT OF WORK +/* S32 ZDSP_elcb_event(xBase*, xBase* xb, U32 toEvent, const F32* toParam, xBase* toParamWidget) { st_ZDISPATCH_DATA* dspdata = (st_ZDISPATCH_DATA*)xb; @@ -225,6 +227,7 @@ S32 ZDSP_elcb_event(xBase*, xBase* xb, U32 toEvent, const F32* toParam, xBase* t } return 1; } +*/ S32 ZDSP_doCommand(st_ZDISPATCH_DATA* dspdata, st_ZDISPATCH_CONTEXT* cmdCtxt) { diff --git a/src/SB/Game/zFMV.cpp b/src/SB/Game/zFMV.cpp index 92ef2cb..3267aa9 100644 --- a/src/SB/Game/zFMV.cpp +++ b/src/SB/Game/zFMV.cpp @@ -64,15 +64,15 @@ zFMVFile zFMVFileTable[] = { { eFMVFile_Pwr_Wagon, "", 0 }, // //{ eFMVFileCount, "", 0 }, //// }; - -U32 zFMVPlay(char* filename, U32 buttons, F32 time, U32 unk0, bool skippable, bool lockController) +U32 zFMVPlay(const char* name, U32 buttons, F32 time, U32 uSubtitlesAID, bool skippable, + bool lockController) { - char fullname[64]; - U32 ret; + U32 retval = 0; + //xSndEffect currentEffect; //iFMVPlay(fullname, buttons, time, skippable, lockController); - return; + return retval; } char* zFMVFileGetName(eFMVFile fileEnum) diff --git a/src/SB/Game/zMain.h b/src/SB/Game/zMain.h index 8d04588..432f0b2 100644 --- a/src/SB/Game/zMain.h +++ b/src/SB/Game/zMain.h @@ -1,4 +1,10 @@ #ifndef ZMAIN_H #define ZMAIN_H -#endif \ No newline at end of file +#include + +F32 SECS_PER_VBLANK; +F32 gSkipTimeCutscene = 1.0f; +F32 gSkipTimeFlythrough = 1.0f; + +#endif diff --git a/src/SB/Game/zMenu.cpp b/src/SB/Game/zMenu.cpp index 38ba915..4c12f7d 100644 --- a/src/SB/Game/zMenu.cpp +++ b/src/SB/Game/zMenu.cpp @@ -1,5 +1,24 @@ -// For some reason including this breaks the bitshift in zMenuPause -//#include "zMenu.h" +#include "iTime.h" +#include "zGame.h" +#include "zMain.h" +#include "zMenu.h" + +//bool menu_fmv_played; +S32 sFirstBoot = 1; +//S32 logoTmr; +F32 time_elapsed = 0.01f; +F32 time_last; +F32 time_current; +F32 sAttractMode_timer; +F32 sOneLiner_timer; +//S32 promptSel; +S32 card; +//S32 var; +//S32 fullCard; +S32 sInMenu; +//F32 ONELINER_WAITTIME; +F32 holdTmr = 10.0f; +U8 sAllowAttract; void zMenuAllowAtract(bool allowAttract) { @@ -8,18 +27,11 @@ void zMenuAllowAtract(bool allowAttract) void zMenuPause(bool bPause) { - S64 time; - U32 Utime; - if (bPause == FALSE) { - Utime = iTimeGet(); - time = iTimeDiffSec((U64)Utime >> 0x20); - time_last = time - SECS_PER_VBLANK; - Utime = iTimeGet(); + time_last = iTimeDiffSec(iTimeGet()) - SECS_PER_VBLANK; + sTimeLast = iTimeGet(); } - - sTimeLast = Utime >> 0x20; } S32 zMenuIsFirstBoot() diff --git a/src/SB/Game/zMenu.h b/src/SB/Game/zMenu.h index fd444b7..8e0877c 100644 --- a/src/SB/Game/zMenu.h +++ b/src/SB/Game/zMenu.h @@ -3,15 +3,13 @@ #include -bool menu_fmv_played; - U32 zMenuUpdateMode(); U32 zMenuIsPaused(); S32 zMenuLoopContinue(); void zMenuFirstBootSet(U32 isFirstBoot); void zMenuFMVPlay(char*, U32, F32, bool, bool); bool zMenuCardCheckStartup(S32* bytesNeeded, S32* availOnDisk, S32* neededFiles); -S32 zMenuGetBadCard(); +U32 zMenuGetBadCard(); U32 zMenuGetCorruptFiles(char name[][64]); S32 zMenuIsFirstBoot(); diff --git a/src/SB/Game/zParticleSystemWaterfall.cpp b/src/SB/Game/zParticleSystemWaterfall.cpp index 95a2162..2033824 100644 --- a/src/SB/Game/zParticleSystemWaterfall.cpp +++ b/src/SB/Game/zParticleSystemWaterfall.cpp @@ -1,8 +1,6 @@ #include "zParticleSystemWaterfall.h" -zParticleGenerator* pGen; - void zParticleGeneratorWaterfallSplash::deactivate() { zParticleGenerator* pGen; diff --git a/src/SB/Game/zWad2.cpp b/src/SB/Game/zWad2.cpp index 2b7f1ba..4c681d7 100644 --- a/src/SB/Game/zWad2.cpp +++ b/src/SB/Game/zWad2.cpp @@ -243,21 +243,6 @@ U32 sManagerIndex; U32 sManagerCount; F32 sLODFadeDistance; zLODManager sManagerList[2048]; -S32 sFirstBoot; -S32 logoTmr; -F32 time_elapsed; -F32 time_last; -F32 time_current; -F32 sAttractMode_timer; -F32 sOneLiner_timer; -S32 promptSel; -S32 card; -S32 var; -S32 fullCard; -S32 sInMenu; -F32 ONELINER_WAITTIME; -F32 holdTmr; -U8 sAllowAttract; PowerUpMenuTableEntry sPowerUpMenuTable[11]; U32 sPowerUpMenuTableSize; char* cPowerUpMenuRefreshGroupName; @@ -322,7 +307,6 @@ U32 ourGlobals[4096]; //_anon37 __vt__20zUICustomExtrasSound; //_anon30 __vt__19zUICustomExtrasIcon; //_anon44 __vt__22zUICustomExtrasManager; -F32 SECS_PER_VBLANK; U32 SCENE_ID_MNU_START; extern _tagTRCPadInfo gTrcPad[4]; xVec3 m_Null;