Various bug fixes

This commit is contained in:
Jack Andersen 2019-03-08 22:58:27 -10:00
parent f40bf707f6
commit 2f963b9ce3
28 changed files with 283 additions and 120 deletions

View File

@ -5,6 +5,7 @@
namespace urde { namespace urde {
hecl::ProjectPath CDvdFile::m_DvdRoot; hecl::ProjectPath CDvdFile::m_DvdRoot;
std::unordered_map<std::string, std::string> CDvdFile::m_caseInsensitiveMap;
class CFileDvdRequest : public IDvdRequest { class CFileDvdRequest : public IDvdRequest {
std::shared_ptr<athena::io::FileReader> m_reader; std::shared_ptr<athena::io::FileReader> m_reader;
@ -90,8 +91,34 @@ std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOr
return ret; return ret;
} }
hecl::ProjectPath CDvdFile::ResolvePath(std::string_view path) {
auto start = path.begin();
while (*start == '/') ++start;
std::string lowerChStr(start, path.end());
std::transform(lowerChStr.begin(), lowerChStr.end(), lowerChStr.begin(), ::tolower);
auto search = m_caseInsensitiveMap.find(lowerChStr);
if (search == m_caseInsensitiveMap.end())
return {};
return hecl::ProjectPath(m_DvdRoot, search->second);
}
void CDvdFile::RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, std::string::size_type prefixLen) {
for (const auto& p : path.enumerateDir()) {
if (p.m_isDir) {
RecursiveBuildCaseInsensitiveMap(hecl::ProjectPath(path, p.m_name), prefixLen);
} else {
hecl::ProjectPath ch(path, p.m_name);
std::string chStr(ch.getAbsolutePathUTF8().begin() + prefixLen, ch.getAbsolutePathUTF8().end());
std::string lowerChStr(chStr);
std::transform(lowerChStr.begin(), lowerChStr.end(), lowerChStr.begin(), ::tolower);
m_caseInsensitiveMap[lowerChStr] = chStr;
}
}
}
void CDvdFile::Initialize(const hecl::ProjectPath& path) { void CDvdFile::Initialize(const hecl::ProjectPath& path) {
m_DvdRoot = path; m_DvdRoot = path;
RecursiveBuildCaseInsensitiveMap(path, path.getAbsolutePathUTF8().length() + 1);
if (m_WorkerRun.load()) if (m_WorkerRun.load())
return; return;
m_WorkerRun.store(true); m_WorkerRun.store(true);

View File

@ -18,6 +18,7 @@ class CDvdFile {
friend class CResLoader; friend class CResLoader;
friend class CFileDvdRequest; friend class CFileDvdRequest;
static hecl::ProjectPath m_DvdRoot; static hecl::ProjectPath m_DvdRoot;
static std::unordered_map<std::string, std::string> m_caseInsensitiveMap;
static std::thread m_WorkerThread; static std::thread m_WorkerThread;
static std::mutex m_WorkerMutex; static std::mutex m_WorkerMutex;
static std::condition_variable m_WorkerCV; static std::condition_variable m_WorkerCV;
@ -29,16 +30,19 @@ class CDvdFile {
std::string x18_path; std::string x18_path;
std::shared_ptr<athena::io::FileReader> m_reader; std::shared_ptr<athena::io::FileReader> m_reader;
static hecl::ProjectPath ResolvePath(std::string_view path);
static void RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, std::string::size_type prefixLen);
public: public:
static void Initialize(const hecl::ProjectPath& path); static void Initialize(const hecl::ProjectPath& path);
static void Shutdown(); static void Shutdown();
CDvdFile(std::string_view path) CDvdFile(std::string_view path)
: x18_path(path) : x18_path(path)
, m_reader(std::make_shared<athena::io::FileReader>(hecl::ProjectPath(m_DvdRoot, path).getAbsolutePath())) {} , m_reader(std::make_shared<athena::io::FileReader>(ResolvePath(path).getAbsolutePath())) {}
operator bool() const { return m_reader->isOpen(); } operator bool() const { return m_reader->isOpen(); }
void UpdateFilePos(int pos) { m_reader->seek(pos, athena::SeekOrigin::Begin); } void UpdateFilePos(int pos) { m_reader->seek(pos, athena::SeekOrigin::Begin); }
static bool FileExists(std::string_view path) { return hecl::ProjectPath(m_DvdRoot, path).isFile(); } static bool FileExists(std::string_view path) { return ResolvePath(path).isFile(); }
void CloseFile() { m_reader->close(); } void CloseFile() { m_reader->close(); }
std::shared_ptr<IDvdRequest> AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off, std::shared_ptr<IDvdRequest> AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off,
std::function<void(u32)>&& cb = {}); std::function<void(u32)>&& cb = {});

View File

@ -97,6 +97,19 @@ void CResFactory::CancelBuild(const SObjectTag& tag) {
} }
} }
void CResFactory::LoadPersistentResources(CSimplePool& sp) {
const auto& paks = x4_loader.GetPaks();
for (auto it = paks.begin(); it != paks.end(); ++it) {
if (!(*it)->IsWorldPak()) {
for (const CAssetId& id : (*it)->GetDepList()) {
SObjectTag tag(GetResourceTypeById(id), id);
m_nonWorldTokens.push_back(sp.GetObj(tag));
m_nonWorldTokens.back().Lock();
}
}
}
}
void CResFactory::LoadOriginalIDs(CSimplePool& sp) { void CResFactory::LoadOriginalIDs(CSimplePool& sp) {
#if RUNTIME_ORIGINAL_IDS #if RUNTIME_ORIGINAL_IDS
m_origIds = sp.GetObj("MP1OriginalIDs"); m_origIds = sp.GetObj("MP1OriginalIDs");

View File

@ -38,6 +38,7 @@ public:
private: private:
std::list<SLoadingData> m_loadList; std::list<SLoadingData> m_loadList;
std::unordered_map<SObjectTag, std::list<SLoadingData>::iterator> m_loadMap; std::unordered_map<SObjectTag, std::list<SLoadingData>::iterator> m_loadMap;
std::vector<CToken> m_nonWorldTokens; /* URDE: always keep non-world resources resident */
void AddToLoadList(SLoadingData&& data); void AddToLoadList(SLoadingData&& data);
CFactoryFnReturn BuildSync(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); CFactoryFnReturn BuildSync(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
bool PumpResource(SLoadingData& data); bool PumpResource(SLoadingData& data);
@ -87,6 +88,9 @@ public:
return x4_loader.EnumerateNamedResources(lambda); return x4_loader.EnumerateNamedResources(lambda);
} }
void LoadPersistentResources(CSimplePool& sp);
void UnloadPersistentResources() { m_nonWorldTokens.clear(); }
void LoadOriginalIDs(CSimplePool& sp); void LoadOriginalIDs(CSimplePool& sp);
CAssetId TranslateOriginalToNew(CAssetId id) const; CAssetId TranslateOriginalToNew(CAssetId id) const;
CAssetId TranslateNewToOriginal(CAssetId id) const; CAssetId TranslateNewToOriginal(CAssetId id) const;

View File

@ -1,5 +1,6 @@
#include "CMetaAnimBlend.hpp" #include "CMetaAnimBlend.hpp"
#include "CMetaAnimFactory.hpp" #include "CMetaAnimFactory.hpp"
#include "CAnimTreeBlend.hpp"
namespace urde { namespace urde {
@ -17,8 +18,14 @@ void CMetaAnimBlend::GetUniquePrimitives(std::set<CPrimitive>& primsOut) const {
std::shared_ptr<CAnimTreeNode> CMetaAnimBlend::VGetAnimationTree(const CAnimSysContext& animSys, std::shared_ptr<CAnimTreeNode> CMetaAnimBlend::VGetAnimationTree(const CAnimSysContext& animSys,
const CMetaAnimTreeBuildOrders& orders) const { const CMetaAnimTreeBuildOrders& orders) const {
// CMetaAnimTreeBuildOrders buildOrders = CMetaAnimTreeBuildOrders::NoSpecialOrders(); CMetaAnimTreeBuildOrders oa = CMetaAnimTreeBuildOrders::NoSpecialOrders();
return {}; CMetaAnimTreeBuildOrders ob = orders.x0_recursiveAdvance ?
CMetaAnimTreeBuildOrders::PreAdvanceForAll(*orders.x0_recursiveAdvance) :
CMetaAnimTreeBuildOrders::NoSpecialOrders();
auto a = x4_animA->GetAnimationTree(animSys, oa);
auto b = x8_animB->GetAnimationTree(animSys, ob);
return std::make_shared<CAnimTreeBlend>(x10_, a, b, xc_blend,
CAnimTreeBlend::CreatePrimitiveName(a, b, xc_blend));
} }
} // namespace urde } // namespace urde

View File

@ -1,5 +1,7 @@
#include "CMetaAnimPhaseBlend.hpp" #include "CMetaAnimPhaseBlend.hpp"
#include "CMetaAnimFactory.hpp" #include "CMetaAnimFactory.hpp"
#include "CAnimTreeTimeScale.hpp"
#include "CAnimTreeBlend.hpp"
namespace urde { namespace urde {
@ -17,7 +19,24 @@ void CMetaAnimPhaseBlend::GetUniquePrimitives(std::set<CPrimitive>& primsOut) co
std::shared_ptr<CAnimTreeNode> CMetaAnimPhaseBlend::VGetAnimationTree(const CAnimSysContext& animSys, std::shared_ptr<CAnimTreeNode> CMetaAnimPhaseBlend::VGetAnimationTree(const CAnimSysContext& animSys,
const CMetaAnimTreeBuildOrders& orders) const { const CMetaAnimTreeBuildOrders& orders) const {
return {}; if (orders.x0_recursiveAdvance)
return GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::PreAdvanceForAll(*orders.x0_recursiveAdvance));
auto a = x4_animA->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders());
auto b = x8_animB->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders());
auto da = a->GetContributionOfHighestInfluence().GetSteadyStateAnimInfo().GetDuration();
auto db = b->GetContributionOfHighestInfluence().GetSteadyStateAnimInfo().GetDuration();
auto dblend = da + (db - da) * xc_blend;
float fa = da / dblend;
float fb = db / dblend;
auto tsa = std::make_shared<CAnimTreeTimeScale>(a, fa,
CAnimTreeTimeScale::CreatePrimitiveName(a, fa, CCharAnimTime::Infinity(), -1.f));
auto tsb = std::make_shared<CAnimTreeTimeScale>(b, fb,
CAnimTreeTimeScale::CreatePrimitiveName(b, fb, CCharAnimTime::Infinity(), -1.f));
return std::make_shared<CAnimTreeBlend>(x10_, tsa, tsb, xc_blend,
CAnimTreeBlend::CreatePrimitiveName(tsa, tsb, xc_blend));
} }
} // namespace urde } // namespace urde

View File

@ -12,17 +12,13 @@ void CMetaAnimPlay::GetUniquePrimitives(std::set<CPrimitive>& primsOut) const {
std::shared_ptr<CAnimTreeNode> CMetaAnimPlay::VGetAnimationTree(const CAnimSysContext& animSys, std::shared_ptr<CAnimTreeNode> CMetaAnimPlay::VGetAnimationTree(const CAnimSysContext& animSys,
const CMetaAnimTreeBuildOrders& orders) const { const CMetaAnimTreeBuildOrders& orders) const {
if (orders.x0_recursiveAdvance) { if (orders.x0_recursiveAdvance)
CMetaAnimTreeBuildOrders modOrders; return GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::PreAdvanceForAll(*orders.x0_recursiveAdvance));
modOrders.PreAdvanceForAll(*orders.x0_recursiveAdvance);
return GetAnimationTree(animSys, modOrders);
}
TLockedToken<CAllFormatsAnimSource> prim = TLockedToken<CAllFormatsAnimSource> prim =
animSys.xc_store.GetObj(SObjectTag{FOURCC('ANIM'), x4_primitive.GetAnimResId()}); animSys.xc_store.GetObj(SObjectTag{FOURCC('ANIM'), x4_primitive.GetAnimResId()});
std::shared_ptr<CAnimTreeNode> ret = std::make_shared<CAnimTreeAnimReaderContainer>( return std::make_shared<CAnimTreeAnimReaderContainer>(
x4_primitive.GetName(), CAllFormatsAnimSource::GetNewReader(prim, x1c_startTime), x4_primitive.GetAnimDbIdx()); x4_primitive.GetName(), CAllFormatsAnimSource::GetNewReader(prim, x1c_startTime), x4_primitive.GetAnimDbIdx());
return ret;
} }
} // namespace urde } // namespace urde

