metaforce/Runtime/GuiSys/CGuiFrame.cpp

244 lines
6.5 KiB
C++
Raw Normal View History

2016-03-11 05:32:18 +00:00
#include "CGuiFrame.hpp"
2016-03-11 22:50:15 +00:00
#include "CGuiWidget.hpp"
#include "CGuiSys.hpp"
2016-03-14 00:58:19 +00:00
#include "CGuiHeadWidget.hpp"
2016-03-15 04:55:57 +00:00
#include "CGuiLight.hpp"
#include "CGuiCamera.hpp"
#include "Graphics/CGraphics.hpp"
2016-03-14 23:32:44 +00:00
#include "Input/CFinalInput.hpp"
2016-03-11 22:50:15 +00:00
#include "zeus/CColor.hpp"
#include "CSimplePool.hpp"
2017-04-13 19:28:31 +00:00
#include "Graphics/CModel.hpp"
2016-03-11 05:32:18 +00:00
namespace urde
{
2017-08-13 05:26:14 +00:00
CGuiFrame::CGuiFrame(CAssetId id, CGuiSys& sys, int a, int b, int c, CSimplePool* sp)
: x0_id(id), x8_guiSys(sys), x4c_a(a), x50_b(b), x54_c(c), x58_24_loaded(false)
2016-03-11 05:32:18 +00:00
{
2017-03-20 05:09:53 +00:00
x3c_lights.reserve(8);
m_indexedLights.reserve(8);
x10_rootWidget.reset(new CGuiWidget(
2016-03-11 22:50:15 +00:00
CGuiWidget::CGuiWidgetParms(this, false, 0, 0, false, false, false, zeus::CColor::skWhite,
2016-03-17 22:19:25 +00:00
CGuiWidget::EGuiModelDrawFlags::Alpha, false,
x8_guiSys.x8_mode != CGuiSys::EUsageMode::Zero)));
2017-01-30 04:16:20 +00:00
x8_guiSys.m_registeredFrames.insert(this);
}
CGuiFrame::~CGuiFrame()
{
x8_guiSys.m_registeredFrames.erase(this);
2016-03-11 05:32:18 +00:00
}
2017-11-13 06:19:18 +00:00
CGuiWidget* CGuiFrame::FindWidget(std::string_view name) const
{
s16 id = x18_idDB.FindWidgetID(name);
if (id == -1)
return nullptr;
return FindWidget(id);
}
CGuiWidget* CGuiFrame::FindWidget(s16 id) const
{
return x10_rootWidget->FindWidget(id);
2016-03-14 00:58:19 +00:00
}
void CGuiFrame::SortDrawOrder()
{
std::sort(x2c_widgets.begin(), x2c_widgets.end(),
[](const std::shared_ptr<CGuiWidget>& a, const std::shared_ptr<CGuiWidget>& b) -> bool
2016-03-14 00:58:19 +00:00
{
2017-01-30 04:16:20 +00:00
return a->GetWorldPosition().y > b->GetWorldPosition().y;
2016-03-14 00:58:19 +00:00
});
}
2017-04-13 19:28:31 +00:00
void CGuiFrame::EnableLights(u32 lights, CBooModel& model) const
2016-03-15 04:55:57 +00:00
{
2017-04-13 19:28:31 +00:00
std::vector<CLight> lightsOut;
lightsOut.reserve(m_indexedLights.size() + 1);
2016-03-15 04:55:57 +00:00
CGraphics::DisableAllLights();
2017-04-13 19:28:31 +00:00
zeus::CColor ambColor(zeus::CColor::skBlack);
2016-03-15 04:55:57 +00:00
ERglLight lightId = ERglLight::Zero;
2016-03-17 02:18:01 +00:00
int idx = 0;
2017-04-13 19:28:31 +00:00
for (CGuiLight* light : m_indexedLights)
2016-03-15 04:55:57 +00:00
{
2017-04-13 19:28:31 +00:00
if (!light || !light->GetIsVisible())
2017-03-20 05:09:53 +00:00
{
++reinterpret_cast<std::underlying_type_t<ERglLight>&>(lightId);
++idx;
continue;
}
2016-03-17 02:18:01 +00:00
if ((lights & (1 << idx)) != 0)
{
2017-04-13 19:28:31 +00:00
const zeus::CColor& geomCol = light->GetGeometryColor();
if (geomCol.r || geomCol.g || geomCol.b)
{
//CGraphics::LoadLight(lightId, light->BuildLight());
lightsOut.push_back(light->BuildLight());
CGraphics::EnableLight(lightId);
}
// accumulate ambient color
ambColor += light->GetAmbientLightColor();
2016-03-17 02:18:01 +00:00
}
2016-03-15 04:55:57 +00:00
++reinterpret_cast<std::underlying_type_t<ERglLight>&>(lightId);
2016-03-17 02:18:01 +00:00
++idx;
2016-03-15 04:55:57 +00:00
}
2017-11-18 03:35:37 +00:00
if (lightsOut.empty())
2017-04-13 19:28:31 +00:00
{
//CGraphics::SetAmbientColor(zeus::CColor::skWhite);
lightsOut.push_back(CLight::BuildLocalAmbient(zeus::CVector3f::skZero, zeus::CColor::skWhite));
}
2016-03-15 04:55:57 +00:00
else
2017-04-13 19:28:31 +00:00
{
//CGraphics::SetAmbientColor(ambColor);
lightsOut.push_back(CLight::BuildLocalAmbient(zeus::CVector3f::skZero, ambColor));
}
model.ActivateLights(lightsOut);
2016-03-15 04:55:57 +00:00
}
void CGuiFrame::DisableLights() const
{
CGraphics::DisableAllLights();
}
void CGuiFrame::RemoveLight(CGuiLight* light)
{
2017-10-24 03:12:10 +00:00
if (m_indexedLights.empty())
return;
2017-06-03 06:03:07 +00:00
m_indexedLights[light->GetLightId()] = nullptr;
2017-03-20 05:09:53 +00:00
}
void CGuiFrame::AddLight(CGuiLight* light)
{
2017-10-24 03:12:10 +00:00
if (m_indexedLights.empty())
m_indexedLights.resize(8);
2017-06-03 06:03:07 +00:00
m_indexedLights[light->GetLightId()] = light;
2016-03-15 04:55:57 +00:00
}
2017-03-20 05:09:53 +00:00
void CGuiFrame::RegisterLight(std::shared_ptr<CGuiLight>&& light)
2016-03-15 04:55:57 +00:00
{
2017-03-20 05:09:53 +00:00
x3c_lights.push_back(std::move(light));
2016-03-15 04:55:57 +00:00
}
bool CGuiFrame::GetIsFinishedLoading() const
{
if (x58_24_loaded)
2016-03-15 04:55:57 +00:00
return true;
for (const auto& widget : x2c_widgets)
2016-03-15 04:55:57 +00:00
{
if (widget->GetIsFinishedLoading())
continue;
return false;
}
const_cast<CGuiFrame*>(this)->x58_24_loaded = true;
2016-03-15 04:55:57 +00:00
return true;
}
void CGuiFrame::Touch() const
{
for (const auto& widget : x2c_widgets)
2016-03-15 04:55:57 +00:00
widget->Touch();
}
2017-01-30 04:16:20 +00:00
void CGuiFrame::SetAspectConstraint(float c)
{
m_aspectConstraint = c;
CGuiSys::ViewportResizeFrame(this);
}
void CGuiFrame::SetMaxAspect(float c)
{
m_maxAspect = c;
CGuiSys::ViewportResizeFrame(this);
}
void CGuiFrame::Update(float dt)
2016-03-14 23:32:44 +00:00
{
xc_headWidget->Update(dt);
2016-03-15 04:55:57 +00:00
}
void CGuiFrame::Draw(const CGuiWidgetDrawParms& parms) const
{
2017-01-29 03:58:16 +00:00
CGraphics::SetCullMode(ERglCullMode::None);
CGraphics::SetAmbientColor(zeus::CColor::skWhite);
DisableLights();
x14_camera->Draw(parms);
// Set one-stage modulate
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
for (const auto& widget : x2c_widgets)
if (widget->GetIsVisible())
widget->Draw(parms);
2016-03-15 04:55:57 +00:00
CGraphics::SetCullMode(ERglCullMode::Front);
}
2016-03-14 00:58:19 +00:00
void CGuiFrame::Initialize()
{
SortDrawOrder();
xc_headWidget->SetColor(xc_headWidget->xa4_color);
2016-12-16 04:35:49 +00:00
xc_headWidget->DispatchInitialize();
2016-03-14 00:58:19 +00:00
}
void CGuiFrame::LoadWidgetsInGame(CInputStream& in, CSimplePool* sp)
2016-03-14 00:58:19 +00:00
{
u32 count = in.readUint32Big();
x2c_widgets.reserve(count);
2016-03-14 00:58:19 +00:00
for (u32 i=0 ; i<count ; ++i)
{
DataSpec::DNAFourCC type;
type.read(in);
std::shared_ptr<CGuiWidget> widget = CGuiSys::CreateWidgetInGame(type, in, this, sp);
2016-03-14 00:58:19 +00:00
type = widget->GetWidgetTypeID();
switch (type)
{
case SBIG('CAMR'):
case SBIG('LITE'):
case SBIG('BGND'):
break;
default:
x2c_widgets.push_back(std::move(widget));
2016-03-14 00:58:19 +00:00
break;
}
}
Initialize();
}
2016-12-16 04:35:49 +00:00
void CGuiFrame::ProcessUserInput(const CFinalInput& input) const
{
2017-01-29 03:58:16 +00:00
if (input.ControllerIdx() != 0)
2016-12-16 04:35:49 +00:00
return;
for (auto& widget : x2c_widgets)
2016-12-16 04:35:49 +00:00
{
if (widget->GetIsActive())
widget->ProcessUserInput(input);
}
}
2017-08-13 05:26:14 +00:00
std::unique_ptr<CGuiFrame> CGuiFrame::CreateFrame(CAssetId frmeId, CGuiSys& sys, CInputStream& in, CSimplePool* sp)
2016-03-14 00:58:19 +00:00
{
in.readInt32Big();
int a = in.readInt32Big();
int b = in.readInt32Big();
int c = in.readInt32Big();
std::unique_ptr<CGuiFrame> ret = std::make_unique<CGuiFrame>(frmeId, sys, a, b, c, sp);
ret->LoadWidgetsInGame(in, sp);
2016-03-14 00:58:19 +00:00
return ret;
}
2016-03-16 20:49:35 +00:00
std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& cvParms,
CObjectReference* selfRef)
2016-03-16 20:49:35 +00:00
{
2016-12-23 06:41:39 +00:00
CSimplePool* sp = cvParms.GetOwnedObj<CSimplePool*>();
std::unique_ptr<CGuiFrame> frame(CGuiFrame::CreateFrame(tag.id, *g_GuiSys, in, sp));
2016-03-16 20:49:35 +00:00
return TToken<CGuiFrame>::GetIObjObjectFor(std::move(frame));
}
2016-03-11 05:32:18 +00:00
}