CGuiTextSupport imps

This commit is contained in:
Jack Andersen 2016-03-21 12:01:19 -10:00
parent 6fcdb3a99c
commit 9f82900cdc
12 changed files with 326 additions and 190 deletions

View File

@ -41,7 +41,7 @@ void CFontRenderState::SetColor(EColorType tp, const CTextColor& col)
case EColorType::Foreground:
x20_[0] = col;
break;
case EColorType::Four:
case EColorType::Background:
x20_[1] = col;
break;
}
@ -51,7 +51,7 @@ void CFontRenderState::SetColor(EColorType tp, const CTextColor& col)
void CFontRenderState::RefreshPalette()
{
RefreshColor(EColorType::Foreground);
RefreshColor(EColorType::Four);
RefreshColor(EColorType::Background);
}
void CFontRenderState::RefreshColor(EColorType tp)
@ -90,7 +90,7 @@ void CFontRenderState::RefreshColor(EColorType tp)
RefreshColor(EColorType::Main);
RefreshColor(EColorType::Geometry);
break;
case EColorType::Four:
case EColorType::Background:
RefreshColor(EColorType::Outline);
break;
}

View File

@ -16,11 +16,14 @@
#include "CAuiEnergyBarT01.hpp"
#include "CTextParser.hpp"
#include "CSimplePool.hpp"
#include "CTextExecuteBuffer.hpp"
namespace urde
{
CGuiSys* g_GuiSys = nullptr;
CTextExecuteBuffer* g_TextExecuteBuf = nullptr;
CTextParser* g_TextParser = nullptr;
void CGuiSys::AddFactories(EUsageMode /* mode */)
{
@ -73,6 +76,7 @@ CGuiWidget* CGuiSys::CreateWidgetInGame(FourCC type, CInputStream& in, CGuiFrame
CGuiSys::CGuiSys(IFactory& resFactory, CSimplePool& resStore, EUsageMode mode)
: x0_resFactory(resFactory), x4_resStore(resStore), x2c_mode(mode),
x38_frameFactoryParams(new TObjOwnerParam<CGuiResFrameData>(CGuiResFrameData(*this))),
x30_textExecuteBuf(new CTextExecuteBuffer()),
x34_textParser(new CTextParser(resStore)),
x40_constructTime(std::chrono::steady_clock::now())
{
@ -123,6 +127,9 @@ CGuiSys::CGuiSys(IFactory& resFactory, CSimplePool& resStore, EUsageMode mode)
x18_repeatMap.emplace(std::make_pair(EPhysicalControllerID::LeftLeftInst,
CGuiAutoRepeatData(EPhysicalControllerID::LeftLeftInst, EPhysicalControllerID::LeftLeft)));
g_TextExecuteBuf = x30_textExecuteBuf.get();
g_TextParser = x34_textParser.get();
}
}

View File

@ -20,6 +20,7 @@ class CSimplePool;
class CGuiWidget;
class CGuiFrame;
class CTextParser;
class CTextExecuteBuffer;
typedef CGuiObject*(*FGuiFactoryFunc)(const SObjectTag&, const CVParamTransfer&);
@ -50,7 +51,7 @@ private:
CGuiFactoryMgr x8_factoryMgr;
std::unordered_map<EPhysicalControllerID, CGuiAutoRepeatData> x18_repeatMap;
EUsageMode x2c_mode;
std::stack<CSaveableState, std::vector<CSaveableState>> x30_saveStack;
std::unique_ptr<CTextExecuteBuffer> x30_textExecuteBuf;
std::unique_ptr<CTextParser> x34_textParser;
CVParamTransfer x38_frameFactoryParams;
std::chrono::time_point<std::chrono::steady_clock> x40_constructTime;
@ -69,6 +70,12 @@ public:
/** Global GuiSys instance */
extern CGuiSys* g_GuiSys;
/** Global CTextExecuteBuffer instance */
extern CTextExecuteBuffer* g_TextExecuteBuf;
/** Global CTextParser instance */
extern CTextParser* g_TextParser;
/** Parameter pack for FRME factory */
struct CGuiResFrameData
{

View File

@ -1,81 +1,200 @@
#include "CGuiTextSupport.hpp"
#include "CSimplePool.hpp"
#include "CFontImageDef.hpp"
#include "CGuiSys.hpp"
#include "CTextExecuteBuffer.hpp"
#include "CTextParser.hpp"
#include "Graphics/CGraphicsPalette.hpp"
#include "Graphics/CGraphics.hpp"
namespace urde
{
CGuiTextSupport::CGuiTextSupport(TResId fontId, const CGuiTextProperties& props,
const zeus::CColor& col1, const zeus::CColor& col2,
const zeus::CColor& col3, int, int, CSimplePool* store)
: x10_props(props), x1c_(col1), x20_(col2), x24_(col3)
const zeus::CColor& col3, s32 padX, s32 padY, CSimplePool* store)
: x10_props(props), x1c_fontColor(col1), x20_outlineColor(col2),
x24_geometryColor(col3), x28_padX(padX), x2c_padY(padY)
{
x2c0_font = store->GetObj({SBIG('FONT'), fontId});
}
void CGuiTextSupport::GetCurrentAnimationOverAge() const
float CGuiTextSupport::GetCurrentAnimationOverAge() const
{
if (!x2ac_ || !x44_)
return;
if (!x2ac_active || !x44_typeEnable)
return 0.f;
if (x34_primStartTimes.size())
{
float val = (x54_renderBuf->x24_primOffsets.size() - x34_primStartTimes.back().second) /
x4c_chRate + x34_primStartTimes.back().first;
return std::max(0.f, val);
}
else
{
float val = x54_renderBuf->x24_primOffsets.size() / x4c_chRate;
return std::max(0.f, val);
}
}
int CGuiTextSupport::GetNumCharsPrinted() const
float CGuiTextSupport::GetNumCharsPrinted() const
{
if (x2ac_active)
return std::min(x30_curTime * x4c_chRate, float(x54_renderBuf->x24_primOffsets.size()));
return 0.f;
}
int CGuiTextSupport::GetTotalAnimationTime() const
float CGuiTextSupport::GetTotalAnimationTime() const
{
if (!x2ac_active || !x44_typeEnable)
return 0.f;
return x54_renderBuf->x24_primOffsets.size() / x4c_chRate;
}
void CGuiTextSupport::SetTypeWriteEffectOptions(bool, float, float)
void CGuiTextSupport::SetTypeWriteEffectOptions(bool enable, float chFadeTime, float chRate)
{
x44_typeEnable = enable;
x48_chFadeTime = std::max(chFadeTime, 0.0001f);
x4c_chRate = std::max(chRate, 1.f);
}
void CGuiTextSupport::Update(float dt)
{
if (!x2ac_active)
return;
if (x44_typeEnable)
{
for (int i=0 ; i<x54_renderBuf->x24_primOffsets.size() ; ++i)
{
float chStartTime = 0.f;
for (const std::pair<float, int>& p : x34_primStartTimes)
{
if (p.second < i)
continue;
if (p.second != i)
break;
chStartTime = p.first;
break;
}
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);
}
}
x30_curTime += dt;
}
void CGuiTextSupport::ClearBuffer()
{
x54_renderBuf = std::experimental::nullopt;
}
void CGuiTextSupport::CheckAndRebuildTextRenderBuffer()
{
if (x2ac_active)
return;
g_TextExecuteBuf->Clear();
g_TextExecuteBuf->x18_textState.x48_enableWordWrap = x10_props.x0_wordWrap;
g_TextExecuteBuf->BeginBlock(0, 0, x28_padX, x2c_padY, ETextDirection(x10_props.x1_vertical),
x10_props.x4_justification, x10_props.x8_vertJustification);
g_TextExecuteBuf->AddColor(EColorType::Main, x1c_fontColor);
g_TextExecuteBuf->AddColor(EColorType::Outline, x20_outlineColor);
std::wstring initStr;
if ((x50_fontId & 0xffff) != 0xffff)
initStr = hecl::WideFormat(L"&font=%08X;", u32(x50_fontId));
initStr += x0_string;
g_TextParser->ParseText(*g_TextExecuteBuf, initStr.c_str(), initStr.size());
g_TextExecuteBuf->EndBlock();
x2b0_assets = g_TextExecuteBuf->GetAssets();
if (GetIsTextSupportFinishedLoading())
{
x54_renderBuf = g_TextExecuteBuf->CreateTextRenderBuffer();
g_TextExecuteBuf->Clear();
}
Update(0.f);
}
void CGuiTextSupport::Render() const
{
if (x2ac_active)
{
zeus::CTransform oldModel = CGraphics::g_GXModelMatrix;
CGraphics::SetModelMatrix(oldModel * zeus::CTransform::Scale(1.f, 1.f, -1.f));
x54_renderBuf->Render(x24_geometryColor, x30_curTime);
CGraphics::SetModelMatrix(oldModel);
}
}
void CGuiTextSupport::SetGeometryColor(const zeus::CColor& col)
{
x24_geometryColor = col;
}
void CGuiTextSupport::SetOutlineColor(const zeus::CColor& col)
{
if (col != x20_outlineColor)
{
ClearBuffer();
x20_outlineColor = col;
}
}
void CGuiTextSupport::SetFontColor(const zeus::CColor& col)
{
if (col != x1c_fontColor)
{
ClearBuffer();
x1c_fontColor = col;
}
}
void CGuiTextSupport::AddText(const std::wstring& str)
{
if (x2ac_active)
{
float t = GetCurrentAnimationOverAge();
x34_primStartTimes.push_back(std::make_pair(std::max(t, x30_curTime),
x54_renderBuf->x24_primOffsets.size()));
}
x0_string += str;
ClearBuffer();
}
void CGuiTextSupport::SetText(const std::wstring& str)
{
if (x0_string.compare(str))
{
x34_primStartTimes.clear();
x30_curTime = 0.f;
x0_string = str;
ClearBuffer();
}
}
void CGuiTextSupport::SetText(const std::string& str)
{
SetText(hecl::UTF8ToWide(str));
}
bool CGuiTextSupport::GetIsTextSupportFinishedLoading() const
{
for (const CToken& tok : x2b0_assets)
{
((CToken&)tok).Lock();
if (!tok.IsLoaded())
return false;
}
return x2c0_font.IsLoaded();
}
}

View File

@ -48,7 +48,7 @@ enum class EColorType
Outline,
Geometry,
Foreground,
Four
Background
};
enum class ETextDirection
@ -57,52 +57,48 @@ enum class ETextDirection
Vertical
};
using CTextColor = zeus::CColor;
class CGuiTextProperties
{
bool x0_a;
bool x1_b;
friend class CGuiTextSupport;
bool x0_wordWrap;
bool x1_vertical;
bool x2_c;
EJustification x4_justification;
EVerticalJustification x8_vertJustification;
public:
CGuiTextProperties(bool a, bool b, bool c, EJustification justification,
EVerticalJustification vertJustification)
: x0_a(a), x1_b(b), x2_c(c), x4_justification(justification),
: x0_wordWrap(a), x1_vertical(b), x2_c(c), x4_justification(justification),
x8_vertJustification(vertJustification) {}
};
class CGuiTextSupport
{
u32 x4_ = 0;
u32 x8_ = 0;
std::wstring x0_string;
CGuiTextProperties x10_props;
zeus::CColor x1c_;
zeus::CColor x20_;
zeus::CColor x24_;
s32 x28_;
s32 x2c_;
float x30_ = 0.f;
std::vector<u32> x34_;
s32 x44_ = 0;
float x48_ = 0.1f;
float x4c_ = 10.0f;
zeus::CColor x1c_fontColor;
zeus::CColor x20_outlineColor;
zeus::CColor x24_geometryColor;
s32 x28_padX;
s32 x2c_padY;
float x30_curTime = 0.f;
std::vector<std::pair<float, int>> x34_primStartTimes;
bool x44_typeEnable = false;
float x48_chFadeTime = 0.1f;
float x4c_chRate = 10.0f;
TResId x50_fontId;
std::experimental::optional<CTextRenderBuffer> x54_renderBuf;
bool x2ac_ = false;
s32 x2b4_ = 0;
s32 x2b8_ = 0;
s32 x2bc_ = 0;
bool x2ac_active = false;
std::vector<CToken> x2b0_assets;
TLockedToken<CRasterFont> x2c0_font;
public:
CGuiTextSupport(TResId fontId, const CGuiTextProperties& props,
const zeus::CColor& col1, const zeus::CColor& col2,
const zeus::CColor& col3, s32, s32, CSimplePool*);
void GetCurrentAnimationOverAge() const;
int GetNumCharsPrinted() const;
int GetTotalAnimationTime() const;
void SetTypeWriteEffectOptions(bool, float, float);
const zeus::CColor& col3, s32 padX, s32 padY, CSimplePool* store);
float GetCurrentAnimationOverAge() const;
float GetNumCharsPrinted() const;
float GetTotalAnimationTime() const;
void SetTypeWriteEffectOptions(bool enable, float chFadeTime, float chRate);
void Update(float dt);
void ClearBuffer();
void CheckAndRebuildTextRenderBuffer();

