Merge remote-tracking branch 'upstream/miami' into miami

This commit is contained in:
Nikolay Korolev 2020-05-08 23:30:04 +03:00
commit 3d394c2f95
3 changed files with 177 additions and 41 deletions

View File

@ -80,6 +80,7 @@ public:
static void Shutdown(void); static void Shutdown(void);
static void UncompressAnimation(CAnimBlendHierarchy *anim); static void UncompressAnimation(CAnimBlendHierarchy *anim);
static void RemoveFromUncompressedCache(CAnimBlendHierarchy *hier); static void RemoveFromUncompressedCache(CAnimBlendHierarchy *hier);
static CAnimBlock *GetAnimationBlock(int32 block) { return &ms_aAnimBlocks[block]; }
static CAnimBlock *GetAnimationBlock(const char *name); static CAnimBlock *GetAnimationBlock(const char *name);
static int32 GetAnimationBlockIndex(const char *name); static int32 GetAnimationBlockIndex(const char *name);
static int32 RegisterAnimBlock(const char *name); static int32 RegisterAnimBlock(const char *name);

View File

@ -328,7 +328,7 @@ CStreaming::LoadCdDirectory(void)
ms_imageSize /= CDSTREAM_SECTOR_SIZE; ms_imageSize /= CDSTREAM_SECTOR_SIZE;
} }
//--MIAMI: needs IFP //--MIAMI: done
void void
CStreaming::LoadCdDirectory(const char *dirname, int n) CStreaming::LoadCdDirectory(const char *dirname, int n)
{ {
@ -382,7 +382,10 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
modelId = CColStore::AddColSlot(direntry.name); modelId = CColStore::AddColSlot(direntry.name);
modelId += STREAM_OFFSET_COL; modelId += STREAM_OFFSET_COL;
bAddToStreaming = true; bAddToStreaming = true;
// TODO(MIAMI): IFP }else if(strncasecmp(dot+1, "IFP", 3) == 0){
modelId = CAnimManager::RegisterAnimBlock(direntry.name);
modelId += STREAM_OFFSET_ANIM;
bAddToStreaming = true;
}else{ }else{
*dot = '.'; *dot = '.';
lastID = -1; lastID = -1;
@ -415,12 +418,15 @@ GetObjectName(int streamId)
sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD)); sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD));
else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM) else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM)
sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL)); sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL));
// TODO(MIAMI): IFP else{
assert(streamId < NUMSTREAMINFO);
sprintf(objname, "%s.ifp", CAnimManager::GetAnimationBlock(streamId-STREAM_OFFSET_ANIM)->name);
}
return objname; return objname;
} }
//--MIAMI: needs IFP //--MIAMI: done
bool bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
{ {
@ -439,22 +445,23 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem); stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
if(streamId < STREAM_OFFSET_TXD){ if(streamId < STREAM_OFFSET_TXD){
//--MIAMI: also check animation
// Model // Model
mi = CModelInfo::GetModelInfo(streamId); mi = CModelInfo::GetModelInfo(streamId);
// Txd has to be loaded // Txd and anim have to be loaded
if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){ int animId = mi->GetAnimFileIndex();
debug("failed to load %s because TXD %s is not in memory\n", mi->GetName(), CTxdStore::GetTxdName(mi->GetTxdSlot())); if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil ||
animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){
RemoveModel(streamId); RemoveModel(streamId);
RemoveTxd(mi->GetTxdSlot());
ReRequestModel(streamId); ReRequestModel(streamId);
RwStreamClose(stream, &mem); RwStreamClose(stream, &mem);
return false; return false;
} }
// Set Txd to use // Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot()); CTxdStore::AddRef(mi->GetTxdSlot());
if(animId != -1)
CAnimManager::AddAnimBlockRef(animId);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){ if(mi->IsSimple()){
@ -471,9 +478,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
} }
UpdateMemoryUsed(); UpdateMemoryUsed();
// Txd no longer needed unless we only read part of the file // Txd and anims no longer needed unless we only read part of the file
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED) if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
if(animId != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
}
if(!success){ if(!success){
debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName()); debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName());
@ -516,7 +526,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
} }
}else if(streamId >= STREAM_OFFSET_ANIM){ }else if(streamId >= STREAM_OFFSET_ANIM){
assert(streamId < NUMSTREAMINFO); assert(streamId < NUMSTREAMINFO);
// TODO(MIAMI): IFP if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
!AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){
RemoveModel(streamId);
RwStreamClose(stream, &mem);
return false;
}
CAnimManager::LoadAnimFile(stream, true, nil);
CAnimManager::CreateAnimAssocGroups();
} }
RwStreamClose(stream, &mem); RwStreamClose(stream, &mem);
@ -538,11 +555,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
if(CanRemoveModel(streamId)) if(CanRemoveModel(streamId))
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
} }
}else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL ||
// Txd streamId >= STREAM_OFFSET_ANIM){
assert(streamId < NUMSTREAMINFO);
// Txd and anims
if(CanRemoveModel(streamId)) if(CanRemoveModel(streamId))
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
// TODO(MIAMI): animations
} }
// Mark objects as loaded // Mark objects as loaded
@ -559,7 +577,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return true; return true;
} }
//--MIAMI: TODO: anim //--MIAMI: done
bool bool
CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
{ {
@ -590,12 +608,15 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
success = AddToLoadedVehiclesList(streamId); success = AddToLoadedVehiclesList(streamId);
mi->RemoveRef(); mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
// TODO(MIAMI): animation if(mi->GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
}else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd // Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD); CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream); success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD); CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
}else{
assert(0 && "invalid streamId");
} }
RwStreamClose(stream, &mem); RwStreamClose(stream, &mem);
@ -619,7 +640,7 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
return true; return true;
} }
//--MIAMI: TODO: anim //--MIAMI: done
void void
CStreaming::RequestModel(int32 id, int32 flags) CStreaming::RequestModel(int32 id, int32 flags)
{ {
@ -655,9 +676,13 @@ CStreaming::RequestModel(int32 id, int32 flags)
ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again? ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again?
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){ if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){
if(id < STREAM_OFFSET_TXD) if(id < STREAM_OFFSET_TXD){
RequestTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot(), flags); mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
// TODO(MIAMI): animation RequestTxd(mi->GetTxdSlot(), flags);
int anim = mi->GetAnimFileIndex();
if(anim != -1)
RequestAnim(anim, STREAMFLAGS_DEPENDENCY);
}
ms_aInfoForModel[id].AddToList(&ms_startRequestedList); ms_aInfoForModel[id].AddToList(&ms_startRequestedList);
ms_numModelsRequested++; ms_numModelsRequested++;
if(flags & STREAMFLAGS_PRIORITY) if(flags & STREAMFLAGS_PRIORITY)
@ -725,7 +750,46 @@ CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
} }
} }
// TODO(MIAMI): InstanceLoadedModels //--MIAMI: done
void
CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list)
{
CPtrNode *node;
CEntity *e;
for(node = list.first; node; node = node->next) {
e = (CEntity *)node->item;
if(IsAreaVisible(e->m_area) && e->m_rwObject == nil)
e->CreateRwObject();
}
}
//--MIAMI: done
void
CStreaming::InstanceLoadedModels(const CVector &pos)
{
int minX = CWorld::GetSectorIndexX(pos.x - 80.0f);
if(minX <= 0) minX = 0;
int minY = CWorld::GetSectorIndexY(pos.y - 80.0f);
if(minY <= 0) minY = 0;
int maxX = CWorld::GetSectorIndexX(pos.x + 80.0f);
if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
int maxY = CWorld::GetSectorIndexY(pos.y + 80.0f);
if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
int x, y;
for(y = minY; y <= maxY; y++){
for(x = minX; x <= maxX; x++){
CSector *sector = CWorld::GetSector(x, y);
InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS]);
InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_OBJECTS]);
InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_DUMMIES]);
}
}
}
//--MIAMI: done //--MIAMI: done
void void
@ -817,7 +881,7 @@ CStreaming::DecrementRef(int32 id)
} }
} }
//--MIAMI: TODO: animation //--MIAMI: done
void void
CStreaming::RemoveModel(int32 id) CStreaming::RemoveModel(int32 id)
{ {
@ -833,7 +897,10 @@ CStreaming::RemoveModel(int32 id)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM) else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM)
CColStore::RemoveCol(id - STREAM_OFFSET_COL); CColStore::RemoveCol(id - STREAM_OFFSET_COL);
// TODO(MIAMI): IFP else if(id >= STREAM_OFFSET_ANIM){
assert(id < NUMSTREAMINFO);
CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM);
}
ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE; ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE;
} }
@ -858,7 +925,10 @@ CStreaming::RemoveModel(int32 id)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM) else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM)
CColStore::RemoveCol(id - STREAM_OFFSET_COL); CColStore::RemoveCol(id - STREAM_OFFSET_COL);
// TODO(MIAMI): IFP else if(id >= STREAM_OFFSET_ANIM){
assert(id < NUMSTREAMINFO);
CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM);
}
} }
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
@ -1033,7 +1103,7 @@ found:
return true; return true;
} }
//--MIAMI: TODO: anim //--MIAMI: done
bool bool
CStreaming::RemoveLeastUsedModel(uint32 excludeMask) CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
{ {
@ -1055,7 +1125,13 @@ CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
RemoveModel(streamId); RemoveModel(streamId);
return true; return true;
} }
// TODO(MIAMI): IFP }else if(streamId >= STREAM_OFFSET_ANIM){
assert(streamId < NUMSTREAMINFO);
if(CAnimManager::GetNumRefsToAnimBlock(streamId - STREAM_OFFSET_ANIM) == 0 &&
!AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){
RemoveModel(streamId);
return true;
}
} }
} }
return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle(); return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle();
@ -1086,7 +1162,7 @@ CStreaming::RemoveUnusedModelsInLoadedList(void)
// empty // empty
} }
//--MIAMI: done, but strangely not found in mobile? //--MIAMI: done
bool bool
CStreaming::IsTxdUsedByRequestedModels(int32 txdId) CStreaming::IsTxdUsedByRequestedModels(int32 txdId)
{ {
@ -1115,6 +1191,34 @@ CStreaming::IsTxdUsedByRequestedModels(int32 txdId)
return false; return false;
} }
bool
CStreaming::AreAnimsUsedByRequestedModels(int32 animId)
{
CStreamingInfo *si;
int streamId;
int i;
for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = si->m_next){
streamId = si - ms_aInfoForModel;
if(streamId < STREAM_OFFSET_TXD &&
CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
return true;
}
for(i = 0; i < 4; i++){
streamId = ms_channel[0].streamIds[i];
if(streamId != -1 && streamId < STREAM_OFFSET_TXD &&
CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
return true;
streamId = ms_channel[1].streamIds[i];
if(streamId != -1 && streamId < STREAM_OFFSET_TXD &&
CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
return true;
}
return false;
}
int32 int32
CStreaming::GetAvailableVehicleSlot(void) CStreaming::GetAvailableVehicleSlot(void)
{ {
@ -1504,12 +1608,15 @@ CStreaming::GetCdImageOffset(int32 lastPosn)
} }
inline bool inline bool
TxdAvailable(int32 txdId) ModelNotLoaded(int32 modelId)
{ {
CStreamingInfo *si = &CStreaming::ms_aInfoForModel[txdId + STREAM_OFFSET_TXD]; CStreamingInfo *si = &CStreaming::ms_aInfoForModel[modelId];
return si->m_loadState == STREAMSTATE_LOADED || si->m_loadState == STREAMSTATE_READING; return si->m_loadState != STREAMSTATE_LOADED && si->m_loadState != STREAMSTATE_READING;
} }
inline bool TxdNotLoaded(int32 txdId) { return ModelNotLoaded(txdId + STREAM_OFFSET_TXD); }
inline bool AnimNotLoaded(int32 animId) { return animId != -1 && ModelNotLoaded(animId + STREAM_OFFSET_ANIM); }
// Find stream id of next requested file in cdimage // Find stream id of next requested file in cdimage
int32 int32
CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority) CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
@ -1533,11 +1640,22 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
if(priority && ms_numPriorityRequests != 0 && !si->IsPriority()) if(priority && ms_numPriorityRequests != 0 && !si->IsPriority())
continue; continue;
// request Txd if necessary // request Txds or anims if necessary
if(streamId < STREAM_OFFSET_TXD && if(streamId < STREAM_OFFSET_TXD){
!TxdAvailable(CModelInfo::GetModelInfo(streamId)->GetTxdSlot())){ int txdId = CModelInfo::GetModelInfo(streamId)->GetTxdSlot();
ReRequestTxd(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()); if(TxdNotLoaded(txdId)){
}else if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){ ReRequestTxd(txdId);
continue;
}
int animId = CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex();
if(AnimNotLoaded(animId)){
ReRequestAnim(animId);
continue;
}
}else if(streamId >= STREAM_OFFSET_ANIM && CCutsceneMgr::IsCutsceneProcessing())
continue;
if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){
if(posn < posnFirst){ if(posn < posnFirst){
// find first requested file in image // find first requested file in image
streamIdFirst = streamId; streamIdFirst = streamId;
@ -1578,6 +1696,7 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
* TODO: two-part files * TODO: two-part files
*/ */
//--MIAMI: done
// Make channel read from disc // Make channel read from disc
void void
CStreaming::RequestModelStream(int32 ch) CStreaming::RequestModelStream(int32 ch)
@ -1599,7 +1718,10 @@ CStreaming::RequestModelStream(int32 ch)
if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
if(IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)) if(IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD))
break; break;
// TODO(MIAMI): anims }else if(streamId >= STREAM_OFFSET_ANIM){
assert(streamId < NUMSTREAMINFO);
if(AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM))
break;
}else }else
break; break;
RemoveModel(streamId); RemoveModel(streamId);
@ -1637,8 +1759,8 @@ CStreaming::RequestModelStream(int32 ch)
if(streamId < STREAM_OFFSET_TXD){ if(streamId < STREAM_OFFSET_TXD){
if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED || if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED ||
haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE || haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE ||
!TxdAvailable(CModelInfo::GetModelInfo(streamId)->GetTxdSlot())) TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()) ||
// TODO(MIAMI): anims AnimNotLoaded(CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex()))
break; break;
}else{ }else{
if(haveBigFile && size > 200) if(haveBigFile && size > 200)
@ -2428,6 +2550,7 @@ CStreaming::MakeSpaceFor(int32 size)
} }
} }
//--MIAMI: done
void void
CStreaming::LoadScene(const CVector &pos) CStreaming::LoadScene(const CVector &pos)
{ {
@ -2465,13 +2588,21 @@ CStreaming::LoadScene(const CVector &pos)
} }
} }
LoadAllRequestedModels(false); LoadAllRequestedModels(false);
// TODO(MIAMI): InstanceLoadedModels InstanceLoadedModels(pos);
for(int i = 0; i < NUMSTREAMINFO; i++) for(int i = 0; i < NUMSTREAMINFO; i++)
ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20; ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20;
debug("End load scene\n"); debug("End load scene\n");
} }
//--MIAMI: done
void
CStreaming::LoadSceneCollision(const CVector &pos)
{
CColStore::LoadCollision(pos);
CStreaming::LoadAllRequestedModels(false);
}
void void
CStreaming::MemoryCardSave(uint8 *buf, uint32 *size) CStreaming::MemoryCardSave(uint8 *buf, uint32 *size)
{ {

View File

@ -135,6 +135,8 @@ public:
static void RequestBigBuildings(eLevelName level); static void RequestBigBuildings(eLevelName level);
static void RequestBigBuildings(eLevelName level, const CVector &pos); static void RequestBigBuildings(eLevelName level, const CVector &pos);
static void InstanceBigBuildings(eLevelName level, const CVector &pos); static void InstanceBigBuildings(eLevelName level, const CVector &pos);
static void InstanceLoadedModelsInSectorList(CPtrList &list);
static void InstanceLoadedModels(const CVector &pos);
static void RequestIslands(eLevelName level); static void RequestIslands(eLevelName level);
static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags); static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags);
static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags); static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags);
@ -156,6 +158,7 @@ public:
static void RemoveUnusedModelsInLoadedList(void); static void RemoveUnusedModelsInLoadedList(void);
static int32 GetAvailableVehicleSlot(void); static int32 GetAvailableVehicleSlot(void);
static bool IsTxdUsedByRequestedModels(int32 txdId); static bool IsTxdUsedByRequestedModels(int32 txdId);
static bool AreAnimsUsedByRequestedModels(int32 animId);
static bool AddToLoadedVehiclesList(int32 modelId); static bool AddToLoadedVehiclesList(int32 modelId);
static bool IsObjectInCdImage(int32 id); static bool IsObjectInCdImage(int32 id);
static void SetModelIsDeletable(int32 id); static void SetModelIsDeletable(int32 id);
@ -196,6 +199,7 @@ public:
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem); static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem);
static void LoadScene(const CVector &pos); static void LoadScene(const CVector &pos);
static void LoadSceneCollision(const CVector &pos);
static void MemoryCardSave(uint8 *buffer, uint32 *length); static void MemoryCardSave(uint8 *buffer, uint32 *length);
static void MemoryCardLoad(uint8 *buffer, uint32 length); static void MemoryCardLoad(uint8 *buffer, uint32 length);