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

View File

@ -129,7 +129,7 @@ private:
{ {
bool x220_24_animating : 1; bool x220_24_animating : 1;
bool x220_25_loop : 1; bool x220_25_loop : 1;
bool x220_26_ : 1; bool x220_26_aligningPos : 1;
bool x220_27_ : 1; bool x220_27_ : 1;
bool x220_28_ : 1; bool x220_28_ : 1;
bool x220_29_animationJustStarted : 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, CAnimSourceReader::CAnimSourceReader(const TSubAnimTypeToken<CAnimSource>& source,
const CCharAnimTime& time) const CCharAnimTime& time)
: CAnimSourceReaderBase(std::make_unique<CAnimSourceInfo>(source), CCharAnimTime()), : CAnimSourceReaderBase(std::make_unique<CAnimSourceInfo>(source), {}),
x54_source(source), x64_steadyStateInfo(false, source->GetDuration(), x54_source(source), x64_steadyStateInfo(false, source->GetDuration(),
source->GetOffset(source->GetRootBoneId(), time)) source->GetOffset(source->GetRootBoneId(), time))
{ {

View File

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

View File

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

View File

@ -31,6 +31,8 @@ public:
CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const; CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const;
u32 GetNumChildren() const; u32 GetNumChildren() const;
std::shared_ptr<IAnimReader> GetBestUnblendedChild() 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, CAnimTreeTransition::CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur, const std::weak_ptr<CAnimTreeNode>& b, const CCharAnimTime& transDur,
const CCharAnimTime& timeInTrans, bool runA, bool loopA, int flags, 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), : 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::static_pointer_cast<CAnimTreeNode>(
std::shared_ptr<IAnimReader>(x18_b->Clone())), std::shared_ptr<IAnimReader>(x18_b->Clone())),
x24_transDur, x2c_timeInTrans, x34_runA, 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() 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(); 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) SAdvancementResults CAnimTreeTransition::AdvanceViewForTransitionalPeriod(const CCharAnimTime& time)
{ {
IncAdvancementDepth(); IncAdvancementDepth();
@ -85,9 +92,9 @@ SAdvancementResults CAnimTreeTransition::AdvanceViewForTransitionalPeriod(const
if (ShouldCullTree()) if (ShouldCullTree())
{ {
if (newWeight < 0.5f) if (newWeight < 0.5f)
x20_25_ = 1; x20_25_cullSelector = 1;
else else
x20_25_ = 2; x20_25_cullSelector = 2;
} }
if (x1c_flags & 0x1) if (x1c_flags & 0x1)
@ -116,12 +123,12 @@ SAdvancementResults CAnimTreeTransition::VAdvanceView(const CCharAnimTime& time)
x14_a->VAdvanceView(time); x14_a->VAdvanceView(time);
DecAdvancementDepth(); DecAdvancementDepth();
if (ShouldCullTree()) if (ShouldCullTree())
x20_25_ = 1; x20_25_cullSelector = 1;
return {}; return {};
} }
if (!x36_) if (!x36_initialized)
x36_ = true; x36_initialized = true;
if (x2c_timeInTrans + time < x24_transDur) if (x2c_timeInTrans + time < x24_transDur)
{ {

View File

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

View File

@ -1,4 +1,6 @@
#include "CAnimTreeTweenBase.hpp" #include "CAnimTreeTweenBase.hpp"
#include "CSegStatementSet.hpp"
#include "CSegIdList.hpp"
namespace urde namespace urde
{ {
@ -10,7 +12,7 @@ CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1, const std::weak_ptr<CAnimTreeNod
: CAnimTreeDoubleChild(a, b, name), x1c_flags(flags) : CAnimTreeDoubleChild(a, b, name), x1c_flags(flags)
{ {
x20_24_b1 = b1; x20_24_b1 = b1;
x20_25_ = 0; x20_25_cullSelector = 0;
} }
void CAnimTreeTweenBase::VGetWeightedReaders( void CAnimTreeTweenBase::VGetWeightedReaders(
@ -21,16 +23,86 @@ void CAnimTreeTweenBase::VGetWeightedReaders(
x18_b->VGetWeightedReaders(out, 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
{
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, void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut,
const CCharAnimTime& time) const 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 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 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() std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTweenBase::VSimplified()
{ {
if (x20_25_ == 0) if (x20_25_cullSelector == 0)
{ {
auto simpA = x14_a->Simplified(); auto simpA = x14_a->Simplified();
auto simpB = x18_b->Simplified(); auto simpB = x18_b->Simplified();
@ -72,7 +144,7 @@ std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTweenBase::VS
} }
else else
{ {
auto tmp = (x20_25_ == 1) ? x18_b : x14_a; auto tmp = (x20_25_cullSelector == 1) ? x18_b : x14_a;
auto tmpUnblended = tmp->GetBestUnblendedChild(); auto tmpUnblended = tmp->GetBestUnblendedChild();
if (!tmpUnblended) if (!tmpUnblended)
return {tmp->Clone()}; return {tmp->Clone()};

View File

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

View File

@ -350,7 +350,7 @@ CSegIdToIndexConverter::CSegIdToIndexConverter(const CFBStreamedAnimReaderTotals
} }
CFBStreamedAnimReader::CFBStreamedAnimReader(const TSubAnimTypeToken<CFBStreamedCompression>& source, const CCharAnimTime& time) 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()), x64_steadyStateInfo(source->IsLooping(), source->GetAnimationDuration(), source->GetRootOffset()),
x7c_totals(source), x104_bitstreamData(source->GetBitstreamPointer()), x108_bitLoader(x104_bitstreamData), 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) 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 bool CGuiTableGroup::IsWorkerSelectable(int idx) const
{ {
CGuiWidget* widget = GetWorkerWidget(idx); if (CGuiWidget* widget = GetWorkerWidget(idx))
if (widget)
return widget->GetIsSelectable(); return widget->GetIsSelectable();
return false; return false;
} }

View File

@ -8,13 +8,18 @@ static logvisor::Module Log("urde::CGuiWidget");
CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms) CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms)
: x70_selfId(parms.x6_selfId), x72_parentId(parms.x8_parentId), : x70_selfId(parms.x6_selfId), x72_parentId(parms.x8_parentId),
xa4_color(parms.x10_color), xa8_color2(parms.x10_color), xa4_color(parms.x10_color), xa8_color2(parms.x10_color),
xac_drawFlags(parms.x14_drawFlags), xb0_frame(parms.x0_frame), 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)
{ {
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); RecalcWidgetColor(ETraversalMode::Single);
} }

View File

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

View File

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

View File

@ -70,6 +70,17 @@ void CPauseScreenBase::InitializeFrameGlue()
x48_tableDoubleStart = x190_tablegroup_double->GetIdlePosition(); x48_tableDoubleStart = x190_tablegroup_double->GetIdlePosition();
x54_tableTripleStart = x194_tablegroup_triple->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) 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)))); 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*>( x14_tablegroup_quitgame = static_cast<CGuiTableGroup*>(
x10_loadedFrame->FindWidget("tablegroup_quitgame")); x10_loadedFrame->FindWidget("tablegroup_quitgame"));
x14_tablegroup_quitgame->SetVertical(false);
x14_tablegroup_quitgame->SetMenuAdvanceCallback( x14_tablegroup_quitgame->SetMenuAdvanceCallback(
std::bind(&CQuitGameScreen::DoAdvance, this, std::placeholders::_1)); std::bind(&CQuitGameScreen::DoAdvance, this, std::placeholders::_1));
x14_tablegroup_quitgame->SetMenuSelectionChangeCallback( x14_tablegroup_quitgame->SetMenuSelectionChangeCallback(
@ -88,7 +89,7 @@ EQuitAction CQuitGameScreen::Update(float dt)
void CQuitGameScreen::Draw() void CQuitGameScreen::Draw()
{ {
if (x0_type == EQuitType::QuitGame) if (x0_type == EQuitType::QuitGame)
m_blackScreen->draw(zeus::CColor::skBlack); m_blackScreen->draw(zeus::CColor(0.f, 0.5f));
if (x10_loadedFrame) if (x10_loadedFrame)
x10_loadedFrame->Draw(CGuiWidgetDrawParms{1.f, 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, CSamusDoll::CSamusDoll(const CDependencyGroup& suitDgrp, const CDependencyGroup& ballDgrp,
CPlayerState::EPlayerSuit suit, CPlayerState::EBeamId beam, CPlayerState::EPlayerSuit suit, CPlayerState::EBeamId beam,
bool hasSpiderBall, bool hasGrappleBeam) 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); x70_fixedRot.rotateZ(M_PIF);
x90_userInterpRot = xb0_userRot = x70_fixedRot; x90_userInterpRot = xb0_userRot = x70_fixedRot;
@ -313,7 +314,7 @@ void CSamusDoll::Update(float dt, CRandom16& rand)
SetupLights(); SetupLights();
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_xf.origin); x22c_ballInnerGlowGen->SetGlobalTranslation(x10_ballXf.origin);
x22c_ballInnerGlowGen->Update(dt); x22c_ballInnerGlowGen->Update(dt);
if (x238_ballTransitionFlashGen) if (x238_ballTransitionFlashGen)
@ -322,7 +323,7 @@ void CSamusDoll::Update(float dt, CRandom16& rand)
x238_ballTransitionFlashGen.reset(); x238_ballTransitionFlashGen.reset();
if (x238_ballTransitionFlashGen) if (x238_ballTransitionFlashGen)
{ {
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_xf.origin); x22c_ballInnerGlowGen->SetGlobalTranslation(x10_ballXf.origin);
x22c_ballInnerGlowGen->Update(dt); x22c_ballInnerGlowGen->Update(dt);
} }
} }
@ -470,17 +471,17 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
flags.x1_matSetIdx = x1e0_ballMatIdx; flags.x1_matSetIdx = x1e0_ballMatIdx;
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly; flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
flags.x4_color = zeus::CColor::skWhite; 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.m_extendedShader = EExtendedShader::ForcedAlpha;
flags.x4_color = zeus::CColor::skWhite; flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = alpha * ballAlpha; 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.m_extendedShader = EExtendedShader::ForcedAdditive;
flags.x4_color = zeus::CColor::skWhite; flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = x6c_ballPulseFactor * alpha * ballAlpha * itemPulse; 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) if (x4d_selectedMorphball && ballT > 0.5f)
@ -507,14 +508,14 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
flags.m_extendedShader = EExtendedShader::ForcedAdditive; flags.m_extendedShader = EExtendedShader::ForcedAdditive;
flags.x1_matSetIdx = x1e0_ballMatIdx; flags.x1_matSetIdx = x1e0_ballMatIdx;
flags.x4_color = zeus::CColor(1.f, spinAlpha * alpha); 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); x24c_actorLights.get(), flags);
} }
} }
if (x270_24_hasSpiderBall) if (x270_24_hasSpiderBall)
{ {
CGraphics::SetModelMatrix(x10_xf); CGraphics::SetModelMatrix(x10_ballXf);
CModelFlags flags = {}; CModelFlags flags = {};
flags.x1_matSetIdx = x1e4_glassMatIdx; flags.x1_matSetIdx = x1e4_glassMatIdx;
x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights); x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights);
@ -551,17 +552,17 @@ void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
flags.x1_matSetIdx = x1e0_ballMatIdx; flags.x1_matSetIdx = x1e0_ballMatIdx;
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly; flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
flags.x4_color = zeus::CColor::skWhite; 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.m_extendedShader = EExtendedShader::ForcedAlpha;
flags.x4_color = zeus::CColor::skWhite; flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = alpha; 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.m_extendedShader = EExtendedShader::ForcedAdditive;
flags.x4_color = zeus::CColor::skWhite; flags.x4_color = zeus::CColor::skWhite;
flags.x4_color.a = x6c_ballPulseFactor * alpha * itemPulse; 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]; const u8* c = CMorphBall::BallGlowColors[x1e8_ballGlowColorIdx];
zeus::CColor color = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, alpha}; 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) if (x270_24_hasSpiderBall)
{ {
CGraphics::SetModelMatrix(x10_xf); CGraphics::SetModelMatrix(x10_ballXf);
CModelFlags flags = {}; CModelFlags flags = {};
flags.x1_matSetIdx = x1e4_glassMatIdx; flags.x1_matSetIdx = x1e4_glassMatIdx;
x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights); x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights);

View File

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

View File

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

View File

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

View File

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

2
hecl

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

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