summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/References.cpp43
-rw-r--r--src/References.h3
-rw-r--r--src/SurfaceTable.cpp53
-rw-r--r--src/SurfaceTable.h1
-rw-r--r--src/Zones.cpp225
-rw-r--r--src/Zones.h5
-rw-r--r--src/config.h3
-rw-r--r--src/entities/Object.cpp22
-rw-r--r--src/entities/Object.h2
-rw-r--r--src/render/Clouds.cpp12
-rw-r--r--src/render/Clouds.h1
-rw-r--r--src/render/Renderer.cpp7
-rw-r--r--src/render/Renderer.h1
13 files changed, 374 insertions, 4 deletions
diff --git a/src/References.cpp b/src/References.cpp
index 187f4ffa..e87f0fd5 100644
--- a/src/References.cpp
+++ b/src/References.cpp
@@ -1,5 +1,9 @@
#include "common.h"
#include "patcher.h"
+#include "World.h"
+#include "Vehicle.h"
+#include "PlayerPed.h"
+#include "Pools.h"
#include "References.h"
CReference *CReferences::aRefs = (CReference*)0x70BBE0; //[NUMREFERENCES];
@@ -17,6 +21,45 @@ CReferences::Init(void)
aRefs[NUMREFERENCES-1].next = nil;
}
+void
+CReferences::RemoveReferencesToPlayer(void)
+{
+ if(FindPlayerVehicle())
+ FindPlayerVehicle()->ResolveReferences();
+ if(FindPlayerPed())
+ FindPlayerPed()->ResolveReferences();
+}
+
+void
+CReferences::PruneAllReferencesInWorld(void)
+{
+ int i;
+ CEntity *e;
+
+ i = CPools::GetPedPool()->GetSize();
+ while(--i >= 0){
+ e = CPools::GetPedPool()->GetSlot(i);
+ if(e)
+ e->PruneReferences();
+ }
+
+ i = CPools::GetVehiclePool()->GetSize();
+ while(--i >= 0){
+ e = CPools::GetVehiclePool()->GetSlot(i);
+ if(e)
+ e->PruneReferences();
+ }
+
+ i = CPools::GetObjectPool()->GetSize();
+ while(--i >= 0){
+ e = CPools::GetObjectPool()->GetSlot(i);
+ if(e)
+ e->PruneReferences();
+ }
+}
+
STARTPATCHES
InjectHook(0x4A7350, CReferences::Init, PATCH_JUMP);
+ InjectHook(0x4A7570, CReferences::RemoveReferencesToPlayer, PATCH_JUMP);
+ InjectHook(0x4A75A0, CReferences::PruneAllReferencesInWorld, PATCH_JUMP);
ENDPATCHES
diff --git a/src/References.h b/src/References.h
index c8017c0d..6476e243 100644
--- a/src/References.h
+++ b/src/References.h
@@ -13,5 +13,8 @@ class CReferences
public:
static CReference *aRefs; //[NUMREFERENCES];
static CReference *&pEmptyList;
+
static void Init(void);
+ static void RemoveReferencesToPlayer(void);
+ static void PruneAllReferencesInWorld(void);
};
diff --git a/src/SurfaceTable.cpp b/src/SurfaceTable.cpp
index 107734e4..2ba884b1 100644
--- a/src/SurfaceTable.cpp
+++ b/src/SurfaceTable.cpp
@@ -1,11 +1,57 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
+#include "FileMgr.h"
#include "Weather.h"
#include "Collision.h"
#include "SurfaceTable.h"
float (*CSurfaceTable::ms_aAdhesiveLimitTable)[NUMADHESIVEGROUPS] = (float (*)[NUMADHESIVEGROUPS])0x8E29D4;
+void
+CSurfaceTable::Initialise(char *filename)
+{
+ int lineno, fieldno;
+ char *line;
+ char surfname[256];
+ float adhesiveLimit;
+
+ CFileMgr::SetDir("");
+ CFileMgr::LoadFile(filename, work_buff, sizeof(work_buff), "r");
+
+ line = (char*)work_buff;
+ for(lineno = 0; lineno < NUMADHESIVEGROUPS; lineno++){
+ // skip white space and comments
+ while(*line == ' ' || *line == '\t' || *line == '\n' || *line == '\r' || *line == ';'){
+ if(*line == ';'){
+ while(*line != '\n' && *line != '\r')
+ line++;
+ }else
+ line++;
+ }
+
+ sscanf(line, "%s", surfname);
+ // skip what we just read
+ while(!(*line == ' ' || *line == '\t' || *line == ','))
+ line++;
+
+ for(fieldno = 0; fieldno <= lineno; fieldno++){
+ // skip white space
+ while(*line == ' ' || *line == '\t' || *line == ',')
+ line++;
+ adhesiveLimit = 0.0f;
+ if(*line != '-')
+ sscanf(line, "%f", &adhesiveLimit);
+ // skip what we just read
+ while(!(*line == ' ' || *line == '\t' || *line == ',' || *line == '\n'))
+ line++;
+
+ ms_aAdhesiveLimitTable[lineno][fieldno] = adhesiveLimit;
+ ms_aAdhesiveLimitTable[fieldno][lineno] = adhesiveLimit;
+ }
+ }
+}
+
int
CSurfaceTable::GetAdhesionGroup(uint8 surfaceType)
{
@@ -95,3 +141,10 @@ CSurfaceTable::GetAdhesiveLimit(CColPoint &colpoint)
{
return ms_aAdhesiveLimitTable[GetAdhesionGroup(colpoint.surfaceB)][GetAdhesionGroup(colpoint.surfaceA)];
}
+
+STARTPATCHES
+ InjectHook(0x4AB8F0, CSurfaceTable::Initialise, PATCH_JUMP);
+ InjectHook(0x4ABA60, CSurfaceTable::GetAdhesionGroup, PATCH_JUMP);
+ InjectHook(0x4ABAA0, CSurfaceTable::GetWetMultiplier, PATCH_JUMP);
+ InjectHook(0x4ABA30, CSurfaceTable::GetAdhesiveLimit, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/SurfaceTable.h b/src/SurfaceTable.h
index e61f5026..e1882e69 100644
--- a/src/SurfaceTable.h
+++ b/src/SurfaceTable.h
@@ -99,6 +99,7 @@ class CSurfaceTable
// static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
static float (*ms_aAdhesiveLimitTable)[NUMADHESIVEGROUPS];
public:
+ static void Initialise(char *filename);
static int GetAdhesionGroup(uint8 surfaceType);
static float GetWetMultiplier(uint8 surfaceType);
static float GetAdhesiveLimit(CColPoint &colpoint);
diff --git a/src/Zones.cpp b/src/Zones.cpp
index 4d2d9e5d..363fc3d9 100644
--- a/src/Zones.cpp
+++ b/src/Zones.cpp
@@ -43,7 +43,9 @@ CheckZoneInfo(CZoneInfo *info)
assert(info->gangThreshold[7] <= info->gangThreshold[8]);
}
-wchar* CZone::GetTranslatedName() {
+wchar*
+CZone::GetTranslatedName(void)
+{
return TheText.Get(name);
}
@@ -621,6 +623,224 @@ CTheZones::InitialiseAudioZoneArray(void)
}
}
+void
+CTheZones::SaveAllZones(uint8 *buffer, uint32 *length)
+{
+ int i;
+
+ *length = 8 + 12 +
+ NUMZONES*56 + 2*NUMZONES*58 + 4 +
+ NUMMAPZONES*56 + NUMAUDIOZONES*2 + 4;
+
+ buffer[0] = 'Z';
+ buffer[1] = 'N';
+ buffer[2] = 'S';
+ buffer[3] = '\0';
+ *(uint32*)(buffer+4) = *length - 8;
+ buffer += 8;
+
+ *(int32*)(buffer) = GetIndexForZonePointer(m_pPlayersZone);
+ *(int32*)(buffer+4) = m_CurrLevel;
+ *(int16*)(buffer+8) = FindIndex;
+ *(int16*)(buffer+10) = 0;
+ buffer += 12;
+
+ for(i = 0; i < NUMZONES; i++){
+ memcpy(buffer, ZoneArray[i].name, 8);
+ *(float*)(buffer+8) = ZoneArray[i].minx;
+ *(float*)(buffer+12) = ZoneArray[i].miny;
+ *(float*)(buffer+16) = ZoneArray[i].minz;
+ *(float*)(buffer+20) = ZoneArray[i].maxx;
+ *(float*)(buffer+24) = ZoneArray[i].maxy;
+ *(float*)(buffer+28) = ZoneArray[i].maxz;
+ *(int32*)(buffer+32) = ZoneArray[i].type;
+ *(int32*)(buffer+36) = ZoneArray[i].level;
+ *(int16*)(buffer+40) = ZoneArray[i].zoneinfoDay;
+ *(int16*)(buffer+42) = ZoneArray[i].zoneinfoNight;
+ *(int32*)(buffer+44) = GetIndexForZonePointer(ZoneArray[i].child);
+ *(int32*)(buffer+48) = GetIndexForZonePointer(ZoneArray[i].parent);
+ *(int32*)(buffer+52) = GetIndexForZonePointer(ZoneArray[i].next);
+ buffer += 56;
+ }
+
+ for(i = 0; i < 2*NUMZONES; i++){
+ *(int16*)(buffer) = ZoneInfoArray[i].carDensity;
+ *(int16*)(buffer+2) = ZoneInfoArray[i].carThreshold[0];
+ *(int16*)(buffer+4) = ZoneInfoArray[i].carThreshold[1];
+ *(int16*)(buffer+6) = ZoneInfoArray[i].carThreshold[2];
+ *(int16*)(buffer+8) = ZoneInfoArray[i].carThreshold[3];
+ *(int16*)(buffer+10) = ZoneInfoArray[i].carThreshold[4];
+ *(int16*)(buffer+12) = ZoneInfoArray[i].carThreshold[5];
+ *(int16*)(buffer+14) = ZoneInfoArray[i].copThreshold;
+ *(int16*)(buffer+16) = ZoneInfoArray[i].gangThreshold[0];
+ *(int16*)(buffer+18) = ZoneInfoArray[i].gangThreshold[1];
+ *(int16*)(buffer+20) = ZoneInfoArray[i].gangThreshold[2];
+ *(int16*)(buffer+22) = ZoneInfoArray[i].gangThreshold[3];
+ *(int16*)(buffer+24) = ZoneInfoArray[i].gangThreshold[4];
+ *(int16*)(buffer+26) = ZoneInfoArray[i].gangThreshold[5];
+ *(int16*)(buffer+28) = ZoneInfoArray[i].gangThreshold[6];
+ *(int16*)(buffer+30) = ZoneInfoArray[i].gangThreshold[7];
+ *(int16*)(buffer+32) = ZoneInfoArray[i].gangThreshold[8];
+ *(uint16*)(buffer+34) = ZoneInfoArray[i].pedDensity;
+ *(uint16*)(buffer+36) = ZoneInfoArray[i].copDensity;
+ *(uint16*)(buffer+38) = ZoneInfoArray[i].gangDensity[0];
+ *(uint16*)(buffer+40) = ZoneInfoArray[i].gangDensity[1];
+ *(uint16*)(buffer+42) = ZoneInfoArray[i].gangDensity[2];
+ *(uint16*)(buffer+44) = ZoneInfoArray[i].gangDensity[3];
+ *(uint16*)(buffer+46) = ZoneInfoArray[i].gangDensity[4];
+ *(uint16*)(buffer+48) = ZoneInfoArray[i].gangDensity[5];
+ *(uint16*)(buffer+50) = ZoneInfoArray[i].gangDensity[6];
+ *(uint16*)(buffer+52) = ZoneInfoArray[i].gangDensity[7];
+ *(uint16*)(buffer+54) = ZoneInfoArray[i].gangDensity[8];
+ *(uint16*)(buffer+56) = ZoneInfoArray[i].pedGroup;
+ buffer += 58;
+ }
+
+ *(uint16*)(buffer) = TotalNumberOfZones;
+ *(uint16*)(buffer+2) = TotalNumberOfZoneInfos;
+ buffer += 4;
+
+ for(i = 0; i < NUMMAPZONES; i++){
+ memcpy(buffer, MapZoneArray[i].name, 8);
+ *(float*)(buffer+8) = MapZoneArray[i].minx;
+ *(float*)(buffer+12) = MapZoneArray[i].miny;
+ *(float*)(buffer+16) = MapZoneArray[i].minz;
+ *(float*)(buffer+20) = MapZoneArray[i].maxx;
+ *(float*)(buffer+24) = MapZoneArray[i].maxy;
+ *(float*)(buffer+28) = MapZoneArray[i].maxz;
+ *(int32*)(buffer+32) = MapZoneArray[i].type;
+ *(int32*)(buffer+36) = MapZoneArray[i].level;
+ *(int16*)(buffer+40) = MapZoneArray[i].zoneinfoDay;
+ *(int16*)(buffer+42) = MapZoneArray[i].zoneinfoNight;
+#ifdef STANDALONE
+ // BUG: GetIndexForZonePointer uses ZoneArray
+ // so indices will be unpredictable with different memory layout
+ assert(0);
+#endif
+ *(int32*)(buffer+44) = GetIndexForZonePointer(MapZoneArray[i].child);
+ *(int32*)(buffer+48) = GetIndexForZonePointer(MapZoneArray[i].parent);
+ *(int32*)(buffer+52) = GetIndexForZonePointer(MapZoneArray[i].next);
+ buffer += 56;
+ }
+
+ for(i = 0; i < NUMAUDIOZONES; i++){
+ *(int16*)buffer = AudioZoneArray[i];
+ buffer += 2;
+ }
+
+ *(uint16*)(buffer) = TotalNumberOfMapZones;
+ *(uint16*)(buffer+2) = NumberOfAudioZones;
+}
+
+void
+CTheZones::LoadAllZones(uint8 *buffer, uint32 length)
+{
+ int i;
+
+ assert(length == 8 + 12 +
+ NUMZONES*56 + 2*NUMZONES*58 + 4 +
+ NUMMAPZONES*56 + NUMAUDIOZONES*2 + 4);
+ assert(buffer[0] == 'Z');
+ assert(buffer[1] == 'N');
+ assert(buffer[2] == 'S');
+ assert(buffer[3] == '\0');
+ assert(*(uint32*)(buffer+4) == length - 8);
+ buffer += 8;
+
+ m_pPlayersZone = GetPointerForZoneIndex(*(int32*)(buffer));
+ m_CurrLevel = (eLevelName)*(int32*)(buffer+4);
+ FindIndex = *(int16*)(buffer+8);
+ assert(*(int16*)(buffer+10) == 0);
+ buffer += 12;
+
+ for(i = 0; i < NUMZONES; i++){
+ memcpy(ZoneArray[i].name, buffer, 8);
+ ZoneArray[i].minx = *(float*)(buffer+8);
+ ZoneArray[i].miny = *(float*)(buffer+12);
+ ZoneArray[i].minz = *(float*)(buffer+16);
+ ZoneArray[i].maxx = *(float*)(buffer+20);
+ ZoneArray[i].maxy = *(float*)(buffer+24);
+ ZoneArray[i].maxz = *(float*)(buffer+28);
+ ZoneArray[i].type = (eZoneType)*(int32*)(buffer+32);
+ ZoneArray[i].level = (eLevelName)*(int32*)(buffer+36);
+ ZoneArray[i].zoneinfoDay = *(int16*)(buffer+40);
+ ZoneArray[i].zoneinfoNight = *(int16*)(buffer+42);
+ ZoneArray[i].child = GetPointerForZoneIndex(*(int32*)(buffer+44));
+ ZoneArray[i].parent = GetPointerForZoneIndex(*(int32*)(buffer+48));
+ ZoneArray[i].next = GetPointerForZoneIndex(*(int32*)(buffer+52));
+ buffer += 56;
+ }
+
+ for(i = 0; i < 2*NUMZONES; i++){
+ ZoneInfoArray[i].carDensity = *(int16*)(buffer);
+ ZoneInfoArray[i].carThreshold[0] = *(int16*)(buffer+2);
+ ZoneInfoArray[i].carThreshold[1] = *(int16*)(buffer+4);
+ ZoneInfoArray[i].carThreshold[2] = *(int16*)(buffer+6);
+ ZoneInfoArray[i].carThreshold[3] = *(int16*)(buffer+8);
+ ZoneInfoArray[i].carThreshold[4] = *(int16*)(buffer+10);
+ ZoneInfoArray[i].carThreshold[5] = *(int16*)(buffer+12);
+ ZoneInfoArray[i].copThreshold = *(int16*)(buffer+14);
+ ZoneInfoArray[i].gangThreshold[0] = *(int16*)(buffer+16);
+ ZoneInfoArray[i].gangThreshold[1] = *(int16*)(buffer+18);
+ ZoneInfoArray[i].gangThreshold[2] = *(int16*)(buffer+20);
+ ZoneInfoArray[i].gangThreshold[3] = *(int16*)(buffer+22);
+ ZoneInfoArray[i].gangThreshold[4] = *(int16*)(buffer+24);
+ ZoneInfoArray[i].gangThreshold[5] = *(int16*)(buffer+26);
+ ZoneInfoArray[i].gangThreshold[6] = *(int16*)(buffer+28);
+ ZoneInfoArray[i].gangThreshold[7] = *(int16*)(buffer+30);
+ ZoneInfoArray[i].gangThreshold[8] = *(int16*)(buffer+32);
+ ZoneInfoArray[i].pedDensity = *(uint16*)(buffer+34);
+ ZoneInfoArray[i].copDensity = *(uint16*)(buffer+36);
+ ZoneInfoArray[i].gangDensity[0] = *(uint16*)(buffer+38);
+ ZoneInfoArray[i].gangDensity[1] = *(uint16*)(buffer+40);
+ ZoneInfoArray[i].gangDensity[2] = *(uint16*)(buffer+42);
+ ZoneInfoArray[i].gangDensity[3] = *(uint16*)(buffer+44);
+ ZoneInfoArray[i].gangDensity[4] = *(uint16*)(buffer+46);
+ ZoneInfoArray[i].gangDensity[5] = *(uint16*)(buffer+48);
+ ZoneInfoArray[i].gangDensity[6] = *(uint16*)(buffer+50);
+ ZoneInfoArray[i].gangDensity[7] = *(uint16*)(buffer+52);
+ ZoneInfoArray[i].gangDensity[8] = *(uint16*)(buffer+54);
+ ZoneInfoArray[i].pedGroup = *(uint16*)(buffer+56);
+ buffer += 58;
+ }
+
+ TotalNumberOfZones = *(uint16*)(buffer);
+ TotalNumberOfZoneInfos = *(uint16*)(buffer+2);
+ buffer += 4;
+
+ for(i = 0; i < NUMMAPZONES; i++){
+ memcpy(MapZoneArray[i].name, buffer, 8);
+ MapZoneArray[i].minx = *(float*)(buffer+8);
+ MapZoneArray[i].miny = *(float*)(buffer+12);
+ MapZoneArray[i].minz = *(float*)(buffer+16);
+ MapZoneArray[i].maxx = *(float*)(buffer+20);
+ MapZoneArray[i].maxy = *(float*)(buffer+24);
+ MapZoneArray[i].maxz = *(float*)(buffer+28);
+ MapZoneArray[i].type = (eZoneType)*(int32*)(buffer+32);
+ MapZoneArray[i].level = (eLevelName)*(int32*)(buffer+36);
+ MapZoneArray[i].zoneinfoDay = *(int16*)(buffer+40);
+ MapZoneArray[i].zoneinfoNight = *(int16*)(buffer+42);
+#ifdef STANDALONE
+ // BUG: GetPointerForZoneIndex uses ZoneArray
+ // so pointers will be unpredictable with different memory layout
+ assert(0);
+#endif
+ MapZoneArray[i].child = GetPointerForZoneIndex(*(int32*)(buffer+44));
+ MapZoneArray[i].parent = GetPointerForZoneIndex(*(int32*)(buffer+48));
+ MapZoneArray[i].next = GetPointerForZoneIndex(*(int32*)(buffer+52));
+ buffer += 56;
+ }
+
+ for(i = 0; i < NUMAUDIOZONES; i++){
+ AudioZoneArray[i] = *(int16*)buffer;
+ buffer += 2;
+ }
+
+ TotalNumberOfMapZones = *(uint16*)(buffer);
+ NumberOfAudioZones = *(uint16*)(buffer+2);
+}
+
+
STARTPATCHES
InjectHook(0x4B5DD0, &CZone::GetTranslatedName, PATCH_JUMP);
InjectHook(0x4B5DE0, CTheZones::Init, PATCH_JUMP);
@@ -649,5 +869,6 @@ STARTPATCHES
InjectHook(0x4B83E0, CTheZones::FindAudioZone, PATCH_JUMP);
InjectHook(0x4B8430, CTheZones::FindZoneForPoint, PATCH_JUMP);
InjectHook(0x4B8340, CTheZones::AddZoneToAudioZoneArray, PATCH_JUMP);
- InjectHook(0x4B8380, CTheZones::InitialiseAudioZoneArray, PATCH_JUMP);
+ InjectHook(0x4B8510, CTheZones::SaveAllZones, PATCH_JUMP);
+ InjectHook(0x4B8950, CTheZones::LoadAllZones, PATCH_JUMP);
ENDPATCHES
diff --git a/src/Zones.h b/src/Zones.h
index 47a4dc47..bf3957de 100644
--- a/src/Zones.h
+++ b/src/Zones.h
@@ -28,7 +28,7 @@ public:
CZone *parent;
CZone *next;
- wchar *GetTranslatedName();
+ wchar *GetTranslatedName(void);
};
class CZoneInfo
@@ -104,6 +104,9 @@ public:
static int16 FindAudioZone(CVector *pos);
static eLevelName FindZoneForPoint(const CVector &pos);
static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; }
+ static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void);
+ static void SaveAllZones(uint8 *buffer, uint32 *length);
+ static void LoadAllZones(uint8 *buffer, uint32 length);
};
diff --git a/src/config.h b/src/config.h
index a1e7335d..8cb02190 100644
--- a/src/config.h
+++ b/src/config.h
@@ -62,6 +62,9 @@ enum Config {
NUMPICKUPS = 336,
};
+// We'll use this once we're ready to become independent of the game
+// Use it to mark bugs in the code that will prevent the game from working then
+//#define STANDALONE
// We don't expect to compile for PS2 or Xbox
// but it might be interesting for documentation purposes
diff --git a/src/entities/Object.cpp b/src/entities/Object.cpp
index dbc38b9d..6712d77b 100644
--- a/src/entities/Object.cpp
+++ b/src/entities/Object.cpp
@@ -1,5 +1,7 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
+#include "Lights.h"
#include "Pools.h"
#include "Radar.h"
#include "Object.h"
@@ -63,6 +65,26 @@ CObject::Render(void)
CEntity::Render();
}
+bool
+CObject::SetupLighting(void)
+{
+ DeActivateDirectional();
+ SetAmbientColours();
+
+ if(bRenderScorched){
+ WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
+ return true;
+ }
+ return false;
+}
+
+void
+CObject::RemoveLighting(bool reset)
+{
+ if(reset)
+ WorldReplaceScorchedLightsWithNormal(Scene.world);
+}
+
WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); }
STARTPATCHES
diff --git a/src/entities/Object.h b/src/entities/Object.h
index 3a8d62f2..de4c8e05 100644
--- a/src/entities/Object.h
+++ b/src/entities/Object.h
@@ -68,6 +68,8 @@ public:
~CObject(void);
void Render(void);
+ bool SetupLighting(void);
+ void RemoveLighting(bool reset);
void ObjectDamage(float amount);
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index bf572841..d582bff8 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -41,6 +41,16 @@ CClouds::Init(void)
}
void
+CClouds::Shutdown(void)
+{
+ RwTextureDestroy(gpCloudTex[0]);
+ RwTextureDestroy(gpCloudTex[1]);
+ RwTextureDestroy(gpCloudTex[2]);
+ RwTextureDestroy(gpCloudTex[3]);
+ RwTextureDestroy(gpCloudTex[4]);
+}
+
+void
CClouds::Update(void)
{
float s = sin(TheCamera.Orientation - 0.85f);
@@ -48,7 +58,6 @@ CClouds::Update(void)
IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep() + 0.3f) * 60.0f;
}
-
void
CClouds::Render(void)
{
@@ -424,6 +433,7 @@ CClouds::RenderHorizon(void)
STARTPATCHES
InjectHook(0x4F6C10, CClouds::Init, PATCH_JUMP);
+ InjectHook(0x4F6CA0, CClouds::Shutdown, PATCH_JUMP);
InjectHook(0x4F6CE0, CClouds::Update, PATCH_JUMP);
InjectHook(0x4F6D90, CClouds::Render, PATCH_JUMP);
InjectHook(0x4F7F00, CClouds::RenderBackground, PATCH_JUMP);
diff --git a/src/render/Clouds.h b/src/render/Clouds.h
index 96f04bb1..c8000569 100644
--- a/src/render/Clouds.h
+++ b/src/render/Clouds.h
@@ -12,6 +12,7 @@ public:
static CRGBA &ms_colourBottom;
static void Init(void);
+ static void Shutdown(void);
static void Update(void);
static void Render(void);
static void RenderBackground(int16 topred, int16 topgreen, int16 topblue,
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 405b9bb2..a6f28443 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -54,6 +54,12 @@ CRenderer::Init(void)
}
void
+CRenderer::Shutdown(void)
+{
+ gSortedVehiclesAndPeds.Shutdown();
+}
+
+void
CRenderer::PreRender(void)
{
int i;
@@ -1170,6 +1176,7 @@ CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset)
STARTPATCHES
InjectHook(0x4A7680, CRenderer::Init, PATCH_JUMP);
+ InjectHook(0x4A76A0, CRenderer::Shutdown, PATCH_JUMP);
InjectHook(0x4A7B90, CRenderer::RenderOneRoad, PATCH_JUMP);
InjectHook(0x4A7BA0, CRenderer::RenderOneNonRoad, PATCH_JUMP);
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index 433035a0..4b96c775 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -27,6 +27,7 @@ public:
static bool &m_loadingPriority;
static void Init(void);
+ static void Shutdown(void);
static void PreRender(void);
static void RenderRoads(void);