2023-07-30 19:18:25 +00:00
|
|
|
#include "MetroidPrime/CGameArea.hpp"
|
|
|
|
|
|
|
|
#include "Kyoto/CDvdRequest.hpp"
|
2023-07-31 15:58:47 +00:00
|
|
|
#include "Kyoto/CResFactory.hpp"
|
|
|
|
|
2023-07-30 19:18:25 +00:00
|
|
|
#define ROUND_UP_32(val) (((val) + 31) & ~31)
|
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
rstl::pair< rstl::auto_ptr< uchar >, int > GetScriptingMemoryAlways(const IGameArea& area) {
|
|
|
|
SObjectTag tag('MREA', area.IGetAreaAssetId());
|
|
|
|
|
2023-10-12 21:52:29 +00:00
|
|
|
rstl::auto_ptr< char > buf = rs_new char[0x60];
|
|
|
|
CInputStream* resource =
|
|
|
|
gpResourceFactory->GetResLoader().LoadNewResourceSync(tag, 0, 0x60, buf.get());
|
2023-07-31 15:58:47 +00:00
|
|
|
if (!resource || *(uint*)(buf.get()) != 0xdeadbeef) {
|
|
|
|
return rstl::pair< rstl::auto_ptr< uchar >, int >(nullptr, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-31 13:35:09 +00:00
|
|
|
CGameArea::CPostConstructed::CPostConstructed() {}
|
|
|
|
CGameArea::CPostConstructed::~CPostConstructed() {}
|
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
const CTransform4f& CGameArea::IGetTM() const { return xc_transform; }
|
|
|
|
|
|
|
|
CAssetId CGameArea::IGetStringTableAssetId() const { return x8_nameSTRG; }
|
|
|
|
|
|
|
|
uint CGameArea::IGetNumAttachedAreas() const { return x8c_attachedAreaIndices.size(); }
|
|
|
|
|
|
|
|
TAreaId CGameArea::IGetAttachedAreaId(int i) const { return x8c_attachedAreaIndices[i]; }
|
|
|
|
|
|
|
|
bool CGameArea::IIsActive() const { return xf0_25_active; }
|
|
|
|
|
|
|
|
CAssetId CGameArea::IGetAreaAssetId() const { return x84_mrea; }
|
|
|
|
|
|
|
|
int CGameArea::IGetAreaSaveId() const { return x88_areaId; }
|
|
|
|
|
|
|
|
rstl::pair< rstl::auto_ptr< uchar >, int > CGameArea::IGetScriptingMemoryAlways() const {
|
|
|
|
return GetScriptingMemoryAlways(*this);
|
|
|
|
}
|
|
|
|
|
2023-07-30 19:18:25 +00:00
|
|
|
bool CGameArea::StartStreamingMainArea() {
|
|
|
|
if (xf0_24_postConstructed)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (xf4_phase) {
|
|
|
|
case kP_LoadHeader: {
|
|
|
|
x110_mreaSecBufs.reserve(3);
|
|
|
|
AllocNewAreaData(0, 96);
|
2023-10-12 21:52:29 +00:00
|
|
|
x12c_postConstructed.Set(rs_new CPostConstructed());
|
2023-07-30 19:18:25 +00:00
|
|
|
xf4_phase = kP_LoadSecSizes;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case kP_LoadSecSizes: {
|
|
|
|
CullDeadAreaRequests();
|
2023-07-31 13:35:09 +00:00
|
|
|
if (!xf8_loadTransactions.empty())
|
2023-07-30 19:18:25 +00:00
|
|
|
break;
|
|
|
|
VerifyHeader();
|
|
|
|
AllocNewAreaData(x110_mreaSecBufs[0].second, ROUND_UP_32(GetNumPartSizes() * 4));
|
|
|
|
xf4_phase = kP_ReserveSections;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case kP_ReserveSections: {
|
|
|
|
CullDeadAreaRequests();
|
2023-07-31 13:35:09 +00:00
|
|
|
if (xf8_loadTransactions.empty()) {
|
2023-07-30 19:18:25 +00:00
|
|
|
x110_mreaSecBufs.reserve(GetNumPartSizes() + 2);
|
|
|
|
x124_secCount = 0;
|
|
|
|
x128_mreaDataOffset = x110_mreaSecBufs[0].second + x110_mreaSecBufs[1].second;
|
|
|
|
xf4_phase = kP_LoadDataSections;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case kP_LoadDataSections: {
|
|
|
|
CullDeadAreaRequests();
|
|
|
|
|
2023-07-31 13:35:09 +00:00
|
|
|
int totalSz = 0;
|
|
|
|
int secCount = x124_secCount;
|
|
|
|
int partSizes = GetNumPartSizes();
|
|
|
|
SObjectTag tag('MREA', x84_mrea);
|
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
// for (uint i = 0; i < secCount; ++i)
|
|
|
|
// totalSz +=
|
|
|
|
// CBasics::SwapBytes(reinterpret_cast<u32*>(x110_mreaSecBufs[1].first.get())[i]);
|
2023-07-30 19:18:25 +00:00
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
// AllocNewAreaData(x128_mreaDataOffset, totalSz);
|
2023-07-30 19:18:25 +00:00
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
// m_resolvedBufs.reserve(secCount);
|
|
|
|
// m_resolvedBufs.emplace_back(x110_mreaSecBufs[0].first.get(), x110_mreaSecBufs[0].second);
|
|
|
|
// m_resolvedBufs.emplace_back(x110_mreaSecBufs[1].first.get(), x110_mreaSecBufs[1].second);
|
2023-07-30 19:18:25 +00:00
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
// uint curOff = 0;
|
|
|
|
// for (uint i = 0; i < secCount; ++i) {
|
|
|
|
// uint size =
|
|
|
|
// CBasics::SwapBytes(reinterpret_cast<u32*>(x110_mreaSecBufs[1].first.get())[i]);
|
|
|
|
// m_resolvedBufs.emplace_back(x110_mreaSecBufs[2].first.get() + curOff, size);
|
|
|
|
// curOff += size;
|
|
|
|
// }
|
2023-07-30 19:18:25 +00:00
|
|
|
|
2023-07-31 13:35:09 +00:00
|
|
|
int dif = partSizes - secCount;
|
|
|
|
int targetSecCount = secCount;
|
|
|
|
for (int i = secCount; i < partSizes; ++i) {
|
|
|
|
int size = x110_mreaSecBufs[i].second;
|
|
|
|
if (targetSecCount != secCount && 0x10000 < size + totalSz)
|
|
|
|
break;
|
|
|
|
totalSz += size;
|
|
|
|
targetSecCount += 1;
|
|
|
|
}
|
|
|
|
|
2023-07-31 15:58:47 +00:00
|
|
|
rstl::auto_ptr< char > buf = (char*)CMemory::Alloc(totalSz, IAllocator::kHI_RoundUpLen);
|
2023-07-30 19:18:25 +00:00
|
|
|
xf8_loadTransactions.push_back(
|
2023-07-31 15:58:47 +00:00
|
|
|
rstl::rc_ptr< CDvdRequest >(gpResourceFactory->GetResLoader().LoadResourcePartAsync(
|
|
|
|
tag, x128_mreaDataOffset, totalSz, buf.get())));
|
2023-07-30 19:18:25 +00:00
|
|
|
x128_mreaDataOffset += totalSz;
|
2023-07-31 15:58:47 +00:00
|
|
|
x110_mreaSecBufs.push_back(rstl::pair< rstl::auto_ptr< char >, int >(buf, 0));
|
2023-07-30 19:18:25 +00:00
|
|
|
|
2023-07-31 13:35:09 +00:00
|
|
|
for (int i = secCount + 1; i < targetSecCount; ++i) {
|
2023-07-31 15:58:47 +00:00
|
|
|
x110_mreaSecBufs.push_back(rstl::pair< rstl::auto_ptr< char >, int >(nullptr, 0));
|
2023-07-31 13:35:09 +00:00
|
|
|
}
|
|
|
|
x124_secCount = targetSecCount;
|
|
|
|
if (targetSecCount == partSizes) {
|
|
|
|
x120_unk = x128_mreaDataOffset;
|
|
|
|
xf4_phase = kP_WaitForFinish;
|
|
|
|
}
|
2023-07-30 19:18:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case kP_WaitForFinish: {
|
|
|
|
CullDeadAreaRequests();
|
2023-07-31 13:35:09 +00:00
|
|
|
if (xf8_loadTransactions.empty())
|
|
|
|
return false;
|
|
|
|
break;
|
2023-07-30 19:18:25 +00:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|