diff --git a/CMakeLists.txt b/CMakeLists.txt index 6682e6622..04fd7b20b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ set(HECL_DATASPEC_PUSHES HECL::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2); HECL::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3);") add_subdirectory(hecl) +add_definitions(${BOO_SYS_DEFINES}) add_subdirectory(libSpecter) set(SPECTER_INCLUDE_DIR libSpecter/include libSpecter/freetype2/include) add_subdirectory(NODLib) diff --git a/DataSpec/DNACommon/CMakeLists.txt b/DataSpec/DNACommon/CMakeLists.txt index 6ca52ff02..e805d53e6 100644 --- a/DataSpec/DNACommon/CMakeLists.txt +++ b/DataSpec/DNACommon/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(DNACommon ParticleCommon.cpp DeafBabe.hpp BabeDead.hpp + NamedResourceCatalog.hpp Tweaks/ITweakGame.hpp Tweaks/ITweakParticle.hpp Tweaks/ITweakPlayer.hpp diff --git a/DataSpec/DNACommon/NamedResourceCatalog.hpp b/DataSpec/DNACommon/NamedResourceCatalog.hpp new file mode 100644 index 000000000..4ce7cda8a --- /dev/null +++ b/DataSpec/DNACommon/NamedResourceCatalog.hpp @@ -0,0 +1,132 @@ +#ifndef __DNACOMMON_NAMEDRESOURCECATALOG_HPP__ +#define __DNACOMMON_NAMEDRESOURCECATALOG_HPP__ + +#include "DNACommon.hpp" +namespace DataSpec +{ +template +struct NamedResourceCatalog : BigYAML +{ + Delete _d; + Value namedResCount = 0; + struct NamedResource : BigYAML + { + Delete _d; + DNAFourCC type; + String<-1> name; + IDType uid; + + void read(Athena::io::IStreamReader& __dna_reader) + { + /* type */ + type.read(__dna_reader); + /* name */ + name = __dna_reader.readString(-1); + /* uid */ + uid.read(__dna_reader); + } + + void write(Athena::io::IStreamWriter& __dna_writer) const + { + /* type */ + type.write(__dna_writer); + /* name */ + __dna_writer.writeString(name, -1); + /* uid */ + uid.write(__dna_writer); + } + + void read(Athena::io::YAMLDocReader& __dna_docin) + { + /* type */ + __dna_docin.enumerate("type", type); + /* name */ + name = __dna_docin.readString("name"); + /* uid */ + __dna_docin.enumerate("uid", uid); + } + + void write(Athena::io::YAMLDocWriter& __dna_docout) const + { + /* type */ + __dna_docout.enumerate("type", type); + /* name */ + __dna_docout.writeString("name", name); + /* uid */ + __dna_docout.enumerate("uid", uid); + } + + static const char* DNAType() { return "DataSpec::DNACommon::NameResourceCatalog::NamedResource"; } + + size_t binarySize(size_t __isz) const + { + __isz = type.binarySize(__isz); + __isz += name.size() + 1; + __isz = uid.binarySize(__isz); + return __isz; + } + }; + Vector namedResources; + + void read(Athena::io::IStreamReader& __dna_reader) + { + /* namedResCount */ + namedResCount = __dna_reader.readUint32Big(); + /* namedResources */ + __dna_reader.enumerate(namedResources, namedResCount); + } + + void write(Athena::io::IStreamWriter& __dna_writer) const + { + /* namedResCount */ + __dna_writer.writeUint32Big(namedResCount); + /* namedResources */ + __dna_writer.enumerate(namedResources); + } + + void read(Athena::io::YAMLDocReader& __dna_docin) + { + /* namedResCount */ + namedResCount = __dna_docin.readUint32("namedResCount"); + /* namedResources */ + __dna_docin.enumerate("namedResources", namedResources, namedResCount); + } + + void write(Athena::io::YAMLDocWriter& __dna_docout) const + { + /* namedResCount */ + __dna_docout.writeUint32("namedResCount", namedResCount); + /* namedResources */ + __dna_docout.enumerate("namedResources", namedResources); + } + + static const char* DNAType() + { + return "DataSpec::DNACommon::NameResourceCatalog"; + } + + size_t binarySize(size_t __isz) const + { + __isz = __EnumerateSize(__isz, namedResources); + return __isz + 4; + } + + void addNamedResource(const std::string& name, const IDType& id, const DNAFourCC& type) + { + NamedResource res; + res.type = type; + res.name = name; + res.uid = id; + auto it = std::find_if(namedResources.begin(), namedResources.end(), [res](const NamedResource& a)->bool + { return (a.name == res.name && a.type == res.type && a.uid == res.uid); }); + + if (it != namedResources.end()) + return; + + namedResources.push_back(std::move(res)); + namedResCount++; + } +}; +} + +#endif // NAMEDRESOURCECATALOG_HPP diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp index 6a4303ac9..93b643efa 100644 --- a/DataSpec/DNACommon/PAK.hpp +++ b/DataSpec/DNACommon/PAK.hpp @@ -2,6 +2,7 @@ #define __DNACOMMON_PAK_HPP__ #include "DNACommon.hpp" +#include "NamedResourceCatalog.hpp" namespace DataSpec { @@ -240,6 +241,7 @@ public: using EntryType = typename PAKType::Entry; using RigPair = std::pair; private: + NamedResourceCatalog m_catalog; const SpecBase& m_dataSpec; const std::vector* m_bridges = nullptr; std::vector> m_bridgePaths; @@ -309,9 +311,21 @@ public: /* Add RigPairs to global map */ bridge.addCMDLRigPairs(*this, m_cmdlRigs); + /* Add named resources to catalog */ + for (const auto& namedEntry : pak.m_nameEntries) + m_catalog.addNamedResource(namedEntry.name, namedEntry.id, namedEntry.type); + progress(++count / bridgesSz); ++bridgeIdx; } + + HECL::SystemString catalogPath = HECL::ProjectPath(m_gameCooked, "catalog.yaml").getAbsolutePath(); + FILE* catalog = HECL::Fopen(catalogPath.c_str(), _S("wb")); + if (catalog) + { + m_catalog.toYAMLFile(catalog); + fclose(catalog); + } } void enterPAKBridge(const BRIDGETYPE& pakBridge) diff --git a/DataSpec/DNAMP2/CMakeLists.txt b/DataSpec/DNAMP2/CMakeLists.txt index 0bd09ef53..7c1e4b45c 100644 --- a/DataSpec/DNAMP2/CMakeLists.txt +++ b/DataSpec/DNAMP2/CMakeLists.txt @@ -6,6 +6,7 @@ make_dnalist(liblist CINF CSKR MREA + PTLA DeafBabe) add_library(DNAMP2 DNAMP2.hpp DNAMP2.cpp diff --git a/DataSpec/DNAMP2/PTLA.hpp b/DataSpec/DNAMP2/PTLA.hpp new file mode 100644 index 000000000..2e59e74c8 --- /dev/null +++ b/DataSpec/DNAMP2/PTLA.hpp @@ -0,0 +1,72 @@ +#ifndef PTLA_HPP +#define PTLA_HPP + +#include "../DNACommon/DNACommon.hpp" + +namespace DataSpec +{ +namespace DNAMP2 +{ +struct PTLA : BigDNA +{ + DECL_DNA + Value magic; + Value version; + struct UnknownStruct1 : BigDNA + { + DECL_DNA + Value count; + struct Entry : BigDNA + { + DECL_DNA + Value unknown1; + Value unknown2; + Value unknown3; + Value unknown4; + Value unknown5; + Value unknown6; + }; + Vector entries; + Value unknown[2]; + }; + Value count1; + Vector entries1; + + struct UnknownStruct2 : BigDNA + { + DECL_DNA + Value count; + struct Entry : BigDNA + { + DECL_DNA + Value unknown1; + Value unknown2; + Value unknown3; + Value unknown4; + }; + Vector entries; + Value unknown; + }; + Value count2; + Vector entries2; + + Value shortCount1; + Vector shorts1; + + Value shortCount2; + Vector shorts2; + + struct UnknownStruct3 : BigDNA + { + DECL_DNA + Value unknown1[2]; + Value unknown2; + Value unknown3; + Value unknown4; + }; + Value count3; + Vector entries3; +}; +} +} +#endif // PTLA_HPP diff --git a/DataSpec/SpecBase.cpp b/DataSpec/SpecBase.cpp index 75ac313cf..a98f7ccef 100644 --- a/DataSpec/SpecBase.cpp +++ b/DataSpec/SpecBase.cpp @@ -25,9 +25,12 @@ static const HECL::SystemChar* MomErr[] = _S("Contradictive narratives unsupported"), _S("Wiimote profile \"NES + Zapper\" not recognized"), _S("Unable to find Waldo"), - _S("Expected Ridley, found furby") + _S("Expected Ridley, found furby"), + _S("Adam has not authorized this, please do not bug the developers"), + _S("Error: Lady returned objection") }; +constexpr uint32_t MomErrCount = 11; SpecBase::SpecBase(HECL::Database::Project& project) : m_project(project), m_masterShader(project.getProjectWorkingPath(), ".hecl/RetroMasterShader.blend") {} @@ -44,9 +47,9 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vectorsetScissor(m_scissorRect); + m_mv.m_lineRenderer->Reset(); + m_mv.m_lineRenderer->AddVertex({-0.5f, 0.f, -0.5f}, Zeus::CColor::skBlue, 1.f); + m_mv.m_lineRenderer->AddVertex({-0.5f, 0.f, 0.5f}, Zeus::CColor::skBlue, 1.f); + m_mv.m_lineRenderer->AddVertex({0.5f, 10.f, 0.5f}, Zeus::CColor::skRed, 3.f); + m_mv.m_lineRenderer->AddVertex({0.5f, 0.f, -0.5f}, Zeus::CColor::skBlue, 1.f); + m_mv.m_lineRenderer->Render(); + gfxQ->setScissor({}); +} + + +} diff --git a/Editor/ModelViewer.hpp b/Editor/ModelViewer.hpp index 33f035e5d..c35b3dc02 100644 --- a/Editor/ModelViewer.hpp +++ b/Editor/ModelViewer.hpp @@ -26,13 +26,20 @@ class ModelViewer : public ViewerSpace } m_state; const Space::State& spaceState() const { return m_state; } - + std::unique_ptr m_lineRenderer; struct View : Specter::View { ModelViewer& m_mv; + boo::SWindowRect m_scissorRect; + View(ModelViewer& mv, Specter::ViewResources& res) : Specter::View(res, mv.m_vm.rootView()), m_mv(mv) - {} + { + commitResources(res); + } + + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void draw(boo::IGraphicsCommandQueue *gfxQ); }; Camera m_camera; @@ -43,6 +50,7 @@ public: : ViewerSpace(vm, Class::ModelViewer, parent) { reloadState(); + m_lineRenderer.reset(new pshag::CLineRenderer(pshag::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true)); } ModelViewer(ViewManager& vm, Space* parent, const ModelViewer& other) diff --git a/Editor/ProjectResourceFactory.cpp b/Editor/ProjectResourceFactory.cpp index b530ff563..eb70c4513 100644 --- a/Editor/ProjectResourceFactory.cpp +++ b/Editor/ProjectResourceFactory.cpp @@ -17,31 +17,26 @@ ProjectResourceFactory::ProjectResourceFactory() m_factoryMgr.AddFactory(HECL::FOURCC('PART'), pshag::FParticleFactory); } -void ProjectResourceFactory::RecursiveAddDirObjects(const HECL::ProjectPath& path) -{ - HECL::DirectoryEnumerator de = path.enumerateDir(); - for (const HECL::DirectoryEnumerator::Entry& ent : de) - { - if (ent.m_isDir) - RecursiveAddDirObjects(HECL::ProjectPath(path, ent.m_name)); - if (ent.m_name.size() == 13 && ent.m_name[4] == _S('_')) - { - HECL::SystemUTF8View entu8(ent.m_name); - u32 id = strtoul(entu8.c_str() + 5, nullptr, 16); - if (id) - { - pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id}; - if (m_resPaths.find(objTag) == m_resPaths.end()) - m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name); - } - } - } -} - -void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec) +void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::ProjectDataSpec &spec) { m_resPaths.clear(); - RecursiveAddDirObjects(spec.cookedPath); + m_namedResources.clear(); + HECL::SystemString catalogPath = HECL::ProjectPath(spec.cookedPath, HECL::SystemString(spec.spec.m_name) + _S("/catalog.yaml")).getAbsolutePath(); + FILE* catalogFile = HECL::Fopen(catalogPath.c_str(), _S("r")); + if (!HECL::StrCmp(spec.spec.m_name, _S("MP3"))) + { + DataSpec::NamedResourceCatalog catalog; + if (catalogFile) + catalog.fromYAMLFile(catalogFile); + RecursiveAddDirObjects(spec.cookedPath, catalog); + } + else + { + DataSpec::NamedResourceCatalog catalog; + if (catalogFile) + catalog.fromYAMLFile(catalogFile); + RecursiveAddDirObjects(spec.cookedPath, catalog); + } } std::unique_ptr ProjectResourceFactory::Build(const pshag::SObjectTag& tag, @@ -83,9 +78,12 @@ bool ProjectResourceFactory::CanBuild(const pshag::SObjectTag& tag) return true; } -const pshag::SObjectTag* ProjectResourceFactory::GetResourceIdByName(const char*) const +const pshag::SObjectTag* ProjectResourceFactory::GetResourceIdByName(const char* name) const { - return nullptr; + if (m_namedResources.find(name) == m_namedResources.end()) + return nullptr; + const pshag::SObjectTag& tag = m_namedResources.at(name); + return &tag; } } diff --git a/Editor/ProjectResourceFactory.hpp b/Editor/ProjectResourceFactory.hpp index 595815003..22cfa974a 100644 --- a/Editor/ProjectResourceFactory.hpp +++ b/Editor/ProjectResourceFactory.hpp @@ -3,6 +3,7 @@ #include "Runtime/IFactory.hpp" #include "Runtime/CFactoryMgr.hpp" +#include "DataSpec/DNACommon/NamedResourceCatalog.hpp" namespace URDE { @@ -10,8 +11,61 @@ namespace URDE class ProjectResourceFactory : public pshag::IFactory { std::unordered_map m_resPaths; + std::unordered_map m_namedResources; pshag::CFactoryMgr m_factoryMgr; - void RecursiveAddDirObjects(const HECL::ProjectPath& path); + template + void RecursiveAddDirObjects(const HECL::ProjectPath& path, const DataSpec::NamedResourceCatalog& catalog) + { + HECL::DirectoryEnumerator de = path.enumerateDir(); + const int idLen = 5 + (IDType::BinarySize() * 2); + for (const HECL::DirectoryEnumerator::Entry& ent : de) + { + if (ent.m_isDir) + RecursiveAddDirObjects(HECL::ProjectPath(path, ent.m_name), catalog); + if (ent.m_name.size() == idLen && ent.m_name[4] == _S('_')) + { + HECL::SystemUTF8View entu8(ent.m_name); +#if _WIN32 + u64 id = _strtoui64(entu8.c_str() + 5, nullptr, 16); +#else + u64 id = strtouq(entu8.c_str() + 5, nullptr, 16); +#endif + + if (id) + { + pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id}; + if (m_resPaths.find(objTag) == m_resPaths.end()) + m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name); + } + } + else + { + HECL::SystemUTF8View nameView(ent.m_name); + auto it = std::find_if(catalog.namedResources.begin(), catalog.namedResources.end(), + [&nameView](const typename DataSpec::NamedResourceCatalog::NamedResource& res) -> bool + { return res.name == nameView.str(); }); + if (it == catalog.namedResources.end()) + continue; + + const typename DataSpec::NamedResourceCatalog::NamedResource& nr = *it; + pshag::SObjectTag objTag = GetTag(nr); + + m_namedResources[nr.name.c_str()] = objTag; + m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name); + } + } + } + + template + pshag::SObjectTag GetTag(const DataSpec::NamedResourceCatalog::NamedResource &nr, + typename std::enable_if::value>::type* = 0) + { return { nr.type, nr.uid.toUint32() }; } + + template + pshag::SObjectTag GetTag(const typename DataSpec::NamedResourceCatalog::NamedResource& nr, + typename std::enable_if::value>::type* = 0) + { return { nr.type, nr.uid.toUint64() }; } + public: ProjectResourceFactory(); void BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec); diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index 5581774d9..68d90fede 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -20,7 +20,8 @@ namespace URDE void ViewManager::BuildTestPART(pshag::IObjectStore& objStore) { - m_partGenDesc = objStore.GetObj({HECL::FOURCC('PART'), 0x1E348530}); + //m_partGenDesc = objStore.GetObj({HECL::FOURCC('PART'), 0x972A5CD2}); + m_partGenDesc = objStore.GetObj("WallSpark"); m_partGen.reset(new pshag::CElementGen(m_partGenDesc, pshag::CElementGen::EModelOrientationType::Normal, pshag::CElementGen::EOptionalSystemFlags::None)); @@ -200,7 +201,7 @@ void ViewManager::pushRecentFile(const HECL::SystemString& path) void ViewManager::init(boo::IApplication* app) { - m_mainWindow = std::unique_ptr(app->newWindow(_S("URDE"))); + m_mainWindow = std::unique_ptr(app->newWindow(_S("URDE"), 1)); m_mainWindow->showWindow(); m_mainWindow->setWaitCursor(true); diff --git a/Editor/main.cpp b/Editor/main.cpp index 4255ba21a..a3c5c157b 100644 --- a/Editor/main.cpp +++ b/Editor/main.cpp @@ -15,26 +15,29 @@ struct Application : boo::IApplicationCallback { HECL::Runtime::FileStoreManager m_fileMgr; HECL::CVarManager m_cvarManager; - ViewManager m_viewManager; + std::unique_ptr m_viewManager; bool m_running = true; Application() : m_fileMgr(_S("urde")), - m_cvarManager(m_fileMgr), - m_viewManager(m_fileMgr, m_cvarManager) {} + m_cvarManager(m_fileMgr) + { + m_viewManager.reset(new ViewManager(m_fileMgr, m_cvarManager)); + } int appMain(boo::IApplication* app) { initialize(app); - m_viewManager.init(app); + m_viewManager->init(app); while (m_running) { - if (!m_viewManager.proc()) + if (!m_viewManager->proc()) break; } - m_viewManager.stop(); + m_viewManager->stop(); m_cvarManager.serialize(); + m_viewManager.reset(); return 0; } void appQuitting(boo::IApplication*) diff --git a/Runtime/CArchitectureMessage.hpp b/Runtime/CArchitectureMessage.hpp index 5c23f8047..e2668e295 100644 --- a/Runtime/CArchitectureMessage.hpp +++ b/Runtime/CArchitectureMessage.hpp @@ -12,7 +12,9 @@ class CIOWin; enum class EArchMsgTarget { IOWinManager = 0, - Game = 1 + Game = 1, + /* PathShagged targets, we start at 255 */ + ArchitectureSupport = 255, }; enum class EArchMsgType @@ -28,6 +30,8 @@ enum class EArchMsgType QuitGameplay = 8, UpdateBegin = 10, FrameBegin = 11, + /* PathShagged messages, we start at 255 */ + ApplicationExit = 255, }; struct IArchMsgParm @@ -39,6 +43,7 @@ struct CArchMsgParmInt32 : IArchMsgParm { u32 x4_parm; CArchMsgParmInt32(u32 parm) : x4_parm(parm) {} + virtual ~CArchMsgParmInt32() {} }; struct CArchMsgParmVoidPtr : IArchMsgParm @@ -46,6 +51,7 @@ struct CArchMsgParmVoidPtr : IArchMsgParm void* x4_parm1; CArchMsgParmVoidPtr(void* parm1) : x4_parm1(parm1) {} + virtual ~CArchMsgParmVoidPtr() {} }; struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm @@ -55,22 +61,26 @@ struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm void* xc_parm3; CArchMsgParmInt32Int32VoidPtr(u32 parm1, u32 parm2, void* parm3) : x4_parm1(parm1), x8_parm2(parm2), xc_parm3(parm3) {} + virtual ~CArchMsgParmInt32Int32VoidPtr() {} }; struct CArchMsgParmNull : IArchMsgParm { + virtual ~CArchMsgParmNull() {} }; struct CArchMsgParmReal32 : IArchMsgParm { float x4_parm; CArchMsgParmReal32(float parm) : x4_parm(parm) {} + virtual ~CArchMsgParmReal32() {} }; struct CArchMsgParmUserInput : IArchMsgParm { CFinalInput x4_parm; CArchMsgParmUserInput(const CFinalInput& parm) : x4_parm(parm) {} + virtual ~CArchMsgParmUserInput() {} }; struct CArchMsgParmControllerStatus : IArchMsgParm @@ -79,6 +89,8 @@ struct CArchMsgParmControllerStatus : IArchMsgParm bool x6_parm2; CArchMsgParmControllerStatus(u16 a, bool b) : x4_parm1(a), x6_parm2(b) {} + + virtual ~CArchMsgParmControllerStatus() {} }; class CArchitectureMessage @@ -143,6 +155,11 @@ public: { return *msg.GetParm(); } + /* PathShagged Messages */ + static CArchitectureMessage CreateApplicationExit(EArchMsgTarget target) + { + return CArchitectureMessage(target, EArchMsgType::ApplicationExit, new CArchMsgParmNull()); + } }; } diff --git a/Runtime/CGraphics.hpp b/Runtime/CGraphics.hpp index ca84f1e39..0b5eab90f 100644 --- a/Runtime/CGraphics.hpp +++ b/Runtime/CGraphics.hpp @@ -206,14 +206,12 @@ public: { g_BooMainCommandQueue->setShaderDataBinding(binding); } - static void DrawInstances(boo::Primitive prim, size_t start, size_t count, size_t instCount) + static void DrawInstances(size_t start, size_t count, size_t instCount) { - g_BooMainCommandQueue->setDrawPrimitive(prim); g_BooMainCommandQueue->drawInstances(start, count, instCount); } - static void DrawArray(boo::Primitive prim, size_t start, size_t count) + static void DrawArray(size_t start, size_t count) { - g_BooMainCommandQueue->setDrawPrimitive(prim); g_BooMainCommandQueue->draw(start, count); } }; diff --git a/Runtime/CTextureBoo.cpp b/Runtime/CTextureBoo.cpp index 72e11ce66..4f1d59cb4 100644 --- a/Runtime/CTextureBoo.cpp +++ b/Runtime/CTextureBoo.cpp @@ -111,10 +111,11 @@ void CTexture::BuildI4FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildI8FromGCN(CInputStream& in) @@ -157,10 +158,11 @@ void CTexture::BuildI8FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildIA4FromGCN(CInputStream& in) @@ -204,10 +206,11 @@ void CTexture::BuildIA4FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildIA8FromGCN(CInputStream& in) @@ -251,10 +254,11 @@ void CTexture::BuildIA8FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } static std::vector DecodePalette(int numEntries, CInputStream& in) @@ -357,10 +361,11 @@ void CTexture::BuildC4FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildC8FromGCN(CInputStream& in) @@ -399,10 +404,11 @@ void CTexture::BuildC8FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildC14X2FromGCN(CInputStream& in) @@ -449,10 +455,11 @@ void CTexture::BuildRGB565FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildRGB5A3FromGCN(CInputStream& in) @@ -504,10 +511,11 @@ void CTexture::BuildRGB5A3FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } void CTexture::BuildRGBA8FromGCN(CInputStream& in) @@ -559,10 +567,11 @@ void CTexture::BuildRGBA8FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, - buf.get(), texelCount * 4, - reinterpret_cast(&m_booTex)); + buf.get(), texelCount * 4, tmp); + m_booTex = tmp; } struct DXT1Block @@ -621,10 +630,11 @@ void CTexture::BuildDXT1FromGCN(CInputStream& in) h /= 2; } + boo::ITextureS* tmp; m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips, boo::TextureFormat::DXT1, - buf.get(), blockCount * 8, - reinterpret_cast(&m_booTex)); + buf.get(), blockCount * 8, tmp); + m_booTex = tmp; } CTexture::CTexture(CInputStream& in) diff --git a/Runtime/CTimeProvider.cpp b/Runtime/CTimeProvider.cpp index 7642c91b8..4054a9bde 100644 --- a/Runtime/CTimeProvider.cpp +++ b/Runtime/CTimeProvider.cpp @@ -12,6 +12,8 @@ CTimeProvider::CTimeProvider(const float& time) if (x8_lastProvider != nullptr) x8_lastProvider->x4_first = false; + g_currentTimeProvider = this; + #if 0 CGraphics::SetExternalTimeProvider(this); #endif diff --git a/Runtime/Graphics/CLineRenderer.cpp b/Runtime/Graphics/CLineRenderer.cpp index d89e79461..8effbe535 100644 --- a/Runtime/Graphics/CLineRenderer.cpp +++ b/Runtime/Graphics/CLineRenderer.cpp @@ -31,10 +31,16 @@ void CLineRendererShaders::Initialize() case boo::IGraphicsDataFactory::Platform::D3D12: m_bindFactory.reset(Initialize(*static_cast(CGraphics::g_BooFactory))); break; -#elif BOO_HAS_METAL +#endif +#if BOO_HAS_METAL case boo::IGraphicsDataFactory::Platform::Metal: m_bindFactory.reset(Initialize(*static_cast(CGraphics::g_BooFactory))); break; +#endif +#if BOO_HAS_VULKAN + case boo::IGraphicsDataFactory::Platform::Vulkan: + m_bindFactory.reset(Initialize(*static_cast(CGraphics::g_BooFactory))); + break; #endif default: break; } @@ -154,7 +160,7 @@ void CLineRenderer::Reset() void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColor& color, float width, const Zeus::CVector2f& uv) { - if (!m_shaderBind || m_nextVert >= m_maxVerts) + if (m_final || !m_shaderBind || m_nextVert >= m_maxVerts) return; float adjWidth = width / 480.f; @@ -385,16 +391,17 @@ void CLineRenderer::Render(const Zeus::CColor& moduColor) SDrawUniform uniformData = {moduColor}; m_uniformBuf->load(&uniformData, sizeof(SDrawUniform)); - CGraphics::SetShaderDataBinding(m_shaderBind); if (m_textured) { m_vertBuf->load(g_StaticLineVertsTex.data(), sizeof(SDrawVertTex) * g_StaticLineVertsTex.size()); - CGraphics::DrawArray(boo::Primitive::TriStrips, 0, g_StaticLineVertsTex.size()); + CGraphics::SetShaderDataBinding(m_shaderBind); + CGraphics::DrawArray(0, g_StaticLineVertsTex.size()); } else { m_vertBuf->load(g_StaticLineVertsNoTex.data(), sizeof(SDrawVertNoTex) * g_StaticLineVertsNoTex.size()); - CGraphics::DrawArray(boo::Primitive::TriStrips, 0, g_StaticLineVertsNoTex.size()); + CGraphics::SetShaderDataBinding(m_shaderBind); + CGraphics::DrawArray(0, g_StaticLineVertsNoTex.size()); } } diff --git a/Runtime/Graphics/CLineRendererShaders.hpp b/Runtime/Graphics/CLineRendererShaders.hpp index bd26608b4..4d810e6d7 100644 --- a/Runtime/Graphics/CLineRendererShaders.hpp +++ b/Runtime/Graphics/CLineRendererShaders.hpp @@ -5,6 +5,7 @@ #include "boo/graphicsdev/GL.hpp" #include "boo/graphicsdev/D3D.hpp" #include "boo/graphicsdev/Metal.hpp" +#include "boo/graphicsdev/Vulkan.hpp" namespace pshag { @@ -36,9 +37,13 @@ public: static IDataBindingFactory* Initialize(boo::GLDataFactory& factory); #if _WIN32 static IDataBindingFactory* Initialize(boo::ID3DDataFactory& factory); -#elif BOO_HAS_METAL +#endif +#if BOO_HAS_METAL static IDataBindingFactory* Initialize(boo::MetalDataFactory& factory); #endif +#if BOO_HAS_VULKAN + static IDataBindingFactory* Initialize(boo::VulkanDataFactory& factory); +#endif static void Initialize(); static void Shutdown(); diff --git a/Runtime/Graphics/CLineRendererShadersGLSL.cpp b/Runtime/Graphics/CLineRendererShadersGLSL.cpp index caf19c08a..57d3d7b28 100644 --- a/Runtime/Graphics/CLineRendererShadersGLSL.cpp +++ b/Runtime/Graphics/CLineRendererShadersGLSL.cpp @@ -6,11 +6,12 @@ namespace pshag static const char* VS_GLSL_TEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "layout(location=0) in vec4 posIn;\n" "layout(location=1) in vec4 colorIn;\n" "layout(location=2) in vec4 uvIn;\n" "\n" -"uniform LineUniform\n" +"UBINDING0 uniform LineUniform\n" "{\n" " vec4 moduColor;\n" "};\n" @@ -31,6 +32,7 @@ static const char* VS_GLSL_TEX = static const char* FS_GLSL_TEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "struct VertToFrag\n" "{\n" " vec4 color;\n" @@ -39,7 +41,7 @@ static const char* FS_GLSL_TEX = "\n" "in VertToFrag vtf;\n" "layout(location=0) out vec4 colorOut;\n" -"uniform sampler2D texs[1];\n" +"TBINDING0 uniform sampler2D texs[1];\n" "void main()\n" "{\n" " colorOut = vtf.color * texture(texs[0], vtf.uv);\n" @@ -47,10 +49,11 @@ static const char* FS_GLSL_TEX = static const char* VS_GLSL_NOTEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "layout(location=0) in vec4 posIn;\n" "layout(location=1) in vec4 colorIn;\n" "\n" -"uniform LineUniform\n" +"UBINDING0 uniform LineUniform\n" "{\n" " vec4 moduColor;\n" "};\n" @@ -81,7 +84,7 @@ static const char* FS_GLSL_NOTEX = " colorOut = vtf.color;\n" "}\n"; -struct GLSLLineDataBindingFactory : CLineRendererShaders::IDataBindingFactory +struct OGLLineDataBindingFactory : CLineRendererShaders::IDataBindingFactory { void BuildShaderDataBinding(CLineRenderer& renderer, boo::IShaderPipeline* pipeline, boo::ITexture* texture) { @@ -136,7 +139,63 @@ CLineRendererShaders::IDataBindingFactory* CLineRendererShaders::Initialize(boo: boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, false, false, false); - return new struct GLSLLineDataBindingFactory; + return new struct OGLLineDataBindingFactory; } +#if BOO_HAS_VULKAN +struct VulkanLineDataBindingFactory : CLineRendererShaders::IDataBindingFactory +{ + void BuildShaderDataBinding(CLineRenderer& renderer, boo::IShaderPipeline* pipeline, boo::ITexture* texture) + { + int texCount = 0; + boo::ITexture* textures[1]; + + if (texture) + { + textures[0] = texture; + texCount = 1; + } + + boo::IGraphicsBuffer* uniforms[] = {renderer.m_uniformBuf}; + + renderer.m_shaderBind = CGraphics::g_BooFactory->newShaderDataBinding(pipeline, nullptr, renderer.m_vertBuf, + nullptr, nullptr, 1, uniforms, + texCount, textures); + } +}; + +CLineRendererShaders::IDataBindingFactory* CLineRendererShaders::Initialize(boo::VulkanDataFactory& factory) +{ + static const boo::VertexElementDescriptor VtxFmtTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::Color}, + {nullptr, nullptr, boo::VertexSemantic::UV4} + }; + m_texVtxFmt = factory.newVertexFormat(3, VtxFmtTex); + + static const boo::VertexElementDescriptor VtxFmtNoTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::Color} + }; + m_noTexVtxFmt = factory.newVertexFormat(2, VtxFmtNoTex); + + m_texAlpha = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_texVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, true, false); + m_texAdditive = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_texVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + false, false, false); + m_noTexAlpha = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_noTexVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, true, false); + m_noTexAdditive = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_noTexVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + false, false, false); + + return new struct VulkanLineDataBindingFactory; +} +#endif + } diff --git a/Runtime/Graphics/CLineRendererShadersHLSL.cpp b/Runtime/Graphics/CLineRendererShadersHLSL.cpp index e69de29bb..909d38f03 100644 --- a/Runtime/Graphics/CLineRendererShadersHLSL.cpp +++ b/Runtime/Graphics/CLineRendererShadersHLSL.cpp @@ -0,0 +1,147 @@ +#include "CLineRendererShaders.hpp" +#include "CLineRenderer.hpp" + +namespace pshag +{ + +static const char* VS_HLSL_TEX = +"struct VertData\n" +"{\n" +" float4 posIn : POSITION;\n" +" float4 colorIn : COLOR;\n" +" float4 uvIn : UV;\n" +"};\n" +"\n" +"cbuffer LineUniform : register(b0)\n" +"{\n" +" float4 moduColor;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" float4 position : SV_Position;\n" +" float4 color : COLOR;\n" +" float2 uv : UV;\n" +"};\n" +"\n" +"VertToFrag main(in VertData v)\n" +"{\n" +" VertToFrag vtf;\n" +" vtf.color = v.colorIn * moduColor;\n" +" vtf.uv = v.uvIn.xy;\n" +" vtf.position = v.posIn;\n" +" return vtf;\n" +"}\n"; + +static const char* FS_HLSL_TEX = +"SamplerState samp : register(s0);\n" +"Texture2D tex0 : register(t0);\n" +"struct VertToFrag\n" +"{\n" +" float4 position : SV_Position;\n" +" float4 color : COLOR;\n" +" float2 uv : UV;\n" +"};\n" +"\n" +"float4 main(in VertToFrag vtf) : SV_Target0\n" +"{\n" +" return vtf.color * tex0.Sample(samp, vtf.uv);\n" +"}\n"; + +static const char* VS_HLSL_NOTEX = +"struct VertData\n" +"{\n" +" float4 posIn : POSITION;\n" +" float4 colorIn : COLOR;\n" +"};\n" +"\n" +"cbuffer LineUniform : register(b0)\n" +"{\n" +" float4 moduColor;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" float4 position : SV_Position;\n" +" float4 color : COLOR;\n" +"};\n" +"\n" +"VertToFrag main(in VertData v)\n" +"{\n" +" VertToFrag vtf;\n" +" vtf.color = v.colorIn * moduColor;\n" +" vtf.position = v.posIn;\n" +" return vtf;\n" +"}\n"; + +static const char* FS_HLSL_NOTEX = +"struct VertToFrag\n" +"{\n" +" float4 position : SV_Position;\n" +" float4 color : COLOR;\n" +"};\n" +"\n" +"float4 main(in VertToFrag vtf) : SV_Target0\n" +"{\n" +" return vtf.color;\n" +"}\n"; + +struct HLSLLineDataBindingFactory : CLineRendererShaders::IDataBindingFactory +{ + void BuildShaderDataBinding(CLineRenderer& renderer, boo::IShaderPipeline* pipeline, boo::ITexture* texture) + { + int texCount = 0; + boo::ITexture* textures[1]; + + if (texture) + { + textures[0] = texture; + texCount = 1; + } + + boo::IGraphicsBuffer* uniforms[] = {renderer.m_uniformBuf}; + + renderer.m_shaderBind = CGraphics::g_BooFactory->newShaderDataBinding(pipeline, nullptr, renderer.m_vertBuf, + nullptr, nullptr, 1, uniforms, + texCount, textures); + } +}; + +CLineRendererShaders::IDataBindingFactory* CLineRendererShaders::Initialize(boo::ID3DDataFactory& factory) +{ + static const boo::VertexElementDescriptor VtxFmtTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::Color}, + {nullptr, nullptr, boo::VertexSemantic::UV4} + }; + m_texVtxFmt = factory.newVertexFormat(3, VtxFmtTex); + + static const boo::VertexElementDescriptor VtxFmtNoTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::Color} + }; + m_noTexVtxFmt = factory.newVertexFormat(2, VtxFmtNoTex); + + m_texAlpha = factory.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, ComPtr(), ComPtr(), + ComPtr(), m_texVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, true, false); + m_texAdditive = factory.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, ComPtr(), ComPtr(), + ComPtr(), m_texVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + false, false, false); + m_noTexAlpha = factory.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, ComPtr(), ComPtr(), + ComPtr(), m_noTexVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, true, false); + m_noTexAdditive = factory.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, ComPtr(), ComPtr(), + ComPtr(), m_noTexVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + false, false, false); + + return new struct HLSLLineDataBindingFactory; +} + +} diff --git a/Runtime/Input/CFinalInput.hpp b/Runtime/Input/CFinalInput.hpp index ca882fa7c..b8ee75992 100644 --- a/Runtime/Input/CFinalInput.hpp +++ b/Runtime/Input/CFinalInput.hpp @@ -72,6 +72,8 @@ public: const CKeyboardMouseControllerData& data, const CFinalInput& prevInput); CFinalInput& operator|=(const CFinalInput& other); + bool operator==(const CFinalInput& other) + { return memcmp(this, &other, sizeof(CFinalInput)) == 0; } bool PStart() const {return x2e_b31_PStart;} bool PR() const {return x2e_b26_PR;} diff --git a/Runtime/Input/CInputGenerator.cpp b/Runtime/Input/CInputGenerator.cpp index cd1abd8c7..6f4abf82a 100644 --- a/Runtime/Input/CInputGenerator.cpp +++ b/Runtime/Input/CInputGenerator.cpp @@ -7,8 +7,14 @@ namespace pshag void CInputGenerator::Update(float dt, CArchitectureQueue& queue) { + if (m_firstFrame) + { + m_firstFrame = false; + return; + } + /* Keyboard/Mouse first */ - CFinalInput kbInput = m_windowCb.getFinalInput(0, dt); + CFinalInput kbInput = getFinalInput(0, dt); bool kbUsed = false; /* Dolphin controllers next */ diff --git a/Runtime/Input/CInputGenerator.hpp b/Runtime/Input/CInputGenerator.hpp index 3dc3bdeb4..160366378 100644 --- a/Runtime/Input/CInputGenerator.hpp +++ b/Runtime/Input/CInputGenerator.hpp @@ -24,6 +24,16 @@ class CInputGenerator : public boo::DeviceFinder * the logical state */ float m_leftDiv; float m_rightDiv; + CKeyboardMouseControllerData m_data; + + CFinalInput m_lastUpdate; + const CFinalInput& getFinalInput(unsigned idx, float dt) + { + m_lastUpdate = CFinalInput(idx, dt, m_data, m_lastUpdate); + return m_lastUpdate; + } + + bool m_firstFrame = true; public: CInputGenerator(float leftDiv, float rightDiv) : boo::DeviceFinder({typeid(boo::DolphinSmashAdapter)}), @@ -35,70 +45,59 @@ public: * for buffering events in its own way, then boo flushes the buffer * at the start of each frame, invoking these methods. No atomic locking * is necessary, only absolute state tracking. */ - struct WindowCallback : boo::IWindowCallback + + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton button, boo::EModifierKey) { - CKeyboardMouseControllerData m_data; + m_data.m_mouseButtons[int(button)] = true; + } + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton button, boo::EModifierKey) + { + m_data.m_mouseButtons[int(button)] = false; + } + void mouseMove(const boo::SWindowCoord& coord) + { + m_data.m_mouseCoord = coord; + } + void scroll(const boo::SWindowCoord&, const boo::SScrollDelta& scroll) + { + m_data.m_accumScroll += scroll; + } - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton button, boo::EModifierKey) - { - m_data.m_mouseButtons[int(button)] = true; - } - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton button, boo::EModifierKey) - { - m_data.m_mouseButtons[int(button)] = false; - } - void mouseMove(const boo::SWindowCoord& coord) - { - m_data.m_mouseCoord = coord; - } - void scroll(const boo::SWindowCoord&, const boo::SScrollDelta& scroll) - { - m_data.m_accumScroll += scroll; - } + void charKeyDown(unsigned long charCode, boo::EModifierKey, bool) + { + charCode = tolower(charCode); + if (charCode > 255) + return; + m_data.m_charKeys[charCode] = true; + } + void charKeyUp(unsigned long charCode, boo::EModifierKey mods) + { + charCode = tolower(charCode); + if (charCode > 255) + return; + m_data.m_charKeys[charCode] = false; + } + void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey, bool) + { + m_data.m_specialKeys[int(key)] = true; + } + void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey) + { + m_data.m_specialKeys[int(key)] = false; + } + void modKeyDown(boo::EModifierKey mod, bool) + { + m_data.m_modMask = m_data.m_modMask | mod; + } + void modKeyUp(boo::EModifierKey mod) + { + m_data.m_modMask = m_data.m_modMask & ~mod; + } - void charKeyDown(unsigned long charCode, boo::EModifierKey, bool) - { - charCode = tolower(charCode); - if (charCode > 255) - return; - m_data.m_charKeys[charCode] = true; - } - void charKeyUp(unsigned long charCode, boo::EModifierKey mods) - { - charCode = tolower(charCode); - if (charCode > 255) - return; - m_data.m_charKeys[charCode] = false; - } - void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey, bool) - { - m_data.m_specialKeys[int(key)] = true; - } - void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey) - { - m_data.m_specialKeys[int(key)] = false; - } - void modKeyDown(boo::EModifierKey mod, bool) - { - m_data.m_modMask = m_data.m_modMask | mod; - } - void modKeyUp(boo::EModifierKey mod) - { - m_data.m_modMask = m_data.m_modMask & ~mod; - } - - void reset() - { - m_data.m_accumScroll.zeroOut(); - } - - CFinalInput m_lastUpdate; - const CFinalInput& getFinalInput(unsigned idx, float dt) - { - m_lastUpdate = CFinalInput(idx, dt, m_data, m_lastUpdate); - return m_lastUpdate; - } - } m_windowCb; + void reset() + { + m_data.m_accumScroll.zeroOut(); + } /* Input via the smash adapter is received asynchronously on a USB * report thread. This class atomically exchanges that data to the @@ -114,7 +113,7 @@ public: /* Controller thread */ m_statusChanges[idx].store(EStatusChange::Connected); } - void controllerDisconnected(unsigned idx, boo::EDolphinControllerType) + void controllerDisconnected(unsigned idx) { /* Controller thread */ std::unique_lock lk(m_stateLock); diff --git a/Runtime/Input/CMakeLists.txt b/Runtime/Input/CMakeLists.txt index a09f2b6e2..4e3926808 100644 --- a/Runtime/Input/CMakeLists.txt +++ b/Runtime/Input/CMakeLists.txt @@ -3,4 +3,7 @@ add_library(RuntimeCommonInput CKeyboardMouseController.hpp ControlMapper.hpp ControlMapper.cpp CInputGenerator.hpp CInputGenerator.cpp - CFinalInput.hpp CFinalInput.cpp) + CFinalInput.hpp CFinalInput.cpp + CRumbleManager.hpp CRumbleManager.cpp + CRumbleGenerator.hpp CRumbleGenerator.cpp + CRumbleVoice.hpp CRumbleVoice.cpp) diff --git a/Runtime/Input/CRumbleGenerator.cpp b/Runtime/Input/CRumbleGenerator.cpp new file mode 100644 index 000000000..24c7861df --- /dev/null +++ b/Runtime/Input/CRumbleGenerator.cpp @@ -0,0 +1,8 @@ +#include "CRumbleGenerator.hpp" + +namespace pshag +{ +CRumbleGenerator::CRumbleGenerator() +{ +} +} diff --git a/Runtime/Input/CRumbleGenerator.hpp b/Runtime/Input/CRumbleGenerator.hpp new file mode 100644 index 000000000..e9c2ca247 --- /dev/null +++ b/Runtime/Input/CRumbleGenerator.hpp @@ -0,0 +1,17 @@ +#ifndef CRUMBLEGENERATOR_HPP +#define CRUMBLEGENERATOR_HPP + +#include "CRumbleVoice.hpp" + +namespace pshag +{ +class CRumbleGenerator +{ +public: + CRumbleGenerator(); + void Update(float); + void HardStopAll(); +}; +} + +#endif // CRUMBLEGENERATOR_HPP diff --git a/Runtime/Input/CRumbleManager.cpp b/Runtime/Input/CRumbleManager.cpp new file mode 100644 index 000000000..f5a0c7618 --- /dev/null +++ b/Runtime/Input/CRumbleManager.cpp @@ -0,0 +1,8 @@ +#include "CRumbleManager.hpp" + +namespace pshag +{ + +void CRumbleManager::Update(float dt) { x0_rumbleGenerator.Update(dt); } + +} diff --git a/Runtime/Input/CRumbleManager.hpp b/Runtime/Input/CRumbleManager.hpp new file mode 100644 index 000000000..cb19adf68 --- /dev/null +++ b/Runtime/Input/CRumbleManager.hpp @@ -0,0 +1,21 @@ +#ifndef __PSHAG_CRUMBLEMANAGER_HPP__ +#define __PSHAG_CRUMBLEMANAGER_HPP__ + +#include "CRumbleGenerator.hpp" + +namespace pshag +{ +class CStateManager; +class CRumbleManager +{ + CRumbleGenerator x0_rumbleGenerator; +public: + CRumbleManager() = default; + void Update(float); + void StopRumble(u16) {} + void Rumble(ERumbleFxId, CStateManager&, ERumblePriority priority); + void Rumble(ERumbleFxId, float, CStateManager&, ERumblePriority priority); +}; +} + +#endif // __PSHAG_CRUMBLEMANAGER_HPP__ diff --git a/Runtime/Input/CRumbleVoice.cpp b/Runtime/Input/CRumbleVoice.cpp new file mode 100644 index 000000000..77ed2dfb1 --- /dev/null +++ b/Runtime/Input/CRumbleVoice.cpp @@ -0,0 +1,5 @@ +#include "CRumbleVoice.hpp" + +namespace pshag +{ +} diff --git a/Runtime/Input/CRumbleVoice.hpp b/Runtime/Input/CRumbleVoice.hpp new file mode 100644 index 000000000..1f61917c3 --- /dev/null +++ b/Runtime/Input/CRumbleVoice.hpp @@ -0,0 +1,76 @@ +#ifndef CRUMBLEVOICE_HPP +#define CRUMBLEVOICE_HPP + +#include "RetroTypes.hpp" + +namespace pshag +{ +enum class ERumbleFxId +{ + +}; +enum class ERumblePriority +{ + None +}; + +struct SAdsrData; +class CRumbleVoice +{ +public: + CRumbleVoice() {} + CRumbleVoice(const SAdsrData& data); +}; + +struct SAdsrData +{ + float x0 = 0.f; + float x4 = 0.f; + float x8 = 0.f; + float xc = 0.f; + float x10 = 0.f; + float x14 = 0.f; + union + { + struct { bool x18_24 : 1; bool x18_25 : 1; }; + u8 dummy = 0; + }; + + SAdsrData() = default; + SAdsrData(float a, float b, float c, float d, float e, float f, bool g, bool h) + : x0(a), x4(b), x8(c), xc(d), x10(e), x14(f) + { + x18_24 = g; + x18_25 = h; + } +}; + +struct SAdsrDelta +{ + enum class EPhase + { + Stop, + Start, + }; + + float x0 = 0.f; + float x4 = 0.f; + float x8 = 0.f; + float xc = 0.f; + float x10 = 0.f; + ERumblePriority x1c_priority; + EPhase x20_phase; + + SAdsrDelta(EPhase phase, ERumblePriority priority) + : x1c_priority(priority), x20_phase(phase) + {} + SAdsrDelta(EPhase phase) + : x1c_priority(ERumblePriority::None), x20_phase(phase) + {} + + static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); } + static SAdsrDelta Start(ERumblePriority priority) { return SAdsrDelta(EPhase::Start, priority); } +}; +} + +#endif // CRUMBLEVOICE_HPP diff --git a/Runtime/MP1/main.cpp b/Runtime/MP1/main.cpp index 37ecaf0a2..9df03844a 100644 --- a/Runtime/MP1/main.cpp +++ b/Runtime/MP1/main.cpp @@ -98,7 +98,7 @@ public: } }; -class CGameArchitectureSupport +class CGameArchitectureSupport : public boo::IWindowCallback { CArchitectureQueue m_archQueue; CAudioSys m_audioSys; @@ -109,6 +109,38 @@ class CGameArchitectureSupport CMainFlow m_mainFlow; CConsoleOutputWindow m_consoleWindow; CAudioStateWin m_audioStateWin; + boo::SWindowRect m_windowRect; + bool m_rectIsDirty; + + void mouseDown(const boo::SWindowCoord &coord, boo::EMouseButton button, boo::EModifierKey mods) + { m_inputGenerator.mouseDown(coord, button, mods); } + void mouseUp(const boo::SWindowCoord &coord, boo::EMouseButton button, boo::EModifierKey mods) + { m_inputGenerator.mouseUp(coord, button, mods); } + void mouseMove(const boo::SWindowCoord &coord) + { m_inputGenerator.mouseMove(coord); } + void scroll(const boo::SWindowCoord &coord, const boo::SScrollDelta &scroll) + { m_inputGenerator.scroll(coord, scroll); } + void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat) + { m_inputGenerator.charKeyDown(charCode, mods, isRepeat); } + void charKeyUp(unsigned long charCode, boo::EModifierKey mods) + { m_inputGenerator.charKeyUp(charCode, mods); } + void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) + { m_inputGenerator.specialKeyDown(key, mods, isRepeat); } + void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) + { m_inputGenerator.specialKeyUp(key, mods); } + void modKeyDown(boo::EModifierKey mod, bool isRepeat) + { m_inputGenerator.modKeyDown(mod, isRepeat);} + void modKeyUp(boo::EModifierKey mod) + { m_inputGenerator.modKeyUp(mod); } + + void destroyed() { m_archQueue.Push(std::move(MakeMsg::CreateApplicationExit(EArchMsgTarget::ArchitectureSupport))); } + + void resized(const boo::SWindowRect &rect) + { + m_windowRect = rect; + m_rectIsDirty = true; + } + public: CGameArchitectureSupport() : m_audioSys(0,0,0,0,0), @@ -120,8 +152,33 @@ public: bool Update() { bool finished = false; + m_inputGenerator.Update(1.0 / 60.0, m_archQueue); + + while(m_archQueue) + { + CArchitectureMessage msg = m_archQueue.Pop(); + if (msg.GetTarget() == EArchMsgTarget::ArchitectureSupport) + { + if (msg.GetType() == EArchMsgType::ApplicationExit) + finished = true; + } + + if (msg.GetTarget() == EArchMsgTarget::Game && msg.GetType() == EArchMsgType::UserInput) + { + const CArchMsgParmUserInput* input = msg.GetParm(); + if (input->x4_parm.DStart()) + m_archQueue.Push(std::move(MakeMsg::CreateApplicationExit(EArchMsgTarget::ArchitectureSupport))); + } + } return finished; } + + bool isRectDirty() { return m_rectIsDirty; } + const boo::SWindowRect& getWindowRect() + { + m_rectIsDirty = false; + return m_windowRect; + } }; CMain::CMain() @@ -167,7 +224,7 @@ void CMain::LoadAudio() int CMain::appMain(boo::IApplication* app) { Zeus::detectCPU(); - mainWindow = app->newWindow(_S("Metroid Prime 1 Reimplementation vZygote")); + mainWindow = app->newWindow(_S("Metroid Prime 1 Reimplementation vZygote"), 1); mainWindow->showWindow(); TOneStatic globalObjs; InitializeSubsystems(); @@ -177,25 +234,31 @@ int CMain::appMain(boo::IApplication* app) g_TweakManager->ReadFromMemoryCard("AudioTweaks"); FillInAssetIDs(); TOneStatic archSupport; + mainWindow->setCallback(archSupport.GetAllocSpace()); boo::IGraphicsCommandQueue* gfxQ = mainWindow->getCommandQueue(); - float rgba[4] = { 0.5f, 0.5f, 0.5f, 1.0f}; + boo::SWindowRect windowRect = mainWindow->getWindowFrame(); + boo::ITextureR* renderTex = mainWindow->getMainContextDataFactory()->newRenderTexture(windowRect.size[0], windowRect.size[1]); + float rgba[4] = { 0.2f, 0.2f, 0.2f, 1.0f}; gfxQ->setClearColor(rgba); - float time = 0.0f; - int frame = 0; - CTimeProvider test(time); - while (!xe8_b24_finished) { - mainWindow->waitForRetrace(); xe8_b24_finished = archSupport->Update(); + + if (archSupport->isRectDirty()) + { + const boo::SWindowRect& windowRect = archSupport->getWindowRect(); + gfxQ->resizeRenderTexture(renderTex, + windowRect.size[0], + windowRect.size[1]); + } + + gfxQ->setRenderTarget(renderTex); gfxQ->clearTarget(); - + gfxQ->resolveDisplay(renderTex); gfxQ->execute(); - - time = (frame++) / 60.f; - //fprintf(stderr, "%f\n", test.x0_currentTime); + mainWindow->waitForRetrace(); } return 0; } diff --git a/Runtime/Particle/CDecalDataFactory.cpp b/Runtime/Particle/CDecalDataFactory.cpp index 33d01bb1f..a35fdd1ce 100644 --- a/Runtime/Particle/CDecalDataFactory.cpp +++ b/Runtime/Particle/CDecalDataFactory.cpp @@ -1,12 +1,146 @@ #include "CDecalDataFactory.hpp" #include "CDecalDescription.hpp" +#include "CGenDescription.hpp" +#include "CSwooshDescription.hpp" +#include "CElectricDescription.hpp" +#include "CParticleDataFactory.hpp" +#include "CModel.hpp" #include "CSimplePool.hpp" +#include "CRandom16.hpp" namespace pshag { -std::unique_ptr FDealDataFactory(const SObjectTag &tag, CInputStream &in, const CVParamTransfer &vparms) +static LogVisor::LogModule Log("pshag::CDecalDataFactory"); + +using CPF = CParticleDataFactory; +CDecalDescription* CDecalDataFactory::GetGeneratorDesc(CInputStream& in, CSimplePool* resPool) +{ + return CreateGeneratorDescription(in, resPool); +} + +CDecalDescription* CDecalDataFactory::CreateGeneratorDescription(CInputStream& in, CSimplePool* resPool) +{ + FourCC clsId = CPF::GetClassID(in); + if (clsId == FOURCC('DPSM')) + { + CDecalDescription* desc = new CDecalDescription; + if (CreateDPSM(desc, in, resPool)) + return desc; + else + delete desc; + } + return nullptr; +} + + +bool CDecalDataFactory::CreateDPSM(CDecalDescription* desc, CInputStream& in, CSimplePool* resPool) +{ + CRandom16 rand{99}; + CGlobalRandom gr{rand}; + FourCC clsId = CPF::GetClassID(in); + + while (clsId != SBIG('_END')) + { + bool loadFirstDesc = false; + switch (clsId) + { + case SBIG('1SZE'): + case SBIG('1LFT'): + case SBIG('1ROT'): + case SBIG('1OFF'): + case SBIG('1CLR'): + case SBIG('1TEX'): + case SBIG('1ADD'): + loadFirstDesc = true; + case SBIG('2LFT'): + case SBIG('2SZE'): + case SBIG('2ROT'): + case SBIG('2OFF'): + case SBIG('2CLR'): + case SBIG('2TEX'): + case SBIG('2ADD'): + if (loadFirstDesc) + GetQuadDecalInfo(in, resPool, clsId, desc->x0_Quad); + else + GetQuadDecalInfo(in, resPool, clsId, desc->x1c_Quad); + break; + + case SBIG('DMDL'): + desc->x38_DMDL = CPF::GetModel(in, resPool); + break; + case SBIG('DFLT'): + desc->x48_DFLT.reset(CPF::GetIntElement(in)); + break; + case SBIG('DMOP'): + desc->x4c_DMOP.reset(CPF::GetVectorElement(in)); + break; + case SBIG('DMRT'): + desc->x50_DMRT.reset(CPF::GetVectorElement(in)); + break; + case SBIG('DMSC'): + desc->x54_DMSC.reset(CPF::GetVectorElement(in)); + break; + case SBIG('DMCL'): + desc->x58_DMCL.reset(CPF::GetColorElement(in)); + break; + case SBIG('DMAB'): + desc->x5c_24_DMAB = CPF::GetBool(in); + break; + case SBIG('DMOO'): + desc->x5c_25_DMOO = CPF::GetBool(in); + break; + default: + { + uint32_t clsName = clsId.toUint32(); + Log.report(LogVisor::FatalError, "Unknown DPSC class %.4s @%" PRIi64, &clsName, in.position()); + return false; + } + } + + clsId = CPF::GetClassID(in); + } + return true; +} + +void CDecalDataFactory::GetQuadDecalInfo(CInputStream& in, CSimplePool* resPool, FourCC clsId, SQuadDescr& quad) +{ + switch (clsId) + { + case SBIG('1LFT'): + case SBIG('2LFT'): + quad.x0_LFT.reset(CPF::GetIntElement(in)); + break; + case SBIG('1SZE'): + case SBIG('2SZE'): + quad.x4_SZE.reset(CPF::GetRealElement(in)); + break; + case SBIG('1ROT'): + case SBIG('2ROT'): + quad.x8_ROT.reset(CPF::GetRealElement(in)); + break; + case SBIG('1OFF'): + case SBIG('2OFF'): + quad.xc_OFF.reset(CPF::GetVectorElement(in)); + break; + case SBIG('1CLR'): + case SBIG('2CLR'): + quad.x10_CLR.reset(CPF::GetColorElement(in)); + break; + case SBIG('1TEX'): + case SBIG('2TEX'): + quad.x14_TEX.reset(CPF::GetTextureElement(in, resPool)); + break; + case SBIG('1ADD'): + case SBIG('2ADD'): + quad.x18_ADD = CPF::GetBool(in); + break; + } +} + +std::unique_ptr FDecalDataFactory(const SObjectTag &tag, CInputStream &in, const CVParamTransfer &vparms) { CSimplePool* sp = static_cast(static_cast*>(vparms.GetObj())->GetParam()); return TToken::GetIObjObjectFor(std::unique_ptr(CDecalDataFactory::GetGeneratorDesc(in, sp))); } + } diff --git a/Runtime/Particle/CDecalDataFactory.hpp b/Runtime/Particle/CDecalDataFactory.hpp index 7d3426f2f..586399c23 100644 --- a/Runtime/Particle/CDecalDataFactory.hpp +++ b/Runtime/Particle/CDecalDataFactory.hpp @@ -9,17 +9,19 @@ namespace pshag { +struct SQuadDescr; class CDecalDescription; class CSimplePool; class CDecalDataFactory { + static bool CreateDPSM(CDecalDescription* desc,CInputStream& in,CSimplePool* resPool); + static CDecalDescription* CreateGeneratorDescription(CInputStream& in, CSimplePool* resPool); + static void GetQuadDecalInfo(CInputStream& in, CSimplePool* resPool, FourCC clsId, SQuadDescr& quad); public: static CDecalDescription* GetGeneratorDesc(CInputStream& in,CSimplePool* resPool); - static CDecalDescription* CreateGeneratorDescription(CInputStream& in, CSimplePool* resPool); - static bool CreateDPSM(CDecalDescription* desc,CInputStream& in,CSimplePool* resPool); }; -std::unique_ptr FDealDataFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms); +std::unique_ptr FDecalDataFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms); } #endif // __PSHAG_CDECALDATAFACTORY_HPP__ diff --git a/Runtime/Particle/CDecalDescription.hpp b/Runtime/Particle/CDecalDescription.hpp index 8c0fc81ca..75bb0aa83 100644 --- a/Runtime/Particle/CDecalDescription.hpp +++ b/Runtime/Particle/CDecalDescription.hpp @@ -1,10 +1,42 @@ #ifndef __PSHAG_CDECALDESCRIPTION_HPP__ #define __PSHAG_CDECALDESCRIPTION_HPP__ +#include "CRealElement.hpp" +#include "CIntElement.hpp" +#include "CVectorElement.hpp" +#include "CColorElement.hpp" +#include "CUVElement.hpp" +#include "CParticleDataFactory.hpp" + namespace pshag { +struct SQuadDescr +{ + std::unique_ptr x0_LFT; + std::unique_ptr x4_SZE; + std::unique_ptr x8_ROT; + std::unique_ptr xc_OFF; + std::unique_ptr x10_CLR; + std::unique_ptr x14_TEX; + bool x18_ADD = false; +}; + class CDecalDescription { +public: + SQuadDescr x0_Quad; + SQuadDescr x1c_Quad; + SParticleModel x38_DMDL; + std::unique_ptr x48_DFLT; + std::unique_ptr x4c_DMOP; + std::unique_ptr x50_DMRT; + std::unique_ptr x54_DMSC; + std::unique_ptr x58_DMCL; + union + { + struct { bool x5c_24_DMAB : 1; bool x5c_25_DMOO : 1;}; + u8 dummy = 0; + }; }; } diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index f50ad12c7..5f7cdd5fb 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -185,10 +185,16 @@ void CElementGenShaders::Initialize() case boo::IGraphicsDataFactory::Platform::D3D12: m_bindFactory.reset(Initialize(*static_cast(CGraphics::g_BooFactory))); break; -#elif BOO_HAS_METAL +#endif +#if BOO_HAS_METAL case boo::IGraphicsDataFactory::Platform::Metal: m_bindFactory.reset(Initialize(*static_cast(CGraphics::g_BooFactory))); break; +#endif +#if BOO_HAS_VULKAN + case boo::IGraphicsDataFactory::Platform::Vulkan: + m_bindFactory.reset(Initialize(*static_cast(CGraphics::g_BooFactory))); + break; #endif default: break; } @@ -1706,11 +1712,11 @@ void CElementGen::RenderParticles() { case CElementGenShaders::EShaderClass::Tex: m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex)); - CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instTexData.size()); + CGraphics::DrawInstances(0, 4, g_instTexData.size()); break; case CElementGenShaders::EShaderClass::NoTex: m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex)); - CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instNoTexData.size()); + CGraphics::DrawInstances(0, 4, g_instNoTexData.size()); break; default: break; } @@ -1845,11 +1851,11 @@ void CElementGen::RenderParticles() { case CElementGenShaders::EShaderClass::Tex: m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex)); - CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instTexData.size()); + CGraphics::DrawInstances(0, 4, g_instTexData.size()); break; case CElementGenShaders::EShaderClass::NoTex: m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex)); - CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instNoTexData.size()); + CGraphics::DrawInstances(0, 4, g_instNoTexData.size()); break; default: break; } diff --git a/Runtime/Particle/CElementGenShaders.hpp b/Runtime/Particle/CElementGenShaders.hpp index 3c7977fd0..f2eab5303 100644 --- a/Runtime/Particle/CElementGenShaders.hpp +++ b/Runtime/Particle/CElementGenShaders.hpp @@ -5,6 +5,7 @@ #include "boo/graphicsdev/GL.hpp" #include "boo/graphicsdev/D3D.hpp" #include "boo/graphicsdev/Metal.hpp" +#include "boo/graphicsdev/Vulkan.hpp" namespace pshag { @@ -63,9 +64,13 @@ public: static IDataBindingFactory* Initialize(boo::GLDataFactory& factory); #if _WIN32 static IDataBindingFactory* Initialize(boo::ID3DDataFactory& factory); -#elif BOO_HAS_METAL +#endif +#if BOO_HAS_METAL static IDataBindingFactory* Initialize(boo::MetalDataFactory& factory); #endif +#if BOO_HAS_VULKAN + static IDataBindingFactory* Initialize(boo::VulkanDataFactory& factory); +#endif static void Initialize(); static void Shutdown(); diff --git a/Runtime/Particle/CElementGenShadersGLSL.cpp b/Runtime/Particle/CElementGenShadersGLSL.cpp index e387204e5..dad9140b6 100644 --- a/Runtime/Particle/CElementGenShadersGLSL.cpp +++ b/Runtime/Particle/CElementGenShadersGLSL.cpp @@ -10,11 +10,12 @@ namespace pshag static const char* VS_GLSL_TEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "layout(location=0) in vec4 posIn[4];\n" "layout(location=4) in vec4 colorIn;\n" "layout(location=5) in vec4 uvsIn[4];\n" "\n" -"uniform ParticleUniform\n" +"UBINDING0 uniform ParticleUniform\n" "{\n" " mat4 mvp;\n" " vec4 moduColor;\n" @@ -36,6 +37,7 @@ static const char* VS_GLSL_TEX = static const char* FS_GLSL_TEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "struct VertToFrag\n" "{\n" " vec4 color;\n" @@ -44,7 +46,7 @@ static const char* FS_GLSL_TEX = "\n" "in VertToFrag vtf;\n" "layout(location=0) out vec4 colorOut;\n" -"uniform sampler2D texs[1];\n" +"TBINDING0 uniform sampler2D texs[1];\n" "void main()\n" "{\n" " colorOut = vtf.color * texture(texs[0], vtf.uv);\n" @@ -52,6 +54,7 @@ static const char* FS_GLSL_TEX = static const char* FS_GLSL_TEX_REDTOALPHA = "#version 330\n" +BOO_GLSL_BINDING_HEAD "struct VertToFrag\n" "{\n" " vec4 color;\n" @@ -60,7 +63,7 @@ static const char* FS_GLSL_TEX_REDTOALPHA = "\n" "in VertToFrag vtf;\n" "layout(location=0) out vec4 colorOut;\n" -"uniform sampler2D texs[1];\n" +"TBINDING0 uniform sampler2D texs[1];\n" "void main()\n" "{\n" " colorOut = vtf.color * texture(texs[0], vtf.uv);\n" @@ -69,12 +72,13 @@ static const char* FS_GLSL_TEX_REDTOALPHA = static const char* VS_GLSL_INDTEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "layout(location=0) in vec4 posIn[4];\n" "layout(location=4) in vec4 colorIn;\n" "layout(location=5) in vec4 uvsInTexrTind[4];\n" "layout(location=9) in vec2 uvsInScene[4];\n" "\n" -"uniform ParticleUniform\n" +"UBINDING0 uniform ParticleUniform\n" "{\n" " mat4 mvp;\n" " vec4 moduColor;\n" @@ -100,6 +104,7 @@ static const char* VS_GLSL_INDTEX = static const char* FS_GLSL_INDTEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "struct VertToFrag\n" "{\n" " vec4 color;\n" @@ -110,7 +115,7 @@ static const char* FS_GLSL_INDTEX = "\n" "in VertToFrag vtf;\n" "layout(location=0) out vec4 colorOut;\n" -"uniform sampler2D texs[3];\n" +"TBINDING0 uniform sampler2D texs[3];\n" "void main()\n" "{\n" " vec2 tindTexel = texture(texs[2], vtf.uvTind).ba;\n" @@ -122,6 +127,7 @@ static const char* FS_GLSL_INDTEX = static const char* FS_GLSL_CINDTEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "struct VertToFrag\n" "{\n" " vec4 color;\n" @@ -132,7 +138,7 @@ static const char* FS_GLSL_CINDTEX = "\n" "in VertToFrag vtf;\n" "layout(location=0) out vec4 colorOut;\n" -"uniform sampler2D texs[3];\n" +"TBINDING0 uniform sampler2D texs[3];\n" "void main()\n" "{\n" " vec2 tindTexel = texture(texs[2], vtf.uvTind).ba;\n" @@ -142,10 +148,11 @@ static const char* FS_GLSL_CINDTEX = static const char* VS_GLSL_NOTEX = "#version 330\n" +BOO_GLSL_BINDING_HEAD "layout(location=0) in vec4 posIn[4];\n" "layout(location=4) in vec4 colorIn;\n" "\n" -"uniform ParticleUniform\n" +"UBINDING0 uniform ParticleUniform\n" "{\n" " mat4 mvp;\n" " vec4 moduColor;\n" @@ -177,7 +184,7 @@ static const char* FS_GLSL_NOTEX = " colorOut = vtf.color;\n" "}\n"; -struct GLSLElementDataBindingFactory : CElementGenShaders::IDataBindingFactory +struct OGLElementDataBindingFactory : CElementGenShaders::IDataBindingFactory { void BuildShaderDataBinding(CElementGen& gen, boo::IShaderPipeline* regPipeline, @@ -333,7 +340,161 @@ CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::GLD boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, false, false, false); - return new struct GLSLElementDataBindingFactory; + return new struct OGLElementDataBindingFactory; } +#if BOO_HAS_VULKAN +struct VulkanElementDataBindingFactory : CElementGenShaders::IDataBindingFactory +{ + void BuildShaderDataBinding(CElementGen& gen, + boo::IShaderPipeline* regPipeline, + boo::IShaderPipeline* redToAlphaPipeline) + { + CGenDescription* desc = gen.GetDesc(); + + CUVElement* texr = desc->x54_TEXR.get(); + CUVElement* tind = desc->x58_TIND.get(); + int texCount = 0; + boo::ITexture* textures[3]; + + if (texr) + { + textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture(); + texCount = 1; + if (tind) + { + textures[1] = CGraphics::g_SpareTexture; + textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture(); + texCount = 3; + } + } + + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + + if (regPipeline) + gen.m_normalDataBind = CGraphics::g_BooFactory->newShaderDataBinding(regPipeline, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + texCount, textures); + if (redToAlphaPipeline) + gen.m_redToAlphaDataBind = CGraphics::g_BooFactory->newShaderDataBinding(redToAlphaPipeline, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + texCount, textures); + } +}; + +CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::VulkanDataFactory& factory) +{ + static const boo::VertexElementDescriptor TexFmtTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3} + }; + m_vtxFormatTex = factory.newVertexFormat(9, TexFmtTex); + + static const boo::VertexElementDescriptor TexFmtIndTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 4}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 5}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 6}, + {nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 7} + }; + m_vtxFormatIndTex = CGraphics::g_BooFactory->newVertexFormat(13, TexFmtIndTex); + + static const boo::VertexElementDescriptor TexFmtNoTex[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} + }; + m_vtxFormatNoTex = CGraphics::g_BooFactory->newVertexFormat(5, TexFmtNoTex); + + m_texZTestZWrite = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, true, false); + m_texNoZTestZWrite = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, true, false); + m_texZTestNoZWrite = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, false, false); + m_texNoZTestNoZWrite = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, false, false); + + m_texAdditiveZTest = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + true, false, false); + m_texAdditiveNoZTest = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + false, false, false); + + m_texRedToAlphaZTest = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, false, false); + m_texRedToAlphaNoZTest = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, false, false); + + m_indTexZWrite = factory.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, true, false); + m_indTexNoZWrite = factory.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, false, false); + m_indTexAdditive = factory.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + true, true, false); + + m_cindTexZWrite = factory.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_CINDTEX, m_vtxFormatIndTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, true, false); + m_cindTexNoZWrite = factory.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_CINDTEX, m_vtxFormatIndTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, false, false); + m_cindTexAdditive = factory.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_CINDTEX, m_vtxFormatIndTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + true, true, false); + + m_noTexZTestZWrite = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, true, false); + m_noTexNoZTestZWrite = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, true, false); + m_noTexZTestNoZWrite = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + true, false, false); + m_noTexNoZTestNoZWrite = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, false, false); + + m_noTexAdditiveZTest = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + true, false, false); + m_noTexAdditiveNoZTest = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + false, false, false); + + return new struct VulkanElementDataBindingFactory; +} +#endif + } diff --git a/Runtime/Particle/CParticleElectricDataFactory.cpp b/Runtime/Particle/CParticleElectricDataFactory.cpp index a5c847c4c..47e548736 100644 --- a/Runtime/Particle/CParticleElectricDataFactory.cpp +++ b/Runtime/Particle/CParticleElectricDataFactory.cpp @@ -132,7 +132,7 @@ void CParticleElectricDataFactory::LoadELSMTokens(CElectricDescription* desc) desc->x60_EPSM.m_gen = desc->x60_EPSM.m_token.GetObj(); } -std::unique_ptr FParticleElecrticFactory(const pshag::SObjectTag &tag, pshag::CInputStream &in, const pshag::CVParamTransfer &vparms) +std::unique_ptr FParticleElectricDataFactory(const SObjectTag &tag, CInputStream &in, const CVParamTransfer &vparms) { CSimplePool* sp = static_cast(static_cast*>(vparms.GetObj())->GetParam()); return TToken::GetIObjObjectFor(std::unique_ptr(CParticleElectricDataFactory::GetGeneratorDesc(in, sp))); diff --git a/Runtime/Particle/CParticleSwooshDataFactory.cpp b/Runtime/Particle/CParticleSwooshDataFactory.cpp index c8b3431f0..f4cc0759c 100644 --- a/Runtime/Particle/CParticleSwooshDataFactory.cpp +++ b/Runtime/Particle/CParticleSwooshDataFactory.cpp @@ -23,8 +23,10 @@ CSwooshDescription*CParticleSwooshDataFactory::CreateGeneratorDescription(CInput if (clsId == FOURCC('SWSH')) { CSwooshDescription* desc = new CSwooshDescription; - CreateWPSM(desc, in, resPool); - return desc; + if (CreateWPSM(desc, in, resPool)) + return desc; + else + delete desc; } return nullptr; } diff --git a/Runtime/Particle/CProjectileWeaponDataFactory.cpp b/Runtime/Particle/CProjectileWeaponDataFactory.cpp index fa47bc7cb..d32a03a45 100644 --- a/Runtime/Particle/CProjectileWeaponDataFactory.cpp +++ b/Runtime/Particle/CProjectileWeaponDataFactory.cpp @@ -78,6 +78,9 @@ bool CProjectileWeaponDataFactory::CreateWPSM(CWeaponDescription* desc, CInputSt desc->x2a_AP11 = CPF::GetBool(in); break; case SBIG('AP21'): + desc->x2b_AP21 = CPF::GetBool(in); + break; + case SBIG('AS11'): desc->x2c_AS11 = CPF::GetBool(in); break; case SBIG('AS12'): diff --git a/Runtime/RetroTypes.hpp b/Runtime/RetroTypes.hpp index 3e4b16683..18a1c8e6b 100644 --- a/Runtime/RetroTypes.hpp +++ b/Runtime/RetroTypes.hpp @@ -12,7 +12,7 @@ namespace pshag { using FourCC = HECL::FourCC; -using TResId = u32; +using TResId = u64; struct SObjectTag { diff --git a/hecl b/hecl index 92604d9ce..47e723844 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 92604d9ce5c32aa9a7c58603683b43f2064850b5 +Subproject commit 47e72384415a5062cc0358512a272fc939aa1514 diff --git a/libSpecter b/libSpecter index 38b3396e0..bb78a2055 160000 --- a/libSpecter +++ b/libSpecter @@ -1 +1 @@ -Subproject commit 38b3396e0853e9bf446859a9d8b042044d9fd78e +Subproject commit bb78a20553ea665c0ec301404dce0c6753b8eb09