mirror of https://github.com/AxioDL/metaforce.git
160 lines
6.0 KiB
C++
160 lines
6.0 KiB
C++
#include "Runtime/GuiSys/CGuiTextPane.hpp"
|
|
|
|
#include <array>
|
|
|
|
#include "Runtime/Graphics/CGraphics.hpp"
|
|
#include "Runtime/Graphics/CGraphicsPalette.hpp"
|
|
#include "Runtime/GuiSys/CFontImageDef.hpp"
|
|
#include "Runtime/GuiSys/CGuiFrame.hpp"
|
|
#include "Runtime/GuiSys/CGuiSys.hpp"
|
|
#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp"
|
|
|
|
namespace metaforce {
|
|
namespace {
|
|
constexpr std::array<zeus::CVector3f, 4> NormalPoints{{
|
|
{0.f, 0.f, -1.f},
|
|
{1.f, 0.f, -1.f},
|
|
{1.f, 0.f, 0.f},
|
|
{0.f, 0.f, 0.f},
|
|
}};
|
|
bool testProjectedLine(const zeus::CVector2f& a, const zeus::CVector2f& b, const zeus::CVector2f& point) {
|
|
const zeus::CVector2f normal = (b - a).perpendicularVector().normalized();
|
|
return point.dot(normal) >= a.dot(normal);
|
|
}
|
|
} // Anonymous namespace
|
|
|
|
bool CGuiTextPane::sDrawPaneRects = true;
|
|
CGuiTextPane::CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim,
|
|
const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props,
|
|
const zeus::CColor& fontCol, const zeus::CColor& outlineCol, s32 extentX, s32 extentY)
|
|
: CGuiPane(parms, dim, vec)
|
|
, xd4_textSupport(fontId, props, fontCol, outlineCol, zeus::skWhite, extentX, extentY, sp, xac_drawFlags) {}
|
|
|
|
void CGuiTextPane::Update(float dt) {
|
|
CGuiWidget::Update(dt);
|
|
xd4_textSupport.Update(dt);
|
|
}
|
|
|
|
bool CGuiTextPane::GetIsFinishedLoadingWidgetSpecific() { return xd4_textSupport.GetIsTextSupportFinishedLoading(); }
|
|
|
|
void CGuiTextPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) {
|
|
CGuiPane::SetDimensions(dim, initVBO);
|
|
if (initVBO)
|
|
InitializeBuffers();
|
|
}
|
|
|
|
void CGuiTextPane::ScaleDimensions(const zeus::CVector3f& scale) {}
|
|
|
|
void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) {
|
|
if (sDrawPaneRects) {
|
|
CGuiPane::Draw({0.2f * parms.x0_alphaMod, parms.x4_cameraOffset});
|
|
}
|
|
|
|
if (!GetIsVisible()) {
|
|
return;
|
|
}
|
|
SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CGuiTextPane::Draw {}"), m_name).c_str(), zeus::skCyan);
|
|
|
|
zeus::CVector2f dims = GetDimensions();
|
|
|
|
if (xd4_textSupport.x34_extentX != 0) {
|
|
dims.x() /= float(xd4_textSupport.x34_extentX);
|
|
} else {
|
|
dims.x() = 0.f;
|
|
}
|
|
|
|
if (xd4_textSupport.x38_extentY != 0) {
|
|
dims.y() /= float(xd4_textSupport.x38_extentY);
|
|
} else {
|
|
dims.y() = 0.f;
|
|
}
|
|
|
|
const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front() + xc8_scaleCenter) *
|
|
zeus::CTransform::Scale(dims.x(), 1.f, dims.y());
|
|
CGraphics::SetModelMatrix(x34_worldXF * local);
|
|
|
|
zeus::CColor geomCol = xa8_color2;
|
|
geomCol.a() *= parms.x0_alphaMod;
|
|
xd4_textSupport.SetGeometryColor(geomCol);
|
|
|
|
#if 0
|
|
CGraphics::SetDepthWriteMode(xb6_31_depthTest, ERglEnum::LEqual, xb7_24_depthWrite);
|
|
|
|
switch (xac_drawFlags)
|
|
{
|
|
case EGuiModelDrawFlags::Shadeless:
|
|
case EGuiModelDrawFlags::Opaque:
|
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One,
|
|
ERglBlendFactor::Zero, ERglLogicOp::Clear);
|
|
xd4_textSupport.Render();
|
|
break;
|
|
case EGuiModelDrawFlags::Alpha:
|
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
|
|
ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
|
|
xd4_textSupport.Render();
|
|
break;
|
|
case EGuiModelDrawFlags::Additive:
|
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
|
|
ERglBlendFactor::One, ERglLogicOp::Clear);
|
|
xd4_textSupport.Render();
|
|
break;
|
|
case EGuiModelDrawFlags::AlphaAdditiveOverdraw:
|
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha,
|
|
ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear);
|
|
xd4_textSupport.Render();
|
|
xd4_textSupport.SetGeometryColor(geomCol * zeus::CColor(geomCol.a(), geomCol.a(), geomCol.a(), 1.f));
|
|
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One,
|
|
ERglBlendFactor::One, ERglLogicOp::Clear);
|
|
xd4_textSupport.Render();
|
|
break;
|
|
}
|
|
#else
|
|
xd4_textSupport.Render();
|
|
#endif
|
|
}
|
|
|
|
bool CGuiTextPane::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const {
|
|
const zeus::CVector2f dims = GetDimensions();
|
|
const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front() + xc8_scaleCenter) *
|
|
zeus::CTransform::Scale(dims.x(), 1.f, dims.y());
|
|
const zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f();
|
|
|
|
std::array<zeus::CVector2f, 4> projPoints;
|
|
for (size_t i = 0; i < projPoints.size(); ++i) {
|
|
projPoints[i] = mvp.multiplyOneOverW(NormalPoints[i]).toVec2f();
|
|
}
|
|
|
|
size_t j;
|
|
for (j = 0; j < 3; ++j) {
|
|
if (!testProjectedLine(projPoints[j], projPoints[j + 1], point)) {
|
|
break;
|
|
}
|
|
}
|
|
return j == 3 && testProjectedLine(projPoints[3], projPoints[0], point);
|
|
}
|
|
|
|
std::shared_ptr<CGuiWidget> CGuiTextPane::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) {
|
|
const CGuiWidgetParms parms = ReadWidgetHeader(frame, in);
|
|
const zeus::CVector2f dim = zeus::CVector2f::ReadBig(in);
|
|
const zeus::CVector3f vec = zeus::CVector3f::ReadBig(in);
|
|
const u32 fontId = in.readUint32Big();
|
|
const bool wordWrap = in.readBool();
|
|
const bool horizontal = in.readBool();
|
|
const auto justification = EJustification(in.readUint32Big());
|
|
const auto vJustification = EVerticalJustification(in.readUint32Big());
|
|
const CGuiTextProperties props(wordWrap, horizontal, justification, vJustification);
|
|
zeus::CColor fontCol;
|
|
fontCol.readRGBABig(in);
|
|
zeus::CColor outlineCol;
|
|
outlineCol.readRGBABig(in);
|
|
const int extentX = static_cast<int>(in.readFloatBig());
|
|
const int extentY = static_cast<int>(in.readFloatBig());
|
|
auto ret = std::make_shared<CGuiTextPane>(parms, sp, dim, vec, fontId, props, fontCol, outlineCol, extentX, extentY);
|
|
ret->ParseBaseInfo(frame, in, parms);
|
|
ret->InitializeBuffers();
|
|
ret->TextSupport().SetText(u"");
|
|
return ret;
|
|
}
|
|
|
|
} // namespace metaforce
|