diff options
| author | engineer124 <47598039+engineer124@users.noreply.github.com> | 2022-10-15 02:16:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-15 02:16:37 -0400 |
| commit | 9675051377c95b95119c6f15c65b648c2f01726a (patch) | |
| tree | a47579c36e5da393f3fb31a43b0534475bda9916 /src/code | |
| parent | d1d946a197e9be2e1f6219f494502d060ffc6e44 (diff) | |
Quake Documentation Pass (#1402)
* begin quake docs
* continue cleanup
* quake offset
* many more docs
* cleanup
* more cleanup
* cleanup headers
* move quake value to internal
* update, still need to test shake zoom/yaw
* more docs
* better docs
* add file descriptions
* fix comment
* explain random index
* cleanup comments
* better type 6 docs
* expand orientation comment
* fix old names, add comment
* remove comment, twas a mistake
* easy PR feedback
* duration in dec
* rm offset, clear up roll
* oops
* merge shakeInfo and QuakeCamData
* match order that always appears in code
* more PR suggestions
* adjust comment
* zeroVec
* rm extra space
* roman PR suggestions
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/z_actor.c | 36 | ||||
| -rw-r--r-- | src/code/z_camera.c | 89 | ||||
| -rw-r--r-- | src/code/z_demo.c | 9 | ||||
| -rw-r--r-- | src/code/z_onepointdemo.c | 115 | ||||
| -rw-r--r-- | src/code/z_play.c | 9 | ||||
| -rw-r--r-- | src/code/z_quake.c | 617 | ||||
| -rw-r--r-- | src/code/z_room.c | 4 | ||||
| -rw-r--r-- | src/code/z_scene_table.c | 19 |
8 files changed, 506 insertions, 392 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c index d026eff6d..b14f32a84 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1,4 +1,5 @@ #include "global.h" +#include "quake.h" #include "vt.h" #include "overlays/actors/ovl_Arms_Hook/z_arms_hook.h" @@ -2179,11 +2180,11 @@ void Actor_Draw(PlayState* play, Actor* actor) { Lights_BindAll(lights, play->lightCtx.listHead, (actor->flags & ACTOR_FLAG_22) ? NULL : &actor->world.pos); Lights_Draw(lights, play->state.gfxCtx); - if (actor->flags & ACTOR_FLAG_12) { - Matrix_SetTranslateRotateYXZ(actor->world.pos.x + play->mainCamera.skyboxOffset.x, + if (actor->flags & ACTOR_FLAG_IGNORE_QUAKE) { + Matrix_SetTranslateRotateYXZ(actor->world.pos.x + play->mainCamera.quakeOffset.x, actor->world.pos.y + - ((actor->shape.yOffset * actor->scale.y) + play->mainCamera.skyboxOffset.y), - actor->world.pos.z + play->mainCamera.skyboxOffset.z, &actor->shape.rot); + ((actor->shape.yOffset * actor->scale.y) + play->mainCamera.quakeOffset.y), + actor->world.pos.z + play->mainCamera.quakeOffset.z, &actor->shape.rot); } else { Matrix_SetTranslateRotateYXZ(actor->world.pos.x, actor->world.pos.y + (actor->shape.yOffset * actor->scale.y), actor->world.pos.z, &actor->shape.rot); @@ -3505,30 +3506,29 @@ void func_80033C30(Vec3f* arg0, Vec3f* arg1, u8 alpha, PlayState* play) { CLOSE_DISPS(play->state.gfxCtx, "../z_actor.c", 8155); } -void func_80033DB8(PlayState* play, s16 arg1, s16 arg2) { - s16 var = Quake_Add(&play->mainCamera, 3); +void Actor_RequestQuake(PlayState* play, s16 y, s16 duration) { + s16 quakeIndex = Quake_Request(&play->mainCamera, QUAKE_TYPE_3); - Quake_SetSpeed(var, 20000); - Quake_SetQuakeValues(var, arg1, 0, 0, 0); - Quake_SetCountdown(var, arg2); + Quake_SetSpeed(quakeIndex, 20000); + Quake_SetPerturbations(quakeIndex, y, 0, 0, 0); + Quake_SetDuration(quakeIndex, duration); } -void func_80033E1C(PlayState* play, s16 arg1, s16 arg2, s16 arg3) { - s16 var = Quake_Add(&play->mainCamera, 3); +void Actor_RequestQuakeWithSpeed(PlayState* play, s16 y, s16 duration, s16 speed) { + s16 quakeIndex = Quake_Request(&play->mainCamera, QUAKE_TYPE_3); - Quake_SetSpeed(var, arg3); - Quake_SetQuakeValues(var, arg1, 0, 0, 0); - Quake_SetCountdown(var, arg2); + Quake_SetSpeed(quakeIndex, speed); + Quake_SetPerturbations(quakeIndex, y, 0, 0, 0); + Quake_SetDuration(quakeIndex, duration); } -void func_80033E88(Actor* actor, PlayState* play, s16 arg2, s16 arg3) { - if (arg2 >= 5) { +void Actor_RequestQuakeAndRumble(Actor* actor, PlayState* play, s16 quakeY, s16 quakeDuration) { + if (quakeY >= 5) { Rumble_Request(actor->xyzDistToPlayerSq, 255, 20, 150); } else { Rumble_Request(actor->xyzDistToPlayerSq, 180, 20, 100); } - - func_80033DB8(play, arg2, arg3); + Actor_RequestQuake(play, quakeY, quakeDuration); } f32 Rand_ZeroFloat(f32 f) { diff --git a/src/code/z_camera.c b/src/code/z_camera.c index c9477d147..815be7475 100644 --- a/src/code/z_camera.c +++ b/src/code/z_camera.c @@ -1,5 +1,6 @@ #include "ultra64.h" #include "global.h" +#include "quake.h" #include "vt.h" #include "overlays/actors/ovl_En_Horse/z_en_horse.h" @@ -6972,7 +6973,7 @@ void Camera_Init(Camera* camera, View* view, CollisionContext* colCtx, PlayState camera->up.y = 1.0f; camera->up.z = camera->up.x = 0.0f; - camera->skyboxOffset.x = camera->skyboxOffset.y = camera->skyboxOffset.z = 0; + camera->quakeOffset.x = camera->quakeOffset.y = camera->quakeOffset.z = 0; camera->atLERPStepScale = 1; sCameraInterfaceFlags = 0xFF00; sDbgModeIdx = -1; @@ -7185,11 +7186,11 @@ void Camera_PrintSettings(Camera* camera) { s32 Camera_UpdateWater(Camera* camera) { f32 waterY; - s16 newQuakeId; + s16 quakeIndex; s32 waterLightsIndex; s32* waterCamSetting = &camera->waterCamSetting; s16 waterBgCamIndex; - s16* quakeId = (s16*)&camera->waterQuakeId; + s16* waterQuakeIndex = (s16*)&camera->waterQuakeIndex; Player* player = camera->player; s16 prevBgId; @@ -7213,7 +7214,7 @@ s32 Camera_UpdateWater(Camera* camera) { camera->unk_14C |= 0x200; camera->waterYPos = waterY; camera->bgCamIndexBeforeUnderwater = camera->bgCamIndex; - *quakeId = -1; + *waterQuakeIndex = -1; } if (camera->playerGroundY != camera->playerPosRot.pos.y) { prevBgId = camera->bgId; @@ -7229,7 +7230,7 @@ s32 Camera_UpdateWater(Camera* camera) { camera->unk_14C |= 0x200; camera->waterYPos = waterY; camera->bgCamIndexBeforeUnderwater = camera->bgCamIndex; - *quakeId = -1; + *waterQuakeIndex = -1; } if (camera->playerGroundY != camera->playerPosRot.pos.y) { prevBgId = camera->bgId; @@ -7266,16 +7267,19 @@ s32 Camera_UpdateWater(Camera* camera) { Audio_SetExtraFilter(0x20); if (PREG(81)) { - Quake_RemoveFromIdx(*quakeId); - *quakeId = -1; + Quake_RemoveRequest(*waterQuakeIndex); + *waterQuakeIndex = -1; PREG(81) = 0; } - if ((*quakeId == -1) || (Quake_GetCountdown(*quakeId) == 0xA)) { - if (*quakeId = newQuakeId = Quake_Add(camera, 5U), newQuakeId != 0) { - Quake_SetSpeed(*quakeId, 550); - Quake_SetQuakeValues(*quakeId, 1, 1, 180, 0); - Quake_SetCountdown(*quakeId, 1000); + if ((*waterQuakeIndex == -1) || (Quake_GetTimeLeft(*waterQuakeIndex) == 10)) { + quakeIndex = Quake_Request(camera, QUAKE_TYPE_5); + + *waterQuakeIndex = quakeIndex; + if (quakeIndex != 0) { + Quake_SetSpeed(*waterQuakeIndex, 550); + Quake_SetPerturbations(*waterQuakeIndex, 1, 1, 180, 0); + Quake_SetDuration(*waterQuakeIndex, 1000); } } @@ -7292,8 +7296,8 @@ s32 Camera_UpdateWater(Camera* camera) { camera->unk_14C &= ~0x100; osSyncPrintf("kankyo changed water off, sound off\n"); Environment_DisableUnderwaterLights(camera->play); - if (*quakeId != 0) { - Quake_RemoveFromIdx(*quakeId); + if (*waterQuakeIndex != 0) { + Quake_RemoveRequest(*waterQuakeIndex); } camera->waterDistortionTimer = 0; camera->distortionFlags = 0; @@ -7438,8 +7442,9 @@ Vec3s Camera_Update(Camera* camera) { f32 playerXZSpeed; VecSph eyeAtAngle; s16 bgCamIndex; + s16 numQuakesApplied; PosRot curPlayerPosRot; - QuakeCamCalc quake; + ShakeInfo camShake; Player* player; player = camera->play->cameraPtrs[CAM_ID_MAIN]->player; @@ -7602,19 +7607,23 @@ Vec3s Camera_Update(Camera* camera) { return camera->inputDir; } - // setting bgId to the ret of Quake_Calc, and checking that - // is required, it doesn't make too much sense though. - if ((bgId = Quake_Calc(camera, &quake), bgId != 0) && (camera->setting != CAM_SET_TURN_AROUND)) { - viewAt.x = camera->at.x + quake.atOffset.x; - viewAt.y = camera->at.y + quake.atOffset.y; - viewAt.z = camera->at.z + quake.atOffset.z; - viewEye.x = camera->eye.x + quake.eyeOffset.x; - viewEye.y = camera->eye.y + quake.eyeOffset.y; - viewEye.z = camera->eye.z + quake.eyeOffset.z; + numQuakesApplied = Quake_Update(camera, &camShake); + + bgId = numQuakesApplied; // required to match + + if ((numQuakesApplied != 0) && (camera->setting != CAM_SET_TURN_AROUND)) { + viewAt.x = camera->at.x + camShake.atOffset.x; + viewAt.y = camera->at.y + camShake.atOffset.y; + viewAt.z = camera->at.z + camShake.atOffset.z; + + viewEye.x = camera->eye.x + camShake.eyeOffset.x; + viewEye.y = camera->eye.y + camShake.eyeOffset.y; + viewEye.z = camera->eye.z + camShake.eyeOffset.z; + OLib_Vec3fDiffToVecSphGeo(&eyeAtAngle, &viewEye, &viewAt); - Camera_CalcUpFromPitchYawRoll(&viewUp, eyeAtAngle.pitch + quake.rotZ, eyeAtAngle.yaw + quake.unk_1A, - camera->roll); - viewFov = camera->fov + CAM_BINANG_TO_DEG(quake.zoom); + Camera_CalcUpFromPitchYawRoll(&viewUp, eyeAtAngle.pitch + camShake.upPitchOffset, + eyeAtAngle.yaw + camShake.upYawOffset, camera->roll); + viewFov = camera->fov + CAM_BINANG_TO_DEG(camShake.fovOffset); } else { viewAt = camera->at; viewEye = camera->eye; @@ -7630,7 +7639,7 @@ Vec3s Camera_Update(Camera* camera) { camera->up = viewUp; } - camera->skyboxOffset = quake.eyeOffset; + camera->quakeOffset = camShake.eyeOffset; Camera_UpdateDistortion(camera); @@ -8010,17 +8019,17 @@ s16 Camera_GetCamDirYaw(Camera* camera) { return camDir.y; } -s32 Camera_AddQuake(Camera* camera, s32 arg1, s16 y, s32 countdown) { - s16 quakeIdx; +s32 Camera_RequestQuake(Camera* camera, s32 unused, s16 y, s32 duration) { + s16 quakeIndex; - quakeIdx = Quake_Add(camera, 3); - if (quakeIdx == 0) { - return 0; + quakeIndex = Quake_Request(camera, QUAKE_TYPE_3); + if (quakeIndex == 0) { + return false; } - Quake_SetSpeed(quakeIdx, 0x61A8); - Quake_SetQuakeValues(quakeIdx, y, 0, 0, 0); - Quake_SetCountdown(quakeIdx, countdown); - return 1; + Quake_SetSpeed(quakeIndex, 0x61A8); + Quake_SetPerturbations(quakeIndex, y, 0, 0, 0); + Quake_SetDuration(quakeIndex, duration); + return true; } s32 Camera_SetParam(Camera* camera, s32 param, void* value) { @@ -8187,9 +8196,9 @@ s32 Camera_GetDbgCamEnabled(void) { return gDbgCamEnabled; } -Vec3f* Camera_GetSkyboxOffset(Vec3f* dst, Camera* camera) { - *dst = camera->skyboxOffset; - return dst; +Vec3f* Camera_GetQuakeOffset(Vec3f* quakeOffset, Camera* camera) { + *quakeOffset = camera->quakeOffset; + return quakeOffset; } void Camera_SetCameraData(Camera* camera, s16 setDataFlags, void* data0, void* data1, s16 data2, s16 data3, diff --git a/src/code/z_demo.c b/src/code/z_demo.c index 9af0c6f93..b7c178ee6 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "quake.h" #include "z64camera.h" #include "assets/scenes/indoors/tokinoma/tokinoma_scene.h" @@ -311,15 +312,15 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { break; case 16: if (sp3F != 0) { - sQuakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 6); + sQuakeIndex = Quake_Request(GET_ACTIVE_CAM(play), QUAKE_TYPE_6); Quake_SetSpeed(sQuakeIndex, 0x7FFF); - Quake_SetQuakeValues(sQuakeIndex, 4, 0, 1000, 0); - Quake_SetCountdown(sQuakeIndex, 800); + Quake_SetPerturbations(sQuakeIndex, 4, 0, 1000, 0); + Quake_SetDuration(sQuakeIndex, 800); } break; case 17: if (sp3F != 0) { - Quake_RemoveFromIdx(sQuakeIndex); + Quake_RemoveRequest(sQuakeIndex); } break; case 18: diff --git a/src/code/z_onepointdemo.c b/src/code/z_onepointdemo.c index e28448f3b..9d62b8910 100644 --- a/src/code/z_onepointdemo.c +++ b/src/code/z_onepointdemo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "quake.h" #include "vt.h" #include "overlays/actors/ovl_En_Sw/z_en_sw.h" @@ -156,10 +157,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act ((mainCam->play->state.frames & 1) ? 3.0f : -3.0f) + Rand_ZeroOne(); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 5); + i = Quake_Request(subCam, QUAKE_TYPE_5); Quake_SetSpeed(i, 400); - Quake_SetQuakeValues(i, 4, 5, 40, 0x3C); - Quake_SetCountdown(i, 1600); + Quake_SetPerturbations(i, 4, 5, 40, 0x3C); + Quake_SetDuration(i, 1600); break; case 2280: csInfo->keyFrames = D_80120D4C; @@ -177,10 +178,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act ((mainCam->play->state.frames & 1) ? 3.0f : -3.0f) + Rand_ZeroOne(); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 5); + i = Quake_Request(subCam, QUAKE_TYPE_5); Quake_SetSpeed(i, 400); - Quake_SetQuakeValues(i, 2, 3, 200, 0x32); - Quake_SetCountdown(i, 9999); + Quake_SetPerturbations(i, 2, 3, 200, 0x32); + Quake_SetDuration(i, 9999); break; case 2220: csInfo->keyFrames = D_80120E64; @@ -188,10 +189,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 5); + i = Quake_Request(subCam, QUAKE_TYPE_5); Quake_SetSpeed(i, 400); - Quake_SetQuakeValues(i, 2, 2, 50, 0); - Quake_SetCountdown(i, 280); + Quake_SetPerturbations(i, 2, 2, 50, 0); + Quake_SetDuration(i, 280); break; case 2230: if (player->actor.world.pos.z < 1000.0f) { @@ -210,10 +211,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 5); + i = Quake_Request(subCam, QUAKE_TYPE_5); Quake_SetSpeed(i, 400); - Quake_SetQuakeValues(i, 2, 2, 50, 0); - Quake_SetCountdown(i, 60); + Quake_SetPerturbations(i, 2, 2, 50, 0); + Quake_SetDuration(i, 60); break; case 2350: csInfo->keyFrames = D_8012110C; @@ -397,10 +398,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 3); + i = Quake_Request(subCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 22000); - Quake_SetQuakeValues(i, 2, 0, 200, 0); - Quake_SetCountdown(i, 10); + Quake_SetPerturbations(i, 2, 0, 200, 0); + Quake_SetDuration(i, 10); break; case 3080: csInfo->keyFrames = D_80121774; @@ -435,10 +436,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_8002DF54(play, NULL, 8); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 24000); - Quake_SetQuakeValues(i, 2, 0, 0, 0); - Quake_SetCountdown(i, 160); + Quake_SetPerturbations(i, 2, 0, 0, 0); + Quake_SetDuration(i, 160); break; case 3060: csInfo->keyFrames = D_80121904; @@ -467,10 +468,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act D_8012021C[D_801202FC - 3].pos.z += (D_8012021C[D_801202FC - 2].pos.z - D_8012021C[D_801202FC - 3].pos.z) / 2; - i = Quake_Add(mainCam, 3); + i = Quake_Request(mainCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 30000); - Quake_SetQuakeValues(i, 2, 1, 1, 0); - Quake_SetCountdown(i, 200); + Quake_SetPerturbations(i, 2, 1, 1, 0); + Quake_SetDuration(i, 200); break; case 3120: csInfo->keyFrames = D_80121954[-(timer + 101)]; @@ -583,10 +584,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act OnePointCutscene_AddVecSphToVec3f(&spB4, &spC0, &spD0); Play_CameraSetAtEye(play, CAM_ID_MAIN, &spC0, &spB4); - i = Quake_Add(subCam, 3); + i = Quake_Request(subCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 22000); - Quake_SetQuakeValues(i, 1, 0, 0, 0); - Quake_SetCountdown(i, 90); + Quake_SetPerturbations(i, 1, 0, 0, 0); + Quake_SetDuration(i, 90); break; case 6010: Actor_GetWorld(&spA0, actor); @@ -637,10 +638,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act OnePointCutscene_SetCsCamPoints(subCam, D_801208E8, D_801208E4, D_801206A0, D_80120760); } - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 32000); - Quake_SetQuakeValues(i, 0, 0, 20, 0); - Quake_SetCountdown(i, D_801208E4 - 10); + Quake_SetPerturbations(i, 0, 0, 20, 0); + Quake_SetDuration(i, D_801208E4 - 10); break; case 3400: Play_CameraChangeSetting(play, subCamId, CAM_SET_CS_3); @@ -649,10 +650,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act OnePointCutscene_Vec3sToVec3f(&mainCam->eye, &D_801205B4[D_80120694 - 2].pos); OnePointCutscene_Vec3sToVec3f(&mainCam->at, &D_801204D4[D_80120694 - 2].pos); - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 0x4E20); - Quake_SetQuakeValues(i, 1, 0, 50, 0); - Quake_SetCountdown(i, D_80120698 - 20); + Quake_SetPerturbations(i, 1, 0, 50, 0); + Quake_SetDuration(i, D_80120698 - 20); break; case 3390: player->actor.shape.rot.y = player->actor.world.rot.y = player->currentYaw = -0x3FD9; @@ -668,10 +669,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_8002DF54(play, NULL, 8); Play_CopyCamera(play, subCamId, CAM_ID_MAIN); - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 32000); - Quake_SetQuakeValues(i, 2, 0, 0, 0); - Quake_SetCountdown(i, timer); + Quake_SetPerturbations(i, 2, 0, 0, 0); + Quake_SetDuration(i, timer); break; case 3290: D_80121F1C[0].atTargetInit = play->view.at; @@ -685,10 +686,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 3); + i = Quake_Request(subCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 12000); - Quake_SetQuakeValues(i, 0, 0, 1000, 0); - Quake_SetCountdown(i, 5); + Quake_SetPerturbations(i, 0, 0, 1000, 0); + Quake_SetDuration(i, 5); break; case 3340: D_80121FBC[0].atTargetInit = play->view.at; @@ -701,10 +702,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_8002DF54(play, NULL, 8); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 3); + i = Quake_Request(subCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 12000); - Quake_SetQuakeValues(i, 0, 0, 1000, 0); - Quake_SetCountdown(i, 5); + Quake_SetPerturbations(i, 0, 0, 1000, 0); + Quake_SetDuration(i, 5); break; case 3360: csInfo->keyFrames = D_8012205C; @@ -746,10 +747,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_8002DF54(play, NULL, 8); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 32000); - Quake_SetQuakeValues(i, 4, 0, 0, 0); - Quake_SetCountdown(i, 20); + Quake_SetPerturbations(i, 4, 0, 0, 0); + Quake_SetDuration(i, 20); break; case 3450: csInfo->keyFrames = D_8012237C; @@ -758,10 +759,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_8002DF38(play, &player->actor, 8); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 32000); - Quake_SetQuakeValues(i, 2, 0, 0, 0); - Quake_SetCountdown(i, 10); + Quake_SetPerturbations(i, 2, 0, 0, 0); + Quake_SetDuration(i, 10); break; case 3440: csInfo->keyFrames = D_801223CC; @@ -772,10 +773,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act player->stateFlags1 |= PLAYER_STATE1_29; player->actor.freezeTimer = 90; - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 32000); - Quake_SetQuakeValues(i, 2, 0, 0, 0); - Quake_SetCountdown(i, 10); + Quake_SetPerturbations(i, 2, 0, 0, 0); + Quake_SetDuration(i, 10); break; case 3430: csInfo->keyFrames = D_801224BC; @@ -784,10 +785,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_8002DF54(play, NULL, 8); func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 1); + i = Quake_Request(subCam, QUAKE_TYPE_1); Quake_SetSpeed(i, 32000); - Quake_SetQuakeValues(i, 1, 0, 10, 0); - Quake_SetCountdown(i, 20); + Quake_SetPerturbations(i, 1, 0, 10, 0); + Quake_SetDuration(i, 20); break; case 4100: csInfo->keyFrames = D_801225D4; @@ -867,10 +868,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_800C0808(play, subCamId, player, CAM_SET_CS_C); - i = Quake_Add(subCam, 3); + i = Quake_Request(subCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 12000); - Quake_SetQuakeValues(i, 0, 1, 100, 0); - Quake_SetCountdown(i, timer - 80); + Quake_SetPerturbations(i, 0, 1, 100, 0); + Quake_SetDuration(i, timer - 80); break; case 4220: csInfo->keyFrames = (player->actor.world.pos.z < -15.0f) ? D_80122C3C : D_80122C64; @@ -879,10 +880,10 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 subCamId, s16 csId, Actor* act func_800C0808(play, subCamId, player, CAM_SET_CS_C); func_8002DF38(play, &player->actor, 1); - i = Quake_Add(subCam, 3); + i = Quake_Request(subCam, QUAKE_TYPE_3); Quake_SetSpeed(i, 12000); - Quake_SetQuakeValues(i, 0, 1, 10, 0); - Quake_SetCountdown(i, timer - 10); + Quake_SetPerturbations(i, 0, 1, 10, 0); + Quake_SetDuration(i, timer - 10); break; case 4221: csInfo->keyFrames = D_80122C8C; diff --git a/src/code/z_play.c b/src/code/z_play.c index 7d0fee621..16948ad77 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1,4 +1,5 @@ #include "global.h" +#include "quake.h" #include "vt.h" void* D_8012D1F0 = NULL; @@ -1176,11 +1177,11 @@ void Play_Draw(PlayState* this) { if ((HREG(80) != 10) || (HREG(83) != 0)) { if ((this->skyboxCtx.unk_140 != 0) && (GET_ACTIVE_CAM(this)->setting != CAM_SET_PREREND_FIXED)) { - Vec3f sp74; + Vec3f quakeOffset; - Camera_GetSkyboxOffset(&sp74, GET_ACTIVE_CAM(this)); - SkyboxDraw_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, 0, this->view.eye.x + sp74.x, - this->view.eye.y + sp74.y, this->view.eye.z + sp74.z); + Camera_GetQuakeOffset(&quakeOffset, GET_ACTIVE_CAM(this)); + SkyboxDraw_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, 0, this->view.eye.x + quakeOffset.x, + this->view.eye.y + quakeOffset.y, this->view.eye.z + quakeOffset.z); } } diff --git a/src/code/z_quake.c b/src/code/z_quake.c index 02fb8e63d..d2538b5dd 100644 --- a/src/code/z_quake.c +++ b/src/code/z_quake.c @@ -1,280 +1,362 @@ #include "global.h" +#include "quake.h" #include "vt.h" -QuakeRequest sQuakeRequest[4]; -s16 D_80126250 = 1; +typedef struct { + /* 0x00 */ s16 index; + /* 0x02 */ s16 duration; + /* 0x04 */ Camera* cam; + /* 0x08 */ u32 type; + /* 0x0C */ s16 y; + /* 0x0E */ s16 x; + /* 0x10 */ s16 fov; + /* 0x12 */ s16 upPitchOffset; + /* 0x14 */ Vec3s orientation; // alters the orientation of the xy perturbation. Only x (pitch) and y (yaw) are used + /* 0x1A */ s16 speed; + /* 0x1C */ s16 isRelativeToScreen; // is the quake relative to the screen or on world coordinates + /* 0x1E */ s16 timer; + /* 0x20 */ s16 camId; +} QuakeRequest; // size = 0x24 + +QuakeRequest sQuakeRequests[4]; +s16 sQuakeUnused = 1; s16 sQuakeRequestCount = 0; -s16 (*sQuakeCallbacks[])(QuakeRequest*, ShakeInfo*) = { - NULL, Quake_Callback1, Quake_Callback2, Quake_Callback3, Quake_Callback4, Quake_Callback5, Quake_Callback6, -}; +Vec3f* Quake_VecSphGeoAddToVec3f(Vec3f* dst, Vec3f* a, VecSph* sph) { + Vec3f vec; + Vec3f b; -Vec3f* Quake_AddVec(Vec3f* dst, Vec3f* arg1, VecSph* arg2) { - Vec3f vec1; - Vec3f vec2; + OLib_VecSphGeoToVec3f(&b, sph); + vec.x = a->x + b.x; + vec.y = a->y + b.y; + vec.z = a->z + b.z; + + *dst = vec; - OLib_VecSphGeoToVec3f(&vec2, arg2); - vec1.x = arg1->x + vec2.x; - vec1.y = arg1->y + vec2.y; - vec1.z = arg1->z + vec2.z; - *dst = vec1; return dst; } void Quake_UpdateShakeInfo(QuakeRequest* req, ShakeInfo* shake, f32 y, f32 x) { - Vec3f* unk50 = &req->cam->at; - Vec3f* unk5C = &req->cam->eye; - - Vec3f vec; - VecSph struc2; - VecSph struc1; - Vec3f vec2; - - if (req->unk_1C) { - vec.x = 0; - vec.y = 0; - vec.z = 0; - OLib_Vec3fDiffToVecSphGeo(&struc1, unk5C, unk50); - struc2.r = req->y * y; - struc2.pitch = struc1.pitch + req->unk_14.unk_00 + 0x4000; - struc2.yaw = struc1.yaw + req->unk_14.unk_02; - Quake_AddVec(&vec, &vec, &struc2); - struc2.r = req->x * x; - struc2.pitch = struc1.pitch + req->unk_14.unk_00; - struc2.yaw = struc1.yaw + req->unk_14.unk_02 + 0x4000; - Quake_AddVec(&vec, &vec, &struc2); + Vec3f* at = &req->cam->at; + Vec3f* eye = &req->cam->eye; + Vec3f offset; + VecSph sph; + VecSph eyeToAtSph; + + if (req->isRelativeToScreen) { + offset.x = 0; + offset.y = 0; + offset.z = 0; + OLib_Vec3fDiffToVecSphGeo(&eyeToAtSph, eye, at); + + // y shake + sph.r = req->y * y; + // point unit vector up, then add on `req->orientation` + sph.pitch = eyeToAtSph.pitch + req->orientation.x + 0x4000; + sph.yaw = eyeToAtSph.yaw + req->orientation.y; + // apply y shake + Quake_VecSphGeoAddToVec3f(&offset, &offset, &sph); + + // x shake + sph.r = req->x * x; + // point unit vector left, then add on `req->orientation` + sph.pitch = eyeToAtSph.pitch + req->orientation.x; + sph.yaw = eyeToAtSph.yaw + req->orientation.y + 0x4000; + // apply x shake + Quake_VecSphGeoAddToVec3f(&offset, &offset, &sph); } else { - vec.x = 0; - vec.y = req->y * y; - vec.z = 0; - struc2.r = req->x * x; - struc2.pitch = req->unk_14.unk_00; - struc2.yaw = req->unk_14.unk_02; - Quake_AddVec(&vec, &vec, &struc2); + offset.x = 0; + offset.y = req->y * y; + offset.z = 0; + sph.r = req->x * x; + sph.pitch = req->orientation.x; + sph.yaw = req->orientation.y; + Quake_VecSphGeoAddToVec3f(&offset, &offset, &sph); } - vec2 = vec; - shake->vec2 = vec2; - shake->vec1 = vec2; - shake->unk_1A = (f32)0x8000 * y; - shake->rotZ = req->rotZ * y; - shake->zoom = req->zoom * y; + shake->atOffset = shake->eyeOffset = offset; + shake->upYawOffset = 0x8000 * y; + shake->upPitchOffset = req->upPitchOffset * y; + shake->fovOffset = req->fov * y; } -s16 Quake_Callback1(QuakeRequest* req, ShakeInfo* shake) { +s16 Quake_CallbackType1(QuakeRequest* req, ShakeInfo* shake) { s32 pad; - if (req->countdown > 0) { - f32 a = Math_SinS(req->speed * req->countdown); + if (req->timer > 0) { + f32 xyOffset = Math_SinS(req->speed * req->timer); - Quake_UpdateShakeInfo(req, shake, a, Rand_ZeroOne() * a); - req->countdown--; + Quake_UpdateShakeInfo(req, shake, xyOffset, Rand_ZeroOne() * xyOffset); + req->timer--; } - return req->countdown; + return req->timer; } -s16 Quake_Callback5(QuakeRequest* req, ShakeInfo* shake) { - if (req->countdown > 0) { - f32 a = Math_SinS(req->speed * req->countdown); +s16 Quake_CallbackType5(QuakeRequest* req, ShakeInfo* shake) { + if (req->timer > 0) { + f32 xyOffset = Math_SinS(req->speed * req->timer); - Quake_UpdateShakeInfo(req, shake, a, a); - req->countdown--; + Quake_UpdateShakeInfo(req, shake, xyOffset, xyOffset); + req->timer--; } - return req->countdown; + return req->timer; } -s16 Quake_Callback6(QuakeRequest* req, ShakeInfo* shake) { +s16 Quake_CallbackType6(QuakeRequest* req, ShakeInfo* shake) { s32 pad; - f32 a; + f32 xyOffset; + + req->timer--; + xyOffset = Math_SinS(req->speed * ((req->timer & 0xF) + 500)); + Quake_UpdateShakeInfo(req, shake, xyOffset, Rand_ZeroOne() * xyOffset); - req->countdown--; - a = Math_SinS(req->speed * ((req->countdown & 0xF) + 500)); - Quake_UpdateShakeInfo(req, shake, a, Rand_ZeroOne() * a); + // Not returning the timer ensures quake type 6 continues indefinitely until manually removed return 1; } -s16 Quake_Callback3(QuakeRequest* req, ShakeInfo* shake) { - if (req->countdown > 0) { - f32 a = Math_SinS(req->speed * req->countdown) * ((f32)req->countdown / (f32)req->countdownMax); +s16 Quake_CallbackType3(QuakeRequest* req, ShakeInfo* shake) { + if (req->timer > 0) { + f32 xyOffset = Math_SinS(req->speed * req->timer) * ((f32)req->timer / req->duration); - Quake_UpdateShakeInfo(req, shake, a, a); - req->countdown--; + Quake_UpdateShakeInfo(req, shake, xyOffset, xyOffset); + req->timer--; } - return req->countdown; + return req->timer; } -s16 Quake_Callback2(QuakeRequest* req, ShakeInfo* shake) { - if (req->countdown > 0) { - f32 a = Rand_ZeroOne(); +s16 Quake_CallbackType2(QuakeRequest* req, ShakeInfo* shake) { + if (req->timer > 0) { + f32 xyOffset = Rand_ZeroOne(); - Quake_UpdateShakeInfo(req, shake, a, Rand_ZeroOne() * a); - req->countdown--; + Quake_UpdateShakeInfo(req, shake, xyOffset, Rand_ZeroOne() * xyOffset); + req->timer--; } - return req->countdown; + return req->timer; } -s16 Quake_Callback4(QuakeRequest* req, ShakeInfo* shake) { - if (req->countdown > 0) { - f32 a = Rand_ZeroOne() * ((f32)req->countdown / (f32)req->countdownMax); +s16 Quake_CallbackType4(QuakeRequest* req, ShakeInfo* shake) { + if (req->timer > 0) { + f32 xyOffset = Rand_ZeroOne() * ((f32)req->timer / req->duration); - Quake_UpdateShakeInfo(req, shake, a, Rand_ZeroOne() * a); - req->countdown--; + Quake_UpdateShakeInfo(req, shake, xyOffset, Rand_ZeroOne() * xyOffset); + req->timer--; } - return req->countdown; + return req->timer; } s16 Quake_GetFreeIndex(void) { s32 i; - s32 ret; - s32 min = 0x10000; + s32 index; + s32 timerMin = 0x10000; // UINT16_MAX + 1 - for (i = 0; i < ARRAY_COUNT(sQuakeRequest); i++) { - if (sQuakeRequest[i].callbackIdx == 0) { - ret = i; - min = 0x20000; + for (i = 0; i < ARRAY_COUNT(sQuakeRequests); i++) { + if (sQuakeRequests[i].type == QUAKE_TYPE_NONE) { + index = i; + timerMin = 0x20000; // Magic Number to indicate there was an unused quake index break; } - if (sQuakeRequest[i].countdown < min) { - min = sQuakeRequest[i].countdown; - ret = i; + if (timerMin > sQuakeRequests[i].timer) { + timerMin = sQuakeRequests[i].timer; + index = i; } } - if (min != 0x20000) { - osSyncPrintf(VT_COL(YELLOW, BLACK) "quake: too many request %d is changed new one !!\n" VT_RST, ret); + if (timerMin != 0x20000) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "quake: too many request %d is changed new one !!\n" VT_RST, index); } - return ret; + return index; } -QuakeRequest* Quake_AddImpl(Camera* camera, u32 callbackIdx) { - s16 idx = Quake_GetFreeIndex(); - QuakeRequest* req = &sQuakeRequest[idx]; +QuakeRequest* Quake_RequestImpl(Camera* camera, u32 type) { + s16 index = Quake_GetFreeIndex(); + QuakeRequest* req = &sQuakeRequests[index]; __osMemset(req, 0, sizeof(QuakeRequest)); + req->cam = camera; - req->camPtrIdx = camera->camId; - req->callbackIdx = callbackIdx; - req->unk_1C = 1; - req->randIdx = ((s16)(Rand_ZeroOne() * (f32)0x10000) & ~3) + idx; + req->camId = camera->camId; + req->type = type; + req->isRelativeToScreen = true; + + // Add a unique random identifier to the upper bits of the index + // The `~3` assumes there are only 4 requests + req->index = index + ((s16)(Rand_ZeroOne() * 0x10000) & ~3); + sQuakeRequestCount++; return req; } void Quake_Remove(QuakeRequest* req) { - req->callbackIdx = 0; - req->countdown = -1; + req->type = QUAKE_TYPE_NONE; + req->timer = -1; sQuakeRequestCount--; } -QuakeRequest* Quake_GetRequest(s16 idx) { - QuakeRequest* req = &sQuakeRequest[idx & 3]; +QuakeRequest* Quake_GetRequest(s16 index) { + QuakeRequest* req = &sQuakeRequests[index & 3]; - if (req->callbackIdx == 0) { + if (req->type == QUAKE_TYPE_NONE) { return NULL; } - if (idx != req->randIdx) { + if (index != req->index) { return NULL; } return req; } -QuakeRequest* Quake_SetValue(s16 idx, s16 valueType, s16 value) { - QuakeRequest* req = Quake_GetRequest(idx); +#define QUAKE_SPEED (1 << 0) +#define QUAKE_Y_OFFSET (1 << 1) +#define QUAKE_X_OFFSET (1 << 2) +#define QUAKE_FOV (1 << 3) +#define QUAKE_ROLL (1 << 4) +#define QUAKE_ORIENTATION_PITCH (1 << 5) +#define QUAKE_ORIENTATION_YAW (1 << 6) +#define QUAKE_ORIENTATION_ROLL (1 << 7) +#define QUAKE_DURATION (1 << 8) +#define QUAKE_IS_RELATIVE_TO_SCREEN (1 << 9) + +QuakeRequest* Quake_SetValue(s16 index, s16 valueType, s16 value) { + QuakeRequest* req = Quake_GetRequest(index); if (req == NULL) { return NULL; - } else { - switch (valueType) { - case 1: - req->speed = value; - break; - case 2: - req->y = value; - break; - case 4: - req->x = value; - break; - case 8: - req->zoom = value; - break; - case 0x10: - req->rotZ = value; - break; - case 0x20: - req->unk_14.unk_00 = value; - break; - case 0x40: - req->unk_14.unk_02 = value; - break; - case 0x80: - req->unk_14.unk_04 = value; - break; - case 0x100: - req->countdown = value; - req->countdownMax = req->countdown; - break; - case 0x200: - req->unk_1C = value; - break; - } } + + switch (valueType) { + case QUAKE_SPEED: + req->speed = value; + break; + + case QUAKE_Y_OFFSET: + req->y = value; + break; + + case QUAKE_X_OFFSET: + req->x = value; + break; + + case QUAKE_FOV: + req->fov = value; + break; + + case QUAKE_ROLL: + req->upPitchOffset = value; + break; + + case QUAKE_ORIENTATION_PITCH: + req->orientation.x = value; + break; + + case QUAKE_ORIENTATION_YAW: + req->orientation.y = value; + break; + + case QUAKE_ORIENTATION_ROLL: + req->orientation.z = value; + break; + + case QUAKE_DURATION: + req->timer = value; + req->duration = req->timer; + break; + + case QUAKE_IS_RELATIVE_TO_SCREEN: + req->isRelativeToScreen = value; + break; + + default: + break; + } + + //! @bug UB: missing return. "req" is in v0 at this point, but doing an + //! explicit return uses an additional register. +#ifdef AVOID_UB + return req; +#endif } -u32 Quake_SetSpeed(s16 idx, s16 value) { - QuakeRequest* req = Quake_GetRequest(idx); +/** + * @param index + * @param speed For periodic types only, the angular frequency of the sine wave (binang / frame) + * @return true if successfully applied, false if the request does not exist + */ +u32 Quake_SetSpeed(s16 index, s16 speed) { + QuakeRequest* req = Quake_GetRequest(index); if (req != NULL) { - req->speed = value; + req->speed = speed; return true; } return false; } -u32 Quake_SetCountdown(s16 idx, s16 value) { - QuakeRequest* req = Quake_GetRequest(idx); +/** + * @param index quake request index to apply + * @param duration Number of frames to apply the quake + * @return true if successfully applied, false if the request does not exist + */ +u32 Quake_SetDuration(s16 index, s16 duration) { + QuakeRequest* req = Quake_GetRequest(index); if (req != NULL) { - req->countdown = value; - req->countdownMax = req->countdown; + req->duration = req->timer = duration; return true; } return false; } -s16 Quake_GetCountdown(s16 idx) { - QuakeRequest* req = Quake_GetRequest(idx); +/** + * @param index quake request index to get + * @return Number of frames until the quake is finished + */ +s16 Quake_GetTimeLeft(s16 index) { + QuakeRequest* req = Quake_GetRequest(index); if (req != NULL) { - return req->countdown; + return req->timer; } return 0; } -u32 Quake_SetQuakeValues(s16 idx, s16 y, s16 x, s16 zoom, s16 rotZ) { - QuakeRequest* req = Quake_GetRequest(idx); +/** + * @param index quake request index to apply + * @param y Apply up/down shake + * @param x Apply left/right shake + * @param fov Apply zooming in/out shake (binang) + * @param roll Apply rolling shake (binang) + * @return true if successfully applied, false if the request does not exist + */ +u32 Quake_SetPerturbations(s16 index, s16 y, s16 x, s16 fov, s16 roll) { + QuakeRequest* req = Quake_GetRequest(index); if (req != NULL) { req->y = y; req->x = x; - req->zoom = zoom; - req->rotZ = rotZ; + req->fov = fov; + // Visual roll is indirectly achieved by offsetting the pitch in calculating the camera "Up" vector + req->upPitchOffset = roll; return true; } return false; } -u32 Quake_SetUnkValues(s16 idx, s16 arg1, SubQuakeRequest14 arg2) { - QuakeRequest* req = Quake_GetRequest(idx); +/** + * @param index quake request index to apply + * @param isRelativeToScreen Is the quake applied relative to the screen or in absolute world coordinates + * @param orientation orient the x/y shake to a different direction + * @return true if successfully applied, false if the request does not exist + */ +u32 Quake_SetOrientation(s16 index, s16 isRelativeToScreen, Vec3s orientation) { + QuakeRequest* req = Quake_GetRequest(index); if (req != NULL) { - req->unk_1C = arg1; - - req->unk_14 = arg2; + req->isRelativeToScreen = isRelativeToScreen; + req->orientation = orientation; return true; } return false; @@ -283,20 +365,20 @@ u32 Quake_SetUnkValues(s16 idx, s16 arg1, SubQuakeRequest14 arg2) { void Quake_Init(void) { s16 i; - for (i = 0; i < ARRAY_COUNT(sQuakeRequest); i++) { - sQuakeRequest[i].callbackIdx = 0; - sQuakeRequest[i].countdown = 0; + for (i = 0; i < ARRAY_COUNT(sQuakeRequests); i++) { + sQuakeRequests[i].type = QUAKE_TYPE_NONE; + sQuakeRequests[i].timer = 0; } - D_80126250 = 1; + sQuakeUnused = 1; sQuakeRequestCount = 0; } -s16 Quake_Add(Camera* camera, u32 callbackIdx) { - return Quake_AddImpl(camera, callbackIdx)->randIdx; +s16 Quake_Request(Camera* camera, u32 type) { + return Quake_RequestImpl(camera, type)->index; } -u32 Quake_RemoveFromIdx(s16 idx) { - QuakeRequest* req = Quake_GetRequest(idx); +u32 Quake_RemoveRequest(s16 index) { + QuakeRequest* req = Quake_GetRequest(index); if (req != NULL) { Quake_Remove(req); @@ -305,101 +387,120 @@ u32 Quake_RemoveFromIdx(s16 idx) { return false; } -s16 Quake_Calc(Camera* camera, QuakeCamCalc* camData) { - f32 max; - f32 max2; - QuakeRequest* req; +s16 (*sQuakeCallbacks[])(QuakeRequest*, ShakeInfo*) = { + NULL, // QUAKE_TYPE_NONE + Quake_CallbackType1, // QUAKE_TYPE_1 + Quake_CallbackType2, // QUAKE_TYPE_2 + Quake_CallbackType3, // QUAKE_TYPE_3 + Quake_CallbackType4, // QUAKE_TYPE_4 + Quake_CallbackType5, // QUAKE_TYPE_5 + Quake_CallbackType6, // QUAKE_TYPE_6 +}; + +s16 Quake_Update(Camera* camera, ShakeInfo* camShake) { + f32 maxCurr; + f32 maxNext; ShakeInfo shake; + QuakeRequest* req; f32 absSpeedDiv; - s16* temp; - u32 pad2; - s32 idx; - s32 ret; - u32 eq; - Vec3f vec; - PlayState* play; - - play = camera->play; - vec.x = 0.0f; - vec.y = 0.0f; - vec.z = 0.0f; - camData->rotZ = 0; - camData->unk_1A = 0; - camData->zoom = 0; - camData->atOffset.x = 0.0f; - camData->atOffset.y = 0.0f; - camData->atOffset.z = 0.0f; - camData->eyeOffset.x = 0.0f; - camData->eyeOffset.y = 0.0f; - camData->eyeOffset.z = 0.0f; - camData->unk_20 = 0.0f; + s16* camId; + s32 index; + s32 numQuakesApplied; + u32 isDifferentCamId; + Vec3f zeroVec; + PlayState* play = camera->play; + + zeroVec.x = 0.0f; + zeroVec.y = 0.0f; + zeroVec.z = 0.0f; + + camShake->upPitchOffset = 0; + camShake->upYawOffset = 0; + camShake->fovOffset = 0; + + camShake->atOffset.x = 0.0f; + camShake->atOffset.y = 0.0f; + camShake->atOffset.z = 0.0f; + + camShake->eyeOffset.x = 0.0f; + camShake->eyeOffset.y = 0.0f; + camShake->eyeOffset.z = 0.0f; + + camShake->maxOffset = 0.0f; if (sQuakeRequestCount == 0) { return 0; } - ret = 0; - for (idx = 0; idx < ARRAY_COUNT(sQuakeRequest); idx++) { - req = &sQuakeRequest[idx]; - if (req->callbackIdx != 0) { - if (play->cameraPtrs[req->camPtrIdx] == NULL) { - osSyncPrintf(VT_COL(YELLOW, BLACK) "quake: stopped! 'coz camera [%d] killed!!\n" VT_RST, - req->camPtrIdx); - Quake_Remove(req); - } else { - temp = &camera->camId; - eq = req->cam->camId != *temp; - absSpeedDiv = ABS(req->speed) / (f32)0x8000; - if (sQuakeCallbacks[req->callbackIdx](req, &shake) == 0) { - Quake_Remove(req); - } else if (eq == 0) { - if (fabsf(camData->atOffset.x) < fabsf(shake.vec1.x)) { - camData->atOffset.x = shake.vec1.x; - } - if (fabsf(camData->atOffset.y) < fabsf(shake.vec1.y)) { - camData->atOffset.y = shake.vec1.y; - } - if (fabsf(camData->atOffset.z) < fabsf(shake.vec1.z)) { - camData->atOffset.z = shake.vec1.z; - } - if (fabsf(camData->eyeOffset.x) < fabsf(shake.vec2.x)) { - camData->eyeOffset.x = shake.vec2.x; - } - if (fabsf(camData->eyeOffset.y) < fabsf(shake.vec2.y)) { - camData->eyeOffset.y = shake.vec2.y; - } - if (fabsf(camData->eyeOffset.z) < fabsf(shake.vec2.z)) { - camData->eyeOffset.z = shake.vec2.z; - } - if (camData->rotZ < shake.rotZ) { - camData->rotZ = shake.rotZ; - camData->unk_1A = shake.unk_1A; - } - if (camData->zoom < shake.zoom) { - camData->zoom = shake.zoom; - } - - max = OLib_Vec3fDist(&shake.vec1, &vec) * absSpeedDiv; - max2 = OLib_Vec3fDist(&shake.vec2, &vec) * absSpeedDiv; - if (max < max2) { - max = max2; - } - max2 = (camData->rotZ * 0.005f) * absSpeedDiv; - if (max < max2) { - max = max2; - } - max2 = (camData->zoom * 0.005f) * absSpeedDiv; - if (max < max2) { - max = max2; - } - if (camData->unk_20 < max) { - camData->unk_20 = max; - } - - ret++; - } - } + numQuakesApplied = 0; + for (index = 0; index < ARRAY_COUNT(sQuakeRequests); index++) { + req = &sQuakeRequests[index]; + if (req->type == QUAKE_TYPE_NONE) { + continue; + } + + if (play->cameraPtrs[req->camId] == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "quake: stopped! 'coz camera [%d] killed!!\n" VT_RST, req->camId); + Quake_Remove(req); + continue; + } + + camId = &camera->camId; + isDifferentCamId = req->cam->camId != *camId; + absSpeedDiv = (f32)ABS(req->speed) / 0x8000; + + if (sQuakeCallbacks[req->type](req, &shake) == 0) { + // Quake has reached the end of its timer. + Quake_Remove(req); + continue; + } + + if (isDifferentCamId) { + // Quake is attached to a different camId + continue; + } + + if (fabsf(camShake->atOffset.x) < fabsf(shake.atOffset.x)) { + camShake->atOffset.x = shake.atOffset.x; + } + if (fabsf(camShake->atOffset.y) < fabsf(shake.atOffset.y)) { + camShake->atOffset.y = shake.atOffset.y; + } + if (fabsf(camShake->atOffset.z) < fabsf(shake.atOffset.z)) { + camShake->atOffset.z = shake.atOffset.z; + } + if (fabsf(camShake->eyeOffset.x) < fabsf(shake.eyeOffset.x)) { + camShake->eyeOffset.x = shake.eyeOffset.x; + } + if (fabsf(camShake->eyeOffset.y) < fabsf(shake.eyeOffset.y)) { + camShake->eyeOffset.y = shake.eyeOffset.y; } + if (fabsf(camShake->eyeOffset.z) < fabsf(shake.eyeOffset.z)) { + camShake->eyeOffset.z = shake.eyeOffset.z; + } + if (camShake->upPitchOffset < shake.upPitchOffset) { + camShake->upPitchOffset = shake.upPitchOffset; + camShake->upYawOffset = shake.upYawOffset; + } + if (camShake->fovOffset < shake.fovOffset) { + camShake->fovOffset = shake.fovOffset; + } + + maxCurr = OLib_Vec3fDist(&shake.atOffset, &zeroVec) * absSpeedDiv; + maxNext = OLib_Vec3fDist(&shake.eyeOffset, &zeroVec) * absSpeedDiv; + maxCurr = CLAMP_MIN(maxCurr, maxNext); + + maxNext = camShake->upPitchOffset * (1.0f / 200.0f) * absSpeedDiv; + maxCurr = CLAMP_MIN(maxCurr, maxNext); + + maxNext = camShake->fovOffset * (1.0f / 200.0f) * absSpeedDiv; + maxCurr = CLAMP_MIN(maxCurr, maxNext); + + if (camShake->maxOffset < maxCurr) { + camShake->maxOffset = maxCurr; + } + + numQuakesApplied++; } - return ret; + return numQuakesApplied; } diff --git a/src/code/z_room.c b/src/code/z_room.c index add510138..953739f2a 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -389,7 +389,7 @@ void Room_DrawImageSingle(PlayState* play, Room* room, u32 flags) { Vec3f quakeOffset; gfx = POLY_OPA_DISP; - Camera_GetSkyboxOffset(&quakeOffset, activeCam); + Camera_GetQuakeOffset(&quakeOffset, activeCam); Room_DrawBackground2D(&gfx, roomShape->source, roomShape->tlut, roomShape->width, roomShape->height, roomShape->fmt, roomShape->siz, roomShape->tlutMode, roomShape->tlutCount, (quakeOffset.x + quakeOffset.z) * 1.2f + quakeOffset.y * 0.6f, @@ -487,7 +487,7 @@ void Room_DrawImageMulti(PlayState* play, Room* room, u32 flags) { Vec3f quakeOffset; gfx = POLY_OPA_DISP; - Camera_GetSkyboxOffset(&quakeOffset, activeCam); + Camera_GetQuakeOffset(&quakeOffset, activeCam); Room_DrawBackground2D(&gfx, bgEntry->source, bgEntry->tlut, bgEntry->width, bgEntry->height, bgEntry->fmt, bgEntry->siz, bgEntry->tlutMode, bgEntry->tlutCount, (quakeOffset.x + quakeOffset.z) * 1.2f + quakeOffset.y * 0.6f, diff --git a/src/code/z_scene_table.c b/src/code/z_scene_table.c index 67d071ece..a95131420 100644 --- a/src/code/z_scene_table.c +++ b/src/code/z_scene_table.c @@ -1,4 +1,5 @@ #include "global.h" +#include "quake.h" #include "assets/scenes/overworld/spot00/spot00_scene.h" #include "assets/scenes/overworld/spot00/spot00_room_0.h" @@ -585,20 +586,20 @@ void Scene_DrawConfigGanonCastleExterior(PlayState* play) { // Screen Shake for Ganon's Tower Collapse void func_8009BEEC(PlayState* play) { - s32 var; + s32 quakeIndex; if (play->gameplayFrames % 128 == 13) { - var = Quake_Add(GET_ACTIVE_CAM(play), 2); - Quake_SetSpeed(var, 10000); - Quake_SetQuakeValues(var, 4, 0, 0, 0); - Quake_SetCountdown(var, 127); + quakeIndex = Quake_Request(GET_ACTIVE_CAM(play), QUAKE_TYPE_2); + Quake_SetSpeed(quakeIndex, 10000); + Quake_SetPerturbations(quakeIndex, 4, 0, 0, 0); + Quake_SetDuration(quakeIndex, 127); } if ((play->gameplayFrames % 64 == 0) && (Rand_ZeroOne() > 0.6f)) { - var = Quake_Add(GET_ACTIVE_CAM(play), 3); - Quake_SetSpeed(var, 32000.0f + (Rand_ZeroOne() * 3000.0f)); - Quake_SetQuakeValues(var, 10.0f - (Rand_ZeroOne() * 9.0f), 0, 0, 0); - Quake_SetCountdown(var, 48.0f - (Rand_ZeroOne() * 15.0f)); + quakeIndex = Quake_Request(GET_ACTIVE_CAM(play), QUAKE_TYPE_3); + Quake_SetSpeed(quakeIndex, 32000.0f + (Rand_ZeroOne() * 3000.0f)); + Quake_SetPerturbations(quakeIndex, 10.0f - (Rand_ZeroOne() * 9.0f), 0, 0, 0); + Quake_SetDuration(quakeIndex, 48.0f - (Rand_ZeroOne() * 15.0f)); } } |
