Ensure directories are created late in extract

This commit is contained in:
Jack Andersen 2017-01-16 15:23:19 -10:00
parent d66d9a24f4
commit 56b24c39f0
50 changed files with 402 additions and 177 deletions

View File

@ -67,20 +67,26 @@ namespace DataSpec
{ {
extern hecl::Database::DataSpecEntry SpecEntMP1; extern hecl::Database::DataSpecEntry SpecEntMP1;
extern hecl::Database::DataSpecEntry SpecEntMP1PC; extern hecl::Database::DataSpecEntry SpecEntMP1PC;
extern hecl::Database::DataSpecEntry SpecEntMP1ORIG;
extern hecl::Database::DataSpecEntry SpecEntMP2; extern hecl::Database::DataSpecEntry SpecEntMP2;
extern hecl::Database::DataSpecEntry SpecEntMP2PC; extern hecl::Database::DataSpecEntry SpecEntMP2PC;
extern hecl::Database::DataSpecEntry SpecEntMP2ORIG;
extern hecl::Database::DataSpecEntry SpecEntMP3; extern hecl::Database::DataSpecEntry SpecEntMP3;
extern hecl::Database::DataSpecEntry SpecEntMP3PC; extern hecl::Database::DataSpecEntry SpecEntMP3PC;
extern hecl::Database::DataSpecEntry SpecEntMP3ORIG;
}") }")
set(HECL_DATASPEC_PUSHES set(HECL_DATASPEC_PUSHES
" /* RetroCommon */ " /* RetroCommon */
hecl::Database::DATA_SPEC_REGISTRY.reserve(6); hecl::Database::DATA_SPEC_REGISTRY.reserve(9);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1); hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1PC); hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1PC);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1ORIG);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2); hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2PC); hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2PC);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2ORIG);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3); hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3PC);") hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3PC);
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3ORIG);")
add_subdirectory(hecl) add_subdirectory(hecl)
if(NOT TARGET atdna) if(NOT TARGET atdna)

View File

@ -84,6 +84,7 @@ void ReadMaterialSetToBlender_1_2(hecl::BlenderConnection::PyOutStream& os,
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (!txtrPath.isNone()) if (!txtrPath.isNone())
{ {
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node); PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath); TXTR::Extract(rs, txtrPath);
} }

View File

@ -119,20 +119,16 @@ hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) con
levelDir.assign(pakPath, *m_levelName); levelDir.assign(pakPath, *m_levelName);
else else
levelDir = pakPath; levelDir = pakPath;
levelDir.makeDir();
if (m_type == Type::Area) if (m_type == Type::Area)
{ {
hecl::ProjectPath areaDir(levelDir, *m_areaName); hecl::ProjectPath areaDir(levelDir, *m_areaName);
areaDir.makeDir();
return areaDir; return areaDir;
} }
else if (m_type == Type::Layer) else if (m_type == Type::Layer)
{ {
hecl::ProjectPath areaDir(levelDir, *m_areaName); hecl::ProjectPath areaDir(levelDir, *m_areaName);
areaDir.makeDir();
hecl::ProjectPath layerDir(areaDir, *m_layerName); hecl::ProjectPath layerDir(areaDir, *m_layerName);
layerDir.makeDir();
return layerDir; return layerDir;
} }
@ -228,6 +224,7 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
/* Write catalog */ /* Write catalog */
intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get()); intptr_t curBridgeIdx = reinterpret_cast<intptr_t>(m_curBridgeIdx.get());
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
pakPath.makeDirChain(true);
hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "!catalog.yaml").getAbsolutePath(); hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "!catalog.yaml").getAbsolutePath();
athena::io::FileWriter writer(catalogPath); athena::io::FileWriter writer(catalogPath);
catalogWriter.finish(&writer); catalogWriter.finish(&writer);
@ -244,8 +241,6 @@ void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge)
{ {
if (&bridge == &pakBridge) if (&bridge == &pakBridge)
{ {
pit->first.makeDir();
pit->second.makeDir();
m_pak.reset(&pakBridge.getPAK()); m_pak.reset(&pakBridge.getPAK());
m_node.reset(&pakBridge.getNode()); m_node.reset(&pakBridge.getNode());
m_curBridgeIdx.reset(reinterpret_cast<void*>(bridgeIdx)); m_curBridgeIdx.reset(reinterpret_cast<void*>(bridgeIdx));
@ -297,7 +292,6 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
if (singleSearch) if (singleSearch)
{ {
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
pakPath.makeDir();
#if HECL_UCS2 #if HECL_UCS2
hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry)); hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry));
#else #else
@ -322,7 +316,6 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
{ {
const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first);
const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first; const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first;
pakPath.makeDir();
#if HECL_UCS2 #if HECL_UCS2
hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry)); hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry));
#else #else
@ -369,7 +362,6 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
auxInfo = chWork.getAuxInfo(); auxInfo = chWork.getAuxInfo();
} }
hecl::ProjectPath sharedPath(m_sharedWorking, entName); hecl::ProjectPath sharedPath(m_sharedWorking, entName);
m_sharedWorking.makeDir();
return sharedPath.ensureAuxInfo(auxInfo); return sharedPath.ensureAuxInfo(auxInfo);
} }
@ -417,7 +409,6 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
if (singleSearch) if (singleSearch)
{ {
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second; const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second;
pakPath.makeDir();
return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); return hecl::ProjectPath(pakPath, getBestEntryName(*entry));
} }
} }
@ -426,7 +417,6 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
{ {
const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first);
const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].second; const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].second;
pakPath.makeDir();
if (bridge.getPAK().m_noShare) if (bridge.getPAK().m_noShare)
{ {
return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); return hecl::ProjectPath(pakPath, getBestEntryName(*entry));
@ -440,7 +430,6 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
auto sharedSearch = m_sharedEntries.find(entry->id); auto sharedSearch = m_sharedEntries.find(entry->id);
if (sharedSearch != m_sharedEntries.end()) if (sharedSearch != m_sharedEntries.end())
{ {
m_sharedCooked.makeDir();
return hecl::ProjectPath(m_sharedCooked, getBestEntryName(*entry)); return hecl::ProjectPath(m_sharedCooked, getBestEntryName(*entry));
} }
LogDNACommon.report(logvisor::Fatal, "Unable to find entry %s", entry->id.toString().c_str()); LogDNACommon.report(logvisor::Fatal, "Unable to find entry %s", entry->id.toString().c_str());
@ -551,14 +540,16 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
const nod::Node* node = m_node.get(); const nod::Node* node = m_node.get();
hecl::ProjectPath working = getWorking(item, extractor); hecl::ProjectPath working = getWorking(item, extractor);
working.makeDirChain(false);
hecl::ResourceLock resLk(working); hecl::ResourceLock resLk(working);
if (!resLk) if (!resLk)
continue; continue;
/* Extract first, so they start out invalid */ /* Extract to unmodified directory */
hecl::ProjectPath cooked = getCooked(item); hecl::ProjectPath cooked = working.getCookedPath(m_dataSpec.getUnmodifiedSpec());
if (force || cooked.isNone()) if (force || cooked.isNone())
{ {
cooked.makeDirChain(false);
PAKEntryReadStream s = item->beginReadStream(*node); PAKEntryReadStream s = item->beginReadStream(*node);
FILE* fout = hecl::Fopen(cooked.getAbsolutePath().c_str(), _S("wb")); FILE* fout = hecl::Fopen(cooked.getAbsolutePath().c_str(), _S("wb"));
fwrite(s.data(), 1, s.length(), fout); fwrite(s.data(), 1, s.length(), fout);

View File

@ -464,6 +464,7 @@ bool FRME::Extract(const SpecBase &dataSpec,
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.isNone()) if (txtrPath.isNone())
{ {
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node); PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath); TXTR::Extract(rs, txtrPath);
} }

View File

@ -43,7 +43,7 @@ void SCLY::exportToLayerDirectories(const PAK::Entry& entry, PAKRouter<PAKBridge
bool active; bool active;
hecl::ProjectPath layerPath = pakRouter.getAreaLayerWorking(entry.id, i, active); hecl::ProjectPath layerPath = pakRouter.getAreaLayerWorking(entry.id, i, active);
if (layerPath.isNone()) if (layerPath.isNone())
layerPath.makeDir(); layerPath.makeDirChain(true);
if (active) if (active)
{ {

View File

@ -126,6 +126,7 @@ void Material::SectionPASS::constructNode(hecl::BlenderConnection::PyOutStream&
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.isNone()) if (txtrPath.isNone())
{ {
txtrPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node); PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath); TXTR::Extract(rs, txtrPath);
} }

View File

@ -106,7 +106,7 @@ void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
{ {
/* Extract root files for repacking later */ /* Extract root files for repacking later */
hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), _S("out")); hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), _S("out"));
outDir.makeDir(); outDir.makeDirChain(true);
nod::ExtractionContext ctx = {true, info.force, nullptr}; nod::ExtractionContext ctx = {true, info.force, nullptr};
if (!m_standalone) if (!m_standalone)
@ -218,7 +218,7 @@ const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::Proj
{ {
return oldEntry; return oldEntry;
} }
return getOriginalSpec(); return &getOriginalSpec();
} }
void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath,
@ -264,6 +264,12 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
cookWorld(cookedPath, path, ds, fast, btok, progress); cookWorld(cookedPath, path, ds, fast, btok, progress);
break; break;
} }
case hecl::BlenderConnection::BlendType::Frame:
{
hecl::BlenderConnection::DataStream ds = conn.beginData();
cookGuiFrame(cookedPath, path, ds, btok, progress);
break;
}
default: break; default: break;
} }
} }

