Animation transitions and pause screen fixes

This commit is contained in:
Jack Andersen 2018-01-04 17:02:30 -10:00
parent 99fc9e3598
commit a78c4c6b36
25 changed files with 179 additions and 67 deletions

View File

@ -438,13 +438,13 @@ void CAnimData::CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms,
(scaleAlign - scaleStart)) / *parms.GetObjectScale() *
(1.f / (timeAlign.GetSeconds() - timeStart.GetSeconds()));
x220_28_ = true;
x220_26_ = false;
x220_26_aligningPos = false;
}
else
{
x1dc_alignPos = zeus::CVector3f::skZero;
x220_28_ = false;
x220_26_ = false;
x220_26_aligningPos = false;
}
}
}
@ -509,20 +509,20 @@ void CAnimData::CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms,
(scaleAlign - scaleStart)) / *parms.GetObjectScale() *
(1.f / (timeAlign.GetSeconds() - timeStart.GetSeconds()));
x220_28_ = true;
x220_26_ = false;
x220_26_aligningPos = false;
}
else
{
x1dc_alignPos = zeus::CVector3f::skZero;
x220_28_ = false;
x220_26_ = false;
x220_26_aligningPos = false;
}
}
else
{
x1dc_alignPos = zeus::CVector3f::skZero;
x220_28_ = false;
x220_26_ = false;
x220_26_aligningPos = false;
}
}
}
@ -632,6 +632,7 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time)
x1f8_animRoot->VGetSegStatementSet(segIdList, segSet);
AddAdditiveSegData(segIdList, segSet);
for (const CSegId& id : segIdList.GetList())
{
if (id == 3)
@ -842,7 +843,7 @@ SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& suspendParticles, CRando
x220_24_animating = false;
x1dc_alignPos = zeus::CVector3f::skZero;
x220_28_ = false;
x220_26_ = false;
x220_26_aligningPos = false;
}
}
}
@ -904,14 +905,14 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::
{
case EUserEventType::AlignTargetPosStart:
{
x220_26_ = true;
x220_26_aligningPos = true;
break;
}
case EUserEventType::AlignTargetPos:
{
x1dc_alignPos = zeus::CVector3f::skZero;
x220_28_ = false;
x220_26_ = false;
x220_26_aligningPos = false;
break;
}
case EUserEventType::AlignTargetRot:
@ -927,7 +928,7 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::
}
offset += results.x8_deltas.x0_posDelta;
if (x220_26_)
if (x220_26_aligningPos)
offset += x1dc_alignPos * time.GetSeconds();
zeus::CQuaternion rot = results.x8_deltas.xc_rotDelta * x1e8_alignRot;

View File

@ -129,7 +129,7 @@ private:
{
bool x220_24_animating : 1;
bool x220_25_loop : 1;
bool x220_26_ : 1;
bool x220_26_aligningPos : 1;
bool x220_27_ : 1;
bool x220_28_ : 1;
bool x220_29_animationJustStarted : 1;

View File

@ -450,7 +450,7 @@ zeus::CQuaternion CAnimSourceReader::VGetRotation(const CSegId& seg) const
CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source,
const CCharAnimTime& time)
: CAnimSourceReaderBase(std::make_unique<CAnimSourceInfo>(source), CCharAnimTime()),
: CAnimSourceReaderBase(std::make_unique<CAnimSourceInfo>(source), {}),
x54_source(source), x64_steadyStateInfo(false, source->GetDuration(),
source->GetOffset(source->GetRootBoneId(), time))
{

View File

@ -60,7 +60,6 @@ public:
CAnimSourceReaderBase(std::unique_ptr<IAnimSourceInfo>&& sourceInfo,
const CCharAnimTime& time);
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
@ -72,6 +71,8 @@ public:
virtual zeus::CVector3f VGetOffset(const CSegId& seg, const CCharAnimTime& b) const=0;
virtual bool VSupportsReverseView() const=0;
virtual SAdvancementResults VReverseView(const CCharAnimTime& time)=0;
const CCharAnimTime& GetCurTime() const { return xc_curTime; }
};
class CAnimSourceReader : public CAnimSourceReaderBase

View File

@ -1,4 +1,5 @@
#include "CAnimTreeAnimReaderContainer.hpp"
#include "CFBStreamedAnimReader.hpp"
namespace urde
{

View File

@ -31,6 +31,8 @@ public:
CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const;
u32 GetNumChildren() const;
std::shared_ptr<IAnimReader> GetBestUnblendedChild() const;
std::string_view GetName() const { return x4_name; }
};
}

View File

@ -12,9 +12,9 @@ std::string CAnimTreeTransition::CreatePrimitiveName(const std::weak_ptr<CAnimTr
CAnimTreeTransition::CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur,
const CCharAnimTime& timeInTrans, bool runA, bool loopA, int flags,
std::string_view name, bool b4)
std::string_view name, bool initialized)
: CAnimTreeTweenBase(b1, a, b, flags, name), x24_transDur(transDur), x2c_timeInTrans(timeInTrans),
x34_runA(runA), x35_loopA(loopA), x36_(b4)
x34_runA(runA), x35_loopA(loopA), x36_initialized(initialized)
{
}
@ -56,7 +56,7 @@ std::unique_ptr<IAnimReader> CAnimTreeTransition::VClone() const
std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x18_b->Clone())),
x24_transDur, x2c_timeInTrans, x34_runA,
x35_loopA, x1c_flags, x4_name, x36_);
x35_loopA, x1c_flags, x4_name, x36_initialized);
}
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTransition::VSimplified()
@ -70,6 +70,13 @@ std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTransition::V
return CAnimTreeTweenBase::VSimplified();
}
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTransition::VReverseSimplified()
{
if (zeus::close_enough(GetBlendingWeight(), 0.f))
return {x14_a->Clone()};
return CAnimTreeTweenBase::VReverseSimplified();
}
SAdvancementResults CAnimTreeTransition::AdvanceViewForTransitionalPeriod(const CCharAnimTime& time)
{
IncAdvancementDepth();
@ -85,9 +92,9 @@ SAdvancementResults CAnimTreeTransition::AdvanceViewForTransitionalPeriod(const
if (ShouldCullTree())
{
if (newWeight < 0.5f)
x20_25_ = 1;
x20_25_cullSelector = 1;
else
x20_25_ = 2;
x20_25_cullSelector = 2;
}
if (x1c_flags & 0x1)
@ -116,12 +123,12 @@ SAdvancementResults CAnimTreeTransition::VAdvanceView(const CCharAnimTime& time)
x14_a->VAdvanceView(time);
DecAdvancementDepth();
if (ShouldCullTree())
x20_25_ = 1;
x20_25_cullSelector = 1;
return {};
}
if (!x36_)
x36_ = true;
if (!x36_initialized)
x36_initialized = true;
if (x2c_timeInTrans + time < x24_transDur)
{

View File

@ -14,7 +14,7 @@ protected:
CCharAnimTime x2c_timeInTrans;
bool x34_runA;
bool x35_loopA;
bool x36_ = false;
bool x36_initialized = false;
SAdvancementResults AdvanceViewForTransitionalPeriod(const CCharAnimTime& time);
public:
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&,
@ -23,7 +23,7 @@ public:
CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur,
const CCharAnimTime& timeInTrans, bool runA, bool loopA, int flags,
std::string_view name, bool b4);
std::string_view name, bool initialized);
CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b,
const CCharAnimTime& transDur, bool runA,
@ -33,6 +33,7 @@ public:
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
std::unique_ptr<IAnimReader> VClone() const;
std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
std::experimental::optional<std::unique_ptr<IAnimReader>> VReverseSimplified();
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
void SetBlendingWeight(float w);
float VGetBlendingWeight() const;

View File

@ -1,4 +1,6 @@
#include "CAnimTreeTweenBase.hpp"
#include "CSegStatementSet.hpp"
#include "CSegIdList.hpp"
namespace urde
{
@ -10,7 +12,7 @@ CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1, const std::weak_ptr<CAnimTreeNod
: CAnimTreeDoubleChild(a, b, name), x1c_flags(flags)
{
x20_24_b1 = b1;
x20_25_ = 0;
x20_25_cullSelector = 0;
}
void CAnimTreeTweenBase::VGetWeightedReaders(
@ -21,16 +23,86 @@ void CAnimTreeTweenBase::VGetWeightedReaders(
x18_b->VGetWeightedReaders(out, weight * w);
}
void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const {}
void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const
{
float w = GetBlendingWeight();
static int sStack = 0;
++sStack;
if (w >= 1.f)
{
x18_b->VGetSegStatementSet(list, setOut);
}
else if (sStack > 3)
{
auto& n = w > 0.5f ? x18_b : x14_a;
n->GetBestUnblendedChild()->VGetSegStatementSet(list, setOut);
}
else
{
CSegStatementSet setA, setB;
x14_a->VGetSegStatementSet(list, setA);
x18_b->VGetSegStatementSet(list, setB);
for (CSegId id : list.GetList())
{
if (w < 0.0001f)
{
setOut[id].x0_rotation = setA[id].x0_rotation;
if (setA[id].x1c_hasOffset)
{
setOut[id].x10_offset = setA[id].x10_offset;
setOut[id].x1c_hasOffset = true;
}
}
else
{
setOut[id].x0_rotation = zeus::CQuaternion::slerpShort(setA[id].x0_rotation, setB[id].x0_rotation, w);
if (setA[id].x1c_hasOffset && setB[id].x1c_hasOffset)
{
setOut[id].x10_offset = zeus::CVector3f::lerp(setA[id].x10_offset, setB[id].x10_offset, w);
setOut[id].x1c_hasOffset = true;
}
}
}
}
--sStack;
}
void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut,
const CCharAnimTime& time) const
{
float w = GetBlendingWeight();
static int sStack = 0;
++sStack;
if (w >= 1.f)
{
x18_b->VGetSegStatementSet(list, setOut, time);
}
else if (sStack > 3)
{
auto& n = w > 0.5f ? x18_b : x14_a;
n->GetBestUnblendedChild()->VGetSegStatementSet(list, setOut, time);
}
else
{
CSegStatementSet setA, setB;
x14_a->VGetSegStatementSet(list, setA, time);
x18_b->VGetSegStatementSet(list, setB, time);
for (CSegId id : list.GetList())
{
setOut[id].x0_rotation = zeus::CQuaternion::slerpShort(setA[id].x0_rotation, setB[id].x0_rotation, w);
if (setA[id].x1c_hasOffset && setB[id].x1c_hasOffset)
{
setOut[id].x10_offset = zeus::CVector3f::lerp(setA[id].x10_offset, setB[id].x10_offset, w);
setOut[id].x1c_hasOffset = true;
}
}
}
--sStack;
}
bool CAnimTreeTweenBase::VHasOffset(const CSegId& seg) const
{
return (x14_a->VHasOffset(seg) || x18_b->VHasOffset(seg));
return (x14_a->VHasOffset(seg) && x18_b->VHasOffset(seg));
}
zeus::CVector3f CAnimTreeTweenBase::VGetOffset(const CSegId& seg) const
@ -57,7 +129,7 @@ zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTweenBase::VSimplified()
{
if (x20_25_ == 0)
if (x20_25_cullSelector == 0)
{
auto simpA = x14_a->Simplified();
auto simpB = x18_b->Simplified();
@ -72,7 +144,7 @@ std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTweenBase::VS
}
else
{
auto tmp = (x20_25_ == 1) ? x18_b : x14_a;
auto tmp = (x20_25_cullSelector == 1) ? x18_b : x14_a;
auto tmpUnblended = tmp->GetBestUnblendedChild();
if (!tmpUnblended)
return {tmp->Clone()};

View File

@ -12,7 +12,7 @@ class CAnimTreeTweenBase : public CAnimTreeDoubleChild
protected:
int x1c_flags;
bool x20_24_b1 : 1;
u8 x20_25_ : 2;
u8 x20_25_cullSelector : 2;
public:
CAnimTreeTweenBase(bool,
const std::weak_ptr<CAnimTreeNode>& a,
@ -34,6 +34,8 @@ public:
zeus::CQuaternion VGetRotation(const CSegId& seg) const;
std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
virtual std::experimental::optional<std::unique_ptr<IAnimReader>> VReverseSimplified()
{ return CAnimTreeTweenBase::VSimplified(); }
static bool ShouldCullTree() { return 3 <= sAdvancementDepth; }
static void IncAdvancementDepth() { sAdvancementDepth++; }

View File

@ -350,7 +350,7 @@ CSegIdToIndexConverter::CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals
}
CFBStreamedAnimReader::CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamedCompression>& source, const CCharAnimTime& time)
: CAnimSourceReaderBase(std::make_unique<TAnimSourceInfo<CFBStreamedCompression>>(source), time), x54_source(source),
: CAnimSourceReaderBase(std::make_unique<TAnimSourceInfo<CFBStreamedCompression>>(source), {}), x54_source(source),
x64_steadyStateInfo(source->IsLooping(), source->GetAnimationDuration(), source->GetRootOffset()),
x7c_totals(source), x104_bitstreamData(source->GetBitstreamPointer()), x108_bitLoader(x104_bitstreamData),
x114_segIdToIndex(x7c_totals.x10_nextSel ? x7c_totals.x14_a : x7c_totals.x3c_b)

View File

@ -81,8 +81,7 @@ void CGuiTableGroup::ProcessUserInput(const CFinalInput& input)
bool CGuiTableGroup::IsWorkerSelectable(int idx) const
{
CGuiWidget* widget = GetWorkerWidget(idx);
if (widget)
if (CGuiWidget* widget = GetWorkerWidget(idx))
return widget->GetIsSelectable();
return false;
}

View File

@ -8,13 +8,18 @@ static logvisor::Module Log("urde::CGuiWidget");
CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms)
: x70_selfId(parms.x6_selfId), x72_parentId(parms.x8_parentId),
xa4_color(parms.x10_color), xa8_color2(parms.x10_color),
xac_drawFlags(parms.x14_drawFlags), xb0_frame(parms.x0_frame),
xb6_24_pg(parms.xd_g), xb6_25_isVisible(parms.xa_defaultVisible),
xb6_26_isActive(parms.xb_defaultActive),
xb6_27_isSelectable(true), xb6_28_eventLock(false),
xb6_29_cullFaces(parms.xc_cullFaces), xb6_30_depthGreater(false),
xb6_31_depthTest(true), xb7_24_depthWrite(false), xb7_25_(true)
xac_drawFlags(parms.x14_drawFlags), xb0_frame(parms.x0_frame)
{
xb6_24_pg = parms.xd_g;
xb6_25_isVisible = parms.xa_defaultVisible;
xb6_26_isActive = parms.xb_defaultActive;
xb6_27_isSelectable = true;
xb6_28_eventLock = false;
xb6_29_cullFaces = parms.xc_cullFaces;
xb6_30_depthGreater = false;
xb6_31_depthTest = true;
xb7_24_depthWrite = false;
xb7_25_ = true;
RecalcWidgetColor(ETraversalMode::Single);
}

View File

@ -184,7 +184,7 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input)
x174_textpane_body->TextSupport().SetPage(newPage);
if (oldPage != newPage)
CSfxManager::SfxStart(1444, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
x198_28_pulseTextArrowTop = newPage > 1;
x198_28_pulseTextArrowTop = newPage > 0;
x198_29_pulseTextArrowBottom = !lastPage;
}
else

View File

@ -362,7 +362,7 @@ void CLogBookScreen::ProcessControllerInput(const CFinalInput& input)
x174_textpane_body->TextSupport().SetPage(newPage);
if (oldPage != newPage)
CSfxManager::SfxStart(1444, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
x198_28_pulseTextArrowTop = newPage > 1;
x198_28_pulseTextArrowTop = newPage > 0;
x198_29_pulseTextArrowBottom = !lastPage;
}
else
@ -421,8 +421,10 @@ void CLogBookScreen::VActivate()
x178_textpane_title->TextSupport().SetText(xc_pauseStrg.GetString(0));
for (int i=0 ; i<5 ; ++i)
#if 0
for (int i=5 ; i<5 ; ++i)
x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(false);
#endif
}
void CLogBookScreen::RightTableSelectionChanged(int oldSel, int newSel)

View File

@ -199,8 +199,10 @@ void COptionsScreen::VActivate()
x178_textpane_title->TextSupport().SetText(xc_pauseStrg.GetString(15));
for (int i=0 ; i<5 ; ++i)
#if 0
for (int i=5 ; i<5 ; ++i)
x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(false);
#endif
x174_textpane_body->TextSupport().SetJustification(EJustification::Center);
x174_textpane_body->TextSupport().SetVerticalJustification(EVerticalJustification::Bottom);

View File

@ -70,6 +70,17 @@ void CPauseScreenBase::InitializeFrameGlue()
x48_tableDoubleStart = x190_tablegroup_double->GetIdlePosition();
x54_tableTripleStart = x194_tablegroup_triple->GetIdlePosition();
for (int i=0 ; i<5 ; ++i)
x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(true);
for (int i=0 ; i<x84_tablegroup_rightlog->GetElementCount() ; ++i)
{
CGuiWidget* w = x84_tablegroup_rightlog->GetWorkerWidget(i);
w->SetLocalTransform(zeus::CTransform::Translate(
x2c_rightTableStart + zeus::CVector3f(0.f, 0.f, x38_highlightPitch * i)));
w->SetIsSelectable(true);
}
for (int i=0 ; i<5 ; ++i)
{
xd8_textpane_titles.push_back(static_cast<CGuiTextPane*>(x8_frame.FindWidget(hecl::Format("textpane_title%d", i + 1))));

View File

@ -39,6 +39,7 @@ void CQuitGameScreen::FinishedLoading()
x14_tablegroup_quitgame = static_cast<CGuiTableGroup*>(
x10_loadedFrame->FindWidget("tablegroup_quitgame"));
x14_tablegroup_quitgame->SetVertical(false);
x14_tablegroup_quitgame->SetMenuAdvanceCallback(
std::bind(&CQuitGameScreen::DoAdvance, this, std::placeholders::_1));
x14_tablegroup_quitgame->SetMenuSelectionChangeCallback(
@ -88,7 +89,7 @@ EQuitAction CQuitGameScreen::Update(float dt)
void CQuitGameScreen::Draw()
{
if (x0_type == EQuitType::QuitGame)
m_blackScreen->draw(zeus::CColor::skBlack);
m_blackScreen->draw(zeus::CColor(0.f, 0.5f));
if (x10_loadedFrame)
x10_loadedFrame->Draw(CGuiWidgetDrawParms{1.f,

View File

@ -116,7 +116,8 @@ static const u32 Character2and3Idxs[8][2] =
CSamusDoll::CSamusDoll(const CDependencyGroup& suitDgrp, const CDependencyGroup& ballDgrp,
CPlayerState::EPlayerSuit suit, CPlayerState::EBeamId beam,
bool hasSpiderBall, bool hasGrappleBeam)
: x44_suit(suit), x48_beam(beam)
: x10_ballXf(zeus::CTransform::Translate(0.f, 0.f, 0.625f * g_tweakPlayer->GetPlayerBallHalfExtent())),
x44_suit(suit), x48_beam(beam)
{
x70_fixedRot.rotateZ(M_PIF);
x90_userInterpRot = xb0_userRot = x70_fixedRot;
@ -313,7 +314,7 @@ void CSamusDoll::Update(float dt, CRandom16& rand)
SetupLights();
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_xf.origin);
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_ballXf.origin);
x22c_ballInnerGlowGen->Update(dt);
if (x238_ballTransitionFlashGen)
@ -322,7 +323,7 @@ void CSamusDoll::Update(float dt, CRandom16& rand)
x238_ballTransitionFlashGen.reset();
if (x238_ballTransitionFlashGen)
{
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_xf.origin);
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_ballXf.origin);
x22c_ballInnerGlowGen->Update(dt);
}
}
@ -470,17 +471,17 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
flags.x1_matSetIdx = x1e0_ballMatIdx;
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
flags.x4_color = zeus::CColor::skWhite;
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
x184_ballModelData->Render(mgr, x10_ballXf, x24c_actorLights.get(), flags);
flags.m_extendedShader = EExtendedShader::ForcedAlpha;
flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = alpha * ballAlpha;
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
x184_ballModelData->Render(mgr, x10_ballXf, x24c_actorLights.get(), flags);
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = x6c_ballPulseFactor * alpha * ballAlpha * itemPulse;
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
x184_ballModelData->Render(mgr, x10_ballXf, x24c_actorLights.get(), flags);
}
if (x4d_selectedMorphball && ballT > 0.5f)
@ -507,14 +508,14 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
flags.x1_matSetIdx = x1e0_ballMatIdx;
flags.x4_color = zeus::CColor(1.f, spinAlpha * alpha);
x184_ballModelData->Render(mgr, x10_xf * zeus::CTransform::RotateZ(spinAngle) * zeus::CTransform::Scale(spinScale),
x184_ballModelData->Render(mgr, x10_ballXf * zeus::CTransform::RotateZ(spinAngle) * zeus::CTransform::Scale(spinScale),
x24c_actorLights.get(), flags);
}
}
if (x270_24_hasSpiderBall)
{
CGraphics::SetModelMatrix(x10_xf);
CGraphics::SetModelMatrix(x10_ballXf);
CModelFlags flags = {};
flags.x1_matSetIdx = x1e4_glassMatIdx;
x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights);
@ -551,17 +552,17 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
flags.x1_matSetIdx = x1e0_ballMatIdx;
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
flags.x4_color = zeus::CColor::skWhite;
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
x184_ballModelData->Render(mgr, x10_ballXf, x24c_actorLights.get(), flags);
flags.m_extendedShader = EExtendedShader::ForcedAlpha;
flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = alpha;
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
x184_ballModelData->Render(mgr, x10_ballXf, x24c_actorLights.get(), flags);
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = x6c_ballPulseFactor * alpha * itemPulse;
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
x184_ballModelData->Render(mgr, x10_ballXf, x24c_actorLights.get(), flags);
const u8* c = CMorphBall::BallGlowColors[x1e8_ballGlowColorIdx];
zeus::CColor color = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, alpha};
@ -587,7 +588,7 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
if (x270_24_hasSpiderBall)
{
CGraphics::SetModelMatrix(x10_xf);
CGraphics::SetModelMatrix(x10_ballXf);
CModelFlags flags = {};
flags.x1_matSetIdx = x1e4_glassMatIdx;
x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights);

