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

View File

@ -30,12 +30,6 @@ std::shared_ptr<IAnimReader> CAnimTreeAnimReaderContainer::VGetBestUnblendedChil
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)
{
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);
}
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeAnimReaderContainer::VSimplified()
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeAnimReaderContainer::VSimplified()
{
return {};
}
@ -135,4 +129,10 @@ SAdvancementResults CAnimTreeAnimReaderContainer::VGetAdvancementResults(const C
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;
u32 VGetNumChildren() 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);
CCharAnimTime VGetTimeRemaining() const;
@ -37,7 +37,7 @@ public:
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) 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);
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)
{
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,
@ -110,8 +157,11 @@ std::shared_ptr<IAnimReader> CAnimTreeDoubleChild::VGetBestUnblendedChild() cons
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:
class CDoubleChildAdvancementResult
{
CCharAnimTime x0_;
SAdvancementDeltas x8_;
SAdvancementDeltas x24_;
CCharAnimTime x0_trueAdvancement;
SAdvancementDeltas x8_leftDeltas;
SAdvancementDeltas x24_rightDeltas;
public:
CDoubleChildAdvancementResult(const CCharAnimTime&, const SAdvancementDeltas&, const SAdvancementDeltas);
void GetLeftAdvancementDeltas() const;
void GetRightAdvancementDeltas() const;
void GetTrueAdvancement() const;
CDoubleChildAdvancementResult(const CCharAnimTime& trueAdvancement, const SAdvancementDeltas& leftDeltas,
const SAdvancementDeltas& rightDeltas)
: x0_trueAdvancement(trueAdvancement), x8_leftDeltas(leftDeltas), x24_rightDeltas(rightDeltas) {}
const SAdvancementDeltas& GetLeftAdvancementDeltas() const { return x8_leftDeltas; }
const SAdvancementDeltas& GetRightAdvancementDeltas() const { return x24_rightDeltas; }
const CCharAnimTime& GetTrueAdvancement() const { return x0_trueAdvancement; }
};
protected:
std::shared_ptr<CAnimTreeNode> x14_a;
std::shared_ptr<CAnimTreeNode> x18_b;
CDoubleChildAdvancementResult AdvanceViewBothChildren(const CCharAnimTime& time, bool runLeft, bool loopLeft);
public:
CAnimTreeDoubleChild(const std::weak_ptr<CAnimTreeNode>& a, const std::weak_ptr<CAnimTreeNode>& b,
std::string_view name);
@ -42,10 +46,8 @@ public:
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
u32 VGetNumChildren() 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;
float GetRightChildWeight() const { return VGetRightChildWeight(); }

View File

@ -13,12 +13,20 @@ protected:
public:
CAnimTreeNode(std::string_view name) : x4_name(name) {}
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 CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const=0;
virtual u32 VGetNumChildren() 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;
u32 GetNumChildren() const;

View File

@ -38,12 +38,6 @@ std::shared_ptr<IAnimReader> CAnimTreeSequence::VGetBestUnblendedChild() const
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)
{
return {};

View File

@ -30,7 +30,6 @@ public:
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() 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);
CCharAnimTime VGetTimeRemaining() const;

View File

@ -31,6 +31,8 @@ public:
SAdvancementResults VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const;
u32 Depth() 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);
}
std::pair<std::unique_ptr<IAnimReader>, bool> CAnimTreeTimeScale::VSimplified()
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTimeScale::VSimplified()
{
return {};
}

View File

@ -19,7 +19,7 @@ public:
CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const;
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,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& time1,
const CCharAnimTime& time2, bool b2, bool b3, int flags,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur,
const CCharAnimTime& timeInTrans, bool runA, bool loopA, int flags,
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,
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)
: 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 time = x24_ * x2c_;
CCharAnimTime bTimeRem = x18_b->VGetTimeRemaining();
if (time < bTimeRem)
return bTimeRem;
return time;
CCharAnimTime transTimeRem = x24_transDur - x2c_timeInTrans;
CCharAnimTime rightTimeRem = x18_b->VGetTimeRemaining();
return (rightTimeRem < transTimeRem) ? transTimeRem : rightTimeRem;
}
CSteadyStateAnimInfo CAnimTreeTransition::VGetSteadyStateAnimInfo() const
{
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(), x24_, bInfo.GetOffset());
return CSteadyStateAnimInfo(bInfo.IsLooping(), x24_transDur, bInfo.GetOffset());
}
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::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x18_b->Clone())), x24_, x2c_,
x34_, x35_, x1c_flags, x4_name, x36_);
std::shared_ptr<IAnimReader>(x18_b->Clone())),
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)
@ -70,8 +150,8 @@ void CAnimTreeTransition::SetBlendingWeight(float w)
float CAnimTreeTransition::VGetBlendingWeight() const
{
if (x24_.GreaterThanZero())
return (1.f / x24_.GetSeconds()) * x2c_.GetSeconds();
if (x24_transDur.GreaterThanZero())
return x2c_timeInTrans.GetSeconds() / x24_transDur.GetSeconds();
return 0.f;
}
}

View File

