diff --git a/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp b/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp index ba078cdaa..982a22564 100644 --- a/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp @@ -15,14 +15,14 @@ struct VisorGoo : IScriptObject String<-1> name; Value position; UniqueID32 particle; - Value unknown1; // always FF - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; // CColor - Value unknown7; - Value unknown8; + UniqueID32 electric; + Value minDist; + Value maxDist; + Value nearProb; + Value farProb; + DNAColor color; + Value sfx; + Value skipAngleTest; void nameIDs(PAKRouter& pakRouter) const { @@ -31,11 +31,17 @@ struct VisorGoo : IScriptObject PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); ent->name = name + "_part"; } + if (electric) + { + PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric); + ent->name = name + "_elsc"; + } } void gatherDependencies(std::vector& pathsOut) const { g_curSpec->flattenDependencies(particle, pathsOut); + g_curSpec->flattenDependencies(electric, pathsOut); } }; } diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index 8eff81e92..0d2159a4f 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -28,7 +28,8 @@ namespace urde void ViewManager::InitMP1(MP1::CMain& main) { main.Init(m_fileStoreManager, m_mainWindow.get(), m_voiceEngine.get(), *m_amuseAllocWrapper); - main.WarmupShaders(); + if (!m_noShaderWarmup) + main.WarmupShaders(); m_testGameView.reset(new TestGameView(*this, m_viewResources, *m_rootView)); @@ -218,11 +219,10 @@ void ViewManager::init(boo::IApplication* app) for (const auto& arg : app->getArgs()) { - if (hecl::SearchForProject(arg)) - { + if (m_deferedProject.empty() && hecl::SearchForProject(arg)) m_deferedProject = arg; - break; - } + if (arg == _S("--no-shader-warmup")) + m_noShaderWarmup = true; } } diff --git a/Editor/ViewManager.hpp b/Editor/ViewManager.hpp index 0a1997183..5a54898fb 100644 --- a/Editor/ViewManager.hpp +++ b/Editor/ViewManager.hpp @@ -148,6 +148,7 @@ class ViewManager : public specter::IViewManager int m_deferSplitThisSlot; boo::SWindowCoord m_deferSplitCoord; hecl::SystemString m_deferedProject; + bool m_noShaderWarmup = false; public: ViewManager(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr); diff --git a/Runtime/Audio/CSfxManager.cpp b/Runtime/Audio/CSfxManager.cpp index 3cb482149..9af9496f6 100644 --- a/Runtime/Audio/CSfxManager.cpp +++ b/Runtime/Audio/CSfxManager.cpp @@ -329,6 +329,8 @@ float CSfxManager::GetReverbAmount() void CSfxManager::PitchBend(const CSfxHandle& handle, float pitch) { + if (!handle) + return; if (!handle->IsPlaying()) CSfxManager::Update(0.f); if (handle->IsPlaying()) @@ -340,6 +342,8 @@ void CSfxManager::PitchBend(const CSfxHandle& handle, float pitch) void CSfxManager::SfxVolume(const CSfxHandle& handle, float vol) { + if (!handle) + return; if (handle->IsEmitter()) { CSfxWrapper& wrapper = static_cast(*handle); @@ -351,6 +355,8 @@ void CSfxManager::SfxVolume(const CSfxHandle& handle, float vol) void CSfxManager::SfxSpan(const CSfxHandle& handle, float span) { + if (!handle) + return; if (handle->IsPlaying()) handle->GetVoice()->setSurroundPan(span); } diff --git a/Runtime/AutoMapper/CMapArea.cpp b/Runtime/AutoMapper/CMapArea.cpp index 03729e474..ad07ee226 100644 --- a/Runtime/AutoMapper/CMapArea.cpp +++ b/Runtime/AutoMapper/CMapArea.cpp @@ -56,7 +56,7 @@ void CMapArea::PostConstruct() CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, x3c_vertexStart, 12, x2c_vertexCount); + m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); /* Only the map universe specifies Always; it draws a maximum of 133 instances */ @@ -206,6 +206,7 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i x1c_outlineOffset = buf + reinterpret_cast(x1c_outlineOffset); m_primStart = index.size(); + bool start = true; { athena::io::MemoryReader r(x18_surfOffset, INT_MAX); u32 primCount = r.readUint32Big(); @@ -219,7 +220,7 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i { for (u32 v=0 ; v& i else { index.push_back(r.readUByte()); + start = false; } index.push_back(r.readUByte()); index.push_back(r.readUByte()); @@ -237,7 +239,7 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i } case GX::Primitive::TRIANGLESTRIP: { - if (index.size()) + if (!start) { index.push_back(index.back()); index.push_back(r.readUByte()); @@ -246,6 +248,7 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i else { index.push_back(r.readUByte()); + start = false; } for (u32 v=1 ; v& i case GX::Primitive::TRIANGLEFAN: { u8 firstVert = r.readUByte(); - if (index.size()) + if (!start) { index.push_back(index.back()); index.push_back(r.readUByte()); @@ -265,6 +268,7 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i { index.push_back(r.readUByte()); index.push_back(index.back()); + start = false; } for (u32 v=1 ; vx30_26_scriptingBlocked) + if (!ent.entity || ent.entity->x30_26_scriptingBlocked) return nullptr; return ent.entity; } @@ -57,7 +57,7 @@ const CEntity* CObjectList::operator[](size_t i) const CEntity* CObjectList::operator[](size_t i) { SObjectListEntry& ent = x0_list[i]; - if (ent.entity->x30_26_scriptingBlocked) + if (!ent.entity || ent.entity->x30_26_scriptingBlocked) return nullptr; return ent.entity; } @@ -67,7 +67,7 @@ const CEntity* CObjectList::GetObjectById(TUniqueId uid) const if (uid == kInvalidUniqueId) return nullptr; const SObjectListEntry& ent = x0_list[uid.Value()]; - if (ent.entity->x30_26_scriptingBlocked) + if (!ent.entity || ent.entity->x30_26_scriptingBlocked) return nullptr; return ent.entity; } @@ -77,7 +77,7 @@ CEntity* CObjectList::GetObjectById(TUniqueId uid) if (uid == kInvalidUniqueId) return nullptr; SObjectListEntry& ent = x0_list[uid.Value()]; - if (ent.entity->x30_26_scriptingBlocked) + if (!ent.entity || ent.entity->x30_26_scriptingBlocked) return nullptr; return ent.entity; } diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 1eb8ae6fd..d62cf95ea 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -696,6 +696,7 @@ void CStateManager::DrawWorld() const SetupFogForArea(area); g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx); g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); + g_Renderer->UpdateAreaUniforms(area.x4_selfIdx); g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, targetMask); } diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index e86b4157d..1135ec413 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -20,13 +20,15 @@ namespace urde { -static rstl::reserved_vector sDataHolder; +static logvisor::Module Log("CBooRenderer"); + +static rstl::reserved_vector sDataHolder; static rstl::reserved_vector, 50> sBucketsHolder; static rstl::reserved_vector sPlaneObjectDataHolder; static rstl::reserved_vector sPlaneObjectBucketHolder; rstl::reserved_vector Buckets::sBucketIndex; -rstl::reserved_vector* Buckets::sData = nullptr; +rstl::reserved_vector* Buckets::sData = nullptr; rstl::reserved_vector, 50>* Buckets::sBuckets = nullptr; rstl::reserved_vector* Buckets::sPlaneObjectData = nullptr; rstl::reserved_vector* Buckets::sPlaneObjectBucket = nullptr; @@ -48,40 +50,73 @@ void Buckets::Clear() void Buckets::Sort() { float delta = std::max(1.f, sMinMaxDistance[1] - sMinMaxDistance[0]); - sPlaneObjectBucket->resize(8); + float pitch = 49.f / delta; + for (auto it = sPlaneObjectData->begin() ; it != sPlaneObjectData->end() ; ++it) + if (sPlaneObjectBucket->size() < 8) + sPlaneObjectBucket->push_back(s16(it - sPlaneObjectData->begin())); - std::sort(sPlaneObjectBucket->begin(), sPlaneObjectBucket->end(), - [](u16 a, u16 b) -> bool + u32 precision = 50; + if (sPlaneObjectBucket->size()) { - return (*sPlaneObjectData)[a].GetDistance() >= (*sPlaneObjectData)[b].GetDistance(); - }); + std::sort(sPlaneObjectBucket->begin(), sPlaneObjectBucket->end(), + [](u16 a, u16 b) -> bool + { + return (*sPlaneObjectData)[a].GetDistance() >= (*sPlaneObjectData)[b].GetDistance(); + }); + precision = 50 / u32(sPlaneObjectBucket->size() + 1); + pitch = 1.f / (delta / float(precision - 2)); - u32 precision = 50 / (8 + 1); - float pitch = 1.f / (delta / float(precision - 2)); - - int accum = 0; - for (u16 idx : *sPlaneObjectBucket) - { - ++accum; - CDrawablePlaneObject& planeObj = (*sPlaneObjectData)[idx]; - planeObj.x24_targetBucket = precision * accum; + int accum = 0; + for (u16 idx : *sPlaneObjectBucket) + { + ++accum; + CDrawablePlaneObject& planeObj = (*sPlaneObjectData)[idx]; + planeObj.x24_targetBucket = u16(precision * accum); + } } for (CDrawable& drawable : *sData) { int slot; + float relDist = drawable.GetDistance() - sMinMaxDistance[0]; if (sPlaneObjectBucket->empty()) { - slot = zeus::clamp(1, int((drawable.GetDistance() - sMinMaxDistance[0]) * pitch), 49); + slot = zeus::clamp(1, int(relDist * pitch), 49); } else { - /* TODO: Planar sort distribution */ + slot = zeus::clamp(0, int(relDist * pitch), int(precision) - 2); + for (u16 idx : *sPlaneObjectBucket) + { + CDrawablePlaneObject& planeObj = (*sPlaneObjectData)[idx]; + bool partial, full; + if (planeObj.x3c_25_zOnly) + { + partial = drawable.GetBounds().max.z > planeObj.GetPlane().d; + full = drawable.GetBounds().min.z > planeObj.GetPlane().d; + } + else + { + partial = planeObj.GetPlane().pointToPlaneDist( + drawable.GetBounds().closestPointAlongVector(planeObj.GetPlane().vec)) > 0.f; + full = planeObj.GetPlane().pointToPlaneDist( + drawable.GetBounds().furthestPointAlongVector(planeObj.GetPlane().vec)) > 0.f; + } + bool cont; + if (drawable.GetType() == EDrawableType::Particle) + cont = planeObj.x3c_24_invertTest ? !partial : full; + else + cont = planeObj.x3c_24_invertTest ? (!partial || !full) : (partial || full); + if (!cont) + break; + } } if (slot == -1) slot = 49; - (*sBuckets)[slot].push_back(&drawable); + rstl::reserved_vector& bucket = (*sBuckets)[slot]; + if (bucket.size() < bucket.capacity()) + bucket.push_back(&drawable); } int bucketIdx = sBuckets->size(); @@ -108,21 +143,28 @@ void Buckets::Sort() } } -void Buckets::InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool b1, - const zeus::CPlane& plane, bool b2, EDrawableType dtype, const void* data) +void Buckets::InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool invertTest, + const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data) { - sPlaneObjectData->push_back(CDrawablePlaneObject(dtype, dist, something, aabb, b1, plane, b2, data)); + sPlaneObjectData->push_back(CDrawablePlaneObject(dtype, dist, something, aabb, invertTest, plane, zOnly, data)); } void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, const void* data, const zeus::CPlane& plane, u16 extraSort) { - float dist = plane.pointToPlaneDist(pos); - sData->push_back(CDrawable(dtype, extraSort, dist, aabb, data)); - if (sMinMaxDistance[0] > dist) - sMinMaxDistance[0] = dist; - if (sMinMaxDistance[1] < dist) - sMinMaxDistance[1] = dist; + if (sData->size() != sData->capacity()) + { + float dist = plane.pointToPlaneDist(pos); + sData->push_back(CDrawable(dtype, extraSort, dist, aabb, data)); + if (sMinMaxDistance[0] > dist) + sMinMaxDistance[0] = dist; + if (sMinMaxDistance[1] < dist) + sMinMaxDistance[1] = dist; + } + else + { + Log.report(logvisor::Fatal, "Rendering buckets filled to capacity"); + } } void Buckets::Shutdown() @@ -236,12 +278,12 @@ void CBooRenderer::RenderBucketItems(CAreaListItem* item) } case EDrawableType::WorldSurface: { - SetupRendererStates(); + //SetupRendererStates(); CBooSurface* surf = static_cast((void*)drawable->GetData()); CBooModel* model = surf->m_parent; if (model) { - ActivateLightsForModel(item, *model); + //ActivateLightsForModel(item, *model); model->DrawSurface(*surf, flags); } break; @@ -262,7 +304,7 @@ void CBooRenderer::RenderBucketItems(CAreaListItem* item) void CBooRenderer::HandleUnsortedModel(CAreaListItem* item, CBooModel& model) { - ActivateLightsForModel(item, model); + //ActivateLightsForModel(item, model); CBooSurface* surf = model.x38_firstUnsortedSurface; CModelFlags flags; flags.m_extendedShader = EExtendedShader::Lighting; @@ -677,6 +719,7 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) GenerateFogVolumeRampTex(ctx); GenerateSphereRampTex(ctx); m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, boo::TextureClampMode::Repeat, 1, 0); + x14c_reflectionTex = ctx.newRenderTexture(256, 256, boo::TextureClampMode::Repeat, 1, 0); GenerateScanLinesVBO(ctx); return true; }); @@ -745,6 +788,29 @@ void CBooRenderer::DisablePVS() xc8_pvs = std::experimental::nullopt; } +void CBooRenderer::UpdateAreaUniforms(int areaIdx) +{ + SetupRendererStates(); + + for (CAreaListItem& item : x1c_areaListItems) + { + if (areaIdx != -1 && item.x18_areaIdx != areaIdx) + continue; + + for (auto it = item.x10_models.begin(); it != item.x10_models.end(); ++it) + { + CBooModel* model = *it; + if (model->TryLockTextures()) + { + ActivateLightsForModel(&item, *model); + CModelFlags flags; + flags.m_extendedShader = EExtendedShader::Lighting; + model->UpdateUniformData(flags, nullptr, nullptr); + } + } + } +} + void CBooRenderer::RemoveStaticGeometry(const std::vector* geometry) { auto search = FindStaticGeometry(geometry); @@ -755,7 +821,7 @@ void CBooRenderer::RemoveStaticGeometry(const std::vector void CBooRenderer::DrawAreaGeometry(int areaIdx, int mask, int targetMask) { x318_30_inAreaDraw = true; - SetupRendererStates(); + //SetupRendererStates(); CModelFlags flags; for (CAreaListItem& item : x1c_areaListItems) @@ -793,7 +859,7 @@ void CBooRenderer::DrawAreaGeometry(int areaIdx, int mask, int targetMask) void CBooRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask) { - SetupRendererStates(); + //SetupRendererStates(); CAreaListItem* lastOctreeItem = nullptr; @@ -871,7 +937,7 @@ void CBooRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask) void CBooRenderer::DrawSortedGeometry(int areaIdx, int mask, int targetMask) { - SetupRendererStates(); + //SetupRendererStates(); CAreaListItem* lastOctreeItem = nullptr; @@ -1327,6 +1393,7 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector(*this).UpdateAreaUniforms(-1); CModelFlags flags; flags.m_extendedShader = EExtendedShader::SolidColor; // Do solid color draw diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 7ac5e9981..2dbeb14df 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -32,7 +32,7 @@ class Buckets friend class CBooRenderer; static rstl::reserved_vector sBucketIndex; - static rstl::reserved_vector* sData; + static rstl::reserved_vector* sData; static rstl::reserved_vector, 50>* sBuckets; static rstl::reserved_vector* sPlaneObjectData; static rstl::reserved_vector* sPlaneObjectBucket; @@ -42,8 +42,8 @@ class Buckets public: static void Clear(); static void Sort(); - static void InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool b1, - const zeus::CPlane& plane, bool b2, EDrawableType dtype, const void* data); + static void InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool invertTest, + const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data); static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, const void* data, const zeus::CPlane& plane, u16 extraSort); static void Shutdown(); @@ -208,6 +208,7 @@ public: void AddStaticGeometry(const std::vector*, const CAreaRenderOctTree*, int areaIdx); void EnablePVS(const CPVSVisSet&, u32); void DisablePVS(); + void UpdateAreaUniforms(int areaIdx); void RemoveStaticGeometry(const std::vector*); void DrawAreaGeometry(int areaIdx, int mask, int targetMask); void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask); diff --git a/Runtime/Graphics/CDrawablePlaneObject.hpp b/Runtime/Graphics/CDrawablePlaneObject.hpp index 8bb583e51..33d79fa64 100644 --- a/Runtime/Graphics/CDrawablePlaneObject.hpp +++ b/Runtime/Graphics/CDrawablePlaneObject.hpp @@ -12,13 +12,14 @@ class CDrawablePlaneObject : public CDrawable u16 x24_targetBucket; float x28_something; zeus::CPlane x2c_plane; - bool x3c_24 : 1; - bool x3c_25 : 1; + bool x3c_24_invertTest : 1; + bool x3c_25_zOnly : 1; public: CDrawablePlaneObject(EDrawableType dtype, float dist, float something, const zeus::CAABox& aabb, - bool b1, const zeus::CPlane& plane, bool b2, const void* data) + bool invertTest, const zeus::CPlane& plane, bool zOnly, const void* data) : CDrawable(dtype, 0, dist, aabb, data), x24_targetBucket(0), x28_something(something), - x2c_plane(plane) {x3c_24 = b1; x3c_25 = b2;} + x2c_plane(plane) {x3c_24_invertTest = invertTest; x3c_25_zOnly = zOnly;} + const zeus::CPlane& GetPlane() const { return x2c_plane; } }; } diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 07ca75fb8..373a4f119 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -606,7 +606,9 @@ void CBooModel::DrawSurfaces(const CModelFlags& flags) const void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const { - if (m_uniUpdateCount > m_instances.size()) + //if (m_uniUpdateCount == 0) + // Log.report(logvisor::Fatal, "UpdateUniformData() not called"); + if (m_uniUpdateCount == 0 || m_uniUpdateCount > m_instances.size()) return; const ModelInstance& inst = m_instances[m_uniUpdateCount-1]; @@ -727,7 +729,8 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati } case UVAnimation::Mode::CylinderEnvironment: { - texMtxOut = (CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix).toMatrix4f(); + //texMtxOut = (CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix).toMatrix4f(); + texMtxOut = CGraphics::g_GXModelView.toMatrix4f(); texMtxOut.vec[3].zeroOut(); const zeus::CVector3f& viewOrigin = CGraphics::g_ViewMatrix.origin; diff --git a/Runtime/Graphics/Shaders/CMapSurfaceShaderGLSL.cpp b/Runtime/Graphics/Shaders/CMapSurfaceShaderGLSL.cpp index 004779133..c780a90d6 100644 --- a/Runtime/Graphics/Shaders/CMapSurfaceShaderGLSL.cpp +++ b/Runtime/Graphics/Shaders/CMapSurfaceShaderGLSL.cpp @@ -1,5 +1,4 @@ #include "CMapSurfaceShader.hpp" -#include "TShader.hpp" namespace urde { diff --git a/Runtime/Graphics/Shaders/CMapSurfaceShaderHLSL.cpp b/Runtime/Graphics/Shaders/CMapSurfaceShaderHLSL.cpp index 3da9daf62..f6cc5496e 100644 --- a/Runtime/Graphics/Shaders/CMapSurfaceShaderHLSL.cpp +++ b/Runtime/Graphics/Shaders/CMapSurfaceShaderHLSL.cpp @@ -1,5 +1,4 @@ #include "CMapSurfaceShader.hpp" -#include "TShader.hpp" namespace urde { diff --git a/Runtime/Graphics/Shaders/CMapSurfaceShaderMetal.cpp b/Runtime/Graphics/Shaders/CMapSurfaceShaderMetal.cpp index f6957f06f..62fbed474 100644 --- a/Runtime/Graphics/Shaders/CMapSurfaceShaderMetal.cpp +++ b/Runtime/Graphics/Shaders/CMapSurfaceShaderMetal.cpp @@ -1,5 +1,4 @@ #include "CMapSurfaceShader.hpp" -#include "TShader.hpp" namespace urde { diff --git a/Runtime/Graphics/Shaders/CRadarPaintShader.cpp b/Runtime/Graphics/Shaders/CRadarPaintShader.cpp index f328e054e..fb12b41e3 100644 --- a/Runtime/Graphics/Shaders/CRadarPaintShader.cpp +++ b/Runtime/Graphics/Shaders/CRadarPaintShader.cpp @@ -16,7 +16,7 @@ void CRadarPaintShader::draw(const std::vector& instances, const CText { m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Instance), m_maxInsts); m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CMatrix4f), 1); - TShader::BuildShaderDataBinding(ctx, *this); + m_dataBind = TShader::BuildShaderDataBinding(ctx, *this); return true; }); } diff --git a/Runtime/GuiSys/CGuiFrame.hpp b/Runtime/GuiSys/CGuiFrame.hpp index 5a715ac2d..02b763b98 100644 --- a/Runtime/GuiSys/CGuiFrame.hpp +++ b/Runtime/GuiSys/CGuiFrame.hpp @@ -46,6 +46,7 @@ public: ~CGuiFrame(); CGuiSys& GetGuiSys() {return x8_guiSys;} + CAssetId GetAssetId() const {return x0_id;} CGuiLight* GetFrameLight(int idx) const { return m_indexedLights[idx]; } CGuiCamera* GetFrameCamera() const { return x14_camera.get(); } diff --git a/Runtime/MP1/CInGameGuiManager.cpp b/Runtime/MP1/CInGameGuiManager.cpp index 52c774ca2..8b746b050 100644 --- a/Runtime/MP1/CInGameGuiManager.cpp +++ b/Runtime/MP1/CInGameGuiManager.cpp @@ -649,7 +649,8 @@ void CInGameGuiManager::Draw(CStateManager& stateMgr) x148_model_automapper->SetIsVisible(true); x148_model_automapper->Draw(CGuiWidgetDrawParms(1.f, zeus::CVector3f::skZero)); // ZTest no write - x38_autoMapper->Draw(stateMgr, zeus::CTransform::Translate(0.f, 0.02f, 0.f) * x18c_camXf, mapAlpha * x1f4_visorStaticAlpha * t); + x38_autoMapper->Draw(stateMgr, zeus::CTransform::Translate(0.f, 0.02f, 0.f) * x18c_camXf, + mapAlpha * x1f4_visorStaticAlpha * t); // Zest and write x148_model_automapper->SetIsVisible(false); } diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 7ffed8b50..e3d053083 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -102,8 +102,8 @@ CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, CStreamAudioManager::SetMusicVolume(0x7f); m->ResetGameState(); - std::shared_ptr splash = std::make_shared(CSplashScreen::ESplashScreen::Nintendo); - x58_ioWinManager.AddIOWin(splash, 1000, 10000); + //std::shared_ptr splash = std::make_shared(CSplashScreen::ESplashScreen::Nintendo); + //x58_ioWinManager.AddIOWin(splash, 1000, 10000); std::shared_ptr mf = std::make_shared(); x58_ioWinManager.AddIOWin(mf, 0, 0); diff --git a/Runtime/MkCastTo.py b/Runtime/MkCastTo.py index b163552ed..655a19e8e 100644 --- a/Runtime/MkCastTo.py +++ b/Runtime/MkCastTo.py @@ -67,6 +67,7 @@ CENTITY_TYPES = ( ('CScriptTimer', 'World/CScriptTimer.hpp'), ('CScriptTrigger', 'World/CScriptTrigger.hpp'), ('CScriptVisorFlare', 'World/CScriptVisorFlare.hpp'), + ('CScriptVisorGoo', 'World/CScriptVisorGoo.hpp'), ('CScriptWater', 'World/CScriptWater.hpp'), ('CScriptWaypoint', 'World/CScriptWaypoint.hpp'), ('CSnakeWeedSwarm', 'World/CSnakeWeedSwarm.hpp'), diff --git a/Runtime/Weapon/CWeaponMode.hpp b/Runtime/Weapon/CWeaponMode.hpp index 6f3b725f8..7ef9f8538 100644 --- a/Runtime/Weapon/CWeaponMode.hpp +++ b/Runtime/Weapon/CWeaponMode.hpp @@ -13,7 +13,7 @@ class CWeaponMode bool x4_26_instantKill : 1; public: - CWeaponMode() = default; + CWeaponMode() { x4_24_charged = false; x4_25_comboed = false; x4_26_instantKill = false; } CWeaponMode(EWeaponType, bool charged = false, bool comboed = false, bool instaKill = false); EWeaponType GetType() const; diff --git a/Runtime/World/CDamageInfo.hpp b/Runtime/World/CDamageInfo.hpp index 412ea7af8..4bb78fec7 100644 --- a/Runtime/World/CDamageInfo.hpp +++ b/Runtime/World/CDamageInfo.hpp @@ -16,10 +16,10 @@ class CDamageVulnerability; class CDamageInfo { CWeaponMode x0_weaponMode; - float x8_damage; - float xc_radiusDamage; - float x10_radius; - float x14_knockback; + float x8_damage = 0.f; + float xc_radiusDamage = 0.f; + float x10_radius = 0.f; + float x14_knockback = 0.f; bool x18_noImmunity = false; public: diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index a573d722d..d6d19c1c8 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -1010,7 +1010,7 @@ void CGameArea::Validate(CStateManager& mgr) PostConstructArea(); if (x4_selfIdx != kInvalidAreaId) - mgr.WorldNC()->MoveAreaToChain3(x4_selfIdx); + mgr.WorldNC()->MoveAreaToAliveChain(x4_selfIdx); LoadScriptObjects(mgr); diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 8594f4be5..d829b73c9 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -127,7 +127,7 @@ class CGameArea : public IGameArea bool xf0_27_paused : 1; bool xf0_28_validated : 1; }; - u8 _dummy = 0; + u32 _dummy = 0; }; enum class EPhase diff --git a/Runtime/World/CMakeLists.txt b/Runtime/World/CMakeLists.txt index 87be6f832..56202b65a 100644 --- a/Runtime/World/CMakeLists.txt +++ b/Runtime/World/CMakeLists.txt @@ -96,6 +96,7 @@ set(WORLD_SOURCES CScriptRoomAcoustics.hpp CScriptRoomAcoustics.cpp CScriptControllerAction.hpp CScriptControllerAction.cpp CVisorFlare.hpp CVisorFlare.cpp + CScriptVisorGoo.hpp CScriptVisorGoo.cpp CGrappleParameters.hpp CActorParameters.hpp CLightParameters.hpp diff --git a/Runtime/World/CPhysicsActor.cpp b/Runtime/World/CPhysicsActor.cpp index e35a8c14d..3d88f6685 100644 --- a/Runtime/World/CPhysicsActor.cpp +++ b/Runtime/World/CPhysicsActor.cpp @@ -99,7 +99,7 @@ void CPhysicsActor::AddMotionState(const CMotionState& mst) { zeus::CNUQuaternion q{x34_transform.buildMatrix3f()}; q += mst.xc_orientation; - SetTransform(zeus::CTransform(q, x34_transform.origin)); + SetTransform(zeus::CTransform(zeus::CQuaternion::fromNUQuaternion(q), x34_transform.origin)); SetTranslation(x34_transform.origin + mst.x0_translation); @@ -115,7 +115,7 @@ CMotionState CPhysicsActor::GetMotionState() const void CPhysicsActor::SetMotionState(const CMotionState& mst) { - SetTransform(zeus::CTransform(mst.xc_orientation, x34_transform.origin)); + SetTransform(zeus::CTransform(zeus::CQuaternion::fromNUQuaternion(mst.xc_orientation), x34_transform.origin)); SetTranslation(mst.x0_translation); xfc_constantForce = mst.x1c_velocity; @@ -302,16 +302,17 @@ CMotionState CPhysicsActor::PredictMotion(float dt) const CMotionState CPhysicsActor::PredictLinearMotion(float dt) const { zeus::CVector3f velocity = CalculateNewVelocityWR_UsingImpulses(); - return {velocity * dt, zeus::CNUQuaternion::skNoRotation, ((x15c_force + x150_momentum) * dt) + x168_impulse, + return {velocity * dt, {0.f, zeus::CVector3f::skZero}, ((x15c_force + x150_momentum) * dt) + x168_impulse, zeus::CAxisAngle::skZero}; } CMotionState CPhysicsActor::PredictAngularMotion(float dt) const { const zeus::CVector3f v1 = xf4_inertiaTensorRecip * (x180_angularImpulse + x198_moveAngularImpulse); - zeus::CNUQuaternion q = 0.5f * zeus::CNUQuaternion({0.f, x144_angularVelocity + v1}); - return {zeus::CVector3f::skZero, q * zeus::CNUQuaternion(x34_transform.buildMatrix3f()) * dt, + zeus::CNUQuaternion q = 0.5f * zeus::CNUQuaternion(0.f, x144_angularVelocity + v1); + CMotionState ret = {zeus::CVector3f::skZero, q * zeus::CNUQuaternion(x34_transform.buildMatrix3f()) * dt, zeus::CVector3f::skZero, (x174_torque * dt) + x180_angularImpulse}; + return ret; } void CPhysicsActor::ApplyForceOR(const zeus::CVector3f& force, const zeus::CAxisAngle& torque) diff --git a/Runtime/World/CScriptAreaAttributes.cpp b/Runtime/World/CScriptAreaAttributes.cpp index 29ac10cf9..f9e5e9528 100644 --- a/Runtime/World/CScriptAreaAttributes.cpp +++ b/Runtime/World/CScriptAreaAttributes.cpp @@ -39,7 +39,7 @@ void CScriptAreaAttributes::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId area->SetAreaAttributes(this); stateMgr.GetEnvFxManager()->SetFxDensity(500, x3c_envFxDensity); } - else if (msg >= EScriptObjectMessage::Deleted) + else if (msg == EScriptObjectMessage::Deleted) { CGameArea* area = stateMgr.WorldNC()->GetArea(x4_areaId); diff --git a/Runtime/World/CScriptDock.hpp b/Runtime/World/CScriptDock.hpp index ec19108e4..63b446ec7 100644 --- a/Runtime/World/CScriptDock.hpp +++ b/Runtime/World/CScriptDock.hpp @@ -33,7 +33,8 @@ class CScriptDock : public CPhysicsActor public: CScriptDock(TUniqueId uid, const std::string& name, const CEntityInfo& info, const zeus::CVector3f position, - const zeus::CVector3f& extent, s32, TAreaId, bool active, s32 w1, bool b1); + const zeus::CVector3f& extent, s32 dock, TAreaId area, bool active, + s32 dockReferenceCount, bool loadConnected); void Accept(IVisitor& visitor); void Think(float, CStateManager&); diff --git a/Runtime/World/CScriptSpindleCamera.cpp b/Runtime/World/CScriptSpindleCamera.cpp index 03e0150e3..3058d9c51 100644 --- a/Runtime/World/CScriptSpindleCamera.cpp +++ b/Runtime/World/CScriptSpindleCamera.cpp @@ -6,21 +6,21 @@ namespace urde { -SSpindleSegment::SSpindleSegment(CInputStream& in) +SSpindleProperty::SSpindleProperty(CInputStream& in) : x0_(in.readUint32Big()), x4_paramFlags(ScriptLoader::LoadParameterFlags(in)), x8_(in.readFloatBig()), xc_(in.readFloatBig()), x10_(in.readFloatBig()), x14_(in.readFloatBig()) {} CScriptSpindleCamera::CScriptSpindleCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf, bool active, u32 r9, - float f1, float f2, float f3, float f4, const SSpindleSegment& seg1, - const SSpindleSegment& seg2, const SSpindleSegment& seg3, - const SSpindleSegment& seg4, const SSpindleSegment& seg5, - const SSpindleSegment& seg6, const SSpindleSegment& seg7, - const SSpindleSegment& seg8, const SSpindleSegment& seg9, - const SSpindleSegment& seg10, const SSpindleSegment& seg11, - const SSpindleSegment& seg12, const SSpindleSegment& seg13, - const SSpindleSegment& seg14, const SSpindleSegment& seg15) + float f1, float f2, float f3, float f4, const SSpindleProperty& seg1, + const SSpindleProperty& seg2, const SSpindleProperty& seg3, + const SSpindleProperty& seg4, const SSpindleProperty& seg5, + const SSpindleProperty& seg6, const SSpindleProperty& seg7, + const SSpindleProperty& seg8, const SSpindleProperty& seg9, + const SSpindleProperty& seg10, const SSpindleProperty& seg11, + const SSpindleProperty& seg12, const SSpindleProperty& seg13, + const SSpindleProperty& seg14, const SSpindleProperty& seg15) : CGameCamera(uid, active, name, info, xf, CCameraManager::ThirdPersonFOV(), CCameraManager::NearPlane(), CCameraManager::FarPlane(), CCameraManager::Aspect(), kInvalidUniqueId, false, 0), x188_r9(r9), x1b0_f1(f1), x1b4_f2(f2), x1b8_f3(f2), x1bc_f4(f4), x1c0_seg1(seg1), x1d8_seg2(seg2), diff --git a/Runtime/World/CScriptSpindleCamera.hpp b/Runtime/World/CScriptSpindleCamera.hpp index 5c76c33ed..fc1e8d5e5 100644 --- a/Runtime/World/CScriptSpindleCamera.hpp +++ b/Runtime/World/CScriptSpindleCamera.hpp @@ -6,7 +6,7 @@ namespace urde { -struct SSpindleSegment +struct SSpindleProperty { u32 x0_; u32 x4_paramFlags; @@ -15,7 +15,7 @@ struct SSpindleSegment float x10_; float x14_; - SSpindleSegment(CInputStream& in); + SSpindleProperty(CInputStream& in); void FixupAngles() { x8_ = zeus::degToRad(x8_); @@ -31,35 +31,35 @@ class CScriptSpindleCamera : public CGameCamera float x1b4_f2; float x1b8_f3; float x1bc_f4; - SSpindleSegment x1c0_seg1; - SSpindleSegment x1d8_seg2; - SSpindleSegment x1f0_seg3; - SSpindleSegment x208_seg4; - SSpindleSegment x220_seg5; - SSpindleSegment x238_seg6; - SSpindleSegment x250_seg7; - SSpindleSegment x268_seg8; - SSpindleSegment x280_seg9; - SSpindleSegment x298_seg10; - SSpindleSegment x2b0_seg11; - SSpindleSegment x2c8_seg12; - SSpindleSegment x2e0_seg13; - SSpindleSegment x2f8_seg14; - SSpindleSegment x310_seg15; + SSpindleProperty x1c0_seg1; + SSpindleProperty x1d8_seg2; + SSpindleProperty x1f0_seg3; + SSpindleProperty x208_seg4; + SSpindleProperty x220_seg5; + SSpindleProperty x238_seg6; + SSpindleProperty x250_seg7; + SSpindleProperty x268_seg8; + SSpindleProperty x280_seg9; + SSpindleProperty x298_seg10; + SSpindleProperty x2b0_seg11; + SSpindleProperty x2c8_seg12; + SSpindleProperty x2e0_seg13; + SSpindleProperty x2f8_seg14; + SSpindleProperty x310_seg15; float x328_ = 0.f; bool x32c_24 = false; zeus::CVector3f x330_lookDir; public: CScriptSpindleCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf, bool active, u32 r9, - float f1, float f2, float f3, float f4, const SSpindleSegment& seg1, - const SSpindleSegment& seg2, const SSpindleSegment& seg3, - const SSpindleSegment& seg4, const SSpindleSegment& seg5, - const SSpindleSegment& seg6, const SSpindleSegment& seg7, - const SSpindleSegment& seg8, const SSpindleSegment& seg9, - const SSpindleSegment& seg10, const SSpindleSegment& seg11, - const SSpindleSegment& seg12, const SSpindleSegment& seg13, - const SSpindleSegment& seg14, const SSpindleSegment& seg15); + float f1, float f2, float f3, float f4, const SSpindleProperty& seg1, + const SSpindleProperty& seg2, const SSpindleProperty& seg3, + const SSpindleProperty& seg4, const SSpindleProperty& seg5, + const SSpindleProperty& seg6, const SSpindleProperty& seg7, + const SSpindleProperty& seg8, const SSpindleProperty& seg9, + const SSpindleProperty& seg10, const SSpindleProperty& seg11, + const SSpindleProperty& seg12, const SSpindleProperty& seg13, + const SSpindleProperty& seg14, const SSpindleProperty& seg15); void Accept(IVisitor& visitor); void ProcessInput(const CFinalInput& input, CStateManager& mgr); diff --git a/Runtime/World/CScriptVisorGoo.cpp b/Runtime/World/CScriptVisorGoo.cpp new file mode 100644 index 000000000..2c940955d --- /dev/null +++ b/Runtime/World/CScriptVisorGoo.cpp @@ -0,0 +1,142 @@ +#include "CScriptVisorGoo.hpp" +#include "CActorParameters.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "TCastTo.hpp" +#include "CStateManager.hpp" +#include "CPlayer.hpp" +#include "CHUDBillboardEffect.hpp" + +namespace urde +{ + +CScriptVisorGoo::CScriptVisorGoo(TUniqueId uid, const std::string& name, const CEntityInfo& info, + const zeus::CTransform& xf, CAssetId particle, CAssetId electric, + float minDist, float maxDist, float nearProb, float farProb, + const zeus::CColor& color, int sfx, bool forceShow, bool active) +: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), {}, CActorParameters::None(), kInvalidUniqueId), + xe8_particleDesc(CToken(TObjOwnerDerivedFromIObj::GetNewDerivedObject({}))), + xf0_electricDesc(CToken(TObjOwnerDerivedFromIObj::GetNewDerivedObject({}))), + xf8_sfx(CSfxManager::TranslateSFXID(sfx)), xfc_particleId(particle), x100_electricId(electric), + x104_minDist(minDist), x108_maxDist(std::max(maxDist, minDist + 0.01f)), x10c_nearProb(nearProb), + x110_farProb(farProb), x114_color(color) +{ + x118_24_angleTest = !forceShow; + if (particle.IsValid()) + xe8_particleDesc = g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), particle}); + if (electric.IsValid()) + xf0_electricDesc = g_SimplePool->GetObj(SObjectTag{FOURCC('ELSC'), electric}); +} + +void CScriptVisorGoo::Accept(IVisitor& visitor) +{ + visitor.Visit(this); +} + +void CScriptVisorGoo::Think(float, CStateManager& mgr) +{ + if (GetActive()) + { + bool loaded = false; + if (xfc_particleId.IsValid()) + { + if (xe8_particleDesc.IsLoaded()) + { + if (x100_electricId.IsValid()) + loaded = xf0_electricDesc.IsLoaded(); + else + loaded = true; + } + } + else + { + loaded = xf0_electricDesc.IsLoaded(); + } + + if (loaded) + { + bool showGoo = false; + if (mgr.GetPlayer().GetCameraState() == CPlayer::EPlayerCameraState::FirstPerson) + { + zeus::CVector3f eyeToGoo = GetTranslation() - mgr.GetPlayer().GetEyePosition(); + float eyeToGooDist = eyeToGoo.magnitude(); + if (eyeToGooDist >= x104_minDist && eyeToGooDist <= x108_maxDist) + { + if (x118_24_angleTest) + { + float angle = zeus::radToDeg( + std::acos(mgr.GetCameraManager()->GetCurrentCameraTransform(mgr).basis[1]. + normalized().dot(eyeToGoo.normalized()))); + float angleThresh = 45.f; + if (eyeToGooDist < 4.f) + { + angleThresh *= 4.f / eyeToGooDist; + angleThresh = std::min(90.f, angleThresh); + } + if (angle <= angleThresh) + showGoo = true; + } + else + { + showGoo = true; + } + if (showGoo) + { + float t = (x108_maxDist - eyeToGooDist) / (x108_maxDist - x104_minDist); + if (mgr.GetActiveRandom()->Float() * 100.f <= (1.f - t) * x110_farProb + t * x10c_nearProb) + { + mgr.AddObject(new CHUDBillboardEffect( + xfc_particleId.IsValid() ? xe8_particleDesc : + std::experimental::optional>(), + x100_electricId.IsValid() ? xf0_electricDesc : + std::experimental::optional>(), + mgr.AllocateUniqueId(), true, "VisorGoo", + CHUDBillboardEffect::GetNearClipDistance(mgr), + CHUDBillboardEffect::GetScaleForPOV(mgr), + x114_color, zeus::CVector3f::skOne, zeus::CVector3f::skZero)); + CSfxManager::SfxStart(xf8_sfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + } + } + } + } + mgr.FreeScriptObject(GetUniqueId()); + } + } +} + +void CScriptVisorGoo::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& mgr) +{ + switch (msg) + { + case EScriptObjectMessage::Activate: + if (xfc_particleId.IsValid()) + xe8_particleDesc.Lock(); + if (x100_electricId.IsValid()) + xf0_electricDesc.Lock(); + default: + break; + } + CActor::AcceptScriptMsg(msg, objId, mgr); +} + +void CScriptVisorGoo::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const +{ + // Empty +} + +void CScriptVisorGoo::Render(const CStateManager& mgr) const +{ + // Empty +} + +rstl::optional_object CScriptVisorGoo::GetTouchBounds() const +{ + return {}; +} + +void CScriptVisorGoo::Touch(CActor& other, CStateManager& mgr) +{ + // Empty +} + +} diff --git a/Runtime/World/CScriptVisorGoo.hpp b/Runtime/World/CScriptVisorGoo.hpp new file mode 100644 index 000000000..0c2b6f1ad --- /dev/null +++ b/Runtime/World/CScriptVisorGoo.hpp @@ -0,0 +1,38 @@ +#ifndef URDE_CSCRIPTVISORGOO_HPP +#define URDE_CSCRIPTVISORGOO_HPP + +#include "CActor.hpp" + +namespace urde +{ + +class CScriptVisorGoo : public CActor +{ + TToken xe8_particleDesc; + TToken xf0_electricDesc; + u16 xf8_sfx; + CAssetId xfc_particleId; + CAssetId x100_electricId; + float x104_minDist; + float x108_maxDist; + float x10c_nearProb; + float x110_farProb; + zeus::CColor x114_color; + bool x118_24_angleTest : 1; +public: + CScriptVisorGoo(TUniqueId uid, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf, + CAssetId particle, CAssetId electric, float minDist, float maxDist, float nearProb, float farProb, + const zeus::CColor& color, int sfx, bool forceShow, bool active); + + void Accept(IVisitor& visitor); + void Think(float, CStateManager& stateMgr); + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); + void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const; + void Render(const CStateManager&) const; + rstl::optional_object GetTouchBounds() const; + void Touch(CActor&, CStateManager&); +}; + +} + +#endif // URDE_CSCRIPTVISORGOO_HPP diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index 9c19ecbd4..b5ec50e0d 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -230,14 +230,14 @@ void CWorld::MoveToChain(CGameArea* area, EChain chain) return; if (area->x138_curChain != EChain::Invalid) - if (x4c_chainHeads[int(chain)] == area) - x4c_chainHeads[int(chain)] = area->x130_next; + if (x4c_chainHeads[int(area->x138_curChain)] == area) + x4c_chainHeads[int(area->x138_curChain)] = area->x130_next; area->SetChain(x4c_chainHeads[int(chain)], chain); x4c_chainHeads[int(chain)] = area; } -void CWorld::MoveAreaToChain3(TAreaId aid) +void CWorld::MoveAreaToAliveChain(TAreaId aid) { MoveToChain(x18_areas[aid].get(), EChain::Alive); } @@ -282,7 +282,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId) { CAssetId skyboxId = r.readUint32Big(); if (skyboxId != -1 && mgr) - x94_skybox = g_SimplePool->GetObj(SObjectTag{FOURCC('CMDL'), skyboxId}); + x94_skyboxWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('CMDL'), skyboxId}); } if (version >= 17) x2c_relays = CWorld::CRelay::ReadMemoryRelays(r); @@ -359,13 +359,13 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId) } case Phase::LoadingSkyBox: { - x70_26_skyboxOverridden = true; - x70_27_needsSky = false; + x70_26_skyboxActive = true; + x70_27_skyboxVisible = false; - if (!x94_skybox.IsLoaded()) + if (!x94_skyboxWorld.IsLoaded()) return false; - CModel* skybox = x94_skybox.GetObj(); + CModel* skybox = x94_skyboxWorld.GetObj(); if (!skybox) return false; @@ -373,7 +373,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId) if (!skybox->IsLoaded(0)) return false; - xa4_skyboxB = x94_skybox; + xa4_skyboxWorldLoaded = x94_skyboxWorld; for (CSoundGroupData& group : x74_soundGroupData) group.x1c_groupData.Lock(); @@ -565,15 +565,15 @@ void CWorld::PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGame void CWorld::Update(float dt) { xc4_neededFx = EEnvFxType::None; - CAssetId skyModel; + CAssetId overrideSkyId; bool needsSky = false; - CGameArea::EOcclusionState occlusionState = CGameArea::EOcclusionState::Occluded; + bool skyVisible = false; - u32 r26 = 0; + u32 areaCount = 0; for (CGameArea* head = x4c_chainHeads[3] ; head != skGlobalNonConstEnd ; - head = head->x130_next, ++r26) + head = head->x130_next, ++areaCount) { head->AliveUpdate(dt); @@ -582,12 +582,14 @@ void CWorld::Update(float dt) const CScriptAreaAttributes* attrs = head->GetPostConstructed()->x10d8_areaAttributes; if (attrs && attrs->GetSkyModel().IsValid()) - skyModel = attrs->GetSkyModel(); + overrideSkyId = attrs->GetSkyModel(); needsSky = true; - occlusionState = (head->IsPostConstructed() + CGameArea::EOcclusionState occlusionState = (head->IsPostConstructed() ? head->GetPostConstructed()->x10dc_occlusionState : CGameArea::EOcclusionState::Occluded); + if (occlusionState == CGameArea::EOcclusionState::Visible) + skyVisible = true; } EEnvFxType envFxType = head->DoesAreaNeedEnvFx(); @@ -595,16 +597,48 @@ void CWorld::Update(float dt) xc4_neededFx = envFxType; } - if (r26 == 0) + if (areaCount == 0) return; - if (skyModel.IsValid() && needsSky) + if (overrideSkyId.IsValid() && needsSky) { - x70_26_skyboxOverridden = true; - x70_27_needsSky = needsSky; - - TToken skybox = g_SimplePool->GetObj({SBIG('CMDL'), skyModel}); - /* TODO: Finish */ + x70_26_skyboxActive = true; + x70_27_skyboxVisible = skyVisible; + xb4_skyboxOverride = g_SimplePool->GetObj({SBIG('CMDL'), overrideSkyId}); + xa4_skyboxWorldLoaded = TLockedToken(); + if (x94_skyboxWorld) + x94_skyboxWorld.Unlock(); + } + else + { + xb4_skyboxOverride = TLockedToken(); + if (!x94_skyboxWorld) + { + x70_26_skyboxActive = false; + x70_27_skyboxVisible = false; + } + else if (!needsSky) + { + xa4_skyboxWorldLoaded = TLockedToken(); + x94_skyboxWorld.Unlock(); + x70_26_skyboxActive = false; + x70_27_skyboxVisible = false; + } + else + { + if (!xa4_skyboxWorldLoaded) + { + x94_skyboxWorld.Lock(); + if (x94_skyboxWorld.IsLoaded()) + { + x94_skyboxWorld->Touch(0); + if (x94_skyboxWorld->IsLoaded(0)) + xa4_skyboxWorldLoaded = x94_skyboxWorld; + } + } + x70_26_skyboxActive = true; + x70_27_skyboxVisible = skyVisible; + } } } @@ -631,14 +665,14 @@ void CWorld::TouchSky() void CWorld::DrawSky(const zeus::CTransform& xf) const { const CModel* model; - if (xa4_skyboxB) - model = xa4_skyboxB.GetObj(); - else if (xb4_skyboxC) - model = xb4_skyboxC.GetObj(); + if (xa4_skyboxWorldLoaded) + model = xa4_skyboxWorldLoaded.GetObj(); + else if (xb4_skyboxOverride) + model = xb4_skyboxOverride.GetObj(); else return; - if (!x70_27_needsSky) + if (!x70_27_skyboxVisible) return; CGraphics::DisableAllLights(); diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index 75140b03b..fe06c504b 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -137,16 +137,16 @@ private: { bool x70_24_currentAreaNeedsAllocation : 1; bool x70_25_paused : 1; - bool x70_26_skyboxOverridden : 1; - bool x70_27_needsSky : 1; + bool x70_26_skyboxActive : 1; + bool x70_27_skyboxVisible : 1; }; - u16 dummy = 0; + u32 dummy = 0; }; std::vector x74_soundGroupData; std::string x84_defAudioTrack; - TLockedToken x94_skybox; - TLockedToken xa4_skyboxB; - TLockedToken xb4_skyboxC; + TLockedToken x94_skyboxWorld; + TLockedToken xa4_skyboxWorldLoaded; + TLockedToken xb4_skyboxOverride; EEnvFxType xc4_neededFx = EEnvFxType::None; std::vector xc8_sfxHandles; @@ -156,7 +156,7 @@ private: public: void MoveToChain(CGameArea* area, EChain chain); - void MoveAreaToChain3(TAreaId aid); + void MoveAreaToAliveChain(TAreaId aid); bool CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId); CGameArea::CChainIterator GetChainHead(EChain chain) { return {x4c_chainHeads[int(chain)]}; } CGameArea::CConstChainIterator GetChainHead(EChain chain) const { return {x4c_chainHeads[int(chain)]}; } diff --git a/Runtime/World/CWorldTransManager.cpp b/Runtime/World/CWorldTransManager.cpp index 2370fc3cb..ad33517d5 100644 --- a/Runtime/World/CWorldTransManager.cpp +++ b/Runtime/World/CWorldTransManager.cpp @@ -155,7 +155,7 @@ void CWorldTransManager::UpdateText(float dt) if (printed >= nextSfxInterval) { x3c_sfxInterval = nextSfxInterval; - CSfxManager::SfxStart(1438, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); + //CSfxManager::SfxStart(1438, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); } } diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index e4ad679c7..9310b8297 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -55,6 +55,7 @@ #include "CScriptSwitch.hpp" #include "CScriptTimer.hpp" #include "CScriptVisorFlare.hpp" +#include "CScriptVisorGoo.hpp" #include "CScriptWater.hpp" #include "CScriptWaypoint.hpp" #include "CScriptWorldTeleporter.hpp" @@ -723,8 +724,8 @@ CEntity* ScriptLoader::LoadDock(CStateManager& mgr, CInputStream& in, int propCo scale.readBig(in); u32 dock = in.readUint32Big(); TAreaId area = in.readUint32Big(); - bool b1 = in.readBool(); - return new CScriptDock(mgr.AllocateUniqueId(), name, info, position, scale, dock, area, active, 0, b1); + bool loadConnected = in.readBool(); + return new CScriptDock(mgr.AllocateUniqueId(), name, info, position, scale, dock, area, active, 0, loadConnected); } CEntity* ScriptLoader::LoadCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1905,6 +1906,28 @@ CEntity* ScriptLoader::LoadWorldTeleporter(CStateManager& mgr, CInputStream& in, CEntity* ScriptLoader::LoadVisorGoo(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { + if (!EnsurePropertyCount(propCount, 11, "VisorGoo")) + return nullptr; + + std::string name = mgr.HashInstanceName(in); + zeus::CVector3f position; + position.readBig(in); + zeus::CTransform xf = zeus::CTransform::Translate(position); + CAssetId particle(in); + CAssetId electric(in); + float minDist = in.readFloatBig(); + float maxDist = in.readFloatBig(); + float nearProb = in.readFloatBig(); + float farProb = in.readFloatBig(); + zeus::CColor color; + color.readRGBABig(in); + u32 sfx = in.readUint32Big(); + bool forceShow = in.readBool(); + + if (particle.IsValid() || electric.IsValid()) + return new CScriptVisorGoo(mgr.AllocateUniqueId(), name, info, xf, particle, electric, + minDist, maxDist, nearProb, farProb, color, sfx, forceShow, false); + return nullptr; } @@ -2325,29 +2348,29 @@ CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, i float f3 = in.readFloatBig(); float f4 = in.readFloatBig(); - SSpindleSegment seg1(in); + SSpindleProperty seg1(in); seg1.FixupAngles(); - SSpindleSegment seg2(in); - SSpindleSegment seg3(in); - SSpindleSegment seg4(in); - SSpindleSegment seg5(in); + SSpindleProperty seg2(in); + SSpindleProperty seg3(in); + SSpindleProperty seg4(in); + SSpindleProperty seg5(in); seg5.FixupAngles(); - SSpindleSegment seg6(in); + SSpindleProperty seg6(in); seg6.FixupAngles(); - SSpindleSegment seg7(in); + SSpindleProperty seg7(in); seg7.FixupAngles(); - SSpindleSegment seg8(in); + SSpindleProperty seg8(in); seg8.FixupAngles(); - SSpindleSegment seg9(in); - SSpindleSegment seg10(in); - SSpindleSegment seg11(in); + SSpindleProperty seg9(in); + SSpindleProperty seg10(in); + SSpindleProperty seg11(in); seg11.FixupAngles(); - SSpindleSegment seg12(in); + SSpindleProperty seg12(in); seg12.FixupAngles(); - SSpindleSegment seg13(in); + SSpindleProperty seg13(in); seg13.FixupAngles(); - SSpindleSegment seg14(in); - SSpindleSegment seg15(in); + SSpindleProperty seg14(in); + SSpindleProperty seg15(in); seg15.FixupAngles(); return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, @@ -2384,7 +2407,22 @@ CEntity* ScriptLoader::LoadCameraHintTrigger(CStateManager& mgr, CInputStream& i CEntity* ScriptLoader::LoadRumbleEffect(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 6, "RumbleEffect")) + return nullptr; + + std::string name = mgr.HashInstanceName(in); + zeus::CVector3f position; + position.readBig(in); + bool active = in.readBool(); + float f1 = in.readFloatBig(); + u32 w1 = in.readUint32Big(); + u32 pFlags = LoadParameterFlags(in); + + return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, + ConvertEditorEulerToTransform4f(zeus::CVector3f::skZero, position), + CScriptSpecialFunction::ESpecialFunction::RumbleEffect, "", + f1, w1, pFlags, 0.f, zeus::CVector3f::skZero, + zeus::CColor::skBlack, active, {}, {}, {}, {}, -1, -1, -1); } CEntity* ScriptLoader::LoadAmbientAI(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) diff --git a/Runtime/rstl.hpp b/Runtime/rstl.hpp index 309d650ec..741eaa3d0 100644 --- a/Runtime/rstl.hpp +++ b/Runtime/rstl.hpp @@ -153,6 +153,7 @@ public: size_t size() const noexcept { return x0_size; } bool empty() const noexcept { return x0_size == 0; } + constexpr size_t capacity() const noexcept { return N; } const T* data() const noexcept { return std::addressof(_value(0)); } T* data() noexcept { return std::addressof(_value(0)); } diff --git a/hecl b/hecl index 2410f7584..3a5ddb35c 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 2410f75845672ebcbf882e6d94d3b6edf1bea194 +Subproject commit 3a5ddb35c6d028a25e9e3eb0e62be5dee04c9373 diff --git a/specter b/specter index 1e6f4fee3..9d1d1aba3 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 1e6f4fee3dd4dff4a94d325d28232f246d73ce82 +Subproject commit 9d1d1aba3962526ea2875d9fd5341079bc932163