TombEngine/TR5Main/Game/spotcam.cpp

908 lines
23 KiB
C++
Raw Normal View History

#include "spotcam.h"
#include "..\Global\global.h"
2019-12-28 15:29:33 +01:00
#include "Camera.h"
#include "control.h"
#include "draw.h"
#include "tomb4fx.h"
#include "switch.h"
short LastSequence;
short SpotcamTimer;
short SpotcamLoopCnt;
int CameraFade;
PHD_VECTOR LaraFixedPosition;
short InitialCameraRoom;
short LastFOV;
PHD_VECTOR InitialCameraPosition;
PHD_VECTOR InitialCameraTarget;
int CurrentSplinePosition;
int SplineToCamera;
short FirstCamera;
short LastCamera;
int CurrentCameraCnt;
int CameraXposition[MAX_CAMERA];
int CameraYposition[MAX_CAMERA];
int CameraZposition[MAX_CAMERA];
int CameraXtarget[MAX_CAMERA];
int CameraYtarget[MAX_CAMERA];
int CameraZtarget[MAX_CAMERA];
int CameraRoll[MAX_CAMERA];
int CameraFOV[MAX_CAMERA];
int CameraSpeed[MAX_CAMERA];
QUAKE_CAMERA QuakeCam;
int SplineFromCamera;
int Unk_0051D024;
void InitSpotCamSequences()
{
int s, cc, n, ce;
n = NumberSpotcams;
TrackCameraInit = 0;
cc = 1;
if (n != 0)
{
ce = 0;
s = SpotCam[0].sequence;
if (cc < n)
{
for (n = 1; n < NumberSpotcams; n++)
{
//Same sequence
if (SpotCam[n].sequence == s)
{
cc++;
}
else
{
//New sequence
CameraCnt[ce] = cc;
cc = 1;
SpotCamRemap[s] = ce;
ce++;
s = SpotCam[n].sequence;
}
}
}
CameraCnt[ce] = cc;
SpotCamRemap[s] = ce;
}
return;
}
void InitialiseSpotCam(short Sequence)
{
SPOTCAM* s;
int cn;
int sp;
int i;
if (TrackCameraInit != 0 && LastSequence == Sequence)
{
TrackCameraInit = 0;
return;
}
BinocularRange = 0;
LaserSight = 0;
AlterFOV(16380);
LaraItem->meshBits = -1;
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Camera.bounce = 0;
Lara.busy = 0;
CameraFade = -1;
LastSequence = Sequence;
TrackCameraInit = 0;
SpotcamTimer = 0;
SpotcamLoopCnt = 0;
DisableLaraControl = 0;
LastFOV = CurrentFOV;
LaraAir = Lara.air;
InitialCameraPosition.x = Camera.pos.x;
InitialCameraPosition.y = Camera.pos.y;
InitialCameraPosition.z = Camera.pos.z;
InitialCameraTarget.x = Camera.target.x;
InitialCameraTarget.y = Camera.target.y;
InitialCameraTarget.z = Camera.target.z;
LaraHealth = LaraItem->hitPoints;
InitialCameraRoom = Camera.pos.roomNumber;
LaraFixedPosition.x = LaraItem->pos.xPos;
LaraFixedPosition.y = LaraItem->pos.yPos;
LaraFixedPosition.z = LaraItem->pos.zPos;
CurrentSpotcamSequence = Sequence;
CurrentSplineCamera = 0;
for (i = 0; i < SpotCamRemap[Sequence]; i++)
{
CurrentSplineCamera += CameraCnt[i];
}
CurrentSplinePosition = 0;
SplineToCamera = 0;
FirstCamera = CurrentSplineCamera;
s = &SpotCam[CurrentSplineCamera];
LastCamera = CurrentSplineCamera + (CameraCnt[SpotCamRemap[Sequence]] - 1);
CurrentCameraCnt = CameraCnt[SpotCamRemap[Sequence]];
if ((s->flags & SCF_DISABLE_LARA_CONTROLS) /*|| gfGameMode == 1*/)
{
DisableLaraControl = 1;
2019-12-28 15:29:33 +01:00
//SetFadeClip(16, 1);
}
if (s->flags & SCF_TRACKING_CAM)
{
2019-12-28 15:29:33 +01:00
CameraXposition[1] = SpotCam[FirstCamera].x;
CameraYposition[1] = SpotCam[FirstCamera].y;
CameraZposition[1] = SpotCam[FirstCamera].z;
2019-12-28 15:29:33 +01:00
CameraXtarget[1] = SpotCam[FirstCamera].tx;
CameraYtarget[1] = SpotCam[FirstCamera].ty;
CameraZtarget[1] = SpotCam[FirstCamera].tz;
2019-12-28 15:29:33 +01:00
CameraXtarget[1] = SpotCam[FirstCamera].tx;
CameraYtarget[1] = SpotCam[FirstCamera].ty;
CameraZtarget[1] = SpotCam[FirstCamera].tz;
2019-12-28 15:29:33 +01:00
CameraRoll[1] = SpotCam[FirstCamera].roll;
CameraFOV[1] = SpotCam[FirstCamera].fov;
SplineFromCamera = 0;
2019-12-28 15:29:33 +01:00
CameraSpeed[1] = SpotCam[FirstCamera].speed;
2019-12-28 15:29:33 +01:00
if (CurrentCameraCnt > 0)
{
s = &SpotCam[FirstCamera];
2019-12-28 15:29:33 +01:00
for (i = 0; i < CurrentCameraCnt; i++, s++)
{
2019-12-28 15:29:33 +01:00
CameraXposition[i + 2] = s->x;
CameraYposition[i + 2] = s->y;
CameraZposition[i + 2] = s->z;
2019-12-28 15:29:33 +01:00
CameraXtarget[i + 2] = s->tx;
CameraYtarget[i + 2] = s->ty;
CameraZtarget[i + 2] = s->tz;
2019-12-28 15:29:33 +01:00
CameraXtarget[i + 2] = s->tx;
CameraYtarget[i + 2] = s->ty;
CameraZtarget[i + 2] = s->tz;
2019-12-28 15:29:33 +01:00
CameraRoll[i + 2] = s->roll;
CameraFOV[i + 2] = s->fov;
CameraSpeed[i + 2] = s->speed;
}
}
//loc_379F8
2019-12-28 15:29:33 +01:00
CameraXposition[CurrentCameraCnt + 1] = SpotCam[LastCamera].x;
CameraYposition[CurrentCameraCnt + 1] = SpotCam[LastCamera].y;
CameraZposition[CurrentCameraCnt + 1] = SpotCam[LastCamera].z;
2019-12-28 15:29:33 +01:00
CameraXtarget[CurrentCameraCnt + 1] = SpotCam[LastCamera].tx;
CameraYtarget[CurrentCameraCnt + 1] = SpotCam[LastCamera].ty;
CameraZtarget[CurrentCameraCnt + 1] = SpotCam[LastCamera].tz;
2019-12-28 15:29:33 +01:00
CameraFOV[CurrentCameraCnt + 1] = SpotCam[LastCamera].fov;
CameraRoll[CurrentCameraCnt + 1] = SpotCam[LastCamera].roll;
CameraSpeed[CurrentCameraCnt + 1] = SpotCam[LastCamera].speed;
}
else
{
//loc_37AA8
sp = 1;
if ((s->flags & SCF_CUT_PAN))
{
2019-12-28 15:29:33 +01:00
CameraXposition[1] = SpotCam[CurrentSplineCamera].x;
CameraYposition[1] = SpotCam[CurrentSplineCamera].y;
CameraZposition[1] = SpotCam[CurrentSplineCamera].z;
2019-12-28 15:29:33 +01:00
CameraXtarget[1] = SpotCam[CurrentSplineCamera].tx;
CameraYtarget[1] = SpotCam[CurrentSplineCamera].ty;
CameraZtarget[1] = SpotCam[CurrentSplineCamera].tz;
2019-12-28 15:29:33 +01:00
CameraRoll[1] = SpotCam[CurrentSplineCamera].roll;
CameraFOV[1] = SpotCam[CurrentSplineCamera].fov;
CameraSpeed[1] = SpotCam[CurrentSplineCamera].speed;
SplineFromCamera = 0;
cn = CurrentSplineCamera;
while (sp < 4)
{
if (LastCamera < CurrentSplineCamera)
{
cn = FirstCamera;
}
//loc_37B74
2019-12-28 15:29:33 +01:00
CameraXposition[sp + 1] = SpotCam[cn].x;
CameraYposition[sp + 1] = SpotCam[cn].y;
CameraZposition[sp + 1] = SpotCam[cn].z;
2019-12-28 15:29:33 +01:00
CameraXtarget[sp + 1] = SpotCam[cn].tx;
CameraYtarget[sp + 1] = SpotCam[cn].ty;
CameraZtarget[sp + 1] = SpotCam[cn].tz;
2019-12-28 15:29:33 +01:00
CameraRoll[sp + 1] = SpotCam[cn].roll;
CameraFOV[sp + 1] = SpotCam[cn].fov;
CameraSpeed[sp + 1] = SpotCam[cn].speed;
cn++;
sp++;
}
CurrentSplineCamera++;
if (CurrentSplineCamera > LastCamera)
{
CurrentSplineCamera = FirstCamera;
}
if (s->flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
{
CheckTrigger = true;
}
if (s->flags & SCF_VIGNETTE)
{
/*if (s->timer < 0)
{
SCOverlay = 1;
}//loc_37C8C
else if (SlowMotion == 0)
{
SlowMotion = s->timer;
}*/
}
if (s->flags & SCF_HIDE_LARA)
{
SpotcamDontDrawLara = true;
}
else
{
QuakeCam.spos.boxNumber = 0;
return;
}
}
else
{
cn = CurrentSplineCamera;
CameraXposition[1] = InitialCameraPosition.x;
CameraYposition[1] = InitialCameraPosition.y;
CameraZposition[1] = InitialCameraPosition.z;
2019-12-28 15:29:33 +01:00
CameraXtarget[1] = InitialCameraTarget.x;
CameraYtarget[1] = InitialCameraTarget.y;
CameraZtarget[1] = InitialCameraTarget.z;
2019-12-28 15:29:33 +01:00
CameraFOV[1] = CurrentFOV;
CameraRoll[1] = 0;
CameraSpeed[1] = s->speed;
2019-12-28 15:29:33 +01:00
CameraXposition[2] = InitialCameraPosition.x;
CameraYposition[2] = InitialCameraPosition.y;
CameraZposition[2] = InitialCameraPosition.z;
CameraXtarget[2] = InitialCameraTarget.x;
CameraYtarget[2] = InitialCameraTarget.y;
CameraZtarget[2] = InitialCameraTarget.z;
CameraRoll[2] = 0;
CameraFOV[2] = 0;
CameraSpeed[2] = s->speed;
CameraXposition[3] = SpotCam[CurrentSplineCamera].x;
CameraYposition[3] = SpotCam[CurrentSplineCamera].y;
CameraZposition[3] = SpotCam[CurrentSplineCamera].z;
CameraXtarget[3] = SpotCam[CurrentSplineCamera].tx;
CameraYtarget[3] = SpotCam[CurrentSplineCamera].ty;
CameraZtarget[3] = SpotCam[CurrentSplineCamera].tz;
CameraRoll[3] = SpotCam[CurrentSplineCamera].roll;
CameraFOV[3] = SpotCam[CurrentSplineCamera].fov;
CameraSpeed[3] = SpotCam[CurrentSplineCamera].speed;
SplineFromCamera = 1;
cn++;
if (LastCamera < cn)
{
cn = FirstCamera;
}
2019-12-28 15:29:33 +01:00
CameraXposition[4] = SpotCam[cn].x;
CameraYposition[4] = SpotCam[cn].y;
CameraZposition[4] = SpotCam[cn].z;
2019-12-28 15:29:33 +01:00
CameraXtarget[4] = SpotCam[cn].tx;
CameraYtarget[4] = SpotCam[cn].ty;
CameraZtarget[4] = SpotCam[cn].tz;
2019-12-28 15:29:33 +01:00
CameraRoll[4] = SpotCam[cn].roll;
CameraFOV[4] = SpotCam[cn].fov;
CameraSpeed[4] = SpotCam[cn].speed;
}
}
if (s->flags & SCF_HIDE_LARA)
{
SpotcamDontDrawLara = true;
}
QuakeCam.spos.boxNumber = 0;
}
void CalculateSpotCameras()
{
int cpx; // stack offset -96
int cpy; // stack offset -92
int cpz; // stack offset -88
int ctx; // stack offset -84
int cty; // stack offset -80
int ctz; // stack offset -76
int cspeed; // stack offset -72
int cfov; // stack offset -68
int croll; // stack offset -64
SPOTCAM* s; // stack offset -60
short spline_cnt; // $s3
int next_spline_camera; // $s0
int n; // $s5
static int bFirstLook; // offset 0x18 dword_A0AC4?
int dx; // $v1
int dy; // $s0
int dz; // $s1
//{ // line 76, offset 0x38114
int cs; // $s6
int sp; // $s2
int cp; // $fp
int clen; // $s4
int tlen; // $v1
int cx; // $s1
int cy; // $s0
int cz; // $v0
int lx; // stack offset -56
int lz; // stack offset -52
int ly; // stack offset -48
int i; // $v1
int var_2C;
int ctype; // $s0
int cn; // $s0
CAMERA_INFO Backup;
if (DisableLaraControl)
{
LaraItem->hitPoints = LaraHealth;
Lara.air = LaraAir;
}
2019-12-28 15:29:33 +01:00
s = &SpotCam[FirstCamera];
spline_cnt = 4;
if ((s->flags & SCF_TRACKING_CAM))
{
spline_cnt = CurrentCameraCnt + 2;
}
//loc_37F64
2019-12-28 15:29:33 +01:00
cpx = Spline(CurrentSplinePosition, &CameraXposition[1], spline_cnt);
cpy = Spline(CurrentSplinePosition, &CameraYposition[1], spline_cnt);
cpz = Spline(CurrentSplinePosition, &CameraZposition[1], spline_cnt);
2019-12-28 15:29:33 +01:00
ctx = Spline(CurrentSplinePosition, &CameraXtarget[1], spline_cnt);
cty = Spline(CurrentSplinePosition, &CameraYtarget[1], spline_cnt);
ctz = Spline(CurrentSplinePosition, &CameraZtarget[1], spline_cnt);
2019-12-28 15:29:33 +01:00
cspeed = Spline(CurrentSplinePosition, &CameraSpeed[1], spline_cnt);
croll = Spline(CurrentSplinePosition, &CameraRoll[1], spline_cnt);
cfov = Spline(CurrentSplinePosition, &CameraFOV[1], spline_cnt);
2019-12-28 15:29:33 +01:00
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_IN)
&& CameraFade != CurrentSplineCamera)
{
CameraFade = CurrentSplineCamera;
/*if (gfCurrentLevel != LVL5_TITLE)
{
ScreenFadedOut = 0;
ScreenFade = 255;
dScreenFade = 0;
SetScreenFadeIn(16);
}*/
2019-12-28 15:29:33 +01:00
}
2019-12-28 15:29:33 +01:00
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_OUT)
&& CameraFade != CurrentSplineCamera)
{
CameraFade = CurrentSplineCamera;
/*if (gfCurrentLevel != LVL5_TITLE)
{
ScreenFadedOut = 0;
ScreenFade = 0;
dScreenFade = 255;
SetScreenFadeOut(16, 0);
}*/
}
2019-12-28 15:29:33 +01:00
sp = 0;
tlen = 0;
clen = 0;
cp = 0;
int temp = 0x2000;
if ((s->flags & SCF_TRACKING_CAM))
{
lx = LaraItem->pos.xPos;
ly = LaraItem->pos.yPos;
lz = LaraItem->pos.zPos;
for (int i = 0; i < 8; i++)
{
clen = 0x10000;
for (int j = 0; j < 8; j++)
{
2019-12-28 15:29:33 +01:00
cx = Spline(sp, &CameraXposition[1], spline_cnt);
cy = Spline(sp, &CameraYposition[1], spline_cnt) ;
cz = Spline(sp, &CameraZposition[1], spline_cnt);
dx = SQUARE(cx - lx);
dy = SQUARE(cy - ly);
2019-12-28 15:29:33 +01:00
dz = SQUARE(cz - lz);
tlen = SQRT_ASM(dx + dy + dz);
if (tlen <= clen)
{
cp = sp;
clen = tlen;
}
sp += temp;
if (sp > 0x10000)
break;
}
temp >>= 1;
sp = cp - 2 * (temp & 0xFFFE); // << 2 ?
if (sp < 0)
sp = 0;
}
CurrentSplinePosition += (cp - CurrentSplinePosition) >> 5;
2019-12-28 15:29:33 +01:00
if ((s->flags & SCF_CUT_PAN))
{
2019-12-28 15:29:33 +01:00
if (abs(cp - CurrentSplinePosition) > 0x8000)
CurrentSplinePosition = cp;
}
2019-12-28 15:29:33 +01:00
if (CurrentSplinePosition > 0x10000)
CurrentSplinePosition = 0x10000;
else if (CurrentSplinePosition < 0)
CurrentSplinePosition = 0;
}
else if (!SpotcamTimer)
{
CurrentSplinePosition += cspeed;
}
if (!(TrInput & IN_LOOK))
{
Unk_0051D024 = 0;
}
2019-12-28 15:29:33 +01:00
if (s->flags & SCF_DISABLE_BREAKOUT
|| !(TrInput & IN_LOOK) /*&& gfGameMode != 1*/)
{
Camera.pos.x = cpx;
Camera.pos.y = cpy;
Camera.pos.z = cpz;
2019-12-28 15:29:33 +01:00
if ((s->flags & SCF_FOCUS_LARA_HEAD
|| s->flags & SCF_TRACKING_CAM))
{
2019-12-28 15:29:33 +01:00
Camera.target.x = LaraItem->pos.xPos;
Camera.target.y = LaraItem->pos.yPos;
Camera.target.z = LaraItem->pos.zPos;
}
else
{
Camera.target.x = ctx;
Camera.target.y = cty;
Camera.target.z = ctz;
}
IsRoomOutsideNo = -1;
IsRoomOutside(cpx, cpy, cpz);
if (IsRoomOutsideNo == -1)
{
Camera.pos.roomNumber = SpotCam[CurrentSplineCamera].roomNumber;
GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.roomNumber);
}
else
{
Camera.pos.roomNumber = IsRoomOutsideNo;
}
AlterFOV(cfov);
2019-12-28 15:29:33 +01:00
// WTF?
if (QuakeCam.spos.boxNumber != 0)
{
dx = (Camera.pos.x - QuakeCam.epos.x);
dy = (Camera.pos.y - QuakeCam.epos.y);
dz = (Camera.pos.z - QuakeCam.epos.z);
if (SQRT_ASM(SQUARE(dx) * SQUARE(dy) * SQUARE(dz)) < QuakeCam.epos.boxNumber)
{
dz = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber) >> 1;
dy = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber);
if (dy > 0)
{
Camera.pos.x += (GetRandomControl() / dy) - dz;
Camera.pos.y += (GetRandomControl() / dy) - dz;
Camera.pos.z += (GetRandomControl() / dy) - dz;
}
}
}
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, 0);
if (CheckTrigger)
{
CAMERA_TYPE oldType = Camera.type;
Camera.type = HEAVY_CAMERA;
if (CurrentLevel != 0)
{
TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0);
}
else
{
TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 0, 0);
TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0);
}
Camera.type = oldType;
CheckTrigger = false;
}
if (s->flags & SCF_TRACKING_CAM)
{
TrackCameraInit = true;
}
2019-12-28 15:29:33 +01:00
else if (CurrentSplinePosition > 0x10000 - cspeed)
{
2019-12-28 15:29:33 +01:00
if (SpotCam[CurrentSplineCamera].flags & SCF_VIGNETTE)
{
2019-12-28 15:29:33 +01:00
if (SpotCam[CurrentSplineCamera].timer >= 0)
{
2019-12-28 15:29:33 +01:00
if (!SlowMotion)
SlowMotion = SpotCam[CurrentSplineCamera].timer;
}
else
{
SpotcamOverlay = 1;
}
}
2019-12-28 15:29:33 +01:00
if (SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
CheckTrigger = true;
2019-12-28 15:29:33 +01:00
if (SpotCam[CurrentSplineCamera].flags & SCF_STOP_MOVEMENT)
{
if (QuakeCam.spos.boxNumber == 0 || SpotCam[CurrentSplineCamera].timer != -1)
{
QuakeCam.spos.x = SpotCam[CurrentSplineCamera].x;
QuakeCam.spos.y = SpotCam[CurrentSplineCamera].y;
QuakeCam.spos.z = SpotCam[CurrentSplineCamera].z;
if (SpotCam[CurrentSplineCamera].timer != -1)
{
QuakeCam.spos.roomNumber = SpotCam[CurrentSplineCamera].timer << 3;
}
else
{
QuakeCam.spos.roomNumber = 0;
}
QuakeCam.spos.boxNumber = 1;
QuakeCam.epos.x = SpotCam[CurrentSplineCamera + 1].x;
QuakeCam.epos.y = SpotCam[CurrentSplineCamera + 1].y;
QuakeCam.epos.z = SpotCam[CurrentSplineCamera + 1].z;
2019-12-28 15:29:33 +01:00
if (SpotCam[CurrentSplineCamera + 1].timer != -1)
{
QuakeCam.epos.roomNumber = SpotCam[CurrentSplineCamera + 1].timer << 3;
}
else
{
2019-12-28 15:29:33 +01:00
QuakeCam.epos.roomNumber = 0;
}
2019-12-28 15:29:33 +01:00
QuakeCam.epos.boxNumber = SQRT_ASM(((QuakeCam.spos.x - QuakeCam.epos.x) * (QuakeCam.spos.x - QuakeCam.epos.x)) + ((QuakeCam.spos.y - QuakeCam.epos.y) * (QuakeCam.spos.y - QuakeCam.epos.y) + ((QuakeCam.spos.z - QuakeCam.epos.z) * (QuakeCam.spos.z - QuakeCam.epos.z))));
}
2019-12-28 15:29:33 +01:00
else
{
QuakeCam.spos.boxNumber = 0;
}
}
2019-12-28 15:29:33 +01:00
if (!SpotcamTimer)
{
CurrentSplinePosition = 0;
if (CurrentSplineCamera != FirstCamera)
{
cn = CurrentSplineCamera - 1;
}
else
{
2019-12-28 15:29:33 +01:00
cn = LastCamera;
}
sp = 1;
2019-12-28 15:29:33 +01:00
if (SplineFromCamera != 0)
{
SplineFromCamera = 0;
cn = FirstCamera - 1;
}
else
{
if ((SpotCam[CurrentSplineCamera].flags & SCF_REENABLE_LARA_CONTROLS))
{
2019-12-28 15:29:33 +01:00
DisableLaraControl = false;
}
2019-12-28 15:29:33 +01:00
if ((SpotCam[CurrentSplineCamera].flags & SCF_DISABLE_LARA_CONTROLS))
{
2019-12-28 15:29:33 +01:00
//SetFadeClip(16, 1);
DisableLaraControl = true;
}
2019-12-28 15:29:33 +01:00
if ((SpotCam[CurrentSplineCamera].flags & SCF_CUT_TO_CAM))
{
2019-12-28 15:29:33 +01:00
cn = (SpotCam[CurrentSplineCamera].timer & 0xF) + FirstCamera;
CameraXposition[1] = SpotCam[cn].x;
CameraYposition[1] = SpotCam[cn].y;
CameraZposition[1] = SpotCam[cn].z;
CameraXtarget[1] = SpotCam[cn].tx;
CameraYtarget[1] = SpotCam[cn].ty;
CameraZtarget[1] = SpotCam[cn].tz;
CameraRoll[1] = SpotCam[cn].roll;
CameraFOV[1] = SpotCam[cn].fov;
CameraSpeed[1] = SpotCam[cn].speed;
sp++;
CurrentSplineCamera = cn;
}
2019-12-28 15:29:33 +01:00
CameraXposition[sp] = SpotCam[cn].x;
CameraYposition[sp] = SpotCam[cn].y;
CameraZposition[sp] = SpotCam[cn].z;
CameraXtarget[sp] = SpotCam[cn].tx;
CameraYtarget[sp] = SpotCam[cn].ty;
CameraZtarget[sp] = SpotCam[cn].tz;
CameraRoll[sp] = SpotCam[cn].roll;
CameraFOV[sp] = SpotCam[cn].fov;
CameraSpeed[sp] = SpotCam[cn].speed;
}
cn++;
if (sp < 4)
{
while (sp < 4)
{
if ((s->flags & SCF_LOOP_SEQUENCE))
{
2019-12-28 15:29:33 +01:00
if (LastCamera < cn)
{
cn = FirstCamera;
}
}
2019-12-28 15:29:33 +01:00
else
{
2019-12-28 15:29:33 +01:00
if (LastCamera < cn)
{
cn = LastCamera;
}
}
CameraXposition[sp] = SpotCam[cn].x;
CameraYposition[sp] = SpotCam[cn].y;
CameraZposition[sp] = SpotCam[cn].z;
CameraXtarget[sp] = SpotCam[cn].tx;
CameraYtarget[sp] = SpotCam[cn].ty;
CameraZtarget[sp] = SpotCam[cn].tz;
CameraRoll[sp] = SpotCam[cn].roll;
CameraFOV[sp] = SpotCam[cn].fov;
CameraSpeed[sp] = SpotCam[cn].speed;
2019-12-28 15:29:33 +01:00
cn++;
sp++;
}
2019-12-28 15:29:33 +01:00
}
2019-12-28 15:29:33 +01:00
CurrentSplineCamera++;
2019-12-28 15:29:33 +01:00
if (LastCamera > CurrentSplineCamera)
{
return;
}
if ((s->flags & SCF_LOOP_SEQUENCE))
{
CurrentSplineCamera = FirstCamera;
SpotcamLoopCnt++;
}
else if (s->flags & SCF_PAN_TO_LARA_CAM || SplineToCamera)
{
if (CheckTrigger)
{
CAMERA_TYPE oldType = Camera.type;
Camera.type = HEAVY_CAMERA;
if (CurrentLevel)
{
TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0);
}
else
{
TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 0, 0);
TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0);
}
Camera.type = oldType;
CheckTrigger = false;
}
//SetFadeClip(0, 1);
UseSpotCam = 0;
DisableLaraControl = 0;
CheckTrigger = 0;
Camera.oldType = FIXED_CAMERA;
Camera.type = CHASE_CAMERA;
Camera.speed = 1;
if (s->flags & SCF_PAN_TO_LARA_CAM)
{
Camera.pos.x = InitialCameraPosition.x;
Camera.pos.y = InitialCameraPosition.y;
Camera.pos.z = InitialCameraPosition.z;
Camera.target.x = InitialCameraTarget.x;
Camera.target.y = InitialCameraTarget.y;
Camera.target.z = InitialCameraTarget.z;
Camera.pos.roomNumber = InitialCameraRoom;
}
SpotcamOverlay = false;
SpotcamDontDrawLara = false;
AlterFOV(LastFOV);
}
else
{
CameraXposition[1] = SpotCam[CurrentSplineCamera - 1].x;
CameraYposition[1] = SpotCam[CurrentSplineCamera - 1].y;
CameraZposition[1] = SpotCam[CurrentSplineCamera - 1].z;
CameraXtarget[1] = SpotCam[CurrentSplineCamera - 1].tx;
CameraYtarget[1] = SpotCam[CurrentSplineCamera - 1].ty;
CameraZtarget[1] = SpotCam[CurrentSplineCamera - 1].tz;
CameraRoll[1] = SpotCam[CurrentSplineCamera - 1].roll;
CameraFOV[1] = SpotCam[CurrentSplineCamera - 1].fov;
CameraSpeed[1] = SpotCam[CurrentSplineCamera - 1].speed;
CameraXposition[2] = SpotCam[CurrentSplineCamera].x;
CameraYposition[2] = SpotCam[CurrentSplineCamera].y;
CameraZposition[2] = SpotCam[CurrentSplineCamera].z;
CameraXtarget[2] = SpotCam[CurrentSplineCamera].tx;
CameraYtarget[2] = SpotCam[CurrentSplineCamera].ty;
CameraZtarget[2] = SpotCam[CurrentSplineCamera].tz;
CameraRoll[2] = SpotCam[CurrentSplineCamera].roll;
CameraFOV[2] = SpotCam[CurrentSplineCamera].fov;
CameraSpeed[2] = SpotCam[CurrentSplineCamera].speed;
memcpy((char*)&Backup, (char*)&Camera, sizeof(CAMERA_INFO));
Camera.oldType = FIXED_CAMERA;
Camera.type = CHASE_CAMERA;
Camera.speed = 1;
int elevation = Camera.targetElevation;
CalculateCamera();
CameraRoll[2] = 0;
CameraRoll[3] = 0;
CameraSpeed[2] = CameraSpeed[1];
InitialCameraPosition.x = Camera.pos.x;
InitialCameraPosition.y = Camera.pos.y;
InitialCameraPosition.z = Camera.pos.z;
InitialCameraTarget.x = Camera.target.x;
InitialCameraTarget.y = Camera.target.y;
InitialCameraTarget.z = Camera.target.z;
CameraXposition[3] = Camera.pos.x;
CameraYposition[3] = Camera.pos.y;
CameraZposition[3] = Camera.pos.z;
CameraXtarget[3] = Camera.target.x;
CameraYtarget[3] = Camera.target.y;
CameraZtarget[3] = Camera.target.z;
CameraFOV[3] = CurrentFOV;
CameraSpeed[3] = CameraSpeed[2];
CameraRoll[3] = 0;
CameraXposition[4] = Camera.pos.x;
CameraYposition[4] = Camera.pos.y;
CameraZposition[4] = Camera.pos.z;
CameraXtarget[4] = Camera.target.x;
CameraYtarget[4] = Camera.target.y;
CameraZtarget[4] = Camera.target.z;
CameraFOV[4] = CurrentFOV;
CameraSpeed[4] = CameraSpeed[2] >> 1;
CameraRoll[4] = 0;
memcpy((char*)&Camera, (char*)&Backup, sizeof(CAMERA_INFO));
Camera.targetElevation = elevation;
LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, croll);
SplineToCamera = 1;
}
}
}
}
else if (s->flags & SCF_TRACKING_CAM)
{
if (!Unk_0051D024)
{
Camera.oldType = FIXED_CAMERA;
Unk_0051D024 = true;
}
CalculateCamera();
}
else
{
UseSpotCam = false;
DisableLaraControl = false;
Camera.speed = 1;
AlterFOV(LastFOV);
CalculateCamera();
CheckTrigger = false;
}
}
void Inject_Spotcam()
{
INJECT(0x0047A800, InitSpotCamSequences);
INJECT(0x0047A9D0, InitialiseSpotCam);
2019-12-28 15:29:33 +01:00
INJECT(0x0047B280, CalculateSpotCameras);
}