├── ImGui-KeyAuth-Base.sln ├── ImGui-KeyAuth-Base.vcxproj ├── ImGui-KeyAuth-Base.vcxproj.filters ├── ImGui-KeyAuth-Base.vcxproj.user ├── README.md ├── imgui ├── imconfig.h ├── imgui.cpp ├── imgui.h ├── imgui_demo.cpp ├── imgui_draw.cpp ├── imgui_impl_dx9.cpp ├── imgui_impl_dx9.h ├── imgui_impl_win32.cpp ├── imgui_impl_win32.h ├── imgui_internal.h ├── imgui_shadow.cpp ├── imgui_shadow.h ├── imgui_tables.cpp ├── imgui_widgets.cpp ├── imstb_rectpack.h ├── imstb_textedit.h └── imstb_truetype.h ├── libcurl.lib ├── library_x64.lib ├── login ├── auth.hpp ├── color.hpp └── login.hpp ├── main ├── main.cpp ├── main.h └── window.h └── protection ├── auth.hpp ├── lazy.h ├── protection.h └── skStr.h /ImGui-KeyAuth-Base.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.33424.131 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImGui-KeyAuth-Base", "ImGui-KeyAuth-Base.vcxproj", "{20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Debug|x64.ActiveCfg = Debug|x64 17 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Debug|x64.Build.0 = Debug|x64 18 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Debug|x86.ActiveCfg = Debug|Win32 19 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Debug|x86.Build.0 = Debug|Win32 20 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Release|x64.ActiveCfg = Release|x64 21 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Release|x64.Build.0 = Release|x64 22 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Release|x86.ActiveCfg = Release|Win32 23 | {20C1CE4C-E412-4E97-B0FB-A751EDD4A4ED}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {6BA0FB88-D76D-4F9F-9403-192236794A6C} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ImGui-KeyAuth-Base.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {20c1ce4c-e412-4e97-b0fb-a751edd4a4ed} 25 | ImGuiKeyAuthBase 26 | 10.0 27 | ImGui-KeyAuth-Base 28 | 29 | 30 | 31 | Application 32 | true 33 | v143 34 | Unicode 35 | 36 | 37 | Application 38 | false 39 | v143 40 | true 41 | Unicode 42 | 43 | 44 | Application 45 | true 46 | v143 47 | Unicode 48 | 49 | 50 | Application 51 | false 52 | v143 53 | true 54 | MultiByte 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Level3 77 | true 78 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 79 | true 80 | 81 | 82 | Console 83 | true 84 | 85 | 86 | 87 | 88 | Level3 89 | true 90 | true 91 | true 92 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 93 | true 94 | 95 | 96 | Console 97 | true 98 | true 99 | true 100 | 101 | 102 | 103 | 104 | Level3 105 | true 106 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 107 | true 108 | C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) 109 | 110 | 111 | Windows 112 | true 113 | library_x64.lib$(CoreLibraryDependencies);%(AdditionalDependencies) 114 | C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;%(AdditionalLibraryDirectories) 115 | 116 | 117 | 118 | 119 | Level3 120 | true 121 | true 122 | true 123 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 124 | true 125 | C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;%(AdditionalIncludeDirectories) 126 | stdcpp17 127 | 4996 128 | stdc11 129 | 130 | 131 | Windows 132 | true 133 | true 134 | true 135 | C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;%(AdditionalLibraryDirectories) 136 | library_x64.lib;%(AdditionalDependencies) 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /ImGui-KeyAuth-Base.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | -------------------------------------------------------------------------------- /ImGui-KeyAuth-Base.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | I've decided to share my base, which I have been using for more than a year, for free. 2 | 3 | ## [Discord 💥](https://discord.gg/BbQCYa46tG) 4 | You can contact me via my Discord server to buy simple/advanced codes etc. from me. 5 | 6 | ## Main 7 | 8 | - Has low-level protection 9 | - Some pretty imgui widgets 10 | - You can use it for literally every project 11 | - Using the latest keyauth library 12 | 13 | ## Requirements 14 | - [Visual Studio](https://visualstudio.microsoft.com/downloads/) 15 | - A [KeyAuth](https://keyauth.cc) account 16 | - An application on KeyAuth. 17 | 18 | ## Usage 19 | - Change strings in login/login.hpp with your application's 20 | - Put your project in it 21 | 22 | ## Images 23 | ![Login screen](https://github.com/RealMove/ImGui-KeyAuth-Base/assets/114800091/af2e4839-e855-451d-8e33-4efa8535a606) 24 | ![Loaded ImGui](https://github.com/RealMove/ImGui-KeyAuth-Base/assets/114800091/f852cc3b-b327-4306-81f9-34826d4e7f47) 25 | -------------------------------------------------------------------------------- /imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) 7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. 8 | //----------------------------------------------------------------------------- 9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp 10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 13 | //----------------------------------------------------------------------------- 14 | 15 | #pragma once 16 | 17 | //---- Define assertion handler. Defaults to calling assert(). 18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 21 | 22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 23 | // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() 25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. 26 | //#define IMGUI_API __declspec( dllexport ) 27 | //#define IMGUI_API __declspec( dllimport ) 28 | 29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 31 | //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions. 32 | 33 | //---- Disable all of Dear ImGui or don't implement standard windows/tools. 34 | // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. 35 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 36 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. 37 | //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88). 38 | 39 | //---- Don't implement some functions to reduce linkage requirements. 40 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) 41 | //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) 42 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) 43 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 44 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 45 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 46 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 47 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) 48 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 49 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 50 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available 51 | 52 | //---- Include imgui_user.h at the end of imgui.h as a convenience 53 | //#define IMGUI_INCLUDE_IMGUI_USER_H 54 | 55 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 56 | //#define IMGUI_USE_BGRA_PACKED_COLOR 57 | 58 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) 59 | //#define IMGUI_USE_WCHAR32 60 | 61 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 62 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. 63 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 64 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 65 | //#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled 66 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 67 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 68 | 69 | //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) 70 | // Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h. 71 | //#define IMGUI_USE_STB_SPRINTF 72 | 73 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) 74 | // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). 75 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. 76 | //#define IMGUI_ENABLE_FREETYPE 77 | 78 | //---- Use stb_truetype to build and rasterize the font atlas (default) 79 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. 80 | //#define IMGUI_ENABLE_STB_TRUETYPE 81 | 82 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 83 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 84 | /* 85 | #define IM_VEC2_CLASS_EXTRA \ 86 | constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ 87 | operator MyVec2() const { return MyVec2(x,y); } 88 | 89 | #define IM_VEC4_CLASS_EXTRA \ 90 | constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ 91 | operator MyVec4() const { return MyVec4(x,y,z,w); } 92 | */ 93 | 94 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 95 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). 96 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 97 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 98 | //#define ImDrawIdx unsigned int 99 | 100 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) 101 | //struct ImDrawList; 102 | //struct ImDrawCmd; 103 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 104 | //#define ImDrawCallback MyImDrawCallback 105 | 106 | //---- Debug Tools: Macro to break in Debugger 107 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 108 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 109 | //#define IM_DEBUG_BREAK __debugbreak() 110 | 111 | //---- Debug Tools: Enable slower asserts 112 | //#define IMGUI_DEBUG_PARANOID 113 | 114 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 115 | /* 116 | namespace ImGui 117 | { 118 | void MyFunction(const char* name, const MyMatrix44& v); 119 | } 120 | */ 121 | -------------------------------------------------------------------------------- /imgui/imgui_impl_dx9.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX9 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. 7 | // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 8 | 9 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 10 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 11 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 12 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 13 | 14 | // CHANGELOG 15 | // (minor and older changes stripped away, please see git history for details) 16 | // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. 17 | // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. 18 | // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). 19 | // 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1. 20 | // 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) 21 | // 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states. 22 | // 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857). 23 | // 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file. 24 | // 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer. 25 | // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 26 | // 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 27 | // 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). 28 | // 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288. 29 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 30 | // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. 31 | // 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 32 | // 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. 33 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. 34 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 35 | 36 | #include "imgui.h" 37 | #include "imgui_impl_dx9.h" 38 | 39 | // DirectX 40 | #include 41 | 42 | // DirectX data 43 | struct ImGui_ImplDX9_Data 44 | { 45 | LPDIRECT3DDEVICE9 pd3dDevice; 46 | LPDIRECT3DVERTEXBUFFER9 pVB; 47 | LPDIRECT3DINDEXBUFFER9 pIB; 48 | LPDIRECT3DTEXTURE9 FontTexture; 49 | int VertexBufferSize; 50 | int IndexBufferSize; 51 | 52 | ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } 53 | }; 54 | 55 | struct CUSTOMVERTEX 56 | { 57 | float pos[3]; 58 | D3DCOLOR col; 59 | float uv[2]; 60 | }; 61 | #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) 62 | 63 | #ifdef IMGUI_USE_BGRA_PACKED_COLOR 64 | #define IMGUI_COL_TO_DX9_ARGB(_COL) (_COL) 65 | #else 66 | #define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16)) 67 | #endif 68 | 69 | // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts 70 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. 71 | static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData() 72 | { 73 | return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; 74 | } 75 | 76 | // Forward Declarations 77 | static void ImGui_ImplDX9_InitPlatformInterface(); 78 | static void ImGui_ImplDX9_ShutdownPlatformInterface(); 79 | static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows(); 80 | static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows(); 81 | 82 | // Functions 83 | static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) 84 | { 85 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 86 | 87 | // Setup viewport 88 | D3DVIEWPORT9 vp; 89 | vp.X = vp.Y = 0; 90 | vp.Width = (DWORD)draw_data->DisplaySize.x; 91 | vp.Height = (DWORD)draw_data->DisplaySize.y; 92 | vp.MinZ = 0.0f; 93 | vp.MaxZ = 1.0f; 94 | bd->pd3dDevice->SetViewport(&vp); 95 | 96 | // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling. 97 | bd->pd3dDevice->SetPixelShader(nullptr); 98 | bd->pd3dDevice->SetVertexShader(nullptr); 99 | bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 100 | bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 101 | bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); 102 | bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 103 | bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 104 | bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 105 | bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 106 | bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); 107 | bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 108 | bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 109 | bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); 110 | bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); 111 | bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); 112 | bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 113 | bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); 114 | bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE); 115 | bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); 116 | bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); 117 | bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE); 118 | bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 119 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 120 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 121 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 122 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 123 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 124 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 125 | bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); 126 | bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); 127 | bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 128 | bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 129 | 130 | // Setup orthographic projection matrix 131 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 132 | // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() 133 | { 134 | float L = draw_data->DisplayPos.x + 0.5f; 135 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f; 136 | float T = draw_data->DisplayPos.y + 0.5f; 137 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f; 138 | D3DMATRIX mat_identity = { { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } } }; 139 | D3DMATRIX mat_projection = 140 | { { { 141 | 2.0f/(R-L), 0.0f, 0.0f, 0.0f, 142 | 0.0f, 2.0f/(T-B), 0.0f, 0.0f, 143 | 0.0f, 0.0f, 0.5f, 0.0f, 144 | (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f 145 | } } }; 146 | bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); 147 | bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); 148 | bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); 149 | } 150 | } 151 | 152 | // Render function. 153 | void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) 154 | { 155 | // Avoid rendering when minimized 156 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 157 | return; 158 | 159 | // Create and grow buffers if needed 160 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 161 | if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) 162 | { 163 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; } 164 | bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; 165 | if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0) 166 | return; 167 | } 168 | if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) 169 | { 170 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; } 171 | bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; 172 | if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0) 173 | return; 174 | } 175 | 176 | // Backup the DX9 state 177 | IDirect3DStateBlock9* d3d9_state_block = nullptr; 178 | if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) 179 | return; 180 | if (d3d9_state_block->Capture() < 0) 181 | { 182 | d3d9_state_block->Release(); 183 | return; 184 | } 185 | 186 | // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) 187 | D3DMATRIX last_world, last_view, last_projection; 188 | bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); 189 | bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); 190 | bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); 191 | 192 | // Allocate buffers 193 | CUSTOMVERTEX* vtx_dst; 194 | ImDrawIdx* idx_dst; 195 | if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) 196 | { 197 | d3d9_state_block->Release(); 198 | return; 199 | } 200 | if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) 201 | { 202 | bd->pVB->Unlock(); 203 | d3d9_state_block->Release(); 204 | return; 205 | } 206 | 207 | // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format. 208 | // FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and 209 | // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR 210 | // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } 211 | for (int n = 0; n < draw_data->CmdListsCount; n++) 212 | { 213 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 214 | const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; 215 | for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) 216 | { 217 | vtx_dst->pos[0] = vtx_src->pos.x; 218 | vtx_dst->pos[1] = vtx_src->pos.y; 219 | vtx_dst->pos[2] = 0.0f; 220 | vtx_dst->col = IMGUI_COL_TO_DX9_ARGB(vtx_src->col); 221 | vtx_dst->uv[0] = vtx_src->uv.x; 222 | vtx_dst->uv[1] = vtx_src->uv.y; 223 | vtx_dst++; 224 | vtx_src++; 225 | } 226 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 227 | idx_dst += cmd_list->IdxBuffer.Size; 228 | } 229 | bd->pVB->Unlock(); 230 | bd->pIB->Unlock(); 231 | bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX)); 232 | bd->pd3dDevice->SetIndices(bd->pIB); 233 | bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); 234 | 235 | // Setup desired DX state 236 | ImGui_ImplDX9_SetupRenderState(draw_data); 237 | 238 | // Render command lists 239 | // (Because we merged all buffers into a single one, we maintain our own offset into them) 240 | int global_vtx_offset = 0; 241 | int global_idx_offset = 0; 242 | ImVec2 clip_off = draw_data->DisplayPos; 243 | for (int n = 0; n < draw_data->CmdListsCount; n++) 244 | { 245 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 246 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 247 | { 248 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 249 | if (pcmd->UserCallback != nullptr) 250 | { 251 | // User callback, registered via ImDrawList::AddCallback() 252 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 253 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 254 | ImGui_ImplDX9_SetupRenderState(draw_data); 255 | else 256 | pcmd->UserCallback(cmd_list, pcmd); 257 | } 258 | else 259 | { 260 | // Project scissor/clipping rectangles into framebuffer space 261 | ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); 262 | ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); 263 | if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) 264 | continue; 265 | 266 | // Apply Scissor/clipping rectangle, Bind texture, Draw 267 | const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; 268 | const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); 269 | bd->pd3dDevice->SetTexture(0, texture); 270 | bd->pd3dDevice->SetScissorRect(&r); 271 | bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3); 272 | } 273 | } 274 | global_idx_offset += cmd_list->IdxBuffer.Size; 275 | global_vtx_offset += cmd_list->VtxBuffer.Size; 276 | } 277 | 278 | // When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows 279 | // from rendering until the first window submits at least one draw call, even once. That's our workaround. (see #2560) 280 | if (global_vtx_offset == 0) 281 | bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0); 282 | 283 | // Restore the DX9 transform 284 | bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); 285 | bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); 286 | bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); 287 | 288 | // Restore the DX9 state 289 | d3d9_state_block->Apply(); 290 | d3d9_state_block->Release(); 291 | } 292 | 293 | bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) 294 | { 295 | ImGuiIO& io = ImGui::GetIO(); 296 | IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); 297 | 298 | // Setup backend capabilities flags 299 | ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)(); 300 | io.BackendRendererUserData = (void*)bd; 301 | io.BackendRendererName = "imgui_impl_dx9"; 302 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 303 | io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) 304 | 305 | bd->pd3dDevice = device; 306 | bd->pd3dDevice->AddRef(); 307 | 308 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 309 | ImGui_ImplDX9_InitPlatformInterface(); 310 | 311 | return true; 312 | } 313 | 314 | void ImGui_ImplDX9_Shutdown() 315 | { 316 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 317 | IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); 318 | ImGuiIO& io = ImGui::GetIO(); 319 | 320 | ImGui_ImplDX9_ShutdownPlatformInterface(); 321 | ImGui_ImplDX9_InvalidateDeviceObjects(); 322 | if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } 323 | io.BackendRendererName = nullptr; 324 | io.BackendRendererUserData = nullptr; 325 | IM_DELETE(bd); 326 | } 327 | 328 | static bool ImGui_ImplDX9_CreateFontsTexture() 329 | { 330 | // Build texture atlas 331 | ImGuiIO& io = ImGui::GetIO(); 332 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 333 | unsigned char* pixels; 334 | int width, height, bytes_per_pixel; 335 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel); 336 | 337 | // Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices) 338 | #ifndef IMGUI_USE_BGRA_PACKED_COLOR 339 | if (io.Fonts->TexPixelsUseColors) 340 | { 341 | ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel); 342 | for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++) 343 | *dst = IMGUI_COL_TO_DX9_ARGB(*src); 344 | pixels = (unsigned char*)dst_start; 345 | } 346 | #endif 347 | 348 | // Upload texture to graphics system 349 | bd->FontTexture = nullptr; 350 | if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0) 351 | return false; 352 | D3DLOCKED_RECT tex_locked_rect; 353 | if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK) 354 | return false; 355 | for (int y = 0; y < height; y++) 356 | memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel); 357 | bd->FontTexture->UnlockRect(0); 358 | 359 | // Store our identifier 360 | io.Fonts->SetTexID((ImTextureID)bd->FontTexture); 361 | 362 | #ifndef IMGUI_USE_BGRA_PACKED_COLOR 363 | if (io.Fonts->TexPixelsUseColors) 364 | ImGui::MemFree(pixels); 365 | #endif 366 | 367 | return true; 368 | } 369 | 370 | bool ImGui_ImplDX9_CreateDeviceObjects() 371 | { 372 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 373 | if (!bd || !bd->pd3dDevice) 374 | return false; 375 | if (!ImGui_ImplDX9_CreateFontsTexture()) 376 | return false; 377 | ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows(); 378 | return true; 379 | } 380 | 381 | void ImGui_ImplDX9_InvalidateDeviceObjects() 382 | { 383 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 384 | if (!bd || !bd->pd3dDevice) 385 | return; 386 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; } 387 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; } 388 | if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well. 389 | ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows(); 390 | } 391 | 392 | void ImGui_ImplDX9_NewFrame() 393 | { 394 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 395 | IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX9_Init()?"); 396 | 397 | if (!bd->FontTexture) 398 | ImGui_ImplDX9_CreateDeviceObjects(); 399 | } 400 | 401 | //-------------------------------------------------------------------------------------------------------- 402 | // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT 403 | // This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. 404 | // If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. 405 | //-------------------------------------------------------------------------------------------------------- 406 | 407 | // Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. 408 | struct ImGui_ImplDX9_ViewportData 409 | { 410 | IDirect3DSwapChain9* SwapChain; 411 | D3DPRESENT_PARAMETERS d3dpp; 412 | 413 | ImGui_ImplDX9_ViewportData() { SwapChain = nullptr; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); } 414 | ~ImGui_ImplDX9_ViewportData() { IM_ASSERT(SwapChain == nullptr); } 415 | }; 416 | 417 | static void ImGui_ImplDX9_CreateWindow(ImGuiViewport* viewport) 418 | { 419 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 420 | ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)(); 421 | viewport->RendererUserData = vd; 422 | 423 | // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). 424 | // Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND. 425 | HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle; 426 | IM_ASSERT(hwnd != 0); 427 | 428 | ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS)); 429 | vd->d3dpp.Windowed = TRUE; 430 | vd->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 431 | vd->d3dpp.BackBufferWidth = (UINT)viewport->Size.x; 432 | vd->d3dpp.BackBufferHeight = (UINT)viewport->Size.y; 433 | vd->d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 434 | vd->d3dpp.hDeviceWindow = hwnd; 435 | vd->d3dpp.EnableAutoDepthStencil = FALSE; 436 | vd->d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 437 | vd->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync 438 | 439 | HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr); 440 | IM_ASSERT(hr == D3D_OK); 441 | IM_ASSERT(vd->SwapChain != nullptr); 442 | } 443 | 444 | static void ImGui_ImplDX9_DestroyWindow(ImGuiViewport* viewport) 445 | { 446 | // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. 447 | if (ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData) 448 | { 449 | if (vd->SwapChain) 450 | vd->SwapChain->Release(); 451 | vd->SwapChain = nullptr; 452 | ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS)); 453 | IM_DELETE(vd); 454 | } 455 | viewport->RendererUserData = nullptr; 456 | } 457 | 458 | static void ImGui_ImplDX9_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) 459 | { 460 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 461 | ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; 462 | if (vd->SwapChain) 463 | { 464 | vd->SwapChain->Release(); 465 | vd->SwapChain = nullptr; 466 | vd->d3dpp.BackBufferWidth = (UINT)size.x; 467 | vd->d3dpp.BackBufferHeight = (UINT)size.y; 468 | HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr); 469 | IM_ASSERT(hr == D3D_OK); 470 | } 471 | } 472 | 473 | static void ImGui_ImplDX9_RenderWindow(ImGuiViewport* viewport, void*) 474 | { 475 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 476 | ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; 477 | ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); 478 | 479 | LPDIRECT3DSURFACE9 render_target = nullptr; 480 | LPDIRECT3DSURFACE9 last_render_target = nullptr; 481 | LPDIRECT3DSURFACE9 last_depth_stencil = nullptr; 482 | vd->SwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &render_target); 483 | bd->pd3dDevice->GetRenderTarget(0, &last_render_target); 484 | bd->pd3dDevice->GetDepthStencilSurface(&last_depth_stencil); 485 | bd->pd3dDevice->SetRenderTarget(0, render_target); 486 | bd->pd3dDevice->SetDepthStencilSurface(nullptr); 487 | 488 | if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) 489 | { 490 | D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f)); 491 | bd->pd3dDevice->Clear(0, nullptr, D3DCLEAR_TARGET, clear_col_dx, 1.0f, 0); 492 | } 493 | 494 | ImGui_ImplDX9_RenderDrawData(viewport->DrawData); 495 | 496 | // Restore render target 497 | bd->pd3dDevice->SetRenderTarget(0, last_render_target); 498 | bd->pd3dDevice->SetDepthStencilSurface(last_depth_stencil); 499 | render_target->Release(); 500 | last_render_target->Release(); 501 | if (last_depth_stencil) last_depth_stencil->Release(); 502 | } 503 | 504 | static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*) 505 | { 506 | ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; 507 | HRESULT hr = vd->SwapChain->Present(nullptr, nullptr, vd->d3dpp.hDeviceWindow, nullptr, 0); 508 | // Let main application handle D3DERR_DEVICELOST by resetting the device. 509 | IM_ASSERT(hr == D3D_OK || hr == D3DERR_DEVICELOST); 510 | } 511 | 512 | static void ImGui_ImplDX9_InitPlatformInterface() 513 | { 514 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); 515 | platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow; 516 | platform_io.Renderer_DestroyWindow = ImGui_ImplDX9_DestroyWindow; 517 | platform_io.Renderer_SetWindowSize = ImGui_ImplDX9_SetWindowSize; 518 | platform_io.Renderer_RenderWindow = ImGui_ImplDX9_RenderWindow; 519 | platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers; 520 | } 521 | 522 | static void ImGui_ImplDX9_ShutdownPlatformInterface() 523 | { 524 | ImGui::DestroyPlatformWindows(); 525 | } 526 | 527 | static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows() 528 | { 529 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); 530 | for (int i = 1; i < platform_io.Viewports.Size; i++) 531 | if (!platform_io.Viewports[i]->RendererUserData) 532 | ImGui_ImplDX9_CreateWindow(platform_io.Viewports[i]); 533 | } 534 | 535 | static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows() 536 | { 537 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); 538 | for (int i = 1; i < platform_io.Viewports.Size; i++) 539 | if (platform_io.Viewports[i]->RendererUserData) 540 | ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]); 541 | } 542 | -------------------------------------------------------------------------------- /imgui/imgui_impl_dx9.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX9 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. 7 | // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 8 | 9 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 10 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 11 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 12 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 13 | 14 | #pragma once 15 | #include "imgui.h" // IMGUI_IMPL_API 16 | 17 | struct IDirect3DDevice9; 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); 20 | IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); 22 | IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); 23 | 24 | // Use if you want to reset your rendering device without losing Dear ImGui state. 25 | IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); 26 | IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects(); 27 | -------------------------------------------------------------------------------- /imgui/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) 6 | // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] 7 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 8 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 9 | // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 10 | 11 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 12 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 13 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 14 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 15 | 16 | #pragma once 17 | #include "imgui.h" // IMGUI_IMPL_API 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 20 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 22 | 23 | // Win32 message handler your application need to call. 24 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. 25 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. 26 | // - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE. 27 | 28 | #if 0 29 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 30 | #endif 31 | 32 | // DPI-related helpers (optional) 33 | // - Use to enable DPI awareness without having to create an application manifest. 34 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 35 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 36 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 37 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 38 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 39 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 40 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 41 | 42 | // Transparency related helpers (optional) [experimental] 43 | // - Use to enable alpha compositing transparency with the desktop. 44 | // - Use together with e.g. clearing your framebuffer with zero-alpha. 45 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd 46 | -------------------------------------------------------------------------------- /imgui/imgui_shadow.cpp: -------------------------------------------------------------------------------- 1 | #include "imgui_shadow.h" 2 | 3 | ImVec2 operator+(ImVec2 p1, ImVec2 p2) { return ImVec2(p1.x + p2.x, p1.y + p2.y); } 4 | ImVec2 operator-(ImVec2 p1, ImVec2 p2) { return ImVec2(p1.x - p2.x, p1.y - p2.y); } 5 | ImVec2 operator/(ImVec2 p1, ImVec2 p2) { return ImVec2(p1.x / p2.x, p1.y / p2.y); } 6 | ImVec2 operator*(ImVec2 p1, int value) { return ImVec2(p1.x * value, p1.y * value); } 7 | ImVec2 operator*(ImVec2 p1, float value) { return ImVec2(p1.x * value, p1.y * value); } 8 | ImVec4 operator+(float val, ImVec4 p2) { return ImVec4(val + p2.x, val + p2.y, val + p2.z, val + p2.w); } 9 | ImVec4 operator*(float val, ImVec4 p2) { return ImVec4(val * p2.x, val * p2.y, val * p2.z, val * p2.w); } 10 | ImVec4 operator*(ImVec4 p2, float val) { return ImVec4(val * p2.x, val * p2.y, val * p2.z, val * p2.w); } 11 | ImVec4 operator-(ImVec4 p1, ImVec4 p2) { return ImVec4(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z, p1.w - p2.w); } 12 | ImVec4 operator*(ImVec4 p1, ImVec4 p2) { return ImVec4(p1.x * p2.x, p1.y * p2.y, p1.z * p2.z, p1.w * p2.w); } 13 | ImVec4 operator/(ImVec4 p1, ImVec4 p2) { return ImVec4(p1.x / p2.x, p1.y / p2.y, p1.z / p2.z, p1.w / p2.w); } 14 | 15 | ImVec4 boxGaussianIntegral(ImVec4 x) 16 | { 17 | const ImVec4 s = ImVec4(x.x > 0 ? 1.0f : -1.0f, x.y > 0 ? 1.0f : -1.0f, x.z > 0 ? 1.0f : -1.0f, x.w > 0 ? 1.0f : -1.0f); 18 | const ImVec4 a = ImVec4(fabsf(x.x), fabsf(x.y), fabsf(x.z), fabsf(x.w)); 19 | const ImVec4 res = 1.0f + (0.278393f + (0.230389f + 0.078108f * (a * a)) * a) * a; 20 | const ImVec4 resSquared = res * res; 21 | return s - s / (resSquared * resSquared); 22 | } 23 | 24 | ImVec4 boxLinearInterpolation(ImVec4 x) 25 | { 26 | const float maxClamp = 1.0f; 27 | const float minClamp = -1.0f; 28 | return ImVec4(x.x > maxClamp ? maxClamp : x.x < minClamp ? minClamp : x.x, 29 | x.y > maxClamp ? maxClamp : x.y < minClamp ? minClamp : x.y, 30 | x.z > maxClamp ? maxClamp : x.z < minClamp ? minClamp : x.z, 31 | x.w > maxClamp ? maxClamp : x.w < minClamp ? minClamp : x.w); 32 | } 33 | 34 | float boxShadow(ImVec2 lower, ImVec2 upper, ImVec2 point, float sigma, bool linearInterpolation) 35 | { 36 | const ImVec2 pointLower = point - lower; 37 | const ImVec2 pointUpper = point - upper; 38 | const ImVec4 query = ImVec4(pointLower.x, pointLower.y, pointUpper.x, pointUpper.y); 39 | const ImVec4 pointToSample = query * (sqrtf(0.5f) / sigma); 40 | const ImVec4 integral = linearInterpolation ? 0.5f + 0.5f * boxLinearInterpolation(pointToSample) : 0.5f + 0.5f * boxGaussianIntegral(pointToSample); 41 | return (integral.z - integral.x) * (integral.w - integral.y); 42 | } 43 | 44 | void ImGui::AddShadow(ImVec2 rectPos, ImVec2 rectSize, float sigma, int rings, int spacingBetweenRings, int samplesPerCornerSide, int spacingBetweenSamples, ImColor shadowColor, ImVec2 shadowOffset) 45 | { 46 | const int samplesSpan = samplesPerCornerSide * spacingBetweenSamples; 47 | const int halfWidth = static_cast(rectSize.x / 2); 48 | const int numSamplesInHalfWidth = (halfWidth / spacingBetweenSamples) == 0 ? 1 : halfWidth / spacingBetweenSamples; 49 | const int numSamplesWidth = samplesSpan > halfWidth ? numSamplesInHalfWidth : samplesPerCornerSide; 50 | const int halfHeight = static_cast(rectSize.y / 2); 51 | const int numSamplesInHalfHeight = (halfHeight / spacingBetweenSamples) == 0 ? 1 : halfHeight / spacingBetweenSamples; 52 | const int numSamplesHeight = samplesSpan > halfHeight ? numSamplesInHalfHeight : samplesPerCornerSide; 53 | const int numVerticesInARing = numSamplesWidth * 4 + numSamplesHeight * 4 + 4; 54 | const ImVec2 whiteTexelUV = ImGui::GetIO().Fonts->TexUvWhitePixel; 55 | const ImVec2 origin = ImGui::GetCursorScreenPos(); 56 | const ImVec2 rectangleTopLeft = origin + rectPos; 57 | const ImVec2 rectangleBottomRight = rectangleTopLeft + rectSize; 58 | const ImVec2 rectangleTopRight = rectangleTopLeft + ImVec2(rectSize.x, 0); 59 | const ImVec2 rectangleBottomLeft = rectangleTopLeft + ImVec2(0, rectSize.y); 60 | 61 | int totalVertices = numVerticesInARing * rings; 62 | int totalIndices = 6 * (numVerticesInARing) * (rings - 1); 63 | 64 | ImDrawList* drawList = ImGui::GetBackgroundDrawList(); 65 | drawList->PrimReserve(totalIndices, totalVertices); 66 | const ImDrawVert* shadowVertices = drawList->_VtxWritePtr; 67 | ImDrawVert* vertexPointer = drawList->_VtxWritePtr; 68 | 69 | for (int r = 0; r < rings; ++r) 70 | { 71 | const float adaptiveScale = (r / 2.5f) + 1; 72 | const ImVec2 ringOffset = ImVec2(adaptiveScale * r * spacingBetweenRings, adaptiveScale * r * spacingBetweenRings); 73 | for (int j = 0; j < 4; ++j) 74 | { 75 | ImVec2 corner; 76 | ImVec2 direction[2]; 77 | const float spacingBetweenSamplesOnARing = static_cast(spacingBetweenSamples); 78 | switch (j) 79 | { 80 | case 0: 81 | corner = rectangleTopLeft + ImVec2(-ringOffset.x, -ringOffset.y); 82 | direction[0] = ImVec2(1, 0) * spacingBetweenSamplesOnARing; 83 | direction[1] = ImVec2(0, 1) * spacingBetweenSamplesOnARing; 84 | for (int i = 0; i < numSamplesWidth; ++i) 85 | { 86 | const ImVec2 point = corner + direction[0] * (numSamplesWidth - i); 87 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 88 | vertexPointer->pos = point; 89 | vertexPointer->uv = whiteTexelUV; 90 | vertexPointer->col = shadowColor; 91 | vertexPointer++; 92 | } 93 | 94 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, corner - shadowOffset, sigma, false); 95 | vertexPointer->pos = corner; 96 | vertexPointer->uv = whiteTexelUV; 97 | vertexPointer->col = shadowColor; 98 | vertexPointer++; 99 | 100 | for (int i = 0; i < numSamplesHeight; ++i) 101 | { 102 | const ImVec2 point = corner + direction[1] * (i + 1); 103 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 104 | vertexPointer->pos = point; 105 | vertexPointer->uv = whiteTexelUV; 106 | vertexPointer->col = shadowColor; 107 | vertexPointer++; 108 | } 109 | break; 110 | case 1: 111 | corner = rectangleBottomLeft + ImVec2(-ringOffset.x, +ringOffset.y); 112 | direction[0] = ImVec2(1, 0) * spacingBetweenSamplesOnARing; 113 | direction[1] = ImVec2(0, -1) * spacingBetweenSamplesOnARing; 114 | for (int i = 0; i < numSamplesHeight; ++i) 115 | { 116 | const ImVec2 point = corner + direction[1] * (numSamplesHeight - i); 117 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 118 | vertexPointer->pos = point; 119 | vertexPointer->uv = whiteTexelUV; 120 | vertexPointer->col = shadowColor; 121 | vertexPointer++; 122 | } 123 | 124 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, corner - shadowOffset, sigma, false); 125 | vertexPointer->pos = corner; 126 | vertexPointer->uv = whiteTexelUV; 127 | vertexPointer->col = shadowColor; 128 | vertexPointer++; 129 | 130 | for (int i = 0; i < numSamplesWidth; ++i) 131 | { 132 | const ImVec2 point = corner + direction[0] * (i + 1); 133 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 134 | vertexPointer->pos = point; 135 | vertexPointer->uv = whiteTexelUV; 136 | vertexPointer->col = shadowColor; 137 | vertexPointer++; 138 | } 139 | break; 140 | case 2: 141 | corner = rectangleBottomRight + ImVec2(+ringOffset.x, +ringOffset.y); 142 | direction[0] = ImVec2(-1, 0) * spacingBetweenSamplesOnARing; 143 | direction[1] = ImVec2(0, -1) * spacingBetweenSamplesOnARing; 144 | for (int i = 0; i < numSamplesWidth; ++i) 145 | { 146 | const ImVec2 point = corner + direction[0] * (numSamplesWidth - i); 147 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 148 | vertexPointer->pos = point; 149 | vertexPointer->uv = whiteTexelUV; 150 | vertexPointer->col = shadowColor; 151 | vertexPointer++; 152 | } 153 | 154 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, corner - shadowOffset, sigma, false); 155 | vertexPointer->pos = corner; 156 | vertexPointer->uv = whiteTexelUV; 157 | vertexPointer->col = shadowColor; 158 | vertexPointer++; 159 | 160 | for (int i = 0; i < numSamplesHeight; ++i) 161 | { 162 | const ImVec2 point = corner + direction[1] * (i + 1); 163 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 164 | vertexPointer->pos = point; 165 | vertexPointer->uv = whiteTexelUV; 166 | vertexPointer->col = shadowColor; 167 | vertexPointer++; 168 | } 169 | break; 170 | case 3: 171 | corner = rectangleTopRight + ImVec2(+ringOffset.x, -ringOffset.y); 172 | direction[0] = ImVec2(-1, 0) * spacingBetweenSamplesOnARing; 173 | direction[1] = ImVec2(0, 1) * spacingBetweenSamplesOnARing; 174 | for (int i = 0; i < numSamplesHeight; ++i) 175 | { 176 | const ImVec2 point = corner + direction[1] * (numSamplesHeight - i); 177 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 178 | vertexPointer->pos = point; 179 | vertexPointer->uv = whiteTexelUV; 180 | vertexPointer->col = shadowColor; 181 | vertexPointer++; 182 | } 183 | 184 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, corner - shadowOffset, sigma, false); 185 | vertexPointer->pos = corner; 186 | vertexPointer->uv = whiteTexelUV; 187 | vertexPointer->col = shadowColor; 188 | vertexPointer++; 189 | 190 | for (int i = 0; i < numSamplesWidth; ++i) 191 | { 192 | const ImVec2 point = corner + direction[0] * (i + 1); 193 | shadowColor.Value.w = boxShadow(rectangleTopLeft, rectangleBottomRight, point - shadowOffset, sigma, false); 194 | vertexPointer->pos = point; 195 | vertexPointer->uv = whiteTexelUV; 196 | vertexPointer->col = shadowColor; 197 | vertexPointer++; 198 | } 199 | break; 200 | } 201 | } 202 | } 203 | 204 | ImDrawIdx idx = (ImDrawIdx)drawList->_VtxCurrentIdx; 205 | 206 | for (int r = 0; r < rings - 1; ++r) 207 | { 208 | const ImDrawIdx startOfRingIndex = idx; 209 | for (int i = 0; i < numVerticesInARing - 1; ++i) 210 | { 211 | drawList->_IdxWritePtr[0] = idx + 0; 212 | drawList->_IdxWritePtr[1] = idx + 1; 213 | drawList->_IdxWritePtr[2] = idx + numVerticesInARing; 214 | drawList->_IdxWritePtr[3] = idx + 1; 215 | drawList->_IdxWritePtr[4] = idx + numVerticesInARing + 1; 216 | drawList->_IdxWritePtr[5] = idx + numVerticesInARing; 217 | 218 | idx += 1; 219 | drawList->_IdxWritePtr += 6; 220 | } 221 | 222 | drawList->_IdxWritePtr[0] = idx + 0; 223 | drawList->_IdxWritePtr[1] = startOfRingIndex + 0; 224 | drawList->_IdxWritePtr[2] = startOfRingIndex + numVerticesInARing; 225 | drawList->_IdxWritePtr[3] = idx + 0; 226 | drawList->_IdxWritePtr[4] = startOfRingIndex + numVerticesInARing; 227 | drawList->_IdxWritePtr[5] = idx + numVerticesInARing; 228 | 229 | drawList->_IdxWritePtr += 6; 230 | idx += 1; 231 | } 232 | 233 | drawList->_VtxCurrentIdx += totalVertices; 234 | 235 | } 236 | -------------------------------------------------------------------------------- /imgui/imgui_shadow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "imgui.h" 3 | #include "imgui_internal.h" 4 | 5 | namespace ImGui 6 | { 7 | void AddShadow(ImVec2 rectPos, ImVec2 rectSize, float sigma, int rings, int spacingBetweenRings, int samplesPerCornerSide, int spacingBetweenSamples, ImColor shadowColor, ImVec2 shadowOffset = ImVec2(0, 0)); 8 | } 9 | -------------------------------------------------------------------------------- /imgui/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.01. 3 | // Grep for [DEAR IMGUI] to find the changes. 4 | // 5 | // stb_rect_pack.h - v1.01 - public domain - rectangle packing 6 | // Sean Barrett 2014 7 | // 8 | // Useful for e.g. packing rectangular textures into an atlas. 9 | // Does not do rotation. 10 | // 11 | // Before #including, 12 | // 13 | // #define STB_RECT_PACK_IMPLEMENTATION 14 | // 15 | // in the file that you want to have the implementation. 16 | // 17 | // Not necessarily the awesomest packing method, but better than 18 | // the totally naive one in stb_truetype (which is primarily what 19 | // this is meant to replace). 20 | // 21 | // Has only had a few tests run, may have issues. 22 | // 23 | // More docs to come. 24 | // 25 | // No memory allocations; uses qsort() and assert() from stdlib. 26 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 27 | // 28 | // This library currently uses the Skyline Bottom-Left algorithm. 29 | // 30 | // Please note: better rectangle packers are welcome! Please 31 | // implement them to the same API, but with a different init 32 | // function. 33 | // 34 | // Credits 35 | // 36 | // Library 37 | // Sean Barrett 38 | // Minor features 39 | // Martins Mozeiko 40 | // github:IntellectualKitty 41 | // 42 | // Bugfixes / warning fixes 43 | // Jeremy Jaussaud 44 | // Fabian Giesen 45 | // 46 | // Version history: 47 | // 48 | // 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section 49 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 50 | // 0.99 (2019-02-07) warning fixes 51 | // 0.11 (2017-03-03) return packing success/fail result 52 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 53 | // 0.09 (2016-08-27) fix compiler warnings 54 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 55 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 56 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 57 | // 0.05: added STBRP_ASSERT to allow replacing assert 58 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 59 | // 0.01: initial release 60 | // 61 | // LICENSE 62 | // 63 | // See end of file for license information. 64 | 65 | ////////////////////////////////////////////////////////////////////////////// 66 | // 67 | // INCLUDE SECTION 68 | // 69 | 70 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 71 | #define STB_INCLUDE_STB_RECT_PACK_H 72 | 73 | #define STB_RECT_PACK_VERSION 1 74 | 75 | #ifdef STBRP_STATIC 76 | #define STBRP_DEF static 77 | #else 78 | #define STBRP_DEF extern 79 | #endif 80 | 81 | #ifdef __cplusplus 82 | extern "C" { 83 | #endif 84 | 85 | typedef struct stbrp_context stbrp_context; 86 | typedef struct stbrp_node stbrp_node; 87 | typedef struct stbrp_rect stbrp_rect; 88 | 89 | typedef int stbrp_coord; 90 | 91 | #define STBRP__MAXVAL 0x7fffffff 92 | // Mostly for internal use, but this is the maximum supported coordinate value. 93 | 94 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 95 | // Assign packed locations to rectangles. The rectangles are of type 96 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 97 | // are 'num_rects' many of them. 98 | // 99 | // Rectangles which are successfully packed have the 'was_packed' flag 100 | // set to a non-zero value and 'x' and 'y' store the minimum location 101 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 102 | // if you imagine y increasing downwards). Rectangles which do not fit 103 | // have the 'was_packed' flag set to 0. 104 | // 105 | // You should not try to access the 'rects' array from another thread 106 | // while this function is running, as the function temporarily reorders 107 | // the array while it executes. 108 | // 109 | // To pack into another rectangle, you need to call stbrp_init_target 110 | // again. To continue packing into the same rectangle, you can call 111 | // this function again. Calling this multiple times with multiple rect 112 | // arrays will probably produce worse packing results than calling it 113 | // a single time with the full rectangle array, but the option is 114 | // available. 115 | // 116 | // The function returns 1 if all of the rectangles were successfully 117 | // packed and 0 otherwise. 118 | 119 | struct stbrp_rect 120 | { 121 | // reserved for your use: 122 | int id; 123 | 124 | // input: 125 | stbrp_coord w, h; 126 | 127 | // output: 128 | stbrp_coord x, y; 129 | int was_packed; // non-zero if valid packing 130 | 131 | }; // 16 bytes, nominally 132 | 133 | 134 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 135 | // Initialize a rectangle packer to: 136 | // pack a rectangle that is 'width' by 'height' in dimensions 137 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 138 | // 139 | // You must call this function every time you start packing into a new target. 140 | // 141 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 142 | // the following stbrp_pack_rects() call (or calls), but can be freed after 143 | // the call (or calls) finish. 144 | // 145 | // Note: to guarantee best results, either: 146 | // 1. make sure 'num_nodes' >= 'width' 147 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 148 | // 149 | // If you don't do either of the above things, widths will be quantized to multiples 150 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 151 | // 152 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 153 | // may run out of temporary storage and be unable to pack some rectangles. 154 | 155 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 156 | // Optionally call this function after init but before doing any packing to 157 | // change the handling of the out-of-temp-memory scenario, described above. 158 | // If you call init again, this will be reset to the default (false). 159 | 160 | 161 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 162 | // Optionally select which packing heuristic the library should use. Different 163 | // heuristics will produce better/worse results for different data sets. 164 | // If you call init again, this will be reset to the default. 165 | 166 | enum 167 | { 168 | STBRP_HEURISTIC_Skyline_default=0, 169 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 170 | STBRP_HEURISTIC_Skyline_BF_sortHeight 171 | }; 172 | 173 | 174 | ////////////////////////////////////////////////////////////////////////////// 175 | // 176 | // the details of the following structures don't matter to you, but they must 177 | // be visible so you can handle the memory allocations for them 178 | 179 | struct stbrp_node 180 | { 181 | stbrp_coord x,y; 182 | stbrp_node *next; 183 | }; 184 | 185 | struct stbrp_context 186 | { 187 | int width; 188 | int height; 189 | int align; 190 | int init_mode; 191 | int heuristic; 192 | int num_nodes; 193 | stbrp_node *active_head; 194 | stbrp_node *free_head; 195 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 196 | }; 197 | 198 | #ifdef __cplusplus 199 | } 200 | #endif 201 | 202 | #endif 203 | 204 | ////////////////////////////////////////////////////////////////////////////// 205 | // 206 | // IMPLEMENTATION SECTION 207 | // 208 | 209 | #ifdef STB_RECT_PACK_IMPLEMENTATION 210 | #ifndef STBRP_SORT 211 | #include 212 | #define STBRP_SORT qsort 213 | #endif 214 | 215 | #ifndef STBRP_ASSERT 216 | #include 217 | #define STBRP_ASSERT assert 218 | #endif 219 | 220 | #ifdef _MSC_VER 221 | #define STBRP__NOTUSED(v) (void)(v) 222 | #define STBRP__CDECL __cdecl 223 | #else 224 | #define STBRP__NOTUSED(v) (void)sizeof(v) 225 | #define STBRP__CDECL 226 | #endif 227 | 228 | enum 229 | { 230 | STBRP__INIT_skyline = 1 231 | }; 232 | 233 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 234 | { 235 | switch (context->init_mode) { 236 | case STBRP__INIT_skyline: 237 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 238 | context->heuristic = heuristic; 239 | break; 240 | default: 241 | STBRP_ASSERT(0); 242 | } 243 | } 244 | 245 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 246 | { 247 | if (allow_out_of_mem) 248 | // if it's ok to run out of memory, then don't bother aligning them; 249 | // this gives better packing, but may fail due to OOM (even though 250 | // the rectangles easily fit). @TODO a smarter approach would be to only 251 | // quantize once we've hit OOM, then we could get rid of this parameter. 252 | context->align = 1; 253 | else { 254 | // if it's not ok to run out of memory, then quantize the widths 255 | // so that num_nodes is always enough nodes. 256 | // 257 | // I.e. num_nodes * align >= width 258 | // align >= width / num_nodes 259 | // align = ceil(width/num_nodes) 260 | 261 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 262 | } 263 | } 264 | 265 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 266 | { 267 | int i; 268 | 269 | for (i=0; i < num_nodes-1; ++i) 270 | nodes[i].next = &nodes[i+1]; 271 | nodes[i].next = NULL; 272 | context->init_mode = STBRP__INIT_skyline; 273 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 274 | context->free_head = &nodes[0]; 275 | context->active_head = &context->extra[0]; 276 | context->width = width; 277 | context->height = height; 278 | context->num_nodes = num_nodes; 279 | stbrp_setup_allow_out_of_mem(context, 0); 280 | 281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 282 | context->extra[0].x = 0; 283 | context->extra[0].y = 0; 284 | context->extra[0].next = &context->extra[1]; 285 | context->extra[1].x = (stbrp_coord) width; 286 | context->extra[1].y = (1<<30); 287 | context->extra[1].next = NULL; 288 | } 289 | 290 | // find minimum y position if it starts at x1 291 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 292 | { 293 | stbrp_node *node = first; 294 | int x1 = x0 + width; 295 | int min_y, visited_width, waste_area; 296 | 297 | STBRP__NOTUSED(c); 298 | 299 | STBRP_ASSERT(first->x <= x0); 300 | 301 | #if 0 302 | // skip in case we're past the node 303 | while (node->next->x <= x0) 304 | ++node; 305 | #else 306 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 307 | #endif 308 | 309 | STBRP_ASSERT(node->x <= x0); 310 | 311 | min_y = 0; 312 | waste_area = 0; 313 | visited_width = 0; 314 | while (node->x < x1) { 315 | if (node->y > min_y) { 316 | // raise min_y higher. 317 | // we've accounted for all waste up to min_y, 318 | // but we'll now add more waste for everything we've visted 319 | waste_area += visited_width * (node->y - min_y); 320 | min_y = node->y; 321 | // the first time through, visited_width might be reduced 322 | if (node->x < x0) 323 | visited_width += node->next->x - x0; 324 | else 325 | visited_width += node->next->x - node->x; 326 | } else { 327 | // add waste area 328 | int under_width = node->next->x - node->x; 329 | if (under_width + visited_width > width) 330 | under_width = width - visited_width; 331 | waste_area += under_width * (min_y - node->y); 332 | visited_width += under_width; 333 | } 334 | node = node->next; 335 | } 336 | 337 | *pwaste = waste_area; 338 | return min_y; 339 | } 340 | 341 | typedef struct 342 | { 343 | int x,y; 344 | stbrp_node **prev_link; 345 | } stbrp__findresult; 346 | 347 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 348 | { 349 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 350 | stbrp__findresult fr; 351 | stbrp_node **prev, *node, *tail, **best = NULL; 352 | 353 | // align to multiple of c->align 354 | width = (width + c->align - 1); 355 | width -= width % c->align; 356 | STBRP_ASSERT(width % c->align == 0); 357 | 358 | // if it can't possibly fit, bail immediately 359 | if (width > c->width || height > c->height) { 360 | fr.prev_link = NULL; 361 | fr.x = fr.y = 0; 362 | return fr; 363 | } 364 | 365 | node = c->active_head; 366 | prev = &c->active_head; 367 | while (node->x + width <= c->width) { 368 | int y,waste; 369 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 370 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 371 | // bottom left 372 | if (y < best_y) { 373 | best_y = y; 374 | best = prev; 375 | } 376 | } else { 377 | // best-fit 378 | if (y + height <= c->height) { 379 | // can only use it if it first vertically 380 | if (y < best_y || (y == best_y && waste < best_waste)) { 381 | best_y = y; 382 | best_waste = waste; 383 | best = prev; 384 | } 385 | } 386 | } 387 | prev = &node->next; 388 | node = node->next; 389 | } 390 | 391 | best_x = (best == NULL) ? 0 : (*best)->x; 392 | 393 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 394 | // 395 | // e.g, if fitting 396 | // 397 | // ____________________ 398 | // |____________________| 399 | // 400 | // into 401 | // 402 | // | | 403 | // | ____________| 404 | // |____________| 405 | // 406 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 407 | // 408 | // This makes BF take about 2x the time 409 | 410 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 411 | tail = c->active_head; 412 | node = c->active_head; 413 | prev = &c->active_head; 414 | // find first node that's admissible 415 | while (tail->x < width) 416 | tail = tail->next; 417 | while (tail) { 418 | int xpos = tail->x - width; 419 | int y,waste; 420 | STBRP_ASSERT(xpos >= 0); 421 | // find the left position that matches this 422 | while (node->next->x <= xpos) { 423 | prev = &node->next; 424 | node = node->next; 425 | } 426 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 427 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 428 | if (y + height <= c->height) { 429 | if (y <= best_y) { 430 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 431 | best_x = xpos; 432 | //STBRP_ASSERT(y <= best_y); [DEAR IMGUI] 433 | best_y = y; 434 | best_waste = waste; 435 | best = prev; 436 | } 437 | } 438 | } 439 | tail = tail->next; 440 | } 441 | } 442 | 443 | fr.prev_link = best; 444 | fr.x = best_x; 445 | fr.y = best_y; 446 | return fr; 447 | } 448 | 449 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 450 | { 451 | // find best position according to heuristic 452 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 453 | stbrp_node *node, *cur; 454 | 455 | // bail if: 456 | // 1. it failed 457 | // 2. the best node doesn't fit (we don't always check this) 458 | // 3. we're out of memory 459 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 460 | res.prev_link = NULL; 461 | return res; 462 | } 463 | 464 | // on success, create new node 465 | node = context->free_head; 466 | node->x = (stbrp_coord) res.x; 467 | node->y = (stbrp_coord) (res.y + height); 468 | 469 | context->free_head = node->next; 470 | 471 | // insert the new node into the right starting point, and 472 | // let 'cur' point to the remaining nodes needing to be 473 | // stiched back in 474 | 475 | cur = *res.prev_link; 476 | if (cur->x < res.x) { 477 | // preserve the existing one, so start testing with the next one 478 | stbrp_node *next = cur->next; 479 | cur->next = node; 480 | cur = next; 481 | } else { 482 | *res.prev_link = node; 483 | } 484 | 485 | // from here, traverse cur and free the nodes, until we get to one 486 | // that shouldn't be freed 487 | while (cur->next && cur->next->x <= res.x + width) { 488 | stbrp_node *next = cur->next; 489 | // move the current node to the free list 490 | cur->next = context->free_head; 491 | context->free_head = cur; 492 | cur = next; 493 | } 494 | 495 | // stitch the list back in 496 | node->next = cur; 497 | 498 | if (cur->x < res.x + width) 499 | cur->x = (stbrp_coord) (res.x + width); 500 | 501 | #ifdef _DEBUG 502 | cur = context->active_head; 503 | while (cur->x < context->width) { 504 | STBRP_ASSERT(cur->x < cur->next->x); 505 | cur = cur->next; 506 | } 507 | STBRP_ASSERT(cur->next == NULL); 508 | 509 | { 510 | int count=0; 511 | cur = context->active_head; 512 | while (cur) { 513 | cur = cur->next; 514 | ++count; 515 | } 516 | cur = context->free_head; 517 | while (cur) { 518 | cur = cur->next; 519 | ++count; 520 | } 521 | STBRP_ASSERT(count == context->num_nodes+2); 522 | } 523 | #endif 524 | 525 | return res; 526 | } 527 | 528 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 529 | { 530 | const stbrp_rect *p = (const stbrp_rect *) a; 531 | const stbrp_rect *q = (const stbrp_rect *) b; 532 | if (p->h > q->h) 533 | return -1; 534 | if (p->h < q->h) 535 | return 1; 536 | return (p->w > q->w) ? -1 : (p->w < q->w); 537 | } 538 | 539 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 540 | { 541 | const stbrp_rect *p = (const stbrp_rect *) a; 542 | const stbrp_rect *q = (const stbrp_rect *) b; 543 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 544 | } 545 | 546 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 547 | { 548 | int i, all_rects_packed = 1; 549 | 550 | // we use the 'was_packed' field internally to allow sorting/unsorting 551 | for (i=0; i < num_rects; ++i) { 552 | rects[i].was_packed = i; 553 | } 554 | 555 | // sort according to heuristic 556 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 557 | 558 | for (i=0; i < num_rects; ++i) { 559 | if (rects[i].w == 0 || rects[i].h == 0) { 560 | rects[i].x = rects[i].y = 0; // empty rect needs no space 561 | } else { 562 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 563 | if (fr.prev_link) { 564 | rects[i].x = (stbrp_coord) fr.x; 565 | rects[i].y = (stbrp_coord) fr.y; 566 | } else { 567 | rects[i].x = rects[i].y = STBRP__MAXVAL; 568 | } 569 | } 570 | } 571 | 572 | // unsort 573 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 574 | 575 | // set was_packed flags and all_rects_packed status 576 | for (i=0; i < num_rects; ++i) { 577 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 578 | if (!rects[i].was_packed) 579 | all_rects_packed = 0; 580 | } 581 | 582 | // return the all_rects_packed status 583 | return all_rects_packed; 584 | } 585 | #endif 586 | 587 | /* 588 | ------------------------------------------------------------------------------ 589 | This software is available under 2 licenses -- choose whichever you prefer. 590 | ------------------------------------------------------------------------------ 591 | ALTERNATIVE A - MIT License 592 | Copyright (c) 2017 Sean Barrett 593 | Permission is hereby granted, free of charge, to any person obtaining a copy of 594 | this software and associated documentation files (the "Software"), to deal in 595 | the Software without restriction, including without limitation the rights to 596 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 597 | of the Software, and to permit persons to whom the Software is furnished to do 598 | so, subject to the following conditions: 599 | The above copyright notice and this permission notice shall be included in all 600 | copies or substantial portions of the Software. 601 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 602 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 603 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 604 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 605 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 606 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 607 | SOFTWARE. 608 | ------------------------------------------------------------------------------ 609 | ALTERNATIVE B - Public Domain (www.unlicense.org) 610 | This is free and unencumbered software released into the public domain. 611 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 612 | software, either in source code form or as a compiled binary, for any purpose, 613 | commercial or non-commercial, and by any means. 614 | In jurisdictions that recognize copyright laws, the author or authors of this 615 | software dedicate any and all copyright interest in the software to the public 616 | domain. We make this dedication for the benefit of the public at large and to 617 | the detriment of our heirs and successors. We intend this dedication to be an 618 | overt act of relinquishment in perpetuity of all present and future rights to 619 | this software under copyright law. 620 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 621 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 622 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 623 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 624 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 625 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 626 | ------------------------------------------------------------------------------ 627 | */ 628 | -------------------------------------------------------------------------------- /libcurl.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RealMove/ImGui-KeyAuth-Base/f32f367b9f9d97550fe4377cf91188a130e4209b/libcurl.lib -------------------------------------------------------------------------------- /library_x64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RealMove/ImGui-KeyAuth-Base/f32f367b9f9d97550fe4377cf91188a130e4209b/library_x64.lib -------------------------------------------------------------------------------- /login/auth.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct channel_struct 7 | { 8 | std::string author; 9 | std::string message; 10 | std::string timestamp; 11 | }; 12 | 13 | namespace KeyAuth { 14 | class api { 15 | public: 16 | 17 | std::string name, ownerid, secret, version, url; 18 | 19 | api(std::string name, std::string ownerid, std::string secret, std::string version, std::string url) : name(name), ownerid(ownerid), secret(secret), version(version), url(url) {} 20 | 21 | void ban(std::string reason = ""); 22 | void init(); 23 | void check(); 24 | void log(std::string msg); 25 | void license(std::string key); 26 | std::string var(std::string varid); 27 | std::string webhook(std::string id, std::string params, std::string body = "", std::string contenttype = ""); 28 | void setvar(std::string var, std::string vardata); 29 | std::string getvar(std::string var); 30 | bool checkblack(); 31 | void web_login(); 32 | void button(std::string value); 33 | void upgrade(std::string username, std::string key); 34 | void login(std::string username, std::string password); 35 | std::vector download(std::string fileid); 36 | void regstr(std::string username, std::string password, std::string key, std::string email = ""); 37 | void chatget(std::string channel); 38 | bool chatsend(std::string message, std::string channel); 39 | void changeusername(std::string newusername); 40 | std::string fetchonline(); 41 | void forgot(std::string username, std::string email); 42 | 43 | class subscriptions_class { 44 | public: 45 | std::string name; 46 | std::string expiry; 47 | }; 48 | 49 | class data_class { 50 | public: 51 | // app data 52 | std::string numUsers; 53 | std::string numOnlineUsers; 54 | std::string numKeys; 55 | std::string version; 56 | std::string customerPanelLink; 57 | // user data 58 | std::string username; 59 | std::string ip; 60 | std::string hwid; 61 | std::string createdate; 62 | std::string lastlogin; 63 | 64 | std::vector subscriptions; 65 | 66 | // response data 67 | std::vector channeldata; 68 | bool success; 69 | std::string message; 70 | }; 71 | data_class data; 72 | 73 | private: 74 | std::string sessionid, enckey; 75 | }; 76 | } 77 | -------------------------------------------------------------------------------- /login/color.hpp: -------------------------------------------------------------------------------- 1 | 2 | //! termcolor 3 | //! ~~~~~~~~~ 4 | //! 5 | //! termcolor is a header-only c++ library for printing colored messages 6 | //! to the terminal. Written just for fun with a help of the Force. 7 | //! 8 | //! :copyright: (c) 2013 by Ihor Kalnytskyi 9 | //! :license: BSD, see LICENSE for details 10 | //! 11 | 12 | #ifndef TERMCOLOR_HPP_ 13 | #define TERMCOLOR_HPP_ 14 | 15 | #include 16 | #include 17 | 18 | // Detect target's platform and set some macros in order to wrap platform 19 | // specific code this library depends on. 20 | #if defined(_WIN32) || defined(_WIN64) 21 | # define TERMCOLOR_TARGET_WINDOWS 22 | #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) 23 | # define TERMCOLOR_TARGET_POSIX 24 | #endif 25 | 26 | // If implementation has not been explicitly set, try to choose one based on 27 | // target platform. 28 | #if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) 29 | # if defined(TERMCOLOR_TARGET_POSIX) 30 | # define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES 31 | # define TERMCOLOR_AUTODETECTED_IMPLEMENTATION 32 | # elif defined(TERMCOLOR_TARGET_WINDOWS) 33 | # define TERMCOLOR_USE_WINDOWS_API 34 | # define TERMCOLOR_AUTODETECTED_IMPLEMENTATION 35 | # endif 36 | #endif 37 | 38 | // These headers provide isatty()/fileno() functions, which are used for 39 | // testing whether a standard stream refers to the terminal. 40 | #if defined(TERMCOLOR_TARGET_POSIX) 41 | # include 42 | #elif defined(TERMCOLOR_TARGET_WINDOWS) 43 | # include 44 | # include 45 | #endif 46 | 47 | 48 | namespace termcolor 49 | { 50 | // Forward declaration of the `_internal` namespace. 51 | // All comments are below. 52 | namespace _internal 53 | { 54 | inline int colorize_index(); 55 | inline FILE* get_standard_stream(const std::ostream& stream); 56 | inline bool is_colorized(std::ostream& stream); 57 | inline bool is_atty(const std::ostream& stream); 58 | 59 | #if defined(TERMCOLOR_TARGET_WINDOWS) 60 | inline void win_change_attributes(std::ostream& stream, int foreground, int background = -1); 61 | #endif 62 | } 63 | 64 | inline 65 | std::ostream& colorize(std::ostream& stream) 66 | { 67 | stream.iword(_internal::colorize_index()) = 1L; 68 | return stream; 69 | } 70 | 71 | inline 72 | std::ostream& nocolorize(std::ostream& stream) 73 | { 74 | stream.iword(_internal::colorize_index()) = 0L; 75 | return stream; 76 | } 77 | 78 | inline 79 | std::ostream& reset(std::ostream& stream) 80 | { 81 | if (_internal::is_colorized(stream)) 82 | { 83 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 84 | stream << "\033[00m"; 85 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 86 | _internal::win_change_attributes(stream, -1, -1); 87 | #endif 88 | } 89 | return stream; 90 | } 91 | 92 | inline 93 | std::ostream& bold(std::ostream& stream) 94 | { 95 | if (_internal::is_colorized(stream)) 96 | { 97 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 98 | stream << "\033[1m"; 99 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 100 | #endif 101 | } 102 | return stream; 103 | } 104 | 105 | inline 106 | std::ostream& dark(std::ostream& stream) 107 | { 108 | if (_internal::is_colorized(stream)) 109 | { 110 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 111 | stream << "\033[2m"; 112 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 113 | #endif 114 | } 115 | return stream; 116 | } 117 | 118 | inline 119 | std::ostream& italic(std::ostream& stream) 120 | { 121 | if (_internal::is_colorized(stream)) 122 | { 123 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 124 | stream << "\033[3m"; 125 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 126 | #endif 127 | } 128 | return stream; 129 | } 130 | 131 | inline 132 | std::ostream& underline(std::ostream& stream) 133 | { 134 | if (_internal::is_colorized(stream)) 135 | { 136 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 137 | stream << "\033[4m"; 138 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 139 | _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); 140 | #endif 141 | } 142 | return stream; 143 | } 144 | 145 | inline 146 | std::ostream& blink(std::ostream& stream) 147 | { 148 | if (_internal::is_colorized(stream)) 149 | { 150 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 151 | stream << "\033[5m"; 152 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 153 | #endif 154 | } 155 | return stream; 156 | } 157 | 158 | inline 159 | std::ostream& reverse(std::ostream& stream) 160 | { 161 | if (_internal::is_colorized(stream)) 162 | { 163 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 164 | stream << "\033[7m"; 165 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 166 | #endif 167 | } 168 | return stream; 169 | } 170 | 171 | inline 172 | std::ostream& concealed(std::ostream& stream) 173 | { 174 | if (_internal::is_colorized(stream)) 175 | { 176 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 177 | stream << "\033[8m"; 178 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 179 | #endif 180 | } 181 | return stream; 182 | } 183 | 184 | inline 185 | std::ostream& crossed(std::ostream& stream) 186 | { 187 | if (_internal::is_colorized(stream)) 188 | { 189 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 190 | stream << "\033[9m"; 191 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 192 | #endif 193 | } 194 | return stream; 195 | } 196 | 197 | template inline 198 | std::ostream& color(std::ostream& stream) 199 | { 200 | if (_internal::is_colorized(stream)) 201 | { 202 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 203 | char command[12]; 204 | std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); 205 | stream << command; 206 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 207 | #endif 208 | } 209 | return stream; 210 | } 211 | 212 | template inline 213 | std::ostream& on_color(std::ostream& stream) 214 | { 215 | if (_internal::is_colorized(stream)) 216 | { 217 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 218 | char command[12]; 219 | std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); 220 | stream << command; 221 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 222 | #endif 223 | } 224 | return stream; 225 | } 226 | 227 | template inline 228 | std::ostream& color(std::ostream& stream) 229 | { 230 | if (_internal::is_colorized(stream)) 231 | { 232 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 233 | char command[20]; 234 | std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); 235 | stream << command; 236 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 237 | #endif 238 | } 239 | return stream; 240 | } 241 | 242 | template inline 243 | std::ostream& on_color(std::ostream& stream) 244 | { 245 | if (_internal::is_colorized(stream)) 246 | { 247 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 248 | char command[20]; 249 | std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); 250 | stream << command; 251 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 252 | #endif 253 | } 254 | return stream; 255 | } 256 | 257 | inline 258 | std::ostream& grey(std::ostream& stream) 259 | { 260 | if (_internal::is_colorized(stream)) 261 | { 262 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 263 | stream << "\033[30m"; 264 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 265 | _internal::win_change_attributes(stream, 266 | 0 // grey (black) 267 | ); 268 | #endif 269 | } 270 | return stream; 271 | } 272 | 273 | inline 274 | std::ostream& red(std::ostream& stream) 275 | { 276 | if (_internal::is_colorized(stream)) 277 | { 278 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 279 | stream << "\033[31m"; 280 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 281 | _internal::win_change_attributes(stream, 282 | FOREGROUND_RED 283 | ); 284 | #endif 285 | } 286 | return stream; 287 | } 288 | 289 | inline 290 | std::ostream& green(std::ostream& stream) 291 | { 292 | if (_internal::is_colorized(stream)) 293 | { 294 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 295 | stream << "\033[32m"; 296 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 297 | _internal::win_change_attributes(stream, 298 | FOREGROUND_GREEN 299 | ); 300 | #endif 301 | } 302 | return stream; 303 | } 304 | 305 | inline 306 | std::ostream& yellow(std::ostream& stream) 307 | { 308 | if (_internal::is_colorized(stream)) 309 | { 310 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 311 | stream << "\033[33m"; 312 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 313 | _internal::win_change_attributes(stream, 314 | FOREGROUND_GREEN | FOREGROUND_RED 315 | ); 316 | #endif 317 | } 318 | return stream; 319 | } 320 | 321 | inline 322 | std::ostream& blue(std::ostream& stream) 323 | { 324 | if (_internal::is_colorized(stream)) 325 | { 326 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 327 | stream << "\033[34m"; 328 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 329 | _internal::win_change_attributes(stream, 330 | FOREGROUND_BLUE 331 | ); 332 | #endif 333 | } 334 | return stream; 335 | } 336 | 337 | inline 338 | std::ostream& magenta(std::ostream& stream) 339 | { 340 | if (_internal::is_colorized(stream)) 341 | { 342 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 343 | stream << "\033[35m"; 344 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 345 | _internal::win_change_attributes(stream, 346 | FOREGROUND_BLUE | FOREGROUND_RED 347 | ); 348 | #endif 349 | } 350 | return stream; 351 | } 352 | 353 | inline 354 | std::ostream& cyan(std::ostream& stream) 355 | { 356 | if (_internal::is_colorized(stream)) 357 | { 358 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 359 | stream << "\033[36m"; 360 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 361 | _internal::win_change_attributes(stream, 362 | FOREGROUND_BLUE | FOREGROUND_GREEN 363 | ); 364 | #endif 365 | } 366 | return stream; 367 | } 368 | 369 | inline 370 | std::ostream& white(std::ostream& stream) 371 | { 372 | if (_internal::is_colorized(stream)) 373 | { 374 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 375 | stream << "\033[37m"; 376 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 377 | _internal::win_change_attributes(stream, 378 | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED 379 | ); 380 | #endif 381 | } 382 | return stream; 383 | } 384 | 385 | 386 | inline 387 | std::ostream& bright_grey(std::ostream& stream) 388 | { 389 | if (_internal::is_colorized(stream)) 390 | { 391 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 392 | stream << "\033[90m"; 393 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 394 | _internal::win_change_attributes(stream, 395 | 0 | FOREGROUND_INTENSITY // grey (black) 396 | ); 397 | #endif 398 | } 399 | return stream; 400 | } 401 | 402 | inline 403 | std::ostream& bright_red(std::ostream& stream) 404 | { 405 | if (_internal::is_colorized(stream)) 406 | { 407 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 408 | stream << "\033[91m"; 409 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 410 | _internal::win_change_attributes(stream, 411 | FOREGROUND_RED | FOREGROUND_INTENSITY 412 | ); 413 | #endif 414 | } 415 | return stream; 416 | } 417 | 418 | inline 419 | std::ostream& bright_green(std::ostream& stream) 420 | { 421 | if (_internal::is_colorized(stream)) 422 | { 423 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 424 | stream << "\033[92m"; 425 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 426 | _internal::win_change_attributes(stream, 427 | FOREGROUND_GREEN | FOREGROUND_INTENSITY 428 | ); 429 | #endif 430 | } 431 | return stream; 432 | } 433 | 434 | inline 435 | std::ostream& bright_yellow(std::ostream& stream) 436 | { 437 | if (_internal::is_colorized(stream)) 438 | { 439 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 440 | stream << "\033[93m"; 441 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 442 | _internal::win_change_attributes(stream, 443 | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY 444 | ); 445 | #endif 446 | } 447 | return stream; 448 | } 449 | 450 | inline 451 | std::ostream& bright_blue(std::ostream& stream) 452 | { 453 | if (_internal::is_colorized(stream)) 454 | { 455 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 456 | stream << "\033[94m"; 457 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 458 | _internal::win_change_attributes(stream, 459 | FOREGROUND_BLUE | FOREGROUND_INTENSITY 460 | ); 461 | #endif 462 | } 463 | return stream; 464 | } 465 | 466 | inline 467 | std::ostream& bright_magenta(std::ostream& stream) 468 | { 469 | if (_internal::is_colorized(stream)) 470 | { 471 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 472 | stream << "\033[95m"; 473 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 474 | _internal::win_change_attributes(stream, 475 | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY 476 | ); 477 | #endif 478 | } 479 | return stream; 480 | } 481 | 482 | inline 483 | std::ostream& bright_cyan(std::ostream& stream) 484 | { 485 | if (_internal::is_colorized(stream)) 486 | { 487 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 488 | stream << "\033[96m"; 489 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 490 | _internal::win_change_attributes(stream, 491 | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY 492 | ); 493 | #endif 494 | } 495 | return stream; 496 | } 497 | 498 | inline 499 | std::ostream& bright_white(std::ostream& stream) 500 | { 501 | if (_internal::is_colorized(stream)) 502 | { 503 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 504 | stream << "\033[97m"; 505 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 506 | _internal::win_change_attributes(stream, 507 | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY 508 | ); 509 | #endif 510 | } 511 | return stream; 512 | } 513 | 514 | 515 | inline 516 | std::ostream& on_grey(std::ostream& stream) 517 | { 518 | if (_internal::is_colorized(stream)) 519 | { 520 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 521 | stream << "\033[40m"; 522 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 523 | _internal::win_change_attributes(stream, -1, 524 | 0 // grey (black) 525 | ); 526 | #endif 527 | } 528 | return stream; 529 | } 530 | 531 | inline 532 | std::ostream& on_red(std::ostream& stream) 533 | { 534 | if (_internal::is_colorized(stream)) 535 | { 536 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 537 | stream << "\033[41m"; 538 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 539 | _internal::win_change_attributes(stream, -1, 540 | BACKGROUND_RED 541 | ); 542 | #endif 543 | } 544 | return stream; 545 | } 546 | 547 | inline 548 | std::ostream& on_green(std::ostream& stream) 549 | { 550 | if (_internal::is_colorized(stream)) 551 | { 552 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 553 | stream << "\033[42m"; 554 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 555 | _internal::win_change_attributes(stream, -1, 556 | BACKGROUND_GREEN 557 | ); 558 | #endif 559 | } 560 | return stream; 561 | } 562 | 563 | inline 564 | std::ostream& on_yellow(std::ostream& stream) 565 | { 566 | if (_internal::is_colorized(stream)) 567 | { 568 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 569 | stream << "\033[43m"; 570 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 571 | _internal::win_change_attributes(stream, -1, 572 | BACKGROUND_GREEN | BACKGROUND_RED 573 | ); 574 | #endif 575 | } 576 | return stream; 577 | } 578 | 579 | inline 580 | std::ostream& on_blue(std::ostream& stream) 581 | { 582 | if (_internal::is_colorized(stream)) 583 | { 584 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 585 | stream << "\033[44m"; 586 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 587 | _internal::win_change_attributes(stream, -1, 588 | BACKGROUND_BLUE 589 | ); 590 | #endif 591 | } 592 | return stream; 593 | } 594 | 595 | inline 596 | std::ostream& on_magenta(std::ostream& stream) 597 | { 598 | if (_internal::is_colorized(stream)) 599 | { 600 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 601 | stream << "\033[45m"; 602 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 603 | _internal::win_change_attributes(stream, -1, 604 | BACKGROUND_BLUE | BACKGROUND_RED 605 | ); 606 | #endif 607 | } 608 | return stream; 609 | } 610 | 611 | inline 612 | std::ostream& on_cyan(std::ostream& stream) 613 | { 614 | if (_internal::is_colorized(stream)) 615 | { 616 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 617 | stream << "\033[46m"; 618 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 619 | _internal::win_change_attributes(stream, -1, 620 | BACKGROUND_GREEN | BACKGROUND_BLUE 621 | ); 622 | #endif 623 | } 624 | return stream; 625 | } 626 | 627 | inline 628 | std::ostream& on_white(std::ostream& stream) 629 | { 630 | if (_internal::is_colorized(stream)) 631 | { 632 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 633 | stream << "\033[47m"; 634 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 635 | _internal::win_change_attributes(stream, -1, 636 | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED 637 | ); 638 | #endif 639 | } 640 | 641 | return stream; 642 | } 643 | 644 | 645 | inline 646 | std::ostream& on_bright_grey(std::ostream& stream) 647 | { 648 | if (_internal::is_colorized(stream)) 649 | { 650 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 651 | stream << "\033[100m"; 652 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 653 | _internal::win_change_attributes(stream, -1, 654 | 0 | BACKGROUND_INTENSITY // grey (black) 655 | ); 656 | #endif 657 | } 658 | return stream; 659 | } 660 | 661 | inline 662 | std::ostream& on_bright_red(std::ostream& stream) 663 | { 664 | if (_internal::is_colorized(stream)) 665 | { 666 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 667 | stream << "\033[101m"; 668 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 669 | _internal::win_change_attributes(stream, -1, 670 | BACKGROUND_RED | BACKGROUND_INTENSITY 671 | ); 672 | #endif 673 | } 674 | return stream; 675 | } 676 | 677 | inline 678 | std::ostream& on_bright_green(std::ostream& stream) 679 | { 680 | if (_internal::is_colorized(stream)) 681 | { 682 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 683 | stream << "\033[102m"; 684 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 685 | _internal::win_change_attributes(stream, -1, 686 | BACKGROUND_GREEN | BACKGROUND_INTENSITY 687 | ); 688 | #endif 689 | } 690 | return stream; 691 | } 692 | 693 | inline 694 | std::ostream& on_bright_yellow(std::ostream& stream) 695 | { 696 | if (_internal::is_colorized(stream)) 697 | { 698 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 699 | stream << "\033[103m"; 700 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 701 | _internal::win_change_attributes(stream, -1, 702 | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY 703 | ); 704 | #endif 705 | } 706 | return stream; 707 | } 708 | 709 | inline 710 | std::ostream& on_bright_blue(std::ostream& stream) 711 | { 712 | if (_internal::is_colorized(stream)) 713 | { 714 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 715 | stream << "\033[104m"; 716 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 717 | _internal::win_change_attributes(stream, -1, 718 | BACKGROUND_BLUE | BACKGROUND_INTENSITY 719 | ); 720 | #endif 721 | } 722 | return stream; 723 | } 724 | 725 | inline 726 | std::ostream& on_bright_magenta(std::ostream& stream) 727 | { 728 | if (_internal::is_colorized(stream)) 729 | { 730 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 731 | stream << "\033[105m"; 732 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 733 | _internal::win_change_attributes(stream, -1, 734 | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY 735 | ); 736 | #endif 737 | } 738 | return stream; 739 | } 740 | 741 | inline 742 | std::ostream& on_bright_cyan(std::ostream& stream) 743 | { 744 | if (_internal::is_colorized(stream)) 745 | { 746 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 747 | stream << "\033[106m"; 748 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 749 | _internal::win_change_attributes(stream, -1, 750 | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY 751 | ); 752 | #endif 753 | } 754 | return stream; 755 | } 756 | 757 | inline 758 | std::ostream& on_bright_white(std::ostream& stream) 759 | { 760 | if (_internal::is_colorized(stream)) 761 | { 762 | #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) 763 | stream << "\033[107m"; 764 | #elif defined(TERMCOLOR_USE_WINDOWS_API) 765 | _internal::win_change_attributes(stream, -1, 766 | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY 767 | ); 768 | #endif 769 | } 770 | 771 | return stream; 772 | } 773 | 774 | 775 | 776 | //! Since C++ hasn't a way to hide something in the header from 777 | //! the outer access, I have to introduce this namespace which 778 | //! is used for internal purpose and should't be access from 779 | //! the user code. 780 | namespace _internal 781 | { 782 | // An index to be used to access a private storage of I/O streams. See 783 | // colorize / nocolorize I/O manipulators for details. Due to the fact 784 | // that static variables ain't shared between translation units, inline 785 | // function with local static variable is used to do the trick and share 786 | // the variable value between translation units. 787 | inline int colorize_index() 788 | { 789 | static int colorize_index = std::ios_base::xalloc(); 790 | return colorize_index; 791 | } 792 | 793 | //! Since C++ hasn't a true way to extract stream handler 794 | //! from the a given `std::ostream` object, I have to write 795 | //! this kind of hack. 796 | inline 797 | FILE* get_standard_stream(const std::ostream& stream) 798 | { 799 | if (&stream == &std::cout) 800 | return stdout; 801 | else if ((&stream == &std::cerr) || (&stream == &std::clog)) 802 | return stderr; 803 | 804 | return nullptr; 805 | } 806 | 807 | // Say whether a given stream should be colorized or not. It's always 808 | // true for ATTY streams and may be true for streams marked with 809 | // colorize flag. 810 | inline 811 | bool is_colorized(std::ostream& stream) 812 | { 813 | return is_atty(stream) || static_cast(stream.iword(colorize_index())); 814 | } 815 | 816 | //! Test whether a given `std::ostream` object refers to 817 | //! a terminal. 818 | inline 819 | bool is_atty(const std::ostream& stream) 820 | { 821 | FILE* std_stream = get_standard_stream(stream); 822 | 823 | // Unfortunately, fileno() ends with segmentation fault 824 | // if invalid file descriptor is passed. So we need to 825 | // handle this case gracefully and assume it's not a tty 826 | // if standard stream is not detected, and 0 is returned. 827 | if (!std_stream) 828 | return false; 829 | 830 | #if defined(TERMCOLOR_TARGET_POSIX) 831 | return ::isatty(fileno(std_stream)); 832 | #elif defined(TERMCOLOR_TARGET_WINDOWS) 833 | return ::_isatty(_fileno(std_stream)); 834 | #else 835 | return false; 836 | #endif 837 | } 838 | 839 | #if defined(TERMCOLOR_TARGET_WINDOWS) 840 | //! Change Windows Terminal colors attribute. If some 841 | //! parameter is `-1` then attribute won't changed. 842 | inline void win_change_attributes(std::ostream& stream, int foreground, int background) 843 | { 844 | // yeah, i know.. it's ugly, it's windows. 845 | static WORD defaultAttributes = 0; 846 | 847 | // Windows doesn't have ANSI escape sequences and so we use special 848 | // API to change Terminal output color. That means we can't 849 | // manipulate colors by means of "std::stringstream" and hence 850 | // should do nothing in this case. 851 | if (!_internal::is_atty(stream)) 852 | return; 853 | 854 | // get terminal handle 855 | HANDLE hTerminal = INVALID_HANDLE_VALUE; 856 | if (&stream == &std::cout) 857 | hTerminal = GetStdHandle(STD_OUTPUT_HANDLE); 858 | else if (&stream == &std::cerr) 859 | hTerminal = GetStdHandle(STD_ERROR_HANDLE); 860 | 861 | // save default terminal attributes if it unsaved 862 | if (!defaultAttributes) 863 | { 864 | CONSOLE_SCREEN_BUFFER_INFO info; 865 | if (!GetConsoleScreenBufferInfo(hTerminal, &info)) 866 | return; 867 | defaultAttributes = info.wAttributes; 868 | } 869 | 870 | // restore all default settings 871 | if (foreground == -1 && background == -1) 872 | { 873 | SetConsoleTextAttribute(hTerminal, defaultAttributes); 874 | return; 875 | } 876 | 877 | // get current settings 878 | CONSOLE_SCREEN_BUFFER_INFO info; 879 | if (!GetConsoleScreenBufferInfo(hTerminal, &info)) 880 | return; 881 | 882 | if (foreground != -1) 883 | { 884 | info.wAttributes &= ~(info.wAttributes & 0x0F); 885 | info.wAttributes |= static_cast(foreground); 886 | } 887 | 888 | if (background != -1) 889 | { 890 | info.wAttributes &= ~(info.wAttributes & 0xF0); 891 | info.wAttributes |= static_cast(background); 892 | } 893 | 894 | SetConsoleTextAttribute(hTerminal, info.wAttributes); 895 | } 896 | #endif // TERMCOLOR_TARGET_WINDOWS 897 | 898 | } // namespace _internal 899 | 900 | } // namespace termcolor 901 | 902 | 903 | #undef TERMCOLOR_TARGET_POSIX 904 | #undef TERMCOLOR_TARGET_WINDOWS 905 | 906 | #if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) 907 | # undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES 908 | # undef TERMCOLOR_USE_WINDOWS_API 909 | #endif 910 | 911 | #endif // TERMCOLOR_HPP_ -------------------------------------------------------------------------------- /login/login.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "auth.hpp" 3 | #include "../protection/skStr.h" 4 | #include 5 | #include 6 | 7 | using namespace KeyAuth; 8 | 9 | std::string name = skCrypt("").decrypt(); // application name. right above the blurred text aka the secret on the licenses tab among other tabs 10 | std::string ownerid = skCrypt("").decrypt(); // ownerid, found in account settings. click your profile picture on top right of dashboard and then account settings. 11 | std::string secret = skCrypt("").decrypt(); // app secret, the blurred text on licenses tab and other tabs 12 | std::string version = skCrypt("1.0").decrypt(); // leave alone unless you've changed version on website 13 | std::string url = skCrypt("https://keyauth.win/api/1.2/").decrypt(); // change if you're self-hosting 14 | 15 | api KeyAuthApp(name, ownerid, secret, version, url); 16 | 17 | void login(std::string key) 18 | { 19 | // Main login function, if you wanna add something different you can change here 20 | KeyAuthApp.init(); 21 | if (KeyAuthApp.checkblack()) { 22 | abort(); 23 | } 24 | KeyAuthApp.license(key); 25 | if (!KeyAuthApp.data.success) 26 | { 27 | std::cout << skCrypt("\n Status: ") << KeyAuthApp.data.message; 28 | Sleep(1500); 29 | exit(0); 30 | } 31 | } -------------------------------------------------------------------------------- /main/main.cpp: -------------------------------------------------------------------------------- 1 | // Discord: realmove 2 | #include 3 | #include 4 | #include "window.h" 5 | #include 6 | #include "main.h" 7 | #include "../imgui/imgui.h" 8 | #include "../imgui/imgui_shadow.h" 9 | #include "../protection/skStr.h" 10 | #include "../protection/protection.h" 11 | #include "../login/login.hpp" 12 | #include "../login/color.hpp" 13 | // My discord server: https://discord.gg/BbQCYa46tG 14 | 15 | int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 16 | { 17 | std::thread(Protection_Loop).detach(); // Protection loop for debuggers etc. 18 | 19 | AllocConsole(); // Call system console 20 | 21 | // Define in/outs to work in console 22 | freopen("CONOUT$", "w", stdout); 23 | freopen("conin$", "r+t", stdin); 24 | freopen("conout$", "w+t", stdout); 25 | freopen("conout$", "w+t", stderr); 26 | 27 | if (!doneLogin) { 28 | ShowWindow(GetConsoleWindow(), SW_HIDE); 29 | std::string key; 30 | system("MODE CON COLS=55 LINES=12"); 31 | SetLayeredWindowAttributes(GetConsoleWindow(), NULL, 195, LWA_ALPHA); 32 | std::string consoleTitle = (std::string)skCrypt("Loader base by [Discord:realmove]"); 33 | SetConsoleTitleA(consoleTitle.c_str()); 34 | ShowWindow(GetConsoleWindow(), SW_SHOW); 35 | std::cout << termcolor::bright_yellow << skCrypt("\n [!] Enter your license: "); 36 | std::cin >> key; 37 | login(key); 38 | doneLogin = true; // Login is done 39 | } 40 | if (doneLogin) { 41 | ShowWindow(GetConsoleWindow(), SW_HIDE); // Hide main console window 42 | 43 | // Create the main window 44 | WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, WINDOW_NAME, NULL }; 45 | RegisterClassEx(&wc); 46 | main_hwnd = CreateWindow(wc.lpszClassName, WINDOW_NAME, WS_POPUP, 0, 0, 5, 5, NULL, NULL, wc.hInstance, NULL); 47 | 48 | 49 | 50 | // Initialize Direct3D 51 | if (!CreateDeviceD3D(main_hwnd)) { 52 | CleanupDeviceD3D(); 53 | UnregisterClass(wc.lpszClassName, wc.hInstance); 54 | return 1; 55 | } 56 | 57 | // Window settings 58 | ShowWindow(main_hwnd, SW_HIDE); 59 | UpdateWindow(main_hwnd); 60 | 61 | // Setup context 62 | ImGui::CreateContext(); 63 | 64 | ImGuiIO& io = ImGui::GetIO(); 65 | io.IniFilename = nullptr; //crutial for not leaving the imgui.ini file 66 | io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows 67 | 68 | // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. 69 | ImGuiStyle& style = ImGui::GetStyle(); 70 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 71 | { 72 | style.WindowRounding = 0.0f; 73 | style.Colors[ImGuiCol_WindowBg].w = 1.0f; 74 | } 75 | 76 | // Setup Platform/Renderer backends 77 | ImGui_ImplWin32_Init(main_hwnd); 78 | ImGui_ImplDX9_Init(g_pd3dDevice); 79 | 80 | MSG msg; 81 | ZeroMemory(&msg, sizeof(msg)); 82 | SetConsoleTitleA(skCrypt("Service Host: Microsoft Account x64")); 83 | while (msg.message != WM_QUIT) 84 | { 85 | if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 86 | { 87 | TranslateMessage(&msg); 88 | DispatchMessage(&msg); 89 | continue; 90 | } 91 | 92 | // Start the frame 93 | ImGui_ImplDX9_NewFrame(); 94 | ImGui_ImplWin32_NewFrame(); 95 | ImGui::NewFrame(); 96 | { 97 | static float r = 1.0f; 98 | static float g = 0.f; 99 | static float b = 0.f; 100 | if (r == 1.f && g >= 0.f && b <= 0.f) 101 | { 102 | g += 0.005f; 103 | b = 0.f; 104 | } 105 | if (r <= 1.f && g >= 1.f && b == 0.f) 106 | { 107 | g = 1.f; 108 | r -= 0.005f; 109 | } 110 | if (r <= 0.f && g == 1.f && b >= 0.f) 111 | { 112 | r = 0.f; 113 | b += 0.005f; 114 | } 115 | if (r == 0.f && g <= 1.f && b >= 1.f) 116 | { 117 | b = 1.f; 118 | g -= 0.005f; 119 | } 120 | if (r >= 0.f && g <= 0.f && b == 1.f) 121 | { 122 | g = 0.f; 123 | r += 0.005f; 124 | } 125 | if (r >= 1.f && g >= 0.f && b <= 1.f) 126 | { 127 | r = 1.f; 128 | b -= 0.005f; 129 | } 130 | 131 | ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Once); 132 | ImGui::SetNextWindowSize(ImVec2(400, 300)); 133 | ImGui::SetNextWindowBgAlpha(1.0f); 134 | ImGui::Begin("Loader base by [Discord:realmove]", &loader_active, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBringToFrontOnFocus); 135 | { 136 | ImGui::StyleColorsClassic(); // Purple theme 137 | ImGui::TextColored(ImVec4(r - 0.15f, g - 0.35f, b, 1.0f), ("Loader Base")); 138 | 139 | ImGui::Spacing(); 140 | if (ImGui::BeginTabBar("#tabs")) { 141 | if (ImGui::BeginTabItem("Main")) { 142 | static int slider_float = 0.f; 143 | ImGui::SliderInt("Slider INT", &slider_float, 0.f, 100.f); 144 | ImGui::Spacing(); 145 | bool checkbox; 146 | ImGui::Checkbox("Checkbox", &checkbox); 147 | ImGui::Spacing(); 148 | static int items_count = 0; 149 | const char* items[3] = { "One", "Two", "Three" }; 150 | ImGui::Combo("Combo", &items_count, items, 3); 151 | ImGui::EndTabItem(); 152 | } 153 | 154 | ImGui::EndTabBar(); 155 | } 156 | 157 | } 158 | ImGui::End(); 159 | } 160 | ImGui::EndFrame(); 161 | 162 | g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0); 163 | if (g_pd3dDevice->BeginScene() >= 0) 164 | { 165 | ImGui::Render(); 166 | ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); 167 | g_pd3dDevice->EndScene(); 168 | } 169 | 170 | // Update and Render platform windows 171 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 172 | { 173 | ImGui::UpdatePlatformWindows(); 174 | ImGui::RenderPlatformWindowsDefault(); 175 | } 176 | 177 | HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 178 | 179 | // Handle loss of D3D9 device 180 | if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) { 181 | ResetDevice(); 182 | } 183 | if (!loader_active) { 184 | msg.message = WM_QUIT; 185 | } 186 | } 187 | ImGui_ImplDX9_Shutdown(); 188 | ImGui_ImplWin32_Shutdown(); 189 | ImGui::DestroyContext(); 190 | 191 | CleanupDeviceD3D(); 192 | DestroyWindow(main_hwnd); 193 | UnregisterClass(wc.lpszClassName, wc.hInstance); 194 | 195 | return 0; 196 | } 197 | } 198 | LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { 199 | if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) 200 | return true; 201 | 202 | switch (msg) 203 | { 204 | case WM_SIZE: 205 | if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) 206 | { 207 | g_d3dpp.BackBufferWidth = LOWORD(lParam); 208 | g_d3dpp.BackBufferHeight = HIWORD(lParam); 209 | ResetDevice(); 210 | } 211 | return 0; 212 | case WM_SYSCOMMAND: 213 | if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu 214 | return 0; 215 | break; 216 | case WM_DESTROY: 217 | PostQuitMessage(0); 218 | return 0; 219 | } 220 | return DefWindowProc(hWnd, msg, wParam, lParam); 221 | } 222 | -------------------------------------------------------------------------------- /main/main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | bool doneLogin = false; -------------------------------------------------------------------------------- /main/window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #pragma comment(lib,"d3d9.lib") 8 | 9 | #include "../imgui/imgui.h" 10 | #include "../imgui/imgui_impl_dx9.h" 11 | #include "../imgui/imgui_impl_win32.h" 12 | 13 | #define WINDOW_NAME "Service Host: Microsoft Account x64" 14 | #define WINDOW_WIDTH 400 15 | #define WINDOW_HEIGHT 300 16 | 17 | bool loader_active = true; 18 | HWND main_hwnd = nullptr; 19 | 20 | LPDIRECT3DDEVICE9 g_pd3dDevice; 21 | D3DPRESENT_PARAMETERS g_d3dpp; 22 | LPDIRECT3D9 g_pD3D; 23 | 24 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 25 | LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 26 | 27 | bool CreateDeviceD3D(HWND hWnd) 28 | { 29 | if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) 30 | return false; 31 | 32 | // Create the D3DDevice 33 | ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); 34 | g_d3dpp.Windowed = TRUE; 35 | g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 36 | g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 37 | g_d3dpp.EnableAutoDepthStencil = TRUE; 38 | g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 39 | g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync 40 | //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate 41 | if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) 42 | return false; 43 | return true; 44 | } 45 | 46 | void CleanupDeviceD3D() 47 | { 48 | if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } 49 | if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; } 50 | } 51 | 52 | void ResetDevice() 53 | { 54 | ImGui_ImplDX9_InvalidateDeviceObjects(); 55 | HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); 56 | if (hr == D3DERR_INVALIDCALL) 57 | IM_ASSERT(0); 58 | ImGui_ImplDX9_CreateDeviceObjects(); 59 | } -------------------------------------------------------------------------------- /protection/auth.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace KeyAuth { 7 | class api { 8 | public: 9 | 10 | std::string name, ownerid, secret, version, url; 11 | 12 | api(std::string name, std::string ownerid, std::string secret, std::string version, std::string url) : name(name), ownerid(ownerid), secret(secret), version(version), url(url) {} 13 | 14 | void ban(std::string reason = ""); 15 | void init(); 16 | void check(); 17 | void log(std::string msg); 18 | void license(std::string key); 19 | std::string var(std::string varid); 20 | std::string webhook(std::string id, std::string params); 21 | void setvar(std::string var, std::string vardata); 22 | std::string getvar(std::string var); 23 | bool checkblack(); 24 | void upgrade(std::string username, std::string key); 25 | void login(std::string username, std::string password); 26 | void web_login(); 27 | void button(std::string value); 28 | std::vector download(std::string fileid); 29 | void regstr(std::string username, std::string password, std::string key); 30 | 31 | class data_class { 32 | public: 33 | // app data 34 | std::string numUsers; 35 | std::string numOnlineUsers; 36 | std::string numKeys; 37 | std::string version; 38 | std::string customerPanelLink; 39 | // user data 40 | std::string username; 41 | std::string ip; 42 | std::string hwid; 43 | std::string createdate; 44 | std::string lastlogin; 45 | std::vector subscriptions; 46 | std::string expiry; 47 | // response data 48 | bool success; 49 | std::string message; 50 | }; 51 | data_class data; 52 | 53 | private: 54 | std::string sessionid, enckey; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /protection/lazy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright 2018-2020 Justas Masiulis 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // documentation is available at https://github.com/JustasMasiulis/lazy_importer 19 | 20 | #ifndef LAZY_IMPORTER_HPP 21 | #define LAZY_IMPORTER_HPP 22 | 23 | #define LI_FN(name) \ 24 | ::li::detail::lazy_function<::li::detail::khash(#name), decltype(&name)>() 25 | 26 | #define LI_FN_DEF(name) ::li::detail::lazy_function<::li::detail::khash(#name), name>() 27 | 28 | #define LI_MODULE(name) ::li::detail::lazy_module<::li::detail::khash(name)>() 29 | 30 | // NOTE only std::forward is used from this header. 31 | // If there is a need to eliminate this dependency the function itself is very small. 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #ifndef LAZY_IMPORTER_NO_FORCEINLINE 38 | #if defined(_MSC_VER) 39 | #define LAZY_IMPORTER_FORCEINLINE __forceinline 40 | #elif defined(__GNUC__) && __GNUC__ > 3 41 | #define LAZY_IMPORTER_FORCEINLINE inline __attribute__((__always_inline__)) 42 | #else 43 | #define LAZY_IMPORTER_FORCEINLINE inline 44 | #endif 45 | #else 46 | #define LAZY_IMPORTER_FORCEINLINE inline 47 | #endif 48 | 49 | #ifdef LAZY_IMPORTER_CASE_INSENSITIVE 50 | #define LAZY_IMPORTER_TOLOWER(c) (c >= 'A' && c <= 'Z' ? (c | (1 << 5)) : c) 51 | #else 52 | #define LAZY_IMPORTER_TOLOWER(c) (c) 53 | #endif 54 | 55 | namespace li { 56 | namespace detail { 57 | 58 | template 59 | struct pair { 60 | First first; 61 | Second second; 62 | }; 63 | 64 | namespace win { 65 | 66 | struct LIST_ENTRY_T { 67 | const char* Flink; 68 | const char* Blink; 69 | }; 70 | 71 | struct UNICODE_STRING_T { 72 | unsigned short Length; 73 | unsigned short MaximumLength; 74 | wchar_t* Buffer; 75 | }; 76 | 77 | struct PEB_LDR_DATA_T { 78 | unsigned long Length; 79 | unsigned long Initialized; 80 | const char* SsHandle; 81 | LIST_ENTRY_T InLoadOrderModuleList; 82 | }; 83 | 84 | struct PEB_T { 85 | unsigned char Reserved1[2]; 86 | unsigned char BeingDebugged; 87 | unsigned char Reserved2[1]; 88 | const char* Reserved3[2]; 89 | PEB_LDR_DATA_T* Ldr; 90 | }; 91 | 92 | struct LDR_DATA_TABLE_ENTRY_T { 93 | LIST_ENTRY_T InLoadOrderLinks; 94 | LIST_ENTRY_T InMemoryOrderLinks; 95 | LIST_ENTRY_T InInitializationOrderLinks; 96 | const char* DllBase; 97 | const char* EntryPoint; 98 | union { 99 | unsigned long SizeOfImage; 100 | const char* _dummy; 101 | }; 102 | UNICODE_STRING_T FullDllName; 103 | UNICODE_STRING_T BaseDllName; 104 | 105 | LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T* 106 | load_order_next() const noexcept 107 | { 108 | return reinterpret_cast( 109 | InLoadOrderLinks.Flink); 110 | } 111 | }; 112 | 113 | struct IMAGE_DOS_HEADER { // DOS .EXE header 114 | unsigned short e_magic; // Magic number 115 | unsigned short e_cblp; // Bytes on last page of file 116 | unsigned short e_cp; // Pages in file 117 | unsigned short e_crlc; // Relocations 118 | unsigned short e_cparhdr; // Size of header in paragraphs 119 | unsigned short e_minalloc; // Minimum extra paragraphs needed 120 | unsigned short e_maxalloc; // Maximum extra paragraphs needed 121 | unsigned short e_ss; // Initial (relative) SS value 122 | unsigned short e_sp; // Initial SP value 123 | unsigned short e_csum; // Checksum 124 | unsigned short e_ip; // Initial IP value 125 | unsigned short e_cs; // Initial (relative) CS value 126 | unsigned short e_lfarlc; // File address of relocation table 127 | unsigned short e_ovno; // Overlay number 128 | unsigned short e_res[4]; // Reserved words 129 | unsigned short e_oemid; // OEM identifier (for e_oeminfo) 130 | unsigned short e_oeminfo; // OEM information; e_oemid specific 131 | unsigned short e_res2[10]; // Reserved words 132 | long e_lfanew; // File address of new exe header 133 | }; 134 | 135 | struct IMAGE_FILE_HEADER { 136 | unsigned short Machine; 137 | unsigned short NumberOfSections; 138 | unsigned long TimeDateStamp; 139 | unsigned long PointerToSymbolTable; 140 | unsigned long NumberOfSymbols; 141 | unsigned short SizeOfOptionalHeader; 142 | unsigned short Characteristics; 143 | }; 144 | 145 | struct IMAGE_EXPORT_DIRECTORY { 146 | unsigned long Characteristics; 147 | unsigned long TimeDateStamp; 148 | unsigned short MajorVersion; 149 | unsigned short MinorVersion; 150 | unsigned long Name; 151 | unsigned long Base; 152 | unsigned long NumberOfFunctions; 153 | unsigned long NumberOfNames; 154 | unsigned long AddressOfFunctions; // RVA from base of image 155 | unsigned long AddressOfNames; // RVA from base of image 156 | unsigned long AddressOfNameOrdinals; // RVA from base of image 157 | }; 158 | 159 | struct IMAGE_DATA_DIRECTORY { 160 | unsigned long VirtualAddress; 161 | unsigned long Size; 162 | }; 163 | 164 | struct IMAGE_OPTIONAL_HEADER64 { 165 | unsigned short Magic; 166 | unsigned char MajorLinkerVersion; 167 | unsigned char MinorLinkerVersion; 168 | unsigned long SizeOfCode; 169 | unsigned long SizeOfInitializedData; 170 | unsigned long SizeOfUninitializedData; 171 | unsigned long AddressOfEntryPoint; 172 | unsigned long BaseOfCode; 173 | unsigned long long ImageBase; 174 | unsigned long SectionAlignment; 175 | unsigned long FileAlignment; 176 | unsigned short MajorOperatingSystemVersion; 177 | unsigned short MinorOperatingSystemVersion; 178 | unsigned short MajorImageVersion; 179 | unsigned short MinorImageVersion; 180 | unsigned short MajorSubsystemVersion; 181 | unsigned short MinorSubsystemVersion; 182 | unsigned long Win32VersionValue; 183 | unsigned long SizeOfImage; 184 | unsigned long SizeOfHeaders; 185 | unsigned long CheckSum; 186 | unsigned short Subsystem; 187 | unsigned short DllCharacteristics; 188 | unsigned long long SizeOfStackReserve; 189 | unsigned long long SizeOfStackCommit; 190 | unsigned long long SizeOfHeapReserve; 191 | unsigned long long SizeOfHeapCommit; 192 | unsigned long LoaderFlags; 193 | unsigned long NumberOfRvaAndSizes; 194 | IMAGE_DATA_DIRECTORY DataDirectory[16]; 195 | }; 196 | 197 | struct IMAGE_OPTIONAL_HEADER32 { 198 | unsigned short Magic; 199 | unsigned char MajorLinkerVersion; 200 | unsigned char MinorLinkerVersion; 201 | unsigned long SizeOfCode; 202 | unsigned long SizeOfInitializedData; 203 | unsigned long SizeOfUninitializedData; 204 | unsigned long AddressOfEntryPoint; 205 | unsigned long BaseOfCode; 206 | unsigned long BaseOfData; 207 | unsigned long ImageBase; 208 | unsigned long SectionAlignment; 209 | unsigned long FileAlignment; 210 | unsigned short MajorOperatingSystemVersion; 211 | unsigned short MinorOperatingSystemVersion; 212 | unsigned short MajorImageVersion; 213 | unsigned short MinorImageVersion; 214 | unsigned short MajorSubsystemVersion; 215 | unsigned short MinorSubsystemVersion; 216 | unsigned long Win32VersionValue; 217 | unsigned long SizeOfImage; 218 | unsigned long SizeOfHeaders; 219 | unsigned long CheckSum; 220 | unsigned short Subsystem; 221 | unsigned short DllCharacteristics; 222 | unsigned long SizeOfStackReserve; 223 | unsigned long SizeOfStackCommit; 224 | unsigned long SizeOfHeapReserve; 225 | unsigned long SizeOfHeapCommit; 226 | unsigned long LoaderFlags; 227 | unsigned long NumberOfRvaAndSizes; 228 | IMAGE_DATA_DIRECTORY DataDirectory[16]; 229 | }; 230 | 231 | struct IMAGE_NT_HEADERS { 232 | unsigned long Signature; 233 | IMAGE_FILE_HEADER FileHeader; 234 | #ifdef _WIN64 235 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 236 | #else 237 | IMAGE_OPTIONAL_HEADER32 OptionalHeader; 238 | #endif 239 | }; 240 | 241 | } // namespace win 242 | 243 | // hashing stuff 244 | struct hash_t { 245 | using value_type = unsigned long; 246 | constexpr static value_type offset = 2166136261; 247 | constexpr static value_type prime = 16777619; 248 | constexpr static unsigned long long prime64 = prime; 249 | 250 | LAZY_IMPORTER_FORCEINLINE constexpr static value_type single(value_type value, 251 | char c) noexcept 252 | { 253 | return static_cast( 254 | (value ^ LAZY_IMPORTER_TOLOWER(c)) * 255 | static_cast(prime)); 256 | } 257 | }; 258 | 259 | template 260 | LAZY_IMPORTER_FORCEINLINE constexpr hash_t::value_type 261 | khash(const CharT* str, hash_t::value_type value = hash_t::offset) noexcept 262 | { 263 | return (*str ? khash(str + 1, hash_t::single(value, *str)) : value); 264 | } 265 | 266 | template 267 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(const CharT* str) noexcept 268 | { 269 | hash_t::value_type value = hash_t::offset; 270 | 271 | for (;;) { 272 | char c = *str++; 273 | if (!c) 274 | return value; 275 | value = hash_t::single(value, c); 276 | } 277 | } 278 | 279 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash( 280 | const win::UNICODE_STRING_T& str) noexcept 281 | { 282 | auto first = str.Buffer; 283 | const auto last = first + (str.Length / sizeof(wchar_t)); 284 | auto value = hash_t::offset; 285 | for (; first != last; ++first) 286 | value = hash_t::single(value, static_cast(*first)); 287 | 288 | return value; 289 | } 290 | 291 | LAZY_IMPORTER_FORCEINLINE pair hash_forwarded( 292 | const char* str) noexcept 293 | { 294 | pair module_and_function{ 295 | hash_t::offset, hash_t::offset 296 | }; 297 | 298 | for (; *str != '.'; ++str) 299 | module_and_function.first = hash_t::single(module_and_function.first, *str); 300 | 301 | ++str; 302 | 303 | for (; *str; ++str) 304 | module_and_function.second = hash_t::single(module_and_function.second, *str); 305 | 306 | return module_and_function; 307 | } 308 | 309 | 310 | // some helper functions 311 | LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept 312 | { 313 | #if defined(_M_X64) || defined(__amd64__) 314 | return reinterpret_cast(__readgsqword(0x60)); 315 | #elif defined(_M_IX86) || defined(__i386__) 316 | return reinterpret_cast(__readfsdword(0x30)); 317 | #elif defined(_M_ARM) || defined(__arm__) 318 | return *reinterpret_cast(_MoveFromCoprocessor(15, 0, 13, 0, 2) + 0x30); 319 | #elif defined(_M_ARM64) || defined(__aarch64__) 320 | return *reinterpret_cast(__getReg(18) + 0x60); 321 | #elif defined(_M_IA64) || defined(__ia64__) 322 | return *reinterpret_cast(static_cast(_rdteb()) + 0x60); 323 | #else 324 | #error Unsupported platform. Open an issue and I'll probably add support. 325 | #endif 326 | } 327 | 328 | LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr() 329 | { 330 | return reinterpret_cast(peb()->Ldr); 331 | } 332 | 333 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers( 334 | const char* base) noexcept 335 | { 336 | return reinterpret_cast( 337 | base + reinterpret_cast(base)->e_lfanew); 338 | } 339 | 340 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir( 341 | const char* base) noexcept 342 | { 343 | return reinterpret_cast( 344 | base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress); 345 | } 346 | 347 | LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept 348 | { 349 | return reinterpret_cast( 350 | ldr()->InLoadOrderModuleList.Flink); 351 | } 352 | 353 | struct exports_directory { 354 | const char* _base; 355 | const win::IMAGE_EXPORT_DIRECTORY* _ied; 356 | unsigned long _ied_size; 357 | 358 | public: 359 | using size_type = unsigned long; 360 | 361 | LAZY_IMPORTER_FORCEINLINE 362 | exports_directory(const char* base) noexcept : _base(base) 363 | { 364 | const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0]; 365 | _ied = reinterpret_cast( 366 | base + ied_data_dir.VirtualAddress); 367 | _ied_size = ied_data_dir.Size; 368 | } 369 | 370 | LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept 371 | { 372 | return reinterpret_cast(_ied) != _base; 373 | } 374 | 375 | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept 376 | { 377 | return _ied->NumberOfNames; 378 | } 379 | 380 | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; } 381 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept 382 | { 383 | return _ied; 384 | } 385 | 386 | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept 387 | { 388 | return reinterpret_cast( 389 | _base + reinterpret_cast( 390 | _base + _ied->AddressOfNames)[index]); 391 | } 392 | 393 | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept 394 | { 395 | const auto* const rva_table = 396 | reinterpret_cast(_base + _ied->AddressOfFunctions); 397 | 398 | const auto* const ord_table = reinterpret_cast( 399 | _base + _ied->AddressOfNameOrdinals); 400 | 401 | return _base + rva_table[ord_table[index]]; 402 | } 403 | 404 | LAZY_IMPORTER_FORCEINLINE bool is_forwarded( 405 | const char* export_address) const noexcept 406 | { 407 | const auto ui_ied = reinterpret_cast(_ied); 408 | return (export_address > ui_ied && export_address < ui_ied + _ied_size); 409 | } 410 | }; 411 | 412 | struct safe_module_enumerator { 413 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T; 414 | value_type* value; 415 | value_type* head; 416 | 417 | LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept 418 | : safe_module_enumerator(ldr_data_entry()) 419 | {} 420 | 421 | LAZY_IMPORTER_FORCEINLINE 422 | safe_module_enumerator(const detail::win::LDR_DATA_TABLE_ENTRY_T* ldr) noexcept 423 | : value(ldr->load_order_next()), head(value) 424 | {} 425 | 426 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept 427 | { 428 | value = head->load_order_next(); 429 | } 430 | 431 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept 432 | { 433 | value = value->load_order_next(); 434 | 435 | return value != head && value->DllBase; 436 | } 437 | }; 438 | 439 | struct unsafe_module_enumerator { 440 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*; 441 | value_type value; 442 | 443 | LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept 444 | : value(ldr_data_entry()) 445 | {} 446 | 447 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); } 448 | 449 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept 450 | { 451 | value = value->load_order_next(); 452 | return true; 453 | } 454 | }; 455 | 456 | // provides the cached functions which use Derive classes methods 457 | template 458 | class lazy_base { 459 | protected: 460 | // This function is needed because every templated function 461 | // with different args has its own static buffer 462 | LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept 463 | { 464 | static void* value = nullptr; 465 | return value; 466 | } 467 | 468 | public: 469 | template 470 | LAZY_IMPORTER_FORCEINLINE static T safe() noexcept 471 | { 472 | return Derived::template get(); 473 | } 474 | 475 | template 476 | LAZY_IMPORTER_FORCEINLINE static T cached() noexcept 477 | { 478 | auto& cached = _cache(); 479 | if (!cached) 480 | cached = Derived::template get(); 481 | 482 | return (T)(cached); 483 | } 484 | 485 | template 486 | LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept 487 | { 488 | return cached(); 489 | } 490 | }; 491 | 492 | template 493 | struct lazy_module : lazy_base> { 494 | template 495 | LAZY_IMPORTER_FORCEINLINE static T get() noexcept 496 | { 497 | Enum e; 498 | do { 499 | if (hash(e.value->BaseDllName) == Hash) 500 | return (T)(e.value->DllBase); 501 | } while (e.next()); 502 | return {}; 503 | } 504 | 505 | template 506 | LAZY_IMPORTER_FORCEINLINE static T in(Ldr ldr) noexcept 507 | { 508 | safe_module_enumerator e((const detail::win::LDR_DATA_TABLE_ENTRY_T*)(ldr)); 509 | do { 510 | if (hash(e.value->BaseDllName) == Hash) 511 | return (T)(e.value->DllBase); 512 | } while (e.next()); 513 | return {}; 514 | } 515 | 516 | template 517 | LAZY_IMPORTER_FORCEINLINE static T in_cached(Ldr ldr) noexcept 518 | { 519 | auto& cached = lazy_base>::_cache(); 520 | if (!cached) 521 | cached = in(ldr); 522 | 523 | return (T)(cached); 524 | } 525 | }; 526 | 527 | template 528 | struct lazy_function : lazy_base, T> { 529 | using base_type = lazy_base, T>; 530 | 531 | template 532 | LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const 533 | { 534 | #ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS 535 | return get()(std::forward(args)...); 536 | #else 537 | return this->cached()(std::forward(args)...); 538 | #endif 539 | } 540 | 541 | template 542 | LAZY_IMPORTER_FORCEINLINE static F get() noexcept 543 | { 544 | // for backwards compatability. 545 | // Before 2.0 it was only possible to resolve forwarded exports when 546 | // this macro was enabled 547 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS 548 | return forwarded(); 549 | #else 550 | 551 | Enum e; 552 | 553 | do { 554 | #ifdef LAZY_IMPORTER_HARDENED_MODULE_CHECKS 555 | if (!e.value->DllBase || !e.value->FullDllName.Length) 556 | continue; 557 | #endif 558 | 559 | const exports_directory exports(e.value->DllBase); 560 | 561 | if (exports) { 562 | auto export_index = exports.size(); 563 | while (export_index--) 564 | if (hash(exports.name(export_index)) == Hash) 565 | return (F)(exports.address(export_index)); 566 | } 567 | } while (e.next()); 568 | return {}; 569 | #endif 570 | } 571 | 572 | template 573 | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept 574 | { 575 | detail::win::UNICODE_STRING_T name; 576 | hash_t::value_type module_hash = 0; 577 | auto function_hash = Hash; 578 | 579 | Enum e; 580 | do { 581 | name = e.value->BaseDllName; 582 | name.Length -= 8; // get rid of .dll extension 583 | 584 | if (!module_hash || hash(name) == module_hash) { 585 | const exports_directory exports(e.value->DllBase); 586 | 587 | if (exports) { 588 | auto export_index = exports.size(); 589 | while (export_index--) 590 | if (hash(exports.name(export_index)) == function_hash) { 591 | const auto addr = exports.address(export_index); 592 | 593 | if (exports.is_forwarded(addr)) { 594 | auto hashes = hash_forwarded( 595 | reinterpret_cast(addr)); 596 | 597 | function_hash = hashes.second; 598 | module_hash = hashes.first; 599 | 600 | e.reset(); 601 | break; 602 | } 603 | return (F)(addr); 604 | } 605 | } 606 | } 607 | } while (e.next()); 608 | return {}; 609 | } 610 | 611 | template 612 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept 613 | { 614 | return forwarded(); 615 | } 616 | 617 | template 618 | LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept 619 | { 620 | auto& value = base_type::_cache(); 621 | if (!value) 622 | value = forwarded(); 623 | return (F)(value); 624 | } 625 | 626 | template 627 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept 628 | { 629 | return forwarded_cached(); 630 | } 631 | 632 | template 633 | LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept 634 | { 635 | if (IsSafe && !m) 636 | return {}; 637 | 638 | const exports_directory exports((const char*)(m)); 639 | if (IsSafe && !exports) 640 | return {}; 641 | 642 | for (unsigned long i{};; ++i) { 643 | if (IsSafe && i == exports.size()) 644 | break; 645 | 646 | if (hash(exports.name(i)) == Hash) 647 | return (F)(exports.address(i)); 648 | } 649 | return {}; 650 | } 651 | 652 | template 653 | LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept 654 | { 655 | return in(m); 656 | } 657 | 658 | template 659 | LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept 660 | { 661 | auto& value = base_type::_cache(); 662 | if (!value) 663 | value = in(m); 664 | return (F)(value); 665 | } 666 | 667 | template 668 | LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept 669 | { 670 | return in_cached(m); 671 | } 672 | 673 | template 674 | LAZY_IMPORTER_FORCEINLINE static F nt() noexcept 675 | { 676 | return in(ldr_data_entry()->load_order_next()->DllBase); 677 | } 678 | 679 | template 680 | LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept 681 | { 682 | return in_safe(ldr_data_entry()->load_order_next()->DllBase); 683 | } 684 | 685 | template 686 | LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept 687 | { 688 | return in_cached(ldr_data_entry()->load_order_next()->DllBase); 689 | } 690 | 691 | template 692 | LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept 693 | { 694 | return in_safe_cached(ldr_data_entry()->load_order_next()->DllBase); 695 | } 696 | }; 697 | 698 | } 699 | } // namespace li::detail 700 | 701 | #endif // include guard -------------------------------------------------------------------------------- /protection/protection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "lazy.h" 5 | #include "skStr.h" 6 | 7 | inline bool hide_thread(HANDLE thread) 8 | { 9 | typedef NTSTATUS(NTAPI* pNtSetInformationThread)(HANDLE, UINT, PVOID, ULONG); 10 | NTSTATUS Status; 11 | 12 | pNtSetInformationThread NtSIT = (pNtSetInformationThread)LI_FN(GetProcAddress).forwarded_safe_cached()((LI_FN(GetModuleHandleA).forwarded_safe_cached())(skCrypt("ntdll.dll")), skCrypt("NtSetInformationThread")); 13 | 14 | if (NtSIT == NULL) return false; 15 | if (thread == NULL) 16 | Status = NtSIT(LI_FN(GetCurrentThread).forwarded_safe_cached(), 0x11, 0, 0); 17 | else 18 | Status = NtSIT(thread, 0x11, 0, 0); 19 | 20 | if (Status != 0x00000000) 21 | return false; 22 | else 23 | return true; 24 | } 25 | 26 | inline int thread_context() // we look for debuggers hiding in the thread context :sus: 27 | { 28 | int found = false; 29 | CONTEXT ctx = { 0 }; 30 | void* h_thread = LI_FN(GetCurrentThread).forwarded_safe_cached(); 31 | 32 | ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; 33 | if (LI_FN(GetThreadContext).forwarded_safe_cached()(h_thread, &ctx)) 34 | { 35 | if ((ctx.Dr0 != 0x00) || (ctx.Dr1 != 0x00) || (ctx.Dr2 != 0x00) || (ctx.Dr3 != 0x00) || (ctx.Dr6 != 0x00) || (ctx.Dr7 != 0x00)) 36 | { 37 | found = true; 38 | } 39 | } 40 | 41 | return found; 42 | } 43 | 44 | inline int remote_is_present() 45 | { 46 | int debugger_present = false; 47 | 48 | LI_FN(CheckRemoteDebuggerPresent).forwarded_safe_cached()(LI_FN(GetCurrentProcess).forwarded_safe_cached()(), &debugger_present); // very interesting method of doing this? possible 49 | 50 | return debugger_present; 51 | } 52 | 53 | int is_debugger_present() 54 | { 55 | return LI_FN(IsDebuggerPresent).forwarded_safe_cached()(); // i am very well aware i couldve just called this in the thread, but this looks better imo & has the same performance 56 | } 57 | 58 | inline bool debug_perms_check() // check if the program has debug permissions, if it does then it returns true 59 | { 60 | PCONTEXT ctx = PCONTEXT(LI_FN(VirtualAlloc).forwarded_safe_cached()(NULL, sizeof(ctx), MEM_COMMIT, PAGE_READWRITE)); 61 | RtlSecureZeroMemory(ctx, sizeof(CONTEXT)); 62 | 63 | ctx->ContextFlags = CONTEXT_DEBUG_REGISTERS; 64 | 65 | if (LI_FN(GetThreadContext).forwarded_safe_cached()(LI_FN(GetCurrentThread).forwarded_safe_cached()(), ctx) == 0) 66 | return -1; 67 | 68 | 69 | if (ctx->Dr0 != 0 || ctx->Dr1 != 0 || ctx->Dr2 != 0 || ctx->Dr3 != 0) 70 | return TRUE; 71 | else 72 | return FALSE; 73 | } 74 | 75 | void Protection_Loop() 76 | { 77 | hide_thread(LI_FN(GetCurrentThread).forwarded_safe_cached()); 78 | if (thread_context()) *(uintptr_t*)(0) = 1; 79 | if (remote_is_present()) *(uintptr_t*)(0) = 1; 80 | if (is_debugger_present()) *(uintptr_t*)(0) = 1; 81 | if (debug_perms_check()) *(uintptr_t*)(0) = 1; 82 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); // increase / decrease depending on how your computer handles it 83 | } 84 | -------------------------------------------------------------------------------- /protection/skStr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*____________________________________________________________________________________________________________ 4 | 5 | Original Author: skadro 6 | Github: https://github.com/skadro-official 7 | License: See end of file 8 | 9 | skCrypter 10 | Compile-time, Usermode + Kernelmode, safe and lightweight string crypter library for C++11+ 11 | 12 | *Not removing this part is appreciated* 13 | ____________________________________________________________________________________________________________*/ 14 | 15 | #ifdef _KERNEL_MODE 16 | namespace std 17 | { 18 | // STRUCT TEMPLATE remove_reference 19 | template 20 | struct remove_reference { 21 | using type = _Ty; 22 | }; 23 | 24 | template 25 | struct remove_reference<_Ty&> { 26 | using type = _Ty; 27 | }; 28 | 29 | template 30 | struct remove_reference<_Ty&&> { 31 | using type = _Ty; 32 | }; 33 | 34 | template 35 | using remove_reference_t = typename remove_reference<_Ty>::type; 36 | 37 | // STRUCT TEMPLATE remove_const 38 | template 39 | struct remove_const { // remove top-level const qualifier 40 | using type = _Ty; 41 | }; 42 | 43 | template 44 | struct remove_const { 45 | using type = _Ty; 46 | }; 47 | 48 | template 49 | using remove_const_t = typename remove_const<_Ty>::type; 50 | } 51 | #else 52 | #include 53 | #endif 54 | 55 | namespace skc 56 | { 57 | template 58 | using clean_type = typename std::remove_const_t>; 59 | 60 | template 61 | class skCrypter 62 | { 63 | public: 64 | __forceinline constexpr skCrypter(T* data) 65 | { 66 | crypt(data); 67 | } 68 | 69 | __forceinline T* get() 70 | { 71 | return _storage; 72 | } 73 | 74 | __forceinline int size() // (w)char count 75 | { 76 | return _size; 77 | } 78 | 79 | __forceinline char key() 80 | { 81 | return _key1; 82 | } 83 | 84 | __forceinline T* encrypt() 85 | { 86 | if (!isEncrypted()) 87 | crypt(_storage); 88 | 89 | return _storage; 90 | } 91 | 92 | __forceinline T* decrypt() 93 | { 94 | if (isEncrypted()) 95 | crypt(_storage); 96 | 97 | return _storage; 98 | } 99 | 100 | __forceinline bool isEncrypted() 101 | { 102 | return _storage[_size - 1] != 0; 103 | } 104 | 105 | __forceinline void clear() // set full storage to 0 106 | { 107 | for (int i = 0; i < _size; i++) 108 | { 109 | _storage[i] = 0; 110 | } 111 | } 112 | 113 | __forceinline operator T* () 114 | { 115 | decrypt(); 116 | 117 | return _storage; 118 | } 119 | 120 | private: 121 | __forceinline constexpr void crypt(T* data) 122 | { 123 | for (int i = 0; i < _size; i++) 124 | { 125 | _storage[i] = data[i] ^ (_key1 + i % (1 + _key2)); 126 | } 127 | } 128 | 129 | T _storage[_size]{}; 130 | }; 131 | } 132 | 133 | #define skCrypt(str) skCrypt_key(str, __TIME__[4], __TIME__[7]) 134 | #define skCrypt_key(str, key1, key2) []() { \ 135 | constexpr static auto crypted = skc::skCrypter \ 136 | >((skc::clean_type*)str); \ 137 | return crypted; }() 138 | 139 | /*________________________________________________________________________________ 140 | 141 | MIT License 142 | 143 | Copyright (c) 2020 skadro 144 | 145 | Permission is hereby granted, free of charge, to any person obtaining a copy 146 | of this software and associated documentation files (the "Software"), to deal 147 | in the Software without restriction, including without limitation the rights 148 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 149 | copies of the Software, and to permit persons to whom the Software is 150 | furnished to do so, subject to the following conditions: 151 | 152 | The above copyright notice and this permission notice shall be included in all 153 | copies or substantial portions of the Software. 154 | 155 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 157 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 158 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 159 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 160 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 161 | SOFTWARE. 162 | 163 | ________________________________________________________________________________*/ --------------------------------------------------------------------------------