From c2b9ddc5b8935dcd8de593c918f50886e0400319 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 5 May 2020 18:04:43 +0300 Subject: Revert "Remove Miami stuff" This reverts commit 9960c411933f9a804eb5f6840d75ad00fd255252. --- src/core/Camera.cpp | 2 + src/core/Collision.cpp | 30 ++++++ src/core/Collision.h | 4 + src/core/FileLoader.cpp | 154 +++++++++++++++++++++++++++ src/core/FileLoader.h | 6 ++ src/core/Frontend.h | 4 + src/core/Game.cpp | 11 ++ src/core/Game.h | 3 + src/core/PlayerInfo.h | 2 + src/core/Streaming.cpp | 275 ++++++++++++++++++++++++++++++++++++++++++++++++ src/core/Streaming.h | 32 ++++++ src/core/ZoneCull.h | 5 + src/core/config.h | 17 +++ src/core/templates.h | 9 +- 14 files changed, 553 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 3f4684e7..830a2bb2 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -934,11 +934,13 @@ CCamera::CamControl(void) if(CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer()) stairs = true; // Some hack for Mr Whoopee in a bomb shop +#ifndef MIAMI // uhh, check this if(Cams[ActiveCam].Using3rdPersonMouseCam() && CCollision::ms_collisionInMemory == LEVEL_COMMERCIAL){ if(pTargetEntity->GetPosition().x < 83.0f && pTargetEntity->GetPosition().x > 18.0f && pTargetEntity->GetPosition().y < -305.0f && pTargetEntity->GetPosition().y > -390.0f) disableGarageCam = true; } +#endif if(!disableGarageCam && (CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs)){ if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer){ if(pToGarageWeAreIn || stairs){ diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 0cdacfdb..f20fee6d 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -20,6 +20,10 @@ #include "SurfaceTable.h" #include "Lines.h" #include "Collision.h" +#ifdef MIAMI +#include "Camera.h" +#include "ColStore.h" +#endif enum Direction { @@ -34,22 +38,32 @@ enum Direction eLevelName CCollision::ms_collisionInMemory; CLinkList CCollision::ms_colModelCache; +//--MIAMI: done void CCollision::Init(void) { ms_colModelCache.Init(NUMCOLCACHELINKS); ms_collisionInMemory = LEVEL_NONE; +#ifdef MIAMI + CColStore::Initialise(); +#endif } +//--MIAMI: done void CCollision::Shutdown(void) { ms_colModelCache.Shutdown(); +#ifdef MIAMI + CColStore::Shutdown(); +#endif } +//--MIAMI: done void CCollision::Update(void) { +#ifndef MIAMI CVector playerCoors; playerCoors = FindPlayerCoors(); eLevelName level = CTheZones::m_CurrLevel; @@ -83,8 +97,10 @@ CCollision::Update(void) if(ms_collisionInMemory != CGame::currLevel) LoadCollisionWhenINeedIt(forceLevelChange); CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); +#endif } +//--MIAMI: unused eLevelName GetCollisionInSectorList(CPtrList &list) { @@ -101,6 +117,7 @@ GetCollisionInSectorList(CPtrList &list) return LEVEL_NONE; } +//--MIAMI: unused // Get a level this sector is in based on collision models eLevelName GetCollisionInSector(CSector §) @@ -121,9 +138,11 @@ GetCollisionInSector(CSector §) return (eLevelName)level; } +//--MIAMI: done void CCollision::LoadCollisionWhenINeedIt(bool forceChange) { +#ifndef MIAMI eLevelName level, l; bool multipleLevels; CVector playerCoors; @@ -210,11 +229,14 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange) CTimer::Update(); DMAudio.SetEffectsFadeVol(127); } +#endif } +//--MIAMI: done void CCollision::SortOutCollisionAfterLoad(void) { +#ifndef MIAMI if(ms_collisionInMemory == CGame::currLevel) return; @@ -226,6 +248,10 @@ CCollision::SortOutCollisionAfterLoad(void) } ms_collisionInMemory = CGame::currLevel; CGame::TidyUpMemory(true, false); +#else + CColStore::LoadCollision(TheCamera.GetPosition()); + CStreaming::LoadAllRequestedModels(false); +#endif } void @@ -1974,7 +2000,11 @@ CColModel::CColModel(void) vertices = nil; triangles = nil; trianglePlanes = nil; +#ifndef MIAMI level = CGame::currLevel; +#else + level = 0; // generic col slot +#endif ownsCollisionVolumes = true; } diff --git a/src/core/Collision.h b/src/core/Collision.h index 895f012a..fc3c1647 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -93,7 +93,11 @@ struct CColModel int16 numLines; int16 numBoxes; int16 numTriangles; +#ifndef MIAMI int32 level; +#else + uint8 level; // colstore slot but probably same name +#endif bool ownsCollisionVolumes; CColSphere *spheres; CColLine *lines; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index a2654369..ab09d72f 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -24,6 +24,10 @@ #include "ZoneCull.h" #include "CdStream.h" #include "FileLoader.h" +#ifdef MIAMI +#include "Streaming.h" +#include "ColStore.h" +#endif char CFileLoader::ms_line[256]; @@ -53,7 +57,9 @@ CFileLoader::LoadLevel(const char *filename) savedTxd = RwTexDictionaryGetCurrent(); objectsLoaded = false; +#ifndef MIAMI savedLevel = CGame::currLevel; +#endif if(savedTxd == nil){ savedTxd = RwTexDictionaryCreate(); RwTexDictionarySetCurrent(savedTxd); @@ -77,12 +83,17 @@ CFileLoader::LoadLevel(const char *filename) AddTexDictionaries(savedTxd, txd); RwTexDictionaryDestroy(txd); }else if(strncmp(line, "COLFILE", 7) == 0){ +#ifndef MIAMI int level; sscanf(line+8, "%d", &level); CGame::currLevel = (eLevelName)level; LoadingScreenLoadingFile(line+10); LoadCollisionFile(line+10); CGame::currLevel = savedLevel; +#else + LoadingScreenLoadingFile(line+10); + LoadCollisionFile(line+10, 0); +#endif }else if(strncmp(line, "MODELFILE", 9) == 0){ LoadingScreenLoadingFile(line + 10); LoadModelFile(line + 10); @@ -94,8 +105,16 @@ CFileLoader::LoadLevel(const char *filename) LoadObjectTypes(line + 4); }else if(strncmp(line, "IPL", 3) == 0){ if(!objectsLoaded){ +#ifndef MIAMI CModelInfo::ConstructMloClumps(); CObjectData::Initialise("DATA\\OBJECT.DAT"); +#else + LoadingScreenLoadingFile("Collision"); + CObjectData::Initialise("DATA\\OBJECT.DAT"); + CStreaming::Init(); + CColStore::LoadAllCollision(); + // TODO: anim indices +#endif objectsLoaded = true; } LoadingScreenLoadingFile(line + 4); @@ -112,8 +131,18 @@ CFileLoader::LoadLevel(const char *filename) CFileMgr::CloseFile(fd); RwTexDictionarySetCurrent(savedTxd); + +#ifdef MIAMI + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(CColStore::GetSlot(i)) + CColStore::GetBoundingBox(i).Grow(120.0f); + CWorld::RepositionCertainDynamicObjects(); + CColStore::RemoveAllCollision(); +#endif } +#ifndef MIAMI void CFileLoader::LoadCollisionFromDatFile(int currlevel) { @@ -137,6 +166,7 @@ CFileLoader::LoadCollisionFromDatFile(int currlevel) CFileMgr::CloseFile(fd); } +#endif char* CFileLoader::LoadLine(int fd) @@ -178,8 +208,14 @@ struct ColHeader uint32 size; }; +//--MIAMI: done +#ifndef MIAMI void CFileLoader::LoadCollisionFile(const char *filename) +#else +void +CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) +#endif { int fd; char modelname[24]; @@ -196,10 +232,17 @@ CFileLoader::LoadCollisionFile(const char *filename) mi = CModelInfo::GetModelInfo(modelname, nil); if(mi){ +#ifndef MIAMI if(mi->GetColModel()){ +#else + if(mi->GetColModel() && mi->DoesOwnColModel()){ +#endif LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname); }else{ CColModel *model = new CColModel; +#ifdef MIAMI + model->level = colSlot; +#endif LoadCollisionModel(work_buff+24, *model, modelname); mi->SetColModel(model, true); } @@ -211,6 +254,82 @@ CFileLoader::LoadCollisionFile(const char *filename) CFileMgr::CloseFile(fd); } +#ifdef MIAMI +bool +CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot) +{ + uint32 modelsize; + char modelname[24]; + CBaseModelInfo *mi; + ColHeader *header; + int modelIndex; + + while(size > 8){ + header = (ColHeader*)buffer; + modelsize = header->size; + if(strncmp(header->ident, "COLL", 4) != 0) + return size-8 < CDSTREAM_SECTOR_SIZE; + memcpy(modelname, buffer+8, 24); + memcpy(work_buff, buffer+32, modelsize-24); + size -= 32 + (modelsize-24); + buffer += 32 + (modelsize-24); + if(modelsize > 15*1024) + debug("colmodel %s is huge, size %d\n", modelname, modelsize); + + mi = CModelInfo::GetModelInfo(modelname, &modelIndex); + if(mi){ +if(modelIndex == 855) +modelIndex = modelIndex; + CColStore::IncludeModelIndex(colSlot, modelIndex); + CColModel *model = new CColModel; + model->level = colSlot; + LoadCollisionModel(work_buff, *model, modelname); + mi->SetColModel(model, true); + }else{ + debug("colmodel %s can't find a modelinfo\n", modelname); + } + } + return true; +} + +bool +CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot) +{ + uint32 modelsize; + char modelname[24]; + CBaseModelInfo *mi; + ColHeader *header; + + while(size > 8){ + header = (ColHeader*)buffer; + modelsize = header->size; + if(strncmp(header->ident, "COLL", 4) != 0) + return size-8 < CDSTREAM_SECTOR_SIZE; + memcpy(modelname, buffer+8, 24); + memcpy(work_buff, buffer+32, modelsize-24); + size -= 32 + (modelsize-24); + buffer += 32 + (modelsize-24); + if(modelsize > 15*1024) + debug("colmodel %s is huge, size %d\n", modelname, modelsize); + + mi = CModelInfo::GetModelInfo(modelname, CColStore::GetSlot(colSlot)->minIndex, CColStore::GetSlot(colSlot)->maxIndex); + if(mi){ + if(mi->GetColModel()){ + LoadCollisionModel(work_buff, *mi->GetColModel(), modelname); + }else{ + CColModel *model = new CColModel; + model->level = colSlot; + LoadCollisionModel(work_buff, *model, modelname); + mi->SetColModel(model, true); + } + }else{ + debug("colmodel %s can't find a modelinfo\n", modelname); + } + } + return true; +} +#endif + void CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) { @@ -1063,18 +1182,36 @@ CFileLoader::LoadObjectInstance(const char *line) CSimpleModelInfo *mi; RwMatrix *xform; CEntity *entity; +#ifdef MIAMI + float area; + + if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f %f", + &id, name, &area, + &trans.x, &trans.y, &trans.z, + &scale.x, &scale.y, &scale.z, + &axis.x, &axis.y, &axis.z, &angle) != 13){ +#endif if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", &id, name, &trans.x, &trans.y, &trans.z, &scale.x, &scale.y, &scale.z, &axis.x, &axis.y, &axis.z, &angle) != 12) return; +#ifdef MIAMI + area = 0; + } +#endif mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); if(mi == nil) return; assert(mi->IsSimple()); +#ifdef MIAMI + if(!CStreaming::IsObjectInCdImage(id)) + debug("Not in cdimage %s\n", mi->GetName()); +#endif + angle = -RADTODEG(2.0f * acosf(angle)); xform = RwMatrixCreate(); RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE); @@ -1089,6 +1226,9 @@ CFileLoader::LoadObjectInstance(const char *line) entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition()); +#ifdef MIAMI + entity->m_area = area; +#endif if(mi->IsSimple()){ if(mi->m_isBigBuilding) entity->SetupBigBuilding(); @@ -1098,14 +1238,28 @@ CFileLoader::LoadObjectInstance(const char *line) if(mi->GetLargestLodDistance() < 2.0f) entity->bIsVisible = false; CWorld::Add(entity); + +#ifdef MIAMI + CColModel *col = entity->GetColModel(); + if(col->numSpheres || col->numBoxes || col->numTriangles){ + if(col->level != 0) + CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect()); + }else + entity->bUsesCollision = false; + // TODO: set some flag here if col min is below 6 +#endif }else{ entity = new CDummyObject; entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); CWorld::Add(entity); +//--MIAMI: TODO if(IsGlass(entity->GetModelIndex())) entity->bIsVisible = false; entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition()); +#ifdef MIAMI + entity->m_area = area; +#endif } RwMatrixDestroy(xform); diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h index 87b8fe61..aa8dcdb8 100644 --- a/src/core/FileLoader.h +++ b/src/core/FileLoader.h @@ -8,7 +8,13 @@ public: static void LoadCollisionFromDatFile(int currlevel); static char *LoadLine(int fd); static RwTexDictionary *LoadTexDictionary(const char *filename); +#ifndef MIAMI static void LoadCollisionFile(const char *filename); +#else + static void LoadCollisionFile(const char *filename, uint8 colSlot = 0); + static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot); + static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot); +#endif static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name); static void LoadModelFile(const char *filename); static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data); diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 3286f275..c27e5239 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -624,6 +624,10 @@ public: void LoadAllTextures(); void LoadSettings(); void MessageScreen(const char *); +#ifdef MIAMI + //--MIAMI: TODO: implement the second argument + void MessageScreen(const char *str, bool) { MessageScreen(str); } +#endif void PickNewPlayerColour(); void PrintBriefs(); static void PrintErrorMessage(); diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 27731f8a..d0b3f5a3 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -89,6 +89,9 @@ eLevelName CGame::currLevel; +#ifdef MIAMI +int32 CGame::currArea; +#endif bool CGame::bDemoMode = true; bool CGame::nastyGame = true; bool CGame::frenchGame; @@ -319,7 +322,9 @@ bool CGame::Initialise(const char* datFile) CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; LoadingScreen("Loading the Game", "Setup streaming", nil); +#ifndef MIAMI CStreaming::Init(); +#endif CStreaming::LoadInitialVehicles(); CStreaming::LoadInitialPeds(); CStreaming::RequestBigBuildings(LEVEL_NONE); @@ -367,8 +372,10 @@ bool CGame::Initialise(const char* datFile) CWaterCannons::Init(); CBridge::Init(); CGarages::Init(); +#ifndef MIAMI LoadingScreen("Loading the Game", "Position dynamic objects", nil); CWorld::RepositionCertainDynamicObjects(); +#endif LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); #ifdef GTA_ZONECULL CCullZones::ResolveVisibilities(); @@ -383,7 +390,9 @@ bool CGame::Initialise(const char* datFile) CTheScripts::Process(); TheCamera.Process(); LoadingScreen("Loading the Game", "Load scene", nil); +#ifndef MIAMI CModelInfo::RemoveColModelsFromOtherLevels(currLevel); +#endif CCollision::ms_collisionInMemory = currLevel; for (int i = 0; i < MAX_PADS; i++) CPad::GetPad(i)->Clear(true); @@ -523,7 +532,9 @@ void CGame::ReloadIPLs(void) CRoadBlocks::Init(); CCranes::InitCranes(); CGarages::Init(); +#ifndef MIAMI CWorld::RepositionCertainDynamicObjects(); +#endif #ifdef GTA_ZONECULL CCullZones::ResolveVisibilities(); #endif diff --git a/src/core/Game.h b/src/core/Game.h index 48f31abc..8db5adf5 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -12,6 +12,9 @@ class CGame { public: static eLevelName currLevel; +#ifdef MIAMI + static int32 currArea; +#endif static bool bDemoMode; static bool nastyGame; static bool frenchGame; diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index e970e42d..13266331 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -80,4 +80,6 @@ public: ~CPlayerInfo() { }; }; +#ifndef MIAMI static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error"); +#endif diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 978e0bb8..d212dd05 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -32,6 +32,10 @@ #include "Replay.h" #endif #include "main.h" +#ifdef MIAMI +#include "ColStore.h" +#include "DMAudio.h" +#endif bool CStreaming::ms_disableStreaming; bool CStreaming::ms_bLoadingBigModel; @@ -53,7 +57,9 @@ int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED]; int32 CStreaming::ms_lastVehicleDeleted; CDirectory *CStreaming::ms_pExtraObjectsDir; int32 CStreaming::ms_numPriorityRequests; +#ifndef MIAMI bool CStreaming::ms_hasLoadedLODs; +#endif int32 CStreaming::ms_currentPedGrp; int32 CStreaming::ms_currentPedLoading; int32 CStreaming::ms_lastCullZone; @@ -184,7 +190,9 @@ CStreaming::Init2(void) ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE); ms_numPriorityRequests = 0; +#ifndef MIAMI ms_hasLoadedLODs = true; +#endif ms_currentPedGrp = -1; ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone ms_loadedGangs = 0; @@ -231,6 +239,7 @@ CStreaming::Init2(void) CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd); CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom); +#ifndef MIAMI for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); if(building == nil) @@ -241,6 +250,7 @@ CStreaming::Init2(void) if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building; if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building; } +#endif } void @@ -292,21 +302,35 @@ CStreaming::Update(void) if(CTimer::GetIsPaused()) return; +#ifndef MIAMI train = FindPlayerTrain(); if(train && train->GetPosition().z < 0.0f){ RequestSubway(); requestedSubway = true; }else if(!ms_disableStreaming) AddModelsToRequestList(TheCamera.GetPosition()); +#else + LoadBigBuildingsWhenNeeded(); + if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f) + AddModelsToRequestList(TheCamera.GetPosition()); +#endif DeleteFarAwayRwObjects(TheCamera.GetPosition()); if(!ms_disableStreaming && +#ifndef MIAMI !CCutsceneMgr::IsRunning() && !requestedSubway && !CGame::playingIntro && +#else + !CCutsceneMgr::IsCutsceneProcessing() && +#endif ms_numModelsRequested < 5 && !CRenderer::m_loadingPriority +#ifdef MIAMI + && CGame::currArea == 0 + // replay is also MIAMI +#endif #ifdef FIX_BUGS && !CReplay::IsPlayingBack() #endif @@ -317,6 +341,16 @@ CStreaming::Update(void) LoadRequestedModels(); +#ifdef MIAMI + if(CWorld::Players[0].m_pRemoteVehicle){ + CColStore::AddCollisionNeededAtPosn(FindPlayerCoors()); + CColStore::LoadCollision(CWorld::Players[0].m_pRemoteVehicle->GetPosition()); + CColStore::EnsureCollisionIsInMemory(CWorld::Players[0].m_pRemoteVehicle->GetPosition()); + }else{ + CColStore::LoadCollision(FindPlayerCoors()); + CColStore::EnsureCollisionIsInMemory(FindPlayerCoors()); + } +#endif for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ prev = si->m_prev; @@ -375,6 +409,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) imgSelector = n<<24; assert(sizeof(direntry) == 32); while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){ +#ifndef MIAMI dot = strchr(direntry.name, '.'); if(dot) *dot = '\0'; if(direntry.size > (uint32)ms_streamingBufferSize) @@ -417,6 +452,64 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) } }else lastID = -1; +#else + bool bAddToStreaming = false; + + if(direntry.size > (uint32)ms_streamingBufferSize) + ms_streamingBufferSize = direntry.size; + direntry.name[23] = '\0'; + dot = strchr(direntry.name, '.'); + if(dot == nil || dot-direntry.name > 20){ + debug("%s is too long\n", direntry.name); + lastID = -1; + continue; + } + + *dot = '\0'; + + if(!CGeneral::faststricmp(dot+1, "DFF")){ + if(CModelInfo::GetModelInfo(direntry.name, &modelId)){ + bAddToStreaming = true; + }else{ +#ifdef FIX_BUGS + // remember which cdimage this came from + ms_pExtraObjectsDir->AddItem(direntry, n); +#else + ms_pExtraObjectsDir->AddItem(direntry); +#endif + lastID = -1; + } + }else if(!CGeneral::faststricmp(dot+1, "TXD")){ + modelId = CTxdStore::FindTxdSlot(direntry.name); + if(modelId == -1) + modelId = CTxdStore::AddTxdSlot(direntry.name); + modelId += STREAM_OFFSET_TXD; + bAddToStreaming = true; + }else if(!CGeneral::faststricmp(dot+1, "COL")){ + modelId = CColStore::FindColSlot(direntry.name); + if(modelId == -1) + modelId = CColStore::AddColSlot(direntry.name); + modelId += STREAM_OFFSET_COL; + bAddToStreaming = true; + // TODO: IFP + }else{ + *dot = '.'; + lastID = -1; + } + + if(bAddToStreaming){ + if(ms_aInfoForModel[modelId].GetCdSize()){ + debug("%s.%s appears more than once in %s\n", direntry.name, dot+1, dirname); + lastID = -1; + }else{ + direntry.offset |= imgSelector; + ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size); + if(lastID != -1) + ms_aInfoForModel[lastID].m_nextID = modelId; + lastID = modelId; + } + } +#endif } CFileMgr::CloseFile(fd); @@ -440,6 +533,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem); if(streamId < STREAM_OFFSET_TXD){ +//--MIAMI: also check animation // Model mi = CModelInfo::GetModelInfo(streamId); @@ -481,7 +575,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } +#ifndef MIAMI }else{ +#else + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ +#endif // Txd assert(streamId < NUMSTREAMINFO); if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && @@ -506,10 +604,22 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } +#ifdef MIAMI + }else if(streamId >= STREAM_OFFSET_COL && streamId < NUMSTREAMINFO){ + if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){ + debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL)); + RemoveModel(streamId); + ReRequestModel(streamId); + RwStreamClose(stream, &mem); + return false; + } + // TODO: IFPs +#endif } RwStreamClose(stream, &mem); +#ifndef MIAMI // We shouldn't even end up here unless load was successful if(!success){ ReRequestModel(streamId); @@ -519,6 +629,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); return false; } +#endif if(streamId < STREAM_OFFSET_TXD){ // Model @@ -537,7 +648,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } +#ifndef MIAMI }else{ +#else + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // TODO: animations +#endif // Txd if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); @@ -552,10 +667,23 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); timeDiff = endTime - startTime; if(timeDiff > 5){ +#ifndef MIAMI if(streamId < STREAM_OFFSET_TXD) debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); else debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); +#else + // TODO: is this inlined? + static char objname[32]; + if(streamId < STREAM_OFFSET_TXD) + sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName()); + else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL) + sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD)); + else if(streamId >= STREAM_OFFSET_COL && streamId < NUMSTREAMINFO) + sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL)); + // TODO: IFP + debug("%s took %d ms\n", objname, timeDiff); +#endif } return true; @@ -713,7 +841,11 @@ CStreaming::RequestSubway(void) } } +#ifndef MIAMI #define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY +#else +#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE +#endif void CStreaming::RequestBigBuildings(eLevelName level) @@ -725,12 +857,54 @@ CStreaming::RequestBigBuildings(eLevelName level) for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding && b->m_level == level) +#ifdef MIAMI + if(!b->bStreamBIGBuilding) +#endif RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } RequestIslands(level); +#ifndef MIAMI ms_hasLoadedLODs = false; +#endif } +#ifdef MIAMI +void +CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize()-1; + for(i = n; i >= 0; i--){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level) + if(b->bStreamBIGBuilding){ + if(CRenderer::ShouldModelBeStreamed(b)) + RequestModel(b->GetModelIndex(), 0); + }else + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); + } + RequestIslands(level); +} + +void +CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize()-1; + for(i = n; i >= 0; i--){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level && + b->bStreamBIGBuilding && b->m_rwObject == nil) + if(CRenderer::ShouldModelBeStreamed(b)) + b->CreateRwObject(); + } +} +#endif + void CStreaming::RequestIslands(eLevelName level) { @@ -828,10 +1002,20 @@ CStreaming::RemoveModel(int32 id) return; if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ +#ifndef MIAMI if(id < STREAM_OFFSET_TXD) CModelInfo::GetModelInfo(id)->DeleteRwObject(); else CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); +#else + if(id < STREAM_OFFSET_TXD) + CModelInfo::GetModelInfo(id)->DeleteRwObject(); + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) + CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < NUMSTREAMINFO) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + // TODO: IFP +#endif ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE; } @@ -850,15 +1034,26 @@ CStreaming::RemoveModel(int32 id) } if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){ +#ifndef MIAMI if(id < STREAM_OFFSET_TXD) RpClumpGtaCancelStream(); else CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); +#else + if(id < STREAM_OFFSET_TXD) + RpClumpGtaCancelStream(); + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) + CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < NUMSTREAMINFO) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + // TODO: IFP +#endif } ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; } +//--MIAMI: change islands void CStreaming::RemoveUnusedBuildings(eLevelName level) { @@ -870,6 +1065,7 @@ CStreaming::RemoveUnusedBuildings(eLevelName level) RemoveBuildings(LEVEL_SUBURBAN); } +//--MIAMI: done void CStreaming::RemoveBuildings(eLevelName level) { @@ -930,6 +1126,7 @@ CStreaming::RemoveBuildings(eLevelName level) } } +//--MIAMI: change islands void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { @@ -958,6 +1155,21 @@ DeleteIsland(CEntity *island) void CStreaming::RemoveIslandsNotUsed(eLevelName level) { +#ifdef MIAMI + int i; + if(pIslandLODindustEntity == nil) + for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ + CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); + if(building == nil) + continue; + if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building; + if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building; + if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building; + if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building; + if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building; + } +#endif + switch(level){ case LEVEL_INDUSTRIAL: DeleteIsland(pIslandLODindustEntity); @@ -984,6 +1196,7 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) } } +//--MIAMI: done void CStreaming::RemoveBigBuildings(eLevelName level) { @@ -1187,6 +1400,7 @@ CStreaming::IsObjectInCdImage(int32 id) return ms_aInfoForModel[id].GetCdPosnAndSize(posn, size); } +#ifndef MIAMI void CStreaming::HaveAllBigBuildingsLoaded(eLevelName level) { @@ -1221,6 +1435,7 @@ CStreaming::HaveAllBigBuildingsLoaded(eLevelName level) RemoveUnusedBigBuildings(level); ms_hasLoadedLODs = true; } +#endif void CStreaming::SetModelIsDeletable(int32 id) @@ -1454,6 +1669,44 @@ CStreaming::RemoveCurrentZonesModels(void) ms_loadedGangCars = 0; } +#ifdef MIAMI +void +CStreaming::LoadBigBuildingsWhenNeeded(void) +{ + // Very much like CCollision::Update and CCollision::LoadCollisionWhenINeedIt + if(CCutsceneMgr::IsCutsceneProcessing()) + return; + + if(CTheZones::m_CurrLevel == LEVEL_NONE || + CTheZones::m_CurrLevel == CGame::currLevel) + return; + + CTimer::Suspend(); + CGame::currLevel = CTheZones::m_CurrLevel; + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + CCollision::LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + + // CPopulation::DealWithZoneChange is unused in VC + RemoveUnusedBigBuildings(CGame::currLevel); + RemoveUnusedBuildings(CGame::currLevel); + RemoveUnusedModelsInLoadedList(); + CGame::TidyUpMemory(true, true); + + CReplay::EmptyReplayBuffer(); + if(CGame::currLevel != LEVEL_NONE) + LoadSplash(GetLevelSplashScreen(CGame::currLevel)); + + CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); + CStreaming::LoadAllRequestedModels(true); + + CGame::TidyUpMemory(true, true); + CTimer::Resume(); + DMAudio.SetEffectsFadeVol(127); +} +#endif + // Find starting offset of the cdimage we next want to read // Not useful at all on PC... @@ -2438,11 +2691,33 @@ CStreaming::LoadScene(const CVector &pos) CCullZones::ForceCullZoneCoors(pos); #endif DeleteAllRwObjects(); +#ifndef MIAMI AddModelsToRequestList(pos); CRadar::StreamRadarSections(pos); RemoveUnusedBigBuildings(level); RequestBigBuildings(level); LoadAllRequestedModels(false); +#else + if(level == LEVEL_NONE) + level = CGame::currLevel; + CGame::currLevel = level; + RemoveUnusedBigBuildings(level); + RequestBigBuildings(level, pos); + RequestBigBuildings(LEVEL_NONE, pos); + RemoveIslandsNotUsed(level); + LoadAllRequestedModels(false); + InstanceBigBuildings(level, pos); + InstanceBigBuildings(LEVEL_NONE, pos); + AddModelsToRequestList(pos); + CRadar::StreamRadarSections(pos); + + // TODO: stream zone vehicles + LoadAllRequestedModels(false); + // TODO: InstanceLoadedModels + + for(int i = 0; i < NUMSTREAMINFO; i++) + ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20; +#endif debug("End load scene\n"); } diff --git a/src/core/Streaming.h b/src/core/Streaming.h index 84434769..d2920824 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -4,7 +4,12 @@ enum { STREAM_OFFSET_TXD = MODELINFOSIZE, +#ifndef MIAMI NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE +#else + STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE, + NUMSTREAMINFO = STREAM_OFFSET_COL+COLSTORESIZE +#endif }; enum StreamFlags @@ -14,6 +19,9 @@ enum StreamFlags STREAMFLAGS_DEPENDENCY = 0x04, // Is this right? STREAMFLAGS_PRIORITY = 0x08, STREAMFLAGS_NOFADE = 0x10, +#ifdef MIAMI + STREAMFLAGS_20 = 0x20, +#endif STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED, STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY, @@ -94,7 +102,9 @@ public: static int32 ms_lastVehicleDeleted; static CDirectory *ms_pExtraObjectsDir; static int32 ms_numPriorityRequests; +#ifndef MIAMI static bool ms_hasLoadedLODs; +#endif static int32 ms_currentPedGrp; static int32 ms_lastCullZone; static uint16 ms_loadedGangs; @@ -115,14 +125,28 @@ public: static bool FinishLoadingLargeFile(int8 *buf, int32 streamId); static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; } static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); } +#ifdef MIAMI + static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); } +#endif static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; } static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); } +#ifdef MIAMI + static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); } +#endif static void RequestModel(int32 model, int32 flags); static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); } static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); } static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); } +#ifdef MIAMI + static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); } + static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); } +#endif static void RequestSubway(void); static void RequestBigBuildings(eLevelName level); +#ifdef MIAMI + static void RequestBigBuildings(eLevelName level, const CVector &pos); + static void InstanceBigBuildings(eLevelName level, const CVector &pos); +#endif static void RequestIslands(eLevelName level); static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags); static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags); @@ -131,6 +155,9 @@ public: static void DecrementRef(int32 id); static void RemoveModel(int32 id); static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); } +#ifdef MIAMI + static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); } +#endif static void RemoveUnusedBuildings(eLevelName level); static void RemoveBuildings(eLevelName level); static void RemoveUnusedBigBuildings(eLevelName level); @@ -145,7 +172,9 @@ public: static bool IsTxdUsedByRequestedModels(int32 txdId); static bool AddToLoadedVehiclesList(int32 modelId); static bool IsObjectInCdImage(int32 id); +#ifndef MIAMI static void HaveAllBigBuildingsLoaded(eLevelName level); +#endif static void SetModelIsDeletable(int32 id); static void SetModelTxdIsDeletable(int32 id); static void SetMissionDoesntRequireModel(int32 id); @@ -154,6 +183,9 @@ public: static void StreamVehiclesAndPeds(void); static void StreamZoneModels(const CVector &pos); static void RemoveCurrentZonesModels(void); +#ifdef MIAMI + static void LoadBigBuildingsWhenNeeded(void); +#endif static int32 GetCdImageOffset(int32 lastPosn); static int32 GetNextFileOnCd(int32 position, bool priority); diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h index 9bc07b8c..3659bca7 100644 --- a/src/core/ZoneCull.h +++ b/src/core/ZoneCull.h @@ -122,4 +122,9 @@ public: static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set); static void CompressIndicesArray() {};// todo + +#ifdef MIAMI + //--MIAMI: TODO + static bool PoliceAbandonCars(void) { return false; } +#endif }; diff --git a/src/core/config.h b/src/core/config.h index 0bbc883e..c3904fa9 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -7,8 +7,14 @@ enum Config { MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, +#ifndef MIAMI MODELINFOSIZE = 5500, TXDSTORESIZE = 850, +#else + MODELINFOSIZE = 6500, + TXDSTORESIZE = 1385, + COLSTORESIZE = 31, +#endif EXTRADIRSIZE = 128, CUTSCENEDIRSIZE = 512, @@ -41,10 +47,17 @@ enum Config { NUMTEMPOBJECTS = 30, // Path data +#ifndef MIAMI NUM_PATHNODES = 4930, NUM_CARPATHLINKS = 2076, NUM_MAPOBJECTS = 1250, NUM_PATHCONNECTIONS = 10260, +#else + NUM_PATHNODES = 9650, + NUM_CARPATHLINKS = 3500, + NUM_MAPOBJECTS = 1250, + NUM_PATHCONNECTIONS = 20400, +#endif // Link list lengths NUMALPHALIST = 20, @@ -110,7 +123,11 @@ enum Config { NUMMODELSPERPEDGROUP = 8, NUMSHOTINFOS = 100, +#ifndef MIAMI NUMROADBLOCKS = 600, +#else + NUMROADBLOCKS = 300, +#endif NUMVISIBLEENTITIES = 2000, NUMINVISIBLEENTITIES = 150, diff --git a/src/core/templates.h b/src/core/templates.h index 921b109a..74bc4713 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -39,13 +39,20 @@ public: m_entries = (U*)malloc(sizeof(U)*size); m_flags = (Flags*)malloc(sizeof(Flags)*size); m_size = size; +#ifndef MIAMI m_allocPtr = 0; +#else + m_allocPtr = -1; +#endif for(int i = 0; i < size; i++){ m_flags[i].id = 0; m_flags[i].free = 1; } } - +#ifdef MIAMI + CPool(int size, const char *name) + : CPool(size) {} +#endif ~CPool() { Flush(); } -- cgit v1.2.3