diff --git a/DataSpec/DNACommon/BabeDead.hpp b/DataSpec/DNACommon/BabeDead.hpp index c9ecc7928..2882fa65a 100644 --- a/DataSpec/DNACommon/BabeDead.hpp +++ b/DataSpec/DNACommon/BabeDead.hpp @@ -49,6 +49,7 @@ void ReadBabeDeadLightToBlender(hecl::BlenderConnection::PyOutStream& os, os.format("lamp.retro_layer = %u\n" "lamp.retro_origtype = %u\n" + "lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n" "lamp.use_nodes = True\n" "falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n" "lamp.energy = 0.0\n" @@ -68,12 +69,15 @@ void ReadBabeDeadLightToBlender(hecl::BlenderConnection::PyOutStream& os, case BabeDeadLight::Falloff::Constant: os << "falloff_node.inputs[0].default_value *= 75.0\n" "lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n"; + os.format("lamp.constant_coefficient = 2.0 / %f\n", light.q); break; case BabeDeadLight::Falloff::Linear: os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n"; + os.format("lamp.linear_coefficient = 250 / %f\n", light.q); break; case BabeDeadLight::Falloff::Quadratic: os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n"; + os.format("lamp.quadratic_coefficient = 25000 / %f\n", light.q); break; default: break; } diff --git a/DataSpec/DNACommon/TXTR.cpp b/DataSpec/DNACommon/TXTR.cpp index 3d4bfe81b..a238934c7 100644 --- a/DataSpec/DNACommon/TXTR.cpp +++ b/DataSpec/DNACommon/TXTR.cpp @@ -32,19 +32,20 @@ static void BoxFilter(const uint8_t* input, unsigned chanCount, int y,x,c; for (y=0 ; y @@ -32,8 +33,8 @@ static const hecl::SystemChar* MomErr[] = }; constexpr uint32_t MomErrCount = std::extent::value; -SpecBase::SpecBase(hecl::Database::Project& project) -: m_project(project), +SpecBase::SpecBase(hecl::Database::Project& project, bool pc) +: m_project(project), m_pc(pc), m_masterShader(project.getProjectWorkingPath(), ".hecl/RetroMasterShader.blend") {} bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector& reps) @@ -139,6 +140,32 @@ bool SpecBase::canCook(const hecl::ProjectPath& path) return false; } +const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path, + const hecl::Database::DataSpecEntry* oldEntry) +{ + if (!checkPathPrefix(path)) + return nullptr; + if (hecl::IsPathBlend(path)) + { + hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection(); + if (!conn.openBlend(path)) + { + Log.report(logvisor::Error, _S("unable to cook '%s'"), + path.getAbsolutePath().c_str()); + return nullptr; + } + hecl::BlenderConnection::BlendType type = conn.getBlendType(); + if (type == hecl::BlenderConnection::BlendType::Mesh || + type == hecl::BlenderConnection::BlendType::Area) + return oldEntry; + } + else if (hecl::IsPathPNG(path)) + { + return oldEntry; + } + return getOriginalSpec(); +} + void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, FCookProgress progress) { @@ -171,6 +198,13 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co default: break; } } + else if (hecl::IsPathPNG(path)) + { + if (m_pc) + TXTR::CookPC(path, cookedPath); + else + TXTR::Cook(path, cookedPath); + } else if (hecl::IsPathYAML(path)) { FILE* fp = hecl::Fopen(path.getAbsolutePath().c_str(), _S("r")); diff --git a/DataSpec/SpecBase.hpp b/DataSpec/SpecBase.hpp index e08adb07e..11cb8e5c1 100644 --- a/DataSpec/SpecBase.hpp +++ b/DataSpec/SpecBase.hpp @@ -17,7 +17,10 @@ struct SpecBase : hecl::Database::IDataSpec void doExtract(const ExtractPassInfo& info, FProgress progress); bool canCook(const hecl::ProjectPath& path); - void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, FCookProgress progress); + const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path, + const hecl::Database::DataSpecEntry* oldEntry); + void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, + bool fast, FCookProgress progress); bool canPackage(const PackagePassInfo& info); void gatherDependencies(const PackagePassInfo& info, @@ -37,6 +40,9 @@ struct SpecBase : hecl::Database::IDataSpec virtual bool extractFromDisc(nod::DiscBase& disc, bool force, FProgress progress)=0; + /* Even if PC spec is being cooked, this will return the vanilla GCN spec */ + virtual const hecl::Database::DataSpecEntry* getOriginalSpec() const=0; + /* Basic path check (game directory matching) */ virtual bool checkPathPrefix(const hecl::ProjectPath& path)=0; @@ -48,10 +54,14 @@ struct SpecBase : hecl::Database::IDataSpec using Mesh = BlendStream::Mesh; using Actor = BlendStream::Actor; - virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, FCookProgress progress) const=0; - virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, FCookProgress progress) const=0; - virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, FCookProgress progress) const=0; - virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FILE* fin, FCookProgress progress) const=0; + virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, bool fast, FCookProgress progress) const=0; + virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, bool fast, FCookProgress progress) const=0; + virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, bool fast, FCookProgress progress) const=0; + virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + FILE* fin, FCookProgress progress) const=0; const hecl::ProjectPath& getMasterShaderPath() const {return m_masterShader;} @@ -62,9 +72,10 @@ struct SpecBase : hecl::Database::IDataSpec /* Project accessor */ hecl::Database::Project& getProject() const {return m_project;} - SpecBase(hecl::Database::Project& project); + SpecBase(hecl::Database::Project& project, bool pc); protected: hecl::Database::Project& m_project; + bool m_pc; hecl::ProjectPath m_masterShader; private: std::unique_ptr m_disc; diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index cf6525ce8..d8b07df44 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -33,8 +33,8 @@ struct SpecMP1 : SpecBase hecl::ProjectPath m_cookPath; PAKRouter m_pakRouter; - SpecMP1(hecl::Database::Project& project) - : SpecBase(project), + SpecMP1(hecl::Database::Project& project, bool pc) + : SpecBase(project, pc), m_workPath(project.getProjectWorkingPath(), _S("MP1")), m_cookPath(project.getProjectCookedPath(SpecEntMP1), _S("MP1")), m_pakRouter(*this, m_workPath, m_cookPath) {} @@ -213,6 +213,8 @@ struct SpecMP1 : SpecBase bool extractFromDisc(nod::DiscBase&, bool force, FProgress progress) { + m_project.enableDataSpecs({"MP1-PC"}); + nod::ExtractionContext ctx = {true, force, nullptr}; m_workPath.makeDir(); @@ -267,7 +269,12 @@ struct SpecMP1 : SpecBase return true; } - virtual hecl::ProjectPath getWorking(class UniqueID32& id) + const hecl::Database::DataSpecEntry* getOriginalSpec() const + { + return &SpecEntMP1; + } + + hecl::ProjectPath getWorking(class UniqueID32& id) { return m_pakRouter.getWorking(id); } @@ -320,15 +327,20 @@ hecl::Database::DataSpecEntry SpecEntMP1 = _S("MP1"), _S("Data specification for original Metroid Prime engine"), [](hecl::Database::Project& project, hecl::Database::DataSpecTool) - -> hecl::Database::IDataSpec* {return new struct SpecMP1(project);} + -> hecl::Database::IDataSpec* {return new struct SpecMP1(project, false);} }; hecl::Database::DataSpecEntry SpecEntMP1PC = { _S("MP1-PC"), _S("Data specification for PC-optimized Metroid Prime engine"), - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) - -> hecl::Database::IDataSpec* {return nullptr;} + [](hecl::Database::Project& project, hecl::Database::DataSpecTool tool) + -> hecl::Database::IDataSpec* + { + if (tool != hecl::Database::DataSpecTool::Extract) + return new struct SpecMP1(project, true); + return nullptr; + } }; } diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp index dff435142..0c28220aa 100644 --- a/DataSpec/SpecMP2.cpp +++ b/DataSpec/SpecMP2.cpp @@ -29,8 +29,8 @@ struct SpecMP2 : SpecBase hecl::ProjectPath m_cookPath; PAKRouter m_pakRouter; - SpecMP2(hecl::Database::Project& project) - : SpecBase(project), + SpecMP2(hecl::Database::Project& project, bool pc) + : SpecBase(project, pc), m_workPath(project.getProjectWorkingPath(), _S("MP2")), m_cookPath(project.getProjectCookedPath(SpecEntMP2), _S("MP2")), m_pakRouter(*this, m_workPath, m_cookPath) {} @@ -257,7 +257,12 @@ struct SpecMP2 : SpecBase return true; } - virtual hecl::ProjectPath getWorking(class UniqueID32& id) + const hecl::Database::DataSpecEntry* getOriginalSpec() const + { + return &SpecEntMP2; + } + + hecl::ProjectPath getWorking(class UniqueID32& id) { return m_pakRouter.getWorking(id); } @@ -302,15 +307,20 @@ hecl::Database::DataSpecEntry SpecEntMP2 _S("MP2"), _S("Data specification for original Metroid Prime 2 engine"), [](hecl::Database::Project& project, hecl::Database::DataSpecTool) - -> hecl::Database::IDataSpec* {return new struct SpecMP2(project);} + -> hecl::Database::IDataSpec* {return new struct SpecMP2(project, false);} ); hecl::Database::DataSpecEntry SpecEntMP2PC = { _S("MP2-PC"), _S("Data specification for PC-optimized Metroid Prime 2 engine"), - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) - -> hecl::Database::IDataSpec* {return nullptr;} + [](hecl::Database::Project& project, hecl::Database::DataSpecTool tool) + -> hecl::Database::IDataSpec* + { + if (tool != hecl::Database::DataSpecTool::Extract) + return new struct SpecMP2(project, true); + return nullptr; + } }; } diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp index ce6c1b6c6..02f318d17 100644 --- a/DataSpec/SpecMP3.cpp +++ b/DataSpec/SpecMP3.cpp @@ -42,8 +42,8 @@ struct SpecMP3 : SpecBase hecl::ProjectPath m_feCookPath; PAKRouter m_fePakRouter; - SpecMP3(hecl::Database::Project& project) - : SpecBase(project), + SpecMP3(hecl::Database::Project& project, bool pc) + : SpecBase(project, pc), m_workPath(project.getProjectWorkingPath(), _S("MP3")), m_cookPath(project.getProjectCookedPath(SpecEntMP3), _S("MP3")), m_pakRouter(*this, m_workPath, m_cookPath), @@ -439,7 +439,12 @@ struct SpecMP3 : SpecBase return true; } - virtual hecl::ProjectPath getWorking(class UniqueID64& id) + const hecl::Database::DataSpecEntry* getOriginalSpec() const + { + return &SpecEntMP3; + } + + hecl::ProjectPath getWorking(class UniqueID64& id) { return m_pakRouter.getWorking(id); } @@ -486,15 +491,20 @@ hecl::Database::DataSpecEntry SpecEntMP3 _S("MP3"), _S("Data specification for original Metroid Prime 3 engine"), [](hecl::Database::Project& project, hecl::Database::DataSpecTool) - -> hecl::Database::IDataSpec* {return new struct SpecMP3(project);} + -> hecl::Database::IDataSpec* {return new struct SpecMP3(project, false);} ); hecl::Database::DataSpecEntry SpecEntMP3PC = { _S("MP3-PC"), _S("Data specification for PC-optimized Metroid Prime 3 engine"), - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) - -> hecl::Database::IDataSpec* {return nullptr;} + [](hecl::Database::Project& project, hecl::Database::DataSpecTool tool) + -> hecl::Database::IDataSpec* + { + if (tool != hecl::Database::DataSpecTool::Extract) + return new struct SpecMP3(project, true); + return nullptr; + } }; } diff --git a/Editor/ProjectManager.cpp b/Editor/ProjectManager.cpp index 353a089e6..5b4914e21 100644 --- a/Editor/ProjectManager.cpp +++ b/Editor/ProjectManager.cpp @@ -8,7 +8,7 @@ static logvisor::Module Log("URDE::ProjectManager"); bool ProjectManager::m_registeredSpecs = false; ProjectManager::ProjectManager(ViewManager &vm) -: m_vm(vm), m_objStore(m_factoryMP1) +: m_vm(vm), m_clientProc(1), m_factoryMP1(m_clientProc), m_objStore(m_factoryMP1) { if (!m_registeredSpecs) { diff --git a/Editor/ProjectManager.hpp b/Editor/ProjectManager.hpp index 8966229e6..cfe0588e4 100644 --- a/Editor/ProjectManager.hpp +++ b/Editor/ProjectManager.hpp @@ -18,6 +18,7 @@ class ProjectManager ViewManager& m_vm; std::unique_ptr m_proj; static bool m_registeredSpecs; + hecl::ClientProcess m_clientProc; ProjectResourceFactoryMP1 m_factoryMP1; urde::CSimplePool m_objStore; diff --git a/Editor/ProjectResourceFactoryBase.hpp b/Editor/ProjectResourceFactoryBase.hpp index 33606dd54..e2fa06b3d 100644 --- a/Editor/ProjectResourceFactoryBase.hpp +++ b/Editor/ProjectResourceFactoryBase.hpp @@ -1,6 +1,7 @@ #ifndef URDE_PROJECT_RESOURCE_FACTORY_BASE_HPP #define URDE_PROJECT_RESOURCE_FACTORY_BASE_HPP +#include "hecl/ClientProcess.hpp" #include "Runtime/IFactory.hpp" #include "Runtime/CFactoryMgr.hpp" #include "Runtime/CResFactory.hpp" @@ -14,6 +15,7 @@ namespace urde class ProjectResourceFactoryBase : public urde::IFactory { + hecl::ClientProcess& m_clientProc; protected: std::unordered_map m_tagToPath; std::unordered_map m_catalogNameToTag; @@ -52,6 +54,7 @@ protected: const CVParamTransfer& paramXfer); public: + ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {} std::unique_ptr Build(const urde::SObjectTag&, const urde::CVParamTransfer&); void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**); void CancelBuild(const urde::SObjectTag&); diff --git a/Editor/ProjectResourceFactoryMP1.cpp b/Editor/ProjectResourceFactoryMP1.cpp index fd4d5cf9a..86b177bd3 100644 --- a/Editor/ProjectResourceFactoryMP1.cpp +++ b/Editor/ProjectResourceFactoryMP1.cpp @@ -21,7 +21,8 @@ extern hecl::Database::DataSpecEntry SpecEntMP1PC; namespace urde { -ProjectResourceFactoryMP1::ProjectResourceFactoryMP1() +ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc) +: ProjectResourceFactoryBase(clientProc) { m_factoryMgr.AddFactory(FOURCC('TXTR'), urde::FTextureFactory); m_factoryMgr.AddFactory(FOURCC('PART'), urde::FParticleFactory); diff --git a/Editor/ProjectResourceFactoryMP1.hpp b/Editor/ProjectResourceFactoryMP1.hpp index a804f0cda..c2d01cdef 100644 --- a/Editor/ProjectResourceFactoryMP1.hpp +++ b/Editor/ProjectResourceFactoryMP1.hpp @@ -9,7 +9,7 @@ namespace urde class ProjectResourceFactoryMP1 : public ProjectResourceFactoryBase { public: - ProjectResourceFactoryMP1(); + ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc); void IndexMP1Resources(const hecl::Database::Project& proj); SObjectTag TagFromPath(const hecl::ProjectPath& path) const; hecl::ProjectPath GetCookedPath(const SObjectTag& tag, diff --git a/hecl b/hecl index b6be61576..50b614abd 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit b6be61576548e44bc5a06e58813965ddd5c5ca94 +Subproject commit 50b614abd46fc59f2cd2ca0b32261263baffd2f2