View File

@ -50,7 +50,10 @@ struct SpecBase : hecl::Database::IDataSpec
hecl::BlenderToken& btok) const=0; hecl::BlenderToken& btok) const=0;
/* Even if PC spec is being cooked, this will return the vanilla GCN spec */ /* Even if PC spec is being cooked, this will return the vanilla GCN spec */
virtual const hecl::Database::DataSpecEntry* getOriginalSpec() const=0; virtual const hecl::Database::DataSpecEntry& getOriginalSpec() const=0;
/* This will return a pseudo-spec for unmodified resources */
virtual const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const=0;
/* Basic path check (game directory matching) */ /* Basic path check (game directory matching) */
virtual bool checkPathPrefix(const hecl::ProjectPath& path) const=0; virtual bool checkPathPrefix(const hecl::ProjectPath& path) const=0;
@ -77,6 +80,9 @@ struct SpecBase : hecl::Database::IDataSpec
virtual void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, virtual void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, hecl::BlenderToken& btok, BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)=0; FCookProgress progress)=0;
virtual void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, hecl::BlenderToken& btok,
FCookProgress progress)=0;
virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
athena::io::IStreamReader& fin, FCookProgress progress)=0; athena::io::IStreamReader& fin, FCookProgress progress)=0;
virtual void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, virtual void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in,

View File

@ -36,6 +36,7 @@ namespace DataSpec
static logvisor::Module Log("urde::SpecMP1"); static logvisor::Module Log("urde::SpecMP1");
extern hecl::Database::DataSpecEntry SpecEntMP1; extern hecl::Database::DataSpecEntry SpecEntMP1;
extern hecl::Database::DataSpecEntry SpecEntMP1PC; extern hecl::Database::DataSpecEntry SpecEntMP1PC;
extern hecl::Database::DataSpecEntry SpecEntMP1ORIG;
struct SpecMP1 : SpecBase struct SpecMP1 : SpecBase
{ {
@ -239,9 +240,6 @@ struct SpecMP1 : SpecBase
nod::ExtractionContext ctx = {true, force, nullptr}; nod::ExtractionContext ctx = {true, force, nullptr};
m_workPath.makeDir(); m_workPath.makeDir();
const hecl::ProjectPath& cookPath = m_project.getProjectCookedPath(SpecEntMP1);
cookPath.makeDir();
m_cookPath.makeDir();
progress(_S("Indexing PAKs"), _S(""), 2, 0.0); progress(_S("Indexing PAKs"), _S(""), 2, 0.0);
m_pakRouter.build(m_paks, [&progress](float factor) m_pakRouter.build(m_paks, [&progress](float factor)
@ -314,9 +312,14 @@ struct SpecMP1 : SpecBase
return true; return true;
} }
const hecl::Database::DataSpecEntry* getOriginalSpec() const const hecl::Database::DataSpecEntry& getOriginalSpec() const
{ {
return &SpecEntMP1; return SpecEntMP1;
}
const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const
{
return SpecEntMP1ORIG;
} }
hecl::ProjectPath getWorking(class UniqueID32& id) hecl::ProjectPath getWorking(class UniqueID32& id)
@ -605,6 +608,13 @@ struct SpecMP1 : SpecBase
DNAMP1::MLVL::Cook(out, in, world, btok); DNAMP1::MLVL::Cook(out, in, world, btok);
} }
void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, hecl::BlenderToken& btok,
FCookProgress progress)
{
ds.compileGuiFrame(out.getAbsolutePathUTF8(), 0);
}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
athena::io::IStreamReader& fin, FCookProgress progress) athena::io::IStreamReader& fin, FCookProgress progress)
{ {
@ -803,6 +813,13 @@ hecl::Database::DataSpecEntry SpecEntMP1PC =
} }
}; };
hecl::Database::DataSpecEntry SpecEntMP1ORIG =
{
_S("MP1-ORIG"),
_S("Data specification for unmodified Metroid Prime resources"),
{}
};
} }

View File

@ -17,6 +17,7 @@ namespace DataSpec
static logvisor::Module Log("urde::SpecMP2"); static logvisor::Module Log("urde::SpecMP2");
extern hecl::Database::DataSpecEntry SpecEntMP2; extern hecl::Database::DataSpecEntry SpecEntMP2;
extern hecl::Database::DataSpecEntry SpecEntMP2ORIG;
struct SpecMP2 : SpecBase struct SpecMP2 : SpecBase
{ {
@ -212,9 +213,6 @@ struct SpecMP2 : SpecBase
nod::ExtractionContext ctx = {true, force, nullptr}; nod::ExtractionContext ctx = {true, force, nullptr};
m_workPath.makeDir(); m_workPath.makeDir();
const hecl::ProjectPath& cookPath = m_project.getProjectCookedPath(SpecEntMP2);
cookPath.makeDir();
m_cookPath.makeDir();
progress(_S("Indexing PAKs"), _S(""), 2, 0.0); progress(_S("Indexing PAKs"), _S(""), 2, 0.0);
m_pakRouter.build(m_paks, [&progress](float factor) m_pakRouter.build(m_paks, [&progress](float factor)
@ -274,9 +272,14 @@ struct SpecMP2 : SpecBase
return true; return true;
} }
const hecl::Database::DataSpecEntry* getOriginalSpec() const const hecl::Database::DataSpecEntry& getOriginalSpec() const
{ {
return &SpecEntMP2; return SpecEntMP2;
}
const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const
{
return SpecEntMP2ORIG;
} }
hecl::ProjectPath getWorking(class UniqueID32& id) hecl::ProjectPath getWorking(class UniqueID32& id)
@ -334,6 +337,12 @@ struct SpecMP2 : SpecBase
{ {
} }
void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
athena::io::IStreamReader& fin, FCookProgress progress) athena::io::IStreamReader& fin, FCookProgress progress)
{ {
@ -379,4 +388,11 @@ hecl::Database::DataSpecEntry SpecEntMP2PC =
} }
}; };
hecl::Database::DataSpecEntry SpecEntMP2ORIG =
{
_S("MP2-ORIG"),
_S("Data specification for unmodified Metroid Prime 2 resources"),
{}
};
} }

