diff --git a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp index f784d90bd..e3a58e810 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp @@ -36,6 +36,8 @@ struct ITweakAutoMapper : public ITweak virtual float GetMiniMapViewportWidth() const=0; virtual float GetMiniMapViewportHeight() const=0; virtual float GetMiniMapCamDistScale() const=0; + virtual float GetMapPlaneScaleX() const=0; + virtual float GetMapPlaneScaleZ() const=0; virtual float GetUniverseCamDist() const=0; virtual float GetMinUniverseCamDist() const=0; virtual float GetMaxUniverseCamDist() const=0; diff --git a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp index cee81d3fb..0b315925d 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp @@ -60,8 +60,8 @@ struct CTweakAutoMapper : public ITweakAutoMapper Value xb8_miniMapViewportWidth; Value xbc_miniMapViewportHeight; Value xc0_miniMapCamDistScale; - Value xc4_; - Value xc8_; + Value xc4_mapPlaneScaleX; + Value xc8_mapPlaneScaleZ; Value xcc_; Value xd0_universeCamDist; Value xd4_minUniverseCamDist; @@ -111,6 +111,8 @@ struct CTweakAutoMapper : public ITweakAutoMapper float GetMiniMapViewportWidth() const { return xb8_miniMapViewportWidth; } float GetMiniMapViewportHeight() const { return xbc_miniMapViewportHeight; } float GetMiniMapCamDistScale() const { return xc0_miniMapCamDistScale; } + float GetMapPlaneScaleX() const { return xc4_mapPlaneScaleX; } + float GetMapPlaneScaleZ() const { return xc8_mapPlaneScaleZ; } float GetUniverseCamDist() const { return xd0_universeCamDist; } float GetMinUniverseCamDist() const { return xd4_minUniverseCamDist; } float GetMaxUniverseCamDist() const { return xd8_maxUniverseCamDist; } diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index fcdf8cb6a..06ba8a7da 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -87,7 +87,7 @@ void CAutoMapper::SAutoMapperRenderState::InterpolateWithClamp(const SAutoMapper } CAutoMapper::CAutoMapper(CStateManager& stateMgr) -: x24_world(stateMgr.WorldNC()) +: x24_world(stateMgr.GetWorld()) { x8_mapu = g_SimplePool->GetObj("MAPU_MapUniverse"); x30_miniMapSamus = g_SimplePool->GetObj("CMDL_MiniMapSamus"); @@ -1180,8 +1180,8 @@ void CAutoMapper::Update(float dt, const CStateManager& mgr) { if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) { - x1d8_ = std::fmod(x1d8_ + dt, 0.75f); - x1dc_ = x1d8_ < 0.375f ? x1d8_ / 0.375f : (0.75f - x1d8_) / 0.375f; + x1d8_flashTimer = std::fmod(x1d8_flashTimer + dt, 0.75f); + x1dc_flashPulse = x1d8_flashTimer < 0.375f ? x1d8_flashTimer / 0.375f : (0.75f - x1d8_flashTimer) / 0.375f; } if (!m_frmeInitialized && x28_frmeMapScreen.IsLoaded()) @@ -1336,17 +1336,239 @@ void CAutoMapper::Update(float dt, const CStateManager& mgr) CompleteMapperStateTransition(mgr); } + ResId stringId = x88_mapAreaStringId; if (IsInMapperState(EAutoMapperState::MapScreenUniverse)) { - if (IWorld* wld = x14_dummyWorlds[x9c_worldIdx].get()) + IWorld* wld = x14_dummyWorlds[x9c_worldIdx].get(); + if (wld && wld->ICheckWorldComplete()) + stringId = wld->IGetStringTableAssetId(); + else if (x24_world) + stringId = x24_world->IGetStringTableAssetId(); + } + else if (x24_world) + { + const IGameArea* area = x24_world->IGetAreaAlways(xa0_curAreaId); + const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); + if (mwInfo.IsMapped(xa0_curAreaId) || mwInfo.IsAreaVisted(xa0_curAreaId)) + stringId = area->IGetStringTableAssetId(); + else + stringId = -1; + } + + if (x88_mapAreaStringId != stringId) + { + x88_mapAreaStringId = stringId; + if (x88_mapAreaStringId != -1) + x8c_mapAreaString = g_SimplePool->GetObj(SObjectTag{FOURCC('STRG'), x88_mapAreaStringId}); + else + x8c_mapAreaString = TLockedToken(); + } + + if (x2f8_textpane_areaname) + { + if (x8c_mapAreaString) { - /* TODO: Finish */ + if (x8c_mapAreaString.IsLoaded()) + x2f8_textpane_areaname->TextSupport()->SetText(x8c_mapAreaString->GetString(0)); } + else + { + x2f8_textpane_areaname->TextSupport()->SetText(u""); + } + } + + if (IsInMapperState(EAutoMapperState::MapScreen)) + { + ResId hintDesc = GetAreaHintDescriptionString(x24_world->IGetAreaAlways(xa0_curAreaId)->IGetAreaAssetId()); + if (hintDesc != x74_areaHintDescId) + { + x74_areaHintDescId = hintDesc; + if (x74_areaHintDescId != -1) + x78_areaHintDesc = g_SimplePool->GetObj(SObjectTag{FOURCC('STRG'), x74_areaHintDescId}); + else + x78_areaHintDesc = TLockedToken(); + } + } + + for (auto& wld : x14_dummyWorlds) + if (wld) + wld->ICheckWorldComplete(); +} + +void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, float alpha) const +{ + alpha *= g_GameState->GameOptions().GetHUDAlpha() / 255.f; + // Blend mode alpha + // Backface cull + float alphaInterp; + if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) + { + alphaInterp = 1.f; + } + else if (IsInMapperState(EAutoMapperState::MiniMap)) + { + alphaInterp = alpha; + } + else if (x1c0_nextState == EAutoMapperState::MiniMap) + { + float t = 0.f; + if (x1c4_interpDur > 0.f) + t = x1c8_interpTime / x1c4_interpDur; + alphaInterp = alpha * t + (1.f - t); + } + else if (x1bc_state == EAutoMapperState::MiniMap) + { + float t = 0.f; + if (x1c4_interpDur > 0.f) + t = x1c8_interpTime / x1c4_interpDur; + alphaInterp = alpha * (1.f - t) + t; } else { - + alphaInterp = 1.f; } + + float aspect = xa8_renderStates[0].x0_viewportSize.x / float(xa8_renderStates[0].x0_viewportSize.y); + float yScale = xa8_renderStates[0].x18_camDist / + std::tan(M_PIF / 2.f - 0.5f * 2.f * M_PIF * (xa8_renderStates[0].x1c_camAngle / 360.f)); + float xScale = yScale * aspect; + zeus::CTransform camXf(xa8_renderStates[0].x8_camOrientation, xa8_renderStates[0].x20_areaPoint); + zeus::CTransform distScale = zeus::CTransform::Scale(1.f / xScale, 0.001f, 1.f / yScale); + zeus::CTransform tweakScale = zeus::CTransform::Scale(g_tweakAutoMapper->GetMapPlaneScaleX(), 0.f, + g_tweakAutoMapper->GetMapPlaneScaleZ()); + zeus::CTransform planeXf = xf * tweakScale * distScale * camXf.inverse(); + + float universeInterp = 0.f; + if (x1c0_nextState == EAutoMapperState::MapScreenUniverse) + { + if (x1bc_state == EAutoMapperState::MapScreenUniverse) + { + universeInterp = 1.f; + } + else + { + if (x1c4_interpDur > 0.f) + universeInterp = x1c8_interpTime / x1c4_interpDur; + else + universeInterp = 0.f; + } + } + else if (x1bc_state == EAutoMapperState::MapScreenUniverse) + { + if (x1c4_interpDur > 0.f) + universeInterp = x1c8_interpTime / x1c4_interpDur; + else + universeInterp = 0.f; + universeInterp = 1.f - universeInterp; + } + + zeus::CTransform preXf; + if (x1bc_state == EAutoMapperState::MapScreenUniverse || x1c0_nextState == EAutoMapperState::MapScreenUniverse) + preXf = x8_mapu->GetMapWorldData(x9c_worldIdx).GetWorldTransform(); + + float objectScale = xa8_renderStates[0].x18_camDist / g_tweakAutoMapper->GetMinCamDist(); + float mapAlpha = alphaInterp * (1.f - universeInterp); + + if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) + { + if (universeInterp < 1.f && x24_world) + { + const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); + const CMapWorld* mw = x24_world->IGetMapWorld(); + float flashIntensity = 0.f; + if (x1e0_hintSteps.size() && x1e0_hintSteps.front().x0_type == SAutoMapperHintStep::Type::ShowBeacon) + { + if (xa0_curAreaId == mgr.GetNextAreaId() && x24_world == mgr.GetWorld()) + { + float pulseTime = std::fmod(x1e0_hintSteps.front().x4_float * 8.f, 1.f); + flashIntensity = 2.f * (pulseTime < 0.5f ? pulseTime : 1.f - pulseTime); + } + else + { + for (const SAutoMapperHintLocation& loc : x1f8_hintLocations) + { + if (x24_world->IGetWorldAssetId() != loc.x8_worldId) + continue; + if (xa0_curAreaId != loc.xc_areaId) + continue; + float pulseTime = std::fmod((1.f - std::max(0.f, (x1e0_hintSteps.front().x4_float - 0.5f) / 0.5f)) * 4.f, 1.f); + flashIntensity = 2.f * (pulseTime < 0.5f ? pulseTime : 1.f - pulseTime); + break; + } + } + } + CMapWorld::CMapWorldDrawParms parms( + xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, + xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, + xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, + xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, + mapAlpha, 2.f, mgr, planeXf * preXf, camXf, *x24_world, + mwInfo, x1dc_flashPulse, flashIntensity, objectScale, true); + mw->Draw(parms, xa0_curAreaId, xa0_curAreaId, + xa8_renderStates[0].x2c_drawDepth1, + xa8_renderStates[0].x30_drawDepth2, true); + } + } + else if (IsInMapperState(EAutoMapperState::MiniMap)) + { + const CMapWorld* mw = x24_world->IGetMapWorld(); + const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); + CMapWorld::CMapWorldDrawParms parms( + xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, + xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, + xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, + xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, + mapAlpha, 1.f, mgr, planeXf, camXf, *x24_world, + mwInfo, 0.f, 0.f, objectScale, false); + mw->Draw(parms, xa0_curAreaId, xa4_otherAreaId, + xa8_renderStates[0].x2c_drawDepth1, + xa8_renderStates[0].x30_drawDepth2, false); + } + else + { + const CMapWorld* mw = x24_world->IGetMapWorld(); + const CMapWorldInfo& mwInfo = *g_GameState->StateForWorld(x24_world->IGetWorldAssetId()).MapWorldInfo(); + CMapWorld::CMapWorldDrawParms parms( + xa8_renderStates[0].x34_alphaSurfaceVisited * alphaInterp, + xa8_renderStates[0].x38_alphaOutlineVisited * alphaInterp, + xa8_renderStates[0].x3c_alphaSurfaceUnvisited * alphaInterp, + xa8_renderStates[0].x40_alphaOutlineUnvisited * alphaInterp, + mapAlpha, 2.f, mgr, planeXf * preXf, camXf, *x24_world, + mwInfo, 0.f, 0.f, objectScale, true); + mw->Draw(parms, xa0_curAreaId, xa0_curAreaId, + xa8_renderStates[0].x2c_drawDepth1, + xa8_renderStates[0].x30_drawDepth2, false); + } + + if (universeInterp > 0.f) + { + zeus::CTransform areaXf = mgr.GetWorld()->GetMapWorld()->GetMapArea(mgr.GetNextAreaId())-> + GetAreaPostTransform(*mgr.GetWorld(), mgr.GetNextAreaId()); + const CMapUniverse::CMapWorldData& mwData = + x8_mapu->GetMapWorldDataByWorldId(g_GameState->CurrentWorldAssetId()); + zeus::CTransform universeAreaXf = mwData.GetWorldTransform() * areaXf; + float minMag = FLT_MAX; + int hexIdx = -1; + for (int i=0 ; iCurrentWorldAssetId(), + hexIdx, x1dc_flashPulse, mgr, planeXf, camXf); + x8_mapu->Draw(parms, zeus::CVector3f::skZero, 0.f, 0.f); + } + + if (!IsInMapperState(EAutoMapperState::MapScreenUniverse)) + { + /* TODO: Finish */ + } + } void CAutoMapper::TransformRenderStatesWorldToUniverse() @@ -1427,6 +1649,31 @@ void CAutoMapper::SetupHintNavigation() } } +ResId CAutoMapper::GetAreaHintDescriptionString(ResId mreaId) +{ + const CHintOptions& hintOpts = g_GameState->HintOptions(); + for (int i=0 ; iGetHints()[i]; + for (const CGameHintInfo::SHintLocation& loc : memHint.GetLocations()) + { + if (loc.x4_mreaId != mreaId) + continue; + for (const SAutoMapperHintLocation& hintLoc : x1f8_hintLocations) + { + if (hintLoc.xc_areaId != loc.x8_areaId) + continue; + if (hintLoc.x4_ > 0.f) + return loc.xc_stringId; + } + } + } + return -1; +} + void CAutoMapper::OnNewInGameGuiState(EInGameGuiState state, const CStateManager& mgr) { if (state == EInGameGuiState::MapScreen) diff --git a/Runtime/AutoMapper/CAutoMapper.hpp b/Runtime/AutoMapper/CAutoMapper.hpp index 3b7ac3b01..d4a0959fe 100644 --- a/Runtime/AutoMapper/CAutoMapper.hpp +++ b/Runtime/AutoMapper/CAutoMapper.hpp @@ -176,8 +176,8 @@ private: ResId x74_areaHintDescId = -1; TLockedToken x78_areaHintDesc; u32 x84_ = 0; - ResId x88_ = -1; - u32 x98_ = 0; + ResId x88_mapAreaStringId = -1; + TLockedToken x8c_mapAreaString; // Used to be optional u32 x9c_worldIdx = 0; TAreaId xa0_curAreaId; TAreaId xa4_otherAreaId; @@ -189,8 +189,8 @@ private: CSfxHandle x1cc_panningSfx; CSfxHandle x1d0_rotatingSfx; CSfxHandle x1d4_zoomingSfx; - float x1d8_ = 0.f; - float x1dc_ = 0.f; + float x1d8_flashTimer = 0.f; + float x1dc_flashPulse = 0.f; std::list x1e0_hintSteps; std::list x1f8_hintLocations; rstl::reserved_vector, 9> x210_lstick; @@ -256,6 +256,7 @@ private: void TransformRenderStatesUniverseToWorld(); void TransformRenderStateWorldToUniverse(SAutoMapperRenderState&); void SetupHintNavigation(); + ResId GetAreaHintDescriptionString(ResId mreaId); public: CAutoMapper(CStateManager& stateMgr); diff --git a/Runtime/AutoMapper/CMapUniverse.cpp b/Runtime/AutoMapper/CMapUniverse.cpp index dabfa7aa1..ee64e9d18 100644 --- a/Runtime/AutoMapper/CMapUniverse.cpp +++ b/Runtime/AutoMapper/CMapUniverse.cpp @@ -43,6 +43,11 @@ CMapUniverse::CMapWorldData::CMapWorldData(CInputStream& in, u32 version) x64_centerPoint *= 1.0f / float(x44_hexagonXfs.size()); } +void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3f&, float, float) const +{ + +} + CFactoryFnReturn FMapUniverseFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference*) { diff --git a/Runtime/AutoMapper/CMapUniverse.hpp b/Runtime/AutoMapper/CMapUniverse.hpp index e16f7bb60..3cc9b51b5 100644 --- a/Runtime/AutoMapper/CMapUniverse.hpp +++ b/Runtime/AutoMapper/CMapUniverse.hpp @@ -17,13 +17,31 @@ class CMapUniverse public: class CMapUniverseDrawParms { + float x0_alpha; + int x4_wldIdx; + ResId x8_wldRes; + int xc_closestHex; + float x10_flashPulse; + const CStateManager& x14_mgr; + const zeus::CTransform& x18_model; + const zeus::CTransform& x1c_view; public: - CMapUniverseDrawParms(float, int, const CStateManager&, - const zeus::CTransform&, const zeus::CTransform&); - s32 GetFocusWorldIndex() const; - zeus::CTransform GetCameraTransform() const; - zeus::CTransform GetPaneProjectionTransform() const; - float GetAlpha() const; + CMapUniverseDrawParms(float alpha, int wldIdx, ResId wldRes, int closestHex, + float flashPulse, const CStateManager& mgr, + const zeus::CTransform& model, const zeus::CTransform& view) + : x0_alpha(alpha), + x4_wldIdx(wldIdx), + x8_wldRes(wldRes), + xc_closestHex(closestHex), + x10_flashPulse(flashPulse), + x14_mgr(mgr), + x18_model(model), + x1c_view(view) + {} + int GetFocusWorldIndex() const { return x4_wldIdx; } + const zeus::CTransform& GetCameraTransform() const { return x1c_view; } + const zeus::CTransform& GetPaneProjectionTransform() const { return x18_model; } + float GetAlpha() const { return x0_alpha; } }; class CMapObjectSortInfo diff --git a/Runtime/AutoMapper/CMapWorld.hpp b/Runtime/AutoMapper/CMapWorld.hpp index 6e39ec9ff..d2023b052 100644 --- a/Runtime/AutoMapper/CMapWorld.hpp +++ b/Runtime/AutoMapper/CMapWorld.hpp @@ -71,21 +71,57 @@ public: class CMapWorldDrawParms { + float x0_alphaSurfVisited; + float x4_alphaOlVisited; + float x8_alphaSurfUnvisited; + float xc_alphaOlUnvisited; + float x10_alpha; + float x14_outlineWidthScale; + const CStateManager& x18_mgr; + const zeus::CTransform& x1c_modelXf; + const zeus::CTransform& x20_viewXf; + const IWorld& x24_wld; + const CMapWorldInfo& x28_mwInfo; + float x2c_flashPulse; + float x30_flashIntensity; + float x34_objectScale; + bool x38_sortDoorSurfs; public: - CMapWorldDrawParms(float, float, float, float, float, const CStateManager&, const zeus::CTransform&, - const zeus::CTransform&, const IWorld&, const CMapWorldInfo&, float, bool); - void GetWorld() const; - float GetOutlineWidthScale() const; - void GetPlaneProjectionTransform() const; - void GetPlayerAreaFlashIntensity() const; - void GetCameraTransform() const; - void GetAlphaOutlineUnvisited() const; - void GetAlphaSurfaceUnvisited() const; - void GetAlphaOutlineVisited() const; - void GetAlphaSurfaceVisited() const; - void GetMapWorldInfo() const; - void GetStateManager() const; - bool GetIsSortDoorSurfaces() const; + CMapWorldDrawParms(float alphaSurfVisited, float alphaOlVisited, + float alphaSurfUnvisited, float alphaOlUnvisited, + float alpha, float outlineWidthScale, const CStateManager& mgr, + const zeus::CTransform& modelXf, const zeus::CTransform& viewXf, + const IWorld& wld, const CMapWorldInfo& mwInfo, float flashPulse, + float flashIntensity, float objectScale, bool sortDoorSurfs) + : x0_alphaSurfVisited(alphaSurfVisited), + x4_alphaOlVisited(alphaOlVisited), + x8_alphaSurfUnvisited(alphaSurfUnvisited), + xc_alphaOlUnvisited(alphaOlUnvisited), + x10_alpha(alpha), + x14_outlineWidthScale(outlineWidthScale), + x18_mgr(mgr), + x1c_modelXf(modelXf), + x20_viewXf(viewXf), + x24_wld(wld), + x28_mwInfo(mwInfo), + x2c_flashPulse(flashPulse), + x30_flashIntensity(flashIntensity), + x34_objectScale(objectScale), + x38_sortDoorSurfs(sortDoorSurfs) + {} + const IWorld& GetWorld() const { return x24_wld; } + float GetOutlineWidthScale() const { return x14_outlineWidthScale; } + const zeus::CTransform& GetPlaneProjectionTransform() const { return x1c_modelXf; } + float GetPlayerAreaFlashIntensity() const { return x30_flashIntensity; } + float GetPlayerAreaFlashPulse() const { return x2c_flashPulse; } + const zeus::CTransform& GetCameraTransform() const { return x20_viewXf; } + float GetAlphaOutlineUnvisited() const { return xc_alphaOlUnvisited; } + float GetAlphaSurfaceUnvisited() const { return x8_alphaSurfUnvisited; } + float GetAlphaOutlineVisited() const { return x4_alphaOlVisited; } + float GetAlphaSurfaceVisited() const { return x0_alphaSurfVisited; } + const CMapWorldInfo& GetMapWorldInfo() const { return x28_mwInfo; } + const CStateManager& GetStateManager() const { return x18_mgr; } + bool GetIsSortDoorSurfaces() const { return x38_sortDoorSurfs; } }; private: