summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2022-10-15 02:16:37 -0400
committerGitHub <noreply@github.com>2022-10-15 02:16:37 -0400
commit9675051377c95b95119c6f15c65b648c2f01726a (patch)
treea47579c36e5da393f3fb31a43b0534475bda9916 /src/code
parentd1d946a197e9be2e1f6219f494502d060ffc6e44 (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.c36
-rw-r--r--src/code/z_camera.c89
-rw-r--r--src/code/z_demo.c9
-rw-r--r--src/code/z_onepointdemo.c115
-rw-r--r--src/code/z_play.c9
-rw-r--r--src/code/z_quake.c617
-rw-r--r--src/code/z_room.c4
-rw-r--r--src/code/z_scene_table.c19
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));
}
}