View File

@ -17,6 +17,7 @@ namespace DataSpec
static logvisor::Module Log("urde::SpecMP3"); static logvisor::Module Log("urde::SpecMP3");
extern hecl::Database::DataSpecEntry SpecEntMP3; extern hecl::Database::DataSpecEntry SpecEntMP3;
extern hecl::Database::DataSpecEntry SpecEntMP3ORIG;
struct SpecMP3 : SpecBase struct SpecMP3 : SpecBase
{ {
@ -340,9 +341,6 @@ struct SpecMP3 : SpecBase
if (doMP3) if (doMP3)
{ {
m_workPath.makeDir(); m_workPath.makeDir();
const hecl::ProjectPath& cookPath = m_project.getProjectCookedPath(SpecEntMP3);
cookPath.makeDir();
m_cookPath.makeDir();
progress(_S("Indexing PAKs"), _S(""), compIdx, 0.0); progress(_S("Indexing PAKs"), _S(""), compIdx, 0.0);
m_pakRouter.build(m_paks, [&progress, &compIdx](float factor) m_pakRouter.build(m_paks, [&progress, &compIdx](float factor)
@ -404,9 +402,6 @@ struct SpecMP3 : SpecBase
if (doMPTFE) if (doMPTFE)
{ {
m_feWorkPath.makeDir(); m_feWorkPath.makeDir();
const hecl::ProjectPath& cookPath = m_project.getProjectCookedPath(SpecEntMP3);
cookPath.makeDir();
m_feCookPath.makeDir();
progress(_S("Indexing PAKs"), _S(""), compIdx, 0.0); progress(_S("Indexing PAKs"), _S(""), compIdx, 0.0);
m_fePakRouter.build(m_fePaks, [&progress, &compIdx](float factor) m_fePakRouter.build(m_fePaks, [&progress, &compIdx](float factor)
@ -465,9 +460,14 @@ struct SpecMP3 : SpecBase
return true; return true;
} }
const hecl::Database::DataSpecEntry* getOriginalSpec() const const hecl::Database::DataSpecEntry& getOriginalSpec() const
{ {
return &SpecEntMP3; return SpecEntMP3;
}
const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const
{
return SpecEntMP3ORIG;
} }
hecl::ProjectPath getWorking(class UniqueID64& id) hecl::ProjectPath getWorking(class UniqueID64& id)
@ -520,6 +520,12 @@ struct SpecMP3 : SpecBase
{ {
} }
void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
athena::io::IStreamReader& fin, FCookProgress progress) athena::io::IStreamReader& fin, FCookProgress progress)
{ {
@ -561,4 +567,11 @@ hecl::Database::DataSpecEntry SpecEntMP3PC =
} }
}; };
hecl::Database::DataSpecEntry SpecEntMP3ORIG =
{
_S("MP3-ORIG"),
_S("Data specification for unmodified Metroid Prime 3 resources"),
{}
};
} }

View File

@ -17,6 +17,7 @@
#include "World/CWorldTransManager.hpp" #include "World/CWorldTransManager.hpp"
#include "Graphics/Shaders/CColoredQuadFilter.hpp" #include "Graphics/Shaders/CColoredQuadFilter.hpp"
#include "Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Graphics/Shaders/CTexturedQuadFilter.hpp"
#include "Audio/CStreamAudioManager.hpp"
#include <cstdio> #include <cstdio>
using YAMLNode = athena::io::YAMLNode; using YAMLNode = athena::io::YAMLNode;
@ -69,8 +70,11 @@ void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
m_videoVoice->start(); m_videoVoice->start();
#endif #endif
m_newAudioPlayer.emplace(*m_voiceEngine, "Audio/frontend_1.rsf", 416480, 1973664); //m_newAudioPlayer.emplace(*m_voiceEngine, "Audio/frontend_1.rsf", 416480, 1973664);
m_newAudioPlayer->StartMixing(); //m_newAudioPlayer->StartMixing();
// Test DSP streaming
CStreamAudioManager::Start(false, "Audio/rui_samusL.dsp|Audio/rui_samusR.dsp", 0x7f, true, 1.f, 1.f);
//m_rootView->accessContentViews().clear(); //m_rootView->accessContentViews().clear();
m_rootView->accessContentViews().push_back(m_particleView.get()); m_rootView->accessContentViews().push_back(m_particleView.get());

View File

@ -20,7 +20,7 @@ CIOWin::EMessageReturn CAudioStateWin::OnMessage(const CArchitectureMessage& msg
else if (msgType == EArchMsgType::QuitGameplay) else if (msgType == EArchMsgType::QuitGameplay)
{ {
if (g_GameState->GetWorldTransitionManager()->GetTransType() == CWorldTransManager::ETransType::Disabled || if (g_GameState->GetWorldTransitionManager()->GetTransType() == CWorldTransManager::ETransType::Disabled ||
g_Main->GetFlowState() != IMain::EFlowState::Zero) g_Main->GetFlowState() != EFlowState::Zero)
{ {
CSfxManager::SetChannel(CSfxManager::ESfxChannels::Zero); CSfxManager::SetChannel(CSfxManager::ESfxChannels::Zero);
CSfxManager::KillAll(CSfxManager::ESfxChannels::One); CSfxManager::KillAll(CSfxManager::ESfxChannels::One);

View File

@ -269,6 +269,8 @@ struct SDSPStream
continue; continue;
stream.x0_active = true; stream.x0_active = true;
stream.x4_ownerId = ++s_HandleCounter2; stream.x4_ownerId = ++s_HandleCounter2;
if (stream.x4_ownerId == -1)
stream.x4_ownerId = ++s_HandleCounter2;
stream.x8_stereoLeft = nullptr; stream.x8_stereoLeft = nullptr;
stream.xc_stereoRight = nullptr; stream.xc_stereoRight = nullptr;
streamOut = &stream; streamOut = &stream;
@ -294,8 +296,9 @@ struct SDSPStream
if (!x0_active || xe8_silent) if (!x0_active || xe8_silent)
return; return;
float coefs[8] = {}; float coefs[8] = {};
coefs[int(boo::AudioChannel::FrontLeft)] = (0x7f - x4d_pan) / 127.f; float fvol = x4c_vol / 127.f;
coefs[int(boo::AudioChannel::FrontRight)] = x4d_pan / 127.f; coefs[int(boo::AudioChannel::FrontLeft)] = ((0x7f - x4d_pan) / 127.f) * fvol;
coefs[int(boo::AudioChannel::FrontRight)] = (x4d_pan / 127.f) * fvol;
m_booVoice->setMonoChannelLevels(nullptr, coefs, true); m_booVoice->setMonoChannelLevels(nullptr, coefs, true);
} }
@ -406,6 +409,7 @@ struct SDSPStream
xd8_ringBytes = 0x11DC0; xd8_ringBytes = 0x11DC0;
xdc_ringSamples = 0x1f410; xdc_ringSamples = 0x1f410;
memset(xd4_ringBuffer.get(), 0, 0x11DC0); memset(xd4_ringBuffer.get(), 0, 0x11DC0);
m_booVoice->resetSampleRate(info.x4_sampleRate);
m_booVoice->start(); m_booVoice->start();
} }
@ -461,7 +465,7 @@ public:
x70_24_unclaimed = true; x70_24_unclaimed = true;
} }
static u32 FindUnlaimedStreamIdx() static u32 FindUnclaimedStreamIdx()
{ {
for (int i=0 ; i<4 ; ++i) for (int i=0 ; i<4 ; ++i)
{ {
@ -474,7 +478,7 @@ public:
static bool FindUnclaimedStereoPair(u32& left, u32& right) static bool FindUnclaimedStereoPair(u32& left, u32& right)
{ {
u32 idx = FindUnlaimedStreamIdx(); u32 idx = FindUnclaimedStreamIdx();
for (u32 i=0 ; i<4 ; ++i) for (u32 i=0 ; i<4 ; ++i)
{ {
@ -646,13 +650,16 @@ public:
(companionStream.x71_companionRight != selfIdx && (companionStream.x71_companionRight != selfIdx &&
companionStream.x72_companionLeft != selfIdx)) companionStream.x72_companionLeft != selfIdx))
{ {
/* No consistent companion available */
*this = CDSPStreamManager(); *this = CDSPStreamManager();
return; return;
} }
/* Companion is pending; its completion will continue */
if (companionStream.x70_26_headerReadState == 1) if (companionStream.x70_26_headerReadState == 1)
return; return;
/* Use whichever stream is the left channel */
if (companionStream.x71_companionRight != -1) if (companionStream.x71_companionRight != -1)
AllocateStream(companion); AllocateStream(companion);
else else
@ -674,10 +681,10 @@ public:
if (!file) if (!file)
return false; return false;
stream.x70_26_headerReadState = 1;
stream.m_dvdReq = file.AsyncRead(&stream.x0_header, sizeof(dspadpcm_header), stream.m_dvdReq = file.AsyncRead(&stream.x0_header, sizeof(dspadpcm_header),
std::bind(&CDSPStreamManager::HeaderReadComplete, &stream, std::bind(&CDSPStreamManager::HeaderReadComplete, &stream,
std::placeholders::_1)); std::placeholders::_1));
stream.x70_26_headerReadState = 1;
return true; return true;
} }
@ -694,7 +701,7 @@ public:
if (pipePos == std::string::npos) if (pipePos == std::string::npos)
{ {
/* Mono stream */ /* Mono stream */
u32 idx = FindUnlaimedStreamIdx(); u32 idx = FindUnclaimedStreamIdx();
if (idx == -1) if (idx == -1)
return -1; return -1;

View File

@ -36,21 +36,19 @@ enum class EArchMsgType
struct IArchMsgParm struct IArchMsgParm
{ {
virtual ~IArchMsgParm() {} virtual ~IArchMsgParm() = default;
}; };
struct CArchMsgParmInt32 : IArchMsgParm struct CArchMsgParmInt32 : IArchMsgParm
{ {
u32 x4_parm; u32 x4_parm;
CArchMsgParmInt32(u32 parm) : x4_parm(parm) {} CArchMsgParmInt32(u32 parm) : x4_parm(parm) {}
virtual ~CArchMsgParmInt32() {}
}; };
struct CArchMsgParmVoidPtr : IArchMsgParm struct CArchMsgParmVoidPtr : IArchMsgParm
{ {
void* x4_parm1; void* x4_parm1;
CArchMsgParmVoidPtr(void* parm1) : x4_parm1(parm1) {} CArchMsgParmVoidPtr(void* parm1) : x4_parm1(parm1) {}
virtual ~CArchMsgParmVoidPtr() {}
}; };
struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm
@ -58,29 +56,33 @@ struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm
u32 x4_parm1; u32 x4_parm1;
u32 x8_parm2; u32 x8_parm2;
void* xc_parm3; void* xc_parm3;
CArchMsgParmInt32Int32VoidPtr(u32 parm1, u32 parm2, void* parm3) : x4_parm1(parm1), x8_parm2(parm2), xc_parm3(parm3) CArchMsgParmInt32Int32VoidPtr(u32 parm1, u32 parm2, void* parm3)
{ : x4_parm1(parm1), x8_parm2(parm2), xc_parm3(parm3) {}
} };
virtual ~CArchMsgParmInt32Int32VoidPtr() {}
struct CArchMsgParmInt32Int32IOWin : IArchMsgParm
{
u32 x4_parm1;
u32 x8_parm2;
std::shared_ptr<CIOWin> xc_parm3;
CArchMsgParmInt32Int32IOWin(u32 parm1, u32 parm2, std::shared_ptr<CIOWin>&& parm3)
: x4_parm1(parm1), x8_parm2(parm2), xc_parm3(std::move(parm3)) {}
}; };
struct CArchMsgParmNull : IArchMsgParm struct CArchMsgParmNull : IArchMsgParm
{ {
virtual ~CArchMsgParmNull() {}
}; };
struct CArchMsgParmReal32 : IArchMsgParm struct CArchMsgParmReal32 : IArchMsgParm
{ {
float x4_parm; float x4_parm;
CArchMsgParmReal32(float parm) : x4_parm(parm) {} CArchMsgParmReal32(float parm) : x4_parm(parm) {}
virtual ~CArchMsgParmReal32() {}
}; };
struct CArchMsgParmUserInput : IArchMsgParm struct CArchMsgParmUserInput : IArchMsgParm
{ {
CFinalInput x4_parm; CFinalInput x4_parm;
CArchMsgParmUserInput(const CFinalInput& parm) : x4_parm(parm) {} CArchMsgParmUserInput(const CFinalInput& parm) : x4_parm(parm) {}
virtual ~CArchMsgParmUserInput() {}
}; };
struct CArchMsgParmControllerStatus : IArchMsgParm struct CArchMsgParmControllerStatus : IArchMsgParm
@ -88,8 +90,6 @@ struct CArchMsgParmControllerStatus : IArchMsgParm
u16 x4_parm1; u16 x4_parm1;
bool x6_parm2; bool x6_parm2;
CArchMsgParmControllerStatus(u16 a, bool b) : x4_parm1(a), x6_parm2(b) {} CArchMsgParmControllerStatus(u16 a, bool b) : x4_parm1(a), x6_parm2(b) {}
virtual ~CArchMsgParmControllerStatus() {}
}; };
class CArchitectureMessage class CArchitectureMessage
@ -99,10 +99,9 @@ class CArchitectureMessage
std::shared_ptr<IArchMsgParm> x8_parm; std::shared_ptr<IArchMsgParm> x8_parm;
public: public:
CArchitectureMessage(EArchMsgTarget target, EArchMsgType type, IArchMsgParm* parm) CArchitectureMessage(EArchMsgTarget target, EArchMsgType type,
: x0_target(target), x4_type(type), x8_parm(parm) std::shared_ptr<IArchMsgParm>&& parm)
{ : x0_target(target), x4_type(type), x8_parm(std::move(parm)) {}
}
EArchMsgTarget GetTarget() const { return x0_target; } EArchMsgTarget GetTarget() const { return x0_target; }
EArchMsgType GetType() const { return x4_type; } EArchMsgType GetType() const { return x4_type; }
@ -118,11 +117,13 @@ class MakeMsg
public: public:
static CArchitectureMessage CreateQuitGameplay(EArchMsgTarget target) static CArchitectureMessage CreateQuitGameplay(EArchMsgTarget target)
{ {
return CArchitectureMessage(target, EArchMsgType::QuitGameplay, new CArchMsgParmNull()); return CArchitectureMessage(target, EArchMsgType::QuitGameplay,
std::make_shared<CArchMsgParmNull>());
} }
static CArchitectureMessage CreateControllerStatus(EArchMsgTarget target, u16 a, bool b) static CArchitectureMessage CreateControllerStatus(EArchMsgTarget target, u16 a, bool b)
{ {
return CArchitectureMessage(target, EArchMsgType::ControllerStatus, new CArchMsgParmControllerStatus(a, b)); return CArchitectureMessage(target, EArchMsgType::ControllerStatus,
std::make_shared<CArchMsgParmControllerStatus>(a, b));
} }
static const CArchMsgParmInt32& GetParmNewGameflowState(const CArchitectureMessage& msg) static const CArchMsgParmInt32& GetParmNewGameflowState(const CArchitectureMessage& msg)
{ {
@ -134,7 +135,8 @@ public:
} }
static CArchitectureMessage CreateUserInput(EArchMsgTarget target, const CFinalInput& input) static CArchitectureMessage CreateUserInput(EArchMsgTarget target, const CFinalInput& input)
{ {
return CArchitectureMessage(target, EArchMsgType::UserInput, new CArchMsgParmUserInput(input)); return CArchitectureMessage(target, EArchMsgType::UserInput,
std::make_shared<CArchMsgParmUserInput>(input));
} }
static const CArchMsgParmReal32& GetParmTimerTick(const CArchitectureMessage& msg) static const CArchMsgParmReal32& GetParmTimerTick(const CArchitectureMessage& msg)
{ {
@ -142,20 +144,22 @@ public:
} }
static CArchitectureMessage CreateTimerTick(EArchMsgTarget target, float val) static CArchitectureMessage CreateTimerTick(EArchMsgTarget target, float val)
{ {
return CArchitectureMessage(target, EArchMsgType::TimerTick, new CArchMsgParmReal32(val)); return CArchitectureMessage(target, EArchMsgType::TimerTick,
std::make_shared<CArchMsgParmReal32>(val));
} }
static const CArchMsgParmInt32Int32VoidPtr& GetParmChangeIOWinPriority(const CArchitectureMessage& msg) static const CArchMsgParmInt32Int32VoidPtr& GetParmChangeIOWinPriority(const CArchitectureMessage& msg)
{ {
return *msg.GetParm<CArchMsgParmInt32Int32VoidPtr>(); return *msg.GetParm<CArchMsgParmInt32Int32VoidPtr>();
} }
static const CArchMsgParmInt32Int32VoidPtr& GetParmCreateIOWin(const CArchitectureMessage& msg) static const CArchMsgParmInt32Int32IOWin& GetParmCreateIOWin(const CArchitectureMessage& msg)
{ {
return *msg.GetParm<CArchMsgParmInt32Int32VoidPtr>(); return *msg.GetParm<CArchMsgParmInt32Int32IOWin>();
} }
static CArchitectureMessage CreateCreateIOWin(EArchMsgTarget target, int pmin, int pmax, CIOWin* iowin) static CArchitectureMessage CreateCreateIOWin(EArchMsgTarget target, int pmin, int pmax,
std::shared_ptr<CIOWin>&& iowin)
{ {
return CArchitectureMessage(target, EArchMsgType::CreateIOWin, return CArchitectureMessage(target, EArchMsgType::CreateIOWin,
new CArchMsgParmInt32Int32VoidPtr(pmin, pmax, iowin)); std::make_shared<CArchMsgParmInt32Int32IOWin>(pmin, pmax, std::move(iowin)));
} }
static const CArchMsgParmVoidPtr& GetParmDeleteIOWin(const CArchitectureMessage& msg) static const CArchMsgParmVoidPtr& GetParmDeleteIOWin(const CArchitectureMessage& msg)
{ {
@ -163,12 +167,14 @@ public:
} }
static CArchitectureMessage CreateFrameBegin(EArchMsgTarget target, const int& a) static CArchitectureMessage CreateFrameBegin(EArchMsgTarget target, const int& a)
{ {
return CArchitectureMessage(target, EArchMsgType::FrameBegin, new CArchMsgParmInt32(a)); return CArchitectureMessage(target, EArchMsgType::FrameBegin,
std::make_shared<CArchMsgParmInt32>(a));
} }
/* URDE Messages */ /* URDE Messages */
static CArchitectureMessage CreateApplicationExit(EArchMsgTarget target) static CArchitectureMessage CreateApplicationExit(EArchMsgTarget target)
{ {
return CArchitectureMessage(target, EArchMsgType::ApplicationExit, new CArchMsgParmNull()); return CArchitectureMessage(target, EArchMsgType::ApplicationExit,
std::make_shared<CArchMsgParmNull>());
} }
}; };
} }

