From 8e7773aa942c0e0c524aaf253aae5700970f099a Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 19 Mar 2017 19:09:53 -1000 Subject: [PATCH] AutoMapper work --- DataSpec/DNACommon/CMakeLists.txt | 2 + DataSpec/DNACommon/DNACommon.cpp | 8 +- DataSpec/DNACommon/DNACommon.hpp | 22 +-- DataSpec/DNACommon/MAPA.cpp | 97 +++++++++++ DataSpec/DNACommon/MAPA.hpp | 3 + DataSpec/DNACommon/MAPU.cpp | 151 ++++++++++++++++++ DataSpec/DNACommon/MAPU.hpp | 48 ++++++ .../DNACommon/Tweaks/ITweakAutoMapper.hpp | 9 ++ DataSpec/DNACommon/Tweaks/ITweakGui.hpp | 1 + DataSpec/DNAMP1/CMakeLists.txt | 1 + DataSpec/DNAMP1/DNAMP1.cpp | 3 + DataSpec/DNAMP1/MAPA.hpp | 9 ++ DataSpec/DNAMP1/MAPU.hpp | 35 ++++ .../DNAMP1/ScriptObjects/CameraShaker.hpp | 2 +- .../DNAMP1/ScriptObjects/NewCameraShaker.hpp | 10 +- DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp | 21 ++- DataSpec/DNAMP1/Tweaks/CTweakGui.hpp | 3 +- DataSpec/DNAMP2/CMakeLists.txt | 1 + DataSpec/DNAMP2/DNAMP2.cpp | 3 + DataSpec/DNAMP2/MAPA.hpp | 9 ++ DataSpec/DNAMP2/MAPU.hpp | 35 ++++ DataSpec/DNAMP3/MAPA.hpp | 9 ++ DataSpec/SpecBase.cpp | 12 ++ DataSpec/SpecBase.hpp | 6 + DataSpec/SpecMP1.cpp | 22 +++ DataSpec/SpecMP2.cpp | 22 +++ DataSpec/SpecMP3.cpp | 17 ++ Runtime/AutoMapper/CAutoMapper.cpp | 137 ++++++++++++++++ Runtime/AutoMapper/CAutoMapper.hpp | 133 ++++++++++++--- Runtime/AutoMapper/CMapArea.cpp | 68 ++++++++ Runtime/AutoMapper/CMapArea.hpp | 5 +- Runtime/AutoMapper/CMapUniverse.hpp | 6 +- Runtime/AutoMapper/CMapWorld.cpp | 8 +- Runtime/AutoMapper/CMapWorld.hpp | 5 +- Runtime/AutoMapper/CMapWorldInfo.cpp | 8 +- Runtime/CObjectList.cpp | 4 +- Runtime/CStateManager.cpp | 18 ++- Runtime/CStateManager.hpp | 2 +- Runtime/Character/CModelData.cpp | 4 +- Runtime/Graphics/CBooRenderer.cpp | 16 +- Runtime/Graphics/CModel.hpp | 10 +- Runtime/Graphics/CModelBoo.cpp | 16 +- Runtime/GuiSys/CGuiFrame.cpp | 24 ++- Runtime/GuiSys/CGuiFrame.hpp | 7 +- Runtime/GuiSys/CGuiLight.cpp | 5 +- Runtime/GuiSys/CGuiModel.cpp | 8 +- Runtime/MP1/CInGameGuiManager.cpp | 2 +- Runtime/World/CActor.cpp | 13 +- Runtime/World/CActor.hpp | 7 +- Runtime/World/CMakeLists.txt | 1 + Runtime/World/CMorphBallShadow.cpp | 8 +- Runtime/World/CPlayer.cpp | 5 + Runtime/World/CPlayer.hpp | 3 +- Runtime/World/CPlayerCameraBob.hpp | 2 +- Runtime/World/CScriptActor.cpp | 28 ++-- Runtime/World/CScriptVisorFlare.cpp | 53 ++++++ Runtime/World/CScriptVisorFlare.hpp | 31 ++++ Runtime/World/CVisorFlare.cpp | 42 +++++ Runtime/World/CVisorFlare.hpp | 51 ++++++ Runtime/World/ScriptLoader.cpp | 21 ++- hecl | 2 +- specter | 2 +- visigen/VISIRenderer.cpp | 10 +- 63 files changed, 1181 insertions(+), 145 deletions(-) create mode 100644 DataSpec/DNACommon/MAPU.cpp create mode 100644 DataSpec/DNACommon/MAPU.hpp create mode 100644 DataSpec/DNAMP1/MAPU.hpp create mode 100644 DataSpec/DNAMP2/MAPU.hpp create mode 100644 Runtime/World/CVisorFlare.cpp create mode 100644 Runtime/World/CVisorFlare.hpp diff --git a/DataSpec/DNACommon/CMakeLists.txt b/DataSpec/DNACommon/CMakeLists.txt index 5633c42fc..576397aa5 100644 --- a/DataSpec/DNACommon/CMakeLists.txt +++ b/DataSpec/DNACommon/CMakeLists.txt @@ -1,6 +1,7 @@ make_dnalist(liblist DNACommon CMDL MAPA + MAPU EGMC SAVWCommon ParticleCommon @@ -14,6 +15,7 @@ set(DNACOMMON_SOURCES MLVL.hpp MLVL.cpp CMDL.cpp MAPA.cpp + MAPU.cpp STRG.hpp STRG.cpp TXTR.hpp TXTR.cpp ANCS.hpp diff --git a/DataSpec/DNACommon/DNACommon.cpp b/DataSpec/DNACommon/DNACommon.cpp index 49e711128..521d8bb02 100644 --- a/DataSpec/DNACommon/DNACommon.cpp +++ b/DataSpec/DNACommon/DNACommon.cpp @@ -90,7 +90,7 @@ void UniqueIDBridge::setThreadProject(hecl::Database::Project& project) /** PAK 32-bit Unique ID */ void UniqueID32::read(athena::io::IStreamReader& reader) -{m_id = reader.readUint32Big();} +{assign(reader.readUint32Big());} void UniqueID32::write(athena::io::IStreamWriter& writer) const {writer.writeUint32Big(m_id);} void UniqueID32::read(athena::io::YAMLDocReader& reader) @@ -120,7 +120,7 @@ std::string UniqueID32::toString() const AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path) { - m_id = path.ensureAuxInfo(m_auxStr).hash().val32(); + assign(path.ensureAuxInfo(m_auxStr).hash().val32()); return *this; } @@ -139,7 +139,7 @@ AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id) void AuxiliaryID32::read(athena::io::IStreamReader& reader) { - m_id = reader.readUint32Big(); + assign(reader.readUint32Big()); m_baseId = *this; } @@ -172,7 +172,7 @@ void AuxiliaryID32::write(athena::io::YAMLDocWriter& writer) const /** PAK 64-bit Unique ID */ void UniqueID64::read(athena::io::IStreamReader& reader) -{m_id = reader.readUint64Big();} +{assign(reader.readUint64Big());} void UniqueID64::write(athena::io::IStreamWriter& writer) const {writer.writeUint64Big(m_id);} void UniqueID64::read(athena::io::YAMLDocReader& reader) diff --git a/DataSpec/DNACommon/DNACommon.hpp b/DataSpec/DNACommon/DNACommon.hpp index f31d6360e..96bfec3e6 100644 --- a/DataSpec/DNACommon/DNACommon.hpp +++ b/DataSpec/DNACommon/DNACommon.hpp @@ -151,9 +151,10 @@ public: void read(athena::io::YAMLDocReader& reader); void write(athena::io::YAMLDocWriter& writer) const; size_t binarySize(size_t __isz) const; + void assign(uint32_t id) { m_id = id ? id : 0xffffffff; } UniqueID32& operator=(const hecl::ProjectPath& path) - {m_id = path.hash().val32(); return *this;} + {assign(path.hash().val32()); return *this;} bool operator!=(const UniqueID32& other) const {return m_id != other.m_id;} bool operator==(const UniqueID32& other) const {return m_id == other.m_id;} @@ -164,7 +165,7 @@ public: void clear() {m_id = 0xffffffff;} UniqueID32() = default; - UniqueID32(uint32_t idin) : m_id(idin) {} + UniqueID32(uint32_t idin) {assign(idin);} UniqueID32(athena::io::IStreamReader& reader) {read(reader);} UniqueID32(const hecl::ProjectPath& path) {*this = path;} UniqueID32(const char* hexStr) @@ -172,14 +173,14 @@ public: char copy[9]; strncpy(copy, hexStr, 8); copy[8] = '\0'; - m_id = strtoul(copy, nullptr, 16); + assign(strtoul(copy, nullptr, 16)); } UniqueID32(const wchar_t* hexStr) { wchar_t copy[9]; wcsncpy(copy, hexStr, 8); copy[8] = L'\0'; - m_id = wcstoul(copy, nullptr, 16); + assign(wcstoul(copy, nullptr, 16)); } static constexpr size_t BinarySize() {return 4;} @@ -216,9 +217,10 @@ public: void read(athena::io::YAMLDocReader& reader); void write(athena::io::YAMLDocWriter& writer) const; size_t binarySize(size_t __isz) const; + void assign(uint64_t id) { m_id = id ? id : 0xffffffffffffffff; } UniqueID64& operator=(const hecl::ProjectPath& path) - {m_id = path.hash().val64(); return *this;} + {assign(path.hash().val64()); return *this;} bool operator!=(const UniqueID64& other) const {return m_id != other.m_id;} bool operator==(const UniqueID64& other) const {return m_id == other.m_id;} @@ -228,7 +230,7 @@ public: void clear() {m_id = 0xffffffffffffffff;} UniqueID64() = default; - UniqueID64(uint64_t idin) : m_id(idin) {} + UniqueID64(uint64_t idin) {assign(idin);} UniqueID64(athena::io::IStreamReader& reader) {read(reader);} UniqueID64(const hecl::ProjectPath& path) {*this = path;} UniqueID64(const char* hexStr) @@ -237,9 +239,9 @@ public: strncpy(copy, hexStr, 16); copy[16] = '\0'; #if _WIN32 - m_id = _strtoui64(copy, nullptr, 16); + assign(_strtoui64(copy, nullptr, 16)); #else - m_id = strtouq(copy, nullptr, 16); + assign(strtouq(copy, nullptr, 16)); #endif } UniqueID64(const wchar_t* hexStr) @@ -248,9 +250,9 @@ public: wcsncpy(copy, hexStr, 16); copy[16] = L'\0'; #if _WIN32 - m_id = _wcstoui64(copy, nullptr, 16); + assign(_wcstoui64(copy, nullptr, 16)); #else - m_id = wcstoull(copy, nullptr, 16); + assign(wcstoull(copy, nullptr, 16)); #endif } diff --git a/DataSpec/DNACommon/MAPA.cpp b/DataSpec/DNACommon/MAPA.cpp index 4d1db0afe..c2858a2fc 100644 --- a/DataSpec/DNACommon/MAPA.cpp +++ b/DataSpec/DNACommon/MAPA.cpp @@ -2,7 +2,11 @@ #include "../DNAMP1/DNAMP1.hpp" #include "../DNAMP2/DNAMP2.hpp" #include "../DNAMP3/DNAMP3.hpp" +#include "../DNAMP1/MAPA.hpp" +#include "../DNAMP2/MAPA.hpp" +#include "../DNAMP3/MAPA.hpp" #include "zeus/CTransform.hpp" +#include "zeus/CAABox.hpp" namespace DataSpec { @@ -335,5 +339,98 @@ template bool ReadMAPAToBlender> const PAKRouter::EntryType& entry, bool force); +template +bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapaIn, const hecl::ProjectPath& out) +{ + MAPAType mapa; + mapa.magic = 0xDEADD00D; + mapa.version = MAPAType::Version(); + + zeus::CAABox aabb; + for (const hecl::BlenderConnection::DataStream::Vector3f& vert : mapaIn.verts) + aabb.accumulateBounds(vert.val); + + mapa.header = std::make_unique(); + memset((void*)mapa.header.get(), 0, sizeof(typename MAPAType::Header)); + typename MAPAType::Header& header = static_cast(*mapa.header); + header.unknown1 = 0; + header.unknown2 = 1; + header.boundingBox[0] = aabb.min; + header.boundingBox[1] = aabb.max; + header.moCount = mapaIn.pois.size(); + header.vtxCount = mapaIn.verts.size(); + header.surfCount = mapaIn.surfaces.size(); + + mapa.mappableObjects.reserve(mapaIn.pois.size()); + for (const hecl::BlenderConnection::DataStream::MapArea::POI& poi : mapaIn.pois) + { + mapa.mappableObjects.push_back(std::make_unique()); + typename MAPAType::MappableObject& mobj = + static_cast(*mapa.mappableObjects.back()); + mobj.type = MAPA::IMappableObject::Type(poi.type); + mobj.unknown1 = poi.unk; + mobj.sclyId = poi.objid; + mobj.transformMtx[0] = poi.xf.val[0]; + mobj.transformMtx[1] = poi.xf.val[1]; + mobj.transformMtx[2] = poi.xf.val[2]; + } + + mapa.vertices.reserve(mapaIn.verts.size()); + for (const hecl::BlenderConnection::DataStream::Vector3f& vert : mapaIn.verts) + mapa.vertices.push_back(vert.val); + + size_t offsetCur = 0; + for (const auto& mo : mapa.mappableObjects) + offsetCur = mo->binarySize(offsetCur); + offsetCur += mapa.vertices.size() * 12; + offsetCur += mapaIn.surfaces.size() * sizeof(DNAMAPA::MAPA::SurfaceHeader); + + mapa.surfaceHeaders.reserve(mapaIn.surfaces.size()); + mapa.surfaces.reserve(mapaIn.surfaces.size()); + for (const hecl::BlenderConnection::DataStream::MapArea::Surface& surfIn : mapaIn.surfaces) + { + mapa.surfaceHeaders.emplace_back(); + DNAMAPA::MAPA::SurfaceHeader& surfHead = mapa.surfaceHeaders.back(); + mapa.surfaces.emplace_back(); + DNAMAPA::MAPA::Surface& surf = mapa.surfaces.back(); + + surf.primitiveCount = 1; + surf.primitives.emplace_back(); + DNAMAPA::MAPA::Surface::Primitive& prim = surf.primitives.back(); + prim.type = GX::TRIANGLESTRIP; + prim.indexCount = surfIn.count; + prim.indices.reserve(surfIn.count); + auto itBegin = mapaIn.indices.begin() + surfIn.start.val; + auto itEnd = itBegin + surfIn.count; + for (auto it = itBegin ; it != itEnd ; ++it) + prim.indices.push_back(it->val); + + surf.borderCount = 1; + surf.borders.emplace_back(); + DNAMAPA::MAPA::Surface::Border& border = surf.borders.back(); + border.indexCount = surfIn.borderCount; + border.indices.reserve(surfIn.borderCount); + auto it2Begin = mapaIn.indices.begin() + surfIn.borderStart.val; + auto it2End = itBegin + surfIn.borderCount; + for (auto it = it2Begin ; it != it2End ; ++it) + border.indices.push_back(it->val); + + surfHead.normal = surfIn.normal.val; + surfHead.centroid = surfIn.centerOfMass; + surfHead.polyOff = offsetCur; + offsetCur = prim.binarySize(offsetCur + 4); + surfHead.edgeOff = offsetCur; + offsetCur = border.binarySize(offsetCur + 4); + } + + athena::io::FileWriter f(out.getAbsolutePath()); + mapa.write(f); + return true; +} + +template bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out); +template bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out); +template bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out); + } } diff --git a/DataSpec/DNACommon/MAPA.hpp b/DataSpec/DNACommon/MAPA.hpp index 479f07c81..4d03a10ac 100644 --- a/DataSpec/DNACommon/MAPA.hpp +++ b/DataSpec/DNACommon/MAPA.hpp @@ -188,6 +188,9 @@ bool ReadMAPAToBlender(hecl::BlenderConnection& conn, const typename PAKRouter::EntryType& entry, bool force); +template +bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out); + } } diff --git a/DataSpec/DNACommon/MAPU.cpp b/DataSpec/DNACommon/MAPU.cpp new file mode 100644 index 000000000..08e3d4304 --- /dev/null +++ b/DataSpec/DNACommon/MAPU.cpp @@ -0,0 +1,151 @@ +#include "MAPU.hpp" +#include "../DNAMP1/DNAMP1.hpp" +#include "../DNAMP2/DNAMP2.hpp" +#include "../DNAMP3/DNAMP3.hpp" +#include "zeus/CTransform.hpp" + +namespace DataSpec +{ +namespace DNAMAPU +{ + +template +bool ReadMAPUToBlender(hecl::BlenderConnection& conn, + const MAPU& mapu, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const typename PAKRouter::EntryType& entry, + bool force) +{ + if (!force && outPath.isFile()) + return true; + + if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::MapUniverse)) + return false; + hecl::BlenderConnection::PyOutStream os = conn.beginPythonOut(true); + + os << "import bpy\n" + "from mathutils import Matrix\n" + "\n" + "# Clear Scene\n" + "bpy.context.scene.camera = None\n" + "for ob in bpy.data.objects:\n" + " bpy.context.scene.objects.unlink(ob)\n" + " bpy.data.objects.remove(ob)\n" + "\n" + "bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color'," + " description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n" + "bpy.types.Object.retro_mapworld_path = bpy.props.StringProperty(name='Retro: MapWorld Path'," + " description='Sets path to World root')\n" + "\n"; + + hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa); + os.linkBlend(hexPath.getAbsolutePathUTF8().c_str(), + pakRouter.getBestEntryName(mapu.hexMapa).c_str()); + os << "hexMesh = bpy.data.objects['MAP'].data\n"; + + for (const MAPU::World& wld : mapu.worlds) + { + hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(wld.mlvl); + const MAPU::Transform& wldXf = wld.transform; + os.format("wldObj = bpy.data.objects.new('%s', None)\n" + "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" + "mtxd = mtx.decompose()\n" + "wldObj.rotation_mode = 'QUATERNION'\n" + "wldObj.location = mtxd[0]\n" + "wldObj.rotation_quaternion = mtxd[1]\n" + "wldObj.scale = mtxd[2]\n" + "wldObj.retro_mapworld_color = (%f, %f, %f, %f)\n" + "wldObj.retro_mapworld_path = '''%s'''\n" + "bpy.context.scene.objects.link(wldObj)\n", wld.name.c_str(), + wldXf.xf[0].vec[0], wldXf.xf[0].vec[1], wldXf.xf[0].vec[2], wldXf.xf[0].vec[3], + wldXf.xf[1].vec[0], wldXf.xf[1].vec[1], wldXf.xf[1].vec[2], wldXf.xf[1].vec[3], + wldXf.xf[2].vec[0], wldXf.xf[2].vec[1], wldXf.xf[2].vec[2], wldXf.xf[2].vec[3], + wld.hexColor.r, wld.hexColor.g, wld.hexColor.b, wld.hexColor.a, + path.getParentPath().getRelativePathUTF8().c_str()); + int idx = 0; + for (const MAPU::Transform& hexXf : wld.hexTransforms) + { + os.format("obj = bpy.data.objects.new('%s_%d', hexMesh)\n" + "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" + "mtxd = mtx.decompose()\n" + "obj.rotation_mode = 'QUATERNION'\n" + "obj.location = mtxd[0]\n" + "obj.rotation_quaternion = mtxd[1]\n" + "obj.scale = mtxd[2]\n" + "bpy.context.scene.objects.link(obj)\n" + "obj.parent = wldObj\n", + wld.name.c_str(), idx++, + hexXf.xf[0].vec[0], hexXf.xf[0].vec[1], hexXf.xf[0].vec[2], hexXf.xf[0].vec[3], + hexXf.xf[1].vec[0], hexXf.xf[1].vec[1], hexXf.xf[1].vec[2], hexXf.xf[1].vec[3], + hexXf.xf[2].vec[0], hexXf.xf[2].vec[1], hexXf.xf[2].vec[2], hexXf.xf[2].vec[3]); + } + } + + os << "for screen in bpy.data.screens:\n" + " for area in screen.areas:\n" + " for space in area.spaces:\n" + " if space.type == 'VIEW_3D':\n" + " space.viewport_shade = 'SOLID'\n" + " space.clip_end = 8000.0\n"; + + os.centerView(); + os.close(); + return conn.saveBlend(); +} + +template bool ReadMAPUToBlender> +(hecl::BlenderConnection& conn, + const MAPU& mapu, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const PAKRouter::EntryType& entry, + bool force); + +template bool ReadMAPUToBlender> +(hecl::BlenderConnection& conn, + const MAPU& mapu, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const PAKRouter::EntryType& entry, + bool force); + +bool MAPU::Cook(const hecl::BlenderConnection::DataStream::MapUniverse& mapuIn, const hecl::ProjectPath& out) +{ + MAPU mapu; + + mapu.magic = 0xABCDEF01; + mapu.version = 1; + mapu.hexMapa = mapuIn.hexagonPath; + + mapu.worldCount = mapuIn.worlds.size(); + mapu.worlds.reserve(mapuIn.worlds.size()); + for (const hecl::BlenderConnection::DataStream::MapUniverse::World& wld : mapuIn.worlds) + { + mapu.worlds.emplace_back(); + MAPU::World& wldOut = mapu.worlds.back(); + wldOut.name = wld.name; + wldOut.mlvl = hecl::ProjectPath(wld.worldPath, _S("!world.*")); + wldOut.transform.xf[0] = wld.xf.val[0]; + wldOut.transform.xf[1] = wld.xf.val[1]; + wldOut.transform.xf[2] = wld.xf.val[2]; + wldOut.hexCount = wld.hexagons.size(); + wldOut.hexTransforms.reserve(wld.hexagons.size()); + for (const hecl::BlenderConnection::DataStream::Matrix4f& mtx : wld.hexagons) + { + wldOut.hexTransforms.emplace_back(); + MAPU::Transform& xf = wldOut.hexTransforms.back(); + xf.xf[0] = mtx.val[0]; + xf.xf[1] = mtx.val[1]; + xf.xf[2] = mtx.val[2]; + } + wldOut.hexColor = zeus::CColor(wld.color.val); + } + + athena::io::FileWriter f(out.getAbsolutePath()); + mapu.write(f); + return true; +} + +} +} diff --git a/DataSpec/DNACommon/MAPU.hpp b/DataSpec/DNACommon/MAPU.hpp new file mode 100644 index 000000000..d8b816fd0 --- /dev/null +++ b/DataSpec/DNACommon/MAPU.hpp @@ -0,0 +1,48 @@ +#ifndef __DNACOMMON_MAPU_HPP__ +#define __DNACOMMON_MAPU_HPP__ + +#include "DNACommon.hpp" + +namespace DataSpec +{ +namespace DNAMAPU +{ +struct MAPU : BigDNA +{ + DECL_DNA + Value magic; + Value version; + UniqueID32 hexMapa; + Value worldCount; + struct Transform : BigDNA + { + DECL_DNA + Value xf[3]; + }; + struct World : BigDNA + { + DECL_DNA + String<-1> name; + UniqueID32 mlvl; + Transform transform; + Value hexCount; + Vector hexTransforms; + DNAColor hexColor; + }; + Vector worlds; + + static bool Cook(const hecl::BlenderConnection::DataStream::MapUniverse& mapu, const hecl::ProjectPath& out); +}; + +template +bool ReadMAPUToBlender(hecl::BlenderConnection& conn, + const MAPU& mapu, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const typename PAKRouter::EntryType& entry, + bool force); + +} +} + +#endif // __DNACOMMON_MAPU_HPP__ diff --git a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp index 237b46097..4128698b2 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp @@ -9,6 +9,15 @@ struct ITweakAutoMapper : public ITweak { virtual const zeus::CVector3f& GetDoorCenter() const=0; virtual float GetCamVerticalOffset() const=0; + virtual float GetX28() const=0; + virtual float GetX2C() const=0; + virtual float GetX30() const=0; + virtual float GetAlphaSurfaceVisited() const=0; + virtual float GetAlphaOutlineVisited() const=0; + virtual float GetAlphaSurfaceUnvisited() const=0; + virtual float GetAlphaOutlineUnvisited() const=0; + virtual float GetMiniMapViewportWidth() const=0; + virtual float GetMiniMapViewportHeight() const=0; }; } diff --git a/DataSpec/DNACommon/Tweaks/ITweakGui.hpp b/DataSpec/DNACommon/Tweaks/ITweakGui.hpp index 5c921895c..58812b4a0 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakGui.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakGui.hpp @@ -26,6 +26,7 @@ struct ITweakGui : ITweak Four }; + virtual float GetMapAlphaInterpolant() const=0; virtual EHudVisMode GetHudVisMode() const=0; virtual EHelmetVisMode GetHelmetVisMode() const=0; virtual atUint32 GetEnableAutoMapper() const=0; diff --git a/DataSpec/DNAMP1/CMakeLists.txt b/DataSpec/DNAMP1/CMakeLists.txt index 98438d243..f077d18a6 100644 --- a/DataSpec/DNAMP1/CMakeLists.txt +++ b/DataSpec/DNAMP1/CMakeLists.txt @@ -48,6 +48,7 @@ set(DNAMP1_SOURCES CMDL.hpp CMDLMaterials.cpp MAPA.hpp + MAPU.hpp MREA.cpp SCLY.hpp SCLY.cpp FRME.cpp diff --git a/DataSpec/DNAMP1/DNAMP1.cpp b/DataSpec/DNAMP1/DNAMP1.cpp index 38ddfd7d4..645d65b39 100644 --- a/DataSpec/DNAMP1/DNAMP1.cpp +++ b/DataSpec/DNAMP1/DNAMP1.cpp @@ -22,6 +22,7 @@ #include "ANCS.hpp" #include "MREA.hpp" #include "MAPA.hpp" +#include "MAPU.hpp" #include "FRME.hpp" #include "AGSC.hpp" #include "CSNG.hpp" @@ -355,6 +356,8 @@ ResExtractor PAKBridge::LookupExtractor(const PAK& pak, const PAK::En return {MREA::Extract, {_S(".blend")}, 4, MREA::Name}; case SBIG('MAPA'): return {MAPA::Extract, {_S(".blend")}, 4}; + case SBIG('MAPU'): + return {MAPU::Extract, {_S(".blend")}, 5}; case SBIG('PART'): return {DNAParticle::ExtractGPSM, {_S(".gpsm.yaml")}}; case SBIG('ELSC'): diff --git a/DataSpec/DNAMP1/MAPA.hpp b/DataSpec/DNAMP1/MAPA.hpp index 7128ac644..1bf581143 100644 --- a/DataSpec/DNAMP1/MAPA.hpp +++ b/DataSpec/DNAMP1/MAPA.hpp @@ -28,6 +28,15 @@ struct MAPA : DNAMAPA::MAPA hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); } + + static bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out) + { + return DNAMAPA::Cook(mapa, out); + } + + static uint32_t Version() { return 2; } + using Header = DNAMAPA::MAPA::HeaderMP1; + using MappableObject = DNAMAPA::MAPA::MappableObjectMP1_2; }; } } diff --git a/DataSpec/DNAMP1/MAPU.hpp b/DataSpec/DNAMP1/MAPU.hpp new file mode 100644 index 000000000..1393ccdd7 --- /dev/null +++ b/DataSpec/DNAMP1/MAPU.hpp @@ -0,0 +1,35 @@ +#ifndef __DNAMP1_MAPU_HPP__ +#define __DNAMP1_MAPU_HPP__ + +#include + +#include "../DNACommon/PAK.hpp" +#include "../DNACommon/MAPU.hpp" +#include "DNAMP1.hpp" + +namespace DataSpec +{ +namespace DNAMP1 +{ + +struct MAPU : DNAMAPU::MAPU +{ + static bool Extract(const SpecBase& dataSpec, + PAKEntryReadStream& rs, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const PAK::Entry& entry, + bool force, + hecl::BlenderToken& btok, + std::function fileChanged) + { + MAPU mapu; + mapu.read(rs); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); + return DNAMAPU::ReadMAPUToBlender(conn, mapu, outPath, pakRouter, entry, force); + } +}; +} +} + +#endif diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp index fbf4f8dea..bf7c5837e 100644 --- a/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp @@ -20,7 +20,7 @@ struct CameraShaker : IScriptObject Value zA; Value zB; Value duration; - Value shakeY; + Value active; }; } } diff --git a/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp b/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp index 9705d2acd..158d20b59 100644 --- a/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp @@ -14,18 +14,18 @@ struct NewCameraShaker : IScriptObject DECL_YAML String<-1> name; Value location; - Value unknown1; - PlayerParameters playerParams; - Value unknown3; + Value active; + PlayerParameters flags; + Value duration; Value unknown4; struct CameraShakerParameters : BigYAML { DECL_YAML - PlayerParameters playerParams; + PlayerParameters flags; struct ShakerInfo : BigYAML { DECL_YAML - PlayerParameters playerParams; + PlayerParameters flags; Value unknown1; Value unknown2; Value unknown3; diff --git a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp index f7bb90f3c..549f3fc13 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp @@ -45,20 +45,20 @@ struct CTweakAutoMapper : public ITweakAutoMapper Value x78_; DNAColor x7c_; DNAColor x80_; - Value x84_; + Value x84_alphaSurfaceVisited; Value x88_; - Value x8c_; + Value x8c_alphaOutlineVisited; Value x90_; - Value x94_; + Value x94_alphaSurfaceUnvisited; Value x98_; - Value x9c_; + Value x9c_alphaOutlineUnvisited; Value xa0_; /* Originally 4 separate floats */ Value xa4_doorCenter; Value xb0_; Value xb4_; - Value xb8_; - Value xbc_; + Value xb8_miniMapViewportWidth; + Value xbc_miniMapViewportHeight; Value xc0_; Value xc4_; Value xc8_; @@ -84,6 +84,15 @@ struct CTweakAutoMapper : public ITweakAutoMapper CTweakAutoMapper(athena::io::IStreamReader& r) { this->read(r); } const zeus::CVector3f& GetDoorCenter() const { return xa4_doorCenter; } float GetCamVerticalOffset() const { return xec_camVerticalOffset; } + float GetX28() const { return x28_; } + float GetX2C() const { return x2c_; } + float GetX30() const { return x30_; } + float GetAlphaSurfaceVisited() const { return x84_alphaSurfaceVisited; } + float GetAlphaOutlineVisited() const { return x8c_alphaOutlineVisited; } + float GetAlphaSurfaceUnvisited() const { return x94_alphaSurfaceUnvisited; } + float GetAlphaOutlineUnvisited() const { return x9c_alphaOutlineUnvisited; } + float GetMiniMapViewportWidth() const { return xb8_miniMapViewportWidth; } + float GetMiniMapViewportHeight() const { return xbc_miniMapViewportHeight; } }; } } diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp index 54e67a9f0..b28b17f22 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp @@ -11,7 +11,7 @@ struct CTweakGui : ITweakGui { DECL_YAML Value x4_; - Value x8_; + Value x8_mapAlphaInterp; Value xc_; Value x10_; Value x14_; @@ -195,6 +195,7 @@ struct CTweakGui : ITweakGui CTweakGui() = default; CTweakGui(athena::io::IStreamReader& r) { this->read(r); } + float GetMapAlphaInterpolant() const { return x8_mapAlphaInterp; } EHudVisMode GetHudVisMode() const { return xf8_hudVisMode; } EHelmetVisMode GetHelmetVisMode() const { return xfc_helmetVisMode; } atUint32 GetEnableAutoMapper() const { return x100_enableAutoMapper; } diff --git a/DataSpec/DNAMP2/CMakeLists.txt b/DataSpec/DNAMP2/CMakeLists.txt index fb8b2be60..b0f1bf0ca 100644 --- a/DataSpec/DNAMP2/CMakeLists.txt +++ b/DataSpec/DNAMP2/CMakeLists.txt @@ -20,6 +20,7 @@ set(DNAMP2_SOURCES CMDL.hpp MREA.cpp MAPA.hpp + MAPU.hpp AFSM.hpp STRG.hpp STRG.cpp) diff --git a/DataSpec/DNAMP2/DNAMP2.cpp b/DataSpec/DNAMP2/DNAMP2.cpp index 5c30a943a..066096c28 100644 --- a/DataSpec/DNAMP2/DNAMP2.cpp +++ b/DataSpec/DNAMP2/DNAMP2.cpp @@ -6,6 +6,7 @@ #include "ANCS.hpp" #include "MREA.hpp" #include "MAPA.hpp" +#include "MAPU.hpp" #include "AFSM.hpp" #include "SAVW.hpp" #include "AGSC.hpp" @@ -278,6 +279,8 @@ ResExtractor PAKBridge::LookupExtractor(const DNAMP1::PAK& pak, const return {MREA::Extract, {_S(".blend")}, 4}; case SBIG('MAPA'): return {MAPA::Extract, {_S(".blend")}, 4}; + case SBIG('MAPU'): + return {MAPU::Extract, {_S(".blend")}, 5}; case SBIG('FSM2'): return {DNAFSM2::ExtractFSM2, {_S(".yaml")}}; case SBIG('FONT'): diff --git a/DataSpec/DNAMP2/MAPA.hpp b/DataSpec/DNAMP2/MAPA.hpp index b3353d9d3..7e1a08282 100644 --- a/DataSpec/DNAMP2/MAPA.hpp +++ b/DataSpec/DNAMP2/MAPA.hpp @@ -25,6 +25,15 @@ struct MAPA : DNAMAPA::MAPA hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); } + + static bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out) + { + return DNAMAPA::Cook(mapa, out); + } + + static uint32_t Version() { return 3; } + using Header = DNAMAPA::MAPA::HeaderMP2; + using MappableObject = DNAMAPA::MAPA::MappableObjectMP1_2; }; } diff --git a/DataSpec/DNAMP2/MAPU.hpp b/DataSpec/DNAMP2/MAPU.hpp new file mode 100644 index 000000000..78886a7f8 --- /dev/null +++ b/DataSpec/DNAMP2/MAPU.hpp @@ -0,0 +1,35 @@ +#ifndef __DNAMP2_MAPU_HPP__ +#define __DNAMP2_MAPU_HPP__ + +#include + +#include "../DNACommon/PAK.hpp" +#include "../DNACommon/MAPU.hpp" +#include "DNAMP2.hpp" + +namespace DataSpec +{ +namespace DNAMP2 +{ + +struct MAPU : DNAMAPU::MAPU +{ + static bool Extract(const SpecBase& dataSpec, + PAKEntryReadStream& rs, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const DNAMP1::PAK::Entry& entry, + bool force, + hecl::BlenderToken& btok, + std::function fileChanged) + { + MAPU mapu; + mapu.read(rs); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); + return DNAMAPU::ReadMAPUToBlender(conn, mapu, outPath, pakRouter, entry, force); + } +}; +} +} + +#endif diff --git a/DataSpec/DNAMP3/MAPA.hpp b/DataSpec/DNAMP3/MAPA.hpp index 12d657ad6..ec759a5f7 100644 --- a/DataSpec/DNAMP3/MAPA.hpp +++ b/DataSpec/DNAMP3/MAPA.hpp @@ -25,6 +25,15 @@ struct MAPA : DNAMAPA::MAPA hecl::BlenderConnection& conn = btok.getBlenderConnection(); return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); } + + static bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapa, const hecl::ProjectPath& out) + { + return DNAMAPA::Cook(mapa, out); + } + + static uint32_t Version() { return 5; } + using Header = DNAMAPA::MAPA::HeaderMP3; + using MappableObject = DNAMAPA::MAPA::MappableObjectMP3; }; } diff --git a/DataSpec/SpecBase.cpp b/DataSpec/SpecBase.cpp index bebc2328c..cf853f76e 100644 --- a/DataSpec/SpecBase.cpp +++ b/DataSpec/SpecBase.cpp @@ -270,6 +270,18 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co cookGuiFrame(cookedPath, path, ds, btok, progress); break; } + case hecl::BlenderConnection::BlendType::MapArea: + { + hecl::BlenderConnection::DataStream ds = conn.beginData(); + cookMapArea(cookedPath, path, ds, btok, progress); + break; + } + case hecl::BlenderConnection::BlendType::MapUniverse: + { + hecl::BlenderConnection::DataStream ds = conn.beginData(); + cookMapUniverse(cookedPath, path, ds, btok, progress); + break; + } default: break; } } diff --git a/DataSpec/SpecBase.hpp b/DataSpec/SpecBase.hpp index df90cfc9c..a44fa4786 100644 --- a/DataSpec/SpecBase.hpp +++ b/DataSpec/SpecBase.hpp @@ -89,6 +89,12 @@ struct SpecBase : hecl::Database::IDataSpec FCookProgress progress)=0; virtual void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress)=0; + virtual void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress)=0; + virtual void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress)=0; /* Dependency flatteners */ void flattenDependencies(const hecl::ProjectPath& in, diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index 3739057c9..0f33b2583 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -14,6 +14,7 @@ #include "DNAMP1/ANCS.hpp" #include "DNAMP1/AGSC.hpp" #include "DNAMP1/CSNG.hpp" +#include "DNAMP1/MAPA.hpp" #include "DNACommon/ATBL.hpp" #include "DNACommon/FONT.hpp" #include "DNACommon/PART.hpp" @@ -23,6 +24,7 @@ #include "DNACommon/CRSC.hpp" #include "DNACommon/DPSC.hpp" #include "DNACommon/DGRP.hpp" +#include "DNACommon/MAPU.hpp" #include "DNACommon/Tweaks/TweakWriter.hpp" #include "DNAMP1/Tweaks/CTweakPlayerRes.hpp" #include "DNAMP1/Tweaks/CTweakGunRes.hpp" @@ -1049,6 +1051,26 @@ struct SpecMP1 : SpecBase DNAMP1::CSNG::Cook(in, out); progress(_S("Done")); } + + void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress) + { + BlendStream::MapArea mapa = ds.compileMapArea(); + ds.close(); + DNAMP1::MAPA::Cook(mapa, out); + progress(_S("Done")); + } + + void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress) + { + BlendStream::MapUniverse mapu = ds.compileMapUniverse(); + ds.close(); + DNAMAPU::MAPU::Cook(mapu, out); + progress(_S("Done")); + } }; hecl::Database::DataSpecEntry SpecEntMP1 = { diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp index f96d36627..46f1a8861 100644 --- a/DataSpec/SpecMP2.cpp +++ b/DataSpec/SpecMP2.cpp @@ -6,7 +6,9 @@ #include "DNAMP2/MLVL.hpp" #include "DNAMP2/STRG.hpp" #include "DNAMP2/AGSC.hpp" +#include "DNAMP2/MAPA.hpp" #include "DNAMP1/CSNG.hpp" +#include "DNACommon/MAPU.hpp" #include "hecl/ClientProcess.hpp" @@ -365,6 +367,26 @@ struct SpecMP2 : SpecBase DNAMP1::CSNG::Cook(in, out); progress(_S("Done")); } + + void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress) + { + BlendStream::MapArea mapa = ds.compileMapArea(); + ds.close(); + DNAMP2::MAPA::Cook(mapa, out); + progress(_S("Done")); + } + + void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress) + { + BlendStream::MapUniverse mapu = ds.compileMapUniverse(); + ds.close(); + DNAMAPU::MAPU::Cook(mapu, out); + progress(_S("Done")); + } }; hecl::Database::DataSpecEntry SpecEntMP2 diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp index ca0d16776..189af9d64 100644 --- a/DataSpec/SpecMP3.cpp +++ b/DataSpec/SpecMP3.cpp @@ -6,6 +6,7 @@ #include "DNAMP3/MLVL.hpp" #include "DNAMP3/STRG.hpp" +#include "DNAMP3/MAPA.hpp" #include "DNAMP2/STRG.hpp" #include "hecl/ClientProcess.hpp" @@ -544,6 +545,22 @@ struct SpecMP3 : SpecBase FCookProgress progress) { } + + void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress) + { + BlendStream::MapArea mapa = ds.compileMapArea(); + ds.close(); + DNAMP3::MAPA::Cook(mapa, out); + progress(_S("Done")); + } + + void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, + BlendStream& ds, hecl::BlenderToken& btok, + FCookProgress progress) + { + } }; hecl::Database::DataSpecEntry SpecEntMP3 diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index 0b415e0fe..ae215f0b4 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -1,18 +1,155 @@ #include "CAutoMapper.hpp" +#include "CSimplePool.hpp" +#include "GameGlobalObjects.hpp" +#include "Camera/CGameCamera.hpp" +#include "AutoMapper/CMapUniverse.hpp" +#include "AutoMapper/CMapArea.hpp" +#include "zeus/CEulerAngles.hpp" +#include "World/CPlayer.hpp" namespace urde { CAutoMapper::CAutoMapper(CStateManager& stateMgr) +: x24_world(*stateMgr.WorldNC()) { + x8_mapu = g_SimplePool->GetObj("MAPU_MapUniverse"); + x30_miniMapSamus = g_SimplePool->GetObj("CMDL_MiniMapSamus"); + x3c_hintBeacon = g_SimplePool->GetObj("TXTR_HintBeacon"); + xa0_curAreaId = xa4_otherAreaId = stateMgr.GetWorld()->IGetCurrentAreaId(); + zeus::CMatrix3f camRot = stateMgr.GetCameraManager()->GetCurrentCamera(stateMgr)->GetTransform().buildMatrix3f(); + xa8_[0] = xa8_[1] = xa8_[2] = BuildMiniMapWorldRenderState(stateMgr, camRot, xa0_curAreaId); + + x48_mapIcons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x4_saveStationIcon})); + x48_mapIcons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x8_missileStationIcon})); + x48_mapIcons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->xc_elevatorIcon})); + x48_mapIcons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x10_minesBreakFirstTopIcon})); + x48_mapIcons.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x14_minesBreakFirstBottomIcon})); + + for (int i=0 ; i<9 ; ++i) + { + x210_lstick.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x24_lStick[i]})); + x25c_cstick.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x4c_cStick[i]})); + } + + for (int i=0 ; i<2 ; ++i) + { + x2a8_ltrigger.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x74_lTrigger[i]})); + x2bc_rtrigger.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x80_rTrigger[i]})); + x2d0_abutton.push_back(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), g_tweakPlayerRes->x98_aButton[i]})); + } } bool CAutoMapper::CheckLoadComplete() { + switch (x4_loadPhase) + { + case ELoadPhase::LoadResources: + for (TLockedToken& tex : x48_mapIcons) + if (!tex.IsLoaded()) + return false; + if (!x30_miniMapSamus.IsLoaded()) + return false; + if (!x3c_hintBeacon.IsLoaded()) + return false; + x4_loadPhase = ELoadPhase::LoadUniverse; + case ELoadPhase::LoadUniverse: + if (x8_mapu.IsLoaded()) + return false; + x14_dummyWorlds.resize(x8_mapu->GetNumMapWorldDatas()); + SetCurWorldAssetId(x24_world.IGetWorldAssetId()); + x4_loadPhase = ELoadPhase::Done; + case ELoadPhase::Done: + return true; + default: break; + } return false; } +void CAutoMapper::SetCurWorldAssetId(ResId mlvlId) +{ + int numWorlds = x8_mapu->GetNumMapWorldDatas(); + for (int i=0 ; iGetMapWorldData(i).GetWorldAssetId() == mlvlId) + { + x9c_worldIdx = i; + break; + } +} + +CAutoMapper::SAutoMapperRenderState +CAutoMapper::BuildMiniMapWorldRenderState(const CStateManager& stateMgr, + const zeus::CQuaternion& rot, + TAreaId area) const +{ + zeus::CQuaternion camOrient = GetMiniMapCameraOrientation(stateMgr); + zeus::CQuaternion useOrient = (camOrient.dot(rot) >= 0.f) ? camOrient : camOrient.buildEquivalent(); + return SAutoMapperRenderState(GetMiniMapViewportSize(), useOrient, g_tweakAutoMapper->GetX28(), + g_tweakAutoMapper->GetX30(), GetAreaPointOfInterest(stateMgr, area), + GetMapAreaMiniMapDrawDepth(), GetMapAreaMiniMapDrawDepth(), + GetMapAreaMiniMapDrawAlphaSurfaceVisited(stateMgr), + GetMapAreaMiniMapDrawAlphaOutlineVisited(stateMgr), + GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(stateMgr), + GetMapAreaMiniMapDrawAlphaOutlineUnvisited(stateMgr)); +} + +zeus::CQuaternion CAutoMapper::GetMiniMapCameraOrientation(const CStateManager& stateMgr) const +{ + const CGameCamera* cam = stateMgr.GetCameraManager()->GetCurrentCamera(stateMgr); + zeus::CEulerAngles camAngles(zeus::CQuaternion(cam->GetTransform().buildMatrix3f())); + float rotMod = -(std::floor(camAngles.z * 0.15915494f) * 2.f * M_PIF - camAngles.z); + if (rotMod < 0.f) + rotMod += 2.f * M_PIF; + + zeus::CQuaternion ret; + ret.rotateZ(rotMod); + ret.rotateX(zeus::degToRad(g_tweakAutoMapper->GetX2C())); + return ret; +} + +zeus::CVector3f CAutoMapper::GetAreaPointOfInterest(const CStateManager&, TAreaId aid) const +{ + const CMapArea* mapa = x24_world.IGetMapWorld()->GetMapArea(aid); + return mapa->GetAreaPostTransform(x24_world, aid) * mapa->GetAreaCenterPoint(); +} + +zeus::CVector2i CAutoMapper::GetMiniMapViewportSize() +{ + float scaleX = g_Viewport.x8_width / 640.f; + float scaleY = g_Viewport.xc_height / 480.f; + return {scaleX * g_tweakAutoMapper->GetMiniMapViewportWidth(), + scaleY * g_tweakAutoMapper->GetMiniMapViewportHeight()}; +} + +float CAutoMapper::GetMapAreaMiniMapDrawAlphaSurfaceVisited(const CStateManager& stateMgr) +{ + float mapAlphaInterp = g_tweakGui->GetMapAlphaInterpolant(); + return g_tweakAutoMapper->GetAlphaOutlineUnvisited() * (1.f - mapAlphaInterp) * + stateMgr.Player()->GetMapAlpha() + mapAlphaInterp; +} + +float CAutoMapper::GetMapAreaMiniMapDrawAlphaOutlineVisited(const CStateManager& stateMgr) +{ + float mapAlphaInterp = g_tweakGui->GetMapAlphaInterpolant(); + return g_tweakAutoMapper->GetAlphaOutlineVisited() * (1.f - mapAlphaInterp) * + stateMgr.Player()->GetMapAlpha() + mapAlphaInterp; +} + +float CAutoMapper::GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(const CStateManager& stateMgr) +{ + float mapAlphaInterp = g_tweakGui->GetMapAlphaInterpolant(); + return g_tweakAutoMapper->GetAlphaSurfaceUnvisited() * (1.f - mapAlphaInterp) * + stateMgr.Player()->GetMapAlpha() + mapAlphaInterp; +} + +float CAutoMapper::GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManager& stateMgr) +{ + float mapAlphaInterp = g_tweakGui->GetMapAlphaInterpolant(); + return g_tweakAutoMapper->GetAlphaOutlineUnvisited() * (1.f - mapAlphaInterp) * + stateMgr.Player()->GetMapAlpha() + mapAlphaInterp; +} + void CAutoMapper::UnmuteAllLoopedSounds() { diff --git a/Runtime/AutoMapper/CAutoMapper.hpp b/Runtime/AutoMapper/CAutoMapper.hpp index e2cce8d70..7991294de 100644 --- a/Runtime/AutoMapper/CAutoMapper.hpp +++ b/Runtime/AutoMapper/CAutoMapper.hpp @@ -14,15 +14,50 @@ class CFinalInput; class IWorld; class CMapWorldInfo; class CStateManager; +class CMapUniverse; + class CAutoMapper { public: using EInGameGuiState = MP1::EInGameGuiState; + enum class ELoadPhase + { + LoadResources, + LoadUniverse, + Done + }; enum class EAutoMapperState { + Zero }; struct SAutoMapperRenderState { + zeus::CVector2i x0_viewportSize; + zeus::CQuaternion x8_camOrientation; + float x18_f1; + float x1c_f2; + zeus::CVector3f x20_areaPoint; + float x2c_drawDepth1; + float x30_drawDepth2; + float x34_alphaSurfaceVisited; + float x38_alphaOutlineVisited; + float x3c_alphaSurfaceUnvisited; + float x40_alphaOutlineUnvisited; + u32 x44_; + u32 x48_; + u32 x4c_; + u32 x50_; + u32 x54_; + u32 x58_; + SAutoMapperRenderState() = default; + SAutoMapperRenderState(const zeus::CVector2i& v1, const zeus::CQuaternion& rot, + float f1, float f2, const zeus::CVector3f& v2, float f3, float f4, + float f5, float f6, float f7, float f8) + : x0_viewportSize(v1), x8_camOrientation(rot), x18_f1(f1), x1c_f2(f2), + x20_areaPoint(v2), x2c_drawDepth1(f3), x30_drawDepth2(f4), + x34_alphaSurfaceVisited(f5), x38_alphaOutlineVisited(f6), + x3c_alphaSurfaceUnvisited(f7), x40_alphaOutlineUnvisited(f8), + x44_(0), x48_(0), x4c_(0), x50_(0), x54_(0), x58_(0) {} }; class CAudioMenu @@ -51,14 +86,70 @@ public: }; private: + ELoadPhase x4_loadPhase = ELoadPhase::LoadResources; + TLockedToken x8_mapu; + std::vector> x14_dummyWorlds; + CWorld& x24_world; + u32 x28_ = 0; + u32 x2c_ = 0; + TLockedToken x30_miniMapSamus; + TLockedToken x3c_hintBeacon; + rstl::reserved_vector, 5> x48_mapIcons; + ResId x74_ = -1; + u32 x84_ = 0; + ResId x88_ = -1; + u32 x98_ = 0; + u32 x9c_worldIdx = 0; + TAreaId xa0_curAreaId; + TAreaId xa4_otherAreaId; + SAutoMapperRenderState xa8_[3]; // xa8, x104, x160 + EAutoMapperState x1bc_state = EAutoMapperState::Zero; + EAutoMapperState x1c0_nextState = EAutoMapperState::Zero; + float x1c4_ = 0.f; + float x1c8_ = 0.f; + u32 x1cc_ = 0; + u32 x1d0_ = 0; + u32 x1d4_ = 0; + float x1d8_ = 0.f; + float x1dc_ = 0.f; + std::list x1e0_; + u32 x1f4_ = 0; + std::list x1f8_; + u32 x20c_ = 0; + rstl::reserved_vector, 9> x210_lstick; + rstl::reserved_vector, 9> x25c_cstick; + rstl::reserved_vector, 2> x2a8_ltrigger; + rstl::reserved_vector, 2> x2bc_rtrigger; + rstl::reserved_vector, 2> x2d0_abutton; + u32 x2e4_ = 0; + u32 x2e8_ = 0; + u32 x2ec_ = 0; + u32 x2f0_ = 0; + u32 x2f4_ = 0; + u32 x2f8_ = 0; + u32 x2fc_ = 0; + u32 x300_ = 0; + u32 x304_ = 0; + u32 x308_ = 0; + u32 x30c_ = 0; + u32 x310_ = 0; + u32 x314_ = 0; + float x318_ = 0.f; + float x31c_ = 0.f; + float x320_ = 0.f; + u32 x324_ = 0; + u32 x328_ = 0; + u32 x32c_ = 0; + public: - CAutoMapper(CStateManager&); + CAutoMapper(CStateManager& stateMgr); bool CheckLoadComplete(); bool CanLeaveMapScrean(const CStateManager&) const; float GetMapRotationX() const; float GetMapRotationZ() const; u32 GetFocusAreaIndex() const; ResId GetCurrWorldAssetId() const; + void SetCurWorldAssetId(ResId mlvlId); void MuteAllLoopedSounds(); void UnmuteAllLoopedSounds(); void ProcessControllerInput(const CFinalInput&, CStateManager&); @@ -70,32 +161,36 @@ public: void BeginMapperStateTransition(EAutoMapperState, const CStateManager&); void CompleteMapperStateTransition(); void ResetInterpolationTimer(float); - void BuildMiniMapWorldRenderState(const CStateManager&, const zeus::CQuaternion&, s32) const; - void BuildMapScreenWorldRenderState(const CStateManager&, const zeus::CQuaternion&, s32) const; - void BuildMapScreenUniverseRenderState(const CStateManager&, const zeus::CQuaternion&, s32) const; + SAutoMapperRenderState BuildMiniMapWorldRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId) const; + SAutoMapperRenderState BuildMapScreenWorldRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId) const; + SAutoMapperRenderState BuildMapScreenUniverseRenderState(const CStateManager&, const zeus::CQuaternion&, TAreaId) const; void SetShouldPanningSoundBePlaying(bool); void SetShouldZoomingSoundBePlaying(bool); void SetShouldRotatingSoundBePlaying(bool); void LeaveMapScreenState(); - void GetMiniMapCameraOrientation(CStateManager&); - void GetAreaPointOfInterest(CStateManager, s32); + zeus::CQuaternion GetMiniMapCameraOrientation(const CStateManager&) const; + zeus::CVector3f GetAreaPointOfInterest(const CStateManager&, TAreaId) const; void FindClosestVisibleArea(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&, const IWorld&, const CMapWorldInfo&) const; void FindClosestVisibleWorld(const zeus::CVector3f&, const zeus::CUnitVector3f&, const CStateManager&) const; - void GetMiniMapViewportSize(); - void GetMapScreenViewportSize(); - float GetMapAreaMiniDrawDepth(); - float GetMapAreaMaxDrawDepth(); - void GetMapAreaMiniMapDrawAlphaSurfaceVisited(const CStateManager&); - void GetMapAreaMiniMapDrawAlphaOutlineVisited(const CStateManager&); - void GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(const CStateManager&); - void GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManager&); - void GetClampedMapScreenCameraDistance(float) const; - void GetDesiredMiniMapCameraDistance(const CStateManager&) const; - float GetBaseCameraMoveSpeed() const; - float GetFinalCameraMoveSpeed() const; - bool IsInMapperState(EAutoMapperState) const; + static zeus::CVector2i GetMiniMapViewportSize(); + static void GetMapScreenViewportSize(); + static float GetMapAreaMiniMapDrawDepth() { return 2.f; } + static float GetMapAreaMaxDrawDepth(); + static float GetMapAreaMiniMapDrawAlphaSurfaceVisited(const CStateManager&); + static float GetMapAreaMiniMapDrawAlphaOutlineVisited(const CStateManager&); + static float GetMapAreaMiniMapDrawAlphaSurfaceUnvisited(const CStateManager&); + static float GetMapAreaMiniMapDrawAlphaOutlineUnvisited(const CStateManager&); + static void GetClampedMapScreenCameraDistance(float); + static void GetDesiredMiniMapCameraDistance(const CStateManager&); + static float GetBaseCameraMoveSpeed(); + static float GetFinalCameraMoveSpeed(); + + bool IsInMapperState(EAutoMapperState state) const + { + return state == x1bc_state && state == x1c0_nextState; + } bool IsInMapperTransition() const; bool IsRenderStateInterpolating() const; void TransformRenderStatesWorldToUniverse(); diff --git a/Runtime/AutoMapper/CMapArea.cpp b/Runtime/AutoMapper/CMapArea.cpp index e36b833e6..7098f1363 100644 --- a/Runtime/AutoMapper/CMapArea.cpp +++ b/Runtime/AutoMapper/CMapArea.cpp @@ -2,6 +2,9 @@ #include "GameGlobalObjects.hpp" #include "CMappableObject.hpp" #include "CToken.hpp" +#include "World/CWorld.hpp" +#include "World/CGameArea.hpp" +#include "CResFactory.hpp" namespace urde { @@ -44,6 +47,71 @@ void CMapArea::PostConstruct() (reinterpret_cast(x40_surfaceStart + j))->PostConstruct(x44_buf.get()); } +static const zeus::CVector3f MinesPostTransforms[3] = +{ + {0.f, 0.f, 200.f}, + {0.f, 0.f, 0.f}, + {0.f, 0.f, -200.f} +}; +static const u8 MinesPostTransformIndices[] = +{ + 0, // 00 Transport to Tallon Overworld South + 0, // 01 Quarry Access + 0, // 02 Main Quarry + 0, // 03 Waste Disposal + 0, // 04 Save Station Mines A + 0, // 05 Security Access A + 0, // 06 Ore Processing + 0, // 07 Mine Security Station + 0, // 08 Research Access + 0, // 09 Storage Depot B + 0, // 10 Elevator Access A + 0, // 11 Security Access B + 0, // 12 Storage Depot A + 0, // 13 Elite Research + 0, // 14 Elevator A + 1, // 15 Elite Control Access + 1, // 16 Elite Control + 1, // 17 Maintenance Tunnel + 1, // 18 Ventilation Shaft + 2, // 19 Phazon Processing Center + 1, // 20 Omega Research + 2, // 21 Transport Access + 2, // 22 Processing Center Access + 1, // 23 Map Station Mines + 1, // 24 Dynamo Access + 2, // 25 Transport to Magmoor Caverns South + 2, // 26 Elite Quarters + 1, // 27 Central Dynamo + 2, // 28 Elite Quarters Access + 1, // 29 Quarantine Access A + 1, // 30 Save Station Mines B + 2, // 31 Metroid Quarantine B + 1, // 32 Metroid Quarantine A + 2, // 33 Quarantine Access B + 2, // 34 Save Station Mines C + 1, // 35 Elevator Access B + 2, // 36 Fungal Hall B + 1, // 37 Elevator B + 2, // 38 Missile Station Mines + 2, // 39 Phazon Mining Tunnel + 2, // 40 Fungal Hall Access + 2, // 41 Fungal Hall A +}; + +zeus::CTransform CMapArea::GetAreaPostTransform(const CWorld& world, TAreaId aid) const +{ + if (world.IGetWorldAssetId() == g_ResFactory->TranslateOriginalToNew(0xB1AC4D65)) // Phazon Mines + { + const zeus::CTransform& areaXf = world.IGetAreaAlways(aid)->IGetTM(); + const zeus::CVector3f& postVec = MinesPostTransforms[MinesPostTransformIndices[aid]]; + return zeus::CTransform::Translate(postVec) * areaXf; + } + else + { + return world.IGetAreaAlways(aid)->IGetTM(); + } +} void CMapArea::CMapAreaSurface::PostConstruct(const void *) { diff --git a/Runtime/AutoMapper/CMapArea.hpp b/Runtime/AutoMapper/CMapArea.hpp index e0fc2b793..2600b967e 100644 --- a/Runtime/AutoMapper/CMapArea.hpp +++ b/Runtime/AutoMapper/CMapArea.hpp @@ -8,6 +8,7 @@ namespace urde { +class CWorld; class CMapArea { public: @@ -38,14 +39,14 @@ public: CMapArea(CInputStream&, u32); void PostConstruct(); bool GetIsVisibleToAutoMapper(bool, bool) const; - zeus::CVector3f GetAreaCenterPoint() const; + zeus::CVector3f GetAreaCenterPoint() const { return x10_box.center(); } zeus::CAABox GetBoundingBox() const; const zeus::CVector3f& GetVertices() const; void GetMappableObject(s32) const; void GetSurface(s32) const; u32 GetNumMappableObjects() const; u32 GetNumSurfaces() const; - + zeus::CTransform GetAreaPostTransform(const CWorld& world, TAreaId aid) const; }; CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in, const CVParamTransfer&); diff --git a/Runtime/AutoMapper/CMapUniverse.hpp b/Runtime/AutoMapper/CMapUniverse.hpp index be7b09227..5a4e53ea5 100644 --- a/Runtime/AutoMapper/CMapUniverse.hpp +++ b/Runtime/AutoMapper/CMapUniverse.hpp @@ -51,7 +51,7 @@ public: zeus::CVector3f x64_ = zeus::CVector3f::skZero; public: CMapWorldData(CInputStream& in, u32 version); - ResId GetWorldAssetId() const; + ResId GetWorldAssetId() const { return x10_worldAssetId; } zeus::CVector3f GetWorldCenterPoint() const; std::string GetWorldLabel() const; zeus::CTransform GetWorldTransform() const; @@ -70,8 +70,8 @@ private: zeus::CVector3f x20_ = zeus::CVector3f::skZero; public: CMapUniverse(CInputStream&, u32); - void GetMapWorldData(s32) const; - u32 GetNumMapWorldDatas() const; + const CMapWorldData& GetMapWorldData(s32 idx) const { return x10_worldDatas[idx]; } + u32 GetNumMapWorldDatas() const { return x10_worldDatas.size(); } float GetMapUniverseRadius() const; zeus::CVector3f GetMapUniverseCenterPoint() const; void Draw(const CMapUniverseDrawParms&, const zeus::CVector3f&, float, float) const; diff --git a/Runtime/AutoMapper/CMapWorld.cpp b/Runtime/AutoMapper/CMapWorld.cpp index df829faf1..5cc5fe570 100644 --- a/Runtime/AutoMapper/CMapWorld.cpp +++ b/Runtime/AutoMapper/CMapWorld.cpp @@ -12,13 +12,9 @@ u32 CMapWorld::GetNumAreas() const return x0_areas.size(); } -void CMapWorld::GetLoadedMapArea(s32) const +const CMapArea* CMapWorld::GetMapArea(TAreaId aid) const { -} - -void CMapWorld::GetMapArea(s32) const -{ - + return x0_areas[aid].GetMapArea(); } void CMapWorld::IsMapAreaInBFSInfoVector(const CMapWorld::CMapAreaData *, const std::vector &) const diff --git a/Runtime/AutoMapper/CMapWorld.hpp b/Runtime/AutoMapper/CMapWorld.hpp index 48c550e9b..476d7ec07 100644 --- a/Runtime/AutoMapper/CMapWorld.hpp +++ b/Runtime/AutoMapper/CMapWorld.hpp @@ -56,7 +56,7 @@ public: void Lock(); void Unlock(); bool IsLoaded() const; - void GetMapArea() const; + const CMapArea* GetMapArea() const { return x0_area.IsLoaded() ? x0_area.GetObj() : nullptr; } void GetNextMapAreaData() const; void GetContainingList() const; void NextMapAreaData(); @@ -88,8 +88,7 @@ private: public: CMapWorld(CInputStream&); u32 GetNumAreas() const; - void GetLoadedMapArea(s32) const; - void GetMapArea(s32) const; + const CMapArea* GetMapArea(TAreaId) const; void IsMapAreaInBFSInfoVector(const CMapAreaData*, const std::vector&) const; void SetWhichMapAreasLoaded(const IWorld&, int start, int count); bool IsMapAreasStreaming() const; diff --git a/Runtime/AutoMapper/CMapWorldInfo.cpp b/Runtime/AutoMapper/CMapWorldInfo.cpp index 0df6bb6ee..eb360524d 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.cpp +++ b/Runtime/AutoMapper/CMapWorldInfo.cpp @@ -69,7 +69,7 @@ bool CMapWorldInfo::IsAreaVisted(TAreaId aid) { if (aid + 1 > x0_visitedAreasAllocated) { - x4_visitedAreas.resize((aid + 31) / 32); + x4_visitedAreas.resize((aid + 32) / 32); x0_visitedAreasAllocated = aid + 1; } return (x4_visitedAreas[aid / 32] >> (aid % 32)) & 0x1; @@ -79,7 +79,7 @@ void CMapWorldInfo::SetAreaVisited(TAreaId aid, bool visited) { if (aid + 1 > x0_visitedAreasAllocated) { - x4_visitedAreas.resize((aid + 31) / 32); + x4_visitedAreas.resize((aid + 32) / 32); x0_visitedAreasAllocated = aid + 1; } if (visited) @@ -92,7 +92,7 @@ bool CMapWorldInfo::IsMapped(TAreaId aid) { if (aid + 1 > x14_mappedAreasAllocated) { - x18_mappedAreas.resize((aid + 31) / 32); + x18_mappedAreas.resize((aid + 32) / 32); x14_mappedAreasAllocated = aid + 1; } return (x18_mappedAreas[aid / 32] >> (aid % 32)) & 0x1; @@ -102,7 +102,7 @@ void CMapWorldInfo::SetIsMapped(TAreaId aid, bool mapped) { if (aid + 1 > x14_mappedAreasAllocated) { - x18_mappedAreas.resize((aid + 31) / 32); + x18_mappedAreas.resize((aid + 32) / 32); x14_mappedAreasAllocated = aid + 1; } if (mapped) diff --git a/Runtime/CObjectList.cpp b/Runtime/CObjectList.cpp index 6ba129d59..211301036 100644 --- a/Runtime/CObjectList.cpp +++ b/Runtime/CObjectList.cpp @@ -65,7 +65,7 @@ CEntity* CObjectList::operator[](size_t i) const CEntity* CObjectList::GetObjectById(TUniqueId uid) const { - if (!uid) + if (uid == kInvalidUniqueId) return nullptr; const SObjectListEntry& ent = x0_list[uid & 0x3ff]; if (ent.entity->x30_26_scriptingBlocked) @@ -75,7 +75,7 @@ const CEntity* CObjectList::GetObjectById(TUniqueId uid) const CEntity* CObjectList::GetObjectById(TUniqueId uid) { - if (!uid) + if (uid == kInvalidUniqueId) return nullptr; SObjectListEntry& ent = x0_list[uid & 0x3ff]; if (ent.entity->x30_26_scriptingBlocked) diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index dd7fdff4b..d472498ab 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -285,7 +285,13 @@ void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx, } } -bool CStateManager::RenderLast(TUniqueId) { return false; } +bool CStateManager::RenderLast(TUniqueId uid) +{ + if (x86c_stateManagerContainer->xf39c_renderLast.size() == 20) + return false; + x86c_stateManagerContainer->xf39c_renderLast.push_back(uid); + return true; +} void CStateManager::AddDrawableActorPlane(const CActor& actor, const zeus::CPlane& plane, const zeus::CAABox& aabb) const @@ -632,10 +638,10 @@ void CStateManager::DrawWorld() const if (thermal) { - if (x86c_stateManagerContainer->xf39c_.size()) + if (x86c_stateManagerContainer->xf39c_renderLast.size()) { CGraphics::SetDepthRange(0.015625f, 0.03125f); - for (TUniqueId id : x86c_stateManagerContainer->xf39c_) + for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) if (const CActor* actor = static_cast(GetObjectById(id))) if (actor->xe6_27_ & 0x2) actor->Render(*this); @@ -703,10 +709,10 @@ void CStateManager::DrawWorld() const if (x84c_player) x84c_player->RenderGun(*this, x870_cameraManager->GetGlobalCameraTranslation(*this)); - if (x86c_stateManagerContainer->xf39c_.size()) + if (x86c_stateManagerContainer->xf39c_renderLast.size()) { CGraphics::SetDepthRange(0.015625f, 0.03125f); - for (TUniqueId id : x86c_stateManagerContainer->xf39c_) + for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) if (const CActor* actor = static_cast(GetObjectById(id))) if (actor->xe6_27_ & 0x4) actor->Render(*this); @@ -772,7 +778,7 @@ void CStateManager::PreRender() if (xf94_24_) { x86c_stateManagerContainer->xf370_.clear(); - x86c_stateManagerContainer->xf39c_.clear(); + x86c_stateManagerContainer->xf39c_renderLast.clear(); xf7c_projectedShadow = nullptr; x850_world->PreRender(); BuildDynamicLightListForWorld(); diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 6b449aa5f..d3a43e2ae 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -109,7 +109,7 @@ class CStateManager CRumbleManager xf250_rumbleManager; u32 xf344_ = 0; rstl::reserved_vector xf370_; - rstl::reserved_vector xf39c_; + rstl::reserved_vector xf39c_renderLast; }; std::unique_ptr x86c_stateManagerContainer; CCameraManager* x870_cameraManager = nullptr; diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 4936addc9..50365758d 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -317,7 +317,7 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& const CActorLights* lights, const CModelFlags& drawFlags) { if ((x14_25_sortThermal && which == EWhichModel::Thermal) || - x10_animData || !x1c_normalModel || drawFlags.m_blendMode > 2) + x10_animData || !x1c_normalModel || drawFlags.x0_blendMode > 2) { const_cast(this)->x14_24_renderSorted = false; return; @@ -342,7 +342,7 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf, { if (x14_25_sortThermal && which == EWhichModel::Thermal) { - zeus::CColor mul(drawFlags.color.a, drawFlags.color.a, drawFlags.color.a, drawFlags.color.a); + zeus::CColor mul(drawFlags.x4_color.a, drawFlags.x4_color.a, drawFlags.x4_color.a, drawFlags.x4_color.a); RenderThermal(xf, mul, {0.f, 0.f, 0.f, 0.25f}); } else diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 4f97be234..8bf9a325c 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -437,19 +437,19 @@ void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* case 0: default: flags.m_extendedShader = EExtendedShader::SolidColorFrontfaceCullLEqualAlphaOnly; - flags.color = zeus::CColor(1.f, 1.f, 1.f, 1.f); + flags.x4_color = zeus::CColor(1.f, 1.f, 1.f, 1.f); break; case 1: flags.m_extendedShader = EExtendedShader::SolidColorFrontfaceCullAlwaysAlphaOnly; - flags.color = zeus::CColor(1.f, 1.f, 1.f, 1.f); + flags.x4_color = zeus::CColor(1.f, 1.f, 1.f, 1.f); break; case 2: flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly; - flags.color = zeus::CColor(1.f, 1.f, 1.f, 0.f); + flags.x4_color = zeus::CColor(1.f, 1.f, 1.f, 0.f); break; case 3: flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullGreaterAlphaOnly; - flags.color = zeus::CColor(1.f, 1.f, 1.f, 0.f); + flags.x4_color = zeus::CColor(1.f, 1.f, 1.f, 0.f); break; } @@ -1004,7 +1004,7 @@ void CBooRenderer::DrawThermalModel(const CModel& model, const zeus::CColor& mul { CModelFlags flags; flags.m_extendedShader = EExtendedShader::Thermal; - flags.color = mulCol; + flags.x4_color = mulCol; flags.addColor = addCol; model.UpdateLastFrame(); model.Draw(flags); @@ -1206,7 +1206,7 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector 255) return alphaVal; - flags.color.a = alphaVal / 255.f; + flags.x4_color.a = alphaVal / 255.f; const CBooModel& model = *item.x10_models[wordModel + j]; const_cast(model).VerifyCurrentShader(0); for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) @@ -1227,7 +1227,7 @@ void CBooRenderer::DrawOverlappingWorldModelShadows(int alphaVal, const std::vec const zeus::CAABox& aabb, float alpha) const { CModelFlags flags; - flags.color.a = alpha; + flags.x4_color.a = alpha; flags.m_extendedShader = EExtendedShader::MorphBallShadow; // Do shadow draw u32 curWord = 0; @@ -1249,7 +1249,7 @@ void CBooRenderer::DrawOverlappingWorldModelShadows(int alphaVal, const std::vec if (alphaVal > 255) return; - flags.color.r = alphaVal / 255.f; + flags.x4_color.r = alphaVal / 255.f; const CBooModel& model = *item.x10_models[wordModel + j]; const_cast(model).VerifyCurrentShader(0); for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 43842ebc9..0df0c5304 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -23,18 +23,18 @@ class CModel; struct CModelFlags { - u8 m_blendMode = 0; /* Blend state 3/5 enable additive */ - u8 m_matSetIdx = 0; + u8 x0_blendMode = 0; /* Blend state 3/5 enable additive */ + u8 x1_matSetIdx = 0; EExtendedShader m_extendedShader = EExtendedShader::Flat; - u16 m_flags = 0; /* Flags */ - zeus::CColor color; /* Set into kcolor slot specified by material */ + u16 x2_flags = 0; /* Flags */ + zeus::CColor x4_color; /* Set into kcolor slot specified by material */ zeus::CColor addColor = zeus::CColor::skClear; zeus::CColor regColors[3]; zeus::CAABox mbShadowBox; CModelFlags() = default; CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col) - : m_blendMode(blendMode), m_matSetIdx(shadIdx), m_flags(flags), color(col) {} + : x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {} /* Flags 0x4: render without texture lock diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index b02961943..e7d9e9a52 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -677,21 +677,21 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags, if (flags.m_extendedShader == EExtendedShader::Thermal) /* Thermal Model (same as UV Mode 0) */ { CModelShaders::ThermalUniform& thermalOut = *reinterpret_cast(dataCur); - thermalOut.mulColor = flags.color; + thermalOut.mulColor = flags.x4_color; thermalOut.addColor = flags.addColor; } else if (flags.m_extendedShader >= EExtendedShader::SolidColor && flags.m_extendedShader <= EExtendedShader::SolidColorBackfaceCullGreaterAlphaOnly) /* Solid color render */ { CModelShaders::SolidUniform& solidOut = *reinterpret_cast(dataCur); - solidOut.solidColor = flags.color; + solidOut.solidColor = flags.x4_color; } else if (flags.m_extendedShader == EExtendedShader::MorphBallShadow) /* MorphBall shadow render */ { CModelShaders::MBShadowUniform& shadowOut = *reinterpret_cast(dataCur); shadowOut.shadowUp = CGraphics::g_GXModelView * zeus::CVector3f::skUp; - shadowOut.shadowUp.w = flags.color.a; - shadowOut.shadowId = flags.color.r; + shadowOut.shadowUp.w = flags.x4_color.a; + shadowOut.shadowId = flags.x4_color.r; } else { @@ -700,7 +700,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags, lightingOut.colorRegs[0] = flags.regColors[0]; lightingOut.colorRegs[1] = flags.regColors[1]; lightingOut.colorRegs[2] = flags.regColors[2]; - lightingOut.mulColor = flags.color; + lightingOut.mulColor = flags.x4_color; lightingOut.fog = CGraphics::g_Fog; } @@ -863,19 +863,19 @@ void CBooModel::Touch(int shaderIdx) const void CModel::DrawSortedParts(const CModelFlags& flags) const { - const_cast(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx); + const_cast(*x28_modelInst).VerifyCurrentShader(flags.x1_matSetIdx); x28_modelInst->DrawAlpha(flags, nullptr, nullptr); } void CModel::DrawUnsortedParts(const CModelFlags& flags) const { - const_cast(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx); + const_cast(*x28_modelInst).VerifyCurrentShader(flags.x1_matSetIdx); x28_modelInst->DrawNormal(flags, nullptr, nullptr); } void CModel::Draw(const CModelFlags& flags) const { - const_cast(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx); + const_cast(*x28_modelInst).VerifyCurrentShader(flags.x1_matSetIdx); x28_modelInst->Draw(flags, nullptr, nullptr); } diff --git a/Runtime/GuiSys/CGuiFrame.cpp b/Runtime/GuiSys/CGuiFrame.cpp index e3210182f..f249711d0 100644 --- a/Runtime/GuiSys/CGuiFrame.cpp +++ b/Runtime/GuiSys/CGuiFrame.cpp @@ -15,7 +15,8 @@ namespace urde CGuiFrame::CGuiFrame(ResId id, CGuiSys& sys, int a, int b, int c, CSimplePool* sp) : x0_id(id), x8_guiSys(sys), x4c_a(a), x50_b(b), x54_c(c), x58_24_loaded(false) { - x3c_lights.resize(8); + x3c_lights.reserve(8); + m_indexedLights.reserve(8); x10_rootWidget.reset(new CGuiWidget( CGuiWidget::CGuiWidgetParms(this, false, 0, 0, false, false, false, zeus::CColor::skWhite, CGuiWidget::EGuiModelDrawFlags::Alpha, false, @@ -56,8 +57,14 @@ void CGuiFrame::EnableLights(u32 lights) const zeus::CColor accumColor(zeus::CColor::skBlack); ERglLight lightId = ERglLight::Zero; int idx = 0; - for (auto& light : x3c_lights) + for (auto& light : m_indexedLights) { + if (!light) + { + ++reinterpret_cast&>(lightId); + ++idx; + continue; + } if ((lights & (1 << idx)) != 0) { // accumulate color @@ -68,7 +75,7 @@ void CGuiFrame::EnableLights(u32 lights) const ++reinterpret_cast&>(lightId); ++idx; } - if (x3c_lights.empty()) + if (m_indexedLights.empty()) CGraphics::SetAmbientColor(zeus::CColor::skWhite); else CGraphics::SetAmbientColor(accumColor); @@ -81,12 +88,17 @@ void CGuiFrame::DisableLights() const void CGuiFrame::RemoveLight(CGuiLight* light) { - x3c_lights[light->GetLoadedIdx()].reset(); + m_indexedLights[light->GetLoadedIdx()] = nullptr; } -void CGuiFrame::AddLight(std::shared_ptr&& light) +void CGuiFrame::AddLight(CGuiLight* light) { - x3c_lights[light->GetLoadedIdx()] = std::move(light); + m_indexedLights[light->GetLoadedIdx()] = light; +} + +void CGuiFrame::RegisterLight(std::shared_ptr&& light) +{ + x3c_lights.push_back(std::move(light)); } bool CGuiFrame::GetIsFinishedLoading() const diff --git a/Runtime/GuiSys/CGuiFrame.hpp b/Runtime/GuiSys/CGuiFrame.hpp index b334433b2..75c4898f8 100644 --- a/Runtime/GuiSys/CGuiFrame.hpp +++ b/Runtime/GuiSys/CGuiFrame.hpp @@ -5,6 +5,7 @@ #include "CGuiHeadWidget.hpp" #include "CGuiWidgetIdDB.hpp" #include "IObj.hpp" +#include namespace urde { @@ -30,6 +31,7 @@ private: CGuiWidgetIdDB x18_idDB; std::vector> x2c_widgets; std::vector> x3c_lights; + std::vector m_indexedLights; int x4c_a; int x50_b; int x54_c; @@ -44,7 +46,7 @@ public: CGuiSys& GetGuiSys() {return x8_guiSys;} - CGuiLight* GetFrameLight(int idx) const { return x3c_lights[idx].get(); } + CGuiLight* GetFrameLight(int idx) const { return m_indexedLights[idx]; } CGuiCamera* GetFrameCamera() const { return x14_camera.get(); } CGuiWidget* FindWidget(const std::string& name) const; CGuiWidget* FindWidget(s16 id) const; @@ -55,7 +57,8 @@ public: void EnableLights(u32 lights) const; void DisableLights() const; void RemoveLight(CGuiLight* light); - void AddLight(std::shared_ptr&& light); + void AddLight(CGuiLight* light); + void RegisterLight(std::shared_ptr&& light); bool GetIsFinishedLoading() const; void Touch() const; const zeus::CTransform& GetAspectTransform() const { return m_aspectTransform; } diff --git a/Runtime/GuiSys/CGuiLight.cpp b/Runtime/GuiSys/CGuiLight.cpp index 66f39dbc4..a433b8228 100644 --- a/Runtime/GuiSys/CGuiLight.cpp +++ b/Runtime/GuiSys/CGuiLight.cpp @@ -48,7 +48,7 @@ CLight CGuiLight::BuildLight() const void CGuiLight::SetIsVisible(bool vis) { if (vis) - xb0_frame->AddLight(shared_from_this()); + xb0_frame->AddLight(this); else xb0_frame->RemoveLight(this); CGuiWidget::SetIsVisible(vis); @@ -100,7 +100,8 @@ std::shared_ptr CGuiLight::Create(CGuiFrame* frame, CInputStream& in } ret->ParseBaseInfo(frame, in, parms); - frame->AddLight(ret->shared_from_this()); + frame->RegisterLight(ret->shared_from_this()); + frame->AddLight(ret.get()); return ret; } diff --git a/Runtime/GuiSys/CGuiModel.cpp b/Runtime/GuiSys/CGuiModel.cpp index 81a7d7283..3c5620201 100644 --- a/Runtime/GuiSys/CGuiModel.cpp +++ b/Runtime/GuiSys/CGuiModel.cpp @@ -96,10 +96,10 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const flags.m_extendedShader = EExtendedShader::ForcedAlpha; model->Draw(flags); - flags.m_blendMode = 5; - flags.m_matSetIdx = 0; - flags.m_flags = (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest); - flags.color = moduCol; + flags.x0_blendMode = 5; + flags.x1_matSetIdx = 0; + flags.x2_flags = (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest); + flags.x4_color = moduCol; flags.m_extendedShader = EExtendedShader::ForcedAdditive; model->Draw(flags); break; diff --git a/Runtime/MP1/CInGameGuiManager.cpp b/Runtime/MP1/CInGameGuiManager.cpp index 5107a39f2..5734f167a 100644 --- a/Runtime/MP1/CInGameGuiManager.cpp +++ b/Runtime/MP1/CInGameGuiManager.cpp @@ -235,7 +235,7 @@ CInGameGuiManager::CInGameGuiManager(CStateManager& stateMgr, xc8_inGameGuiDGRPs.reserve(14); for (int i=0 ; i<14 ; ++i) - xc8_inGameGuiDGRPs.push_back(g_SimplePool->GetObj(PauseScreenDGRPs[i])); + xc8_inGameGuiDGRPs.push_back(g_SimplePool->GetObj(InGameGuiDGRPs[i])); } bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) diff --git a/Runtime/World/CActor.cpp b/Runtime/World/CActor.cpp index d2dca9021..82aa11e17 100644 --- a/Runtime/World/CActor.cpp +++ b/Runtime/World/CActor.cpp @@ -302,6 +302,17 @@ float CActor::GetPitch() const { return zeus::CQuaternion(x34_transform.buildMat float CActor::GetYaw() const { return zeus::CQuaternion(x34_transform.buildMatrix3f()).yaw(); } +void CActor::EnsureRendered(const CStateManager& stateMgr, const zeus::CVector3f& pos, + const zeus::CAABox& aabb) const +{ + if (x64_modelData) + { + x64_modelData->RenderUnsortedParts(x64_modelData->GetRenderingModel(stateMgr), + x34_transform, x90_actorLights.get(), xb4_drawFlags); + } + stateMgr.AddDrawableActor(*this, pos, aabb); +} + SAdvancementDeltas CActor::UpdateAnimation(float, CStateManager&, bool) { return {}; @@ -319,7 +330,7 @@ bool CActor::CanDrawStatic() const return false; if (x64_modelData && x64_modelData->HasNormalModel()) - return xb4_ <= 4; + return xb4_drawFlags.x0_blendMode <= 4; return false; } diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index eafd4ab0f..707910d86 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -38,10 +38,7 @@ protected: std::unique_ptr x94_simpleShadow; std::unique_ptr> x98_scanObjectInfo; zeus::CAABox x9c_aabox; - u8 xb4_ = 0; - u8 xb5_ = 0; - u16 xb6_ = 3; - zeus::CColor xb8_ = zeus::CColor::skWhite; + CModelFlags xb4_drawFlags; float xbc_time = 0.f; s32 xc0_ = 0; TUniqueId xc4_fluidId = kInvalidUniqueId; @@ -158,7 +155,7 @@ public: const CModelData* GetModelData() const { return x64_modelData.get(); } CModelData* ModelData() { return x64_modelData.get(); } void EnsureRendered(const CStateManager&); - void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CVector3f&); + void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CAABox&) const; SAdvancementDeltas UpdateAnimation(float, CStateManager&, bool); void SetActorLights(std::unique_ptr); bool CanDrawStatic() const; diff --git a/Runtime/World/CMakeLists.txt b/Runtime/World/CMakeLists.txt index 9e8ffa1e9..040ef1d28 100644 --- a/Runtime/World/CMakeLists.txt +++ b/Runtime/World/CMakeLists.txt @@ -91,6 +91,7 @@ set(WORLD_SOURCES CScriptStreamedMusic.hpp CScriptStreamedMusic.cpp CScriptRoomAcoustics.hpp CScriptRoomAcoustics.cpp CScriptControllerAction.hpp CScriptControllerAction.cpp + CVisorFlare.hpp CVisorFlare.cpp CGrappleParameters.hpp CActorParameters.hpp CLightParameters.hpp diff --git a/Runtime/World/CMorphBallShadow.cpp b/Runtime/World/CMorphBallShadow.cpp index e85cee3f6..66ddf9d49 100644 --- a/Runtime/World/CMorphBallShadow.cpp +++ b/Runtime/World/CMorphBallShadow.cpp @@ -81,7 +81,7 @@ void CMorphBallShadow::RenderIdBuffer(const zeus::CAABox& aabb, const CStateMana CModelFlags flags(0, 0, 3, zeus::CColor{1.f, 1.f, 1.f, alphaVal / 255.f}); flags.m_extendedShader = EExtendedShader::SolidColor; // Do solid color draw const CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); - const_cast(model).VerifyCurrentShader(flags.m_matSetIdx); + const_cast(model).VerifyCurrentShader(flags.x1_matSetIdx); model.DrawNormal(flags, nullptr, nullptr); alphaVal += 4; } @@ -128,7 +128,7 @@ void CMorphBallShadow::Render(const CStateManager& mgr, float alpha) return; CModelFlags flags; - flags.color.a = alpha; + flags.x4_color.a = alpha; flags.m_extendedShader = EExtendedShader::MorphBallShadow; int alphaVal = 4; @@ -138,9 +138,9 @@ void CMorphBallShadow::Render(const CStateManager& mgr, float alpha) zeus::CTransform modelXf = actor->GetTransform() * zeus::CTransform::Scale(modelData->GetScale()); CGraphics::SetModelMatrix(modelXf); - flags.color.r = alphaVal / 255.f; + flags.x4_color.r = alphaVal / 255.f; const CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); - const_cast(model).VerifyCurrentShader(flags.m_matSetIdx); + const_cast(model).VerifyCurrentShader(flags.x1_matSetIdx); model.DrawNormal(flags, nullptr, nullptr); alphaVal += 4; } diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index c65ab7bd8..2eb0950d6 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -23,7 +23,12 @@ CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& MakePlayerAnimRes(resId, playerScale), ml, aabb, SMoverData(mass), CActorParameters::None(), stepUp, stepDown), x7d0_animRes(resId, 0, playerScale, 0, true) { + x490_gun.reset(new CPlayerGun(uid)); x768_morphball.reset(new CMorphBall(*this, f4)); + x76c_cameraBob.reset(new CPlayerCameraBob(CPlayerCameraBob::ECameraBobType::One, + zeus::CVector2f{CPlayerCameraBob::kCameraBobExtentX, + CPlayerCameraBob::kCameraBobExtentY}, + CPlayerCameraBob::kCameraBobPeriod)); x9c4_26_ = true; x9c4_27_ = true; x9c4_28_ = true; diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index 06aa15732..fc126684d 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -162,7 +162,7 @@ private: zeus::CVector3f x480_ = zeus::CVector3f::skZero; float x48c_ = 0.f; std::unique_ptr x490_gun; - float x494_ = 1.f; + float x494_mapAlpha = 1.f; float x49c_; /* Value retrieved from TweakPlayerGun */ // std::unqiue_ptr<> x4a0_; u32 x4a4_ = 0; @@ -411,6 +411,7 @@ public: float GetDampedClampedVelocityWR() const; const CVisorSteam& GetVisorSteam() const { return x7a0_visorSteam; } float Get74C() const { return x74c_; } + float GetMapAlpha() const { return x494_mapAlpha; } void UpdateCinematicState(CStateManager& mgr); CPlayerGun* GetPlayerGun() const { return x490_gun.get(); } CMorphBall* GetMorphBall() const { return x768_morphball.get(); } diff --git a/Runtime/World/CPlayerCameraBob.hpp b/Runtime/World/CPlayerCameraBob.hpp index 2f3822b52..68f0454cb 100644 --- a/Runtime/World/CPlayerCameraBob.hpp +++ b/Runtime/World/CPlayerCameraBob.hpp @@ -32,7 +32,6 @@ public: Eight }; -private: static float kCameraBobExtentX; static float kCameraBobExtentY; static float kCameraBobPeriod; @@ -49,6 +48,7 @@ private: static float kHelmetBobMagnitude; static const float kLandingBobDamping; +private: ECameraBobType x0_type; zeus::CVector2f x4_vec; float xc_; diff --git a/Runtime/World/CScriptActor.cpp b/Runtime/World/CScriptActor.cpp index 578bd664e..a543109c3 100644 --- a/Runtime/World/CScriptActor.cpp +++ b/Runtime/World/CScriptActor.cpp @@ -135,37 +135,37 @@ void CScriptActor::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) zeus::CColor col(1.f, 1.f, x2dc_xrayAlpha); if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { - xb4_ = 5; - xb5_ = 0; - xb6_ = 3; - xb8_ = col; + xb4_drawFlags.x0_blendMode = 5; + xb4_drawFlags.x1_matSetIdx = 0; + xb4_drawFlags.x2_flags = 3; + xb4_drawFlags.x4_color = col; x2e2_28_ = true; } - - if (x2e2_28_) + else if (x2e2_28_) { x2e2_28_ = false; - if (xb4_ != 5 && xb5_ != 0 && xb4_ != 3 && xb8_ != col) + if (xb4_drawFlags.x0_blendMode != 5 && xb4_drawFlags.x1_matSetIdx != 0 && + xb4_drawFlags.x2_flags != 3 && xb4_drawFlags.x4_color != col) { - xb4_ = 5; - xb5_ = 0; - xb6_ = 3; - xb8_ = col; + xb4_drawFlags.x0_blendMode = 5; + xb4_drawFlags.x1_matSetIdx = 0; + xb4_drawFlags.x2_flags = 3; + xb4_drawFlags.x4_color = col; } } if (!x2e2_24_ && xe6_27_ == 2 && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { - xb6_ &= ~3; + xb4_drawFlags.x2_flags &= ~3; } else { - xb6_ |= 3; + xb4_drawFlags.x2_flags |= 3; } if (x2d8_ != 0) - xb5_ = 0; + xb4_drawFlags.x1_matSetIdx = 0; } if (mgr.GetObjectById(x2e0_triggerId) == nullptr) diff --git a/Runtime/World/CScriptVisorFlare.cpp b/Runtime/World/CScriptVisorFlare.cpp index e69de29bb..f8dc30f4b 100644 --- a/Runtime/World/CScriptVisorFlare.cpp +++ b/Runtime/World/CScriptVisorFlare.cpp @@ -0,0 +1,53 @@ +#include "CScriptVisorFlare.hpp" +#include "CActorParameters.hpp" +#include "TCastTo.hpp" +#include "CStateManager.hpp" +#include "CPlayer.hpp" + +namespace urde +{ + +CScriptVisorFlare::CScriptVisorFlare(TUniqueId uid, const std::string& name, const CEntityInfo& info, + bool active, const zeus::CVector3f& pos, CVisorFlare::EBlendMode blendMode, + bool b1, float f1, float f2, float f3, u32 w1, u32 w2, + const std::vector& flares) +: CActor(uid, active, name, info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), + CMaterialList(EMaterialTypes::Unknown), CActorParameters::None(), kInvalidUniqueId), + xe8_flare(blendMode, b1, f1, f2, f3, w1, w2, flares) +{ + xe6_27_ = 2; +} + +void CScriptVisorFlare::Accept(IVisitor& visitor) +{ + visitor.Visit(this); +} + +void CScriptVisorFlare::Think(float dt, CStateManager& stateMgr) +{ + if (GetActive()) + xe8_flare.Update(dt, GetTranslation(), this, stateMgr); +} + +void CScriptVisorFlare::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) +{ + CActor::AcceptScriptMsg(msg, objId, stateMgr); +} + +void CScriptVisorFlare::PreRender(CStateManager& stateMgr, const zeus::CFrustum&) +{ + x11c_notInRenderLast = !stateMgr.RenderLast(x8_uid); +} + +void CScriptVisorFlare::AddToRenderer(const zeus::CFrustum&, const CStateManager& stateMgr) const +{ + if (x11c_notInRenderLast) + EnsureRendered(stateMgr, stateMgr.GetPlayer().GetTranslation(), GetSortingBounds(stateMgr)); +} + +void CScriptVisorFlare::Render(const CStateManager& stateMgr) const +{ + xe8_flare.Render(GetTranslation(), stateMgr); +} + +} diff --git a/Runtime/World/CScriptVisorFlare.hpp b/Runtime/World/CScriptVisorFlare.hpp index e69de29bb..b90be87a2 100644 --- a/Runtime/World/CScriptVisorFlare.hpp +++ b/Runtime/World/CScriptVisorFlare.hpp @@ -0,0 +1,31 @@ +#ifndef __URDE_CSCRIPTVISORFLARE_HPP__ +#define __URDE_CSCRIPTVISORFLARE_HPP__ + +#include "CActor.hpp" +#include "CVisorFlare.hpp" + +namespace urde +{ + +class CScriptVisorFlare : public CActor +{ + CVisorFlare xe8_flare; + bool x11c_notInRenderLast = true; + +public: + CScriptVisorFlare(TUniqueId, const std::string& name, const CEntityInfo& info, + bool, const zeus::CVector3f&, CVisorFlare::EBlendMode blendMode, + bool, float, float, float, u32, u32, + const std::vector& flares); + + void Accept(IVisitor& visitor); + void Think(float, CStateManager& stateMgr); + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); + void PreRender(CStateManager&, const zeus::CFrustum&); + void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const; + void Render(const CStateManager&) const; +}; + +} + +#endif // __URDE_CSCRIPTVISORFLARE_HPP__ diff --git a/Runtime/World/CVisorFlare.cpp b/Runtime/World/CVisorFlare.cpp new file mode 100644 index 000000000..092c8a9af --- /dev/null +++ b/Runtime/World/CVisorFlare.cpp @@ -0,0 +1,42 @@ +#include "CVisorFlare.hpp" +#include "CSimplePool.hpp" +#include "GameGlobalObjects.hpp" + +namespace urde +{ + +std::experimental::optional CVisorFlare::LoadFlareDef(CInputStream& in) +{ + u32 propCount = in.readUint32Big(); + if (propCount != 4) + return {}; + + u32 txtrId = in.readUint32Big(); + float f1 = in.readFloatBig(); + float f2 = in.readFloatBig(); + zeus::CColor color = zeus::CColor::ReadRGBABig(in); + if (txtrId == -1) + return {}; + + TToken tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), txtrId}); + + return CFlareDef(tex, f1, f2, color); +} + +CVisorFlare::CVisorFlare(EBlendMode blendMode, bool b1, float f1, float f2, float f3, u32 w1, u32 w2, + const std::vector& flares) +: x0_blendMode(blendMode), x4_flareDefs(flares), x14_b1(b1), x18_f1(std::max(f1, 0.0001f)), + x1c_f2(f2), x20_f3(f3), x2c_w1(w1), x30_w2(w2) +{} + +void CVisorFlare::Update(float dt, const zeus::CVector3f& pos, const CActor* act, CStateManager& mgr) +{ + +} + +void CVisorFlare::Render(const zeus::CVector3f& pos, const CStateManager& mgr) const +{ + +} + +} diff --git a/Runtime/World/CVisorFlare.hpp b/Runtime/World/CVisorFlare.hpp new file mode 100644 index 000000000..de83d3bd6 --- /dev/null +++ b/Runtime/World/CVisorFlare.hpp @@ -0,0 +1,51 @@ +#ifndef __URDE_CVISORFLARE_HPP__ +#define __URDE_CVISORFLARE_HPP__ + +#include "RetroTypes.hpp" +#include "CToken.hpp" + +namespace urde +{ +class CTexture; +class CActor; +class CStateManager; + +class CVisorFlare +{ +public: + enum class EBlendMode + { + + }; + class CFlareDef + { + TToken x0_tex; + float x8_f1; + float xc_f2; + zeus::CColor x10_color; + public: + CFlareDef(const TToken& tex, float f1, float f2, const zeus::CColor& color) + : x0_tex(tex), x8_f1(f1), xc_f2(f2), x10_color(color) { x0_tex.Lock(); } + }; +private: + EBlendMode x0_blendMode; + std::vector x4_flareDefs; + bool x14_b1; + float x18_f1; + float x1c_f2; + float x20_f3; + float x24_ = 0.f; + float x28_ = 0.f; + u32 x2c_w1; + u32 x30_w2; +public: + CVisorFlare(EBlendMode blendMode, bool, float, float, float, u32, u32, + const std::vector& flares); + void Update(float dt, const zeus::CVector3f& pos, const CActor* act, CStateManager& mgr); + void Render(const zeus::CVector3f& pos, const CStateManager& mgr) const; + static std::experimental::optional LoadFlareDef(CInputStream& in); +}; + +} + +#endif // __URDE_CVISORFLARE_HPP__ diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index e73eaa9b3..f6bb50814 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -57,6 +57,7 @@ #include "CRepulsor.hpp" #include "CScriptCameraPitchVolume.hpp" #include "CScriptCameraHintTrigger.hpp" +#include "CScriptVisorFlare.hpp" #include "CScriptBeam.hpp" #include "Camera/CCinematicCamera.hpp" #include "MP1/World/CNewIntroBoss.hpp" @@ -1823,7 +1824,25 @@ CEntity* ScriptLoader::LoadFishCloudModifier(CStateManager& mgr, CInputStream& i CEntity* ScriptLoader::LoadVisorFlare(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 14, "VisorFlare")) + return nullptr; + + std::string name = mgr.HashInstanceName(in); + zeus::CVector3f pos = zeus::CVector3f::ReadBig(in); + bool b1 = in.readBool(); + CVisorFlare::EBlendMode w1 = CVisorFlare::EBlendMode(in.readUint32Big()); + bool b2 = in.readBool(); + float f1 = in.readFloatBig(); + float f2 = in.readFloatBig(); + float f3 = in.readFloatBig(); + u32 w2 = in.readUint32Big(); + std::vector flares; + flares.reserve(5); + for (int i=0 ; i<5 ; ++i) + if (auto flare = CVisorFlare::LoadFlareDef(in)) + flares.push_back(*flare); + + return new CScriptVisorFlare(mgr.AllocateUniqueId(), name, info, b1, pos, w1, b2, f1, f2, f3, 2, w2, flares); } CEntity* ScriptLoader::LoadWorldTeleporter(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) diff --git a/hecl b/hecl index 8e1bc5d94..2bc1c3054 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 8e1bc5d94e83949e13fcb4c83071f8b195d9e23b +Subproject commit 2bc1c30547e891355bc99d8809f356d93c3ff7f3 diff --git a/specter b/specter index 6b909b404..d66529af9 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 6b909b404061c98df1fd8320bcffe2ccb13c9bcb +Subproject commit d66529af905afd39da49c6175c8bd9cf5c3a415e diff --git a/visigen/VISIRenderer.cpp b/visigen/VISIRenderer.cpp index d1c2cc3d5..5de3b8aed 100644 --- a/visigen/VISIRenderer.cpp +++ b/visigen/VISIRenderer.cpp @@ -551,12 +551,12 @@ void VISIRenderer::Run(FPercent updatePercent) Light& light = m_lights[i]; light.point = r.readVec3fBig(); } + } - if (!SetupVertexBuffersAndFormats()) - { - m_return = 1; - return; - } + if (!SetupVertexBuffersAndFormats()) + { + m_return = 1; + return; } VISIBuilder builder(*this);