mirror of
https://github.com/GabsPuNs/Project-Zenith-Main.git
synced 2026-07-09 21:18:08 +00:00
226 lines
5.6 KiB
C++
226 lines
5.6 KiB
C++
#include "RmlManager.h"
|
|
|
|
#pragma push_macro("byte")
|
|
#pragma push_macro("GetNextSibling")
|
|
#pragma push_macro("GetFirstChild")
|
|
#undef byte
|
|
#undef GetNextSibling
|
|
#undef GetFirstChild
|
|
|
|
#include <RmlUi/Core/ElementText.h>
|
|
|
|
#pragma pop_macro("GetFirstChild")
|
|
#pragma pop_macro("GetNextSibling")
|
|
#pragma pop_macro("byte")
|
|
|
|
extern ID3D11Device* g_pd3dDevice;
|
|
extern ID3D11DeviceContext* g_pImmediateContext;
|
|
extern ID3D11RenderTargetView* g_pRenderTargetView;
|
|
|
|
RmlManager& RmlManager::Get()
|
|
{
|
|
static RmlManager instance;
|
|
return instance;
|
|
}
|
|
|
|
RmlManager::RmlManager()
|
|
: m_initialised(false)
|
|
, m_context(nullptr)
|
|
{
|
|
}
|
|
|
|
RmlManager::~RmlManager()
|
|
{
|
|
Shutdown();
|
|
}
|
|
|
|
bool RmlManager::Init(int width, int height)
|
|
{
|
|
if (m_initialised)
|
|
return true;
|
|
|
|
m_file_interface = std::make_unique<FileInterface_Game>();
|
|
m_system_interface = std::make_unique<SystemInterface_Win64>();
|
|
m_renderer = std::make_unique<RenderInterface_D3D11>(g_pd3dDevice, g_pImmediateContext);
|
|
|
|
if (!m_renderer->IsInitialised())
|
|
{
|
|
app.DebugPrintf("[RmlManager] Renderer failed to initialise\n");
|
|
return false;
|
|
}
|
|
|
|
// Set asset path for RmlUi files (relative to exe directory)
|
|
Rml::String assetPath = utils.GetExeDir().string() + "/Assets/UI";
|
|
m_file_interface->SetAssetPath(assetPath);
|
|
|
|
Rml::SetRenderInterface(m_renderer.get());
|
|
Rml::SetSystemInterface(m_system_interface.get());
|
|
Rml::SetFileInterface(m_file_interface.get());
|
|
|
|
if (!Rml::Initialise())
|
|
{
|
|
app.DebugPrintf("[RmlManager] RmlUi Core failed to initialise\n");
|
|
return false;
|
|
}
|
|
|
|
// Minecraft's UI fonts (from tryashtar/minecraft-ttf)
|
|
if (!Rml::LoadFontFace(assetPath + "/fonts/Mojangles.ttf", "Minecraft Default", Rml::Style::FontStyle::Normal, Rml::Style::FontWeight::Normal, false))
|
|
app.DebugPrintf("[RmlManager] FAILED loading Mojangles.ttf\n");
|
|
if (!Rml::LoadFontFace(assetPath + "/fonts/MinecraftTen.ttf", "Minecraft Default", Rml::Style::FontStyle::Normal, Rml::Style::FontWeight::Bold, true))
|
|
app.DebugPrintf("[RmlManager] FAILED loading MinecraftTen.ttf\n");
|
|
|
|
m_context = Rml::CreateContext("main", Rml::Vector2i(width, height));
|
|
if (!m_context)
|
|
{
|
|
app.DebugPrintf("[RmlManager] Failed to create RmlUi context\n");
|
|
Rml::Shutdown();
|
|
return false;
|
|
}
|
|
|
|
app.DebugPrintf("[RmlManager] Context created (%dx%d)\n", width, height);
|
|
|
|
m_renderer->SetViewport(width, height);
|
|
m_initialised = true;
|
|
|
|
app.DebugPrintf("[RmlManager] Initialised (%dx%d)\n", width, height);
|
|
|
|
UpdateDpRatio(width, height);
|
|
|
|
return true;
|
|
}
|
|
|
|
void RmlManager::Shutdown()
|
|
{
|
|
if (!m_initialised)
|
|
return;
|
|
|
|
if (m_context)
|
|
{
|
|
m_context->UnloadAllDocuments();
|
|
Rml::RemoveContext(m_context->GetName());
|
|
m_context = nullptr;
|
|
}
|
|
|
|
Rml::Shutdown();
|
|
|
|
m_renderer.reset();
|
|
m_system_interface.reset();
|
|
m_file_interface.reset();
|
|
|
|
m_initialised = false;
|
|
app.DebugPrintf("[RmlManager] Shutdown\n");
|
|
}
|
|
|
|
void RmlManager::Update()
|
|
{
|
|
if (!m_initialised || !m_context)
|
|
return;
|
|
|
|
m_context->Update();
|
|
}
|
|
|
|
void RmlManager::Render()
|
|
{
|
|
if (!m_initialised || !m_context)
|
|
return;
|
|
|
|
// Ensure we render to the backbuffer (gamma post-process may have restored a
|
|
// different RTV). Use the singleton backbuffer RTV that the rest of the engine
|
|
// binds at frame start.
|
|
if (g_pRenderTargetView)
|
|
{
|
|
ID3D11DepthStencilView* nullDSV = nullptr;
|
|
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, nullDSV);
|
|
}
|
|
|
|
// Clear any SRV still bound from gamma post-process so it doesn't
|
|
// interfere with RmlUi's own texture binding.
|
|
ID3D11ShaderResourceView* nullSRV[1] = { nullptr };
|
|
g_pImmediateContext->PSSetShaderResources(0, 1, nullSRV);
|
|
|
|
m_renderer->BeginFrame();
|
|
|
|
//GabsPuN: This DebugPrintf is called each frame when RMLUI is not used.
|
|
/*
|
|
int docCount = 0;
|
|
for (int i = 0; i < m_context->GetNumDocuments(); i++)
|
|
{
|
|
auto* doc = m_context->GetDocument(i);
|
|
if (doc && doc->IsVisible())
|
|
docCount++;
|
|
}
|
|
if (docCount == 0)
|
|
app.DebugPrintf("[RmlManager] WARNING: No visible documents in context\n");
|
|
*/
|
|
|
|
m_context->Render();
|
|
m_renderer->EndFrame();
|
|
}
|
|
|
|
void RmlManager::OnResize(int width, int height)
|
|
{
|
|
if (!m_initialised || !m_context)
|
|
return;
|
|
|
|
m_context->SetDimensions(Rml::Vector2i(width, height));
|
|
m_renderer->SetViewport(width, height);
|
|
UpdateDpRatio(width, height);
|
|
}
|
|
|
|
void RmlManager::UpdateDpRatio(int width, int height)
|
|
{
|
|
if (!m_context)
|
|
return;
|
|
|
|
float scale_x = static_cast<float>(width) / 1920;
|
|
float scale_y = static_cast<float>(height) / 1080;
|
|
float base_ratio = (scale_x < scale_y) ? scale_x : scale_y;
|
|
|
|
float auto_dp = base_ratio;
|
|
float viewport_cap = 0.88f * static_cast<float>(height) / 850.0f;
|
|
if (auto_dp > viewport_cap)
|
|
auto_dp = viewport_cap;
|
|
|
|
float dp_ratio = auto_dp;
|
|
|
|
if (dp_ratio < 0.5f)
|
|
dp_ratio = 0.5f;
|
|
if (dp_ratio > 3.0f)
|
|
dp_ratio = 3.0f;
|
|
|
|
m_context->SetDensityIndependentPixelRatio(dp_ratio);
|
|
}
|
|
|
|
static void ReTranslateElement(Rml::Element* elem, Rml::SystemInterface* system_if)
|
|
{
|
|
Rml::ElementText* text_elem = rmlui_dynamic_cast<Rml::ElementText*>(elem);
|
|
if (text_elem)
|
|
{
|
|
const Rml::Variant* src = elem->GetAttribute("data-rml-source");
|
|
if (src)
|
|
{
|
|
Rml::String original = src->Get<Rml::String>();
|
|
Rml::String translated;
|
|
system_if->TranslateString(translated, original);
|
|
if (translated != text_elem->GetText())
|
|
text_elem->SetText(translated);
|
|
}
|
|
}
|
|
for (int i = 0; i < elem->GetNumChildren(true); i++)
|
|
ReTranslateElement(elem->GetChild(i), system_if);
|
|
}
|
|
|
|
void RmlManager::OnLanguageChanged()
|
|
{
|
|
if (!m_initialised || !m_context)
|
|
return;
|
|
|
|
app.DebugPrintf("[RmlManager] Re-translating all documents\n");
|
|
|
|
for (int i = 0; i < m_context->GetNumDocuments(); i++)
|
|
{
|
|
Rml::ElementDocument* doc = m_context->GetDocument(i);
|
|
if (doc)
|
|
ReTranslateElement(doc, m_system_interface.get());
|
|
}
|
|
} |