good
This commit is contained in:
830
examples/cs2-silent-aim-master/cstrike/utilities/draw.cpp
Normal file
830
examples/cs2-silent-aim-master/cstrike/utilities/draw.cpp
Normal file
@@ -0,0 +1,830 @@
|
||||
#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"
|
||||
|
||||
// used: iinputsystem
|
||||
#include "../core/interfaces.h"
|
||||
#include "../sdk/interfaces/iinputsystem.h"
|
||||
// used: bMainWindowOpened
|
||||
#include "../core/menu.h"
|
||||
|
||||
// used: hkIsRelativeMouseMode.GetOriginal();
|
||||
#include "../core/hooks.h"
|
||||
|
||||
#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);
|
||||
|
||||
const ImRect rectFrame(pWindow->DC.CursorPos + ImVec2(vecLabelSize.x > 0.0f ? style.ItemInnerSpacing.x + GetFrameHeight() : 0.0f, 0.0f), pWindow->DC.CursorPos + ImVec2(flWidth, 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, " ");
|
||||
|
||||
// modified by asphyxia
|
||||
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() * 0.75f);
|
||||
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::MultiCombo(const char* szLabel, unsigned int* pFlags, const char* const* arrItems, int nItemsCount)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* pWindow = g.CurrentWindow;
|
||||
|
||||
if (pWindow->SkipItems)
|
||||
return false;
|
||||
|
||||
IM_ASSERT(nItemsCount < 32); // bitflags shift overflow, decrease items count or change variable type
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImVec2 vecLabelSize = CalcTextSize(szLabel, nullptr, true);
|
||||
const float flActiveWidth = CalcItemWidth() - (vecLabelSize.x > 0.0f ? style.ItemInnerSpacing.x + GetFrameHeight() : 0.0f);
|
||||
|
||||
std::vector<const char*> vecActiveItems = {};
|
||||
|
||||
// collect active items
|
||||
for (int i = 0; i < nItemsCount; i++)
|
||||
{
|
||||
if (*pFlags & (1 << i))
|
||||
vecActiveItems.push_back(arrItems[i]);
|
||||
}
|
||||
|
||||
// fuck it, stl still haven't boost::join, fmt::join replacement
|
||||
std::string strBuffer = {};
|
||||
for (std::size_t i = 0U; i < vecActiveItems.size(); i++)
|
||||
{
|
||||
strBuffer.append(vecActiveItems[i]);
|
||||
|
||||
if (i < vecActiveItems.size() - 1U)
|
||||
strBuffer.append(", ");
|
||||
}
|
||||
|
||||
if (strBuffer.empty())
|
||||
strBuffer.assign("none");
|
||||
else
|
||||
{
|
||||
const char* szWrapPosition = g.Font->CalcWordWrapPositionA(GetCurrentWindow()->FontWindowScale, strBuffer.data(), strBuffer.data() + strBuffer.length(), flActiveWidth - style.FramePadding.x * 2.0f);
|
||||
const std::size_t nWrapLength = szWrapPosition - strBuffer.data();
|
||||
|
||||
if (nWrapLength > 0U && nWrapLength < strBuffer.length())
|
||||
{
|
||||
strBuffer.resize(nWrapLength);
|
||||
strBuffer.append("...");
|
||||
}
|
||||
}
|
||||
|
||||
bool bValueChanged = false;
|
||||
if (BeginCombo(szLabel, strBuffer.c_str()))
|
||||
{
|
||||
for (int i = 0; i < nItemsCount; i++)
|
||||
{
|
||||
const int nCurrentFlag = (1 << i);
|
||||
if (Selectable(arrItems[i], (*pFlags & nCurrentFlag), ImGuiSelectableFlags_DontClosePopups))
|
||||
{
|
||||
// flip bitflag
|
||||
*pFlags ^= nCurrentFlag;
|
||||
bValueChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
EndCombo();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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, 15 * 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, 15 * 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
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
bool D::Setup(HWND hWnd, ID3D11Device* pDevice, ID3D11DeviceContext* pContext)
|
||||
{
|
||||
// check is it were already initialized
|
||||
if (bInitialized)
|
||||
return true;
|
||||
|
||||
ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper);
|
||||
|
||||
ImGui::CreateContext();
|
||||
|
||||
// setup platform and renderer bindings
|
||||
if (!ImGui_ImplWin32_Init(hWnd))
|
||||
return false;
|
||||
|
||||
if (!ImGui_ImplDX11_Init(pDevice, pContext))
|
||||
return false;
|
||||
|
||||
// create draw data containers
|
||||
pDrawListActive = IM_NEW(ImDrawList)(ImGui::GetDrawListSharedData());
|
||||
pDrawListSafe = IM_NEW(ImDrawList)(ImGui::GetDrawListSharedData());
|
||||
pDrawListRender = IM_NEW(ImDrawList)(ImGui::GetDrawListSharedData());
|
||||
|
||||
// setup styles
|
||||
#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;
|
||||
#pragma endregion
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||
ImFontConfig icons_config;
|
||||
icons_config.MergeMode = true;
|
||||
icons_config.PixelSnapH = true;
|
||||
icons_config.FontDataOwnedByAtlas = false;
|
||||
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
|
||||
ImFontConfig imVerdanaConfig;
|
||||
imVerdanaConfig.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
|
||||
for (int i = 0; i < CS_ARRAYSIZE(FONT::pMenu); i++)
|
||||
{
|
||||
const float flFontSize = 12.f * CalculateDPI(i);
|
||||
FONT::pMenu[i] = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), flFontSize, &imVerdanaConfig, io.Fonts->GetGlyphRangesCyrillic());
|
||||
io.Fonts->AddFontFromMemoryTTF((void*)fa_solid_900, sizeof(fa_solid_900), flFontSize, &icons_config, icons_ranges);
|
||||
}
|
||||
|
||||
imVerdanaConfig.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_Bold;
|
||||
FONT::pExtra = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Verdana.ttf"), 14.f, &imVerdanaConfig, io.Fonts->GetGlyphRangesCyrillic());
|
||||
|
||||
ImFontConfig imTahomaConfig;
|
||||
imTahomaConfig.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
|
||||
FONT::pVisual = io.Fonts->AddFontFromFileTTF(CS_XOR("C:\\Windows\\Fonts\\Tahoma.ttf"), 14.f, &imTahomaConfig, io.Fonts->GetGlyphRangesCyrillic());
|
||||
|
||||
io.Fonts->FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LightHinting;
|
||||
bInitialized = io.Fonts->Build();
|
||||
return bInitialized;
|
||||
}
|
||||
|
||||
void D::Destroy()
|
||||
{
|
||||
// check is it already destroyed or wasn't initialized at all
|
||||
if (!bInitialized)
|
||||
return;
|
||||
|
||||
// free draw data containers
|
||||
IM_DELETE(pDrawListActive);
|
||||
IM_DELETE(pDrawListSafe);
|
||||
IM_DELETE(pDrawListRender);
|
||||
|
||||
// shutdown imgui directx9 renderer binding
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
|
||||
// shutdown imgui win32 platform binding
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
|
||||
// destroy imgui context
|
||||
ImGui::DestroyContext();
|
||||
|
||||
bInitialized = false;
|
||||
}
|
||||
|
||||
#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 IsRelativeMouseMode original
|
||||
const auto oIsRelativeMouseMode = H::hkIsRelativeMouseMode.GetOriginal();
|
||||
oIsRelativeMouseMode(I::InputSystem, MENU::bMainWindowOpened ? false : MENU::bMainActive);
|
||||
}
|
||||
|
||||
// handle ImGui's window messages and block game's input if menu is opened
|
||||
return ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam) || MENU::bMainWindowOpened;
|
||||
}
|
||||
|
||||
void D::NewFrame()
|
||||
{
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void D::Render()
|
||||
{
|
||||
ImGui::Render();
|
||||
RenderDrawData(ImGui::GetDrawData());
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region draw_main
|
||||
|
||||
void D::RenderDrawData(ImDrawData* pDrawData)
|
||||
{
|
||||
if (::TryAcquireSRWLockExclusive(&drawLock))
|
||||
{
|
||||
*pDrawListRender = *pDrawListSafe;
|
||||
::ReleaseSRWLockExclusive(&drawLock);
|
||||
}
|
||||
|
||||
if (pDrawListRender->CmdBuffer.empty())
|
||||
return;
|
||||
|
||||
// remove trailing command if unused
|
||||
// @note: equivalent to pDrawList->_PopUnusedDrawCmd()
|
||||
if (const ImDrawCmd& lastCommand = pDrawListRender->CmdBuffer.back(); 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);
|
||||
|
||||
IM_ASSERT(pDrawListActive->VtxBuffer.Size == 0 || pDrawListActive->_VtxWritePtr == pDrawListActive->VtxBuffer.Data + pDrawListActive->VtxBuffer.Size);
|
||||
IM_ASSERT(pDrawListActive->IdxBuffer.Size == 0 || pDrawListActive->_IdxWritePtr == pDrawListActive->IdxBuffer.Data + pDrawListActive->IdxBuffer.Size);
|
||||
|
||||
if (!(pDrawListActive->Flags & ImDrawListFlags_AllowVtxOffset))
|
||||
IM_ASSERT(static_cast<int>(pDrawListActive->_VtxCurrentIdx) == pDrawListActive->VtxBuffer.Size);
|
||||
|
||||
*pDrawListSafe = *pDrawListActive;
|
||||
|
||||
::ReleaseSRWLockExclusive(&drawLock);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region draw_bindings
|
||||
|
||||
bool D::WorldToScreen(const Vector_t& vecOrigin, ImVec2* pvecScreen)
|
||||
{
|
||||
const float flWidth = SDK::ViewMatrix[3][0] * vecOrigin.x + SDK::ViewMatrix[3][1] * vecOrigin.y + SDK::ViewMatrix[3][2] * vecOrigin.z + SDK::ViewMatrix[3][3];
|
||||
|
||||
// check is point can't fit on screen, because it's behind us
|
||||
if (flWidth < 0.001f)
|
||||
return false;
|
||||
|
||||
// compute the scene coordinates of a point in 3D
|
||||
const float flInverse = 1.0f / flWidth;
|
||||
pvecScreen->x = (SDK::ViewMatrix[0][0] * vecOrigin.x + SDK::ViewMatrix[0][1] * vecOrigin.y + SDK::ViewMatrix[0][2] * vecOrigin.z + SDK::ViewMatrix[0][3]) * flInverse;
|
||||
pvecScreen->y = (SDK::ViewMatrix[1][0] * vecOrigin.x + SDK::ViewMatrix[1][1] * vecOrigin.y + SDK::ViewMatrix[1][2] * vecOrigin.z + SDK::ViewMatrix[1][3]) * flInverse;
|
||||
|
||||
// screen transform
|
||||
// get the screen position in pixels of given point
|
||||
const ImVec2 vecDisplaySize = ImGui::GetIO().DisplaySize;
|
||||
pvecScreen->x = (vecDisplaySize.x * 0.5f) + (pvecScreen->x * vecDisplaySize.x) * 0.5f;
|
||||
pvecScreen->y = (vecDisplaySize.y * 0.5f) - (pvecScreen->y * vecDisplaySize.y) * 0.5f;
|
||||
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
|
||||
Reference in New Issue
Block a user