View File

@ -18,7 +18,7 @@ namespace MP1
class CSamusDoll
{
std::vector<CToken> x0_depToks;
zeus::CTransform x10_xf;
zeus::CTransform x10_ballXf;
float x40_alphaIn = 0.f;
CPlayerState::EPlayerSuit x44_suit;
CPlayerState::EBeamId x48_beam;

View File

@ -493,6 +493,14 @@ CGameArea::CGameArea(CAssetId mreaId)
CBooModel::SetDummyTextures(false);
}
CGameArea::~CGameArea()
{
if (xf0_24_postConstructed)
RemoveStaticGeometry();
else
while (!Invalidate(nullptr)) {}
}
std::pair<std::unique_ptr<u8[]>, s32> CGameArea::IGetScriptingMemoryAlways() const
{
return GetScriptingMemoryAlways(*this);

View File

@ -288,6 +288,7 @@ public:
CGameArea(CInputStream& in, int idx, int mlvlVersion);
CGameArea(CAssetId mreaId); // Warmup constructor
~CGameArea();
bool IsFinishedOccluding() const;
void ReadDependencyList();

View File

@ -475,8 +475,7 @@ void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther)
x70_24_currentAreaNeedsAllocation = false;
x68_curAreaId = aid;
CGameArea* toDeallocateAreas = x4c_chainHeads[0];
while (toDeallocateAreas)
while (CGameArea* toDeallocateAreas = x4c_chainHeads[0])
{
if (toDeallocateAreas->Invalidate(&mgr))
{
@ -486,15 +485,13 @@ void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther)
toDeallocateAreas = toDeallocateAreas->x130_next;
}
CGameArea* aliveAreas = x4c_chainHeads[3];
while (aliveAreas)
while (CGameArea* aliveAreas = x4c_chainHeads[3])
{
MoveToChain(aliveAreas, EChain::AliveJudgement);
aliveAreas = aliveAreas->x130_next;
}
CGameArea* loadingAreas = x4c_chainHeads[2];
while (loadingAreas)
while (CGameArea* loadingAreas = x4c_chainHeads[2])
{
MoveToChain(loadingAreas, EChain::ToDeallocate);
loadingAreas = loadingAreas->x130_next;
@ -535,16 +532,14 @@ void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther)
}
}
CGameArea* judgementArea = x4c_chainHeads[4];
while (judgementArea)
while (CGameArea* judgementArea = x4c_chainHeads[4])
{
MoveToChain(judgementArea, EChain::ToDeallocate);
judgementArea = judgementArea->x130_next;
}
size_t toStreamCount = 0;
toDeallocateAreas = x4c_chainHeads[0];
while (toDeallocateAreas)
while (CGameArea* toDeallocateAreas = x4c_chainHeads[0])
{
toDeallocateAreas->RemoveStaticGeometry();
toDeallocateAreas = toDeallocateAreas->x130_next;

2
hecl

@ -1 +1 @@
Subproject commit d2cfde52c3bd591e5b39e7375a1c185f9ea39aa7
Subproject commit 2961e49fbd209d442b4fa4f3ef9387dc526bcae9

@ -1 +1 @@
Subproject commit be725e27ceb722649ef9e959845affde3c86a12f
Subproject commit 71cbcc9af81e5b05544021bc8afd81ae7700a4ce