@ -10,24 +10,30 @@ namespace urde
class CAnimTreeTransition : public CAnimTreeTweenBase
{
protected:
CCharAnimTime x24_;
CCharAnimTime x2c_;
bool x34_;
bool x35_;
CCharAnimTime x24_transDur;
CCharAnimTime x2c_timeInTrans;
bool x34_runA;
bool x35_loopA;
bool x36_ = false;
SAdvancementResults AdvanceViewForTransitionalPeriod(const CCharAnimTime& time);
public:
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&,
float);
CAnimTreeTransition(bool, const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&,
const CCharAnimTime&, const CCharAnimTime&, bool, bool, int, std::string_view, bool);
CAnimTreeTransition(bool, const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&,
const CCharAnimTime&, bool, int, std::string_view);
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);
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;
CCharAnimTime VGetTimeRemaining() const;
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() 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);
float VGetBlendingWeight() const;
};

View File

@ -7,13 +7,19 @@ s32 CAnimTreeTweenBase::sAdvancementDepth = 0;
CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
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 {}
@ -49,5 +55,29 @@ zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const
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;
protected:
int x1c_flags;
bool x20_31_b1;
bool x20_30_b2 = false;
bool x20_24_b1 : 1;
u8 x20_25_ : 2;
public:
CAnimTreeTweenBase(bool,
const std::weak_ptr<CAnimTreeNode>& a,
@ -24,7 +24,7 @@ public:
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(); }
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
@ -33,9 +33,9 @@ public:
zeus::CVector3f VGetOffset(const CSegId& seg) const;
zeus::CQuaternion VGetRotation(const CSegId& seg) const;
std::pair<std::unique_ptr<IAnimReader>, bool> VSimplified();
bool ShouldCullTree() const { return false; }
std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
static bool ShouldCullTree() { return 3 <= sAdvancementDepth; }
static void IncAdvancementDepth() { sAdvancementDepth++; }
static void DecAdvancementDepth() { sAdvancementDepth--; }
};

View File

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

View File

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

View File

@ -4,6 +4,17 @@
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
IAnimReader::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
{

View File

@ -23,6 +23,9 @@ struct SAdvancementDeltas
{
zeus::CVector3f x0_posDelta;
zeus::CQuaternion xc_rotDelta;
static SAdvancementDeltas Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b,
float oldWeight, float newWeight);
};
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 CCharAnimTime& time) 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 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 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(); }
};

View File

@ -195,10 +195,11 @@ bool CGuiTableGroup::PreDecrement()
void CGuiTableGroup::DoDecrement()
{
int oldSel = xc4_userSelection;
if (!PreDecrement())
return;
if (x104_doMenuSelChange)
x104_doMenuSelChange(this, xc4_userSelection);
x104_doMenuSelChange(this, oldSel);
}
bool CGuiTableGroup::PreIncrement()
@ -234,10 +235,11 @@ bool CGuiTableGroup::PreIncrement()
void CGuiTableGroup::DoIncrement()
{
int oldSel = xc4_userSelection;
if (!PreIncrement())
return;
if (x104_doMenuSelChange)
x104_doMenuSelChange(this, xc4_userSelection);
x104_doMenuSelChange(this, oldSel);
}
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;
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;
inst2->Invoke(rstate, &rbuf);
@ -96,10 +96,13 @@ std::list<CTextRenderBuffer> CTextExecuteBuffer::BuildRenderBufferPages(const ze
InstList::const_iterator pageEnd = it;
{
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;
if (it2 != it)
if (it2 == it)
seekingToPage = false;
if (seekingToPage)
{
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);
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);
}
void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, int userSel)
void CFrontEndUI::SFusionBonusFrame::DoSelectionChange(CGuiTableGroup* caller, int oldSel)
{
if (caller == x28_tablegroup_options)
{
@ -1381,7 +1381,7 @@ void CFrontEndUI::SFrontEndFrame::DoCancel(CGuiTableGroup* caller)
/* 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);
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);
if (x24_tablegroup_leftmenu == caller)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,7 +80,7 @@ void COptionsScreen::OnSliderChanged(CGuiSliderGroup* caller, float val)
CGameOptions::SetOption(opt, caller->GetGurVal());
}
void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int sel)
void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int oldSel)
{
if (x10_mode != EMode::RightTable)
return;
@ -225,7 +225,7 @@ void COptionsScreen::VActivate()
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();
}

View File

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

View File

@ -326,10 +326,10 @@ void CPauseScreenBase::UpdateRightTable()
UpdateSideTable(x84_tablegroup_rightlog);
}
void CPauseScreenBase::SetRightTableSelection(int begin, int end)
void CPauseScreenBase::SetRightTableSelection(int oldSel, int newSel)
{
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)
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);
UpdateSideTable(x84_tablegroup_rightlog);
RightTableSelectionChanged(begin, end);
RightTableSelectionChanged(oldSel, newSel);
}
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);
if (x70_tablegroup_leftlog == caller)
@ -372,7 +372,7 @@ void CPauseScreenBase::OnTableSelectionChange(CGuiTableGroup* caller, int sel)
}
else
{
SetRightTableSelection(sel, x84_tablegroup_rightlog->GetUserSelection());
SetRightTableSelection(oldSel, x84_tablegroup_rightlog->GetUserSelection());
}
}

View File

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

View File

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

View File

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

View File

@ -608,7 +608,7 @@ void CSaveGameScreen::DoAdvance(CGuiTableGroup* caller)
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();
CSfxManager::SfxStart(x88_navMoveSfx, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);

View File

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

2
hecl

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

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