summaryrefslogtreecommitdiffstats
path: root/src/core/Streaming.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/Streaming.cpp')
-rw-r--r--src/core/Streaming.cpp212
1 files changed, 185 insertions, 27 deletions
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index 40d4acee..2fd8bf1c 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -32,6 +32,10 @@
#include "ColStore.h"
#include "DMAudio.h"
#include "Script.h"
+#include "MemoryMgr.h"
+#include "MemoryHeap.h"
+#include "Font.h"
+#include "Frontend.h"
//--MIAMI: file done (possibly bugs)
@@ -289,12 +293,22 @@ CStreaming::Shutdown(void)
}
}
+#ifndef MASTER
+uint64 timeProcessingTXD;
+uint64 timeProcessingDFF;
+#endif
+
void
CStreaming::Update(void)
{
CStreamingInfo *si, *prev;
bool requestedSubway = false;
+#ifndef MASTER
+ timeProcessingTXD = 0;
+ timeProcessingDFF = 0;
+#endif
+
UpdateMemoryUsed();
if(ms_channelError != -1){
@@ -332,6 +346,10 @@ CStreaming::Update(void)
CColStore::EnsureCollisionIsInMemory(FindPlayerCoors());
}
+ // TODO: PrintRequestList
+ //if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
+ // PrintRequestList();
+
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0)
@@ -463,6 +481,14 @@ GetObjectName(int streamId)
return objname;
}
+#ifdef USE_CUSTOM_ALLOCATOR
+RpAtomic*
+RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data)
+{
+ // empty because we expect models to be pre-instanced
+ return atomic;
+}
+#endif
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
@@ -497,10 +523,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
if(animId != -1)
CAnimManager::AddAnimBlockRef(animId);
- CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
+#endif
+ PUSH_MEMID(MEMID_STREAM_MODELS);
+ CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){
success = CFileLoader::LoadAtomicFile(stream, streamId);
// TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that
@@ -512,14 +541,21 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else{
success = CFileLoader::LoadClumpFile(stream, streamId);
+#ifdef USE_CUSTOM_ALLOCATOR
+ if(success)
+ RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
+#endif
}
+ POP_MEMID();
UpdateMemoryUsed();
// Txd and anims no longer needed unless we only read part of the file
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
if(animId != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
+#endif
}
if(!success){
@@ -538,12 +574,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
+ PUSH_MEMID(MEMID_STREAM_TEXUTRES);
if(ms_bLoadingBigModel || cdsize > 200){
success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
if(success)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else
success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream);
+ POP_MEMID();
UpdateMemoryUsed();
if(!success){
@@ -554,7 +592,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
}else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){
- if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){
+ PUSH_MEMID(MEMID_STREAM_COLLISION);
+ bool success = CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length);
+ POP_MEMID();
+ if(!success){
debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL));
RemoveModel(streamId);
ReRequestModel(streamId);
@@ -569,8 +610,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+ PUSH_MEMID(MEMID_STREAM_ANIMATION);
CAnimManager::LoadAnimFile(stream, true, nil);
CAnimManager::CreateAnimAssocGroups();
+ POP_MEMID();
}
RwStreamClose(stream, &mem);
@@ -603,7 +646,9 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Mark objects as loaded
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
+#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
+#endif
}
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
@@ -638,26 +683,39 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
if(streamId < STREAM_OFFSET_TXD){
// Model
mi = CModelInfo::GetModelInfo(streamId);
+ PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
success = CFileLoader::FinishLoadClumpFile(stream, streamId);
- if(success)
+ if(success){
+#ifdef USE_CUSTOM_ALLOCATOR
+ RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
+#endif
success = AddToLoadedVehiclesList(streamId);
+ }
+ POP_MEMID();
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
if(mi->GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
+#endif
}else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
+ PUSH_MEMID(MEMID_STREAM_TEXUTRES);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
+ POP_MEMID();
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
}else{
assert(0 && "invalid streamId");
}
RwStreamClose(stream, &mem);
+
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
+#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
+#endif
if(!success){
RemoveModel(streamId);
@@ -740,7 +798,15 @@ CStreaming::RequestBigBuildings(eLevelName level)
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 && b->bIsBIGBuilding
+#ifdef NO_ISLAND_LOADING
+ && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) &&
+ (b != pIslandLODbeachEntity)) ||
+ (b->m_level == level))
+#else
+ && b->m_level == level
+#endif
+ )
if(!b->bStreamBIGBuilding)
RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
@@ -757,8 +823,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding
-#ifndef NO_ISLAND_LOADING
- && b->m_level == level
+#ifdef NO_ISLAND_LOADING
+ && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && (b != pIslandLODbeachEntity)
+ ) || (b->m_level == level))
+#else
+ && b->m_level == level
#endif
)
if(b->bStreamBIGBuilding){
@@ -828,7 +897,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos)
void
CStreaming::RequestIslands(eLevelName level)
{
-#ifndef NO_ISLAND_LOADING
+ ISLAND_LOADING_ISNT(HIGH)
switch(level){
case LEVEL_MAINLAND:
if(islandLODbeach != -1)
@@ -840,7 +909,6 @@ CStreaming::RequestIslands(eLevelName level)
break;
default: break;
}
-#endif
}
static char *IGnames[] = {
@@ -1170,12 +1238,13 @@ CStreaming::RemoveBuildingsNotInArea(int32 area)
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
-#ifndef NO_ISLAND_LOADING
+ ISLAND_LOADING_IS(LOW)
+ {
if(level != LEVEL_BEACH)
RemoveBigBuildings(LEVEL_BEACH);
if(level != LEVEL_MAINLAND)
RemoveBigBuildings(LEVEL_MAINLAND);
-#endif
+ }
RemoveIslandsNotUsed(level);
}
@@ -1195,7 +1264,6 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
-#ifndef NO_ISLAND_LOADING
int i;
if(pIslandLODmainlandEntity == nil)
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
@@ -1207,7 +1275,12 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
if(building->GetModelIndex() == islandLODbeach)
pIslandLODbeachEntity = building;
}
-
+#ifdef NO_ISLAND_LOADING
+ if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
+ DeleteIsland(pIslandLODmainlandEntity);
+ DeleteIsland(pIslandLODbeachEntity);
+ } else
+#endif
switch(level){
case LEVEL_MAINLAND:
DeleteIsland(pIslandLODmainlandEntity);
@@ -1217,7 +1290,6 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
break;
}
-#endif // !NO_ISLAND_LOADING
}
void
@@ -1818,26 +1890,36 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
CTimer::Suspend();
CGame::currLevel = CTheZones::m_CurrLevel;
- DMAudio.SetEffectsFadeVol(0);
- CPad::StopPadsShaking();
- CCollision::LoadCollisionScreen(CGame::currLevel);
- DMAudio.Service();
-
- RemoveUnusedBigBuildings(CGame::currLevel);
- RemoveUnusedBuildings(CGame::currLevel);
- RemoveUnusedModelsInLoadedList();
- CGame::TidyUpMemory(true, true);
-
+ ISLAND_LOADING_IS(LOW)
+ {
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+
+ RemoveUnusedBigBuildings(CGame::currLevel);
+ RemoveUnusedBuildings(CGame::currLevel);
+ RemoveUnusedModelsInLoadedList();
+ CGame::TidyUpMemory(true, true);
+ }
CReplay::EmptyReplayBuffer();
if(CGame::currLevel != LEVEL_GENERIC)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ ISLAND_LOADING_IS(LOW)
+ CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) {
+ RemoveIslandsNotUsed(CGame::currLevel);
+ CStreaming::RequestIslands(CGame::currLevel);
+ }
+
CStreaming::LoadAllRequestedModels(false);
CGame::TidyUpMemory(true, true);
CTimer::Resume();
- DMAudio.SetEffectsFadeVol(127);
+
+ ISLAND_LOADING_IS(LOW)
+ DMAudio.SetEffectsFadeVol(127);
}
@@ -2415,19 +2497,27 @@ CStreaming::FlushRequestList(void)
void
CStreaming::ImGonnaUseStreamingMemory(void)
{
- // empty
+ PUSH_MEMID(MEMID_STREAM);
}
void
CStreaming::IHaveUsedStreamingMemory(void)
{
+ POP_MEMID();
UpdateMemoryUsed();
}
void
CStreaming::UpdateMemoryUsed(void)
{
- // empty
+#ifdef USE_CUSTOM_ALLOCATOR
+ ms_memoryUsed =
+ gMainHeap.GetMemoryUsed(MEMID_STREAM) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION);
+#endif
}
#define STREAM_DIST 80.0f
@@ -3041,3 +3131,71 @@ CStreaming::UpdateForAnimViewer(void)
CStreaming::RetryLoadFile(CStreaming::ms_channelError);
}
}
+
+
+void
+CStreaming::PrintStreamingBufferState()
+{
+ char str[128];
+ wchar wstr[128];
+ uint32 offset, size;
+
+ CTimer::Stop();
+ int i = 0;
+ while (i < NUMSTREAMINFO) {
+ while (true) {
+ int j = 0;
+ DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255);
+ CPad::UpdatePads();
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ DefinedState();
+
+ CRect unusedRect(0, 0, RsGlobal.maximumWidth, RsGlobal.maximumHeight);
+ CRGBA unusedColor(255, 255, 255, 255);
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetBackgroundOff();
+ CFont::SetWrapx(DEFAULT_SCREEN_WIDTH);
+ CFont::SetScale(0.5f, 0.75f);
+ CFont::SetCentreOff();
+ CFont::SetCentreSize(DEFAULT_SCREEN_WIDTH);
+ CFont::SetJustifyOff();
+ CFont::SetColor(CRGBA(200, 200, 200, 200));
+ CFont::SetBackGroundOnlyTextOff();
+ int modelIndex = i;
+ if (modelIndex < NUMSTREAMINFO) {
+ int y = 24;
+ for ( ; j < 34 && modelIndex < NUMSTREAMINFO; modelIndex++) {
+ CStreamingInfo *streamingInfo = &ms_aInfoForModel[modelIndex];
+ CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelIndex);
+ if (streamingInfo->m_loadState != STREAMSTATE_LOADED || !streamingInfo->GetCdPosnAndSize(offset, size))
+ continue;
+
+ if (modelIndex >= STREAM_OFFSET_TXD)
+ sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD),
+ CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags);
+ else
+ sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetName(), modelInfo->GetNumRefs(), 2 * size,
+ streamingInfo->m_flags);
+ AsciiToUnicode(str, wstr);
+ CFont::PrintString(24.0f, y, wstr);
+ y += 12;
+ j++;
+ }
+ }
+
+ if (CPad::GetPad(1)->GetCrossJustDown())
+ i = modelIndex;
+
+ if (!CPad::GetPad(1)->GetTriangleJustDown())
+ break;
+
+ i = 0;
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
+ }
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
+ }
+ CTimer::Update();
+} \ No newline at end of file