View File

@ -24,25 +24,20 @@ void CMetaAnimSequence::GetUniquePrimitives(std::set<CPrimitive>& primsOut) cons
std::shared_ptr<CAnimTreeNode> CMetaAnimSequence::VGetAnimationTree(const CAnimSysContext& animSys, std::shared_ptr<CAnimTreeNode> CMetaAnimSequence::VGetAnimationTree(const CAnimSysContext& animSys,
const CMetaAnimTreeBuildOrders& orders) const { const CMetaAnimTreeBuildOrders& orders) const {
if (orders.x0_recursiveAdvance) { if (orders.x0_recursiveAdvance)
CMetaAnimTreeBuildOrders modOrders; return GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::PreAdvanceForAll(*orders.x0_recursiveAdvance));
modOrders.PreAdvanceForAll(*orders.x0_recursiveAdvance);
return GetAnimationTree(animSys, modOrders);
}
#if 0 #if 0
std::vector<std::string> anims; /* Originally used to generate name string */
anims.reserve(anims.size()); std::vector<std::string> anims;
for (const std::shared_ptr<IMetaAnim>& anim : x4_sequence) anims.reserve(anims.size());
{ for (const std::shared_ptr<IMetaAnim>& anim : x4_sequence) {
std::shared_ptr<CAnimTreeNode> chNode = anim->GetAnimationTree(animSys, orders); std::shared_ptr<CAnimTreeNode> chNode = anim->GetAnimationTree(animSys, orders);
anims.emplace_back(chNode->GetName()); anims.emplace_back(chNode->GetName());
} }
#endif #endif
std::shared_ptr<CAnimTreeNode> ret = std::make_shared<CAnimTreeSequence>(x4_sequence, animSys, ""); return std::make_shared<CAnimTreeSequence>(x4_sequence, animSys, "");
return ret;
} }
} // namespace urde } // namespace urde

View File

@ -11,10 +11,14 @@ CTransitionDatabaseGame::CTransitionDatabaseGame(const std::vector<CTransition>&
x14_transitions.reserve(transitions.size()); x14_transitions.reserve(transitions.size());
for (const CTransition& trans : transitions) for (const CTransition& trans : transitions)
x14_transitions.emplace_back(trans.GetAnimPair(), trans.GetMetaTrans()); x14_transitions.emplace_back(trans.GetAnimPair(), trans.GetMetaTrans());
std::sort(x14_transitions.begin(), x14_transitions.end(),
[](const auto& a, const auto& b) { return a.first < b.first; });
x24_halfTransitions.reserve(halfTransitions.size()); x24_halfTransitions.reserve(halfTransitions.size());
for (const CHalfTransition& trans : halfTransitions) for (const CHalfTransition& trans : halfTransitions)
x24_halfTransitions.emplace_back(trans.GetId(), trans.GetMetaTrans()); x24_halfTransitions.emplace_back(trans.GetId(), trans.GetMetaTrans());
std::sort(x24_halfTransitions.begin(), x24_halfTransitions.end(),
[](const auto& a, const auto& b) { return a.first < b.first; });
} }
const std::shared_ptr<IMetaTrans>& CTransitionDatabaseGame::GetMetaTrans(u32 a, u32 b) const { const std::shared_ptr<IMetaTrans>& CTransitionDatabaseGame::GetMetaTrans(u32 a, u32 b) const {

View File

@ -46,7 +46,6 @@ struct CMetaAnimTreeBuildOrders {
static CMetaAnimTreeBuildOrders NoSpecialOrders() { return {}; } static CMetaAnimTreeBuildOrders NoSpecialOrders() { return {}; }
static CMetaAnimTreeBuildOrders PreAdvanceForAll(const CPreAdvanceIndicator& ind) { static CMetaAnimTreeBuildOrders PreAdvanceForAll(const CPreAdvanceIndicator& ind) {
CMetaAnimTreeBuildOrders ret; CMetaAnimTreeBuildOrders ret;
ret.x0_recursiveAdvance.emplace(ind);
ret.x44_singleAdvance.emplace(ind); ret.x44_singleAdvance.emplace(ind);
return ret; return ret;
} }

View File

@ -117,7 +117,7 @@ zeus::CVector3f CCollisionActor::GetScanObjectIndicatorPosition(const CStateMana
} }
scanScale *= 3.0f; scanScale *= 3.0f;
zeus::CVector3f orbitPos = GetOrbitPosition(mgr); zeus::CVector3f orbitPos = GetOrbitPosition(mgr);
return (scanScale * (orbitPos - gameCamera->GetTransform().origin).normalized()) - orbitPos; return orbitPos - scanScale * (orbitPos - gameCamera->GetTranslation()).normalized();
} }
const CCollisionPrimitive* CCollisionActor::GetCollisionPrimitive() const { const CCollisionPrimitive* CCollisionActor::GetCollisionPrimitive() const {

View File

@ -18,11 +18,10 @@ CGuiModel::CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId mod
bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const { bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const {
if (!xb8_model) if (!xb8_model)
return true; return true;
const CModel* model = xb8_model.GetObj(); if (!xb8_model.IsLoaded())
if (!model)
return false; return false;
model->GetInstance().Touch(0); xb8_model->GetInstance().Touch(0);
return model->IsLoaded(0); return xb8_model->IsLoaded(0);
} }
void CGuiModel::Touch() const { void CGuiModel::Touch() const {

View File

@ -358,7 +358,8 @@ void CSamusHud::UpdateEnergy(float dt, const CStateManager& mgr, bool init) {
float curLastTankEnergy = x2d0_playerHealth; float curLastTankEnergy = x2d0_playerHealth;
while (curLastTankEnergy > CPlayerState::GetBaseHealthCapacity()) while (curLastTankEnergy > CPlayerState::GetBaseHealthCapacity())
curLastTankEnergy -= CPlayerState::GetEnergyTankCapacity(); curLastTankEnergy -= CPlayerState::GetEnergyTankCapacity();
x28c_energyIntf->SetCurrEnergy(lastTankEnergy, curLastTankEnergy < lastTankEnergy); x28c_energyIntf->SetCurrEnergy(lastTankEnergy,
curLastTankEnergy > lastTankEnergy != x2d0_playerHealth > energy);
} }
x2d0_playerHealth = energy; x2d0_playerHealth = energy;
if (x28c_energyIntf) { if (x28c_energyIntf) {

View File

@ -759,6 +759,10 @@ bool CMain::Proc() {
// Warmup cycle overrides update // Warmup cycle overrides update
if (m_warmupTags.size()) if (m_warmupTags.size())
return false; return false;
if (!m_loadedPersistentResources) {
x128_globalObjects.m_gameResFactory->LoadPersistentResources(*g_SimplePool);
m_loadedPersistentResources = true;
}
m_console->proc(); m_console->proc();
if (!m_console->isOpen()) { if (!m_console->isOpen()) {
@ -832,6 +836,7 @@ void CMain::ShutdownSubsystems() {
void CMain::Shutdown() { void CMain::Shutdown() {
m_console->unregisterCommand("Give"); m_console->unregisterCommand("Give");
x128_globalObjects.m_gameResFactory->UnloadPersistentResources();
x164_archSupport.reset(); x164_archSupport.reset();
ShutdownSubsystems(); ShutdownSubsystems();
CParticleSwooshShaders::Shutdown(); CParticleSwooshShaders::Shutdown();

View File

@ -242,6 +242,7 @@ private:
std::vector<SObjectTag> m_warmupTags; std::vector<SObjectTag> m_warmupTags;
std::vector<SObjectTag>::iterator m_warmupIt; std::vector<SObjectTag>::iterator m_warmupIt;
bool m_needsWarmupClear = false; bool m_needsWarmupClear = false;
bool m_loadedPersistentResources = false;
bool m_doQuit = false; bool m_doQuit = false;
void InitializeSubsystems(); void InitializeSubsystems();

View File

@ -25,7 +25,7 @@ CAtomicAlpha::CAtomicAlpha(TUniqueId uid, std::string_view name, const CEntityIn
, x580_pathFind(nullptr, 3, pInfo.GetPathfindingIndex(), 1.f, 1.f) , x580_pathFind(nullptr, 3, pInfo.GetPathfindingIndex(), 1.f, 1.f)
, x668_bombProjectile(bombWeapon, bombDamage) , x668_bombProjectile(bombWeapon, bombDamage)
, x690_bombModel(CStaticRes(cmdl, GetModelData()->GetScale())) { , x690_bombModel(CStaticRes(cmdl, GetModelData()->GetScale())) {
const_cast<TToken<CWeaponDescription>*>(&x668_bombProjectile.Token())->Lock(); x668_bombProjectile.Token().Lock();
for (u32 i = 0; i < skBombCount; ++i) { for (u32 i = 0; i < skBombCount; ++i) {
x6dc_bombLocators.push_back( x6dc_bombLocators.push_back(
SBomb(skBombLocators[i], pas::ELocomotionType(u32(pas::ELocomotionType::Internal10) + i))); SBomb(skBombLocators[i], pas::ELocomotionType(u32(pas::ELocomotionType::Internal10) + i)));

View File

@ -76,7 +76,7 @@ CBabygoth::CBabygoth(TUniqueId uid, std::string_view name, const CEntityInfo& in
if (x570_babyData.x148_.IsValid()) if (x570_babyData.x148_.IsValid())
xa38_ = g_SimplePool->GetObj({SBIG('PART'), babyData.x148_}); xa38_ = g_SimplePool->GetObj({SBIG('PART'), babyData.x148_});
xa48_31_ = true; xa48_31_ = true;
const_cast<TToken<CWeaponDescription>*>(&x958_.Token())->Lock(); x958_.Token().Lock();
UpdateTouchBounds(); UpdateTouchBounds();
x460_knockBackController.SetEnableFreeze(false); x460_knockBackController.SetEnableFreeze(false);
x460_knockBackController.SetAutoResetImpulse(true); x460_knockBackController.SetAutoResetImpulse(true);

View File

@ -25,8 +25,9 @@ CNewIntroBoss::CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntity
, x5f0_beamContactFxId(beamContactFxId) , x5f0_beamContactFxId(beamContactFxId)
, x5f4_beamPulseFxId(beamPulseFxId) , x5f4_beamPulseFxId(beamPulseFxId)
, x5f8_beamTextureId(beamTextureId) , x5f8_beamTextureId(beamTextureId)
, x5fc_beamGlowTextureId(beamGlowTextureId) { , x5fc_beamGlowTextureId(beamGlowTextureId)
const_cast<TToken<CWeaponDescription>*>(&x5ac_projectileInfo.Token())->Lock(); , x644_initialXf(xf) {
x5ac_projectileInfo.Token().Lock();
x574_boneTracking.SetActive(true); x574_boneTracking.SetActive(true);
} }
@ -257,7 +258,7 @@ void CNewIntroBoss::Think(float dt, CStateManager& mgr) {
curProjectile->ResetBeam(mgr, true); curProjectile->ResetBeam(mgr, true);
x450_bodyController->SetPlaybackRate(1.f); x450_bodyController->SetPlaybackRate(1.f);
SetTransform(x644_); SetTransform(x644_initialXf);
StopRumble(mgr); StopRumble(mgr);
Death(mgr, GetTransform().frontVector(), EScriptObjectState::DeathRattle); Death(mgr, GetTransform().frontVector(), EScriptObjectState::DeathRattle);
} }

View File

@ -34,7 +34,7 @@ class CNewIntroBoss : public CPatterned {
float x638_ = 0.2f; float x638_ = 0.2f;
float x63c_attackTime = 8.f; float x63c_attackTime = 8.f;
float x640_initialHp = 0.f; float x640_initialHp = 0.f;
zeus::CTransform x644_; zeus::CTransform x644_initialXf;
s16 x674_rumbleVoice = -1; s16 x674_rumbleVoice = -1;
TUniqueId x676_curProjectile = kInvalidUniqueId; TUniqueId x676_curProjectile = kInvalidUniqueId;
bool x678_ = false; bool x678_ = false;

View File

@ -38,7 +38,7 @@ CPuddleSpore::CPuddleSpore(TUniqueId uid, std::string_view name, EFlavorType fla
x5dc_elemGens.reserve(kEyeCount); x5dc_elemGens.reserve(kEyeCount);
for (u32 i = 0; i < kEyeCount; ++i) for (u32 i = 0; i < kEyeCount; ++i)
x5dc_elemGens.emplace_back(new CElementGen(x5d0_)); x5dc_elemGens.emplace_back(new CElementGen(x5d0_));
const_cast<TToken<CWeaponDescription>*>(&x5ec_projectileInfo.Token())->Lock(); x5ec_projectileInfo.Token().Lock();
x460_knockBackController.SetAutoResetImpulse(false); x460_knockBackController.SetAutoResetImpulse(false);
} }

View File

@ -22,7 +22,7 @@ CSeedling::CSeedling(TUniqueId uid, std::string_view name, const CEntityInfo& in
, x6e8_deathDamage(dInfo2) , x6e8_deathDamage(dInfo2)
, x722_24_renderOnlyClusterA(true) , x722_24_renderOnlyClusterA(true)
, x722_25_curNeedleCluster(false) { , x722_25_curNeedleCluster(false) {
const_cast<TToken<CWeaponDescription>*>(&x6c0_projectileInfo.Token())->Lock(); x6c0_projectileInfo.Token().Lock();
CreateShadow(false); CreateShadow(false);
MakeThermalColdAndHot(); MakeThermalColdAndHot();
} }

View File

@ -237,7 +237,7 @@ bool CElementGen::Update(double t) {
if (pswtElem && !x26d_25_warmedUp) { if (pswtElem && !x26d_25_warmedUp) {
int pswt = 0; int pswt = 0;
pswtElem->GetValue(x74_curFrame, pswt); pswtElem->GetValue(x74_curFrame, pswt);
Log.report(logvisor::Info, "Running warmup on particle system 0x%08x for %d ticks.", desc, pswt); //Log.report(logvisor::Info, "Running warmup on particle system 0x%08x for %d ticks.", desc, pswt);
InternalUpdate((1.f / 60.f) * pswt); InternalUpdate((1.f / 60.f) * pswt);
x26d_25_warmedUp = true; x26d_25_warmedUp = true;
} }

View File

@ -27,16 +27,16 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
kInvalidUniqueId) kInvalidUniqueId)
, xe8_function(func) , xe8_function(func)
, xec_locatorName(lcName) , xec_locatorName(lcName)
, xfc_(f1) , xfc_float1(f1)
, x100_(f2) , x100_float2(f2)
, x104_(f3) , x104_float3(f3)
, x108_(f4) , x108_float4(f4)
, x10c_(vec) , x10c_vector3f(vec)
, x118_(col) , x118_color(col)
, x11c_damageInfo(dInfo) , x11c_damageInfo(dInfo)
, x170_(CSfxManager::TranslateSFXID(sId1)) , x170_sfx1(CSfxManager::TranslateSFXID(sId1))
, x172_(CSfxManager::TranslateSFXID(sId2)) , x172_sfx2(CSfxManager::TranslateSFXID(sId2))
, x174_(CSfxManager::TranslateSFXID(sId3)) , x174_sfx3(CSfxManager::TranslateSFXID(sId3))
, x1bc_areaSaveId(aId1) , x1bc_areaSaveId(aId1)
, x1c0_layerIdx(aId2) , x1c0_layerIdx(aId2)
, x1c4_item(itemType) { , x1c4_item(itemType) {
@ -126,12 +126,12 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
switch (xe8_function) { switch (xe8_function) {
case ESpecialFunction::HUDFadeIn: { case ESpecialFunction::HUDFadeIn: {
if (msg == EScriptObjectMessage::Action) if (msg == EScriptObjectMessage::Action)
mgr.Player()->SetHudDisable(xfc_, 0.f, 0.5f); mgr.Player()->SetHudDisable(xfc_float1, 0.f, 0.5f);
break; break;
} }
case ESpecialFunction::EscapeSequence: { case ESpecialFunction::EscapeSequence: {
if (msg == EScriptObjectMessage::Action && xfc_ >= 0.f) if (msg == EScriptObjectMessage::Action && xfc_float1 >= 0.f)
mgr.ResetEscapeSequenceTimer(xfc_); mgr.ResetEscapeSequenceTimer(xfc_float1);
break; break;
} }
case ESpecialFunction::SpinnerController: { case ESpecialFunction::SpinnerController: {
@ -165,7 +165,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
break; break;
} }
case EScriptObjectMessage::SetToZero: { case EScriptObjectMessage::SetToZero: {
x16c_ = -0.5f * x104_; x16c_ = -0.5f * x104_float3;
break; break;
} }
default: default:
@ -210,10 +210,10 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
break; break;
} }
case ESpecialFunction::IntroBossRingController: { case ESpecialFunction::IntroBossRingController: {
if (x1a8_ != 3) { if (x1a8_ringState != ERingState::Breakup) {
switch (msg) { switch (msg) {
case EScriptObjectMessage::Play: { case EScriptObjectMessage::Play: {
if (x1a8_ != 0) if (x1a8_ringState != ERingState::Scramble)
RingScramble(mgr); RingScramble(mgr);
for (SRingController& cont : x198_ringControllers) { for (SRingController& cont : x198_ringControllers) {
@ -223,14 +223,14 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
cont.xc_ = zeus::skForward; cont.xc_ = zeus::skForward;
} }
x1a8_ = 3; x1a8_ringState = ERingState::Breakup;
break; break;
} }
case EScriptObjectMessage::SetToZero: { case EScriptObjectMessage::SetToZero: {
x1a8_ = 1; x1a8_ringState = ERingState::Rotate;
x1ac_ = GetTranslation() - mgr.GetPlayer().GetTranslation(); x1ac_ringRotateTarget = GetTranslation() - mgr.GetPlayer().GetTranslation();
x1ac_.z() = 0.f; x1ac_ringRotateTarget.z() = 0.f;
x1ac_.normalize(); x1ac_ringRotateTarget.normalize();
break; break;
} }
case EScriptObjectMessage::Action: { case EScriptObjectMessage::Action: {
@ -250,8 +250,20 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
act->RemoveMaterial(EMaterialTypes::Occluder, mgr); act->RemoveMaterial(EMaterialTypes::Occluder, mgr);
} }
} }
}
// std::sort(x198_ringControllers.begin(), x198_ringControllers.end()); std::sort(x198_ringControllers.begin(), x198_ringControllers.end(),
[&mgr](const SRingController& a, const SRingController& b) {
TCastToConstPtr<CActor> actA(mgr.GetObjectById(a.x0_id));
TCastToConstPtr<CActor> actB(mgr.GetObjectById(b.x0_id));
if (actA && actB)
return actA->GetTranslation().z() < actB->GetTranslation().z();
return false;
});
for (auto& rc : x198_ringControllers) {
rc.x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1;
rc.x8_reachedTarget = false;
} }
break; break;
} }
@ -264,7 +276,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
case ESpecialFunction::RadialDamage: { case ESpecialFunction::RadialDamage: {
if (msg == EScriptObjectMessage::Action) { if (msg == EScriptObjectMessage::Action) {
CDamageInfo dInfo = x11c_damageInfo; CDamageInfo dInfo = x11c_damageInfo;
dInfo.SetRadius(xfc_); dInfo.SetRadius(xfc_float1);
mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), dInfo, mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), dInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull})); CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}));
} }
@ -272,7 +284,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
} }
case ESpecialFunction::BossEnergyBar: { case ESpecialFunction::BossEnergyBar: {
if (msg == EScriptObjectMessage::Increment) if (msg == EScriptObjectMessage::Increment)
mgr.SetBossParams(uid, xfc_, u32(x100_) + 86); mgr.SetBossParams(uid, xfc_float1, u32(x100_float2) + 86);
else if (msg == EScriptObjectMessage::Decrement) else if (msg == EScriptObjectMessage::Decrement)
mgr.SetBossParams(kInvalidUniqueId, 0.f, 0); mgr.SetBossParams(kInvalidUniqueId, 0.f, 0);
break; break;
@ -332,12 +344,12 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
*/ */
case ESpecialFunction::EnvFxDensityController: { case ESpecialFunction::EnvFxDensityController: {
if (msg == EScriptObjectMessage::Action) if (msg == EScriptObjectMessage::Action)
mgr.GetEnvFxManager()->SetFxDensity(s32(x100_), xfc_); mgr.GetEnvFxManager()->SetFxDensity(s32(x100_float2), xfc_float1);
break; break;
} }
case ESpecialFunction::RumbleEffect: case ESpecialFunction::RumbleEffect:
if (msg == EScriptObjectMessage::Action) { if (msg == EScriptObjectMessage::Action) {
s32 rumbFx = s32(x100_); s32 rumbFx = s32(x100_float2);
/* Retro originally did not check the upper bounds, this could potentially cause a crash /* Retro originally did not check the upper bounds, this could potentially cause a crash
* with some runtimes, so let's make sure we're not out of bounds in either direction * with some runtimes, so let's make sure we're not out of bounds in either direction
*/ */
@ -367,7 +379,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
} }
case ESpecialFunction::DropBomb: { case ESpecialFunction::DropBomb: {
if (msg == EScriptObjectMessage::Action) { if (msg == EScriptObjectMessage::Action) {
if (xfc_ >= 1.f) if (xfc_float1 >= 1.f)
mgr.GetPlayer().GetPlayerGun()->DropBomb(CPlayerGun::EBWeapon::PowerBomb, mgr); mgr.GetPlayer().GetPlayerGun()->DropBomb(CPlayerGun::EBWeapon::PowerBomb, mgr);
else else
mgr.GetPlayer().GetPlayerGun()->DropBomb(CPlayerGun::EBWeapon::Bomb, mgr); mgr.GetPlayer().GetPlayerGun()->DropBomb(CPlayerGun::EBWeapon::Bomb, mgr);
@ -389,13 +401,13 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
const SObjectTag* objectTag = g_ResFactory->GetResourceIdByName(xec_locatorName); const SObjectTag* objectTag = g_ResFactory->GetResourceIdByName(xec_locatorName);
CAssetId assetId = objectTag ? objectTag->id : CAssetId(); CAssetId assetId = objectTag ? objectTag->id : CAssetId();
mgr.SetPendingOnScreenTex(assetId, {int(x104_), int(x108_)}, {int(xfc_), int(x100_)}); mgr.SetPendingOnScreenTex(assetId, {int(x104_float3), int(x108_float4)}, {int(xfc_float1), int(x100_float2)});
if (objectTag) { if (objectTag) {
x1e8_ = g_SimplePool->GetObj(*objectTag); x1e8_ = g_SimplePool->GetObj(*objectTag);
x1e5_26_displayBillboard = true; x1e5_26_displayBillboard = true;
} }
} else if (msg == EScriptObjectMessage::Decrement) { } else if (msg == EScriptObjectMessage::Decrement) {
mgr.SetPendingOnScreenTex({}, {int(x104_), int(x108_)}, {int(xfc_), int(x100_)}); mgr.SetPendingOnScreenTex({}, {int(x104_float3), int(x108_float4)}, {int(xfc_float1), int(x100_float2)});
if (x1e8_) if (x1e8_)
x1e8_ = TLockedToken<CTexture>(); x1e8_ = TLockedToken<CTexture>();
x1e5_26_displayBillboard = false; x1e5_26_displayBillboard = false;
@ -418,9 +430,9 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
} }
case ESpecialFunction::FogFader: { case ESpecialFunction::FogFader: {
if (msg == EScriptObjectMessage::Increment) if (msg == EScriptObjectMessage::Increment)
mgr.GetCameraManager()->SetFogDensity(x100_, xfc_); mgr.GetCameraManager()->SetFogDensity(x100_float2, xfc_float1);
else if (msg == EScriptObjectMessage::Decrement) else if (msg == EScriptObjectMessage::Decrement)
mgr.GetCameraManager()->SetFogDensity(x100_, 1.f); mgr.GetCameraManager()->SetFogDensity(x100_float2, 1.f);
break; break;
} }
case ESpecialFunction::EnterLogbook: { case ESpecialFunction::EnterLogbook: {
@ -429,7 +441,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
break; break;
} }
case ESpecialFunction::Ending: { case ESpecialFunction::Ending: {
if (msg == EScriptObjectMessage::Action && GetSpecialEnding(mgr) == u32(xfc_)) if (msg == EScriptObjectMessage::Action && GetSpecialEnding(mgr) == u32(xfc_float1))
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
break; break;
} }
@ -450,15 +462,83 @@ void CScriptSpecialFunction::SkipCinematic(CStateManager& stateMgr) {
stateMgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId); stateMgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId);
} }
void CScriptSpecialFunction::RingMoveCloser(CStateManager&, float) {} void CScriptSpecialFunction::RingScramble(CStateManager& mgr) {
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
x1a8_ringState = ERingState::Scramble;
x1b8_ringReverse = !x1b8_ringReverse;
float dir = (x1b8_ringReverse ? 1.f : -1.f);
for (auto& rc : x198_ringControllers) {
rc.x4_rotateSpeed = dir * mgr.GetActiveRandom()->Range(x100_float2, x104_float3);
dir = -dir;
rc.x8_reachedTarget = false;
}
}
void CScriptSpecialFunction::RingMoveAway(CStateManager&, float) {} void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManager& mgr) {
if (x1a8_ringState != ERingState::Breakup) {
void CScriptSpecialFunction::ThinkRingPuller(float, CStateManager&) {} for (const auto& rc : x198_ringControllers) {
if (TCastToPtr<CActor> act = mgr.ObjectById(rc.x0_id)) {
void CScriptSpecialFunction::RingScramble(CStateManager&) {} zeus::CTransform newXf = act->GetTransform();
newXf.rotateLocalZ(zeus::degToRad(rc.x4_rotateSpeed * dt));
void CScriptSpecialFunction::ThinkIntroBossRingController(float, CStateManager&) {} act->SetTransform(newXf);
}
}
}
switch (x1a8_ringState) {
case ERingState::Breakup: {
float minMag = 0.f;
for (const auto& rc : x198_ringControllers) {
if (TCastToPtr<CActor> act = mgr.ObjectById(rc.x0_id)) {
act->SetTranslation(act->GetTransform().basis[1] * 50.f * dt + act->GetTranslation());
minMag = std::min(act->GetTranslation().magnitude(), minMag);
}
}
CalculateRenderBounds();
if (minMag != 0.f) {
/* Never actually happens */
for (const auto& rc : x198_ringControllers) {
if (CEntity* ent = mgr.ObjectById(rc.x0_id))
ent->SetActive(false);
}
SetActive(false);
}
break;
}
case ERingState::Rotate: {
x1ac_ringRotateTarget =
zeus::CQuaternion::fromAxisAngle(zeus::skUp,
zeus::degToRad(xfc_float1 * (x1b8_ringReverse ? 1.f : -1.f) * dt)).transform(x1ac_ringRotateTarget);
bool allReachedTarget = true;
for (auto& rc : x198_ringControllers) {
if (TCastToPtr<CActor> act = mgr.ObjectById(rc.x0_id)) {
zeus::CVector3f lookDirFlat = act->GetTransform().basis[1];
lookDirFlat.z() = 0.f;
lookDirFlat.normalize();
if (std::acos(zeus::clamp(-1.f, lookDirFlat.dot(x1ac_ringRotateTarget), 1.f)) <=
zeus::degToRad((xfc_float1 + std::fabs(rc.x4_rotateSpeed)) / 30.f)) {
zeus::CTransform newXf = zeus::lookAt(zeus::skZero3f, x1ac_ringRotateTarget);
newXf.origin = act->GetTranslation();
act->SetTransform(newXf);
rc.x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1;
rc.x8_reachedTarget = true;
} else {
allReachedTarget = false;
break;
}
}
}
if (allReachedTarget) {
SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None);
x1a8_ringState = ERingState::Stopped;
for (auto& rc : x198_ringControllers)
rc.x8_reachedTarget = false;
}
break;
}
default:
break;
}
}
void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager&) {} void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager&) {}
@ -498,7 +578,7 @@ void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager&) {}
void CScriptSpecialFunction::ThinkChaffTarget(float, CStateManager&) {} void CScriptSpecialFunction::ThinkChaffTarget(float, CStateManager&) {}
void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) { void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) {
float deltaScale = dt * xfc_; float deltaScale = dt * xfc_float1;
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate)
@ -509,9 +589,9 @@ void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) {
zeus::CVector3f scale = mData->GetScale(); zeus::CVector3f scale = mData->GetScale();
if (deltaScale > 0.f) if (deltaScale > 0.f)
scale = zeus::min(zeus::CVector3f(deltaScale) + scale, zeus::CVector3f(x100_)); scale = zeus::min(zeus::CVector3f(deltaScale) + scale, zeus::CVector3f(x100_float2));
else else
scale = zeus::max(zeus::CVector3f(deltaScale) + scale, zeus::CVector3f(x100_)); scale = zeus::max(zeus::CVector3f(deltaScale) + scale, zeus::CVector3f(x100_float2));
mData->SetScale(scale); mData->SetScale(scale);
} }
@ -575,6 +655,6 @@ u32 CScriptSpecialFunction::GetSpecialEnding(const CStateManager& mgr) const {
return 2; return 2;
} }
CScriptSpecialFunction::SRingController::SRingController(TUniqueId uid, float f, bool b) : x0_id(uid), x4_(f), x8_(b) {} CScriptSpecialFunction::SRingController::SRingController(TUniqueId uid, float f, bool b) : x0_id(uid), x4_rotateSpeed(f), x8_reachedTarget(b) {}
} // namespace urde } // namespace urde

