├── Images.h ├── Variables.h ├── screenshot ├── unknown.png └── Screenshot_20.png ├── ImGUIHook.vcxproj.user ├── README.md ├── ImGui ├── imgui_impl_dx9.h ├── imgui_impl_win32.h ├── imconfig.h ├── imgui_impl_win32.cpp ├── imgui_impl_dx9.cpp ├── imstb_rectpack.h └── imstb_textedit.h ├── Functions.h ├── ImGUIHook.sln ├── Hook.h ├── ImGUIHook.vcxproj.filters ├── Cursor.h ├── ImGUIHook.vcxproj ├── Main.cpp └── Detours.h /Images.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /Variables.h: -------------------------------------------------------------------------------- 1 | // GENERAL 2 | static float f = 0.0f; 3 | static int counter = 0; 4 | static int switchTabs; -------------------------------------------------------------------------------- /screenshot/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SepulTura35/ImGui-Cheat-Base-ex-CyberHunter/HEAD/screenshot/unknown.png -------------------------------------------------------------------------------- /screenshot/Screenshot_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SepulTura35/ImGui-Cheat-Base-ex-CyberHunter/HEAD/screenshot/Screenshot_20.png -------------------------------------------------------------------------------- /ImGUIHook.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImGui-Cheat-Base-ex-CyberHunter 2 | ImGui Cheat Base with DirectX, this source also have Cyber Hunter cheat in their code. 3 | 4 | Check out the screenshot folder to review other in-game footage. (Ex: Zula, Cyber Hunter etc.) 5 | -------------------------------------------------------------------------------- /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 in imgui.cpp. 6 | 7 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 8 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 9 | // https://github.com/ocornut/imgui 10 | 11 | #pragma once 12 | 13 | struct IDirect3DDevice9; 14 | 15 | IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); 16 | IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); 17 | IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); 18 | IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); 19 | 20 | // Use if you want to reset your rendering device without losing ImGui state. 21 | IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects(); 22 | IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); 23 | -------------------------------------------------------------------------------- /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 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 | // Missing features: 9 | // [ ] Platform: Gamepad support (best leaving it to user application to fill io.NavInputs[] with gamepad inputs from their source of choice). 10 | 11 | #pragma once 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 | // Handler for Win32 messages, update mouse/keyboard data. 18 | // You may or not need this for your implementation, but it can serve as reference for handling inputs. 19 | // Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead. 20 | /* 21 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 22 | */ 23 | -------------------------------------------------------------------------------- /Functions.h: -------------------------------------------------------------------------------- 1 | #pragma warning(disable: 4244) 2 | #pragma warning(disable: 4996) 3 | 4 | #define C_Text (DT_CENTER|DT_NOCLIP) 5 | #define L_Text (DT_LEFT|DT_NOCLIP) 6 | #define R_Text (DT_RIGHT|DT_NOCLIP) 7 | 8 | #define NOP 0x90 9 | 10 | #define KEY_Z 0x5A 11 | #define KEY_V 0x56 12 | #define KEY_T 0x54 13 | float ScreenCenterX; 14 | float ScreenCenterY; 15 | D3DVIEWPORT9 viewport; 16 | 17 | #include 18 | DWORD GetModule(LPCSTR name) 19 | { 20 | HANDLE SN = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); 21 | 22 | DWORD dwRetValue = 0x0; 23 | 24 | MODULEENTRY32 ME; 25 | ME.dwSize = sizeof(MODULEENTRY32); 26 | bool done = !Module32First(SN, &ME) ? true : false; 27 | 28 | while (!done) 29 | { 30 | if (strstr(ME.szModule, name)) 31 | { 32 | dwRetValue = (DWORD)ME.modBaseAddr; 33 | } 34 | 35 | done = !Module32Next(SN, &ME) ? true : false; 36 | } 37 | CloseHandle(SN); 38 | return dwRetValue; 39 | } 40 | 41 | ImU32 MyImU32(float Col[]) 42 | { 43 | ImU32 col32_no_alpha = ImGui::ColorConvertFloat4ToU32(ImVec4(Col[0], Col[1], Col[2], Col[3])); 44 | return col32_no_alpha; 45 | } 46 | 47 | namespace Helper 48 | { 49 | // custom helper function.. 50 | void WriteTextToFile(std::string str) 51 | { 52 | std::ofstream myfile; 53 | myfile.open("lithe.log"); 54 | myfile << (str + "\n").data(); 55 | myfile.close(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ImGUIHook.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30804.86 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XorHook", "ImGUIHook.vcxproj", "{ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}" 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 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Debug|x64.ActiveCfg = Debug|x64 17 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Debug|x64.Build.0 = Debug|x64 18 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Debug|x86.ActiveCfg = Debug|Win32 19 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Debug|x86.Build.0 = Debug|Win32 20 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Release|x64.ActiveCfg = Release|x64 21 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Release|x64.Build.0 = Release|x64 22 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Release|x86.ActiveCfg = Release|Win32 23 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {3BE362FD-4A9D-4C22-9ADD-018CF6DFA753} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Hook.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | typedef HRESULT(APIENTRY *SetStreamSource)(IDirect3DDevice9*, UINT, IDirect3DVertexBuffer9*, UINT, UINT); 4 | SetStreamSource SetStreamSource_orig = 0; 5 | 6 | typedef HRESULT(APIENTRY *DrawIndexedPrimitive)(IDirect3DDevice9*, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT); 7 | DrawIndexedPrimitive DrawIndexedPrimitive_orig = 0; 8 | 9 | typedef HRESULT(APIENTRY* Present) (IDirect3DDevice9*, const RECT *, const RECT *, HWND, const RGNDATA *); 10 | Present Present_orig = 0; 11 | 12 | typedef HRESULT(APIENTRY* EndScene) (IDirect3DDevice9*); 13 | EndScene EndScene_orig = 0; 14 | 15 | typedef HRESULT(APIENTRY *Reset)(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*); 16 | Reset Reset_orig = 0; 17 | 18 | bool Menu = true; 19 | HMODULE Hand; 20 | UINT Stride; 21 | HWND TargetWnd = NULL; 22 | WNDPROC oWndProc = NULL; 23 | 24 | #define Red D3DCOLOR_XRGB(223,43,43) 25 | #define Green D3DCOLOR_ARGB(215,000,255,000) 26 | #define Orange D3DCOLOR_ARGB(255, 255, 140, 000) 27 | #define Blue D3DCOLOR_XRGB(68,80,248) 28 | #define Yellow D3DCOLOR_ARGB(255, 255, 255, 51) 29 | #define Black D3DCOLOR_ARGB(255, 000, 000, 000) 30 | #define Grey D3DCOLOR_ARGB(255, 112, 112, 112) 31 | #define Gold D3DCOLOR_ARGB(255, 255, 215, 000) 32 | #define Pink D3DCOLOR_ARGB(255, 255, 192, 203) 33 | #define Purple D3DCOLOR_ARGB(255, 128, 000, 128) 34 | #define White D3DCOLOR_ARGB(255, 255, 255, 249) 35 | #define Cyan D3DCOLOR_ARGB(255, 000, 255, 255) 36 | #define Magenta D3DCOLOR_ARGB(255, 255, 000, 255) 37 | #define TBlack D3DCOLOR_ARGB(128, 000, 000, 000) 38 | 39 | 40 | /*CHEATS*/ 41 | 42 | static bool nosmoke = false; 43 | static bool noflash = false; 44 | static bool norecoil = false; 45 | static bool nospread = false; 46 | static bool fastreload = false; 47 | static bool fastswitch = false; 48 | static bool rapidfire = false; 49 | 50 | /*ESP*/ 51 | 52 | bool asd = 0; 53 | bool wallhack = 0; 54 | bool distanceesp = 0; 55 | bool espbox3d = 0; 56 | bool chams = 0; 57 | bool espb = 0; 58 | bool wiref = 0; 59 | bool espline = 0; 60 | bool esplogin = 0; 61 | bool cros = 0; 62 | bool xray = 0; 63 | bool bright = 0; 64 | bool fog = 0; 65 | bool name = 0; 66 | bool lineesp = 0; 67 | 68 | #pragma warning (disable: 4099) 69 | #if defined _M_X64 70 | #pragma comment(lib, "detours.X64/detours.lib") 71 | #elif defined _M_IX86 72 | #pragma comment(lib, "detours.X86/detours.lib") 73 | #endif 74 | 75 | 76 | -------------------------------------------------------------------------------- /ImGUIHook.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 6 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 7 | 8 | 9 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 10 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 11 | 12 | 13 | {792da054-1fd1-43e1-aa76-6f4c86073396} 14 | 15 | 16 | 17 | 18 | ImGui 19 | 20 | 21 | ImGui 22 | 23 | 24 | ImGui 25 | 26 | 27 | ImGui 28 | 29 | 30 | ImGui 31 | 32 | 33 | ImGui 34 | 35 | 36 | Main 37 | 38 | 39 | 40 | 41 | Hook 42 | 43 | 44 | ImGui 45 | 46 | 47 | ImGui 48 | 49 | 50 | ImGui 51 | 52 | 53 | ImGui 54 | 55 | 56 | ImGui 57 | 58 | 59 | ImGui 60 | 61 | 62 | ImGui 63 | 64 | 65 | ImGui 66 | 67 | 68 | Hook 69 | 70 | 71 | Hook 72 | 73 | 74 | Hook 75 | 76 | 77 | Hook 78 | 79 | 80 | Hook 81 | 82 | 83 | -------------------------------------------------------------------------------- /Cursor.h: -------------------------------------------------------------------------------- 1 | unsigned char MJCursor[1199] = { 2 | 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 3 | 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 4 | 0x08, 0x06, 0x00, 0x00, 0x01, 0x04, 0x7D, 0x4A, 0x62, 0x00, 0x00, 0x00, 5 | 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x12, 0x00, 0x00, 0x0B, 6 | 0x12, 0x01, 0xD2, 0xDD, 0x7E, 0xFC, 0x00, 0x00, 0x04, 0x61, 0x49, 0x44, 7 | 0x41, 0x54, 0x58, 0xC3, 0xB5, 0x57, 0x49, 0x68, 0x14, 0x41, 0x14, 0x9D, 8 | 0xE9, 0xC9, 0x32, 0xD9, 0xF7, 0x7D, 0x83, 0xC4, 0x44, 0x12, 0x12, 0x08, 9 | 0x09, 0x59, 0x0C, 0x1A, 0x03, 0x09, 0x98, 0xE4, 0x10, 0x9C, 0x98, 0xC5, 10 | 0x4B, 0x10, 0x72, 0xD0, 0x8B, 0x92, 0x9B, 0x20, 0x22, 0x82, 0x37, 0x45, 11 | 0x2F, 0x5E, 0x04, 0x8F, 0x01, 0xF1, 0x20, 0x7A, 0xD4, 0x83, 0xA8, 0x28, 12 | 0x82, 0x78, 0x12, 0x54, 0x3C, 0xE9, 0x51, 0xBD, 0x78, 0x89, 0xA2, 0xC6, 13 | 0xE9, 0xA5, 0x7C, 0x6F, 0xAC, 0x6A, 0x2A, 0x9D, 0xEE, 0x74, 0x4F, 0x4C, 14 | 0x3E, 0x7C, 0x66, 0xBA, 0xBA, 0xEA, 0xD7, 0xAB, 0xF7, 0x97, 0xFA, 0x1D, 15 | 0x8B, 0xC7, 0xE3, 0xCF, 0x63, 0x5E, 0xA9, 0xAF, 0xAF, 0x77, 0xF0, 0x73, 16 | 0x47, 0x1F, 0x10, 0x0D, 0x0D, 0x0D, 0xA2, 0xB6, 0xB6, 0xD6, 0xCE, 0x0C, 17 | 0xE4, 0xE6, 0xE6, 0xDA, 0xB1, 0x40, 0x69, 0x6C, 0x6C, 0x74, 0x30, 0xDD, 18 | 0xC2, 0xDF, 0x84, 0x1A, 0xFB, 0xC9, 0xF5, 0x50, 0xBE, 0x10, 0x99, 0x11, 19 | 0x3E, 0x60, 0x7B, 0x77, 0xD5, 0x20, 0xAC, 0x3B, 0xD8, 0xE9, 0x57, 0x90, 20 | 0xD9, 0x78, 0x61, 0x61, 0xA1, 0x50, 0x50, 0xB8, 0x7A, 0x72, 0x72, 0xD2, 21 | 0xC4, 0xF8, 0x11, 0xBE, 0x53, 0x93, 0xEA, 0xB8, 0x39, 0x27, 0x51, 0xF1, 22 | 0xFC, 0x8C, 0x83, 0x89, 0x44, 0x62, 0x8B, 0x25, 0x61, 0x18, 0xC6, 0x01, 23 | 0xBF, 0x2D, 0xCE, 0x42, 0x8D, 0xC0, 0x73, 0x71, 0xDF, 0x9E, 0x9E, 0x1E, 24 | 0x72, 0x53, 0xE5, 0x35, 0xA9, 0xC4, 0x94, 0xE0, 0xC4, 0xD4, 0xD4, 0x94, 25 | 0xD8, 0xF6, 0x96, 0xFB, 0x92, 0x5D, 0x35, 0xA9, 0xAA, 0xAA, 0x4A, 0xF4, 26 | 0xF6, 0xF6, 0x66, 0x26, 0xBA, 0x5C, 0x90, 0x07, 0x35, 0x41, 0x9E, 0xC4, 27 | 0x59, 0x5E, 0x5E, 0x76, 0xAD, 0x71, 0x9A, 0xE2, 0xC1, 0xA9, 0xAB, 0xAB, 28 | 0x13, 0xDA, 0xB8, 0x2B, 0xDF, 0xF8, 0x32, 0x99, 0x4C, 0x0A, 0xDD, 0x09, 29 | 0xBA, 0x94, 0xD0, 0x4A, 0xD0, 0xCB, 0x07, 0x2D, 0x2D, 0x2D, 0x9B, 0x50, 30 | 0x4E, 0x38, 0xA4, 0xCC, 0xEB, 0xCE, 0x0A, 0x95, 0x92, 0x92, 0x12, 0x17, 31 | 0x63, 0x75, 0x75, 0xB5, 0x33, 0x36, 0x36, 0x26, 0x8A, 0x8A, 0x8A, 0xDE, 32 | 0xF1, 0x5D, 0x41, 0x41, 0x81, 0x11, 0xB6, 0x9E, 0x13, 0x6E, 0xC3, 0x80, 33 | 0xA9, 0x39, 0xDC, 0x3D, 0x70, 0x77, 0x77, 0xB7, 0x39, 0x3E, 0x3E, 0x4E, 34 | 0x74, 0x6B, 0xDA, 0x7C, 0x5F, 0x11, 0x32, 0x1A, 0x85, 0x57, 0x69, 0x98, 35 | 0xEF, 0x6A, 0x6A, 0x6A, 0x9C, 0x95, 0x95, 0x15, 0xFE, 0x6E, 0xD2, 0xB3, 36 | 0x3A, 0x93, 0x24, 0xE7, 0x5A, 0x7E, 0x7E, 0x7E, 0x5A, 0x45, 0x94, 0xB6, 37 | 0xD8, 0x91, 0x06, 0x2C, 0x1C, 0x4F, 0x20, 0x1C, 0x3E, 0x62, 0x6E, 0x47, 38 | 0x20, 0x0A, 0x72, 0xA0, 0xF8, 0xA0, 0x96, 0x96, 0x96, 0x12, 0x7E, 0x7B, 39 | 0x79, 0x79, 0x79, 0x28, 0xB1, 0x39, 0xD0, 0x8B, 0x8C, 0xAD, 0xE6, 0xE6, 40 | 0x66, 0x01, 0xF2, 0x7C, 0x1D, 0x1E, 0x45, 0xB8, 0xF0, 0x46, 0x90, 0xCF, 41 | 0xB7, 0x6F, 0x9B, 0x93, 0xB3, 0x41, 0x66, 0x87, 0x87, 0x87, 0x99, 0x7A, 42 | 0xB1, 0xAC, 0x85, 0xC4, 0x74, 0x76, 0x76, 0x8A, 0xBC, 0xBC, 0xBC, 0xC7, 43 | 0x32, 0x82, 0x12, 0x59, 0x19, 0xC0, 0xC2, 0x0C, 0x59, 0x8C, 0x83, 0x81, 44 | 0x81, 0x01, 0xC2, 0xBF, 0xAA, 0x79, 0x26, 0x92, 0xAC, 0x37, 0x35, 0x35, 45 | 0x99, 0xCA, 0x5D, 0x1D, 0x1D, 0x1D, 0x66, 0x7F, 0x7F, 0x3F, 0x0D, 0x9D, 46 | 0x08, 0x0B, 0x1C, 0x25, 0xBD, 0x3C, 0x86, 0x96, 0xB4, 0x0C, 0x67, 0x01, 47 | 0x4E, 0xAC, 0xF6, 0xF6, 0x76, 0x1A, 0xEA, 0x8A, 0x42, 0xA4, 0x1B, 0x71, 48 | 0x7A, 0xE4, 0x21, 0xFB, 0x9D, 0xD9, 0xD9, 0x59, 0x81, 0x18, 0xF8, 0xCA, 49 | 0xA2, 0x3A, 0x3D, 0x3D, 0x1D, 0x2B, 0x2E, 0x2E, 0xF6, 0xB5, 0xF1, 0x47, 50 | 0xD5, 0x35, 0x6F, 0x08, 0x13, 0x11, 0xE2, 0xC2, 0x5E, 0x58, 0x58, 0x70, 51 | 0xEB, 0x9D, 0x97, 0x68, 0x3E, 0xDC, 0xAC, 0xA8, 0xA8, 0x48, 0x7B, 0x0D, 52 | 0xE8, 0x89, 0x85, 0xF8, 0x17, 0x23, 0x23, 0x23, 0xE6, 0xCC, 0xCC, 0x0C, 53 | 0x0D, 0x5D, 0xDF, 0x52, 0x7A, 0xA1, 0x2D, 0xB0, 0x2A, 0xA4, 0x37, 0x7C, 54 | 0x93, 0x89, 0x1C, 0x11, 0x25, 0xD4, 0x5C, 0x5C, 0x5C, 0xA4, 0x91, 0x59, 55 | 0x2F, 0x92, 0x6D, 0x06, 0xD4, 0x11, 0xD4, 0x62, 0xD4, 0x08, 0x2E, 0xBC, 56 | 0x1C, 0xC4, 0xE5, 0x06, 0x12, 0xC7, 0xD1, 0x89, 0x94, 0x0B, 0x4D, 0xB9, 57 | 0x70, 0x4C, 0x9D, 0xDF, 0x2F, 0xA9, 0x08, 0xE5, 0x0A, 0x34, 0xAD, 0x2D, 58 | 0xCE, 0xA4, 0x30, 0xC6, 0x5E, 0xAA, 0x39, 0xB8, 0xDB, 0x02, 0x3D, 0x49, 59 | 0x93, 0x95, 0x9E, 0x63, 0xF0, 0x3A, 0xB8, 0x94, 0x75, 0x26, 0xC2, 0xCF, 60 | 0x34, 0x90, 0xA6, 0x67, 0x10, 0x1F, 0x46, 0xB6, 0x06, 0xBE, 0xB0, 0x1E, 61 | 0x40, 0xBF, 0xC7, 0x76, 0x21, 0x2C, 0x28, 0xE7, 0x65, 0x3D, 0x88, 0x2E, 62 | 0xA8, 0x71, 0xEA, 0x16, 0x17, 0xA8, 0x07, 0x6F, 0x31, 0x94, 0x52, 0xEF, 63 | 0xC0, 0xBE, 0xA1, 0x92, 0x09, 0x21, 0x1D, 0xDB, 0x2F, 0x59, 0x63, 0xDD, 64 | 0xA4, 0xBB, 0x71, 0x0D, 0x30, 0x01, 0xAD, 0xBE, 0xBE, 0x3E, 0xC1, 0xB2, 65 | 0x08, 0x77, 0xAF, 0xE3, 0x7D, 0xA7, 0xC7, 0xDB, 0x7B, 0x2E, 0x49, 0xE8, 66 | 0x27, 0xA6, 0x0A, 0x58, 0xB0, 0x55, 0x3F, 0xC3, 0x2B, 0x04, 0x20, 0xCC, 67 | 0xC1, 0xC1, 0x41, 0xC1, 0x3A, 0x55, 0x59, 0x59, 0x49, 0xFF, 0x9C, 0x93, 68 | 0x54, 0xC7, 0x46, 0x47, 0x47, 0x19, 0x39, 0x46, 0x50, 0x72, 0x67, 0x2B, 69 | 0x67, 0x10, 0xA3, 0x04, 0x60, 0xA9, 0x30, 0xD4, 0x6F, 0x16, 0xB4, 0x0F, 70 | 0x04, 0x64, 0xA3, 0xAF, 0x30, 0x27, 0x26, 0x26, 0x78, 0x59, 0x0A, 0x44, 71 | 0xD8, 0x13, 0xAC, 0x3B, 0xEC, 0x61, 0x27, 0xBE, 0xA5, 0xEF, 0x88, 0x2A, 72 | 0x30, 0xCE, 0x53, 0x7D, 0x60, 0xC6, 0xC1, 0x15, 0xB6, 0x2A, 0xAE, 0xDE, 73 | 0xAC, 0x54, 0xE0, 0x58, 0xE6, 0xDA, 0xDA, 0xDA, 0x08, 0x86, 0x2D, 0x1B, 74 | 0xE7, 0xFC, 0xE6, 0xBD, 0x2A, 0x2F, 0x5B, 0x17, 0x10, 0x9A, 0xA3, 0x68, 75 | 0x71, 0x28, 0x7F, 0x4F, 0x31, 0x82, 0x41, 0xB5, 0xE5, 0x57, 0x1A, 0xFD, 76 | 0xCA, 0xA4, 0xBC, 0xED, 0xD9, 0xC6, 0x3A, 0x43, 0x43, 0x43, 0x66, 0x2A, 77 | 0x95, 0x62, 0x21, 0x17, 0xB8, 0xE0, 0xDF, 0xC3, 0xD6, 0x92, 0xDA, 0x40, 78 | 0xF6, 0x27, 0x19, 0x34, 0xAD, 0xAD, 0xAD, 0x81, 0x2C, 0x90, 0xB7, 0x37, 79 | 0x40, 0x2D, 0x18, 0x8C, 0x1E, 0x57, 0x44, 0x02, 0xC3, 0x5E, 0x06, 0x07, 80 | 0x10, 0x5D, 0x5D, 0x5D, 0x16, 0xC0, 0x58, 0xF3, 0xF3, 0xF3, 0x02, 0x4C, 81 | 0x31, 0x2D, 0xEF, 0x42, 0x0F, 0x7A, 0x2A, 0xCF, 0x76, 0x16, 0xE0, 0xBB, 82 | 0x93, 0x64, 0x01, 0x88, 0x6D, 0xBD, 0xF1, 0x0D, 0x03, 0xE1, 0x07, 0x88, 83 | 0xCA, 0x7E, 0x14, 0x6D, 0x9F, 0x33, 0x37, 0x37, 0x67, 0xAE, 0xAE, 0xAE, 84 | 0x0A, 0xC6, 0x0F, 0x6E, 0xA7, 0xCF, 0xD8, 0xA3, 0x6F, 0xA7, 0xFB, 0xF2, 85 | 0x15, 0x41, 0x94, 0x95, 0x95, 0xD1, 0x15, 0xA1, 0x00, 0xBC, 0x01, 0xAB, 86 | 0x57, 0x71, 0x16, 0x63, 0x3E, 0x63, 0x53, 0x81, 0x0B, 0x8B, 0xDF, 0x02, 87 | 0xF7, 0xA0, 0x93, 0x61, 0xB1, 0x70, 0x9C, 0x00, 0xC0, 0x86, 0xCD, 0x54, 88 | 0xF4, 0x6C, 0xE2, 0x7B, 0x52, 0xF9, 0xDF, 0x56, 0x0D, 0x9C, 0x6C, 0x95, 89 | 0x1F, 0x41, 0x17, 0x65, 0x9A, 0xAB, 0x4F, 0x1F, 0xE3, 0x5F, 0xED, 0x0B, 90 | 0x2F, 0x27, 0x4F, 0x09, 0x02, 0x3D, 0x8B, 0xA5, 0x03, 0xD0, 0x4F, 0xAB, 91 | 0x9F, 0x94, 0x54, 0xC3, 0x28, 0x3B, 0xAC, 0xD3, 0xCA, 0x00, 0x02, 0x31, 92 | 0xAE, 0xB9, 0x36, 0x7A, 0x65, 0x96, 0xBF, 0xC7, 0x64, 0x4D, 0x77, 0xD0, 93 | 0x7D, 0x3B, 0xCA, 0x15, 0xFA, 0x69, 0xA9, 0xFC, 0x8A, 0xC2, 0x9C, 0x5B, 94 | 0x9E, 0xFB, 0x60, 0xCF, 0xE4, 0xA1, 0x04, 0x61, 0x92, 0x56, 0x45, 0x37, 95 | 0x69, 0x96, 0x9D, 0xEB, 0x85, 0x4C, 0x19, 0x4D, 0x26, 0xE3, 0xBB, 0xE9, 96 | 0x60, 0xC3, 0x3E, 0x19, 0x28, 0x47, 0x15, 0x0B, 0x48, 0x4D, 0x07, 0x41, 97 | 0x69, 0xB2, 0x5A, 0xE2, 0xF9, 0x35, 0xBE, 0xDD, 0xE2, 0xBB, 0x6D, 0x9D, 98 | 0xA3, 0x8A, 0x32, 0x7C, 0x5F, 0x82, 0x48, 0xCB, 0xDF, 0xA5, 0xFD, 0xA0, 99 | 0x7A, 0x27, 0x00, 0xFC, 0xBE, 0xFD, 0x01, 0x7D, 0xB1, 0x53, 0x11, 0xF9, 100 | 0x1F, 0xF9, 0x0B, 0x70, 0x25, 0x0B, 0x6F, 0x7B, 0x39, 0x4F, 0x27, 0x00, 101 | 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 102 | }; 103 | -------------------------------------------------------------------------------- /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 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 52 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 53 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 54 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 55 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 56 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 57 | 58 | //---- 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. 59 | // 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. 60 | // #define IMGUI_USE_STB_SPRINTF 61 | 62 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 63 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 64 | /* 65 | #define IM_VEC2_CLASS_EXTRA \ 66 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 67 | operator MyVec2() const { return MyVec2(x,y); } 68 | 69 | #define IM_VEC4_CLASS_EXTRA \ 70 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 71 | operator MyVec4() const { return MyVec4(x,y,z,w); } 72 | */ 73 | 74 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 75 | // Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices). 76 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 77 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 78 | //#define ImDrawIdx unsigned int 79 | 80 | //---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly) 81 | //struct ImDrawList; 82 | //struct ImDrawCmd; 83 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 84 | //#define ImDrawCallback MyImDrawCallback 85 | 86 | //---- Debug Tools: Macro to break in Debugger 87 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 88 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 89 | //#define IM_DEBUG_BREAK __debugbreak() 90 | 91 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 92 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 93 | // This adds a small runtime cost which is why it is not enabled by default. 94 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 95 | 96 | //---- Debug Tools: Enable slower asserts 97 | //#define IMGUI_DEBUG_PARANOID 98 | 99 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 100 | /* 101 | namespace ImGui 102 | { 103 | void MyFunction(const char* name, const MyMatrix44& v); 104 | } 105 | */ 106 | -------------------------------------------------------------------------------- /ImGUIHook.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 | 15.0 23 | {ADC0170F-6DE7-41DF-A7F1-8686D8B2DFE3} 24 | Win32Proj 25 | SWBF2MultiHack 26 | 10.0.19041.0 27 | XorHook 28 | 29 | 30 | 31 | DynamicLibrary 32 | true 33 | v142 34 | MultiByte 35 | 36 | 37 | DynamicLibrary 38 | false 39 | v142 40 | true 41 | MultiByte 42 | 43 | 44 | DynamicLibrary 45 | true 46 | v142 47 | MultiByte 48 | 49 | 50 | DynamicLibrary 51 | false 52 | v142 53 | true 54 | MultiByte 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | $(SolutionDir)\ImGUIHook\Directories\Include;$(IncludePath) 77 | D:\Directories\Lib;$(LibraryWPath) 78 | $(SolutionDir)\ImGUIHook\Directories\Lib;$(LibraryPath) 79 | 80 | 81 | true 82 | 83 | C:\Users\105HYP\Desktop\ImGUIHook\ImGui\Directories\Include;$(IncludePath) 84 | C:\Users\105HYP\Desktop\ImGUIHook\ImGui\Directories\Lib;$(LibraryPath) 85 | 86 | 87 | false 88 | C:\Users\105HYP\Desktop\ImGUIHook\Directories\Include;$(IncludePath) 89 | C:\Users\105HYP\Desktop\ImGUIHook\Directories\Lib\x86;$(LibraryPath) 90 | 91 | 92 | false 93 | 94 | $(SolutionDir)\ImGUIHook\Directories\Include;$(IncludePath) 95 | $(SolutionDir)\ImGUIHook\Directories\Lib;$(LibraryPath) 96 | 97 | 98 | 99 | Level3 100 | Disabled 101 | WIN32;_DEBUG;SWBF2MULTIHACK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 102 | true 103 | 104 | 105 | true 106 | Windows 107 | 108 | 109 | 110 | 111 | Level3 112 | Disabled 113 | _DEBUG;SWBF2MULTIHACK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 114 | true 115 | 116 | 117 | true 118 | Windows 119 | 120 | 121 | 122 | 123 | TurnOffAllWarnings 124 | MaxSpeed 125 | true 126 | true 127 | WIN32;NDEBUG;SWBF2MULTIHACK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 128 | true 129 | 130 | 131 | true 132 | true 133 | true 134 | Windows 135 | false 136 | 137 | 138 | 139 | 140 | Level3 141 | MaxSpeed 142 | true 143 | true 144 | NDEBUG;SWBF2MULTIHACK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 145 | true 146 | 147 | 148 | true 149 | true 150 | true 151 | Windows 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 | -------------------------------------------------------------------------------- /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 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 | // Missing features: 9 | // [ ] Platform: Gamepad support (best leaving it to user application to fill io.NavInputs[] with gamepad inputs from their source of choice). 10 | 11 | #include "imgui.h" 12 | #include "imgui_impl_win32.h" 13 | #ifndef WIN32_LEAN_AND_MEAN 14 | #define WIN32_LEAN_AND_MEAN 15 | #endif 16 | #include 17 | #include 18 | 19 | // CHANGELOG 20 | // (minor and older changes stripped away, please see git history for details) 21 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 22 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 23 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). 24 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. 25 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. 26 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). 27 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 28 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 29 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 30 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 31 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. 32 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. 33 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. 34 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 35 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. 36 | 37 | // Win32 Data 38 | static HWND g_hWnd = 0; 39 | static INT64 g_Time = 0; 40 | static INT64 g_TicksPerSecond = 0; 41 | static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; 42 | 43 | // Functions 44 | bool ImGui_ImplWin32_Init(void* hwnd) 45 | { 46 | if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) 47 | return false; 48 | if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) 49 | return false; 50 | 51 | // Setup back-end capabilities flags 52 | g_hWnd = (HWND)hwnd; 53 | ImGuiIO& io = ImGui::GetIO(); 54 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 55 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 56 | io.BackendPlatformName = "imgui_impl_win32"; 57 | io.ImeWindowHandle = hwnd; 58 | 59 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. 60 | io.KeyMap[ImGuiKey_Tab] = VK_TAB; 61 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; 62 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; 63 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP; 64 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; 65 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; 66 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; 67 | io.KeyMap[ImGuiKey_Home] = VK_HOME; 68 | io.KeyMap[ImGuiKey_End] = VK_END; 69 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT; 70 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE; 71 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK; 72 | io.KeyMap[ImGuiKey_Space] = VK_SPACE; 73 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN; 74 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 75 | io.KeyMap[ImGuiKey_A] = 'A'; 76 | io.KeyMap[ImGuiKey_C] = 'C'; 77 | io.KeyMap[ImGuiKey_V] = 'V'; 78 | io.KeyMap[ImGuiKey_X] = 'X'; 79 | io.KeyMap[ImGuiKey_Y] = 'Y'; 80 | io.KeyMap[ImGuiKey_Z] = 'Z'; 81 | 82 | return true; 83 | } 84 | 85 | void ImGui_ImplWin32_Shutdown() 86 | { 87 | g_hWnd = (HWND)0; 88 | } 89 | 90 | static bool ImGui_ImplWin32_UpdateMouseCursor() 91 | { 92 | ImGuiIO& io = ImGui::GetIO(); 93 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 94 | return false; 95 | 96 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 97 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) 98 | { 99 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 100 | ::SetCursor(NULL); 101 | } 102 | else 103 | { 104 | // Show OS mouse cursor 105 | LPTSTR win32_cursor = IDC_ARROW; 106 | switch (imgui_cursor) 107 | { 108 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; 109 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; 110 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; 111 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; 112 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; 113 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; 114 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; 115 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; 116 | } 117 | ::SetCursor(::LoadCursor(NULL, win32_cursor)); 118 | } 119 | return true; 120 | } 121 | 122 | static void ImGui_ImplWin32_UpdateMousePos() 123 | { 124 | ImGuiIO& io = ImGui::GetIO(); 125 | 126 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 127 | if (io.WantSetMousePos) 128 | { 129 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; 130 | ::ClientToScreen(g_hWnd, &pos); 131 | ::SetCursorPos(pos.x, pos.y); 132 | } 133 | 134 | // Set mouse position 135 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 136 | POINT pos; 137 | if (::GetForegroundWindow() == g_hWnd && ::GetCursorPos(&pos)) 138 | if (::ScreenToClient(g_hWnd, &pos)) 139 | io.MousePos = ImVec2((float)pos.x, (float)pos.y); 140 | } 141 | 142 | void ImGui_ImplWin32_NewFrame() 143 | { 144 | ImGuiIO& io = ImGui::GetIO(); 145 | 146 | // Setup display size (every frame to accommodate for window resizing) 147 | RECT rect; 148 | ::GetClientRect(g_hWnd, &rect); 149 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); 150 | 151 | // Setup time step 152 | INT64 current_time; 153 | ::QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); 154 | io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; 155 | g_Time = current_time; 156 | 157 | // Read keyboard modifiers inputs 158 | io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; 159 | io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; 160 | io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; 161 | io.KeySuper = false; 162 | // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. 163 | 164 | // Update OS mouse position 165 | ImGui_ImplWin32_UpdateMousePos(); 166 | 167 | // Update OS mouse cursor with the cursor requested by imgui 168 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); 169 | if (g_LastMouseCursor != mouse_cursor) 170 | { 171 | g_LastMouseCursor = mouse_cursor; 172 | ImGui_ImplWin32_UpdateMouseCursor(); 173 | } 174 | } 175 | 176 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. 177 | #ifndef WM_MOUSEHWHEEL 178 | #define WM_MOUSEHWHEEL 0x020E 179 | #endif 180 | 181 | // Process Win32 mouse/keyboard inputs. 182 | // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 183 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 184 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 185 | // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 186 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. 187 | // 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. 188 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 189 | { 190 | if (ImGui::GetCurrentContext() == NULL) 191 | return 0; 192 | 193 | ImGuiIO& io = ImGui::GetIO(); 194 | switch (msg) 195 | { 196 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: 197 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: 198 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: 199 | { 200 | int button = 0; 201 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; 202 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1; 203 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2; 204 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) 205 | ::SetCapture(hwnd); 206 | io.MouseDown[button] = true; 207 | return 0; 208 | } 209 | case WM_LBUTTONUP: 210 | case WM_RBUTTONUP: 211 | case WM_MBUTTONUP: 212 | { 213 | int button = 0; 214 | if (msg == WM_LBUTTONUP) button = 0; 215 | if (msg == WM_RBUTTONUP) button = 1; 216 | if (msg == WM_MBUTTONUP) button = 2; 217 | io.MouseDown[button] = false; 218 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) 219 | ::ReleaseCapture(); 220 | return 0; 221 | } 222 | case WM_MOUSEWHEEL: 223 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 224 | return 0; 225 | case WM_MOUSEHWHEEL: 226 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 227 | return 0; 228 | case WM_KEYDOWN: 229 | case WM_SYSKEYDOWN: 230 | if (wParam < 256) 231 | io.KeysDown[wParam] = 1; 232 | return 0; 233 | case WM_KEYUP: 234 | case WM_SYSKEYUP: 235 | if (wParam < 256) 236 | io.KeysDown[wParam] = 0; 237 | return 0; 238 | case WM_CHAR: 239 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters. 240 | if (wParam > 0 && wParam < 0x10000) 241 | io.AddInputCharacter((unsigned short)wParam); 242 | return 0; 243 | case WM_SETCURSOR: 244 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) 245 | return 1; 246 | return 0; 247 | } 248 | return 0; 249 | } 250 | 251 | -------------------------------------------------------------------------------- /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 in imgui.cpp. 6 | 7 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 8 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 9 | // https://github.com/ocornut/imgui 10 | 11 | // CHANGELOG 12 | // (minor and older changes stripped away, please see git history for details) 13 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 14 | // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. 15 | // 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 16 | // 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. 17 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. 18 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 19 | 20 | #include "imgui.h" 21 | #include "imgui_impl_dx9.h" 22 | 23 | // DirectX 24 | #include 25 | #define DIRECTINPUT_VERSION 0x0800 26 | #include 27 | 28 | // DirectX data 29 | static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; 30 | static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; 31 | static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; 32 | static LPDIRECT3DTEXTURE9 g_FontTexture = NULL; 33 | static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; 34 | 35 | struct CUSTOMVERTEX 36 | { 37 | float pos[3]; 38 | D3DCOLOR col; 39 | float uv[2]; 40 | }; 41 | #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) 42 | 43 | // Render function. 44 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) 45 | void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) 46 | { 47 | // Avoid rendering when minimized 48 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 49 | return; 50 | 51 | // Create and grow buffers if needed 52 | if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 53 | { 54 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 55 | g_VertexBufferSize = draw_data->TotalVtxCount + 5000; 56 | if (g_pd3dDevice->CreateVertexBuffer(g_VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0) 57 | return; 58 | } 59 | if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) 60 | { 61 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 62 | g_IndexBufferSize = draw_data->TotalIdxCount + 10000; 63 | 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) 64 | return; 65 | } 66 | 67 | // Backup the DX9 state 68 | IDirect3DStateBlock9* d3d9_state_block = NULL; 69 | if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) 70 | return; 71 | 72 | // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) 73 | D3DMATRIX last_world, last_view, last_projection; 74 | g_pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); 75 | g_pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); 76 | g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); 77 | 78 | // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format. 79 | // FIXME-OPT: This is a waste of resource, the ideal is to use imconfig.h and 80 | // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR 81 | // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } 82 | CUSTOMVERTEX* vtx_dst; 83 | ImDrawIdx* idx_dst; 84 | if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) 85 | return; 86 | if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) 87 | return; 88 | for (int n = 0; n < draw_data->CmdListsCount; n++) 89 | { 90 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 91 | const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; 92 | for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) 93 | { 94 | vtx_dst->pos[0] = vtx_src->pos.x; 95 | vtx_dst->pos[1] = vtx_src->pos.y; 96 | vtx_dst->pos[2] = 0.0f; 97 | vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000) >> 16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9 98 | vtx_dst->uv[0] = vtx_src->uv.x; 99 | vtx_dst->uv[1] = vtx_src->uv.y; 100 | vtx_dst++; 101 | vtx_src++; 102 | } 103 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 104 | idx_dst += cmd_list->IdxBuffer.Size; 105 | } 106 | g_pVB->Unlock(); 107 | g_pIB->Unlock(); 108 | g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX)); 109 | g_pd3dDevice->SetIndices(g_pIB); 110 | g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); 111 | 112 | // Setup viewport 113 | D3DVIEWPORT9 vp; 114 | vp.X = vp.Y = 0; 115 | vp.Width = (DWORD)draw_data->DisplaySize.x; 116 | vp.Height = (DWORD)draw_data->DisplaySize.y; 117 | vp.MinZ = 0.0f; 118 | vp.MaxZ = 1.0f; 119 | g_pd3dDevice->SetViewport(&vp); 120 | 121 | // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient) 122 | g_pd3dDevice->SetPixelShader(NULL); 123 | g_pd3dDevice->SetVertexShader(NULL); 124 | g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 125 | g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false); 126 | g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); 127 | g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); 128 | g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); 129 | g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); 130 | g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 131 | g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 132 | g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true); 133 | g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 134 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 135 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 136 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 137 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 138 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 139 | g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 140 | g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 141 | g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 142 | 143 | // Setup orthographic projection matrix 144 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). 145 | // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() 146 | { 147 | float L = draw_data->DisplayPos.x + 0.5f; 148 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f; 149 | float T = draw_data->DisplayPos.y + 0.5f; 150 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f; 151 | 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 } }; 152 | D3DMATRIX mat_projection = 153 | { 154 | 2.0f/(R-L), 0.0f, 0.0f, 0.0f, 155 | 0.0f, 2.0f/(T-B), 0.0f, 0.0f, 156 | 0.0f, 0.0f, 0.5f, 0.0f, 157 | (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f, 158 | }; 159 | g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); 160 | g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); 161 | g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); 162 | } 163 | 164 | // Render command lists 165 | int vtx_offset = 0; 166 | int idx_offset = 0; 167 | ImVec2 pos = draw_data->DisplayPos; 168 | for (int n = 0; n < draw_data->CmdListsCount; n++) 169 | { 170 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 171 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 172 | { 173 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 174 | if (pcmd->UserCallback) 175 | { 176 | pcmd->UserCallback(cmd_list, pcmd); 177 | } 178 | else 179 | { 180 | const RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; 181 | const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->TextureId; 182 | g_pd3dDevice->SetTexture(0, texture); 183 | g_pd3dDevice->SetScissorRect(&r); 184 | g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, idx_offset, pcmd->ElemCount/3); 185 | } 186 | idx_offset += pcmd->ElemCount; 187 | } 188 | vtx_offset += cmd_list->VtxBuffer.Size; 189 | } 190 | 191 | // Restore the DX9 transform 192 | g_pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); 193 | g_pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); 194 | g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); 195 | 196 | // Restore the DX9 state 197 | d3d9_state_block->Apply(); 198 | d3d9_state_block->Release(); 199 | } 200 | 201 | bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) 202 | { 203 | ImGuiIO& io = ImGui::GetIO(); 204 | io.BackendRendererName = "imgui_impl_dx9"; 205 | 206 | g_pd3dDevice = device; 207 | return true; 208 | } 209 | 210 | void ImGui_ImplDX9_Shutdown() 211 | { 212 | ImGui_ImplDX9_InvalidateDeviceObjects(); 213 | g_pd3dDevice = NULL; 214 | } 215 | 216 | static bool ImGui_ImplDX9_CreateFontsTexture() 217 | { 218 | // Build texture atlas 219 | ImGuiIO& io = ImGui::GetIO(); 220 | unsigned char* pixels; 221 | int width, height, bytes_per_pixel; 222 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel); 223 | 224 | // Upload texture to graphics system 225 | g_FontTexture = NULL; 226 | if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0) 227 | return false; 228 | D3DLOCKED_RECT tex_locked_rect; 229 | if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) 230 | return false; 231 | for (int y = 0; y < height; y++) 232 | memcpy((unsigned char *)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, pixels + (width * bytes_per_pixel) * y, (width * bytes_per_pixel)); 233 | g_FontTexture->UnlockRect(0); 234 | 235 | // Store our identifier 236 | io.Fonts->TexID = (ImTextureID)g_FontTexture; 237 | 238 | return true; 239 | } 240 | 241 | bool ImGui_ImplDX9_CreateDeviceObjects() 242 | { 243 | if (!g_pd3dDevice) 244 | return false; 245 | if (!ImGui_ImplDX9_CreateFontsTexture()) 246 | return false; 247 | return true; 248 | } 249 | 250 | void ImGui_ImplDX9_InvalidateDeviceObjects() 251 | { 252 | if (!g_pd3dDevice) 253 | return; 254 | if (g_pVB) 255 | { 256 | g_pVB->Release(); 257 | g_pVB = NULL; 258 | } 259 | if (g_pIB) 260 | { 261 | g_pIB->Release(); 262 | g_pIB = NULL; 263 | } 264 | 265 | // At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both. 266 | ImGuiIO& io = ImGui::GetIO(); 267 | IM_ASSERT(g_FontTexture == io.Fonts->TexID); 268 | if (g_FontTexture) 269 | g_FontTexture->Release(); 270 | g_FontTexture = NULL; 271 | io.Fonts->TexID = NULL; 272 | } 273 | 274 | void ImGui_ImplDX9_NewFrame() 275 | { 276 | if (!g_FontTexture) 277 | ImGui_ImplDX9_CreateDeviceObjects(); 278 | } 279 | -------------------------------------------------------------------------------- /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 | AUTHORS 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 author or authors 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 | AUTHORS 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 | -------------------------------------------------------------------------------- /Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ImGui/imgui.h" 9 | #include "ImGui/imgui_internal.h" 10 | #include "ImGui/imgui_impl_dx9.h" 11 | #include "ImGui/imgui_impl_win32.h" 12 | 13 | #include "rawData.h" 14 | #include "Detours.h" 15 | #include "Hook.h" 16 | #include "Variables.h" 17 | #include "Functions.h" 18 | 19 | #include 20 | #include 21 | 22 | #pragma comment (lib, "d3dx9.lib") 23 | #pragma comment (lib, "d3d9.lib") 24 | 25 | #pragma comment(lib, "legacy_stdio_definitions.lib") 26 | 27 | using namespace std; 28 | namespace bytes 29 | { 30 | BYTE settings[] = { 0x89, 0x50, 0x4E, 0x47, 0xD, 0xA, 0x1A, 0xA, 0x0, 0x0, 0x0, 0xD, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x18, 0x8, 0x6, 0x0, 0x0, 0x0, 0xE0, 0x77, 0x3D, 0xF8, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4B, 0x47, 0x44, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xA0, 0xBD, 0xA7, 0x93, 0x0, 0x0, 0x2, 0xF, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xE5, 0x94, 0xBD, 0x6B, 0x13, 0x61, 0x1C, 0xC7, 0x3F, 0xBF, 0x4B, 0x6A, 0xA4, 0x36, 0x77, 0x97, 0xE6, 0x45, 0x10, 0x5, 0x27, 0x85, 0xBA, 0xD4, 0xA5, 0xE2, 0xD4, 0x4, 0x7, 0x7, 0x17, 0x5, 0x95, 0x82, 0x8B, 0x8E, 0x5D, 0x14, 0x71, 0x90, 0xFA, 0x87, 0xB8, 0xEA, 0x22, 0x74, 0xCC, 0xE2, 0xDC, 0xD6, 0x4D, 0x17, 0xED, 0x52, 0xC8, 0x26, 0x38, 0x19, 0xF2, 0x34, 0x77, 0x97, 0x9A, 0x42, 0x92, 0xE6, 0xE7, 0x60, 0x93, 0x5E, 0xEE, 0xA5, 0x89, 0x88, 0x8B, 0x7E, 0xE1, 0xE0, 0xEE, 0xFB, 0x7C, 0x5F, 0x9E, 0xE3, 0x79, 0x81, 0xFF, 0x2, 0xA6, 0xED, 0x3F, 0x6B, 0x79, 0xBE, 0x4E, 0x3C, 0xBE, 0xFF, 0x74, 0x16, 0xAF, 0x35, 0x8B, 0x48, 0x2D, 0xAE, 0x27, 0xD0, 0x49, 0xDC, 0xEF, 0x17, 0x18, 0xD3, 0xB9, 0x86, 0xB2, 0x1A, 0x6F, 0xA5, 0x6A, 0x3A, 0x9D, 0xA5, 0x69, 0x7E, 0x99, 0xF0, 0xA8, 0xCA, 0xBE, 0xEF, 0x6F, 0x2B, 0xB4, 0x4, 0x36, 0x15, 0xA9, 0x2, 0xEB, 0x51, 0xDD, 0x44, 0x8D, 0xF2, 0x5A, 0x44, 0x77, 0x14, 0xD6, 0x44, 0xA4, 0xBC, 0x68, 0xDB, 0x55, 0x11, 0x19, 0x26, 0x16, 0xB4, 0xDA, 0xC1, 0x63, 0x44, 0xDF, 0x4C, 0x9B, 0xD5, 0xA9, 0x50, 0x79, 0x52, 0x2A, 0xD8, 0x6F, 0x63, 0x5, 0xCD, 0x66, 0x73, 0xC1, 0xCA, 0xE5, 0x1A, 0x28, 0x17, 0xFE, 0xA8, 0x0, 0xBE, 0xCB, 0xD1, 0xE0, 0x4A, 0xB1, 0x58, 0xC, 0x20, 0xB4, 0x6, 0xD6, 0x99, 0xB3, 0xAF, 0x4E, 0x9, 0xFF, 0x26, 0xE8, 0x7D, 0xED, 0xF7, 0x6C, 0xED, 0xF7, 0x6C, 0x54, 0xEE, 0x1, 0x8D, 0x14, 0xED, 0x79, 0xCD, 0xCC, 0x6D, 0x8C, 0x3E, 0xB2, 0x63, 0x5A, 0xF9, 0x84, 0xD0, 0x5, 0xE6, 0xA3, 0xE1, 0x73, 0xC2, 0xB2, 0xE3, 0xB8, 0xFB, 0x21, 0xAE, 0xEE, 0x79, 0xDE, 0xCE, 0x0, 0xD9, 0x5, 0x2E, 0x45, 0xF4, 0x5D, 0x94, 0x8F, 0xE3, 0x89, 0x8F, 0x5E, 0x4A, 0x5, 0xBB, 0x8E, 0x50, 0x3, 0x3D, 0xC, 0xAB, 0x5, 0x7D, 0xEE, 0x38, 0x4E, 0x38, 0x1C, 0x0, 0xD7, 0x75, 0xDB, 0x82, 0xBE, 0x98, 0x64, 0xF5, 0x10, 0xA1, 0x56, 0x2A, 0xD8, 0xF5, 0x13, 0x7F, 0x4, 0x2D, 0xCF, 0x3F, 0x0, 0xCE, 0x8D, 0x2D, 0xFD, 0x9E, 0x5D, 0x2E, 0x97, 0x3B, 0x51, 0x1D, 0x80, 0x31, 0xC6, 0xD6, 0x4C, 0xD6, 0xF, 0x51, 0x3F, 0x4A, 0xAE, 0xB3, 0x10, 0xD6, 0xCC, 0x74, 0xD0, 0xD2, 0x20, 0x22, 0x69, 0xDB, 0x37, 0xB9, 0xA0, 0xE5, 0xFB, 0x2B, 0xA0, 0x13, 0x9C, 0x64, 0x73, 0xB7, 0xD2, 0xCC, 0x6A, 0x59, 0xB7, 0xA3, 0xCC, 0xAF, 0x8C, 0x90, 0x7F, 0x1C, 0xDE, 0xE, 0xEE, 0x22, 0xFA, 0x8E, 0xF8, 0x22, 0x37, 0xB2, 0xE8, 0x4D, 0xD7, 0x75, 0xDB, 0x61, 0x32, 0x8, 0x82, 0x62, 0x6F, 0xC8, 0x17, 0xD0, 0x8B, 0x11, 0x7D, 0x17, 0x95, 0x47, 0xA3, 0x75, 0x38, 0x99, 0xAD, 0xB0, 0x92, 0x10, 0xE, 0x70, 0x75, 0x80, 0xEC, 0x1A, 0xCF, 0x7B, 0x60, 0x8C, 0xB1, 0x8D, 0x31, 0xB6, 0xF1, 0xBC, 0x87, 0x29, 0xE1, 0x0, 0xF3, 0x8, 0x37, 0x62, 0x7F, 0xF0, 0xD7, 0xF, 0x5A, 0xA5, 0x52, 0x39, 0x60, 0xC8, 0x46, 0xBA, 0x6F, 0x46, 0xA8, 0xBC, 0x1C, 0x85, 0x43, 0xC2, 0x65, 0x67, 0x7C, 0x7F, 0xB, 0x30, 0x2, 0x9B, 0xAA, 0xB2, 0x8A, 0xB0, 0x4E, 0xFA, 0x6E, 0x1B, 0x1E, 0x5F, 0x76, 0x1F, 0x14, 0xD6, 0x4, 0x4A, 0x8B, 0x8E, 0x53, 0x4B, 0xBD, 0xEC, 0x92, 0x60, 0x3A, 0x9D, 0x25, 0x3D, 0x1A, 0xBE, 0x7, 0x2E, 0x47, 0x86, 0xBE, 0x4A, 0xC6, 0xBA, 0x53, 0xCC, 0xE7, 0xF7, 0x4E, 0xF3, 0x4F, 0x3D, 0x7, 0xC5, 0x7C, 0x7E, 0xF, 0x61, 0x3B, 0x3E, 0xA2, 0x5B, 0xD3, 0xC2, 0x67, 0x2A, 0x38, 0xC6, 0xE7, 0x18, 0x23, 0x12, 0xE7, 0xFE, 0x49, 0xFC, 0x4, 0x65, 0x42, 0xD3, 0xDF, 0x16, 0x46, 0x85, 0x2B, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 }; 31 | BYTE aimimg[] = { 0x89, 0x50, 0x4E, 0x47, 0xD, 0xA, 0x1A, 0xA, 0x0, 0x0, 0x0, 0xD, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, 0x1A, 0x8, 0x6, 0x0, 0x0, 0x0, 0xA9, 0x4A, 0x4C, 0xCE, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4B, 0x47, 0x44, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xA0, 0xBD, 0xA7, 0x93, 0x0, 0x0, 0x2, 0xDE, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0x9D, 0x96, 0xCF, 0x4F, 0x13, 0x41, 0x14, 0xC7, 0xBF, 0x6F, 0xB6, 0x2D, 0x10, 0x5B, 0xDA, 0x58, 0x68, 0x40, 0x2F, 0x9E, 0x24, 0x6, 0xC, 0x5E, 0xF4, 0x60, 0xA2, 0x82, 0x47, 0x88, 0x7, 0x3, 0x7F, 0x3, 0x9A, 0x6A, 0x62, 0x4C, 0x4C, 0x3C, 0x18, 0x2F, 0x84, 0xA3, 0x7, 0x8D, 0x31, 0x31, 0xC4, 0x7F, 0x1, 0xA2, 0x7, 0xCE, 0xA8, 0x10, 0x41, 0x39, 0x58, 0xC1, 0x18, 0x38, 0x79, 0x31, 0xA6, 0xE9, 0x6E, 0xE9, 0x4C, 0x4B, 0xD3, 0xC6, 0x2E, 0xFB, 0x3C, 0xB0, 0x3B, 0x2C, 0x2D, 0xFD, 0xB1, 0x7D, 0xC9, 0x26, 0x33, 0x3B, 0xF3, 0xBE, 0x9F, 0x97, 0xF7, 0x76, 0xDF, 0xC, 0x10, 0xD0, 0xF2, 0x52, 0x7E, 0xB2, 0xA4, 0xDA, 0xA, 0xEA, 0x17, 0xA, 0xEA, 0xC0, 0xA0, 0x9B, 0x41, 0x7D, 0x0, 0x80, 0xDA, 0x6D, 0xC8, 0xE5, 0x72, 0x51, 0x11, 0xEE, 0x9D, 0x5, 0x61, 0xA, 0xE0, 0x71, 0x0, 0x17, 0xDD, 0xA5, 0x3D, 0x80, 0xB6, 0xC1, 0x58, 0x71, 0x6A, 0xD5, 0xA5, 0x54, 0x2A, 0x75, 0xD0, 0x15, 0x88, 0x99, 0x23, 0x79, 0xA5, 0x1E, 0x3, 0xF4, 0xC, 0x40, 0xAC, 0x4D, 0x3C, 0x45, 0x6, 0x2D, 0xC, 0xC4, 0x63, 0xAF, 0x88, 0xE8, 0x5F, 0xC7, 0x20, 0xB3, 0x5C, 0x1E, 0xA6, 0x9A, 0xFD, 0x1, 0xC0, 0xD5, 0x36, 0x80, 0x7A, 0xB1, 0xC, 0xE, 0xED, 0x3B, 0xC9, 0x64, 0xF2, 0x4F, 0xFD, 0x9A, 0x68, 0x80, 0x98, 0xE5, 0x73, 0x54, 0xB3, 0x37, 0xFD, 0x10, 0x2, 0x32, 0x0, 0xA7, 0xC9, 0x10, 0xA3, 0xFA, 0x9D, 0x21, 0x46, 0x41, 0x78, 0xC0, 0xA0, 0x1F, 0xDE, 0x3B, 0x6, 0xAE, 0xB0, 0x11, 0x5A, 0x33, 0xCB, 0xE5, 0xE1, 0x96, 0x11, 0x31, 0x73, 0xC4, 0x92, 0x6A, 0xCB, 0x92, 0x8A, 0xDD, 0xA7, 0x62, 0x4A, 0x39, 0xC7, 0xCC, 0x3A, 0x20, 0x53, 0xA9, 0xB5, 0xBC, 0x52, 0x9F, 0x7D, 0x3E, 0xC2, 0x94, 0xF2, 0xBE, 0x25, 0x55, 0xD5, 0xE7, 0xF7, 0x95, 0x99, 0x23, 0x4D, 0x41, 0x96, 0x94, 0x4F, 0x4F, 0x40, 0xA, 0xA5, 0x5B, 0x2D, 0x23, 0xF3, 0x67, 0xA2, 0x50, 0x98, 0xF0, 0xC3, 0x4C, 0x59, 0x7C, 0xE2, 0x5F, 0xD7, 0x35, 0xCA, 0xE5, 0x72, 0x51, 0x11, 0xE9, 0xF9, 0xB, 0xB7, 0xF0, 0xC, 0xBE, 0x37, 0x98, 0x48, 0x2C, 0x76, 0xA, 0x2, 0x0, 0x4B, 0xA9, 0x34, 0x18, 0x6F, 0xDC, 0xA9, 0xB2, 0xAB, 0x95, 0xF3, 0x43, 0x43, 0x43, 0x65, 0xC0, 0x57, 0x23, 0x11, 0xEE, 0x9D, 0xF5, 0x20, 0x4, 0x64, 0x6, 0xE2, 0xF1, 0x77, 0x41, 0x20, 0x0, 0x90, 0xEC, 0xEF, 0x7F, 0xB, 0xF0, 0x8E, 0x3B, 0x8D, 0x87, 0x7A, 0xFA, 0x66, 0xB4, 0xBE, 0xDE, 0x45, 0x98, 0xF2, 0x86, 0xC, 0x5E, 0x24, 0x22, 0x27, 0x28, 0x88, 0x88, 0x1C, 0x10, 0xE9, 0x2C, 0x30, 0x61, 0xBA, 0x11, 0x74, 0xF4, 0x33, 0x1E, 0x99, 0x61, 0x7C, 0xC, 0xA, 0xD1, 0x30, 0x5B, 0xAC, 0xEA, 0x31, 0xA0, 0x35, 0xC9, 0x94, 0xC5, 0xC, 0xF9, 0x21, 0xC7, 0xD1, 0xAC, 0xF, 0xC6, 0xE3, 0x37, 0x3A, 0x5, 0x30, 0x33, 0x59, 0xAA, 0xF4, 0xBD, 0x99, 0x96, 0x20, 0xF0, 0xA9, 0x29, 0x12, 0x0, 0x77, 0xA, 0x71, 0x8D, 0x5A, 0x69, 0xE9, 0xAF, 0xCE, 0x92, 0x6A, 0x17, 0xC0, 0x8, 0x70, 0xF4, 0x33, 0x26, 0x63, 0xB1, 0x5F, 0x1, 0x41, 0x0, 0x80, 0xFD, 0xFD, 0xD2, 0x98, 0x23, 0x1C, 0xEF, 0x83, 0xD8, 0x1D, 0x48, 0xC4, 0x2F, 0xB9, 0x30, 0x1D, 0xD0, 0xB6, 0x37, 0x62, 0xC7, 0x99, 0xE8, 0x6, 0x2, 0x0, 0x8E, 0xE1, 0x4C, 0x6A, 0x1D, 0x40, 0x77, 0x8D, 0x63, 0x10, 0x63, 0x45, 0xF, 0x99, 0x4E, 0x74, 0x83, 0x4E, 0x8D, 0x99, 0x5, 0x98, 0xE7, 0xBC, 0x39, 0xD1, 0xB1, 0xA6, 0x16, 0x73, 0x6A, 0xD5, 0x25, 0x0, 0x45, 0x0, 0x20, 0xF0, 0xB8, 0xA5, 0xD4, 0x1C, 0x2, 0x5A, 0xBE, 0x58, 0x4C, 0x3, 0x34, 0xE6, 0x4E, 0x95, 0x5D, 0xA9, 0x2C, 0x37, 0x80, 0x52, 0xA9, 0xD4, 0x1, 0x83, 0x16, 0x74, 0x34, 0xA0, 0x97, 0x66, 0xA1, 0xD0, 0x71, 0xA, 0x2D, 0x29, 0x6F, 0x83, 0xF1, 0x42, 0xFB, 0x33, 0xCD, 0x7B, 0x5D, 0xA1, 0xC1, 0xDC, 0xA6, 0xFA, 0xCD, 0xD7, 0xEF, 0xAA, 0x96, 0x52, 0x69, 0x7F, 0x1A, 0xDD, 0xA3, 0x7C, 0xC3, 0xE7, 0x23, 0x2C, 0xA5, 0x1E, 0xD6, 0x35, 0xD5, 0xD, 0x66, 0xE, 0xFB, 0xB5, 0x1B, 0xCE, 0x23, 0xF7, 0x2C, 0xFA, 0x2, 0xE0, 0x82, 0x2F, 0x84, 0x1D, 0x10, 0x2D, 0x92, 0x2D, 0x56, 0xD9, 0x70, 0x7E, 0x2, 0x0, 0x1D, 0x8A, 0x31, 0xE, 0x39, 0x93, 0x47, 0x35, 0xA1, 0xCB, 0x7A, 0x27, 0xF0, 0x9B, 0x43, 0xC6, 0xF5, 0x54, 0x34, 0x9A, 0x6D, 0x9, 0xF2, 0xC1, 0xDE, 0x3, 0xB8, 0xD6, 0x24, 0x53, 0xCD, 0x6C, 0xD3, 0x9, 0x19, 0x77, 0xEB, 0x21, 0x4D, 0x41, 0x0, 0xC0, 0xCC, 0x61, 0x4B, 0x95, 0x1E, 0x11, 0xF8, 0x39, 0x80, 0xFE, 0x36, 0x0, 0x45, 0x4C, 0xF3, 0x67, 0x13, 0xB1, 0xD7, 0x44, 0x54, 0x3B, 0x6D, 0x43, 0xDB, 0xCB, 0x49, 0x36, 0x9B, 0x3D, 0x13, 0xEA, 0xE9, 0x9B, 0x61, 0xC2, 0xB4, 0xDB, 0xBB, 0x46, 0xDC, 0xA5, 0x3D, 0x6, 0x32, 0x44, 0x58, 0xB1, 0x2B, 0x95, 0xE5, 0xA6, 0x85, 0xEF, 0xD6, 0xBC, 0x82, 0x7, 0xF5, 0xB, 0x7E, 0xAF, 0x23, 0xAC, 0x77, 0xD1, 0x7, 0xF1, 0x1F, 0x27, 0x75, 0x88, 0x9, 0x2F, 0x3A, 0x34, 0x20, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 }; 32 | BYTE eyeimg[] = { 0x89, 0x50, 0x4E, 0x47, 0xD, 0xA, 0x1A, 0xA, 0x0, 0x0, 0x0, 0xD, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x18, 0x8, 0x6, 0x0, 0x0, 0x0, 0xE0, 0x77, 0x3D, 0xF8, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4B, 0x47, 0x44, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xA0, 0xBD, 0xA7, 0x93, 0x0, 0x0, 0x2, 0x42, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xED, 0x94, 0xC1, 0x4E, 0x13, 0x51, 0x14, 0x86, 0xBF, 0x73, 0x69, 0x6B, 0x48, 0x60, 0x66, 0x4A, 0x8B, 0x51, 0x23, 0x91, 0x85, 0xB8, 0x74, 0x23, 0x18, 0x37, 0x24, 0xBA, 0x36, 0x2, 0x3E, 0x80, 0x2F, 0x81, 0x89, 0x10, 0x30, 0x9A, 0x68, 0x44, 0xBA, 0x81, 0x27, 0x30, 0x26, 0xFA, 0x0, 0xB6, 0x81, 0x27, 0x70, 0xE1, 0xA6, 0xBA, 0xD0, 0xAD, 0x24, 0x90, 0x54, 0xD1, 0xC0, 0x14, 0x66, 0xA6, 0x24, 0x25, 0x30, 0xCC, 0x71, 0xD1, 0x82, 0x74, 0x3A, 0x5A, 0x5C, 0x18, 0x36, 0xFC, 0xAB, 0x7B, 0xCF, 0x39, 0xF7, 0xFF, 0xFF, 0x73, 0x73, 0x72, 0xE0, 0xC, 0xA7, 0xD, 0xF9, 0x5B, 0xD2, 0xF7, 0xFD, 0xBE, 0x50, 0xE5, 0xBE, 0x8A, 0x8E, 0xA3, 0x5C, 0x5, 0x6, 0x9A, 0xA9, 0xA, 0xC2, 0x8A, 0x44, 0x52, 0x4C, 0x19, 0x2D, 0xDA, 0xB6, 0xBD, 0xF5, 0x4F, 0x2, 0x95, 0x8A, 0x76, 0x77, 0x5B, 0xC1, 0x43, 0x94, 0x29, 0xA0, 0xA7, 0x83, 0xC9, 0x1D, 0xD0, 0xF9, 0x7A, 0xCD, 0x5E, 0x18, 0x18, 0x90, 0x7A, 0x47, 0x81, 0x6A, 0xB5, 0x7A, 0x59, 0xBB, 0x52, 0x45, 0xE0, 0x46, 0x7, 0xE2, 0x16, 0x28, 0xF2, 0x25, 0x4D, 0x34, 0xE1, 0x38, 0xCE, 0xEA, 0xF1, 0xB8, 0x39, 0x7E, 0xD9, 0xC, 0x82, 0x6B, 0xDA, 0x95, 0x2A, 0xB7, 0x91, 0xB, 0x25, 0x55, 0x73, 0x3B, 0xDC, 0xAD, 0xF7, 0x84, 0xBB, 0xF5, 0x1E, 0xD5, 0xE8, 0xE, 0xC2, 0x52, 0x6B, 0x89, 0x5E, 0xF, 0x91, 0xF, 0x1B, 0xBE, 0x3F, 0x94, 0xD8, 0xC1, 0x8F, 0x5A, 0xAD, 0x3F, 0x7D, 0x10, 0x95, 0x81, 0x2B, 0x31, 0x6F, 0xD3, 0x79, 0xC7, 0x29, 0x24, 0xB9, 0x76, 0x3D, 0x6F, 0x6, 0xE4, 0x45, 0x2C, 0xBC, 0x96, 0x31, 0x32, 0x62, 0x59, 0x96, 0xDB, 0xD2, 0x41, 0x26, 0x8C, 0x5E, 0xB7, 0x91, 0xB, 0xA5, 0xBC, 0xE3, 0x14, 0x54, 0x35, 0xE3, 0x7A, 0x5E, 0xC1, 0xDD, 0xF6, 0xD7, 0x5D, 0xDF, 0xFF, 0xEE, 0x7A, 0xC1, 0xBC, 0xAA, 0x66, 0xF2, 0x8E, 0x33, 0x87, 0xB2, 0x1C, 0x13, 0x18, 0xDC, 0x53, 0x7D, 0x75, 0x78, 0x31, 0x0, 0x9B, 0xDB, 0xC1, 0x98, 0xA, 0x77, 0xE3, 0xE, 0x35, 0x32, 0x8B, 0x0, 0x55, 0xBF, 0xF6, 0xC, 0xE4, 0x11, 0xC2, 0x45, 0x94, 0x4B, 0xA0, 0x53, 0x8D, 0x18, 0x28, 0xD1, 0x42, 0x5B, 0x6B, 0xCA, 0xD8, 0xE6, 0x56, 0x70, 0xEF, 0x48, 0x40, 0xD0, 0x97, 0x49, 0x5F, 0xA0, 0xFB, 0xF5, 0x4F, 0x8D, 0x4E, 0xF4, 0x41, 0x5B, 0xF2, 0x30, 0x16, 0x86, 0x1F, 0x93, 0xDE, 0x8A, 0xE8, 0xFC, 0x91, 0xC0, 0xFF, 0x84, 0x1, 0x50, 0x95, 0xE9, 0x44, 0x17, 0xE9, 0xF4, 0x30, 0x0, 0x2A, 0x6F, 0xDB, 0x92, 0x2A, 0x6F, 0x9A, 0x35, 0x23, 0x49, 0x6F, 0xB5, 0x4B, 0xA6, 0x8E, 0x4, 0xFA, 0xFB, 0xAC, 0xA5, 0xF8, 0xD8, 0x1, 0x88, 0x31, 0x93, 0x0, 0x39, 0xBB, 0xF7, 0x9, 0x48, 0x1, 0x61, 0x1D, 0x61, 0x1D, 0xA4, 0x90, 0xB3, 0x7B, 0x9F, 0x2, 0x88, 0xCA, 0x64, 0xBB, 0x33, 0x4A, 0xFD, 0x96, 0xB5, 0xDC, 0x38, 0x36, 0x11, 0x4, 0x41, 0x7E, 0x2F, 0xD2, 0x32, 0x30, 0x18, 0xF3, 0x32, 0x9B, 0x77, 0x9C, 0xB9, 0x24, 0x97, 0xAE, 0xEF, 0x3F, 0x46, 0x79, 0xDE, 0x52, 0xD, 0xAB, 0xE7, 0x1A, 0x63, 0x5A, 0x6D, 0x11, 0x0, 0xD8, 0xF0, 0xFD, 0x21, 0xA3, 0xBC, 0x7, 0x2E, 0xB4, 0x6A, 0xB0, 0xAC, 0x44, 0xB, 0xBA, 0xBF, 0x5F, 0x6, 0x30, 0x99, 0xCC, 0x4D, 0x51, 0x99, 0x4C, 0x98, 0xBC, 0x9F, 0x91, 0x30, 0x7A, 0xDE, 0xB6, 0x57, 0x7E, 0x37, 0x13, 0x43, 0x73, 0x55, 0xBC, 0x3, 0x86, 0x93, 0x5C, 0xFF, 0x9, 0x8A, 0x7C, 0x4E, 0xE9, 0xC1, 0x44, 0x36, 0x9B, 0x5D, 0x3B, 0x1E, 0x6F, 0x9B, 0xA2, 0x5C, 0x2E, 0xF7, 0xAD, 0x66, 0x5B, 0xA3, 0xA0, 0xB3, 0xC0, 0xCE, 0x9, 0xB8, 0x6B, 0xA0, 0x33, 0x3B, 0x76, 0xEF, 0xAD, 0x38, 0x39, 0x74, 0x58, 0xD7, 0x9E, 0xE7, 0x65, 0x43, 0x35, 0xE3, 0x18, 0x9D, 0x20, 0x62, 0x8, 0x69, 0xAE, 0x6B, 0xA5, 0x82, 0xE1, 0x2B, 0x91, 0x14, 0x53, 0x12, 0x95, 0x1C, 0xC7, 0xD9, 0x3E, 0x81, 0x91, 0x33, 0x9C, 0x12, 0x7E, 0x1, 0xBF, 0x62, 0xE3, 0xCD, 0x5D, 0x3C, 0x27, 0xA2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 }; 33 | } 34 | LPDIRECT3DTEXTURE9 setx; 35 | LPDIRECT3DTEXTURE9 aimimgx; 36 | LPDIRECT3DTEXTURE9 eyeimgx; 37 | 38 | typedef HRESULT(__stdcall* DrawIndexedPrimitive_t)(IDirect3DDevice9*, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT); 39 | typedef HRESULT(__stdcall* Reset_t)(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*); 40 | 41 | HANDLE MEMORY = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()); 42 | 43 | void InputHandler() 44 | { 45 | for (int i = 0; i < 5; i++) ImGui::GetIO().MouseDown[i] = false; 46 | int button = -1; 47 | if (GetAsyncKeyState(VK_LBUTTON)) button = 0; 48 | if (button != -1) ImGui::GetIO().MouseDown[button] = true; 49 | } 50 | 51 | LPDIRECT3DTEXTURE9 img2; 52 | LPDIRECT3DTEXTURE9 chamscolor; 53 | void ToggleButton(const char* str_id, bool* v) 54 | { 55 | ImVec2 p = ImGui::GetCursorScreenPos(); 56 | ImDrawList* draw_list = ImGui::GetWindowDrawList(); 57 | 58 | float height = ImGui::GetFrameHeight(); 59 | float width = height * 1.55f; 60 | float radius = height * 0.50f; 61 | 62 | ImGui::InvisibleButton(str_id, ImVec2(width, height)); 63 | if (ImGui::IsItemClicked()) 64 | *v = !*v; 65 | 66 | float t = *v ? 1.0f : 0.0f; 67 | 68 | ImGuiContext& g = *GImGui; 69 | float ANIM_SPEED = 0.08f; 70 | if (g.LastActiveId == g.CurrentWindow->GetID(str_id))// && g.LastActiveIdTimer < ANIM_SPEED) 71 | { 72 | float t_anim = ImSaturate(g.LastActiveIdTimer / ANIM_SPEED); 73 | t = *v ? (t_anim) : (1.0f - t_anim); 74 | } 75 | 76 | ImU32 col_bg; 77 | if (ImGui::IsItemHovered()) 78 | col_bg = ImGui::GetColorU32(ImLerp(ImVec4(0.78f, 0.78f, 0.78f, 1.0f), ImVec4(0.64f, 0.83f, 0.34f, 1.0f), t)); 79 | else 80 | col_bg = ImGui::GetColorU32(ImLerp(ImVec4(0.85f, 0.85f, 0.85f, 1.0f), ImVec4(0.56f, 0.83f, 0.26f, 1.0f), t)); 81 | 82 | draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), col_bg, height * 0.5f); 83 | draw_list->AddCircleFilled(ImVec2(p.x + radius + t * (width - radius * 2.0f), p.y + radius), radius - 1.5f, IM_COL32(255, 255, 255, 255)); 84 | } 85 | 86 | HRESULT GenerateTexture(IDirect3DDevice9* pD3Ddev, IDirect3DTexture9** ppD3Dtex, DWORD colour32) 87 | { 88 | pD3Ddev->CreateTexture(8, 8, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, ppD3Dtex, NULL); 89 | 90 | WORD colour16 = ((WORD)((colour32 >> 28) & 0xF) << 12) 91 | | (WORD)(((colour32 >> 20) & 0xF) << 8) 92 | | (WORD)(((colour32 >> 12) & 0xF) << 4) 93 | | (WORD)(((colour32 >> 4) & 0xF) << 0); 94 | 95 | D3DLOCKED_RECT d3dlr; 96 | (*ppD3Dtex)->LockRect(0, &d3dlr, 0, 0); 97 | WORD* pDst16 = (WORD*)d3dlr.pBits; 98 | 99 | for (int xy = 0; xy < 8 * 8; xy++) 100 | *pDst16++ = colour16; 101 | 102 | 103 | return S_OK; 104 | } 105 | 106 | D3DCOLOR FLOAT4TOD3DCOLOR(float Col[]) 107 | { 108 | ImU32 col32_no_alpha = ImGui::ColorConvertFloat4ToU32(ImVec4(Col[0], Col[1], Col[2], Col[3])); 109 | float a = (col32_no_alpha >> 24) & 255; 110 | float r = (col32_no_alpha >> 16) & 255; 111 | float g = (col32_no_alpha >> 8) & 255; 112 | float b = col32_no_alpha & 255; 113 | return D3DCOLOR_ARGB((int)a, (int)b, (int)g, (int)r); 114 | } 115 | 116 | 117 | 118 | extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 119 | LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 120 | { 121 | if (Menu && ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) 122 | { 123 | return true; 124 | } 125 | 126 | return CallWindowProc(oWndProc, hWnd, msg, wParam, lParam); 127 | } 128 | 129 | IDirect3DPixelShader9* Front, * Back; 130 | void Style() 131 | { 132 | ImGuiStyle* style = &ImGui::GetStyle(); 133 | ImVec4* colors = style->Colors; 134 | 135 | colors[ImGuiCol_Button] = ImVec4(0.79f, 0.79f, 0.79f, 1.00f); 136 | colors[ImGuiCol_ButtonHovered] = ImVec4(0.85f, 0.85f, 0.85f, 1.00f); 137 | colors[ImGuiCol_ButtonActive] = ImVec4(0.85f, 0.85f, 0.85f, 1.00f); 138 | } 139 | 140 | HRESULT CreateMyShader(IDirect3DPixelShader9** pShader, IDirect3DDevice9* Device, float red, float green, float blue, float alpha) 141 | { 142 | ID3DXBuffer* MyBuffer = NULL; 143 | char MyShader[256]; 144 | sprintf(MyShader, "ps.1.1\ndef c0, %f, %f, %f, %f\nmov r0,c0", red / 255, green / 255, blue / 255, alpha / 255); 145 | D3DXAssembleShader(MyShader, sizeof(MyShader), NULL, NULL, 0, &MyBuffer, NULL); 146 | if (FAILED(Device->CreatePixelShader((const DWORD*)MyBuffer->GetBufferPointer(), pShader)))return E_FAIL; 147 | return S_OK; 148 | } 149 | HRESULT APIENTRY Present_hook(IDirect3DDevice9* pDevice, const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) 150 | { 151 | 152 | if (GetAsyncKeyState(VK_INSERT) & 1) Menu = !Menu; 153 | static bool init = true; 154 | if (init) 155 | { 156 | init = false; 157 | ImGui::CreateContext(); 158 | ImGuiIO& io = ImGui::GetIO(); 159 | D3DDEVICE_CREATION_PARAMETERS d3dcp; 160 | pDevice->GetCreationParameters(&d3dcp); 161 | TargetWnd = d3dcp.hFocusWindow; 162 | if (TargetWnd != NULL) 163 | { 164 | oWndProc = (WNDPROC)SetWindowLongPtr(TargetWnd, GWLP_WNDPROC, (LONG_PTR)WndProc); 165 | ImGui_ImplWin32_Init(TargetWnd); 166 | ImGui_ImplDX9_Init(pDevice); 167 | ImFont* font = io.Fonts->AddFontFromMemoryTTF((void*)rawData, sizeof(rawData), 15); 168 | ImGui::GetIO().ImeWindowHandle = TargetWnd; 169 | } 170 | pDevice->GetViewport(&viewport); 171 | ScreenCenterX = viewport.Width / 2.0f; 172 | ScreenCenterY = viewport.Height / 2.0f; 173 | } 174 | 175 | if (eyeimgx == NULL) 176 | D3DXCreateTextureFromFileInMemory(pDevice, bytes::eyeimg, sizeof(bytes::eyeimg), &eyeimgx); 177 | 178 | if (aimimgx == NULL) 179 | D3DXCreateTextureFromFileInMemory(pDevice, bytes::aimimg, sizeof(bytes::aimimg), &aimimgx); 180 | 181 | if (setx == NULL) 182 | D3DXCreateTextureFromFileInMemory(pDevice, bytes::settings, sizeof(bytes::settings), &setx); 183 | 184 | ImGui_ImplDX9_NewFrame(); 185 | ImGui_ImplWin32_NewFrame(); 186 | ImGui::NewFrame(); 187 | 188 | ImGuiStyle& style = ImGui::GetStyle(); 189 | ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoInputs; 190 | 191 | ImGui::GetIO().MouseDrawCursor = 1; 192 | if (Menu == true) 193 | { 194 | InputHandler(); 195 | ImGui::SetNextWindowPos(ImVec2(40.0f, 40.0f)); 196 | ImGui::SetNextWindowSize(ImVec2(600.0f, 420.0f)); 197 | ImGui::Begin("NotSimpleBase - by 105HYP", 0, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus); 198 | 199 | 200 | ImGui::SetCursorPosX(160); ImGui::SetCursorPosY(35); 201 | if (ImGui::Button("", ImVec2(425, 50))) 202 | { 203 | wallhack = !wallhack; 204 | } 205 | ImGui::SetWindowFontScale(1.4); 206 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(42); ImGui::Text("WallHack"); 207 | ImGui::SetWindowFontScale(0.8); 208 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(60); ImGui::Text("Show enemies behind the wall."); 209 | ImGui::SetCursorPosX(530); ImGui::SetCursorPosY(50); ToggleButton("x", &wallhack); 210 | 211 | 212 | 213 | ImGui::SetCursorPosX(160); ImGui::SetCursorPosY(100); 214 | if (ImGui::Button(" ", ImVec2(425, 50))) 215 | { 216 | chams = !chams; 217 | } 218 | ImGui::SetWindowFontScale(1.4); 219 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(107); ImGui::Text("Chams"); 220 | ImGui::SetWindowFontScale(0.8); 221 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(125); ImGui::Text("Paints the enemies behind the wall."); 222 | ImGui::SetCursorPosX(530); ImGui::SetCursorPosY(115); ToggleButton("a", &chams); 223 | 224 | 225 | ImGui::SetCursorPosX(160); ImGui::SetCursorPosY(165); 226 | if (ImGui::Button(" ", ImVec2(425, 50))) 227 | { 228 | espbox3d = !espbox3d; 229 | } 230 | ImGui::SetWindowFontScale(1.4); 231 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(172); ImGui::Text("Esp Box"); 232 | ImGui::SetWindowFontScale(0.8); 233 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(190); ImGui::Text("Boxes enemies behind the wall."); 234 | ImGui::SetCursorPosX(530); ImGui::SetCursorPosY(180); ToggleButton("b", &espbox3d); 235 | 236 | 237 | ImGui::SetCursorPosX(160); ImGui::SetCursorPosY(230); 238 | if (ImGui::Button(" ", ImVec2(425, 50))) 239 | { 240 | lineesp = !lineesp; 241 | } 242 | ImGui::SetWindowFontScale(1.4); 243 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(237); ImGui::Text("Esp Line"); 244 | ImGui::SetWindowFontScale(0.8); 245 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(255); ImGui::Text("Mark the enemies behind the wall with a line."); 246 | ImGui::SetCursorPosX(530); ImGui::SetCursorPosY(245); ToggleButton("c", &lineesp); 247 | 248 | 249 | ImGui::SetCursorPosX(160); ImGui::SetCursorPosY(295); 250 | if (ImGui::Button(" ", ImVec2(425, 50))) 251 | { 252 | distanceesp = !distanceesp; 253 | } 254 | ImGui::SetWindowFontScale(1.4); 255 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(302); ImGui::Text("Esp Distance"); 256 | ImGui::SetWindowFontScale(0.8); 257 | ImGui::SetCursorPosX(170); ImGui::SetCursorPosY(320); ImGui::Text("Show the distance of the enemies behind the wall."); 258 | ImGui::SetCursorPosX(530); ImGui::SetCursorPosY(310); ToggleButton("d", &distanceesp); 259 | 260 | 261 | ImGui::SetCursorPosX(0); ImGui::SetCursorPosY(0); ImGui::BeginChild("xd", ImVec2(150, 420)); 262 | 263 | ImGui::SetWindowFontScale(1.6); 264 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(20); ImGui::Text("--- Visual"); 265 | ImGui::SetCursorPosX(78); ImGui::SetCursorPosY(17); ImGui::Image(eyeimgx, ImVec2(24, 24)); 266 | ImGui::SetWindowFontScale(1.3); 267 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(45); ImGui::Button("Player", ImVec2(135, 25)); 268 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(78); ImGui::Button("BattleRoyale", ImVec2(135, 25)); 269 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(108); ImGui::Button("Color & Settings", ImVec2(135, 25)); 270 | 271 | ImGui::SetWindowFontScale(1.6); 272 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(150); ImGui::Text("--- AimBot"); 273 | ImGui::SetCursorPosX(87); ImGui::SetCursorPosY(149); ImGui::Image(aimimgx, ImVec2(22, 22)); 274 | ImGui::SetWindowFontScale(1.3); 275 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(177); ImGui::Button("AimBot", ImVec2(135, 25)); 276 | 277 | ImGui::SetWindowFontScale(1.6); 278 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(220); ImGui::Text("--- Misc"); 279 | ImGui::SetCursorPosX(70); ImGui::SetCursorPosY(218); ImGui::Image(setx, ImVec2(22, 22)); 280 | ImGui::SetWindowFontScale(1.3); 281 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(246); ImGui::Button("Weapon", ImVec2(135, 25)); 282 | ImGui::SetCursorPosX(20); ImGui::SetCursorPosY(279); ImGui::Button("Memory", ImVec2(135, 25)); 283 | 284 | ImGui::GetIO().MouseDrawCursor = true; 285 | ImGui::End(); 286 | } 287 | ImGui::GetIO().MouseDrawCursor = Menu; 288 | 289 | 290 | ImGui::EndFrame(); 291 | ImGui::Render(); 292 | ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); 293 | 294 | 295 | return Present_orig(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); 296 | } 297 | 298 | HRESULT APIENTRY EndScene_hook(IDirect3DDevice9* pDevice) 299 | { 300 | 301 | if (pDevice == nullptr) return EndScene_orig(pDevice); 302 | { 303 | { 304 | 305 | } 306 | } 307 | 308 | 309 | return EndScene_orig(pDevice); 310 | } 311 | 312 | HRESULT APIENTRY Reset_hook(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters) 313 | { 314 | ImGui_ImplDX9_InvalidateDeviceObjects(); 315 | HRESULT ResetReturn = Reset_orig(pDevice, pPresentationParameters); 316 | ImGui_ImplDX9_CreateDeviceObjects(); 317 | return ResetReturn; 318 | } 319 | 320 | IDirect3DVertexBuffer9* pStreamData; 321 | UINT XOffset = 0; 322 | UINT LStride = 0; 323 | IDirect3DVertexShader9* vShader; 324 | UINT vSize; 325 | FILE* LOG; 326 | char dllpath[255]; 327 | char logfile[255]; 328 | DWORD CSH; 329 | HANDLE hProcces; 330 | 331 | struct sscreen 332 | { 333 | int height; 334 | int width; 335 | }screen; 336 | 337 | 338 | char* GetFile(char* file); 339 | void WriteFile(FILE* file, const char* fmt, ...); 340 | 341 | HANDLE Process = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()); 342 | 343 | DrawIndexedPrimitive_t OrigDrawIndexedPrimitive; 344 | Reset_t OrigReset; 345 | 346 | HRESULT __stdcall ResetHook(IDirect3DDevice9* Device, D3DPRESENT_PARAMETERS* Params) 347 | { 348 | return OrigReset(Device, Params); 349 | } 350 | 351 | HRESULT GenerateShader(IDirect3DDevice9* Device, IDirect3DPixelShader9** Shader, float r, float g, float b) 352 | { 353 | char ShaderAsmBuf[256]; 354 | ID3DXBuffer* ShaderBuf = NULL; 355 | sprintf_s(ShaderAsmBuf, "ps_3_0\ndef c0, %f, %f, %f, %f\nmov oC0,c0", r, g, b, 1.0f); 356 | if (FAILED(D3DXAssembleShader(ShaderAsmBuf, (strlen(ShaderAsmBuf) + 1), NULL, NULL, 0, &ShaderBuf, NULL))) 357 | { 358 | return E_FAIL; 359 | } 360 | return Device->CreatePixelShader((const DWORD*)ShaderBuf->GetBufferPointer(), Shader); 361 | } 362 | 363 | bool DIPInit = true; 364 | DWORD D3d9Base; 365 | DWORD* D3d9VTable; 366 | wchar_t DllPath[512]; 367 | wchar_t PathBuffer[512]; 368 | IDirect3DPixelShader9* RedShader; 369 | IDirect3DPixelShader9* GreenShader; 370 | IDirect3DTexture9* RedTexture; 371 | IDirect3DTexture9* GreenTexture; 372 | 373 | 374 | HRESULT APIENTRY DrawIndexedPrimitive_hook(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) 375 | { 376 | // TOP OF VISUALS 377 | 378 | if (DIPInit) 379 | { 380 | 381 | DIPInit = false; 382 | } 383 | 384 | if (SUCCEEDED(pDevice->GetVertexShader(&vShader))) 385 | if (vShader != NULL) 386 | if (SUCCEEDED(vShader->GetFunction(NULL, &vSize))) 387 | if (vShader != NULL) { vShader->Release(); vShader = NULL; } 388 | 389 | if(wallhack) 390 | if(Stride == 36 && vSize > 255 && NumVertices > 1160) 391 | { 392 | float bias = 1000.0f; 393 | float bias_float = static_cast(-bias); 394 | bias_float /= 2000;//10000.0f; 395 | pDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&bias_float); 396 | DrawIndexedPrimitive_orig(pDevice, Type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); 397 | pDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); 398 | } 399 | 400 | if (chams) 401 | if (Stride == 36 && vSize > 255 && NumVertices > 1160) 402 | { 403 | pDevice->SetRenderState(D3DRS_ZENABLE, false); 404 | pDevice->SetTexture(0, chamscolor); 405 | DrawIndexedPrimitive_orig(pDevice, Type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); 406 | pDevice->SetTexture(0, chamscolor); 407 | pDevice->SetRenderState(D3DRS_ZENABLE, true); 408 | } 409 | 410 | HRESULT hRet = DrawIndexedPrimitive_orig(pDevice, Type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); 411 | 412 | 413 | return DrawIndexedPrimitive_orig(pDevice, Type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); 414 | } 415 | 416 | 417 | HRESULT APIENTRY SetStreamSource_hook(LPDIRECT3DDEVICE9 pDevice, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT sStride) 418 | { 419 | if (StreamNumber == 0) 420 | Stride = sStride; 421 | 422 | return SetStreamSource_orig(pDevice, StreamNumber, pStreamData, OffsetInBytes, sStride); 423 | } 424 | 425 | DWORD WINAPI Thread(LPVOID) 426 | { 427 | 428 | while (!GetModuleHandleA("d3d9.dll")) { 429 | Sleep(200); 430 | } 431 | IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION); 432 | IDirect3DDevice9* d3ddev = NULL; 433 | HWND tmpWnd = CreateWindowA("BUTTON", "DX", WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, Hand, NULL); 434 | D3DPRESENT_PARAMETERS d3dpp; 435 | ZeroMemory(&d3dpp, sizeof(d3dpp)); 436 | d3dpp.Windowed = TRUE; 437 | d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 438 | d3dpp.hDeviceWindow = tmpWnd; 439 | d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 440 | HRESULT result = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, tmpWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); 441 | #if defined _M_X64 442 | DWORD64* dVtable = (DWORD64*)d3ddev; 443 | dVtable = (DWORD64*)dVtable[0]; 444 | #elif defined _M_IX86 445 | DWORD* dVtable = (DWORD*)d3ddev; 446 | dVtable = (DWORD*)dVtable[0]; 447 | #endif 448 | SetStreamSource_orig = (SetStreamSource)dVtable[100]; 449 | DrawIndexedPrimitive_orig = (DrawIndexedPrimitive)dVtable[82]; 450 | Present_orig = (Present)dVtable[17]; 451 | EndScene_orig = (EndScene)dVtable[42]; 452 | Reset_orig = (Reset)dVtable[16]; 453 | Sleep(2000); 454 | DetourTransactionBegin(); 455 | DetourUpdateThread(GetCurrentThread()); 456 | DetourAttach(&(LPVOID&)SetStreamSource_orig, (PBYTE)SetStreamSource_hook); 457 | DetourAttach(&(LPVOID&)DrawIndexedPrimitive_orig, (PBYTE)DrawIndexedPrimitive_hook); 458 | DetourAttach(&(LPVOID&)Present_orig, (PBYTE)Present_hook); 459 | DetourAttach(&(LPVOID&)EndScene_orig, (PBYTE)EndScene_hook); 460 | DetourAttach(&(LPVOID&)Reset_orig, (PBYTE)Reset_hook); 461 | DetourTransactionCommit(); 462 | d3ddev->Release(); 463 | d3d->Release(); 464 | DestroyWindow(tmpWnd); 465 | return 1; 466 | } 467 | 468 | BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved) 469 | { 470 | if (dwReason == DLL_PROCESS_ATTACH) { 471 | 472 | CreateThread(0, 0, Thread, 0, 0, 0); 473 | } 474 | return TRUE; 475 | } -------------------------------------------------------------------------------- /Detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #ifdef DETOURS_INTERNAL 20 | 21 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 22 | #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 23 | 24 | #pragma warning(disable:4068) // unknown pragma (suppress) 25 | 26 | #if _MSC_VER >= 1900 27 | #pragma warning(push) 28 | #pragma warning(disable:4091) // empty typedef 29 | #endif 30 | 31 | #include 32 | #if (_MSC_VER < 1310) 33 | #else 34 | #pragma warning(push) 35 | #if _MSC_VER > 1400 36 | #pragma warning(disable:6102 6103) // /analyze warnings 37 | #endif 38 | #include 39 | #pragma warning(pop) 40 | #endif 41 | 42 | #endif // DETOURS_INTERNAL 43 | 44 | ////////////////////////////////////////////////////////////////////////////// 45 | // 46 | 47 | #undef DETOURS_X64 48 | #undef DETOURS_X86 49 | #undef DETOURS_IA64 50 | #undef DETOURS_ARM 51 | #undef DETOURS_ARM64 52 | #undef DETOURS_BITS 53 | #undef DETOURS_32BIT 54 | #undef DETOURS_64BIT 55 | 56 | #if defined(_X86_) 57 | #define DETOURS_X86 58 | #define DETOURS_OPTION_BITS 64 59 | 60 | #elif defined(_AMD64_) 61 | #define DETOURS_X64 62 | #define DETOURS_OPTION_BITS 32 63 | 64 | #elif defined(_IA64_) 65 | #define DETOURS_IA64 66 | #define DETOURS_OPTION_BITS 32 67 | 68 | #elif defined(_ARM_) 69 | #define DETOURS_ARM 70 | 71 | #elif defined(_ARM64_) 72 | #define DETOURS_ARM64 73 | 74 | #else 75 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 76 | #endif 77 | 78 | #ifdef _WIN64 79 | #undef DETOURS_32BIT 80 | #define DETOURS_64BIT 1 81 | #define DETOURS_BITS 64 82 | // If all 64bit kernels can run one and only one 32bit architecture. 83 | //#define DETOURS_OPTION_BITS 32 84 | #else 85 | #define DETOURS_32BIT 1 86 | #undef DETOURS_64BIT 87 | #define DETOURS_BITS 32 88 | // If all 64bit kernels can run one and only one 32bit architecture. 89 | //#define DETOURS_OPTION_BITS 32 90 | #endif 91 | 92 | /////////////////////////////////////////////////////////////// Helper Macros. 93 | // 94 | #define DETOURS_STRINGIFY_(x) #x 95 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 96 | 97 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 98 | 99 | ////////////////////////////////////////////////////////////////////////////// 100 | // 101 | 102 | #if (_MSC_VER < 1299) 103 | typedef LONG LONG_PTR; 104 | typedef ULONG ULONG_PTR; 105 | #endif 106 | 107 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 108 | // 109 | // These definitions are include so that Detours will build even if the 110 | // compiler doesn't have full SAL 2.0 support. 111 | // 112 | #ifndef DETOURS_DONT_REMOVE_SAL_20 113 | 114 | #ifdef DETOURS_TEST_REMOVE_SAL_20 115 | #undef _Analysis_assume_ 116 | #undef _Benign_race_begin_ 117 | #undef _Benign_race_end_ 118 | #undef _Field_range_ 119 | #undef _Field_size_ 120 | #undef _In_ 121 | #undef _In_bytecount_ 122 | #undef _In_count_ 123 | #undef _In_opt_ 124 | #undef _In_opt_bytecount_ 125 | #undef _In_opt_count_ 126 | #undef _In_opt_z_ 127 | #undef _In_range_ 128 | #undef _In_reads_ 129 | #undef _In_reads_bytes_ 130 | #undef _In_reads_opt_ 131 | #undef _In_reads_opt_bytes_ 132 | #undef _In_reads_or_z_ 133 | #undef _In_z_ 134 | #undef _Inout_ 135 | #undef _Inout_opt_ 136 | #undef _Inout_z_count_ 137 | #undef _Out_ 138 | #undef _Out_opt_ 139 | #undef _Out_writes_ 140 | #undef _Outptr_result_maybenull_ 141 | #undef _Readable_bytes_ 142 | #undef _Success_ 143 | #undef _Writable_bytes_ 144 | #undef _Pre_notnull_ 145 | #endif 146 | 147 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 148 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 149 | #endif 150 | 151 | #if defined(_In_count_) && !defined(_In_reads_) 152 | #define _In_reads_(x) _In_count_(x) 153 | #endif 154 | 155 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 156 | #define _In_reads_opt_(x) _In_opt_count_(x) 157 | #endif 158 | 159 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 160 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 161 | #endif 162 | 163 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 164 | #define _In_reads_bytes_(x) _In_bytecount_(x) 165 | #endif 166 | 167 | #ifndef _In_ 168 | #define _In_ 169 | #endif 170 | 171 | #ifndef _In_bytecount_ 172 | #define _In_bytecount_(x) 173 | #endif 174 | 175 | #ifndef _In_count_ 176 | #define _In_count_(x) 177 | #endif 178 | 179 | #ifndef _In_opt_ 180 | #define _In_opt_ 181 | #endif 182 | 183 | #ifndef _In_opt_bytecount_ 184 | #define _In_opt_bytecount_(x) 185 | #endif 186 | 187 | #ifndef _In_opt_count_ 188 | #define _In_opt_count_(x) 189 | #endif 190 | 191 | #ifndef _In_opt_z_ 192 | #define _In_opt_z_ 193 | #endif 194 | 195 | #ifndef _In_range_ 196 | #define _In_range_(x,y) 197 | #endif 198 | 199 | #ifndef _In_reads_ 200 | #define _In_reads_(x) 201 | #endif 202 | 203 | #ifndef _In_reads_bytes_ 204 | #define _In_reads_bytes_(x) 205 | #endif 206 | 207 | #ifndef _In_reads_opt_ 208 | #define _In_reads_opt_(x) 209 | #endif 210 | 211 | #ifndef _In_reads_opt_bytes_ 212 | #define _In_reads_opt_bytes_(x) 213 | #endif 214 | 215 | #ifndef _In_reads_or_z_ 216 | #define _In_reads_or_z_ 217 | #endif 218 | 219 | #ifndef _In_z_ 220 | #define _In_z_ 221 | #endif 222 | 223 | #ifndef _Inout_ 224 | #define _Inout_ 225 | #endif 226 | 227 | #ifndef _Inout_opt_ 228 | #define _Inout_opt_ 229 | #endif 230 | 231 | #ifndef _Inout_z_count_ 232 | #define _Inout_z_count_(x) 233 | #endif 234 | 235 | #ifndef _Out_ 236 | #define _Out_ 237 | #endif 238 | 239 | #ifndef _Out_opt_ 240 | #define _Out_opt_ 241 | #endif 242 | 243 | #ifndef _Out_writes_ 244 | #define _Out_writes_(x) 245 | #endif 246 | 247 | #ifndef _Outptr_result_maybenull_ 248 | #define _Outptr_result_maybenull_ 249 | #endif 250 | 251 | #ifndef _Writable_bytes_ 252 | #define _Writable_bytes_(x) 253 | #endif 254 | 255 | #ifndef _Readable_bytes_ 256 | #define _Readable_bytes_(x) 257 | #endif 258 | 259 | #ifndef _Success_ 260 | #define _Success_(x) 261 | #endif 262 | 263 | #ifndef _Pre_notnull_ 264 | #define _Pre_notnull_ 265 | #endif 266 | 267 | #ifdef DETOURS_INTERNAL 268 | 269 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 270 | 271 | #ifndef _Benign_race_begin_ 272 | #define _Benign_race_begin_ 273 | #endif 274 | 275 | #ifndef _Benign_race_end_ 276 | #define _Benign_race_end_ 277 | #endif 278 | 279 | #ifndef _Field_size_ 280 | #define _Field_size_(x) 281 | #endif 282 | 283 | #ifndef _Field_range_ 284 | #define _Field_range_(x,y) 285 | #endif 286 | 287 | #ifndef _Analysis_assume_ 288 | #define _Analysis_assume_(x) 289 | #endif 290 | 291 | #endif // DETOURS_INTERNAL 292 | #endif // DETOURS_DONT_REMOVE_SAL_20 293 | 294 | ////////////////////////////////////////////////////////////////////////////// 295 | // 296 | #ifndef GUID_DEFINED 297 | #define GUID_DEFINED 298 | typedef struct _GUID 299 | { 300 | DWORD Data1; 301 | WORD Data2; 302 | WORD Data3; 303 | BYTE Data4[8]; 304 | } GUID; 305 | 306 | #ifdef INITGUID 307 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 308 | const GUID name \ 309 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 310 | #else 311 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 312 | const GUID name 313 | #endif // INITGUID 314 | #endif // !GUID_DEFINED 315 | 316 | #if defined(__cplusplus) 317 | #ifndef _REFGUID_DEFINED 318 | #define _REFGUID_DEFINED 319 | #define REFGUID const GUID & 320 | #endif // !_REFGUID_DEFINED 321 | #else // !__cplusplus 322 | #ifndef _REFGUID_DEFINED 323 | #define _REFGUID_DEFINED 324 | #define REFGUID const GUID * const 325 | #endif // !_REFGUID_DEFINED 326 | #endif // !__cplusplus 327 | 328 | #ifndef ARRAYSIZE 329 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 330 | #endif 331 | 332 | // 333 | ////////////////////////////////////////////////////////////////////////////// 334 | 335 | #ifdef __cplusplus 336 | extern "C" { 337 | #endif // __cplusplus 338 | 339 | /////////////////////////////////////////////////// Instruction Target Macros. 340 | // 341 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 342 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 343 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 344 | 345 | extern const GUID DETOUR_EXE_RESTORE_GUID; 346 | extern const GUID DETOUR_EXE_HELPER_GUID; 347 | 348 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 349 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 350 | 351 | /////////////////////////////////////////////////////////// Binary Structures. 352 | // 353 | #pragma pack(push, 8) 354 | typedef struct _DETOUR_SECTION_HEADER 355 | { 356 | DWORD cbHeaderSize; 357 | DWORD nSignature; 358 | DWORD nDataOffset; 359 | DWORD cbDataSize; 360 | 361 | DWORD nOriginalImportVirtualAddress; 362 | DWORD nOriginalImportSize; 363 | DWORD nOriginalBoundImportVirtualAddress; 364 | DWORD nOriginalBoundImportSize; 365 | 366 | DWORD nOriginalIatVirtualAddress; 367 | DWORD nOriginalIatSize; 368 | DWORD nOriginalSizeOfImage; 369 | DWORD cbPrePE; 370 | 371 | DWORD nOriginalClrFlags; 372 | DWORD reserved1; 373 | DWORD reserved2; 374 | DWORD reserved3; 375 | 376 | // Followed by cbPrePE bytes of data. 377 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 378 | 379 | typedef struct _DETOUR_SECTION_RECORD 380 | { 381 | DWORD cbBytes; 382 | DWORD nReserved; 383 | GUID guid; 384 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 385 | 386 | typedef struct _DETOUR_CLR_HEADER 387 | { 388 | // Header versioning 389 | ULONG cb; 390 | USHORT MajorRuntimeVersion; 391 | USHORT MinorRuntimeVersion; 392 | 393 | // Symbol table and startup information 394 | IMAGE_DATA_DIRECTORY MetaData; 395 | ULONG Flags; 396 | 397 | // Followed by the rest of the IMAGE_COR20_HEADER 398 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 399 | 400 | typedef struct _DETOUR_EXE_RESTORE 401 | { 402 | DWORD cb; 403 | DWORD cbidh; 404 | DWORD cbinh; 405 | DWORD cbclr; 406 | 407 | PBYTE pidh; 408 | PBYTE pinh; 409 | PBYTE pclr; 410 | 411 | IMAGE_DOS_HEADER idh; 412 | union { 413 | IMAGE_NT_HEADERS inh; // all environments have this 414 | #ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this 415 | IMAGE_NT_HEADERS32 inh32; 416 | #endif 417 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 418 | IMAGE_NT_HEADERS64 inh64; 419 | #endif 420 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 421 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 422 | sizeof(IMAGE_SECTION_HEADER) * 32]; 423 | #else 424 | BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32]; 425 | #endif 426 | }; 427 | DETOUR_CLR_HEADER clr; 428 | 429 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 430 | 431 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC 432 | C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); 433 | #endif 434 | 435 | // The size can change, but assert for clarity due to the muddying #ifdefs. 436 | #ifdef _WIN64 437 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); 438 | #else 439 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); 440 | #endif 441 | 442 | typedef struct _DETOUR_EXE_HELPER 443 | { 444 | DWORD cb; 445 | DWORD pid; 446 | DWORD nDlls; 447 | CHAR rDlls[4]; 448 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 449 | 450 | #pragma pack(pop) 451 | 452 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 453 | { \ 454 | sizeof(DETOUR_SECTION_HEADER),\ 455 | DETOUR_SECTION_HEADER_SIGNATURE,\ 456 | sizeof(DETOUR_SECTION_HEADER),\ 457 | (cbSectionSize),\ 458 | \ 459 | 0,\ 460 | 0,\ 461 | 0,\ 462 | 0,\ 463 | \ 464 | 0,\ 465 | 0,\ 466 | 0,\ 467 | 0,\ 468 | } 469 | 470 | ///////////////////////////////////////////////////////////// Binary Typedefs. 471 | // 472 | typedef BOOL(CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 473 | _In_opt_ PVOID pContext, 474 | _In_opt_ LPCSTR pszFile, 475 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 476 | 477 | typedef BOOL(CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 478 | _In_opt_ PVOID pContext, 479 | _In_ LPCSTR pszOrigFile, 480 | _In_ LPCSTR pszFile, 481 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 482 | 483 | typedef BOOL(CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 484 | _In_opt_ PVOID pContext, 485 | _In_ ULONG nOrigOrdinal, 486 | _In_ ULONG nOrdinal, 487 | _Out_ ULONG *pnOutOrdinal, 488 | _In_opt_ LPCSTR pszOrigSymbol, 489 | _In_opt_ LPCSTR pszSymbol, 490 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 491 | 492 | typedef BOOL(CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 493 | _In_opt_ PVOID pContext); 494 | 495 | typedef BOOL(CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 496 | _In_ ULONG nOrdinal, 497 | _In_opt_ LPCSTR pszName, 498 | _In_opt_ PVOID pCode); 499 | 500 | typedef BOOL(CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 501 | _In_opt_ HMODULE hModule, 502 | _In_opt_ LPCSTR pszFile); 503 | 504 | typedef BOOL(CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 505 | _In_ DWORD nOrdinal, 506 | _In_opt_ LPCSTR pszFunc, 507 | _In_opt_ PVOID pvFunc); 508 | 509 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 510 | typedef BOOL(CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 511 | _In_ DWORD nOrdinal, 512 | _In_opt_ LPCSTR pszFunc, 513 | _In_opt_ PVOID* ppvFunc); 514 | 515 | typedef VOID * PDETOUR_BINARY; 516 | typedef VOID * PDETOUR_LOADED_BINARY; 517 | 518 | //////////////////////////////////////////////////////////// Transaction APIs. 519 | // 520 | LONG WINAPI DetourTransactionBegin(VOID); 521 | LONG WINAPI DetourTransactionAbort(VOID); 522 | LONG WINAPI DetourTransactionCommit(VOID); 523 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 524 | 525 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 526 | 527 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 528 | _In_ PVOID pDetour); 529 | 530 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 531 | _In_ PVOID pDetour, 532 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 533 | _Out_opt_ PVOID *ppRealTarget, 534 | _Out_opt_ PVOID *ppRealDetour); 535 | 536 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 537 | _In_ PVOID pDetour); 538 | 539 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 540 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 541 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 542 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 543 | 544 | ////////////////////////////////////////////////////////////// Code Functions. 545 | // 546 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 547 | _In_ LPCSTR pszFunction); 548 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 549 | _Out_opt_ PVOID *ppGlobals); 550 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 551 | _Inout_opt_ PVOID *ppDstPool, 552 | _In_ PVOID pSrc, 553 | _Out_opt_ PVOID *ppTarget, 554 | _Out_opt_ LONG *plExtra); 555 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 556 | _In_ BOOL fLimitReferencesToModule); 557 | PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, 558 | _Out_ PDWORD pcbAllocatedSize); 559 | 560 | ///////////////////////////////////////////////////// Loaded Binary Functions. 561 | // 562 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 563 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 564 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 565 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 566 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 567 | _In_opt_ PVOID pContext, 568 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 569 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 570 | _In_opt_ PVOID pContext, 571 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 572 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 573 | 574 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 575 | _In_opt_ PVOID pContext, 576 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 577 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 578 | 579 | _Writable_bytes_(*pcbData) 580 | _Readable_bytes_(*pcbData) 581 | _Success_(return != NULL) 582 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 583 | _In_ REFGUID rguid, 584 | _Out_ DWORD *pcbData); 585 | 586 | _Writable_bytes_(*pcbData) 587 | _Readable_bytes_(*pcbData) 588 | _Success_(return != NULL) 589 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 590 | _Out_ DWORD * pcbData); 591 | 592 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 593 | 594 | ///////////////////////////////////////////////// Persistent Binary Functions. 595 | // 596 | 597 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 598 | 599 | _Writable_bytes_(*pcbData) 600 | _Readable_bytes_(*pcbData) 601 | _Success_(return != NULL) 602 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 603 | _Out_opt_ GUID *pGuid, 604 | _Out_ DWORD *pcbData, 605 | _Inout_ DWORD *pnIterator); 606 | 607 | _Writable_bytes_(*pcbData) 608 | _Readable_bytes_(*pcbData) 609 | _Success_(return != NULL) 610 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 611 | _In_ REFGUID rguid, 612 | _Out_ DWORD *pcbData); 613 | 614 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 615 | _In_ REFGUID rguid, 616 | _In_reads_opt_(cbData) PVOID pData, 617 | _In_ DWORD cbData); 618 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 619 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 620 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 621 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 622 | _In_opt_ PVOID pContext, 623 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 624 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 625 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 626 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 627 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 628 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 629 | 630 | /////////////////////////////////////////////////// Create Process & Load Dll. 631 | // 632 | typedef BOOL(WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 633 | _In_opt_ LPCSTR lpApplicationName, 634 | _Inout_opt_ LPSTR lpCommandLine, 635 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 636 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 637 | _In_ BOOL bInheritHandles, 638 | _In_ DWORD dwCreationFlags, 639 | _In_opt_ LPVOID lpEnvironment, 640 | _In_opt_ LPCSTR lpCurrentDirectory, 641 | _In_ LPSTARTUPINFOA lpStartupInfo, 642 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 643 | 644 | typedef BOOL(WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 645 | _In_opt_ LPCWSTR lpApplicationName, 646 | _Inout_opt_ LPWSTR lpCommandLine, 647 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 648 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 649 | _In_ BOOL bInheritHandles, 650 | _In_ DWORD dwCreationFlags, 651 | _In_opt_ LPVOID lpEnvironment, 652 | _In_opt_ LPCWSTR lpCurrentDirectory, 653 | _In_ LPSTARTUPINFOW lpStartupInfo, 654 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 655 | 656 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 657 | _Inout_opt_ LPSTR lpCommandLine, 658 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 659 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 660 | _In_ BOOL bInheritHandles, 661 | _In_ DWORD dwCreationFlags, 662 | _In_opt_ LPVOID lpEnvironment, 663 | _In_opt_ LPCSTR lpCurrentDirectory, 664 | _In_ LPSTARTUPINFOA lpStartupInfo, 665 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 666 | _In_ LPCSTR lpDllName, 667 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 668 | 669 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 670 | _Inout_opt_ LPWSTR lpCommandLine, 671 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 672 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 673 | _In_ BOOL bInheritHandles, 674 | _In_ DWORD dwCreationFlags, 675 | _In_opt_ LPVOID lpEnvironment, 676 | _In_opt_ LPCWSTR lpCurrentDirectory, 677 | _In_ LPSTARTUPINFOW lpStartupInfo, 678 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 679 | _In_ LPCSTR lpDllName, 680 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 681 | 682 | #ifdef UNICODE 683 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 684 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 685 | #else 686 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 687 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 688 | #endif // !UNICODE 689 | 690 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 691 | _Inout_opt_ LPSTR lpCommandLine, 692 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 693 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 694 | _In_ BOOL bInheritHandles, 695 | _In_ DWORD dwCreationFlags, 696 | _In_opt_ LPVOID lpEnvironment, 697 | _In_opt_ LPCSTR lpCurrentDirectory, 698 | _In_ LPSTARTUPINFOA lpStartupInfo, 699 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 700 | _In_ LPCSTR lpDllName, 701 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 702 | 703 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 704 | _Inout_opt_ LPWSTR lpCommandLine, 705 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 706 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 707 | _In_ BOOL bInheritHandles, 708 | _In_ DWORD dwCreationFlags, 709 | _In_opt_ LPVOID lpEnvironment, 710 | _In_opt_ LPCWSTR lpCurrentDirectory, 711 | _In_ LPSTARTUPINFOW lpStartupInfo, 712 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 713 | _In_ LPCSTR lpDllName, 714 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 715 | 716 | #ifdef UNICODE 717 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 718 | #else 719 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 720 | #endif // !UNICODE 721 | 722 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 723 | _Inout_opt_ LPSTR lpCommandLine, 724 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 725 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 726 | _In_ BOOL bInheritHandles, 727 | _In_ DWORD dwCreationFlags, 728 | _In_opt_ LPVOID lpEnvironment, 729 | _In_opt_ LPCSTR lpCurrentDirectory, 730 | _In_ LPSTARTUPINFOA lpStartupInfo, 731 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 732 | _In_ DWORD nDlls, 733 | _In_reads_(nDlls) LPCSTR *rlpDlls, 734 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 735 | 736 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 737 | _Inout_opt_ LPWSTR lpCommandLine, 738 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 739 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 740 | _In_ BOOL bInheritHandles, 741 | _In_ DWORD dwCreationFlags, 742 | _In_opt_ LPVOID lpEnvironment, 743 | _In_opt_ LPCWSTR lpCurrentDirectory, 744 | _In_ LPSTARTUPINFOW lpStartupInfo, 745 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 746 | _In_ DWORD nDlls, 747 | _In_reads_(nDlls) LPCSTR *rlpDlls, 748 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 749 | 750 | #ifdef UNICODE 751 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 752 | #else 753 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 754 | #endif // !UNICODE 755 | 756 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 757 | _In_ LPCSTR lpDllName, 758 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 759 | 760 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 761 | _In_ LPCSTR lpDllName, 762 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 763 | 764 | #ifdef UNICODE 765 | #define DetourProcessViaHelper DetourProcessViaHelperW 766 | #else 767 | #define DetourProcessViaHelper DetourProcessViaHelperA 768 | #endif // !UNICODE 769 | 770 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 771 | _In_ DWORD nDlls, 772 | _In_reads_(nDlls) LPCSTR *rlpDlls, 773 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 774 | 775 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 776 | _In_ DWORD nDlls, 777 | _In_reads_(nDlls) LPCSTR *rlpDlls, 778 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 779 | 780 | #ifdef UNICODE 781 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 782 | #else 783 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 784 | #endif // !UNICODE 785 | 786 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 787 | _In_reads_(nDlls) LPCSTR *rlpDlls, 788 | _In_ DWORD nDlls); 789 | 790 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 791 | _In_ HMODULE hImage, 792 | _In_ BOOL bIs32Bit, 793 | _In_reads_(nDlls) LPCSTR *rlpDlls, 794 | _In_ DWORD nDlls); 795 | 796 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 797 | _In_ REFGUID rguid, 798 | _In_reads_bytes_(cbData) PVOID pvData, 799 | _In_ DWORD cbData); 800 | BOOL WINAPI DetourRestoreAfterWith(VOID); 801 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 802 | _In_ DWORD cbData); 803 | BOOL WINAPI DetourIsHelperProcess(VOID); 804 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 805 | _In_ HINSTANCE, 806 | _In_ LPSTR, 807 | _In_ INT); 808 | 809 | // 810 | ////////////////////////////////////////////////////////////////////////////// 811 | #ifdef __cplusplus 812 | } 813 | #endif // __cplusplus 814 | 815 | //////////////////////////////////////////////// Detours Internal Definitions. 816 | // 817 | #ifdef __cplusplus 818 | #ifdef DETOURS_INTERNAL 819 | 820 | #define NOTHROW 821 | // #define NOTHROW (nothrow) 822 | 823 | ////////////////////////////////////////////////////////////////////////////// 824 | // 825 | #if (_MSC_VER < 1299) 826 | #include 827 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 828 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 829 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 830 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 831 | 832 | static inline 833 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 834 | { 835 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 836 | } 837 | #else 838 | #pragma warning(push) 839 | #pragma warning(disable:4091) // empty typedef 840 | #include 841 | #pragma warning(pop) 842 | #endif 843 | 844 | #ifdef IMAGEAPI // defined by DBGHELP.H 845 | typedef LPAPI_VERSION(NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 846 | 847 | typedef BOOL(NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 848 | _In_opt_ LPCSTR UserSearchPath, 849 | _In_ BOOL fInvadeProcess); 850 | typedef DWORD(NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 851 | typedef DWORD(NTAPI *PF_SymGetOptions)(VOID); 852 | typedef DWORD64(NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 853 | _In_opt_ HANDLE hFile, 854 | _In_ LPSTR ImageName, 855 | _In_opt_ LPSTR ModuleName, 856 | _In_ DWORD64 BaseOfDll, 857 | _In_opt_ DWORD SizeOfDll); 858 | typedef BOOL(NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 859 | _In_ DWORD64 qwAddr, 860 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 861 | typedef BOOL(NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 862 | _In_ LPSTR Name, 863 | _Out_ PSYMBOL_INFO Symbol); 864 | 865 | typedef struct _DETOUR_SYM_INFO 866 | { 867 | HANDLE hProcess; 868 | HMODULE hDbgHelp; 869 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 870 | PF_SymInitialize pfSymInitialize; 871 | PF_SymSetOptions pfSymSetOptions; 872 | PF_SymGetOptions pfSymGetOptions; 873 | PF_SymLoadModule64 pfSymLoadModule64; 874 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 875 | PF_SymFromName pfSymFromName; 876 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 877 | 878 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 879 | 880 | #endif // IMAGEAPI 881 | 882 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 883 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 884 | #endif 885 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 886 | 887 | #ifndef DETOUR_TRACE 888 | #if DETOUR_DEBUG 889 | #define DETOUR_TRACE(x) printf x 890 | #define DETOUR_BREAK() __debugbreak() 891 | #include 892 | #include 893 | #else 894 | #define DETOUR_TRACE(x) 895 | #define DETOUR_BREAK() 896 | #endif 897 | #endif 898 | 899 | #if 1 || defined(DETOURS_IA64) 900 | 901 | // 902 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 903 | // 904 | 905 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 906 | 907 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 908 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 909 | 910 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 911 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 912 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 913 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 914 | 915 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 916 | 917 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 918 | { 919 | public: 920 | union 921 | { 922 | BYTE data[16]; 923 | UINT64 wide[2]; 924 | }; 925 | 926 | enum { 927 | A_UNIT = 1u, 928 | I_UNIT = 2u, 929 | M_UNIT = 3u, 930 | B_UNIT = 4u, 931 | F_UNIT = 5u, 932 | L_UNIT = 6u, 933 | X_UNIT = 7u, 934 | }; 935 | struct DETOUR_IA64_METADATA 936 | { 937 | ULONG nTemplate : 8; // Instruction template. 938 | ULONG nUnit0 : 4; // Unit for slot 0 939 | ULONG nUnit1 : 4; // Unit for slot 1 940 | ULONG nUnit2 : 4; // Unit for slot 2 941 | }; 942 | 943 | protected: 944 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 945 | 946 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 947 | 948 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 949 | _In_ BYTE slot, 950 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 951 | 952 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 953 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 954 | 955 | // 00 956 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 957 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 958 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 959 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 960 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 961 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 962 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 963 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 964 | BYTE GetTemplate() const; 965 | // Get 4 bit opcodes. 966 | BYTE GetInst0() const; 967 | BYTE GetInst1() const; 968 | BYTE GetInst2() const; 969 | BYTE GetUnit(BYTE slot) const; 970 | BYTE GetUnit0() const; 971 | BYTE GetUnit1() const; 972 | BYTE GetUnit2() const; 973 | // Get 37 bit data. 974 | UINT64 GetData0() const; 975 | UINT64 GetData1() const; 976 | UINT64 GetData2() const; 977 | 978 | // Get/set the full 41 bit instructions. 979 | UINT64 GetInstruction(BYTE slot) const; 980 | UINT64 GetInstruction0() const; 981 | UINT64 GetInstruction1() const; 982 | UINT64 GetInstruction2() const; 983 | void SetInstruction(BYTE slot, UINT64 instruction); 984 | void SetInstruction0(UINT64 instruction); 985 | void SetInstruction1(UINT64 instruction); 986 | void SetInstruction2(UINT64 instruction); 987 | 988 | // Get/set bitfields. 989 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 990 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 991 | 992 | // Get specific read-only fields. 993 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 994 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 995 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 996 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 997 | 998 | // Get/set specific fields. 999 | static UINT64 GetImm7a(UINT64 instruction); 1000 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 1001 | static UINT64 GetImm13c(UINT64 instruction); 1002 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 1003 | static UINT64 GetSignBit(UINT64 instruction); 1004 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 1005 | static UINT64 GetImm20a(UINT64 instruction); 1006 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 1007 | static UINT64 GetImm20b(UINT64 instruction); 1008 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 1009 | 1010 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 1011 | 1012 | BOOL IsMovlGp() const; 1013 | 1014 | VOID SetInst(BYTE Slot, BYTE nInst); 1015 | VOID SetInst0(BYTE nInst); 1016 | VOID SetInst1(BYTE nInst); 1017 | VOID SetInst2(BYTE nInst); 1018 | VOID SetData(BYTE Slot, UINT64 nData); 1019 | VOID SetData0(UINT64 nData); 1020 | VOID SetData1(UINT64 nData); 1021 | VOID SetData2(UINT64 nData); 1022 | BOOL SetNop(BYTE Slot); 1023 | BOOL SetNop0(); 1024 | BOOL SetNop1(); 1025 | BOOL SetNop2(); 1026 | 1027 | public: 1028 | BOOL IsBrl() const; 1029 | VOID SetBrl(); 1030 | VOID SetBrl(UINT64 target); 1031 | UINT64 GetBrlTarget() const; 1032 | VOID SetBrlTarget(UINT64 target); 1033 | VOID SetBrlImm(UINT64 imm); 1034 | UINT64 GetBrlImm() const; 1035 | 1036 | UINT64 GetMovlGp() const; 1037 | VOID SetMovlGp(UINT64 gp); 1038 | 1039 | VOID SetStop(); 1040 | 1041 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 1042 | }; 1043 | #endif // DETOURS_IA64 1044 | 1045 | #ifdef DETOURS_ARM 1046 | 1047 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 1048 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1049 | 1050 | #endif // DETOURS_ARM 1051 | 1052 | ////////////////////////////////////////////////////////////////////////////// 1053 | 1054 | #ifdef __cplusplus 1055 | extern "C" { 1056 | #endif // __cplusplus 1057 | 1058 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1059 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1060 | _Inout_opt_ PVOID *ppDstPool, \ 1061 | _In_ PVOID pSrc, \ 1062 | _Out_opt_ PVOID *ppTarget, \ 1063 | _Out_opt_ LONG *plExtra); \ 1064 | \ 1065 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1066 | _In_ BOOL fLimitReferencesToModule); \ 1067 | 1068 | DETOUR_OFFLINE_LIBRARY(X86) 1069 | DETOUR_OFFLINE_LIBRARY(X64) 1070 | DETOUR_OFFLINE_LIBRARY(ARM) 1071 | DETOUR_OFFLINE_LIBRARY(ARM64) 1072 | DETOUR_OFFLINE_LIBRARY(IA64) 1073 | 1074 | #undef DETOUR_OFFLINE_LIBRARY 1075 | 1076 | ////////////////////////////////////////////////////////////////////////////// 1077 | // 1078 | // Helpers for manipulating page protection. 1079 | // 1080 | 1081 | _Success_(return != FALSE) 1082 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1083 | _In_ PVOID pAddress, 1084 | _In_ SIZE_T nSize, 1085 | _In_ DWORD dwNewProtect, 1086 | _Out_ PDWORD pdwOldProtect); 1087 | 1088 | _Success_(return != FALSE) 1089 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1090 | _In_ SIZE_T nSize, 1091 | _In_ DWORD dwNewProtect, 1092 | _Out_ PDWORD pdwOldProtect); 1093 | #ifdef __cplusplus 1094 | } 1095 | #endif // __cplusplus 1096 | 1097 | ////////////////////////////////////////////////////////////////////////////// 1098 | 1099 | #define MM_ALLOCATION_GRANULARITY 0x10000 1100 | 1101 | ////////////////////////////////////////////////////////////////////////////// 1102 | 1103 | #endif // DETOURS_INTERNAL 1104 | #endif // __cplusplus 1105 | 1106 | #endif // _DETOURS_H_ 1107 | // 1108 | //////////////////////////////////////////////////////////////// End of File. -------------------------------------------------------------------------------- /ImGui/imstb_textedit.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_textedit.h 1.13. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_textedit.h - v1.13 - public domain - Sean Barrett 8 | // Development of this library was sponsored by RAD Game Tools 9 | // 10 | // This C header file implements the guts of a multi-line text-editing 11 | // widget; you implement display, word-wrapping, and low-level string 12 | // insertion/deletion, and stb_textedit will map user inputs into 13 | // insertions & deletions, plus updates to the cursor position, 14 | // selection state, and undo state. 15 | // 16 | // It is intended for use in games and other systems that need to build 17 | // their own custom widgets and which do not have heavy text-editing 18 | // requirements (this library is not recommended for use for editing large 19 | // texts, as its performance does not scale and it has limited undo). 20 | // 21 | // Non-trivial behaviors are modelled after Windows text controls. 22 | // 23 | // 24 | // LICENSE 25 | // 26 | // See end of file for license information. 27 | // 28 | // 29 | // DEPENDENCIES 30 | // 31 | // Uses the C runtime function 'memmove', which you can override 32 | // by defining STB_TEXTEDIT_memmove before the implementation. 33 | // Uses no other functions. Performs no runtime allocations. 34 | // 35 | // 36 | // VERSION HISTORY 37 | // 38 | // 1.13 (2019-02-07) fix bug in undo size management 39 | // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash 40 | // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield 41 | // 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual 42 | // 1.9 (2016-08-27) customizable move-by-word 43 | // 1.8 (2016-04-02) better keyboard handling when mouse button is down 44 | // 1.7 (2015-09-13) change y range handling in case baseline is non-0 45 | // 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove 46 | // 1.5 (2014-09-10) add support for secondary keys for OS X 47 | // 1.4 (2014-08-17) fix signed/unsigned warnings 48 | // 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary 49 | // 1.2 (2014-05-27) fix some RAD types that had crept into the new code 50 | // 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE ) 51 | // 1.0 (2012-07-26) improve documentation, initial public release 52 | // 0.3 (2012-02-24) bugfixes, single-line mode; insert mode 53 | // 0.2 (2011-11-28) fixes to undo/redo 54 | // 0.1 (2010-07-08) initial version 55 | // 56 | // ADDITIONAL CONTRIBUTORS 57 | // 58 | // Ulf Winklemann: move-by-word in 1.1 59 | // Fabian Giesen: secondary key inputs in 1.5 60 | // Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6 61 | // 62 | // Bugfixes: 63 | // Scott Graham 64 | // Daniel Keller 65 | // Omar Cornut 66 | // Dan Thompson 67 | // 68 | // USAGE 69 | // 70 | // This file behaves differently depending on what symbols you define 71 | // before including it. 72 | // 73 | // 74 | // Header-file mode: 75 | // 76 | // If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this, 77 | // it will operate in "header file" mode. In this mode, it declares a 78 | // single public symbol, STB_TexteditState, which encapsulates the current 79 | // state of a text widget (except for the string, which you will store 80 | // separately). 81 | // 82 | // To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a 83 | // primitive type that defines a single character (e.g. char, wchar_t, etc). 84 | // 85 | // To save space or increase undo-ability, you can optionally define the 86 | // following things that are used by the undo system: 87 | // 88 | // STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position 89 | // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow 90 | // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer 91 | // 92 | // If you don't define these, they are set to permissive types and 93 | // moderate sizes. The undo system does no memory allocations, so 94 | // it grows STB_TexteditState by the worst-case storage which is (in bytes): 95 | // 96 | // [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT 97 | // + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT 98 | // 99 | // 100 | // Implementation mode: 101 | // 102 | // If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it 103 | // will compile the implementation of the text edit widget, depending 104 | // on a large number of symbols which must be defined before the include. 105 | // 106 | // The implementation is defined only as static functions. You will then 107 | // need to provide your own APIs in the same file which will access the 108 | // static functions. 109 | // 110 | // The basic concept is that you provide a "string" object which 111 | // behaves like an array of characters. stb_textedit uses indices to 112 | // refer to positions in the string, implicitly representing positions 113 | // in the displayed textedit. This is true for both plain text and 114 | // rich text; even with rich text stb_truetype interacts with your 115 | // code as if there was an array of all the displayed characters. 116 | // 117 | // Symbols that must be the same in header-file and implementation mode: 118 | // 119 | // STB_TEXTEDIT_CHARTYPE the character type 120 | // STB_TEXTEDIT_POSITIONTYPE small type that is a valid cursor position 121 | // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow 122 | // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer 123 | // 124 | // Symbols you must define for implementation mode: 125 | // 126 | // STB_TEXTEDIT_STRING the type of object representing a string being edited, 127 | // typically this is a wrapper object with other data you need 128 | // 129 | // STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1)) 130 | // STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters 131 | // starting from character #n (see discussion below) 132 | // STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character 133 | // to the xpos of the i+1'th char for a line of characters 134 | // starting at character #n (i.e. accounts for kerning 135 | // with previous char) 136 | // STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character 137 | // (return type is int, -1 means not valid to insert) 138 | // STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based 139 | // STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize 140 | // as manually wordwrapping for end-of-line positioning 141 | // 142 | // STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i 143 | // STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*) 144 | // 145 | // STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key 146 | // 147 | // STB_TEXTEDIT_K_LEFT keyboard input to move cursor left 148 | // STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right 149 | // STB_TEXTEDIT_K_UP keyboard input to move cursor up 150 | // STB_TEXTEDIT_K_DOWN keyboard input to move cursor down 151 | // STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME 152 | // STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END 153 | // STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME 154 | // STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END 155 | // STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor 156 | // STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor 157 | // STB_TEXTEDIT_K_UNDO keyboard input to perform undo 158 | // STB_TEXTEDIT_K_REDO keyboard input to perform redo 159 | // 160 | // Optional: 161 | // STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode 162 | // STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), 163 | // required for default WORDLEFT/WORDRIGHT handlers 164 | // STB_TEXTEDIT_MOVEWORDLEFT(obj,i) custom handler for WORDLEFT, returns index to move cursor to 165 | // STB_TEXTEDIT_MOVEWORDRIGHT(obj,i) custom handler for WORDRIGHT, returns index to move cursor to 166 | // STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT 167 | // STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT 168 | // STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line 169 | // STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line 170 | // STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text 171 | // STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text 172 | // 173 | // Todo: 174 | // STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page 175 | // STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page 176 | // 177 | // Keyboard input must be encoded as a single integer value; e.g. a character code 178 | // and some bitflags that represent shift states. to simplify the interface, SHIFT must 179 | // be a bitflag, so we can test the shifted state of cursor movements to allow selection, 180 | // i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. 181 | // 182 | // You can encode other things, such as CONTROL or ALT, in additional bits, and 183 | // then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, 184 | // my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN 185 | // bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit, 186 | // and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the 187 | // API below. The control keys will only match WM_KEYDOWN events because of the 188 | // keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN 189 | // bit so it only decodes WM_CHAR events. 190 | // 191 | // STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed 192 | // row of characters assuming they start on the i'th character--the width and 193 | // the height and the number of characters consumed. This allows this library 194 | // to traverse the entire layout incrementally. You need to compute word-wrapping 195 | // here. 196 | // 197 | // Each textfield keeps its own insert mode state, which is not how normal 198 | // applications work. To keep an app-wide insert mode, update/copy the 199 | // "insert_mode" field of STB_TexteditState before/after calling API functions. 200 | // 201 | // API 202 | // 203 | // void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) 204 | // 205 | // void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 206 | // void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 207 | // int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 208 | // int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) 209 | // void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key) 210 | // 211 | // Each of these functions potentially updates the string and updates the 212 | // state. 213 | // 214 | // initialize_state: 215 | // set the textedit state to a known good default state when initially 216 | // constructing the textedit. 217 | // 218 | // click: 219 | // call this with the mouse x,y on a mouse down; it will update the cursor 220 | // and reset the selection start/end to the cursor point. the x,y must 221 | // be relative to the text widget, with (0,0) being the top left. 222 | // 223 | // drag: 224 | // call this with the mouse x,y on a mouse drag/up; it will update the 225 | // cursor and the selection end point 226 | // 227 | // cut: 228 | // call this to delete the current selection; returns true if there was 229 | // one. you should FIRST copy the current selection to the system paste buffer. 230 | // (To copy, just copy the current selection out of the string yourself.) 231 | // 232 | // paste: 233 | // call this to paste text at the current cursor point or over the current 234 | // selection if there is one. 235 | // 236 | // key: 237 | // call this for keyboard inputs sent to the textfield. you can use it 238 | // for "key down" events or for "translated" key events. if you need to 239 | // do both (as in Win32), or distinguish Unicode characters from control 240 | // inputs, set a high bit to distinguish the two; then you can define the 241 | // various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit 242 | // set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is 243 | // clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to 244 | // anything other type you wante before including. 245 | // 246 | // 247 | // When rendering, you can read the cursor position and selection state from 248 | // the STB_TexteditState. 249 | // 250 | // 251 | // Notes: 252 | // 253 | // This is designed to be usable in IMGUI, so it allows for the possibility of 254 | // running in an IMGUI that has NOT cached the multi-line layout. For this 255 | // reason, it provides an interface that is compatible with computing the 256 | // layout incrementally--we try to make sure we make as few passes through 257 | // as possible. (For example, to locate the mouse pointer in the text, we 258 | // could define functions that return the X and Y positions of characters 259 | // and binary search Y and then X, but if we're doing dynamic layout this 260 | // will run the layout algorithm many times, so instead we manually search 261 | // forward in one pass. Similar logic applies to e.g. up-arrow and 262 | // down-arrow movement.) 263 | // 264 | // If it's run in a widget that *has* cached the layout, then this is less 265 | // efficient, but it's not horrible on modern computers. But you wouldn't 266 | // want to edit million-line files with it. 267 | 268 | 269 | //////////////////////////////////////////////////////////////////////////// 270 | //////////////////////////////////////////////////////////////////////////// 271 | //// 272 | //// Header-file mode 273 | //// 274 | //// 275 | 276 | #ifndef INCLUDE_STB_TEXTEDIT_H 277 | #define INCLUDE_STB_TEXTEDIT_H 278 | 279 | //////////////////////////////////////////////////////////////////////// 280 | // 281 | // STB_TexteditState 282 | // 283 | // Definition of STB_TexteditState which you should store 284 | // per-textfield; it includes cursor position, selection state, 285 | // and undo state. 286 | // 287 | 288 | #ifndef STB_TEXTEDIT_UNDOSTATECOUNT 289 | #define STB_TEXTEDIT_UNDOSTATECOUNT 99 290 | #endif 291 | #ifndef STB_TEXTEDIT_UNDOCHARCOUNT 292 | #define STB_TEXTEDIT_UNDOCHARCOUNT 999 293 | #endif 294 | #ifndef STB_TEXTEDIT_CHARTYPE 295 | #define STB_TEXTEDIT_CHARTYPE int 296 | #endif 297 | #ifndef STB_TEXTEDIT_POSITIONTYPE 298 | #define STB_TEXTEDIT_POSITIONTYPE int 299 | #endif 300 | 301 | typedef struct 302 | { 303 | // private data 304 | STB_TEXTEDIT_POSITIONTYPE where; 305 | STB_TEXTEDIT_POSITIONTYPE insert_length; 306 | STB_TEXTEDIT_POSITIONTYPE delete_length; 307 | int char_storage; 308 | } StbUndoRecord; 309 | 310 | typedef struct 311 | { 312 | // private data 313 | StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; 314 | STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; 315 | short undo_point, redo_point; 316 | int undo_char_point, redo_char_point; 317 | } StbUndoState; 318 | 319 | typedef struct 320 | { 321 | ///////////////////// 322 | // 323 | // public data 324 | // 325 | 326 | int cursor; 327 | // position of the text cursor within the string 328 | 329 | int select_start; // selection start point 330 | int select_end; 331 | // selection start and end point in characters; if equal, no selection. 332 | // note that start may be less than or greater than end (e.g. when 333 | // dragging the mouse, start is where the initial click was, and you 334 | // can drag in either direction) 335 | 336 | unsigned char insert_mode; 337 | // each textfield keeps its own insert mode state. to keep an app-wide 338 | // insert mode, copy this value in/out of the app state 339 | 340 | ///////////////////// 341 | // 342 | // private data 343 | // 344 | unsigned char cursor_at_end_of_line; // not implemented yet 345 | unsigned char initialized; 346 | unsigned char has_preferred_x; 347 | unsigned char single_line; 348 | unsigned char padding1, padding2, padding3; 349 | float preferred_x; // this determines where the cursor up/down tries to seek to along x 350 | StbUndoState undostate; 351 | } STB_TexteditState; 352 | 353 | 354 | //////////////////////////////////////////////////////////////////////// 355 | // 356 | // StbTexteditRow 357 | // 358 | // Result of layout query, used by stb_textedit to determine where 359 | // the text in each row is. 360 | 361 | // result of layout query 362 | typedef struct 363 | { 364 | float x0,x1; // starting x location, end x location (allows for align=right, etc) 365 | float baseline_y_delta; // position of baseline relative to previous row's baseline 366 | float ymin,ymax; // height of row above and below baseline 367 | int num_chars; 368 | } StbTexteditRow; 369 | #endif //INCLUDE_STB_TEXTEDIT_H 370 | 371 | 372 | //////////////////////////////////////////////////////////////////////////// 373 | //////////////////////////////////////////////////////////////////////////// 374 | //// 375 | //// Implementation mode 376 | //// 377 | //// 378 | 379 | 380 | // implementation isn't include-guarded, since it might have indirectly 381 | // included just the "header" portion 382 | #ifdef STB_TEXTEDIT_IMPLEMENTATION 383 | 384 | #ifndef STB_TEXTEDIT_memmove 385 | #include 386 | #define STB_TEXTEDIT_memmove memmove 387 | #endif 388 | 389 | 390 | ///////////////////////////////////////////////////////////////////////////// 391 | // 392 | // Mouse input handling 393 | // 394 | 395 | // traverse the layout to locate the nearest character to a display position 396 | static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) 397 | { 398 | StbTexteditRow r; 399 | int n = STB_TEXTEDIT_STRINGLEN(str); 400 | float base_y = 0, prev_x; 401 | int i=0, k; 402 | 403 | r.x0 = r.x1 = 0; 404 | r.ymin = r.ymax = 0; 405 | r.num_chars = 0; 406 | 407 | // search rows to find one that straddles 'y' 408 | while (i < n) { 409 | STB_TEXTEDIT_LAYOUTROW(&r, str, i); 410 | if (r.num_chars <= 0) 411 | return n; 412 | 413 | if (i==0 && y < base_y + r.ymin) 414 | return 0; 415 | 416 | if (y < base_y + r.ymax) 417 | break; 418 | 419 | i += r.num_chars; 420 | base_y += r.baseline_y_delta; 421 | } 422 | 423 | // below all text, return 'after' last character 424 | if (i >= n) 425 | return n; 426 | 427 | // check if it's before the beginning of the line 428 | if (x < r.x0) 429 | return i; 430 | 431 | // check if it's before the end of the line 432 | if (x < r.x1) { 433 | // search characters in row for one that straddles 'x' 434 | prev_x = r.x0; 435 | for (k=0; k < r.num_chars; ++k) { 436 | float w = STB_TEXTEDIT_GETWIDTH(str, i, k); 437 | if (x < prev_x+w) { 438 | if (x < prev_x+w/2) 439 | return k+i; 440 | else 441 | return k+i+1; 442 | } 443 | prev_x += w; 444 | } 445 | // shouldn't happen, but if it does, fall through to end-of-line case 446 | } 447 | 448 | // if the last character is a newline, return that. otherwise return 'after' the last character 449 | if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) 450 | return i+r.num_chars-1; 451 | else 452 | return i+r.num_chars; 453 | } 454 | 455 | // API click: on mouse down, move the cursor to the clicked location, and reset the selection 456 | static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 457 | { 458 | // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse 459 | // goes off the top or bottom of the text 460 | if( state->single_line ) 461 | { 462 | StbTexteditRow r; 463 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0); 464 | y = r.ymin; 465 | } 466 | 467 | state->cursor = stb_text_locate_coord(str, x, y); 468 | state->select_start = state->cursor; 469 | state->select_end = state->cursor; 470 | state->has_preferred_x = 0; 471 | } 472 | 473 | // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location 474 | static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) 475 | { 476 | int p = 0; 477 | 478 | // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse 479 | // goes off the top or bottom of the text 480 | if( state->single_line ) 481 | { 482 | StbTexteditRow r; 483 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0); 484 | y = r.ymin; 485 | } 486 | 487 | if (state->select_start == state->select_end) 488 | state->select_start = state->cursor; 489 | 490 | p = stb_text_locate_coord(str, x, y); 491 | state->cursor = state->select_end = p; 492 | } 493 | 494 | ///////////////////////////////////////////////////////////////////////////// 495 | // 496 | // Keyboard input handling 497 | // 498 | 499 | // forward declarations 500 | static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); 501 | static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); 502 | static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); 503 | static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); 504 | static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); 505 | 506 | typedef struct 507 | { 508 | float x,y; // position of n'th character 509 | float height; // height of line 510 | int first_char, length; // first char of row, and length 511 | int prev_first; // first char of previous row 512 | } StbFindState; 513 | 514 | // find the x/y location of a character, and remember info about the previous row in 515 | // case we get a move-up event (for page up, we'll have to rescan) 516 | static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) 517 | { 518 | StbTexteditRow r; 519 | int prev_start = 0; 520 | int z = STB_TEXTEDIT_STRINGLEN(str); 521 | int i=0, first; 522 | 523 | if (n == z) { 524 | // if it's at the end, then find the last line -- simpler than trying to 525 | // explicitly handle this case in the regular code 526 | if (single_line) { 527 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0); 528 | find->y = 0; 529 | find->first_char = 0; 530 | find->length = z; 531 | find->height = r.ymax - r.ymin; 532 | find->x = r.x1; 533 | } else { 534 | find->y = 0; 535 | find->x = 0; 536 | find->height = 1; 537 | while (i < z) { 538 | STB_TEXTEDIT_LAYOUTROW(&r, str, i); 539 | prev_start = i; 540 | i += r.num_chars; 541 | } 542 | find->first_char = i; 543 | find->length = 0; 544 | find->prev_first = prev_start; 545 | } 546 | return; 547 | } 548 | 549 | // search rows to find the one that straddles character n 550 | find->y = 0; 551 | 552 | for(;;) { 553 | STB_TEXTEDIT_LAYOUTROW(&r, str, i); 554 | if (n < i + r.num_chars) 555 | break; 556 | prev_start = i; 557 | i += r.num_chars; 558 | find->y += r.baseline_y_delta; 559 | } 560 | 561 | find->first_char = first = i; 562 | find->length = r.num_chars; 563 | find->height = r.ymax - r.ymin; 564 | find->prev_first = prev_start; 565 | 566 | // now scan to find xpos 567 | find->x = r.x0; 568 | for (i=0; first+i < n; ++i) 569 | find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); 570 | } 571 | 572 | #define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) 573 | 574 | // make the selection/cursor state valid if client altered the string 575 | static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 576 | { 577 | int n = STB_TEXTEDIT_STRINGLEN(str); 578 | if (STB_TEXT_HAS_SELECTION(state)) { 579 | if (state->select_start > n) state->select_start = n; 580 | if (state->select_end > n) state->select_end = n; 581 | // if clamping forced them to be equal, move the cursor to match 582 | if (state->select_start == state->select_end) 583 | state->cursor = state->select_start; 584 | } 585 | if (state->cursor > n) state->cursor = n; 586 | } 587 | 588 | // delete characters while updating undo 589 | static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) 590 | { 591 | stb_text_makeundo_delete(str, state, where, len); 592 | STB_TEXTEDIT_DELETECHARS(str, where, len); 593 | state->has_preferred_x = 0; 594 | } 595 | 596 | // delete the section 597 | static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 598 | { 599 | stb_textedit_clamp(str, state); 600 | if (STB_TEXT_HAS_SELECTION(state)) { 601 | if (state->select_start < state->select_end) { 602 | stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); 603 | state->select_end = state->cursor = state->select_start; 604 | } else { 605 | stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); 606 | state->select_start = state->cursor = state->select_end; 607 | } 608 | state->has_preferred_x = 0; 609 | } 610 | } 611 | 612 | // canoncialize the selection so start <= end 613 | static void stb_textedit_sortselection(STB_TexteditState *state) 614 | { 615 | if (state->select_end < state->select_start) { 616 | int temp = state->select_end; 617 | state->select_end = state->select_start; 618 | state->select_start = temp; 619 | } 620 | } 621 | 622 | // move cursor to first character of selection 623 | static void stb_textedit_move_to_first(STB_TexteditState *state) 624 | { 625 | if (STB_TEXT_HAS_SELECTION(state)) { 626 | stb_textedit_sortselection(state); 627 | state->cursor = state->select_start; 628 | state->select_end = state->select_start; 629 | state->has_preferred_x = 0; 630 | } 631 | } 632 | 633 | // move cursor to last character of selection 634 | static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 635 | { 636 | if (STB_TEXT_HAS_SELECTION(state)) { 637 | stb_textedit_sortselection(state); 638 | stb_textedit_clamp(str, state); 639 | state->cursor = state->select_end; 640 | state->select_start = state->select_end; 641 | state->has_preferred_x = 0; 642 | } 643 | } 644 | 645 | #ifdef STB_TEXTEDIT_IS_SPACE 646 | static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx ) 647 | { 648 | return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1; 649 | } 650 | 651 | #ifndef STB_TEXTEDIT_MOVEWORDLEFT 652 | static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c ) 653 | { 654 | --c; // always move at least one character 655 | while( c >= 0 && !is_word_boundary( str, c ) ) 656 | --c; 657 | 658 | if( c < 0 ) 659 | c = 0; 660 | 661 | return c; 662 | } 663 | #define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous 664 | #endif 665 | 666 | #ifndef STB_TEXTEDIT_MOVEWORDRIGHT 667 | static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c ) 668 | { 669 | const int len = STB_TEXTEDIT_STRINGLEN(str); 670 | ++c; // always move at least one character 671 | while( c < len && !is_word_boundary( str, c ) ) 672 | ++c; 673 | 674 | if( c > len ) 675 | c = len; 676 | 677 | return c; 678 | } 679 | #define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next 680 | #endif 681 | 682 | #endif 683 | 684 | // update selection and cursor to match each other 685 | static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) 686 | { 687 | if (!STB_TEXT_HAS_SELECTION(state)) 688 | state->select_start = state->select_end = state->cursor; 689 | else 690 | state->cursor = state->select_end; 691 | } 692 | 693 | // API cut: delete selection 694 | static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 695 | { 696 | if (STB_TEXT_HAS_SELECTION(state)) { 697 | stb_textedit_delete_selection(str,state); // implicitly clamps 698 | state->has_preferred_x = 0; 699 | return 1; 700 | } 701 | return 0; 702 | } 703 | 704 | // API paste: replace existing selection with passed-in text 705 | static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) 706 | { 707 | // if there's a selection, the paste should delete it 708 | stb_textedit_clamp(str, state); 709 | stb_textedit_delete_selection(str,state); 710 | // try to insert the characters 711 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { 712 | stb_text_makeundo_insert(state, state->cursor, len); 713 | state->cursor += len; 714 | state->has_preferred_x = 0; 715 | return 1; 716 | } 717 | // remove the undo since we didn't actually insert the characters 718 | if (state->undostate.undo_point) 719 | --state->undostate.undo_point; 720 | return 0; 721 | } 722 | 723 | #ifndef STB_TEXTEDIT_KEYTYPE 724 | #define STB_TEXTEDIT_KEYTYPE int 725 | #endif 726 | 727 | // API key: process a keyboard input 728 | static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key) 729 | { 730 | retry: 731 | switch (key) { 732 | default: { 733 | int c = STB_TEXTEDIT_KEYTOTEXT(key); 734 | if (c > 0) { 735 | STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; 736 | 737 | // can't add newline in single-line mode 738 | if (c == '\n' && state->single_line) 739 | break; 740 | 741 | if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { 742 | stb_text_makeundo_replace(str, state, state->cursor, 1, 1); 743 | STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); 744 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { 745 | ++state->cursor; 746 | state->has_preferred_x = 0; 747 | } 748 | } else { 749 | stb_textedit_delete_selection(str,state); // implicitly clamps 750 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { 751 | stb_text_makeundo_insert(state, state->cursor, 1); 752 | ++state->cursor; 753 | state->has_preferred_x = 0; 754 | } 755 | } 756 | } 757 | break; 758 | } 759 | 760 | #ifdef STB_TEXTEDIT_K_INSERT 761 | case STB_TEXTEDIT_K_INSERT: 762 | state->insert_mode = !state->insert_mode; 763 | break; 764 | #endif 765 | 766 | case STB_TEXTEDIT_K_UNDO: 767 | stb_text_undo(str, state); 768 | state->has_preferred_x = 0; 769 | break; 770 | 771 | case STB_TEXTEDIT_K_REDO: 772 | stb_text_redo(str, state); 773 | state->has_preferred_x = 0; 774 | break; 775 | 776 | case STB_TEXTEDIT_K_LEFT: 777 | // if currently there's a selection, move cursor to start of selection 778 | if (STB_TEXT_HAS_SELECTION(state)) 779 | stb_textedit_move_to_first(state); 780 | else 781 | if (state->cursor > 0) 782 | --state->cursor; 783 | state->has_preferred_x = 0; 784 | break; 785 | 786 | case STB_TEXTEDIT_K_RIGHT: 787 | // if currently there's a selection, move cursor to end of selection 788 | if (STB_TEXT_HAS_SELECTION(state)) 789 | stb_textedit_move_to_last(str, state); 790 | else 791 | ++state->cursor; 792 | stb_textedit_clamp(str, state); 793 | state->has_preferred_x = 0; 794 | break; 795 | 796 | case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: 797 | stb_textedit_clamp(str, state); 798 | stb_textedit_prep_selection_at_cursor(state); 799 | // move selection left 800 | if (state->select_end > 0) 801 | --state->select_end; 802 | state->cursor = state->select_end; 803 | state->has_preferred_x = 0; 804 | break; 805 | 806 | #ifdef STB_TEXTEDIT_MOVEWORDLEFT 807 | case STB_TEXTEDIT_K_WORDLEFT: 808 | if (STB_TEXT_HAS_SELECTION(state)) 809 | stb_textedit_move_to_first(state); 810 | else { 811 | state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); 812 | stb_textedit_clamp( str, state ); 813 | } 814 | break; 815 | 816 | case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: 817 | if( !STB_TEXT_HAS_SELECTION( state ) ) 818 | stb_textedit_prep_selection_at_cursor(state); 819 | 820 | state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); 821 | state->select_end = state->cursor; 822 | 823 | stb_textedit_clamp( str, state ); 824 | break; 825 | #endif 826 | 827 | #ifdef STB_TEXTEDIT_MOVEWORDRIGHT 828 | case STB_TEXTEDIT_K_WORDRIGHT: 829 | if (STB_TEXT_HAS_SELECTION(state)) 830 | stb_textedit_move_to_last(str, state); 831 | else { 832 | state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); 833 | stb_textedit_clamp( str, state ); 834 | } 835 | break; 836 | 837 | case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: 838 | if( !STB_TEXT_HAS_SELECTION( state ) ) 839 | stb_textedit_prep_selection_at_cursor(state); 840 | 841 | state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); 842 | state->select_end = state->cursor; 843 | 844 | stb_textedit_clamp( str, state ); 845 | break; 846 | #endif 847 | 848 | case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: 849 | stb_textedit_prep_selection_at_cursor(state); 850 | // move selection right 851 | ++state->select_end; 852 | stb_textedit_clamp(str, state); 853 | state->cursor = state->select_end; 854 | state->has_preferred_x = 0; 855 | break; 856 | 857 | case STB_TEXTEDIT_K_DOWN: 858 | case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { 859 | StbFindState find; 860 | StbTexteditRow row; 861 | int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; 862 | 863 | if (state->single_line) { 864 | // on windows, up&down in single-line behave like left&right 865 | key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); 866 | goto retry; 867 | } 868 | 869 | if (sel) 870 | stb_textedit_prep_selection_at_cursor(state); 871 | else if (STB_TEXT_HAS_SELECTION(state)) 872 | stb_textedit_move_to_last(str,state); 873 | 874 | // compute current position of cursor point 875 | stb_textedit_clamp(str, state); 876 | stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); 877 | 878 | // now find character position down a row 879 | if (find.length) { 880 | float goal_x = state->has_preferred_x ? state->preferred_x : find.x; 881 | float x; 882 | int start = find.first_char + find.length; 883 | state->cursor = start; 884 | STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); 885 | x = row.x0; 886 | for (i=0; i < row.num_chars; ++i) { 887 | float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); 888 | #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE 889 | if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) 890 | break; 891 | #endif 892 | x += dx; 893 | if (x > goal_x) 894 | break; 895 | ++state->cursor; 896 | } 897 | stb_textedit_clamp(str, state); 898 | 899 | state->has_preferred_x = 1; 900 | state->preferred_x = goal_x; 901 | 902 | if (sel) 903 | state->select_end = state->cursor; 904 | } 905 | break; 906 | } 907 | 908 | case STB_TEXTEDIT_K_UP: 909 | case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { 910 | StbFindState find; 911 | StbTexteditRow row; 912 | int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; 913 | 914 | if (state->single_line) { 915 | // on windows, up&down become left&right 916 | key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); 917 | goto retry; 918 | } 919 | 920 | if (sel) 921 | stb_textedit_prep_selection_at_cursor(state); 922 | else if (STB_TEXT_HAS_SELECTION(state)) 923 | stb_textedit_move_to_first(state); 924 | 925 | // compute current position of cursor point 926 | stb_textedit_clamp(str, state); 927 | stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); 928 | 929 | // can only go up if there's a previous row 930 | if (find.prev_first != find.first_char) { 931 | // now find character position up a row 932 | float goal_x = state->has_preferred_x ? state->preferred_x : find.x; 933 | float x; 934 | state->cursor = find.prev_first; 935 | STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); 936 | x = row.x0; 937 | for (i=0; i < row.num_chars; ++i) { 938 | float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); 939 | #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE 940 | if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) 941 | break; 942 | #endif 943 | x += dx; 944 | if (x > goal_x) 945 | break; 946 | ++state->cursor; 947 | } 948 | stb_textedit_clamp(str, state); 949 | 950 | state->has_preferred_x = 1; 951 | state->preferred_x = goal_x; 952 | 953 | if (sel) 954 | state->select_end = state->cursor; 955 | } 956 | break; 957 | } 958 | 959 | case STB_TEXTEDIT_K_DELETE: 960 | case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: 961 | if (STB_TEXT_HAS_SELECTION(state)) 962 | stb_textedit_delete_selection(str, state); 963 | else { 964 | int n = STB_TEXTEDIT_STRINGLEN(str); 965 | if (state->cursor < n) 966 | stb_textedit_delete(str, state, state->cursor, 1); 967 | } 968 | state->has_preferred_x = 0; 969 | break; 970 | 971 | case STB_TEXTEDIT_K_BACKSPACE: 972 | case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: 973 | if (STB_TEXT_HAS_SELECTION(state)) 974 | stb_textedit_delete_selection(str, state); 975 | else { 976 | stb_textedit_clamp(str, state); 977 | if (state->cursor > 0) { 978 | stb_textedit_delete(str, state, state->cursor-1, 1); 979 | --state->cursor; 980 | } 981 | } 982 | state->has_preferred_x = 0; 983 | break; 984 | 985 | #ifdef STB_TEXTEDIT_K_TEXTSTART2 986 | case STB_TEXTEDIT_K_TEXTSTART2: 987 | #endif 988 | case STB_TEXTEDIT_K_TEXTSTART: 989 | state->cursor = state->select_start = state->select_end = 0; 990 | state->has_preferred_x = 0; 991 | break; 992 | 993 | #ifdef STB_TEXTEDIT_K_TEXTEND2 994 | case STB_TEXTEDIT_K_TEXTEND2: 995 | #endif 996 | case STB_TEXTEDIT_K_TEXTEND: 997 | state->cursor = STB_TEXTEDIT_STRINGLEN(str); 998 | state->select_start = state->select_end = 0; 999 | state->has_preferred_x = 0; 1000 | break; 1001 | 1002 | #ifdef STB_TEXTEDIT_K_TEXTSTART2 1003 | case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: 1004 | #endif 1005 | case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: 1006 | stb_textedit_prep_selection_at_cursor(state); 1007 | state->cursor = state->select_end = 0; 1008 | state->has_preferred_x = 0; 1009 | break; 1010 | 1011 | #ifdef STB_TEXTEDIT_K_TEXTEND2 1012 | case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: 1013 | #endif 1014 | case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: 1015 | stb_textedit_prep_selection_at_cursor(state); 1016 | state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); 1017 | state->has_preferred_x = 0; 1018 | break; 1019 | 1020 | 1021 | #ifdef STB_TEXTEDIT_K_LINESTART2 1022 | case STB_TEXTEDIT_K_LINESTART2: 1023 | #endif 1024 | case STB_TEXTEDIT_K_LINESTART: 1025 | stb_textedit_clamp(str, state); 1026 | stb_textedit_move_to_first(state); 1027 | if (state->single_line) 1028 | state->cursor = 0; 1029 | else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) 1030 | --state->cursor; 1031 | state->has_preferred_x = 0; 1032 | break; 1033 | 1034 | #ifdef STB_TEXTEDIT_K_LINEEND2 1035 | case STB_TEXTEDIT_K_LINEEND2: 1036 | #endif 1037 | case STB_TEXTEDIT_K_LINEEND: { 1038 | int n = STB_TEXTEDIT_STRINGLEN(str); 1039 | stb_textedit_clamp(str, state); 1040 | stb_textedit_move_to_first(state); 1041 | if (state->single_line) 1042 | state->cursor = n; 1043 | else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) 1044 | ++state->cursor; 1045 | state->has_preferred_x = 0; 1046 | break; 1047 | } 1048 | 1049 | #ifdef STB_TEXTEDIT_K_LINESTART2 1050 | case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: 1051 | #endif 1052 | case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: 1053 | stb_textedit_clamp(str, state); 1054 | stb_textedit_prep_selection_at_cursor(state); 1055 | if (state->single_line) 1056 | state->cursor = 0; 1057 | else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) 1058 | --state->cursor; 1059 | state->select_end = state->cursor; 1060 | state->has_preferred_x = 0; 1061 | break; 1062 | 1063 | #ifdef STB_TEXTEDIT_K_LINEEND2 1064 | case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: 1065 | #endif 1066 | case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { 1067 | int n = STB_TEXTEDIT_STRINGLEN(str); 1068 | stb_textedit_clamp(str, state); 1069 | stb_textedit_prep_selection_at_cursor(state); 1070 | if (state->single_line) 1071 | state->cursor = n; 1072 | else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) 1073 | ++state->cursor; 1074 | state->select_end = state->cursor; 1075 | state->has_preferred_x = 0; 1076 | break; 1077 | } 1078 | 1079 | // @TODO: 1080 | // STB_TEXTEDIT_K_PGUP - move cursor up a page 1081 | // STB_TEXTEDIT_K_PGDOWN - move cursor down a page 1082 | } 1083 | } 1084 | 1085 | ///////////////////////////////////////////////////////////////////////////// 1086 | // 1087 | // Undo processing 1088 | // 1089 | // @OPTIMIZE: the undo/redo buffer should be circular 1090 | 1091 | static void stb_textedit_flush_redo(StbUndoState *state) 1092 | { 1093 | state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; 1094 | state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; 1095 | } 1096 | 1097 | // discard the oldest entry in the undo list 1098 | static void stb_textedit_discard_undo(StbUndoState *state) 1099 | { 1100 | if (state->undo_point > 0) { 1101 | // if the 0th undo state has characters, clean those up 1102 | if (state->undo_rec[0].char_storage >= 0) { 1103 | int n = state->undo_rec[0].insert_length, i; 1104 | // delete n characters from all other records 1105 | state->undo_char_point -= n; 1106 | STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); 1107 | for (i=0; i < state->undo_point; ++i) 1108 | if (state->undo_rec[i].char_storage >= 0) 1109 | state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it 1110 | } 1111 | --state->undo_point; 1112 | STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0]))); 1113 | } 1114 | } 1115 | 1116 | // discard the oldest entry in the redo list--it's bad if this 1117 | // ever happens, but because undo & redo have to store the actual 1118 | // characters in different cases, the redo character buffer can 1119 | // fill up even though the undo buffer didn't 1120 | static void stb_textedit_discard_redo(StbUndoState *state) 1121 | { 1122 | int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; 1123 | 1124 | if (state->redo_point <= k) { 1125 | // if the k'th undo state has characters, clean those up 1126 | if (state->undo_rec[k].char_storage >= 0) { 1127 | int n = state->undo_rec[k].insert_length, i; 1128 | // move the remaining redo character data to the end of the buffer 1129 | state->redo_char_point += n; 1130 | STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); 1131 | // adjust the position of all the other records to account for above memmove 1132 | for (i=state->redo_point; i < k; ++i) 1133 | if (state->undo_rec[i].char_storage >= 0) 1134 | state->undo_rec[i].char_storage += n; 1135 | } 1136 | // now move all the redo records towards the end of the buffer; the first one is at 'redo_point' 1137 | // {DEAR IMGUI] 1138 | size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0])); 1139 | const char* buf_begin = (char*)state->undo_rec; (void)buf_begin; 1140 | const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end; 1141 | IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin); 1142 | IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end); 1143 | STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size); 1144 | 1145 | // now move redo_point to point to the new one 1146 | ++state->redo_point; 1147 | } 1148 | } 1149 | 1150 | static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) 1151 | { 1152 | // any time we create a new undo record, we discard redo 1153 | stb_textedit_flush_redo(state); 1154 | 1155 | // if we have no free records, we have to make room, by sliding the 1156 | // existing records down 1157 | if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) 1158 | stb_textedit_discard_undo(state); 1159 | 1160 | // if the characters to store won't possibly fit in the buffer, we can't undo 1161 | if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { 1162 | state->undo_point = 0; 1163 | state->undo_char_point = 0; 1164 | return NULL; 1165 | } 1166 | 1167 | // if we don't have enough free characters in the buffer, we have to make room 1168 | while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) 1169 | stb_textedit_discard_undo(state); 1170 | 1171 | return &state->undo_rec[state->undo_point++]; 1172 | } 1173 | 1174 | static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) 1175 | { 1176 | StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); 1177 | if (r == NULL) 1178 | return NULL; 1179 | 1180 | r->where = pos; 1181 | r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len; 1182 | r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len; 1183 | 1184 | if (insert_len == 0) { 1185 | r->char_storage = -1; 1186 | return NULL; 1187 | } else { 1188 | r->char_storage = state->undo_char_point; 1189 | state->undo_char_point += insert_len; 1190 | return &state->undo_char[r->char_storage]; 1191 | } 1192 | } 1193 | 1194 | static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 1195 | { 1196 | StbUndoState *s = &state->undostate; 1197 | StbUndoRecord u, *r; 1198 | if (s->undo_point == 0) 1199 | return; 1200 | 1201 | // we need to do two things: apply the undo record, and create a redo record 1202 | u = s->undo_rec[s->undo_point-1]; 1203 | r = &s->undo_rec[s->redo_point-1]; 1204 | r->char_storage = -1; 1205 | 1206 | r->insert_length = u.delete_length; 1207 | r->delete_length = u.insert_length; 1208 | r->where = u.where; 1209 | 1210 | if (u.delete_length) { 1211 | // if the undo record says to delete characters, then the redo record will 1212 | // need to re-insert the characters that get deleted, so we need to store 1213 | // them. 1214 | 1215 | // there are three cases: 1216 | // there's enough room to store the characters 1217 | // characters stored for *redoing* don't leave room for redo 1218 | // characters stored for *undoing* don't leave room for redo 1219 | // if the last is true, we have to bail 1220 | 1221 | if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { 1222 | // the undo records take up too much character space; there's no space to store the redo characters 1223 | r->insert_length = 0; 1224 | } else { 1225 | int i; 1226 | 1227 | // there's definitely room to store the characters eventually 1228 | while (s->undo_char_point + u.delete_length > s->redo_char_point) { 1229 | // should never happen: 1230 | if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) 1231 | return; 1232 | // there's currently not enough room, so discard a redo record 1233 | stb_textedit_discard_redo(s); 1234 | } 1235 | r = &s->undo_rec[s->redo_point-1]; 1236 | 1237 | r->char_storage = s->redo_char_point - u.delete_length; 1238 | s->redo_char_point = s->redo_char_point - u.delete_length; 1239 | 1240 | // now save the characters 1241 | for (i=0; i < u.delete_length; ++i) 1242 | s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); 1243 | } 1244 | 1245 | // now we can carry out the deletion 1246 | STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); 1247 | } 1248 | 1249 | // check type of recorded action: 1250 | if (u.insert_length) { 1251 | // easy case: was a deletion, so we need to insert n characters 1252 | STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); 1253 | s->undo_char_point -= u.insert_length; 1254 | } 1255 | 1256 | state->cursor = u.where + u.insert_length; 1257 | 1258 | s->undo_point--; 1259 | s->redo_point--; 1260 | } 1261 | 1262 | static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) 1263 | { 1264 | StbUndoState *s = &state->undostate; 1265 | StbUndoRecord *u, r; 1266 | if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) 1267 | return; 1268 | 1269 | // we need to do two things: apply the redo record, and create an undo record 1270 | u = &s->undo_rec[s->undo_point]; 1271 | r = s->undo_rec[s->redo_point]; 1272 | 1273 | // we KNOW there must be room for the undo record, because the redo record 1274 | // was derived from an undo record 1275 | 1276 | u->delete_length = r.insert_length; 1277 | u->insert_length = r.delete_length; 1278 | u->where = r.where; 1279 | u->char_storage = -1; 1280 | 1281 | if (r.delete_length) { 1282 | // the redo record requires us to delete characters, so the undo record 1283 | // needs to store the characters 1284 | 1285 | if (s->undo_char_point + u->insert_length > s->redo_char_point) { 1286 | u->insert_length = 0; 1287 | u->delete_length = 0; 1288 | } else { 1289 | int i; 1290 | u->char_storage = s->undo_char_point; 1291 | s->undo_char_point = s->undo_char_point + u->insert_length; 1292 | 1293 | // now save the characters 1294 | for (i=0; i < u->insert_length; ++i) 1295 | s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); 1296 | } 1297 | 1298 | STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); 1299 | } 1300 | 1301 | if (r.insert_length) { 1302 | // easy case: need to insert n characters 1303 | STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); 1304 | s->redo_char_point += r.insert_length; 1305 | } 1306 | 1307 | state->cursor = r.where + r.insert_length; 1308 | 1309 | s->undo_point++; 1310 | s->redo_point++; 1311 | } 1312 | 1313 | static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) 1314 | { 1315 | stb_text_createundo(&state->undostate, where, 0, length); 1316 | } 1317 | 1318 | static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) 1319 | { 1320 | int i; 1321 | STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); 1322 | if (p) { 1323 | for (i=0; i < length; ++i) 1324 | p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); 1325 | } 1326 | } 1327 | 1328 | static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) 1329 | { 1330 | int i; 1331 | STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); 1332 | if (p) { 1333 | for (i=0; i < old_length; ++i) 1334 | p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); 1335 | } 1336 | } 1337 | 1338 | // reset the state to default 1339 | static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) 1340 | { 1341 | state->undostate.undo_point = 0; 1342 | state->undostate.undo_char_point = 0; 1343 | state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; 1344 | state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; 1345 | state->select_end = state->select_start = 0; 1346 | state->cursor = 0; 1347 | state->has_preferred_x = 0; 1348 | state->preferred_x = 0; 1349 | state->cursor_at_end_of_line = 0; 1350 | state->initialized = 1; 1351 | state->single_line = (unsigned char) is_single_line; 1352 | state->insert_mode = 0; 1353 | } 1354 | 1355 | // API initialize 1356 | static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) 1357 | { 1358 | stb_textedit_clear_state(state, is_single_line); 1359 | } 1360 | 1361 | #if defined(__GNUC__) || defined(__clang__) 1362 | #pragma GCC diagnostic push 1363 | #pragma GCC diagnostic ignored "-Wcast-qual" 1364 | #endif 1365 | 1366 | static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) 1367 | { 1368 | return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len); 1369 | } 1370 | 1371 | #if defined(__GNUC__) || defined(__clang__) 1372 | #pragma GCC diagnostic pop 1373 | #endif 1374 | 1375 | #endif//STB_TEXTEDIT_IMPLEMENTATION 1376 | 1377 | /* 1378 | ------------------------------------------------------------------------------ 1379 | This software is available under 2 licenses -- choose whichever you prefer. 1380 | ------------------------------------------------------------------------------ 1381 | ALTERNATIVE A - MIT License 1382 | Copyright (c) 2017 Sean Barrett 1383 | Permission is hereby granted, free of charge, to any person obtaining a copy of 1384 | this software and associated documentation files (the "Software"), to deal in 1385 | the Software without restriction, including without limitation the rights to 1386 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1387 | of the Software, and to permit persons to whom the Software is furnished to do 1388 | so, subject to the following conditions: 1389 | The above copyright notice and this permission notice shall be included in all 1390 | copies or substantial portions of the Software. 1391 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1392 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1393 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1394 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1395 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1396 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1397 | SOFTWARE. 1398 | ------------------------------------------------------------------------------ 1399 | ALTERNATIVE B - Public Domain (www.unlicense.org) 1400 | This is free and unencumbered software released into the public domain. 1401 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 1402 | software, either in source code form or as a compiled binary, for any purpose, 1403 | commercial or non-commercial, and by any means. 1404 | In jurisdictions that recognize copyright laws, the author or authors of this 1405 | software dedicate any and all copyright interest in the software to the public 1406 | domain. We make this dedication for the benefit of the public at large and to 1407 | the detriment of our heirs and successors. We intend this dedication to be an 1408 | overt act of relinquishment in perpetuity of all present and future rights to 1409 | this software under copyright law. 1410 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1411 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1412 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1413 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 1414 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 1415 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 1416 | ------------------------------------------------------------------------------ 1417 | */ 1418 | --------------------------------------------------------------------------------