summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Collision.cpp299
-rw-r--r--src/Collision.h2
-rw-r--r--src/CullZones.cpp29
-rw-r--r--src/FileLoader.cpp4
-rw-r--r--src/Game.cpp3
-rw-r--r--src/Game.h15
-rw-r--r--src/control/Population.cpp2
-rw-r--r--src/control/Population.h1
-rw-r--r--src/control/Replay.cpp2
-rw-r--r--src/control/Replay.h1
-rw-r--r--src/entities/Train.h11
-rw-r--r--src/main.cpp31
-rw-r--r--src/main.h3
-rw-r--r--src/modelinfo/ModelInfo.cpp18
-rw-r--r--src/modelinfo/ModelInfo.h1
-rw-r--r--src/skel/win/win.cpp11
16 files changed, 388 insertions, 45 deletions
diff --git a/src/Collision.cpp b/src/Collision.cpp
index 774caf9d..2ab609f1 100644
--- a/src/Collision.cpp
+++ b/src/Collision.cpp
@@ -1,7 +1,20 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
+#include "Lists.h"
#include "Game.h"
+#include "Zones.h"
#include "General.h"
+#include "CullZones.h"
+#include "World.h"
+#include "Entity.h"
+#include "Train.h"
+#include "Streaming.h"
+#include "Pad.h"
+#include "DMAudio.h"
+#include "Population.h"
+#include "FileLoader.h"
+#include "Replay.h"
#include "RenderBuffer.h"
#include "SurfaceTable.h"
#include "Collision.h"
@@ -19,8 +32,6 @@ enum Direction
eLevelName &CCollision::ms_collisionInMemory = *(eLevelName*)0x8F6250;
CLinkList<CColModel*> &CCollision::ms_colModelCache = *(CLinkList<CColModel*>*)0x95CB58;
-#if 0
-
void
CCollision::Init(void)
{
@@ -29,71 +40,201 @@ CCollision::Init(void)
}
void
+CCollision::Shutdown(void)
+{
+ ms_colModelCache.Shutdown();
+}
+
+void
CCollision::Update(void)
{
- CVector pos = FindPlayerCoors();
+ CVector playerCoors;
+ FindPlayerCoors(playerCoors);
eLevelName level = CTheZones::m_CurrLevel;
- bool changeLevel = false;
+ bool forceLevelChange = false;
// hardcode a level if there are no zones
if(level == LEVEL_NONE){
if(CGame::currLevel == LEVEL_INDUSTRIAL &&
- pos.x < 400.0f){
+ playerCoors.x < 400.0f){
level = LEVEL_COMMERCIAL;
- changeLevel = true;
+ forceLevelChange = true;
}else if(CGame::currLevel == LEVEL_SUBURBAN &&
- pos.x > -450.0f && pos.y < -1400.0f){
+ playerCoors.x > -450.0f && playerCoors.y < -1400.0f){
level = LEVEL_COMMERCIAL;
- changeLevel = true;
+ forceLevelChange = true;
}else{
- if(pos.x > 800.0f){
+ if(playerCoors.x > 800.0f){
level = LEVEL_INDUSTRIAL;
- changeLevel = true;
- }else if(pos.x < -800.0f){
+ forceLevelChange = true;
+ }else if(playerCoors.x < -800.0f){
level = LEVEL_SUBURBAN;
- changeLevel = true;
+ forceLevelChange = true;
}
}
}
- if(level != LEVEL_NONE && level != CGame::currLevel){
- debug("changing level %d -> %d\n", CGame::currLevel, level);
+ if(level != LEVEL_NONE && level != CGame::currLevel)
CGame::currLevel = level;
- }
if(ms_collisionInMemory != CGame::currLevel)
- LoadCollisionWhenINeedIt(changeLevel);
+ LoadCollisionWhenINeedIt(forceLevelChange);
CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
}
+eLevelName
+GetCollisionInSectorList(CPtrList &list)
+{
+ CPtrNode *node;
+ CEntity *e;
+ int level;
+
+ for(node = list.first; node; node = node->next){
+ e = (CEntity*)node->item;
+ level = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel()->level;
+ if(level != LEVEL_NONE)
+ return (eLevelName)level;
+ }
+ return LEVEL_NONE;
+}
+
+// Get a level this sector is in based on collision models
+eLevelName
+GetCollisionInSector(CSector &sect)
+{
+ int level;
+
+ level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_BUILDINGS]);
+ if(level == LEVEL_NONE)
+ level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
+ if(level == LEVEL_NONE)
+ level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_OBJECTS]);
+ if(level == LEVEL_NONE)
+ level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_OBJECTS_OVERLAP]);
+ if(level == LEVEL_NONE)
+ level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_DUMMIES]);
+ if(level == LEVEL_NONE)
+ level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_DUMMIES_OVERLAP]);
+ return (eLevelName)level;
+}
+
void
-CCollision::LoadCollisionWhenINeedIt(bool changeLevel)
+CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
- eLevelName level;
+ eLevelName level, l;
+ bool multipleLevels;
+ CVector playerCoors;
+ CVehicle *veh;
+ CEntryInfoNode *ei;
+ int sx, sy;
+ int xmin, xmax, ymin, ymax;
+ int x, y;
+
level = LEVEL_NONE;
- if(!changeLevel){
- //assert(0 && "unimplemented");
+
+ FindPlayerCoors(playerCoors);
+ sx = CWorld::GetSectorIndexX(playerCoors.x);
+ sy = CWorld::GetSectorIndexX(playerCoors.y);
+ multipleLevels = false;
+
+ veh = FindPlayerVehicle();
+ if(veh && veh->IsTrain()){
+ if(((CTrain*)veh)->m_doorState != TRAIN_DOOR_STATE2)
+ return ;
+ }else if(playerCoors.z < 4.0f && !CCullZones::DoINeedToLoadCollision())
+ return;
+
+ // Figure out whose level's collisions we're most likely to be interested in
+ if(!forceChange){
+ if(veh && veh->IsBoat()){
+ // on water we expect to be between levels
+ multipleLevels = true;
+ }else{
+ xmin = max(sx - 1, 0);
+ xmax = min(sx + 1, NUMSECTORS_X-1);
+ ymin = max(sy - 1, 0);
+ ymax = min(sy + 1, NUMSECTORS_Y-1);
+
+ for(x = xmin; x <= xmax; x++)
+ for(y = ymin; y <= ymax; y++){
+ l = GetCollisionInSector(*CWorld::GetSector(x, y));
+ if(l != LEVEL_NONE){
+ if(level == LEVEL_NONE)
+ level = l;
+ if(level != l)
+ multipleLevels = true;
+ }
+ }
+ }
+
+ if(multipleLevels && veh && veh->IsBoat())
+ for(ei = veh->m_entryInfoList.first; ei; ei = ei->next){
+ level = GetCollisionInSector(*ei->sector);
+ if(level != LEVEL_NONE)
+ break;
+ }
}
- if(level != CGame::currLevel || changeLevel){
+ if(level == CGame::currLevel || forceChange){
CTimer::Stop();
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+ CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false);
CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
+ CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
+ CStreaming::RemoveUnusedModelsInLoadedList();
+ CGame::TidyUpMemory(true, true);
+ CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
ms_collisionInMemory = CGame::currLevel;
+ CReplay::EmptyReplayBuffer();
+ if(CGame::currLevel != LEVEL_NONE)
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
CStreaming::RequestBigBuildings(CGame::currLevel);
- CStreaming::LoadAllRequestedModels();
+ CStreaming::LoadAllRequestedModels(true);
CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
+ CGame::TidyUpMemory(true, true);
CTimer::Update();
+ DMAudio.SetEffectsFadeVol(127);
}
}
-#endif
+void
+CCollision::SortOutCollisionAfterLoad(void)
+{
+ if(ms_collisionInMemory == CGame::currLevel)
+ return;
-WRAPPER void CCollision::SortOutCollisionAfterLoad(void) { EAXJMP(0x40B900); }
+ CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
+ if(CGame::currLevel != LEVEL_NONE){
+ CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
+ if(!CGame::playingIntro)
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
+ }
+ ms_collisionInMemory = CGame::currLevel;
+ CGame::TidyUpMemory(true, false);
+}
+
+void
+CCollision::LoadCollisionScreen(eLevelName level)
+{
+ static char *levelNames[4] = {
+ "",
+ "IND_ZON",
+ "COM_ZON",
+ "SUB_ZON"
+ };
+
+ // Why twice?
+ LoadingIslandScreen(levelNames[level]);
+ LoadingIslandScreen(levelNames[level]);
+}
//
// Test
@@ -1585,11 +1726,119 @@ CColModel::GetTrianglePoint(CVector &v, int i) const
v = vertices[i];
}
-WRAPPER CColModel& CColModel::operator=(const CColModel& other) { EAXJMP(0x411710); }
+CColModel&
+CColModel::operator=(const CColModel &other)
+{
+ int i;
+ int numVerts;
+
+ assert(0);
+
+ boundingSphere = other.boundingSphere;
+ boundingBox = other.boundingBox;
+
+ // copy spheres
+ if(other.numSpheres){
+ if(numSpheres != other.numSpheres){
+ numSpheres = other.numSpheres;
+ if(spheres)
+ RwFree(spheres);
+ spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere));
+ }
+ for(i = 0; i < numSpheres; i++)
+ spheres[i] = other.spheres[i];
+ }else{
+ numSpheres = 0;
+ if(spheres)
+ RwFree(spheres);
+ spheres = nil;
+ }
+
+ // copy lines
+ if(other.numLines){
+ if(numLines != other.numLines){
+ numLines = other.numLines;
+ if(lines)
+ RwFree(lines);
+ lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine));
+ }
+ for(i = 0; i < numLines; i++)
+ lines[i] = other.lines[i];
+ }else{
+ numLines = 0;
+ if(lines)
+ RwFree(lines);
+ lines = nil;
+ }
+
+ // copy boxes
+ if(other.numBoxes){
+ if(numBoxes != other.numBoxes){
+ numBoxes = other.numBoxes;
+ if(boxes)
+ RwFree(boxes);
+ boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox));
+ }
+ for(i = 0; i < numBoxes; i++)
+ boxes[i] = other.boxes[i];
+ }else{
+ numBoxes = 0;
+ if(boxes)
+ RwFree(boxes);
+ boxes = nil;
+ }
+
+ // copy mesh
+ if(other.numTriangles){
+ // copy vertices
+ numVerts = 0;
+ for(i = 0; i < other.numTriangles; i++){
+ if(other.triangles[i].a > numVerts)
+ other.triangles[i].a = numVerts;
+ if(other.triangles[i].b > numVerts)
+ other.triangles[i].b = numVerts;
+ if(other.triangles[i].c > numVerts)
+ other.triangles[i].c = numVerts;
+ }
+ numVerts++;
+ if(vertices)
+ RwFree(vertices);
+ if(numVerts){
+ vertices = (CVector*)RwMalloc(numVerts*sizeof(CVector));
+ for(i = 0; i < numVerts; i++)
+ vertices[i] = other.vertices[i];
+ }
+
+ // copy triangles
+ if(numTriangles != other.numTriangles){
+ numTriangles = other.numTriangles;
+ if(triangles)
+ RwFree(triangles);
+ triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
+ }
+ for(i = 0; i < numTriangles; i++)
+ triangles[i] = other.triangles[i];
+ }else{
+ numTriangles = 0;
+ if(triangles)
+ RwFree(triangles);
+ triangles = nil;
+ if(vertices)
+ RwFree(vertices);
+ vertices = nil;
+ }
+ return *this;
+}
STARTPATCHES
InjectHook(0x4B9C30, (CMatrix& (*)(const CMatrix &src, CMatrix &dst))Invert, PATCH_JUMP);
+ InjectHook(0x40B380, CCollision::Init, PATCH_JUMP);
+ InjectHook(0x40B3A0, CCollision::Shutdown, PATCH_JUMP);
+ InjectHook(0x40B3B0, CCollision::Update, PATCH_JUMP);
+ InjectHook(0x40B5B0, CCollision::LoadCollisionWhenINeedIt, PATCH_JUMP);
+ InjectHook(0x40B900, CCollision::SortOutCollisionAfterLoad, PATCH_JUMP);
+
InjectHook(0x40BB70, CCollision::TestSphereBox, PATCH_JUMP);
InjectHook(0x40E130, CCollision::TestLineBox, PATCH_JUMP);
InjectHook(0x40E5C0, CCollision::TestVerticalLineBox, PATCH_JUMP);
diff --git a/src/Collision.h b/src/Collision.h
index aa125334..5a9058d3 100644
--- a/src/Collision.h
+++ b/src/Collision.h
@@ -118,9 +118,11 @@ public:
static CLinkList<CColModel*> &ms_colModelCache;
static void Init(void);
+ static void Shutdown(void);
static void Update(void);
static void LoadCollisionWhenINeedIt(bool changeLevel);
static void SortOutCollisionAfterLoad(void);
+ static void LoadCollisionScreen(eLevelName level);
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
diff --git a/src/CullZones.cpp b/src/CullZones.cpp
index f89d8256..9e020f73 100644
--- a/src/CullZones.cpp
+++ b/src/CullZones.cpp
@@ -2,6 +2,7 @@
#include "patcher.h"
#include "Building.h"
#include "Treadable.h"
+#include "Train.h"
#include "Pools.h"
#include "Timer.h"
#include "Camera.h"
@@ -162,9 +163,33 @@ CCullZones::FindZoneWithStairsAttributeForPlayer(void)
return nil;
}
-WRAPPER void
+void
CCullZones::MarkSubwayAsInvisible(bool visible)
-{ EAXJMP(0x525AF0);
+{
+ int i, n;
+ CEntity *e;
+ CVehicle *v;
+
+ n = CPools::GetBuildingPool()->GetSize();
+ for(i = 0; i < n; i++){
+ e = CPools::GetBuildingPool()->GetSlot(i);
+ if(e && e->bIsSubway)
+ e->bIsVisible = visible;
+ }
+
+ n = CPools::GetTreadablePool()->GetSize();
+ for(i = 0; i < n; i++){
+ e = CPools::GetTreadablePool()->GetSlot(i);
+ if(e && e->bIsSubway)
+ e->bIsVisible = visible;
+ }
+
+ n = CPools::GetVehiclePool()->GetSize();
+ for(i = 0; i < n; i++){
+ v = CPools::GetVehiclePool()->GetSlot(i);
+ if(v && v->IsTrain() && ((CTrain*)v)->m_trackId != 0)
+ v->bIsVisible = visible;
+ }
}
void
diff --git a/src/FileLoader.cpp b/src/FileLoader.cpp
index dd58614d..8213a5c7 100644
--- a/src/FileLoader.cpp
+++ b/src/FileLoader.cpp
@@ -46,7 +46,7 @@ CFileLoader::LoadLevel(const char *filename)
{
int fd;
RwTexDictionary *savedTxd;
- int savedLevel;
+ eLevelName savedLevel;
bool objectsLoaded;
char *line;
char txdname[64];
@@ -79,7 +79,7 @@ CFileLoader::LoadLevel(const char *filename)
}else if(strncmp(line, "COLFILE", 7) == 0){
int level;
sscanf(line+8, "%d", &level);
- CGame::currLevel = level;
+ CGame::currLevel = (eLevelName)level;
LoadingScreenLoadingFile(line+10);
LoadCollisionFile(line+10);
CGame::currLevel = savedLevel;
diff --git a/src/Game.cpp b/src/Game.cpp
index f158e9db..cbd55c48 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -2,7 +2,7 @@
#include "patcher.h"
#include "Game.h"
-int &CGame::currLevel = *(int*)0x941514;
+eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4;
bool &CGame::frenchGame = *(bool*)0x95CDCB;
@@ -11,6 +11,7 @@ bool &CGame::noProstitutes = *(bool*)0x95CDCF;
bool &CGame::playingIntro = *(bool*)0x95CDC2;
char *CGame::aDatFile = (char*)0x773A48;
+WRAPPER void CGame::Initialise(const char *datFile) { EAXJMP(0x48BED0); }
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
WRAPPER bool CGame::InitialiseOnceBeforeRW(void) { EAXJMP(0x48BB80); }
WRAPPER bool CGame::InitialiseRenderWare(void) { EAXJMP(0x48BBA0); }
diff --git a/src/Game.h b/src/Game.h
index 6b071125..3bc3e633 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -11,7 +11,7 @@ enum eLevelName
class CGame
{
public:
- static int &currLevel;
+ static eLevelName &currLevel;
static bool &bDemoMode;
static bool &nastyGame;
static bool &frenchGame;
@@ -20,13 +20,18 @@ public:
static bool &playingIntro;
static char *aDatFile; //[32];
- static void Process(void);
+ static void Initialise(const char *datFile);
static bool InitialiseOnceBeforeRW(void);
static bool InitialiseRenderWare(void);
+ static bool InitialiseOnceAfterRW(void);
+ static void InitialiseWhenRestarting(void);
+ static void ShutDown(void);
static void ShutdownRenderWare(void);
static void FinalShutdown(void);
- static void ShutDown(void);
static void ShutDownForRestart(void);
- static void InitialiseWhenRestarting(void);
- static bool InitialiseOnceAfterRW(void);
+ static void Process(void);
+
+ // NB: these do something on PS2
+ static void TidyUpMemory(bool, bool) {}
+ static void DrasticTidyUpMemory(void) {}
};
diff --git a/src/control/Population.cpp b/src/control/Population.cpp
index fd1a89f5..7b1acaaf 100644
--- a/src/control/Population.cpp
+++ b/src/control/Population.cpp
@@ -1,8 +1,10 @@
#include "common.h"
#include "patcher.h"
+#include "Game.h"
#include "Population.h"
PedGroup *CPopulation::ms_pPedGroups = (PedGroup*)0x6E9248;
bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6;
WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); }
+WRAPPER void CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool) { EAXJMP(0x4F6200); }
diff --git a/src/control/Population.h b/src/control/Population.h
index 76442442..e93e14fc 100644
--- a/src/control/Population.h
+++ b/src/control/Population.h
@@ -14,4 +14,5 @@ public:
static bool &ms_bGivePedsWeapons;
static void UpdatePedCount(uint32, bool);
+ static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
};
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 8003b407..2e0f07ee 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -165,6 +165,8 @@ void CReplay::Init(void)
bDoLoadSceneWhenDone = false;
}
+WRAPPER void CReplay::EmptyReplayBuffer(void) { EAXJMP(0x595BD0); }
+
void CReplay::DisableReplays(void)
{
bReplayEnabled = false;
diff --git a/src/control/Replay.h b/src/control/Replay.h
index b622788f..c4f3b1a2 100644
--- a/src/control/Replay.h
+++ b/src/control/Replay.h
@@ -244,6 +244,7 @@ private:
public:
static void Init(void);
+ static void EmptyReplayBuffer(void);
static void DisableReplays(void);
static void EnableReplays(void);
static void Update(void);
diff --git a/src/entities/Train.h b/src/entities/Train.h
index e591239b..f3fb9a40 100644
--- a/src/entities/Train.h
+++ b/src/entities/Train.h
@@ -2,10 +2,19 @@
#include "Vehicle.h"
+enum
+{
+ TRAIN_DOOR_STATE2 = 2
+};
+
class CTrain : public CVehicle
{
public:
// 0x288
- uint8 stuff[92];
+ uint8 stuff1[20];
+ uint8 m_trackId;
+ uint8 stuff2[7];
+ int16 m_doorState;
+ uint8 stuff3[62];
};
static_assert(sizeof(CTrain) == 0x2E4, "CTrain: error");
diff --git a/src/main.cpp b/src/main.cpp
index d1ffbe6b..7b7c28e4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -90,6 +90,18 @@ void PrintGameVersion();
RwRGBA gColourTop;
+#ifndef DEBUG
+// This is the weirdest shit. In Debug this causes my game to crash in CPed::IsPedInControl shortly after level change
+void
+InitialiseGame(void)
+{
+ LoadingScreen(nil, nil, "loadsc0");
+ CGame::Initialise("DATA\\GTA3.DAT");
+}
+#else
+WRAPPER void InitialiseGame(void) { EAXJMP(0x48E7E0); }
+#endif
+
void
Idle(void *arg)
{
@@ -591,6 +603,25 @@ ResetLoadingScreenBar(void)
NumberOfChunksLoaded = 0.0f;
}
+WRAPPER void
+LoadingIslandScreen(const char *levelName)
+{
+ EAXJMP(0x48DA50);
+}
+
+char*
+GetLevelSplashScreen(int level)
+{
+ static char *splashScreens[4] = {
+ nil,
+ "splash1",
+ "splash2",
+ "splash3",
+ };
+
+ return splashScreens[level];
+}
+
char*
GetRandomSplashScreen(void)
{
diff --git a/src/main.h b/src/main.h
index 45948b34..c7914549 100644
--- a/src/main.h
+++ b/src/main.h
@@ -13,6 +13,9 @@ extern wchar *gUString;
class CSprite2d;
+void InitialiseGame(void);
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
+void LoadingIslandScreen(const char *levelName);
CSprite2d *LoadSplash(const char *name);
+char *GetLevelSplashScreen(int level);
char *GetRandomSplashScreen(void);
diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp
index acc40824..454a73f1 100644
--- a/src/modelinfo/ModelInfo.cpp
+++ b/src/modelinfo/ModelInfo.cpp
@@ -175,6 +175,23 @@ CModelInfo::IsBoatModel(int32 id)
((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_BOAT;
}
+void
+CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level)
+{
+ int i;
+ CBaseModelInfo *mi;
+ CColModel *colmodel;
+
+ for(i = 0; i < MODELINFOSIZE; i++){
+ mi = GetModelInfo(i);
+ if(mi){
+ colmodel = mi->GetColModel();
+ if(colmodel && colmodel->level != LEVEL_NONE && colmodel->level != level)
+ colmodel->RemoveCollisionVolumes();
+ }
+ }
+}
+
STARTPATCHES
InjectHook(0x50B310, CModelInfo::Initialise, PATCH_JUMP);
InjectHook(0x50B5B0, CModelInfo::ShutDown, PATCH_JUMP);
@@ -184,4 +201,5 @@ STARTPATCHES
InjectHook(0x50BAD0, CModelInfo::AddPedModel, PATCH_JUMP);
InjectHook(0x50BA60, CModelInfo::AddVehicleModel, PATCH_JUMP);
InjectHook(0x50B860, (CBaseModelInfo *(*)(const char*, int*))CModelInfo::GetModelInfo, PATCH_JUMP);
+ InjectHook(0x50BBC0, CModelInfo::RemoveColModelsFromOtherLevels, PATCH_JUMP);
ENDPATCHES
diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h
index 30be96ca..d20367d1 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -36,4 +36,5 @@ public:
}
static bool IsBoatModel(int32 id);
+ static void RemoveColModelsFromOtherLevels(eLevelName level);
};
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 814cac84..2943475b 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -114,18 +114,11 @@ DWORD _dwMemAvailVideo;
DWORD &_dwOperatingSystemVersion = *(DWORD*)0x70F290;
RwUInt32 &gGameState = *(RwUInt32*)0x8F5838;
-WRAPPER bool InitialiseGame(void) { EAXJMP(0x48E7E0); }
-
-WRAPPER const char *GetLevelSplashScreen(int32 number) { EAXJMP(0x48D750); }
-//
-
-void LoadingScreen(char const *msg1, char const *msg2, char const *screen);
-CSprite2d *LoadSplash(const char *name);
enum eJoypadState
{
- JOYPAD_UNUSED,
- JOYPAD_ATTACHED,
+ JOYPAD_UNUSED,
+ JOYPAD_ATTACHED,
};
struct tJoy