Various bug fixes and CAnimTree implementations

This commit is contained in:
Jack Andersen 2018-01-03 18:17:44 -10:00
parent 53bb9f1ba0
commit 99fc9e3598
38 changed files with 339 additions and 140 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17
if(APPLE AND NOT CMAKE_OSX_SYSROOT) if(APPLE AND NOT CMAKE_OSX_SYSROOT)
# If the Xcode SDK is lagging behind system version, CMake needs this done first # If the Xcode SDK is lagging behind system version, CMake needs this done first
execute_process(COMMAND xcrun --show-sdk-path execute_process(COMMAND xcrun --sdk macosx --show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
endif() endif()

View File

@ -126,9 +126,9 @@ void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stS
SAdvancementResults CAnimData::AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time) SAdvancementResults CAnimData::AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time)
{ {
SAdvancementResults ret = anim->VAdvanceView(time); SAdvancementResults ret = anim->VAdvanceView(time);
std::pair<std::unique_ptr<IAnimReader>, bool> simplified = anim->Simplified(); auto simplified = anim->Simplified();
if (simplified.second) if (simplified)
anim = std::static_pointer_cast<CAnimTreeNode>(std::shared_ptr<IAnimReader>(std::move(simplified.first))); anim = CAnimTreeNode::Cast(std::move(*simplified));
return ret; return ret;
} }
@ -883,7 +883,7 @@ SAdvancementDeltas CAnimData::AdvanceIgnoreParticles(float dt, CRandom16& random
void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat) void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat)
{ {
SAdvancementResults results; SAdvancementResults results;
std::pair<std::unique_ptr<IAnimReader>, bool> simplified = {}; std::experimental::optional<std::unique_ptr<IAnimReader>> simplified;
if (x104_animDir == EAnimDir::Forward) if (x104_animDir == EAnimDir::Forward)
{ {
@ -891,11 +891,8 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::
simplified = x1f8_animRoot->Simplified(); simplified = x1f8_animRoot->Simplified();
} }
if (simplified.second) if (simplified)
{ x1f8_animRoot = CAnimTreeNode::Cast(std::move(*simplified));
x1f8_animRoot = std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(std::move(simplified.first)));
}
if ((x220_28_ || x220_27_) && x210_passedIntCount > 0) if ((x220_28_ || x220_27_) && x210_passedIntCount > 0)
{ {

View File

@ -30,12 +30,6 @@ std::shared_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VGetBestUnblendedChil
return {}; return {};
} }
void CAnimTreeAnimReaderContainer::VGetWeightedReaders
(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const
{
out.push_back(std::make_pair(w, x14_reader));
}
SAdvancementResults CAnimTreeAnimReaderContainer::VAdvanceView(const CCharAnimTime& dt) SAdvancementResults CAnimTreeAnimReaderContainer::VAdvanceView(const CCharAnimTime& dt)
{ {
return x14_reader->VAdvanceView(dt); return x14_reader->VAdvanceView(dt);
@ -120,7 +114,7 @@ std::unique_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VClone() const
return std::make_unique<CAnimTreeAnimReaderContainer>(x4_name, x14_reader->Clone(), x1c_animDbIdx); return std::make_unique<CAnimTreeAnimReaderContainer>(x4_name, x14_reader->Clone(), x1c_animDbIdx);
} }
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeAnimReaderContainer::VSimplified() std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeAnimReaderContainer::VSimplified()
{ {
return {}; return {};
} }
@ -135,4 +129,10 @@ SAdvancementResults CAnimTreeAnimReaderContainer::VGetAdvancementResults(const C
return x14_reader->VGetAdvancementResults(a, b); return x14_reader->VGetAdvancementResults(a, b);
} }
void CAnimTreeAnimReaderContainer::VGetWeightedReaders(
rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const
{
out.emplace_back(std::make_pair(w, x14_reader));
}
} }

View File

@ -19,7 +19,7 @@ public:
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
u32 VGetNumChildren() const; u32 VGetNumChildren() const;
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const; std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
void VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const; void VGetWeightedReaders(rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a); SAdvancementResults VAdvanceView(const CCharAnimTime& a);
CCharAnimTime VGetTimeRemaining() const; CCharAnimTime VGetTimeRemaining() const;
@ -37,7 +37,7 @@ public:
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
std::unique_ptr<IAnimReader> VClone() const; std::unique_ptr<IAnimReader> VClone() const;
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified(); std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
void VSetPhase(float); void VSetPhase(float);
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
}; };

View File

@ -10,9 +10,56 @@ CAnimTreeDoubleChild::CAnimTreeDoubleChild(const std::weak_ptr<CAnimTreeNode>& a
{ {
} }
CAnimTreeDoubleChild::CDoubleChildAdvancementResult
CAnimTreeDoubleChild::AdvanceViewBothChildren(const CCharAnimTime& time, bool runLeft, bool loopLeft)
{
CCharAnimTime lRemTime = time;
CCharAnimTime totalTime;
if (!runLeft)
totalTime = CCharAnimTime();
else if (loopLeft)
totalTime = CCharAnimTime::Infinity();
else
totalTime = x14_a->VGetTimeRemaining();
SAdvancementDeltas leftDeltas, rightDeltas;
CCharAnimTime rRemTime = time;
if (time.GreaterThanZero())
{
while (lRemTime.GreaterThanZero() && !lRemTime.EpsilonZero() &&
totalTime.GreaterThanZero() && (loopLeft || !totalTime.EpsilonZero()))
{
SAdvancementResults res = x14_a->VAdvanceView(lRemTime);
auto simp = x14_a->Simplified();
if (simp)
x14_a = CAnimTreeNode::Cast(std::move(*simp));
leftDeltas.x0_posDelta += res.x8_deltas.x0_posDelta;
leftDeltas.xc_rotDelta = leftDeltas.xc_rotDelta * res.x8_deltas.xc_rotDelta;
if (!loopLeft)
totalTime = x14_a->VGetTimeRemaining();
lRemTime = res.x0_remTime;
}
while (rRemTime.GreaterThanZero() && !rRemTime.EpsilonZero())
{
SAdvancementResults res = x18_b->VAdvanceView(rRemTime);
auto simp = x18_b->Simplified();
if (simp)
x18_b = CAnimTreeNode::Cast(std::move(*simp));
rightDeltas.x0_posDelta += res.x8_deltas.x0_posDelta;
rightDeltas.xc_rotDelta = rightDeltas.xc_rotDelta * res.x8_deltas.xc_rotDelta;
rRemTime = res.x0_remTime;
}
}
return {time, leftDeltas, rightDeltas};
}
SAdvancementResults CAnimTreeDoubleChild::VAdvanceView(const CCharAnimTime& a) SAdvancementResults CAnimTreeDoubleChild::VAdvanceView(const CCharAnimTime& a)
{ {
return {}; SAdvancementResults resA = x14_a->VAdvanceView(a);
SAdvancementResults resB = x14_a->VAdvanceView(a);
return (resA.x0_remTime > resB.x0_remTime) ? resA : resB;
} }
u32 CAnimTreeDoubleChild::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 CAnimTreeDoubleChild::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut,
@ -110,8 +157,11 @@ std::shared_ptr<IAnimReader> CAnimTreeDoubleChild::VGetBestUnblendedChild() cons
return {}; return {};
} }
void CAnimTreeDoubleChild::VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const void CAnimTreeDoubleChild::VGetWeightedReaders(
rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const
{ {
x14_a->VGetWeightedReaders(out, w);
x18_b->VGetWeightedReaders(out, w);
} }
} }

