2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 13:07:42 +00:00

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

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