View File

@ -72,6 +72,7 @@ bool CDvdFile::m_WorkerRun = false;
std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue; std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue;
void CDvdFile::WorkerProc() void CDvdFile::WorkerProc()
{ {
logvisor::RegisterThreadName("CDvdFile Thread");
while (m_WorkerRun) while (m_WorkerRun)
{ {
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
@ -87,6 +88,7 @@ void CDvdFile::WorkerProc()
concreteReq.DoRequest(); concreteReq.DoRequest();
} }
waitlk.unlock(); waitlk.unlock();
swapQueue.clear();
lk.lock(); lk.lock();
} }
if (!m_WorkerRun) if (!m_WorkerRun)

View File

@ -376,7 +376,7 @@ void CGameOptions::EnsureSettings()
SetSfxVolume(x58_sfxVol, true); SetSfxVolume(x58_sfxVol, true);
SetMusicVolume(x5c_musicVol, true); SetMusicVolume(x5c_musicVol, true);
SetSurroundMode(int(x44_soundMode), true); SetSurroundMode(int(x44_soundMode), true);
SetHUDAlpha(x60_hudAlpha); SetHelmetAlpha(x64_helmetAlpha);
SetHUDLag(x68_24_hudLag); SetHUDLag(x68_24_hudLag);
SetInvertYAxis(x68_25_invertY); SetInvertYAxis(x68_25_invertY);
SetIsRumbleEnabled(x68_26_rumble); SetIsRumbleEnabled(x68_26_rumble);

