From b3859c4476e92931ffdbc8d8886d9a3ec588fc87 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 15 Mar 2016 13:23:45 -1000 Subject: [PATCH] Many CGuiWidget imps --- DataSpec/DNAMP1/FRME.hpp | 4 +- Runtime/GuiSys/CGuiAnimBase.hpp | 22 +- Runtime/GuiSys/CGuiAnimController.cpp | 161 +++++++++ Runtime/GuiSys/CGuiAnimController.hpp | 31 +- Runtime/GuiSys/CGuiFrame.cpp | 22 +- Runtime/GuiSys/CGuiObject.hpp | 2 +- Runtime/GuiSys/CGuiRandomVar.hpp | 1 + Runtime/GuiSys/CGuiWidget.cpp | 490 ++++++++++++++++++++++++-- Runtime/GuiSys/CGuiWidget.hpp | 63 ++-- specter | 2 +- 10 files changed, 712 insertions(+), 86 deletions(-) diff --git a/DataSpec/DNAMP1/FRME.hpp b/DataSpec/DNAMP1/FRME.hpp index ef240fd94..7b32d0358 100644 --- a/DataSpec/DNAMP1/FRME.hpp +++ b/DataSpec/DNAMP1/FRME.hpp @@ -29,8 +29,8 @@ struct FRME : BigDNA String<-1> name; String<-1> parent; Value unk1; - Value unk2; - Value unk3; + Value defaultVisible; + Value defaultActive; Value unk4; Value color; Value modelDrawFlags; diff --git a/Runtime/GuiSys/CGuiAnimBase.hpp b/Runtime/GuiSys/CGuiAnimBase.hpp index 9ad975a89..bb2f44ce4 100644 --- a/Runtime/GuiSys/CGuiAnimBase.hpp +++ b/Runtime/GuiSys/CGuiAnimBase.hpp @@ -1,11 +1,13 @@ #ifndef __URDE_CGUIANIMBASE_HPP__ #define __URDE_CGUIANIMBASE_HPP__ +#include "RetroTypes.hpp" +#include "CGuiRandomVar.hpp" + namespace urde { class CGuiAnimController; class CGuiWidgetDrawParams; -class CGuiRandomVar; enum class EGuiAnimType { @@ -21,17 +23,29 @@ enum class EGuiAnimType 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: 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 AnimUpdate(CGuiAnimController* controller, float dt); virtual void AnimDraw(const CGuiWidgetDrawParams& params) const; virtual void CalcInitVelocity(const CGuiAnimController* controller); virtual void GetAnimType(const CGuiAnimController* controller) const; - virtual void GetItFinishedLoading() const {return true;} + virtual bool GetIsFinishedLoading() const {return true;} }; class CGuiAnimRotation : public CGuiAnimBase diff --git a/Runtime/GuiSys/CGuiAnimController.cpp b/Runtime/GuiSys/CGuiAnimController.cpp index 66dd824f1..1dac21293 100644 --- a/Runtime/GuiSys/CGuiAnimController.cpp +++ b/Runtime/GuiSys/CGuiAnimController.cpp @@ -1,13 +1,174 @@ #include "CGuiAnimController.hpp" #include "CGuiLogicalEventTrigger.hpp" +#include "CGuiAnimBase.hpp" +#include "CGuiControllerInfo.hpp" namespace urde { +void CGuiAnimSet::AddAnim(CGuiAnimBase* anim) +{ + x0_map[x20_++] = anim; + RecalcTotalTime(); +} + +void CGuiAnimSet::RecalcTotalTime() +{ + x28_totalTime = 0.f; + for (std::pair& 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& anim : x0_map) + { + x2c_ = 1.f; + anim.second->AnimInit(controller, fval); + } +} + +void CGuiAnimSet::Update(CGuiAnimController* controller, bool flag) +{ + x19_isDone = true; + for (std::pair& 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) : 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(id); + set = xf8_sets[int(id)].get(); + } + set->AddAnim(anim); +} + +void CGuiAnimController::ResetListUpdateState() +{ + for (std::unique_ptr& 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& set : xf8_sets) + if (set && set->x18_update) + set->Update(this, flag); +} + } diff --git a/Runtime/GuiSys/CGuiAnimController.hpp b/Runtime/GuiSys/CGuiAnimController.hpp index 62a68b2a6..b397b3caf 100644 --- a/Runtime/GuiSys/CGuiAnimController.hpp +++ b/Runtime/GuiSys/CGuiAnimController.hpp @@ -9,18 +9,47 @@ namespace urde class CGuiAnimSet { + friend class CGuiAnimController; + std::unordered_map 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 { + friend class CGuiAnimSet; std::array, 13> xf8_sets; float x164_ = 0.f; CGuiWidget* x168_widget; - u32 x16c_ = 0; + zeus::CColor x16c_ = zeus::CColor::skClear; u32 x170_ = 0; public: 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); }; } diff --git a/Runtime/GuiSys/CGuiFrame.cpp b/Runtime/GuiSys/CGuiFrame.cpp index 4e5630cf2..3f4777792 100644 --- a/Runtime/GuiSys/CGuiFrame.cpp +++ b/Runtime/GuiSys/CGuiFrame.cpp @@ -475,7 +475,7 @@ bool CGuiFrame::Update(float dt) } if (listId != EGuiAnimBehListID::NegOne) - x44_headWidget->IsAllAnimsDone(listId, something, ETraversalMode::Zero); + x44_headWidget->IsAllAnimsDone(listId, something, ETraversalMode::ChildrenAndSiblings); if (something) { @@ -484,15 +484,15 @@ bool CGuiFrame::Update(float dt) case EFrameStates::One: { 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, - EGuiAnimInitMode::Five, ETraversalMode::NonRecursive); + EGuiAnimInitMode::Five, ETraversalMode::Single); CGuiWidget* camSib = static_cast(x4c_camera->GetNextSibling()); if (camSib) { - camSib->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::Zero); + camSib->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::ChildrenAndSiblings); camSib->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false, - EGuiAnimInitMode::Five, ETraversalMode::Zero); + EGuiAnimInitMode::Five, ETraversalMode::ChildrenAndSiblings); } xbd_flag2 = false; break; @@ -548,12 +548,12 @@ void CGuiFrame::Stop(const CGuiFrameTransitionOptions& transOpts, EFrameStates s else { x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true, - EGuiAnimInitMode::Two, ETraversalMode::NonRecursive); + EGuiAnimInitMode::Two, ETraversalMode::Single); CGuiWidget* camSib = static_cast(x4c_camera->GetNextSibling()); if (camSib) { 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; x38_ = EFrameStates::Two; 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_; x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true, - EGuiAnimInitMode::One, ETraversalMode::NonRecursive); + EGuiAnimInitMode::One, ETraversalMode::Single); CGuiWidget* camSib = static_cast(x4c_camera->GetNextSibling()); if (camSib) { camSib->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true, - EGuiAnimInitMode::One, ETraversalMode::Zero); + EGuiAnimInitMode::One, ETraversalMode::ChildrenAndSiblings); } x18_ |= 0x7; - x44_headWidget->RegisterEventHandler(ETraversalMode::Zero); + x44_headWidget->RegisterEventHandler(ETraversalMode::ChildrenAndSiblings); } void CGuiFrame::Initialize() diff --git a/Runtime/GuiSys/CGuiObject.hpp b/Runtime/GuiSys/CGuiObject.hpp index 005a5bf9a..d703e7a88 100644 --- a/Runtime/GuiSys/CGuiObject.hpp +++ b/Runtime/GuiSys/CGuiObject.hpp @@ -10,7 +10,7 @@ namespace urde class CGuiWidgetDrawParms; class CGuiMessage; class CGuiFunctionDef; -class CGuiControllerInfo; +struct CGuiControllerInfo; class CGuiObject { diff --git a/Runtime/GuiSys/CGuiRandomVar.hpp b/Runtime/GuiSys/CGuiRandomVar.hpp index 467835d55..d28d334d4 100644 --- a/Runtime/GuiSys/CGuiRandomVar.hpp +++ b/Runtime/GuiSys/CGuiRandomVar.hpp @@ -6,6 +6,7 @@ namespace urde class CGuiRandomVar { +public: enum class Type { Zero, diff --git a/Runtime/GuiSys/CGuiWidget.cpp b/Runtime/GuiSys/CGuiWidget.cpp index be0526bd6..fd381735e 100644 --- a/Runtime/GuiSys/CGuiWidget.cpp +++ b/Runtime/GuiSys/CGuiWidget.cpp @@ -25,13 +25,14 @@ CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms) : x7c_selfId(parms.x6_selfId), x7e_parentId(parms.x8_parentId), xbc_color(parms.x10_color), xc0_color2(parms.x10_color), 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_27_(true), xf6_28_(false), xf6_29_pf(parms.xc_f), xf6_30_(false), + xf6_24_pg(parms.xd_g), xf6_25_isVisible(parms.xa_defaultVisible), + 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) { if (parms.x4_a) EnsureHasAnimController(); - RecalcWidgetColor(ETraversalMode::NonRecursive); + RecalcWidgetColor(ETraversalMode::Single); } CGuiWidget::CGuiWidgetParms @@ -43,15 +44,15 @@ CGuiWidget::ReadWidgetHeader(CGuiFrame* frame, CInputStream& in, bool flag) s16 parentId = frame->GetWidgetIdDB().AddWidget(parent); bool a = in.readBool(); - bool d = in.readBool(); - bool e = in.readBool(); + bool defaultVis = in.readBool(); + bool defaultActive = in.readBool(); bool f = in.readBool(); zeus::CColor color; color.readRGBABig(in); EGuiModelDrawFlags df = EGuiModelDrawFlags(in.readUint32Big()); - return CGuiWidget::CGuiWidgetParms(frame, a, selfId, parentId, d, e, f, - color, df, true, flag); + return CGuiWidget::CGuiWidgetParms(frame, a, selfId, parentId, defaultVis, defaultActive, + f, color, df, true, 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); } +std::vector CGuiWidget::GetTextureAssets() const +{ + return {}; +} + +std::vector CGuiWidget::GetModelAssets() const +{ + return {}; +} + +std::vector 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(GetParent()); + if (parent) + ModifyRGBA(parent); + CGuiWidget* nextSib = static_cast(GetNextSibling()); + if (nextSib) + nextSib->RecalculateAllRGBA(); + CGuiWidget* child = static_cast(GetChildObject()); + if (child) + child->RecalculateAllRGBA(); +} + +void CGuiWidget::InitializeRGBAFactor() +{ + CGuiWidget* child = static_cast(GetChildObject()); + if (child) + child->InitializeRGBAFactor(); + CGuiWidget* nextSib = static_cast(GetNextSibling()); + if (nextSib) + nextSib->InitializeRGBAFactor(); +} + +bool CGuiWidget::GetIsFinishedLoadingWidgetSpecific() const +{ + return true; +} + +std::vector>* 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&& trigger) +{ + int tid = trigger->GetTriggerId(); + std::vector>* list = FindTriggerList(tid); + if (!list) + { + auto it = + xcc_triggerMap.emplace(std::make_pair(tid, + std::make_unique>>())); + list = it.first->second.get(); + } + list->push_back(std::move(trigger)); +} + +std::vector>* 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&& def) +{ + std::vector>* list = FindFunctionDefList(id); + if (!list) + { + auto it = + xe0_functionMap.emplace(std::make_pair(id, + std::make_unique>>())); + 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() { RotateReset(); @@ -125,26 +248,29 @@ void CGuiWidget::EnsureHasAnimController() } } -std::vector>* CGuiWidget::FindTriggerList(int id) +void CGuiWidget::BroadcastMessage(int id, CGuiControllerInfo* info) { - auto search = xcc_functionMap.find(id); - if (search == xcc_functionMap.cend()) - return nullptr; - return &search->second; + CGuiFuncParm a((intptr_t(x7c_selfId))); + CGuiFuncParm b((intptr_t(id))); + CGuiFunctionDef def(0, false, a, b); + MAF_SendMessage(&def, info); + + CGuiWidget* ch = static_cast(GetChildObject()); + if (ch) + ch->BroadcastMessage(id, info); + + CGuiWidget* sib = static_cast(GetNextSibling()); + if (sib) + sib->BroadcastMessage(id, info); } -void CGuiWidget::AddTrigger(std::unique_ptr&& trigger) +void CGuiWidget::LockEvents(bool lock) { - int tid = trigger->GetTriggerId(); - std::vector>* list = FindTriggerList(tid); - if (!list) - { - auto it = - xcc_functionMap.emplace(std::make_pair(tid, - std::vector>())); - list = &it.first->second; - } - list->push_back(std::move(trigger)); + xf6_28_eventLock = lock; + if (lock) + DoUnregisterEventHandler(); + else + DoRegisterEventHandler(); } void CGuiWidget::UnregisterEventHandler() @@ -165,7 +291,7 @@ void CGuiWidget::UnregisterEventHandler(ETraversalMode mode) { switch (mode) { - case ETraversalMode::Recursive: + case ETraversalMode::Children: if (!DoUnregisterEventHandler()) { CGuiWidget* ch = static_cast(GetChildObject()); @@ -173,7 +299,7 @@ void CGuiWidget::UnregisterEventHandler(ETraversalMode mode) ch->UnregisterEventHandler(); } break; - case ETraversalMode::NonRecursive: + case ETraversalMode::Single: DoUnregisterEventHandler(); break; default: @@ -184,8 +310,8 @@ void CGuiWidget::UnregisterEventHandler(ETraversalMode mode) bool CGuiWidget::DoUnregisterEventHandler() { - for (auto& item : xcc_functionMap) - for (std::unique_ptr& trigger : item.second) + for (auto& item : xcc_triggerMap) + for (std::unique_ptr& trigger : *item.second) xc8_frame->ClearMessageMap(trigger.get(), x7c_selfId); return false; } @@ -208,7 +334,7 @@ void CGuiWidget::RegisterEventHandler(ETraversalMode mode) { switch (mode) { - case ETraversalMode::Recursive: + case ETraversalMode::Children: if (!DoRegisterEventHandler()) { CGuiWidget* ch = static_cast(GetChildObject()); @@ -216,7 +342,7 @@ void CGuiWidget::RegisterEventHandler(ETraversalMode mode) ch->RegisterEventHandler(); } break; - case ETraversalMode::NonRecursive: + case ETraversalMode::Single: DoRegisterEventHandler(); break; default: @@ -227,15 +353,298 @@ void CGuiWidget::RegisterEventHandler(ETraversalMode mode) bool CGuiWidget::DoRegisterEventHandler() { - if (xf6_28_ || !GetIsActive()) + if (xf6_28_eventLock || !GetIsActive()) return false; - for (auto& item : xcc_functionMap) - for (std::unique_ptr& trigger : item.second) + for (auto& item : xcc_triggerMap) + for (std::unique_ptr& trigger : *item.second) xc8_frame->AddMessageMap(trigger.get(), x7c_selfId); return false; } -void CGuiWidget::Initialize() {} +CGuiWidget* CGuiWidget::RemoveChildWidget(CGuiWidget* widget, bool makeWorldLocal) +{ + return static_cast(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(GetChildObject()); + if (child) + child->ResetAllAnimUpdateState(); + CGuiWidget* nextSib = static_cast(GetNextSibling()); + if (nextSib) + nextSib->ResetAllAnimUpdateState(); +} + +void CGuiWidget::SetVisibility(bool vis, ETraversalMode mode) +{ + switch (mode) + { + case ETraversalMode::Children: + { + CGuiWidget* child = static_cast(GetChildObject()); + if (child) + child->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings); + break; + } + case ETraversalMode::ChildrenAndSiblings: + { + CGuiWidget* child = static_cast(GetChildObject()); + if (child) + child->SetVisibility(vis, ETraversalMode::ChildrenAndSiblings); + CGuiWidget* nextSib = static_cast(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(GetChildObject()); + if (child) + child->SetAnimUpdateState(id, state); + CGuiWidget* nextSib = static_cast(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(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(GetChildObject()); + if (child) + child->GetBranchAnimLen(id, len); + CGuiWidget* nextSib = static_cast(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(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(GetChildObject()); + if (child) + child->IsAllAnimsDone(id, isDone); + CGuiWidget* nextSib = static_cast(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(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(GetChildObject()); + if (child) + child->InitializeAnimControllers(id, fval, flag, initMode); + CGuiWidget* nextSib = static_cast(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(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(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(GetNextSibling()); + if (nextSib) + nextSib->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings); + } + case ETraversalMode::Children: + { + CGuiWidget* child = static_cast(GetChildObject()); + if (child) + child->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings); + } + default: break; + } +} + +CGuiWidget* CGuiWidget::FindWidget(s16 id) +{ + if (x7c_selfId == id) + return this; + CGuiWidget* child = static_cast(GetChildObject()); + if (child) + { + CGuiWidget* found = child->FindWidget(id); + if (found) + return found; + } + CGuiWidget* nextSib = static_cast(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() { @@ -251,7 +660,7 @@ void CGuiWidget::InitializeRecursive() void CGuiWidget::SetColor(const zeus::CColor& color) { xbc_color = color; - RecalcWidgetColor(ETraversalMode::Recursive); + RecalcWidgetColor(ETraversalMode::Children); } void CGuiWidget::OnDeActivate() {} @@ -259,6 +668,15 @@ void CGuiWidget::OnActivate(bool) {} void CGuiWidget::OnInvisible() {} void CGuiWidget::OnVisible() {} +void CGuiWidget::SetIsVisible(bool vis) +{ + xf6_25_isVisible = vis; + if (vis) + OnVisible(); + else + OnInvisible(); +} + void CGuiWidget::SetIsActive(bool a, bool b) { if (a == xf6_26_isActive) @@ -266,12 +684,12 @@ void CGuiWidget::SetIsActive(bool a, bool b) xf6_26_isActive = a; if (a) { - RegisterEventHandler(ETraversalMode::Recursive); + RegisterEventHandler(ETraversalMode::Children); OnActivate(b); } else { - RegisterEventHandler(ETraversalMode::Recursive); + RegisterEventHandler(ETraversalMode::Children); OnDeActivate(); } } diff --git a/Runtime/GuiSys/CGuiWidget.hpp b/Runtime/GuiSys/CGuiWidget.hpp index f715d7ebe..7a79c823b 100644 --- a/Runtime/GuiSys/CGuiWidget.hpp +++ b/Runtime/GuiSys/CGuiWidget.hpp @@ -13,26 +13,29 @@ class CGuiFrame; class CGuiMessage; class CGuiAnimController; class CGuiLogicalEventTrigger; +class CGuiTextSupport; enum class EGuiAnimBehListID { NegOne = -1, Zero = 0, One = 1, - Two = 2 + Two = 2, + EGuiAnimBehListIDMAX = 13 }; enum class ETraversalMode { - Zero = 0, - Recursive = 1, - NonRecursive = 2 + ChildrenAndSiblings = 0, + Children = 1, + Single = 2 }; enum class EGuiAnimInitMode { One = 1, Two = 2, + Three = 3, Five = 5 }; @@ -58,22 +61,23 @@ public: bool x4_a; s16 x6_selfId; s16 x8_parentId; - bool xa_d; + bool xa_defaultVisible; bool xb_defaultActive; bool xc_f; bool xd_g; bool xe_h; zeus::CColor x10_color; 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) - : 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), x14_drawFlags(drawFlags) {} }; static void LoadWidgetFnMap(); virtual FourCC GetWidgetTypeID() const {return hecl::FOURCC('BWIG');} -private: +protected: s16 x7c_selfId; s16 x7e_parentId; zeus::CTransform x80_transform; @@ -84,17 +88,14 @@ private: zeus::CColor xc0_color2; EGuiModelDrawFlags xc4_drawFlags; CGuiFrame* xc8_frame; - std::unordered_map>> xcc_functionMap; - u32 xe4_ = 0; - u32 xe8_ = 0; - u32 xec_ = 0; - u32 xf0_ = 0; + std::unordered_map>>> xcc_triggerMap; + std::unordered_map>>> xe0_functionMap; s16 xf4_workerId = -1; bool xf6_24_pg : 1; - bool xf6_25_pd : 1; + bool xf6_25_isVisible : 1; bool xf6_26_isActive : 1; bool xf6_27_ : 1; - bool xf6_28_ : 1; + bool xf6_28_eventLock : 1; bool xf6_29_pf : 1; bool xf6_30_ : 1; bool xf6_31_ : 1; @@ -111,22 +112,21 @@ public: virtual void ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms); virtual void ParseMessages(CInputStream& in, const CGuiWidgetParms& parms); virtual void ParseAnimations(CInputStream& in, const CGuiWidgetParms& parms); - virtual void GetTextureAssets() const; - virtual void GetModelAssets() const; - virtual void GetFontAssets() const; - virtual void GetKFAMAssets() const; + virtual std::vector GetTextureAssets() const; + virtual std::vector GetModelAssets() const; + virtual std::vector GetFontAssets() const; virtual void Initialize(); virtual void Touch() const; virtual bool GetIsVisible() const; virtual bool GetIsActive() const; - virtual void TextSupport(); - virtual void GetTextSupport() const; + virtual CGuiTextSupport* TextSupport(); + virtual CGuiTextSupport* GetTextSupport() const; virtual void ModifyRGBA(CGuiWidget* widget); virtual void AddAnim(EGuiAnimBehListID, CGuiAnimBase*); - virtual void AddChildWidget(CGuiWidget* widget, bool, bool); - virtual void RemoveChildWidget(CGuiWidget* widget, bool); + virtual void AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd); + virtual CGuiWidget* RemoveChildWidget(CGuiWidget* widget, bool makeWorldLocal); virtual bool AddWorkerWidget(CGuiWidget* worker); - virtual void GetFinishedLoadingWidgetSpecific() const; + virtual bool GetIsFinishedLoadingWidgetSpecific() const; virtual void OnVisible(); virtual void OnInvisible(); virtual void OnActivate(bool); @@ -134,16 +134,19 @@ public: virtual bool DoRegisterEventHandler(); virtual bool DoUnregisterEventHandler(); - void AddFunctionDef(u32, CGuiFunctionDef* def); - void FindFunctionDefList(int); - zeus::CVector3f GetIdlePosition() const; - void SetIdlePosition(const zeus::CVector3f& pos); + s16 GetSelfId() const {return x7c_selfId;} + s16 GetParentId() const {return x7e_parentId;} + const zeus::CTransform& GetTransform() const {return x80_transform;} + std::vector>* FindTriggerList(int id); + void AddTrigger(std::unique_ptr&& trigger); + std::vector>* FindFunctionDefList(int id); + void AddFunctionDef(s32 id, std::unique_ptr&& def); + const zeus::CVector3f& GetIdlePosition() const {return x80_transform.m_origin;} + void SetIdlePosition(const zeus::CVector3f& pos, bool reapply); void ReapplyXform(); void SetIsVisible(bool); void SetIsActive(bool, bool); void EnsureHasAnimController(); - std::vector>* FindTriggerList(int); - void AddTrigger(std::unique_ptr&& trigger); void BroadcastMessage(int, CGuiControllerInfo* info); void LockEvents(bool); diff --git a/specter b/specter index 6ce9df20f..8a6317a45 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 6ce9df20fa041d9a4bc52bc6e5628c2763222465 +Subproject commit 8a6317a45035035a9fe911232edb4adf4b7260d9