diff --git a/include/functions.h b/include/functions.h index f260cc29cc..8a3e3f526b 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1352,13 +1352,13 @@ void func_800AA4A8(View* view, f32 fovy, f32 near, f32 far); void func_800AA4E0(View* view, f32* fovy, f32* near, f32* far); void View_SetViewport(View* view, Viewport* viewport); void View_GetViewport(View* view, Viewport* viewport); -void func_800AA76C(View* view, f32 arg1, f32 arg2, f32 arg3); -void func_800AA78C(View* view, f32 arg1, f32 arg2, f32 arg3); -s32 func_800AA7AC(View* view, f32 arg1); -void func_800AA7B8(View* view); -void func_800AA814(View* view); -void func_800AA840(View* view, Vec3f vec1, Vec3f vec2, f32 arg3); -s32 func_800AA890(View* view, Mtx* mtx); +void View_SetDistortionOrientation(View* view, f32 rotX, f32 rotY, f32 rotZ); +void View_SetDistortionScale(View* view, f32 scaleX, f32 scaleY, f32 scaleZ); +s32 View_SetDistortionSpeed(View* view, f32 speed); +void View_InitDistortion(View* view); +void View_ClearDistortion(View* view); +void View_SetDistortion(View* view, Vec3f orientation, Vec3f scale, f32 speed); +s32 View_StepDistortion(View* view, Mtx* projectionMtx); void func_800AAA50(View* view, s32 arg1); s32 func_800AAA9C(View* view); s32 func_800AB0A8(View* view); diff --git a/include/z64.h b/include/z64.h index 0c07a192ba..c97508796c 100644 --- a/include/z64.h +++ b/include/z64.h @@ -178,11 +178,11 @@ typedef struct { /* 0x00A0 */ Mtx viewing; /* 0x00E0 */ Mtx* projectionPtr; /* 0x00E4 */ Mtx* viewingPtr; - /* 0x00E8 */ Vec3f unk_E8; - /* 0x00F4 */ Vec3f unk_F4; - /* 0x0100 */ f32 unk_100; - /* 0x0104 */ Vec3f unk_104; - /* 0x0110 */ Vec3f unk_110; + /* 0x00E8 */ Vec3f distortionOrientation; + /* 0x00F4 */ Vec3f distortionScale; + /* 0x0100 */ f32 distortionSpeed; + /* 0x0104 */ Vec3f curDistortionOrientation; + /* 0x0110 */ Vec3f curDistortionScale; /* 0x011C */ u16 normal; // used to normalize the projection matrix /* 0x0120 */ s32 flags; /* 0x0124 */ s32 unk_124; diff --git a/include/z64camera.h b/include/z64camera.h index 86f96579a1..9d737455c6 100644 --- a/include/z64camera.h +++ b/include/z64camera.h @@ -1202,8 +1202,8 @@ typedef struct { /* 0x14A */ s16 unk_14A; /* 0x14C */ s16 unk_14C; /* 0x14E */ s16 childCamIdx; - /* 0x150 */ s16 unk_150; - /* 0x152 */ s16 unk_152; + /* 0x150 */ s16 waterDistortionTimer; + /* 0x152 */ s16 distortionFlags; /* 0x154 */ s16 prevSetting; /* 0x156 */ s16 nextCamDataIdx; /* 0x158 */ s16 nextBGCheckId; diff --git a/src/code/z_camera.c b/src/code/z_camera.c index ac4eac6fc6..62cc90acf4 100644 --- a/src/code/z_camera.c +++ b/src/code/z_camera.c @@ -6,7 +6,7 @@ s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags); s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags); s32 Camera_QRegInit(void); -s32 Camera_CheckWater(Camera* camera); +s32 Camera_UpdateWater(Camera* camera); #define RELOAD_PARAMS \ (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14 || R_RELOAD_CAM_PARAMS) @@ -23,6 +23,12 @@ s32 Camera_CheckWater(Camera* camera); #define FLG_ADJSLOPE (1 << 0) #define FLG_OFFGROUND (1 << 7) +#define DISTORTION_HOT_ROOM (1 << 0) +#define DISTORTION_UNDERWATER_WEAK (1 << 1) +#define DISTORTION_UNDERWATER_MEDIUM (1 << 2) +#define DISTORTION_UNDERWATER_STRONG (1 << 3) +#define DISTORTION_UNDERWATER_FISHING (1 << 4) + #include "z_camera_data.c" /*===============================================================*/ @@ -968,7 +974,7 @@ s32 func_80045B08(Camera* camera, VecSph* eyeAtDir, f32 yExtra, s16 arg3) { f32 phi_f2; Vec3f posOffsetTarget; Vec3f atTarget; - f32 sp38; // unused + f32 pad; f32 temp_ret; PosRot* playerPosRot = &camera->playerPosRot; @@ -6954,7 +6960,7 @@ void Camera_InitPlayerSettings(Camera* camera, Player* player) { osSyncPrintf(VT_FGCOL(BLUE) "camera: personalize ---" VT_RST "\n"); if (camera->thisIdx == MAIN_CAM) { - Camera_CheckWater(camera); + Camera_UpdateWater(camera); } } @@ -7062,7 +7068,7 @@ void Camera_PrintSettings(Camera* camera) { } } -s32 Camera_CheckWater(Camera* camera) { +s32 Camera_UpdateWater(Camera* camera) { f32 waterY; s16 newQuakeId; s32 waterLightsIndex; @@ -7139,7 +7145,7 @@ s32 Camera_CheckWater(Camera* camera) { camera->unk_14C |= 0x100; osSyncPrintf("kankyo changed water, sound on\n"); Environment_EnableUnderwaterLights(camera->globalCtx, waterLightsIndex); - camera->unk_150 = 0x50; + camera->waterDistortionTimer = 80; } Audio_SetExtraFilter(0x20); @@ -7158,13 +7164,13 @@ s32 Camera_CheckWater(Camera* camera) { } } - if (camera->unk_150 > 0) { - camera->unk_150--; - camera->unk_152 |= 8; - } else if (camera->globalCtx->sceneNum == 0x49) { - camera->unk_152 |= 0x10; + if (camera->waterDistortionTimer > 0) { + camera->waterDistortionTimer--; + camera->distortionFlags |= DISTORTION_UNDERWATER_STRONG; + } else if (camera->globalCtx->sceneNum == SCENE_TURIBORI) { + camera->distortionFlags |= DISTORTION_UNDERWATER_FISHING; } else { - camera->unk_152 |= 2; + camera->distortionFlags |= DISTORTION_UNDERWATER_WEAK; } } else { if (camera->unk_14C & 0x100) { @@ -7174,21 +7180,18 @@ s32 Camera_CheckWater(Camera* camera) { if (*quakeId != 0) { Quake_RemoveFromIdx(*quakeId); } - camera->unk_150 = 0; - camera->unk_152 = 0; + camera->waterDistortionTimer = 0; + camera->distortionFlags = 0; } Audio_SetExtraFilter(0); } //! @bug: doesn't always return a value, but sometimes does. } -/** - * Sets the room to be hot camera quake flag - */ -s32 Camera_SetRoomHotFlag(Camera* camera) { - camera->unk_152 &= ~1; +s32 Camera_UpdateHotRoom(Camera* camera) { + camera->distortionFlags &= ~DISTORTION_HOT_ROOM; if (camera->globalCtx->roomCtx.curRoom.unk_02 == 3) { - camera->unk_152 |= 1; + camera->distortionFlags |= DISTORTION_HOT_ROOM; } return 1; @@ -7223,80 +7226,87 @@ s32 Camera_DbgChangeMode(Camera* camera) { return true; } -void func_80058E8C(Camera* camera) { - static s16 D_8011DB08 = 0x3F0; - static s16 D_8011DB0C = 0x156; - s32 pad3; - f32 sp60; - s32 pad; - s32 pad1; - s32 pad4; - f32 phi_f2; - s32 pad2; - f32 phi_f0; - f32 phi_f20; - f32 sp40; - f32 sp3C; - f32 sp38; - f32 sp34; +void Camera_UpdateDistortion(Camera* camera) { + static s16 depthPhase = 0x3F0; + static s16 screenPlanePhase = 0x156; + f32 scaleFactor; + f32 speedFactor; + f32 depthPhaseStep; + f32 screenPlanePhaseStep; + s32 pad[5]; + f32 xScale; + f32 yScale; + f32 zScale; + f32 speed; - if (camera->unk_152 != 0) { - if (camera->unk_152 & 4) { - phi_f0 = 0.0f; - phi_f2 = 170.0f; - sp3C = 0.01f; - sp40 = -0.01f; - sp38 = 0.0f; - sp34 = 0.6f; - phi_f20 = camera->unk_150 / 60.0f; - sp60 = 1.0f; - } else if (camera->unk_152 & 8) { - phi_f0 = 248.0f; - phi_f2 = -90.0f; - sp38 = 0.2f; - sp34 = 0.2f; - sp40 = -0.3f; - sp3C = 0.3f; - phi_f20 = camera->unk_150 / 80.0f; - sp60 = 1.0f; - } else if (camera->unk_152 & 2) { - phi_f0 = 359.2f; - phi_f2 = -18.5f; - sp40 = 0.09f; - sp38 = 0.01f; - sp3C = 0.09f; - sp34 = 0.08f; - phi_f20 = + if (camera->distortionFlags != 0) { + if (camera->distortionFlags & DISTORTION_UNDERWATER_MEDIUM) { + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 170.0f; + + xScale = -0.01f; + yScale = 0.01f; + zScale = 0.0f; + + speed = 0.6f; + scaleFactor = camera->waterDistortionTimer / 60.0f; + speedFactor = 1.0f; + } else if (camera->distortionFlags & DISTORTION_UNDERWATER_STRONG) { + depthPhaseStep = 248.0f; + screenPlanePhaseStep = -90.0f; + + xScale = -0.3f; + yScale = 0.3f; + zScale = 0.2f; + + speed = 0.2f; + scaleFactor = camera->waterDistortionTimer / 80.0f; + speedFactor = 1.0f; + } else if (camera->distortionFlags & DISTORTION_UNDERWATER_WEAK) { + depthPhaseStep = 359.2f; + screenPlanePhaseStep = -18.5f; + + xScale = 0.09f; + yScale = 0.09f; + zScale = 0.01f; + + speed = 0.08f; + scaleFactor = (((camera->waterYPos - camera->eye.y) > 150.0f ? 1.0f : (camera->waterYPos - camera->eye.y) / 150.0f) * 0.45f) + (camera->speedRatio * 0.45f); - sp60 = phi_f20; - } else if (camera->unk_152 & 1) { - // hot room flag - phi_f2 = 150.0f; - phi_f0 = 0.0f; - sp3C = 0.01f; - sp38 = 0.01f; - sp40 = -0.01f; - sp34 = 0.6f; - sp60 = 1.0f; - phi_f20 = 1.0f; + speedFactor = scaleFactor; + } else if (camera->distortionFlags & DISTORTION_HOT_ROOM) { + // Gives the hot-room a small mirage-like appearance + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 150.0f; + xScale = -0.01f; + yScale = 0.01f; + zScale = 0.01f; + + speed = 0.6f; + speedFactor = 1.0f; + scaleFactor = 1.0f; } else { + // DISTORTION_UNDERWATER_FISHING return; } - D_8011DB08 += DEGF_TO_BINANG(phi_f0); - D_8011DB0C += DEGF_TO_BINANG(phi_f2); - Math_CosS(D_8011DB08); - Math_SinS(D_8011DB08); - Math_SinS(D_8011DB0C); - func_800AA76C(&camera->globalCtx->view, 0.0f, 0.0f, 0.0f); - func_800AA78C(&camera->globalCtx->view, Math_SinS(D_8011DB0C) * (sp40 * phi_f20) + 1.0f, - Math_CosS(D_8011DB0C) * (sp3C * phi_f20) + 1.0f, Math_CosS(D_8011DB08) * (sp38 * phi_f20) + 1.0f); - func_800AA7AC(&camera->globalCtx->view, sp34 * sp60); + + depthPhase += DEGF_TO_BINANG(depthPhaseStep); + screenPlanePhase += DEGF_TO_BINANG(screenPlanePhaseStep); + + View_SetDistortionOrientation(&camera->globalCtx->view, Math_CosS(depthPhase) * 0.0f, Math_SinS(depthPhase) * 0.0f, + Math_SinS(screenPlanePhase) * 0.0f); + View_SetDistortionScale(&camera->globalCtx->view, Math_SinS(screenPlanePhase) * (xScale * scaleFactor) + 1.0f, + Math_CosS(screenPlanePhase) * (yScale * scaleFactor) + 1.0f, + Math_CosS(depthPhase) * (zScale * scaleFactor) + 1.0f); + View_SetDistortionSpeed(&camera->globalCtx->view, speed * speedFactor); + camera->unk_14C |= 0x40; + } else if (camera->unk_14C & 0x40) { - func_800AA814(&camera->globalCtx->view); + View_ClearDistortion(&camera->globalCtx->view); camera->unk_14C &= ~0x40; } } @@ -7365,8 +7375,8 @@ Vec3s Camera_Update(Camera* camera) { if (sOOBTimer < 200) { if (camera->status == CAM_STAT_ACTIVE) { - Camera_CheckWater(camera); - Camera_SetRoomHotFlag(camera); + Camera_UpdateWater(camera); + Camera_UpdateHotRoom(camera); } if (!(camera->unk_14C & 4)) { @@ -7506,7 +7516,8 @@ Vec3s Camera_Update(Camera* camera) { camera->skyboxOffset = quake.eyeOffset; - func_80058E8C(camera); + Camera_UpdateDistortion(camera); + if ((camera->globalCtx->sceneNum == SCENE_SPOT00) && (camera->fov < 59.0f)) { View_SetScale(&camera->globalCtx->view, 0.79f); } else { diff --git a/src/code/z_scene_table.c b/src/code/z_scene_table.c index da0505731c..8aff9fcd23 100644 --- a/src/code/z_scene_table.c +++ b/src/code/z_scene_table.c @@ -2312,12 +2312,14 @@ void func_8009FE58(GlobalContext* globalCtx) { D_8012A3A0 += 1820; temp = 0.020000001f; - func_800AA76C(&globalCtx->view, ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_CosS(D_8012A39C), - ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(D_8012A39C), - ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(D_8012A3A0)); - func_800AA78C(&globalCtx->view, 1.f + (0.79999995f * temp * Math_SinS(D_8012A3A0)), - 1.f + (0.39999998f * temp * Math_CosS(D_8012A3A0)), 1.f + (1 * temp * Math_CosS(D_8012A39C))); - func_800AA7AC(&globalCtx->view, 0.95f); + View_SetDistortionOrientation(&globalCtx->view, + ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_CosS(D_8012A39C), + ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(D_8012A39C), + ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(D_8012A3A0)); + View_SetDistortionScale(&globalCtx->view, 1.f + (0.79999995f * temp * Math_SinS(D_8012A3A0)), + 1.f + (0.39999998f * temp * Math_CosS(D_8012A3A0)), + 1.f + (1 * temp * Math_CosS(D_8012A39C))); + View_SetDistortionSpeed(&globalCtx->view, 0.95f); switch (globalCtx->roomCtx.unk_74[0]) { case 0: diff --git a/src/code/z_view.c b/src/code/z_view.c index 74c554c551..340d15aea0 100644 --- a/src/code/z_view.c +++ b/src/code/z_view.c @@ -59,7 +59,7 @@ void View_Init(View* view, GraphicsContext* gfxCtx) { view->unk_124 = 0; view->flags = 1 | 2 | 4; - func_800AA7B8(view); + View_InitDistortion(view); } void func_800AA358(View* view, Vec3f* eye, Vec3f* lookAt, Vec3f* up) { @@ -172,81 +172,87 @@ void func_800AA550(View* view) { CLOSE_DISPS(gfxCtx, "../z_view.c", 472); } -void func_800AA76C(View* view, f32 x, f32 y, f32 z) { - view->unk_E8.x = x; - view->unk_E8.y = y; - view->unk_E8.z = z; +void View_SetDistortionOrientation(View* view, f32 rotX, f32 rotY, f32 rotZ) { + view->distortionOrientation.x = rotX; + view->distortionOrientation.y = rotY; + view->distortionOrientation.z = rotZ; } -void func_800AA78C(View* view, f32 x, f32 y, f32 z) { - view->unk_F4.x = x; - view->unk_F4.y = y; - view->unk_F4.z = z; +void View_SetDistortionScale(View* view, f32 scaleX, f32 scaleY, f32 scaleZ) { + view->distortionScale.x = scaleX; + view->distortionScale.y = scaleY; + view->distortionScale.z = scaleZ; } -s32 func_800AA7AC(View* view, f32 arg1) { - view->unk_100 = arg1; +s32 View_SetDistortionSpeed(View* view, f32 speed) { + view->distortionSpeed = speed; } -void func_800AA7B8(View* view) { - view->unk_E8.x = 0.0f; - view->unk_E8.y = 0.0f; - view->unk_E8.z = 0.0f; - view->unk_F4.x = 1.0f; - view->unk_F4.y = 1.0f; - view->unk_F4.z = 1.0f; - view->unk_104 = view->unk_E8; - view->unk_110 = view->unk_F4; - view->unk_100 = 0.0f; +void View_InitDistortion(View* view) { + view->distortionOrientation.x = 0.0f; + view->distortionOrientation.y = 0.0f; + view->distortionOrientation.z = 0.0f; + view->distortionScale.x = 1.0f; + view->distortionScale.y = 1.0f; + view->distortionScale.z = 1.0f; + view->curDistortionOrientation = view->distortionOrientation; + view->curDistortionScale = view->distortionScale; + view->distortionSpeed = 0.0f; } -void func_800AA814(View* view) { - view->unk_E8.x = 0.0f; - view->unk_E8.y = 0.0f; - view->unk_E8.z = 0.0f; - view->unk_F4.x = 1.0f; - view->unk_F4.y = 1.0f; - view->unk_F4.z = 1.0f; - view->unk_100 = 1.0f; +void View_ClearDistortion(View* view) { + view->distortionOrientation.x = 0.0f; + view->distortionOrientation.y = 0.0f; + view->distortionOrientation.z = 0.0f; + view->distortionScale.x = 1.0f; + view->distortionScale.y = 1.0f; + view->distortionScale.z = 1.0f; + view->distortionSpeed = 1.0f; } -void func_800AA840(View* view, Vec3f vec1, Vec3f vec2, f32 arg3) { - view->unk_E8 = vec1; - view->unk_F4 = vec2; - view->unk_100 = arg3; +void View_SetDistortion(View* view, Vec3f orientation, Vec3f scale, f32 speed) { + view->distortionOrientation = orientation; + view->distortionScale = scale; + view->distortionSpeed = speed; } -s32 func_800AA890(View* view, Mtx* mtx) { - MtxF mf; +s32 View_StepDistortion(View* view, Mtx* projectionMtx) { + MtxF projectionMtxF; - if (view->unk_100 == 0.0f) { - return 0; - } else if (view->unk_100 == 1.0f) { - view->unk_104 = view->unk_E8; - view->unk_110 = view->unk_F4; - view->unk_100 = 0.0f; + if (view->distortionSpeed == 0.0f) { + return false; + } else if (view->distortionSpeed == 1.0f) { + view->curDistortionOrientation = view->distortionOrientation; + view->curDistortionScale = view->distortionScale; + view->distortionSpeed = 0.0f; } else { - view->unk_104.x += ((view->unk_E8.x - view->unk_104.x) * view->unk_100); - view->unk_104.y += ((view->unk_E8.y - view->unk_104.y) * view->unk_100); - view->unk_104.z += ((view->unk_E8.z - view->unk_104.z) * view->unk_100); + view->curDistortionOrientation.x = + F32_LERPIMP(view->curDistortionOrientation.x, view->distortionOrientation.x, view->distortionSpeed); + view->curDistortionOrientation.y = + F32_LERPIMP(view->curDistortionOrientation.y, view->distortionOrientation.y, view->distortionSpeed); + view->curDistortionOrientation.z = + F32_LERPIMP(view->curDistortionOrientation.z, view->distortionOrientation.z, view->distortionSpeed); - view->unk_110.x += ((view->unk_F4.x - view->unk_110.x) * view->unk_100); - view->unk_110.y += ((view->unk_F4.y - view->unk_110.y) * view->unk_100); - view->unk_110.z += ((view->unk_F4.z - view->unk_110.z) * view->unk_100); + view->curDistortionScale.x = + F32_LERPIMP(view->curDistortionScale.x, view->distortionScale.x, view->distortionSpeed); + view->curDistortionScale.y = + F32_LERPIMP(view->curDistortionScale.y, view->distortionScale.y, view->distortionSpeed); + view->curDistortionScale.z = + F32_LERPIMP(view->curDistortionScale.z, view->distortionScale.z, view->distortionSpeed); } - Matrix_MtxToMtxF(mtx, &mf); - Matrix_Put(&mf); - Matrix_RotateX(view->unk_104.x, MTXMODE_APPLY); - Matrix_RotateY(view->unk_104.y, MTXMODE_APPLY); - Matrix_RotateZ(view->unk_104.z, MTXMODE_APPLY); - Matrix_Scale(view->unk_110.x, view->unk_110.y, view->unk_110.z, MTXMODE_APPLY); - Matrix_RotateZ(-view->unk_104.z, MTXMODE_APPLY); - Matrix_RotateY(-view->unk_104.y, MTXMODE_APPLY); - Matrix_RotateX(-view->unk_104.x, MTXMODE_APPLY); - Matrix_ToMtx(mtx, "../z_view.c", 566); + Matrix_MtxToMtxF(projectionMtx, &projectionMtxF); + Matrix_Put(&projectionMtxF); + Matrix_RotateX(view->curDistortionOrientation.x, MTXMODE_APPLY); + Matrix_RotateY(view->curDistortionOrientation.y, MTXMODE_APPLY); + Matrix_RotateZ(view->curDistortionOrientation.z, MTXMODE_APPLY); + Matrix_Scale(view->curDistortionScale.x, view->curDistortionScale.y, view->curDistortionScale.z, MTXMODE_APPLY); + Matrix_RotateZ(-view->curDistortionOrientation.z, MTXMODE_APPLY); + Matrix_RotateY(-view->curDistortionOrientation.y, MTXMODE_APPLY); + Matrix_RotateX(-view->curDistortionOrientation.x, MTXMODE_APPLY); + Matrix_ToMtx(projectionMtx, "../z_view.c", 566); - return 1; + return true; } void func_800AAA50(View* view, s32 arg1) { @@ -319,7 +325,7 @@ s32 func_800AAA9C(View* view) { view->projection = *projection; - func_800AA890(view, projection); + View_StepDistortion(view, projection); gSPPerspNormalize(POLY_OPA_DISP++, view->normal); gSPMatrix(POLY_OPA_DISP++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);