View File

@ -53,10 +53,17 @@ public:
One, One,
}; };
enum class ERingState {
Scramble,
Rotate,
Stopped,
Breakup
};
struct SRingController { struct SRingController {
TUniqueId x0_id; TUniqueId x0_id;
float x4_; float x4_rotateSpeed;
bool x8_; bool x8_reachedTarget;
zeus::CVector3f xc_; zeus::CVector3f xc_;
SRingController(TUniqueId uid, float f, bool b); SRingController(TUniqueId uid, float f, bool b);
}; };
@ -64,28 +71,28 @@ public:
private: private:
ESpecialFunction xe8_function; ESpecialFunction xe8_function;
std::string xec_locatorName; std::string xec_locatorName;
float xfc_; float xfc_float1;
float x100_; float x100_float2;
float x104_; float x104_float3;
float x108_; float x108_float4;
zeus::CVector3f x10c_; zeus::CVector3f x10c_vector3f;
zeus::CColor x118_; zeus::CColor x118_color;
CDamageInfo x11c_damageInfo; CDamageInfo x11c_damageInfo;
float x138_ = 0.f; float x138_ = 0.f;
zeus::CTransform x13c_ = zeus::CTransform(); zeus::CTransform x13c_ = zeus::CTransform();
float x16c_ = 0.f; float x16c_ = 0.f;
s16 x170_; s16 x170_sfx1;
s16 x172_; s16 x172_sfx2;
s16 x174_; s16 x174_sfx3;
CSfxHandle x178_sfxHandle; CSfxHandle x178_sfxHandle;
u32 x17c_; u32 x17c_;
float x180_ = 0.f; float x180_ = 0.f;
std::vector<float> x184_; std::vector<float> x184_;
float x194_ = 0.f; float x194_ = 0.f;
std::vector<SRingController> x198_ringControllers; std::vector<SRingController> x198_ringControllers;
u32 x1a8_ = 2; ERingState x1a8_ringState = ERingState::Stopped;
zeus::CVector3f x1ac_ = zeus::skZero3f; zeus::CVector3f x1ac_ringRotateTarget = zeus::skZero3f;
bool x1b8_ = true; bool x1b8_ringReverse = true;
s32 x1bc_areaSaveId; s32 x1bc_areaSaveId;
s32 x1c0_layerIdx; s32 x1c0_layerIdx;
CPlayerState::EItemType x1c4_item; CPlayerState::EItemType x1c4_item;
@ -120,9 +127,6 @@ public:
void Render(const CStateManager&) const; void Render(const CStateManager&) const;
void SkipCinematic(CStateManager&); void SkipCinematic(CStateManager&);
void RingMoveCloser(CStateManager&, float);
void RingMoveAway(CStateManager&, float);
void ThinkRingPuller(float, CStateManager&);
void RingScramble(CStateManager&); void RingScramble(CStateManager&);
void ThinkIntroBossRingController(float, CStateManager&); void ThinkIntroBossRingController(float, CStateManager&);
void ThinkPlayerFollowLocator(float, CStateManager&); void ThinkPlayerFollowLocator(float, CStateManager&);

