2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 21:11:21 +00:00

Frame and Widget imps

This commit is contained in:
Jack Andersen 2016-03-13 14:58:19 -10:00
parent a6f412b390
commit aa207d3e5f
26 changed files with 502 additions and 70 deletions

View File

@ -73,12 +73,12 @@ void FRME::Widget::read(athena::io::IStreamReader& __dna_reader)
/* widgetInfo */
widgetInfo->read(__dna_reader);
/* hasGroup */
hasGroup = __dna_reader.readBool();
if (hasGroup)
/* isWorker */
isWorker = __dna_reader.readBool();
if (isWorker)
{
/* group */
group = __dna_reader.readUint16Big();
/* workerId */
workerId = __dna_reader.readUint16Big();
}
/* origin */
origin = __dna_reader.readVec3fBig();
@ -90,12 +90,12 @@ void FRME::Widget::read(athena::io::IStreamReader& __dna_reader)
basis[2] = __dna_reader.readVec3fBig();
/* rotationCenter */
rotationCenter = __dna_reader.readVec3fBig();
/* unk2 */
unk2 = __dna_reader.readUint32Big();
/* unk3 */
unk3 = __dna_reader.readBool();
/* unk4 */
unk4 = __dna_reader.readBool();
/* msgCount */
msgCount = __dna_reader.readInt16Big();
/* funcDefCount */
funcDefCount = __dna_reader.readInt16Big();
/* animControllerCount */
animControllerCount = __dna_reader.readInt16Big();
}
void FRME::Widget::write(athena::io::IStreamWriter& __dna_writer) const
@ -108,12 +108,12 @@ void FRME::Widget::write(athena::io::IStreamWriter& __dna_writer) const
/* widgetInfo */
widgetInfo->write(__dna_writer);
/* hasGroup */
__dna_writer.writeBool(hasGroup);
if (hasGroup)
/* isWorker */
__dna_writer.writeBool(isWorker);
if (isWorker)
{
/* group */
__dna_writer.writeUint16Big(group);
/* workerId */
__dna_writer.writeUint16Big(workerId);
}
/* origin */
__dna_writer.writeVec3fBig(origin);
@ -125,12 +125,12 @@ void FRME::Widget::write(athena::io::IStreamWriter& __dna_writer) const
__dna_writer.writeVec3fBig(basis[2]);
/* rotationCenter */
__dna_writer.writeVec3fBig(rotationCenter);
/* unk2 */
__dna_writer.writeUint32Big(unk2);
/* unk3 */
__dna_writer.writeBool(unk3);
/* unk4 */
__dna_writer.writeBool(unk4);
/* msgCount */
__dna_writer.writeInt16Big(msgCount);
/* funcDefCount */
__dna_writer.writeInt16Big(funcDefCount);
/* animControllerCount */
__dna_writer.writeInt16Big(animControllerCount);
}
size_t FRME::Widget::binarySize(size_t __isz) const
@ -138,7 +138,7 @@ size_t FRME::Widget::binarySize(size_t __isz) const
__isz = type.binarySize(__isz);
__isz = header.binarySize(__isz);
__isz = widgetInfo->binarySize(__isz);
if (hasGroup)
if (isWorker)
__isz += 4;
return __isz + 67;
}

View File

@ -45,14 +45,14 @@ struct FRME : BigDNA
};
std::unique_ptr<IWidgetInfo> widgetInfo;
Value<bool> hasGroup;
Value<atUint16> group;
Value<bool> isWorker;
Value<atUint16> workerId;
Value<atVec3f> origin;
Value<atVec3f> basis[3];
Value<atVec3f> rotationCenter;
Value<atUint32> unk2;
Value<bool> unk3;
Value<bool> unk4;
Value<atInt16> msgCount;
Value<atInt16> funcDefCount;
Value<atInt16> animControllerCount;
struct BWIGInfo : IWidgetInfo
{ Delete _d; };

View File

@ -1,4 +1,6 @@
#include "CAuiEnergyBarT01.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{

View File

