diff --git a/Runtime/GuiSys/CDrawStringOptions.hpp b/Runtime/GuiSys/CDrawStringOptions.hpp index f889c5190..7f144dee6 100644 --- a/Runtime/GuiSys/CDrawStringOptions.hpp +++ b/Runtime/GuiSys/CDrawStringOptions.hpp @@ -3,7 +3,7 @@ #include #include "RetroTypes.hpp" -#include "zeus/CColor.hpp" +#include "CGuiTextSupport.hpp" namespace urde { @@ -14,7 +14,7 @@ class CDrawStringOptions friend class CFontRenderState; friend class CRasterFont; u32 x0_ = 0; - std::vector x4_vec; + std::vector x4_vec; public: CDrawStringOptions() { diff --git a/Runtime/GuiSys/CFontRenderState.hpp b/Runtime/GuiSys/CFontRenderState.hpp index a111b125d..6268610a6 100644 --- a/Runtime/GuiSys/CFontRenderState.hpp +++ b/Runtime/GuiSys/CFontRenderState.hpp @@ -7,12 +7,16 @@ namespace urde { +class CLineInstruction; class CFontRenderState : public CSaveableState { - u32 x54_ = 0; + friend class CLineInstruction; + + /* void* x54_ = 0; top-to-bottom state */ CDrawStringOptions x58_drawOpts; u32 x6c_ = 0; + const CLineInstruction* x74_currentLineInst = nullptr; bool xa0_ = true; std::vector xa4_pushedStates; public: diff --git a/Runtime/GuiSys/CGuiFrame.cpp b/Runtime/GuiSys/CGuiFrame.cpp index 5dfc2bfea..828649c69 100644 --- a/Runtime/GuiSys/CGuiFrame.cpp +++ b/Runtime/GuiSys/CGuiFrame.cpp @@ -634,10 +634,9 @@ CGuiFrame* CGuiFrame::CreateFrame(TResId frmeId, CGuiSys& sys, CInputStream& in) } std::unique_ptr RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in, - const CVParamTransfer& vparms) + const CVParamTransfer&) { - CGuiResFrameData& rfData = static_cast*>(vparms.GetObj())->GetParam(); - std::unique_ptr frame(CGuiFrame::CreateFrame(tag.id, rfData.x0_guiSys, in)); + std::unique_ptr frame(CGuiFrame::CreateFrame(tag.id, *g_GuiSys, in)); return TToken::GetIObjObjectFor(std::move(frame)); } diff --git a/Runtime/GuiSys/CGuiSys.cpp b/Runtime/GuiSys/CGuiSys.cpp index 8b64c8d93..3d955e76f 100644 --- a/Runtime/GuiSys/CGuiSys.cpp +++ b/Runtime/GuiSys/CGuiSys.cpp @@ -18,6 +18,8 @@ namespace urde { +CGuiSys* g_GuiSys = nullptr; + void CGuiSys::AddFactories(EUsageMode /* mode */) { x8_factoryMgr.m_factories.clear(); diff --git a/Runtime/GuiSys/CGuiSys.hpp b/Runtime/GuiSys/CGuiSys.hpp index 88441c113..993cfb3b9 100644 --- a/Runtime/GuiSys/CGuiSys.hpp +++ b/Runtime/GuiSys/CGuiSys.hpp @@ -64,6 +64,9 @@ public: EUsageMode GetUsageMode() const {return x2c_mode;} }; +/** Global GuiSys instance */ +extern CGuiSys* g_GuiSys; + /** Parameter pack for FRME factory */ struct CGuiResFrameData { diff --git a/Runtime/GuiSys/CGuiTextSupport.hpp b/Runtime/GuiSys/CGuiTextSupport.hpp index 2b1c837f7..2ebba3718 100644 --- a/Runtime/GuiSys/CGuiTextSupport.hpp +++ b/Runtime/GuiSys/CGuiTextSupport.hpp @@ -32,11 +32,7 @@ enum class ETextDirection { }; -class CTextColor : public zeus::CColor -{ -public: - CTextColor(const zeus::CColor& col) : zeus::CColor(col) {} -}; +using CTextColor = zeus::CColor; class CGuiTextProperties { diff --git a/Runtime/GuiSys/CInstruction.cpp b/Runtime/GuiSys/CInstruction.cpp index ce5c9d830..844aca8dd 100644 --- a/Runtime/GuiSys/CInstruction.cpp +++ b/Runtime/GuiSys/CInstruction.cpp @@ -1,5 +1,6 @@ #include "CInstruction.hpp" #include "CFontRenderState.hpp" +#include "CTextRenderBuffer.hpp" namespace urde { @@ -25,4 +26,41 @@ void CColorOverrideInstruction::Invoke(CFontRenderState& state, CTextRenderBuffe state.x0_drawStrOpts.x4_vec[x4_overrideIdx] = convCol; } +void CFontInstruction::Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const +{ + buf->AddFontChange(x4_font); + state.x14_token = x4_font; + state.RefreshPalette(); +} + +void CFontInstruction::GetAssets(std::vector& assetsOut) const +{ + assetsOut.push_back(x4_font); +} + +size_t CFontInstruction::GetAssetCount() const +{ + return 1; +} + +void CExtraLineSpaceInstruction::Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const +{ + state.x44_extraLineSpace = x4_extraSpace; +} + +void CLineInstruction::TestLargestFont(int, int, int) +{ +} + +void CLineInstruction::InvokeLTR(CFontRenderState& state) const +{ +} + +void CLineInstruction::Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const +{ + InvokeLTR(state); + state.xa0_ = true; + state.x74_currentLineInst = this; +} + } diff --git a/Runtime/GuiSys/CInstruction.hpp b/Runtime/GuiSys/CInstruction.hpp index d3a399255..b7c3bde77 100644 --- a/Runtime/GuiSys/CInstruction.hpp +++ b/Runtime/GuiSys/CInstruction.hpp @@ -24,6 +24,8 @@ class CColorInstruction : public CInstruction EColorType x4_cType; CTextColor x8_color; public: + CColorInstruction(EColorType tp, const CTextColor& color) + : x4_cType(tp), x8_color(color) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; }; @@ -32,19 +34,44 @@ class CColorOverrideInstruction : public CInstruction int x4_overrideIdx; CTextColor x8_color; public: + CColorOverrideInstruction(int idx, const CTextColor& color) + : x4_overrideIdx(idx), x8_color(color) {} void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; }; class CFontInstruction : public CInstruction { + TLockedToken x4_font; +public: + CFontInstruction(const TToken& font) : x4_font(font) {} + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void GetAssets(std::vector& assetsOut) const; + size_t GetAssetCount() const; }; class CExtraLineSpaceInstruction : public CInstruction { + s32 x4_extraSpace; +public: + CExtraLineSpaceInstruction(s32 extraSpace) : x4_extraSpace(extraSpace) {} + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; }; class CLineInstruction : public CInstruction { + u32 x4_ = 0; + u32 x8_ = 0; + u32 xc_ = 0; + u32 x10_ = 0; + u32 x14_ = 0; + u32 x18_ = 0; + u32 x1c_; + u32 x20_; +public: + CLineInstruction(u32 a, u32 b) : x1c_(a), x20_(b) {} + void TestLargestFont(int, int, int); + void InvokeLTR(CFontRenderState& state) const; + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; }; class CLineSpacingInstruction : public CInstruction @@ -73,6 +100,26 @@ class CTextInstruction : public CInstruction class CBlockInstruction : public CInstruction { + friend class CTextExecuteBuffer; + int x4_; + int x8_; + int xc_; + int x10_; + ETextDirection x14_direction; + EJustification x18_justification; + EVerticalJustification x1c_vertJustification; + int x20_ = 0; + int x24_ = 0; + int x28_ = 0; + int x2c_ = 0; + int x30_ = 0; + int x34_wordCount = 0; +public: + CBlockInstruction(int a, int b, int c, int d, ETextDirection dir, + EJustification just, EVerticalJustification vjust) + : x4_(a), x8_(b), xc_(c), x10_(d), x14_direction(dir), + x18_justification(just), x1c_vertJustification(vjust) {} + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; }; class CWordInstruction : public CInstruction diff --git a/Runtime/GuiSys/CSaveableState.hpp b/Runtime/GuiSys/CSaveableState.hpp index 7902f4e91..16841ad19 100644 --- a/Runtime/GuiSys/CSaveableState.hpp +++ b/Runtime/GuiSys/CSaveableState.hpp @@ -12,14 +12,17 @@ class CRasterFont; class CSaveableState { + friend class CTextExecuteBuffer; friend class CColorOverrideInstruction; + friend class CFontInstruction; + friend class CExtraLineSpaceInstruction; protected: CDrawStringOptions x0_drawStrOpts; TToken x14_token; std::vector x20_; std::vector x30_; float x40_ = 1.f; - u32 x44_ = 0; + s32 x44_extraLineSpace = 0; bool x48_ = false; u32 x4c_ = 0; u32 x50_ = 0; diff --git a/Runtime/GuiSys/CTextExecuteBuffer.cpp b/Runtime/GuiSys/CTextExecuteBuffer.cpp index e69de29bb..302fda4e9 100644 --- a/Runtime/GuiSys/CTextExecuteBuffer.cpp +++ b/Runtime/GuiSys/CTextExecuteBuffer.cpp @@ -0,0 +1,57 @@ +#include "CTextExecuteBuffer.hpp" +#include "CTextRenderBuffer.hpp" +#include "CFontRenderState.hpp" +#include "CFontImageDef.hpp" +#include "CInstruction.hpp" +#include "Graphics/CGraphicsPalette.hpp" + +namespace urde +{ + +CTextRenderBuffer CTextExecuteBuffer::CreateTextRenderBuffer() const +{ + CTextRenderBuffer ret(CTextRenderBuffer::EMode::Zero); + + { + CFontRenderState rendState; + for (const std::shared_ptr& inst : x0_instList) + inst->Invoke(rendState, &ret); + } + + ret.SetMode(CTextRenderBuffer::EMode::One); + + { + CFontRenderState rendState; + for (const std::shared_ptr& inst : x0_instList) + inst->Invoke(rendState, &ret); + } + + return ret; +} + +void CTextExecuteBuffer::StartNewLine() +{ + if (x70_curLine) + TerminateLine(); + + x74_curInst = x0_instList.emplace(x0_instList.cend(), + new CLineInstruction(x18_.x4c_, x18_.x50_)); + x88_curFontSize = 0; + + StartNewWord(); + ++x6c_curBlock->x34_wordCount; +} + +void CTextExecuteBuffer::Clear() +{ + x0_instList.clear(); + x18_ = CSaveableState(); + x6c_curBlock = nullptr; + x70_curLine = nullptr; + x74_curInst = x0_instList.begin(); + x80_ = 0; + x84_ = 0; + x88_curFontSize = 0; +} + +} diff --git a/Runtime/GuiSys/CTextExecuteBuffer.hpp b/Runtime/GuiSys/CTextExecuteBuffer.hpp index ee208e3ed..2f146a2d0 100644 --- a/Runtime/GuiSys/CTextExecuteBuffer.hpp +++ b/Runtime/GuiSys/CTextExecuteBuffer.hpp @@ -9,18 +9,21 @@ namespace urde { class CInstruction; class CFontImageDef; +class CTextRenderBuffer; +class CBlockInstruction; +class CLineInstruction; class CTextExecuteBuffer { - std::list> x0_instList; + std::list> x0_instList; u32 x14_ = 0; CSaveableState x18_; - u32 x6c_ = 0; - u32 x70_ = 0; + CBlockInstruction* x6c_curBlock = nullptr; + CLineInstruction* x70_curLine = nullptr; std::list>::iterator x74_curInst; u32 x80_ = 0; u32 x84_ = 0; - u32 x88_ = 0; + u32 x88_curFontSize = 0; u32 x90_ = 0; u32 x94_ = 0; u32 x98_ = 0; @@ -31,7 +34,7 @@ public: x74_curInst = x0_instList.begin(); } - void CreateTextRenderBuffer() const; + CTextRenderBuffer CreateTextRenderBuffer() const; std::vector GetAssets() const; void AddString(const wchar_t* str, int); void AddStringFragment(const wchar_t* str, int); diff --git a/Runtime/GuiSys/CTextRenderBuffer.hpp b/Runtime/GuiSys/CTextRenderBuffer.hpp index 7ab0a0443..755137933 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.hpp +++ b/Runtime/GuiSys/CTextRenderBuffer.hpp @@ -26,6 +26,8 @@ public: }; enum class EMode { + Zero, + One }; private: EMode x0_mode; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 80a8fe3ae..b05d0e4ca 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -148,6 +148,7 @@ public: 0.0f /*g_tweakPlayer->GetRightLogicalThreshold()*/), m_guiSys(*g_ResFactory, *g_SimplePool, CGuiSys::EUsageMode::Zero) { + g_GuiSys = &m_guiSys; m_inputGenerator.startScanning(); } bool Update()