Many CGuiWidget imps

This commit is contained in:
Jack Andersen 2016-03-15 13:23:45 -10:00
parent 5566c5b002
commit b3859c4476
10 changed files with 712 additions and 86 deletions

View File

@ -29,8 +29,8 @@ struct FRME : BigDNA
String<-1> name; String<-1> name;
String<-1> parent; String<-1> parent;
Value<bool> unk1; Value<bool> unk1;
Value<bool> unk2; Value<bool> defaultVisible;
Value<bool> unk3; Value<bool> defaultActive;
Value<bool> unk4; Value<bool> unk4;
Value<atVec4f> color; Value<atVec4f> color;
Value<atUint32> modelDrawFlags; Value<atUint32> modelDrawFlags;

View File

@ -1,11 +1,13 @@
#ifndef __URDE_CGUIANIMBASE_HPP__ #ifndef __URDE_CGUIANIMBASE_HPP__
#define __URDE_CGUIANIMBASE_HPP__ #define __URDE_CGUIANIMBASE_HPP__
#include "RetroTypes.hpp"
#include "CGuiRandomVar.hpp"
namespace urde namespace urde
{ {
class CGuiAnimController; class CGuiAnimController;
class CGuiWidgetDrawParams; class CGuiWidgetDrawParams;
class CGuiRandomVar;
enum class EGuiAnimType enum class EGuiAnimType
{ {
@ -21,17 +23,29 @@ enum class EGuiAnimType
class CGuiAnimBase class CGuiAnimBase
{ {
const CGuiRandomVar& x30_randomVar; friend class CGuiAnimSet;
float x4_ = 0.f;
float x8_ = 0.f;
float xc_;
CGuiRandomVar x10_randomVar;
float x1c_ = 0.f;
bool x20_isDone = false;
s32 x24_ = -1;
bool x28_;
public: public:
virtual ~CGuiAnimBase() = default; virtual ~CGuiAnimBase() = default;
CGuiAnimBase(float, const CGuiRandomVar&, bool); CGuiAnimBase(float fval, const CGuiRandomVar& randVar, bool flag)
: xc_(fval), x10_randomVar(randVar), x28_(flag) {}
float GetFVal() const {return xc_;}
const CGuiRandomVar& GetRandomVar() const {return x10_randomVar;}
virtual void AnimInit(const CGuiAnimController* controller, float); virtual void AnimInit(const CGuiAnimController* controller, float);
virtual void AnimUpdate(CGuiAnimController* controller, float dt); virtual void AnimUpdate(CGuiAnimController* controller, float dt);
virtual void AnimDraw(const CGuiWidgetDrawParams& params) const; virtual void AnimDraw(const CGuiWidgetDrawParams& params) const;
virtual void CalcInitVelocity(const CGuiAnimController* controller); virtual void CalcInitVelocity(const CGuiAnimController* controller);
virtual void GetAnimType(const CGuiAnimController* controller) const; virtual void GetAnimType(const CGuiAnimController* controller) const;
virtual void GetItFinishedLoading() const {return true;} virtual bool GetIsFinishedLoading() const {return true;}
}; };
class CGuiAnimRotation : public CGuiAnimBase class CGuiAnimRotation : public CGuiAnimBase

View File

@ -1,13 +1,174 @@
#include "CGuiAnimController.hpp" #include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp" #include "CGuiLogicalEventTrigger.hpp"
#include "CGuiAnimBase.hpp"
#include "CGuiControllerInfo.hpp"
namespace urde namespace urde
{ {
void CGuiAnimSet::AddAnim(CGuiAnimBase* anim)
{
x0_map[x20_++] = anim;
RecalcTotalTime();
}
void CGuiAnimSet::RecalcTotalTime()
{
x28_totalTime = 0.f;
for (std::pair<const int, CGuiAnimBase*>& anim : x0_map)
{
float num = anim.second->GetRandomVar().GenNum();
if (num < x28_totalTime)
num = x28_totalTime;
else
num += anim.second->GetFVal();
if (num > x28_totalTime)
x28_totalTime = num;
}
}
void CGuiAnimSet::Init(CGuiAnimController* controller, float fval)
{
x19_isDone = false;
x1c_ = false;
for (std::pair<const int, CGuiAnimBase*>& anim : x0_map)
{
x2c_ = 1.f;
anim.second->AnimInit(controller, fval);
}
}
void CGuiAnimSet::Update(CGuiAnimController* controller, bool flag)
{
x19_isDone = true;
for (std::pair<const int, CGuiAnimBase*>& anim : x0_map)
{
anim.second->AnimUpdate(controller, controller->x164_ * x2c_);
if (!anim.second->x20_isDone)
x19_isDone = false;
}
if (x19_isDone && !x1c_)
{
x1c_ = true;
CGuiFuncParm a(intptr_t(controller->x168_widget->GetSelfId()));
CGuiFuncParm b(intptr_t(int(x14_id) + 5));
CGuiFunctionDef fa(0, false, a, b);
CGuiControllerInfo cInfo;
controller->x168_widget->MAF_SendMessage(&fa, &cInfo);
if (x1b_)
controller->x168_widget->SetVisibility(false, ETraversalMode::Children);
}
if (x19_isDone && x1a_ && flag)
Init(controller, 0.f);
}
CGuiAnimController::CGuiAnimController(const CGuiWidget::CGuiWidgetParms& parms, CGuiWidget* widget) CGuiAnimController::CGuiAnimController(const CGuiWidget::CGuiWidgetParms& parms, CGuiWidget* widget)
: CGuiWidget(parms), x168_widget(widget) : CGuiWidget(parms), x168_widget(widget)
{ {
} }
CGuiAnimSet* CGuiAnimController::FindAnimSet(EGuiAnimBehListID id) const
{
if (id < EGuiAnimBehListID::Zero || id >= EGuiAnimBehListID::EGuiAnimBehListIDMAX)
return nullptr;
return xf8_sets[int(id)].get();
}
void CGuiAnimController::AddAnimation(CGuiAnimBase* anim, EGuiAnimBehListID id)
{
CGuiAnimSet* set = FindAnimSet(id);
if (!set)
{
xf8_sets[int(id)] = std::make_unique<CGuiAnimSet>(id);
set = xf8_sets[int(id)].get();
}
set->AddAnim(anim);
}
void CGuiAnimController::ResetListUpdateState()
{
for (std::unique_ptr<CGuiAnimSet>& set : xf8_sets)
set->x18_update = false;
}
void CGuiAnimController::SetListUpdateState(EGuiAnimBehListID id, bool state)
{
CGuiAnimSet* set = FindAnimSet(id);
if (set)
set->x18_update = false;
}
float CGuiAnimController::GetAnimSetLength(EGuiAnimBehListID id) const
{
CGuiAnimSet* set = FindAnimSet(id);
if (set)
return set->x28_totalTime;
return 0.f;
}
void CGuiAnimController::IsAnimsDone(EGuiAnimBehListID id, bool& isDone) const
{
CGuiAnimSet* set = FindAnimSet(id);
if (set)
isDone = set->x19_isDone;
else
isDone = true;
}
void CGuiAnimController::InitTransform(CGuiWidget* widget, EGuiAnimBehListID id, float fval,
bool flag, EGuiAnimInitMode initMode)
{
switch (initMode)
{
case EGuiAnimInitMode::One:
case EGuiAnimInitMode::Three:
FinishAnim();
default: break;
}
x80_transform = widget->GetTransform();
switch (initMode)
{
case EGuiAnimInitMode::Three:
case EGuiAnimInitMode::Two:
x16c_ = xb8_;
break;
case EGuiAnimInitMode::One:
x16c_ = zeus::CColor::skClear;
default: break;
}
if (flag)
ResetListUpdateState();
CGuiAnimSet* set = FindAnimSet(id);
if (set)
{
set->Init(this, fval);
set->x18_update = true;
}
Update(0.f);
}
void CGuiAnimController::FinishAnim()
{
float bup = x164_;
x164_ = 100000.f;
Step(false);
x164_ = bup;
}
void CGuiAnimController::Step(bool flag)
{
x170_ = 0;
for (std::unique_ptr<CGuiAnimSet>& set : xf8_sets)
if (set && set->x18_update)
set->Update(this, flag);
}
} }

View File

@ -9,18 +9,47 @@ namespace urde
class CGuiAnimSet class CGuiAnimSet
{ {
friend class CGuiAnimController;
std::unordered_map<int, CGuiAnimBase*> x0_map;
EGuiAnimBehListID x14_id;
bool x18_update = false;
bool x19_isDone = true;
bool x1a_ = false;
bool x1b_ = false;
bool x1c_ = false;
u32 x20_ = 0;
u32 x24_ = 0;
float x28_totalTime = 0.f;
float x2c_ = 1.f;
public:
CGuiAnimSet(EGuiAnimBehListID id) : x14_id(id) {}
void AddAnim(CGuiAnimBase* anim);
void RecalcTotalTime();
void Init(CGuiAnimController* controller, float fval);
void Update(CGuiAnimController* controller, bool flag);
}; };
class CGuiAnimController : public CGuiWidget class CGuiAnimController : public CGuiWidget
{ {
friend class CGuiAnimSet;
std::array<std::unique_ptr<CGuiAnimSet>, 13> xf8_sets; std::array<std::unique_ptr<CGuiAnimSet>, 13> xf8_sets;
float x164_ = 0.f; float x164_ = 0.f;
CGuiWidget* x168_widget; CGuiWidget* x168_widget;
u32 x16c_ = 0; zeus::CColor x16c_ = zeus::CColor::skClear;
u32 x170_ = 0; u32 x170_ = 0;
public: public:
CGuiAnimController(const CGuiWidget::CGuiWidgetParms& parms, CGuiWidget* widget); CGuiAnimController(const CGuiWidget::CGuiWidgetParms& parms, CGuiWidget* widget);
CGuiAnimSet* FindAnimSet(EGuiAnimBehListID id) const;
void AddAnimation(CGuiAnimBase* anim, EGuiAnimBehListID id);
void ResetListUpdateState();
void SetListUpdateState(EGuiAnimBehListID id, bool state);
float GetAnimSetLength(EGuiAnimBehListID id) const;
void IsAnimsDone(EGuiAnimBehListID id, bool& isDone) const;
void InitTransform(CGuiWidget* widget, EGuiAnimBehListID id, float fval, bool flag,
EGuiAnimInitMode initMode);
void FinishAnim();
void Step(bool flag);
}; };
} }

View File

@ -475,7 +475,7 @@ bool CGuiFrame::Update(float dt)
} }
if (listId != EGuiAnimBehListID::NegOne) if (listId != EGuiAnimBehListID::NegOne)
x44_headWidget->IsAllAnimsDone(listId, something, ETraversalMode::Zero); x44_headWidget->IsAllAnimsDone(listId, something, ETraversalMode::ChildrenAndSiblings);
if (something) if (something)
{ {
@ -484,15 +484,15 @@ bool CGuiFrame::Update(float dt)
case EFrameStates::One: case EFrameStates::One:
{ {
x34_ = x38_; x34_ = x38_;
x44_headWidget->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::NonRecursive); x44_headWidget->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::Single);
x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false, x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false,
EGuiAnimInitMode::Five, ETraversalMode::NonRecursive); EGuiAnimInitMode::Five, ETraversalMode::Single);
CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling()); CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling());
if (camSib) if (camSib)
{ {
camSib->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::Zero); camSib->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::ChildrenAndSiblings);
camSib->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false, camSib->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false,
EGuiAnimInitMode::Five, ETraversalMode::Zero); EGuiAnimInitMode::Five, ETraversalMode::ChildrenAndSiblings);
} }
xbd_flag2 = false; xbd_flag2 = false;
break; break;
@ -548,12 +548,12 @@ void CGuiFrame::Stop(const CGuiFrameTransitionOptions& transOpts, EFrameStates s
else else
{ {
x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true, x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true,
EGuiAnimInitMode::Two, ETraversalMode::NonRecursive); EGuiAnimInitMode::Two, ETraversalMode::Single);
CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling()); CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling());
if (camSib) if (camSib)
{ {
camSib->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true, camSib->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true,
EGuiAnimInitMode::Two, ETraversalMode::Zero); EGuiAnimInitMode::Two, ETraversalMode::ChildrenAndSiblings);
} }
} }
} }
@ -565,18 +565,18 @@ void CGuiFrame::Run(CGuiFrame* frame, const CGuiFrameTransitionOptions& transOpt
x34_ = EFrameStates::One; x34_ = EFrameStates::One;
x38_ = EFrameStates::Two; x38_ = EFrameStates::Two;
float len = 0.f; float len = 0.f;
x4c_camera->GetBranchAnimLen(EGuiAnimBehListID::Zero, len, ETraversalMode::NonRecursive); x4c_camera->GetBranchAnimLen(EGuiAnimBehListID::Zero, len, ETraversalMode::Single);
len += transOpts.xc_ + transOpts.x10_ + transOpts.x14_; len += transOpts.xc_ + transOpts.x10_ + transOpts.x14_;
x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true, x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true,
EGuiAnimInitMode::One, ETraversalMode::NonRecursive); EGuiAnimInitMode::One, ETraversalMode::Single);
CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling()); CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling());
if (camSib) if (camSib)
{ {
camSib->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true, camSib->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true,
EGuiAnimInitMode::One, ETraversalMode::Zero); EGuiAnimInitMode::One, ETraversalMode::ChildrenAndSiblings);
} }
x18_ |= 0x7; x18_ |= 0x7;
x44_headWidget->RegisterEventHandler(ETraversalMode::Zero); x44_headWidget->RegisterEventHandler(ETraversalMode::ChildrenAndSiblings);
} }
void CGuiFrame::Initialize() void CGuiFrame::Initialize()

