Additional CAutoMapper work

This commit is contained in:
Jack Andersen 2017-04-16 10:56:34 -10:00
parent c3f04bcbaa
commit 89b6935e1a
7 changed files with 343 additions and 32 deletions

View File

@ -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;

View File

@ -60,8 +60,8 @@ struct CTweakAutoMapper : public ITweakAutoMapper
Value<float> xb8_miniMapViewportWidth;
Value<float> xbc_miniMapViewportHeight;
Value<float> xc0_miniMapCamDistScale;
Value<float> xc4_;
Value<float> xc8_;
Value<float> xc4_mapPlaneScaleX;
Value<float> xc8_mapPlaneScaleZ;
Value<bool> xcc_;
Value<float> xd0_universeCamDist;
Value<float> 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; }

View File

@ -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<CStringTable>();
}
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<CStringTable>();
}
}
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 ; i<mwData.GetNumMapAreaDatas() ; ++i)
{
float mag = (universeAreaXf.origin - mwData.GetMapAreaData(i).origin).magnitude();
if (mag < minMag)
{
hexIdx = i;
minMag = mag;
}
}
CMapUniverse::CMapUniverseDrawParms parms(universeInterp, x9c_worldIdx, g_GameState->CurrentWorldAssetId(),
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 ; i<hintOpts.GetHintStates().size() ; ++i)
{
const CHintOptions::SHintState& state = hintOpts.GetHintStates()[i];
if (state.x0_state != CHintOptions::EHintState::Displaying)
continue;
const CGameHintInfo::CGameHint& memHint = g_MemoryCardSys->GetHints()[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)

View File

@ -176,8 +176,8 @@ private:
ResId x74_areaHintDescId = -1;
TLockedToken<CStringTable> x78_areaHintDesc;
u32 x84_ = 0;
ResId x88_ = -1;
u32 x98_ = 0;
ResId x88_mapAreaStringId = -1;
TLockedToken<CStringTable> 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<SAutoMapperHintStep> x1e0_hintSteps;
std::list<SAutoMapperHintLocation> x1f8_hintLocations;
rstl::reserved_vector<TLockedToken<CTexture>, 9> x210_lstick;
@ -256,6 +256,7 @@ private:
void TransformRenderStatesUniverseToWorld();
void TransformRenderStateWorldToUniverse(SAutoMapperRenderState&);
void SetupHintNavigation();
ResId GetAreaHintDescriptionString(ResId mreaId);
public:
CAutoMapper(CStateManager& stateMgr);

View File

@ -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*)
{

View File

@ -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

View File

@ -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: