mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-05-10 19:21:38 +00:00
172 lines
5.9 KiB
C++
172 lines
5.9 KiB
C++
#pragma once
|
|
|
|
#include <gpu/imgui_common.h>
|
|
|
|
static std::vector<std::unique_ptr<ImGuiCallbackData>> g_callbackData;
|
|
static uint32_t g_callbackDataIndex = 0;
|
|
|
|
static ImGuiCallbackData* AddCallback(ImGuiCallback callback)
|
|
{
|
|
if (g_callbackDataIndex >= g_callbackData.size())
|
|
g_callbackData.emplace_back(std::make_unique<ImGuiCallbackData>());
|
|
|
|
auto& callbackData = g_callbackData[g_callbackDataIndex];
|
|
++g_callbackDataIndex;
|
|
|
|
ImGui::GetForegroundDrawList()->AddCallback(reinterpret_cast<ImDrawCallback>(callback), callbackData.get());
|
|
|
|
return callbackData.get();
|
|
}
|
|
|
|
static void SetGradient(const ImVec2& min, const ImVec2& max, ImU32 top, ImU32 bottom)
|
|
{
|
|
auto callbackData = AddCallback(ImGuiCallback::SetGradient);
|
|
callbackData->setGradient.gradientMin[0] = min.x;
|
|
callbackData->setGradient.gradientMin[1] = min.y;
|
|
callbackData->setGradient.gradientMax[0] = max.x;
|
|
callbackData->setGradient.gradientMax[1] = max.y;
|
|
callbackData->setGradient.gradientTop = top;
|
|
callbackData->setGradient.gradientBottom = bottom;
|
|
}
|
|
|
|
static void ResetGradient()
|
|
{
|
|
auto callbackData = AddCallback(ImGuiCallback::SetGradient);
|
|
memset(&callbackData->setGradient, 0, sizeof(callbackData->setGradient));
|
|
}
|
|
|
|
static void SetShaderModifier(uint32_t shaderModifier)
|
|
{
|
|
auto callbackData = AddCallback(ImGuiCallback::SetShaderModifier);
|
|
callbackData->setShaderModifier.shaderModifier = shaderModifier;
|
|
}
|
|
|
|
// Aspect ratio aware.
|
|
static float Scale(float size)
|
|
{
|
|
auto& io = ImGui::GetIO();
|
|
|
|
if (io.DisplaySize.x > io.DisplaySize.y)
|
|
return size * std::max(1.0f, io.DisplaySize.y / 720.0f);
|
|
else
|
|
return size * std::max(1.0f, io.DisplaySize.x / 1280.0f);
|
|
}
|
|
|
|
// Not aspect ratio aware. Will stretch.
|
|
static float ScaleX(float x)
|
|
{
|
|
auto& io = ImGui::GetIO();
|
|
return x * io.DisplaySize.x / 1280.0f;
|
|
}
|
|
|
|
// Not aspect ratio aware. Will stretch.
|
|
static float ScaleY(float y)
|
|
{
|
|
auto& io = ImGui::GetIO();
|
|
return y * io.DisplaySize.y / 720.0f;
|
|
}
|
|
|
|
static void DrawTextWithMarquee(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 color, const char* text, double time, double delay, double speed)
|
|
{
|
|
auto drawList = ImGui::GetForegroundDrawList();
|
|
auto rectWidth = max.x - min.x;
|
|
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0.0f, text);
|
|
auto textX = pos.x - fmodf(std::max(0.0, ImGui::GetTime() - (time + delay)) * speed, textSize.x + rectWidth);
|
|
|
|
drawList->PushClipRect(min, max, true);
|
|
|
|
if (textX <= pos.x)
|
|
drawList->AddText(font, fontSize, { textX, pos.y }, color, text);
|
|
|
|
if (textX + textSize.x < pos.x)
|
|
drawList->AddText(font, fontSize, { textX + textSize.x + rectWidth, pos.y }, color, text);
|
|
|
|
drawList->PopClipRect();
|
|
}
|
|
|
|
template<typename T>
|
|
static void DrawTextWithOutline(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 color, const char* text, T outlineSize, ImU32 outlineColor)
|
|
{
|
|
auto drawList = ImGui::GetForegroundDrawList();
|
|
|
|
if constexpr (std::is_same_v<float, T> || std::is_same_v<double, T>)
|
|
{
|
|
// TODO: This is still very inefficient!
|
|
for (float i = -outlineSize; i <= outlineSize; i += 0.5f)
|
|
{
|
|
for (float j = -outlineSize; j <= outlineSize; j += 0.5f)
|
|
{
|
|
if (i == 0.0f && j == 0.0f)
|
|
continue;
|
|
|
|
drawList->AddText(font, fontSize, { pos.x + i, pos.y + j }, outlineColor, text);
|
|
}
|
|
}
|
|
}
|
|
else if constexpr (std::is_integral_v<T>)
|
|
{
|
|
// TODO: This is very inefficient!
|
|
for (int32_t i = -outlineSize + 1; i < outlineSize; i++)
|
|
{
|
|
for (int32_t j = -outlineSize + 1; j < outlineSize; j++)
|
|
drawList->AddText(font, fontSize, { pos.x + i, pos.y + j }, outlineColor, text);
|
|
}
|
|
}
|
|
|
|
drawList->AddText(font, fontSize, pos, color, text);
|
|
}
|
|
|
|
static void DrawTextWithShadow(const ImFont* font, float fontSize, const ImVec2& pos, ImU32 colour, const char* text, float offset = 2.0f, float radius = 0.4f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255))
|
|
{
|
|
auto drawList = ImGui::GetForegroundDrawList();
|
|
|
|
DrawTextWithOutline<float>(font, fontSize, { pos.x + offset, pos.y + offset }, shadowColour, text, radius, shadowColour);
|
|
drawList->AddText(font, fontSize, pos, colour, text);
|
|
}
|
|
|
|
static void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset = 2.0f, float radius = 0.4f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255))
|
|
{
|
|
auto drawList = ImGui::GetForegroundDrawList();
|
|
auto rectWidth = max.x - min.x;
|
|
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0.0f, text);
|
|
auto textX = pos.x - fmodf(std::max(0.0, ImGui::GetTime() - (time + delay)) * speed, textSize.x + rectWidth);
|
|
|
|
drawList->PushClipRect(min, max, true);
|
|
|
|
if (textX <= pos.x)
|
|
DrawTextWithShadow(font, fontSize, { textX, pos.y }, colour, text, offset, radius, shadowColour);
|
|
|
|
if (textX + textSize.x < pos.x)
|
|
DrawTextWithShadow(font, fontSize, { textX + textSize.x + rectWidth, pos.y }, colour, text, offset, radius, shadowColour);
|
|
|
|
drawList->PopClipRect();
|
|
}
|
|
|
|
static float Lerp(float a, float b, float t)
|
|
{
|
|
return a + (b - a) * t;
|
|
}
|
|
|
|
static float CubicEase(float a, float b, float t)
|
|
{
|
|
return a + (b - a) * (t * t * t);
|
|
}
|
|
|
|
static ImVec2 Lerp(const ImVec2& a, const ImVec2& b, float t)
|
|
{
|
|
return { a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t };
|
|
}
|
|
|
|
static ImU32 ColourLerp(ImU32 c0, ImU32 c1, float t)
|
|
{
|
|
auto a = ImGui::ColorConvertU32ToFloat4(c0);
|
|
auto b = ImGui::ColorConvertU32ToFloat4(c1);
|
|
|
|
ImVec4 result;
|
|
result.x = a.x + (b.x - a.x) * t;
|
|
result.y = a.y + (b.y - a.y) * t;
|
|
result.z = a.z + (b.z - a.z) * t;
|
|
result.w = a.w + (b.w - a.w) * t;
|
|
|
|
return ImGui::ColorConvertFloat4ToU32(result);
|
|
}
|