View File

@ -20,6 +20,7 @@ class CSaveableState
friend class CLineSpacingInstruction;
friend class CRemoveColorOverrideInstruction;
friend class CWordInstruction;
friend class CGuiTextSupport;
protected:
CDrawStringOptions x0_drawStrOpts;
TToken<CRasterFont> x14_font;
@ -27,7 +28,7 @@ protected:
std::vector<bool> x30_colorOverrides;
float x40_lineSpacing = 1.f;
s32 x44_extraLineSpace = 0;
bool x48_ = false;
bool x48_enableWordWrap = false;
EJustification x4c_just = EJustification::Left;
EVerticalJustification x50_vjust = EVerticalJustification::Top;

View File

@ -108,7 +108,7 @@ int CTextExecuteBuffer::WrapOneLTR(const wchar_t* str, int len)
x18_textState.x14_font.GetObj()->GetSize(x18_textState.x0_drawStrOpts,
w, h, str, len);
if (x18_textState.x48_)
if (x18_textState.x48_enableWordWrap)
{
if (w + x70_curLine->x8_curX > x6c_curBlock->xc_blockPaddingX &&
x70_curLine->x4_wordCount > 1 &&

View File

@ -15,6 +15,8 @@ class CLineInstruction;
class CTextExecuteBuffer
{
friend class CGuiTextSupport;
std::list<std::shared_ptr<CInstruction>> x0_instList;
u32 x14_ = 0;
CSaveableState x18_textState;

View File

@ -12,17 +12,20 @@ class CFontImageDef;
class CGraphicsPalette;
class CRasterFont;
using CTextColor = zeus::CColor;
class CTextRenderBuffer
{
friend class CGuiTextSupport;
public:
struct Primitive
{
u32 x0_;
CTextColor x0_color1;
u32 x4_;
u16 x8_;
u16 xa_;
u16 xc_;
u16 xe_;
u8 xe_;
};
enum class EMode
{

View File

@ -11,161 +11,161 @@ struct CCharacterIdentifier
static const CCharacterIdentifier gCantBeginChars[]=
{
{0x21, 1},
{0x29, 1},
{0x2C, 1},
{0x2D, 1},
{0x2E, 1},
{0x3A, 1},
{0x3B, 1},
{0x3F, 1},
{0x5D, 1},
{0x7D, 1},
{L'!', 1},
{L')', 1},
{L',', 1},
{L'-', 1},
{L'.', 1},
{L':', 1},
{L';', 1},
{L'?', 1},
{L']', 1},
{L'}', 1},
{0x92, 1},
{0x94, 1},
{0xBB, 1},
{0x3001, 1},
{0x3002, 1},
{0x3005, 1},
{0x300D, 1},
{0x300F, 1},
{0x3011, 1},
{0x3015, 1},
{0x3017, 1},
{0x3019, 1},
{0x301B, 1},
{0x301C, 3},
{0x301E, 1},
{0x302B, 3},
{0x3041, 2},
{0x3043, 2},
{0x3045, 2},
{0x3047, 2},
{0x3049, 2},
{0x3063, 2},
{0x3083, 2},
{0x3085, 2},
{0x3087, 2},
{0x308E, 2},
{0x309D, 3},
{0x309E, 3},
{0x30A1, 2},
{0x30A3, 2},
{0x30A5, 2},
{0x30A7, 2},
{0x30A9, 2},
{0x30C3, 2},
{0x30E3, 2},
{0x30E5, 2},
{0x30E7, 2},
{0x30EE, 2},
{0x30F5, 2},
{0x30F6, 2},
{0x30FC, 2},
{0x30FD, 3},
{0x30FE, 3},
{0xFF01, 1},
{0xFF05, 3},
{0xFF09, 1},
{0xFF0D, 1},
{0xFF3D, 1},
{0xFF5D, 1},
{0xFF61, 1},
{0xFF63, 1},
{0xFF64, 1},
{0xFF1F, 1}
{L'»', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 3},
{L'', 1},
{L'', 3},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 3},
{L'', 3},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 3},
{L'', 3},
{L'', 1},
{L'', 3},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1}
};
static const CCharacterIdentifier gCantEndChars[] =
{
{0x23, 2},
{0x24, 2},
{0x28, 1},
{0x40, 2},
{0x42, 4},
{0x43, 4},
{0x44, 4},
{0x46, 4},
{0x47, 4},
{0x48, 4},
{0x4A, 4},
{0x4B, 4},
{0x4C, 4},
{0x4D, 4},
{0x4E, 4},
{0x50, 4},
{0x51, 4},
{0x52, 4},
{0x53, 4},
{0x54, 4},
{0x56, 4},
{0x57, 4},
{0x58, 4},
{0x59, 4},
{0x5A, 4},
{0x62, 4},
{0x63, 4},
{0x64, 4},
{0x66, 4},
{0x67, 4},
{0x68, 4},
{0x6A, 4},
{0x6B, 4},
{0x6C, 4},
{0x6D, 4},
{0x6E, 4},
{0x70, 4},
{0x71, 4},
{0x72, 4},
{0x73, 4},
{0x74, 4},
{0x76, 4},
{0x77, 4},
{0x78, 4},
{0x79, 4},
{0x7A, 4},
{0xD1, 4},
{0xF1, 4},
{0x5B, 1},
{0x7B, 1},
{L'#', 2},
{L'$', 2},
{L'(', 1},
{L'@', 2},
{L'B', 4},
{L'C', 4},
{L'D', 4},
{L'E', 4},
{L'F', 4},
{L'G', 4},
{L'J', 4},
{L'K', 4},
{L'L', 4},
{L'M', 4},
{L'N', 4},
{L'P', 4},
{L'Q', 4},
{L'R', 4},
{L'S', 4},
{L'T', 4},
{L'V', 4},
{L'W', 4},
{L'X', 4},
{L'Y', 4},
{L'Z', 4},
{L'b', 4},
{L'c', 4},
{L'd', 4},
{L'f', 4},
{L'g', 4},
{L'h', 4},
{L'j', 4},
{L'k', 4},
{L'l', 4},
{L'm', 4},
{L'n', 4},
{L'p', 4},
{L'q', 4},
{L'r', 4},
{L's', 4},
{L't', 4},
{L'v', 4},
{L'w', 4},
{L'x', 4},
{L'y', 4},
{L'z', 4},
{L'Ñ', 4},
{L'ñ', 4},
{L'[', 1},
{L'{', 1},
{0x91, 1},
{0x93, 1},
{0x91, 1},
{0x93, 1},
{0xA2, 2},
{0xA3, 2},
{0xA5, 2},
{0xA7, 2},
{0xA9, 2},
{0xAB, 1},
{0x20A0, 2},
{0x20A1, 2},
{0x20A2, 2},
{0x20A3, 2},
{0x20A4, 2},
{0x20A5, 2},
{0x20A6, 2},
{0x20A7, 2},
{0x20A8, 2},
{0x20A9, 2},
{0x20AA, 2},
{0x20AB, 2},
{0x20AC, 2},
{0x300C, 1},
{0x300E, 1},
{0x3010, 1},
{0x3012, 2},
{0x3014, 1},
{0x3016, 1},
{0x3018, 1},
{0x301A, 1},
{0xFF03, 2},
{0xFF04, 2},
{0xFF20, 2},
{0xFF3C, 1},
{0xFF5C, 1},
{0xFFE0, 2},
{0xFFE1, 2},
{L'¢', 2},
{L'£', 2},
{L'¥', 2},
{L'§', 2},
{L'©', 2},
{L'«', 1},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 2},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 1},
{L'', 2},
{L'', 2},
{L'', 2},
{L'', 1},
{L'', 1},
{L'', 2},
{L'', 2},
{0xFFEF, 2},
};

View File

@ -34,6 +34,7 @@
#include "CArchitectureQueue.hpp"
#include "MP1.hpp"
#include "CTimeProvider.hpp"
#include "GuiSys/CTextExecuteBuffer.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakGame.hpp"

2
hecl

@ -1 +1 @@
Subproject commit 5a83ba09d46970db3452ab3084ff0b469b746490
Subproject commit 420a3b078b9532f382028a3890fa47c7e870f0c8