summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFire_Head <Fire-Head@users.noreply.github.com>2019-06-02 23:56:56 +0200
committerGitHub <noreply@github.com>2019-06-02 23:56:56 +0200
commitaa1163ccb2784f618f012ca878e07af54b2e9041 (patch)
tree04a15b6ef8896ad99ba22258c7bdee00c43c7df6
parentgamestates fixed, mpeg now working (diff)
parentadded CPhysical flags from Nick (diff)
downloadre3-aa1163ccb2784f618f012ca878e07af54b2e9041.tar
re3-aa1163ccb2784f618f012ca878e07af54b2e9041.tar.gz
re3-aa1163ccb2784f618f012ca878e07af54b2e9041.tar.bz2
re3-aa1163ccb2784f618f012ca878e07af54b2e9041.tar.lz
re3-aa1163ccb2784f618f012ca878e07af54b2e9041.tar.xz
re3-aa1163ccb2784f618f012ca878e07af54b2e9041.tar.zst
re3-aa1163ccb2784f618f012ca878e07af54b2e9041.zip
Diffstat (limited to '')
-rw-r--r--src/Pools.cpp6
-rw-r--r--src/Pools.h15
-rw-r--r--src/Zones.cpp2
-rw-r--r--src/entities/Automobile.h2
-rw-r--r--src/entities/Boat.h11
-rw-r--r--src/entities/CivilianPed.h9
-rw-r--r--src/entities/CopPed.h11
-rw-r--r--src/entities/Dummy.cpp7
-rw-r--r--src/entities/Dummy.h14
-rw-r--r--src/entities/DummyObject.h8
-rw-r--r--src/entities/DummyPed.h11
-rw-r--r--src/entities/EmergencyPed.h11
-rw-r--r--src/entities/Entity.cpp82
-rw-r--r--src/entities/Entity.h7
-rw-r--r--src/entities/Ped.cpp4
-rw-r--r--src/entities/Ped.h8
-rw-r--r--src/entities/Physical.cpp10
-rw-r--r--src/entities/Physical.h6
-rw-r--r--src/entities/Plane.h11
-rw-r--r--src/entities/PlayerPed.h11
-rw-r--r--src/entities/Train.h11
-rw-r--r--src/entities/Vehicle.cpp7
-rw-r--r--src/entities/Vehicle.h3
-rw-r--r--src/render/Renderer.cpp1
24 files changed, 250 insertions, 18 deletions
diff --git a/src/Pools.cpp b/src/Pools.cpp
index 106715e4..f7f93292 100644
--- a/src/Pools.cpp
+++ b/src/Pools.cpp
@@ -3,9 +3,12 @@
CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044;
CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448;
+CPedPool *&CPools::ms_pPedPool = *(CPedPool**)0x8F2C60;
+CVehiclePool *&CPools::ms_pVehiclePool = *(CVehiclePool**)0x9430DC;
CBuildingPool *&CPools::ms_pBuildingPool = *(CBuildingPool**)0x8F2C04;
CTreadablePool *&CPools::ms_pTreadablePool = *(CTreadablePool**)0x8F2568;
CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28;
+CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
void
CPools::Initialise(void)
@@ -13,7 +16,10 @@ CPools::Initialise(void)
// TODO: unused right now
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
+ ms_pPedPool = new CPedPool(NUMPEDS);
+ ms_pVehiclePool = new CVehiclePool(NUMVEHICLES);
ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS);
ms_pTreadablePool = new CTreadablePool(NUMTREADABLES);
ms_pObjectPool = new CObjectPool(NUMOBJECTS);
+ ms_pDummyPool = new CDummyPool(NUMDUMMIES);
}
diff --git a/src/Pools.h b/src/Pools.h
index aa804788..3496064c 100644
--- a/src/Pools.h
+++ b/src/Pools.h
@@ -5,30 +5,39 @@
#include "Treadable.h"
#include "Object.h"
#include "CutsceneHead.h"
+#include "PlayerPed.h"
+#include "Automobile.h"
+#include "DummyPed.h"
typedef CPool<CPtrNode> CCPtrNodePool;
typedef CPool<CEntryInfoNode> CEntryInfoNodePool;
+typedef CPool<CPed,CPlayerPed> CPedPool;
+typedef CPool<CVehicle,CAutomobile> CVehiclePool;
typedef CPool<CBuilding> CBuildingPool;
typedef CPool<CTreadable> CTreadablePool;
typedef CPool<CObject, CCutsceneHead> CObjectPool;
+typedef CPool<CDummy, CDummyPed> CDummyPool;
class CPools
{
static CCPtrNodePool *&ms_pPtrNodePool;
static CEntryInfoNodePool *&ms_pEntryInfoNodePool;
- // ms_pPedPool
- // ms_pVehiclePool
+ static CPedPool *&ms_pPedPool;
+ static CVehiclePool *&ms_pVehiclePool;
static CBuildingPool *&ms_pBuildingPool;
static CTreadablePool *&ms_pTreadablePool;
static CObjectPool *&ms_pObjectPool;
- // ms_pDummyPool
+ static CDummyPool *&ms_pDummyPool;
// ms_pAudioScriptObjectPool
public:
static CCPtrNodePool *GetPtrNodePool(void) { return ms_pPtrNodePool; }
static CEntryInfoNodePool *GetEntryInfoNodePool(void) { return ms_pEntryInfoNodePool; }
+ static CPedPool *GetPedPool(void) { return ms_pPedPool; }
+ static CVehiclePool *GetVehiclePool(void) { return ms_pVehiclePool; }
static CBuildingPool *GetBuildingPool(void) { return ms_pBuildingPool; }
static CTreadablePool *GetTreadablePool(void) { return ms_pTreadablePool; }
static CObjectPool *GetObjectPool(void) { return ms_pObjectPool; }
+ static CDummyPool *GetDummyPool(void) { return ms_pDummyPool; }
static void Initialise(void);
};
diff --git a/src/Zones.cpp b/src/Zones.cpp
index 741fff7d..0f9bedfb 100644
--- a/src/Zones.cpp
+++ b/src/Zones.cpp
@@ -629,6 +629,8 @@ STARTPATCHES
InjectHook(0x4B6790, CTheZones::FindSmallestZonePositionType, PATCH_JUMP);
InjectHook(0x4B6890, CTheZones::FindSmallestZonePositionILN, PATCH_JUMP);
InjectHook(0x4B6800, CTheZones::FindZoneByLabelAndReturnIndex, PATCH_JUMP);
+ InjectHook(0x4B6FA0, CTheZones::GetZone, PATCH_JUMP);
+ InjectHook(0x4B84F0, CTheZones::GetPointerForZoneIndex, PATCH_JUMP);
InjectHook(0x4B6A10, CTheZones::GetZoneInfo, PATCH_JUMP);
InjectHook(0x4B6FB0, CTheZones::GetZoneInfoForTimeOfDay, PATCH_JUMP);
InjectHook(0x4B6A50, CTheZones::SetZoneCarInfo, PATCH_JUMP);
diff --git a/src/entities/Automobile.h b/src/entities/Automobile.h
index 06c0e742..379124e6 100644
--- a/src/entities/Automobile.h
+++ b/src/entities/Automobile.h
@@ -5,7 +5,7 @@
class CAutomobile : public CVehicle
{
public:
- // 0x228
+ // 0x288
uint8 stuff1[484];
float m_afWheelSuspDist[4];
uint8 stuff2[300];
diff --git a/src/entities/Boat.h b/src/entities/Boat.h
new file mode 100644
index 00000000..b66ab107
--- /dev/null
+++ b/src/entities/Boat.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Vehicle.h"
+
+class CBoat : public CVehicle
+{
+public:
+ // 0x288
+ uint8 stuff[508];
+};
+static_assert(sizeof(CBoat) == 0x484, "CBoat: error");
diff --git a/src/entities/CivilianPed.h b/src/entities/CivilianPed.h
new file mode 100644
index 00000000..7a592279
--- /dev/null
+++ b/src/entities/CivilianPed.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "Ped.h"
+
+class CCivilianPed : public CPed
+{
+public:
+};
+static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
diff --git a/src/entities/CopPed.h b/src/entities/CopPed.h
new file mode 100644
index 00000000..2658a386
--- /dev/null
+++ b/src/entities/CopPed.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Ped.h"
+
+class CCopPed : public CPed
+{
+public:
+ // 0x53C
+ uint8 stuff[28];
+};
+static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp
new file mode 100644
index 00000000..a4880175
--- /dev/null
+++ b/src/entities/Dummy.cpp
@@ -0,0 +1,7 @@
+#include "common.h"
+#include "patcher.h"
+#include "Dummy.h"
+#include "Pools.h"
+
+void *CDummy::operator new(size_t sz) { return CPools::GetDummyPool()->New(); }
+void CDummy::operator delete(void *p, size_t sz) { CPools::GetDummyPool()->Delete((CDummy*)p); }
diff --git a/src/entities/Dummy.h b/src/entities/Dummy.h
new file mode 100644
index 00000000..e7506617
--- /dev/null
+++ b/src/entities/Dummy.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "Lists.h"
+#include "Entity.h"
+
+class CDummy : public CEntity
+{
+public:
+ CEntryInfoList m_entryInfoList;
+
+ static void *operator new(size_t);
+ static void operator delete(void*, size_t);
+};
+static_assert(sizeof(CDummy) == 0x68, "CDummy: error");
diff --git a/src/entities/DummyObject.h b/src/entities/DummyObject.h
new file mode 100644
index 00000000..7bfe3a57
--- /dev/null
+++ b/src/entities/DummyObject.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "Dummy.h"
+
+class CDummyObject : CDummy
+{
+};
+static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error");
diff --git a/src/entities/DummyPed.h b/src/entities/DummyPed.h
new file mode 100644
index 00000000..af633dc4
--- /dev/null
+++ b/src/entities/DummyPed.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Dummy.h"
+
+// actually unused
+class CDummyPed : CDummy
+{
+ int32 pedType;
+ int32 unknown;
+};
+static_assert(sizeof(CDummyPed) == 0x70, "CDummyPed: error");
diff --git a/src/entities/EmergencyPed.h b/src/entities/EmergencyPed.h
new file mode 100644
index 00000000..f21996e8
--- /dev/null
+++ b/src/entities/EmergencyPed.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Ped.h"
+
+class CEmergencyPed : public CPed
+{
+public:
+ // 0x53C
+ uint8 stuff[24];
+};
+static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error");
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 439d1462..2338f627 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -12,6 +12,63 @@
int gBuildings;
+CEntity::CEntity(void)
+{
+ m_type = ENTITY_TYPE_NOTHING;
+ m_status = STATUS_ABANDONED;
+
+ bUsesCollision = false;
+ bCollisionProcessed = false;
+ bIsStatic = false;
+ bHasContacted = false;
+ bPedPhysics = false;
+ bIsStuck = false;
+ bIsInSafePosition = false;
+ bUseCollisionRecords = false;
+
+ bWasPostponed = false;
+ m_flagB2 = false;
+ bIsVisible = true;
+ bHasCollided = false;
+ bRenderScorched = false;
+ m_flagB20 = false;
+ bIsBIGBuilding = false;
+ bRenderDamaged = false;
+
+ m_flagC1 = false;
+ m_flagC2 = false;
+ m_flagC4 = false;
+ m_flagC8 = false;
+ m_flagC10 = false;
+ m_flagC20 = false;
+ m_bZoneCulled = false;
+ m_bZoneCulled2 = false;
+
+ bRemoveFromWorld = false;
+ bHasHitWall = false;
+ bImBeingRendered = false;
+ m_flagD8 = false;
+ m_flagD10 = false;
+ bDrawLast = false;
+ m_flagD40 = false;
+ m_flagD80 = false;
+
+ bDistanceFade = false;
+ m_flagE2 = false;
+
+ m_scanCode = 0;
+ m_modelIndex = -1;
+ m_rwObject = nil;
+ m_randomSeed = rand();
+ m_pFirstReference = nil;
+}
+
+CEntity::~CEntity(void)
+{
+ DeleteRwObject();
+ ResolveReferences();
+}
+
void
CEntity::GetBoundCentre(CVector &out)
{
@@ -309,6 +366,28 @@ CEntity::SetupLighting(void)
}
void
+CEntity::AttachToRwObject(RwObject *obj)
+{
+ m_rwObject = obj;
+ if(m_rwObject){
+ if(RwObjectGetType(m_rwObject) == rpATOMIC)
+ m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
+ else if(RwObjectGetType(m_rwObject) == rpCLUMP)
+ m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
+ CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
+ }
+}
+
+void
+CEntity::DetachFromRwObject(void)
+{
+ if(m_rwObject)
+ CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef();
+ m_rwObject = nil;
+ m_matrix.Detach();
+}
+
+void
CEntity::RegisterReference(CEntity **pent)
{
if(IsBuilding())
@@ -381,6 +460,9 @@ STARTPATCHES
InjectHook(0x4A74E0, &CEntity::ResolveReferences, PATCH_JUMP);
InjectHook(0x4A7530, &CEntity::PruneReferences, PATCH_JUMP);
+ InjectHook(0x473F10, &CEntity::AttachToRwObject, PATCH_JUMP);
+ InjectHook(0x473F60, &CEntity::DetachFromRwObject, PATCH_JUMP);
+
InjectHook(0x475080, &CEntity::Add_, PATCH_JUMP);
InjectHook(0x475310, &CEntity::Remove_, PATCH_JUMP);
InjectHook(0x473EA0, &CEntity::CreateRwObject_, PATCH_JUMP);
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 8bcd7348..c4a5c467 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -94,6 +94,9 @@ public:
uint16 m_level; // int16
CReference *m_pFirstReference;
+ CEntity(void);
+ ~CEntity(void);
+
virtual void Add(void);
virtual void Remove(void);
virtual void SetModelIndex(uint32 i) { m_modelIndex = i; CreateRwObject(); }
@@ -120,6 +123,7 @@ public:
void GetBoundCentre(CVector &out);
CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; }
float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; }
+ float GetDistanceFromCentreOfMassToBaseOfModel(void) { return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; }
bool GetIsTouching(CVector const &center, float r);
bool GetIsOnScreen(void);
bool GetIsOnScreenComplex(void);
@@ -129,6 +133,9 @@ public:
void UpdateRwFrame(void);
void SetupBigBuilding(void);
+ void AttachToRwObject(RwObject *obj);
+ void DetachFromRwObject(void);
+
void RegisterReference(CEntity **pent);
void ResolveReferences(void);
void PruneReferences(void);
diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp
index 0d83ed97..018979eb 100644
--- a/src/entities/Ped.cpp
+++ b/src/entities/Ped.cpp
@@ -3,8 +3,8 @@
#include "Ped.h"
#include "Pools.h"
-//void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); }
-//void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
+void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); }
+void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); }
diff --git a/src/entities/Ped.h b/src/entities/Ped.h
index 04763cc1..366674d4 100644
--- a/src/entities/Ped.h
+++ b/src/entities/Ped.h
@@ -179,10 +179,10 @@ public:
CWeapon m_weapons[PED_MAX_WEAPONS];
int32 stuff7;
uint8 m_currentWeapon;
- uint8 stuff[167];
+ uint8 stuff[163];
-// static void *operator new(size_t);
-// static void operator delete(void*, size_t);
+ static void *operator new(size_t);
+ static void operator delete(void*, size_t);
bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; }
bool UseGroundColModel(void);
@@ -196,4 +196,4 @@ static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error");
static_assert(offsetof(CPed, m_pCollidingEntity) == 0x34C, "CPed: error");
static_assert(offsetof(CPed, m_weapons) == 0x35C, "CPed: error");
static_assert(offsetof(CPed, m_currentWeapon) == 0x498, "CPed: error");
-static_assert(sizeof(CPed) == 0x540, "CPed: error");
+static_assert(sizeof(CPed) == 0x53C, "CPed: error");
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 55eab951..9cd36070 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -272,7 +272,7 @@ void
CPhysical::ProcessControl(void)
{
if(!IsPed())
- m_phy_flagA8 = false;
+ bIsInWater = false;
bHasContacted = false;
bIsInSafePosition = false;
bWasPostponed = false;
@@ -438,7 +438,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(B->IsPed() && ((CPed*)B)->m_pCurrentPhysSurface == A)
ispedcontactA = true;
}else
- timestepA = A->m_phy_flagA1 ? 2.0f : 1.0f;
+ timestepA = A->bIsHeavy ? 2.0f : 1.0f;
float timestepB;
if(A->bPedPhysics){
@@ -451,7 +451,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(A->IsPed() && ((CPed*)A)->m_pCurrentPhysSurface == B)
ispedcontactB = true;
}else
- timestepB = B->m_phy_flagA1 ? 2.0f : 1.0f;
+ timestepB = B->bIsHeavy ? 2.0f : 1.0f;
float speedA, speedB;
if(B->bIsStatic){
@@ -1821,7 +1821,7 @@ CPhysical::ProcessCollision(void)
m_phy_flagA80 = false;
if(!m_vecMoveSpeed.IsZero() ||
!m_vecTurnSpeed.IsZero() ||
- m_phy_flagA40 ||
+ bHitByTrain ||
m_status == STATUS_PLAYER || IsPed() && ped->IsPlayer()){
if(IsVehicle())
((CVehicle*)this)->m_veh_flagD4 = true;
@@ -1830,7 +1830,7 @@ CPhysical::ProcessCollision(void)
return;
}
}
- m_phy_flagA40 = false;
+ bHitByTrain = false;
m_fDistanceTravelled = (GetPosition() - *savedMatrix.GetPosition()).Magnitude();
m_phy_flagA80 = false;
diff --git a/src/entities/Physical.h b/src/entities/Physical.h
index 514994f7..c6944b76 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -49,13 +49,13 @@ public:
CVector m_vecDamageNormal;
int16 m_nDamagePieceType;
- uint8 m_phy_flagA1 : 1;
+ uint8 bIsHeavy : 1;
uint8 bAffectedByGravity : 1;
uint8 bInfiniteMass : 1;
- uint8 m_phy_flagA8 : 1;
+ uint8 bIsInWater : 1;
uint8 m_phy_flagA10 : 1;
uint8 m_phy_flagA20 : 1;
- uint8 m_phy_flagA40 : 1;
+ uint8 bHitByTrain : 1; // from nick
uint8 m_phy_flagA80 : 1;
uint8 m_nLastCollType;
diff --git a/src/entities/Plane.h b/src/entities/Plane.h
new file mode 100644
index 00000000..9acc24ec
--- /dev/null
+++ b/src/entities/Plane.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Vehicle.h"
+
+class CPlane : public CVehicle
+{
+public:
+ // 0x288
+ uint8 stuff[20];
+};
+static_assert(sizeof(CPlane) == 0x29C, "CPlane: error");
diff --git a/src/entities/PlayerPed.h b/src/entities/PlayerPed.h
new file mode 100644
index 00000000..35128f46
--- /dev/null
+++ b/src/entities/PlayerPed.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Ped.h"
+
+class CPlayerPed : public CPed
+{
+public:
+ // 0x53C
+ uint8 stuff[180];
+};
+static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error");
diff --git a/src/entities/Train.h b/src/entities/Train.h
new file mode 100644
index 00000000..e591239b
--- /dev/null
+++ b/src/entities/Train.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "Vehicle.h"
+
+class CTrain : public CVehicle
+{
+public:
+ // 0x288
+ uint8 stuff[92];
+};
+static_assert(sizeof(CTrain) == 0x2E4, "CTrain: error");
diff --git a/src/entities/Vehicle.cpp b/src/entities/Vehicle.cpp
new file mode 100644
index 00000000..f18cb5a7
--- /dev/null
+++ b/src/entities/Vehicle.cpp
@@ -0,0 +1,7 @@
+#include "common.h"
+#include "patcher.h"
+#include "Vehicle.h"
+#include "Pools.h"
+
+void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); }
+void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
diff --git a/src/entities/Vehicle.h b/src/entities/Vehicle.h
index 16f11763..46e1c57c 100644
--- a/src/entities/Vehicle.h
+++ b/src/entities/Vehicle.h
@@ -54,6 +54,9 @@ uint8 m_extra2;
uint8 stuff4[139];
int32 m_vehType;
+ static void *operator new(size_t);
+ static void operator delete(void*, size_t);
+
bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; }
bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; }
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 6979bb19..c2b341dc 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -1169,6 +1169,7 @@ STARTPATCHES
InjectHook(0x4A9920, CRenderer::SetupBigBuildingVisibility, PATCH_JUMP);
InjectHook(0x4A76B0, CRenderer::ConstructRenderList, PATCH_JUMP);
+ InjectHook(0x4A7840, CRenderer::PreRender, PATCH_JUMP);
InjectHook(0x4A8970, CRenderer::ScanWorld, PATCH_JUMP);
InjectHook(0x4AA240, CRenderer::RequestObjectsInFrustum, PATCH_JUMP);
InjectHook(0x4A7F30, CRenderer::ScanSectorPoly, PATCH_JUMP);