947 lines
32 KiB
C++
947 lines
32 KiB
C++
#include "draw.h"
|
|
|
|
// used: cheat variables
|
|
#include "../core/variables.h"
|
|
// used: viewmatrix
|
|
#include "../core/sdk.h"
|
|
|
|
// used: m_deg2rad
|
|
#include "math.h"
|
|
// used: memoryset
|
|
#include "crt.h"
|
|
// used: easing
|
|
#include "easing.h"
|
|
// used: ipt
|
|
#include "inputsystem.h"
|
|
|
|
// used: [ext] imgui
|
|
#include "../../dependencies/imgui/imgui_freetype.h"
|
|
#include "../../dependencies/imgui/imgui_impl_dx11.h"
|
|
#include "../../dependencies/imgui/imgui_impl_win32.h"
|
|
|
|
// used: [resouces] font awesome
|
|
#include "../../resources/fa_solid_900.h"
|
|
#include "../../resources/font_awesome_5.h"
|
|
#include "../core/ImFont.h"
|
|
#include "../core/imfonts.h"
|
|
#include "../core/Bgs.h"
|
|
#include "../core/Header.h"
|
|
#include "../core/gui.hpp"
|
|
#include "../cstrike/font.h"
|
|
#include "../cstrike/texture.h"
|
|
#include "../dependencies/imgui/imgui_settings.h"
|
|
// used: engine/engineclient
|
|
#include "../sdk/interfaces/iengineclient.h"
|
|
|
|
//dx11:
|
|
#include "../sdk/interfaces/iswapchaindx11.h"
|
|
|
|
// used: iinputsystem
|
|
#include "../core/interfaces.h"
|
|
#include "../sdk/interfaces/iinputsystem.h"
|
|
|
|
// used: bMainWindowOpened
|
|
#include "../core/menu.h"
|
|
#include "../core/ui_icons.hpp"
|
|
|
|
#pragma region imgui_extended
|
|
static constexpr const char* arrKeyNames[] = {
|
|
"",
|
|
"mouse 1", "mouse 2", "cancel", "mouse 3", "mouse 4", "mouse 5", "",
|
|
"backspace", "tab", "", "", "clear", "enter", "", "",
|
|
"shift", "control", "alt", "pause", "caps", "", "", "", "", "", "",
|
|
"escape", "", "", "", "", "space", "page up", "page down",
|
|
"end", "home", "left", "up", "right", "down", "", "", "",
|
|
"print", "insert", "delete", "",
|
|
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
|
"", "", "", "", "", "", "",
|
|
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
|
|
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
|
|
"v", "w", "x", "y", "z", "lwin", "rwin", "", "", "",
|
|
"num0", "num1", "num2", "num3", "num4", "num5",
|
|
"num6", "num7", "num8", "num9",
|
|
"*", "+", "", "-", ".", "/",
|
|
"f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8",
|
|
"f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16",
|
|
"f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24",
|
|
"", "", "", "", "", "", "", "",
|
|
"num lock", "scroll lock",
|
|
"", "", "", "", "", "", "",
|
|
"", "", "", "", "", "", "",
|
|
"lshift", "rshift", "lctrl",
|
|
"rctrl", "lmenu", "rmenu"
|
|
};
|
|
|
|
void ImGui::HelpMarker(const char* szDescription)
|
|
{
|
|
TextDisabled(CS_XOR("(?)"));
|
|
if (IsItemHovered())
|
|
{
|
|
BeginTooltip();
|
|
PushTextWrapPos(450.f);
|
|
TextUnformatted(szDescription);
|
|
PopTextWrapPos();
|
|
EndTooltip();
|
|
}
|
|
}
|
|
|
|
bool ImGui::HotKey(const char* szLabel, unsigned int* pValue)
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiWindow* pWindow = g.CurrentWindow;
|
|
|
|
if (pWindow->SkipItems)
|
|
return false;
|
|
|
|
ImGuiIO& io = g.IO;
|
|
const ImGuiStyle& style = g.Style;
|
|
const ImGuiID nIndex = pWindow->GetID(szLabel);
|
|
|
|
const float flWidth = CalcItemWidth();
|
|
const ImVec2 vecLabelSize = CalcTextSize(szLabel, nullptr, true);
|
|
float xOffset = 50.f;
|
|
const ImRect rectFrame(pWindow->DC.CursorPos + ImVec2(vecLabelSize.x > 0.0f ? style.ItemInnerSpacing.x + GetFrameHeight() + xOffset : xOffset, 0.0f), pWindow->DC.CursorPos + ImVec2(flWidth + xOffset, vecLabelSize.x > 0.0f ? vecLabelSize.y + style.FramePadding.y : 0.f));
|
|
const ImRect rectTotal(rectFrame.Min, rectFrame.Max);
|
|
|
|
|
|
ItemSize(rectTotal, style.FramePadding.y);
|
|
if (!ItemAdd(rectTotal, nIndex, &rectFrame))
|
|
return false;
|
|
|
|
const bool bHovered = ItemHoverable(rectFrame, nIndex, ImGuiItemFlags_None);
|
|
if (bHovered)
|
|
{
|
|
SetHoveredID(nIndex);
|
|
g.MouseCursor = ImGuiMouseCursor_TextInput;
|
|
}
|
|
|
|
const bool bClicked = bHovered && io.MouseClicked[0];
|
|
const bool bDoubleClicked = bHovered && io.MouseDoubleClicked[0];
|
|
if (bClicked || bDoubleClicked)
|
|
{
|
|
if (g.ActiveId != nIndex)
|
|
{
|
|
CRT::MemorySet(io.MouseDown, 0, sizeof(io.MouseDown));
|
|
CRT::MemorySet(io.KeysDown, 0, sizeof(io.KeysDown));
|
|
*pValue = 0U;
|
|
}
|
|
|
|
SetActiveID(nIndex, pWindow);
|
|
FocusWindow(pWindow);
|
|
}
|
|
|
|
bool bValueChanged = false;
|
|
if (unsigned int nKey = *pValue; g.ActiveId == nIndex)
|
|
{
|
|
for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++)
|
|
{
|
|
if (IsMouseDown(n))
|
|
{
|
|
switch (n)
|
|
{
|
|
case 0:
|
|
nKey = VK_LBUTTON;
|
|
break;
|
|
case 1:
|
|
nKey = VK_RBUTTON;
|
|
break;
|
|
case 2:
|
|
nKey = VK_MBUTTON;
|
|
break;
|
|
case 3:
|
|
nKey = VK_XBUTTON1;
|
|
break;
|
|
case 4:
|
|
nKey = VK_XBUTTON2;
|
|
break;
|
|
}
|
|
|
|
bValueChanged = true;
|
|
ClearActiveID();
|
|
}
|
|
}
|
|
|
|
if (!bValueChanged)
|
|
{
|
|
for (int n = VK_BACK; n <= VK_RMENU; n++)
|
|
{
|
|
if (IsKeyDown((ImGuiKey)n))
|
|
{
|
|
nKey = n;
|
|
bValueChanged = true;
|
|
ClearActiveID();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsKeyPressed(ImGuiKey_Escape))
|
|
{
|
|
*pValue = 0U;
|
|
ClearActiveID();
|
|
}
|
|
else
|
|
*pValue = nKey;
|
|
}
|
|
|
|
char szBuffer[64] = {};
|
|
char* szBufferEnd = CRT::StringCopy(szBuffer, " ");
|
|
if (*pValue != 0 && g.ActiveId != nIndex)
|
|
szBufferEnd = CRT::StringCat(szBufferEnd, arrKeyNames[*pValue]);
|
|
else if (g.ActiveId == nIndex)
|
|
szBufferEnd = CRT::StringCat(szBufferEnd, CS_XOR("press"));
|
|
else
|
|
szBufferEnd = CRT::StringCat(szBufferEnd, CS_XOR("none"));
|
|
CRT::StringCat(szBufferEnd, " ");
|
|
|
|
PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x, -1));
|
|
|
|
const ImVec2 vecBufferSize = CalcTextSize(szBuffer);
|
|
RenderFrame(ImVec2(rectFrame.Max.x - vecBufferSize.x, rectTotal.Min.y), ImVec2(rectFrame.Max.x, rectTotal.Min.y + style.FramePadding.y + vecBufferSize.y), GetColorU32((bHovered || bClicked || bDoubleClicked) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
pWindow->DrawList->AddText(ImVec2(rectFrame.Max.x - vecBufferSize.x, rectTotal.Min.y + style.FramePadding.y), GetColorU32(g.ActiveId == nIndex ? ImGuiCol_Text : ImGuiCol_TextDisabled), szBuffer);
|
|
|
|
//if (vecLabelSize.x > 0.f)
|
|
//RenderText(ImVec2(rectTotal.Min.x, rectTotal.Min.y + style.FramePadding.y), szLabel);
|
|
|
|
PopStyleVar();
|
|
return bValueChanged;
|
|
}
|
|
|
|
bool ImGui::HotKey(const char* szLabel, KeyBind_t* pKeyBind, const bool bAllowSwitch)
|
|
{
|
|
const bool bValueChanged = HotKey(szLabel, &pKeyBind->uKey);
|
|
|
|
if (bAllowSwitch)
|
|
{
|
|
|
|
char* szUniqueID = static_cast<char*>(MEM_STACKALLOC(CRT::StringLength(szLabel) + 6));
|
|
CRT::StringCat(CRT::StringCopy(szUniqueID, CS_XOR("key##")), szLabel);
|
|
|
|
if (IsItemClicked(ImGuiMouseButton_Right))
|
|
OpenPopup(szUniqueID);
|
|
|
|
if (BeginPopup(szUniqueID))
|
|
{
|
|
SetNextItemWidth(ImGui::GetWindowWidth() + 20.f);
|
|
if (Combo(CS_XOR("##keybind.mode"), reinterpret_cast<int*>(&pKeyBind->nMode), CS_XOR("Hold\0Toggle\0\0")))
|
|
CloseCurrentPopup();
|
|
|
|
EndPopup();
|
|
}
|
|
|
|
MEM_STACKFREE(szUniqueID);
|
|
}
|
|
|
|
return bValueChanged;
|
|
}
|
|
|
|
|
|
|
|
bool ImGui::BeginListBox(const char* szLabel, int nItemsCount, int nHeightInItems)
|
|
{
|
|
float height = GetTextLineHeightWithSpacing() * ((nHeightInItems < 0 ? ImMin(nItemsCount, 7) : nHeightInItems) + 0.25f) + GetStyle().FramePadding.y * 2.0f;
|
|
return BeginListBox(szLabel, ImVec2(0.0f, height));
|
|
}
|
|
|
|
bool ImGui::ColorEdit3(const char* szLabel, Color_t* pColor, ImGuiColorEditFlags flags)
|
|
{
|
|
return ColorEdit4(szLabel, pColor, flags | ImGuiColorEditFlags_NoAlpha);
|
|
}
|
|
|
|
bool ImGui::ColorEdit4(const char* szLabel, Color_t* pColor, ImGuiColorEditFlags flags, int type)
|
|
{
|
|
if (type == 0) {
|
|
ImVec2 v1 = ImGui::GetItemRectSize();
|
|
ImVec2 v1pos = ImGui::GetCursorPos();
|
|
ImGui::SameLine(v1pos.x + v1.x + 230);
|
|
}
|
|
if (type == 1) {
|
|
ImVec2 v1 = ImGui::GetItemRectSize();
|
|
ImVec2 v1pos = ImGui::GetCursorPos();
|
|
ImGui::SameLine(v1pos.x + v1.x + 75.f);
|
|
}
|
|
float arrColor[4];
|
|
pColor->BaseAlpha(arrColor);
|
|
|
|
if (ColorEdit4(szLabel, &arrColor[0], flags))
|
|
{
|
|
*pColor = Color_t::FromBase4(arrColor);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool ImGui::ColorEdit3(const char* szLabel, ColorPickerVar_t* pColor, ImGuiColorEditFlags flags)
|
|
{
|
|
return ColorEdit4(szLabel, pColor, flags | ImGuiColorEditFlags_NoAlpha);
|
|
}
|
|
|
|
bool ImGui::ColorEdit4(const char* szLabel, ColorPickerVar_t* pColorVar, ImGuiColorEditFlags flags, int type)
|
|
{
|
|
const bool bResult = ColorEdit4(szLabel, &pColorVar->colValue, flags);
|
|
|
|
// switch rainbow mode on middle mouse click
|
|
if (IsItemHovered())
|
|
{
|
|
// tooltip for turn on/off rainbow mode
|
|
BeginTooltip();
|
|
{
|
|
PushTextWrapPos(450.f);
|
|
TextUnformatted(CS_XOR("use mouse middle-click to turn on/off rainbow mode!"));
|
|
PopTextWrapPos();
|
|
}
|
|
EndTooltip();
|
|
|
|
if (IsMouseClicked(ImGuiMouseButton_Middle))
|
|
pColorVar->bRainbow = !pColorVar->bRainbow;
|
|
}
|
|
|
|
// open the context popup
|
|
OpenPopupOnItemClick(CS_XOR("context##color.picker"), ImGuiPopupFlags_MouseButtonRight);
|
|
// @todo: cleaner code
|
|
SetNextWindowSize(ImVec2((pColorVar->bRainbow ? 120.f : 60.f) * D::CalculateDPI(C_GET(int, Vars.nDpiScale)), 0.f));
|
|
if (BeginPopup(CS_XOR("context##color.picker")))
|
|
{
|
|
if (Button(CS_XOR("copy##color.picker"), ImVec2(-1, 25 * D::CalculateDPI(C_GET(int, Vars.nDpiScale)))))
|
|
{
|
|
// @todo: im32 hex format is AARRGGBB, but we need RRGGBBAA
|
|
CRT::String_t<64U> szBuffer(CS_XOR("#%X"), pColorVar->colValue.GetU32());
|
|
SetClipboardText(szBuffer.Data());
|
|
szBuffer.Clear();
|
|
|
|
CloseCurrentPopup();
|
|
}
|
|
|
|
if (Button(CS_XOR("paste##color.picker"), ImVec2(-1, 25 * D::CalculateDPI(C_GET(int, Vars.nDpiScale)))))
|
|
{
|
|
const char* szClipboardText = GetClipboardText();
|
|
// @note: +1U for '#' prefix skipping
|
|
const ImU32 uConvertedColor = CRT::StringToInteger<ImU32>(szClipboardText + 1U, nullptr, 16);
|
|
|
|
pColorVar->colValue = Color_t(uConvertedColor);
|
|
CloseCurrentPopup();
|
|
}
|
|
|
|
if (pColorVar->bRainbow)
|
|
{
|
|
// @note: urgh padding moment idk
|
|
SetNextItemWidth(ImGui::GetWindowWidth() * 0.90f + 1.f);
|
|
SliderFloat(CS_XOR("##speed.color.picker"), &pColorVar->flRainbowSpeed, 0.f, 5.f, CS_XOR("speed: %.1f"), ImGuiSliderFlags_AlwaysClamp);
|
|
}
|
|
|
|
EndPopup();
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
|
|
#include <d3dcompiler.h>
|
|
|
|
// Forward declaration of the ImGui render function.
|
|
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
|
void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx);
|
|
|
|
// thread-safe draw data mutex
|
|
static SRWLOCK drawLock = {};
|
|
|
|
static void* __cdecl ImGuiAllocWrapper(const std::size_t nSize, [[maybe_unused]] void* pUserData = nullptr)
|
|
{
|
|
return MEM::HeapAlloc(nSize);
|
|
}
|
|
|
|
static void __cdecl ImGuiFreeWrapper(void* pMemory, [[maybe_unused]] void* pUserData = nullptr) noexcept
|
|
{
|
|
MEM::HeapFree(pMemory);
|
|
}
|
|
|
|
// Function to load a texture from memory
|
|
HRESULT LoadTextureFromMemory(ID3D11Device* device, const void* data, size_t dataSize, ID3D11ShaderResourceView** textureView)
|
|
{
|
|
D3D11_TEXTURE2D_DESC desc;
|
|
ZeroMemory(&desc, sizeof(desc));
|
|
desc.Width = 512; // Set the width of your texture
|
|
desc.Height = 512; // Set the height of your texture
|
|
desc.MipLevels = 1;
|
|
desc.ArraySize = 1;
|
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Adjust the format based on your texture data
|
|
desc.SampleDesc.Count = 1;
|
|
desc.SampleDesc.Quality = 0;
|
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
|
desc.CPUAccessFlags = 0;
|
|
desc.MiscFlags = 0;
|
|
|
|
D3D11_SUBRESOURCE_DATA initData;
|
|
ZeroMemory(&initData, sizeof(initData));
|
|
initData.pSysMem = data;
|
|
initData.SysMemPitch = static_cast<UINT>(desc.Width * 4); // Assuming 4 bytes per pixel, adjust as needed
|
|
|
|
ID3D11Texture2D* texture = nullptr;
|
|
HRESULT hr = device->CreateTexture2D(&desc, &initData, &texture);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
|
srvDesc.Format = desc.Format;
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
|
|
|
hr = device->CreateShaderResourceView(texture, &srvDesc, textureView);
|
|
|
|
// Release the texture because we have created a shader resource view
|
|
texture->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#include "stb_image.h"
|
|
#include "../core/hooks.h"
|
|
|
|
// Simple helper function to load an image into a DX11 texture with common settings
|
|
bool LoadTextureFromFile(const char* filename, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height)
|
|
{
|
|
// Load from disk into a raw RGBA buffer
|
|
int image_width = 0;
|
|
int image_height = 0;
|
|
unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
|
|
if (image_data == NULL)
|
|
return false;
|
|
|
|
// Create texture
|
|
D3D11_TEXTURE2D_DESC desc;
|
|
ZeroMemory(&desc, sizeof(desc));
|
|
desc.Width = image_width;
|
|
desc.Height = image_height;
|
|
desc.MipLevels = 1;
|
|
desc.ArraySize = 1;
|
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
desc.SampleDesc.Count = 1;
|
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
|
desc.CPUAccessFlags = 0;
|
|
|
|
ID3D11Texture2D* pTexture = NULL;
|
|
D3D11_SUBRESOURCE_DATA subResource;
|
|
subResource.pSysMem = image_data;
|
|
subResource.SysMemPitch = desc.Width * 4;
|
|
subResource.SysMemSlicePitch = 0;
|
|
I::Device->CreateTexture2D(&desc, &subResource, &pTexture);
|
|
|
|
// Create texture view
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
|
I::Device->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
|
|
pTexture->Release();
|
|
|
|
*out_width = image_width;
|
|
*out_height = image_height;
|
|
stbi_image_free(image_data);
|
|
|
|
return true;
|
|
}
|
|
#include "../icons/iconscs2.c"
|
|
int my_image_width = 170;
|
|
int my_image_height = 295;
|
|
float font_size = 18.f; // The desired font size
|
|
|
|
bool D::InitImGui()
|
|
{
|
|
if (bInitialized) {
|
|
L_PRINT(LOG_WARNING) << CS_XOR("Aready Initialized overlay");
|
|
return false;
|
|
}
|
|
ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper);
|
|
|
|
ImGui::CreateContext();
|
|
ImGui::SetCurrentContext(ImGui::GetCurrentContext());
|
|
ImGui_ImplWin32_Init(IPT::hWindow);
|
|
ImGui_ImplDX11_Init(I::Device, I::DeviceContext);
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.IniFilename = nullptr;
|
|
io.LogFilename = nullptr;
|
|
|
|
io.MouseDrawCursor = MENU::bMainWindowOpened;
|
|
|
|
|
|
// create draw data containers
|
|
pDrawListActive = IM_NEW(ImDrawList)(ImGui::GetDrawListSharedData());
|
|
pDrawListSafe = IM_NEW(ImDrawList)(ImGui::GetDrawListSharedData());
|
|
pDrawListRender = IM_NEW(ImDrawList)(ImGui::GetDrawListSharedData());
|
|
|
|
#pragma region draw_setup_style
|
|
ImGuiStyle& style = ImGui::GetStyle();
|
|
style.Alpha = 1.0f;
|
|
style.WindowPadding = ImVec2(8, 8);
|
|
style.WindowRounding = 4.0f;
|
|
style.WindowBorderSize = 1.0f;
|
|
style.WindowMinSize = ImVec2(32, 32);
|
|
style.WindowTitleAlign = ImVec2(0.5f, 0.5f);
|
|
style.ChildRounding = 4.0f;
|
|
style.ChildBorderSize = 1.0f;
|
|
style.PopupRounding = 4.0f;
|
|
style.PopupBorderSize = 1.0f;
|
|
style.FramePadding = ImVec2(4, 2);
|
|
style.FrameRounding = 4.0f;
|
|
style.FrameBorderSize = 1.0f;
|
|
style.ItemSpacing = ImVec2(8, 4);
|
|
style.ItemInnerSpacing = ImVec2(4, 4);
|
|
style.IndentSpacing = 6.0f;
|
|
style.ColumnsMinSpacing = 6.0f;
|
|
style.ScrollbarSize = 6.0f;
|
|
style.ScrollbarRounding = 9.0f;
|
|
style.GrabMinSize = 0.0f;
|
|
style.GrabRounding = 4.0f;
|
|
style.TabRounding = 4.0f;
|
|
style.TabBorderSize = 1.0f;
|
|
style.ButtonTextAlign = ImVec2(0.5f, 0.5f);
|
|
style.SelectableTextAlign = ImVec2(0.0f, 0.5f);
|
|
style.WindowShadowSize = 0.f;
|
|
style.AntiAliasedLines = true;
|
|
style.AntiAliasedFill = true;
|
|
style.AntiAliasedLinesUseTex = true;
|
|
style.ColorButtonPosition = ImGuiDir_Right;
|
|
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
|
|
style.Colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f);
|
|
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
|
style.Colors[ImGuiCol_Header] = ImVec4{ ImColor(15, 18, 15, 155) };
|
|
style.Colors[ImGuiCol_HeaderHovered] = ImVec4{ ImColor(15, 18, 15, 155) };
|
|
style.Colors[ImGuiCol_HeaderActive] = ImVec4{ ImColor(15, 18, 15, 155) };
|
|
style.Colors[ImGuiCol_Separator] = style.Colors[ImGuiCol_Border];
|
|
style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
|
|
style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 0.00f);
|
|
style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0);
|
|
style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0);
|
|
style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0);
|
|
style.Colors[ImGuiCol_Button] = ImVec4{ ImColor(15, 18, 15, 155) };
|
|
style.Colors[ImGuiCol_ButtonHovered] = ImVec4{ ImColor(15, 18, 15, 155) };
|
|
style.Colors[ImGuiCol_ButtonActive] = ImVec4{ ImColor(15, 18, 15, 155) };
|
|
#pragma endregion
|
|
|
|
io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
|
|
|
|
for (int i = 0; i < CS_ARRAYSIZE(FONT::pMenu); i++) {
|
|
const float flFontSize = 16.f * CalculateDPI(i);
|
|
FONT::pMenu[i] = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), flFontSize, nullptr, io.Fonts->GetGlyphRangesCyrillic());
|
|
}
|
|
|
|
ImFontConfig verdana_cfg;
|
|
ImFontConfig name_cfg;
|
|
ImFontConfig seg_cfg;
|
|
ImFontConfig tahoma_cfg;
|
|
verdana_cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
|
|
tahoma_cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_Bitmap;
|
|
seg_cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_NoHinting;
|
|
name_cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_ForceAutoHint;
|
|
|
|
ImFontConfig cfg;
|
|
cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_ForceAutoHint | ImGuiFreeTypeBuilderFlags_LightHinting | ImGuiFreeTypeBuilderFlags_LoadColor;
|
|
|
|
font::lexend_general_bold = io.Fonts->AddFontFromFileTTF(("C:\\Windows\\Fonts\\segoeui.ttf"), 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
|
font::lexend_bold = io.Fonts->AddFontFromFileTTF(("C:\\Windows\\Fonts\\segoeui.ttf"), 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
|
|
|
font::lexend_regular = io.Fonts->AddFontFromMemoryTTF(lexend_regular, sizeof(lexend_regular), 14.f, &cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
font::icomoon = io.Fonts->AddFontFromMemoryTTF(icomoon, sizeof(icomoon), 20.f, &cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
|
|
font::icomoon_widget = io.Fonts->AddFontFromMemoryTTF(icomoon_widget, sizeof(icomoon_widget), 15.f, &cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
font::icomoon_widget2 = io.Fonts->AddFontFromMemoryTTF(icomoon, sizeof(icomoon), 16.f, &cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
|
|
|
|
FONT::pExtra = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 12.f, &verdana_cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
FONT::pEspHealth = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 9.f, &verdana_cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
FONT::pMenuTabsDesc = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 12.f, &verdana_cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
FONT::pEspWepName = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 10.f, &name_cfg, io.Fonts->GetGlyphRangesDefault());
|
|
FONT::pEspName = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 11.5f, &name_cfg, io.Fonts->GetGlyphRangesDefault());
|
|
FONT::pVisual = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Tahoma.ttf"), 14.f, &tahoma_cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
FONT::pEspFlagsName = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 11.f, &verdana_cfg, io.Fonts->GetGlyphRangesDefault());
|
|
FONT::pEspIcons = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 10.f, &name_cfg, io.Fonts->GetGlyphRangesDefault());
|
|
|
|
LoadTextureFromFile("C:\\Program Files\\cs2.png", &I::Maintexture, &my_image_width, &my_image_height);
|
|
|
|
FONT::isis = io.Fonts->AddFontFromFileTTF(("C:\\Windows\\Fonts\\segoeui.ttf"), 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
|
FONT::icon_font = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Tahoma.ttf"), 18.f, &tahoma_cfg, io.Fonts->GetGlyphRangesCyrillic());
|
|
FONT::font = io.Fonts->AddFontFromFileTTF(("C:\\Windows\\Fonts\\segoeui.ttf"), 16.0f, NULL, io.Fonts->GetGlyphRangesCyrillic());
|
|
FONT::mainfont = io.Fonts->AddFontFromFileTTF(("C:\\Windows\\Fonts\\segoeui.ttf"), 18.f, NULL, io.Fonts->GetGlyphRangesCyrillic());
|
|
|
|
io.Fonts->FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
|
|
bInitialized = io.Fonts->Build();
|
|
return bInitialized;
|
|
}
|
|
|
|
#include "../cstrike/features/visuals/overlay.h"
|
|
|
|
void D::Destroy()
|
|
{
|
|
// check is it already destroyed or wasn't initialized at all
|
|
if (!bInitialized)
|
|
return;
|
|
|
|
ImGui::GetIO().Fonts->Clear();
|
|
ImGui::GetIO().Fonts->TexID = 0;
|
|
|
|
// free draw data containers
|
|
IM_DELETE(pDrawListActive);
|
|
IM_DELETE(pDrawListSafe);
|
|
IM_DELETE(pDrawListRender);
|
|
|
|
// shutdown imgui direct<x9 renderer binding
|
|
ImGui_ImplDX11_Shutdown();
|
|
|
|
// shutdown imgui win32 platform binding
|
|
ImGui_ImplWin32_Shutdown();
|
|
|
|
// destroy imgui context
|
|
ImGui::DestroyContext();
|
|
L_PRINT(LOG_ERROR) << CS_XOR("\"Destroy\" unloaded");
|
|
|
|
bInitialized = false;
|
|
}
|
|
#pragma region draw_render
|
|
void D::Render() {
|
|
ImGui_ImplDX11_NewFrame();
|
|
ImGui_ImplWin32_NewFrame();
|
|
ImGui::NewFrame();
|
|
|
|
|
|
|
|
F::VISUALS::OVERLAY::Render();
|
|
|
|
MENU::RenderMainWindow();
|
|
|
|
ImGui::Render();
|
|
|
|
I::DeviceContext->OMSetRenderTargets(1, &I::RenderTargetView, NULL);
|
|
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
|
}
|
|
#pragma endregion
|
|
|
|
#pragma region draw_callbacks
|
|
|
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
bool D::OnWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// check is drawing initialized
|
|
if (!bInitialized)
|
|
return false;
|
|
|
|
IPT::OnWndProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
// switch menu state
|
|
if (IPT::IsKeyReleased(C_GET(unsigned int, Vars.nMenuKey)))
|
|
{
|
|
MENU::bMainWindowOpened = !MENU::bMainWindowOpened;
|
|
// update animation
|
|
MENU::animMenuDimBackground.Switch();
|
|
// handle mouse input when menu is opened
|
|
if (I::InputSystem->IsRelativeMouseMode())
|
|
{
|
|
// set input system mouse mode
|
|
MEM::fnSetRelativeMouseMode(!MENU::bMainWindowOpened);
|
|
// set input system window grab state
|
|
MEM::fnSetWindowGrab(I::InputSystem->GetSDLWindow(), !MENU::bMainWindowOpened);
|
|
// warp our cursor into middle of the screen
|
|
const ImVec2 vecScreenCenter = ImGui::GetIO().DisplaySize / 2.f;
|
|
MEM::fnWarpMouseInWindow(nullptr, vecScreenCenter.x, vecScreenCenter.y);
|
|
}
|
|
}
|
|
|
|
// handle ImGui's window messages and block game's input if menu is opened
|
|
return ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam) || MENU::bMainWindowOpened;
|
|
}
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region draw_main
|
|
|
|
void D::RenderDrawData(ImDrawData* pDrawData)
|
|
{
|
|
if (!pDrawData)
|
|
return;
|
|
|
|
if (TryAcquireSRWLockExclusive(&drawLock))
|
|
{
|
|
*pDrawListRender = *pDrawListSafe;
|
|
ReleaseSRWLockExclusive(&drawLock);
|
|
}
|
|
|
|
if (pDrawListRender->CmdBuffer.empty())
|
|
return;
|
|
|
|
// remove trailing command if unused
|
|
// @note: equivalent to pDrawList->_PopUnusedDrawCmd()
|
|
const ImDrawCmd& lastCommand = pDrawListRender->CmdBuffer.back();
|
|
if ( lastCommand.ElemCount == 0 && lastCommand.UserCallback == nullptr)
|
|
{
|
|
pDrawListRender->CmdBuffer.pop_back();
|
|
if (pDrawListRender->CmdBuffer.empty())
|
|
return;
|
|
}
|
|
|
|
ImGuiContext* pContext = ImGui::GetCurrentContext();
|
|
ImGuiViewportP* pViewport = pContext->Viewports[0];
|
|
ImVector<ImDrawList*>* vecDrawLists = pViewport->DrawDataBuilder.Layers[0];
|
|
vecDrawLists->push_front(pDrawListRender); // this one being most background
|
|
|
|
pDrawData->CmdLists.push_front(pDrawListRender);
|
|
pDrawData->CmdListsCount = vecDrawLists->Size;
|
|
pDrawData->TotalVtxCount += pDrawListRender->VtxBuffer.Size;
|
|
pDrawData->TotalIdxCount += pDrawListRender->IdxBuffer.Size;
|
|
}
|
|
|
|
void D::ResetDrawData()
|
|
{
|
|
pDrawListActive->_ResetForNewFrame();
|
|
pDrawListActive->PushTextureID(ImGui::GetIO().Fonts->TexID);
|
|
pDrawListActive->PushClipRectFullScreen();
|
|
}
|
|
|
|
void D::SwapDrawData()
|
|
{
|
|
::AcquireSRWLockExclusive(&drawLock);
|
|
|
|
|
|
*pDrawListSafe = *pDrawListActive;
|
|
|
|
::ReleaseSRWLockExclusive(&drawLock);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region draw_bindings
|
|
|
|
bool D::WorldToScreen(const Vector_t& in, ImVec2& out)
|
|
{
|
|
if (!ImGui::GetCurrentContext())
|
|
return false;
|
|
|
|
auto z = SDK::ViewMatrix[3][0] * in.x + SDK::ViewMatrix[3][1] * in.y + SDK::ViewMatrix[3][2] * in.z + SDK::ViewMatrix[3][3];
|
|
if (z < 0.001f) return false;
|
|
|
|
out = ImGui::GetIO().DisplaySize * 0.5f;
|
|
out.x *= 1.0f + (SDK::ViewMatrix[0][0] * in.x + SDK::ViewMatrix[0][1] * in.y + SDK::ViewMatrix[0][2] * in.z + SDK::ViewMatrix[0][3]) / z;
|
|
out.y *= 1.0f - (SDK::ViewMatrix[1][0] * in.x + SDK::ViewMatrix[1][1] * in.y + SDK::ViewMatrix[1][2] * in.z + SDK::ViewMatrix[1][3]) / z;
|
|
|
|
// Prevents rounded corners.
|
|
out = ImFloor(out);
|
|
|
|
return true;
|
|
}
|
|
|
|
float D::CalculateDPI(const int nScaleTarget)
|
|
{
|
|
switch ((EMiscDpiScale)nScaleTarget)
|
|
{
|
|
case EMiscDpiScale::MISC_DPISCALE_DEFAULT:
|
|
return 1.f;
|
|
case EMiscDpiScale::MISC_DPISCALE_125:
|
|
return 1.25f;
|
|
case EMiscDpiScale::MISC_DPISCALE_150:
|
|
return 1.5f;
|
|
case EMiscDpiScale::MISC_DPISCALE_175:
|
|
return 1.75f;
|
|
case EMiscDpiScale::MISC_DPISCALE_200:
|
|
return 2.f;
|
|
default:
|
|
return 1.f;
|
|
}
|
|
}
|
|
|
|
void D::AddDrawListRect(ImDrawList* pDrawList, const ImVec2& vecMin, const ImVec2& vecMax, const Color_t& colRect, const unsigned int uFlags, const Color_t& colOutline, const float flRounding, const ImDrawFlags roundingCorners, float flThickness, const float flOutlineThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
const ImU32 colRectPacked = colRect.GetU32();
|
|
const ImU32 colOutlinePacked = colOutline.GetU32();
|
|
|
|
if (uFlags & DRAW_RECT_FILLED)
|
|
pDrawList->AddRectFilled(vecMin, vecMax, colRectPacked, flRounding, roundingCorners);
|
|
else
|
|
{
|
|
pDrawList->AddRect(vecMin, vecMax, colRectPacked, flRounding, roundingCorners, flThickness);
|
|
flThickness *= 0.5f;
|
|
}
|
|
|
|
const float flHalfOutlineThickness = flOutlineThickness * 0.5f;
|
|
const ImVec2 vecThicknessOffset = { flThickness + flHalfOutlineThickness, flThickness + flHalfOutlineThickness };
|
|
|
|
if (uFlags & DRAW_RECT_BORDER)
|
|
pDrawList->AddRect(vecMin + vecThicknessOffset, vecMax - vecThicknessOffset, colOutlinePacked, flRounding, roundingCorners, flOutlineThickness);
|
|
|
|
if (uFlags & DRAW_RECT_OUTLINE)
|
|
pDrawList->AddRect(vecMin - vecThicknessOffset, vecMax + vecThicknessOffset, colOutlinePacked, flRounding, roundingCorners, flOutlineThickness);
|
|
}
|
|
|
|
void D::AddDrawListRectMultiColor(ImDrawList* pDrawList, const ImVec2& vecMin, const ImVec2& vecMax, const Color_t& colUpperLeft, const Color_t& colUpperRight, const Color_t& colBottomRight, const Color_t& colBottomLeft)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
pDrawList->AddRectFilledMultiColor(vecMin, vecMax, colUpperLeft.GetU32(), colUpperRight.GetU32(), colBottomRight.GetU32(), colBottomLeft.GetU32());
|
|
}
|
|
|
|
void D::AddDrawListCircle(ImDrawList* pDrawList, const ImVec2& vecCenter, const float flRadius, const Color_t& colCircle, const int nSegments, const unsigned int uFlags, const Color_t& colOutline, float flThickness, const float flOutlineThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
const ImU32 colCirclePacked = colCircle.GetU32();
|
|
|
|
if (uFlags & DRAW_CIRCLE_FILLED)
|
|
{
|
|
pDrawList->AddCircleFilled(vecCenter, flRadius, colCirclePacked, nSegments);
|
|
flThickness = 0.0f;
|
|
}
|
|
else
|
|
pDrawList->AddCircle(vecCenter, flRadius, colCirclePacked, nSegments, flThickness);
|
|
|
|
if (uFlags & DRAW_CIRCLE_OUTLINE)
|
|
pDrawList->AddCircle(vecCenter, flRadius + flOutlineThickness, colOutline.GetU32(), nSegments, flThickness + flOutlineThickness);
|
|
}
|
|
|
|
void D::AddDrawListArc(ImDrawList* pDrawList, const ImVec2& vecPosition, const float flRadius, const float flMinimumAngle, const float flMaximumAngle, const Color_t& colArc, const float flThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
pDrawList->PathArcTo(vecPosition, flRadius, M_DEG2RAD(flMinimumAngle), M_DEG2RAD(flMaximumAngle), 32);
|
|
pDrawList->PathStroke(colArc.GetU32(), false, flThickness);
|
|
}
|
|
|
|
void D::AddDrawListLine(ImDrawList* pDrawList, const ImVec2& vecFirst, const ImVec2& vecSecond, const Color_t& colLine, const float flThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
pDrawList->AddLine(vecFirst, vecSecond, colLine.GetU32(), flThickness);
|
|
}
|
|
|
|
void D::AddDrawListTriangle(ImDrawList* pDrawList, const ImVec2& vecFirst, const ImVec2& vecSecond, const ImVec2& vecThird, const Color_t& colTriangle, const unsigned int uFlags, const Color_t& colOutline, const float flThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
const ImU32 colTrianglePacked = colTriangle.GetU32();
|
|
|
|
if (uFlags & DRAW_TRIANGLE_FILLED)
|
|
pDrawList->AddTriangleFilled(vecFirst, vecSecond, vecThird, colTrianglePacked);
|
|
else
|
|
pDrawList->AddTriangle(vecFirst, vecSecond, vecThird, colTrianglePacked, flThickness);
|
|
|
|
if (uFlags & DRAW_TRIANGLE_OUTLINE)
|
|
pDrawList->AddTriangle(vecFirst, vecSecond, vecThird, colOutline.GetU32(), flThickness + 1.0f);
|
|
}
|
|
|
|
void D::AddDrawListQuad(ImDrawList* pDrawList, const ImVec2& vecFirst, const ImVec2& vecSecond, const ImVec2& vecThird, const ImVec2& vecFourth, const Color_t& colQuad, const unsigned int uFlags, const Color_t& colOutline, const float flThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
const ImU32 colQuadPacked = colQuad.GetU32();
|
|
|
|
if (uFlags & DRAW_QUAD_FILLED)
|
|
pDrawList->AddQuadFilled(vecFirst, vecSecond, vecThird, vecFourth, colQuadPacked);
|
|
else
|
|
pDrawList->AddQuad(vecFirst, vecSecond, vecThird, vecFourth, colQuadPacked, flThickness);
|
|
|
|
if (uFlags & DRAW_QUAD_OUTLINE)
|
|
pDrawList->AddQuad(vecFirst, vecSecond, vecThird, vecFourth, colOutline.GetU32(), flThickness + 1.0f);
|
|
}
|
|
|
|
void D::AddDrawListPolygon(ImDrawList* pDrawList, const ImVec2* vecPoints, const int nPointsCount, const Color_t& colPolygon, unsigned int uFlags, const Color_t& colOutline, const bool bClosed, const float flThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
const ImU32 colPolygonPacked = colPolygon.GetU32();
|
|
|
|
if (uFlags & DRAW_POLYGON_FILLED)
|
|
pDrawList->AddConvexPolyFilled(vecPoints, nPointsCount, colPolygonPacked);
|
|
else
|
|
pDrawList->AddPolyline(vecPoints, nPointsCount, colPolygonPacked, bClosed, flThickness);
|
|
|
|
if (uFlags & DRAW_POLYGON_OUTLINE)
|
|
pDrawList->AddPolyline(vecPoints, nPointsCount, colOutline.GetU32(), bClosed, flThickness + 1.0f);
|
|
}
|
|
|
|
void D::AddDrawListText(ImDrawList* pDrawList, const ImFont* pFont, const ImVec2& vecPosition, const char* szText, const Color_t& colText, const unsigned int uFlags, const Color_t& colOutline, const float flThickness)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
// set font texture
|
|
pDrawList->PushTextureID(pFont->ContainerAtlas->TexID);
|
|
|
|
const ImU32 colOutlinePacked = colOutline.GetU32();
|
|
|
|
if (uFlags & DRAW_TEXT_DROPSHADOW)
|
|
pDrawList->AddText(pFont, pFont->FontSize, vecPosition + ImVec2(flThickness, flThickness), colOutlinePacked, szText);
|
|
else if (uFlags & DRAW_TEXT_OUTLINE)
|
|
{
|
|
pDrawList->AddText(pFont, pFont->FontSize, vecPosition + ImVec2(flThickness, -flThickness), colOutlinePacked, szText);
|
|
pDrawList->AddText(pFont, pFont->FontSize, vecPosition + ImVec2(-flThickness, flThickness), colOutlinePacked, szText);
|
|
}
|
|
|
|
pDrawList->AddText(pFont, pFont->FontSize, vecPosition, colText.GetU32(), szText);
|
|
pDrawList->PopTextureID();
|
|
}
|
|
|
|
void D::AddDrawListShadowRect(ImDrawList* pDrawList, const ImVec2& vecMin, const ImVec2& vecMax, const Color_t& colShadow, float flThickness, float flRounding, ImDrawFlags roundingCorners)
|
|
{
|
|
if (pDrawList == nullptr)
|
|
pDrawList = pDrawListActive;
|
|
|
|
pDrawList->AddShadowRect(vecMin, vecMax, colShadow.GetU32(), flThickness, ImVec2(0, 0), roundingCorners, flRounding);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
#pragma region draw_structures
|
|
|
|
void AnimationHandler_t::Update(const float flDeltaTime, const float flDuration)
|
|
{
|
|
if (fnEaseIn == nullptr)
|
|
fnEaseIn = &EASING::InSine;
|
|
|
|
if (fnEaseOut == nullptr)
|
|
fnEaseOut = &EASING::OutSine;
|
|
|
|
// Reset the elapsed time if the bool switches
|
|
if (bSwitch != bLastSwitch)
|
|
flElapsedTime = 0;
|
|
|
|
flElapsedTime = MATH::Max(0.0f, MATH::Min(flElapsedTime, flDuration));
|
|
float flTime = flElapsedTime / flDuration;
|
|
|
|
// Determine the initial and target value based on the current state
|
|
float flInitialValue = bSwitch ? 0.1f : flValue;
|
|
float flTargetValue = bSwitch ? 1.0f : 0.1f; /*(1.0f is max value)*/
|
|
|
|
// Select the appropriate easing function based on the current state
|
|
EasingFunction_t fnCurrentEase = bSwitch ? fnEaseIn : fnEaseOut;
|
|
|
|
// Apply the appropriate easing function based on fade-in or fade-out (with lerping, which is basically what's the math were doing)
|
|
flValue = (flInitialValue + (flTargetValue - flInitialValue)) * (float)fnCurrentEase(flTime);
|
|
flValue = MATH::Clamp(flValue, 0.1f, 1.0f);
|
|
|
|
flElapsedTime += flDeltaTime;
|
|
bLastSwitch = bSwitch;
|
|
}
|
|
|
|
#pragma endregion
|