View File

@ -11,19 +11,23 @@ class CAnimTreeDoubleChild : public CAnimTreeNode
public: public:
class CDoubleChildAdvancementResult class CDoubleChildAdvancementResult
{ {
CCharAnimTime x0_; CCharAnimTime x0_trueAdvancement;
SAdvancementDeltas x8_; SAdvancementDeltas x8_leftDeltas;
SAdvancementDeltas x24_; SAdvancementDeltas x24_rightDeltas;
public: public:
CDoubleChildAdvancementResult(const CCharAnimTime&, const SAdvancementDeltas&, const SAdvancementDeltas); CDoubleChildAdvancementResult(const CCharAnimTime& trueAdvancement, const SAdvancementDeltas& leftDeltas,
void GetLeftAdvancementDeltas() const; const SAdvancementDeltas& rightDeltas)
void GetRightAdvancementDeltas() const; : x0_trueAdvancement(trueAdvancement), x8_leftDeltas(leftDeltas), x24_rightDeltas(rightDeltas) {}
void GetTrueAdvancement() const; const SAdvancementDeltas& GetLeftAdvancementDeltas() const { return x8_leftDeltas; }
const SAdvancementDeltas& GetRightAdvancementDeltas() const { return x24_rightDeltas; }
const CCharAnimTime& GetTrueAdvancement() const { return x0_trueAdvancement; }
}; };
protected: protected:
std::shared_ptr<CAnimTreeNode> x14_a; std::shared_ptr<CAnimTreeNode> x14_a;
std::shared_ptr<CAnimTreeNode> x18_b; std::shared_ptr<CAnimTreeNode> x18_b;
CDoubleChildAdvancementResult AdvanceViewBothChildren(const CCharAnimTime& time, bool runLeft, bool loopLeft);
public: public:
CAnimTreeDoubleChild(const std::weak_ptr<CAnimTreeNode>& a, const std::weak_ptr<CAnimTreeNode>& b, CAnimTreeDoubleChild(const std::weak_ptr<CAnimTreeNode>& a, const std::weak_ptr<CAnimTreeNode>& b,
std::string_view name); std::string_view name);
@ -42,10 +46,8 @@ public:
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
u32 VGetNumChildren() const; u32 VGetNumChildren() const;
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const; std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
void VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const; void VGetWeightedReaders(rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const;
//virtual float VGetTotalChildWeight(float) const = 0;
//float GetTotalChildWeight(float f) const { return VGetTotalChildWeight(f); }
virtual float VGetRightChildWeight() const = 0; virtual float VGetRightChildWeight() const = 0;
float GetRightChildWeight() const { return VGetRightChildWeight(); } float GetRightChildWeight() const { return VGetRightChildWeight(); }

View File

@ -13,12 +13,20 @@ protected:
public: public:
CAnimTreeNode(std::string_view name) : x4_name(name) {} CAnimTreeNode(std::string_view name) : x4_name(name) {}
bool IsCAnimTreeNode() const {return true;} bool IsCAnimTreeNode() const {return true;}
static std::shared_ptr<CAnimTreeNode> Cast(std::unique_ptr<IAnimReader>&& ptr)
{
if (ptr->IsCAnimTreeNode())
return std::static_pointer_cast<CAnimTreeNode>(std::shared_ptr<IAnimReader>(std::move(ptr)));
return {};
}
virtual u32 Depth() const=0; virtual u32 Depth() const=0;
virtual CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const=0; virtual CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const=0;
virtual u32 VGetNumChildren() const=0; virtual u32 VGetNumChildren() const=0;
virtual std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const=0; virtual std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const=0;
virtual void VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const=0; virtual void VGetWeightedReaders(rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const=0;
void GetWeightedReaders(rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const
{ VGetWeightedReaders(out, w); }
CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const; CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const;
u32 GetNumChildren() const; u32 GetNumChildren() const;

View File

@ -38,12 +38,6 @@ std::shared_ptr<IAnimReader> CAnimTreeSequence::VGetBestUnblendedChild() const
x28_, x18_, x4_name, x3c_fundamentals, x94_curTime); x28_, x18_, x4_name, x3c_fundamentals, x94_curTime);
} }
void CAnimTreeSequence::VGetWeightedReaders
(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const
{
x14_child->VGetWeightedReaders(out, w);
}
SAdvancementResults CAnimTreeSequence::VAdvanceView(const CCharAnimTime& a) SAdvancementResults CAnimTreeSequence::VAdvanceView(const CCharAnimTime& a)
{ {
return {}; return {};

View File

@ -30,7 +30,6 @@ public:
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const; CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const; std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
void VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a); SAdvancementResults VAdvanceView(const CCharAnimTime& a);
CCharAnimTime VGetTimeRemaining() const; CCharAnimTime VGetTimeRemaining() const;

View File

@ -31,6 +31,8 @@ public:
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
u32 Depth() const; u32 Depth() const;
u32 VGetNumChildren() const; u32 VGetNumChildren() const;
void VGetWeightedReaders(rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const
{ x14_child->VGetWeightedReaders(out, w); }
}; };
} }

View File

@ -47,7 +47,7 @@ void CAnimTreeTimeScale::VSetPhase(float phase)
x14_child->VSetPhase(phase); x14_child->VSetPhase(phase);
} }
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeTimeScale::VSimplified() std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTimeScale::VSimplified()
{ {
return {}; return {};
} }

View File

@ -19,7 +19,7 @@ public:
CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const; CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const;
void VSetPhase(float); void VSetPhase(float);
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified(); std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
}; };
} }

View File