View File

@ -10,7 +10,7 @@ namespace urde
class CGuiWidgetDrawParms; class CGuiWidgetDrawParms;
class CGuiMessage; class CGuiMessage;
class CGuiFunctionDef; class CGuiFunctionDef;
class CGuiControllerInfo; struct CGuiControllerInfo;
class CGuiObject class CGuiObject
{ {

View File

@ -6,6 +6,7 @@ namespace urde
class CGuiRandomVar class CGuiRandomVar
{ {
public:
enum class Type enum class Type
{ {
Zero, Zero,

View File

@ -25,13 +25,14 @@ CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms)
: x7c_selfId(parms.x6_selfId), x7e_parentId(parms.x8_parentId), : x7c_selfId(parms.x6_selfId), x7e_parentId(parms.x8_parentId),
xbc_color(parms.x10_color), xc0_color2(parms.x10_color), xbc_color(parms.x10_color), xc0_color2(parms.x10_color),
xc4_drawFlags(parms.x14_drawFlags), xc8_frame(parms.x0_frame), xc4_drawFlags(parms.x14_drawFlags), xc8_frame(parms.x0_frame),
xf6_24_pg(parms.xd_g), xf6_25_pd(parms.xa_d), xf6_26_isActive(parms.xb_defaultActive), xf6_24_pg(parms.xd_g), xf6_25_isVisible(parms.xa_defaultVisible),
xf6_27_(true), xf6_28_(false), xf6_29_pf(parms.xc_f), xf6_30_(false), xf6_26_isActive(parms.xb_defaultActive),
xf6_27_(true), xf6_28_eventLock(false), xf6_29_pf(parms.xc_f), xf6_30_(false),
xf6_31_(true), xf7_24_(false), xf7_25_(true) xf6_31_(true), xf7_24_(false), xf7_25_(true)
{ {
if (parms.x4_a) if (parms.x4_a)
EnsureHasAnimController(); EnsureHasAnimController();
RecalcWidgetColor(ETraversalMode::NonRecursive); RecalcWidgetColor(ETraversalMode::Single);
} }
CGuiWidget::CGuiWidgetParms CGuiWidget::CGuiWidgetParms
@ -43,15 +44,15 @@ CGuiWidget::ReadWidgetHeader(CGuiFrame* frame, CInputStream& in, bool flag)
s16 parentId = frame->GetWidgetIdDB().AddWidget(parent); s16 parentId = frame->GetWidgetIdDB().AddWidget(parent);
bool a = in.readBool(); bool a = in.readBool();
bool d = in.readBool(); bool defaultVis = in.readBool();
bool e = in.readBool(); bool defaultActive = in.readBool();
bool f = in.readBool(); bool f = in.readBool();
zeus::CColor color; zeus::CColor color;
color.readRGBABig(in); color.readRGBABig(in);
EGuiModelDrawFlags df = EGuiModelDrawFlags(in.readUint32Big()); EGuiModelDrawFlags df = EGuiModelDrawFlags(in.readUint32Big());
return CGuiWidget::CGuiWidgetParms(frame, a, selfId, parentId, d, e, f, return CGuiWidget::CGuiWidgetParms(frame, a, selfId, parentId, defaultVis, defaultActive,
color, df, true, flag); f, color, df, true, flag);
} }
CGuiWidget* CGuiWidget::Create(CGuiFrame* frame, CInputStream& in, bool flag) CGuiWidget* CGuiWidget::Create(CGuiFrame* frame, CInputStream& in, bool flag)
@ -107,6 +108,128 @@ void CGuiWidget::ParseAnimations(CInputStream& in, const CGuiWidgetParms& parms)
assert(count == 0); assert(count == 0);
} }
std::vector<TResId> CGuiWidget::GetTextureAssets() const
{
return {};
}
std::vector<TResId> CGuiWidget::GetModelAssets() const
{
return {};
}
std::vector<TResId> CGuiWidget::GetFontAssets() const
{
return {};
}
void CGuiWidget::Initialize() {}
void CGuiWidget::Touch() const {}
bool CGuiWidget::GetIsVisible() const
{
return xf6_25_isVisible;
}
bool CGuiWidget::GetIsActive() const
{
return xf6_26_isActive;
}
CGuiTextSupport* CGuiWidget::TextSupport()
{
return nullptr;
}
CGuiTextSupport* CGuiWidget::GetTextSupport() const
{
return nullptr;
}
void CGuiWidget::ModifyRGBA(CGuiWidget* widget)
{
xb8_ += widget->xb8_;
xb4_ = xb8_ + xc0_color2;
}
void CGuiWidget::RecalculateAllRGBA()
{
CGuiWidget* parent = static_cast<CGuiWidget*>(GetParent());
if (parent)
ModifyRGBA(parent);
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->RecalculateAllRGBA();
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->RecalculateAllRGBA();
}
void CGuiWidget::InitializeRGBAFactor()
{
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->InitializeRGBAFactor();
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->InitializeRGBAFactor();
}
bool CGuiWidget::GetIsFinishedLoadingWidgetSpecific() const
{
return true;
}
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* CGuiWidget::FindTriggerList(int id)
{
auto search = xcc_triggerMap.find(id);
if (search == xcc_triggerMap.cend())
return nullptr;
return search->second.get();
}
void CGuiWidget::AddTrigger(std::unique_ptr<CGuiLogicalEventTrigger>&& trigger)
{
int tid = trigger->GetTriggerId();
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* list = FindTriggerList(tid);
if (!list)
{
auto it =
xcc_triggerMap.emplace(std::make_pair(tid,
std::make_unique<std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>>()));
list = it.first->second.get();
}
list->push_back(std::move(trigger));
}
std::vector<std::unique_ptr<CGuiFunctionDef>>* CGuiWidget::FindFunctionDefList(int id)
{
auto search = xe0_functionMap.find(id);
if (search == xe0_functionMap.cend())
return nullptr;
return search->second.get();
}
void CGuiWidget::AddFunctionDef(s32 id, std::unique_ptr<CGuiFunctionDef>&& def)
{
std::vector<std::unique_ptr<CGuiFunctionDef>>* list = FindFunctionDefList(id);
if (!list)
{
auto it =
xe0_functionMap.emplace(std::make_pair(id,
std::make_unique<std::vector<std::unique_ptr<CGuiFunctionDef>>>()));
list = it.first->second.get();
}
list->push_back(std::move(def));
}
void CGuiWidget::SetIdlePosition(const zeus::CVector3f& pos, bool reapply)
{
x80_transform.m_origin = pos;
if (reapply)
ReapplyXform();
}
void CGuiWidget::ReapplyXform() void CGuiWidget::ReapplyXform()
{ {
RotateReset(); RotateReset();
@ -125,26 +248,29 @@ void CGuiWidget::EnsureHasAnimController()
} }
} }
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* CGuiWidget::FindTriggerList(int id) void CGuiWidget::BroadcastMessage(int id, CGuiControllerInfo* info)
{ {
auto search = xcc_functionMap.find(id); CGuiFuncParm a((intptr_t(x7c_selfId)));
if (search == xcc_functionMap.cend()) CGuiFuncParm b((intptr_t(id)));
return nullptr; CGuiFunctionDef def(0, false, a, b);
return &search->second; MAF_SendMessage(&def, info);
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
if (ch)
ch->BroadcastMessage(id, info);
CGuiWidget* sib = static_cast<CGuiWidget*>(GetNextSibling());
if (sib)
sib->BroadcastMessage(id, info);
} }
void CGuiWidget::AddTrigger(std::unique_ptr<CGuiLogicalEventTrigger>&& trigger) void CGuiWidget::LockEvents(bool lock)
{ {
int tid = trigger->GetTriggerId(); xf6_28_eventLock = lock;
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* list = FindTriggerList(tid); if (lock)
if (!list) DoUnregisterEventHandler();
{ else
auto it = DoRegisterEventHandler();
xcc_functionMap.emplace(std::make_pair(tid,
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>()));
list = &it.first->second;
}
list->push_back(std::move(trigger));
} }
void CGuiWidget::UnregisterEventHandler() void CGuiWidget::UnregisterEventHandler()
@ -165,7 +291,7 @@ void CGuiWidget::UnregisterEventHandler(ETraversalMode mode)
{ {
switch (mode) switch (mode)
{ {
case ETraversalMode::Recursive: case ETraversalMode::Children:
if (!DoUnregisterEventHandler()) if (!DoUnregisterEventHandler())
{ {
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject()); CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
@ -173,7 +299,7 @@ void CGuiWidget::UnregisterEventHandler(ETraversalMode mode)
ch->UnregisterEventHandler(); ch->UnregisterEventHandler();
} }
break; break;
case ETraversalMode::NonRecursive: case ETraversalMode::Single:
DoUnregisterEventHandler(); DoUnregisterEventHandler();
break; break;
default: default:
@ -184,8 +310,8 @@ void CGuiWidget::UnregisterEventHandler(ETraversalMode mode)
bool CGuiWidget::DoUnregisterEventHandler() bool CGuiWidget::DoUnregisterEventHandler()
{ {
for (auto& item : xcc_functionMap) for (auto& item : xcc_triggerMap)
for (std::unique_ptr<CGuiLogicalEventTrigger>& trigger : item.second) for (std::unique_ptr<CGuiLogicalEventTrigger>& trigger : *item.second)
xc8_frame->ClearMessageMap(trigger.get(), x7c_selfId); xc8_frame->ClearMessageMap(trigger.get(), x7c_selfId);
return false; return false;
} }
@ -208,7 +334,7 @@ void CGuiWidget::RegisterEventHandler(ETraversalMode mode)
{ {
switch (mode) switch (mode)
{ {
case ETraversalMode::Recursive: case ETraversalMode::Children:
if (!DoRegisterEventHandler()) if (!DoRegisterEventHandler())
{ {
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject()); CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
@ -216,7 +342,7 @@ void CGuiWidget::RegisterEventHandler(ETraversalMode mode)
ch->RegisterEventHandler(); ch->RegisterEventHandler();
} }
break; break;
case ETraversalMode::NonRecursive: case ETraversalMode::Single:
DoRegisterEventHandler(); DoRegisterEventHandler();
break; break;
default: default:
@ -227,15 +353,298 @@ void CGuiWidget::RegisterEventHandler(ETraversalMode mode)
bool CGuiWidget::DoRegisterEventHandler() bool CGuiWidget::DoRegisterEventHandler()
{ {
if (xf6_28_ || !GetIsActive()) if (xf6_28_eventLock || !GetIsActive())
return false; return false;
for (auto& item : xcc_functionMap) for (auto& item : xcc_triggerMap)
for (std::unique_ptr<CGuiLogicalEventTrigger>& trigger : item.second) for (std::unique_ptr<CGuiLogicalEventTrigger>& trigger : *item.second)
xc8_frame->AddMessageMap(trigger.get(), x7c_selfId); xc8_frame->AddMessageMap(trigger.get(), x7c_selfId);
return false; return false;
} }
void CGuiWidget::Initialize() {} CGuiWidget* CGuiWidget::RemoveChildWidget(CGuiWidget* widget, bool makeWorldLocal)
{
return static_cast<CGuiWidget*>(RemoveChildObject(widget, makeWorldLocal));
}
void CGuiWidget::AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd)
{
AddChildObject(widget, makeWorldLocal, atEnd);
}
void CGuiWidget::AddAnim(EGuiAnimBehListID id, CGuiAnimBase* anim)
{
if (!xb0_animController)
{
xb0_animController.reset(new CGuiAnimController(
CGuiWidgetParms(xc8_frame, false, -1, -1, false, false, false,
zeus::CColor::skWhite, EGuiModelDrawFlags::Two, true, false), this));
}
xb0_animController->AddAnimation(anim, id);
}
void CGuiWidget::ResetAllAnimUpdateState()
{
if (xb0_animController)
xb0_animController->ResetListUpdateState();
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->ResetAllAnimUpdateState();
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->ResetAllAnimUpdateState();
}
void CGuiWidget::SetVisibility(bool vis, ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Children:
{
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings);
break;
}
case ETraversalMode::ChildrenAndSiblings:
{
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings);
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings);
break;
}
default: break;
}
SetIsVisible(vis);
}
void CGuiWidget::SetAnimUpdateState(EGuiAnimBehListID id, bool state)
{
if (xb0_animController)
xb0_animController->SetListUpdateState(id, state);
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->SetAnimUpdateState(id, state);
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->SetAnimUpdateState(id, state);
}
void CGuiWidget::SetAnimUpdateState(EGuiAnimBehListID id, bool state, ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Children:
{
if (xb0_animController)
xb0_animController->SetListUpdateState(id, state);
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->SetAnimUpdateState(id, state);
break;
}
case ETraversalMode::Single:
{
if (xb0_animController)
xb0_animController->SetListUpdateState(id, state);
break;
}
default:
SetAnimUpdateState(id, state);
break;
}
}
void CGuiWidget::GetBranchAnimLen(EGuiAnimBehListID id, float& len)
{
if (xb0_animController)
{
float aLen = xb0_animController->GetAnimSetLength(id);
if (aLen > len)
len = aLen;
}
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->GetBranchAnimLen(id, len);
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->GetBranchAnimLen(id, len);
}
void CGuiWidget::GetBranchAnimLen(EGuiAnimBehListID id, float& len, ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Children:
{
if (xb0_animController)
{
float aLen = xb0_animController->GetAnimSetLength(id);
if (aLen > len)
len = aLen;
}
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->GetBranchAnimLen(id, len);
break;
}
case ETraversalMode::Single:
{
if (xb0_animController)
{
float aLen = xb0_animController->GetAnimSetLength(id);
if (aLen > len)
len = aLen;
}
break;
}
default:
GetBranchAnimLen(id, len);
break;
}
}
void CGuiWidget::IsAllAnimsDone(EGuiAnimBehListID id, bool& isDone)
{
if (xb0_animController)
{
if (!isDone)
return;
xb0_animController->IsAnimsDone(id, isDone);
}
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->IsAllAnimsDone(id, isDone);
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->IsAllAnimsDone(id, isDone);
}
void CGuiWidget::IsAllAnimsDone(EGuiAnimBehListID id, bool& isDone, ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Children:
{
if (xb0_animController)
{
xb0_animController->IsAnimsDone(id, isDone);
if (!isDone)
return;
}
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->IsAllAnimsDone(id, isDone);
break;
}
case ETraversalMode::Single:
{
if (xb0_animController)
xb0_animController->IsAnimsDone(id, isDone);
break;
}
default:
IsAllAnimsDone(id, isDone);
break;
}
}
void CGuiWidget::InitializeAnimControllers(EGuiAnimBehListID id, float fval, bool flag,
EGuiAnimInitMode initMode)
{
if (xb0_animController)
xb0_animController->InitTransform(this, id, fval, flag, initMode);
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->InitializeAnimControllers(id, fval, flag, initMode);
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->InitializeAnimControllers(id, fval, flag, initMode);
}
void CGuiWidget::InitializeAnimControllers(EGuiAnimBehListID id, float fval, bool flag,
EGuiAnimInitMode initMode, ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Children:
{
if (xb0_animController)
xb0_animController->InitTransform(this, id, fval, flag, initMode);
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->InitializeAnimControllers(id, fval, flag, initMode);
break;
}
case ETraversalMode::Single:
{
if (xb0_animController)
xb0_animController->InitTransform(this, id, fval, flag, initMode);
break;
}
default:
InitializeAnimControllers(id, fval, flag, initMode);
break;
}
}
void CGuiWidget::RecalcWidgetColor(ETraversalMode mode)
{
CGuiWidget* parent = static_cast<CGuiWidget*>(GetParent());
if (parent)
xc0_color2 = xbc_color * parent->xc0_color2;
else
xc0_color2 = xbc_color;
xb4_ = xb8_ + xc0_color2;
switch (mode)
{
case ETraversalMode::ChildrenAndSiblings:
{
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
nextSib->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings);
}
case ETraversalMode::Children:
{
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
child->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings);
}
default: break;
}
}
CGuiWidget* CGuiWidget::FindWidget(s16 id)
{
if (x7c_selfId == id)
return this;
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)
{
CGuiWidget* found = child->FindWidget(id);
if (found)
return found;
}
CGuiWidget* nextSib = static_cast<CGuiWidget*>(GetNextSibling());
if (nextSib)
{
CGuiWidget* found = nextSib->FindWidget(id);
if (found)
return found;
}
return nullptr;
}
bool CGuiWidget::GetIsFinishedLoading() const
{
bool widgetFinished = GetIsFinishedLoadingWidgetSpecific();
if (!xb0_animController)
return widgetFinished;
return widgetFinished && xb0_animController->GetIsFinishedLoading();
}
void CGuiWidget::InitializeRecursive() void CGuiWidget::InitializeRecursive()
{ {
@ -251,7 +660,7 @@ void CGuiWidget::InitializeRecursive()
void CGuiWidget::SetColor(const zeus::CColor& color) void CGuiWidget::SetColor(const zeus::CColor& color)
{ {
xbc_color = color; xbc_color = color;
RecalcWidgetColor(ETraversalMode::Recursive); RecalcWidgetColor(ETraversalMode::Children);
} }
void CGuiWidget::OnDeActivate() {} void CGuiWidget::OnDeActivate() {}
@ -259,6 +668,15 @@ void CGuiWidget::OnActivate(bool) {}
void CGuiWidget::OnInvisible() {} void CGuiWidget::OnInvisible() {}
void CGuiWidget::OnVisible() {} void CGuiWidget::OnVisible() {}
void CGuiWidget::SetIsVisible(bool vis)
{
xf6_25_isVisible = vis;
if (vis)
OnVisible();
else
OnInvisible();
}
void CGuiWidget::SetIsActive(bool a, bool b) void CGuiWidget::SetIsActive(bool a, bool b)
{ {
if (a == xf6_26_isActive) if (a == xf6_26_isActive)
@ -266,12 +684,12 @@ void CGuiWidget::SetIsActive(bool a, bool b)
xf6_26_isActive = a; xf6_26_isActive = a;
if (a) if (a)
{ {
RegisterEventHandler(ETraversalMode::Recursive); RegisterEventHandler(ETraversalMode::Children);
OnActivate(b); OnActivate(b);
} }
else else
{ {
RegisterEventHandler(ETraversalMode::Recursive); RegisterEventHandler(ETraversalMode::Children);
OnDeActivate(); OnDeActivate();
} }
} }

View File

@ -13,26 +13,29 @@ class CGuiFrame;
class CGuiMessage; class CGuiMessage;
class CGuiAnimController; class CGuiAnimController;
class CGuiLogicalEventTrigger; class CGuiLogicalEventTrigger;
class CGuiTextSupport;
enum class EGuiAnimBehListID enum class EGuiAnimBehListID
{ {
NegOne = -1, NegOne = -1,
Zero = 0, Zero = 0,
One = 1, One = 1,
Two = 2 Two = 2,
EGuiAnimBehListIDMAX = 13
}; };
enum class ETraversalMode enum class ETraversalMode
{ {
Zero = 0, ChildrenAndSiblings = 0,
Recursive = 1, Children = 1,
NonRecursive = 2 Single = 2
}; };
enum class EGuiAnimInitMode enum class EGuiAnimInitMode
{ {
One = 1, One = 1,
Two = 2, Two = 2,
Three = 3,
Five = 5 Five = 5
}; };
@ -58,22 +61,23 @@ public:
bool x4_a; bool x4_a;
s16 x6_selfId; s16 x6_selfId;
s16 x8_parentId; s16 x8_parentId;
bool xa_d; bool xa_defaultVisible;
bool xb_defaultActive; bool xb_defaultActive;
bool xc_f; bool xc_f;
bool xd_g; bool xd_g;
bool xe_h; bool xe_h;
zeus::CColor x10_color; zeus::CColor x10_color;
EGuiModelDrawFlags x14_drawFlags; EGuiModelDrawFlags x14_drawFlags;
CGuiWidgetParms(CGuiFrame* frame, bool a, s16 selfId, s16 parentId, bool d, bool defaultActive, CGuiWidgetParms(CGuiFrame* frame, bool a, s16 selfId, s16 parentId,
bool defaultVisible, bool defaultActive,
bool f, const zeus::CColor& color, EGuiModelDrawFlags drawFlags, bool g, bool h) bool f, const zeus::CColor& color, EGuiModelDrawFlags drawFlags, bool g, bool h)
: x0_frame(frame), x4_a(a), x6_selfId(selfId), x8_parentId(parentId), xa_d(d), : x0_frame(frame), x4_a(a), x6_selfId(selfId), x8_parentId(parentId), xa_defaultVisible(defaultVisible),
xb_defaultActive(defaultActive), xc_f(f), xd_g(g), xe_h(h), x10_color(color), xb_defaultActive(defaultActive), xc_f(f), xd_g(g), xe_h(h), x10_color(color),
x14_drawFlags(drawFlags) {} x14_drawFlags(drawFlags) {}
}; };
static void LoadWidgetFnMap(); static void LoadWidgetFnMap();
virtual FourCC GetWidgetTypeID() const {return hecl::FOURCC('BWIG');} virtual FourCC GetWidgetTypeID() const {return hecl::FOURCC('BWIG');}
private: protected:
s16 x7c_selfId; s16 x7c_selfId;
s16 x7e_parentId; s16 x7e_parentId;
zeus::CTransform x80_transform; zeus::CTransform x80_transform;
@ -84,17 +88,14 @@ private:
zeus::CColor xc0_color2; zeus::CColor xc0_color2;
EGuiModelDrawFlags xc4_drawFlags; EGuiModelDrawFlags xc4_drawFlags;
CGuiFrame* xc8_frame; CGuiFrame* xc8_frame;
std::unordered_map<int, std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>> xcc_functionMap; std::unordered_map<int, std::unique_ptr<std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>>> xcc_triggerMap;
u32 xe4_ = 0; std::unordered_map<int, std::unique_ptr<std::vector<std::unique_ptr<CGuiFunctionDef>>>> xe0_functionMap;
u32 xe8_ = 0;
u32 xec_ = 0;
u32 xf0_ = 0;
s16 xf4_workerId = -1; s16 xf4_workerId = -1;
bool xf6_24_pg : 1; bool xf6_24_pg : 1;
bool xf6_25_pd : 1; bool xf6_25_isVisible : 1;
bool xf6_26_isActive : 1; bool xf6_26_isActive : 1;
bool xf6_27_ : 1; bool xf6_27_ : 1;
bool xf6_28_ : 1; bool xf6_28_eventLock : 1;
bool xf6_29_pf : 1; bool xf6_29_pf : 1;
bool xf6_30_ : 1; bool xf6_30_ : 1;
bool xf6_31_ : 1; bool xf6_31_ : 1;
@ -111,22 +112,21 @@ public:
virtual void ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms); virtual void ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms);
virtual void ParseMessages(CInputStream& in, const CGuiWidgetParms& parms); virtual void ParseMessages(CInputStream& in, const CGuiWidgetParms& parms);
virtual void ParseAnimations(CInputStream& in, const CGuiWidgetParms& parms); virtual void ParseAnimations(CInputStream& in, const CGuiWidgetParms& parms);
virtual void GetTextureAssets() const; virtual std::vector<TResId> GetTextureAssets() const;
virtual void GetModelAssets() const; virtual std::vector<TResId> GetModelAssets() const;
virtual void GetFontAssets() const; virtual std::vector<TResId> GetFontAssets() const;
virtual void GetKFAMAssets() const;
virtual void Initialize(); virtual void Initialize();
virtual void Touch() const; virtual void Touch() const;
virtual bool GetIsVisible() const; virtual bool GetIsVisible() const;
virtual bool GetIsActive() const; virtual bool GetIsActive() const;
virtual void TextSupport(); virtual CGuiTextSupport* TextSupport();
virtual void GetTextSupport() const; virtual CGuiTextSupport* GetTextSupport() const;
virtual void ModifyRGBA(CGuiWidget* widget); virtual void ModifyRGBA(CGuiWidget* widget);
virtual void AddAnim(EGuiAnimBehListID, CGuiAnimBase*); virtual void AddAnim(EGuiAnimBehListID, CGuiAnimBase*);
virtual void AddChildWidget(CGuiWidget* widget, bool, bool); virtual void AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd);
virtual void RemoveChildWidget(CGuiWidget* widget, bool); virtual CGuiWidget* RemoveChildWidget(CGuiWidget* widget, bool makeWorldLocal);
virtual bool AddWorkerWidget(CGuiWidget* worker); virtual bool AddWorkerWidget(CGuiWidget* worker);
virtual void GetFinishedLoadingWidgetSpecific() const; virtual bool GetIsFinishedLoadingWidgetSpecific() const;
virtual void OnVisible(); virtual void OnVisible();
virtual void OnInvisible(); virtual void OnInvisible();
virtual void OnActivate(bool); virtual void OnActivate(bool);
@ -134,16 +134,19 @@ public:
virtual bool DoRegisterEventHandler(); virtual bool DoRegisterEventHandler();
virtual bool DoUnregisterEventHandler(); virtual bool DoUnregisterEventHandler();
void AddFunctionDef(u32, CGuiFunctionDef* def); s16 GetSelfId() const {return x7c_selfId;}
void FindFunctionDefList(int); s16 GetParentId() const {return x7e_parentId;}
zeus::CVector3f GetIdlePosition() const; const zeus::CTransform& GetTransform() const {return x80_transform;}
void SetIdlePosition(const zeus::CVector3f& pos); std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* FindTriggerList(int id);
void AddTrigger(std::unique_ptr<CGuiLogicalEventTrigger>&& trigger);
std::vector<std::unique_ptr<CGuiFunctionDef>>* FindFunctionDefList(int id);
void AddFunctionDef(s32 id, std::unique_ptr<CGuiFunctionDef>&& def);
const zeus::CVector3f& GetIdlePosition() const {return x80_transform.m_origin;}
void SetIdlePosition(const zeus::CVector3f& pos, bool reapply);
void ReapplyXform(); void ReapplyXform();
void SetIsVisible(bool); void SetIsVisible(bool);
void SetIsActive(bool, bool); void SetIsActive(bool, bool);
void EnsureHasAnimController(); void EnsureHasAnimController();
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* FindTriggerList(int);
void AddTrigger(std::unique_ptr<CGuiLogicalEventTrigger>&& trigger);
void BroadcastMessage(int, CGuiControllerInfo* info); void BroadcastMessage(int, CGuiControllerInfo* info);
void LockEvents(bool); void LockEvents(bool);

@ -1 +1 @@
Subproject commit 6ce9df20fa041d9a4bc52bc6e5628c2763222465 Subproject commit 8a6317a45035035a9fe911232edb4adf4b7260d9