diff --git a/include/z64camera.h b/include/z64camera.h index 7ecede994..53508fa57 100644 --- a/include/z64camera.h +++ b/include/z64camera.h @@ -921,6 +921,7 @@ struct Camera { /* 0x166 */ s16 prevCamDataIdx; /* 0x168 */ s16 csId; /* 0x16A */ s16 unk_16A; + /* 0x16C */ s16 startControlTimer; }; // size = 0x16C /** diff --git a/src/code/z_camera.cpp b/src/code/z_camera.cpp index e739ab8d2..55d1ef581 100644 --- a/src/code/z_camera.cpp +++ b/src/code/z_camera.cpp @@ -1338,9 +1338,51 @@ s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 acc velFactor = Camera_InterpolateCurve(0.5f, camera->speedRatio); yawUpdRate = 1.0f / camera->yawUpdateRateInv; +#ifndef FIZZLE_CAM return cur + (s16)(angDelta * velocity * velFactor * yawUpdRate); +#else + return cur + (s16)(angDelta * yawUpdRate); +#endif } +#ifdef FIZZLE_CAM +#include "../port/controller/controller.h" +#include "../port/player/players.h" + +s16 Camera_CalcControllerPitch(Camera* camera, s16 cur, s16 target, s16 arg3) { + f32 pitchUpdRate; + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + s16 rStickY = (s16)sControlInput->state().r_stick_y * (s16)-100; + if (rStickY != 0) { + camera->startControlTimer = 250;//10s + } + + pitchUpdRate = 1.0f / camera->pitchUpdateRateInv; + return cur + (s16)(rStickY * pitchUpdRate); +} + +s16 Camera_CalcControllerYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 accel) { + f32 yawUpdRate; + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + s16 rStickX = (s16)sControlInput->state().r_stick_x * (s16)-250; + if (rStickX != 0) { + camera->startControlTimer = 250;//10s + } + yawUpdRate = 1.0f / camera->yawUpdateRateInv; + return cur + (s16)(rStickX * yawUpdRate); +} + +void StepControlTimer(Camera* camera) +{ + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + if(camera->xzSpeed > 0.001f && (sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0)) { + camera->startControlTimer = 250;//10s + } + if(camera->startControlTimer > 0) { + camera->startControlTimer--; + } +} +#endif void func_80046E20(Camera* camera, VecSph* eyeAdjustment, f32 minDist, f32 arg3, f32* arg4, SwingAnimation* anim) { static CamColChk atEyeColChk; static CamColChk eyeAtColChk; @@ -1442,6 +1484,7 @@ s32 Camera_Noop(Camera* camera) { return true; } +// regular camera used in field s32 Camera_Normal1(Camera* camera) { Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; @@ -1507,6 +1550,9 @@ s32 Camera_Normal1(Camera* camera) { anim->swingYawTarget = atEyeGeo.yaw; sUpdateCameraDirection = 0; anim->startSwingTimer = OREG(50) + OREG(51); +#ifdef FIZZLE_CAM + camera->startControlTimer = OREG(50) + OREG(51); +#endif break; default: break; @@ -1518,10 +1564,13 @@ s32 Camera_Normal1(Camera* camera) { if (anim->unk_28 != 0) { anim->unk_28--; } - +#ifndef FIZZLE_CAM if (camera->xzSpeed > 0.001f) { anim->startSwingTimer = OREG(50) + OREG(51); } else if (anim->startSwingTimer > 0) { +#else + if (anim->startSwingTimer > 0) { +#endif if (anim->startSwingTimer > OREG(50)) { anim->swingYawTarget = atEyeGeo.yaw + (BINANG_SUB(BINANG_ROT180(camera->playerPosRot.rot.y), atEyeGeo.yaw) / anim->startSwingTimer); @@ -1590,7 +1639,7 @@ s32 Camera_Normal1(Camera* camera) { camera->dist = eyeAdjustment.r = Camera_ClampDist(camera, eyeAdjustment.r, norm1->distMin, norm1->distMax, anim->unk_28); - +#ifndef FIZZLE_CAM if (anim->startSwingTimer <= 0) { eyeAdjustment.pitch = atEyeNextGeo.pitch; eyeAdjustment.yaw = @@ -1607,7 +1656,22 @@ s32 Camera_Normal1(Camera* camera) { eyeAdjustment.pitch = Camera_CalcDefaultPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj); } - +#else + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + StepControlTimer(camera); + if (camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) { + eyeAdjustment.yaw = Camera_CalcControllerYaw(camera, atEyeNextGeo.yaw, camera->playerPosRot.rot.y, norm1->unk_14, sp94); + eyeAdjustment.pitch = Camera_CalcControllerPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj); + } else if (anim->swing.unk_18 != 0) { + eyeAdjustment.yaw = + Camera_LERPCeilS(anim->swing.unk_16, atEyeNextGeo.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + eyeAdjustment.pitch = + Camera_LERPCeilS(anim->swing.unk_14, atEyeNextGeo.pitch, 1.0f / camera->yawUpdateRateInv, 0xA); + } else if (anim->startSwingTimer <= 0 && camera->startControlTimer <= 0) { + eyeAdjustment.yaw = Camera_CalcDefaultYaw(camera, atEyeNextGeo.yaw, camera->playerPosRot.rot.y, norm1->unk_14, sp94); + eyeAdjustment.pitch = Camera_CalcDefaultPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj); + } +#endif // set eyeAdjustment pitch from 79.65 degrees to -85 degrees if (eyeAdjustment.pitch > 0x38A4) { eyeAdjustment.pitch = 0x38A4; @@ -1620,13 +1684,20 @@ s32 Camera_Normal1(Camera* camera) { if ((camera->status == CAM_STAT_ACTIVE) && (!(norm1->interfaceFlags & 0x10))) { anim->swingYawTarget = BINANG_ROT180(camera->playerPosRot.rot.y); if (anim->startSwingTimer > 0) { +#ifdef FIZZLE_CAM + anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f; +#endif func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing); } else { sp88 = *eyeNext; anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f; if (Camera_BGCheck(camera, at, &sp88)) { +#ifndef FIZZLE_CAM anim->swingYawTarget = atEyeNextGeo.yaw; anim->startSwingTimer = -1; +#else + func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing); +#endif } else { *eye = *eyeNext; } @@ -1669,6 +1740,7 @@ s32 Camera_Normal1(Camera* camera) { return 1; } +//rotating follow camera in specific locations s32 Camera_Normal2(Camera* camera) { Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; @@ -1956,13 +2028,34 @@ s32 Camera_Normal3(Camera* camera) { sp90 -= sp98; sp98 = sp98 + (sp94 * sp90); sp98 = (sp98 * phi_a0) / camera->yawUpdateRateInv; - +#ifndef FIZZLE_CAM sp84.yaw = fabsf(sp98) > (150.0f * (1.0f - camera->speedRatio)) ? (s16)(sp74.yaw + sp98) : sp74.yaw; - if (anim->yawTimer > 0) { - sp84.yaw += anim->yawUpdAmt; - anim->yawTimer--; + if(anim->yawTimer > 0) + { + sp84.yaw += anim->yawUpdAmt; + anim->yawTimer--; } +#else + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + StepControlTimer(camera); + if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) + { + sp84.yaw = Camera_CalcControllerYaw(camera, sp74.yaw, playerPosRot->rot.y, norm3->yOffset, 0.0f); + sp84.pitch = Camera_CalcControllerPitch(camera, sp74.pitch, norm3->pitchTarget, 0); + } + else if(camera->startControlTimer <= 0) + { + sp84.yaw = fabsf(sp98) > (150.0f * (1.0f - camera->speedRatio)) ? (s16)(sp74.yaw + sp98) : sp74.yaw; + + if(anim->yawTimer > 0) + { + sp84.yaw += anim->yawUpdAmt; + anim->yawTimer--; + } + } +#endif + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp84); @@ -2282,8 +2375,9 @@ s32 Camera_Jump1(Camera* camera) { OLib_Vec3fDiffToVecSphGeo(&eyeDiffTarget, at, eye); eyeDiffSph.r = Camera_LERPCeilF(eyeDiffTarget.r, eyeAtOffset.r, PCT(OREG(29)), 1.0f); + +#ifndef FIZZLE_CAM eyeDiffSph.pitch = Camera_LERPCeilS(eyeDiffTarget.pitch, eyeAtOffset.pitch, PCT(OREG(29)), 0xA); - if (anim->swing.unk_18) { eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); @@ -2293,7 +2387,23 @@ s32 Camera_Jump1(Camera* camera) { eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, camera->playerPosRot.rot.y, jump1->maxYawUpdate, 0.0f); } - +#else + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + StepControlTimer(camera); + if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) + { + eyeDiffSph.yaw = Camera_CalcControllerYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, 0, 0.0f); + eyeDiffSph.pitch = Camera_CalcControllerPitch(camera, eyeNextAtOffset.pitch, 0, 0); + } + else if(anim->swing.unk_18) + { + eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + eyeDiffSph.pitch = Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA); + } else if(camera->startControlTimer <= 0) { + eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, camera->playerPosRot.rot.y, jump1->maxYawUpdate, 0.0f); + eyeDiffSph.pitch = Camera_LERPCeilS(eyeDiffTarget.pitch, eyeAtOffset.pitch, PCT(OREG(29)), 0xA); + } +#endif // Clamp the eye->at distance to jump1->distMin < eyeDiffSph.r < jump1->distMax if (eyeDiffSph.r < jump1->distMin) { eyeDiffSph.r = jump1->distMin; @@ -2448,25 +2558,12 @@ s32 Camera_Jump2(Camera* camera) { adjAtToEyeDir.r = temp_f14; } - yawDiff = BINANG_SUB(BINANG_ROT180(playerPosRot->rot.y), adjAtToEyeDir.yaw); - if (anim->animTimer != 0) { - anim->yawTarget = BINANG_ROT180(playerPosRot->rot.y); - anim->animTimer--; - adjAtToEyeDir.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.5f, 0xA); - } else if (anim->yawAdj < ABS(yawDiff)) { - playerYawRot180 = BINANG_ROT180(playerPosRot->rot.y); - adjAtToEyeDir.yaw = Camera_LERPFloorS( - ((yawDiff < 0) ? (s16)(playerYawRot180 + anim->yawAdj) : (s16)(playerYawRot180 - anim->yawAdj)), - atToEyeNextDir.yaw, 0.1f, 0xA); - } else { - adjAtToEyeDir.yaw = Camera_LERPCeilS(adjAtToEyeDir.yaw, atToEyeNextDir.yaw, 0.25f, 0xA); - } // Check the floor at the top of the climb bgChkPos.x = playerPosRot->pos.x + (Math_SinS(playerPosRot->rot.y) * 25.0f); bgChkPos.y = playerPosRot->pos.y + (playerHeight * 2.2f); bgChkPos.z = playerPosRot->pos.z + (Math_CosS(playerPosRot->rot.y) * 25.0f); - +#ifndef FIZZLE_CAM sp90 = Camera_GetFloorYNorm(camera, &floorNorm, &bgChkPos, &bgId); if ((sp90 != BGCHECK_Y_MIN) && (playerPosRot->pos.y < sp90)) { // top of the climb is within 2.2x of the player's height. @@ -2483,6 +2580,36 @@ s32 Camera_Jump2(Camera* camera) { camera->rUpdateRateInv = 100.0f; } + yawDiff = BINANG_SUB(BINANG_ROT180(playerPosRot->rot.y), adjAtToEyeDir.yaw); + if(anim->animTimer != 0) + { + anim->yawTarget = BINANG_ROT180(playerPosRot->rot.y); + anim->animTimer--; + adjAtToEyeDir.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.5f, 0xA); + } + else if(anim->yawAdj < ABS(yawDiff)) + { + playerYawRot180 = BINANG_ROT180(playerPosRot->rot.y); + adjAtToEyeDir.yaw = Camera_LERPFloorS(((yawDiff < 0) ? (s16)(playerYawRot180 + anim->yawAdj) : (s16)(playerYawRot180 - anim->yawAdj)), atToEyeNextDir.yaw, 0.1f, 0xA); + } + else + { + adjAtToEyeDir.yaw = Camera_LERPCeilS(adjAtToEyeDir.yaw, atToEyeNextDir.yaw, 0.25f, 0xA); + } +#else + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + StepControlTimer(camera); + if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) + { + adjAtToEyeDir.yaw = Camera_CalcControllerYaw(camera, atToEyeNextDir.yaw, playerPosRot->rot.y, 0, 0.0f); + adjAtToEyeDir.pitch = Camera_CalcControllerPitch(camera, atToEyeNextDir.pitch, 0, 0); + } + else if(camera->startControlTimer <= 0) { + adjAtToEyeDir.yaw = Camera_CalcDefaultYaw(camera, atToEyeNextDir.yaw, playerPosRot->rot.y, 0, 0.0f); + adjAtToEyeDir.pitch = Camera_CalcDefaultPitch(camera, atToEyeNextDir.pitch, 0, 0); + } +#endif + // max pitch to +/- ~ 60 degrees if (adjAtToEyeDir.pitch > 0x2AF8) { adjAtToEyeDir.pitch = 0x2AF8; @@ -2501,14 +2628,17 @@ s32 Camera_Jump2(Camera* camera) { bgChkPara.r = adjAtToEyeDir.r; bgChkPara.pitch = 0; bgChkPara.yaw = adjAtToEyeDir.yaw; + Camera_Vec3fVecSphGeoAdd(&camBgChk.pos, at, &bgChkPara); if (Camera_BGCheckInfo(camera, at, &camBgChk)) { // Collision found between parallel at->eyeNext, set eye position to // first collsion point. *eye = bgChkPos; } else { - // no collision found with the parallel at->eye, animate to be parallel +#ifndef FIZZLE_CAM //blocking to allow pitch on lader with stick control + // no collision found with the parallel at->eye, animate to be parallel adjAtToEyeDir.pitch = Camera_LERPCeilS(0, adjAtToEyeDir.pitch, 0.2f, 0xA); +#endif Camera_Vec3fVecSphGeoAdd(eye, at, &adjAtToEyeDir); // useless? Camera_BGCheck(camera, at, eye); @@ -2660,6 +2790,7 @@ s32 Camera_Jump3(Camera* camera) { camera->pitchUpdateRateInv = 100.0f; } } +#ifndef FIZZLE_CAM if (anim->swing.unk_18 != 0) { eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); @@ -2669,7 +2800,20 @@ s32 Camera_Jump3(Camera* camera) { eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f); eyeDiffSph.pitch = Camera_CalcDefaultPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0); } - +#else + const oot::hid::N64Controller* sControlInput = oot::hid::Players::GetController(); + StepControlTimer(camera); + if(camera->startControlTimer > 0 || sControlInput->state().r_stick_x != 0 || sControlInput->state().r_stick_y != 0) { + eyeDiffSph.yaw = Camera_CalcControllerYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f); + eyeDiffSph.pitch = Camera_CalcControllerPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0); + } else if(anim->swing.unk_18 != 0) { + eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + eyeDiffSph.pitch = Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA); + } else if(camera->startControlTimer <= 0) { + eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f); + eyeDiffSph.pitch = Camera_CalcDefaultPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0); + } +#endif if (eyeDiffSph.pitch > R_CAM_MAX_PHI) { eyeDiffSph.pitch = R_CAM_MAX_PHI; }