@ -0,0 +1,13 @@
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{
CGuiAnimController::CGuiAnimController(const CGuiWidget::CGuiWidgetParms& parms, CGuiWidget* widget)
: CGuiWidget(parms), x168_widget(widget)
{
}
}

View File

@ -1,6 +1,9 @@
#ifndef __URDE_CGUIANIMCONTROLLER_HPP__
#define __URDE_CGUIANIMCONTROLLER_HPP__
#include "CGuiWidget.hpp"
#include <array>
namespace urde
{
@ -8,8 +11,16 @@ class CGuiAnimSet
{
};
class CGuiAnimController
class CGuiAnimController : public CGuiWidget
{
std::array<std::unique_ptr<CGuiAnimSet>, 13> xf8_sets;
float x164_ = 0.f;
CGuiWidget* x168_widget;
u32 x16c_ = 0;
u32 x170_ = 0;
public:
CGuiAnimController(const CGuiWidget::CGuiWidgetParms& parms, CGuiWidget* widget);
};
}

View File

@ -1,4 +1,6 @@
#include "CGuiBackground.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{
@ -21,7 +23,7 @@ CGuiBackground* CGuiBackground::Create(CGuiFrame* frame, CInputStream& in, bool
std::vector<float> floats = {a, b, a, d, c, b, c, d};
zeus::CVector3f vec;
vec.read(in);
vec.readBig(in);
in.readUint32Big();
in.readUint32Big();
in.readUint32Big();

View File

@ -1,5 +1,6 @@
#include "CGuiCamera.hpp"
#include "CGuiFrame.hpp"
#include "CGuiAnimController.hpp"
namespace urde
{

View File

@ -1,12 +1,14 @@
#include "CGuiFrame.hpp"
#include "CGuiWidget.hpp"
#include "CGuiSys.hpp"
#include "CGuiHeadWidget.hpp"
#include "CGuiAnimController.hpp"
#include "zeus/CColor.hpp"
namespace urde
{
CGuiFrame::CGuiFrame(u32 id, const std::string& name, CGuiSys& sys, int a, int b, int c)
CGuiFrame::CGuiFrame(TResId id, const std::string& name, CGuiSys& sys, int a, int b, int c)
: x4_name(name), x14_id(id), x1c_transitionOpts(EFrameTransitionOptions::Zero),
x3c_guiSys(sys), xb0_a(a), xb4_b(b), xb8_c(c), xbc_24_flag1(false)
{
@ -38,5 +40,119 @@ void CGuiFrame::ResetControllerStatus()
x0_controllerStatus[3] = false;
}
CGuiFrame::WidgetToLogicalEventMap* CGuiFrame::FindWidget2LogicalEventMap(u64 events)
{
auto search = x7c_messageMap.find(events);
if (search == x7c_messageMap.cend())
return nullptr;
return search->second.get();
}
CGuiFrame::LogicalEventList* CGuiFrame::FindLogicalEventList(u64 events, s16 id)
{
CGuiFrame::WidgetToLogicalEventMap* map = FindWidget2LogicalEventMap(events);
if (!map)
return nullptr;
auto search = map->find(id);
if (search == map->cend())
return nullptr;
return search->second.get();
}
void CGuiFrame::ClearMessageMap(const CGuiLogicalEventTrigger* trigger, s16 id)
{
CGuiFrame::LogicalEventList* list =
FindLogicalEventList(trigger->GetPhysicalMsg().x0_curStates, id);
if (list)
list->clear();
}
void CGuiFrame::AddMessageMap(const CGuiLogicalEventTrigger* trigger, s16 id)
{
u64 events = trigger->GetPhysicalMsg().x0_curStates;
int triggerId = trigger->GetTriggerId();
CGuiFrame::WidgetToLogicalEventMap* map = FindWidget2LogicalEventMap(events);
if (!map)
{
auto it =
x7c_messageMap.emplace(std::make_pair(events, std::make_unique<WidgetToLogicalEventMap>()));
map = it.first->second.get();
}
CGuiFrame::LogicalEventList* list = FindLogicalEventList(events, id);
if (!list)
{
auto it =
map->emplace(std::make_pair(id, std::make_unique<LogicalEventList>()));
list = it.first->second.get();
}
for (std::unique_ptr<CGuiFrameMessageMapNode>& node : *list)
if (node->GetTrigger().GetTriggerId() == triggerId)
return;
list->push_back(std::make_unique<CGuiFrameMessageMapNode>(trigger->GetPhysicalMsg(), triggerId));
}
void CGuiFrame::SortDrawOrder()
{
std::sort(x90_widgets.begin(), x90_widgets.end(),
[](const CGuiWidget* a, const CGuiWidget* b) -> bool
{
return a->GetWorldPosition().y < b->GetWorldPosition().y;
});
}
void CGuiFrame::Initialize()
{
SortDrawOrder();
x44_headWidget->SetColor(x44_headWidget->xbc_color);
x44_headWidget->InitializeRecursive();
}
void CGuiFrame::LoadWidgetsInGame(CInputStream& in)
{
u32 count = in.readUint32Big();
x90_widgets.reserve(count);
for (u32 i=0 ; i<count ; ++i)
{
FourCC type = in.readUint32Big();
CGuiWidget* widget = CGuiSys::CreateWidgetInGame(type, in, this);
type = widget->GetWidgetTypeID();
switch (type)
{
case SBIG('CAMR'):
case SBIG('LITE'):
case SBIG('BGND'):
break;
default:
x90_widgets.push_back(widget);
break;
}
}
Initialize();
}
CGuiFrame* CGuiFrame::CreateFrame(TResId frmeId, CGuiSys& sys, CInputStream& in)
{
std::string name = CreateFrameName(frmeId);
in.readInt32Big();
int a = in.readInt32Big();
int b = in.readInt32Big();
int c = in.readInt32Big();
CGuiFrame* ret = new CGuiFrame(frmeId, name, sys, a, b, c);
ret->LoadWidgetsInGame(in);
return ret;
}
std::string CGuiFrame::CreateFrameName(TResId frmeId)
{
/* formatting token originally "frame_%x" for 32-bit ids */
return hecl::Format("frame_%016" PRIX64, frmeId);
}
}

View File

@ -39,6 +39,7 @@ class CGuiFrameMessageMapNode
public:
CGuiFrameMessageMapNode(const CGuiPhysicalMsg& msg, int val)
: x0_trigger(msg, val, false) {}
const CGuiLogicalEventTrigger& GetTrigger() const {return x0_trigger;}
};
class CGuiFrame
@ -50,7 +51,7 @@ public:
private:
bool x0_controllerStatus[4] = {};
std::string x4_name;
u32 x14_id;
TResId x14_id;
CGuiFrameTransitionOptions x1c_transitionOpts;
u32 x34_ = 0;
u32 x38_ = 0;
@ -62,8 +63,11 @@ private:
CGuiWidget* x50_background = nullptr;
zeus::CQuaternion x54_;
CGuiWidgetIdDB x64_idDB;
std::unordered_map<u32, u32> x7c_;
std::vector<u32> x90_;
using LogicalEventList = std::list<std::unique_ptr<CGuiFrameMessageMapNode>>;
using WidgetToLogicalEventMap =
std::unordered_map<s16, std::unique_ptr<LogicalEventList>>;
std::unordered_map<u64, std::unique_ptr<WidgetToLogicalEventMap>> x7c_messageMap;
std::vector<CGuiWidget*> x90_widgets;
std::vector<CGuiLight*> xa0_lights;
int xb0_a;
int xb4_b;
@ -72,7 +76,7 @@ private:
bool xbd_flag2 = false;
public:
CGuiFrame(u32 id, const std::string& name, CGuiSys& sys, int a, int b, int c);
CGuiFrame(TResId id, const std::string& name, CGuiSys& sys, int a, int b, int c);
CGuiSys& GetGuiSys() {return x3c_guiSys;}
@ -87,13 +91,15 @@ public:
void InterpretGUIControllerState(const CFinalInput& input,
CGuiPhysicalMsg::PhysicalMap& state,
char&, char&, char&, char&);
void FindWidget2LogicalEventMap(u64);
void FindLogicalEventList(u64, s16);
WidgetToLogicalEventMap* FindWidget2LogicalEventMap(u64 events);
LogicalEventList* FindLogicalEventList(u64 events, s16 id);
void SendWidgetMessage(s16,
std::list<std::unique_ptr<CGuiFrameMessageMapNode>>&,
CGuiPhysicalMsg::PhysicalMap& state,
CGuiControllerInfo::CGuiControllerStateInfo& csInfo);
void ClearAllMessageMap();
void ClearMessageMap(const CGuiLogicalEventTrigger* trigger, s16 id);
void AddMessageMap(const CGuiLogicalEventTrigger* trigger, s16 id);
void SortDrawOrder();
void EnableLights(u32) const;
void DisableLights() const;
@ -112,8 +118,8 @@ public:
CGuiWidgetIdDB& GetWidgetIdDB() {return x64_idDB;}
static CGuiFrame* CreateFrame(u32, CGuiSys& sys, CInputStream& in);
static std::string CreateFrameName(u32);
static CGuiFrame* CreateFrame(TResId frmeId, CGuiSys& sys, CInputStream& in);
static std::string CreateFrameName(TResId frmeId);
};
}

View File

@ -1,5 +1,6 @@
#include "CGuiHeadWidget.hpp"
#include "CGuiFrame.hpp"
#include "CGuiAnimController.hpp"
namespace urde
{

View File

@ -9,7 +9,7 @@ namespace urde
class CGuiHeadWidget : public CGuiWidget
{
public:
hecl::FourCC GetWidgetTypeID() const {return hecl::FOURCC('HWIG');}
FourCC GetWidgetTypeID() const {return hecl::FOURCC('HWIG');}
CGuiHeadWidget(const CGuiWidgetParms& parms);
static CGuiHeadWidget* Create(CGuiFrame* frame, CInputStream& in, bool);
};

View File

@ -1,4 +1,6 @@
#include "CGuiLight.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{

View File

@ -9,11 +9,13 @@ namespace urde
class CGuiLogicalEventTrigger
{
CGuiPhysicalMsg x0_msg;
int x10_val;
int x10_triggerId;
bool x14_flag;
public:
CGuiLogicalEventTrigger(const CGuiPhysicalMsg& msg, int val, bool flag)
: x0_msg(msg), x10_val(val), x14_flag(flag) {}
: x0_msg(msg), x10_triggerId(val), x14_flag(flag) {}
const CGuiPhysicalMsg& GetPhysicalMsg() const {return x0_msg;}
int GetTriggerId() const {return x10_triggerId;}
};
}

