From 1471c3da3b565c9734913c403d9633dad99eb530 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 29 Nov 2025 21:54:42 -0500 Subject: [PATCH 1/4] Ported more stuff from: xCamera, xEntMotion, xPad, xSerializer, xString --- src/SB/Core/x/xCamera.cpp | 561 ++++++++++++++++++++++++++++++- src/SB/Core/x/xCamera.h | 1 + src/SB/Core/x/xCollide.h | 1 + src/SB/Core/x/xEntMotion.cpp | 562 ++++++++++++++++++++++---------- src/SB/Core/x/xEntMotionAsset.h | 35 ++ src/SB/Core/x/xMath.h | 1 + src/SB/Core/x/xMath3.h | 1 + src/SB/Core/x/xPad.cpp | 159 +++++++++ src/SB/Core/x/xPad.h | 19 +- src/SB/Core/x/xString.cpp | 170 +++++++++- src/SB/Core/x/xVec3Inlines.h | 30 +- src/SB/Core/x/xpkrsvc.cpp | 2 +- src/SB/Core/x/xserializer.cpp | 126 +++++-- src/SB/Core/x/xserializer.h | 3 +- src/SB/Game/zMovePoint.cpp | 5 - src/SB/Game/zMovePoint.h | 16 +- src/SB/Game/zScene.h | 2 + 17 files changed, 1453 insertions(+), 241 deletions(-) create mode 100644 src/SB/Core/x/xEntMotionAsset.h diff --git a/src/SB/Core/x/xCamera.cpp b/src/SB/Core/x/xCamera.cpp index d04d64e09..ca929d706 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 "zGrid.h" #include "iMath.h" @@ -29,6 +31,8 @@ static xMat4x3 sCameraFXMatOld; cameraFX sCameraFX[10]; cameraFXTableEntry sCameraFXTable[3] = {}; +zGlobals globals; + static void xCameraFXInit(); void add_camera_tweaks(); @@ -466,8 +470,417 @@ void SweptSphereHitsCameraEnt(xScene*, xRay3* ray, xQCData* qcd, xEnt* ent, void } static void _xCameraUpdate(xCamera* cam, F32 dt) +// NONMATCH("https://decomp.me/scratch/2q6zO") { - // lol nope + 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 xCameraUpdate(xCamera* cam, F32 dt) @@ -1098,7 +1511,153 @@ void xBinaryCamera::stop() } void xBinaryCamera::update(F32 dt) +// NONMATCH("https://decomp.me/scratch/c9iST") { + xVec3& A = camera->mat.pos; + const xVec3& B = *s1; + const xVec3& C = *s2; + + xVec3 CA = { 0.0f, 0.0f, 0.0f }; + CA.x = A.x - C.x; + CA.z = A.z - C.z; + + F32 dCA = CA.length(); + if (dCA < 0.01f) + { + CA.assign(A.x - B.x, 0.0f, A.z - B.z).right_normalize(); + dCA = 0.01f; + } + else + { + CA /= dCA; + } + + F32 yaw_start = xatan2(B.x - A.x, B.z - A.z); + F32 yaw_end; + if (dCA > s2_radius) + { + xVec3 Q1, Q2; + bound_sphere_xz(Q1, Q2, C, s2_radius, CA, dCA); + F32 yaw_Q1 = xatan2(Q1.x - A.x, Q1.z - A.z); + F32 yaw_Q2 = xatan2(Q2.x - A.x, Q2.z - A.z); + F32 dyaw1 = xrmod(yaw_Q1 - yaw_start + PI) - PI; + F32 dyaw2 = xrmod(yaw_Q2 - yaw_start + PI) - PI; + + F32 fov = DEG2RAD(1.0f) * xCameraGetFOV(camera) * 0.5f + cfg.margin_angle; + fov = range_limit(fov, 0.0f, PI); + F32 max_dyaw = 0.5f * xabs(dyaw2 - dyaw1); + if (max_dyaw > fov) + { + yaw_end = xatan2(C.x - B.x, C.z - B.z); + } + else if (dyaw1 >= dyaw2) + { + yaw_end = xatan2(C.x - B.x, C.z - B.z); + } + else if (dyaw1 >= -fov) + { + if (dyaw2 <= fov) + { + yaw_end = yaw_start; + } + else + { + yaw_end = yaw_start + (dyaw2 - fov); + } + } + else + { + yaw_end = yaw_start + (dyaw1 + fov); + } + } + else + { + yaw_end = xatan2(C.x - B.x, C.z - B.z); + } + + F32 sstick = 1.0f - xexp(-cfg.stick_speed * dt); + _tagxPad::analog_data& stick = globals.pad0->analog[1]; + + stick_offset.x += (cfg.stick_yaw_vel * stick.offset.x * dt - stick_offset.x) * sstick; + yaw_end += stick_offset.x; + + F32 yaw_diff = xrmod(yaw_end - yaw_start + PI) - PI; + F32 max_yaw_diff = cfg.max_yaw_vel * dt; + if (xabs(yaw_diff) > max_yaw_diff) + { + if (yaw_diff < 0.0f) + { + if (max_yaw_diff > 0.0f) + { + max_yaw_diff = -max_yaw_diff; + } + } + else + { + if (max_yaw_diff < 0.0f) + { + max_yaw_diff = -max_yaw_diff; + } + } + yaw_end = yaw_start + max_yaw_diff; + } + + stick_offset.y += (stick.offset.y - stick_offset.y) * sstick; + + F32 d, h, hf; + if (stick_offset.y > 0.0f) + { + F32 s = stick_offset.y; + d = xlerp(cfg.zone_rest.distance, cfg.zone_below.distance, s); + h = xlerp(cfg.zone_rest.height, cfg.zone_below.height, s); + hf = xlerp(cfg.zone_rest.height_focus, cfg.zone_below.height_focus, s); + } + else + { + F32 s = -stick_offset.y; + d = xlerp(cfg.zone_rest.distance, cfg.zone_above.distance, s); + h = xlerp(cfg.zone_rest.height, cfg.zone_above.height, s); + hf = xlerp(cfg.zone_rest.height_focus, cfg.zone_above.height_focus, s); + } + + xVec3 end_loc = { 0.0f, 0.0f, 0.0f }; + end_loc.x = B.x - d * isin(yaw_end); + end_loc.y = B.y + h; + end_loc.z = B.z - d * icos(yaw_end); + + F32 sloc = 1.0f - xexp(-cfg.move_speed * dt); + + xVec3 cam_loc = { 0.0f, 0.0f, 0.0f }; + cam_loc.x = xlerp(A.x, end_loc.x, sloc); + cam_loc.y = xlerp(A.y, end_loc.y, sloc); + cam_loc.z = xlerp(A.z, end_loc.z, sloc); + + xVec3 heading = { 0.0f, 0.0f, 0.0f }; + heading.x = B.x - end_loc.x; + heading.y = B.y - end_loc.y + hf; + heading.z = B.z - end_loc.z; + + F32 heading_dist2 = heading.length2(); + if (heading_dist2 >= 0.001f) + { + heading /= xsqrt(heading_dist2); + + xQuat end_dir; + xMat3x3 mat; + xMat3x3LookVec(&mat, &heading.invert()); + xQuatFromMat(&end_dir, &mat); + + F32 sdir = 1.0f - xexp(-cfg.turn_speed * dt); + xQuatSlerp(&cam_dir, &cam_dir, &end_dir, sdir); + } + + xMat3x3 mat; + xQuatToMat(&cam_dir, &mat); + + xCameraMove(camera, cam_loc); + xCameraRotate(camera, mat, 0.0f, 0.0f, 0.0f); + + render_debug(); } void xCameraSetFOV(xCamera* cam, F32 fov) diff --git a/src/SB/Core/x/xCamera.h b/src/SB/Core/x/xCamera.h index 17a8a9d53..c12240f5e 100644 --- a/src/SB/Core/x/xCamera.h +++ b/src/SB/Core/x/xCamera.h @@ -286,6 +286,7 @@ void xCameraMove(xCamera* cam, const xVec3& loc); void xCameraMove(xCamera* cam, const xVec3& loc, F32 maxSpeed); void xCameraFOV(xCamera* cam, F32 fov, F32 maxSpeed, F32 dt); void xCameraRotate(xCamera* cam, const xMat3x3& m, F32 time, F32 accel, F32 decl); +void xCameraLook(xCamera* cam, U32 flags, const xQuat* orn_goal, F32 tm, F32 tm_acc, F32 tm_dec); void xCameraLookYPR(xCamera* cam, U32 flags, F32 yaw, F32 pitch, F32 roll, F32 tm, F32 tm_acc, F32 tm_dec); F32 xCameraGetFOV(const xCamera* cam); diff --git a/src/SB/Core/x/xCollide.h b/src/SB/Core/x/xCollide.h index 6d0084383..3805878bd 100644 --- a/src/SB/Core/x/xCollide.h +++ b/src/SB/Core/x/xCollide.h @@ -126,6 +126,7 @@ struct xScene; void xCollideInit(xScene* sc); void xCollideCalcTri(xCollis::tri_data&, const xModelInstance&, const xVec3&, const xVec3&); S32 xSweptSphereToBox(xSweptSphere* sws, xBox* box, xMat4x3* mat); +S32 xSweptSphereToEnv(xSweptSphere* sws, xEnv* env); S32 xSweptSphereToModel(xSweptSphere* sws, RpAtomic* model, RwMatrix* mat); S32 xSweptSphereToScene(xSweptSphere* sws, xScene* sc, xEnt* mover, U8 collType); void xSweptSpherePrepare(xSweptSphere* sws, xVec3* start, xVec3* end, F32 radius); diff --git a/src/SB/Core/x/xEntMotion.cpp b/src/SB/Core/x/xEntMotion.cpp index 475fe16ea..1a2ddecf3 100644 --- a/src/SB/Core/x/xEntMotion.cpp +++ b/src/SB/Core/x/xEntMotion.cpp @@ -1,11 +1,17 @@ #include "xDebug.h" +#include "xDraw.h" #include "xEntMotion.h" +#include "xEntMotionAsset.h" #include "xMath.h" +#include "xMath3.h" +#include "xMathInlines.h" #include "xPad.h" #include "xScene.h" #include "xSpline.h" +#include "zMovePoint.h" + #include static void xEntMotionDebugIPad(xEntMotion* xem); @@ -48,9 +54,9 @@ void xEntMotionInit(xEntMotion* motion, xEnt* owner, xEntMotionAsset* asset) motion->er.p = 1.0f; } - motion->er.brt = motion->er.et + motion->er.wet; + motion->er.brt = motion->er.et + motion->er.wet; motion->er.ert = motion->er.brt + motion->er.rt; - motion->er.p = motion->er.ert + motion->er.wrt; + motion->er.p = motion->er.ert + motion->er.wrt; } else if (motion->type == XENTMOTION_TYPE_ORB) { @@ -143,13 +149,13 @@ void xEntMotionReset(xEntMotion* motion, xScene* sc) } else if (motion->type == XENTMOTION_TYPE_ORB) { - xVec3Copy(&motion->orb.orig, (xVec3 *)&motion->owner->model->Mat->pos); + xVec3Copy(&motion->orb.orig, (xVec3*)&motion->owner->model->Mat->pos); } else if (motion->type == XENTMOTION_TYPE_PEN) { xVec3 a, b, c; - modlpos = (xVec3 *)&motion->owner->model->Mat->pos; + modlpos = (xVec3*)&motion->owner->model->Mat->pos; modlrot = (xMat4x3*)motion->owner->model->Mat; aspen = &motion->asset->pen; @@ -183,25 +189,26 @@ void xEntMotionReset(xEntMotion* motion, xScene* sc) if ((ownr != NULL) && (ownr->frame != NULL) && (ownr->model != NULL)) { - xVec3Copy(&mech->apos, (xVec3 *)&ownr->model->Mat->pos); + xVec3Copy(&mech->apos, (xVec3*)&ownr->model->Mat->pos); if (mkasst->sld_axis == 0) { - xVec3Copy(&mech->dir, (xVec3 *)&ownr->model->Mat->right); + xVec3Copy(&mech->dir, (xVec3*)&ownr->model->Mat->right); } else if (mkasst->sld_axis == 1) { - xVec3Copy(&mech->dir, (xVec3 *)&ownr->model->Mat->up); + xVec3Copy(&mech->dir, (xVec3*)&ownr->model->Mat->up); } else { - xVec3Copy(&mech->dir, (xVec3 *)&ownr->model->Mat->at); + xVec3Copy(&mech->dir, (xVec3*)&ownr->model->Mat->at); } xVec3SMul(&mech->bpos, &mech->dir, mkasst->sld_dist); xVec3AddTo(&mech->bpos, &mech->apos); - mech->ss = mkasst->sld_dist / -((mkasst->sld_acc_tm + mkasst->sld_dec_tm) * 0.5f - mkasst->sld_tm); + mech->ss = mkasst->sld_dist / + -((mkasst->sld_acc_tm + mkasst->sld_dec_tm) * 0.5f - mkasst->sld_tm); mech->tsfd = mkasst->sld_tm - mkasst->sld_dec_tm; mech->tsbd = mkasst->sld_tm - mkasst->sld_acc_tm; @@ -394,6 +401,139 @@ void xEntMPGetNext(xEntMotion* motion, xMovePoint* prev, xScene* sc) } } +U32 xQuatEquals(const xQuat* a, const xQuat* b); // Should be linked weakly + +static void xEntMPMove(xEntMotion* motion, xScene* sc, F32 dt, xEntFrame* frame) +{ + xEntMPData* mp = &motion->mp; + + if (mp->dest == mp->src || !mp->dest) + return; + + if (motion->tmr > 0.0f) + { + motion->tmr -= dt; + return; + } + + frame->mode = 2; + + F32 newdist = mp->curdist + mp->speed * dt; + if (newdist >= mp->dist) + { + frame->dpos.x = mp->dest->pos->x - frame->mat.pos.x; + frame->dpos.y = mp->dest->pos->y - frame->mat.pos.y; + frame->dpos.z = mp->dest->pos->z - frame->mat.pos.z; + + if (motion->asset->mp.flags & 0x1) + { + xEntMotionStop(motion); + } + + xMovePoint* prev = mp->src; + mp->src = mp->dest; + xEntMPGetNext(motion, prev, sc); + + motion->tmr = mp->src->asset->delay; + return; + } + + mp->curdist = newdist; + + F32 qdot; + xVec3 tgt, dir, bank; + xQuat quat, qold; + xMat3x3 tmpmat; + if (mp->spl) + { + F32 u = xSpline3_EvalArcApprox(mp->spl, newdist, 0, &tgt); + + if (motion->asset->flags & 1) + { + xSpline3_EvalSeg(mp->spl, u, 1, &dir); + if (motion->asset->use_banking == 1) + { + xSpline3_EvalSeg(mp->spl, u, 2, &bank); + } + + if (xVec3Length2(&dir) < 0.000001f) + { + if (u < 0.1f) + u += 0.01f; + else + u -= 0.01f; + xSpline3_EvalSeg(mp->spl, u, 1, &dir); + if (motion->asset->use_banking == 1) + { + xSpline3_EvalSeg(mp->spl, u, 2, &bank); + } + } + + if (motion->asset->use_banking != 1) + { + xVec3Inv(&dir, &dir); + xMat3x3LookVec(&tmpmat, &dir); + } + else + { + xVec3 gravity = { 0.0f, -sc->gravity, 0.0f }; + + bank = bank * mp->speed * 0.01f + gravity; + dir.normalize(); + bank -= dir * bank.dot(dir); + bank.normalize(); + + tmpmat.at = dir; + tmpmat.right = bank.cross(dir); + tmpmat.up = bank; + } + + xQuatFromMat(&quat, &tmpmat); + xQuatFromMat(&qold, &frame->mat); + + qdot = xQuatDot(&quat, &qold); + if (qdot < 0.0f) + { + xQuatFlip(&quat, &quat); + qdot = -qdot; + } + if (qdot > 1.0f) + { + qdot = 1.0f; + } + qdot = 2.0f * xacos(qdot); + + if (qdot <= PI * dt) + { + frame->mode |= 0x10; + (xMat3x3) frame->mat = tmpmat; + } + else + { + qdot = PI * dt / qdot; + xQuatSlerp(&quat, &qold, &quat, qdot); + xQuatNormalize(&quat, &quat); + xQuatToMat(&quat, &frame->mat); + } + } + } + else + { + xVec3Lerp(&tgt, mp->src->pos, mp->dest->pos, mp->curdist / mp->dist); + + if ((motion->asset->flags & 1) && !xQuatEquals(&mp->aquat, &mp->bquat)) + { + xQuatSlerp(&quat, &mp->aquat, &mp->bquat, MIN(1.0f, 2.0f * (mp->curdist / mp->dist))); + xQuatToMat(&quat, &frame->mat); + frame->mode |= 0x10; + } + } + + frame->dpos.x = tgt.x - frame->mat.pos.x; + frame->dpos.y = tgt.y - frame->mat.pos.y; + frame->dpos.z = tgt.z - frame->mat.pos.z; +} + static void xEntPenMove(xEntMotion* motion, xScene* sc, F32 dt, xEntFrame* frame) { xEntPenData* pen = &motion->pen; @@ -799,7 +939,7 @@ void xEntMotionTranslate(xEntMotion* motion, const xVec3* dpos, xMat4x3* dmat) { xMat4x3Toworld(&motion->mech.apos, dmat, &motion->mech.apos); xMat4x3Toworld(&motion->mech.bpos, dmat, &motion->mech.bpos); - xMat3x3RMulVec(&motion->mech.dir, dmat, &motion->mech.dir); + xMat3x3RMulVec(&motion->mech.dir, dmat, &motion->mech.dir); } } else @@ -889,27 +1029,27 @@ static void xEntMotionDebugWrite(const xEntMotion* xem) switch (xem->type) { - case XENTMOTION_TYPE_ER: - gps = "extend/retract"; - break; - case XENTMOTION_TYPE_ORB: - gps = "orbital"; - break; - case XENTMOTION_TYPE_SPL: - gps = "spline"; - break; - case XENTMOTION_TYPE_MP: - gps = "movepoint"; - break; - case XENTMOTION_TYPE_MECH: - gps = "mechanism"; - break; - case XENTMOTION_TYPE_PEN: - gps = "pendulum"; - break; - default: - gps = "????"; - break; + case XENTMOTION_TYPE_ER: + gps = "extend/retract"; + break; + case XENTMOTION_TYPE_ORB: + gps = "orbital"; + break; + case XENTMOTION_TYPE_SPL: + gps = "spline"; + break; + case XENTMOTION_TYPE_MP: + gps = "movepoint"; + break; + case XENTMOTION_TYPE_MECH: + gps = "mechanism"; + break; + case XENTMOTION_TYPE_PEN: + gps = "pendulum"; + break; + default: + gps = "????"; + break; } xprintf("type: %s\n", gps); @@ -929,175 +1069,241 @@ static void xEntMotionDebugWrite(const xEntMotion* xem) switch (xem->type) { - case XENTMOTION_TYPE_ER: - xprintf("a: <%.3f %.3f %.3f>\n", xem->er.a.x, xem->er.a.y, xem->er.a.z); - xprintf("b: <%.3f %.3f %.3f>\n", xem->er.b.x, xem->er.b.y, xem->er.b.z); - xprintf("b-a: <%.3f %.3f %.3f>\n", xem->asset->er.ext_dpos.x, xem->asset->er.ext_dpos.y, xem->asset->er.ext_dpos.z); - xprintf("ext_tm: %.3f\n", xem->er.et); - xprintf("ret_tm: %.3f\n", xem->er.rt); - xprintf("wait_et: %.3f\n", xem->er.wet); - xprintf("wait_rt: %.3f\n", xem->er.wrt); - xprintf("period: %.3f\n", xem->er.p); + case XENTMOTION_TYPE_ER: + xprintf("a: <%.3f %.3f %.3f>\n", xem->er.a.x, xem->er.a.y, xem->er.a.z); + xprintf("b: <%.3f %.3f %.3f>\n", xem->er.b.x, xem->er.b.y, xem->er.b.z); + xprintf("b-a: <%.3f %.3f %.3f>\n", xem->asset->er.ext_dpos.x, xem->asset->er.ext_dpos.y, + xem->asset->er.ext_dpos.z); + xprintf("ext_tm: %.3f\n", xem->er.et); + xprintf("ret_tm: %.3f\n", xem->er.rt); + xprintf("wait_et: %.3f\n", xem->er.wet); + xprintf("wait_rt: %.3f\n", xem->er.wrt); + xprintf("period: %.3f\n", xem->er.p); + break; + case XENTMOTION_TYPE_ORB: + xprintf("c: <%.3f %.3f %.3f>\n", xem->orb.c.x, xem->orb.c.y, xem->orb.c.z); + xprintf("a: %.3f\n", xem->orb.a); + xprintf("b: %.3f\n", xem->orb.b); + xprintf("p: %.3f\n", xem->orb.p); + xprintf("w: %.3f\n", xem->orb.w); + break; + case XENTMOTION_TYPE_MP: + if (xem->mp.src != NULL) + { + gps = xSceneID2Name(g_xSceneCur, xem->mp.src->id); + } + else + { + gps = ""; + } + + xprintf("src-mp: %s\n", gps); + + if (xem->mp.dest != NULL) + { + gps = xSceneID2Name(g_xSceneCur, xem->mp.dest->id); + } + else + { + gps = ""; + } + + xprintf("dest-mp: %s\n", gps); + xprintf("dist: %.3f\n", xem->mp.dist); + xprintf("speed: %.3f\n", xem->mp.speed); + break; + case XENTMOTION_TYPE_MECH: + switch (xem->asset->mech.type) + { + case 0: + gps = "slide"; break; - case XENTMOTION_TYPE_ORB: - xprintf("c: <%.3f %.3f %.3f>\n", xem->orb.c.x, xem->orb.c.y, xem->orb.c.z); - xprintf("a: %.3f\n", xem->orb.a); - xprintf("b: %.3f\n", xem->orb.b); - xprintf("p: %.3f\n", xem->orb.p); - xprintf("w: %.3f\n", xem->orb.w); + case 1: + gps = "rot"; break; - case XENTMOTION_TYPE_MP: - if (xem->mp.src != NULL) - { - gps = xSceneID2Name(g_xSceneCur, xem->mp.src->id); - } - else - { - gps = ""; - } + case 2: + gps = "slide_rot"; + break; + case 3: + gps = "slide_then_rot"; + break; + case 4: + gps = "rot_then_slide"; + break; + } + + xprintf("type: %s\n", gps); + xprintf("returns: %s", xbtoa(xem->asset->mech.flags & 1)); + + if (xem->asset->mech.flags & 1) + { + xprintf(" ret_delay: %.3f", xem->asset->mech.ret_delay); + } + + xprintf("\n"); + xprintf("continuous: %s", xbtoa(!(xem->asset->mech.flags & 2))); - xprintf("src-mp: %s\n", gps); + if (!(xem->asset->mech.flags & 2)) + { + xprintf(" end_delay: %.3f", xem->asset->mech.post_ret_delay); + } + + xprintf("\n"); - if (xem->mp.dest != NULL) + switch (xem->mech.state) + { + case 0: + if (xem->asset->mech.type == 2) { - gps = xSceneID2Name(g_xSceneCur, xem->mp.dest->id); + gps = "sliding + rotating forth"; } else { - gps = ""; + gps = "sliding forth"; } - - xprintf("dest-mp: %s\n", gps); - xprintf("dist: %.3f\n", xem->mp.dist); - xprintf("speed: %.3f\n", xem->mp.speed); break; - case XENTMOTION_TYPE_MECH: - switch (xem->asset->mech.type) + case 1: + gps = "rotating forth"; + break; + case 2: + gps = "waiting to return"; + break; + case 3: + if (xem->asset->mech.type == 2) { - case 0: - gps = "slide"; - break; - case 1: - gps = "rot"; - break; - case 2: - gps = "slide_rot"; - break; - case 3: - gps = "slide_then_rot"; - break; - case 4: - gps = "rot_then_slide"; - break; + gps = "sliding + rotating back"; } - - xprintf("type: %s\n", gps); - xprintf("returns: %s", xbtoa(xem->asset->mech.flags & 1)); - - if (xem->asset->mech.flags & 1) + else { - xprintf(" ret_delay: %.3f", xem->asset->mech.ret_delay); + gps = "sliding back"; } + break; + case 4: + gps = "rotating back"; + break; + case 5: + gps = "waiting to begin again"; + break; + case 6: + gps = "done"; + break; + case 7: + gps = "undone"; + break; + } - xprintf("\n"); - xprintf("continuous: %s", xbtoa(!(xem->asset->mech.flags & 2))); + xprintf("state: %s\n", gps); - if (!(xem->asset->mech.flags & 2)) - { - xprintf(" end_delay: %.3f", xem->asset->mech.post_ret_delay); - } + if (xem->asset->mech.type != 1) + { + gps = xem->asset->mech.sld_axis == 0 ? "X" : xem->asset->mech.sld_axis == 1 ? "Y" : "Z"; + + xprintf("slide_axis: %s", gps); + xprintf(" slide_dist: %.3f\n", xem->asset->mech.sld_dist); + xprintf("slide_tm: %.3f", xem->asset->mech.sld_tm); + xprintf(" slide_speed: %.3f\n", xem->mech.ss); + xprintf("slide_acc_tm: %.3f", xem->asset->mech.sld_acc_tm); + xprintf(" slide_dec_tm: %.3f\n", xem->asset->mech.sld_dec_tm); + xprintf("slide_bd_tm: %.3f", xem->mech.tsbd); + xprintf(" slide_fd_tm: %.3f\n", xem->mech.tsfd); + xprintf("start_pos: <%.3f %.3f %.3f>\n", xem->mech.apos.x, xem->mech.apos.y, + xem->mech.apos.z); + xprintf("end_pos: <%.3f %.3f %.3f>\n", xem->mech.bpos.x, xem->mech.bpos.y, + xem->mech.bpos.z); + xprintf("dir: <%.3f %.3f %.3f>\n", xem->mech.dir.x, xem->mech.dir.y, + xem->mech.dir.z); + } - xprintf("\n"); + if (xem->asset->mech.type != 0) + { + gps = xem->asset->mech.rot_axis == 0 ? "X" : xem->asset->mech.rot_axis == 1 ? "Y" : "Z"; + + xprintf("rot_axis: %s", gps); + xprintf(" rot_dist: %.3f\n", xem->asset->mech.rot_dist); + xprintf("rot_tm: %.3f", xem->asset->mech.rot_tm); + xprintf(" rot_speed: %.3f\n", (xem->mech.sr * 180.0f) / PI); + xprintf("rot_acc_tm: %.3f", xem->asset->mech.rot_acc_tm); + xprintf(" rot_dec_tm: %.3f\n", xem->asset->mech.rot_dec_tm); + xprintf("rot_bd_tm: %.3f", xem->mech.trbd); + xprintf(" rot_fd_tm: %.3f\n", xem->mech.trfd); + xprintf("arot: %.3f\n", (xem->mech.arot * 180.0f) / PI); + xprintf("brot: %.3f\n", (xem->mech.brot * 180.0f) / PI); + } + break; + case XENTMOTION_TYPE_PEN: + xprintf("top: <%.3f %.3f %.3f>\n", xem->pen.top.x, xem->pen.top.y, xem->pen.top.z); + xprintf("length: %.3f\n", xem->asset->pen.len); + xprintf("period: %.3f\n", xem->asset->pen.period); + xprintf("phase: %.3f\n", (xem->asset->pen.phase * 180.0f) / PI); + xprintf("range: %.3f\n", (xem->asset->pen.range * 180.0f) / PI); + xprintf("w: %.3f\n", xem->pen.w); + break; + } +} + +static void xEntMotionDebugDraw(const xEntMotion* xem) +//NONMATCH("https://decomp.me/scratch/j2sCX") +{ + if (xem->owner && xem->target) + { + xDrawSetColor(g_NEON_GREEN); + xDrawLine(xEntGetPos(xem->owner), xEntGetPos(xem->target)); + } - switch (xem->mech.state) + switch (xem->type) + { + case k_XENTMOTIONTYPE_ER: + xDrawSetColor(g_NEON_RED); + xDrawLine(&xem->er.a, &xem->er.b); + break; + case k_XENTMOTIONTYPE_ORBIT: + if (xem->owner) + { + xDrawSetColor(g_NEON_RED); + xDrawLine(&xem->orb.c, xEntGetPos(xem->owner)); + } + break; + case k_XENTMOTIONTYPE_MP: + { + xDrawSetColor(g_PIMP_GOLD); + xMovePoint* xmp = xem->mp.dest; + if (xmp) + { + for (U16 idx = 0; idx < xMovePointGetNumPoints(xmp); idx++) { - case 0: - if (xem->asset->mech.type == 2) - { - gps = "sliding + rotating forth"; - } - else + xMovePoint* omp = xMovePointGetPoint(xmp, idx); + if (omp != xem->mp.src) { - gps = "sliding forth"; + xDrawLine(xMovePointGetPos(xmp), xMovePointGetPos(omp)); } - break; - case 1: - gps = "rotating forth"; - break; - case 2: - gps = "waiting to return"; - break; - case 3: - if (xem->asset->mech.type == 2) - { - gps = "sliding + rotating back"; - } - else + for (U16 jdx = 0; jdx < xMovePointGetNumPoints(omp); jdx++) { - gps = "sliding back"; + xMovePoint* pmp = xMovePointGetPoint(omp, jdx); + xDrawLine(xMovePointGetPos(omp), xMovePointGetPos(pmp)); } - break; - case 4: - gps = "rotating back"; - break; - case 5: - gps = "waiting to begin again"; - break; - case 6: - gps = "done"; - break; - case 7: - gps = "undone"; - break; } - - xprintf("state: %s\n", gps); - - if (xem->asset->mech.type != 1) - { - gps = xem->asset->mech.sld_axis == 0 ? "X" : - xem->asset->mech.sld_axis == 1 ? "Y" : "Z"; - - xprintf("slide_axis: %s", gps); - xprintf(" slide_dist: %.3f\n", xem->asset->mech.sld_dist); - xprintf("slide_tm: %.3f", xem->asset->mech.sld_tm); - xprintf(" slide_speed: %.3f\n", xem->mech.ss); - xprintf("slide_acc_tm: %.3f", xem->asset->mech.sld_acc_tm); - xprintf(" slide_dec_tm: %.3f\n", xem->asset->mech.sld_dec_tm); - xprintf("slide_bd_tm: %.3f", xem->mech.tsbd); - xprintf(" slide_fd_tm: %.3f\n", xem->mech.tsfd); - xprintf("start_pos: <%.3f %.3f %.3f>\n", xem->mech.apos.x, xem->mech.apos.y, xem->mech.apos.z); - xprintf("end_pos: <%.3f %.3f %.3f>\n", xem->mech.bpos.x, xem->mech.bpos.y, xem->mech.bpos.z); - xprintf("dir: <%.3f %.3f %.3f>\n", xem->mech.dir.x, xem->mech.dir.y, xem->mech.dir.z); - } - - if (xem->asset->mech.type != 0) - { - gps = xem->asset->mech.rot_axis == 0 ? "X" : - xem->asset->mech.rot_axis == 1 ? "Y" : "Z"; - - xprintf("rot_axis: %s", gps); - xprintf(" rot_dist: %.3f\n", xem->asset->mech.rot_dist); - xprintf("rot_tm: %.3f", xem->asset->mech.rot_tm); - xprintf(" rot_speed: %.3f\n", (xem->mech.sr * 180.0f) / PI); - xprintf("rot_acc_tm: %.3f", xem->asset->mech.rot_acc_tm); - xprintf(" rot_dec_tm: %.3f\n", xem->asset->mech.rot_dec_tm); - xprintf("rot_bd_tm: %.3f", xem->mech.trbd); - xprintf(" rot_fd_tm: %.3f\n", xem->mech.trfd); - xprintf("arot: %.3f\n", (xem->mech.arot * 180.0f) / PI); - xprintf("brot: %.3f\n", (xem->mech.brot * 180.0f) / PI); - } - break; - case XENTMOTION_TYPE_PEN: - xprintf("top: <%.3f %.3f %.3f>\n", xem->pen.top.x, xem->pen.top.y, xem->pen.top.z); - xprintf("length: %.3f\n", xem->asset->pen.len); - xprintf("period: %.3f\n", xem->asset->pen.period); - xprintf("phase: %.3f\n", (xem->asset->pen.phase * 180.0f) / PI); - xprintf("range: %.3f\n", (xem->asset->pen.range * 180.0f) / PI); - xprintf("w: %.3f\n", xem->pen.w); - break; + } + if (xem->mp.src && xem->mp.dest) + { + xDrawSetColor(g_NEON_RED); + xDrawLine(xMovePointGetPos(xem->mp.src), xMovePointGetPos(xem->mp.dest)); + } + break; + } + case k_XENTMOTIONTYPE_MECH: + xDrawSetColor(g_NEON_RED); + xDrawLine(&xem->mech.apos, &xem->mech.bpos); + break; + case k_XENTMOTIONTYPE_PEND: + if (xem->owner) + { + xDrawSetColor(g_NEON_RED); + xDrawLine(&xem->pen.top, xEntGetPos(xem->owner)); + } + break; } } + void xEntMotionDebugDraw(const xEntMotion*); _tagxPad* gDebugPad; @@ -1172,10 +1378,6 @@ F32 xQuatDot(const xQuat* a, const xQuat* b) return xVec3Dot(&a->v, &b->v) + a->s * b->s; } -void xDrawLine(const xVec3* start, const xVec3* end) -{ -} - void xDrawSetColor(iColor_tag color) { } @@ -1213,7 +1415,7 @@ static void xEntMotionDebugIPad(xEntMotion* xem) { xEntReset(xem->owner); } - xEntMotionReset(xem,g_xSceneCur); + xEntMotionReset(xem, g_xSceneCur); } if (gDebugPad->pressed & 0x20000) { @@ -1226,4 +1428,4 @@ static void xEntMotionDebugIPad(xEntMotion* xem) xEntMotionStop(xem); } } -} \ No newline at end of file +} diff --git a/src/SB/Core/x/xEntMotionAsset.h b/src/SB/Core/x/xEntMotionAsset.h new file mode 100644 index 000000000..24f84b531 --- /dev/null +++ b/src/SB/Core/x/xEntMotionAsset.h @@ -0,0 +1,35 @@ +#pragma once + +#include "xVec3.h" + +enum +{ + k_XENTMOTIONMECH_SLIDE, + k_XENTMOTIONMECH_ROT, + k_XENTMOTIONMECH_SLIDE_ROT, + k_XENTMOTIONMECH_SLIDE_THEN_ROT, + k_XENTMOTIONMECH_ROT_THEN_SLIDE +}; + +enum +{ + k_XENTMOTIONMECH_RETURNS = (1 << 0), + k_XENTMOTIONMECH_ONCE = (1 << 1), +}; + +enum +{ + k_XENTMOTIONTYPE_ER, + k_XENTMOTIONTYPE_ORBIT, + k_XENTMOTIONTYPE_SPLINE, + k_XENTMOTIONTYPE_MP, + k_XENTMOTIONTYPE_MECH, + k_XENTMOTIONTYPE_PEND, + k_XENTMOTIONTYPE_NONE +}; + +enum +{ + k_XENTMOTION_0x1 = (1 << 0), + k_XENTMOTION_STOPPED = (1 << 2) +}; diff --git a/src/SB/Core/x/xMath.h b/src/SB/Core/x/xMath.h index b580bd8a2..156a6fbff 100644 --- a/src/SB/Core/x/xMath.h +++ b/src/SB/Core/x/xMath.h @@ -13,6 +13,7 @@ #define xfeq0(x) (((x) >= -1e-5f) && ((x) <= 1e-5f)) #define CLAMP(x, a, b) (MAX((a), MIN((x), (b)))) +#define xlerp(a, b, t) ((a) + (t) * ((b) - (a))) #define SQR(x) ((x) * (x)) diff --git a/src/SB/Core/x/xMath3.h b/src/SB/Core/x/xMath3.h index 02068cb80..fc7728676 100644 --- a/src/SB/Core/x/xMath3.h +++ b/src/SB/Core/x/xMath3.h @@ -160,6 +160,7 @@ void xQuatToMat(const xQuat* q, xMat3x3* m); void xQuatDiff(xQuat* o, const xQuat* a, const xQuat* b); F32 xQuatGetAngle(const xQuat* q); void xQuatFromMat(xQuat* q, const xMat3x3* m); +void xQuatToAxisAngle(const xQuat* q, xVec3* a, F32* t); void xQuatSlerp(xQuat* q, const xQuat* a, const xQuat* b, F32 t); void xQuatConj(xQuat* o, const xQuat* q); void xQuatCopy(xQuat*, const xQuat*); diff --git a/src/SB/Core/x/xPad.cpp b/src/SB/Core/x/xPad.cpp index 7786ae06f..65e79310a 100644 --- a/src/SB/Core/x/xPad.cpp +++ b/src/SB/Core/x/xPad.cpp @@ -1,5 +1,13 @@ #include "xPad.h" +#include "xMathInlines.h" + +#include "zMenu.h" +#include "zScene.h" +#include "zGame.h" +#include "zGameExtras.h" +#include "zGlobals.h" + #include #include @@ -53,6 +61,157 @@ void xPadRumbleEnable(S32 idx, S32 enable) } } +S32 xPadUpdate(S32 idx, F32 time_passed) +{ + U32 new_on = 0; + + if (zScene_ScreenAdjustMode()) + { + xPadAnalogIsDigital(0, 0); + } + else if (zMenuRunning() || zGameIsPaused() || zGame_HackIsGallery()) + { + xPadAnalogIsDigital(0, 0); + } + else + { + xPadAnalogIsDigital(0, 0); + } + + _tagxPad* p = &mPad[idx]; + + if (!iPadUpdate(p, &new_on)) + { + p->pressed = 0; + p->released = 0; + return 1; + } + + if ((p->flags & 0x10) && (p->flags & 0x1)) + { + U32 fake_dpad = 0; + if (p->analog1.x >= 50) + { + fake_dpad |= 0x20; + } + else if (p->analog1.x <= -50) + { + fake_dpad |= 0x80; + } + if (p->analog1.y >= 50) + { + fake_dpad |= 0x40; + } + else if (p->analog1.y <= -50) + { + fake_dpad |= 0x10; + } + if (fake_dpad == 0) + { + p->al2d_timer = 0.0f; + } + else + { + p->al2d_timer -= time_passed; + if (p->al2d_timer <= 0.0f) + { + new_on |= fake_dpad; + p->al2d_timer = 0.35f; + } + } + } +#ifdef DEBUGRELEASE + static S32 submap = 0; + if (submap) + { + SubMapAll((S32*)&new_on, p); + } +#endif + + p->pressed = new_on & ~p->on; + p->released = p->on & ~new_on; + p->on = new_on; + + for (S32 i = 0; i < 22; i++) + { + if (p->pressed & (1 << i)) + { + p->down_tmr[i] = 0.0f; + } + else if (p->released & (1 << i)) + { + p->up_tmr[i] = 0.0f; + } + if (p->on & (1 << i)) + { + p->down_tmr[i] += time_passed; + } + else + { + p->up_tmr[i] += time_passed; + } + } + + if (p->flags & 0x10) + { + if (!(p->on & 0x10) && !(p->on & 0x40) && !(p->on & 0x80) && !(p->on & 0x20)) + { + p->d_timer = 0.0f; + } + else + { + p->d_timer -= time_passed; + if (p->d_timer <= 0.0f) + { + p->d_timer = 0.35f; + if (p->on & 0x10) + { + p->pressed |= 0x10; + } + else if (p->on & 0x40) + { + p->pressed |= 0x40; + } + if (p->on & 0x80) + { + p->pressed |= 0x80; + } + else if (p->on & 0x20) + { + p->pressed |= 0x20; + } + } + } + } + + return 1; +} + +void xPadNormalizeAnalog(_tagxPad& pad, S32 inner_zone, S32 outer_zone) +{ + const _tagPadAnalog* src = &pad.analog1; + for (S32 i = 0; i < 2; i++) + { + pad.analog[i].offset.x = + normalize_analog(src[i].x, -outer_zone, outer_zone, 0, -inner_zone, inner_zone); + pad.analog[i].offset.y = + normalize_analog(src[i].y, -outer_zone, outer_zone, 0, -inner_zone, inner_zone); + if (pad.analog[i].offset.x == 0.0f && pad.analog[i].offset.y == 0.0f) + { + pad.analog[i].mag = 0.0f; + pad.analog[i].dir.assign(1.0f, 0.0f); + pad.analog[i].ang = 0.0f; + } + else + { + pad.analog[i].mag = pad.analog[i].offset.length(); + pad.analog[i].dir = pad.analog[i].offset; + pad.analog[i].dir /= pad.analog[i].mag; + pad.analog[i].ang = xatan2(pad.analog[i].dir.y, pad.analog[i].dir.x); + } + } +} + void xPadAnalogIsDigital(S32 idx, S32 enable) { if (idx != 0) diff --git a/src/SB/Core/x/xPad.h b/src/SB/Core/x/xPad.h index c4ef619f5..b70084246 100644 --- a/src/SB/Core/x/xPad.h +++ b/src/SB/Core/x/xPad.h @@ -35,16 +35,16 @@ struct _tagPadAnalog S8 y; }; -struct analog_data -{ - xVec2 offset; - xVec2 dir; - F32 mag; - F32 ang; -}; - struct _tagxPad { + struct analog_data + { + xVec2 offset; + xVec2 dir; + F32 mag; + F32 ang; + }; + S8 value[22]; // Offset: 0x16 @@ -110,4 +110,7 @@ S32 xPadAddRumble(S32 idx, _tagRumbleType type, F32 time, S32 replace, U32 fxfla void xPadAnalogIsDigital(F32, F32); +inline F32 normalize_analog(S32 v, S32 v_min, S32 v_max, S32 dead_center, S32 dead_min, + S32 dead_max); + #endif diff --git a/src/SB/Core/x/xString.cpp b/src/SB/Core/x/xString.cpp index 95ad1f06e..8a1ce327d 100644 --- a/src/SB/Core/x/xString.cpp +++ b/src/SB/Core/x/xString.cpp @@ -1,4 +1,5 @@ #include "xString.h" +#include "rwplcore.h" #include "xMath.h" #include @@ -47,6 +48,84 @@ U32 xStrHashCat(U32 prefix, const char* str) return hash; } +char* xStrTok(char* string, const char* control, char** nextoken) +{ + U8* str; + U8* ctrl; + U8 map[32]; + S32 count; + + map[0] = 0; + map[1] = 0; + map[2] = 0; + map[3] = 0; + map[4] = 0; + map[5] = 0; + map[6] = 0; + map[7] = 0; + map[8] = 0; + map[9] = 0; + map[10] = 0; + map[11] = 0; + map[12] = 0; + map[13] = 0; + map[14] = 0; + map[15] = 0; + map[16] = 0; + map[17] = 0; + map[18] = 0; + map[19] = 0; + map[20] = 0; + map[21] = 0; + map[22] = 0; + map[23] = 0; + map[24] = 0; + map[25] = 0; + map[26] = 0; + map[27] = 0; + map[28] = 0; + map[29] = 0; + map[30] = 0; + map[31] = 0; + + ctrl = (U8*)control; + + do + { + map[*ctrl >> 3] |= 1 << (*ctrl & 0x7); + } while (*ctrl++ != '\0'); + + str = (string) ? (U8*)string : (U8*)*nextoken; + + while (map[(*str >> 3) & 0x1F] & (1 << (*str & 0x7)) && *str != '\0') + { + str++; + } + + string = (char*)str; + + while (*str != '\0') + { + if (map[(*str >> 3) & 0x1F] & (1 << (*str & 0x7))) + { + *str = '\0'; + str++; + break; + } + + str++; + } + + *nextoken = (char*)str; + + if (string == (char*)str) + { + string = NULL; + } + + return string; +} + char* xStrupr(char* string) { char* p = string; @@ -67,6 +146,85 @@ namespace U32 tolower(S32 param_1); } // namespace +S32 xStrParseFloatList(F32* dest, const char* strbuf, S32 max) +{ + char* str = (char*)strbuf; + S32 index; + S32 digits; + bool negate; + char* numstart; + char savech; + + if (!str) + { + return 0; + } + + for (index = 0; *str != '\0' && index < max; index++) + { + while (*str == '\t' || *str == ' ' || *str == '[' || *str == ']' || *str == '{' || + *str == '}' || *str == '(' || *str == ')' || *str == '+' || *str == ',' || + *str == ':' || *str == ';') + { + str++; + } + + if (*str == '\0') + { + return index; + } + + if (*str == '-') + { + negate = TRUE; + str++; + + while (*str == '\t' || *str == ' ') + { + str++; + } + } + else + { + negate = FALSE; + } + + numstart = str; + digits = 0; + + while ((*str >= '0' && *str <= '9') || *str == '.' || *str == 'E' || *str == 'e' || + *str == 'f') + { + if (*str >= '0' && *str <= '9') + { + digits++; + } + + str++; + } + + if (digits == 0) + { + return index; + } + + savech = *str; + + *str = '\0'; + *dest = xatof(numstart); + + if (negate) + { + *dest = -*dest; + } + + *str = savech; + dest++; + } + + return index; +} + S32 imemcmp(void const* d1, void const* d2, size_t size) { const char* s1 = (char*)d1; @@ -79,8 +237,8 @@ S32 imemcmp(void const* d1, void const* d2, size_t size) if (cval1 != cval2) { return cval1 - cval2; -} -} + } + } return 0; } @@ -93,9 +251,9 @@ namespace } U32 tolower(S32 param_1) -{ - return param_1 | ((param_1 >> 1) & 32); -} + { + return param_1 | ((param_1 >> 1) & 32); + } } // End anonymous namespace S32 icompare(const substr& s1, const substr& s2) @@ -104,7 +262,7 @@ S32 icompare(const substr& s1, const substr& s2) S32 result = imemcmp(s1.text, s2.text, len); switch (result) { - case 0: + case 0: if (s1.size == s2.size) { result = 0; diff --git a/src/SB/Core/x/xVec3Inlines.h b/src/SB/Core/x/xVec3Inlines.h index ddc252c85..b89883cae 100644 --- a/src/SB/Core/x/xVec3Inlines.h +++ b/src/SB/Core/x/xVec3Inlines.h @@ -21,6 +21,34 @@ F32 xVec3LengthFast(F32 x, F32 y, F32 z); F32 xVec3LengthFast(const xVec3* vec); void xVec3AddScaled(xVec3* o, const xVec3* v, F32 s); +#define xVec3NormalizeDistXZMacro(o, a, b, dist) \ + MACRO_START \ + { \ + F32 dx__ = (b)->x - (a)->x; \ + F32 dz__ = (b)->z - (a)->z; \ + F32 dist2 = SQR(dx__) + SQR(dz__); \ + if (xeq(dist2, 1.0f, 1e-5f)) \ + { \ + (o)->x = dx__; \ + (o)->z = dz__; \ + *(dist) = 1.0f; \ + } \ + else if (xeq(dist2, 0.0f, 1e-5f)) \ + { \ + (o)->x = 0.0f; \ + (o)->z = 0.0f; \ + *(dist) = 0.0f; \ + } \ + else \ + { \ + *(dist) = xsqrt(dist2); \ + F32 dist_inv = 1.0f / *(dist); \ + (o)->x = dx__ * dist_inv; \ + (o)->z = dz__ * dist_inv; \ + } \ + } \ + MACRO_STOP + inline void xVec3SMulBy(xVec3* v, F32 s) { v->x *= s; @@ -35,6 +63,4 @@ inline void xVec3SubFrom(xVec3* o, const xVec3* v) o->z -= v->z; } -F32 LERP(F32 dt, xVec3*, xVec3*, xVec3*); - #endif diff --git a/src/SB/Core/x/xpkrsvc.cpp b/src/SB/Core/x/xpkrsvc.cpp index 18fb512a2..598d8d805 100644 --- a/src/SB/Core/x/xpkrsvc.cpp +++ b/src/SB/Core/x/xpkrsvc.cpp @@ -716,7 +716,7 @@ S32 PKR_LoadLayer(st_PACKER_READ_DATA* pr, en_LAYER_TYPE layer) return 0; } -void* PKR_LoadAsset(st_PACKER_READ_DATA* pr, U32 aid, char*, void*) +void* PKR_LoadAsset(st_PACKER_READ_DATA* pr, U32 aid, const char*, void*) { return PKR_FindAsset(pr, aid); } diff --git a/src/SB/Core/x/xserializer.cpp b/src/SB/Core/x/xserializer.cpp index 86dd7d15a..caa12a767 100644 --- a/src/SB/Core/x/xserializer.cpp +++ b/src/SB/Core/x/xserializer.cpp @@ -1,38 +1,33 @@ #include "xserializer.h" +#include "xMemMgr.h" #include "xutil.h" #include static S32 g_serinit; -static st_XSERIAL_DATA_PRIV g_xserdata = {0, NULL, 0, NULL, NULL, NULL}; +static st_XSERIAL_DATA_PRIV g_xserdata = { 0, NULL, 0, NULL, NULL, NULL }; -static S32 g_tbl_onbit[32] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; +static S32 g_tbl_onbit[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static S32 g_tbl_clear[32] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; +static S32 g_tbl_clear[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static void xSER_init_tables(); static st_SERIAL_CLIENTINFO* XSER_get_client(U32 idtag); static S32 xSER_xsgclt_svinfo_ver(void*, st_XSAVEGAME_DATA*, S32* cur_space, S32* max_fullgame); static S32 xSER_xsgclt_svproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_WRITECONTEXT* wctxt); -static S32 xSER_xsgclt_ldproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, U32, S32); -static S32 xSER_xsgclt_svinfo_clt(void* cltdata, st_XSAVEGAME_DATA*, S32* cur_space, S32* max_fullgame); -static S32 xSER_xsgclt_svproc_clt(void* cltdata, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_WRITECONTEXT* wctxt); -static S32 xSER_xsgclt_ldproc_clt(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, U32 idtag, S32); +static S32 xSER_xsgclt_ldproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, + U32, S32); +static S32 xSER_xsgclt_svinfo_clt(void* cltdata, st_XSAVEGAME_DATA*, S32* cur_space, + S32* max_fullgame); +static S32 xSER_xsgclt_svproc_clt(void* cltdata, st_XSAVEGAME_DATA* xsg, + st_XSAVEGAME_WRITECONTEXT* wctxt); +static S32 xSER_xsgclt_ldproc_clt(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, + U32 idtag, S32); static S32 xSER_xsgclt_svproc_fill(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_WRITECONTEXT* wctxt); static S32 xSER_xsgclt_svinfo_fill(void*, st_XSAVEGAME_DATA*, S32* cur_space, S32* max_fullgame); -static S32 xSER_xsgclt_ldproc_fill(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, U32, S32); - +static S32 xSER_xsgclt_ldproc_fill(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, + U32, S32); S32 xSerialStartup(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo) { @@ -42,7 +37,7 @@ S32 xSerialStartup(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo) xSER_init_tables(); xSER_init_buffers(count, sizeinfo); } - + return g_serinit; } @@ -51,7 +46,7 @@ S32 xSerialShutdown() return g_serinit--; } -void xSerialTraverse(S32(*func)(U32, xSerial*)) +void xSerialTraverse(S32 (*func)(U32, xSerial*)) { xSerial xser; @@ -102,7 +97,7 @@ S32 xSerial::Write(char* data, S32 elesize, S32 n) if (n < 0) { S32 bidx = 0; - for (S32 i = 0; i < nbit; i++) + for (S32 i = 0; i < nbit; i++) { S32* iptr = (S32*)data; wrbit(*iptr & g_tbl_onbit[bidx]); @@ -282,7 +277,7 @@ S32 xSerial::rdbit() { st_SERIAL_CLIENTINFO* clt = ctxtdata; - if (bittally + 1 > clt->actsize * 8 ) + if (bittally + 1 > clt->actsize * 8) { warned = TRUE; return 0; @@ -327,9 +322,63 @@ static void xSER_init_tables() } } -void xSER_init_buffers(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo) +static void xSER_init_buffers(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo) +//NONMATCH("https://decomp.me/scratch/uex0C") { - // TODO + st_XSERIAL_DATA_PRIV* xsd = &g_xserdata; + S32 i = 0; + S32 tally = 0; + S32 sicnt = 0; + st_SERIAL_PERCID_SIZE* sitmp = NULL; + st_SERIAL_CLIENTINFO* tmp_clt = NULL; + + XOrdInit(&g_xserdata.cltlist, count, 0); + + xsd->cltbuf = + (st_SERIAL_CLIENTINFO*)xMemAlloc(gActiveHeap, count * sizeof(st_SERIAL_CLIENTINFO), 0); + memset(xsd->cltbuf, 0, count * sizeof(st_SERIAL_CLIENTINFO)); + xsd->cltnext = xsd->cltbuf; + + sitmp = sizeinfo; + while (sitmp->idtag != 0) + { + tally += (sitmp->needsize + 3) & ~3; + sicnt++; + sitmp++; + } + tally += (count - sicnt) * 400; + + xsd->bitbuf = (S32*)xMemAlloc(gActiveHeap, tally, 0); + memset(xsd->bitbuf, 0, tally); + + xsd->buf_bytcnt = tally; + + sitmp = sizeinfo; + tally = 0; + tmp_clt = xsd->cltnext; + while (sitmp->idtag != 0) + { + tmp_clt->idtag = sitmp->idtag; + tmp_clt->trueoff = tally; + tmp_clt->actsize = (sitmp->needsize + 3) & ~3; + tmp_clt->membuf = xsd->bitbuf + tally / 4; + XOrdAppend(&xsd->cltlist, tmp_clt); + tally += tmp_clt->actsize; + sitmp++; + tmp_clt++; + } + XOrdSort(&xsd->cltlist, xSER_ord_compare); + xsd->cltnext = tmp_clt; + + for (i = sicnt; i < count; i++) + { + tmp_clt->idtag = 0; + tmp_clt->trueoff = tally; + tmp_clt->actsize = 400; + tmp_clt->membuf = xsd->bitbuf + tally / 4; + tally += tmp_clt->actsize; + tmp_clt++; + } } // non-matching @@ -339,7 +388,7 @@ static S32 xSER_ord_compare(void* e1, void* e2) { return -1; } - + if (*(U32*)e2 < *(U32*)e1) { return 1; @@ -354,7 +403,7 @@ static S32 xSER_ord_test(const void* key, void* elt) { return -1; } - + if (*(U32*)elt < *(U32*)key) { return 1; @@ -423,7 +472,8 @@ static S32 xSER_xsgclt_svproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_WR return 1; } -static S32 xSER_xsgclt_ldproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, U32, S32) +static S32 xSER_xsgclt_ldproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, + U32, S32) { st_XSERIAL_DATA_PRIV* xsd = &g_xserdata; S32 ver = 0; @@ -435,21 +485,24 @@ static S32 xSER_xsgclt_ldproc_ver(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_RE return 1; } -static S32 xSER_xsgclt_svinfo_clt(void* cltdata, st_XSAVEGAME_DATA*, S32* cur_space, S32* max_fullgame) +static S32 xSER_xsgclt_svinfo_clt(void* cltdata, st_XSAVEGAME_DATA*, S32* cur_space, + S32* max_fullgame) { *cur_space = *(S32*)((S32)cltdata + 12); *max_fullgame = *(S32*)((S32)cltdata + 12); return 1; } -static S32 xSER_xsgclt_svproc_clt(void* cltdata, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_WRITECONTEXT* wctxt) +static S32 xSER_xsgclt_svproc_clt(void* cltdata, st_XSAVEGAME_DATA* xsg, + st_XSAVEGAME_WRITECONTEXT* wctxt) { st_SERIAL_CLIENTINFO* clt = XSER_get_client(*(U32*)cltdata); xSGWriteData(xsg, wctxt, (char*)clt->membuf, clt->actsize); return 1; } -static S32 xSER_xsgclt_ldproc_clt(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, U32 idtag, S32) +static S32 xSER_xsgclt_ldproc_clt(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, + U32 idtag, S32) { if ((g_xserdata.flg_info & 1) == 0) { @@ -461,14 +514,15 @@ static S32 xSER_xsgclt_ldproc_clt(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_RE static S32 xSER_xsgclt_svproc_fill(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_WRITECONTEXT* wctxt) { - char filbuf[9] = { 'R', 'y', 'a', 'n', 'N', 'e', 'i', 'l', '\x00'}; + char filbuf[9] = { 'R', 'y', 'a', 'n', 'N', 'e', 'i', 'l', '\x00' }; xSGWriteData(xsg, wctxt, (char*)&filbuf, 8); return 1; } -static S32 xSER_xsgclt_ldproc_fill(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, U32, S32) +static S32 xSER_xsgclt_ldproc_fill(void*, st_XSAVEGAME_DATA* xsg, st_XSAVEGAME_READCONTEXT* rctxt, + U32, S32) { - char filbuf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + char filbuf[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if ((g_xserdata.flg_info & 1) == 0) { xSGReadData(xsg, rctxt, (char*)&filbuf, 8); diff --git a/src/SB/Core/x/xserializer.h b/src/SB/Core/x/xserializer.h index 9f6744bd5..9949f2211 100644 --- a/src/SB/Core/x/xserializer.h +++ b/src/SB/Core/x/xserializer.h @@ -70,7 +70,8 @@ S32 xSerialStartup(S32, st_SERIAL_PERCID_SIZE*); S32 xSerialShutdown(); void xSerialTraverse(S32 (*func)(U32 clientID, xSerial* xser)); void xSerialWipeMainBuffer(); -void xSER_init_buffers(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo); +static void xSER_init_buffers(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo); S32 xSerial_svgame_register(st_XSAVEGAME_DATA* sgctxt, en_SAVEGAME_MODE mode); +static S32 xSER_ord_compare(void* e1, void* e2); #endif diff --git a/src/SB/Game/zMovePoint.cpp b/src/SB/Game/zMovePoint.cpp index 0f0e1a80a..6bd002c13 100644 --- a/src/SB/Game/zMovePoint.cpp +++ b/src/SB/Game/zMovePoint.cpp @@ -120,8 +120,3 @@ F32 zMovePointGetDelay(const zMovePoint* m) { return xMovePointGetDelay((xMovePoint*)m); } - -inline F32 xMovePointGetDelay(const xMovePoint* m) -{ - return m->delay; -} diff --git a/src/SB/Game/zMovePoint.h b/src/SB/Game/zMovePoint.h index 5cd6b372e..388ec8559 100644 --- a/src/SB/Game/zMovePoint.h +++ b/src/SB/Game/zMovePoint.h @@ -43,6 +43,20 @@ F32 zMovePointGetNext(const zMovePoint* current, const zMovePoint* prev, zMovePo xVec3* hdng); xVec3* zMovePointGetPos(const zMovePoint* m); F32 zMovePointGetDelay(const zMovePoint* m); -F32 xMovePointGetDelay(const xMovePoint* m); + +inline U16 xMovePointGetNumPoints(const xMovePoint* m) +{ + return m->asset->numPoints; +} + +inline xMovePoint* xMovePointGetPoint(const xMovePoint* m, U16 n) +{ + return m->nodes[n]; +} + +inline F32 xMovePointGetDelay(const xMovePoint* m) +{ + return m->delay; +} #endif diff --git a/src/SB/Game/zScene.h b/src/SB/Game/zScene.h index a944ab351..142bcd747 100644 --- a/src/SB/Game/zScene.h +++ b/src/SB/Game/zScene.h @@ -70,4 +70,6 @@ void zSceneSetOldScreenAdj(); U32 zScene_ScreenAdjustMode(); void zSceneSpawnRandomBubbles(); +U32 zScene_ScreenAdjustMode(); + #endif From a2585580576e28b0247e5a59da44c1b0a9fbf73f Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 29 Nov 2025 22:41:14 -0500 Subject: [PATCH 2/4] Elegant code --- src/SB/Core/x/xString.cpp | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/src/SB/Core/x/xString.cpp b/src/SB/Core/x/xString.cpp index 8a1ce327d..c923392bf 100644 --- a/src/SB/Core/x/xString.cpp +++ b/src/SB/Core/x/xString.cpp @@ -55,38 +55,10 @@ char* xStrTok(char* string, const char* control, char** nextoken) U8 map[32]; S32 count; - map[0] = 0; - map[1] = 0; - map[2] = 0; - map[3] = 0; - map[4] = 0; - map[5] = 0; - map[6] = 0; - map[7] = 0; - map[8] = 0; - map[9] = 0; - map[10] = 0; - map[11] = 0; - map[12] = 0; - map[13] = 0; - map[14] = 0; - map[15] = 0; - map[16] = 0; - map[17] = 0; - map[18] = 0; - map[19] = 0; - map[20] = 0; - map[21] = 0; - map[22] = 0; - map[23] = 0; - map[24] = 0; - map[25] = 0; - map[26] = 0; - map[27] = 0; - map[28] = 0; - map[29] = 0; - map[30] = 0; - map[31] = 0; + for (S32 i = 0; i < 32; i++) + { + map[i] = 0; + } ctrl = (U8*)control; From e00a18ac06d41b3c64b3816220b1ad7c5332c6e7 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sun, 30 Nov 2025 01:53:05 -0500 Subject: [PATCH 3/4] Add remaining xEntBoulder functions, and a few iModel functions. --- src/SB/Core/gc/iModel.cpp | 768 +++++++++++++++++++++++++++--- src/SB/Core/gc/iModel.h | 5 +- src/SB/Core/x/xEntBoulder.cpp | 858 ++++++++++++++++++++++------------ 3 files changed, 1268 insertions(+), 363 deletions(-) diff --git a/src/SB/Core/gc/iModel.cpp b/src/SB/Core/gc/iModel.cpp index c1a8d4dc8..6fd4b05e6 100644 --- a/src/SB/Core/gc/iModel.cpp +++ b/src/SB/Core/gc/iModel.cpp @@ -7,18 +7,26 @@ #include "zAssetTypes.h" #include "xMathInlines.h" -extern RwGlobals* RwEngineInstance; -static RpAtomic* sLastMaterial; -static U32 sMaterialFlags; -static U32 sMaterialIdx; -static RwTexture* sMaterialTexture[16]; -static U32 gLastAtomicCount; -static RpAtomic* gLastAtomicList[256]; +#define MAX2(a, b) ((a) >= (b) ? (a) : (b)) +#define MAX3(a, b, c) (MAX2((a), MAX2((b), (c)))) -static RpLight* sEmptyDirectionalLight[4]; -static RpLight* sEmptyAmbientLight; +#define IMODEL_MAX_ATOMICS 256 +#define IMODEL_MAX_DIRECTIONAL_LIGHTS 4 +#define IMODEL_MAX_MATERIALS 16 + +RpWorld* instance_world; +RwCamera* instance_camera; -int iModelHack_DisablePrelight; +static U32 gLastAtomicCount; +static RpAtomic* gLastAtomicList[IMODEL_MAX_ATOMICS]; +static RpLight* sEmptyDirectionalLight[IMODEL_MAX_DIRECTIONAL_LIGHTS]; +static RpLight* sEmptyAmbientLight; +static RwRGBA sMaterialColor[IMODEL_MAX_MATERIALS]; +static RwTexture* sMaterialTexture[IMODEL_MAX_MATERIALS]; +static U8 sMaterialAlpha[IMODEL_MAX_MATERIALS]; +static U32 sMaterialIdx; +static U32 sMaterialFlags; +static RpAtomic* sLastMaterial; RwFrame* GetChildFrameHierarchy(RwFrame* frame, void* data) { @@ -26,7 +34,7 @@ RwFrame* GetChildFrameHierarchy(RwFrame* frame, void* data) if (hierarchy == 0) { RwFrameForAllChildren(frame, &GetChildFrameHierarchy, data); - return frame; + return frame; } else { @@ -49,13 +57,13 @@ void iModelInit() RwRGBAReal black = { 0.0f, 0.0f, 0.0f, 0.0f }; if (sEmptyDirectionalLight[0] == 0) { - for (int i = 0; i < (int)(sizeof(sEmptyDirectionalLight) / sizeof(RpLight*)); i++) - { - sEmptyDirectionalLight[i] = RpLightCreate(rpLIGHTDIRECTIONAL); + for (int i = 0; i < (int)(sizeof(sEmptyDirectionalLight) / sizeof(RpLight*)); i++) + { + sEmptyDirectionalLight[i] = RpLightCreate(rpLIGHTDIRECTIONAL); RpLightSetColor(sEmptyDirectionalLight[i], &black); - RwFrame* frame = RwFrameCreate(); + RwFrame* frame = RwFrameCreate(); _rwObjectHasFrameSetFrame(sEmptyDirectionalLight[i], frame); - } + } sEmptyAmbientLight = RpLightCreate(rpLIGHTAMBIENT); RpLightSetColor(sEmptyAmbientLight, &black); // Redundant sEmptyAmbientLight load here. } @@ -63,18 +71,19 @@ void iModelInit() RpAtomic* FindAndInstanceAtomicCallback(RpAtomic* model, void* data) { - RpHAnimHierarchy* hierarchy = (RpHAnimHierarchy *)GetHierarchy(model); + RpHAnimHierarchy* hierarchy = (RpHAnimHierarchy*)GetHierarchy(model); RpGeometry* geom = model->geometry; RpSkin* skin = RpSkinGeometryGetSkin(geom); if ((skin != NULL) && (hierarchy == NULL)) { - hierarchy = (RpHAnimHierarchy *)RpHAnimHierarchyCreate(RpSkinGetNumBones(skin), 0, 0, rpHANIMHIERARCHYLOCALSPACEMATRICES, 0x24); + hierarchy = (RpHAnimHierarchy*)RpHAnimHierarchyCreate( + RpSkinGetNumBones(skin), 0, 0, rpHANIMHIERARCHYLOCALSPACEMATRICES, 0x24); RpHAnimFrameSetHierarchy((RwFrame*)(model->object).object.parent, hierarchy); } if ((hierarchy != NULL) && (skin != NULL)) { - RpSkinAtomicSetHAnimHierarchy(model,hierarchy); + RpSkinAtomicSetHAnimHierarchy(model, hierarchy); } if (hierarchy != NULL) { @@ -83,32 +92,33 @@ RpAtomic* FindAndInstanceAtomicCallback(RpAtomic* model, void* data) if (gLastAtomicCount < 0x100) { gLastAtomicList[gLastAtomicCount] = model; - gLastAtomicCount++; + gLastAtomicCount++; } RwFrame* root = RwFrameGetRoot((RwFrame*)(model->object).object.parent); - RpMaterialList* matList = &geom->matList; - int numMats = matList->numMaterials; + RpMaterialList* matList = &geom->matList; + int numMats = matList->numMaterials; - for (int i = 0; i < numMats; i++) - { - RpMaterial *pRVar4 = (RpMaterial *)_rpMaterialListGetMaterial(matList, i); + for (int i = 0; i < numMats; i++) + { + RpMaterial* pRVar4 = (RpMaterial*)_rpMaterialListGetMaterial(matList, i); if ((pRVar4 != NULL) && (RpMatFXMaterialGetEffects(pRVar4) != 0)) { RpMatFXAtomicEnableEffects(model); - model->pipeline = (RxPipeline *)RpMatFXGetGameCubePipeline(rpMATFXGAMECUBEATOMICPIPELINE); + model->pipeline = + (RxPipeline*)RpMatFXGetGameCubePipeline(rpMATFXGAMECUBEATOMICPIPELINE); if (RpSkinGeometryGetSkin(geom) != 0) { RpSkinAtomicSetType(model, rpSKINTYPEMATFX); } - break; + break; } - } + } if (gLastAtomicCount < 0x100) { gLastAtomicList[gLastAtomicCount] = model; - gLastAtomicCount++; + gLastAtomicCount++; } return model; @@ -155,14 +165,14 @@ static RpAtomic* NextAtomicCallback(RpAtomic* atomic, void* data) } else if (*(U32*)data == 0) { - *(RpAtomic **)data = atomic; + *(RpAtomic**)data = atomic; } return atomic; } RpAtomic* iModelFile_RWMultiAtomic(RpAtomic* model) { - RpClump* clump; + RpClump* clump; RpAtomic* nextModel; if (model == 0) @@ -171,10 +181,10 @@ RpAtomic* iModelFile_RWMultiAtomic(RpAtomic* model) } else { - clump = model->clump; + clump = model->clump; nextModel = model; RpClumpForAllAtomics(clump, NextAtomicCallback, &nextModel); - return nextModel; + return nextModel; } } @@ -184,6 +194,117 @@ U32 iModelNumBones(RpAtomic* model) return obj != 0 ? (U32)obj->numNodes : 0; } +S32 iModelCull(RpAtomic* model, RwMatrix* mat) +{ + RwCamera* cam = RwCameraGetCurrentCamera(); + RwSphere sph; + + RwV3dTransformPoints(&sph.center, &model->boundingSphere.center, 1, mat); + + RwReal f1 = RwV3dDotProductMacro(&mat->right, &mat->right); + RwReal f3 = RwV3dDotProductMacro(&mat->up, &mat->up); + RwReal f4 = RwV3dDotProductMacro(&mat->at, &mat->at); + + sph.radius = model->boundingSphere.radius * xsqrt(MAX(f1, MAX(f3, f4))); + + model->worldBoundingSphere = sph; + + if (!cam) + { + return 1; + } + + return (RwCameraFrustumTestSphere(cam, &sph) == rwSPHEREOUTSIDE); +} + +S32 iModelSphereCull(xSphere* sphere) +{ + RwCamera* camera = RwCameraGetCurrentCamera(); + RwFrustumTestResult result = RwCameraFrustumTestSphere(camera, (RwSphere*)sphere); + return (result == rwSPHEREOUTSIDE); +} + +// Very nonmatching +S32 iModelCullPlusShadow(RpAtomic* model, RwMatrix* mat, xVec3* shadowVec, S32* shadowOutside) +//NONMATCH("https://decomp.me/scratch/nx6io") +{ + F32 xScale2, yScale2, zScale2; + RwV3d *right, *up, *at; + RwCamera* cam; + RwSphere worldsph; + const RwFrustumPlane* frustumPlane; + S32 numPlanes; + + cam = RwCameraGetCurrentCamera(); + + RwV3dTransformPoints(&worldsph.center, &model->boundingSphere.center, 1, mat); + + right = &mat->right; + up = &mat->up; + at = &mat->at; + xScale2 = SQR(right->x) + SQR(right->y) + SQR(right->z); + yScale2 = SQR(up->x) + SQR(up->y) + SQR(up->z); + zScale2 = SQR(at->x) + SQR(at->y) + SQR(at->z); + worldsph.radius = model->boundingSphere.radius * xsqrt(MAX3(xScale2, yScale2, zScale2)); + model->worldBoundingSphere = worldsph; + + numPlanes = 6; + frustumPlane = cam->frustumPlanes; + while (numPlanes--) + { + F32 nDot = worldsph.center.x * frustumPlane->plane.normal.x + + worldsph.center.y * frustumPlane->plane.normal.y + + worldsph.center.z * frustumPlane->plane.normal.z; + nDot -= frustumPlane->plane.distance; + + if (nDot > worldsph.radius) + { + F32 nDot; + + F32 sDot = shadowVec->x * frustumPlane->plane.normal.x + + shadowVec->y * frustumPlane->plane.normal.y + + shadowVec->z * frustumPlane->plane.normal.z; + sDot -= frustumPlane->plane.distance; + + if (sDot > worldsph.radius) + { + *shadowOutside = 1; + return 1; + } + + frustumPlane++; + while (numPlanes--) + { + nDot = worldsph.center.x * frustumPlane->plane.normal.x + + worldsph.center.y * frustumPlane->plane.normal.y + + worldsph.center.z * frustumPlane->plane.normal.z; + nDot -= frustumPlane->plane.distance; + + sDot = shadowVec->x * frustumPlane->plane.normal.x + + shadowVec->y * frustumPlane->plane.normal.y + + shadowVec->z * frustumPlane->plane.normal.z; + sDot -= frustumPlane->plane.distance; + + if (nDot > worldsph.radius && sDot > worldsph.radius) + { + *shadowOutside = 1; + return 1; + } + + frustumPlane++; + } + + *shadowOutside = 0; + return 1; + } + + frustumPlane++; + } + + *shadowOutside = 0; + return 0; +} + void iModelQuatToMat(xQuat* q, xVec3* a, RwMatrixTag* t) { q->s = -q->s; @@ -199,17 +320,17 @@ void iModelAnimMatrices(RpAtomic* model, xQuat* quat, xVec3* tran, RwMatrixTag* { RwMatrixTag* pMatrixArray; RpHAnimNodeInfo* iVar1; - RwMatrixTag matrixStack [33]; + RwMatrixTag matrixStack[33]; U32 pCurrentFrameFlags; RpHAnimNodeInfo* pCurrentFrame; int numFrames; RwMatrixTag* pMatrixStackTop; - pCurrentFrame = (RpHAnimNodeInfo *)GetHierarchy(model); + pCurrentFrame = (RpHAnimNodeInfo*)GetHierarchy(model); if (pCurrentFrame != NULL) { - pMatrixStackTop = &matrixStack[0]; + pMatrixStackTop = &matrixStack[0]; pMatrixStackTop->at.z = 1.0; matrixStack[0].up.y = 1.0; @@ -225,48 +346,48 @@ void iModelAnimMatrices(RpAtomic* model, xQuat* quat, xVec3* tran, RwMatrixTag* matrixStack[0].pos.x = 0.0; matrixStack[0].flags |= 0x20003; - matrixStack[1] = matrixStack[0]; + matrixStack[1] = matrixStack[0]; numFrames = pCurrentFrame->nodeIndex; pMatrixArray = (&matrixStack[1]); - iVar1 = (RpHAnimNodeInfo *)pCurrentFrame[1].nodeID; + iVar1 = (RpHAnimNodeInfo*)pCurrentFrame[1].nodeID; - pMatrixArray++; - for (int i = 0; i < numFrames; i++) - { - pCurrentFrameFlags = iVar1->flags; + pMatrixArray++; + for (int i = 0; i < numFrames; i++) + { + pCurrentFrameFlags = iVar1->flags; if ((pCurrentFrameFlags & 2) != 0) { - *pMatrixArray++ = matrixStack[0]; + *pMatrixArray++ = matrixStack[0]; } - RwMatrixTag afStack_8e8; + RwMatrixTag afStack_8e8; iModelQuatToMat(quat, tran, &afStack_8e8); - RwMatrixTag auStack_8a8; - xMat4x3Mul((xMat4x3*)&auStack_8a8,(xMat4x3*)&afStack_8e8, (xMat4x3*)&matrixStack[0]); + RwMatrixTag auStack_8a8; + xMat4x3Mul((xMat4x3*)&auStack_8a8, (xMat4x3*)&afStack_8e8, (xMat4x3*)&matrixStack[0]); - *mat = auStack_8a8; + *mat = auStack_8a8; if ((pCurrentFrameFlags & 1) != 0) { - pMatrixArray = &pMatrixArray[-1]; + pMatrixArray = &pMatrixArray[-1]; pMatrixStackTop = pMatrixArray; } else { - pMatrixStackTop = (RwMatrixTag *)&auStack_8a8; + pMatrixStackTop = (RwMatrixTag*)&auStack_8a8; } matrixStack[0] = *pMatrixStackTop; mat++; quat++; tran++; iVar1++; - } + } } } RpAtomic* iModelCacheAtomic(RpAtomic* model) { - return model; + return model; } void iModelRender(RpAtomic* model, RwMatrixTag* mat) @@ -278,7 +399,7 @@ void iModelRender(RpAtomic* model, RwMatrixTag* mat) hierarchy = (RpHAnimHierarchy*)GetHierarchy(model); - static S32 draw_all = 1; + static S32 draw_all = 1; if (hierarchy != NULL) { @@ -305,14 +426,484 @@ void iModelRender(RpAtomic* model, RwMatrixTag* mat) S32 iModelSphereCull(const xSphere* sphere) { - return RwCameraFrustumTestSphere((const RwCamera*)RwEngineInstance->curCamera, (const RwSphere*)sphere) == 0; + return RwCameraFrustumTestSphere((const RwCamera*)RwEngineInstance->curCamera, + (const RwSphere*)sphere) == 0; } -U32 iModelVertCount(RpAtomic *model) +U32 iModelVertCount(RpAtomic* model) { return model->geometry->numVertices; } +static inline void SkinXform(xVec3* dest, const xVec3* vert, RwMatrix* mat, const RwMatrix* skinmat, + const F32* wt, const U32* idx, U32 count) +// NONMATCH("https://decomp.me/scratch/8dnNK") +{ + U32 catMatFlags[2] = { 0, 0 }; + RwMatrix* catmat = (RwMatrix*)giAnimScratch; + RwMatrix* rootmat = mat; + mat++; + + while (count != 0) + { + for (U32 i = 0; i < 4; i++) + { + U32 r18 = ((*idx >> (i << 3)) >> 5) & 0x7; + U32 r29 = 1 << ((*idx >> (i << 3)) & 0x1F); + U32 midx = (*idx >> (i << 3)) & 0xFF; + if (!(r29 & catMatFlags[r18])) + { + xMat4x3Mul((xMat4x3*)(catmat + midx), (const xMat4x3*)(skinmat + midx), + (const xMat4x3*)(mat + midx)); + catMatFlags[r18] |= r29; + } + } + + xVec3 accumV; + accumV.x = accumV.y = accumV.z = 0.0f; + + RwMatrix* pMatrix; + const F32* fwt = wt; + U32 wtidx = *idx; + U32 maxwt = 4; + + while (*fwt != 0.0f && maxwt) + { + pMatrix = catmat + (wtidx & 0xFF); + + accumV.x += *fwt * (pMatrix->right.x * vert->x + pMatrix->up.x * vert->y + + pMatrix->at.x * vert->z + pMatrix->pos.x); + accumV.y += *fwt * (pMatrix->right.y * vert->x + pMatrix->up.y * vert->y + + pMatrix->at.y * vert->z + pMatrix->pos.y); + accumV.z += *fwt * (pMatrix->right.z * vert->x + pMatrix->up.z * vert->y + + pMatrix->at.z * vert->z + pMatrix->pos.z); + + fwt++; + wtidx >>= 8; + maxwt--; + } + + dest->x = rootmat->right.x * accumV.x + rootmat->up.x * accumV.y + + rootmat->at.x * accumV.z + rootmat->pos.x; + dest->y = rootmat->right.y * accumV.x + rootmat->up.y * accumV.y + + rootmat->at.y * accumV.z + rootmat->pos.y; + dest->z = rootmat->right.z * accumV.x + rootmat->up.z * accumV.y + + rootmat->at.z * accumV.z + rootmat->pos.z; + + vert++; + idx++; + wt += 4; + count--; + dest++; + } +} + +// TODO: uncomment all code after RW gets implemented + +U32 iModelVertEval(RpAtomic* model, U32 index, U32 count, RwMatrix* mat, xVec3* vert, xVec3* dest) +{ + // RpGeometry* geom = RpAtomicGetGeometry(model); + + // if (!vert) + // { + // U32 numV = RpGeometryGetNumVertices(geom); + // if (index >= numV || count == 0) + // { + // return 0; + // } + // count = xmin(count, numV - index); + // vert = (xVec3*)RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geom, 0)); + // vert += index; + // } + + // RpSkin* skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(model)); + // if (skin) + // { + // SkinXform(dest, vert, mat, RpSkinGetSkinToBoneMatrices(skin), + // (F32*)(RpSkinGetVertexBoneWeights(skin) + index), + // RpSkinGetVertexBoneIndices(skin) + index, count); + // } + // else + // { + // RwV3dTransformPoints((RwV3d*)dest, (const RwV3d*)vert, count, mat); + // } + + // return count; + return 0; +} + +static inline void SkinNormals(xVec3* dest, const xVec3* normal, const RwMatrix* mat, + const RwMatrix* skinmat, const F32* wt, const U32* idx, U32 count) +//NONMATCH("https://decomp.me/scratch/WTMKS") +{ + U32 catMatFlags[2] = { 0, 0 }; + RwMatrix* catmat = (RwMatrix*)giAnimScratch; + const RwMatrix* rootmat = mat; + mat++; + + RwV3d right; + right.x = rootmat->right.x; + right.y = rootmat->right.y; + right.z = rootmat->right.z; + + RwV3d up; + up.x = rootmat->up.x; + up.y = rootmat->up.y; + up.z = rootmat->up.z; + + RwV3d at; + at.x = rootmat->at.x; + at.y = rootmat->at.y; + at.z = rootmat->at.z; + + while (count != 0) + { + for (U32 i = 0; i < 4; i++) + { + U32 r18 = ((*idx >> (i << 3)) >> 5) & 0x7; + U32 r29 = 1 << ((*idx >> (i << 3)) & 0x1F); + U32 midx = (*idx >> (i << 3)) & 0xFF; + if (!(r29 & catMatFlags[r18])) + { + xMat3x3Mul((xMat3x3*)(catmat + midx), (const xMat3x3*)(skinmat + midx), + (const xMat3x3*)(mat + midx)); + xMat3x3Normalize((xMat3x3*)(catmat + midx), (xMat3x3*)(catmat + midx)); + catMatFlags[r18] |= r29; + } + } + + xVec3 accumV; + accumV.x = accumV.y = accumV.z = 0.0f; + + RwMatrix* pMatrix; + const F32* fwt = wt; + U32 wtidx = *idx; + U32 maxwt = 4; + + while (*fwt != 0.0f && maxwt) + { + pMatrix = catmat + (wtidx & 0xFF); + + accumV.x += *fwt * (pMatrix->right.x * normal->x + pMatrix->up.x * normal->y + + pMatrix->at.x * normal->z); + accumV.y += *fwt * (pMatrix->right.y * normal->x + pMatrix->up.y * normal->y + + pMatrix->at.y * normal->z); + accumV.z += *fwt * (pMatrix->right.z * normal->x + pMatrix->up.z * normal->y + + pMatrix->at.z * normal->z); + + fwt++; + wtidx >>= 8; + maxwt--; + } + + dest->x = right.x * accumV.x + up.x * accumV.y + at.x * accumV.z; + dest->y = right.y * accumV.x + up.y * accumV.y + at.y * accumV.z; + dest->z = right.z * accumV.x + up.z * accumV.y + at.z * accumV.z; + + normal++; + idx++; + wt += 4; + count--; + dest++; + } +} + +// TODO: Fix the below 3 functions after RW gets implemented + +U32 iModelNormalEval(xVec3* out, const RpAtomic& m, const RwMatrix* mat, size_t index, S32 size, + const xVec3* in) +{ + // RpGeometry* geom = RpAtomicGetGeometry(&m); + + // if (!in) + // { + // S32 numV = RpGeometryGetNumVertices(geom); + // S32 max_size = numV - index; + // if (size < 0 || size > max_size) + // { + // size = max_size; + // } + // in = (const xVec3*)RpMorphTargetGetVertexNormals(RpGeometryGetMorphTarget(geom, 0)); + // } + + // if (size <= 0) + // return 0; + + // in += index; + + // RpSkin* skin = RpSkinGeometryGetSkin(geom); + // if (skin) + // { + // const RwMatrix* skin_mats = RpSkinGetSkinToBoneMatrices(skin); + // const F32* bone_weights = (F32*)RpSkinGetVertexBoneWeights(skin) + index; + // const U32* bone_indices = RpSkinGetVertexBoneIndices(skin) + index; + // SkinNormals(out, in, mat, skin_mats, bone_weights, bone_indices, size); + // } + // else + // { + // xMat4x3 nmat; + // xMat3x3Normalize( + // &nmat, (xMat3x3*)&mat); // BUG: mat is already a pointer, nmat will have garbage data!!! + // nmat.pos.assign(0.0f, 0.0f, 0.0f); + // RwV3dTransformPoints((RwV3d*)out, (RwV3d*)in, size, (RwMatrix*)&nmat); + // } + + // return size; + return 0; +} + +static U32 iModelTagUserData(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z, S32 closeV) +{ + // S32 i, count; + // RpUserDataArray *array, *testarray; + // F32 distSqr, closeDistSqr; + // S32 numTags, t; + // xModelTag* tagList; + + // count = RpGeometryGetUserDataArrayCount(model->geometry); + // array = NULL; + + // for (i = 0; i < count; i++) + // { + // testarray = RpGeometryGetUserDataArray(model->geometry, i); + // if (strcmp(testarray->name, "HI_Tags") == 0) + // { + // array = testarray; + // break; + // } + // } + + // if (!array) + // { + // memset(tag, 0, sizeof(xModelTag)); + // return 0; + // } + + // numTags = *(S32*)array->data; + // closeDistSqr = 1.0e9f; + // tagList = (xModelTag*)((S32*)array->data + 1); + + // if (closeV < 0 || closeV > numTags) + // { + // closeV = 0; + // for (t = 0; t < numTags; t++) + // { + // distSqr = + // xsqr(tagList[t].v.x - x) + xsqr(tagList[t].v.y - y) + xsqr(tagList[t].v.z - z); + // if (distSqr < closeDistSqr) + // { + // closeV = t; + // closeDistSqr = distSqr; + // } + // } + // if (tag) + // { + // *tag = tagList[closeV]; + // } + // } + // else + // { + // if (tag) + // { + // *tag = tagList[closeV]; + // } + // } + + // return closeV; + return 0; +} + +static U32 iModelTagInternal(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z, S32 closeV) + +//NONMATCH("https://decomp.me/scratch/NgdD8") +{ + // RpGeometry* geom; + // RwV3d* vert; + // S32 v, numV; + // F32 distSqr, closeDistSqr; + // RpSkin* skin; + // const RwMatrixWeights* wt; + + // geom = RpAtomicGetGeometry(model); + // vert = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geom, 0)); + + // if (!vert) + // { + // return iModelTagUserData(tag, model, x, y, z, closeV); + // } + + // numV = RpGeometryGetNumVertices(geom); + // closeDistSqr = 1.0e9f; + + // if (closeV < 0 || closeV > numV) + // { + // closeV = 0; + // for (v = 0; v < numV; v++) + // { + // distSqr = xsqr(vert[v].x - x) + xsqr(vert[v].y - y) + xsqr(vert[v].z - z); + // if (distSqr < closeDistSqr) + // { + // closeV = v; + // closeDistSqr = distSqr; + // } + // } + // if (tag) + // { + // tag->v.x = x; + // tag->v.y = y; + // tag->v.z = z; + // } + // } + // else + // { + // if (tag) + // { + // tag->v.x = vert[closeV].x; + // tag->v.y = vert[closeV].y; + // tag->v.z = vert[closeV].z; + // } + // } + + // if (tag) + // { + // skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(model)); + // if (skin) + // { + // wt = RpSkinGetVertexBoneWeights(skin) + closeV; + // tag->matidx = RpSkinGetVertexBoneIndices(skin)[closeV]; + // tag->wt[0] = wt->w0; + // tag->wt[1] = wt->w1; + // tag->wt[2] = wt->w2; + // tag->wt[3] = wt->w3; + // } + // else + // { + // tag->matidx = 0; + // tag->wt[0] = 0.0f; + // tag->wt[1] = 0.0f; + // tag->wt[2] = 0.0f; + // tag->wt[3] = 0.0f; + // } + // } + + // return closeV; + return 0; +} + +U32 iModelTagSetup(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z) +{ + return iModelTagInternal(tag, model, x, y, z, -1); +} + +U32 iModelTagSetup(xModelTagWithNormal* tag, RpAtomic* model, F32 x, F32 y, F32 z) +{ + U32 index = iModelTagInternal(tag, model, x, y, z, -1); + xVec3* normals = (xVec3*)model->geometry->morphTarget[0].normals; + tag->normal = normals[index]; + return index; +} + +void iModelTagEval(RpAtomic* model, const xModelTag* tag, RwMatrix* mat, xVec3* dest) +//NONMATCH("https://decomp.me/scratch/L7pKU") +{ + if (tag->wt[0]) + { + RpGeometry* geom = RpAtomicGetGeometry(model); + RpSkin* skin = RpSkinGeometryGetSkin(geom); + const RwMatrix* skinmat = RpSkinGetSkinToBoneMatrices(skin); + SkinXform(dest, &tag->v, mat, skinmat, tag->wt, &tag->matidx, 1); + } + else + { + RwV3dTransformPoints((RwV3d*)dest, (RwV3d*)&tag->v, 1, mat); + } +} + +void iModelTagEval(RpAtomic* model, const xModelTagWithNormal* tag, RwMatrix* mat, xVec3* dest, + xVec3* normal) +{ + iModelTagEval(model, tag, mat, dest); + if (tag->wt[0]) + { + RpGeometry* geom = RpAtomicGetGeometry(model); + RpSkin* skin = RpSkinGeometryGetSkin(geom); + const RwMatrix* skinmat = RpSkinGetSkinToBoneMatrices(skin); + SkinNormals(normal, &tag->normal, mat, skinmat, tag->wt, &tag->matidx, 1); + } + else + { + RwV3dTransformPoints((RwV3d*)normal, (RwV3d*)&tag->normal, 1, mat); + } +} + +static RpMaterial* iModelSetMaterialAlphaCB(RpMaterial* material, void* data) +{ + const RwRGBA* col = RpMaterialGetColor(material); + sMaterialAlpha[sMaterialIdx++] = col->alpha; + + RwRGBA new_col = *col; + new_col.alpha = *(U8*)data; + + RpMaterialSetColor(material, &new_col); + + return material; +} + +// TODO: another thing that needs fixed after RW gets implemented +void iModelSetMaterialAlpha(RpAtomic* model, U8 alpha) +// NONMATCH("https://decomp.me/scratch/Oyo8b") +{ + // RpGeometry* geom = RpAtomicGetGeometry(model); + + // if (model != sLastMaterial) + // { + // sMaterialFlags = 0; + // } + + // RpGeometrySetFlags(geom, RpGeometryGetFlags(geom) | rpGEOMETRYMODULATEMATERIALCOLOR); + + // sMaterialIdx = 0; + + // RpGeometryForAllMaterials(geom, iModelSetMaterialAlphaCB, &alpha); + + // sMaterialFlags |= 0x1; + // sLastMaterial = model; +} + +static RpMaterial* iModelResetMaterialCB(RpMaterial* material, void* data) +// NONMATCH("https://decomp.me/scratch/eBpxV") +{ + if ((sMaterialFlags & 0x3) == 0x3) + { + RwRGBA newColor = sMaterialColor[sMaterialIdx]; + newColor.alpha = sMaterialAlpha[sMaterialIdx]; + RpMaterialSetColor(material, &newColor); + } + else + { + if (sMaterialFlags & 0x2) + { + RwRGBA newColor = sMaterialColor[sMaterialIdx]; + newColor.alpha = RpMaterialGetColor(material)->alpha; + RpMaterialSetColor(material, &newColor); + } + if (sMaterialFlags & 0x1) + { + RwRGBA newColor = *RpMaterialGetColor(material); + newColor.alpha = sMaterialAlpha[sMaterialIdx]; + RpMaterialSetColor(material, &newColor); + } + } + + if (sMaterialFlags & 0x4) + { + RpMaterialSetTexture(material, sMaterialTexture[sMaterialIdx]); + } + + sMaterialIdx++; + return material; +} + void iModelResetMaterial(RpAtomic* model) { RpAtomic* material = sLastMaterial; // r2 @@ -323,7 +914,7 @@ void iModelResetMaterial(RpAtomic* model) sMaterialFlags = 0; } - geom = model->geometry; + geom = model->geometry; sMaterialIdx = 0; RpGeometryForAllMaterials(geom, iModelResetMaterialCB, 0); @@ -333,7 +924,7 @@ void iModelResetMaterial(RpAtomic* model) RpMaterial* iModelSetMaterialTextureCB(RpMaterial* material, void* data) { int i = sMaterialIdx; - RwTexture* texture = material->texture; + RwTexture* texture = material->texture; sMaterialIdx++; sMaterialTexture[i] = texture; RpMaterialSetTexture(material, (RwTexture*)data); @@ -342,14 +933,73 @@ RpMaterial* iModelSetMaterialTextureCB(RpMaterial* material, void* data) void iModelSetMaterialTexture(RpAtomic* model, void* texture) { - RpGeometry* geom; + RpGeometry* geom; if (model != sLastMaterial) { sMaterialFlags = 0; } - geom = model->geometry; + geom = model->geometry; sMaterialIdx = 0; RpGeometryForAllMaterials(geom, iModelSetMaterialTextureCB, texture); sMaterialFlags |= 4; sLastMaterial = model; -} \ No newline at end of file +} + +namespace +{ + inline void U8_COLOR_CLAMP(U8& destu8, F32 srcf32) + //NONMATCH("https://decomp.me/scratch/dl7BD") + { + if (srcf32 < 0.0f) + srcf32 = 0.0f; + else if (srcf32 > 255.0f) + srcf32 = 255.0f; + destu8 = (U8)srcf32; + } +} // namespace + +static RpMaterial* iModelMaterialMulCB(RpMaterial* material, void* data) +// NONMATCH("https://decomp.me/scratch/ig80z") +{ + const RwRGBA* rw_col = RpMaterialGetColor(material); + RwRGBA col = sMaterialColor[sMaterialIdx++] = *rw_col; + F32 tmp; + F32* mods = (F32*)data; + + tmp = col.red * mods[0]; + U8_COLOR_CLAMP(col.red, tmp); + + tmp = col.green * mods[1]; + U8_COLOR_CLAMP(col.green, tmp); + + tmp = col.blue * mods[2]; + U8_COLOR_CLAMP(col.blue, tmp); + + RpMaterialSetColor(material, &col); + + return material; +} + +// TODO: once again, fix after RW implementation +void iModelMaterialMul(RpAtomic* model, F32 rm, F32 gm, F32 bm) +// NONMATCH("https://decomp.me/scratch/zDCk9") +{ + // RpGeometry* geom = RpAtomicGetGeometry(model); + + // if (model != sLastMaterial) + // { + // sMaterialFlags = 0; + // } + + // RpGeometrySetFlags(geom, RpGeometryGetFlags(geom) | rpGEOMETRYMODULATEMATERIALCOLOR); + + // F32 cols[3]; + // cols[0] = rm; + // cols[1] = gm; + // cols[2] = bm; + + // RpGeometryForAllMaterials(geom, iModelMaterialMulCB, cols); + + // sLastMaterial = model; + // sMaterialFlags |= 0x2; +} diff --git a/src/SB/Core/gc/iModel.h b/src/SB/Core/gc/iModel.h index f472549b2..ff4a7e0b2 100644 --- a/src/SB/Core/gc/iModel.h +++ b/src/SB/Core/gc/iModel.h @@ -11,7 +11,7 @@ void iModelInit(); static RpAtomic* FindAndInstanceAtomicCallback(RpAtomic* model, void* data); static RpAtomic* iModelCacheAtomic(RpAtomic*); -RpMaterial* iModelResetMaterialCB(RpMaterial*, void*); +static RpMaterial* iModelResetMaterialCB(RpMaterial*, void*); static void* GetHierarchy(RpAtomic* frame); static RwFrame* GetChildFrameHierarchy(RwFrame* frame, void* data); U32 iModelNumBones(RpAtomic* model); @@ -29,7 +29,8 @@ void iModelTagEval(RpAtomic* model, const xModelTag* tag, RwMatrixTag* mat, xVec U32 iModelTagSetup(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z); void iModelSetMaterialAlpha(RpAtomic* model, U8 alpha); U32 iModelVertCount(RpAtomic* model); -U32 iModelVertEval(RpAtomic* model, U32 index, U32 count, RwMatrixTag* mat, xVec3* vert, xVec3* dest); +U32 iModelVertEval(RpAtomic* model, U32 index, U32 count, RwMatrixTag* mat, xVec3* vert, + xVec3* dest); void iModelMaterialMul(RpAtomic* model, F32 rm, F32 gm, F32 bm); RpAtomic* iModelFileNew(void* buffer, U32 size); void iModelRender(RpAtomic* model, RwMatrix* mat); diff --git a/src/SB/Core/x/xEntBoulder.cpp b/src/SB/Core/x/xEntBoulder.cpp index 4f3672200..8c99ff420 100644 --- a/src/SB/Core/x/xEntBoulder.cpp +++ b/src/SB/Core/x/xEntBoulder.cpp @@ -1,7 +1,9 @@ #include "xCollide.h" #include "xEntBoulder.h" #include "xFX.h" +#include "xGroup.h" #include "xMarkerAsset.h" +#include "xMathInlines.h" #include "xMath3.h" #include "xNPCBasic.h" #include "xShadow.h" @@ -26,9 +28,11 @@ static xEntCollis sBoulderCollis; void xShadowManager_Add(xEnt* ent); S32 xEntBoulder_KilledBySurface(xEntBoulder* ent); S32 xEntBoulder_KilledBySurface(xEntBoulder* ent, xScene* sc, F32 dt); -S32 xBoulderGenerator_EventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget); +S32 xBoulderGenerator_EventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget); void xBoulderGenerator_Reset(xBoulderGenerator* gen); -S32 RecurseLinks(xLinkAsset*, S32, xEntBoulder**); +static S32 RecurseLinks(xLinkAsset*, S32, xEntBoulder**); +static void RecurseChild(xBase* child, xEntBoulder** boulList, S32& currBoul); void xEntBoulder_FitToModel(xEntBoulder* ent) { @@ -49,43 +53,43 @@ void xEntBoulder_Render(xEnt* ent) { switch (model->Flags & 0x400) { - case 0: - if (ent->flags & 0x40) + case 0: + if (ent->flags & 0x40) + { + if (!iModelCull(model->Data, model->Mat)) { - if (!iModelCull(model->Data, model->Mat)) - { - xModelRender(model); - } + xModelRender(model); } - else + } + else + { + shadVec.x = model->Mat->pos.x; + shadVec.y = model->Mat->pos.y - 10.0f; + shadVec.z = model->Mat->pos.z; + + if (!iModelCullPlusShadow(model->Data, model->Mat, &shadVec, &shadowResult)) { - shadVec.x = model->Mat->pos.x; - shadVec.y = model->Mat->pos.y - 10.0f; - shadVec.z = model->Mat->pos.z; + xModelRender(model); + } - if (!iModelCullPlusShadow(model->Data, model->Mat, &shadVec, &shadowResult)) + if (!shadowResult) + { + if (ent->flags & 0x10) { - xModelRender(model); + xShadowManager_Add(ent); } - - if (!shadowResult) + else { - if (ent->flags & 0x10) - { - xShadowManager_Add(ent); - } - else + radius = ent->model->Data->boundingSphere.radius; + if (radius > 0.75f) { - radius = ent->model->Data->boundingSphere.radius; - if (radius > 0.75f) - { - radius = 0.75f; - } - xShadowSimple_Add(ent->simpShadow,ent, 2.0f * radius, 1.0f); + radius = 0.75f; } + xShadowSimple_Add(ent->simpShadow, ent, 2.0f * radius, 1.0f); } } - break; + } + break; } } } @@ -96,8 +100,8 @@ void xEntBoulder_Init(void* ent, void* asset) } S32 xEntBoulderEventCB(xBase*, xBase*, U32, const F32*, xBase*); -void xEntBoulder_BUpdate(xEnt *, xVec3 *); -void xEntBoulder_Update(xEntBoulder *, xScene *, F32); +void xEntBoulder_BUpdate(xEnt*, xVec3*); +void xEntBoulder_Update(xEntBoulder*, xScene*, F32); void xEntBoulder_Init(xEntBoulder* ent, xEntAsset* asset) { @@ -112,7 +116,7 @@ void xEntBoulder_Init(xEntBoulder* ent, xEntAsset* asset) xEntInitShadow(*ent, ent->entShadow_embedded); ent->simpShadow = &ent->simpShadow_embedded; xShadowSimple_CacheInit(ent->simpShadow, ent, 0x50); - ent->frame = (xEntFrame *)xMemAlloc(gActiveHeap, sizeof(xEntFrame), 0); + ent->frame = (xEntFrame*)xMemAlloc(gActiveHeap, sizeof(xEntFrame), 0); memset(ent->frame, 0, sizeof(xEntFrame)); basset = (xEntBoulderAsset*)(&asset[1]); ent->collis = NULL; @@ -124,7 +128,7 @@ void xEntBoulder_Init(xEntBoulder* ent, xEntAsset* asset) if (ent->linkCount != 0) { - ent->link = (xLinkAsset *)(&ent->asset[1]); + ent->link = (xLinkAsset*)(&ent->asset[1]); } else { @@ -176,10 +180,10 @@ void xEntBoulder_ApplyForces(xEntCollis* collis) xBase* obj = (xBase*)(coll->optr); if ((obj != NULL) && (obj->baseType == eBaseTypeBoulder)) { - xEntBoulder* boul = ((xEntBoulder *)(coll->optr)); + xEntBoulder* boul = ((xEntBoulder*)(coll->optr)); xVec3 vec; xVec3SMul(&vec, &collis->colls[i].norm, -5.0f); - if ((boul == globals.player.drv.odriver) || (boul == globals.player.drv.driver)) + if ((boul == globals.player.drv.odriver) || (boul == globals.player.drv.driver)) { if (collis->colls[i].norm.y > 0.5f) { @@ -224,7 +228,7 @@ void xEntBoulder_RealBUpdate(xEnt* ent, xVec3* pos) xVec3 vec; xEntBoulder* boul = (xEntBoulder*)ent; - xMat3x3RMulVec(&vec, (xMat3x3 *)boul->model->Mat, (xVec3 *)&boul->localCenter); + xMat3x3RMulVec(&vec, (xMat3x3*)boul->model->Mat, (xVec3*)&boul->localCenter); xVec3Add(&boul->bound.sph.center, pos, &vec); xBoundUpdate(&boul->bound); zGridUpdateEnt(boul); @@ -268,16 +272,11 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) zEntEvent(ent, eEventKill); return; } - else if - ( - (ent == globals.player.bubblebowl) && - ( - dx__ = (globals.player.ent.bound.sph.center.x - ent->model->Mat->pos.x), - dy__ = (globals.player.ent.bound.sph.center.y - ent->model->Mat->pos.y), - dz__ = (globals.player.ent.bound.sph.center.z - ent->model->Mat->pos.z), - (dx__ * dx__) + (dy__ * dy__) + (dz__ * dz__) > 3600.0f - ) - ) + else if ((ent == globals.player.bubblebowl) && + (dx__ = (globals.player.ent.bound.sph.center.x - ent->model->Mat->pos.x), + dy__ = (globals.player.ent.bound.sph.center.y - ent->model->Mat->pos.y), + dz__ = (globals.player.ent.bound.sph.center.z - ent->model->Mat->pos.z), + (dx__ * dx__) + (dy__ * dy__) + (dz__ * dz__) > 3600.0f)) { zEntEvent(ent, eEventKill); return; @@ -285,14 +284,14 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) if (ent->collis == NULL) { - ent->collis = (xEntCollis *)&sBoulderCollis; + ent->collis = (xEntCollis*)&sBoulderCollis; } ent->collis->chk = ent->collis_chk; ent->collis->pen = ent->collis_pen; ent->collis->post = NULL; ent->collis->depenq = NULL; - xMat3x3RMulVec(&newRotVec, (xMat3x3 *)ent->model->Mat, &ent->localCenter); + xMat3x3RMulVec(&newRotVec, (xMat3x3*)ent->model->Mat, &ent->localCenter); xVec3Add(&ent->bound.sph.center, (xVec3*)&ent->model->Mat->pos, &newRotVec); if ((sBubbleStreakID != 0xDEAD) && (globals.player.bubblebowl == ent)) @@ -350,13 +349,10 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) numDepens = 0; xVec3Init(&tmp, 0.0f, 0.0f, 0.0f); // Let's initialize a vector for no reason. - if - ( - (ent->collis->env_eidx > ent->collis->env_sidx) || - (ent->collis->dyn_eidx > ent->collis->dyn_sidx) || - (ent->collis->npc_eidx > ent->collis->npc_sidx) || - (ent->collis->stat_eidx > ent->collis->stat_sidx) - ) + if ((ent->collis->env_eidx > ent->collis->env_sidx) || + (ent->collis->dyn_eidx > ent->collis->dyn_sidx) || + (ent->collis->npc_eidx > ent->collis->npc_sidx) || + (ent->collis->stat_eidx > ent->collis->stat_sidx)) { xVec3Init(&depen, 0.0f, 0.0f, 0.0f); @@ -365,18 +361,15 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) { if (ent->basset->flags & 1) { - xVec3AddTo(&depen, (xVec3 *)(&ent->collis->colls[i].depen)); + xVec3AddTo(&depen, (xVec3*)(&ent->collis->colls[i].depen)); } else { uVar19 = xVec3Dot(&ent->collis->colls[i].norm, &ent->collis->colls[i].depen); - if - ( - (ent == globals.player.bubblebowl) && - (xVec3Dot(&ent->collis->colls[i].norm, &velNorm) < -0.70710676f) && - (ent->timeToLive > 0.05f) - ) + if ((ent == globals.player.bubblebowl) && + (xVec3Dot(&ent->collis->colls[i].norm, &velNorm) < -0.70710676f) && + (ent->timeToLive > 0.05f)) { ent->timeToLive = 0.05f; } @@ -391,22 +384,24 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) { if (ent->basset->flags & 1) { - xVec3AddTo(&depen, (xVec3 *)(&ent->collis->colls[i].depen)); + xVec3AddTo(&depen, (xVec3*)(&ent->collis->colls[i].depen)); } else { - xVec3AddScaled(&depen, &ent->collis->colls[i].norm, xVec3Dot(&ent->collis->colls[i].norm, &ent->collis->colls[i].depen)); + xVec3AddScaled(&depen, &ent->collis->colls[i].norm, + xVec3Dot(&ent->collis->colls[i].norm, &ent->collis->colls[i].depen)); } - xEntBoulder* boul = ((xEntBoulder *)(ent->collis->colls[i].optr)); + xEntBoulder* boul = ((xEntBoulder*)(ent->collis->colls[i].optr)); if (boul->baseType == eBaseTypeBoulder) { - xVec3Normalize(&depenNorm0, (xVec3 *)(&ent->collis->colls[i].depen)); + xVec3Normalize(&depenNorm0, (xVec3*)(&ent->collis->colls[i].depen)); dVar18 = xVec3Dot(&ent->vel, &depenNorm0); dVar16 = xVec3Dot(&boul->vel, &depenNorm0); F32 collMass = boul->basset->mass; F32 boulMass = ent->basset->mass; - xVec3SMulBy(&depenNorm0, ((2.0f * boulMass) * collMass * (dVar16 - dVar18)) / (boulMass + collMass)); + xVec3SMulBy(&depenNorm0, ((2.0f * boulMass) * collMass * (dVar16 - dVar18)) / + (boulMass + collMass)); xVec3SMul(&force, &depenNorm0, ent->basset->bounce); xEntBoulder_AddInstantForce(ent, &force); xVec3SMul(&force, &depenNorm0, -boul->basset->bounce); @@ -425,15 +420,13 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) } zPlatform* plat = ((zPlatform*)(boul)); - if - ( - (ent == globals.player.bubblebowl) && - (plat->moreFlags & 0x10) && + if ((ent == globals.player.bubblebowl) && (plat->moreFlags & 0x10) && (plat->baseType == eBaseTypePlatform) && - (plat->subType == ZPLATFORM_SUBTYPE_PADDLE && (plat->passet->paddle.paddleFlags & 0x10)) - ) + (plat->subType == ZPLATFORM_SUBTYPE_PADDLE && + (plat->passet->paddle.paddleFlags & 0x10))) { - zPlatform_PaddleCollide(&ent->collis->colls[i], (xVec3 *)(&ent->model->Mat->pos), &ent->vel, 1); + zPlatform_PaddleCollide(&ent->collis->colls[i], (xVec3*)(&ent->model->Mat->pos), + &ent->vel, 1); } numDepens++; @@ -444,42 +437,32 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) { if (ent->basset->flags & 1) { - xVec3AddTo(&depen, (xVec3 *)(&ent->collis->colls[i].depen)); + xVec3AddTo(&depen, (xVec3*)(&ent->collis->colls[i].depen)); } else { uVar19 = xVec3Dot(&ent->collis->colls[i].norm, &ent->collis->colls[i].depen); - if - ( - (ent == globals.player.bubblebowl) && + if ((ent == globals.player.bubblebowl) && (xVec3Dot(&ent->collis->colls[i].norm, &velNorm) < -0.70710676f) && - (ent->timeToLive > 0.05f) - ) + (ent->timeToLive > 0.05f)) { ent->timeToLive = 0.05f; } xVec3AddScaled(&depen, &ent->collis->colls[i].norm, uVar19); } - boul = (xEntBoulder *)(ent->collis->colls[i].optr); + boul = (xEntBoulder*)(ent->collis->colls[i].optr); if ((ent->basset->flags & 4) && (boul->baseType == eBaseTypeDestructObj)) { - if - ( - (zEntDestructObj_GetHit((zEntDestructObj*)boul, 0x8000)) && - (ent == globals.player.bubblebowl) && - (ent->timeToLive > 0.05f)) + if ((zEntDestructObj_GetHit((zEntDestructObj*)boul, 0x8000)) && + (ent == globals.player.bubblebowl) && (ent->timeToLive > 0.05f)) { ent->timeToLive = 0.05f; } zEntDestructObj_Hit((zEntDestructObj*)boul, 0x8000); } - else if - ( - (ent == globals.player.bubblebowl) && - (boul->moreFlags & 0x10) && - (boul->baseType != eBaseTypeBoulder || (boul->basset->flags & 0x100)) - ) + else if ((ent == globals.player.bubblebowl) && (boul->moreFlags & 0x10) && + (boul->baseType != eBaseTypeBoulder || (boul->basset->flags & 0x100))) { zEntEvent(ent, boul, eEventHit_BubbleBowl); zEntEvent(ent, boul, eEventHit); @@ -498,16 +481,13 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) npc = (zNPCCommon*)(ent->collis->colls[iter_npc].optr); if (ent->basset->flags & 1) { - xVec3AddTo(&depen, (xVec3 *)(&ent->collis->colls[iter_npc].depen)); + xVec3AddTo(&depen, (xVec3*)(&ent->collis->colls[iter_npc].depen)); } else { - uVar19 = xVec3Dot(&ent->collis->colls[iter_npc].norm, &ent->collis->colls[iter_npc].depen); - if - ( - (ent != globals.player.bubblebowl) || - (npc->SelfType() & ~0xFF) != 'NTT\0' - ) + uVar19 = xVec3Dot(&ent->collis->colls[iter_npc].norm, + &ent->collis->colls[iter_npc].depen); + if ((ent != globals.player.bubblebowl) || (npc->SelfType() & ~0xFF) != 'NTT\0') { xVec3AddScaled(&depen, &ent->collis->colls[iter_npc].norm, uVar19); } @@ -516,17 +496,16 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) if (ent->basset->flags & 8) { zEntEvent(ent, npc, eEventHit, 0); - zEntPlayer_SNDPlayStreamRandom(0x00, 0x10, ePlayerStreamSnd_BowlComment1, ePlayerStreamSnd_BowlComment3, 0.1f); - zEntPlayer_SNDPlayStreamRandom(0x10, 0x23, ePlayerStreamSnd_BowlComment1, ePlayerStreamSnd_BowlComment4, 0.1f); - zEntPlayer_SNDPlayStreamRandom(0x24, 0x64, ePlayerStreamSnd_BowlComment1, ePlayerStreamSnd_BowlComment5, 0.1f); - if - ( - (ent == globals.player.bubblebowl) && - ( - ((npc->SelfType() & ~0xFF) != 'NTT\0') || - (npc->SelfType() == NPC_TYPE_TIKI_STONE)) && - (ent->timeToLive > 0.05f) - ) + zEntPlayer_SNDPlayStreamRandom(0x00, 0x10, ePlayerStreamSnd_BowlComment1, + ePlayerStreamSnd_BowlComment3, 0.1f); + zEntPlayer_SNDPlayStreamRandom(0x10, 0x23, ePlayerStreamSnd_BowlComment1, + ePlayerStreamSnd_BowlComment4, 0.1f); + zEntPlayer_SNDPlayStreamRandom(0x24, 0x64, ePlayerStreamSnd_BowlComment1, + ePlayerStreamSnd_BowlComment5, 0.1f); + if ((ent == globals.player.bubblebowl) && + (((npc->SelfType() & ~0xFF) != 'NTT\0') || + (npc->SelfType() == NPC_TYPE_TIKI_STONE)) && + (ent->timeToLive > 0.05f)) { ent->timeToLive = 0.05f; } @@ -599,7 +578,8 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) else { F32 div = xVec3Length(&ent->vel) / ent->bound.sph.r; - ent->angVel = ((1.0f - ent->basset->stickiness) * ent->angVel) + (ent->basset->stickiness * div); + ent->angVel = + ((1.0f - ent->basset->stickiness) * ent->angVel) + (ent->basset->stickiness * div); } } @@ -617,7 +597,7 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) xMat3x3Mul((xMat3x3*)ent->model->Mat, (xMat3x3*)ent->model->Mat, &rotM); } - xMat3x3RMulVec(&newRotVec, (xMat3x3 *)(ent->model->Mat), &ent->localCenter); + xMat3x3RMulVec(&newRotVec, (xMat3x3*)(ent->model->Mat), &ent->localCenter); xVec3Sub((xVec3*)&ent->model->Mat->pos, &ent->bound.sph.center, &newRotVec); if ((ent->basset->soundID != 0) && (numDepens != 0) && (ent->lastRolling > 0.25f)) { @@ -635,19 +615,8 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) vol *= (ent->basset->volume * 0.77f); - xSndPlay3D - ( - ent->basset->soundID, - vol, - 0.0f, - 0, - 0, - (xVec3*)&ent->model->Mat->pos, - ent->basset->innerRadius, - ent->basset->outerRadius, - SND_CAT_GAME, - 0.0f - ); + xSndPlay3D(ent->basset->soundID, vol, 0.0f, 0, 0, (xVec3*)&ent->model->Mat->pos, + ent->basset->innerRadius, ent->basset->outerRadius, SND_CAT_GAME, 0.0f); } } @@ -655,18 +624,8 @@ void xEntBoulder_Update(xEntBoulder* ent, xScene* sc, F32 dt) { vol = 0.77f; - xSndPlay3D - ( - ent->rollingID, - vol, - 0.0f, - 0, - 0, - (xVec3 *)(&ent->model->Mat->pos), - 20.0f, - SND_CAT_GAME, - 0.0f - ); + xSndPlay3D(ent->rollingID, vol, 0.0f, 0, 0, (xVec3*)(&ent->model->Mat->pos), 20.0f, + SND_CAT_GAME, 0.0f); } if (numDepens != 0) @@ -706,9 +665,11 @@ S32 xEntBoulder_KilledBySurface(xEntBoulder* ent, xScene* sc, F32 dt) continue; } - if ((ent->basset->flags & 0x40) && (coll->optr != NULL) && (zGooIs((xEnt*)coll->optr, temp, 0))) + if ((ent->basset->flags & 0x40) && (coll->optr != NULL) && + (zGooIs((xEnt*)coll->optr, temp, 0))) { - xVec3AddScaled(&ent->vel, &coll->norm, -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); + xVec3AddScaled(&ent->vel, &coll->norm, + -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); zEntEvent(ent, eEventKill); return 1; } @@ -729,32 +690,36 @@ S32 xEntBoulder_KilledBySurface(xEntBoulder* ent, xScene* sc, F32 dt) { switch (prop->asset->game_damage_type) { - case 0: - break; - case 1: - case 2: - case 3: - case 4: - case 6: - ent->hitpoints--; - if (ent->hitpoints <= 0) - { - xVec3AddScaled(&ent->vel, &coll->norm, -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); - zEntEvent(ent, eEventKill); - return 1; - } - break; - case 5: - xVec3AddScaled(&ent->vel, &coll->norm, -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); - zEntEvent((xBase *)ent, eEventKill); + case 0: + break; + case 1: + case 2: + case 3: + case 4: + case 6: + ent->hitpoints--; + if (ent->hitpoints <= 0) + { + xVec3AddScaled(&ent->vel, &coll->norm, + -(ent->basset->bounce + 1.0f) * + xVec3Dot(&ent->vel, &coll->norm)); + zEntEvent(ent, eEventKill); return 1; + } + break; + case 5: + xVec3AddScaled(&ent->vel, &coll->norm, + -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); + zEntEvent((xBase*)ent, eEventKill); + return 1; } } if ((ent->basset->flags & 0x20) && (prop->asset->phys_flags & 0x10)) { - xVec3AddScaled(&ent->vel, &coll->norm, -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); - zEntEvent((xBase *)ent, eEventKill); + xVec3AddScaled(&ent->vel, &coll->norm, + -(ent->basset->bounce + 1.0f) * xVec3Dot(&ent->vel, &coll->norm)); + zEntEvent((xBase*)ent, eEventKill); return 1; } } @@ -804,19 +769,25 @@ void xEntBoulder_BubbleBowl(F32 multiplier) } xVec3Copy((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->pos); - xVec3AddScaled((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->right, globals.player.g.BubbleBowlLaunchPosLeft); - xVec3AddScaled((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->up, globals.player.g.BubbleBowlLaunchPosUp); - xVec3AddScaled((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->at, globals.player.g.BubbleBowlLaunchPosAt); + xVec3AddScaled((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->right, + globals.player.g.BubbleBowlLaunchPosLeft); + xVec3AddScaled((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->up, + globals.player.g.BubbleBowlLaunchPosUp); + xVec3AddScaled((xVec3*)&ent->model->Mat->pos, (xVec3*)&globals.player.ent.model->Mat->at, + globals.player.g.BubbleBowlLaunchPosAt); xVec3Copy(&ent->bound.sph.center, (xVec3*)&ent->model->Mat->pos); xVec3Copy(&ent->frame->mat.pos, (xVec3*)&ent->model->Mat->pos); - xVec3SMul(&ent->vel, (xVec3 *)&globals.player.ent.model->Mat->right, globals.player.g.BubbleBowlLaunchVelLeft); - xVec3AddScaled(&ent->vel, (xVec3 *)&globals.player.ent.model->Mat->up, globals.player.g.BubbleBowlLaunchVelUp); - xVec3AddScaled(&ent->vel, (xVec3 *)&globals.player.ent.model->Mat->at, globals.player.g.BubbleBowlLaunchVelAt); + xVec3SMul(&ent->vel, (xVec3*)&globals.player.ent.model->Mat->right, + globals.player.g.BubbleBowlLaunchVelLeft); + xVec3AddScaled(&ent->vel, (xVec3*)&globals.player.ent.model->Mat->up, + globals.player.g.BubbleBowlLaunchVelUp); + xVec3AddScaled(&ent->vel, (xVec3*)&globals.player.ent.model->Mat->at, + globals.player.g.BubbleBowlLaunchVelAt); xVec3SMulBy(&ent->vel, multiplier); - xVec3Copy(&ent->rotVec, (xVec3 *)globals.player.ent.model->Mat); + xVec3Copy(&ent->rotVec, (xVec3*)globals.player.ent.model->Mat); ent->angVel = (multiplier * 10.0f); - xVec3Copy(&ray.origin, (xVec3 *)&globals.player.ent.bound.sph.center); - xVec3Sub(&ray.dir, (xVec3 *)&ent->model->Mat->pos, &ray.origin); + xVec3Copy(&ray.origin, (xVec3*)&globals.player.ent.bound.sph.center); + xVec3Sub(&ray.dir, (xVec3*)&ent->model->Mat->pos, &ray.origin); ray.max_t = xVec3Normalize(&ray.dir, &ray.dir); ray.min_t = 0.01f + globals.player.ent.bound.box.box.upper.x; ray.flags = 0xc00; @@ -825,13 +796,11 @@ void xEntBoulder_BubbleBowl(F32 multiplier) if (rayCollis.flags & 1) { optr = (xEnt*)(rayCollis.optr); - if - ((optr == NULL) || - ((((optr->baseType == eBaseTypeDestructObj) && (zEntDestructObj_GetHit((zEntDestructObj*)optr, 0x8000) == 0)) || - !(optr->moreFlags & 0x10) || (optr->baseType == eBaseTypeStatic)) - ) && - (optr->baseType != eBaseTypeNPC) - ) + if ((optr == NULL) || + ((((optr->baseType == eBaseTypeDestructObj) && + (zEntDestructObj_GetHit((zEntDestructObj*)optr, 0x8000) == 0)) || + !(optr->moreFlags & 0x10) || (optr->baseType == eBaseTypeStatic))) && + (optr->baseType != eBaseTypeNPC)) { if ((optr != NULL) && (optr->collLev == 5)) { @@ -885,10 +854,10 @@ void xEntBoulder_Reset(xEntBoulder* boul, xScene* sc) boul->flags |= 0x10; } - xVec3Init(&boul->force, 0.0f, 0.0f, 0.0f); + xVec3Init(&boul->force, 0.0f, 0.0f, 0.0f); xVec3Init(&boul->instForce, 0.0f, 0.0f, 0.0f); - xVec3Init(&boul->vel, 0.0f, 0.0f, 0.0f); - xVec3Init(&boul->rotVec, 1.0f, 0.0f, 0.0f); + xVec3Init(&boul->vel, 0.0f, 0.0f, 0.0f); + xVec3Init(&boul->rotVec, 1.0f, 0.0f, 0.0f); boul->angVel = 0.0f; @@ -902,7 +871,7 @@ void xEntBoulder_Reset(xEntBoulder* boul, xScene* sc) } boul->hitpoints = boul->basset->hitpoints; - xEntBoulder_RealBUpdate(boul, (xVec3 *)&boul->model->Mat->pos); + xEntBoulder_RealBUpdate(boul, (xVec3*)&boul->model->Mat->pos); if ((globals.sceneCur->sceneID == 'BC04') && (boul->id == xStrHash("BALL_BOULDER"))) { @@ -910,6 +879,177 @@ void xEntBoulder_Reset(xEntBoulder* boul, xScene* sc) } } +S32 xEntBoulderEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget) +{ + xEntBoulder* s = (xEntBoulder*)to; + + switch (toEvent) + { + case eEventVisible: + case eEventFastVisible: + xEntShow(s); + if (toParam && (S32)(0.5f + toParam[0]) == 77) + { + zFXPopOn(*s, toParam[1], toParam[2]); + } + break; + case eEventInvisible: + case eEventFastInvisible: + xEntHide(s); + if (toParam && (S32)(0.5f + toParam[0]) == 77) + { + zFXPopOff(*s, toParam[1], toParam[2]); + } + break; + case eEventCollisionOn: + s->chkby |= XENT_COLLTYPE_PLYR; + break; + case eEventCollisionOff: + s->chkby &= (U8)~XENT_COLLTYPE_PLYR; + break; + case eEventCollision_Visible_On: + s->chkby |= XENT_COLLTYPE_PLYR; + xEntShow(s); + if (toParam && (S32)(0.5f + toParam[0]) == 77) + { + zFXPopOn(*s, toParam[1], toParam[2]); + } + break; + case eEventCollision_Visible_Off: + s->chkby &= (U8)~XENT_COLLTYPE_PLYR; + xEntHide(s); + if (toParam && (S32)(0.5f + toParam[0]) == 77) + { + zFXPopOff(*s, toParam[1], toParam[2]); + } + break; + case eEventCameraCollideOn: + zCollGeom_CamEnable(s); + break; + case eEventCameraCollideOff: + zCollGeom_CamDisable(s); + break; + case eEventReset: + xEntBoulder_Reset(s, globals.sceneCur); + if (xEntIsVisible(s)) + { + s->update = (xEntUpdateCallback)xEntBoulder_Update; + } + break; + case eEventHit: + if (s->update) + { + s->hitpoints--; + if (s->hitpoints <= 0) + { + zEntEvent(s, eEventKill); + } + } + break; + case eEventKill: + xEntBoulder_Kill(s); + if (s == globals.player.bubblebowl) + { + zFX_SpawnBubbleHit(&s->bound.sph.center, xrand() % 64 + 36); + } + break; + case eEventSetUpdateDistance: + if (globals.updateMgr) + { + if (toParam[0] <= 0.0f) + { + xUpdateCull_SetCB(globals.updateMgr, s, xUpdateCull_AlwaysTrueCB, NULL); + } + else + { + FloatAndVoid dist; + dist.f = SQR(toParam[0]); + xUpdateCull_SetCB(globals.updateMgr, s, xUpdateCull_DistanceSquaredCB, dist.v); + } + } + break; + case eEventLaunchShrapnel: + if (toParamWidget) + { + zShrapnelAsset* shrap = (zShrapnelAsset*)toParamWidget; + if (shrap->initCB) + { + shrap->initCB(shrap, s->model, &s->vel, NULL); + } + } + break; + case eEventSetLightKit: + s->lightKit = (xLightKit*)toParamWidget; + break; + } + + return 1; +} + +static S32 RecurseLinks(xLinkAsset* link, S32 count, xEntBoulder** boulList) +{ + S32 i; + S32 numInList = 0; + + for (i = 0; i < count; i++) + { + xLinkAsset* currLink = &link[i]; + if (currLink->dstEvent == eEventConnectToChild) + { + xBase* mychild = zSceneFindObject(currLink->dstAssetID); + if (mychild) + { + RecurseChild(mychild, boulList, numInList); + } + } + } + + return numInList; +} + +static void RecurseChild(xBase* child, xEntBoulder** boulList, S32& currBoul) +{ + switch (child->baseType) + { + case eBaseTypeBoulder: + if (boulList) + { + boulList[currBoul] = (xEntBoulder*)child; + } + currBoul++; + break; + case eBaseTypeGroup: + { + S32 i, cnt; + xGroup* grp = (xGroup*)child; + + cnt = xGroupGetCount(grp); + for (i = 0; i < cnt; i++) + { + xBase* grpitem = xGroupGetItemPtr(grp, i); + if (grpitem) + { + if (grpitem->baseType == eBaseTypeBoulder) + { + if (boulList) + { + boulList[currBoul] = (xEntBoulder*)grpitem; + } + currBoul++; + } + else if (grpitem->baseType == eBaseTypeGroup) + { + RecurseChild(grpitem, boulList, currBoul); + } + } + } + + break; + } + } +} + void xBoulderGenerator_Init(xBase& data, xDynAsset& asset, unsigned long) { xBoulderGenerator_Init((xBoulderGenerator*)&data, (xBoulderGeneratorAsset*)&asset); @@ -943,12 +1083,14 @@ void xBoulderGenerator_Init(xBoulderGenerator* bg, xBoulderGeneratorAsset* asset else { bg->isMarker = 0; - bg->objectPtr = (void *)zSceneFindObject(asset->object); + bg->objectPtr = (void*)zSceneFindObject(asset->object); } bg->numBoulders = RecurseLinks(bg->link, bg->linkCount, 0); bg->nextBoulder = bg->numBoulders; - bg->boulderList = (xEntBoulder **)xMemAlloc(gActiveHeap, (bg->numBoulders * sizeof(xEntBoulder*)) + (bg->numBoulders * sizeof(xEntBoulder*)), 0); + bg->boulderList = (xEntBoulder**)xMemAlloc( + gActiveHeap, + (bg->numBoulders * sizeof(xEntBoulder*)) + (bg->numBoulders * sizeof(xEntBoulder*)), 0); bg->boulderAges = (S32*)(&bg->boulderList[bg->numBoulders]); RecurseLinks(bg->link, bg->linkCount, bg->boulderList); @@ -1018,12 +1160,14 @@ static S32 GetBoulderForGenerating(xBoulderGenerator* bg) } else if (bg->boulderList[oldestCulled]->isCulled) { - if (bg->boulderList[j]->isCulled && (bg->boulderAges[oldestCulled] < bg->boulderAges[j])) + if (bg->boulderList[j]->isCulled && + (bg->boulderAges[oldestCulled] < bg->boulderAges[j])) { oldestCulled = j; } } - else if (bg->boulderList[j]->isCulled || (bg->boulderAges[oldestCulled] < bg->boulderAges[j])) + else if (bg->boulderList[j]->isCulled || + (bg->boulderAges[oldestCulled] < bg->boulderAges[j])) { oldestCulled = j; } @@ -1067,13 +1211,14 @@ void xBoulderGenerator_Launch(xBoulderGenerator* bg, xVec3* pnt, F32 t) b->update = (xEntUpdateCallback)xEntBoulder_Update; if (bg->isMarker) { - xVec3Copy((xVec3 *)(&b->model->Mat->pos), &((xMarkerAsset *)(bg->objectPtr))->pos); + xVec3Copy((xVec3*)(&b->model->Mat->pos), &((xMarkerAsset*)(bg->objectPtr))->pos); } else { - xVec3Copy((xVec3 *)(&b->model->Mat->pos), (xVec3 *)(&((xEnt *)(bg->objectPtr))->model->Mat->pos)); + xVec3Copy((xVec3*)(&b->model->Mat->pos), + (xVec3*)(&((xEnt*)(bg->objectPtr))->model->Mat->pos)); } - xVec3AddTo((xVec3 *)(&b->model->Mat->pos), &bg->bgasset->offset); + xVec3AddTo((xVec3*)(&b->model->Mat->pos), &bg->bgasset->offset); xVec3Copy(&b->rotVec, &bg->bgasset->initaxis); b->angVel = bg->bgasset->angvel; } @@ -1087,125 +1232,78 @@ void xBoulderGenerator_Launch(xBoulderGenerator* bg, xVec3* pnt, F32 t) void xBoulderGenerator_GenBoulder(xBoulderGenerator*); -S32 xBoulderGenerator_EventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget) +S32 xBoulderGenerator_EventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, + xBase* toParamWidget) { xVec3 pnt; switch (toEvent) { - case eEventGenerateBoulder: - xBoulderGenerator_GenBoulder((xBoulderGenerator*)to); - break; - case eEventLaunchBoulderAtWidget: - switch(toParamWidget->baseType) - { - case eBaseTypeVillain: - case eBaseTypePlayer: - case eBaseTypePickup: - case eBaseTypePlatform: - case eBaseTypeDoor: - case eBaseTypeStatic: - case eBaseTypeDynamic: - case eBaseTypePendulum: - case eBaseTypeHangable: - case eBaseTypeButton: - case eBaseTypeDestructObj: - case eBaseTypeNPC: - case eBaseTypeBoulder: - { - xVec3Copy(&pnt, (xVec3 *)xEntGetPos((xEnt*)toParamWidget)); - - F32 f0 = 0.0f; - F32 f1 = toParam[1]; - F32 f2; - F32 f3; + case eEventGenerateBoulder: + xBoulderGenerator_GenBoulder((xBoulderGenerator*)to); + break; + case eEventLaunchBoulderAtWidget: + switch (toParamWidget->baseType) + { + case eBaseTypeVillain: + case eBaseTypePlayer: + case eBaseTypePickup: + case eBaseTypePlatform: + case eBaseTypeDoor: + case eBaseTypeStatic: + case eBaseTypeDynamic: + case eBaseTypePendulum: + case eBaseTypeHangable: + case eBaseTypeButton: + case eBaseTypeDestructObj: + case eBaseTypeNPC: + case eBaseTypeBoulder: + { + xVec3Copy(&pnt, (xVec3*)xEntGetPos((xEnt*)toParamWidget)); - if (f1 != f0) - { - f1 = xurand(); - f0 = 0.5f; - f2 = 2.0f; - f3 = f1 - f0; - f1 = toParam[1]; - f0 = pnt.x; - f2 *= f3; - pnt.x = (f1 * f2) + f0; - - f1 = xurand(); - f0 = 0.5f; - f2 = 2.0f; - f3 = f1 - f0; - f1 = toParam[1]; - f2 *= f3; - pnt.y = (f1 * f2) + pnt.y; - - f1 = xurand(); - f0 = 0.5f; - f2 = 2.0f; - f3 = f1 - f0; - f1 = toParam[1]; - f0 = pnt.z; - f2 *= f3; - pnt.z = (f1 * f2) + f0; - } + F32 f0 = 0.0f; + F32 f1 = toParam[1]; + F32 f2; + F32 f3; - xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, *toParam); - break; - } - case eBaseTypeMovePoint: - { - xVec3Copy(&pnt, (xVec3 *)zMovePointGetPos((zMovePoint*)toParamWidget)); + if (f1 != f0) + { + f1 = xurand(); + f0 = 0.5f; + f2 = 2.0f; + f3 = f1 - f0; + f1 = toParam[1]; + f0 = pnt.x; + f2 *= f3; + pnt.x = (f1 * f2) + f0; - F32 f0 = 0.0f; - F32 f1 = toParam[1]; - F32 f2; - F32 f3; + f1 = xurand(); + f0 = 0.5f; + f2 = 2.0f; + f3 = f1 - f0; + f1 = toParam[1]; + f2 *= f3; + pnt.y = (f1 * f2) + pnt.y; - if (f1 != f0) - { - f1 = xurand(); - f2 = 2.0f; - f3 = f1 - 0.5f; - f1 = toParam[1]; - f0 = pnt.x; - f2 *= f3; - pnt.x = (f1 * f2) + f0; - - f1 = xurand(); - f0 = 0.5f; - f2 = 2.0f; - f3 = f1 - f0; - f1 = toParam[1]; - f2 *= f3; - pnt.y = (f1 * f2) + pnt.y; - - f1 = xurand(); - f0 = 0.5f; - f2 = 2.0f; - f3 = f1 - f0; - f1 = toParam[1]; - f0 = pnt.z; - f2 *= f3; - pnt.z = (f1 * f2) + f0; - } - xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, *toParam); - break; - } + f1 = xurand(); + f0 = 0.5f; + f2 = 2.0f; + f3 = f1 - f0; + f1 = toParam[1]; + f0 = pnt.z; + f2 *= f3; + pnt.z = (f1 * f2) + f0; } + + xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, *toParam); break; - case eEventLaunchBoulderAtPoint: - pnt.x = toParam[0]; - pnt.y = toParam[1]; - pnt.z = toParam[2]; - xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, toParam[3]); - break; - case eEventLaunchBoulderAtPlayer: + } + case eBaseTypeMovePoint: { - xVec3Copy(&pnt, (xVec3 *)&(globals.player.ent.model)->Mat->pos); - xVec3AddScaled(&pnt, &globals.player.ent.frame->dpos, ((*toParam * toParam[1]) / globals.update_dt)); + xVec3Copy(&pnt, (xVec3*)zMovePointGetPos((zMovePoint*)toParamWidget)); F32 f0 = 0.0f; - F32 f1 = toParam[2]; + F32 f1 = toParam[1]; F32 f2; F32 f3; @@ -1214,30 +1312,186 @@ S32 xBoulderGenerator_EventCB(xBase* from, xBase* to, U32 toEvent, const F32* to f1 = xurand(); f2 = 2.0f; f3 = f1 - 0.5f; - f1 = toParam[2]; + f1 = toParam[1]; + f0 = pnt.x; f2 *= f3; - pnt.x = (f1 * f2) + pnt.x; + pnt.x = (f1 * f2) + f0; f1 = xurand(); + f0 = 0.5f; f2 = 2.0f; - f3 = f1 - 0.5f; + f3 = f1 - f0; + f1 = toParam[1]; f2 *= f3; - pnt.y = (toParam[2] * f2) + pnt.y; + pnt.y = (f1 * f2) + pnt.y; f1 = xurand(); + f0 = 0.5f; f2 = 2.0f; - f3 = f1 - 0.5f; - f1 = toParam[2]; + f3 = f1 - f0; + f1 = toParam[1]; + f0 = pnt.z; f2 *= f3; - pnt.z += (f1 * f2); + pnt.z = (f1 * f2) + f0; } - xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, *toParam); break; } - case eEventReset: - xBoulderGenerator_Reset((xBoulderGenerator*)to); - break; + } + break; + case eEventLaunchBoulderAtPoint: + pnt.x = toParam[0]; + pnt.y = toParam[1]; + pnt.z = toParam[2]; + xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, toParam[3]); + break; + case eEventLaunchBoulderAtPlayer: + { + xVec3Copy(&pnt, (xVec3*)&(globals.player.ent.model)->Mat->pos); + xVec3AddScaled(&pnt, &globals.player.ent.frame->dpos, + ((*toParam * toParam[1]) / globals.update_dt)); + + F32 f0 = 0.0f; + F32 f1 = toParam[2]; + F32 f2; + F32 f3; + + if (f1 != f0) + { + f1 = xurand(); + f2 = 2.0f; + f3 = f1 - 0.5f; + f1 = toParam[2]; + f2 *= f3; + pnt.x = (f1 * f2) + pnt.x; + + f1 = xurand(); + f2 = 2.0f; + f3 = f1 - 0.5f; + f2 *= f3; + pnt.y = (toParam[2] * f2) + pnt.y; + + f1 = xurand(); + f2 = 2.0f; + f3 = f1 - 0.5f; + f1 = toParam[2]; + f2 *= f3; + pnt.z += (f1 * f2); + } + + xBoulderGenerator_Launch((xBoulderGenerator*)to, &pnt, *toParam); + break; + } + case eEventReset: + xBoulderGenerator_Reset((xBoulderGenerator*)to); + break; } return 1; -} \ No newline at end of file +} + +void xBoulderGenerator_GenBoulder(xBoulderGenerator* bg) +{ + S32 i = GetBoulderForGenerating(bg); + xEntBoulder* b = bg->boulderList[i]; + + if (bg->objectPtr == globals.player.bubblebowl) + { + xEntBoulder_Reset(b, globals.sceneCur); + zEntEvent(b, eEventBorn); + + b->update = (xEntUpdateCallback)xEntBoulder_Update; + + xEntBoulder* bb = globals.player.bubblebowl; + + xVec3Copy((xVec3*)&b->model->Mat->pos, (xVec3*)&bb->model->Mat->pos); + xVec3Copy(&b->rotVec, &bb->rotVec); + b->angVel = bb->angVel; + xVec3Copy(&b->vel, &bb->vel); + + xEntBoulder_Kill(bb); + } + else + { + if (b != bg->objectPtr || !xEntIsVisible(b)) + { + xEntBoulder_Reset(b, globals.sceneCur); + zEntEvent(b, eEventBorn); + + b->update = (xEntUpdateCallback)xEntBoulder_Update; + + if (bg->isMarker) + { + xVec3Copy((xVec3*)&b->model->Mat->pos, &((xMarkerAsset*)bg->objectPtr)->pos); + } + else + { + xVec3Copy((xVec3*)&b->model->Mat->pos, + (xVec3*)&((xEnt*)bg->objectPtr)->model->Mat->pos); + } + + xVec3AddTo((xVec3*)&b->model->Mat->pos, &bg->bgasset->offset); + + if (bg->bgasset->offsetRand) + { + b->model->Mat->pos.x += 2.0f * (xurand() - 0.5f) * bg->bgasset->offsetRand; + b->model->Mat->pos.y += 2.0f * (xurand() - 0.5f) * bg->bgasset->offsetRand; + b->model->Mat->pos.z += 2.0f * (xurand() - 0.5f) * bg->bgasset->offsetRand; + } + + xVec3Copy(&b->rotVec, &bg->bgasset->initaxis); + + b->angVel = bg->bgasset->angvel; + } + + if (bg->lengthOfInitVel > 0.00001f && bg->bgasset->velAngleRand > 0.00001f) + { + F32 p1c = xurand() - 0.5f; + F32 p2c = xurand() - 0.5f; + F32 nf = 1.0f / xsqrt(SQR(p1c) + SQR(p2c)); + if (nf < 0.00001f) + { + p1c = 1.0f; + p2c = 0.0f; + } + else + { + p1c *= nf; + p2c *= nf; + } + + xVec3 perpRand; + xVec3SMul(&perpRand, &bg->perp1, p1c); + xVec3AddScaled(&perpRand, &bg->perp2, p2c); + + F32 randAng = bg->bgasset->velAngleRand * (xurand() - 0.5f); + randAng = DEG2RAD(randAng); + + p1c = icos(randAng); + p2c = isin(randAng); + + xVec3SMul(&b->vel, &bg->bgasset->initvel, p1c); + xVec3AddScaled(&b->vel, &perpRand, p2c); + } + else + { + xVec3Copy(&b->vel, &bg->bgasset->initvel); + } + + if (bg->bgasset->velMagRand > 0.00001f) + { + if (bg->lengthOfInitVel > 0.00001f) + { + F32 sclMag = bg->bgasset->velMagRand * xurand() + 1.0f; + xVec3SMulBy(&b->vel, sclMag); + } + else + { + b->vel.x = 2.0f * (xurand() - 0.5f) * bg->bgasset->velMagRand; + b->vel.y = 2.0f * (xurand() - 0.5f) * bg->bgasset->velMagRand; + b->vel.z = 2.0f * (xurand() - 0.5f) * bg->bgasset->velMagRand; + } + } + } + + BoulderGen_GiveBirth(bg, i); +} From 7f0df5254bbb702b2ea70e177d11fc18c67505c8 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sun, 30 Nov 2025 07:52:20 -0500 Subject: [PATCH 4/4] removed all decomp.me scratches from repo --- src/SB/Core/gc/iModel.cpp | 10 ---------- src/SB/Core/x/xCamera.cpp | 2 -- src/SB/Core/x/xCollide.cpp | 8 -------- src/SB/Core/x/xEntMotion.cpp | 1 - src/SB/Core/x/xGrid.cpp | 1 - src/SB/Core/x/xGrid.h | 2 -- src/SB/Core/x/xScene.cpp | 5 ----- src/SB/Core/x/xserializer.cpp | 1 - src/SB/Game/zNPCSupport.cpp | 16 +++++----------- src/SB/Game/zNPCTypeCommon.cpp | 29 +++++++++++++---------------- 10 files changed, 18 insertions(+), 57 deletions(-) diff --git a/src/SB/Core/gc/iModel.cpp b/src/SB/Core/gc/iModel.cpp index 6fd4b05e6..e8f15677d 100644 --- a/src/SB/Core/gc/iModel.cpp +++ b/src/SB/Core/gc/iModel.cpp @@ -226,7 +226,6 @@ S32 iModelSphereCull(xSphere* sphere) // Very nonmatching S32 iModelCullPlusShadow(RpAtomic* model, RwMatrix* mat, xVec3* shadowVec, S32* shadowOutside) -//NONMATCH("https://decomp.me/scratch/nx6io") { F32 xScale2, yScale2, zScale2; RwV3d *right, *up, *at; @@ -437,7 +436,6 @@ U32 iModelVertCount(RpAtomic* model) static inline void SkinXform(xVec3* dest, const xVec3* vert, RwMatrix* mat, const RwMatrix* skinmat, const F32* wt, const U32* idx, U32 count) -// NONMATCH("https://decomp.me/scratch/8dnNK") { U32 catMatFlags[2] = { 0, 0 }; RwMatrix* catmat = (RwMatrix*)giAnimScratch; @@ -534,7 +532,6 @@ U32 iModelVertEval(RpAtomic* model, U32 index, U32 count, RwMatrix* mat, xVec3* static inline void SkinNormals(xVec3* dest, const xVec3* normal, const RwMatrix* mat, const RwMatrix* skinmat, const F32* wt, const U32* idx, U32 count) -//NONMATCH("https://decomp.me/scratch/WTMKS") { U32 catMatFlags[2] = { 0, 0 }; RwMatrix* catmat = (RwMatrix*)giAnimScratch; @@ -715,7 +712,6 @@ static U32 iModelTagUserData(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 static U32 iModelTagInternal(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z, S32 closeV) -//NONMATCH("https://decomp.me/scratch/NgdD8") { // RpGeometry* geom; // RwV3d* vert; @@ -804,7 +800,6 @@ U32 iModelTagSetup(xModelTagWithNormal* tag, RpAtomic* model, F32 x, F32 y, F32 } void iModelTagEval(RpAtomic* model, const xModelTag* tag, RwMatrix* mat, xVec3* dest) -//NONMATCH("https://decomp.me/scratch/L7pKU") { if (tag->wt[0]) { @@ -851,7 +846,6 @@ static RpMaterial* iModelSetMaterialAlphaCB(RpMaterial* material, void* data) // TODO: another thing that needs fixed after RW gets implemented void iModelSetMaterialAlpha(RpAtomic* model, U8 alpha) -// NONMATCH("https://decomp.me/scratch/Oyo8b") { // RpGeometry* geom = RpAtomicGetGeometry(model); @@ -871,7 +865,6 @@ void iModelSetMaterialAlpha(RpAtomic* model, U8 alpha) } static RpMaterial* iModelResetMaterialCB(RpMaterial* material, void* data) -// NONMATCH("https://decomp.me/scratch/eBpxV") { if ((sMaterialFlags & 0x3) == 0x3) { @@ -948,7 +941,6 @@ void iModelSetMaterialTexture(RpAtomic* model, void* texture) namespace { inline void U8_COLOR_CLAMP(U8& destu8, F32 srcf32) - //NONMATCH("https://decomp.me/scratch/dl7BD") { if (srcf32 < 0.0f) srcf32 = 0.0f; @@ -959,7 +951,6 @@ namespace } // namespace static RpMaterial* iModelMaterialMulCB(RpMaterial* material, void* data) -// NONMATCH("https://decomp.me/scratch/ig80z") { const RwRGBA* rw_col = RpMaterialGetColor(material); RwRGBA col = sMaterialColor[sMaterialIdx++] = *rw_col; @@ -982,7 +973,6 @@ static RpMaterial* iModelMaterialMulCB(RpMaterial* material, void* data) // TODO: once again, fix after RW implementation void iModelMaterialMul(RpAtomic* model, F32 rm, F32 gm, F32 bm) -// NONMATCH("https://decomp.me/scratch/zDCk9") { // RpGeometry* geom = RpAtomicGetGeometry(model); diff --git a/src/SB/Core/x/xCamera.cpp b/src/SB/Core/x/xCamera.cpp index ca929d706..e081f6c5b 100644 --- a/src/SB/Core/x/xCamera.cpp +++ b/src/SB/Core/x/xCamera.cpp @@ -470,7 +470,6 @@ void SweptSphereHitsCameraEnt(xScene*, xRay3* ray, xQCData* qcd, xEnt* ent, void } static void _xCameraUpdate(xCamera* cam, F32 dt) -// NONMATCH("https://decomp.me/scratch/2q6zO") { if (!cam->tgt_mat) return; @@ -1511,7 +1510,6 @@ void xBinaryCamera::stop() } void xBinaryCamera::update(F32 dt) -// NONMATCH("https://decomp.me/scratch/c9iST") { xVec3& A = camera->mat.pos; const xVec3& B = *s1; diff --git a/src/SB/Core/x/xCollide.cpp b/src/SB/Core/x/xCollide.cpp index df4a9496a..a14ea1f09 100644 --- a/src/SB/Core/x/xCollide.cpp +++ b/src/SB/Core/x/xCollide.cpp @@ -263,7 +263,6 @@ U32 xSphereHitsBox(const xSphere* a, const xBox* b, xCollis* coll) } U32 xSphereHitsOBB_nu(const xSphere* s, const xBox* b, const xMat4x3* m, xCollis* coll) -//NONMATCH("https://decomp.me/scratch/YoEeE") { xSphere xfs; xVec3 scale; @@ -325,7 +324,6 @@ static RpCollisionTriangle* sphereHitsModelCB(RpIntersection* isx, RpCollisionTr } U32 xSphereHitsModel(const xSphere* b, const xModelInstance* m, xCollis* coll) -// NONMATCH("https://decomp.me/scratch/XU6BL") { RpIntersection isx; @@ -556,7 +554,6 @@ static S32 xParabolaEnvCB(xClumpCollBSPTriangle* triangles, void* data) } S32 xParabolaHitsEnv(xParabola* p, const xEnv* env, xCollis* colls) -//NONMATCH("https://decomp.me/scratch/Hli1c") { RwBBox xb; F32 tmp; @@ -1286,7 +1283,6 @@ RpCollBSPTree* _rpCollBSPTreeForAllCapsuleLeafNodeIntersections( } void xSweptSpherePrepare(xSweptSphere* sws, xVec3* start, xVec3* end, F32 radius) -//NONMATCH("https://decomp.me/scratch/5VJcM") { sws->start = *start; sws->end = *end; @@ -1393,7 +1389,6 @@ void xSweptSphereGetResults(xSweptSphere* sws) } S32 xSweptSphereToTriangle(xSweptSphere* sws, xVec3* v0, xVec3* v1, xVec3* v2) -//NONMATCH("https://decomp.me/scratch/MJ9KD") { S32 i; @@ -1652,7 +1647,6 @@ S32 xSweptSphereToSphere(xSweptSphere* sws, xSphere* sph) } S32 xSweptSphereToBox(xSweptSphere* sws, xBox* box, xMat4x3* mat) -//NONMATCH("https://decomp.me/scratch/97pAl") { S32 i; xMat4x3 tmpmat; @@ -2036,7 +2030,6 @@ S32 xSweptSphereToEnv(xSweptSphere* sws, xEnv* env) } static S32 SweptSphereModelCB(S32 numTriangles, S32 triOffset, void* data) -// NONMATCH("https://decomp.me/scratch/XMJhx") { SweptSphereCollParam* isData = (SweptSphereCollParam*)data; RpGeometry* geometry = isData->geometry; @@ -2066,7 +2059,6 @@ static S32 SweptSphereModelCB(S32 numTriangles, S32 triOffset, void* data) } S32 xSweptSphereToModel(xSweptSphere* sws, RpAtomic* model, RwMatrix* mat) -//NONMATCH("https://decomp.me/scratch/3R1PB") { if (!sws->dist) return 0; diff --git a/src/SB/Core/x/xEntMotion.cpp b/src/SB/Core/x/xEntMotion.cpp index 1a2ddecf3..ecd0cbe31 100644 --- a/src/SB/Core/x/xEntMotion.cpp +++ b/src/SB/Core/x/xEntMotion.cpp @@ -1242,7 +1242,6 @@ static void xEntMotionDebugWrite(const xEntMotion* xem) } static void xEntMotionDebugDraw(const xEntMotion* xem) -//NONMATCH("https://decomp.me/scratch/j2sCX") { if (xem->owner && xem->target) { diff --git a/src/SB/Core/x/xGrid.cpp b/src/SB/Core/x/xGrid.cpp index 9ff56f898..b83196b29 100644 --- a/src/SB/Core/x/xGrid.cpp +++ b/src/SB/Core/x/xGrid.cpp @@ -125,7 +125,6 @@ void xGridAdd(xGrid* grid, xGridBound* bound, S32 x, S32 z) } S32 xGridAdd(xGrid* grid, xEnt* ent) -//NONMATCH("https://decomp.me/scratch/5R7FZ") { xBound* bound; xVec3* center; diff --git a/src/SB/Core/x/xGrid.h b/src/SB/Core/x/xGrid.h index 0f0c543f9..ae8da34e0 100644 --- a/src/SB/Core/x/xGrid.h +++ b/src/SB/Core/x/xGrid.h @@ -185,8 +185,6 @@ struct grid_index }; inline grid_index get_grid_index(const xGrid& grid, F32 x, F32 z) - -//NONMATCH("https://decomp.me/scratch/pMa66") { grid_index index = { range_limit((U16)((x - grid.minx) * grid.inv_csizex), 0, grid.nx - 1), range_limit((U16)((z - grid.minz) * grid.inv_csizez), 0, diff --git a/src/SB/Core/x/xScene.cpp b/src/SB/Core/x/xScene.cpp index 785551bec..206f9c85c 100644 --- a/src/SB/Core/x/xScene.cpp +++ b/src/SB/Core/x/xScene.cpp @@ -179,7 +179,6 @@ void xSceneForAllNPCs(xScene* sc, xSceneEntCallback func, void* data) void xRayHitsGrid(xGrid* grid, xScene* sc, xRay3* r, xRayEntCallback rentcb, xQCData* qcr, void* data) -//NONMATCH("https://decomp.me/scratch/2kH6a") { xLine3 ln; xGridIterator it; @@ -658,7 +657,6 @@ cb_ray_hits_ent::cb_ray_hits_ent(const xRay3& ray, xCollis& coll, U8 chkby, U8 c } void xRayHitsSceneFlags(xScene* sc, xRay3* r, xCollis* coll, U8 collType, U8 chk) -//NONMATCH("https://decomp.me/scratch/ZJEEb") { coll->dist = HUGE; coll->flags = (coll->flags & ~k_HIT_IT) | k_HIT_0x100; @@ -745,7 +743,6 @@ void ProjectBox(xVec3* param_1, xBox* param_2, float* param_3, float* param_4) } static U32 Mgc_TriBoxTest(xVec3* apkTri, xBox* rkBox) -// NONMATCH("https://decomp.me/scratch/xYaVl") { F32 fMin0, fMax0, fMin1, fMax1; xVec3 kD, akE[3], baxis; @@ -840,7 +837,6 @@ static U32 Mgc_TriBoxTest(xVec3* apkTri, xBox* rkBox) static RpCollisionTriangle* nearestFloorCB(RpIntersection*, RpCollisionTriangle* collTriangle, RwReal, void* data) -//NONMATCH("https://decomp.me/scratch/0VY4M") { xNearFloorPoly* nfpoly = (xNearFloorPoly*)data; F32 currnear = nfpoly->neardist; @@ -1064,7 +1060,6 @@ static S32 gridNearestFloorCB(xEnt* ent, void* cbdata) } U32 xSceneNearestFloorPoly(xScene* sc, xNearFloorPoly* nfpoly, U8 collType, U8 chk) -//NONMATCH("https://decomp.me/scratch/yCzQV") { sNearestBound.type = XBOUND_TYPE_BOX; sNearestBound.box.box = nfpoly->box; diff --git a/src/SB/Core/x/xserializer.cpp b/src/SB/Core/x/xserializer.cpp index caa12a767..3fbe8d8d6 100644 --- a/src/SB/Core/x/xserializer.cpp +++ b/src/SB/Core/x/xserializer.cpp @@ -323,7 +323,6 @@ static void xSER_init_tables() } static void xSER_init_buffers(S32 count, st_SERIAL_PERCID_SIZE* sizeinfo) -//NONMATCH("https://decomp.me/scratch/uex0C") { st_XSERIAL_DATA_PRIV* xsd = &g_xserdata; S32 i = 0; diff --git a/src/SB/Game/zNPCSupport.cpp b/src/SB/Game/zNPCSupport.cpp index 5d4cc5c14..c40601158 100644 --- a/src/SB/Game/zNPCSupport.cpp +++ b/src/SB/Game/zNPCSupport.cpp @@ -253,7 +253,6 @@ void NPCTarget::TargetClear() } S32 NPCTarget::FindNearest(S32 flg_consider, xBase* skipme, xVec3* from, F32 dst_max) -//NONMATCH("https://decomp.me/scratch/wWBRW") { S32 found = 0; st_XORDEREDARRAY* npclist; @@ -378,7 +377,6 @@ S32 NPCTarget::IsDead() } // void NPCLaser::Render(xVec3* pos_src, xVec3* pos_tgt) -// //NONMATCH("https://decomp.me/scratch/lNgTd") // { // xVec3 var_70; // xVec3Copy(&var_70, pos_src); @@ -494,7 +492,6 @@ S32 NPCTarget::IsDead() // } // void NPCCone::RenderCone(xVec3* pos_tiptop, xVec3* pos_botcenter) -// //NONMATCH("https://decomp.me/scratch/G9pbs") // { // RwRGBA rgba_top = this->rgba_top; // RwRGBA rgba_bot = this->rgba_bot; @@ -645,7 +642,7 @@ void Firework::Update(F32 dt) this->tmr_remain = MAX(-1.0f, this->tmr_remain - dt); } -void Firework::FlyFlyFly(F32 dt) //NONMATCH("https://decomp.me/scratch/6hPC3") +void Firework::FlyFlyFly(F32 dt) { F32 pam_life = 1.0f - CLAMP(this->tmr_remain / this->tym_lifespan, 0.0f, 1.0f); if (pam_life < 0.75f) @@ -684,7 +681,7 @@ void NPCC_aimMiss(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_miss, } F32 NPCC_aimVary(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_vary, S32 flg_vary, - xVec3* pos_aimPoint) //NONMATCH("https://decomp.me/scratch/D1gIj") + xVec3* pos_aimPoint) { F32 dst_toFake = 0.0f; xVec3 dir_left = {}; @@ -769,8 +766,7 @@ F32 NPCC_aimVary(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_vary, S return (flg_vary & 0x4) ? f31 : mag_vary; } -S32 NPCC_chk_hitEnt(xEnt* tgt, xBound* bnd, - xCollis* collide) //NONMATCH("https://decomp.me/scratch/Bf1rk") +S32 NPCC_chk_hitEnt(xEnt* tgt, xBound* bnd, xCollis* collide) { S32 hittgt = 0; xCollis* colrec; @@ -881,8 +877,7 @@ RwRaster* NPCC_FindRWRaster(RwTexture* txtr) return NULL; } -void NPCC_GenSmooth(xVec3** pos_base, - xVec3** pos_mid) //WIP NONMATCH("https://decomp.me/scratch/1MplX") +void NPCC_GenSmooth(xVec3** pos_base, xVec3** pos_mid) { static F32 prepute[4][4]; static const F32 yews[4] = { 0.25f, 0.5f, 0.75f, 1.0f }; @@ -916,7 +911,7 @@ void NPCC_GenSmooth(xVec3** pos_base, } } -void zNPC_SNDInit() //NONMATCH("https://decomp.me/scratch/VlDh8") +void zNPC_SNDInit() { sNPCSndID[eNPCSnd_GloveAttack] = 0; sNPCSndID[eNPCSnd_SleepyAttack] = 0; @@ -1111,7 +1106,6 @@ void NPCC_xBoundBack(xBound* bnd) void NPCC_DstSq(const xVec3*, const xVec3*, xVec3*); S32 NPCC_HaveLOSToPos(xVec3* pos_src, xVec3* pos_tgt, F32 dst_max, xBase* tgt, xCollis* colCallers) -//NONMATCH("https://decomp.me/scratch/LyDtk") { S32 result; xRay3 ray = {}; diff --git a/src/SB/Game/zNPCTypeCommon.cpp b/src/SB/Game/zNPCTypeCommon.cpp index 39cabea94..0a8d65148 100644 --- a/src/SB/Game/zNPCTypeCommon.cpp +++ b/src/SB/Game/zNPCTypeCommon.cpp @@ -232,7 +232,7 @@ void zNPCCommon::Init(xEntAsset* entass) this->InitBounds(); } -void zNPCCommon::InitBounds() //NONMATCH("https://decomp.me/scratch/JPhdS") +void zNPCCommon::InitBounds() { NPCConfig* cfg = this->cfg_npc; xVec3 half = {}; @@ -422,7 +422,7 @@ void zNPCCommon::Setup() } } -void zNPCCommon::Reset() //NONMATCH("https://decomp.me/scratch/cl84A") +void zNPCCommon::Reset() { xSceneID2Name(globals.sceneCur, this->id); @@ -748,7 +748,7 @@ S32 zNPCCommon::NPCMessage(NPCMsg* mail) void zNPCCommon::Move(xScene* xscn, F32 dt, xEntFrame* frm) { bool retval = false; - if ((npcset.useNavSplines) && ((flg_move) & 8)) + if ((npcset.useNavSplines) && ((flg_move)&8)) if (this->drv_data && (this->drv_data->driver || this->drv_data->odriver)) { retval = true; @@ -783,7 +783,7 @@ void zNPCCommon::Process(xScene* xscn, F32 dt) xNPCBasic::Process(xscn, dt); } -void zNPCCommon::BUpdate(xVec3* pos) //NONMATCH("https://decomp.me/scratch/zpv2r") +void zNPCCommon::BUpdate(xVec3* pos) { NPCConfig* cfg = this->cfg_npc; @@ -816,7 +816,7 @@ void zNPCCommon::BUpdate(xVec3* pos) //NONMATCH("https://decomp.me/scratch/zpv2r zGridUpdateEnt(this); } -F32 zNPCCommon::BoundAsRadius(S32 useCfg) const //NONMATCH("https://decomp.me/scratch/rCFqE") +F32 zNPCCommon::BoundAsRadius(S32 useCfg) const { F32 rad = 1.0f; @@ -1329,7 +1329,7 @@ void zNPCCommon::ConvertHitEvent(xBase* from, xBase* to, U32 toEvent, const F32* this->Damage(what, from, vec_hit); } -void zNPCCommon::VelStop() //NONMATCH("https://decomp.me/scratch/YizcX") +void zNPCCommon::VelStop() { this->spd_throttle = 0.0f; this->frame->dvel.x = 0.0f; @@ -1434,7 +1434,6 @@ F32 zNPCCommon::ThrottleApply(F32 dt, const xVec3* dir, S32 force3D) } F32 zNPCCommon::TurnToFace(F32 dt, const xVec3* dir_want, F32 useTurnRate) -//NONMATCH("https://decomp.me/scratch/KRonE") { F32 f29 = (useTurnRate < 0.0f) ? (dt * this->cfg_npc->spd_turnMax) : (dt * useTurnRate); F32 f30 = NPCC_dir_toXZAng(dir_want); @@ -1951,7 +1950,7 @@ void zNPCCommon::PlayerKiltMe() } } -void zNPCCommon::ISeePlayer() //NONMATCH("https://decomp.me/scratch/M08oY") +void zNPCCommon::ISeePlayer() { en_xEventTags ven = eEventUnknown; @@ -2153,7 +2152,7 @@ void zNPCCommon::GetParm(en_npcparm pid, zMovePoint** val) this->GetParm(pid, (void*)val); } -void zNPCCommon::GetParm(en_npcparm pid, void* val) //NONMATCH("https://decomp.me/scratch/dg7eV") +void zNPCCommon::GetParm(en_npcparm pid, void* val) { char** names = g_strz_params; xModelAssetParam* pmdata = this->parmdata; @@ -2266,7 +2265,6 @@ void zNPCCommon::GetParm(en_npcparm pid, void* val) //NONMATCH("https://decomp.m } void zNPCCommon::GetParmDefault(en_npcparm pid, void* val) -//NONMATCH("https://decomp.me/scratch/mNHLS") { // Should be a S32? S32 result = 1; @@ -2429,7 +2427,7 @@ void zNPCCommon_WonderReset() U32 zNPCCommon::CanDoSplines() { bool retval = false; - if ((npcset.useNavSplines) && ((flg_move) & 8)) + if ((npcset.useNavSplines) && ((flg_move)&8)) { retval = true; } @@ -2443,7 +2441,7 @@ zMovePoint* zNPCCommon::FirstAssigned() return nav_first; } -void zNPCCommon::MvptReset(zMovePoint* nav_goto) //NONMATCH("https://decomp.me/scratch/lhUW9") +void zNPCCommon::MvptReset(zMovePoint* nav_goto) { if (nav_goto) { @@ -2462,7 +2460,7 @@ void zNPCCommon::MvptReset(zMovePoint* nav_goto) //NONMATCH("https://decomp.me/s this->dst_curspline = 0.0f; } -S32 zNPCCommon::MvptCycle() //NONMATCH("https://decomp.me/scratch/CGooj") +S32 zNPCCommon::MvptCycle() { zMovePoint* nav_tmp = NULL; @@ -2517,7 +2515,6 @@ S32 zNPCCommon::MvptCycle() //NONMATCH("https://decomp.me/scratch/CGooj") } S32 zNPCCommon::HaveLOSToPos(xVec3* pos, F32 dist, xScene* xscn, xBase* tgt, xCollis* colCallers) -//NONMATCH("https://decomp.me/scratch/wxm2S") { S32 result; xRay3 ray = {}; @@ -2762,7 +2759,7 @@ zNPCSettings* zNPCSettings_Find(U32 id) return set; } -void zNPCCommon::Vibrate(F32 ds2_cur, F32 ds2_max) //NONMATCH("https://decomp.me/scratch/A5HIP") +void zNPCCommon::Vibrate(F32 ds2_cur, F32 ds2_max) { F32 rat = ds2_cur / MAX(ds2_max, 1.0f); @@ -2857,7 +2854,7 @@ F32 zNPCCommon::AnimTimeCurrent() return model->Anim->Single->Time; } -void zNPCSettings_MakeDummy() //NONMATCH("https://decomp.me/scratch/amPtL") +void zNPCSettings_MakeDummy() { static zNPCSettings dum; dum.id = 0xFEEDCAFE;