2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 21:11:21 +00:00
metaforce/Runtime/GuiSys/CGuiFrame.cpp
2016-03-13 14:58:19 -10:00

159 lines
4.4 KiB
C++

#include "CGuiFrame.hpp"
#include "CGuiWidget.hpp"
#include "CGuiSys.hpp"
#include "CGuiHeadWidget.hpp"
#include "CGuiAnimController.hpp"
#include "zeus/CColor.hpp"
namespace urde
{
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)
{
xa0_lights.resize(8);
x48_rootWidget.reset(new CGuiWidget(
CGuiWidget::CGuiWidgetParms(this, false, 0, 0, false, false, false, zeus::CColor::skWhite,
CGuiWidget::EGuiModelDrawFlags::Two, false,
x3c_guiSys.x2c_mode != CGuiSys::EUsageMode::Zero)));
}
CGuiWidget* CGuiFrame::FindWidget(const std::string& name) const
{
s16 id = x64_idDB.FindWidgetID(name);
if (id == -1)
return nullptr;
return FindWidget(id);
}
CGuiWidget* CGuiFrame::FindWidget(s16 id) const
{
return x48_rootWidget->FindWidget(id);
}
void CGuiFrame::ResetControllerStatus()
{
x0_controllerStatus[0] = false;
x0_controllerStatus[1] = false;
x0_controllerStatus[2] = false;
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);
}
}