From b405f33ded5b22940c2468790a7d6879418a73fd Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Wed, 14 Feb 2018 18:37:21 -1000 Subject: [PATCH] Correct rstl::prereserved_vector implementation --- DataSpec/DNAMP1/PATH.hpp | 2 +- Runtime/CPlayerState.cpp | 4 +- Runtime/CPlayerState.hpp | 2 +- Runtime/GuiSys/CHudVisorBeamMenu.cpp | 4 +- Runtime/GuiSys/CHudVisorBeamMenu.hpp | 4 +- Runtime/MP1/CSamusHud.cpp | 28 +- Runtime/MP1/CSamusHud.hpp | 4 +- Runtime/World/CActorModelParticles.hpp | 2 +- Runtime/World/CPathFindArea.cpp | 55 +- Runtime/World/CPathFindArea.hpp | 18 +- Runtime/World/CPathFindRegion.cpp | 69 ++- Runtime/World/CPathFindRegion.hpp | 26 +- Runtime/World/CPathFindSearch.cpp | 11 +- Runtime/World/CPathFindSearch.hpp | 7 +- Runtime/World/CScriptActorRotate.cpp | 2 +- Runtime/rstl.hpp | 737 ++++++++++--------------- specter | 2 +- 17 files changed, 478 insertions(+), 499 deletions(-) diff --git a/DataSpec/DNAMP1/PATH.hpp b/DataSpec/DNAMP1/PATH.hpp index 7ae59c25f..1ed69996f 100644 --- a/DataSpec/DNAMP1/PATH.hpp +++ b/DataSpec/DNAMP1/PATH.hpp @@ -22,8 +22,8 @@ struct PATH : BigDNA struct Link : BigDNA { DECL_DNA - Value regionIdx; Value nodeIdx; + Value regionIdx; Value width2d; Value oneOverWidth2d; }; diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp index 814489b8d..3eba07191 100644 --- a/Runtime/CPlayerState.cpp +++ b/Runtime/CPlayerState.cpp @@ -63,7 +63,7 @@ CPlayerState::CPlayerState() : x188_staticIntf(5) { x0_24_alive = true; - x24_powerups.set_size(41); + x24_powerups.resize(41); } CPlayerState::CPlayerState(CBitStreamReader& stream) @@ -74,7 +74,7 @@ CPlayerState::CPlayerState(CBitStreamReader& stream) xc_health.SetHP(*reinterpret_cast(&tmp)); x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5))); x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4))); - x24_powerups.set_size(41); + x24_powerups.resize(41); for (u32 i = 0; i < x24_powerups.size(); ++i) { if (PowerUpMaxValues[i] == 0) diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index 97d047731..1c63d9208 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -122,7 +122,7 @@ private: EPlayerVisor x18_transitioningVisor = x14_currentVisor; float x1c_visorTransitionFactor = 0.2f; EPlayerSuit x20_currentSuit = EPlayerSuit::Power; - rstl::prereserved_vector x24_powerups; + rstl::reserved_vector x24_powerups; rstl::reserved_vector, 846> x170_scanTimes; std::pair x180_scanCompletionRate = {}; CStaticInterference x188_staticIntf; diff --git a/Runtime/GuiSys/CHudVisorBeamMenu.cpp b/Runtime/GuiSys/CHudVisorBeamMenu.cpp index 3092dc7d3..7a6cf991d 100644 --- a/Runtime/GuiSys/CHudVisorBeamMenu.cpp +++ b/Runtime/GuiSys/CHudVisorBeamMenu.cpp @@ -52,7 +52,7 @@ static const u16 SelectionSfxs[] = }; CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, - const rstl::prereserved_vector& enables) + const rstl::reserved_vector& enables) : x0_baseHud(baseHud), x4_type(type) { x14_24_visibleDebug = true; @@ -300,7 +300,7 @@ void CHudVisorBeamMenu::SetIsVisibleGame(bool v) Update(0.f, true); } -void CHudVisorBeamMenu::SetPlayerHas(const rstl::prereserved_vector& enables) +void CHudVisorBeamMenu::SetPlayerHas(const rstl::reserved_vector& enables) { for (int i=0 ; i<4 ; ++i) { diff --git a/Runtime/GuiSys/CHudVisorBeamMenu.hpp b/Runtime/GuiSys/CHudVisorBeamMenu.hpp index a86eed863..0914d3d6a 100644 --- a/Runtime/GuiSys/CHudVisorBeamMenu.hpp +++ b/Runtime/GuiSys/CHudVisorBeamMenu.hpp @@ -59,11 +59,11 @@ private: void UpdateMenuWidgetTransform(int, CGuiWidget& w, float); public: CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type, - const rstl::prereserved_vector& enables); + const rstl::reserved_vector& enables); void Update(float dt, bool init); void UpdateHudAlpha(float alpha); void SetIsVisibleGame(bool v); - void SetPlayerHas(const rstl::prereserved_vector& enables); + void SetPlayerHas(const rstl::reserved_vector& enables); void SetSelection(int, int, float); }; diff --git a/Runtime/MP1/CSamusHud.cpp b/Runtime/MP1/CSamusHud.cpp index d6703dd55..d80d0cb7d 100644 --- a/Runtime/MP1/CSamusHud.cpp +++ b/Runtime/MP1/CSamusHud.cpp @@ -51,12 +51,12 @@ CSamusHud::CSamusHud(CStateManager& stateMgr) x274_loadedFrmeBaseHud->SetMaxAspect(1.78f); x2a0_helmetIntf = std::make_unique(*x264_loadedFrmeHelmet); - rstl::prereserved_vector hasVisors = BuildPlayerHasVisors(stateMgr); + rstl::reserved_vector hasVisors = BuildPlayerHasVisors(stateMgr); x2a4_visorMenu = std::make_unique(*x274_loadedFrmeBaseHud, CHudVisorBeamMenu::EHudVisorBeamMenu::Visor, hasVisors); - rstl::prereserved_vector hasBeams = BuildPlayerHasBeams(stateMgr); + rstl::reserved_vector hasBeams = BuildPlayerHasBeams(stateMgr); x2a8_beamMenu = std::make_unique(*x274_loadedFrmeBaseHud, CHudVisorBeamMenu::EHudVisorBeamMenu::Beam, hasBeams); @@ -76,23 +76,23 @@ CSamusHud::~CSamusHud() g_SamusHud = nullptr; } -rstl::prereserved_vector CSamusHud::BuildPlayerHasVisors(const CStateManager& mgr) +rstl::reserved_vector CSamusHud::BuildPlayerHasVisors(const CStateManager& mgr) { - rstl::prereserved_vector ret; - ret[0] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::CombatVisor); - ret[1] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::XRayVisor); - ret[2] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ScanVisor); - ret[3] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ThermalVisor); + rstl::reserved_vector ret; + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::CombatVisor)); + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::XRayVisor)); + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ScanVisor)); + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ThermalVisor)); return ret; } -rstl::prereserved_vector CSamusHud::BuildPlayerHasBeams(const CStateManager& mgr) +rstl::reserved_vector CSamusHud::BuildPlayerHasBeams(const CStateManager& mgr) { - rstl::prereserved_vector ret; - ret[0] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PowerBeam); - ret[1] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::IceBeam); - ret[2] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::WaveBeam); - ret[3] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PlasmaBeam); + rstl::reserved_vector ret; + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PowerBeam)); + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::IceBeam)); + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::WaveBeam)); + ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PlasmaBeam)); return ret; } diff --git a/Runtime/MP1/CSamusHud.hpp b/Runtime/MP1/CSamusHud.hpp index 3797fdea6..c3eafda95 100644 --- a/Runtime/MP1/CSamusHud.hpp +++ b/Runtime/MP1/CSamusHud.hpp @@ -194,8 +194,8 @@ class CSamusHud CCookieCutterDepthRandomStaticFilter m_cookieCutterStatic = { EFilterType::NoColor }; static CSamusHud* g_SamusHud; - static rstl::prereserved_vector BuildPlayerHasVisors(const CStateManager& mgr); - static rstl::prereserved_vector BuildPlayerHasBeams(const CStateManager& mgr); + static rstl::reserved_vector BuildPlayerHasVisors(const CStateManager& mgr); + static rstl::reserved_vector BuildPlayerHasBeams(const CStateManager& mgr); void InitializeFrameGluePermanent(const CStateManager& mgr); void InitializeFrameGlueMutable(const CStateManager& mgr); void UninitializeFrameGlueMutable(); diff --git a/Runtime/World/CActorModelParticles.hpp b/Runtime/World/CActorModelParticles.hpp index 228568bf1..737ba5a11 100644 --- a/Runtime/World/CActorModelParticles.hpp +++ b/Runtime/World/CActorModelParticles.hpp @@ -34,7 +34,7 @@ public: u32 x80_ = 0; u32 x84_ = -1; u32 x88_seed1 = 99; - rstl::prereserved_vector, 4> x8c_thermalColdParticles; + rstl::reserved_vector, 4> x8c_thermalColdParticles; s32 xb0_ = -1; u32 xb4_seed2 = 99; std::unique_ptr xb8_; diff --git a/Runtime/World/CPathFindArea.cpp b/Runtime/World/CPathFindArea.cpp index 5ea8ad5bf..d60902ec8 100644 --- a/Runtime/World/CPathFindArea.cpp +++ b/Runtime/World/CPathFindArea.cpp @@ -1,3 +1,4 @@ +#include #include "CPathFindArea.hpp" #include "IVParamObj.hpp" #include "CToken.hpp" @@ -8,12 +9,12 @@ namespace urde CPFAreaOctree::CPFAreaOctree(CMemoryInStream& in) { x0_isLeaf = in.readUint32Big(); - for (int i=0 ; i<3 ; ++i) - x4_points[i] = in.readVec3fBig(); + x4_aabb.readBoundingBoxBig(in); + x1c_center.readBig(in); for (int i=0 ; i<8 ; ++i) x28_children[i] = reinterpret_cast(in.readUint32Big()); - x48_regionCount = in.readUint32Big(); - x4c_regions = reinterpret_cast(in.readUint32Big()); + x48_regions.set_size(in.readUint32Big()); + x48_regions.set_data(reinterpret_cast(in.readUint32Big())); } void CPFAreaOctree::Fixup(CPFArea& area) @@ -21,9 +22,9 @@ void CPFAreaOctree::Fixup(CPFArea& area) x0_isLeaf = x0_isLeaf != 0 ? 1 : 0; if (x0_isLeaf) { - if (!x48_regionCount) + if (x48_regions.empty()) return; - x4c_regions = &area.x160_octreeRegionLookup[reinterpret_cast(x4c_regions)]; + x48_regions.set_data(&area.x160_octreeRegionLookup[reinterpret_cast(x48_regions.data())]); return; } @@ -36,6 +37,18 @@ void CPFAreaOctree::Fixup(CPFArea& area) } } +int CPFAreaOctree::GetChildIndex(const zeus::CVector3f& point) const +{ + int idx = 0x0; + if (point.x > x1c_center.x) + idx = 0x1; + if (point.y > x1c_center.y) + idx |= 0x2; + if (point.z > x1c_center.z) + idx |= 0x4; + return idx; +} + CPFOpenList::CPFOpenList() { @@ -75,12 +88,12 @@ CPFArea::CPFArea(std::unique_ptr&& buf, u32 len) x10_.reserve(maxRegionNodes); u32 numBitfieldWords = (numRegions * (numRegions - 1) / 2 + 31) / 32; - x168_connectionsA.reserve(numBitfieldWords); + x168_connectionsGround.reserve(numBitfieldWords); for (u32 i=0 ; i&& buf, u32 len) node.Fixup(*this); } +bool CPFArea::PathExists(const CPFRegion* r1, const CPFRegion* r2, u32 flags) const +{ + if (r1 == r2 || (flags & 0x4) != 0) + return true; + + u32 i1 = r1->GetIndex(); + u32 i2 = r2->GetIndex(); + if (i1 > i2) + std::swap(i1, i2); + + u32 remRegions = u32(x150_regions.size()) - i1; + u32 remConnections = remRegions * (remRegions - 1) / 2; + u32 totalConnections = u32(x150_regions.size()) * (u32(x150_regions.size()) - 1) / 2; + u32 bit = totalConnections - remConnections + i2 - (i1 + 1); + + auto d = std::div(bit, 32); + if ((flags & 0x2) != 0) + return ((x170_connectionsFlyers[d.quot] >> d.rem) & 0x1) == 0x1; + else + return ((x168_connectionsGround[d.quot] >> d.rem) & 0x1) == 0x1; +} + CFactoryFnReturn FPathFindAreaFactory(const urde::SObjectTag& tag, std::unique_ptr&& in, u32 len, const urde::CVParamTransfer& vparms, diff --git a/Runtime/World/CPathFindArea.hpp b/Runtime/World/CPathFindArea.hpp index 9c6282249..c21ac4625 100644 --- a/Runtime/World/CPathFindArea.hpp +++ b/Runtime/World/CPathFindArea.hpp @@ -25,16 +25,16 @@ public: class CPFAreaOctree { u32 x0_isLeaf; - zeus::CVector3f x4_points[3]; + zeus::CAABox x4_aabb; + zeus::CVector3f x1c_center; CPFAreaOctree* x28_children[8]; - u32 x48_regionCount; - CPFRegion** x4c_regions; + rstl::prereserved_vector x48_regions; public: CPFAreaOctree(CMemoryInStream& in); void Fixup(CPFArea& area); - void GetChildIndex(const zeus::CVector3f&) const; + int GetChildIndex(const zeus::CVector3f& point) const; void GetRegionList(const zeus::CVector3f&) const; - //void GetRegionListList(rstl::reserved_vector, 32>, const zeus::CVector3f&, float); + void GetRegionListList(rstl::reserved_vector*, 32>, const zeus::CVector3f&, float); bool IsPointInPaddedAABox(const zeus::CVector3f&, float); void Render(); }; @@ -102,13 +102,16 @@ class CPFArea CPFOpenList x78_; u32 x138_; //std::unique_ptr x13c_data; + /* Used to be prereserved_vectors backed by x13c_data + * This has been changed to meet storage requirements of + * modern systems */ std::vector x140_nodes; // x140: count, x144: ptr std::vector x148_links; // x148: count, x14c: ptr std::vector x150_regions; // x150: count, x154: ptr std::vector x158_octree; // x158: count, x15c: ptr std::vector x160_octreeRegionLookup; // x160: count, x164: ptr - std::vector x168_connectionsA; // x168: word_count, x16c: ptr - std::vector x170_connectionsB; // x170: word_count, x174: ptr + std::vector x168_connectionsGround; // x168: word_count, x16c: ptr + std::vector x170_connectionsFlyers; // x170: word_count, x174: ptr std::vector x178_regionDatas; zeus::CTransform x188_transform; public: @@ -129,6 +132,7 @@ public: void FindRegions(rstl::reserved_vector&, const zeus::CVector3f&, u32); void FindClosestRegion(const zeus::CVector3f&, u32, float); void FindClosestReachablePoint(rstl::reserved_vector&, const zeus::CVector3f&, u32); + bool PathExists(const CPFRegion* r1, const CPFRegion* r2, u32 flags) const; }; diff --git a/Runtime/World/CPathFindRegion.cpp b/Runtime/World/CPathFindRegion.cpp index c89b8fd7f..c21d3e898 100644 --- a/Runtime/World/CPathFindRegion.cpp +++ b/Runtime/World/CPathFindRegion.cpp @@ -12,8 +12,8 @@ CPFNode::CPFNode(CMemoryInStream& in) CPFLink::CPFLink(CMemoryInStream& in) { - x0_region = in.readUint32Big(); - x4_node = in.readUint32Big(); + x0_node = in.readUint32Big(); + x4_region = in.readUint32Big(); x8_2dWidth = in.readFloatBig(); xc_oo2dWidth = in.readFloatBig(); } @@ -48,4 +48,69 @@ void CPFRegion::Fixup(CPFArea& area, u32& maxRegionNodes) maxRegionNodes = x0_numNodes; } +zeus::CVector3f CPFRegion::FitThroughLink2d(const zeus::CVector3f& p1, const CPFLink& link, + const zeus::CVector3f& p2, float f1) const +{ + CPFNode& node = x4_startNode[link.GetNode()]; + CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes]; + zeus::CVector3f nodeDelta = nextNode.GetPos() - node.GetPos(); + float t = 0.5f; + if (f1 < 0.5f * link.Get2dWidth()) + { + zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y); + delta2d *= link.GetOO2dWidth(); + zeus::CVector3f nodeToP1 = p1 - node.GetPos(); + float f27 = nodeToP1.dot(node.GetNormal()); + float f31 = delta2d.dot(zeus::CVector2f(nodeToP1.y, nodeToP1.y)); + zeus::CVector3f nodeToP2 = p2 - node.GetPos(); + float f26 = -nodeToP2.dot(node.GetNormal()); + float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y)); + float f3 = f27 + f26; + if (f3 > FLT_EPSILON) + t = zeus::clamp(f1, 1.f / f3 * (f26 * f31 + f27 * f1b), link.Get2dWidth() - f1) * link.GetOO2dWidth(); + } + return nodeDelta * t + node.GetPos(); +} + +zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPFLink& link, + float f1, const zeus::CVector3f& p2, float f2, float f3) const +{ + CPFNode& node = x4_startNode[link.GetNode()]; + CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes]; + zeus::CVector3f nodeDelta = nextNode.GetPos() - node.GetPos(); + float f25 = (p1 - node.GetPos()).dot(node.GetNormal()); + float f24 = (node.GetPos() - p2).dot(node.GetNormal()); + float f23 = f25 + f24; +# if 0 + if (f2 < 0.5f * link.Get2dWidth()) + { + zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y); + delta2d *= link.GetOO2dWidth(); + zeus::CVector3f nodeToP1 = p1 - node.GetPos(); + float f29 = delta2d.dot(zeus::CVector2f(nodeToP1.y, nodeToP1.y)); + zeus::CVector3f nodeToP2 = p2 - node.GetPos(); + float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y)); + if (f23 > FLT_EPSILON) + { + zeus::clamp(f2, 1.f / f23 * f24 * f29 + f25 * f1b, link.Get2dWidth() - f2) * link.GetOO2dWidth(); + } + } +#endif + zeus::CVector3f midPoint = nodeDelta * 0.5f + node.GetPos(); + float z; + if (f3 < 0.5f * f1) + { + float minZ = f3 + midPoint.z; + z = 0.5f * (p1.z + p2.z); + if (f23 > FLT_EPSILON) + z = 1.f / f23 * (f24 * p1.z + f25 * p2.z); + z = zeus::clamp(minZ, z, f1 + midPoint.z - f3); + } + else + { + z = (p1.z + p2.z) * 0.5f; + } + return {midPoint.x, midPoint.y, z}; +} + } diff --git a/Runtime/World/CPathFindRegion.hpp b/Runtime/World/CPathFindRegion.hpp index 401d2b503..36bba5712 100644 --- a/Runtime/World/CPathFindRegion.hpp +++ b/Runtime/World/CPathFindRegion.hpp @@ -22,14 +22,14 @@ public: class CPFLink { - u32 x0_region; - u32 x4_node; + u32 x0_node; + u32 x4_region; float x8_2dWidth; float xc_oo2dWidth; public: CPFLink(CMemoryInStream& in); - u32 GetRegion() const { return x0_region; } - u32 GetNode() const { return x4_node; } + u32 GetNode() const { return x0_node; } + u32 GetRegion() const { return x4_region; } float Get2dWidth() const { return x8_2dWidth; } float GetOO2dWidth() const { return xc_oo2dWidth; } }; @@ -52,7 +52,7 @@ public: CPFRegion(CMemoryInStream& in); void SetData(CPFRegionData* data) { x4c_regionData = data; } CPFRegionData* Data() const { return x4c_regionData; } - void GetIndex() const; + u32 GetIndex() const { return x24_regionIdx; } float GetHeight() const { return x14_height; } void GetPathLink() const {} u32 GetNumLinks() const { return x8_numLinks; } @@ -72,8 +72,8 @@ public: void SetLinkTo(s32); void DropToGround(zeus::CVector3f&) const; void GetLinkMidPoint(const CPFLink&); - void FitThroughLink2d(const zeus::CVector3f&, const CPFLink&, const zeus::CVector3f&, float) const; - void FitThroughLink3d(const zeus::CVector3f&, const CPFLink&, float, const zeus::CVector3f&, float, float) const; + zeus::CVector3f FitThroughLink2d(const zeus::CVector3f&, const CPFLink&, const zeus::CVector3f&, float) const; + zeus::CVector3f FitThroughLink3d(const zeus::CVector3f&, const CPFLink&, float, const zeus::CVector3f&, float, float) const; void IsPointInsidePaddedAABox(const zeus::CVector3f&, float) const; }; @@ -81,12 +81,12 @@ class CPFRegionData { float x0_ = 0.f; zeus::CVector3f x4_; - s32 x10_ = -1; + s32 x10_cookie = -1; zeus::CVector3f x14_; s32 x20_ = 0; CPFRegion* x24_openLess = nullptr; CPFRegion* x28_openMore = nullptr; - s32 x2c_ = 0; + s32 x2c_pathLink = 0; public: CPFRegionData() = default; @@ -95,16 +95,16 @@ public: CPFRegion* GetOpenLess() const { return x24_openLess; } CPFRegion* GetOpenMore() const { return x28_openMore; } void GetCost(); - void GetPathLink() const; + s32 GetPathLink() const { return x2c_pathLink; } + void SetPathLink(s32 l) { x2c_pathLink = l; } void GetParent() const; void Setup(CPFRegion*, float, float); void SetBestPoint(const zeus::CVector3f&); void SetBestPointDistanceSquared(float); float GetBestPointDistanceSquared() const; - void SetPathLink(s32); - void SetCookie(s32); zeus::CVector3f GetBestPoint() const; - void GetCookie() const; + void SetCookie(s32 c) { x10_cookie = c; } + s32 GetCookie() const { return x10_cookie; } }; } diff --git a/Runtime/World/CPathFindSearch.cpp b/Runtime/World/CPathFindSearch.cpp index cdd7a0699..c7aee4c88 100644 --- a/Runtime/World/CPathFindSearch.cpp +++ b/Runtime/World/CPathFindSearch.cpp @@ -3,10 +3,17 @@ namespace urde { -CPathFindSearch::CPathFindSearch(CPFArea* area, u32 w1, u32 w2, float f1, float f2) -: x0_area(area), xd0_f2(f2), xd4_f1(f1), xdc_w1(w1), xe0_w2(1u << w2) +CPathFindSearch::CPathFindSearch(CPFArea* area, u32 flags, u32 w2, float f1, float f2) +: x0_area(area), xd0_f2(f2), xd4_f1(f1), xdc_flags(flags), xe0_w2(1u << w2) { } +void CPathFindSearch::Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2) +{ + x4_.clear(); + xc8_ = 0; + +} + } diff --git a/Runtime/World/CPathFindSearch.hpp b/Runtime/World/CPathFindSearch.hpp index 687382151..47cd4e65e 100644 --- a/Runtime/World/CPathFindSearch.hpp +++ b/Runtime/World/CPathFindSearch.hpp @@ -10,15 +10,16 @@ namespace urde class CPathFindSearch { CPFArea* x0_area; - u32 x4_ = 0; + rstl::reserved_vector x4_; u32 xc8_ = 0; float xd0_f2; float xd4_f1; float xd8_ = 10.f; - u32 xdc_w1; + u32 xdc_flags; // 0x2: flyer, 0x4: path-always-exists u32 xe0_w2; public: - CPathFindSearch(CPFArea* area, u32 w1, u32 w2, float f1, float f2); + CPathFindSearch(CPFArea* area, u32 flags, u32 w2, float f1, float f2); + void Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2); }; } diff --git a/Runtime/World/CScriptActorRotate.cpp b/Runtime/World/CScriptActorRotate.cpp index 8744218c8..aa82216c6 100644 --- a/Runtime/World/CScriptActorRotate.cpp +++ b/Runtime/World/CScriptActorRotate.cpp @@ -142,7 +142,7 @@ void CScriptActorRotate::UpdateActors(bool next, CStateManager& mgr) void CScriptActorRotate::UpdateSpiderBallWaypoints(CStateManager& mgr) { - rstl::prereserved_vector waypointIds; + rstl::reserved_vector waypointIds; CObjectList& objectList = mgr.GetAllObjectList(); for (CEntity* ent : objectList) { diff --git a/Runtime/rstl.hpp b/Runtime/rstl.hpp index 2437381f4..317e534c9 100644 --- a/Runtime/rstl.hpp +++ b/Runtime/rstl.hpp @@ -21,37 +21,17 @@ using optional_object = std::experimental::optional; /** * @brief Base vector backed by statically-allocated array */ -template +template class _reserved_vector_base { -protected: - union alignas(T) storage_t - { - struct {} _dummy; - T _value; - storage_t() : _dummy() {} - ~storage_t() {} - }; - explicit _reserved_vector_base(size_t _init_sz) : x0_size(_init_sz) {} - size_t x0_size; - storage_t x4_data[N]; - T& _value(std::ptrdiff_t idx) { return x4_data[idx]._value; } - const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; } - template - static void destroy(Tp& t, std::enable_if_t::value && - !std::is_trivially_destructible::value>* = 0) { t.Tp::~Tp(); } - template - static void destroy(Tp& t, std::enable_if_t::value || - std::is_trivially_destructible::value>* = 0) {} - public: class const_iterator { friend class _reserved_vector_base; protected: const T* m_val; - explicit const_iterator(const T* val) : m_val(val) {} public: + explicit const_iterator(const T* val) : m_val(val) {} using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -81,8 +61,8 @@ public: class iterator : public const_iterator { friend class _reserved_vector_base; - explicit iterator(T* val) : const_iterator(val) {} public: + explicit iterator(T* val) : const_iterator(val) {} T& operator*() const { return *const_cast(const_iterator::m_val); } T* operator->() const { return const_cast(const_iterator::m_val); } iterator& operator++() { ++const_iterator::m_val; return *this; } @@ -102,8 +82,8 @@ public: friend class _reserved_vector_base; protected: const T* m_val; - explicit const_reverse_iterator(const T* val) : m_val(val) {} public: + explicit const_reverse_iterator(const T* val) : m_val(val) {} using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; @@ -133,8 +113,8 @@ public: class reverse_iterator : public const_reverse_iterator { friend class _reserved_vector_base; - explicit reverse_iterator(T* val) : const_reverse_iterator(val) {} public: + explicit reverse_iterator(T* val) : const_reverse_iterator(val) {} T& operator*() const { return *const_cast(const_reverse_iterator::m_val); } T* operator->() const { return const_cast(const_reverse_iterator::m_val); } reverse_iterator& operator++() { --const_reverse_iterator::m_val; return *this; } @@ -151,6 +131,265 @@ public: T& operator[](std::ptrdiff_t i) const { return const_cast(const_reverse_iterator::m_val)[-i]; } }; +protected: + static iterator _const_cast_iterator(const const_iterator& it) { return iterator(const_cast(it.m_val)); } +}; + +/** + * @brief Vector backed by statically-allocated array with uninitialized storage + */ +template +class reserved_vector : public _reserved_vector_base +{ + union alignas(T) storage_t + { + struct {} _dummy; + T _value; + storage_t() : _dummy() {} + ~storage_t() {} + }; + size_t x0_size; + storage_t x4_data[N]; + T& _value(std::ptrdiff_t idx) { return x4_data[idx]._value; } + const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; } + template + static void destroy(Tp& t, std::enable_if_t::value && + !std::is_trivially_destructible::value>* = 0) { t.Tp::~Tp(); } + template + static void destroy(Tp& t, std::enable_if_t::value || + std::is_trivially_destructible::value>* = 0) {} + +public: + using base = _reserved_vector_base; + using iterator = typename base::iterator; + using const_iterator = typename base::const_iterator; + using reverse_iterator = typename base::reverse_iterator; + using const_reverse_iterator = typename base::const_reverse_iterator; + reserved_vector() : x0_size(0) {} + + reserved_vector(const reserved_vector& other) : x0_size(other.x0_size) + { + for (size_t i=0 ; i(std::addressof(_value(i)))) T(other._value(i)); + } + + reserved_vector& operator=(const reserved_vector& other) + { + size_t i = 0; + if (other.x0_size > x0_size) + { + for (; i(std::addressof(_value(i)))) T(other._value(i)); + } + else if (other.x0_size < x0_size) + { + for (; i::value && !std::is_trivially_destructible::value) + for (; i(std::addressof(_value(i)))) T(std::forward(other._value(i))); + } + + reserved_vector& operator=(reserved_vector&& other) + { + size_t i = 0; + if (other.x0_size > x0_size) + { + for (; i(other._value(i)); + for (; i(std::addressof(_value(i)))) T(std::forward(other._value(i))); + } + else if (other.x0_size < x0_size) + { + for (; i(other._value(i)); + if (std::is_destructible::value && !std::is_trivially_destructible::value) + for (; i(other._value(i)); + } + x0_size = other.x0_size; + return *this; + } + + ~reserved_vector() + { + if (std::is_destructible::value && !std::is_trivially_destructible::value) + for (size_t i=0 ; i(std::addressof(_value(x0_size)))) T(d); + ++x0_size; + } + + void push_back(T&& d) + { +#ifndef NDEBUG + if (x0_size == N) + Log.report(logvisor::Fatal, "push_back() called on full rstl::reserved_vector."); +#endif + ::new (static_cast(std::addressof(_value(x0_size)))) T(std::forward(d)); + ++x0_size; + } + + template + void emplace_back(_Args&&... args) + { +#ifndef NDEBUG + if (x0_size == N) + Log.report(logvisor::Fatal, "emplace_back() called on full rstl::reserved_vector."); +#endif + ::new (static_cast(std::addressof(_value(x0_size)))) T(std::forward<_Args>(args)...); + ++x0_size; + } + + void pop_back() + { +#ifndef NDEBUG + if (x0_size == 0) + Log.report(logvisor::Fatal, "pop_back() called on empty rstl::reserved_vector."); +#endif + --x0_size; + destroy(_value(x0_size)); + } + + iterator insert(const_iterator pos, const T& value) + { +#ifndef NDEBUG + if (x0_size == N) + Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector."); +#endif + auto target_it = base::_const_cast_iterator(pos); + if (pos == cend()) + { + ::new (static_cast(std::addressof(_value(x0_size)))) T(value); + } + else + { + ::new (static_cast(std::addressof(_value(x0_size)))) + T(std::forward(_value(x0_size - 1))); + for (auto it = end() - 1; it != target_it; --it) + *it = std::forward(*(it - 1)); + *target_it = value; + } + ++x0_size; + return target_it; + } + + iterator insert(const_iterator pos, T&& value) + { +#ifndef NDEBUG + if (x0_size == N) + Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector."); +#endif + auto target_it = base::_const_cast_iterator(pos); + if (pos == cend()) + { + ::new (static_cast(std::addressof(_value(x0_size)))) T(std::forward(value)); + } + else + { + ::new (static_cast(std::addressof(_value(x0_size)))) + T(std::forward(_value(x0_size - 1))); + for (auto it = end() - 1; it != target_it; --it) + *it = std::forward(*(it - 1)); + *target_it = std::forward(value); + } + ++x0_size; + return target_it; + } + + void resize(size_t size) + { +#ifndef NDEBUG + if (size > N) + Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector."); +#endif + if (size > x0_size) + { + for (size_t i = x0_size; i < size; ++i) + ::new (static_cast(std::addressof(_value(i)))) T(); + x0_size = size; + } + else if (size < x0_size) + { + if (std::is_destructible::value && !std::is_trivially_destructible::value) + for (size_t i = size; i < x0_size; ++i) + destroy(_value(i)); + x0_size = size; + } + } + + void resize(size_t size, const T& value) + { +#ifndef NDEBUG + if (size > N) + Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector."); +#endif + if (size > x0_size) + { + for (size_t i = x0_size; i < size; ++i) + ::new (static_cast(std::addressof(_value(i)))) T(value); + x0_size = size; + } + else if (size < x0_size) + { + if (std::is_destructible::value && !std::is_trivially_destructible::value) + for (size_t i = size; i < x0_size; ++i) + destroy(_value(i)); + x0_size = size; + } + } + + iterator erase(const_iterator pos) + { +#ifndef NDEBUG + if (x0_size == 0) + Log.report(logvisor::Fatal, "erase() called on empty rstl::reserved_vector."); +#endif + for (auto it = base::_const_cast_iterator(pos) + 1; it != end(); ++it) + *(it - 1) = std::forward(*it); + --x0_size; + destroy(_value(x0_size)); + return base::_const_cast_iterator(pos); + } + + void clear() + { + if (std::is_destructible::value && !std::is_trivially_destructible::value) + for (auto it = begin(); it != end(); ++it) + destroy(*it); + x0_size = 0; + } + size_t size() const noexcept { return x0_size; } bool empty() const noexcept { return x0_size == 0; } constexpr size_t capacity() const noexcept { return N; } @@ -179,430 +418,58 @@ public: T& operator[](size_t idx) { return _value(idx); } const T& operator[](size_t idx) const { return _value(idx); } - -protected: - static iterator _const_cast_iterator(const const_iterator& it) { return iterator(const_cast(it.m_val)); } }; /** - * @brief Vector backed by statically-allocated array with uninitialized storage + * @brief Vector-style view backed by externally-allocated storage */ -template -class reserved_vector : public _reserved_vector_base +template +class prereserved_vector : public _reserved_vector_base { + size_t x0_size; + T* x4_data; + T& _value(std::ptrdiff_t idx) { return x4_data[idx]; } + const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]; } + public: - using base = _reserved_vector_base; + using base = _reserved_vector_base; using iterator = typename base::iterator; using const_iterator = typename base::const_iterator; - reserved_vector() : base(0) {} + using reverse_iterator = typename base::reverse_iterator; + using const_reverse_iterator = typename base::const_reverse_iterator; + prereserved_vector() : x0_size(0), x4_data(nullptr) {} + prereserved_vector(size_t size, T* data) : x0_size(size), x4_data(data) {} - reserved_vector(const reserved_vector& other) : base(other.x0_size) - { - for (size_t i=0 ; i(std::addressof(base::_value(i)))) T(other.base::_value(i)); - } + void set_size(size_t n) { x0_size = n; } + void set_data(T* data) { x4_data = data; } - reserved_vector& operator=(const reserved_vector& other) - { - size_t i = 0; - if (other.base::x0_size > base::x0_size) - { - for (; i(std::addressof(base::_value(i)))) T(other.base::_value(i)); - } - else if (other.base::x0_size < base::x0_size) - { - for (; i::value && !std::is_trivially_destructible::value) - for (; i(std::addressof(base::_value(i)))) T(std::forward(other.base::_value(i))); - } + T& back() { return _value(x0_size - 1); } + T& front() { return _value(0); } + const T& back() const { return _value(x0_size - 1); } + const T& front() const { return _value(0); } - reserved_vector& operator=(reserved_vector&& other) - { - size_t i = 0; - if (other.base::x0_size > base::x0_size) - { - for (; i(other.base::_value(i)); - for (; i(std::addressof(base::_value(i)))) T(std::forward(other.base::_value(i))); - } - else if (other.base::x0_size < base::x0_size) - { - for (; i(other.base::_value(i)); - if (std::is_destructible::value && !std::is_trivially_destructible::value) - for (; i(other.base::_value(i)); - } - base::x0_size = other.base::x0_size; - return *this; - } + const_iterator begin() const noexcept { return const_iterator(std::addressof(_value(0))); } + const_iterator end() const noexcept { return const_iterator(std::addressof(_value(x0_size))); } + iterator begin() noexcept { return iterator(std::addressof(_value(0))); } + iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); } + const_iterator cbegin() const noexcept { return begin(); } + const_iterator cend() const noexcept { return end(); } - ~reserved_vector() - { - if (std::is_destructible::value && !std::is_trivially_destructible::value) - for (size_t i=0 ; i(std::addressof(base::_value(base::x0_size)))) T(d); - ++base::x0_size; - } - - void push_back(T&& d) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "push_back() called on full rstl::reserved_vector."); -#endif - ::new (static_cast(std::addressof(base::_value(base::x0_size)))) T(std::forward(d)); - ++base::x0_size; - } - - template - void emplace_back(_Args&&... args) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "emplace_back() called on full rstl::reserved_vector."); -#endif - ::new (static_cast(std::addressof(base::_value(base::x0_size)))) T(std::forward<_Args>(args)...); - ++base::x0_size; - } - - void pop_back() - { -#ifndef NDEBUG - if (base::x0_size == 0) - Log.report(logvisor::Fatal, "pop_back() called on empty rstl::reserved_vector."); -#endif - --base::x0_size; - base::destroy(base::_value(base::x0_size)); - } - - iterator insert(const_iterator pos, const T& value) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector."); -#endif - auto target_it = base::_const_cast_iterator(pos); - if (pos == base::cend()) - { - ::new (static_cast(std::addressof(base::_value(base::x0_size)))) T(value); - } - else - { - ::new (static_cast(std::addressof(base::_value(base::x0_size)))) - T(std::forward(base::_value(base::x0_size - 1))); - for (auto it = base::end() - 1; it != target_it; --it) - *it = std::forward(*(it - 1)); - *target_it = value; - } - ++base::x0_size; - return target_it; - } - - iterator insert(const_iterator pos, T&& value) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector."); -#endif - auto target_it = base::_const_cast_iterator(pos); - if (pos == base::cend()) - { - ::new (static_cast(std::addressof(base::_value(base::x0_size)))) T(std::forward(value)); - } - else - { - ::new (static_cast(std::addressof(base::_value(base::x0_size)))) - T(std::forward(base::_value(base::x0_size - 1))); - for (auto it = base::end() - 1; it != target_it; --it) - *it = std::forward(*(it - 1)); - *target_it = std::forward(value); - } - ++base::x0_size; - return target_it; - } - - void resize(size_t size) - { -#ifndef NDEBUG - if (size > N) - Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector."); -#endif - if (size > base::x0_size) - { - for (size_t i = base::x0_size; i < size; ++i) - ::new (static_cast(std::addressof(base::_value(i)))) T(); - base::x0_size = size; - } - else if (size < base::x0_size) - { - if (std::is_destructible::value && !std::is_trivially_destructible::value) - for (size_t i = size; i < base::x0_size; ++i) - base::destroy(base::_value(i)); - base::x0_size = size; - } - } - - void resize(size_t size, const T& value) - { -#ifndef NDEBUG - if (size > N) - Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector."); -#endif - if (size > base::x0_size) - { - for (size_t i = base::x0_size; i < size; ++i) - ::new (static_cast(std::addressof(base::_value(i)))) T(value); - base::x0_size = size; - } - else if (size < base::x0_size) - { - if (std::is_destructible::value && !std::is_trivially_destructible::value) - for (size_t i = size; i < base::x0_size; ++i) - base::destroy(base::_value(i)); - base::x0_size = size; - } - } - - iterator erase(const_iterator pos) - { -#ifndef NDEBUG - if (base::x0_size == 0) - Log.report(logvisor::Fatal, "erase() called on empty rstl::reserved_vector."); -#endif - for (auto it = base::_const_cast_iterator(pos) + 1; it != base::end(); ++it) - *(it - 1) = std::forward(*it); - --base::x0_size; - base::destroy(base::_value(base::x0_size)); - return base::_const_cast_iterator(pos); - } - - void clear() - { - if (std::is_destructible::value && !std::is_trivially_destructible::value) - for (auto it = base::begin(); it != base::end(); ++it) - base::destroy(*it); - base::x0_size = 0; - } -}; - -/** - * @brief Vector backed by statically-allocated array with default-initialized elements - */ -template -class prereserved_vector : public _reserved_vector_base -{ - void _init() - { - for (auto& i : base::x4_data) - ::new (static_cast(std::addressof(i._value))) T(); - } - void _deinit() - { - if (std::is_destructible::value && !std::is_trivially_destructible::value) - for (auto& i : base::x4_data) - base::destroy(i._value); - } -public: - using base = _reserved_vector_base; - using iterator = typename base::iterator; - using const_iterator = typename base::const_iterator; - prereserved_vector() : base(1) { _init(); } - - prereserved_vector(const prereserved_vector& other) : base(other.x0_size) - { - for (size_t i=0 ; i(std::addressof(base::_value(i)))) T(other.base::_value(i)); - } - - prereserved_vector& operator=(const prereserved_vector& other) - { - for (size_t i=0 ; i(std::addressof(base::_value(i)))) T(std::forward(other.base::_value(i))); - } - - prereserved_vector& operator=(prereserved_vector&& other) - { - for (size_t i=0 ; i(other.base::_value(i)); - base::x0_size = other.base::x0_size; - return *this; - } - - ~prereserved_vector() { _deinit(); } - - void set_size(size_t n) - { - if (n <= N) - base::x0_size = n; - } - - void set_data(const T* data) { memmove(base::x4_data, data, sizeof(T) * base::x0_size); } - - void push_back(const T& d) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "push_back() called on full rstl::prereserved_vector."); -#endif - base::_value(base::x0_size) = d; - ++base::x0_size; - } - - void push_back(T&& d) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "push_back() called on full rstl::prereserved_vector."); -#endif - base::_value(base::x0_size) = std::forward(d); - ++base::x0_size; - } - - template - void emplace_back(_Args&&... args) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "emplace_back() called on full rstl::prereserved_vector."); -#endif - base::_value(base::x0_size) = T(std::forward<_Args>(args)...); - ++base::x0_size; - } - - void pop_back() - { -#ifndef NDEBUG - if (base::x0_size == 0) - Log.report(logvisor::Fatal, "pop_back() called on empty rstl::prereserved_vector."); -#endif - --base::x0_size; - } - - iterator insert(const_iterator pos, const T& value) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector."); -#endif - auto target_it = base::_const_cast_iterator(pos); - if (pos == base::cend()) - { - *target_it = value; - } - else - { - for (auto it = base::end(); it != target_it; --it) - *it = std::forward(*(it - 1)); - *target_it = value; - } - ++base::x0_size; - return target_it; - } - - iterator insert(const_iterator pos, T&& value) - { -#ifndef NDEBUG - if (base::x0_size == N) - Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector."); -#endif - auto target_it = base::_const_cast_iterator(pos); - if (pos == base::cend()) - { - *target_it = std::forward(value); - } - else - { - for (auto it = base::end(); it != target_it; --it) - *it = std::forward(*(it - 1)); - *target_it = std::forward(value); - } - ++base::x0_size; - return target_it; - } - - void resize(size_t size) - { -#ifndef NDEBUG - if (size > N) - Log.report(logvisor::Fatal, "resized() call overflows rstl::prereserved_vector."); -#endif - base::x0_size = size; - } - - void resize(size_t size, const T& value) - { -#ifndef NDEBUG - if (size > N) - Log.report(logvisor::Fatal, "resized() call overflows rstl::prereserved_vector."); -#endif - if (size > base::x0_size) - { - for (size_t i = base::x0_size; i < size; ++i) - base::_value(i) = T(value); - base::x0_size = size; - } - else if (size < base::x0_size) - { - base::x0_size = size; - } - } - - iterator erase(const_iterator pos) - { -#ifndef NDEBUG - if (base::x0_size == 0) - Log.report(logvisor::Fatal, "erase() called on empty rstl::prereserved_vector."); -#endif - for (auto it = base::_const_cast_iterator(pos) + 1; it != base::end(); ++it) - *(it - 1) = std::forward(*it); - --base::x0_size; - return base::_const_cast_iterator(pos); - } - - void clear() { base::x0_size = 0; } + T& operator[](size_t idx) { return _value(idx); } + const T& operator[](size_t idx) const { return _value(idx); } }; template diff --git a/specter b/specter index f1d71e3e8..5c6e64c53 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit f1d71e3e86f241ebd959b0a4e07f77913b34be63 +Subproject commit 5c6e64c53f831b405e23dc2a105a16259dc5a076