├── LICENSE ├── ManualMap ├── Map.cpp └── Map.hpp ├── README.md ├── Security ├── LazyImporter.hpp ├── Security.cpp └── Security.hpp ├── UserInterface ├── Fonts │ ├── Font.h │ ├── Icons.h │ └── SecondFont.h ├── 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_widgets.cpp │ ├── imstb_rectpack.h │ ├── imstb_textedit.h │ ├── imstb_truetype.h │ └── stringimgui.h ├── UserInterface.cpp └── UserInterface.hpp ├── Utils ├── FileReader.cpp ├── FileReader.hpp └── Utils.hpp ├── auth └── Auth.hpp ├── includes.hpp ├── loader-ui.sln ├── loader-ui.vcxproj ├── loader-ui.vcxproj.user ├── main.cpp └── xorstr.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jacob Gluska/UntitledEntity 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ManualMap/Map.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Map.hpp" 3 | #include "../includes.hpp" 4 | 5 | void __stdcall Shellcode(MANUAL_MAPPING_DATA* pData); 6 | 7 | bool ManualMap(HANDLE hProc, std::uint8_t* szDllFile) 8 | { 9 | BYTE* pSourceData = nullptr; 10 | IMAGE_NT_HEADERS* pOldNtHeader = nullptr; 11 | IMAGE_OPTIONAL_HEADER* pOldOptionalHeader = nullptr; 12 | IMAGE_FILE_HEADER* pOldFileHeader = nullptr; 13 | BYTE* pTargetBase = nullptr; 14 | 15 | //We are at the end of the file, so we know the size already. 16 | auto FileSize = sizeof(szDllFile); 17 | //Let's get the byte array of the file. 18 | pSourceData = (BYTE*)szDllFile; 19 | //If we couldn't allocate memory for this data we failed 20 | if (!pSourceData) 21 | { 22 | return false; 23 | } 24 | 25 | if (reinterpret_cast(pSourceData)->e_magic != 0x5A4D) 26 | { 27 | delete[] pSourceData; 28 | return false; 29 | } 30 | //Save the old NT Header 31 | pOldNtHeader = reinterpret_cast(pSourceData + reinterpret_cast(pSourceData)->e_lfanew); 32 | //Save the old optional header 33 | pOldOptionalHeader = &pOldNtHeader->OptionalHeader; 34 | //Save the old file header 35 | pOldFileHeader = &pOldNtHeader->FileHeader; 36 | //Handle X86 and X64 37 | #ifdef _WIN64 38 | //If the machine type is not the current file type we fail 39 | if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_AMD64) 40 | { 41 | delete[] pSourceData; 42 | return false; 43 | } 44 | #else 45 | //If the machine type is not the current file type we fail 46 | if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_I386) 47 | { 48 | delete[] pSourceData; 49 | return false; 50 | } 51 | #endif 52 | //Get the target base address to allocate memory in the target process 53 | //Try to load at image base of the old optional header, the size of the optional header image, commit = make , reserve it, execute read write to write the memory 54 | pTargetBase = reinterpret_cast(LI_FN(VirtualAllocEx).Get()(hProc, reinterpret_cast(pOldOptionalHeader->ImageBase), pOldOptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); 55 | if (!pTargetBase) 56 | { 57 | //We can't allocate it, lets initialize it instead? 58 | //Forget the image base, just use nullptr, if this fails we cannot allocate memory in the target process. 59 | pTargetBase = reinterpret_cast(LI_FN(VirtualAllocEx).Get()(hProc, nullptr, pOldOptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); 60 | if (!pTargetBase) 61 | { 62 | delete[] pSourceData; 63 | return false; 64 | } 65 | } 66 | //Declare data to map 67 | MANUAL_MAPPING_DATA data{ 0 }; 68 | //Declare function prototype 69 | data.pLoadLibraryA = LI_FN(LoadLibraryA).Get(); 70 | //Declare function prototype 71 | data.pGetProcAddress = reinterpret_cast(LI_FN(GetProcAddress).Get()); 72 | 73 | //Get the section header 74 | auto* pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader); 75 | //Loop the file header sections for section data, we only care about the raw data in here, it contains other data that is used after runtime which we dont care about. 76 | for (UINT i = 0; i != pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader) 77 | { 78 | //If it's raw data 79 | if (pSectionHeader->SizeOfRawData) 80 | { 81 | //Try to write our source data into the process, mapping. 82 | if (!LI_FN(WriteProcessMemory).Get()(hProc, pTargetBase + pSectionHeader->VirtualAddress, pSourceData + pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData, nullptr)) 83 | { 84 | //We couldn't allocate memory 85 | // printf("Failed to allocate memory: 0x%x\n", GetLastError()); 86 | delete[] pSourceData; 87 | VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE); 88 | return false; 89 | } 90 | } 91 | } 92 | 93 | LI_FN(memcpy)(pSourceData, &data, sizeof(data)); 94 | LI_FN(WriteProcessMemory)(hProc, pTargetBase, pSourceData, 0x1000, nullptr); 95 | 96 | void* pShellcode = LI_FN(VirtualAllocEx).Get()(hProc, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 97 | if (!pShellcode) 98 | { 99 | //printf("Memory allocation failed (1) (ex) 0x%X\n", GetLastError()); 100 | LI_FN(VirtualFreeEx)(hProc, pTargetBase, 0, MEM_RELEASE); 101 | return false; 102 | } 103 | 104 | LI_FN(WriteProcessMemory).Get()(hProc, pShellcode, Shellcode, 0x1000, nullptr); 105 | 106 | HANDLE hThread = LI_FN(CreateRemoteThread).Get()(hProc, nullptr, 0, reinterpret_cast(pShellcode), pTargetBase, 0, nullptr); 107 | if (!hThread) 108 | { 109 | // printf("Thread creation failed 0x%X\n", GetLastError()); 110 | LI_FN(VirtualFreeEx).Get()(hProc, pTargetBase, 0, MEM_RELEASE); 111 | LI_FN(VirtualFreeEx).Get()(hProc, pShellcode, 0, MEM_RELEASE); 112 | return false; 113 | } 114 | 115 | LI_FN(CloseHandle)(hThread); 116 | 117 | HINSTANCE hCheck = NULL; 118 | while (!hCheck) 119 | { 120 | MANUAL_MAPPING_DATA data_checked{ 0 }; 121 | LI_FN(ReadProcessMemory)(hProc, pTargetBase, &data_checked, sizeof(data_checked), nullptr); 122 | hCheck = data_checked.hMod; 123 | LI_FN(Sleep)(10); 124 | } 125 | 126 | LI_FN(VirtualFreeEx)(hProc, pShellcode, 0, MEM_RELEASE); 127 | 128 | return true; 129 | } 130 | 131 | #define RELOC_FLAG32(RelInfo) ((RelInfo >> 0x0C) == IMAGE_REL_BASED_HIGHLOW) 132 | #define RELOC_FLAG64(RelInfo) ((RelInfo >> 0x0C) == IMAGE_REL_BASED_DIR64) 133 | 134 | #ifdef _WIN64 135 | #define RELOC_FLAG RELOC_FLAG64 136 | #else 137 | #define RELOC_FLAG RELOC_FLAG32 138 | #endif 139 | 140 | void __stdcall Shellcode(MANUAL_MAPPING_DATA* pData) 141 | { 142 | if (!pData) 143 | return; 144 | //Process base 145 | BYTE* pBase = reinterpret_cast(pData); 146 | //Optional data 147 | auto* pOptionalHeader = &reinterpret_cast(pBase + reinterpret_cast(pData)->e_lfanew)->OptionalHeader; 148 | 149 | auto _LoadLibraryA = pData->pLoadLibraryA; 150 | auto _GetProcAddress = pData->pGetProcAddress; 151 | auto _DllMain = reinterpret_cast(pBase + pOptionalHeader->AddressOfEntryPoint); 152 | 153 | BYTE* LocationDelta = pBase - pOptionalHeader->ImageBase; 154 | if (LocationDelta) 155 | { 156 | if (!pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) 157 | return; 158 | 159 | auto* pRelocData = reinterpret_cast(pBase + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 160 | while (pRelocData->VirtualAddress) 161 | { 162 | UINT AmountOfEntries = (pRelocData->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); 163 | WORD* pRelativeInfo = reinterpret_cast(pRelocData + 1); 164 | 165 | for (UINT i = 0; i != AmountOfEntries; ++i, ++pRelativeInfo) 166 | { 167 | if (RELOC_FLAG(*pRelativeInfo)) 168 | { 169 | UINT_PTR* pPatch = reinterpret_cast(pBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF)); 170 | *pPatch += reinterpret_cast(LocationDelta); 171 | } 172 | } 173 | pRelocData = reinterpret_cast(reinterpret_cast(pRelocData) + pRelocData->SizeOfBlock); 174 | } 175 | } 176 | 177 | if (pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) 178 | { 179 | auto* pImportDescr = reinterpret_cast(pBase + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 180 | while (pImportDescr->Name) 181 | { 182 | char* szMod = reinterpret_cast(pBase + pImportDescr->Name); 183 | HINSTANCE hDll = _LoadLibraryA(szMod); 184 | 185 | ULONG_PTR* pThunkRef = reinterpret_cast(pBase + pImportDescr->OriginalFirstThunk); 186 | ULONG_PTR* pFuncRef = reinterpret_cast(pBase + pImportDescr->FirstThunk); 187 | 188 | if (!pThunkRef) 189 | pThunkRef = pFuncRef; 190 | 191 | for (; *pThunkRef; ++pThunkRef, ++pFuncRef) 192 | { 193 | if (IMAGE_SNAP_BY_ORDINAL(*pThunkRef)) 194 | { 195 | *pFuncRef = _GetProcAddress(hDll, reinterpret_cast(*pThunkRef & 0xFFFF)); 196 | } 197 | else 198 | { 199 | auto* pImport = reinterpret_cast(pBase + (*pThunkRef)); 200 | *pFuncRef = _GetProcAddress(hDll, pImport->Name); 201 | } 202 | } 203 | ++pImportDescr; 204 | } 205 | } 206 | 207 | if (pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) 208 | { 209 | auto* pTLS = reinterpret_cast(pBase + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); 210 | auto* pCallback = reinterpret_cast(pTLS->AddressOfCallBacks); 211 | for (; pCallback && *pCallback; ++pCallback) 212 | (*pCallback)(pBase, DLL_PROCESS_ATTACH, nullptr); 213 | } 214 | //Execute dll main 215 | _DllMain(pBase, DLL_PROCESS_ATTACH, nullptr); 216 | 217 | pData->hMod = reinterpret_cast(pBase); 218 | } -------------------------------------------------------------------------------- /ManualMap/Map.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using f_LoadLibraryA = HINSTANCE(WINAPI*)(const char* lpLibFilename); 9 | using f_GetProcAddress = UINT_PTR(WINAPI*)(HINSTANCE hModule, const char* lpProcName); 10 | using f_DLL_ENTRY_POINT = BOOL(WINAPI*)(void* hDll, DWORD dwReason, void* pReserved); 11 | 12 | struct MANUAL_MAPPING_DATA 13 | { 14 | f_LoadLibraryA pLoadLibraryA; 15 | f_GetProcAddress pGetProcAddress; 16 | HINSTANCE hMod; 17 | }; 18 | 19 | bool ManualMap(HANDLE hProc, std::uint8_t* szDllFile); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## P2C-Client 2 | 3 | [![C++](https://img.shields.io/badge/language-C%2B%2B-%23f34b7d.svg?style=plastic)](https://en.wikipedia.org/wiki/C%2B%2B) 4 | [![Windows](https://img.shields.io/badge/platform-Windows-0078d7.svg?style=plastic)](https://en.wikipedia.org/wiki/Microsoft_Windows) 5 | [![x86](https://img.shields.io/badge/arch-x86-red.svg?style=plastic)](https://en.wikipedia.org/wiki/X86) 6 | 7 | Open-source P2C Loader designed for CS:GO, Built around [KeyAuth](https://keyauth.win/). Uses the [Themida](https://www.oreans.com/Themida.php) SDK. 8 | 9 | ## Dependencies 10 | 11 | - [Dear imgui](https://github.com/ocornut/imgui). 12 | - [cryptoPP](https://github.com/weidai11/cryptopp). 13 | - [curl](https://github.com/curl/curl) 14 | - [json](https://github.com/nlohmann/json) 15 | - [openssl](https://github.com/openssl/openssl) 16 | 17 | ## Instructions 18 | 19 | Download the dependencies [here](https://files.catbox.moe/qtx3kt.zip)
20 | Place them into the main directory (along with all the other folders)
21 | Extract them, then rename the folder to "Dependencies"
22 | 23 | Change your keyauth credentials [here](https://github.com/UntitledEntity/P2C-Client/blob/main/UserInterface/UserInterface.cpp#L5)
24 | Add your file IDs [here](https://github.com/UntitledEntity/P2C-Client/blob/main/auth/Auth.hpp#L457) and [here](https://github.com/UntitledEntity/P2C-Client/blob/main/auth/Auth.hpp#L486) 25 | 26 | ## FAQ 27 | 28 | ### Help 29 | I will not help with any errors as after the dependencies are extracted, and the directories are fixed, the solution will build with no errors. Apoligies. 30 | 31 | ## License 32 | 33 | > Copyright (c) 2022 Jacob Gluska/UntitledEntity 34 | 35 | This project is licensed under the [MIT License](https://opensource.org/licenses/mit-license.php) - see the [LICENSE](https://github.com/UntitledEntity/P2C-Client/blob/main/LICENSE) file for details. 36 | -------------------------------------------------------------------------------- /Security/LazyImporter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Justas Masiulis 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // documentation is available at https://github.com/JustasMasiulis/lazy_importer 18 | 19 | #ifndef LAZY_IMPORTER_HPP 20 | #define LAZY_IMPORTER_HPP 21 | 22 | #define LI_FN(name) \ 23 | ::li::detail::lazy_function<::li::detail::khash(#name), decltype(&name)>() 24 | 25 | #define LI_FN_DEF(name) ::li::detail::lazy_function<::li::detail::khash(#name), name>() 26 | 27 | #define LI_MODULE(name) ::li::detail::lazy_module<::li::detail::khash(name)>() 28 | 29 | // NOTE only std::forward is used from this header. 30 | // If there is a need to eliminate this dependency the function itself is very small. 31 | #include 32 | #include 33 | #include 34 | 35 | #ifndef LAZY_IMPORTER_NO_FORCEINLINE 36 | #if defined(_MSC_VER) 37 | #define LAZY_IMPORTER_FORCEINLINE __forceinline 38 | #elif defined(__GNUC__) && __GNUC__ > 3 39 | #define LAZY_IMPORTER_FORCEINLINE inline __attribute_STR((__always_inline__)) 40 | #else 41 | #define LAZY_IMPORTER_FORCEINLINE inline 42 | #endif 43 | #else 44 | #define LAZY_IMPORTER_FORCEINLINE inline 45 | #endif 46 | 47 | #ifdef LAZY_IMPORTER_CASE_INSENSITIVE 48 | #define LAZY_IMPORTER_TOLOWER(c) (c >= 'A' && c <= 'Z' ? (c | (1 << 5)) : c) 49 | #else 50 | #define LAZY_IMPORTER_TOLOWER(c) (c) 51 | #endif 52 | 53 | namespace li { 54 | namespace detail { 55 | 56 | template 57 | struct pair { 58 | First first; 59 | Second second; 60 | }; 61 | 62 | namespace win { 63 | 64 | struct LIST_ENTRY_T { 65 | const char* Flink; 66 | const char* Blink; 67 | }; 68 | 69 | struct UNICODE_STRING_T { 70 | unsigned short Length; 71 | unsigned short MaximumLength; 72 | wchar_t* Buffer; 73 | }; 74 | 75 | struct PEB_LDR_DATA_T { 76 | unsigned long Length; 77 | unsigned long Initialized; 78 | const char* SsHandle; 79 | LIST_ENTRY_T InLoadOrderModuleList; 80 | }; 81 | 82 | struct PEB_T { 83 | unsigned char Reserved1[2]; 84 | unsigned char BeingDebugged; 85 | unsigned char Reserved2[1]; 86 | const char* Reserved3[2]; 87 | PEB_LDR_DATA_T* Ldr; 88 | }; 89 | 90 | struct LDR_DATA_TABLE_ENTRY_T { 91 | LIST_ENTRY_T InLoadOrderLinks; 92 | LIST_ENTRY_T InMemoryOrderLinks; 93 | LIST_ENTRY_T InInitializationOrderLinks; 94 | const char* DllBase; 95 | const char* EntryPoint; 96 | union { 97 | unsigned long SizeOfImage; 98 | const char* _dummy; 99 | }; 100 | UNICODE_STRING_T FullDllName; 101 | UNICODE_STRING_T BaseDllName; 102 | 103 | LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T* 104 | load_order_next() const noexcept 105 | { 106 | return reinterpret_cast( 107 | InLoadOrderLinks.Flink); 108 | } 109 | }; 110 | 111 | struct IMAGE_DOS_HEADER { // DOS .EXE header 112 | unsigned short e_magic; // Magic number 113 | unsigned short e_cblp; // Bytes on last page of file 114 | unsigned short e_cp; // Pages in file 115 | unsigned short e_crlc; // Relocations 116 | unsigned short e_cparhdr; // Size of header in paragraphs 117 | unsigned short e_minalloc; // Minimum extra paragraphs needed 118 | unsigned short e_maxalloc; // Maximum extra paragraphs needed 119 | unsigned short e_ss; // Initial (relative) SS value 120 | unsigned short e_sp; // Initial SP value 121 | unsigned short e_csum; // Checksum 122 | unsigned short e_ip; // Initial IP value 123 | unsigned short e_cs; // Initial (relative) CS value 124 | unsigned short e_lfarlc; // File address of relocation table 125 | unsigned short e_ovno; // Overlay number 126 | unsigned short e_res[4]; // Reserved words 127 | unsigned short e_oemid; // OEM identifier (for e_oeminfo) 128 | unsigned short e_oeminfo; // OEM information; e_oemid specific 129 | unsigned short e_res2[10]; // Reserved words 130 | long e_lfanew; // File address of new exe header 131 | }; 132 | 133 | struct IMAGE_FILE_HEADER { 134 | unsigned short Machine; 135 | unsigned short NumberOfSections; 136 | unsigned long TimeDateStamp; 137 | unsigned long PointerToSymbolTable; 138 | unsigned long NumberOfSymbols; 139 | unsigned short SizeOfOptionalHeader; 140 | unsigned short Characteristics; 141 | }; 142 | 143 | struct IMAGE_EXPORT_DIRECTORY { 144 | unsigned long Characteristics; 145 | unsigned long TimeDateStamp; 146 | unsigned short MajorVersion; 147 | unsigned short MinorVersion; 148 | unsigned long Name; 149 | unsigned long Base; 150 | unsigned long NumberOfFunctions; 151 | unsigned long NumberOfNames; 152 | unsigned long AddressOfFunctions; // RVA from base of image 153 | unsigned long AddressOfNames; // RVA from base of image 154 | unsigned long AddressOfNameOrdinals; // RVA from base of image 155 | }; 156 | 157 | struct IMAGE_DATA_DIRECTORY { 158 | unsigned long VirtualAddress; 159 | unsigned long Size; 160 | }; 161 | 162 | struct IMAGE_OPTIONAL_HEADER64 { 163 | unsigned short Magic; 164 | unsigned char MajorLinkerVersion; 165 | unsigned char MinorLinkerVersion; 166 | unsigned long SizeOfCode; 167 | unsigned long SizeOfInitializedData; 168 | unsigned long SizeOfUninitializedData; 169 | unsigned long AddressOfEntryPoint; 170 | unsigned long BaseOfCode; 171 | unsigned long long ImageBase; 172 | unsigned long SectionAlignment; 173 | unsigned long FileAlignment; 174 | unsigned short MajorOperatingSystemVersion; 175 | unsigned short MinorOperatingSystemVersion; 176 | unsigned short MajorImageVersion; 177 | unsigned short MinorImageVersion; 178 | unsigned short MajorSubsystemVersion; 179 | unsigned short MinorSubsystemVersion; 180 | unsigned long Win32VersionValue; 181 | unsigned long SizeOfImage; 182 | unsigned long SizeOfHeaders; 183 | unsigned long CheckSum; 184 | unsigned short Subsystem; 185 | unsigned short DllCharacteristics; 186 | unsigned long long SizeOfStackReserve; 187 | unsigned long long SizeOfStackCommit; 188 | unsigned long long SizeOfHeapReserve; 189 | unsigned long long SizeOfHeapCommit; 190 | unsigned long LoaderFlags; 191 | unsigned long NumberOfRvaAndSizes; 192 | IMAGE_DATA_DIRECTORY DataDirectory[16]; 193 | }; 194 | 195 | struct IMAGE_OPTIONAL_HEADER32 { 196 | unsigned short Magic; 197 | unsigned char MajorLinkerVersion; 198 | unsigned char MinorLinkerVersion; 199 | unsigned long SizeOfCode; 200 | unsigned long SizeOfInitializedData; 201 | unsigned long SizeOfUninitializedData; 202 | unsigned long AddressOfEntryPoint; 203 | unsigned long BaseOfCode; 204 | unsigned long BaseOfData; 205 | unsigned long ImageBase; 206 | unsigned long SectionAlignment; 207 | unsigned long FileAlignment; 208 | unsigned short MajorOperatingSystemVersion; 209 | unsigned short MinorOperatingSystemVersion; 210 | unsigned short MajorImageVersion; 211 | unsigned short MinorImageVersion; 212 | unsigned short MajorSubsystemVersion; 213 | unsigned short MinorSubsystemVersion; 214 | unsigned long Win32VersionValue; 215 | unsigned long SizeOfImage; 216 | unsigned long SizeOfHeaders; 217 | unsigned long CheckSum; 218 | unsigned short Subsystem; 219 | unsigned short DllCharacteristics; 220 | unsigned long SizeOfStackReserve; 221 | unsigned long SizeOfStackCommit; 222 | unsigned long SizeOfHeapReserve; 223 | unsigned long SizeOfHeapCommit; 224 | unsigned long LoaderFlags; 225 | unsigned long NumberOfRvaAndSizes; 226 | IMAGE_DATA_DIRECTORY DataDirectory[16]; 227 | }; 228 | 229 | struct IMAGE_NT_HEADERS { 230 | unsigned long Signature; 231 | IMAGE_FILE_HEADER FileHeader; 232 | #ifdef _WIN64 233 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 234 | #else 235 | IMAGE_OPTIONAL_HEADER32 OptionalHeader; 236 | #endif 237 | }; 238 | 239 | } // namespace win 240 | 241 | // hashing stuff 242 | struct hash_t { 243 | using value_type = unsigned long; 244 | constexpr static value_type offset = 2166136261; 245 | constexpr static value_type prime = 16777619; 246 | constexpr static unsigned long long prime64 = prime; 247 | 248 | LAZY_IMPORTER_FORCEINLINE constexpr static value_type single(value_type value, 249 | char c) noexcept 250 | { 251 | return static_cast( 252 | (value ^ LAZY_IMPORTER_TOLOWER(c)) * 253 | static_cast(prime)); 254 | } 255 | }; 256 | 257 | template 258 | LAZY_IMPORTER_FORCEINLINE constexpr hash_t::value_type 259 | khash(const CharT* str, hash_t::value_type value = hash_t::offset) noexcept 260 | { 261 | return (*str ? khash(str + 1, hash_t::single(value, *str)) : value); 262 | } 263 | 264 | template 265 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(const CharT* str) noexcept 266 | { 267 | hash_t::value_type value = hash_t::offset; 268 | 269 | for (;;) { 270 | char c = *str++; 271 | if (!c) 272 | return value; 273 | value = hash_t::single(value, c); 274 | } 275 | } 276 | 277 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash( 278 | const win::UNICODE_STRING_T& str) noexcept 279 | { 280 | auto first = str.Buffer; 281 | const auto last = first + (str.Length / sizeof(wchar_t)); 282 | auto value = hash_t::offset; 283 | for (; first != last; ++first) 284 | value = hash_t::single(value, static_cast(*first)); 285 | 286 | return value; 287 | } 288 | 289 | LAZY_IMPORTER_FORCEINLINE pair hash_forwarded( 290 | const char* str) noexcept 291 | { 292 | pair module_and_function{ 293 | hash_t::offset, hash_t::offset 294 | }; 295 | 296 | for (; *str != '.'; ++str) 297 | hash_t::single(module_and_function.first, *str); 298 | 299 | ++str; 300 | 301 | for (; *str; ++str) 302 | hash_t::single(module_and_function.second, *str); 303 | 304 | return module_and_function; 305 | } 306 | 307 | 308 | // some helper functions 309 | LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept 310 | { 311 | #if defined(_WIN64) 312 | return reinterpret_cast(__readgsqword(0x60)); 313 | #elif defined(_WIN32) 314 | return reinterpret_cast(__readfsdword(0x30)); 315 | #else 316 | #error Unsupported platform. Open an issue and I'll probably add support. 317 | #endif 318 | } 319 | 320 | LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr() 321 | { 322 | return reinterpret_cast(peb()->Ldr); 323 | } 324 | 325 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers( 326 | const char* base) noexcept 327 | { 328 | return reinterpret_cast( 329 | base + reinterpret_cast(base)->e_lfanew); 330 | } 331 | 332 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir( 333 | const char* base) noexcept 334 | { 335 | return reinterpret_cast( 336 | base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress); 337 | } 338 | 339 | LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept 340 | { 341 | return reinterpret_cast( 342 | ldr()->InLoadOrderModuleList.Flink); 343 | } 344 | 345 | struct exports_directory { 346 | const char* _base; 347 | const win::IMAGE_EXPORT_DIRECTORY* _ied; 348 | unsigned long _ied_size; 349 | 350 | public: 351 | using size_type = unsigned long; 352 | 353 | LAZY_IMPORTER_FORCEINLINE 354 | exports_directory(const char* base) noexcept : _base(base) 355 | { 356 | const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0]; 357 | _ied = reinterpret_cast( 358 | base + ied_data_dir.VirtualAddress); 359 | _ied_size = ied_data_dir.Size; 360 | } 361 | 362 | LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept 363 | { 364 | return reinterpret_cast(_ied) != _base; 365 | } 366 | 367 | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept 368 | { 369 | return _ied->NumberOfNames; 370 | } 371 | 372 | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; } 373 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept 374 | { 375 | return _ied; 376 | } 377 | 378 | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept 379 | { 380 | return reinterpret_cast( 381 | _base + reinterpret_cast( 382 | _base + _ied->AddressOfNames)[index]); 383 | } 384 | 385 | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept 386 | { 387 | const auto* const rva_table = 388 | reinterpret_cast(_base + _ied->AddressOfFunctions); 389 | 390 | const auto* const ord_table = reinterpret_cast( 391 | _base + _ied->AddressOfNameOrdinals); 392 | 393 | return _base + rva_table[ord_table[index]]; 394 | } 395 | 396 | LAZY_IMPORTER_FORCEINLINE bool is_forwarded(const char* export_address) const 397 | noexcept 398 | { 399 | const auto ui_ied = reinterpret_cast(_ied); 400 | return (export_address > ui_ied && export_address < ui_ied + _ied_size); 401 | } 402 | }; 403 | 404 | struct safe_module_enumerator { 405 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T; 406 | value_type* value; 407 | value_type* const head; 408 | 409 | LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept 410 | : value(ldr_data_entry()), head(value) 411 | {} 412 | 413 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = head; } 414 | 415 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept 416 | { 417 | value = value->load_order_next(); 418 | return value != head && value->DllBase; 419 | } 420 | }; 421 | 422 | struct unsafe_module_enumerator { 423 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*; 424 | value_type value; 425 | 426 | LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept 427 | : value(ldr_data_entry()) 428 | {} 429 | 430 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); } 431 | 432 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept 433 | { 434 | value = value->load_order_next(); 435 | return true; 436 | } 437 | }; 438 | 439 | // provides the cached functions which use Derive classes methods 440 | template 441 | class lazy_base { 442 | protected: 443 | // This function is needed because every templated function 444 | // with different args has its own static buffer 445 | LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept 446 | { 447 | static void* value = nullptr; 448 | return value; 449 | } 450 | 451 | public: 452 | template 453 | LAZY_IMPORTER_FORCEINLINE static T safe() noexcept 454 | { 455 | return Derived::template get(); 456 | } 457 | 458 | template 459 | LAZY_IMPORTER_FORCEINLINE static T cached() noexcept 460 | { 461 | auto& cached = _cache(); 462 | if (!cached) 463 | cached = Derived::template get(); 464 | 465 | return (T)(cached); 466 | } 467 | 468 | template 469 | LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept 470 | { 471 | return cached(); 472 | } 473 | }; 474 | 475 | template 476 | struct lazy_module : lazy_base> { 477 | template 478 | LAZY_IMPORTER_FORCEINLINE static T Get() noexcept 479 | { 480 | Enum e; 481 | do { 482 | if (hash(e.value->BaseDllName) == Hash) 483 | return (T)(e.value->DllBase); 484 | } while (e.next()); 485 | return {}; 486 | } 487 | }; 488 | 489 | template 490 | struct lazy_function : lazy_base, T> { 491 | using base_type = lazy_base, T>; 492 | 493 | template 494 | LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const 495 | { 496 | #ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS 497 | return Get()(std::forward(args)...); 498 | #else 499 | return this->cached()(std::forward(args)...); 500 | #endif 501 | } 502 | 503 | template 504 | LAZY_IMPORTER_FORCEINLINE static F Get() noexcept 505 | { 506 | // for backwards compatability. 507 | // Before 2.0 it was only possible to resolve forwarded exports when 508 | // this macro was enabled 509 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS 510 | return forwarded(); 511 | #else 512 | Enum e; 513 | do { 514 | const exports_directory exports(e.value->DllBase); 515 | 516 | if (exports) { 517 | auto export_index = exports.size(); 518 | while (export_index--) 519 | if (hash(exports.name(export_index)) == Hash) 520 | return (F)(exports.address(export_index)); 521 | } 522 | } while (e.next()); 523 | return {}; 524 | #endif 525 | } 526 | 527 | template 528 | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept 529 | { 530 | detail::win::UNICODE_STRING_T name; 531 | hash_t::value_type module_hash = 0; 532 | auto function_hash = Hash; 533 | 534 | Enum e; 535 | do { 536 | name = e.value->BaseDllName; 537 | name.Length -= 8; // get rid of .dll extension 538 | 539 | if (!module_hash || hash(name) == module_hash) { 540 | const exports_directory exports(e.value->DllBase); 541 | 542 | if (exports) { 543 | auto export_index = exports.size(); 544 | while (export_index--) 545 | if (hash(exports.name(export_index)) == function_hash) { 546 | const auto addr = exports.address(export_index); 547 | 548 | if (exports.is_forwarded(addr)) { 549 | auto hashes = hash_forwarded( 550 | reinterpret_cast(addr)); 551 | 552 | function_hash = hashes.second; 553 | module_hash = hashes.first; 554 | 555 | e.reset(); 556 | break; 557 | } 558 | return (F)(addr); 559 | } 560 | } 561 | } 562 | } while (e.next()); 563 | return {}; 564 | } 565 | 566 | template 567 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept 568 | { 569 | return forwarded(); 570 | } 571 | 572 | template 573 | LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept 574 | { 575 | auto& value = base_type::_cache(); 576 | if (!value) 577 | value = forwarded(); 578 | return (F)(value); 579 | } 580 | 581 | template 582 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept 583 | { 584 | return forwarded_cached(); 585 | } 586 | 587 | template 588 | LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept 589 | { 590 | if (IsSafe && !m) 591 | return {}; 592 | 593 | const exports_directory exports((const char*)(m)); 594 | if (IsSafe && !exports) 595 | return {}; 596 | 597 | for (unsigned long i{};; ++i) { 598 | if (IsSafe && i == exports.size()) 599 | break; 600 | 601 | if (hash(exports.name(i)) == Hash) 602 | return (F)(exports.address(i)); 603 | } 604 | return {}; 605 | } 606 | 607 | template 608 | LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept 609 | { 610 | return in(m); 611 | } 612 | 613 | template 614 | LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept 615 | { 616 | auto& value = base_type::_cache(); 617 | if (!value) 618 | value = in(m); 619 | return (F)(value); 620 | } 621 | 622 | template 623 | LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept 624 | { 625 | return in_cached(m); 626 | } 627 | 628 | template 629 | LAZY_IMPORTER_FORCEINLINE static F nt() noexcept 630 | { 631 | return in(ldr_data_entry()->load_order_next()->DllBase); 632 | } 633 | 634 | template 635 | LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept 636 | { 637 | return in_safe(ldr_data_entry()->load_order_next()->DllBase); 638 | } 639 | 640 | template 641 | LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept 642 | { 643 | return in_cached(ldr_data_entry()->load_order_next()->DllBase); 644 | } 645 | 646 | template 647 | LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept 648 | { 649 | return in_safe_cached(ldr_data_entry()->load_order_next()->DllBase); 650 | } 651 | }; 652 | 653 | } 654 | } // namespace li::detail 655 | 656 | #endif // include guard -------------------------------------------------------------------------------- /Security/Security.cpp: -------------------------------------------------------------------------------- 1 | #include "Security.hpp" 2 | #include "../Utils/Utils.hpp" 3 | 4 | SEC::RuntimeSecurityPtr RuntimeSecurity = std::make_unique(); 5 | 6 | namespace SEC { 7 | 8 | BOOL SecurityClass::IsAdministrator() 9 | { 10 | SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 11 | PSID AdministratorsGroup; 12 | 13 | if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, 14 | DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) 15 | { 16 | return FALSE; 17 | } 18 | 19 | BOOL IsInAdminGroup = FALSE; 20 | 21 | if (!CheckTokenMembership(NULL, AdministratorsGroup, &IsInAdminGroup)) 22 | { 23 | IsInAdminGroup = FALSE; 24 | } 25 | 26 | FreeSid(AdministratorsGroup); 27 | return IsInAdminGroup; 28 | } 29 | 30 | void SecurityClass::KillTasks() { 31 | 32 | LI_FN(WinExec)(STR("taskkill /f /im HTTPDebuggerUI.exe >nul 2>&1"), SW_HIDE); 33 | LI_FN(WinExec)(STR("taskkill /f /im HTTPDebuggerSvc.exe >nul 2>&1"), SW_HIDE); 34 | LI_FN(WinExec)(STR("sc stop HTTPDebuggerPro >nul 2>&1"), SW_HIDE); 35 | LI_FN(WinExec)(STR("cmd.exe /c @RD /S /Q \"C:\\Users\\%username%\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE\" >nul 2>&1"), SW_HIDE); 36 | 37 | } 38 | #pragma optimize("", off) 39 | 40 | void SecurityClass::CheckDebugger() { 41 | 42 | MUTATE_START 43 | 44 | for (;;) { 45 | BOOL DebuggerPresent = TRUE; 46 | LI_FN(CheckRemoteDebuggerPresent)(CurrentProc, &DebuggerPresent); 47 | 48 | if (LI_FN(IsDebuggerPresent)() || DebuggerPresent) 49 | SecurityCallback(STR("Malicious activity [Debugger present]")); 50 | 51 | LI_FN(Sleep)(25); 52 | } 53 | 54 | MUTATE_END 55 | } 56 | 57 | void SecurityClass::CheckDrivers() { 58 | 59 | MUTATE_START 60 | 61 | for (;;) { 62 | const TCHAR* handles[] = { 63 | _T("\\\\.\\KsDumper") 64 | }; 65 | 66 | WORD iLength = sizeof(handles) / sizeof(handles[0]); 67 | for (int i = 0; i < iLength; i++) 68 | { 69 | HANDLE hFile = CreateFile(handles[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 70 | 71 | if (hFile != INVALID_HANDLE_VALUE) 72 | SecurityCallback(STR("Malicious activity [Blacklisted driver present]")); 73 | } 74 | 75 | LI_FN(Sleep)(10); 76 | } 77 | 78 | MUTATE_END 79 | } 80 | 81 | void SecurityClass::CheckTraversedMem() { 82 | 83 | MUTATE_START 84 | 85 | for (;;) { 86 | const auto m = LI_FN(VirtualAlloc).Get()(nullptr, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 87 | 88 | PSAPI_WORKING_SET_EX_INFORMATION set{ }; 89 | set.VirtualAddress = m; 90 | 91 | if (LI_FN(K32QueryWorkingSetEx).Get()(CurrentProc, &set, sizeof(set) && (set.VirtualAttributes.Valid & 0x1))) 92 | SecurityCallback(STR("Malicious activity [MemoryTraversed]")); 93 | 94 | LI_FN(Sleep)(30); 95 | } 96 | 97 | 98 | MUTATE_END 99 | } 100 | 101 | void SecurityClass::CheckKernelInfo() { 102 | 103 | MUTATE_START 104 | 105 | for (;;) { 106 | 107 | SYSTEM_KERNEL_DEBUGGER_INFORMATION Info; 108 | 109 | // We have to import the function 110 | pZwQuerySystemInformation ZwQuerySystemInformation = NULL; 111 | 112 | ZwQuerySystemInformation = (pZwQuerySystemInformation)GetProcAddress(NtDLL, STR("ZwQuerySystemInformation")); 113 | if (!ZwQuerySystemInformation) 114 | return; 115 | 116 | NTSTATUS Status = ZwQuerySystemInformation(SystemKernelDebuggerInformation, &Info, sizeof(Info), NULL); 117 | 118 | if (Status != 0x00000000L /* SUCCESS */ || !Info.DebuggerEnabled) 119 | return; 120 | 121 | if (!Info.DebuggerNotPresent) 122 | SecurityCallback(STR("Malicious activity [Debugger present]")); 123 | 124 | LI_FN(Sleep)(50); 125 | } 126 | 127 | MUTATE_END 128 | } 129 | 130 | #pragma optimize("", on) 131 | 132 | bool SecurityClass::Init() 133 | { 134 | WRAP_IF_RELEASE( 135 | 136 | // if we don't have admin permissions, just exit the proccess 137 | if (!IsAdministrator()) 138 | return false; 139 | 140 | // kill http debugger and other services 141 | KillTasks(); 142 | 143 | // create threads 144 | CreateThreads(); 145 | ); 146 | 147 | return true; 148 | } 149 | 150 | #pragma optimize("", off) 151 | void SecurityClass::CreateThreads() 152 | { 153 | MUTATE_START 154 | 155 | std::thread DebugThread(&SecurityClass::CheckDebugger, this); DebugThread.detach(); 156 | std::thread DriverThread(&SecurityClass::CheckDrivers, this); DriverThread.detach(); 157 | std::thread CheckMemThread(&SecurityClass::CheckTraversedMem, this); CheckMemThread.detach(); 158 | std::thread KernalInfoThread(&SecurityClass::CheckKernelInfo, this); KernalInfoThread.detach(); 159 | 160 | MUTATE_END 161 | } 162 | #pragma optimize("", on) 163 | 164 | void SecurityClass::SecurityCallback(const char* Reason) { 165 | 166 | static bool Triggered = false; 167 | 168 | if (!Triggered) { 169 | 170 | Auth.BanUser(); 171 | 172 | std::ofstream File("loader.errr"); 173 | File.write(Reason, LI_FN(strlen).Get()(Reason)); 174 | File.close(); 175 | 176 | LI_FN(ExitProcess)(rand() % RAND_MAX); 177 | 178 | Triggered = true; 179 | } 180 | 181 | } 182 | } -------------------------------------------------------------------------------- /Security/Security.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../includes.hpp" 4 | 5 | namespace SEC { 6 | 7 | typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION { 8 | BOOLEAN DebuggerEnabled; 9 | BOOLEAN DebuggerNotPresent; 10 | } SYSTEM_KERNEL_DEBUGGER_INFORMATION, * PSYSTEM_KERNEL_DEBUGGER_INFORMATION; 11 | 12 | enum SYSTEM_INFORMATION_CLASS { SystemKernelDebuggerInformation = 35 }; 13 | 14 | // Function Pointer Typedef for ZwQuerySystemInformation 15 | typedef NTSTATUS(WINAPI* pZwQuerySystemInformation)(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength); 16 | 17 | 18 | class SecurityClass { 19 | 20 | protected: 21 | 22 | BOOL IsAdministrator(); 23 | void KillTasks(); 24 | 25 | void CheckDebugger(); 26 | void CheckDrivers(); 27 | void CheckTraversedMem(); 28 | void CheckKernelInfo(); 29 | 30 | void CreateThreads(); 31 | 32 | public: 33 | 34 | bool Init(); 35 | bool IsTampered = false; 36 | 37 | void SecurityCallback(const char* Reason); 38 | 39 | }; 40 | 41 | using RuntimeSecurityPtr = std::unique_ptr; 42 | 43 | } 44 | 45 | extern SEC::RuntimeSecurityPtr RuntimeSecurity; 46 | -------------------------------------------------------------------------------- /UserInterface/Fonts/Icons.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | inline unsigned char IconFont[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x80, 0x00, 0x03, 0x00, 0x50, 0x46, 0x46, 0x54, 0x4D, 3 | 0x8E, 0xD4, 0xCA, 0xD1, 0x00, 0x00, 0x0B, 0x58, 0x00, 0x00, 0x00, 0x1C, 0x47, 0x44, 0x45, 0x46, 4 | 0x00, 0x29, 0x00, 0x10, 0x00, 0x00, 0x0B, 0x38, 0x00, 0x00, 0x00, 0x1E, 0x4F, 0x53, 0x2F, 0x32, 5 | 0x4F, 0xB1, 0x5C, 0x62, 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x56, 0x63, 0x6D, 0x61, 0x70, 6 | 0x0C, 0x88, 0x09, 0x97, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x00, 0x01, 0x4A, 0x67, 0x61, 0x73, 0x70, 7 | 0xFF, 0xFF, 0x00, 0x03, 0x00, 0x00, 0x0B, 0x30, 0x00, 0x00, 0x00, 0x08, 0x67, 0x6C, 0x79, 0x66, 8 | 0x7A, 0xA8, 0x03, 0x2A, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x05, 0xAC, 0x68, 0x65, 0x61, 0x64, 9 | 0x1A, 0x05, 0xC6, 0x15, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61, 10 | 0x04, 0x16, 0x01, 0xF3, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6D, 0x74, 0x78, 11 | 0x06, 0x4A, 0x00, 0x98, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00, 0x1C, 0x6C, 0x6F, 0x63, 0x61, 12 | 0x06, 0xB6, 0x05, 0x10, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x00, 0x16, 0x6D, 0x61, 0x78, 0x70, 13 | 0x00, 0x4F, 0x00, 0x81, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, 0x20, 0x6E, 0x61, 0x6D, 0x65, 14 | 0xA9, 0x4D, 0xF0, 0xC0, 0x00, 0x00, 0x08, 0xDC, 0x00, 0x00, 0x01, 0xE3, 0x70, 0x6F, 0x73, 0x74, 15 | 0xEB, 0x36, 0x33, 0xA6, 0x00, 0x00, 0x0A, 0xC0, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x01, 0x00, 0x00, 16 | 0x00, 0x01, 0x00, 0x00, 0x65, 0x0F, 0x04, 0x90, 0x5F, 0x0F, 0x3C, 0xF5, 0x00, 0x0B, 0x02, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0xDC, 0x73, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x73, 0xC2, 0x8C, 18 | 0xFF, 0xEE, 0x00, 0x1A, 0x02, 0x12, 0x01, 0xE6, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xE6, 0x00, 0x00, 0x00, 0x2E, 0x02, 0x00, 20 | 0xFF, 0xEE, 0xFF, 0xEE, 0x02, 0x12, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x7E, 22 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 23 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x90, 0x00, 0x05, 24 | 0x00, 0x08, 0x01, 0x4C, 0x01, 0x66, 0x00, 0x00, 0x00, 0x47, 0x01, 0x4C, 0x01, 0x66, 0x00, 0x00, 25 | 0x00, 0xF5, 0x00, 0x19, 0x00, 0x84, 0x00, 0x00, 0x02, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x50, 0x66, 0x45, 0x64, 0x00, 0x40, 0x00, 0x31, 0x00, 0x37, 0x01, 0xE0, 0xFF, 0xE0, 28 | 0x00, 0x2E, 0x01, 0xE6, 0xFF, 0xE6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x29, 30 | 0x00, 0x37, 0x00, 0x25, 0xFF, 0xEE, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 31 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 32 | 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 33 | 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x37, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x31, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xD2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 36 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x68, 0x00, 0xC4, 0x01, 0x7A, 0x01, 0xAC, 0x01, 0xFE, 0x02, 0xA0, 0x02, 0xD6, 0x00, 0x00, 53 | 0x00, 0x02, 0x00, 0x29, 0x00, 0x1A, 0x01, 0xD7, 0x01, 0xE6, 0x00, 0x1B, 0x00, 0x47, 0x00, 0x00, 54 | 0x25, 0x36, 0x35, 0x36, 0x26, 0x27, 0x16, 0x06, 0x27, 0x3E, 0x01, 0x2E, 0x02, 0x37, 0x0E, 0x01, 55 | 0x15, 0x16, 0x17, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36, 0x35, 0x34, 0x25, 0x06, 0x16, 0x33, 0x32, 56 | 0x37, 0x16, 0x17, 0x16, 0x07, 0x15, 0x06, 0x07, 0x06, 0x23, 0x06, 0x31, 0x07, 0x06, 0x07, 0x22, 57 | 0x07, 0x22, 0x06, 0x23, 0x22, 0x07, 0x2B, 0x02, 0x22, 0x26, 0x2B, 0x01, 0x26, 0x23, 0x2F, 0x01, 58 | 0x23, 0x2E, 0x01, 0x37, 0x07, 0x36, 0x01, 0x94, 0x02, 0x01, 0x33, 0x2E, 0x0A, 0x39, 0x2C, 0x18, 59 | 0x0A, 0x11, 0x12, 0x0B, 0x0B, 0x2C, 0x48, 0x02, 0x05, 0x44, 0x7E, 0xB2, 0x7E, 0xFE, 0xD7, 0x0B, 60 | 0x2E, 0x21, 0x3F, 0x19, 0x24, 0x03, 0x03, 0x28, 0x0C, 0x07, 0x01, 0x01, 0x08, 0x02, 0x0A, 0x0D, 61 | 0x03, 0x01, 0x02, 0x06, 0x01, 0x03, 0x01, 0x0E, 0x09, 0x03, 0x01, 0x06, 0x01, 0x01, 0x08, 0x02, 62 | 0x01, 0x09, 0x01, 0x1E, 0x23, 0x01, 0x01, 0x02, 0xB8, 0x0C, 0x08, 0x3B, 0x3F, 0x1B, 0x37, 0x3F, 63 | 0x0C, 0x27, 0x3C, 0x21, 0x27, 0x24, 0x20, 0x1F, 0x93, 0x3E, 0x25, 0x19, 0x1C, 0x27, 0x25, 0x36, 64 | 0x36, 0x25, 0x27, 0x8A, 0x34, 0x4B, 0x64, 0x1B, 0x2D, 0x31, 0x22, 0x01, 0x08, 0x04, 0x01, 0x04, 65 | 0x01, 0x04, 0x03, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03, 0x0C, 0x37, 0x26, 0x01, 0x30, 0x00, 66 | 0x00, 0x02, 0x00, 0x37, 0x00, 0x25, 0x01, 0xC9, 0x01, 0xDB, 0x00, 0x2F, 0x00, 0x3B, 0x00, 0x00, 67 | 0x25, 0x14, 0x07, 0x06, 0x2B, 0x01, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 68 | 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1F, 0x01, 0x1E, 0x01, 0x32, 0x36, 0x3F, 69 | 0x01, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 70 | 0x27, 0x14, 0x07, 0x06, 0x22, 0x27, 0x26, 0x35, 0x34, 0x36, 0x32, 0x16, 0x01, 0xC9, 0x15, 0x14, 71 | 0x23, 0xFA, 0x23, 0x14, 0x15, 0x01, 0x02, 0x02, 0x04, 0x03, 0x03, 0x0A, 0x08, 0x09, 0x0A, 0x0F, 72 | 0x0F, 0x11, 0x02, 0x0A, 0x15, 0x0B, 0x28, 0x24, 0x28, 0x0B, 0x15, 0x0A, 0x02, 0x11, 0x0F, 0x0F, 73 | 0x0A, 0x09, 0x08, 0x0A, 0x03, 0x03, 0x04, 0x02, 0x02, 0x01, 0x5B, 0x20, 0x22, 0x58, 0x22, 0x20, 74 | 0x40, 0x5C, 0x40, 0x6F, 0x22, 0x15, 0x13, 0x13, 0x15, 0x22, 0x14, 0x09, 0x14, 0x0B, 0x16, 0x09, 75 | 0x0A, 0x12, 0x0E, 0x09, 0x0A, 0x06, 0x05, 0x06, 0x0E, 0x07, 0x0C, 0x0C, 0x07, 0x0E, 0x06, 0x05, 76 | 0x06, 0x0A, 0x09, 0x0E, 0x12, 0x0A, 0x09, 0x16, 0x0B, 0x14, 0x09, 0xEB, 0x2C, 0x22, 0x20, 0x20, 77 | 0x22, 0x2C, 0x2D, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x25, 0x01, 0xDB, 78 | 0x01, 0xDB, 0x00, 0x0B, 0x00, 0x7D, 0x00, 0x00, 0x24, 0x34, 0x27, 0x26, 0x22, 0x07, 0x06, 0x14, 79 | 0x17, 0x16, 0x32, 0x3F, 0x01, 0x15, 0x14, 0x07, 0x06, 0x0F, 0x01, 0x06, 0x07, 0x16, 0x17, 0x16, 80 | 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x2F, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x2B, 0x01, 81 | 0x22, 0x27, 0x26, 0x35, 0x27, 0x26, 0x27, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 82 | 0x37, 0x3E, 0x01, 0x37, 0x3E, 0x01, 0x37, 0x26, 0x2F, 0x01, 0x22, 0x27, 0x26, 0x3D, 0x01, 0x34, 83 | 0x37, 0x36, 0x3F, 0x01, 0x36, 0x37, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 84 | 0x1F, 0x01, 0x36, 0x37, 0x36, 0x37, 0x36, 0x3B, 0x01, 0x32, 0x17, 0x16, 0x15, 0x17, 0x16, 0x17, 85 | 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x0E, 0x01, 0x07, 0x0E, 0x01, 0x07, 86 | 0x16, 0x1F, 0x01, 0x32, 0x17, 0x16, 0x01, 0x49, 0x15, 0x16, 0x3C, 0x16, 0x15, 0x15, 0x16, 0x3C, 87 | 0x16, 0xA7, 0x02, 0x01, 0x05, 0x34, 0x07, 0x05, 0x13, 0x0C, 0x03, 0x03, 0x08, 0x14, 0x16, 0x05, 88 | 0x04, 0x03, 0x28, 0x08, 0x12, 0x04, 0x04, 0x01, 0x09, 0x40, 0x05, 0x02, 0x03, 0x08, 0x12, 0x08, 89 | 0x28, 0x03, 0x08, 0x03, 0x25, 0x0A, 0x02, 0x02, 0x01, 0x0A, 0x03, 0x03, 0x0B, 0x02, 0x07, 0x05, 90 | 0x34, 0x05, 0x01, 0x02, 0x02, 0x01, 0x04, 0x35, 0x05, 0x07, 0x0F, 0x10, 0x03, 0x03, 0x08, 0x14, 91 | 0x15, 0x06, 0x04, 0x03, 0x28, 0x08, 0x12, 0x04, 0x04, 0x01, 0x09, 0x40, 0x05, 0x02, 0x03, 0x08, 92 | 0x12, 0x08, 0x28, 0x03, 0x08, 0x03, 0x27, 0x08, 0x02, 0x02, 0x01, 0x0A, 0x03, 0x03, 0x0B, 0x02, 93 | 0x08, 0x04, 0x34, 0x05, 0x01, 0x02, 0xE2, 0x3C, 0x16, 0x15, 0x15, 0x16, 0x3C, 0x16, 0x15, 0x15, 94 | 0x53, 0x3F, 0x05, 0x02, 0x02, 0x02, 0x08, 0x11, 0x09, 0x18, 0x0F, 0x03, 0x08, 0x03, 0x0A, 0x15, 95 | 0x14, 0x03, 0x1F, 0x05, 0x06, 0x23, 0x12, 0x08, 0x02, 0x03, 0x03, 0x35, 0x06, 0x04, 0x1E, 0x03, 96 | 0x03, 0x22, 0x0E, 0x02, 0x05, 0x04, 0x02, 0x01, 0x0D, 0x05, 0x04, 0x0F, 0x02, 0x0C, 0x10, 0x08, 97 | 0x03, 0x02, 0x05, 0x3F, 0x05, 0x02, 0x02, 0x02, 0x08, 0x0E, 0x0C, 0x14, 0x13, 0x04, 0x06, 0x04, 98 | 0x0C, 0x12, 0x15, 0x03, 0x1F, 0x05, 0x06, 0x23, 0x12, 0x08, 0x02, 0x03, 0x03, 0x35, 0x06, 0x04, 99 | 0x1E, 0x03, 0x03, 0x24, 0x0D, 0x01, 0x05, 0x04, 0x02, 0x02, 0x0D, 0x04, 0x05, 0x0D, 0x03, 0x0E, 100 | 0x0E, 0x08, 0x03, 0x02, 0x00, 0x01, 0xFF, 0xEE, 0x00, 0x49, 0x02, 0x12, 0x01, 0xDB, 0x00, 0x1F, 101 | 0x00, 0x00, 0x25, 0x14, 0x06, 0x23, 0x21, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x35, 102 | 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 103 | 0x1E, 0x01, 0x02, 0x12, 0x40, 0x2D, 0xFE, 0xC9, 0x35, 0x26, 0x25, 0x14, 0x16, 0x1F, 0x2B, 0x2A, 104 | 0x3D, 0x2F, 0x23, 0x24, 0x12, 0x14, 0x1B, 0x1E, 0x16, 0x15, 0x0C, 0x25, 0x30, 0xB7, 0x2E, 0x40, 105 | 0x26, 0x25, 0x35, 0x27, 0x1E, 0x21, 0x0E, 0x0C, 0x3D, 0x2B, 0x2A, 0x19, 0x18, 0x29, 0x11, 0x15, 106 | 0x15, 0x1F, 0x15, 0x12, 0x09, 0x3C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x25, 0x00, 0x25, 0x01, 0xDB, 107 | 0x01, 0xDB, 0x00, 0x0B, 0x00, 0x1F, 0x00, 0x33, 0x00, 0x00, 0x00, 0x14, 0x07, 0x06, 0x22, 0x27, 108 | 0x26, 0x34, 0x37, 0x36, 0x32, 0x17, 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, 0x14, 0x17, 0x16, 0x17, 109 | 0x16, 0x32, 0x37, 0x36, 0x37, 0x36, 0x34, 0x27, 0x26, 0x27, 0x16, 0x14, 0x07, 0x06, 0x07, 0x06, 110 | 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x01, 0x49, 111 | 0x15, 0x16, 0x3C, 0x16, 0x15, 0x15, 0x16, 0x3C, 0x16, 0x0B, 0x52, 0x25, 0x24, 0x15, 0x14, 0x14, 112 | 0x15, 0x24, 0x25, 0x52, 0x25, 0x24, 0x15, 0x14, 0x14, 0x15, 0x24, 0x8D, 0x1D, 0x1E, 0x32, 0x30, 113 | 0x7C, 0x30, 0x32, 0x1E, 0x1D, 0x1D, 0x1E, 0x32, 0x30, 0x7C, 0x30, 0x32, 0x1E, 0x01, 0x1E, 0x3C, 114 | 0x16, 0x15, 0x15, 0x16, 0x3C, 0x16, 0x15, 0x15, 0x67, 0x14, 0x15, 0x24, 0x25, 0x52, 0x25, 0x24, 115 | 0x15, 0x14, 0x14, 0x15, 0x24, 0x25, 0x52, 0x25, 0x24, 0x15, 0x49, 0x7C, 0x30, 0x32, 0x1E, 0x1D, 116 | 0x1D, 0x1E, 0x32, 0x30, 0x7C, 0x30, 0x32, 0x1E, 0x1D, 0x1D, 0x1E, 0x32, 0x00, 0x02, 0x00, 0x25, 117 | 0x00, 0x25, 0x01, 0xDB, 0x01, 0xDB, 0x00, 0x3B, 0x00, 0x77, 0x00, 0x00, 0x25, 0x23, 0x22, 0x27, 118 | 0x26, 0x3D, 0x01, 0x34, 0x37, 0x36, 0x3B, 0x01, 0x26, 0x27, 0x26, 0x27, 0x15, 0x14, 0x07, 0x06, 119 | 0x2B, 0x01, 0x22, 0x27, 0x26, 0x3D, 0x01, 0x06, 0x07, 0x06, 0x07, 0x33, 0x32, 0x17, 0x16, 0x1D, 120 | 0x01, 0x14, 0x07, 0x06, 0x2B, 0x01, 0x16, 0x17, 0x16, 0x17, 0x35, 0x34, 0x37, 0x36, 0x3B, 0x01, 121 | 0x32, 0x17, 0x16, 0x1D, 0x01, 0x36, 0x37, 0x36, 0x37, 0x15, 0x14, 0x07, 0x06, 0x2B, 0x01, 0x06, 122 | 0x07, 0x06, 0x07, 0x15, 0x14, 0x07, 0x06, 0x2B, 0x01, 0x22, 0x27, 0x26, 0x3D, 0x01, 0x26, 0x27, 123 | 0x26, 0x27, 0x23, 0x22, 0x27, 0x26, 0x3D, 0x01, 0x34, 0x37, 0x36, 0x3B, 0x01, 0x36, 0x37, 0x36, 124 | 0x37, 0x35, 0x34, 0x37, 0x36, 0x3B, 0x01, 0x32, 0x17, 0x16, 0x1D, 0x01, 0x16, 0x17, 0x16, 0x17, 125 | 0x33, 0x32, 0x17, 0x16, 0x01, 0x7B, 0x20, 0x07, 0x05, 0x06, 0x06, 0x05, 0x07, 0x20, 0x0B, 0x16, 126 | 0x14, 0x21, 0x06, 0x05, 0x08, 0x24, 0x08, 0x05, 0x06, 0x21, 0x14, 0x16, 0x0B, 0x20, 0x07, 0x05, 127 | 0x06, 0x06, 0x05, 0x07, 0x20, 0x0B, 0x16, 0x14, 0x21, 0x06, 0x05, 0x08, 0x24, 0x08, 0x05, 0x06, 128 | 0x21, 0x14, 0x16, 0x6B, 0x05, 0x06, 0x07, 0x29, 0x0B, 0x21, 0x1F, 0x30, 0x06, 0x04, 0x09, 0x24, 129 | 0x09, 0x04, 0x06, 0x30, 0x1F, 0x21, 0x0B, 0x29, 0x07, 0x06, 0x05, 0x05, 0x06, 0x07, 0x29, 0x0B, 130 | 0x21, 0x1F, 0x30, 0x06, 0x04, 0x09, 0x24, 0x09, 0x04, 0x06, 0x30, 0x1F, 0x21, 0x0B, 0x29, 0x07, 131 | 0x06, 0x05, 0xDB, 0x06, 0x05, 0x08, 0x24, 0x08, 0x05, 0x06, 0x21, 0x14, 0x16, 0x0B, 0x20, 0x07, 132 | 0x05, 0x06, 0x06, 0x05, 0x07, 0x20, 0x0B, 0x16, 0x14, 0x21, 0x06, 0x05, 0x08, 0x24, 0x08, 0x05, 133 | 0x06, 0x21, 0x14, 0x16, 0x0B, 0x20, 0x07, 0x05, 0x06, 0x06, 0x05, 0x07, 0x20, 0x0B, 0x16, 0x14, 134 | 0x58, 0x24, 0x09, 0x04, 0x06, 0x30, 0x1F, 0x21, 0x0B, 0x29, 0x07, 0x06, 0x05, 0x05, 0x06, 0x07, 135 | 0x29, 0x0B, 0x21, 0x1F, 0x30, 0x06, 0x04, 0x09, 0x24, 0x09, 0x04, 0x06, 0x30, 0x1F, 0x21, 0x0B, 136 | 0x29, 0x07, 0x06, 0x05, 0x05, 0x06, 0x07, 0x29, 0x0B, 0x21, 0x1F, 0x30, 0x06, 0x04, 0x00, 0x00, 137 | 0x00, 0x02, 0x00, 0x25, 0x00, 0x25, 0x01, 0xDB, 0x01, 0xDB, 0x00, 0x0B, 0x00, 0x1F, 0x00, 0x00, 138 | 0x25, 0x11, 0x22, 0x07, 0x06, 0x07, 0x06, 0x14, 0x17, 0x16, 0x17, 0x16, 0x24, 0x14, 0x07, 0x06, 139 | 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 140 | 0x01, 0x00, 0x29, 0x25, 0x24, 0x15, 0x14, 0x14, 0x15, 0x24, 0x25, 0x01, 0x04, 0x1D, 0x1E, 0x32, 141 | 0x30, 0x7C, 0x30, 0x32, 0x1E, 0x1D, 0x1D, 0x1E, 0x32, 0x30, 0x7C, 0x30, 0x32, 0x1E, 0x65, 0x01, 142 | 0x36, 0x14, 0x15, 0x24, 0x25, 0x52, 0x25, 0x24, 0x15, 0x14, 0xD9, 0x7C, 0x30, 0x32, 0x1E, 0x1D, 143 | 0x1D, 0x1E, 0x32, 0x30, 0x7C, 0x30, 0x32, 0x1E, 0x1D, 0x1D, 0x1E, 0x32, 0x00, 0x00, 0x00, 0x0C, 144 | 0x00, 0x96, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00, 0x20, 0x00, 0x01, 145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 146 | 0x00, 0x03, 0x00, 0x2B, 0x00, 0x9D, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0F, 147 | 0x00, 0xE9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0B, 0x01, 0x11, 0x00, 0x01, 148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0F, 0x01, 0x3D, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 149 | 0x00, 0x01, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0C, 150 | 0x00, 0x30, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x56, 0x00, 0x45, 0x00, 0x03, 151 | 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x1E, 0x00, 0xC9, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 152 | 0x00, 0x05, 0x00, 0x16, 0x00, 0xF9, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x1E, 153 | 0x01, 0x1D, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x65, 154 | 0x00, 0x64, 0x00, 0x2D, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x2D, 0x00, 0x31, 155 | 0x00, 0x00, 0x75, 0x6E, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x64, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 156 | 0x31, 0x00, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x2D, 0x00, 0x31, 0x00, 0x00, 157 | 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x31, 0x00, 0x00, 0x46, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x74, 0x00, 158 | 0x46, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2E, 0x00, 159 | 0x30, 0x00, 0x20, 0x00, 0x3A, 0x00, 0x20, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x69, 0x00, 160 | 0x74, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x64, 0x00, 0x2D, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x6E, 0x00, 161 | 0x74, 0x00, 0x2D, 0x00, 0x31, 0x00, 0x20, 0x00, 0x3A, 0x00, 0x20, 0x00, 0x31, 0x00, 0x34, 0x00, 162 | 0x2D, 0x00, 0x33, 0x00, 0x2D, 0x00, 0x32, 0x00, 0x30, 0x00, 0x32, 0x00, 0x31, 0x00, 0x00, 0x46, 163 | 0x6F, 0x6E, 0x74, 0x46, 0x6F, 0x72, 0x67, 0x65, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x3A, 0x20, 0x75, 164 | 0x6E, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x64, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x31, 0x20, 0x3A, 165 | 0x20, 0x31, 0x34, 0x2D, 0x33, 0x2D, 0x32, 0x30, 0x32, 0x31, 0x00, 0x00, 0x75, 0x00, 0x6E, 0x00, 166 | 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x64, 0x00, 0x2D, 0x00, 0x66, 0x00, 167 | 0x6F, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x2D, 0x00, 0x31, 0x00, 0x00, 0x75, 0x6E, 0x74, 0x69, 0x74, 168 | 0x6C, 0x65, 0x64, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x31, 0x00, 0x00, 0x56, 0x00, 0x65, 0x00, 169 | 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2E, 0x00, 170 | 0x30, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x30, 0x00, 0x00, 171 | 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x64, 0x00, 172 | 0x2D, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x2D, 0x00, 0x31, 0x00, 0x00, 0x75, 173 | 0x6E, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x64, 0x2D, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x31, 0x00, 0x00, 174 | 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 175 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 | 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x01, 0x05, 177 | 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x0A, 0x66, 0x65, 0x65, 0x64, 0x62, 0x75, 0x72, 0x6E, 0x65, 178 | 0x72, 0x04, 0x75, 0x73, 0x65, 0x72, 0x03, 0x63, 0x6F, 0x67, 0x05, 0x63, 0x6C, 0x6F, 0x75, 0x64, 179 | 0x0C, 0x64, 0x6F, 0x74, 0x2D, 0x63, 0x69, 0x72, 0x63, 0x6C, 0x65, 0x2D, 0x6F, 0x0A, 0x63, 0x72, 180 | 0x6F, 0x73, 0x73, 0x68, 0x61, 0x69, 0x72, 0x73, 0x06, 0x61, 0x64, 0x6A, 0x75, 0x73, 0x74, 0x00, 181 | 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 182 | 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x09, 0x00, 0x01, 0x00, 0x04, 183 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 184 | 0xD5, 0xED, 0x45, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x73, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, 185 | 0xDC, 0x73, 0xC2, 0x8C }; -------------------------------------------------------------------------------- /UserInterface/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/branch with your modifications to imconfig.h) 7 | // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" 8 | // If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include 9 | // the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 10 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 11 | // 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. 12 | //----------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | //---- Define assertion handler. Defaults to calling assert(). 17 | // 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. 18 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 19 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 20 | 21 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 22 | // 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. 23 | //#define IMGUI_API __declspec( dllexport ) 24 | //#define IMGUI_API __declspec( dllimport ) 25 | 26 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 27 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 28 | 29 | //---- Disable all of Dear ImGui or don't implement standard windows. 30 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. 31 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 32 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. 33 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable debug/metrics window: ShowMetricsWindow() will be empty. 34 | 35 | //---- Don't implement some functions to reduce linkage requirements. 36 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. 37 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. 38 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 39 | //#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). 40 | //#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) 41 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 42 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite 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. 43 | //#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(). 44 | 45 | //---- Include imgui_user.h at the end of imgui.h as a convenience 46 | //#define IMGUI_INCLUDE_IMGUI_USER_H 47 | 48 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 49 | //#define IMGUI_USE_BGRA_PACKED_COLOR 50 | 51 | //---- Use 32-bit for ImWchar (default is 16-bit) to support full unicode code points. 52 | //#define IMGUI_USE_WCHAR32 53 | 54 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 55 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 56 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 57 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 58 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 59 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 60 | 61 | //---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library. 62 | // Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. 63 | // #define IMGUI_USE_STB_SPRINTF 64 | 65 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 66 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 67 | /* 68 | #define IM_VEC2_CLASS_EXTRA \ 69 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 70 | operator MyVec2() const { return MyVec2(x,y); } 71 | 72 | #define IM_VEC4_CLASS_EXTRA \ 73 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 74 | operator MyVec4() const { return MyVec4(x,y,z,w); } 75 | */ 76 | 77 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 78 | // Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices). 79 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 80 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 81 | //#define ImDrawIdx unsigned int 82 | 83 | //---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly) 84 | //struct ImDrawList; 85 | //struct ImDrawCmd; 86 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 87 | //#define ImDrawCallback MyImDrawCallback 88 | 89 | //---- Debug Tools: Macro to break in Debugger 90 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 91 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 92 | //#define IM_DEBUG_BREAK __debugbreak() 93 | 94 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 95 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 96 | // This adds a small runtime cost which is why it is not enabled by default. 97 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 98 | 99 | //---- Debug Tools: Enable slower asserts 100 | //#define IMGUI_DEBUG_PARANOID 101 | 102 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 103 | /* 104 | namespace ImGui 105 | { 106 | void MyFunction(const char* name, const MyMatrix44& v); 107 | } 108 | */ 109 | -------------------------------------------------------------------------------- /UserInterface/ImGui/imgui_impl_dx9.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for DirectX9 2 | // This needs to be used along with a Platform Binding (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: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 9 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 10 | // https://github.com/ocornut/imgui 11 | 12 | // CHANGELOG 13 | // (minor and older changes stripped away, please see git history for details) 14 | // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 15 | // 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 16 | // 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). 17 | // 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288. 18 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 19 | // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. 20 | // 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 21 | // 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. 22 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. 23 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 24 | 25 | #include "imgui.h" 26 | #include "imgui_impl_dx9.h" 27 | 28 | // DirectX 29 | #include 30 | #define DIRECTINPUT_VERSION 0x0800 31 | #include 32 | 33 | // DirectX data 34 | static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; 35 | static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; 36 | static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; 37 | static LPDIRECT3DTEXTURE9 g_FontTexture = NULL; 38 | static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; 39 | 40 | struct CUSTOMVERTEX 41 | { 42 | float pos[3]; 43 | D3DCOLOR col; 44 | float uv[2]; 45 | }; 46 | #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) 47 | 48 | static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) 49 | { 50 | // Setup viewport 51 | D3DVIEWPORT9 vp; 52 | vp.X = vp.Y = 0; 53 | vp.Width = (DWORD)draw_data->DisplaySize.x; 54 | vp.Height = (DWORD)draw_data->DisplaySize.y; 55 | vp.MinZ = 0.0f; 56 | vp.MaxZ = 1.0f; 57 | g_pd3dDevice->SetViewport(&vp); 58 | 59 | // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient) 60 | g_pd3dDevice->SetPixelShader(NULL); 61 | g_pd3dDevice->SetVertexShader(NULL); 62 | g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 63 | g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 64 | g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 65 | g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 66 | g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 67 | g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); 68 | g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 69 | g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 70 | g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 71 | g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 72 | g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); 73 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 74 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 75 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 76 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 77 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 78 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 79 | g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 80 | g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 81 | 82 | // Setup orthographic projection matrix 83 | // 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. 84 | // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() 85 | { 86 | float L = draw_data->DisplayPos.x + 0.5f; 87 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f; 88 | float T = draw_data->DisplayPos.y + 0.5f; 89 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f; 90 | 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 } } }; 91 | D3DMATRIX mat_projection = 92 | { { { 93 | 2.0f/(R-L), 0.0f, 0.0f, 0.0f, 94 | 0.0f, 2.0f/(T-B), 0.0f, 0.0f, 95 | 0.0f, 0.0f, 0.5f, 0.0f, 96 | (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f 97 | } } }; 98 | g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); 99 | g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); 100 | g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); 101 | } 102 | } 103 | 104 | // Render function. 105 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) 106 | void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) 107 | { 108 | // Avoid rendering when minimized 109 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 110 | return; 111 | 112 | // Create and grow buffers if needed 113 | if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 114 | { 115 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 116 | g_VertexBufferSize = draw_data->TotalVtxCount + 5000; 117 | if (g_pd3dDevice->CreateVertexBuffer(g_VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0) 118 | return; 119 | } 120 | if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) 121 | { 122 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 123 | g_IndexBufferSize = draw_data->TotalIdxCount + 10000; 124 | if (g_pd3dDevice->CreateIndexBuffer(g_IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &g_pIB, NULL) < 0) 125 | return; 126 | } 127 | 128 | // Backup the DX9 state 129 | IDirect3DStateBlock9* d3d9_state_block = NULL; 130 | if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) 131 | return; 132 | 133 | // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) 134 | D3DMATRIX last_world, last_view, last_projection; 135 | g_pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); 136 | g_pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); 137 | g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); 138 | 139 | // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format. 140 | // FIXME-OPT: This is a waste of resource, the ideal is to use imconfig.h and 141 | // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR 142 | // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } 143 | CUSTOMVERTEX* vtx_dst; 144 | ImDrawIdx* idx_dst; 145 | if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) 146 | return; 147 | if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) 148 | return; 149 | for (int n = 0; n < draw_data->CmdListsCount; n++) 150 | { 151 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 152 | const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; 153 | for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) 154 | { 155 | vtx_dst->pos[0] = vtx_src->pos.x; 156 | vtx_dst->pos[1] = vtx_src->pos.y; 157 | vtx_dst->pos[2] = 0.0f; 158 | vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000) >> 16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9 159 | vtx_dst->uv[0] = vtx_src->uv.x; 160 | vtx_dst->uv[1] = vtx_src->uv.y; 161 | vtx_dst++; 162 | vtx_src++; 163 | } 164 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 165 | idx_dst += cmd_list->IdxBuffer.Size; 166 | } 167 | g_pVB->Unlock(); 168 | g_pIB->Unlock(); 169 | g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX)); 170 | g_pd3dDevice->SetIndices(g_pIB); 171 | g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); 172 | 173 | // Setup desired DX state 174 | ImGui_ImplDX9_SetupRenderState(draw_data); 175 | 176 | // Render command lists 177 | // (Because we merged all buffers into a single one, we maintain our own offset into them) 178 | int global_vtx_offset = 0; 179 | int global_idx_offset = 0; 180 | ImVec2 clip_off = draw_data->DisplayPos; 181 | for (int n = 0; n < draw_data->CmdListsCount; n++) 182 | { 183 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 184 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 185 | { 186 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 187 | if (pcmd->UserCallback != NULL) 188 | { 189 | // User callback, registered via ImDrawList::AddCallback() 190 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 191 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 192 | ImGui_ImplDX9_SetupRenderState(draw_data); 193 | else 194 | pcmd->UserCallback(cmd_list, pcmd); 195 | } 196 | else 197 | { 198 | const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; 199 | const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->TextureId; 200 | g_pd3dDevice->SetTexture(0, texture); 201 | g_pd3dDevice->SetScissorRect(&r); 202 | g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3); 203 | } 204 | } 205 | global_idx_offset += cmd_list->IdxBuffer.Size; 206 | global_vtx_offset += cmd_list->VtxBuffer.Size; 207 | } 208 | 209 | // Restore the DX9 transform 210 | g_pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); 211 | g_pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); 212 | g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); 213 | 214 | // Restore the DX9 state 215 | d3d9_state_block->Apply(); 216 | d3d9_state_block->Release(); 217 | } 218 | 219 | bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) 220 | { 221 | // Setup back-end capabilities flags 222 | ImGuiIO& io = ImGui::GetIO(); 223 | io.BackendRendererName = "imgui_impl_dx9"; 224 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 225 | 226 | g_pd3dDevice = device; 227 | g_pd3dDevice->AddRef(); 228 | return true; 229 | } 230 | 231 | void ImGui_ImplDX9_Shutdown() 232 | { 233 | ImGui_ImplDX9_InvalidateDeviceObjects(); 234 | if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } 235 | } 236 | 237 | static bool ImGui_ImplDX9_CreateFontsTexture() 238 | { 239 | // Build texture atlas 240 | ImGuiIO& io = ImGui::GetIO(); 241 | unsigned char* pixels; 242 | int width, height, bytes_per_pixel; 243 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel); 244 | 245 | // Upload texture to graphics system 246 | g_FontTexture = NULL; 247 | if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0) 248 | return false; 249 | D3DLOCKED_RECT tex_locked_rect; 250 | if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) 251 | return false; 252 | for (int y = 0; y < height; y++) 253 | memcpy((unsigned char*)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, pixels + (width * bytes_per_pixel) * y, (width * bytes_per_pixel)); 254 | g_FontTexture->UnlockRect(0); 255 | 256 | // Store our identifier 257 | io.Fonts->TexID = (ImTextureID)g_FontTexture; 258 | 259 | return true; 260 | } 261 | 262 | bool ImGui_ImplDX9_CreateDeviceObjects() 263 | { 264 | if (!g_pd3dDevice) 265 | return false; 266 | if (!ImGui_ImplDX9_CreateFontsTexture()) 267 | return false; 268 | return true; 269 | } 270 | 271 | void ImGui_ImplDX9_InvalidateDeviceObjects() 272 | { 273 | if (!g_pd3dDevice) 274 | return; 275 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 276 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 277 | if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. 278 | } 279 | 280 | void ImGui_ImplDX9_NewFrame() 281 | { 282 | if (!g_FontTexture) 283 | ImGui_ImplDX9_CreateDeviceObjects(); 284 | } 285 | -------------------------------------------------------------------------------- /UserInterface/ImGui/imgui_impl_dx9.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for DirectX9 2 | // This needs to be used along with a Platform Binding (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: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 9 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 10 | // https://github.com/ocornut/imgui 11 | 12 | #pragma once 13 | #include "imgui.h" // IMGUI_IMPL_API 14 | 15 | struct IDirect3DDevice9; 16 | 17 | IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); 18 | IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); 19 | IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); 20 | IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); 21 | 22 | // Use if you want to reset your rendering device without losing Dear ImGui state. 23 | IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); 24 | IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects(); 25 | -------------------------------------------------------------------------------- /UserInterface/ImGui/imgui_impl_win32.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 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: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | #include "imgui.h" 11 | #include "imgui_impl_win32.h" 12 | #ifndef WIN32_LEAN_AND_MEAN 13 | #define WIN32_LEAN_AND_MEAN 14 | #endif 15 | #include 16 | #include 17 | 18 | // Using XInput library for gamepad (with recent Windows SDK this may leads to executables which won't run on Windows 7) 19 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 20 | #include 21 | #else 22 | #define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT 23 | #endif 24 | #if defined(_MSC_VER) && !defined(IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT) 25 | #pragma comment(lib, "xinput") 26 | //#pragma comment(lib, "Xinput9_1_0") 27 | #endif 28 | 29 | // CHANGELOG 30 | // (minor and older changes stripped away, please see git history for details) 31 | // 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs) 32 | // 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions. 33 | // 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT. 34 | // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. 35 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). 36 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent. 37 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. 38 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 39 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 40 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 41 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). 42 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. 43 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. 44 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). 45 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 46 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 47 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 48 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 49 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. 50 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. 51 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. 52 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 53 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. 54 | 55 | // Win32 Data 56 | static HWND g_hWnd = NULL; 57 | static INT64 g_Time = 0; 58 | static INT64 g_TicksPerSecond = 0; 59 | static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; 60 | static bool g_HasGamepad = false; 61 | static bool g_WantUpdateHasGamepad = true; 62 | 63 | // Functions 64 | bool ImGui_ImplWin32_Init(void* hwnd) 65 | { 66 | if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&g_TicksPerSecond)) 67 | return false; 68 | if (!::QueryPerformanceCounter((LARGE_INTEGER*)&g_Time)) 69 | return false; 70 | 71 | // Setup back-end capabilities flags 72 | g_hWnd = (HWND)hwnd; 73 | ImGuiIO& io = ImGui::GetIO(); 74 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 75 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 76 | io.BackendPlatformName = "imgui_impl_win32"; 77 | io.ImeWindowHandle = hwnd; 78 | 79 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. 80 | io.KeyMap[ImGuiKey_Tab] = VK_TAB; 81 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; 82 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; 83 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP; 84 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; 85 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; 86 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; 87 | io.KeyMap[ImGuiKey_Home] = VK_HOME; 88 | io.KeyMap[ImGuiKey_End] = VK_END; 89 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT; 90 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE; 91 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK; 92 | io.KeyMap[ImGuiKey_Space] = VK_SPACE; 93 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN; 94 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 95 | io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN; 96 | io.KeyMap[ImGuiKey_A] = 'A'; 97 | io.KeyMap[ImGuiKey_C] = 'C'; 98 | io.KeyMap[ImGuiKey_V] = 'V'; 99 | io.KeyMap[ImGuiKey_X] = 'X'; 100 | io.KeyMap[ImGuiKey_Y] = 'Y'; 101 | io.KeyMap[ImGuiKey_Z] = 'Z'; 102 | 103 | return true; 104 | } 105 | 106 | void ImGui_ImplWin32_Shutdown() 107 | { 108 | g_hWnd = (HWND)0; 109 | } 110 | 111 | static bool ImGui_ImplWin32_UpdateMouseCursor() 112 | { 113 | ImGuiIO& io = ImGui::GetIO(); 114 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 115 | return false; 116 | 117 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 118 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) 119 | { 120 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 121 | ::SetCursor(NULL); 122 | } 123 | else 124 | { 125 | // Show OS mouse cursor 126 | LPTSTR win32_cursor = IDC_ARROW; 127 | switch (imgui_cursor) 128 | { 129 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; 130 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; 131 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; 132 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; 133 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; 134 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; 135 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; 136 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; 137 | case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; 138 | } 139 | ::SetCursor(::LoadCursor(NULL, win32_cursor)); 140 | } 141 | return true; 142 | } 143 | 144 | static void ImGui_ImplWin32_UpdateMousePos() 145 | { 146 | ImGuiIO& io = ImGui::GetIO(); 147 | 148 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 149 | if (io.WantSetMousePos) 150 | { 151 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; 152 | ::ClientToScreen(g_hWnd, &pos); 153 | ::SetCursorPos(pos.x, pos.y); 154 | } 155 | 156 | // Set mouse position 157 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 158 | POINT pos; 159 | if (HWND active_window = ::GetForegroundWindow()) 160 | if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd)) 161 | if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos)) 162 | io.MousePos = ImVec2((float)pos.x, (float)pos.y); 163 | } 164 | 165 | // Gamepad navigation mapping 166 | static void ImGui_ImplWin32_UpdateGamepads() 167 | { 168 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 169 | ImGuiIO& io = ImGui::GetIO(); 170 | memset(io.NavInputs, 0, sizeof(io.NavInputs)); 171 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) 172 | return; 173 | 174 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. 175 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. 176 | if (g_WantUpdateHasGamepad) 177 | { 178 | XINPUT_CAPABILITIES caps; 179 | g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); 180 | g_WantUpdateHasGamepad = false; 181 | } 182 | 183 | XINPUT_STATE xinput_state; 184 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; 185 | if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) 186 | { 187 | const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; 188 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; 189 | 190 | #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } 191 | #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } 192 | MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A 193 | MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B 194 | MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X 195 | MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y 196 | MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left 197 | MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right 198 | MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up 199 | MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down 200 | MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 201 | MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 202 | MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 203 | MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 204 | MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); 205 | MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 206 | MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 207 | MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); 208 | #undef MAP_BUTTON 209 | #undef MAP_ANALOG 210 | } 211 | #endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 212 | } 213 | 214 | void ImGui_ImplWin32_NewFrame() 215 | { 216 | ImGuiIO& io = ImGui::GetIO(); 217 | IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); 218 | 219 | // Setup display size (every frame to accommodate for window resizing) 220 | RECT rect; 221 | ::GetClientRect(g_hWnd, &rect); 222 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); 223 | 224 | // Setup time step 225 | INT64 current_time; 226 | ::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time); 227 | io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; 228 | g_Time = current_time; 229 | 230 | // Read keyboard modifiers inputs 231 | io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; 232 | io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; 233 | io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; 234 | io.KeySuper = false; 235 | // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. 236 | 237 | // Update OS mouse position 238 | ImGui_ImplWin32_UpdateMousePos(); 239 | 240 | // Update OS mouse cursor with the cursor requested by imgui 241 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); 242 | if (g_LastMouseCursor != mouse_cursor) 243 | { 244 | g_LastMouseCursor = mouse_cursor; 245 | ImGui_ImplWin32_UpdateMouseCursor(); 246 | } 247 | 248 | // Update game controllers (if enabled and available) 249 | ImGui_ImplWin32_UpdateGamepads(); 250 | } 251 | 252 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. 253 | #ifndef WM_MOUSEHWHEEL 254 | #define WM_MOUSEHWHEEL 0x020E 255 | #endif 256 | #ifndef DBT_DEVNODES_CHANGED 257 | #define DBT_DEVNODES_CHANGED 0x0007 258 | #endif 259 | 260 | // Win32 message handler (process Win32 mouse/keyboard inputs, etc.) 261 | // Call from your application's message handler. 262 | // When implementing your own back-end, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs. 263 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 264 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 265 | // Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags. 266 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. 267 | // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. 268 | #if 0 269 | // Copy this line into your .cpp file to forward declare the function. 270 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 271 | #endif 272 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 273 | { 274 | if (ImGui::GetCurrentContext() == NULL) 275 | return 0; 276 | 277 | ImGuiIO& io = ImGui::GetIO(); 278 | switch (msg) 279 | { 280 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: 281 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: 282 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: 283 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: 284 | { 285 | int button = 0; 286 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } 287 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } 288 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } 289 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 290 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) 291 | ::SetCapture(hwnd); 292 | io.MouseDown[button] = true; 293 | return 0; 294 | } 295 | case WM_LBUTTONUP: 296 | case WM_RBUTTONUP: 297 | case WM_MBUTTONUP: 298 | case WM_XBUTTONUP: 299 | { 300 | int button = 0; 301 | if (msg == WM_LBUTTONUP) { button = 0; } 302 | if (msg == WM_RBUTTONUP) { button = 1; } 303 | if (msg == WM_MBUTTONUP) { button = 2; } 304 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 305 | io.MouseDown[button] = false; 306 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) 307 | ::ReleaseCapture(); 308 | return 0; 309 | } 310 | case WM_MOUSEWHEEL: 311 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 312 | return 0; 313 | case WM_MOUSEHWHEEL: 314 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 315 | return 0; 316 | case WM_KEYDOWN: 317 | case WM_SYSKEYDOWN: 318 | if (wParam < 256) 319 | io.KeysDown[wParam] = 1; 320 | return 0; 321 | case WM_KEYUP: 322 | case WM_SYSKEYUP: 323 | if (wParam < 256) 324 | io.KeysDown[wParam] = 0; 325 | return 0; 326 | case WM_CHAR: 327 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters. 328 | if (wParam > 0 && wParam < 0x10000) 329 | io.AddInputCharacterUTF16((unsigned short)wParam); 330 | return 0; 331 | case WM_SETCURSOR: 332 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) 333 | return 1; 334 | return 0; 335 | case WM_DEVICECHANGE: 336 | if ((UINT)wParam == DBT_DEVNODES_CHANGED) 337 | g_WantUpdateHasGamepad = true; 338 | return 0; 339 | } 340 | return 0; 341 | } 342 | 343 | 344 | //-------------------------------------------------------------------------------------------------------- 345 | // DPI-related helpers (optional) 346 | //-------------------------------------------------------------------------------------------------------- 347 | // - Use to enable DPI awareness without having to create an application manifest. 348 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 349 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 350 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 351 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 352 | //--------------------------------------------------------------------------------------------------------- 353 | // This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable. 354 | // ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically. 355 | // If you are trying to implement your own back-end for your own engine, you may ignore that noise. 356 | //--------------------------------------------------------------------------------------------------------- 357 | 358 | // Implement some of the functions and types normally declared in recent Windows SDK. 359 | #if !defined(_versionhelpers_H_INCLUDED_) && !defined(_INC_VERSIONHELPERS) 360 | static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) 361 | { 362 | OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, { 0 }, sp, 0, 0, 0, 0 }; 363 | DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; 364 | ULONGLONG cond = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); 365 | cond = ::VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); 366 | cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 367 | return ::VerifyVersionInfoW(&osvi, mask, cond); 368 | } 369 | #define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WINBLUE 370 | #endif 371 | 372 | #ifndef DPI_ENUMS_DECLARED 373 | typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; 374 | typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; 375 | #endif 376 | #ifndef _DPI_AWARENESS_CONTEXTS_ 377 | DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); 378 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3 379 | #endif 380 | #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 381 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4 382 | #endif 383 | typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+ 384 | typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+ 385 | typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update) 386 | 387 | // Helper function to enable DPI awareness without setting up a manifest 388 | void ImGui_ImplWin32_EnableDpiAwareness() 389 | { 390 | // if (IsWindows10OrGreater()) // This needs a manifest to succeed. Instead we try to grab the function pointer! 391 | { 392 | static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process 393 | if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) 394 | { 395 | SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); 396 | return; 397 | } 398 | } 399 | if (IsWindows8Point1OrGreater()) 400 | { 401 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process 402 | if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness")) 403 | { 404 | SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE); 405 | return; 406 | } 407 | } 408 | #if _WIN32_WINNT >= 0x0600 409 | ::SetProcessDPIAware(); 410 | #endif 411 | } 412 | 413 | #if defined(_MSC_VER) && !defined(NOGDI) 414 | #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps() 415 | #endif 416 | 417 | float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) 418 | { 419 | UINT xdpi = 96, ydpi = 96; 420 | static BOOL bIsWindows8Point1OrGreater = IsWindows8Point1OrGreater(); 421 | if (bIsWindows8Point1OrGreater) 422 | { 423 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process 424 | if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) 425 | GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); 426 | } 427 | #ifndef NOGDI 428 | else 429 | { 430 | const HDC dc = ::GetDC(NULL); 431 | xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); 432 | ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); 433 | ::ReleaseDC(NULL, dc); 434 | } 435 | #endif 436 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! 437 | return xdpi / 96.0f; 438 | } 439 | 440 | float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) 441 | { 442 | HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); 443 | return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); 444 | } 445 | 446 | //--------------------------------------------------------------------------------------------------------- 447 | -------------------------------------------------------------------------------- /UserInterface/ImGui/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 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: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | #pragma once 11 | #include "imgui.h" // IMGUI_IMPL_API 12 | 13 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 14 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 15 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 16 | 17 | // Configuration 18 | // - Disable gamepad support or linking with xinput.lib 19 | //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD 20 | //#define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT 21 | 22 | // Win32 message handler your application need to call. 23 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. 24 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. 25 | #if 0 26 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 27 | #endif 28 | 29 | // DPI-related helpers (optional) 30 | // - Use to enable DPI awareness without having to create an application manifest. 31 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 32 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 33 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 34 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 35 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 36 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 37 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 38 | -------------------------------------------------------------------------------- /UserInterface/ImGui/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.00. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Added STBRP__CDECL 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing 8 | // Sean Barrett 2014 9 | // 10 | // Useful for e.g. packing rectangular textures into an atlas. 11 | // Does not do rotation. 12 | // 13 | // Not necessarily the awesomest packing method, but better than 14 | // the totally naive one in stb_truetype (which is primarily what 15 | // this is meant to replace). 16 | // 17 | // Has only had a few tests run, may have issues. 18 | // 19 | // More docs to come. 20 | // 21 | // No memory allocations; uses qsort() and assert() from stdlib. 22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 23 | // 24 | // This library currently uses the Skyline Bottom-Left algorithm. 25 | // 26 | // Please note: better rectangle packers are welcome! Please 27 | // implement them to the same API, but with a different init 28 | // function. 29 | // 30 | // Credits 31 | // 32 | // Library 33 | // Sean Barrett 34 | // Minor features 35 | // Martins Mozeiko 36 | // github:IntellectualKitty 37 | // 38 | // Bugfixes / warning fixes 39 | // Jeremy Jaussaud 40 | // Fabian Giesen 41 | // 42 | // Version history: 43 | // 44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 45 | // 0.99 (2019-02-07) warning fixes 46 | // 0.11 (2017-03-03) return packing success/fail result 47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 48 | // 0.09 (2016-08-27) fix compiler warnings 49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 52 | // 0.05: added STBRP_ASSERT to allow replacing assert 53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 54 | // 0.01: initial release 55 | // 56 | // LICENSE 57 | // 58 | // See end of file for license information. 59 | 60 | ////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // INCLUDE SECTION 63 | // 64 | 65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 66 | #define STB_INCLUDE_STB_RECT_PACK_H 67 | 68 | #define STB_RECT_PACK_VERSION 1 69 | 70 | #ifdef STBRP_STATIC 71 | #define STBRP_DEF static 72 | #else 73 | #define STBRP_DEF extern 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | typedef struct stbrp_context stbrp_context; 81 | typedef struct stbrp_node stbrp_node; 82 | typedef struct stbrp_rect stbrp_rect; 83 | 84 | #ifdef STBRP_LARGE_RECTS 85 | typedef int stbrp_coord; 86 | #else 87 | typedef unsigned short stbrp_coord; 88 | #endif 89 | 90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 91 | // Assign packed locations to rectangles. The rectangles are of type 92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 93 | // are 'num_rects' many of them. 94 | // 95 | // Rectangles which are successfully packed have the 'was_packed' flag 96 | // set to a non-zero value and 'x' and 'y' store the minimum location 97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 98 | // if you imagine y increasing downwards). Rectangles which do not fit 99 | // have the 'was_packed' flag set to 0. 100 | // 101 | // You should not try to access the 'rects' array from another thread 102 | // while this function is running, as the function temporarily reorders 103 | // the array while it executes. 104 | // 105 | // To pack into another rectangle, you need to call stbrp_init_target 106 | // again. To continue packing into the same rectangle, you can call 107 | // this function again. Calling this multiple times with multiple rect 108 | // arrays will probably produce worse packing results than calling it 109 | // a single time with the full rectangle array, but the option is 110 | // available. 111 | // 112 | // The function returns 1 if all of the rectangles were successfully 113 | // packed and 0 otherwise. 114 | 115 | struct stbrp_rect 116 | { 117 | // reserved for your use: 118 | int id; 119 | 120 | // input: 121 | stbrp_coord w, h; 122 | 123 | // output: 124 | stbrp_coord x, y; 125 | int was_packed; // non-zero if valid packing 126 | 127 | }; // 16 bytes, nominally 128 | 129 | 130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 131 | // Initialize a rectangle packer to: 132 | // pack a rectangle that is 'width' by 'height' in dimensions 133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 134 | // 135 | // You must call this function every time you start packing into a new target. 136 | // 137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 138 | // the following stbrp_pack_rects() call (or calls), but can be freed after 139 | // the call (or calls) finish. 140 | // 141 | // Note: to guarantee best results, either: 142 | // 1. make sure 'num_nodes' >= 'width' 143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 144 | // 145 | // If you don't do either of the above things, widths will be quantized to multiples 146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 147 | // 148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 149 | // may run out of temporary storage and be unable to pack some rectangles. 150 | 151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 152 | // Optionally call this function after init but before doing any packing to 153 | // change the handling of the out-of-temp-memory scenario, described above. 154 | // If you call init again, this will be reset to the default (false). 155 | 156 | 157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 158 | // Optionally select which packing heuristic the library should use. Different 159 | // heuristics will produce better/worse results for different data sets. 160 | // If you call init again, this will be reset to the default. 161 | 162 | enum 163 | { 164 | STBRP_HEURISTIC_Skyline_default=0, 165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 166 | STBRP_HEURISTIC_Skyline_BF_sortHeight 167 | }; 168 | 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | // 172 | // the details of the following structures don't matter to you, but they must 173 | // be visible so you can handle the memory allocations for them 174 | 175 | struct stbrp_node 176 | { 177 | stbrp_coord x,y; 178 | stbrp_node *next; 179 | }; 180 | 181 | struct stbrp_context 182 | { 183 | int width; 184 | int height; 185 | int align; 186 | int init_mode; 187 | int heuristic; 188 | int num_nodes; 189 | stbrp_node *active_head; 190 | stbrp_node *free_head; 191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 192 | }; 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | 200 | ////////////////////////////////////////////////////////////////////////////// 201 | // 202 | // IMPLEMENTATION SECTION 203 | // 204 | 205 | #ifdef STB_RECT_PACK_IMPLEMENTATION 206 | #ifndef STBRP_SORT 207 | #include 208 | #define STBRP_SORT qsort 209 | #endif 210 | 211 | #ifndef STBRP_ASSERT 212 | #include 213 | #define STBRP_ASSERT assert 214 | #endif 215 | 216 | // [DEAR IMGUI] Added STBRP__CDECL 217 | #ifdef _MSC_VER 218 | #define STBRP__NOTUSED(v) (void)(v) 219 | #define STBRP__CDECL __cdecl 220 | #else 221 | #define STBRP__NOTUSED(v) (void)sizeof(v) 222 | #define STBRP__CDECL 223 | #endif 224 | 225 | enum 226 | { 227 | STBRP__INIT_skyline = 1 228 | }; 229 | 230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 231 | { 232 | switch (context->init_mode) { 233 | case STBRP__INIT_skyline: 234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 235 | context->heuristic = heuristic; 236 | break; 237 | default: 238 | STBRP_ASSERT(0); 239 | } 240 | } 241 | 242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 243 | { 244 | if (allow_out_of_mem) 245 | // if it's ok to run out of memory, then don't bother aligning them; 246 | // this gives better packing, but may fail due to OOM (even though 247 | // the rectangles easily fit). @TODO a smarter approach would be to only 248 | // quantize once we've hit OOM, then we could get rid of this parameter. 249 | context->align = 1; 250 | else { 251 | // if it's not ok to run out of memory, then quantize the widths 252 | // so that num_nodes is always enough nodes. 253 | // 254 | // I.e. num_nodes * align >= width 255 | // align >= width / num_nodes 256 | // align = ceil(width/num_nodes) 257 | 258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 259 | } 260 | } 261 | 262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 263 | { 264 | int i; 265 | #ifndef STBRP_LARGE_RECTS 266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 267 | #endif 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 | #ifdef STBRP_LARGE_RECTS 287 | context->extra[1].y = (1<<30); 288 | #else 289 | context->extra[1].y = 65535; 290 | #endif 291 | context->extra[1].next = NULL; 292 | } 293 | 294 | // find minimum y position if it starts at x1 295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 296 | { 297 | stbrp_node *node = first; 298 | int x1 = x0 + width; 299 | int min_y, visited_width, waste_area; 300 | 301 | STBRP__NOTUSED(c); 302 | 303 | STBRP_ASSERT(first->x <= x0); 304 | 305 | #if 0 306 | // skip in case we're past the node 307 | while (node->next->x <= x0) 308 | ++node; 309 | #else 310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 311 | #endif 312 | 313 | STBRP_ASSERT(node->x <= x0); 314 | 315 | min_y = 0; 316 | waste_area = 0; 317 | visited_width = 0; 318 | while (node->x < x1) { 319 | if (node->y > min_y) { 320 | // raise min_y higher. 321 | // we've accounted for all waste up to min_y, 322 | // but we'll now add more waste for everything we've visted 323 | waste_area += visited_width * (node->y - min_y); 324 | min_y = node->y; 325 | // the first time through, visited_width might be reduced 326 | if (node->x < x0) 327 | visited_width += node->next->x - x0; 328 | else 329 | visited_width += node->next->x - node->x; 330 | } else { 331 | // add waste area 332 | int under_width = node->next->x - node->x; 333 | if (under_width + visited_width > width) 334 | under_width = width - visited_width; 335 | waste_area += under_width * (min_y - node->y); 336 | visited_width += under_width; 337 | } 338 | node = node->next; 339 | } 340 | 341 | *pwaste = waste_area; 342 | return min_y; 343 | } 344 | 345 | typedef struct 346 | { 347 | int x,y; 348 | stbrp_node **prev_link; 349 | } stbrp__findresult; 350 | 351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 352 | { 353 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 354 | stbrp__findresult fr; 355 | stbrp_node **prev, *node, *tail, **best = NULL; 356 | 357 | // align to multiple of c->align 358 | width = (width + c->align - 1); 359 | width -= width % c->align; 360 | STBRP_ASSERT(width % c->align == 0); 361 | 362 | // if it can't possibly fit, bail immediately 363 | if (width > c->width || height > c->height) { 364 | fr.prev_link = NULL; 365 | fr.x = fr.y = 0; 366 | return fr; 367 | } 368 | 369 | node = c->active_head; 370 | prev = &c->active_head; 371 | while (node->x + width <= c->width) { 372 | int y,waste; 373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 375 | // bottom left 376 | if (y < best_y) { 377 | best_y = y; 378 | best = prev; 379 | } 380 | } else { 381 | // best-fit 382 | if (y + height <= c->height) { 383 | // can only use it if it first vertically 384 | if (y < best_y || (y == best_y && waste < best_waste)) { 385 | best_y = y; 386 | best_waste = waste; 387 | best = prev; 388 | } 389 | } 390 | } 391 | prev = &node->next; 392 | node = node->next; 393 | } 394 | 395 | best_x = (best == NULL) ? 0 : (*best)->x; 396 | 397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 398 | // 399 | // e.g, if fitting 400 | // 401 | // ____________________ 402 | // |____________________| 403 | // 404 | // into 405 | // 406 | // | | 407 | // | ____________| 408 | // |____________| 409 | // 410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 411 | // 412 | // This makes BF take about 2x the time 413 | 414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 415 | tail = c->active_head; 416 | node = c->active_head; 417 | prev = &c->active_head; 418 | // find first node that's admissible 419 | while (tail->x < width) 420 | tail = tail->next; 421 | while (tail) { 422 | int xpos = tail->x - width; 423 | int y,waste; 424 | STBRP_ASSERT(xpos >= 0); 425 | // find the left position that matches this 426 | while (node->next->x <= xpos) { 427 | prev = &node->next; 428 | node = node->next; 429 | } 430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 432 | if (y + height <= c->height) { 433 | if (y <= best_y) { 434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 435 | best_x = xpos; 436 | STBRP_ASSERT(y <= best_y); 437 | best_y = y; 438 | best_waste = waste; 439 | best = prev; 440 | } 441 | } 442 | } 443 | tail = tail->next; 444 | } 445 | } 446 | 447 | fr.prev_link = best; 448 | fr.x = best_x; 449 | fr.y = best_y; 450 | return fr; 451 | } 452 | 453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 454 | { 455 | // find best position according to heuristic 456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 457 | stbrp_node *node, *cur; 458 | 459 | // bail if: 460 | // 1. it failed 461 | // 2. the best node doesn't fit (we don't always check this) 462 | // 3. we're out of memory 463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 464 | res.prev_link = NULL; 465 | return res; 466 | } 467 | 468 | // on success, create new node 469 | node = context->free_head; 470 | node->x = (stbrp_coord) res.x; 471 | node->y = (stbrp_coord) (res.y + height); 472 | 473 | context->free_head = node->next; 474 | 475 | // insert the new node into the right starting point, and 476 | // let 'cur' point to the remaining nodes needing to be 477 | // stiched back in 478 | 479 | cur = *res.prev_link; 480 | if (cur->x < res.x) { 481 | // preserve the existing one, so start testing with the next one 482 | stbrp_node *next = cur->next; 483 | cur->next = node; 484 | cur = next; 485 | } else { 486 | *res.prev_link = node; 487 | } 488 | 489 | // from here, traverse cur and free the nodes, until we get to one 490 | // that shouldn't be freed 491 | while (cur->next && cur->next->x <= res.x + width) { 492 | stbrp_node *next = cur->next; 493 | // move the current node to the free list 494 | cur->next = context->free_head; 495 | context->free_head = cur; 496 | cur = next; 497 | } 498 | 499 | // stitch the list back in 500 | node->next = cur; 501 | 502 | if (cur->x < res.x + width) 503 | cur->x = (stbrp_coord) (res.x + width); 504 | 505 | #ifdef _DEBUG 506 | cur = context->active_head; 507 | while (cur->x < context->width) { 508 | STBRP_ASSERT(cur->x < cur->next->x); 509 | cur = cur->next; 510 | } 511 | STBRP_ASSERT(cur->next == NULL); 512 | 513 | { 514 | int count=0; 515 | cur = context->active_head; 516 | while (cur) { 517 | cur = cur->next; 518 | ++count; 519 | } 520 | cur = context->free_head; 521 | while (cur) { 522 | cur = cur->next; 523 | ++count; 524 | } 525 | STBRP_ASSERT(count == context->num_nodes+2); 526 | } 527 | #endif 528 | 529 | return res; 530 | } 531 | 532 | // [DEAR IMGUI] Added STBRP__CDECL 533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 534 | { 535 | const stbrp_rect *p = (const stbrp_rect *) a; 536 | const stbrp_rect *q = (const stbrp_rect *) b; 537 | if (p->h > q->h) 538 | return -1; 539 | if (p->h < q->h) 540 | return 1; 541 | return (p->w > q->w) ? -1 : (p->w < q->w); 542 | } 543 | 544 | // [DEAR IMGUI] Added STBRP__CDECL 545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 546 | { 547 | const stbrp_rect *p = (const stbrp_rect *) a; 548 | const stbrp_rect *q = (const stbrp_rect *) b; 549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 550 | } 551 | 552 | #ifdef STBRP_LARGE_RECTS 553 | #define STBRP__MAXVAL 0xffffffff 554 | #else 555 | #define STBRP__MAXVAL 0xffff 556 | #endif 557 | 558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 559 | { 560 | int i, all_rects_packed = 1; 561 | 562 | // we use the 'was_packed' field internally to allow sorting/unsorting 563 | for (i=0; i < num_rects; ++i) { 564 | rects[i].was_packed = i; 565 | } 566 | 567 | // sort according to heuristic 568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 569 | 570 | for (i=0; i < num_rects; ++i) { 571 | if (rects[i].w == 0 || rects[i].h == 0) { 572 | rects[i].x = rects[i].y = 0; // empty rect needs no space 573 | } else { 574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 575 | if (fr.prev_link) { 576 | rects[i].x = (stbrp_coord) fr.x; 577 | rects[i].y = (stbrp_coord) fr.y; 578 | } else { 579 | rects[i].x = rects[i].y = STBRP__MAXVAL; 580 | } 581 | } 582 | } 583 | 584 | // unsort 585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 586 | 587 | // set was_packed flags and all_rects_packed status 588 | for (i=0; i < num_rects; ++i) { 589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 590 | if (!rects[i].was_packed) 591 | all_rects_packed = 0; 592 | } 593 | 594 | // return the all_rects_packed status 595 | return all_rects_packed; 596 | } 597 | #endif 598 | 599 | /* 600 | ------------------------------------------------------------------------------ 601 | This software is available under 2 licenses -- choose whichever you prefer. 602 | ------------------------------------------------------------------------------ 603 | ALTERNATIVE A - MIT License 604 | Copyright (c) 2017 Sean Barrett 605 | Permission is hereby granted, free of charge, to any person obtaining a copy of 606 | this software and associated documentation files (the "Software"), to deal in 607 | the Software without restriction, including without limitation the rights to 608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 609 | of the Software, and to permit persons to whom the Software is furnished to do 610 | so, subject to the following conditions: 611 | The above copyright notice and this permission notice shall be included in all 612 | copies or substantial portions of the Software. 613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 616 | WebORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 619 | SOFTWARE. 620 | ------------------------------------------------------------------------------ 621 | ALTERNATIVE B - Public Domain (www.unlicense.org) 622 | This is free and unencumbered software released into the public domain. 623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 624 | software, either in source code form or as a compiled binary, for any purpose, 625 | commercial or non-commercial, and by any means. 626 | In jurisdictions that recognize copyright laws, the Webor or Webors of this 627 | software dedicate any and all copyright interest in the software to the public 628 | domain. We make this dedication for the benefit of the public at large and to 629 | the detriment of our heirs and successors. We intend this dedication to be an 630 | overt act of relinquishment in perpetuity of all present and future rights to 631 | this software under copyright law. 632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 635 | WebORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 638 | ------------------------------------------------------------------------------ 639 | */ 640 | -------------------------------------------------------------------------------- /UserInterface/ImGui/stringimgui.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "imgui.h" 3 | #include "imgui_impl_dx9.h" 4 | #include 5 | 6 | namespace ImGui 7 | { 8 | // ImGui::InputText() with std::string 9 | // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity 10 | IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); 11 | IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); 12 | IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); 13 | } -------------------------------------------------------------------------------- /UserInterface/UserInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "UserInterface.hpp" 2 | #include "../Utils/Utils.hpp" 3 | 4 | UI::UserInterfacePtr UserInterface = std::make_unique(); 5 | KeyAuth::api Auth(STR("APPNAME"), STR("OWNERID"), STR("SECRET"), STR(LOADER_VER)); 6 | 7 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 8 | 9 | namespace UI 10 | { 11 | // Win32 message handler 12 | inline LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 13 | { 14 | if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) 15 | return true; 16 | 17 | switch (msg) 18 | { 19 | case WM_LBUTTONDOWN: 20 | { 21 | m_Pos = MAKEPOINTS(lParam); // set click points 22 | return 0; 23 | } 24 | case WM_MOUSEMOVE: 25 | { 26 | if (wParam == MK_LBUTTON) 27 | { 28 | POINTS p = MAKEPOINTS(lParam); // get cur mousemove click points 29 | RECT rect; 30 | GetWindowRect(hWnd, &rect); 31 | rect.left += p.x - m_Pos.x; // get xDelta 32 | rect.top += p.y - m_Pos.y; // get yDelta 33 | if (m_Pos.x >= 0 && m_Pos.x <= LOADERW - 20 /* cuz 20px - close btn */ && m_Pos.y >= 0 && m_Pos.y <= ImGui::GetFontSize() + ImGui::GetStyle().FramePadding.y * 2.0f) 34 | SetWindowPos(hWnd, HWND_TOPMOST, rect.left, rect.top, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER); 35 | } 36 | return 0; 37 | } 38 | case WM_SIZE: 39 | if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) 40 | { 41 | g_d3dpp.BackBufferWidth = LOWORD(lParam); 42 | g_d3dpp.BackBufferHeight = HIWORD(lParam); 43 | ResetDevice(); 44 | } 45 | return 0; 46 | case WM_SYSCOMMAND: 47 | if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu 48 | return 0; 49 | break; 50 | case WM_DESTROY: 51 | ::PostQuitMessage(0); 52 | return 0; 53 | } 54 | return ::DefWindowProc(hWnd, msg, wParam, lParam); 55 | } 56 | 57 | void UserInterfaceClass::Theme() 58 | { 59 | ImVec4* colors = ImGui::GetStyle().Colors; 60 | colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f); 61 | colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f); 62 | colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); 63 | colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f); 64 | colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); 65 | colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f); 66 | colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); 67 | colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); 68 | colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f); 69 | colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f); 70 | colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f); 71 | colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f); 72 | colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); 73 | colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f); 74 | colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f); 75 | colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); 76 | colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f); 77 | colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f); 78 | colors[ImGuiCol_CheckMark] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); 79 | colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); 80 | colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f); 81 | colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 0.00f); 82 | colors[ImGuiCol_ButtonHovered] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); 83 | colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); 84 | colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f); 85 | colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); 86 | colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); 87 | colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); 88 | colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); 89 | colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); 90 | colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); 91 | colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); 92 | colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); 93 | colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); 94 | colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); 95 | colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); 96 | colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); 97 | colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); 98 | colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); 99 | colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); 100 | colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); 101 | colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); 102 | colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); 103 | colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); 104 | colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); 105 | colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); 106 | colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); 107 | colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); 108 | } 109 | 110 | void UserInterfaceClass::Init() 111 | { 112 | WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("Loader"), NULL }; 113 | ::RegisterClassEx(&wc); 114 | int x = GetSystemMetrics(SM_CXSCREEN) / 2 - LOADERW / 2; // cetner screen x 115 | int y = GetSystemMetrics(SM_CYSCREEN) / 2 - LOADERH / 2; // center screen y 116 | HWND hwnd = ::CreateWindowExW(WS_EX_LAYERED, (LPCWSTR)wc.lpszClassName, (LPCWSTR)STR("Loader"), WS_POPUP, x, y, LOADERW, LOADERH, NULL, NULL, wc.hInstance, NULL); 117 | 118 | SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY); 119 | 120 | // Initialize Direct3D 121 | if (!CreateDeviceD3D(hwnd)) 122 | { 123 | CleanupDeviceD3D(); 124 | ::UnregisterClass(wc.lpszClassName, wc.hInstance); 125 | return; 126 | } 127 | 128 | // Show the window 129 | ::ShowWindow(hwnd, SW_SHOWDEFAULT); 130 | ::UpdateWindow(hwnd); 131 | 132 | // Setup Dear ImGui context 133 | IMGUI_CHECKVERSION(); 134 | ImGui::CreateContext(); 135 | ImGuiIO& io = ImGui::GetIO(); 136 | io.Fonts->AddFontFromMemoryTTF(&LogoFont, sizeof LogoFont, 15); 137 | ImFont* Logo = io.Fonts->AddFontFromMemoryTTF(&LogoFont, sizeof LogoFont, 18); 138 | ImFont* Main = io.Fonts->AddFontFromMemoryTTF(&OtherFont, sizeof OtherFont, 18); 139 | ImFont* Icon = io.Fonts->AddFontFromMemoryTTF(&IconFont, sizeof IconFont, 24); 140 | 141 | ImGui::GetStyle().WindowRounding = 0.0f; 142 | ImGui::GetStyle().WindowPadding = ImVec2(0.0f, 0.0f); 143 | ImGui::GetStyle().ChildRounding = 0.0f; 144 | ImGui::GetStyle().WindowBorderSize = 0.0f; 145 | ImGui::GetStyle().WindowTitleAlign = ImVec2(0.5, 0.5); 146 | ImGui::GetStyle().PopupBorderSize = 0.0f; 147 | 148 | // Setup Platform/Renderer bindings 149 | ImGui_ImplWin32_Init(hwnd); 150 | ImGui_ImplDX9_Init(g_pd3dDevice); 151 | 152 | // Load Fonts 153 | // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. 154 | // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. 155 | // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). 156 | // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. 157 | // - Read 'docs/FONTS.md' for more instructions and details. 158 | // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! 159 | //io.Fonts->AddFontDefault(); 160 | //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); 161 | //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); 162 | //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); 163 | //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); 164 | //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); 165 | //IM_ASSERT(font != NULL); 166 | 167 | UserInterface->Theme(); 168 | 169 | // Our state 170 | static bool opened = true; 171 | 172 | // Main loop 173 | MSG msg; 174 | ZeroMemory(&msg, sizeof(msg)); 175 | while (msg.message != WM_QUIT) 176 | { 177 | // Poll and handle messages (inputs, window resize, etc.) 178 | // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 179 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 180 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 181 | // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 182 | if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 183 | { 184 | ::TranslateMessage(&msg); 185 | ::DispatchMessage(&msg); 186 | continue; 187 | } 188 | 189 | // Start the Dear ImGui frame 190 | ImGui_ImplDX9_NewFrame(); 191 | ImGui_ImplWin32_NewFrame(); 192 | ImGui::NewFrame(); 193 | 194 | ImGui::SetNextWindowPos(ImVec2(0, 0)); 195 | ImGui::SetNextWindowSize(ImVec2(LOADERW, LOADERH)); 196 | 197 | ImGui::Begin(STR("Loader"), &opened, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoDecoration); // Create a window called "Hello, world!" and append into it. 198 | { 199 | ImGui::SetCursorPos(ImVec2(0, 0)); 200 | UserInterface->RenderUI(Logo, Main, Icon); 201 | } 202 | ImGui::End(); 203 | 204 | ImGui::EndFrame(); 205 | g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 206 | g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 207 | g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 208 | g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, NULL, 1.0f, 0); 209 | if (g_pd3dDevice->BeginScene() >= 0) 210 | { 211 | ImGui::Render(); 212 | ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); 213 | g_pd3dDevice->EndScene(); 214 | } 215 | HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 216 | 217 | if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) 218 | ResetDevice(); 219 | 220 | if (!opened) msg.message = WM_QUIT; 221 | } 222 | 223 | ImGui_ImplDX9_Shutdown(); 224 | ImGui_ImplWin32_Shutdown(); 225 | ImGui::DestroyContext(); 226 | 227 | CleanupDeviceD3D(); 228 | ::DestroyWindow(hwnd); 229 | ::UnregisterClass(wc.lpszClassName, wc.hInstance); 230 | } 231 | 232 | void UserInterfaceClass::RenderTabs(ImFont* Logo, ImFont* Icon) 233 | { 234 | ImGui::PushFont(Logo); 235 | ImGui::SetCursorPos(ImVec2(5, 30)); 236 | ImGui::Text(STR("Intertwined")); 237 | ImGui::PushFont(Icon); 238 | 239 | if (ImGui::Button(STR("2"), ImVec2(130, 42))) 240 | CurrentTab = 0; 241 | 242 | if (ImGui::Button(STR("3"), ImVec2(130, 42))) 243 | CurrentTab = 1; 244 | 245 | ImGui::PushFont(Logo); 246 | ImGui::SetCursorPosY(400); 247 | 248 | if (ImGui::Button(STR("Close"), ImVec2(130, 42))) 249 | ExitProcess(0); 250 | 251 | ImGui::PopFont(); 252 | } 253 | 254 | void UserInterfaceClass::RenderUI(ImFont* Logo, ImFont* Main, ImFont* Icon) 255 | { 256 | ImGui::BeginChild(STR("TabsBar"), ImVec2(130, 450)); 257 | { 258 | RenderTabs(Logo, Icon); 259 | } 260 | ImGui::EndChild(); 261 | 262 | 263 | ImGui::PushFont(Main); 264 | ImGui::SetCursorPos(ImVec2(146, 40)); 265 | 266 | switch (CurrentTab) 267 | { 268 | case 0: 269 | { 270 | ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(0, 52), ImVec2(130, 94), ImGui::ColorConvertFloat4ToU32(ImVec4(0.00f, 0.00f, 2.55f, 0.1f))); 271 | ImGui::BeginChild(STR("MainWindow"), ImVec2(440, 388)); 272 | { 273 | if (Auth.Data.LoggedIn) { 274 | ImGui::PushItemWidth(22); 275 | ImGui::SetCursorPos(ImVec2(148, 10)); 276 | 277 | ImGui::Text(STR(" Welcome %s"), Data.Username); 278 | 279 | ImGui::PushItemWidth(22); 280 | ImGui::SetCursorPos(ImVec2(125, 125)); 281 | ImGui::Text(STR("Game")); 282 | 283 | const char* Games[] = { "CSGO", "CSGO (L)" }; 284 | ImGui::SetCursorPos(ImVec2(125, 150)); 285 | ImGui::PushItemWidth(200); 286 | ImGui::Combo(STR("##Game"), &Data.Game, Games, IM_ARRAYSIZE(Games)); 287 | 288 | if (Data.Beta) { 289 | ImGui::SetCursorPos(ImVec2(125, 250)); 290 | ImGui::Checkbox("Beta", &Data.SelectedBeta); 291 | } 292 | 293 | ImGui::SetCursorPos(ImVec2(125, 300)); 294 | if (ImGui::Button(STR("Inject"), ImVec2(165, 40))) { 295 | 296 | if (Utils::GetPid(STR("csgo.exe"))) 297 | Data.ShouldInject = true; 298 | else 299 | MessageBoxA(NULL, STR("Please open CS:GO"), STR("Intertwined Client"), MB_OK); 300 | } 301 | } 302 | else { 303 | ImGui::SetCursorPos(ImVec2(165, 38)); 304 | ImGui::PushItemWidth(22); 305 | ImGui::Text(STR(" Username")); 306 | ImGui::PushItemWidth(401); 307 | ImGui::SetCursorPos(ImVec2(19, 60)); 308 | ImGui::InputText(STR("###Username"), Data.Username, IM_ARRAYSIZE(Data.Username)); 309 | 310 | ImGui::SetCursorPos(ImVec2(165, 100)); 311 | ImGui::PushItemWidth(22); 312 | ImGui::Text(STR(" Password")); 313 | ImGui::PushItemWidth(401); 314 | ImGui::SetCursorPos(ImVec2(19, 130)); 315 | ImGui::InputText(STR("###Password"), Data.Password, IM_ARRAYSIZE(Data.Password), ImGuiInputTextFlags_Password); 316 | 317 | ImGui::PopItemWidth(); 318 | ImGui::SetCursorPos(ImVec2(125, 200)); 319 | 320 | if (ImGui::Button(STR("Sign in"), ImVec2(165, 40))) 321 | { 322 | if (Auth.Login(Data.Username, Data.Password)) { 323 | if (Data.SaveLogin) 324 | SaveLogin(Data.Username, Data.Password); 325 | 326 | Data.Admin = Auth.User.Sub == STR("admin"); 327 | Data.Beta = Auth.User.Sub == STR("beta") || STR("mod") || Data.Admin; 328 | } 329 | 330 | else 331 | ASSERT_ERROR(Auth.Data.ErrorMsg.c_str(), STR("[ERR:003B00]")) 332 | } 333 | 334 | ImGui::PopItemWidth(); 335 | ImGui::SetCursorPos(ImVec2(100, 250)); 336 | 337 | if (LoginDataExists() && ImGui::Button(STR("Sign in using saved data"), ImVec2(200, 40))) 338 | { 339 | GetLogin(); 340 | 341 | if (Auth.Login(Data.LoginData.first, Data.LoginData.second)) { 342 | Data.Admin = Auth.User.Sub == STR("admin"); 343 | Data.Beta = Auth.User.Sub != STR("normal"); 344 | } 345 | 346 | else { 347 | std::filesystem::remove(STR("C:\\ProgramData\\int.data")); 348 | ASSERT_ERROR(Auth.Data.ErrorMsg.c_str(), STR("[ERR:003B00]")); 349 | } 350 | 351 | } 352 | } 353 | 354 | } 355 | ImGui::EndChild(); 356 | 357 | break; 358 | } 359 | case 1: { 360 | ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(0, 98), ImVec2(130, 140), ImGui::ColorConvertFloat4ToU32(ImVec4(0.00f, 0.00f, 2.55f, 0.1f))); 361 | 362 | ImGui::BeginChild(STR("Options"), ImVec2(440, 388)); 363 | { 364 | ImGui::SetCursorPos(ImVec2(25, 25)); 365 | ImGui::Checkbox(STR("Save password"), &Data.SaveLogin); 366 | ImGui::SetCursorPosX(25); 367 | ImGui::Checkbox(STR("Automatically inject"), &Data.AutoInject); 368 | } 369 | ImGui::EndChild(); 370 | 371 | break; 372 | } 373 | 374 | default: 375 | break; 376 | } 377 | 378 | } 379 | } -------------------------------------------------------------------------------- /UserInterface/UserInterface.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../includes.hpp" 3 | #include "../auth/Auth.hpp" 4 | 5 | namespace UI { 6 | 7 | inline static LPDIRECT3D9 g_pD3D = NULL; 8 | inline static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; 9 | inline static D3DPRESENT_PARAMETERS g_d3dpp = {}; 10 | 11 | inline bool CreateDeviceD3D(HWND hWnd) 12 | { 13 | if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) 14 | return false; 15 | 16 | // Create the D3DDevice 17 | ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); 18 | g_d3dpp.Windowed = TRUE; 19 | g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 20 | g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 21 | g_d3dpp.EnableAutoDepthStencil = TRUE; 22 | g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 23 | g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync 24 | //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate 25 | if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) 26 | return false; 27 | 28 | return true; 29 | } 30 | 31 | inline void CleanupDeviceD3D() 32 | { 33 | if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } 34 | if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; } 35 | } 36 | 37 | inline void ResetDevice() 38 | { 39 | ImGui_ImplDX9_InvalidateDeviceObjects(); 40 | HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); 41 | if (hr == D3DERR_INVALIDCALL) 42 | IM_ASSERT(0); 43 | ImGui_ImplDX9_CreateDeviceObjects(); 44 | } 45 | 46 | inline POINTS m_Pos; // store user click pos 47 | 48 | inline void SaveLogin(const char* User, const char* Pass) { 49 | std::fstream DataFile; 50 | DataFile.open(STR("C:\\ProgramData\\loader.data"), std::ios::out); 51 | 52 | // encrypt this 53 | DataFile << User << std::endl << Pass << std::endl; 54 | 55 | DataFile.close(); 56 | } 57 | 58 | inline bool LoginDataExists() { 59 | std::fstream DataFile; 60 | // decrypt this 61 | DataFile.open(STR("C:\\ProgramData\\loader.data"), std::ios::in); 62 | 63 | return !DataFile.fail(); 64 | } 65 | 66 | struct UserData { 67 | 68 | char Username[255]; 69 | char Password[255]; 70 | 71 | std::pair LoginData; 72 | 73 | bool Admin = false; 74 | bool Beta = false; 75 | bool SelectedBeta = false; 76 | bool ShouldInject = false; 77 | bool SaveLogin = false; 78 | bool AutoInject = false; 79 | 80 | int Game = 1; 81 | }; 82 | 83 | class UserInterfaceClass 84 | { 85 | public: 86 | UserData Data; 87 | 88 | void Init(); 89 | void Theme(); 90 | void RenderUI(ImFont* Logo, ImFont* Main, ImFont* Icon); 91 | 92 | private: 93 | 94 | void RenderTabs(ImFont* Logo, ImFont* Icon); 95 | 96 | inline void GetLogin() { 97 | 98 | std::string User, Pass; 99 | 100 | std::fstream DataFile; 101 | DataFile.open(std::string(STR("C:\\ProgramData\\int.data")), std::ios::in); 102 | 103 | DataFile >> User; 104 | DataFile >> Pass; 105 | 106 | DataFile.close(); 107 | 108 | Data.LoginData = std::make_pair(User, Pass); 109 | } 110 | 111 | int CurrentTab = 0; 112 | }; 113 | 114 | using UserInterfacePtr = std::unique_ptr; 115 | 116 | } 117 | 118 | extern UI::UserInterfacePtr UserInterface; 119 | extern KeyAuth::api Auth; 120 | 121 | #define ASSERT_ERROR(Error, Code, ...) { char Buffer[1024 * 16]; sprintf_s(Buffer, sizeof Buffer, Error, __VA_ARGS__); char Buffer2[1024 * 16]; sprintf_s(Buffer2, sizeof Buffer2, Code, __VA_ARGS__); MessageBoxA(NULL, Buffer, Buffer2, MB_SYSTEMMODAL | MB_ICONERROR); ExitProcess(0); } -------------------------------------------------------------------------------- /Utils/FileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "FileReader.hpp" 2 | 3 | bool FileReader::Start(const char* FileName) 4 | { 5 | std::ifstream File(FileName, std::ios::in | std::ios::binary); 6 | 7 | // File does not exist/is not open. 8 | if (!File.is_open()) 9 | return false; 10 | 11 | // Do not skip white-space, read file. 12 | File.unsetf(std::ios::skipws); 13 | m_Contents.insert( 14 | m_Contents.begin(), 15 | std::istream_iterator(File), 16 | std::istream_iterator() 17 | ); 18 | 19 | if (m_Contents.empty()) 20 | return false; 21 | 22 | // Close the handle. 23 | File.close(); 24 | 25 | return true; 26 | } 27 | -------------------------------------------------------------------------------- /Utils/FileReader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using ByteArray = std::vector< uint8_t >; 9 | 10 | class FileReader 11 | { 12 | // Contents of the file. 13 | ByteArray m_Contents; 14 | 15 | public: 16 | FileReader() = default; 17 | 18 | // Constructor (ignores exception-handling). 19 | FileReader(const char* FileName) { Start(FileName); } 20 | 21 | // Read a file. 22 | bool Start(const char* FileName); 23 | 24 | // Self-explanatory. 25 | size_t GetFileLength() { return m_Contents.size(); } 26 | 27 | // Allow the user to walk the data. 28 | operator uint8_t* () { return m_Contents.data(); } 29 | }; -------------------------------------------------------------------------------- /Utils/Utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../includes.hpp" 3 | 4 | #pragma warning(disable : 4996) 5 | 6 | inline nlohmann::json response_decoder; 7 | 8 | namespace Utils { 9 | 10 | inline std::string RandomString(const int len) { 11 | const std::string alpha_numeric(STR("ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvz123456789")); 12 | std::default_random_engine generator{ std::random_device{}() }; 13 | const std::uniform_int_distribution< std::string::size_type > distribution{ 0, alpha_numeric.size() - 1 }; 14 | std::string str(len, 0); 15 | for (auto& it : str) { 16 | it = alpha_numeric[distribution(generator)]; 17 | } 18 | 19 | return str; 20 | } 21 | 22 | inline int RandomInt(int min, int max) 23 | { 24 | int range = max - min + 1; 25 | return LI_FN(rand).Get()() % range + min; 26 | } 27 | 28 | inline DWORD_PTR GetPid(const std::string process_name) { 29 | PROCESSENTRY32 process_info; 30 | process_info.dwSize = sizeof(process_info); 31 | 32 | HANDLE snapshot = LI_FN(CreateToolhelp32Snapshot).Get()(TH32CS_SNAPPROCESS, NULL); 33 | if (snapshot == INVALID_HANDLE_VALUE) 34 | return 0; 35 | 36 | LI_FN(Process32First).Get()(snapshot, &process_info); 37 | if (!process_name.compare((const char*)process_info.szExeFile)) { 38 | LI_FN(CloseHandle).Get()(snapshot); 39 | return process_info.th32ProcessID; 40 | } 41 | 42 | while (LI_FN(Process32Next).Get()(snapshot, &process_info)) { 43 | if (!process_name.compare((const char*)process_info.szExeFile)) { 44 | LI_FN(CloseHandle).Get()(snapshot); 45 | return process_info.th32ProcessID; 46 | } 47 | } 48 | 49 | LI_FN(CloseHandle).Get()(snapshot); 50 | 51 | return 0; 52 | } 53 | 54 | inline void AdminPrint(const char* message, ...) 55 | { 56 | if (!UserInterface->Data.Admin) 57 | return; 58 | 59 | std::string to_print = message; to_print.append(STR("\n")); 60 | printf(to_print.c_str()); 61 | } 62 | 63 | inline std::wstring StringToWString(const std::string& str) { 64 | std::wstring_convert> myconv; 65 | return myconv.from_bytes(str); 66 | } 67 | 68 | inline std::string GetPcName() { 69 | char acUserName[100]; 70 | DWORD nUserName = sizeof(acUserName); 71 | LI_FN(GetUserNameA)(acUserName, &nUserName); 72 | return acUserName; 73 | } 74 | 75 | #define SELF_REMOVE_STRING TEXT("cmd.exe /C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del /f /q \"%s\"") 76 | 77 | inline void Seppuku() { 78 | TCHAR szModuleName[MAX_PATH]; 79 | TCHAR szCmd[2 * MAX_PATH]; 80 | STARTUPINFO si = { 0 }; 81 | PROCESS_INFORMATION pi = { 0 }; 82 | 83 | GetModuleFileName(NULL, szModuleName, MAX_PATH); 84 | 85 | StringCbPrintf(szCmd, 2 * MAX_PATH, STR(SELF_REMOVE_STRING), szModuleName); 86 | 87 | CreateProcess(NULL, szCmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); 88 | 89 | LI_FN(CloseHandle)(pi.hThread); 90 | LI_FN(CloseHandle)(pi.hProcess); 91 | } 92 | } -------------------------------------------------------------------------------- /auth/Auth.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | #include "../xorstr.h" 29 | 30 | #pragma comment(lib, "rpcrt4.lib") 31 | 32 | namespace KeyAuth { 33 | 34 | class encryption { 35 | public: 36 | std::string name; 37 | static std::string encrypt_string(const std::string& plain_text, const std::string& key, const std::string& iv) { 38 | std::string cipher_text; 39 | 40 | try { 41 | CryptoPP::CBC_Mode::Encryption encryption; 42 | encryption.SetKeyWithIV((CryptoPP::byte*)key.c_str(), key.size(), (CryptoPP::byte*)iv.c_str()); 43 | 44 | CryptoPP::StringSource encryptor(plain_text, true, 45 | new CryptoPP::StreamTransformationFilter(encryption, 46 | new CryptoPP::HexEncoder( 47 | new CryptoPP::StringSink(cipher_text), 48 | false 49 | ) 50 | ) 51 | ); 52 | } 53 | catch (CryptoPP::Exception& ex) { 54 | exit(5000); 55 | } 56 | return cipher_text; 57 | } 58 | 59 | static std::string decrypt_string(const std::string& cipher_text, const std::string& key, const std::string& iv) { 60 | std::string plain_text; 61 | 62 | try { 63 | CryptoPP::CBC_Mode::Decryption decryption; 64 | decryption.SetKeyWithIV((CryptoPP::byte*)key.c_str(), key.size(), (CryptoPP::byte*)iv.c_str()); 65 | 66 | CryptoPP::StringSource decryptor(cipher_text, true, 67 | new CryptoPP::HexDecoder( 68 | new CryptoPP::StreamTransformationFilter(decryption, 69 | new CryptoPP::StringSink(plain_text) 70 | ) 71 | ) 72 | ); 73 | } 74 | catch (CryptoPP::Exception& ex) { 75 | exit(5000); 76 | } 77 | return plain_text; 78 | } 79 | 80 | static std::string sha256(const std::string& plain_text) { 81 | std::string hashed_text; 82 | CryptoPP::SHA256 hash; 83 | 84 | try { 85 | CryptoPP::StringSource hashing(plain_text, true, 86 | new CryptoPP::HashFilter(hash, 87 | new CryptoPP::HexEncoder( 88 | new CryptoPP::StringSink(hashed_text), 89 | false 90 | ) 91 | ) 92 | ); 93 | } 94 | catch (CryptoPP::Exception& ex) { 95 | exit(5000); 96 | } 97 | 98 | return hashed_text; 99 | } 100 | 101 | static std::string encode(const std::string& plain_text) { 102 | std::string encoded_text; 103 | 104 | try { 105 | CryptoPP::StringSource encoding(plain_text, true, 106 | new CryptoPP::HexEncoder( 107 | new CryptoPP::StringSink(encoded_text), 108 | false 109 | ) 110 | ); 111 | } 112 | catch (CryptoPP::Exception& ex) { 113 | exit(5000); 114 | } 115 | 116 | return encoded_text; 117 | } 118 | 119 | static std::string decode(const std::string& encoded_text) { 120 | std::string out; 121 | 122 | try { 123 | CryptoPP::StringSource decoding(encoded_text, true, 124 | new CryptoPP::HexDecoder( 125 | new CryptoPP::StringSink(out) 126 | ) 127 | ); 128 | } 129 | catch (CryptoPP::Exception& ex) { 130 | exit(5000); 131 | } 132 | 133 | return out; 134 | } 135 | 136 | static std::string iv_key() { 137 | UUID uuid = { 0 }; 138 | std::string guid; 139 | 140 | ::UuidCreate(&uuid); 141 | 142 | RPC_CSTR szUuid = NULL; 143 | if (::UuidToStringA(&uuid, &szUuid) == RPC_S_OK) 144 | { 145 | guid = (char*)szUuid; 146 | ::RpcStringFreeA(&szUuid); 147 | } 148 | 149 | return guid.substr(0, 16); 150 | } 151 | 152 | static std::string encrypt(std::string message, std::string enc_key, std::string iv) { 153 | enc_key = sha256(enc_key).substr(0, 32); 154 | iv = sha256(iv).substr(0, 16); 155 | return encrypt_string(message, enc_key, iv); 156 | } 157 | 158 | static std::string decrypt(std::string message, std::string enc_key, std::string iv) { 159 | enc_key = sha256(enc_key).substr(0, 32); 160 | 161 | iv = sha256(iv).substr(0, 16); 162 | 163 | return decrypt_string(message, enc_key, iv); 164 | } 165 | }; 166 | 167 | class utils { 168 | public: 169 | 170 | static std::string get_hwid() { 171 | ATL::CAccessToken accessToken; 172 | ATL::CSid currentUserSid; 173 | if (accessToken.GetProcessToken(TOKEN_READ | TOKEN_QUERY) && 174 | accessToken.GetUser(¤tUserSid)) 175 | return std::string(CT2A(currentUserSid.Sid())); 176 | } 177 | 178 | static std::time_t string_to_timet(std::string timestamp) { 179 | auto cv = strtol(timestamp.c_str(), NULL, 10); 180 | 181 | return (time_t)cv; 182 | } 183 | 184 | static std::tm timet_to_tm(time_t timestamp) { 185 | std::tm context; 186 | 187 | localtime_s(&context, ×tamp); 188 | 189 | return context; 190 | } 191 | 192 | static ByteArray to_uc_vector(std::string value) { 193 | return std::vector(value.data(), value.data() + value.length() + 1); 194 | } 195 | 196 | }; 197 | 198 | 199 | inline auto iv = encryption::sha256(encryption::iv_key()); 200 | class api { 201 | 202 | 203 | public: 204 | 205 | std::string name, ownerid, secret, version; 206 | 207 | api(std::string name, std::string ownerid, std::string secret, std::string version) 208 | : name(name), ownerid(ownerid), secret(secret), version(version) {} 209 | 210 | bool Init() 211 | { 212 | enckey = encryption::sha256(encryption::iv_key()); 213 | 214 | auto data = 215 | STR("type=") + encryption::encode(STR("init")) + 216 | STR("&ver=") + encryption::encrypt(version, secret, iv) + 217 | STR("&hash=") + encryption::encode(STR("NULL")) + 218 | STR("&enckey=") + encryption::encrypt(enckey, secret, iv) + 219 | STR("&name=") + encryption::encode(name) + 220 | STR("&ownerid=") + encryption::encode(ownerid) + 221 | STR("&init_iv=") + iv; 222 | 223 | auto response = req(data); 224 | response = encryption::decrypt(response, secret, iv); 225 | auto json = response_decoder.parse(response); 226 | 227 | if (json[("success")]) 228 | { 229 | sessionid = json[("sessionid")]; 230 | load_app_data(json[("appinfo")]); 231 | Data.Initiated = true; 232 | 233 | return true; 234 | } 235 | else if (json[("message")] == "invalidver") 236 | { 237 | Data.InvalidVer = true; 238 | MessageBoxA(NULL, STR("New loader version detected. Click OK to download new version. "), STR("Intertwined Client"), MB_OK); 239 | 240 | std::string dl = json[("download")]; 241 | ShellExecuteA(0, "open", dl.c_str(), 0, 0, SW_SHOWNORMAL); 242 | return false; 243 | } 244 | else { 245 | Data.ErrorMsg = json[("message")]; 246 | return false; 247 | } 248 | } 249 | 250 | bool Login(std::string username, std::string password) 251 | { 252 | std::string hwid = utils::get_hwid(); 253 | auto iv = encryption::sha256(encryption::iv_key()); 254 | auto data = 255 | STR("type=") + encryption::encode(STR("login")) + 256 | STR("&username=") + encryption::encrypt(username, enckey, iv) + 257 | STR("&pass=") + encryption::encrypt(password, enckey, iv) + 258 | STR("&hwid=") + encryption::encrypt(hwid, enckey, iv) + 259 | STR("&sessionid=") + encryption::encode(sessionid) + 260 | STR("&name=") + encryption::encode(name) + 261 | STR("&ownerid=") + encryption::encode(ownerid) + 262 | STR("&init_iv=") + iv; 263 | 264 | auto response = req(data); 265 | response = encryption::decrypt(response, enckey, iv); 266 | 267 | auto json = response_decoder.parse(response); 268 | 269 | if (json[("success")]) 270 | { 271 | load_user_data(json[("info")]); 272 | Data.LoggedIn = true; 273 | return true; 274 | } 275 | else if (json[("message")] == STR("The user is banned")) 276 | { 277 | Data.Banned = true; 278 | return false; 279 | } 280 | else 281 | { 282 | Data.ErrorMsg = json[("message")]; 283 | return false; 284 | } 285 | } 286 | 287 | void SetVar(const std::string var, const std::string vardata) { 288 | 289 | auto iv = encryption::sha256(encryption::iv_key()); 290 | auto data = 291 | STR("type=") + encryption::encode(STR("setvar")) + 292 | STR("&var=") + encryption::encrypt(var, enckey, iv) + 293 | STR("&data=") + encryption::encrypt(vardata, enckey, iv) + 294 | STR("&sessionid=") + encryption::encode(sessionid) + 295 | STR("&name=") + encryption::encode(name) + 296 | STR("&ownerid=") + encryption::encode(ownerid) + 297 | STR("&init_iv=") + iv; 298 | 299 | auto response = req(data); 300 | response = encryption::decrypt(response, enckey, iv); 301 | auto json = response_decoder.parse(response); 302 | 303 | if (!json[("success")]) 304 | Data.ErrorMsg = json[("message")]; 305 | } 306 | 307 | std::string GetVar(const std::string var) { 308 | 309 | auto iv = encryption::sha256(encryption::iv_key()); 310 | auto data = 311 | STR("type=") + encryption::encode(STR("getvar")) + 312 | STR("&var=") + encryption::encrypt(var, enckey, iv) + 313 | STR("&sessionid=") + encryption::encode(sessionid) + 314 | STR("&name=") + encryption::encode(name) + 315 | STR("&ownerid=") + encryption::encode(ownerid) + 316 | STR("&init_iv=") + iv; 317 | auto response = req(data); 318 | response = encryption::decrypt(response, enckey, iv); 319 | auto json = response_decoder.parse(response); 320 | 321 | if (json[("success")]) 322 | { 323 | return json[("response")]; 324 | } 325 | else { 326 | Data.ErrorMsg = json[("message")]; 327 | return STR("NULL"); 328 | } 329 | } 330 | 331 | std::string Variable(const std::string var) { 332 | 333 | 334 | auto iv = encryption::sha256(encryption::iv_key()); 335 | auto data = 336 | STR("type=") + encryption::encode(STR("var")) + 337 | STR("&varid=") + encryption::encrypt(var, enckey, iv) + 338 | STR("&sessionid=") + encryption::encode(sessionid) + 339 | STR("&name=") + encryption::encode(name) + 340 | STR("&ownerid=") + encryption::encode(ownerid) + 341 | STR("&init_iv=") + iv; 342 | 343 | auto response = req(data); 344 | response = encryption::decrypt(response, secret, iv); 345 | 346 | auto json = response_decoder.parse(response); 347 | return json[("success")] ? json[("message")] : "NULL"; 348 | } 349 | 350 | bool CheckBlacklisted() { 351 | std::string hwid = utils::get_hwid(); 352 | auto iv = encryption::sha256(encryption::iv_key()); 353 | auto data = 354 | STR("type=") + encryption::encode(STR("checkblacklist")) + 355 | STR("&hwid=") + encryption::encrypt(hwid, enckey, iv) + 356 | STR("&sessionid=") + encryption::encode(sessionid) + 357 | STR("&name=") + encryption::encode(name) + 358 | STR("&ownerid=") + encryption::encode(ownerid) + 359 | STR("&init_iv=") + iv; 360 | 361 | auto response = req(data); 362 | response = encryption::decrypt(response, enckey, iv); 363 | 364 | auto json = response_decoder.parse(response); 365 | return json[("success")]; 366 | } 367 | 368 | bool CheckExistingSession() { 369 | std::string hwid = utils::get_hwid(); 370 | auto iv = encryption::sha256(encryption::iv_key()); 371 | auto data = 372 | STR("type=") + encryption::encode(STR("check")) + 373 | STR("&sessionid=") + encryption::encode(sessionid) + 374 | STR("&name=") + encryption::encode(name) + 375 | STR("&ownerid=") + encryption::encode(ownerid) + 376 | STR("&init_iv=") + iv; 377 | 378 | auto response = req(data); 379 | response = encryption::decrypt(response, enckey, iv); 380 | 381 | auto json = response_decoder.parse(response); 382 | return json[("success")]; 383 | } 384 | 385 | void BanUser() { 386 | 387 | if (!Data.LoggedIn) 388 | return; 389 | 390 | auto iv = encryption::sha256(encryption::iv_key()); 391 | std::string hwid = utils::get_hwid(); 392 | 393 | auto data = 394 | STR("type=") + encryption::encode(STR("ban")) + 395 | STR("&sessionid=") + encryption::encode(sessionid) + 396 | STR("&name=") + encryption::encode(name) + 397 | STR("&ownerid=") + encryption::encode(ownerid) + 398 | STR("&init_iv=") + iv; 399 | 400 | req(data); 401 | } 402 | 403 | void Log(std::string message) { 404 | 405 | auto iv = encryption::sha256(encryption::iv_key()); 406 | 407 | char acUserName[100]; 408 | DWORD nUserName = sizeof(acUserName); 409 | GetUserNameA(acUserName, &nUserName); 410 | std::string UsernamePC = acUserName; 411 | 412 | auto data = 413 | STR("type=") + encryption::encode(STR("log")) + 414 | STR("&pcuser=") + encryption::encrypt(UsernamePC, enckey, iv) + 415 | STR("&message=") + encryption::encrypt(message, enckey, iv) + 416 | STR("&sessionid=") + encryption::encode(sessionid) + 417 | STR("&name=") + encryption::encode(name) + 418 | STR("&ownerid=") + encryption::encode(ownerid) + 419 | STR("&init_iv=") + iv; 420 | 421 | req(data); 422 | } 423 | 424 | ByteArray Download(std::string fileid) { 425 | auto iv = encryption::sha256(encryption::iv_key()); 426 | 427 | auto data = 428 | STR("type=") + encryption::encode(STR("file")) + 429 | STR("&fileid=") + encryption::encrypt(fileid, enckey, iv) + 430 | STR("&sessionid=") + encryption::encode(sessionid) + 431 | STR("&name=") + encryption::encode(name) + 432 | STR("&ownerid=") + encryption::encode(ownerid) + 433 | STR("&init_iv=") + iv; 434 | 435 | auto response = req(data); 436 | response = encryption::decrypt(response, enckey, iv); 437 | auto json = response_decoder.parse(response); 438 | 439 | if (!json["success"]) 440 | { 441 | Data.ErrorMsg = json[("message")]; 442 | return { }; 443 | } 444 | 445 | auto file = encryption::decode(json["contents"]); 446 | 447 | return utils::to_uc_vector(file); 448 | } 449 | 450 | ByteArray RecieveData(bool beta) 451 | { 452 | auto iv = encryption::sha256(encryption::iv_key()); 453 | auto to_uc_vector = [](std::string value) { 454 | return std::vector(value.data(), value.data() + value.length() + 1); 455 | }; 456 | 457 | std::string fileid = beta ? STR("BETAFILEID") : STR("FILEID"); 458 | 459 | auto data = 460 | STR("type=") + encryption::encode(STR("file")) + 461 | STR("&fileid=") + encryption::encrypt(fileid, enckey, iv) + 462 | STR("&sessionid=") + encryption::encode(sessionid) + 463 | STR("&name=") + encryption::encode(name) + 464 | STR("&ownerid=") + encryption::encode(ownerid) + 465 | STR("&init_iv=") + iv; 466 | 467 | auto response = req(data); 468 | response = encryption::decrypt(response, enckey, iv); 469 | auto json = response_decoder.parse(response); 470 | 471 | if (!json["success"]) { 472 | Data.ErrorMsg = json[("message")]; 473 | return to_uc_vector(nullptr); 474 | } 475 | 476 | return to_uc_vector(encryption::decode(json["contents"])); 477 | } 478 | 479 | ByteArray RecieveLegacyData(bool beta) 480 | { 481 | auto iv = encryption::sha256(encryption::iv_key()); 482 | auto to_uc_vector = [](std::string value) { 483 | return std::vector(value.data(), value.data() + value.length() + 1); 484 | }; 485 | 486 | std::string fileid = beta ? STR("BETAFILEID") : STR("FILEID"); 487 | 488 | auto data = 489 | STR("type=") + encryption::encode(STR("file")) + 490 | STR("&fileid=") + encryption::encrypt(fileid, enckey, iv) + 491 | STR("&sessionid=") + encryption::encode(sessionid) + 492 | STR("&name=") + encryption::encode(name) + 493 | STR("&ownerid=") + encryption::encode(ownerid) + 494 | STR("&init_iv=") + iv; 495 | 496 | auto response = req(data); 497 | response = encryption::decrypt(response, enckey, iv); 498 | auto json = response_decoder.parse(response); 499 | 500 | if (!json["success"]) { 501 | Data.ErrorMsg = json[("message")]; 502 | return to_uc_vector(nullptr); 503 | } 504 | 505 | return to_uc_vector(encryption::decode(json["contents"])); 506 | } 507 | 508 | class user_data_class { 509 | public: 510 | std::string Name, Ip, Sub, HWID; 511 | }; 512 | 513 | class app_data_class { 514 | public: 515 | std::string TotalUsers, UsersOnline, Version, TotalLicenses; 516 | }; 517 | 518 | class data_class { 519 | public: 520 | std::string ErrorMsg; 521 | bool LoggedIn, Banned, InvalidVer, Initiated; 522 | }; 523 | 524 | 525 | data_class Data; 526 | user_data_class User; 527 | app_data_class App; 528 | private: 529 | std::string sessionid, enckey; 530 | 531 | static size_t write_callback(void* contents, size_t size, size_t nmemb, void* userp) { 532 | ((std::string*)userp)->append((char*)contents, size * nmemb); 533 | return size * nmemb; 534 | } 535 | 536 | static std::string req(std::string data) { 537 | 538 | CURL* curl = curl_easy_init(); 539 | 540 | if (!curl) 541 | return STR("NULL"); 542 | 543 | std::string to_return; 544 | 545 | curl_easy_setopt(curl, CURLOPT_URL, STR("https://keyauth.win/api/1.0/")); 546 | 547 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); 548 | curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); 549 | 550 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); 551 | 552 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); 553 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &to_return); 554 | 555 | auto code = curl_easy_perform(curl); 556 | 557 | if (code != CURLE_OK) 558 | MessageBoxA(0, curl_easy_strerror(code), 0, MB_ICONERROR); 559 | 560 | curl_easy_cleanup(curl); 561 | 562 | long http_code = 0; 563 | curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); 564 | 565 | if (http_code == 429) { 566 | std::this_thread::sleep_for(std::chrono::seconds(1)); 567 | return req(data); 568 | } 569 | 570 | return to_return; 571 | } 572 | 573 | class user_data_structure { 574 | public: 575 | std::string Name, Ip, Sub, HWID; 576 | }; 577 | 578 | class app_data_structure { 579 | public: 580 | std::string TotalUsers, UsersOnline, Version, TotalLicenses; 581 | }; 582 | 583 | class data_structure { 584 | public: 585 | std::string ErrorMsg; 586 | bool LoggedIn, Banned, InvalidVer; 587 | }; 588 | 589 | void load_user_data(nlohmann::json data) { 590 | User.Name = data["username"]; 591 | User.Ip = data["ip"]; 592 | User.Sub = data["subscriptions"][0]["subscription"]; 593 | User.HWID = data["hwid"]; 594 | } 595 | 596 | void load_app_data(nlohmann::json data) { 597 | App.TotalUsers = data["numUsers"]; 598 | App.UsersOnline = data["numOnlineUsers"]; 599 | App.TotalLicenses = data["numKeys"]; 600 | App.Version = data["version"]; 601 | } 602 | 603 | nlohmann::json response_decoder; 604 | 605 | }; 606 | } 607 | -------------------------------------------------------------------------------- /includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #pragma comment(lib, "d3d9.lib") 4 | 5 | #define DIRECTINPUT_VERSION 0x0800 6 | 7 | #define LOADERW 600 8 | #define LOADERH 450 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include "xorstr.h" 33 | 34 | #include "Utils/FileReader.hpp" 35 | 36 | #include "UserInterface/ImGui/stringimgui.h" 37 | #include "UserInterface/ImGui/imgui.h" 38 | #include "UserInterface/ImGui/imgui_impl_dx9.h" 39 | #include "UserInterface/ImGui/imgui_impl_win32.h" 40 | #include "UserInterface/ImGui/imgui_internal.h" 41 | #include "UserInterface/ImGui/imstb_rectpack.h" 42 | 43 | #include "UserInterface/Fonts/Icons.h" 44 | #include "UserInterface/Fonts/Font.h" 45 | #include "UserInterface/Fonts/SecondFont.h" 46 | 47 | #include "UserInterface/UserInterface.hpp" 48 | 49 | #include "ManualMap/Map.hpp" 50 | 51 | #include "Security/LazyImporter.hpp" 52 | #include "Security/Security.hpp" 53 | 54 | #pragma comment(lib, "dwmapi.lib") 55 | 56 | #define LOADER_VER "1.01" 57 | 58 | #define NULLSTR ("NULL") 59 | 60 | inline HANDLE CurrentProc; 61 | inline HMODULE NtDLL; 62 | 63 | #define WRAP_IF_RELEASE( s ) { s; } 64 | #define WRAP_IF_DEBUG( s ) -------------------------------------------------------------------------------- /loader-ui.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30611.23 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loader", "loader-ui.vcxproj", "{94966CBC-57B0-4B28-A485-F7520859145D}" 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 | {94966CBC-57B0-4B28-A485-F7520859145D}.Debug|x64.ActiveCfg = Debug|x64 17 | {94966CBC-57B0-4B28-A485-F7520859145D}.Debug|x64.Build.0 = Debug|x64 18 | {94966CBC-57B0-4B28-A485-F7520859145D}.Debug|x86.ActiveCfg = Debug|Win32 19 | {94966CBC-57B0-4B28-A485-F7520859145D}.Debug|x86.Build.0 = Debug|Win32 20 | {94966CBC-57B0-4B28-A485-F7520859145D}.Release|x64.ActiveCfg = Release|x64 21 | {94966CBC-57B0-4B28-A485-F7520859145D}.Release|x64.Build.0 = Release|x64 22 | {94966CBC-57B0-4B28-A485-F7520859145D}.Release|x86.ActiveCfg = Release|Win32 23 | {94966CBC-57B0-4B28-A485-F7520859145D}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {9F7F07B2-7274-4140-9CBA-6ABD4A7FF995} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /loader-ui.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 | {833D6C00-E880-452C-9ECA-00F506273F41} 24 | Win32Proj 25 | example 26 | 10.0.18362.0 27 | csgo-loader 28 | 29 | 30 | 31 | Application 32 | false 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 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | $(ProjectDir)/Dependencies/directx/Include;$(ProjectDir)/Dependencies/cryptopp/include;$(ProjectDir)/Dependencies/curl/include;$(ProjectDir)/Dependencies/json/include;$(ProjectDir)/Dependencies/openssl/include;$(ProjectDir)/Dependencies/Themidia/Include;$(ProjectDir)/Dependencies/registry;$(IncludePath) 77 | $(ProjectDir)/Dependencies/directx/Lib;$(ProjectDir)/Dependencies/cryptopp/lib;$(ProjectDir)/Dependencies/curl/lib;$(ProjectDir)/Dependencies/openssl/lib;$(ProjectDir)/Dependencies;$(ProjectDir)/Dependencies/Themidia/Lib;$(LibraryPath) 78 | 79 | 80 | false 81 | $(ProjectDir)/Dependencies/directx/Include;$(ProjectDir)/Dependencies/cryptopp/include;$(ProjectDir)/Dependencies/curl/include;$(ProjectDir)/Dependencies/json/include;$(ProjectDir)/Dependencies/openssl/include;$(ProjectDir)/Dependencies/Themidia/Include;$(ProjectDir)/Dependencies/registry;$(IncludePath) 82 | $(ProjectDir)/Dependencies/directx/Lib;$(ProjectDir)/Dependencies/cryptopp/lib;$(ProjectDir)/Dependencies/curl/lib;$(ProjectDir)/Dependencies/openssl/lib;$(ProjectDir)/Dependencies;$(ProjectDir)/Dependencies/Themidia/Lib;$(LibraryPath) 83 | 84 | 85 | true 86 | 87 | 88 | false 89 | 90 | 91 | 92 | TurnOffAllWarnings 93 | true 94 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 95 | true 96 | stdcpp17 97 | 98 | 99 | Windows 100 | true 101 | 102 | 103 | 104 | 105 | 106 | 107 | Level1 108 | true 109 | true 110 | true 111 | WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) 112 | true 113 | SyncCThrow 114 | stdcpp17 115 | 116 | 117 | Windows 118 | true 119 | true 120 | true 121 | ./Dependencies/cryptopp/lib/cryptopp-static.lib;./Dependencies/curl/lib/libcurl.lib;./Dependencies/openssl/lib/libcrypto.lib;./Dependencies/openssl/lib/libssl.lib;./Dependencies/zlib.lib;Normaliz.lib;Ws2_32.lib;Wldap32.lib;Crypt32.lib;advapi32.lib;%(AdditionalDependencies) 122 | RequireAdministrator 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | true 131 | 132 | 133 | Console 134 | true 135 | 136 | 137 | 138 | 139 | Level3 140 | true 141 | true 142 | true 143 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 144 | true 145 | 146 | 147 | Console 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /loader-ui.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "includes.hpp" 5 | 6 | #include "UserInterface/UserInterface.hpp" 7 | #include "Utils/Utils.hpp" 8 | 9 | #include 10 | 11 | /* 12 | NOTES: 13 | Themida macros - may error if optimization is on for that function 14 | Refrence: https://www.oreans.com/help/tm/hm_faq_when-i-use-macros-directly-aro.htm 15 | 16 | Themida is included into this source, which requires this library in the same directory 17 | https://cdn.discordapp.com/attachments/1003540719895592981/1008544405625516062/SecureEngineSDK32.rar 18 | This includes SecureEngineSDK32.dll, which can be found in Themida\ThemidaSDK (InstallDir\ThemidaSDK) 19 | 20 | */ 21 | 22 | int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int) 23 | { 24 | CurrentProc = LI_FN(GetCurrentProcess).Get()(); 25 | NtDLL = LI_FN(LoadLibraryA).Get()(STR("ntdll.dll")); 26 | 27 | // Initiate auth. 28 | if (!Auth.Init() && !Auth.Data.InvalidVer) 29 | ASSERT_ERROR(Auth.Data.ErrorMsg.c_str(), STR("[ERR:001A00]")); 30 | 31 | if (Auth.CheckBlacklisted()) 32 | RuntimeSecurity->SecurityCallback(STR("Blacklisted.")); 33 | 34 | // hide console 35 | LI_FN(AllocConsole)(); 36 | LI_FN(ShowWindow)(FindWindowA(STR("ConsoleWindowClass"), NULL), false); 37 | 38 | FileReader File; 39 | 40 | if (!File.Start(STR("SecureEngineSDK32.dll"))) 41 | ASSERT_ERROR(STR("Unable to find needed DLLs, please reinstall. If this happens repeatedly contact an administrator."), STR("[ERR:003A00]")); 42 | 43 | if (!RuntimeSecurity->Init()) 44 | ASSERT_ERROR(STR("Unable to initialize."), STR("[ERR:004A00]")); 45 | 46 | // Initiate UI. 47 | std::thread UserInterfaceThread([&] { UserInterface->Init(); }); UserInterfaceThread.detach(); 48 | 49 | auto Inject = [&]() -> void 50 | { 51 | DWORD PID = Utils::GetPid(STR("csgo.exe")); 52 | if (!PID) 53 | ASSERT_ERROR(STR("Unable to find CS:GO."), STR("[ERR:001B00]")); 54 | 55 | HANDLE hProc = LI_FN(OpenProcess).Get()(PROCESS_ALL_ACCESS, FALSE, PID); 56 | 57 | ByteArray Internal = UserInterface->Data.Game ? Auth.RecieveLegacyData(UserInterface->Data.SelectedBeta) : Auth.RecieveData(UserInterface->Data.SelectedBeta); 58 | if (!ManualMap(hProc, &Internal[0])) 59 | ASSERT_ERROR(STR("Unable to inject."), STR("[ERR:002B00]")); 60 | 61 | Internal.clear(); 62 | }; 63 | 64 | // Allow the user to login. 65 | while (!Auth.Data.LoggedIn) { LI_FN(Sleep)(1); } 66 | 67 | if (UserInterface->Data.AutoInject) 68 | { 69 | while (!Utils::GetPid(STR("csgo.exe"))) { LI_FN(Sleep)(1); } 70 | 71 | LI_FN(Sleep)(1000); 72 | 73 | Inject(); 74 | } 75 | 76 | while (!UserInterface->Data.ShouldInject) { LI_FN(Sleep)(1); } 77 | 78 | Inject(); 79 | 80 | LI_FN(ExitProcess)(1); 81 | return 1; 82 | } 83 | -------------------------------------------------------------------------------- /xorstr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 - 2021 Justas Masiulis 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef JM_XORSTR_HPP 18 | #define JM_XORSTR_HPP 19 | 20 | #if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__) 21 | #include 22 | #elif defined(_M_X64) || defined(__amd64__) || defined(_M_IX86) || defined(__i386__) 23 | #include 24 | #else 25 | #error Unsupported platform 26 | #endif 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #define STR__(str) ::jm::xor_string([]() { return str; }, std::integral_constant{}, std::make_index_sequence<::jm::detail::_buffer_size()>{}) 34 | #define STR(str) STR__(str).crypt_get() 35 | 36 | #ifdef _MSC_VER 37 | #define XORSTR_FORCEINLINE __forceinline 38 | #else 39 | #define XORSTR_FORCEINLINE __attribute__((always_inline)) inline 40 | #endif 41 | 42 | namespace jm { 43 | 44 | namespace detail { 45 | 46 | template 47 | XORSTR_FORCEINLINE constexpr std::size_t _buffer_size() 48 | { 49 | return ((Size / 16) + (Size % 16 != 0)) * 2; 50 | } 51 | 52 | template 53 | XORSTR_FORCEINLINE constexpr std::uint32_t key4() noexcept 54 | { 55 | std::uint32_t value = Seed; 56 | for (char c : __TIME__) 57 | value = static_cast((value ^ c) * 16777619ull); 58 | return value; 59 | } 60 | 61 | template 62 | XORSTR_FORCEINLINE constexpr std::uint64_t key8() 63 | { 64 | constexpr auto first_part = key4<2166136261 + S>(); 65 | constexpr auto second_part = key4(); 66 | return (static_cast(first_part) << 32) | second_part; 67 | } 68 | 69 | // loads up to 8 characters of string into uint64 and xors it with the key 70 | template 71 | XORSTR_FORCEINLINE constexpr std::uint64_t 72 | load_xored_str8(std::uint64_t key, std::size_t idx, const CharT* str) noexcept 73 | { 74 | using cast_type = typename std::make_unsigned::type; 75 | constexpr auto value_size = sizeof(CharT); 76 | constexpr auto idx_offset = 8 / value_size; 77 | 78 | std::uint64_t value = key; 79 | for (std::size_t i = 0; i < idx_offset && i + idx * idx_offset < N; ++i) 80 | value ^= 81 | (std::uint64_t{ static_cast(str[i + idx * idx_offset]) } 82 | << ((i % idx_offset) * 8 * value_size)); 83 | 84 | return value; 85 | } 86 | 87 | // forces compiler to use registers instead of stuffing constants in rdata 88 | XORSTR_FORCEINLINE std::uint64_t load_from_reg(std::uint64_t value) noexcept 89 | { 90 | #if defined(__clang__) || defined(__GNUC__) 91 | asm("" : "=r"(value) : "0"(value) : ); 92 | return value; 93 | #else 94 | volatile std::uint64_t reg = value; 95 | return reg; 96 | #endif 97 | } 98 | 99 | } // namespace detail 100 | 101 | template 102 | class xor_string; 103 | 104 | template 105 | class xor_string, std::index_sequence> { 106 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS 107 | constexpr static inline std::uint64_t alignment = ((Size > 16) ? 32 : 16); 108 | #else 109 | constexpr static inline std::uint64_t alignment = 16; 110 | #endif 111 | 112 | alignas(alignment) std::uint64_t _storage[sizeof...(Keys)]; 113 | 114 | public: 115 | using value_type = CharT; 116 | using size_type = std::size_t; 117 | using pointer = CharT*; 118 | using const_pointer = const CharT*; 119 | 120 | template 121 | XORSTR_FORCEINLINE xor_string(L l, std::integral_constant, std::index_sequence) noexcept 122 | : _storage{ ::jm::detail::load_from_reg((std::integral_constant(Keys, Indices, l())>::value))... } 123 | {} 124 | 125 | XORSTR_FORCEINLINE constexpr size_type size() const noexcept 126 | { 127 | return Size - 1; 128 | } 129 | 130 | XORSTR_FORCEINLINE void crypt() noexcept 131 | { 132 | // everything is inlined by hand because a certain compiler with a certain linker is _very_ slow 133 | #if defined(__clang__) 134 | alignas(alignment) 135 | std::uint64_t arr[]{ ::jm::detail::load_from_reg(Keys)... }; 136 | std::uint64_t* keys = 137 | (std::uint64_t*)::jm::detail::load_from_reg((std::uint64_t)arr); 138 | #else 139 | alignas(alignment) std::uint64_t keys[]{ ::jm::detail::load_from_reg(Keys)... }; 140 | #endif 141 | 142 | #if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__) 143 | #if defined(__clang__) 144 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : __builtin_neon_vst1q_v( 145 | reinterpret_cast(_storage) + Indices * 2, 146 | veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast(_storage) + Indices * 2, 51), 147 | __builtin_neon_vld1q_v(reinterpret_cast(keys) + Indices * 2, 51)), 148 | 51)), ...); 149 | #else // GCC, MSVC 150 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : vst1q_u64( 151 | reinterpret_cast(_storage) + Indices * 2, 152 | veorq_u64(vld1q_u64(reinterpret_cast(_storage) + Indices * 2), 153 | vld1q_u64(reinterpret_cast(keys) + Indices * 2)))), ...); 154 | #endif 155 | #elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS) 156 | ((Indices >= sizeof(_storage) / 32 ? static_cast(0) : _mm256_store_si256( 157 | reinterpret_cast<__m256i*>(_storage) + Indices, 158 | _mm256_xor_si256( 159 | _mm256_load_si256(reinterpret_cast(_storage) + Indices), 160 | _mm256_load_si256(reinterpret_cast(keys) + Indices)))), ...); 161 | 162 | if constexpr (sizeof(_storage) % 32 != 0) 163 | _mm_store_si128( 164 | reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2), 165 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage + sizeof...(Keys) - 2)), 166 | _mm_load_si128(reinterpret_cast(keys + sizeof...(Keys) - 2)))); 167 | #else 168 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : _mm_store_si128( 169 | reinterpret_cast<__m128i*>(_storage) + Indices, 170 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage) + Indices), 171 | _mm_load_si128(reinterpret_cast(keys) + Indices)))), ...); 172 | #endif 173 | } 174 | 175 | XORSTR_FORCEINLINE const_pointer get() const noexcept 176 | { 177 | return reinterpret_cast(_storage); 178 | } 179 | 180 | XORSTR_FORCEINLINE pointer get() noexcept 181 | { 182 | return reinterpret_cast(_storage); 183 | } 184 | 185 | XORSTR_FORCEINLINE pointer crypt_get() noexcept 186 | { 187 | // crypt() is inlined by hand because a certain compiler with a certain linker is _very_ slow 188 | #if defined(__clang__) 189 | alignas(alignment) 190 | std::uint64_t arr[]{ ::jm::detail::load_from_reg(Keys)... }; 191 | std::uint64_t* keys = 192 | (std::uint64_t*)::jm::detail::load_from_reg((std::uint64_t)arr); 193 | #else 194 | alignas(alignment) std::uint64_t keys[]{ ::jm::detail::load_from_reg(Keys)... }; 195 | #endif 196 | 197 | #if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__) 198 | #if defined(__clang__) 199 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : __builtin_neon_vst1q_v( 200 | reinterpret_cast(_storage) + Indices * 2, 201 | veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast(_storage) + Indices * 2, 51), 202 | __builtin_neon_vld1q_v(reinterpret_cast(keys) + Indices * 2, 51)), 203 | 51)), ...); 204 | #else // GCC, MSVC 205 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : vst1q_u64( 206 | reinterpret_cast(_storage) + Indices * 2, 207 | veorq_u64(vld1q_u64(reinterpret_cast(_storage) + Indices * 2), 208 | vld1q_u64(reinterpret_cast(keys) + Indices * 2)))), ...); 209 | #endif 210 | #elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS) 211 | ((Indices >= sizeof(_storage) / 32 ? static_cast(0) : _mm256_store_si256( 212 | reinterpret_cast<__m256i*>(_storage) + Indices, 213 | _mm256_xor_si256( 214 | _mm256_load_si256(reinterpret_cast(_storage) + Indices), 215 | _mm256_load_si256(reinterpret_cast(keys) + Indices)))), ...); 216 | 217 | if constexpr (sizeof(_storage) % 32 != 0) 218 | _mm_store_si128( 219 | reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2), 220 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage + sizeof...(Keys) - 2)), 221 | _mm_load_si128(reinterpret_cast(keys + sizeof...(Keys) - 2)))); 222 | #else 223 | ((Indices >= sizeof(_storage) / 16 ? static_cast(0) : _mm_store_si128( 224 | reinterpret_cast<__m128i*>(_storage) + Indices, 225 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(_storage) + Indices), 226 | _mm_load_si128(reinterpret_cast(keys) + Indices)))), ...); 227 | #endif 228 | 229 | return (pointer)(_storage); 230 | } 231 | }; 232 | 233 | template 234 | xor_string(L l, std::integral_constant, std::index_sequence)->xor_string< 235 | std::remove_const_t>, 236 | Size, 237 | std::integer_sequence()...>, 238 | std::index_sequence>; 239 | 240 | } // namespace jm 241 | 242 | #endif // include guard --------------------------------------------------------------------------------