View File

@ -24,13 +24,13 @@ public:
RemoveIOWin = 3 RemoveIOWin = 3
}; };
virtual ~CIOWin() {} virtual ~CIOWin() {}
CIOWin(const char* name) : x4_name(name) {m_nameHash = std::hash<std::string>()(x4_name);} CIOWin(const char* name) : x4_name(name) { m_nameHash = std::hash<std::string>()(x4_name); }
virtual EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&)=0; virtual EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&)=0;
virtual bool GetIsContinueDraw() const {return true;} virtual bool GetIsContinueDraw() const { return true; }
virtual void Draw() const {} virtual void Draw() const {}
virtual void PreDraw() const {} virtual void PreDraw() const {}
const std::string& GetName() const {return x4_name;} const std::string& GetName() const { return x4_name; }
size_t GetNameHash() const {return m_nameHash;} size_t GetNameHash() const { return m_nameHash; }
}; };
static bool operator==(std::shared_ptr<CIOWin> a, std::shared_ptr<CIOWin> b) static bool operator==(std::shared_ptr<CIOWin> a, std::shared_ptr<CIOWin> b)

View File

@ -19,9 +19,8 @@ bool CIOWinManager::OnIOWinMessage(const CArchitectureMessage& msg)
} }
case EArchMsgType::CreateIOWin: case EArchMsgType::CreateIOWin:
{ {
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmCreateIOWin(msg); const CArchMsgParmInt32Int32IOWin& parm = MakeMsg::GetParmCreateIOWin(msg);
std::shared_ptr<CIOWin> iow(static_cast<CIOWin*>(parm.xc_parm3)); AddIOWin(parm.xc_parm3, parm.x4_parm1, parm.x8_parm2);
AddIOWin(iow, parm.x4_parm1, parm.x8_parm2);
return false; return false;
} }
case EArchMsgType::ChangeIOWinPriority: case EArchMsgType::ChangeIOWinPriority:

View File

@ -9,10 +9,10 @@ namespace urde
enum class EClientFlowStates enum class EClientFlowStates
{ {
Unspecified = -1, Unspecified = -1,
FrontEnd = 7, PreFrontEnd = 7,
StateLoad = 8, FrontEnd = 8,
GameLoad = 13, Game = 14,
MoviePlay = 14 GameExit = 15
}; };
class CMainFlowBase : public CIOWin class CMainFlowBase : public CIOWin

View File

@ -41,7 +41,7 @@ CIOWin::EMessageReturn CSplashScreen::OnMessage(const CArchitectureMessage& msg,
{ {
if (x14_which != ESplashScreen::Retro) if (x14_which != ESplashScreen::Retro)
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 9999, 9999, queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 9999, 9999,
new CSplashScreen(ESplashScreen(int(x14_which) + 1)))); std::make_shared<CSplashScreen>(ESplashScreen(int(x14_which) + 1))));
return EMessageReturn::RemoveIOWinAndExit; return EMessageReturn::RemoveIOWinAndExit;
} }
break; break;

View File

@ -18,20 +18,21 @@ enum class EGameplayResult
Playing Playing
}; };
enum class EFlowState
{
Zero,
One,
Two,
Three,
Four,
Five,
Six,
};
class IMain class IMain
{ {
public: public:
enum class EFlowState virtual ~IMain() = default;
{
Zero,
One,
Two,
Three,
Four,
Five,
Six,
};
virtual void RegisterResourceTweaks() {} virtual void RegisterResourceTweaks() {}
virtual void ResetGameState()=0; virtual void ResetGameState()=0;
virtual void StreamNewGameState(CBitStreamReader&, u32 idx) {} virtual void StreamNewGameState(CBitStreamReader&, u32 idx) {}
@ -51,6 +52,7 @@ public:
virtual void ShutdownSubsystems()=0; virtual void ShutdownSubsystems()=0;
virtual EGameplayResult GetGameplayResult() const=0; virtual EGameplayResult GetGameplayResult() const=0;
virtual void SetGameplayResult(EGameplayResult wl)=0; virtual void SetGameplayResult(EGameplayResult wl)=0;
virtual void SetFlowState(EFlowState s)=0;
virtual EFlowState GetFlowState() const=0; virtual EFlowState GetFlowState() const=0;
}; };
} }

View File

@ -18,10 +18,5 @@ CBeetle::CBeetle(TUniqueId uid, const std::string& name, const CEntityInfo& info
} }
void CBeetle::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
} }
} }

View File

@ -23,8 +23,6 @@ public:
const CPatternedInfo&, CPatterned::EFlavorType,EEntranceType, const CDamageInfo &, const CDamageVulnerability&, const CPatternedInfo&, CPatterned::EFlavorType,EEntranceType, const CDamageInfo &, const CDamageVulnerability&,
const zeus::CVector3f&, float, float, float, const CDamageVulnerability&, const CActorParameters&, const zeus::CVector3f&, float, float, float, const CDamageVulnerability&, const CActorParameters&,
const rstl::optional_object<CStaticRes>); const rstl::optional_object<CStaticRes>);
void Accept(IVisitor& visitor);
}; };
} }
} }

25
Runtime/MP1/CCredits.cpp Normal file
View File

@ -0,0 +1,25 @@
#include "CCredits.hpp"
namespace urde
{
namespace MP1
{
CCredits::CCredits()
: CIOWin("Credits")
{
}
CIOWin::EMessageReturn CCredits::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue)
{
return EMessageReturn::Normal;
}
void CCredits::Draw() const
{
}
}
}

23
Runtime/MP1/CCredits.hpp Normal file
View File

@ -0,0 +1,23 @@
#ifndef __URDE_MP1_CCREDITS_HPP__
#define __URDE_MP1_CCREDITS_HPP__
#include "CIOWin.hpp"
namespace urde
{
namespace MP1
{
class CCredits : public CIOWin
{
public:
CCredits();
EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&);
bool GetIsContinueDraw() const { return false; }
void Draw() const;
};
}
}
#endif // __URDE_MP1_CCREDITS_HPP__

View File

@ -1715,7 +1715,7 @@ void CFrontEndUI::SOptionsFrontEndFrame::Draw() const
} }
} }
CFrontEndUI::CFrontEndUI(CArchitectureQueue& queue) CFrontEndUI::CFrontEndUI()
: CIOWin("FrontEndUI") : CIOWin("FrontEndUI")
{ {
x18_rndA = std::min(rand() * 3 / RAND_MAX, 2); x18_rndA = std::min(rand() * 3 / RAND_MAX, 2);
@ -1735,7 +1735,8 @@ CFrontEndUI::CFrontEndUI(CArchitectureQueue& queue)
void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue) void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue)
{ {
xf4_curAudio->StopMixing(); xf4_curAudio->StopMixing();
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11, new CSlideShow())); queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11,
std::make_shared<CSlideShow>()));
} }
std::string CFrontEndUI::GetAttractMovieFileName(int idx) std::string CFrontEndUI::GetAttractMovieFileName(int idx)

View File

@ -426,7 +426,7 @@ private:
bool PumpLoad(); bool PumpLoad();
public: public:
CFrontEndUI(CArchitectureQueue& queue); CFrontEndUI();
void StartSlideShow(CArchitectureQueue& queue); void StartSlideShow(CArchitectureQueue& queue);
std::string GetAttractMovieFileName(int idx); std::string GetAttractMovieFileName(int idx);
std::string GetNextAttractMovieFileName(); std::string GetNextAttractMovieFileName();

View File

@ -33,8 +33,8 @@ CMFGameLoader::CMFGameLoader() : CMFGameLoaderBase("CMFGameLoader")
{ {
switch (g_Main->GetFlowState()) switch (g_Main->GetFlowState())
{ {
case CMain::EFlowState::Five: case EFlowState::Five:
case CMain::EFlowState::Six: case EFlowState::Six:
{ {
ResId mlvlId = g_GameState->CurrentWorldAssetId(); ResId mlvlId = g_GameState->CurrentWorldAssetId();
// g_GameState->WorldTransitionManager()-> // g_GameState->WorldTransitionManager()->

View File

@ -7,6 +7,12 @@
#include "CFrontEndUI.hpp" #include "CFrontEndUI.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include "Character/CCharLayoutInfo.hpp" #include "Character/CCharLayoutInfo.hpp"
#include "CSaveUI.hpp"
#include "CCredits.hpp"
#include "CPreFrontEnd.hpp"
#include "CStateSetterFlow.hpp"
#include "CNESEmulator.hpp"
#include "CQuitScreen.hpp"
namespace urde namespace urde
{ {
@ -17,61 +23,90 @@ void CMainFlow::AdvanceGameState(CArchitectureQueue& queue)
{ {
switch (x14_gameState) switch (x14_gameState)
{ {
case EClientFlowStates::Unspecified: case EClientFlowStates::Game:
CMainFlow::SetGameState(EClientFlowStates::GameExit, queue);
break;
case EClientFlowStates::PreFrontEnd:
CMainFlow::SetGameState(EClientFlowStates::FrontEnd, queue); CMainFlow::SetGameState(EClientFlowStates::FrontEnd, queue);
break; break;
case EClientFlowStates::FrontEnd: case EClientFlowStates::FrontEnd:
CMainFlow::SetGameState(EClientFlowStates::GameLoad, queue); CMainFlow::SetGameState(EClientFlowStates::Game, queue);
break; break;
case EClientFlowStates::GameLoad: case EClientFlowStates::GameExit:
CMainFlow::SetGameState(EClientFlowStates::MoviePlay, queue); {
break; MP1::CMain* main = static_cast<MP1::CMain*>(g_Main);
case EClientFlowStates::MoviePlay: if (main->GetFlowState() != EFlowState::Zero &&
CMainFlow::SetGameState(EClientFlowStates::FrontEnd, queue); main->GetFlowState() != EFlowState::Six)
main->SetX30(true);
}
case EClientFlowStates::Unspecified:
CMainFlow::SetGameState(EClientFlowStates::PreFrontEnd, queue);
break; break;
} }
} }
void CMainFlow::SetGameState(EClientFlowStates state, CArchitectureQueue& queue) void CMainFlow::SetGameState(EClientFlowStates state, CArchitectureQueue& queue)
{ {
x14_gameState = state;
MP1::CMain* main = static_cast<MP1::CMain*>(g_Main);
switch (state) switch (state)
{ {
case EClientFlowStates::FrontEnd: case EClientFlowStates::GameExit:
{ {
if (g_Main->GetGameplayResult() == EGameplayResult::None) switch (main->GetFlowState())
{ {
g_Main->SetGameplayResult(EGameplayResult::Playing); case EFlowState::One:
case EFlowState::Two:
case EFlowState::Three:
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11,
std::make_shared<CCredits>()));
break; break;
} case EFlowState::Four:
/* TODO: URDE handling queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11,
CResLoader& loader = g_ResFactory->GetLoader(); std::make_shared<CPlayMovie>(CPlayMovie::EWhichMovie::AfterCredits)));
while (!loader.AreAllPaksLoaded())
loader.AsyncIdlePakLoading();
*/
g_Main->LoadAudio();
g_Main->RegisterResourceTweaks();
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11, new CFrontEndUI(queue)));
break;
}
case EClientFlowStates::GameLoad:
{
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 10, 1000, new CMFGameLoader()));
break;
}
case EClientFlowStates::MoviePlay:
{
switch (g_Main->GetGameplayResult())
{
case EGameplayResult::Win:
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11, new CPlayMovie(CPlayMovie::EWhichMovie::WinGame)));
break;
case EGameplayResult::Lose:
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11, new CPlayMovie(CPlayMovie::EWhichMovie::LoseGame)));
break; break;
default: break; default: break;
} }
break; break;
} }
case EClientFlowStates::PreFrontEnd:
{
if (main->GetFlowState() == EFlowState::Zero)
return;
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11,
std::make_shared<CPreFrontEnd>()));
break;
}
case EClientFlowStates::FrontEnd:
{
std::shared_ptr<CIOWin> nextIOWin;
switch (main->GetFlowState())
{
case EFlowState::Six:
nextIOWin = std::make_shared<CStateSetterFlow>();
break;
case EFlowState::One:
case EFlowState::Two:
case EFlowState::Three:
case EFlowState::Four:
case EFlowState::Five:
nextIOWin = std::make_shared<CFrontEndUI>();
break;
default: return;
}
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 12, 11, std::move(nextIOWin)));
break;
}
case EClientFlowStates::Game:
{
g_GameState->GameOptions().EnsureSettings();
main->SetFlowState(EFlowState::Five);
queue.Push(MakeMsg::CreateCreateIOWin(EArchMsgTarget::IOWinManager, 10, 1000,
std::make_shared<CMFGameLoader>()));
break;
}
default: break; default: break;
} }
} }

View File

@ -11,6 +11,7 @@ set(MP1_SOURCES
CMFGame.hpp CMFGame.cpp CMFGame.hpp CMFGame.cpp
CPlayMovie.hpp CPlayMovie.cpp CPlayMovie.hpp CPlayMovie.cpp
CFrontEndUI.hpp CFrontEndUI.cpp CFrontEndUI.hpp CFrontEndUI.cpp
CPreFrontEnd.hpp CPreFrontEnd.cpp
CSlideShow.hpp CSlideShow.cpp CSlideShow.hpp CSlideShow.cpp
CNewIntroBoss.hpp CNewIntroBoss.cpp CNewIntroBoss.hpp CNewIntroBoss.cpp
CBeetle.hpp CBeetle.cpp CBeetle.hpp CBeetle.cpp
@ -20,6 +21,8 @@ set(MP1_SOURCES
CSaveUI.hpp CSaveUI.cpp CSaveUI.hpp CSaveUI.cpp
CMemoryCardDriver.hpp CMemoryCardDriver.cpp CMemoryCardDriver.hpp CMemoryCardDriver.cpp
CQuitScreen.hpp CQuitScreen.cpp CQuitScreen.hpp CQuitScreen.cpp
CCredits.hpp CCredits.cpp
CStateSetterFlow.hpp CStateSetterFlow.cpp
MP1.hpp MP1.cpp) MP1.hpp MP1.cpp)
runtime_add_list(MP1 MP1_SOURCES) runtime_add_list(MP1 MP1_SOURCES)

View File

@ -16,10 +16,5 @@ CNewIntroBoss::CNewIntroBoss(TUniqueId uid, const std::string& name, const CEnti
{ {
} }
void CNewIntroBoss::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
} }
} }

View File

@ -17,8 +17,6 @@ public:
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& actParms, float, u32, const CDamageInfo& dInfo, const CActorParameters& actParms, float, u32, const CDamageInfo& dInfo,
u32, u32, u32, u32); u32, u32, u32, u32);
void Accept(IVisitor& visitor);
}; };
} }

View File

@ -16,7 +16,9 @@ public:
enum class EWhichMovie enum class EWhichMovie
{ {
WinGame, WinGame,
LoseGame LoseGame,
Two,
AfterCredits
}; };
private: private:
EWhichMovie x14_which; EWhichMovie x14_which;

View File