View File

@ -2,6 +2,7 @@
#include "CGuiFrame.hpp"
#include "CGuiSys.hpp"
#include "CSimplePool.hpp"
#include "CGuiAnimController.hpp"
namespace urde
{

View File

@ -35,6 +35,11 @@ void CGuiObject::MoveInWorld(const zeus::CVector3f& vec)
RecalculateTransforms();
}
void CGuiObject::SetLocalPosition(const zeus::CVector3f& pos)
{
MoveInWorld(pos - x4_localXF.m_origin);
}
void CGuiObject::RotateReset()
{
x4_localXF.m_basis = zeus::CMatrix3f::skIdentityMatrix3f;

View File

@ -28,6 +28,7 @@ public:
void MoveInWorld(const zeus::CVector3f& vec);
const zeus::CVector3f& GetLocalPosition() const {return x4_localXF.m_origin;}
void SetLocalPosition(const zeus::CVector3f& pos);
const zeus::CVector3f& GetWorldPosition() const {return x34_worldXF.m_origin;}
void SetRotationCenter(const zeus::CVector3f& center) {x64_rotationCenter = center;}
void RotateReset();

View File

@ -1,4 +1,6 @@
#include "CGuiPane.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{
@ -15,7 +17,7 @@ CGuiPane* CGuiPane::Create(CGuiFrame* frame, CInputStream& in, bool flag)
float a = in.readFloatBig();
float b = in.readFloatBig();
zeus::CVector3f vec;
vec.read(in);
vec.readBig(in);
return new CGuiPane(parms, a, b, vec);
}

View File

@ -23,16 +23,16 @@ void CGuiPhysicalMsg::SetMessage(const PhysicalMap& map, bool pressed)
else
x0_curStates &= ~physicalBit;
if (item.second.x4_pressed)
if (item.second.x4_active)
x8_repeatStates |= physicalBit;
else
x8_repeatStates &= ~physicalBit;
}
}
void CGuiPhysicalMsg::AddControllerID(PhysicalMap& map, EPhysicalControllerID key, bool pressed)
void CGuiPhysicalMsg::AddControllerID(PhysicalMap& map, EPhysicalControllerID key, bool active)
{
map.emplace(std::make_pair(key, CPhysicalID{key, pressed}));
map.emplace(std::make_pair(key, CPhysicalID{key, active}));
}
CGuiPhysicalMsg::ControllerState
@ -41,7 +41,7 @@ CGuiPhysicalMsg::FindControllerID(const PhysicalMap& map, EPhysicalControllerID
auto search = map.find(key);
if (search == map.cend())
return ControllerState::NotFound;
return search->second.x4_pressed ? ControllerState::Pressed : ControllerState::NotPressed;
return search->second.x4_active ? ControllerState::Pressed : ControllerState::NotPressed;
}
}

View File

@ -62,8 +62,8 @@ struct CGuiPhysicalMsg
struct CPhysicalID
{
EPhysicalControllerID x0_key;
bool x4_pressed;
CPhysicalID(EPhysicalControllerID key, bool pressed) : x0_key(key), x4_pressed(pressed) {}
bool x4_active;
CPhysicalID(EPhysicalControllerID key, bool active) : x0_key(key), x4_active(active) {}
};
using PhysicalMap = std::unordered_map<EPhysicalControllerID, CPhysicalID>;

View File

