mirror of https://github.com/AxioDL/metaforce.git
652 lines
22 KiB
C++
652 lines
22 KiB
C++
#include "CGuiFrame.hpp"
|
|
#include "CGuiWidget.hpp"
|
|
#include "CGuiSys.hpp"
|
|
#include "CGuiHeadWidget.hpp"
|
|
#include "CGuiAnimController.hpp"
|
|
#include "CGuiMessage.hpp"
|
|
#include "CGuiLight.hpp"
|
|
#include "CGuiCamera.hpp"
|
|
#include "Graphics/CGraphics.hpp"
|
|
#include "Input/CFinalInput.hpp"
|
|
#include "zeus/CColor.hpp"
|
|
|
|
namespace urde
|
|
{
|
|
|
|
CGuiFrame::CGuiFrame(ResId 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_loaded(false)
|
|
{
|
|
xa0_lights.resize(8);
|
|
x48_rootWidget.reset(new CGuiWidget(
|
|
CGuiWidget::CGuiWidgetParms(this, false, 0, 0, false, false, false, zeus::CColor::skWhite,
|
|
CGuiWidget::EGuiModelDrawFlags::Alpha, 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;
|
|
}
|
|
|
|
void CGuiFrame::InterpretGUIControllerState(const CFinalInput& input,
|
|
CGuiPhysicalMsg::PhysicalMap& state,
|
|
char& lx, char& ly, char& rx, char& ry)
|
|
{
|
|
zeus::CVector2f left(std::fabs(input.ALeftX()), std::fabs(input.ALeftY()));
|
|
bool leftThreshold = false;
|
|
if (left.magnitude() >= 0.6f)
|
|
leftThreshold = true;
|
|
|
|
zeus::CVector2f right(std::fabs(input.ARightX()), std::fabs(input.ARightY()));
|
|
bool rightThreshold = false;
|
|
if (right.magnitude() >= 0.6f)
|
|
rightThreshold = true;
|
|
|
|
if (leftThreshold)
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickThreshold, false);
|
|
|
|
if (input.ALeftX() < 0.f)
|
|
lx = input.ALeftX() * 128.f;
|
|
else
|
|
lx = input.ALeftX() * 127.f;
|
|
|
|
if (input.ALeftY() < 0.f)
|
|
ly = input.ALeftY() * 128.f;
|
|
else
|
|
ly = input.ALeftY() * 127.f;
|
|
|
|
if (0.7f < input.ALeftY())
|
|
{
|
|
if (input.PLAUp())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickUpInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftUpInst, false);
|
|
}
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickUp, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftUp, false);
|
|
}
|
|
|
|
if (-0.7f > input.ALeftY())
|
|
{
|
|
if (input.PLADown())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickDownInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftDownInst, false);
|
|
}
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickDown, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftDown, false);
|
|
}
|
|
|
|
if (0.7f < input.ALeftX())
|
|
{
|
|
if (input.PLARight())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickRightInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftRightInst, false);
|
|
}
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickRight, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftRight, false);
|
|
}
|
|
|
|
if (-0.7f > input.ALeftX())
|
|
{
|
|
if (input.PLALeft())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickLeftInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftLeftInst, false);
|
|
}
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickLeft, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftLeft, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftStickRelease, false);
|
|
lx = 0;
|
|
ly = 0;
|
|
}
|
|
|
|
if (rightThreshold)
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickThreshold, false);
|
|
|
|
if (input.ARightX() < 0.f)
|
|
rx = input.ARightX() * 128.f;
|
|
else
|
|
rx = input.ARightX() * 127.f;
|
|
|
|
if (input.ARightY() < 0.f)
|
|
ry = input.ARightY() * 128.f;
|
|
else
|
|
ry = input.ARightY() * 127.f;
|
|
|
|
if (0.7f < input.ARightY())
|
|
{
|
|
if (input.PRAUp())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickUpInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickUp, false);
|
|
}
|
|
|
|
if (-0.7f > input.ARightY())
|
|
{
|
|
if (input.PRADown())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickDownInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickDown, false);
|
|
}
|
|
|
|
if (0.7f < input.ARightX())
|
|
{
|
|
if (input.PRARight())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickRightInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickRight, false);
|
|
}
|
|
|
|
if (-0.7f > input.ARightX())
|
|
{
|
|
if (input.PRALeft())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickLeftInst, false);
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickLeft, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RightStickRelease, false);
|
|
rx = 0;
|
|
ry = 0;
|
|
}
|
|
|
|
if (input.PDPUp())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadUpInst, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftUpInst, false);
|
|
}
|
|
else if (input.DDPUp())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadUp, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftUp, false);
|
|
}
|
|
|
|
if (input.PDPDown())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadDownInst, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftDownInst, false);
|
|
}
|
|
else if (input.DDPDown())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadDown, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftDown, false);
|
|
}
|
|
|
|
if (input.PDPRight())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadRightInst, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftRightInst, false);
|
|
}
|
|
else if (input.DDPRight())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadRight, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftRight, false);
|
|
}
|
|
|
|
if (input.PDPLeft())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadLeftInst, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftLeftInst, false);
|
|
}
|
|
else if (input.DDPLeft())
|
|
{
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::DPadLeft, false);
|
|
if (leftThreshold)
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LeftLeft, false);
|
|
}
|
|
|
|
if (input.PStart())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::StartInst, false);
|
|
if (input.DStart())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::Start, false);
|
|
|
|
if (input.PB())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::BInst, false);
|
|
if (input.DB())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::B, false);
|
|
|
|
if (input.PA())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::AInst, false);
|
|
if (input.DA())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::A, false);
|
|
|
|
if (input.PX())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::XInst, false);
|
|
if (input.DX())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::X, false);
|
|
|
|
if (input.PY())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::YInst, false);
|
|
if (input.DY())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::Y, false);
|
|
|
|
if (input.PZ())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::ZInst, false);
|
|
if (input.DZ())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::Z, false);
|
|
|
|
if (input.PLTrigger())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::LInst, false);
|
|
if (input.DLTrigger())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::L, false);
|
|
|
|
if (input.PRTrigger())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::RInst, false);
|
|
if (input.DRTrigger())
|
|
CGuiPhysicalMsg::AddControllerID(state, EPhysicalControllerID::R, 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();
|
|
}
|
|
|
|
bool CGuiFrame::SendWidgetMessage(s16 id,
|
|
std::list<std::unique_ptr<CGuiFrameMessageMapNode>>& list,
|
|
CGuiPhysicalMsg::PhysicalMap& state,
|
|
CGuiControllerInfo::CGuiControllerStateInfo& csInfo)
|
|
{
|
|
CGuiWidget* widget = FindWidget(id);
|
|
for (std::unique_ptr<CGuiFrameMessageMapNode>& node : list)
|
|
{
|
|
CGuiMessage msg(CGuiMessage::Type(node->GetTrigger().GetTriggerId()),
|
|
reinterpret_cast<intptr_t>(&state),
|
|
reinterpret_cast<intptr_t>(&csInfo));
|
|
if (!widget->Message(msg))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CGuiFrame::ClearAllMessageMap()
|
|
{
|
|
x7c_messageMap.clear();
|
|
}
|
|
|
|
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::EnableLights(u32 lights) const
|
|
{
|
|
CGraphics::DisableAllLights();
|
|
zeus::CColor accumColor(zeus::CColor::skBlack);
|
|
ERglLight lightId = ERglLight::Zero;
|
|
int idx = 0;
|
|
for (CGuiLight* light : xa0_lights)
|
|
{
|
|
if ((lights & (1 << idx)) != 0)
|
|
{
|
|
// accumulate color
|
|
accumColor += light->GetColor();
|
|
CGraphics::LoadLight(lightId, light->BuildLight());
|
|
CGraphics::EnableLight(lightId);
|
|
}
|
|
++reinterpret_cast<std::underlying_type_t<ERglLight>&>(lightId);
|
|
++idx;
|
|
}
|
|
if (xa0_lights.empty())
|
|
CGraphics::SetAmbientColor(zeus::CColor::skWhite);
|
|
else
|
|
CGraphics::SetAmbientColor(accumColor);
|
|
}
|
|
|
|
void CGuiFrame::DisableLights() const
|
|
{
|
|
CGraphics::DisableAllLights();
|
|
}
|
|
|
|
void CGuiFrame::RemoveLight(CGuiLight* light)
|
|
{
|
|
xa0_lights[light->GetLoadedIdx()] = nullptr;
|
|
}
|
|
|
|
void CGuiFrame::AddLight(CGuiLight* light)
|
|
{
|
|
xa0_lights[light->GetLoadedIdx()] = light;
|
|
}
|
|
|
|
bool CGuiFrame::GetIsFinishedLoading() const
|
|
{
|
|
if (xbc_24_loaded)
|
|
return true;
|
|
for (const CGuiWidget* widget : x90_widgets)
|
|
{
|
|
if (widget->GetIsFinishedLoading())
|
|
continue;
|
|
return false;
|
|
}
|
|
const_cast<CGuiFrame*>(this)->xbc_24_loaded = true;
|
|
return true;
|
|
}
|
|
|
|
void CGuiFrame::Touch() const
|
|
{
|
|
for (const CGuiWidget* widget : x90_widgets)
|
|
widget->Touch();
|
|
}
|
|
|
|
void CGuiFrame::ProcessControllerInput(const CFinalInput& input)
|
|
{
|
|
if (x18_ & 0x4 && input.ControllerIdx() == 0)
|
|
{
|
|
CGuiPhysicalMsg::PhysicalMap state;
|
|
CGuiControllerInfo::CGuiControllerStateInfo stateInfo;
|
|
stateInfo.cIdx = input.ControllerIdx();
|
|
InterpretGUIControllerState(input, state, stateInfo.lx, stateInfo.ly, stateInfo.rx, stateInfo.ry);
|
|
float eventTime = std::chrono::duration_cast<std::chrono::microseconds>(
|
|
std::chrono::steady_clock::now() - x3c_guiSys.x40_constructTime).count() / 1000000.f;
|
|
|
|
for (const std::pair<EPhysicalControllerID, CGuiPhysicalMsg::CPhysicalID>& newPair : state)
|
|
{
|
|
auto search = x3c_guiSys.GetRepeatMap().find(newPair.first);
|
|
if (search != x3c_guiSys.GetRepeatMap().end())
|
|
search->second.SetActive(input.ControllerIdx(), eventTime);
|
|
}
|
|
|
|
for (std::pair<const EPhysicalControllerID, CGuiAutoRepeatData>& pair : x3c_guiSys.GetRepeatMap())
|
|
{
|
|
pair.second.AddAutoEvent(input.ControllerIdx(), state, eventTime);
|
|
}
|
|
|
|
CGuiPhysicalMsg msg(state);
|
|
SetControllerStatus(input.ControllerIdx(), true);
|
|
|
|
for (std::pair<const u64, std::unique_ptr<WidgetToLogicalEventMap>>& outer : x7c_messageMap)
|
|
{
|
|
if (outer.second)
|
|
{
|
|
for (std::pair<const s16, std::unique_ptr<LogicalEventList>>& inner : *outer.second)
|
|
{
|
|
if (inner.second && inner.second->size())
|
|
{
|
|
LogicalEventList& list = *inner.second;
|
|
if (msg.Exists(list.back()->GetTrigger().GetPhysicalMsg()))
|
|
if (!SendWidgetMessage(inner.first, list, state, stateInfo))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CGuiFrame::Update(float dt)
|
|
{
|
|
if (x34_ != EFrameStates::Four)
|
|
return false;
|
|
if (x18_ & 2)
|
|
{
|
|
EGuiAnimBehListID listId = EGuiAnimBehListID::NegOne;
|
|
bool something = true;
|
|
x44_headWidget->InitializeRGBAFactor();
|
|
x44_headWidget->Update(dt);
|
|
x44_headWidget->RecalculateAllRGBA();
|
|
switch (x34_)
|
|
{
|
|
case EFrameStates::One:
|
|
if (!xbd_flag2)
|
|
{
|
|
CGuiControllerInfo cInfo;
|
|
x44_headWidget->BroadcastMessage(0, &cInfo);
|
|
xbd_flag2 = true;
|
|
}
|
|
break;
|
|
case EFrameStates::Three:
|
|
listId = EGuiAnimBehListID::One;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (listId != EGuiAnimBehListID::NegOne)
|
|
x44_headWidget->IsAllAnimsDone(listId, something, ETraversalMode::ChildrenAndSiblings);
|
|
|
|
if (something)
|
|
{
|
|
switch (x34_)
|
|
{
|
|
case EFrameStates::One:
|
|
{
|
|
x34_ = x38_;
|
|
x44_headWidget->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::Single);
|
|
x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false,
|
|
EGuiAnimInitMode::Five, ETraversalMode::Single);
|
|
CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling());
|
|
if (camSib)
|
|
{
|
|
camSib->SetAnimUpdateState(EGuiAnimBehListID::Zero, false, ETraversalMode::ChildrenAndSiblings);
|
|
camSib->InitializeAnimControllers(EGuiAnimBehListID::Two, 0.f, false,
|
|
EGuiAnimInitMode::Five, ETraversalMode::ChildrenAndSiblings);
|
|
}
|
|
xbd_flag2 = false;
|
|
break;
|
|
}
|
|
case EFrameStates::Three:
|
|
{
|
|
CGuiControllerInfo cInfo;
|
|
x44_headWidget->BroadcastMessage(1, &cInfo);
|
|
ClearAllMessageMap();
|
|
x18_ &= ~0x3;
|
|
x44_headWidget->ResetAllAnimUpdateState();
|
|
xbd_flag2 = false;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return x34_ != EFrameStates::Zero;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CGuiFrame::Draw(const CGuiWidgetDrawParms& parms) const
|
|
{
|
|
if (x18_)
|
|
{
|
|
CGraphics::SetCullMode(ERglCullMode::None);
|
|
CGraphics::SetAmbientColor(zeus::CColor::skWhite);
|
|
DisableLights();
|
|
x4c_camera->Draw(parms);
|
|
// Set one-stage modulate
|
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
|
|
ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
|
|
if (x50_background)
|
|
x50_background->Draw(parms);
|
|
|
|
for (const CGuiWidget* widget : x90_widgets)
|
|
if (widget->GetIsVisible())
|
|
widget->Draw(parms);
|
|
}
|
|
CGraphics::SetCullMode(ERglCullMode::Front);
|
|
}
|
|
|
|
void CGuiFrame::Stop(const CGuiFrameTransitionOptions& transOpts, EFrameStates states, bool flag)
|
|
{
|
|
x18_ &= 0xFFFFFFFB;
|
|
x38_ = states;
|
|
if (flag)
|
|
x34_ = x38_;
|
|
else
|
|
{
|
|
x44_headWidget->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true,
|
|
EGuiAnimInitMode::Two, ETraversalMode::Single);
|
|
CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling());
|
|
if (camSib)
|
|
{
|
|
camSib->InitializeAnimControllers(EGuiAnimBehListID::One, transOpts.xc_, true,
|
|
EGuiAnimInitMode::Two, ETraversalMode::ChildrenAndSiblings);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CGuiFrame::Run(CGuiFrame* frame, const CGuiFrameTransitionOptions& transOpts,
|
|
EFrameStates states, bool flag)
|
|
{
|
|
ResetControllerStatus();
|
|
x34_ = EFrameStates::One;
|
|
x38_ = EFrameStates::Two;
|
|
float len = 0.f;
|
|
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::Single);
|
|
CGuiWidget* camSib = static_cast<CGuiWidget*>(x4c_camera->GetNextSibling());
|
|
if (camSib)
|
|
{
|
|
camSib->InitializeAnimControllers(EGuiAnimBehListID::Zero, len, true,
|
|
EGuiAnimInitMode::One, ETraversalMode::ChildrenAndSiblings);
|
|
}
|
|
x18_ |= 0x7;
|
|
x44_headWidget->RegisterEventHandler(ETraversalMode::ChildrenAndSiblings);
|
|
}
|
|
|
|
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(ResId 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::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in,
|
|
const CVParamTransfer&,
|
|
CObjectReference* selfRef)
|
|
{
|
|
std::unique_ptr<CGuiFrame> frame(CGuiFrame::CreateFrame(tag.id, *g_GuiSys, in));
|
|
return TToken<CGuiFrame>::GetIObjObjectFor(std::move(frame));
|
|
}
|
|
|
|
std::string CGuiFrame::CreateFrameName(ResId frmeId)
|
|
{
|
|
/* formatting token originally "frame_%x" for 32-bit ids */
|
|
return hecl::Format("frame_%016" PRIX64, frmeId);
|
|
}
|
|
|
|
|
|
}
|