@ -10,17 +10,20 @@ std::string CAnimTreeTransition::CreatePrimitiveName(const std::weak_ptr<CAnimTr
} }
CAnimTreeTransition::CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a, CAnimTreeTransition::CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& time1, const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur,
const CCharAnimTime& time2, bool b2, bool b3, int flags, const CCharAnimTime& timeInTrans, bool runA, bool loopA, int flags,
std::string_view name, bool b4) std::string_view name, bool b4)
: CAnimTreeTweenBase(b1, a, b, flags, name), x24_(time1), x2c_(time2), x34_(b2), x35_(b3), x36_(b4) : CAnimTreeTweenBase(b1, a, b, flags, name), x24_transDur(transDur), x2c_timeInTrans(timeInTrans),
x34_runA(runA), x35_loopA(loopA), x36_(b4)
{ {
} }
CAnimTreeTransition::CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a, CAnimTreeTransition::CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& time, bool b2, const std::weak_ptr<CAnimTreeNode>& b,
const CCharAnimTime& transDur, bool runA,
int flags, std::string_view name) int flags, std::string_view name)
: CAnimTreeTweenBase(b1, a, b, flags, name), x24_(time), x34_(b2), x35_(a.lock()->VGetBoolPOIState("Loop")) : CAnimTreeTweenBase(b1, a, b, flags, name), x24_transDur(transDur), x34_runA(runA),
x35_loopA(a.lock()->VGetBoolPOIState("Loop"))
{ {
} }
@ -32,35 +35,112 @@ std::shared_ptr<IAnimReader> CAnimTreeTransition::VGetBestUnblendedChild() const
CCharAnimTime CAnimTreeTransition::VGetTimeRemaining() const CCharAnimTime CAnimTreeTransition::VGetTimeRemaining() const
{ {
CCharAnimTime time = x24_ * x2c_; CCharAnimTime transTimeRem = x24_transDur - x2c_timeInTrans;
CCharAnimTime bTimeRem = x18_b->VGetTimeRemaining(); CCharAnimTime rightTimeRem = x18_b->VGetTimeRemaining();
return (rightTimeRem < transTimeRem) ? transTimeRem : rightTimeRem;
if (time < bTimeRem)
return bTimeRem;
return time;
} }
CSteadyStateAnimInfo CAnimTreeTransition::VGetSteadyStateAnimInfo() const CSteadyStateAnimInfo CAnimTreeTransition::VGetSteadyStateAnimInfo() const
{ {
CSteadyStateAnimInfo bInfo = x18_b->VGetSteadyStateAnimInfo(); CSteadyStateAnimInfo bInfo = x18_b->VGetSteadyStateAnimInfo();
if (x24_ < bInfo.GetDuration()) if (x24_transDur < bInfo.GetDuration())
return CSteadyStateAnimInfo(bInfo.IsLooping(), bInfo.GetDuration(), bInfo.GetOffset()); return CSteadyStateAnimInfo(bInfo.IsLooping(), bInfo.GetDuration(), bInfo.GetOffset());
return CSteadyStateAnimInfo(bInfo.IsLooping(), x24_, bInfo.GetOffset()); return CSteadyStateAnimInfo(bInfo.IsLooping(), x24_transDur, bInfo.GetOffset());
} }
std::unique_ptr<IAnimReader> CAnimTreeTransition::VClone() const std::unique_ptr<IAnimReader> CAnimTreeTransition::VClone() const
{ {
return std::make_unique<CAnimTreeTransition>(x20_31_b1, std::static_pointer_cast<CAnimTreeNode>( return std::make_unique<CAnimTreeTransition>(x20_24_b1, std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x14_a->Clone())), std::shared_ptr<IAnimReader>(x14_a->Clone())),
std::static_pointer_cast<CAnimTreeNode>( std::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x18_b->Clone())), x24_, x2c_, std::shared_ptr<IAnimReader>(x18_b->Clone())),
x34_, x35_, x1c_flags, x4_name, x36_); x24_transDur, x2c_timeInTrans, x34_runA,
x35_loopA, x1c_flags, x4_name, x36_);
} }
SAdvancementResults CAnimTreeTransition::VAdvanceView(const CCharAnimTime& time) const std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTransition::VSimplified()
{ {
return {}; if (zeus::close_enough(GetBlendingWeight(), 1.f))
{
if (auto simp = x18_b->Simplified())
return simp;
return {x18_b->Clone()};
}
return CAnimTreeTweenBase::VSimplified();
}
SAdvancementResults CAnimTreeTransition::AdvanceViewForTransitionalPeriod(const CCharAnimTime& time)
{
IncAdvancementDepth();
CDoubleChildAdvancementResult res = AdvanceViewBothChildren(time, x34_runA, x35_loopA);
DecAdvancementDepth();
if (res.GetTrueAdvancement().EqualsZero())
return {};
float oldWeight = GetBlendingWeight();
x2c_timeInTrans += res.GetTrueAdvancement();
float newWeight = GetBlendingWeight();
if (ShouldCullTree())
{
if (newWeight < 0.5f)
x20_25_ = 1;
else
x20_25_ = 2;
}
if (x1c_flags & 0x1)
{
return {
res.GetTrueAdvancement(),
SAdvancementDeltas::Interpolate(res.GetLeftAdvancementDeltas(),
res.GetRightAdvancementDeltas(),
oldWeight, newWeight)
};
}
return {
res.GetTrueAdvancement(),
res.GetRightAdvancementDeltas()
};
}
SAdvancementResults CAnimTreeTransition::VAdvanceView(const CCharAnimTime& time)
{
if (time.EqualsZero())
{
IncAdvancementDepth();
x18_b->VAdvanceView(time);
if (x34_runA)
x14_a->VAdvanceView(time);
DecAdvancementDepth();
if (ShouldCullTree())
x20_25_ = 1;
return {};
}
if (!x36_)
x36_ = true;
if (x2c_timeInTrans + time < x24_transDur)
{
SAdvancementResults res = AdvanceViewForTransitionalPeriod(time);
res.x0_remTime = time - res.x0_remTime;
return res;
}
CCharAnimTime transTimeRem = x24_transDur - x2c_timeInTrans;
SAdvancementResults res;
if (transTimeRem.GreaterThanZero())
{
res = AdvanceViewForTransitionalPeriod(transTimeRem);
if (res.x0_remTime != transTimeRem)
return res;
}
res.x0_remTime = time - transTimeRem;
return res;
} }
void CAnimTreeTransition::SetBlendingWeight(float w) void CAnimTreeTransition::SetBlendingWeight(float w)
@ -70,8 +150,8 @@ void CAnimTreeTransition::SetBlendingWeight(float w)
float CAnimTreeTransition::VGetBlendingWeight() const float CAnimTreeTransition::VGetBlendingWeight() const
{ {
if (x24_.GreaterThanZero()) if (x24_transDur.GreaterThanZero())
return (1.f / x24_.GetSeconds()) * x2c_.GetSeconds(); return x2c_timeInTrans.GetSeconds() / x24_transDur.GetSeconds();
return 0.f; return 0.f;
} }
} }

View File

@ -10,24 +10,30 @@ namespace urde
class CAnimTreeTransition : public CAnimTreeTweenBase class CAnimTreeTransition : public CAnimTreeTweenBase
{ {
protected: protected:
CCharAnimTime x24_; CCharAnimTime x24_transDur;
CCharAnimTime x2c_; CCharAnimTime x2c_timeInTrans;
bool x34_; bool x34_runA;
bool x35_; bool x35_loopA;
bool x36_ = false; bool x36_ = false;
SAdvancementResults AdvanceViewForTransitionalPeriod(const CCharAnimTime& time);
public: public:
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&, static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&,
float); float);
CAnimTreeTransition(bool, const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&, CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const CCharAnimTime&, const CCharAnimTime&, bool, bool, int, std::string_view, bool); const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur,
CAnimTreeTransition(bool, const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&, const CCharAnimTime& timeInTrans, bool runA, bool loopA, int flags,
const CCharAnimTime&, bool, int, std::string_view); std::string_view name, bool b4);
CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b,
const CCharAnimTime& transDur, bool runA,
int flags, std::string_view name);
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const; std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
CCharAnimTime VGetTimeRemaining() const; CCharAnimTime VGetTimeRemaining() const;
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const; CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
std::unique_ptr<IAnimReader> VClone() const; std::unique_ptr<IAnimReader> VClone() const;
SAdvancementResults VAdvanceView(const CCharAnimTime& a) const; std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
void SetBlendingWeight(float w); void SetBlendingWeight(float w);
float VGetBlendingWeight() const; float VGetBlendingWeight() const;
}; };

View File

@ -7,13 +7,19 @@ s32 CAnimTreeTweenBase::sAdvancementDepth = 0;
CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1, const std::weak_ptr<CAnimTreeNode>& a, CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, int flags, std::string_view name) const std::weak_ptr<CAnimTreeNode>& b, int flags, std::string_view name)
: CAnimTreeDoubleChild(a, b, name), x1c_flags(flags), x20_31_b1(b1) : CAnimTreeDoubleChild(a, b, name), x1c_flags(flags)
{ {
x20_24_b1 = b1;
x20_25_ = 0;
} }
/*void CAnimTreeTweenBase::VGetTotalChildWeight(float t) const void CAnimTreeTweenBase::VGetWeightedReaders(
rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const
{ {
}*/ float weight = GetBlendingWeight();
x14_a->VGetWeightedReaders(out, (1.f - weight) * w);
x18_b->VGetWeightedReaders(out, weight * w);
}
void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const {} void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const {}
@ -49,5 +55,29 @@ zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const
return zeus::CQuaternion::slerp(qA, qB, weight); return zeus::CQuaternion::slerp(qA, qB, weight);
} }
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeTweenBase::VSimplified() { return {}; } std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTweenBase::VSimplified()
{
if (x20_25_ == 0)
{
auto simpA = x14_a->Simplified();
auto simpB = x18_b->Simplified();
if (!simpA && !simpB)
return {};
auto clone = Clone();
if (simpA)
static_cast<CAnimTreeTweenBase&>(*clone).x14_a = CAnimTreeNode::Cast(std::move(*simpA));
if (simpB)
static_cast<CAnimTreeTweenBase&>(*clone).x18_b = CAnimTreeNode::Cast(std::move(*simpB));
return {std::move(clone)};
}
else
{
auto tmp = (x20_25_ == 1) ? x18_b : x14_a;
auto tmpUnblended = tmp->GetBestUnblendedChild();
if (!tmpUnblended)
return {tmp->Clone()};
else
return {tmpUnblended->Clone()};
}
}
} }

View File

@ -11,8 +11,8 @@ class CAnimTreeTweenBase : public CAnimTreeDoubleChild
static s32 sAdvancementDepth; static s32 sAdvancementDepth;
protected: protected:
int x1c_flags; int x1c_flags;
bool x20_31_b1; bool x20_24_b1 : 1;
bool x20_30_b2 = false; u8 x20_25_ : 2;
public: public:
CAnimTreeTweenBase(bool, CAnimTreeTweenBase(bool,
const std::weak_ptr<CAnimTreeNode>& a, const std::weak_ptr<CAnimTreeNode>& a,
@ -24,7 +24,7 @@ public:
float GetBlendingWeight() const { return VGetBlendingWeight(); } float GetBlendingWeight() const { return VGetBlendingWeight(); }
//void VGetTotalChildWeight(float) const; void VGetWeightedReaders(rstl::reserved_vector<std::pair<float, std::weak_ptr<IAnimReader>>, 16>& out, float w) const;
float VGetRightChildWeight() const { return GetBlendingWeight(); } float VGetRightChildWeight() const { return GetBlendingWeight(); }
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const; void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
@ -33,9 +33,9 @@ public:
zeus::CVector3f VGetOffset(const CSegId& seg) const; zeus::CVector3f VGetOffset(const CSegId& seg) const;
zeus::CQuaternion VGetRotation(const CSegId& seg) const; zeus::CQuaternion VGetRotation(const CSegId& seg) const;
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified(); std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
bool ShouldCullTree() const { return false; }
static bool ShouldCullTree() { return 3 <= sAdvancementDepth; }
static void IncAdvancementDepth() { sAdvancementDepth++; } static void IncAdvancementDepth() { sAdvancementDepth++; }
static void DecAdvancementDepth() { sAdvancementDepth--; } static void DecAdvancementDepth() { sAdvancementDepth--; }
}; };

View File

@ -6,17 +6,17 @@ namespace urde
CMetaTransTrans::CMetaTransTrans(CInputStream& in) CMetaTransTrans::CMetaTransTrans(CInputStream& in)
{ {
x4_animTime = CCharAnimTime(in); x4_transDur = CCharAnimTime(in);
xc_ = in.readBool(); xc_ = in.readBool();
xd_ = in.readBool(); xd_runA = in.readBool();
x10_ = in.readUint32Big(); x10_flags = in.readUint32Big();
} }
std::shared_ptr<CAnimTreeNode> CMetaTransTrans::VGetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a, std::shared_ptr<CAnimTreeNode> CMetaTransTrans::VGetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, const std::weak_ptr<CAnimTreeNode>& b,
const CAnimSysContext& animSys) const const CAnimSysContext& animSys) const
{ {
return std::make_shared<CAnimTreeTransition>(xc_, a, b, x4_animTime, xd_, x10_, return std::make_shared<CAnimTreeTransition>(xc_, a, b, x4_transDur, xd_runA, x10_flags,
CAnimTreeTransition::CreatePrimitiveName(a, b, x4_animTime.GetSeconds())); CAnimTreeTransition::CreatePrimitiveName(a, b, x4_transDur.GetSeconds()));
} }
} }

View File

@ -10,10 +10,10 @@ namespace urde
class CMetaTransTrans : public IMetaTrans class CMetaTransTrans : public IMetaTrans
{ {
CCharAnimTime x4_animTime; CCharAnimTime x4_transDur;
bool xc_; bool xc_;
bool xd_; bool xd_runA;
u32 x10_; u32 x10_flags;
public: public:
CMetaTransTrans(CInputStream& in); CMetaTransTrans(CInputStream& in);
EMetaTransType GetType() const {return EMetaTransType::Trans;} EMetaTransType GetType() const {return EMetaTransType::Trans;}

View File

@ -4,6 +4,17 @@
namespace urde namespace urde
{ {
SAdvancementDeltas
SAdvancementDeltas::Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b,
float oldWeight, float newWeight)
{
float weightSum = oldWeight + newWeight;
return {
b.x0_posDelta * weightSum * 0.5f - a.x0_posDelta * (weightSum - 2.f) * 0.5f,
zeus::CQuaternion::slerpShort(a.xc_rotDelta, b.xc_rotDelta, weightSum * 0.5f)
};
}
SAdvancementResults SAdvancementResults
IAnimReader::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const IAnimReader::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
{ {

View File

@ -23,6 +23,9 @@ struct SAdvancementDeltas
{ {
zeus::CVector3f x0_posDelta; zeus::CVector3f x0_posDelta;
zeus::CQuaternion xc_rotDelta; zeus::CQuaternion xc_rotDelta;
static SAdvancementDeltas Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b,
float oldWeight, float newWeight);
}; };
struct SAdvancementResults struct SAdvancementResults
@ -124,7 +127,7 @@ public:
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const=0; virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const=0;
virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const=0; virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const=0;
virtual std::unique_ptr<IAnimReader> VClone() const=0; virtual std::unique_ptr<IAnimReader> VClone() const=0;
virtual std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified() {return {};} virtual std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified() {return {};}
virtual void VSetPhase(float)=0; virtual void VSetPhase(float)=0;
virtual SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const; virtual SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
@ -133,7 +136,7 @@ public:
u32 GetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const; u32 GetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
u32 GetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const; u32 GetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const;
std::pair<std::unique_ptr<IAnimReader>, bool> Simplified() { return VSimplified(); } std::experimental::optional<std::unique_ptr<IAnimReader>> Simplified() { return VSimplified(); }
std::unique_ptr<IAnimReader> Clone() const { return VClone(); } std::unique_ptr<IAnimReader> Clone() const { return VClone(); }
}; };

View File

@ -195,10 +195,11 @@ bool CGuiTableGroup::PreDecrement()
void CGuiTableGroup::DoDecrement() void CGuiTableGroup::DoDecrement()
{ {
int oldSel = xc4_userSelection;
if (!PreDecrement()) if (!PreDecrement())
return; return;
if (x104_doMenuSelChange) if (x104_doMenuSelChange)
x104_doMenuSelChange(this, xc4_userSelection); x104_doMenuSelChange(this, oldSel);
} }
bool CGuiTableGroup::PreIncrement() bool CGuiTableGroup::PreIncrement()
@ -234,10 +235,11 @@ bool CGuiTableGroup::PreIncrement()
void CGuiTableGroup::DoIncrement() void CGuiTableGroup::DoIncrement()
{ {
int oldSel = xc4_userSelection;
if (!PreIncrement()) if (!PreIncrement())
return; return;
if (x104_doMenuSelChange) if (x104_doMenuSelChange)
x104_doMenuSelChange(this, xc4_userSelection); x104_doMenuSelChange(this, oldSel);
} }
std::shared_ptr<CGuiWidget> CGuiTableGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) std::shared_ptr<CGuiWidget> CGuiTableGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp)

View File

@ -84,7 +84,7 @@ std::list<CTextRenderBuffer> CTextExecuteBuffer::BuildRenderBufferPages(const ze
{ {
CFontRenderState rstate; CFontRenderState rstate;
for (auto it2 = x0_instList.begin() ; it2 != x0_instList.end() ;) for (auto it2 = x0_instList.begin() ; it2 != x0_instList.end() ; ++it2)
{ {
const std::shared_ptr<CInstruction>& inst2 = *it2; const std::shared_ptr<CInstruction>& inst2 = *it2;
inst2->Invoke(rstate, &rbuf); inst2->Invoke(rstate, &rbuf);
@ -96,10 +96,13 @@ std::list<CTextRenderBuffer> CTextExecuteBuffer::BuildRenderBufferPages(const ze
InstList::const_iterator pageEnd = it; InstList::const_iterator pageEnd = it;
{ {
CFontRenderState rstate; CFontRenderState rstate;
for (auto it2 = x0_instList.begin() ; it2 != x0_instList.end() ;) bool seekingToPage = true;
for (auto it2 = x0_instList.begin() ; it2 != x0_instList.end() ; ++it2)
{ {
const std::shared_ptr<CInstruction>& inst2 = *it2; const std::shared_ptr<CInstruction>& inst2 = *it2;
if (it2 != it) if (it2 == it)
seekingToPage = false;
if (seekingToPage)
{ {
inst2->PageInvoke(rstate, &rbuf); inst2->PageInvoke(rstate, &rbuf);
} }

View File

@ -646,7 +646,7 @@ void CFrontEndUI::SNewFileSelectFrame::DoFileMenuCancel(CGuiTableGroup* caller)
} }
} }
void CFrontEndUI::SNewFileSelectFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) void CFrontEndUI::SNewFileSelectFrame::DoSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
HandleActiveChange(caller); HandleActiveChange(caller);
CSfxManager::SfxStart(1093, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1093, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
@ -1172,7 +1172,7 @@ void CFrontEndUI::SFusionBonusFrame::DoCancel(CGuiTableGroup* caller)
SetTableColors(x28_tablegroup_options); SetTableColors(x28_tablegroup_options);
} }
void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
if (caller == x28_tablegroup_options) if (caller == x28_tablegroup_options)
{ {
@ -1381,7 +1381,7 @@ void CFrontEndUI::SFrontEndFrame::DoCancel(CGuiTableGroup* caller)
/* Intentionally empty */ /* Intentionally empty */
} }
void CFrontEndUI::SFrontEndFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel) void CFrontEndUI::SFrontEndFrame::DoSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
CSfxManager::SfxStart(1093, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1093, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
HandleActiveChange(caller); HandleActiveChange(caller);
@ -1619,7 +1619,7 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoMenuCancel(CGuiTableGroup* caller)
} }
} }
void CFrontEndUI::SOptionsFrontEndFrame::DoMenuSelectionChange(CGuiTableGroup* caller, int sel) void CFrontEndUI::SOptionsFrontEndFrame::DoMenuSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
SetTableColors(caller); SetTableColors(caller);
if (x24_tablegroup_leftmenu == caller) if (x24_tablegroup_leftmenu == caller)

View File

@ -168,7 +168,7 @@ public:
void DoPopupCancel(CGuiTableGroup* caller); void DoPopupCancel(CGuiTableGroup* caller);
void DoPopupAdvance(CGuiTableGroup* caller); void DoPopupAdvance(CGuiTableGroup* caller);
void DoFileMenuCancel(CGuiTableGroup* caller); void DoFileMenuCancel(CGuiTableGroup* caller);
void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoSelectionChange(CGuiTableGroup* caller, int oldSel);
void DoFileMenuAdvance(CGuiTableGroup* caller); void DoFileMenuAdvance(CGuiTableGroup* caller);
static SFileMenuOption FindFileSelectOption(CGuiFrame* frame, int idx); static SFileMenuOption FindFileSelectOption(CGuiFrame* frame, int idx);
@ -265,7 +265,7 @@ public:
} }
void DoCancel(CGuiTableGroup* caller); void DoCancel(CGuiTableGroup* caller);
void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoSelectionChange(CGuiTableGroup* caller, int oldSel);
void DoAdvance(CGuiTableGroup* caller); void DoAdvance(CGuiTableGroup* caller);
}; };
@ -299,7 +299,7 @@ public:
void HandleActiveChange(CGuiTableGroup* active); void HandleActiveChange(CGuiTableGroup* active);
void DoCancel(CGuiTableGroup* caller); void DoCancel(CGuiTableGroup* caller);
void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoSelectionChange(CGuiTableGroup* caller, int oldSel);
void DoAdvance(CGuiTableGroup* caller); void DoAdvance(CGuiTableGroup* caller);
}; };
@ -361,7 +361,7 @@ public:
void DoSliderChange(CGuiSliderGroup* caller, float value); void DoSliderChange(CGuiSliderGroup* caller, float value);
void DoMenuCancel(CGuiTableGroup* caller); void DoMenuCancel(CGuiTableGroup* caller);
void DoMenuSelectionChange(CGuiTableGroup* caller, int sel); void DoMenuSelectionChange(CGuiTableGroup* caller, int oldSel);
void DoLeftMenuAdvance(CGuiTableGroup* caller); void DoLeftMenuAdvance(CGuiTableGroup* caller);
void DeactivateRightMenu(); void DeactivateRightMenu();

View File

