2019-05-15 16:52:37 +02:00
|
|
|
#include "common.h"
|
|
|
|
#include "patcher.h"
|
2019-06-17 10:30:02 +02:00
|
|
|
#include "main.h"
|
2019-05-15 16:52:37 +02:00
|
|
|
#include "Draw.h"
|
2019-05-29 18:06:33 +02:00
|
|
|
#include "World.h"
|
|
|
|
#include "Vehicle.h"
|
|
|
|
#include "Ped.h"
|
2019-06-29 11:09:33 +02:00
|
|
|
#include "PlayerPed.h"
|
2019-05-29 18:06:33 +02:00
|
|
|
#include "Pad.h"
|
|
|
|
#include "General.h"
|
2019-07-07 13:09:11 +02:00
|
|
|
#include "ZoneCull.h"
|
2019-05-29 18:06:33 +02:00
|
|
|
#include "SurfaceTable.h"
|
2019-05-31 11:44:43 +02:00
|
|
|
#include "MBlur.h"
|
2019-05-15 16:52:37 +02:00
|
|
|
#include "Camera.h"
|
|
|
|
|
|
|
|
CCamera &TheCamera = *(CCamera*)0x6FACF8;
|
2019-06-17 00:16:38 +02:00
|
|
|
bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8;
|
2019-06-13 02:35:26 +02:00
|
|
|
|
2019-07-09 18:50:35 +02:00
|
|
|
WRAPPER void CCamera::CamShake(float strength, float x, float y, float z) { EAXJMP(0x46B200); }
|
2019-05-30 21:24:47 +02:00
|
|
|
WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); }
|
2019-06-30 18:22:44 +02:00
|
|
|
WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); }
|
2019-07-04 00:16:24 +02:00
|
|
|
WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); }
|
2019-07-17 12:24:04 +02:00
|
|
|
WRAPPER void CamShakeNoPos(CCamera*, float) { EAXJMP(0x46B100); }
|
2019-08-03 15:01:13 +02:00
|
|
|
WRAPPER void CCamera::TakeControl(CEntity*, int16, int16, int32) { EAXJMP(0x471500); }
|
|
|
|
WRAPPER void CCamera::TakeControlNoEntity(const CVector&, int16, int32) { EAXJMP(0x4715B0); }
|
2019-08-15 16:51:39 +02:00
|
|
|
WRAPPER void CCamera::Init(void) { EAXJMP(0x46BAD0); }
|
|
|
|
WRAPPER void CCamera::Process(void) { EAXJMP(0x46D3F0); }
|
2019-09-28 16:03:00 +02:00
|
|
|
WRAPPER void CCamera::LoadPathSplines(int file) { EAXJMP(0x46D1D0); }
|
|
|
|
WRAPPER void CCamera::RestoreWithJumpCut(void) { EAXJMP(0x46FAE0); };
|
2020-01-28 15:30:13 +01:00
|
|
|
WRAPPER void CCamera::SetPercentAlongCutScene(float) { EAXJMP(0x46FE20); };
|
2020-02-16 21:08:54 +01:00
|
|
|
WRAPPER void CCamera::SetParametersForScriptInterpolation(float, float, int32) { EAXJMP(0x46FDE0); }
|
2019-08-03 15:01:13 +02:00
|
|
|
|
|
|
|
bool
|
|
|
|
CCamera::GetFading()
|
|
|
|
{
|
|
|
|
return m_bFading;
|
|
|
|
}
|
2019-05-30 21:24:47 +02:00
|
|
|
|
2020-03-26 14:16:06 +01:00
|
|
|
int
|
|
|
|
CCamera::GetFadingDirection()
|
|
|
|
{
|
|
|
|
if(m_bFading)
|
|
|
|
return m_iFadingDirection == FADE_IN ? FADE_IN : FADE_OUT;
|
|
|
|
else
|
|
|
|
return FADE_NONE;
|
|
|
|
}
|
|
|
|
|
2019-05-15 16:52:37 +02:00
|
|
|
bool
|
|
|
|
CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat)
|
|
|
|
{
|
|
|
|
RwV3d c;
|
|
|
|
c = *(RwV3d*)¢er;
|
|
|
|
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
|
|
|
|
if(c.y + radius < CDraw::GetNearClipZ()) return false;
|
|
|
|
if(c.y - radius > CDraw::GetFarClipZ()) return false;
|
|
|
|
if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > radius) return false;
|
|
|
|
if(c.x*m_vecFrustumNormals[1].x + c.y*m_vecFrustumNormals[1].y > radius) return false;
|
|
|
|
if(c.y*m_vecFrustumNormals[2].y + c.z*m_vecFrustumNormals[2].z > radius) return false;
|
|
|
|
if(c.y*m_vecFrustumNormals[3].y + c.z*m_vecFrustumNormals[3].z > radius) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-07-14 13:49:27 +02:00
|
|
|
bool
|
|
|
|
CCamera::IsSphereVisible(const CVector ¢er, float radius)
|
|
|
|
{
|
|
|
|
CMatrix mat = m_cameraMatrix;
|
|
|
|
return IsSphereVisible(center, radius, &mat);
|
|
|
|
}
|
|
|
|
|
2019-05-15 16:52:37 +02:00
|
|
|
bool
|
|
|
|
CCamera::IsPointVisible(const CVector ¢er, const CMatrix *mat)
|
|
|
|
{
|
|
|
|
RwV3d c;
|
|
|
|
c = *(RwV3d*)¢er;
|
|
|
|
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
|
|
|
|
if(c.y < CDraw::GetNearClipZ()) return false;
|
|
|
|
if(c.y > CDraw::GetFarClipZ()) return false;
|
|
|
|
if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > 0.0f) return false;
|
|
|
|
if(c.x*m_vecFrustumNormals[1].x + c.y*m_vecFrustumNormals[1].y > 0.0f) return false;
|
|
|
|
if(c.y*m_vecFrustumNormals[2].y + c.z*m_vecFrustumNormals[2].z > 0.0f) return false;
|
|
|
|
if(c.y*m_vecFrustumNormals[3].y + c.z*m_vecFrustumNormals[3].z > 0.0f) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CCamera::IsBoxVisible(RwV3d *box, const CMatrix *mat)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int frustumTests[6] = { 0 };
|
|
|
|
RwV3dTransformPoints(box, box, 8, &mat->m_matrix);
|
|
|
|
|
|
|
|
for(i = 0; i < 8; i++){
|
|
|
|
if(box[i].y < CDraw::GetNearClipZ()) frustumTests[0]++;
|
|
|
|
if(box[i].y > CDraw::GetFarClipZ()) frustumTests[1]++;
|
|
|
|
if(box[i].x*m_vecFrustumNormals[0].x + box[i].y*m_vecFrustumNormals[0].y > 0.0f) frustumTests[2]++;
|
|
|
|
if(box[i].x*m_vecFrustumNormals[1].x + box[i].y*m_vecFrustumNormals[1].y > 0.0f) frustumTests[3]++;
|
|
|
|
// Why not test z?
|
|
|
|
// if(box[i].y*m_vecFrustumNormals[2].y + box[i].z*m_vecFrustumNormals[2].z > 0.0f) frustumTests[4]++;
|
|
|
|
// if(box[i].y*m_vecFrustumNormals[3].y + box[i].z*m_vecFrustumNormals[3].z > 0.0f) frustumTests[5]++;
|
|
|
|
}
|
|
|
|
for(i = 0; i < 6; i++)
|
|
|
|
if(frustumTests[i] == 8)
|
|
|
|
return false; // Box is completely outside of one plane
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-06-01 01:58:19 +02:00
|
|
|
int
|
|
|
|
CCamera::GetLookDirection(void)
|
|
|
|
{
|
2019-10-27 04:17:30 +01:00
|
|
|
if(Cams[ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING ||
|
|
|
|
Cams[ActiveCam].Mode == CCam::MODE_1STPERSON ||
|
2019-06-01 01:58:19 +02:00
|
|
|
Cams[ActiveCam].Mode == CCam::MODE_BEHINDBOAT ||
|
|
|
|
Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED)
|
|
|
|
return Cams[ActiveCam].DirectionWasLooking;
|
|
|
|
return LOOKING_FORWARD;;
|
|
|
|
}
|
|
|
|
|
2019-07-18 15:41:09 +02:00
|
|
|
bool
|
|
|
|
CCamera::GetLookingForwardFirstPerson()
|
|
|
|
{
|
2019-10-27 04:17:30 +01:00
|
|
|
return Cams[ActiveCam].Mode == CCam::MODE_1STPERSON &&
|
2019-07-18 15:41:09 +02:00
|
|
|
Cams[ActiveCam].DirectionWasLooking == LOOKING_FORWARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-30 21:24:47 +02:00
|
|
|
WRAPPER void CCamera::Fade(float timeout, int16 direction) { EAXJMP(0x46B3A0); }
|
|
|
|
WRAPPER void CCamera::ProcessFade(void) { EAXJMP(0x46F080); }
|
|
|
|
WRAPPER void CCamera::ProcessMusicFade(void) { EAXJMP(0x46F1E0); }
|
|
|
|
|
2019-05-31 11:44:43 +02:00
|
|
|
int
|
|
|
|
CCamera::GetScreenFadeStatus(void)
|
|
|
|
{
|
|
|
|
if(m_fFLOATingFade == 0.0f)
|
|
|
|
return FADE_0;
|
|
|
|
if(m_fFLOATingFade == 255.0f)
|
|
|
|
return FADE_2;
|
|
|
|
return FADE_1;
|
|
|
|
}
|
|
|
|
|
2019-05-30 21:24:47 +02:00
|
|
|
void
|
|
|
|
CCamera::SetFadeColour(uint8 r, uint8 g, uint8 b)
|
|
|
|
{
|
|
|
|
m_FadeTargetIsSplashScreen = r == 0 && g == 0 && b == 0;
|
|
|
|
CDraw::FadeRed = r;
|
|
|
|
CDraw::FadeGreen = g;
|
|
|
|
CDraw::FadeBlue = b;
|
|
|
|
}
|
2019-05-15 16:52:37 +02:00
|
|
|
|
2019-05-31 11:44:43 +02:00
|
|
|
void
|
|
|
|
CCamera::SetMotionBlur(int r, int g, int b, int a, int type)
|
|
|
|
{
|
|
|
|
m_BlurRed = r;
|
|
|
|
m_BlurGreen = g;
|
|
|
|
m_BlurBlue = b;
|
|
|
|
m_motionBlur = a;
|
|
|
|
m_BlurType = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::SetMotionBlurAlpha(int a)
|
|
|
|
{
|
|
|
|
m_imotionBlurAddAlpha = a;
|
|
|
|
}
|
|
|
|
|
2020-02-16 21:08:54 +01:00
|
|
|
void
|
|
|
|
CCamera::SetNearClipScript(float clip)
|
|
|
|
{
|
|
|
|
m_fNearClipScript = clip;
|
|
|
|
m_bUseNearClipScript = true;
|
|
|
|
}
|
|
|
|
|
2019-05-31 11:44:43 +02:00
|
|
|
void
|
|
|
|
CCamera::RenderMotionBlur(void)
|
|
|
|
{
|
|
|
|
if(m_BlurType == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CMBlur::MotionBlurRender(m_pRwCamera,
|
|
|
|
m_BlurRed, m_BlurGreen, m_BlurBlue,
|
|
|
|
m_motionBlur, m_BlurType, m_imotionBlurAddAlpha);
|
|
|
|
}
|
|
|
|
|
2019-07-04 22:31:21 +02:00
|
|
|
void
|
|
|
|
CCamera::ClearPlayerWeaponMode()
|
|
|
|
{
|
|
|
|
PlayerWeaponMode.Mode = 0;
|
|
|
|
PlayerWeaponMode.MaxZoom = 1;
|
|
|
|
PlayerWeaponMode.MinZoom = -1;
|
|
|
|
PlayerWeaponMode.Duration = 0.0f;
|
|
|
|
}
|
|
|
|
|
2019-07-25 17:06:24 +02:00
|
|
|
float
|
|
|
|
CCamera::Find3rdPersonQuickAimPitch(void)
|
|
|
|
{
|
|
|
|
float clampedFrontZ = clamp(Cams[ActiveCam].Front.z, -1.0f, 1.0f);
|
|
|
|
|
|
|
|
// float rot = atan2(clampedFrontZ, sqrt(1.0f - sq(clampedFrontZ)));
|
|
|
|
float rot = Asin(clampedFrontZ);
|
|
|
|
|
|
|
|
return -(DEGTORAD(((0.5f - m_f3rdPersonCHairMultY) * 1.8f * 0.5f * Cams[ActiveCam].FOV)) + rot);
|
|
|
|
}
|
|
|
|
|
2019-10-06 01:41:35 +02:00
|
|
|
void
|
|
|
|
CCamera::SetCamCutSceneOffSet(const CVector &pos)
|
|
|
|
{
|
|
|
|
m_vecCutSceneOffset = pos;
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::TakeControlWithSpline(short nSwitch)
|
|
|
|
{
|
2020-02-25 20:01:56 +01:00
|
|
|
m_iModeToGoTo = CCam::MODE_FLYBY;
|
|
|
|
m_bLookingAtPlayer = false;
|
|
|
|
m_bLookingAtVector = false;
|
|
|
|
m_bcutsceneFinished = false;
|
|
|
|
m_iTypeOfSwitch = nSwitch;
|
|
|
|
m_bStartInterScript = true;
|
|
|
|
|
2019-10-06 01:41:35 +02:00
|
|
|
//FindPlayerPed(); // unused
|
|
|
|
};
|
|
|
|
|
2020-02-25 20:01:56 +01:00
|
|
|
void CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString()
|
|
|
|
{
|
|
|
|
m_bCamDirectlyInFront = true;
|
|
|
|
CPlayerPed *player = FindPlayerPed();
|
|
|
|
if (player)
|
|
|
|
m_PedOrientForBehindOrInFront = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y);
|
2019-10-07 23:29:30 +02:00
|
|
|
}
|
|
|
|
|
2020-02-25 20:01:56 +01:00
|
|
|
void CCamera::SetCameraDirectlyBehindForFollowPed_CamOnAString()
|
|
|
|
{
|
|
|
|
m_bCamDirectlyBehind = true;
|
|
|
|
CPlayerPed *player = FindPlayerPed();
|
|
|
|
if (player)
|
|
|
|
m_PedOrientForBehindOrInFront = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y);
|
2020-01-03 17:48:13 +01:00
|
|
|
}
|
|
|
|
|
2019-10-13 21:19:51 +02:00
|
|
|
void
|
|
|
|
CCamera::SetWideScreenOn(void)
|
|
|
|
{
|
|
|
|
m_WideScreenOn = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::SetWideScreenOff(void)
|
|
|
|
{
|
|
|
|
m_bWantsToSwitchWidescreenOff = m_WideScreenOn;
|
|
|
|
}
|
|
|
|
|
2020-02-25 20:01:56 +01:00
|
|
|
void
|
|
|
|
CCamera::SetNewPlayerWeaponMode(int16 mode, int16 minZoom, int16 maxZoom)
|
|
|
|
{
|
|
|
|
PlayerWeaponMode.Mode = mode;
|
|
|
|
PlayerWeaponMode.MaxZoom = maxZoom;
|
|
|
|
PlayerWeaponMode.MinZoom = minZoom;
|
|
|
|
PlayerWeaponMode.Duration = 0.0f;
|
2020-01-23 21:21:50 +01:00
|
|
|
}
|
|
|
|
|
2020-02-25 20:01:56 +01:00
|
|
|
void
|
|
|
|
CCamera::UpdateAimingCoors(CVector const &coors)
|
|
|
|
{
|
|
|
|
m_cvecAimingTargetCoors = coors;
|
2020-01-23 21:21:50 +01:00
|
|
|
}
|
|
|
|
|
2020-01-28 15:30:13 +01:00
|
|
|
void
|
|
|
|
CCamera::SetCamPositionForFixedMode(const CVector &Source, const CVector &UpOffSet)
|
|
|
|
{
|
2020-02-25 20:01:56 +01:00
|
|
|
m_vecFixedModeSource = Source;
|
2020-01-28 15:30:13 +01:00
|
|
|
m_vecFixedModeUpOffSet = UpOffSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::SetRwCamera(RwCamera *cam)
|
|
|
|
{
|
2020-02-25 20:01:56 +01:00
|
|
|
m_pRwCamera = cam;
|
|
|
|
m_viewMatrix.Attach(&m_pRwCamera->viewMatrix, false);
|
2020-01-28 15:30:13 +01:00
|
|
|
CMBlur::MotionBlurOpen(m_pRwCamera);
|
|
|
|
}
|
|
|
|
|
2020-01-30 17:15:27 +01:00
|
|
|
uint32
|
|
|
|
CCamera::GetCutSceneFinishTime(void)
|
2020-01-28 15:30:13 +01:00
|
|
|
{
|
2020-02-25 20:01:56 +01:00
|
|
|
int cam = ActiveCam;
|
|
|
|
if (Cams[cam].Mode == CCam::MODE_FLYBY)
|
|
|
|
return Cams[cam].m_uiFinishTime;
|
|
|
|
cam = (cam + 1) % 2;
|
|
|
|
if (Cams[cam].Mode == CCam::MODE_FLYBY)
|
|
|
|
return Cams[cam].m_uiFinishTime;
|
|
|
|
|
2020-01-28 15:30:13 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::FinishCutscene(void)
|
|
|
|
{
|
2020-02-25 20:01:56 +01:00
|
|
|
SetPercentAlongCutScene(100.0f);
|
|
|
|
m_fPositionAlongSpline = 1.0f;
|
2020-01-28 15:30:13 +01:00
|
|
|
m_bcutsceneFinished = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::SetZoomValueFollowPedScript(int16 mode)
|
2020-02-25 20:01:56 +01:00
|
|
|
{
|
|
|
|
switch (mode) {
|
|
|
|
case 0: m_fPedZoomValueScript = 0.25f; break;
|
|
|
|
case 1: m_fPedZoomValueScript = 1.5f; break;
|
|
|
|
case 2: m_fPedZoomValueScript = 2.9f; break;
|
|
|
|
default: m_fPedZoomValueScript = m_fPedZoomValueScript; break;
|
|
|
|
}
|
|
|
|
|
2020-01-28 15:30:13 +01:00
|
|
|
m_bUseScriptZoomValuePed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CCamera::SetZoomValueCamStringScript(int16 mode)
|
2020-02-25 20:01:56 +01:00
|
|
|
{
|
|
|
|
switch (mode) {
|
|
|
|
case 0: m_fCarZoomValueScript = 0.05f; break;
|
|
|
|
case 1: m_fCarZoomValueScript = 1.9f; break;
|
|
|
|
case 2: m_fCarZoomValueScript = 3.9f; break;
|
|
|
|
default: m_fCarZoomValueScript = m_fCarZoomValueScript; break;
|
|
|
|
}
|
|
|
|
|
2020-01-28 15:30:13 +01:00
|
|
|
m_bUseScriptZoomValueCar = true;
|
|
|
|
}
|
|
|
|
|
2019-05-15 16:52:37 +02:00
|
|
|
STARTPATCHES
|
2019-07-14 13:49:27 +02:00
|
|
|
InjectHook(0x42C760, (bool (CCamera::*)(const CVector ¢er, float radius, const CMatrix *mat))&CCamera::IsSphereVisible, PATCH_JUMP);
|
2019-05-30 21:24:47 +02:00
|
|
|
InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP);
|
|
|
|
|
2019-05-31 11:44:43 +02:00
|
|
|
InjectHook(0x46FD40, &CCamera::SetMotionBlur, PATCH_JUMP);
|
|
|
|
InjectHook(0x46FD80, &CCamera::SetMotionBlurAlpha, PATCH_JUMP);
|
|
|
|
InjectHook(0x46F940, &CCamera::RenderMotionBlur, PATCH_JUMP);
|
|
|
|
|
2019-10-07 23:29:30 +02:00
|
|
|
InjectHook(0x46FC90, &CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString, PATCH_JUMP);
|
|
|
|
|
2019-10-13 21:19:51 +02:00
|
|
|
InjectHook(0x46FF00, &CCamera::SetWideScreenOn, PATCH_JUMP);
|
|
|
|
InjectHook(0x46FF10, &CCamera::SetWideScreenOff, PATCH_JUMP);
|
|
|
|
|
2020-01-28 15:30:13 +01:00
|
|
|
InjectHook(0x46FCC0, &CCamera::SetCamPositionForFixedMode, PATCH_JUMP);
|
|
|
|
InjectHook(0x46FEC0, &CCamera::SetRwCamera, PATCH_JUMP);
|
|
|
|
InjectHook(0x46B920, &CCamera::GetCutSceneFinishTime, PATCH_JUMP);
|
|
|
|
InjectHook(0x46B560, &CCamera::FinishCutscene, PATCH_JUMP);
|
|
|
|
InjectHook(0x46FF30, &CCamera::SetZoomValueFollowPedScript, PATCH_JUMP);
|
|
|
|
InjectHook(0x46FF90, &CCamera::SetZoomValueCamStringScript, PATCH_JUMP);
|
2019-05-15 16:52:37 +02:00
|
|
|
ENDPATCHES
|