View File

@ -47,11 +47,7 @@ CScriptStreamedMusic::CScriptStreamedMusic(TUniqueId id, const CEntityInfo& info
, x47_music(music) , x47_music(music)
, x48_fadeIn(fadeIn) , x48_fadeIn(fadeIn)
, x4c_fadeOut(fadeOut) , x4c_fadeOut(fadeOut)
, x50_volume(volume) { , x50_volume(volume) {}
size_t pos;
while ((pos = x34_fileName.find("audio/")) != std::string::npos)
x34_fileName.replace(pos, 6, "Audio/");
}
void CScriptStreamedMusic::Stop(CStateManager& mgr) { void CScriptStreamedMusic::Stop(CStateManager& mgr) {
if (x45_fileIsDsp) if (x45_fileIsDsp)

View File

@ -18,7 +18,8 @@ CWorld::CSoundGroupData::CSoundGroupData(int grpId, CAssetId agsc) : x0_groupId(
CDummyWorld::CDummyWorld(CAssetId mlvlId, bool loadMap) : x4_loadMap(loadMap), xc_mlvlId(mlvlId) { CDummyWorld::CDummyWorld(CAssetId mlvlId, bool loadMap) : x4_loadMap(loadMap), xc_mlvlId(mlvlId) {
SObjectTag tag{FOURCC('MLVL'), mlvlId}; SObjectTag tag{FOURCC('MLVL'), mlvlId};
x34_loadBuf.reset(new u8[g_ResFactory->ResourceSize(tag)]); x38_bufSz = g_ResFactory->ResourceSize(tag);
x34_loadBuf.reset(new u8[x38_bufSz]);
x30_loadToken = g_ResFactory->LoadResourceAsync(tag, x34_loadBuf.get()); x30_loadToken = g_ResFactory->LoadResourceAsync(tag, x34_loadBuf.get());
} }
@ -99,10 +100,9 @@ void CWorldLayers::ReadWorldLayers(athena::io::MemoryReader& r, int version, CAs
bool CDummyWorld::ICheckWorldComplete() { bool CDummyWorld::ICheckWorldComplete() {
switch (x8_phase) { switch (x8_phase) {
case Phase::Loading: { case Phase::Loading: {
if (x30_loadToken && !x30_loadToken->IsComplete()) if (!x30_loadToken->IsComplete())
return false; return false;
x30_loadToken.reset(); athena::io::MemoryReader r(x34_loadBuf.get(), x38_bufSz);
athena::io::MemoryReader r(x34_loadBuf.get(), UINT32_MAX, false);
r.readUint32Big(); r.readUint32Big();
int version = r.readUint32Big(); int version = r.readUint32Big();
x10_strgId = r.readUint32Big(); x10_strgId = r.readUint32Big();
@ -141,6 +141,10 @@ bool CDummyWorld::ICheckWorldComplete() {
CWorldLayers::ReadWorldLayers(r, version, xc_mlvlId); CWorldLayers::ReadWorldLayers(r, version, xc_mlvlId);
x30_loadToken.reset();
x34_loadBuf.reset();
x38_bufSz = 0;
if (x4_loadMap) if (x4_loadMap)
x8_phase = Phase::LoadingMap; x8_phase = Phase::LoadingMap;
else { else {
@ -179,8 +183,9 @@ CWorld::CWorld(IObjectStore& objStore, IFactory& resFactory, CAssetId mlvlId)
: x8_mlvlId(mlvlId), x60_objectStore(objStore), x64_resFactory(resFactory) { : x8_mlvlId(mlvlId), x60_objectStore(objStore), x64_resFactory(resFactory) {
x70_24_currentAreaNeedsAllocation = true; x70_24_currentAreaNeedsAllocation = true;
SObjectTag tag{FOURCC('MLVL'), mlvlId}; SObjectTag tag{FOURCC('MLVL'), mlvlId};
x40_loadBuf.reset(new u8[resFactory.ResourceSize(tag)]); x44_bufSz = resFactory.ResourceSize(tag);
resFactory.LoadResourceAsync(tag, x40_loadBuf.get()); x40_loadBuf.reset(new u8[x44_bufSz]);
x3c_loadToken = resFactory.LoadResourceAsync(tag, x40_loadBuf.get());
} }
CWorld::~CWorld() { CWorld::~CWorld() {
@ -277,9 +282,9 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
switch (x4_phase) { switch (x4_phase) {
case Phase::Loading: { case Phase::Loading: {
if (!x40_loadBuf) if (!x3c_loadToken->IsComplete())
return false; return false;
athena::io::MemoryReader r(x40_loadBuf.get(), UINT32_MAX); athena::io::MemoryReader r(x40_loadBuf.get(), x44_bufSz);
r.readUint32Big(); r.readUint32Big();
int version = r.readUint32Big(); int version = r.readUint32Big();
xc_strgId = r.readUint32Big(); xc_strgId = r.readUint32Big();
@ -338,6 +343,9 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
CWorldLayers::ReadWorldLayers(r, version, x8_mlvlId); CWorldLayers::ReadWorldLayers(r, version, x8_mlvlId);
x3c_loadToken.reset();
x40_loadBuf.reset();
x44_bufSz = 0;
x4_phase = Phase::LoadingMap; x4_phase = Phase::LoadingMap;
[[fallthrough]]; [[fallthrough]];
} }

View File

@ -47,7 +47,7 @@ class CDummyWorld : public IWorld {
TLockedToken<CMapWorld> x2c_mapWorld; TLockedToken<CMapWorld> x2c_mapWorld;
std::shared_ptr<IDvdRequest> x30_loadToken; std::shared_ptr<IDvdRequest> x30_loadToken;
std::unique_ptr<uint8_t[]> x34_loadBuf; std::unique_ptr<uint8_t[]> x34_loadBuf;
// u32 x38_bufSz; u32 x38_bufSz;
TAreaId x3c_curAreaId = kInvalidAreaId; TAreaId x3c_curAreaId = kInvalidAreaId;
public: public:
@ -116,9 +116,9 @@ private:
CAssetId x24_mapwId; CAssetId x24_mapwId;
TLockedToken<CMapWorld> x28_mapWorld; TLockedToken<CMapWorld> x28_mapWorld;
std::vector<CRelay> x2c_relays; std::vector<CRelay> x2c_relays;
// AsyncTask x3c_loadToken; std::shared_ptr<IDvdRequest> x3c_loadToken;
std::unique_ptr<uint8_t[]> x40_loadBuf; std::unique_ptr<uint8_t[]> x40_loadBuf;
// u32 x44_bufSz; u32 x44_bufSz;
u32 x48_chainCount = 0; u32 x48_chainCount = 0;
CGameArea* x4c_chainHeads[5] = {}; CGameArea* x4c_chainHeads[5] = {};

2
amuse

@ -1 +1 @@
Subproject commit a4b8946ee2a395477683e40088aaa5d1d2245194 Subproject commit aa5abd5ff5561f3b105a20046588fa1d8bd7785c