@ -83,12 +83,12 @@ CInventoryScreen::CInventoryScreen(const CStateManager& mgr, CGuiFrame& frame, c
bool CInventoryScreen::InputDisabled() const bool CInventoryScreen::InputDisabled() const
{ {
return std::fabs(x19c_samusDoll->GetViewInterpolation()) > 0 || x1a8_ == 1; return std::fabs(x19c_samusDoll->GetViewInterpolation()) > 0 || x1a8_state == EState::Leaving;
} }
void CInventoryScreen::TransitioningAway() void CInventoryScreen::TransitioningAway()
{ {
x1a8_ = 1; x1a8_state = EState::Leaving;
} }
void CInventoryScreen::Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue) void CInventoryScreen::Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue)
@ -98,21 +98,21 @@ void CInventoryScreen::Update(float dt, CRandom16& rand, CArchitectureQueue& arc
if (x10_mode == EMode::TextScroll) if (x10_mode == EMode::TextScroll)
{ {
if (x1ad_textBodyVisible) if (x1ad_textViewing)
x1a4_textBodyAlpha = std::min(4.f * dt + x1a4_textBodyAlpha, 1.f); x1a4_textBodyAlpha = std::min(4.f * dt + x1a4_textBodyAlpha, 1.f);
else else
x1a4_textBodyAlpha = std::max(0.f, x1a4_textBodyAlpha - 4.f * dt); x1a4_textBodyAlpha = std::max(0.f, x1a4_textBodyAlpha - 4.f * dt);
x174_textpane_body->SetColor(zeus::CColor(1.f, x1a4_textBodyAlpha)); x174_textpane_body->SetColor(zeus::CColor(1.f, x1a4_textBodyAlpha));
x180_basewidget_yicon->SetColor(zeus::CColor(1.f, 1.f - x1a4_textBodyAlpha)); x180_basewidget_yicon->SetColor(zeus::CColor(1.f, 1.f - x1a4_textBodyAlpha));
if (x1a4_textBodyAlpha == 0.f && x1a8_ == 0) if (x1a4_textBodyAlpha == 0.f && x1a8_state == EState::Active)
ChangeMode(EMode::RightTable); ChangeMode(EMode::RightTable);
} }
x19c_samusDoll->SetInMorphball( x19c_samusDoll->SetInMorphball(
x70_tablegroup_leftlog->GetUserSelection() == 1 && x10_mode != EMode::LeftTable); x70_tablegroup_leftlog->GetUserSelection() == 1 && x10_mode != EMode::LeftTable);
UpdateSamusDollPulses(); UpdateSamusDollPulses();
if (x1a8_ == 1 && x1a4_textBodyAlpha == 0.f) if (x1a8_state == EState::Leaving && x1a4_textBodyAlpha == 0.f)
x1a8_ = 2; x1a8_state = EState::Inactive;
} }
void CInventoryScreen::Touch() void CInventoryScreen::Touch()
@ -124,7 +124,7 @@ void CInventoryScreen::Touch()
void CInventoryScreen::ProcessControllerInput(const CFinalInput& input) void CInventoryScreen::ProcessControllerInput(const CFinalInput& input)
{ {
float viewInterp = x19c_samusDoll->GetViewInterpolation(); float viewInterp = x19c_samusDoll->GetViewInterpolation();
if (x1a8_ == 2 || (viewInterp != 0.f && viewInterp != 1.f)) if (x1a8_state == EState::Inactive || (viewInterp != 0.f && viewInterp != 1.f))
return; return;
float absViewInterp = std::fabs(viewInterp); float absViewInterp = std::fabs(viewInterp);
@ -168,7 +168,7 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input)
} }
else else
{ {
x1ad_textBodyVisible = false; x1ad_textViewing = false;
if (x10_mode == EMode::TextScroll) if (x10_mode == EMode::TextScroll)
{ {
int oldPage = x174_textpane_body->TextSupport().GetPageCounter(); int oldPage = x174_textpane_body->TextSupport().GetPageCounter();
@ -192,6 +192,9 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input)
x198_29_pulseTextArrowBottom = false; x198_29_pulseTextArrowBottom = false;
x198_28_pulseTextArrowTop = false; x198_28_pulseTextArrowTop = false;
} }
if (!x1ac_textLeaveRequested)
x1ac_textLeaveRequested = input.PB() || (input.PA() && lastPage);
x1ad_textViewing = !x1ac_textLeaveRequested;
} }
else else
{ {
@ -199,8 +202,8 @@ void CInventoryScreen::ProcessControllerInput(const CFinalInput& input)
x198_28_pulseTextArrowTop = false; x198_28_pulseTextArrowTop = false;
} }
if (x1a8_) if (x1a8_state != EState::Active)
x1ad_textBodyVisible = false; x1ad_textViewing = false;
CPauseScreenBase::ProcessControllerInput(input); CPauseScreenBase::ProcessControllerInput(input);
} }
@ -268,10 +271,12 @@ void CInventoryScreen::VActivate()
x180_basewidget_yicon->SetVisibility(true, ETraversalMode::Children); x180_basewidget_yicon->SetVisibility(true, ETraversalMode::Children);
} }
void CInventoryScreen::RightTableSelectionChanged(int selBegin, int selEnd) {} void CInventoryScreen::RightTableSelectionChanged(int oldSel, int newSel) {}
void CInventoryScreen::UpdateTextBody() void CInventoryScreen::UpdateTextBody()
{ {
x1ac_textLeaveRequested = false;
const SInventoryItem& sel = InventoryRegistry[x70_tablegroup_leftlog->GetUserSelection()].second[x1c_rightSel]; const SInventoryItem& sel = InventoryRegistry[x70_tablegroup_leftlog->GetUserSelection()].second[x1c_rightSel];
std::u16string entryText = xc_pauseStrg.GetString(sel.entryStrIdx); std::u16string entryText = xc_pauseStrg.GetString(sel.entryStrIdx);
@ -292,7 +297,7 @@ void CInventoryScreen::ChangedMode(EMode oldMode)
{ {
if (x10_mode == EMode::TextScroll) if (x10_mode == EMode::TextScroll)
{ {
x1ad_textBodyVisible = true; x1ad_textViewing = true;
UpdateTextBody(); UpdateTextBody();
} }
} }

View File

@ -14,12 +14,19 @@ namespace MP1
class CInventoryScreen : public CPauseScreenBase class CInventoryScreen : public CPauseScreenBase
{ {
enum class EState
{
Active,
Leaving,
Inactive
};
std::unique_ptr<CSamusDoll> x19c_samusDoll; std::unique_ptr<CSamusDoll> x19c_samusDoll;
float x1a0_ = 0.f; float x1a0_ = 0.f;
float x1a4_textBodyAlpha = 0.f; float x1a4_textBodyAlpha = 0.f;
u32 x1a8_ = 0; EState x1a8_state = EState::Active;
bool x1ac_ = false; bool x1ac_textLeaveRequested = false;
bool x1ad_textBodyVisible; bool x1ad_textViewing;
void UpdateSamusDollPulses(); void UpdateSamusDollPulses();
bool HasLeftInventoryItem(int idx) const; bool HasLeftInventoryItem(int idx) const;
@ -39,7 +46,7 @@ public:
float GetCameraYBias() const; float GetCameraYBias() const;
bool VReady() const; bool VReady() const;
void VActivate(); void VActivate();
void RightTableSelectionChanged(int selBegin, int selEnd); void RightTableSelectionChanged(int oldSel, int newSel);
void ChangedMode(EMode oldMode); void ChangedMode(EMode oldMode);
void UpdateRightTable(); void UpdateRightTable();
bool ShouldLeftTableAdvance() const; bool ShouldLeftTableAdvance() const;

View File

@ -425,7 +425,7 @@ void CLogBookScreen::VActivate()
x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(false); x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(false);
} }
void CLogBookScreen::RightTableSelectionChanged(int selBegin, int selEnd) void CLogBookScreen::RightTableSelectionChanged(int oldSel, int newSel)
{ {
UpdateRightTitles(); UpdateRightTitles();
} }

View File

@ -61,7 +61,7 @@ public:
void Draw(float transInterp, float totalAlpha, float yOff); void Draw(float transInterp, float totalAlpha, float yOff);
bool VReady() const; bool VReady() const;
void VActivate(); void VActivate();
void RightTableSelectionChanged(int selBegin, int selEnd); void RightTableSelectionChanged(int oldSel, int newSel);
void ChangedMode(EMode oldMode); void ChangedMode(EMode oldMode);
void UpdateRightTable(); void UpdateRightTable();
bool ShouldLeftTableAdvance() const; bool ShouldLeftTableAdvance() const;

View File

@ -80,7 +80,7 @@ void COptionsScreen::OnSliderChanged(CGuiSliderGroup* caller, float val)
CGameOptions::SetOption(opt, caller->GetGurVal()); CGameOptions::SetOption(opt, caller->GetGurVal());
} }
void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int sel) void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int oldSel)
{ {
if (x10_mode != EMode::RightTable) if (x10_mode != EMode::RightTable)
return; return;
@ -225,7 +225,7 @@ void COptionsScreen::VActivate()
std::bind(&COptionsScreen::OnEnumChanged, this, std::placeholders::_1, std::placeholders::_2)); std::bind(&COptionsScreen::OnEnumChanged, this, std::placeholders::_1, std::placeholders::_2));
} }
void COptionsScreen::RightTableSelectionChanged(int selBegin, int selEnd) void COptionsScreen::RightTableSelectionChanged(int oldSel, int newSel)
{ {
UpdateOptionView(); UpdateOptionView();
} }

View File

@ -21,7 +21,7 @@ class COptionsScreen : public CPauseScreenBase
void UpdateOptionView(); void UpdateOptionView();
void ResetOptionWidgetVisibility(); void ResetOptionWidgetVisibility();
void OnSliderChanged(CGuiSliderGroup* caller, float val); void OnSliderChanged(CGuiSliderGroup* caller, float val);
void OnEnumChanged(CGuiTableGroup* caller, int sel); void OnEnumChanged(CGuiTableGroup* caller, int oldSel);
public: public:
COptionsScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg); COptionsScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg);
@ -34,7 +34,7 @@ public:
void Draw(float transInterp, float totalAlpha, float yOff); void Draw(float transInterp, float totalAlpha, float yOff);
bool VReady() const; bool VReady() const;
void VActivate(); void VActivate();
void RightTableSelectionChanged(int selBegin, int selEnd); void RightTableSelectionChanged(int oldSel, int newSel);
void ChangedMode(EMode oldMode); void ChangedMode(EMode oldMode);
void UpdateRightTable(); void UpdateRightTable();
bool ShouldLeftTableAdvance() const; bool ShouldLeftTableAdvance() const;

View File