@ -0,0 +1,20 @@
#include "CPreFrontEnd.hpp"
namespace urde
{
namespace MP1
{
CPreFrontEnd::CPreFrontEnd()
: CIOWin("Pre front-end window")
{
}
CIOWin::EMessageReturn CPreFrontEnd::OnMessage(const CArchitectureMessage&, CArchitectureQueue&)
{
return EMessageReturn::Normal;
}
}
}

View File

@ -0,0 +1,21 @@
#ifndef __URDE_MP1_CPREFRONTEND_HPP__
#define __URDE_MP1_CPREFRONTEND_HPP__
#include "CIOWin.hpp"
namespace urde
{
namespace MP1
{
class CPreFrontEnd : public CIOWin
{
public:
CPreFrontEnd();
EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&);
};
}
}
#endif // __URDE_MP1_CPREFRONTEND_HPP__

View File

@ -14,10 +14,5 @@ CSpacePirate::CSpacePirate(TUniqueId uid, const std::string& name, const CEntity
{ {
} }
void CSpacePirate::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
} }
} }

View File

@ -12,8 +12,6 @@ class CSpacePirate : public CPatterned
public: public:
CSpacePirate(TUniqueId, const std::string&, const CEntityInfo&, const zeus::CTransform&, CModelData&&, CSpacePirate(TUniqueId, const std::string&, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
const CActorParameters&, const CPatternedInfo&, CInputStream&, u32); const CActorParameters&, const CPatternedInfo&, CInputStream&, u32);
void Accept(IVisitor& visitor);
}; };
} }
} }

View File

@ -0,0 +1,20 @@
#include "CStateSetterFlow.hpp"
namespace urde
{
namespace MP1
{
CStateSetterFlow::CStateSetterFlow()
: CIOWin("")
{
}
CIOWin::EMessageReturn CStateSetterFlow::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue)
{
return EMessageReturn::Normal;
}
}
}

View File

@ -0,0 +1,21 @@
#ifndef __URDE_MP1_CSTATESETTERFLOW_HPP__
#define __URDE_MP1_CSTATESETTERFLOW_HPP__
#include "CIOWin.hpp"
namespace urde
{
namespace MP1
{
class CStateSetterFlow : public CIOWin
{
public:
CStateSetterFlow();
EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&);
};
}
}
#endif // __URDE_MP1_CSTATESETTERFLOW_HPP__

View File

@ -16,11 +16,6 @@ CWarWasp::CWarWasp(TUniqueId uid, const std::string& name, const CEntityInfo& in
} }
void CWarWasp::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
} }
} }

View File

@ -15,8 +15,6 @@ public:
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
CPatterned::EFlavorType flavor, CPatterned::EColliderType, const CDamageInfo& dInfo1, const CActorParameters&, CPatterned::EFlavorType flavor, CPatterned::EColliderType, const CDamageInfo& dInfo1, const CActorParameters&,
ResId weapon, const CDamageInfo& dInfo2, ResId particle, u32 w3); ResId weapon, const CDamageInfo& dInfo2, ResId particle, u32 w3);
void Accept(IVisitor& visitor);
}; };
} }
} }

View File

@ -265,6 +265,9 @@ public:
void SetCardBusy(bool v) { x160_31_cardBusy = v; } void SetCardBusy(bool v) { x160_31_cardBusy = v; }
EFlowState GetFlowState() const { return x12c_flowState; } EFlowState GetFlowState() const { return x12c_flowState; }
void SetFlowState(EFlowState s) { x12c_flowState = s; }
void SetX30(bool v) { x160_30_ = v; }
}; };
} }

View File

@ -62,13 +62,6 @@ CENTITY_TYPES = (
('CScriptDockAreaChange', 'World/CScriptDockAreaChange.hpp'), ('CScriptDockAreaChange', 'World/CScriptDockAreaChange.hpp'),
('CScriptSpecialFunction', 'World/CScriptSpecialFunction.hpp'), ('CScriptSpecialFunction', 'World/CScriptSpecialFunction.hpp'),
('CScriptDebris', 'World/CScriptDebris.hpp'), ('CScriptDebris', 'World/CScriptDebris.hpp'),
Namespace('MP1'),
('CBeetle', 'MP1/CBeetle.hpp', 'MP1'),
('CWarWasp', 'MP1/CWarWasp.hpp', 'MP1'),
('CSpacePirate', 'MP1/CSpacePirate.hpp', 'MP1'),
('CNewIntroBoss', 'MP1/CNewIntroBoss.hpp', 'MP1'),
EndNamespace(),
) )
def getqualified(tp): def getqualified(tp):

View File

@ -1,5 +1,6 @@
#include "CPatterned.hpp" #include "CPatterned.hpp"
#include "CPatternedInfo.hpp" #include "CPatternedInfo.hpp"
#include "TCastTo.hpp"
namespace urde namespace urde
{ {
@ -23,4 +24,10 @@ CPatterned::CPatterned(EUnknown, TUniqueId uid, const std::string& name, CPatter
pInfo.xfc_stateMachineId, actorParms, pInfo.xd8_stepUpHeight, 0.8f) pInfo.xfc_stateMachineId, actorParms, pInfo.xd8_stepUpHeight, 0.8f)
{ {
} }
void CPatterned::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
} }

View File

@ -41,6 +41,7 @@ public:
CPatterned::EMovementType movement, EColliderType collider, EBodyType body, CPatterned::EMovementType movement, EColliderType collider, EBodyType body,
const CActorParameters& params, bool b1); const CActorParameters& params, bool b1);
void Accept(IVisitor& visitor);
virtual void Death(const zeus::CVector3f&, CStateManager&) {} virtual void Death(const zeus::CVector3f&, CStateManager&) {}
virtual void KnockBack(const zeus::CVector3f&, CStateManager&) {} virtual void KnockBack(const zeus::CVector3f&, CStateManager&) {}
}; };

View File

@ -35,7 +35,7 @@ void CScriptStreamedMusic::TweakOverride(CStateManager& mgr)
const CWorld* wld = mgr.GetWorld(); const CWorld* wld = mgr.GetWorld();
const CGameArea* area = wld->GetAreaAlways(x4_areaId); const CGameArea* area = wld->GetAreaAlways(x4_areaId);
std::string twkName = hecl::Format("Area %8.8x MusicObject: %s", std::string twkName = hecl::Format("Area %8.8x MusicObject: %s",
area->GetAreaAssetId(), x10_name.c_str()); unsigned(area->GetAreaAssetId()), x10_name.c_str());
if (g_TweakManager->HasTweakValue(twkName)) if (g_TweakManager->HasTweakValue(twkName))
{ {
const CTweakValue::Audio& audio = g_TweakManager->GetTweakValue(twkName)->GetAudio(); const CTweakValue::Audio& audio = g_TweakManager->GetTweakValue(twkName)->GetAudio();

2
hecl

@ -1 +1 @@
Subproject commit 0c6a88a95af7a36cebda27f3c511ba585d195230 Subproject commit 146a96ad65a6fbfbf1d2c2f9077d6d530bf5a80d

2
nod

@ -1 +1 @@
Subproject commit 31a06ea7266abace21473488d5191cea8e6554d2 Subproject commit cf2f68f8b2f5869940426a5cdd12519538bb0c26

@ -1 +1 @@
Subproject commit e961af19ee4d69ef8e7f9cb912058b8397027973 Subproject commit 03e7124c5f576033c10ad2d0a116e4a331c0381d