@ -1,4 +1,6 @@
#include "CGuiStaticImage.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{
@ -22,7 +24,7 @@ CGuiStaticImage* CGuiStaticImage::Create(CGuiFrame* frame, CInputStream& in, boo
std::vector<float> floats = {a, b, a, d, c, b, c, d};
zeus::CVector3f vec;
vec.read(in);
vec.readBig(in);
u32 e = in.readUint32Big();
u32 f = in.readUint32Big();
u32 g = in.readUint32Big();

View File

@ -27,7 +27,7 @@ void CGuiSys::LoadWidgetFunctions()
{
}
CGuiWidget* CGuiSys::CreateWidgetInGame(hecl::FourCC type, CInputStream& in, CGuiFrame* frame)
CGuiWidget* CGuiSys::CreateWidgetInGame(FourCC type, CInputStream& in, CGuiFrame* frame)
{
switch (type)
{

View File

@ -25,9 +25,9 @@ typedef CGuiObject*(*FGuiFactoryFunc)(const SObjectTag&, const CVParamTransfer&)
class CGuiFactoryMgr
{
friend class CGuiSys;
std::unordered_map<hecl::FourCC, FGuiFactoryFunc> m_factories;
std::unordered_map<FourCC, FGuiFactoryFunc> m_factories;
public:
void AddFactory(hecl::FourCC key, FGuiFactoryFunc func)
void AddFactory(FourCC key, FGuiFactoryFunc func)
{
m_factories[key] = func;
}
@ -55,7 +55,7 @@ private:
void AddFactories(EUsageMode mode);
void LoadWidgetFunctions();
CGuiWidget* CreateWidgetInGame(hecl::FourCC type, CInputStream& in, CGuiFrame* frame);
static CGuiWidget* CreateWidgetInGame(FourCC type, CInputStream& in, CGuiFrame* frame);
public:
CGuiSys(IFactory& resFactory, CSimplePool& resStore, EUsageMode mode);

View File

@ -1,4 +1,6 @@
#include "CGuiTextPane.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{
@ -17,7 +19,7 @@ CGuiTextPane* CGuiTextPane::Create(CGuiFrame* frame, CInputStream& in, bool flag
float a = in.readFloatBig();
float b = in.readFloatBig();
zeus::CVector3f vec;
vec.read(in);
vec.readBig(in);
u32 c = in.readUint32Big();
bool d = in.readBool();
bool e = in.readBool();
@ -25,9 +27,9 @@ CGuiTextPane* CGuiTextPane::Create(CGuiFrame* frame, CInputStream& in, bool flag
EVerticalJustification vJustification = EVerticalJustification(in.readUint32Big());
CGuiTextProperties props(d, e, 0, justification, vJustification);
zeus::CColor col1;
col1.readRGBA(in);
col1.readRGBABig(in);
zeus::CColor col2;
col2.readRGBA(in);
col2.readRGBABig(in);
int f = in.readFloatBig();
int g = in.readFloatBig();
return new CGuiTextPane(parms, a, b, vec, c, props, col1, col2, f, g);

View File

@ -1,8 +1,11 @@
#include "CGuiWidget.hpp"
#include "CGuiFrame.hpp"
#include "CGuiAnimController.hpp"
#include "CGuiLogicalEventTrigger.hpp"
namespace urde
{
static logvisor::Module Log("urde::CGuiWidget");
typedef bool(CGuiWidget::*FMAF)(CGuiFunctionDef* def, CGuiControllerInfo* info);
static std::unordered_map<u32, FMAF> WidgetFnMap;
@ -18,7 +21,16 @@ void CGuiWidget::LoadWidgetFnMap()
}
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_31_(true), xf7_24_(false), xf7_25_(true)
{
if (parms.x4_a)
EnsureHasAnimController();
RecalcWidgetColor(ETraversalMode::NonRecursive);
}
CGuiWidget::CGuiWidgetParms
@ -34,15 +46,229 @@ CGuiWidget::ReadWidgetHeader(CGuiFrame* frame, CInputStream& in, bool flag)
bool e = in.readBool();
bool f = in.readBool();
zeus::CColor color;
color.readRGBA(in);
color.readRGBABig(in);
EGuiModelDrawFlags df = EGuiModelDrawFlags(in.readUint32Big());
return CGuiWidget::CGuiWidgetParms(frame, a, selfId, parentId, d, e, f,
color, df, true, flag);
}
CGuiWidget* CGuiWidget::Create(CGuiFrame* frame, CInputStream& in, bool)
CGuiWidget* CGuiWidget::Create(CGuiFrame* frame, CInputStream& in, bool flag)
{
CGuiWidgetParms parms = ReadWidgetHeader(frame, in, flag);
CGuiWidget* ret = new CGuiWidget(parms);
ret->ParseBaseInfo(frame, in, parms);
return ret;
}
void CGuiWidget::ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms)
{
CGuiWidget* parent = frame->FindWidget(parms.x8_parentId);
bool a = in.readBool();
if (a)
xf4_workerId = in.readInt16Big();
zeus::CVector3f trans;
trans.readBig(in);
zeus::CMatrix3f orient;
orient.readBig(in);
x80_transform = zeus::CTransform(orient, trans);
ReapplyXform();
zeus::CVector3f rotCenter;
rotCenter.readBig(in);
SetRotationCenter(rotCenter);
ParseMessages(in, parms);
ParseAnimations(in, parms);
if (a)
if (!parent->AddWorkerWidget(this))
{
Log.report(logvisor::Warning,
"Warning: Discarding useless worker id. Parent is not a compound widget.");
xf4_workerId = -1;
}
parent->AddChildWidget(this, false, true);
}
void CGuiWidget::ParseMessages(CInputStream& in, const CGuiWidgetParms& parms)
{
s16 count = in.readInt16Big();
assert(count == 0);
count = in.readInt16Big();
assert(count == 0);
}
void CGuiWidget::ParseAnimations(CInputStream& in, const CGuiWidgetParms& parms)
{
s16 count = in.readInt16Big();
assert(count == 0);
}
void CGuiWidget::ReapplyXform()
{
RotateReset();
SetLocalPosition(zeus::CVector3f::skZero);
MultiplyO2P(x80_transform);
}
void CGuiWidget::EnsureHasAnimController()
{
if (!xb0_animController)
{
xb0_animController.reset(new CGuiAnimController(
CGuiWidgetParms(xc8_frame, false, -1, -1, true, false, false,
zeus::CColor::skWhite, EGuiModelDrawFlags::Two,
true, false), this));
}
}
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* CGuiWidget::FindTriggerList(int id)
{
auto search = xcc_functionMap.find(id);
if (search == xcc_functionMap.cend())
return nullptr;
return &search->second;
}
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_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()
{
bool flag = DoUnregisterEventHandler();
if (!flag)
{
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
if (ch)
ch->UnregisterEventHandler();
}
CGuiWidget* sib = static_cast<CGuiWidget*>(GetNextSibling());
if (sib && flag)
sib->UnregisterEventHandler();
}
void CGuiWidget::UnregisterEventHandler(ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Recursive:
if (!DoUnregisterEventHandler())
{
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
if (ch)
ch->UnregisterEventHandler();
}
break;
case ETraversalMode::NonRecursive:
DoUnregisterEventHandler();
break;
default:
UnregisterEventHandler();
break;
}
}
bool CGuiWidget::DoUnregisterEventHandler()
{
for (auto& item : xcc_functionMap)
for (std::unique_ptr<CGuiLogicalEventTrigger>& trigger : item.second)
xc8_frame->ClearMessageMap(trigger.get(), x7c_selfId);
return false;
}
void CGuiWidget::RegisterEventHandler()
{
bool flag = DoRegisterEventHandler();
if (!flag)
{
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
if (ch)
ch->RegisterEventHandler();
}
CGuiWidget* sib = static_cast<CGuiWidget*>(GetNextSibling());
if (sib && flag)
sib->RegisterEventHandler();
}
void CGuiWidget::RegisterEventHandler(ETraversalMode mode)
{
switch (mode)
{
case ETraversalMode::Recursive:
if (!DoRegisterEventHandler())
{
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
if (ch)
ch->RegisterEventHandler();
}
break;
case ETraversalMode::NonRecursive:
DoRegisterEventHandler();
break;
default:
RegisterEventHandler();
break;
}
}
bool CGuiWidget::DoRegisterEventHandler()
{
if (xf6_28_ || !GetIsActive())
return false;
for (auto& item : xcc_functionMap)
for (std::unique_ptr<CGuiLogicalEventTrigger>& trigger : item.second)
xc8_frame->AddMessageMap(trigger.get(), x7c_selfId);
return false;
}
void CGuiWidget::Initialize() {}
void CGuiWidget::InitializeRecursive()
{
Initialize();
CGuiWidget* ch = static_cast<CGuiWidget*>(GetChildObject());
if (ch)
ch->InitializeRecursive();
CGuiWidget* sib = static_cast<CGuiWidget*>(GetNextSibling());
if (sib)
sib->InitializeRecursive();
}
void CGuiWidget::SetColor(const zeus::CColor& color)
{
xbc_color = color;
RecalcWidgetColor(ETraversalMode::Recursive);
}
void CGuiWidget::OnDeActivate() {}
void CGuiWidget::OnActivate(bool) {}
void CGuiWidget::OnInvisible() {}
void CGuiWidget::OnVisible() {}
void CGuiWidget::SetIsActive(bool a, bool b)
{
if (a == xf6_26_isActive)
return;
xf6_26_isActive = a;
if (a)
{
RegisterEventHandler(ETraversalMode::Recursive);
OnActivate(b);
}
else
{
RegisterEventHandler(ETraversalMode::Recursive);
OnDeActivate();
}
}
bool CGuiWidget::MAF_StartAnimationSet(CGuiFunctionDef* def, CGuiControllerInfo* info)

View File

@ -3,6 +3,7 @@
#include "IOStreams.hpp"
#include "CGuiObject.hpp"
#include "CGuiFunctionDef.hpp"
#include "zeus/CColor.hpp"
namespace urde
@ -10,6 +11,8 @@ namespace urde
class CGuiAnimBase;
class CGuiFrame;
class CGuiMessage;
class CGuiAnimController;
class CGuiLogicalEventTrigger;
enum class EGuiAnimBehListID
{
@ -17,6 +20,8 @@ enum class EGuiAnimBehListID
enum class ETraversalMode
{
Recursive = 1,
NonRecursive = 2
};
enum class EGuiAnimInitMode
@ -33,6 +38,7 @@ enum class EGuiTextureClampModeVert
class CGuiWidget : public CGuiObject
{
friend class CGuiFrame;
public:
enum class EGuiModelDrawFlags
{
@ -45,20 +51,48 @@ public:
s16 x6_selfId;
s16 x8_parentId;
bool xa_d;
bool xb_e;
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 e, 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), xb_e(e), xc_f(f),
xd_g(g), xe_h(h), x10_color(color), x14_drawFlags(drawFlags) {}
CGuiWidgetParms(CGuiFrame* frame, bool a, s16 selfId, s16 parentId, bool d, 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),
xb_defaultActive(defaultActive), xc_f(f), xd_g(g), xe_h(h), x10_color(color),
x14_drawFlags(drawFlags) {}
};
static void LoadWidgetFnMap();
virtual hecl::FourCC GetWidgetTypeID() const {return hecl::FOURCC('BWIG');}
virtual FourCC GetWidgetTypeID() const {return hecl::FOURCC('BWIG');}
private:
s16 x7c_selfId;
s16 x7e_parentId;
zeus::CTransform x80_transform;
std::unique_ptr<CGuiAnimController> xb0_animController;
zeus::CColor xb4_ = zeus::CColor::skWhite;
zeus::CColor xb8_ = zeus::CColor::skClear;
zeus::CColor xbc_color;
zeus::CColor xc0_color2;
EGuiModelDrawFlags xc4_drawFlags;
CGuiFrame* xc8_frame;
std::unordered_map<int, std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>> xcc_functionMap;
u32 xe4_ = 0;
u32 xe8_ = 0;
u32 xec_ = 0;
u32 xf0_ = 0;
s16 xf4_workerId = -1;
bool xf6_24_pg : 1;
bool xf6_25_pd : 1;
bool xf6_26_isActive : 1;
bool xf6_27_ : 1;
bool xf6_28_ : 1;
bool xf6_29_pf : 1;
bool xf6_30_ : 1;
bool xf6_31_ : 1;
bool xf7_24_ : 1;
bool xf7_25_ : 1;
public:
CGuiWidget(const CGuiWidgetParms& parms);
@ -76,21 +110,21 @@ public:
virtual void Initialize();
virtual void Touch() const;
virtual void GetIsVisible() const;
virtual void GetIsActive() const;
virtual bool GetIsActive() const;
virtual void TextSupport();
virtual void 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 AddWorkerWidget(CGuiWidget* worker);
virtual bool AddWorkerWidget(CGuiWidget* worker);
virtual void GetFinishedLoadingWidgetSpecific() const;
virtual void OnVisible();
virtual void OnInvisible();
virtual void OnActivate(bool);
virtual void OnDeActivate();
virtual void DoRegisterEventHandler();
virtual void DoUnregisterEventHandler();
virtual bool DoRegisterEventHandler();
virtual bool DoUnregisterEventHandler();
void AddFunctionDef(u32, CGuiFunctionDef* def);
void FindFunctionDefList(int);
@ -99,6 +133,9 @@ public:
void ReapplyXform();
void SetIsVisible(bool);
void SetIsActive(bool, bool);
void EnsureHasAnimController();
std::vector<std::unique_ptr<CGuiLogicalEventTrigger>>* FindTriggerList(int);
void AddTrigger(std::unique_ptr<CGuiLogicalEventTrigger>&& trigger);
void BroadcastMessage(int, CGuiControllerInfo* info);
void LockEvents(bool);

@ -1 +1 @@
Subproject commit ce321d80fe2b8d5d20a8f4bfce7718700c7e2809
Subproject commit 6ce9df20fa041d9a4bc52bc6e5628c2763222465