@ -326,10 +326,10 @@ void CPauseScreenBase::UpdateRightTable()
UpdateSideTable(x84_tablegroup_rightlog); UpdateSideTable(x84_tablegroup_rightlog);
} }
void CPauseScreenBase::SetRightTableSelection(int begin, int end) void CPauseScreenBase::SetRightTableSelection(int oldSel, int newSel)
{ {
int oldRightSel = x1c_rightSel; int oldRightSel = x1c_rightSel;
x1c_rightSel = zeus::clamp(end, x1c_rightSel + (end - begin), int(GetRightTableCount()) - 1); x1c_rightSel = zeus::clamp(0, x1c_rightSel + (newSel - oldSel), int(GetRightTableCount()) - 1);
if (oldRightSel != x1c_rightSel) if (oldRightSel != x1c_rightSel)
CSfxManager::SfxStart(1436, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1436, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
@ -340,7 +340,7 @@ void CPauseScreenBase::SetRightTableSelection(int begin, int end)
x84_tablegroup_rightlog->SetUserSelection(x1c_rightSel + 1 - x18_firstViewRightSel); x84_tablegroup_rightlog->SetUserSelection(x1c_rightSel + 1 - x18_firstViewRightSel);
UpdateSideTable(x84_tablegroup_rightlog); UpdateSideTable(x84_tablegroup_rightlog);
RightTableSelectionChanged(begin, end); RightTableSelectionChanged(oldSel, newSel);
} }
void CPauseScreenBase::OnLeftTableAdvance(CGuiTableGroup* caller) void CPauseScreenBase::OnLeftTableAdvance(CGuiTableGroup* caller)
@ -362,7 +362,7 @@ void CPauseScreenBase::OnRightTableAdvance(CGuiTableGroup* caller)
} }
} }
void CPauseScreenBase::OnTableSelectionChange(CGuiTableGroup* caller, int sel) void CPauseScreenBase::OnTableSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
UpdateSideTable(caller); UpdateSideTable(caller);
if (x70_tablegroup_leftlog == caller) if (x70_tablegroup_leftlog == caller)
@ -372,7 +372,7 @@ void CPauseScreenBase::OnTableSelectionChange(CGuiTableGroup* caller, int sel)
} }
else else
{ {
SetRightTableSelection(sel, x84_tablegroup_rightlog->GetUserSelection()); SetRightTableSelection(oldSel, x84_tablegroup_rightlog->GetUserSelection());
} }
} }

View File

@ -94,11 +94,11 @@ protected:
void InitializeFrameGlue(); void InitializeFrameGlue();
void ChangeMode(EMode mode); void ChangeMode(EMode mode);
void UpdateSideTable(CGuiTableGroup* table); void UpdateSideTable(CGuiTableGroup* table);
void SetRightTableSelection(int selBegin, int selEnd); void SetRightTableSelection(int oldSel, int newSel);
void OnLeftTableAdvance(CGuiTableGroup* caller); void OnLeftTableAdvance(CGuiTableGroup* caller);
void OnRightTableAdvance(CGuiTableGroup* caller); void OnRightTableAdvance(CGuiTableGroup* caller);
void OnTableSelectionChange(CGuiTableGroup* caller, int sel); void OnTableSelectionChange(CGuiTableGroup* caller, int oldSel);
void OnRightTableCancel(CGuiTableGroup* caller); void OnRightTableCancel(CGuiTableGroup* caller);
public: public:
@ -122,15 +122,15 @@ public:
virtual float GetCameraYBias() const { return 0.f; } virtual float GetCameraYBias() const { return 0.f; }
virtual bool VReady() const=0; virtual bool VReady() const=0;
virtual void VActivate()=0; virtual void VActivate()=0;
virtual void RightTableSelectionChanged(int selBegin, int selEnd) {} virtual void RightTableSelectionChanged(int oldSel, int newSel) {}
virtual void ChangedMode(EMode oldMode) {} virtual void ChangedMode(EMode oldMode) {}
virtual void UpdateRightTable(); virtual void UpdateRightTable();
virtual bool ShouldLeftTableAdvance() const { return true; } virtual bool ShouldLeftTableAdvance() const { return true; }
virtual bool ShouldRightTableAdvance() const { return true; } virtual bool ShouldRightTableAdvance() const { return true; }
virtual u32 GetRightTableCount() const=0; virtual u32 GetRightTableCount() const=0;
virtual bool IsRightLogDynamic() const { return false; } virtual bool IsRightLogDynamic() const { return false; }
virtual void UpdateRightLogColors(bool active, const zeus::CColor& activeColor, zeus::CColor& inactiveColor) {} virtual void UpdateRightLogColors(bool active, const zeus::CColor& activeColor, const zeus::CColor& inactiveColor) {}
virtual void UpdateRightLogHighlight(bool active, int idx, const zeus::CColor& activeColor, zeus::CColor& inactiveColor) {} virtual void UpdateRightLogHighlight(bool active, int idx, const zeus::CColor& activeColor, const zeus::CColor& inactiveColor) {}
}; };
} }

View File

@ -56,7 +56,7 @@ void CQuitGameScreen::FinishedLoading()
SetColors(); SetColors();
} }
void CQuitGameScreen::DoSelectionChange(CGuiTableGroup* caller, int userSel) void CQuitGameScreen::DoSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
SetColors(); SetColors();
CSfxManager::SfxStart(1424, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(1424, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);

View File

@ -42,7 +42,7 @@ class CQuitGameScreen
void SetColors(); void SetColors();
public: public:
void FinishedLoading(); void FinishedLoading();
void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoSelectionChange(CGuiTableGroup* caller, int oldSel);
void DoAdvance(CGuiTableGroup* caller); void DoAdvance(CGuiTableGroup* caller);
EQuitAction Update(float dt); EQuitAction Update(float dt);
void Draw(); void Draw();

View File

@ -608,7 +608,7 @@ void CSaveGameScreen::DoAdvance(CGuiTableGroup* caller)
CSfxManager::SfxStart(sfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(sfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
} }
void CSaveGameScreen::DoSelectionChange(CGuiTableGroup* caller, int userSel) void CSaveGameScreen::DoSelectionChange(CGuiTableGroup* caller, int oldSel)
{ {
SetUIColors(); SetUIColors();
CSfxManager::SfxStart(x88_navMoveSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); CSfxManager::SfxStart(x88_navMoveSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);

View File

@ -107,7 +107,7 @@ public:
void Draw() const; void Draw() const;
void DoAdvance(CGuiTableGroup* caller); void DoAdvance(CGuiTableGroup* caller);
void DoSelectionChange(CGuiTableGroup* caller, int userSel); void DoSelectionChange(CGuiTableGroup* caller, int oldSel);
void ProcessUserInput(const CFinalInput& input); void ProcessUserInput(const CFinalInput& input);
void StartGame(int idx); void StartGame(int idx);

2
hecl

@ -1 +1 @@
Subproject commit 1e5fe44f759a77693a6ffba0d5d478bf1def02e6 Subproject commit d2cfde52c3bd591e5b39e7375a1c185f9ea39aa7

@ -1 +1 @@
Subproject commit 857c8f425927436b82541a75c234a9ea41256075 Subproject commit be725e27ceb722649ef9e959845affde3c86a12f