metaforce/Runtime/GuiSys/CGuiTextSupport.cpp

207 lines
5.5 KiB
C++
Raw Normal View History

2016-03-19 00:07:31 +00:00
#include "CGuiTextSupport.hpp"
#include "CSimplePool.hpp"
#include "CFontImageDef.hpp"
2016-03-21 22:01:19 +00:00
#include "CGuiSys.hpp"
#include "CTextExecuteBuffer.hpp"
#include "CTextParser.hpp"
#include "Graphics/CGraphicsPalette.hpp"
2016-03-21 22:01:19 +00:00
#include "Graphics/CGraphics.hpp"
2016-03-22 18:35:52 +00:00
#include "GuiSys/CRasterFont.hpp"
2016-03-19 00:07:31 +00:00
namespace urde
{
2016-04-14 21:42:47 +00:00
CGuiTextSupport::CGuiTextSupport(ResId fontId, const CGuiTextProperties& props,
2016-03-22 02:27:46 +00:00
const zeus::CColor& fontCol, const zeus::CColor& outlineCol,
const zeus::CColor& geomCol, s32 padX, s32 padY, CSimplePool* store)
2016-08-15 20:58:07 +00:00
: x14_props(props), x24_fontColor(fontCol), x28_outlineColor(outlineCol),
x2c_geometryColor(geomCol), x34_extentX(padX), x38_extentY(padY)
{
2016-08-15 20:58:07 +00:00
x2cc_font = store->GetObj({SBIG('FONT'), fontId});
}
2016-03-21 22:01:19 +00:00
float CGuiTextSupport::GetCurrentAnimationOverAge() const
{
2016-08-15 20:58:07 +00:00
if (!x2ac_active || !x50_typeEnable)
2016-03-21 22:01:19 +00:00
return 0.f;
2016-08-15 20:58:07 +00:00
if (x44_primStartTimes.size())
2016-03-21 22:01:19 +00:00
{
2016-08-15 20:58:07 +00:00
float val = (x60_renderBuf->GetPrimitiveCount() - x44_primStartTimes.back().second) /
x58_chRate + x44_primStartTimes.back().first;
2016-03-21 22:01:19 +00:00
return std::max(0.f, val);
}
else
{
2016-08-15 20:58:07 +00:00
float val = x60_renderBuf->GetPrimitiveCount() / x58_chRate;
2016-03-21 22:01:19 +00:00
return std::max(0.f, val);
}
}
2016-03-21 22:01:19 +00:00
float CGuiTextSupport::GetNumCharsPrinted() const
{
2016-03-21 22:01:19 +00:00
if (x2ac_active)
2016-08-15 20:58:07 +00:00
return std::min(x3c_curTime * x58_chRate, float(x60_renderBuf->GetPrimitiveCount()));
2016-03-21 22:01:19 +00:00
return 0.f;
}
2016-03-21 22:01:19 +00:00
float CGuiTextSupport::GetTotalAnimationTime() const
{
2016-08-15 20:58:07 +00:00
if (!x2ac_active || !x50_typeEnable)
2016-03-21 22:01:19 +00:00
return 0.f;
2016-08-15 20:58:07 +00:00
return x60_renderBuf->GetPrimitiveCount() / x58_chRate;
}
2016-03-21 22:01:19 +00:00
void CGuiTextSupport::SetTypeWriteEffectOptions(bool enable, float chFadeTime, float chRate)
{
2016-08-15 20:58:07 +00:00
x50_typeEnable = enable;
x54_chFadeTime = std::max(chFadeTime, 0.0001f);
x58_chRate = std::max(chRate, 1.f);
}
void CGuiTextSupport::Update(float dt)
{
2016-03-21 22:01:19 +00:00
if (!x2ac_active)
return;
2016-08-15 20:58:07 +00:00
if (x50_typeEnable)
2016-03-21 22:01:19 +00:00
{
2016-08-15 20:58:07 +00:00
for (int i=0 ; i<x60_renderBuf->GetPrimitiveCount() ; ++i)
2016-03-21 22:01:19 +00:00
{
float chStartTime = 0.f;
2016-08-15 20:58:07 +00:00
for (const std::pair<float, int>& p : x44_primStartTimes)
2016-03-21 22:01:19 +00:00
{
if (p.second < i)
continue;
if (p.second != i)
break;
chStartTime = p.first;
break;
}
2016-03-22 08:15:00 +00:00
#if 0
2016-03-21 22:01:19 +00:00
CTextRenderBuffer::Primitive prim = x54_renderBuf->GetPrimitive(i);
prim.x0_color1.a = std::min(std::max(0.f, (x30_curTime - chStartTime) / x48_chFadeTime), 1.f);
x54_renderBuf->SetPrimitive(prim, i);
2016-03-22 08:15:00 +00:00
#else
2016-08-15 20:58:07 +00:00
x60_renderBuf->SetPrimitiveOpacity(i,
std::min(std::max(0.f, (x3c_curTime - chStartTime) / x54_chFadeTime), 1.f));
2016-03-22 08:15:00 +00:00
#endif
2016-03-21 22:01:19 +00:00
}
}
2016-08-15 20:58:07 +00:00
x3c_curTime += dt;
}
void CGuiTextSupport::ClearBuffer()
{
2016-08-15 20:58:07 +00:00
x60_renderBuf = std::experimental::nullopt;
}
void CGuiTextSupport::CheckAndRebuildTextRenderBuffer()
{
2016-03-21 22:01:19 +00:00
if (x2ac_active)
return;
g_TextExecuteBuf->Clear();
2016-08-15 20:58:07 +00:00
g_TextExecuteBuf->x18_textState.x48_enableWordWrap = x14_props.x0_wordWrap;
2016-08-16 22:49:19 +00:00
g_TextExecuteBuf->BeginBlock(0, 0, x34_extentX, x38_extentY, x14_props.xc_direction,
2016-08-15 20:58:07 +00:00
x14_props.x4_justification, x14_props.x8_vertJustification);
g_TextExecuteBuf->AddColor(EColorType::Main, x24_fontColor);
g_TextExecuteBuf->AddColor(EColorType::Outline, x28_outlineColor);
2016-03-21 22:01:19 +00:00
std::wstring initStr;
2016-08-15 20:58:07 +00:00
if ((x5c_fontId & 0xffff) != 0xffff)
initStr = hecl::WideFormat(L"&font=%08X;", u32(x5c_fontId));
2016-03-21 22:01:19 +00:00
initStr += x0_string;
g_TextParser->ParseText(*g_TextExecuteBuf, initStr.c_str(), initStr.size());
g_TextExecuteBuf->EndBlock();
x2b0_assets = g_TextExecuteBuf->GetAssets();
if (GetIsTextSupportFinishedLoading())
{
2016-08-15 20:58:07 +00:00
x60_renderBuf = g_TextExecuteBuf->CreateTextRenderBuffer();
2016-03-21 22:01:19 +00:00
g_TextExecuteBuf->Clear();
}
Update(0.f);
}
void CGuiTextSupport::Render() const
{
2016-03-21 22:01:19 +00:00
if (x2ac_active)
{
zeus::CTransform oldModel = CGraphics::g_GXModelMatrix;
CGraphics::SetModelMatrix(oldModel * zeus::CTransform::Scale(1.f, 1.f, -1.f));
2016-08-15 20:58:07 +00:00
x60_renderBuf->Render(x2c_geometryColor, x3c_curTime);
2016-03-21 22:01:19 +00:00
CGraphics::SetModelMatrix(oldModel);
}
}
void CGuiTextSupport::SetGeometryColor(const zeus::CColor& col)
{
2016-08-15 20:58:07 +00:00
x2c_geometryColor = col;
}
void CGuiTextSupport::SetOutlineColor(const zeus::CColor& col)
{
2016-08-15 20:58:07 +00:00
if (col != x28_outlineColor)
2016-03-21 22:01:19 +00:00
{
ClearBuffer();
2016-08-15 20:58:07 +00:00
x28_outlineColor = col;
2016-03-21 22:01:19 +00:00
}
}
void CGuiTextSupport::SetFontColor(const zeus::CColor& col)
{
2016-08-15 20:58:07 +00:00
if (col != x24_fontColor)
2016-03-21 22:01:19 +00:00
{
ClearBuffer();
2016-08-15 20:58:07 +00:00
x24_fontColor = col;
2016-03-21 22:01:19 +00:00
}
}
void CGuiTextSupport::AddText(const std::wstring& str)
{
2016-03-21 22:01:19 +00:00
if (x2ac_active)
{
float t = GetCurrentAnimationOverAge();
2016-08-15 20:58:07 +00:00
x44_primStartTimes.push_back(std::make_pair(std::max(t, x3c_curTime),
x60_renderBuf->GetPrimitiveCount()));
2016-03-21 22:01:19 +00:00
}
x0_string += str;
ClearBuffer();
}
void CGuiTextSupport::SetText(const std::wstring& str)
{
2016-03-21 22:01:19 +00:00
if (x0_string.compare(str))
{
2016-08-15 20:58:07 +00:00
x44_primStartTimes.clear();
x3c_curTime = 0.f;
2016-03-21 22:01:19 +00:00
x0_string = str;
ClearBuffer();
}
}
void CGuiTextSupport::SetText(const std::string& str)
{
2016-03-21 22:01:19 +00:00
SetText(hecl::UTF8ToWide(str));
}
bool CGuiTextSupport::GetIsTextSupportFinishedLoading() const
2016-03-19 00:07:31 +00:00
{
2016-03-21 22:01:19 +00:00
for (const CToken& tok : x2b0_assets)
{
((CToken&)tok).Lock();
if (!tok.IsLoaded())
return false;
}
2016-08-15 20:58:07 +00:00
return x2cc_font.IsLoaded();
2016-03-19 00:07:31 +00:00
}
}