├── .gitattributes
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── .vscode
├── c_cpp_properties.json
├── launch.json
├── settings.json
└── tasks.json
├── LICENSE
├── README.md
├── examples
├── cleo5
│ ├── example.jpg
│ ├── imgui_test.cs
│ └── imgui_test.txt
└── redux
│ └── imgui_test
│ ├── example.jpg
│ └── index.js
├── include
├── cleo
│ ├── CLEO.h
│ ├── CLEO_Utils.h
│ └── cleo_redux_sdk.h
├── imgui
│ ├── imconfig.h
│ ├── imgui.cpp
│ ├── imgui.h
│ ├── imgui_demo.cpp
│ ├── imgui_draw.cpp
│ ├── imgui_impl_dx11.cpp
│ ├── imgui_impl_dx11.h
│ ├── imgui_impl_dx9.cpp
│ ├── imgui_impl_dx9.h
│ ├── imgui_impl_opengl3.cpp
│ ├── imgui_impl_opengl3.h
│ ├── imgui_impl_opengl3_loader.h
│ ├── imgui_impl_win32.cpp
│ ├── imgui_impl_win32.h
│ ├── imgui_internal.h
│ ├── imgui_stdlib.cpp
│ ├── imgui_stdlib.h
│ ├── imgui_tables.cpp
│ ├── imgui_widgets.cpp
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ └── imstb_truetype.h
├── injector
│ ├── assembly.hpp
│ ├── calling.hpp
│ ├── gvm
│ │ ├── gvm.hpp
│ │ └── translator.hpp
│ ├── hooking.hpp
│ ├── injector.hpp
│ └── utility.hpp
├── kiero
│ ├── MinHook.h
│ ├── kiero.cpp
│ └── kiero.h
└── misc
│ └── stb_image.h
├── lib
├── CLEO.lib
├── cleo_redux.lib
├── cleo_redux64.lib
├── d3dx9.lib
├── d3dx9x64.lib
├── libMinHook-x64.lib
└── libMinHook-x86.lib
├── src
├── dllmain.cpp
├── font.h
├── hook.cpp
├── hook.h
├── imguiframe.hpp
├── notifypopup.cpp
├── notifypopup.h
├── opcodemgr.cpp
├── opcodemgr.h
├── pch.cpp
├── pch.h
├── scriptextender.hpp
├── table.hpp
├── texturemgr.cpp
├── texturemgr.h
└── wrapper.hpp
└── tools
├── AStyle.exe
├── Debug.bat
├── Debug64.bat
├── DebugCleo.bat
├── FormatCode.bat
├── Release.bat
├── Release64.bat
├── ReleaseCleo.bat
├── Setup.bat
├── out.json
├── premake5.exe
├── premake5.lua
├── tes.py
└── test.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build ImGuiRedux
2 | on: push
3 | jobs:
4 | ImGuiRedux:
5 | runs-on: windows-latest
6 | strategy:
7 | matrix:
8 | platform: [Win32, Win64]
9 | buildtype: [Release]
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v3.0.0
13 | - name: Setup premake
14 | uses: abel0b/setup-premake@v2
15 | with:
16 | version: "5.0.0-beta1"
17 | - name: Configure build
18 | uses: ilammy/msvc-dev-cmd@v1
19 | with:
20 | arch: ${{matrix.platform}}
21 | - name: Build plugin
22 | run: |
23 | cd tools
24 | premake5 vs2022
25 | cd ../build
26 | MsBuild ImGuiRedux.sln /property:Configuration=${{matrix.buildtype}} /p:Platform=${{matrix.platform}} /t:ImGuiRedux
27 | - name: Upload plugin
28 | uses: actions/upload-artifact@v3
29 | with:
30 | name: ImGuiRedux${{matrix.platform}}
31 | path: build\bin\ImGuiRedux${{matrix.platform}}.cleo
32 | - name: Archive plugin
33 | uses: papeloto/action-zip@v1
34 | with:
35 | files: build\bin\ImGuiRedux${{matrix.platform}}.cleo
36 | dest: ImGuiRedux${{matrix.platform}}.zip
37 | - name: Add build to release tag
38 | uses: ncipollo/release-action@v1
39 | with:
40 | artifacts: ImGuiRedux${{matrix.platform}}.zip
41 | name: "${{matrix.platform}} Builds"
42 | body: "This release is updated frequently with newer builds.\n\n- ImGuiReduxWin64 -> For CLEORedux (Supports 64 bit games)"
43 | allowUpdates: true
44 | tag: "${{matrix.platform}}-latest"
45 | ImGuiCleo:
46 | runs-on: windows-latest
47 | steps:
48 | - name: Checkout
49 | uses: actions/checkout@v3.0.0
50 | - name: Setup premake
51 | uses: abel0b/setup-premake@v2
52 | with:
53 | version: "5.0.0-beta1"
54 | - name: Configure build
55 | uses: ilammy/msvc-dev-cmd@v1
56 | with:
57 | arch: Win32
58 | - name: Build plugin
59 | run: |
60 | cd tools
61 | premake5 vs2022
62 | cd ../build
63 | MsBuild ImGuiRedux.sln /property:Configuration=ReleaseCleo /p:Platform=Win32 /t:ImGuiRedux
64 | - name: Upload plugin
65 | uses: actions/upload-artifact@v3
66 | with:
67 | name: ImGuiCleoWin32
68 | path: build\bin\ImGuiCleoWin32.cleo
69 | - name: Archive plugin
70 | uses: papeloto/action-zip@v1
71 | with:
72 | files: build\bin\ImGuiCleoWin32.cleo
73 | dest: ImGuiCleoWin32.zip
74 | - name: Add build to release tag
75 | uses: ncipollo/release-action@v1
76 | with:
77 | artifacts: ImGuiCleoWin32.zip
78 | name: "Win32 Builds"
79 | body: "This release is updated frequently with newer builds.\n\n- ImGuiCleoWin32 -> For CLEO5 (Supports GTA SA). Only required if you use ImGui in .cs scripts. \n- ImGuiReduxWin32 -> For CLEORedux (Supports 32 bit games). GTA SA Support is also included."
80 | allowUpdates: true
81 | tag: "Win32-latest"
82 |
83 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | archives/
2 | build/
3 | tools/pack/
4 | .gitignore
5 | CheatMenuVC.7z
6 | CheatMenuIII.7z
7 | CheatMenuSA.7z
8 |
--------------------------------------------------------------------------------
/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "configurations": [
3 | {
4 | "name": "GTASA",
5 | "includePath": [
6 | "${workspaceFolder}/**",
7 | "${DXSDK_DIR}/Include/*",
8 | "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt\\*"
9 | ],
10 | "defines": [
11 | "_DEBUG",
12 | "_DX9_SDK_INSTALLED",
13 | "RUNTIME_CLEO",
14 | ],
15 | "windowsSdkVersion": "10.0.19041.0",
16 | "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe",
17 | "cStandard": "c17",
18 | "cppStandard": "c++20",
19 | "intelliSenseMode": "windows-msvc-x86"
20 | }
21 | ],
22 | "version": 4
23 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Launch SS",
9 | "type": "cppvsdbg",
10 | "request": "launch",
11 | "program": "${env:GTA_SS_DIR}/gta_sa.exe",
12 | "args": [],
13 | "stopAtEntry": false,
14 | "cwd": "${env:GTA_SS_DIR}",
15 | "environment": [],
16 | "console": "internalConsole"
17 | },
18 | {
19 | "name": "Launch SA",
20 | "type": "cppvsdbg",
21 | "request": "launch",
22 | "program": "${env:GTA_SA_DIR}/gta_sa.exe",
23 | "args": [],
24 | "stopAtEntry": false,
25 | "cwd": "${env:GTA_SA_DIR}",
26 | "environment": [],
27 | "console": "internalConsole"
28 | },
29 | {
30 | "name": "Launch VC",
31 | "type": "cppvsdbg",
32 | "request": "launch",
33 | "program": "${env:GTA_VC_DIR}/gta-vc.exe",
34 | "args": [],
35 | "stopAtEntry": false,
36 | "cwd": "${env:GTA_VC_DIR}",
37 | "environment": [],
38 | "console": "internalConsole"
39 | },
40 | {
41 | "name": "Launch III",
42 | "type": "cppvsdbg",
43 | "request": "launch",
44 | "program": "${env:GTA_III_DIR}/Gta3.exe",
45 | "args": [],
46 | "stopAtEntry": false,
47 | "cwd": "${env:GTA_III_DIR}",
48 | "environment": [],
49 | "console": "internalConsole"
50 | },
51 | {
52 | "name": "Attach",
53 | "type": "cppvsdbg",
54 | "request": "attach",
55 | "processId": "${command:pickProcess}"
56 | }
57 | ]
58 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "algorithm": "cpp",
4 | "chrono": "cpp",
5 | "functional": "cpp",
6 | "memory": "cpp",
7 | "thread": "cpp",
8 | "xmemory": "cpp",
9 | "iosfwd": "cpp",
10 | "array": "cpp",
11 | "atomic": "cpp",
12 | "bit": "cpp",
13 | "cctype": "cpp",
14 | "charconv": "cpp",
15 | "clocale": "cpp",
16 | "cmath": "cpp",
17 | "compare": "cpp",
18 | "concepts": "cpp",
19 | "condition_variable": "cpp",
20 | "cstddef": "cpp",
21 | "cstdint": "cpp",
22 | "cstdio": "cpp",
23 | "cstdlib": "cpp",
24 | "cstring": "cpp",
25 | "ctime": "cpp",
26 | "cwchar": "cpp",
27 | "exception": "cpp",
28 | "filesystem": "cpp",
29 | "format": "cpp",
30 | "forward_list": "cpp",
31 | "fstream": "cpp",
32 | "initializer_list": "cpp",
33 | "iomanip": "cpp",
34 | "ios": "cpp",
35 | "iostream": "cpp",
36 | "istream": "cpp",
37 | "iterator": "cpp",
38 | "limits": "cpp",
39 | "list": "cpp",
40 | "locale": "cpp",
41 | "map": "cpp",
42 | "mutex": "cpp",
43 | "new": "cpp",
44 | "numeric": "cpp",
45 | "optional": "cpp",
46 | "ostream": "cpp",
47 | "ratio": "cpp",
48 | "shared_mutex": "cpp",
49 | "sstream": "cpp",
50 | "stdexcept": "cpp",
51 | "stop_token": "cpp",
52 | "streambuf": "cpp",
53 | "string": "cpp",
54 | "system_error": "cpp",
55 | "tuple": "cpp",
56 | "type_traits": "cpp",
57 | "typeinfo": "cpp",
58 | "unordered_map": "cpp",
59 | "utility": "cpp",
60 | "valarray": "cpp",
61 | "vector": "cpp",
62 | "xfacet": "cpp",
63 | "xhash": "cpp",
64 | "xiosbase": "cpp",
65 | "xlocale": "cpp",
66 | "xlocbuf": "cpp",
67 | "xlocinfo": "cpp",
68 | "xlocmes": "cpp",
69 | "xlocmon": "cpp",
70 | "xlocnum": "cpp",
71 | "xloctime": "cpp",
72 | "xstddef": "cpp",
73 | "xstring": "cpp",
74 | "xtr1common": "cpp",
75 | "xtree": "cpp",
76 | "xutility": "cpp",
77 | "*.rh": "cpp",
78 | "any": "cpp",
79 | "deque": "cpp",
80 | "stack": "cpp"
81 | }
82 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "Build Debug",
8 | "type": "shell",
9 | "command": "${workspaceFolder}/tools/Debug.bat",
10 | "presentation": {
11 | "echo": true,
12 | "reveal": "always",
13 | "focus": false,
14 | "panel": "shared",
15 | "showReuseMessage": false,
16 | "clear": true
17 | },
18 | "group": {
19 | "kind": "build",
20 | "isDefault": true
21 | },
22 | "windows": {
23 | "options": {
24 | "shell": {
25 | "executable": "cmd.exe",
26 | "args": [
27 | "/d", "/c"
28 | ]
29 | }
30 | }
31 | },
32 | },
33 | {
34 | "label": "Build Release",
35 | "type": "shell",
36 | "command": "${workspaceFolder}/tools/Release.bat",
37 | "presentation": {
38 | "echo": true,
39 | "reveal": "always",
40 | "focus": false,
41 | "panel": "shared",
42 | "showReuseMessage": false,
43 | "clear": true
44 | },
45 | "group": {
46 | "kind": "build",
47 | "isDefault": true
48 | },
49 | "windows": {
50 | "options": {
51 | "shell": {
52 | "executable": "cmd.exe",
53 | "args": [
54 | "/d", "/c"
55 | ]
56 | }
57 | }
58 | },
59 | },
60 | {
61 | "label": "Build Debug CLEO",
62 | "type": "shell",
63 | "command": "${workspaceFolder}/tools/DebugCleo.bat",
64 | "presentation": {
65 | "echo": true,
66 | "reveal": "always",
67 | "focus": false,
68 | "panel": "shared",
69 | "showReuseMessage": false,
70 | "clear": true
71 | },
72 | "group": {
73 | "kind": "build",
74 | "isDefault": true
75 | },
76 | "windows": {
77 | "options": {
78 | "shell": {
79 | "executable": "cmd.exe",
80 | "args": [
81 | "/d", "/c"
82 | ]
83 | }
84 | }
85 | },
86 | },
87 | {
88 | "label": "Build Release CLEO",
89 | "type": "shell",
90 | "command": "${workspaceFolder}/tools/ReleaseCleo.bat",
91 | "presentation": {
92 | "echo": true,
93 | "reveal": "always",
94 | "focus": false,
95 | "panel": "shared",
96 | "showReuseMessage": false,
97 | "clear": true
98 | },
99 | "group": {
100 | "kind": "build",
101 | "isDefault": true
102 | },
103 | "windows": {
104 | "options": {
105 | "shell": {
106 | "executable": "cmd.exe",
107 | "args": [
108 | "/d", "/c"
109 | ]
110 | }
111 | }
112 | },
113 | },
114 | {
115 | "label": "Build Debug64",
116 | "type": "shell",
117 | "command": "${workspaceFolder}/tools/Debug64.bat",
118 | "presentation": {
119 | "echo": true,
120 | "reveal": "always",
121 | "focus": false,
122 | "panel": "shared",
123 | "showReuseMessage": false,
124 | "clear": true
125 | },
126 | "group": {
127 | "kind": "build",
128 | "isDefault": true
129 | },
130 | "windows": {
131 | "options": {
132 | "shell": {
133 | "executable": "cmd.exe",
134 | "args": [
135 | "/d", "/c"
136 | ]
137 | }
138 | }
139 | },
140 | },
141 | {
142 | "label": "Build Release64",
143 | "type": "shell",
144 | "command": "${workspaceFolder}/tools/Release64.bat",
145 | "presentation": {
146 | "echo": true,
147 | "reveal": "always",
148 | "focus": false,
149 | "panel": "shared",
150 | "showReuseMessage": false,
151 | "clear": true
152 | },
153 | "group": {
154 | "kind": "build",
155 | "isDefault": true
156 | },
157 | "windows": {
158 | "options": {
159 | "shell": {
160 | "executable": "cmd.exe",
161 | "args": [
162 | "/d", "/c"
163 | ]
164 | }
165 | }
166 | },
167 | },
168 | {
169 | "label": "Format Code",
170 | "type": "shell",
171 | "command": "${workspaceFolder}/tools/FormatCode.bat",
172 | "presentation": {
173 | "echo": true,
174 | "reveal": "always",
175 | "focus": false,
176 | "panel": "shared",
177 | "showReuseMessage": false,
178 | "clear": true
179 | },
180 | "group": {
181 | "kind": "build",
182 | "isDefault": true
183 | },
184 | "windows": {
185 | "options": {
186 | "shell": {
187 | "executable": "cmd.exe",
188 | "args": [
189 | "/d", "/c"
190 | ]
191 | }
192 | }
193 | },
194 | },
195 | ]
196 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ImGuiRedux
2 | [Dear ImGui](https://github.com/ocornut/imgui) bindings for [CLEORedux](https://re.cleo.li/). Check out the example script [here](https://github.com/user-grinch/ImGuiRedux/blob/master/resource/imgui_test.js) & download binaries from [here](https://github.com/user-grinch/ImGuiRedux/releases)
3 |
4 | ## Supported Games
5 | - GTA III
6 | - GTA III DE
7 | - GTA Vice City
8 | - GTA Vice City DE
9 | - GTA San Andreas
10 | - GTA San Andreas DE
11 | - GTA 4 Complete Edition
12 | - Bully Scholarship Edition
13 |
14 | ## Versions
15 | - ImGuiCleoWin32 -> For CLEO5 (Supports GTA SA). Only required if you use ImGui in .cs scripts.
16 | - ImGuiReduxWin32 -> For CLEORedux (Supports 32 bit games). GTA SA Support is also included.
17 | - ImGuiReduxWin64 -> For CLEORedux (Supports 64 bit games)
18 |
19 |
20 | ### Installation
21 | 1. Install [ASI Loader](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases) & [ImGuiRedux x86](https://github.com/user-grinch/ImGuiRedux/releases/tag/Win32-latest)
22 | 3. For GTAs install [SilentPatch](https://gtaforums.com/topic/669045-silentpatch/)
23 | 4. For GTA III & VC install [d3d8to9 Wrapper](https://github.com/crosire/d3d8to9/releases)
24 |
25 | ## Unknown hosts
26 | Unknown hosts are basically untested games. They may or may not work on per game basis. Use it at your own risk!
27 | **PS: Let me know if your X game works. I'll add it in the list above.**
28 |
29 | Below version of DirectX games are supported,
30 | 1. D3D8 (with [wrapper](https://github.com/user-grinch/ImGuiRedux/blob/master/resource/d3d8.dll))
31 | 2. D3D9
32 | 3. D3D11
33 | 4. OpenGL3 (Soon)
34 |
35 | ### Installation
36 | 1. Install your required version of [ASI Loader](https://github.com/ThirteenAG/Ultimate-ASI-Loader/releases) & [ImGuiRedux](https://github.com/user-grinch/ImGuiRedux/releases/) (x86 or x64)
37 | 2. Cross your fingers and try it in game!
38 |
39 | More info [here](https://re.cleo.li/docs/en/embedding.html)
40 |
41 |
--------------------------------------------------------------------------------
/examples/cleo5/example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/user-grinch/ImGuiRedux/11604d4dc061ba8a9f4c4a41f65a84174b5d1223/examples/cleo5/example.jpg
--------------------------------------------------------------------------------
/examples/cleo5/imgui_test.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/user-grinch/ImGuiRedux/11604d4dc061ba8a9f4c4a41f65a84174b5d1223/examples/cleo5/imgui_test.cs
--------------------------------------------------------------------------------
/examples/cleo5/imgui_test.txt:
--------------------------------------------------------------------------------
1 | //
2 | // ImGuiCleo Example Script
3 | //
4 | {$CLEO}
5 | {$USE CLEO}
6 | {$USE imgui}
7 |
8 | const TOGGLE_KEY = 116 // F5
9 | int $gShowWindow = 0
10 | int $gVersionInfo = 0
11 | int $gRadioBtn = 1
12 | int $gTimerExample = 0
13 | int $gPrevTimer = 0
14 | int $gComboSelection = 1
15 | int $gImage = ImGui.LoadImage("cleo\example.jpg")
16 |
17 | while true
18 | /*
19 | This must always be 0 to render ImGui each frame
20 | If you need to wait for something use timers instead,
21 | example below
22 | */
23 | wait 0
24 |
25 |
26 | /*
27 | All ImGui code must be wrapped inside the BeginFrame() .. EndFrame()
28 | You need to pass a "UNIQUE ID" for the frame name.
29 | Use something that's unlikely to be used by any other scripts
30 | */
31 | ImGui.BeginFrame("IMGUI_CLEO_DEMO")
32 | ImGui.SetCursorVisible($gShowWindow)
33 |
34 | if $gShowWindow == 1
35 | then
36 | ImGui.SetNextWindowSize(350.0, 600.0, ImGuiCond.Once)
37 | $gShowWindow = ImGui.Begin("ImGuiCleo Demo Window", $gShowWindow, 0, 0, 0, 0)
38 |
39 | float $reduxVer = ImGui.GetPluginVersion()
40 | s$imguiVer = ImGui.GetVersion()
41 | int $fps = Game.GetFramerate()
42 |
43 | ImGui.Spacing()
44 |
45 | if $gVersionInfo == 1
46 | then
47 | ImGui.Columns(2)
48 | Text.StringFormat(s$temp, "ImGui: %s", s$imguiVer)
49 | ImGui.Text(s$temp)
50 | Text.StringFormat(s$temp, "Framerate: %d", $fps)
51 | ImGui.Text(s$temp)
52 | ImGui.NextColumn()
53 | Text.StringFormat(s$temp, "CLEO: %f", $reduxVer)
54 | ImGui.Text(s$temp)
55 | ImGui.Columns(1)
56 | ImGui.Spacing()
57 | end
58 |
59 | ImGui.BeginChild("WindowChild")
60 |
61 | int $tab = ImGui.Tabs("TabBar", "Checkbox,Button,Input,Text,Styles")
62 |
63 | if $tab == 0
64 | then
65 | ImGui.Spacing()
66 | ImGui.Columns(2)
67 | $gVersionInfo = ImGui.Checkbox("Show version info", $gVersionInfo)
68 | ImGui.NextColumn()
69 | $gTimerExample = ImGui.Checkbox("Show timer example", $gTimerExample)
70 | ImGui.Columns(1)
71 | ImGui.Spacing()
72 | end
73 |
74 |
75 | if $tab == 1
76 | then
77 | ImGui.Spacing()
78 | if ImGui.CollapsingHeader("Arrow buttons")
79 | then
80 | ImGui.ButtonArrow("Left", 0)
81 | ImGui.SameLine()
82 | ImGui.ButtonArrow("Right", 1)
83 | ImGui.SameLine()
84 | ImGui.ButtonArrow("Up", 2)
85 | ImGui.SameLine()
86 | ImGui.ButtonArrow("Down", 3)
87 |
88 | ImGui.Separator()
89 | ImGui.Spacing()
90 | end
91 |
92 | if ImGui.CollapsingHeader("Radio buttons")
93 | then
94 | $gRadioBtn = ImGui.RadioButton("RB1", $gRadioBtn, 1)
95 | ImGui.SameLine()
96 | $gRadioBtn = ImGui.RadioButton("RB2", $gRadioBtn, 2)
97 | ImGui.SameLine()
98 | $gRadioBtn = ImGui.RadioButton("RB3", $gRadioBtn, 3)
99 | ImGui.Spacing()
100 | end
101 |
102 | if ImGui.CollapsingHeader("Regular buttons")
103 | then
104 | ImGui.GetScalingSize("S0", 2, 0, $szX, $szY)
105 | if ImGui.Button("Normal button", $szX, $szY)
106 | then
107 | Text.PrintString("Normal button was pressed", 1000)
108 | end
109 | ImGui.SameLine()
110 | if ImGui.ButtonImage("Image Button", $gImage, $szX, $szY)
111 | then
112 | Text.PrintString("Image Button was pressed", 1000)
113 | end
114 |
115 | ImGui.Spacing()
116 |
117 | float $szX = 0
118 | float $szY = 0
119 | $szX, $szY = ImGui.GetScalingSize("S1", 3, 0)
120 | if ImGui.ButtonColored("CB 1", 1.0, 0.0, 0.0, 1.0, $szX, $szY)
121 | then
122 | Text.PrintString("Color button 1 was pressed", 1000)
123 | end
124 | ImGui.SameLine()
125 | if ImGui.ButtonColored("CB 2", 0.0, 1.0, 0.0, 1.0, $szX, $szY)
126 | then
127 | Text.PrintString("Color button 2 was pressed", 1000)
128 | end
129 | ImGui.SameLine()
130 | if ImGui.ButtonColored("CB 3", 0.0, 0.0, 1.0, 1.0, $szX, $szY)
131 | then
132 | Text.PrintString("Color button 3 was pressed", 1000)
133 | end
134 |
135 | ImGui.GetScalingSize("S2", 1, 0, $szX, $szY)
136 | ImGui.Text("Tip:\n\tClick the below area")
137 | if ImGui.ButtonInvisible("Invis button", $szX, $szY)
138 | then
139 | Text.PrintString("Invisible button was pressed", 1000)
140 | end
141 |
142 | if ImGui.IsItemHovered("HOver")
143 | then
144 | ImGui.Text("Hovering invisible button")
145 | end
146 |
147 | ImGui.Spacing()
148 | ImGui.Separator()
149 | end
150 | end
151 |
152 | ImGui.Spacing()
153 |
154 | // Input and Slider example
155 | if $tab == 2
156 | then
157 | ImGui.Spacing()
158 | 1@ = ImGui.InputInt("Int input", 420, 0, 1000)
159 | 1@ = ImGui.InputFloat("Float input", 69.9, 0.0, 100.0)
160 | ImGui.Spacing()
161 | 1@ = ImGui.SliderInt("Int slider", 5, 0, 10)
162 | 1@ = ImGui.SliderFloat("Float slider", 5.0, 0.0, 10.0)
163 | ImGui.Spacing()
164 | s$text = ImGui.InputText("Text input widget")
165 | ImGui.Spacing()
166 |
167 | float $szX = 0
168 | float $szY = 0
169 | $szX, $szY = ImGui.GetScalingSize("S012", 2, 0)
170 | if ImGui.Button("Rest Inputs", $szX, $szY)
171 | then
172 | ImGui.SetItemValueInt("Int input", 420)
173 | ImGui.SetItemValueInt("Int slider", 5)
174 | end
175 | ImGui.SameLine()
176 | if ImGui.Button("Rest Sliders", $szX, $szY)
177 | then
178 | ImGui.SetItemValueFloat("Float input", 69.9)
179 | ImGui.SetItemValueFloat("Float slider", 5.0)
180 | end
181 |
182 | ImGui.Dummy(0.0, 20.0)
183 |
184 | float $r = 0
185 | float $g = 0
186 | float $b = 0
187 | float $a = 0
188 | $r, $g, $b, $a = ImGui.ColorPicker("Color Picker")
189 | ImGui.ButtonColored("COLORBTN", $r, $g, $b, $a, 70.0, 30.0)
190 |
191 | ImGui.Dummy(0.0, 10.0)
192 | ImGui.Text("Text input: " + text)
193 |
194 | $gComboSelection = ImGui.ComboBox("Combo", "Option1,Option2,Option3", $gComboSelection)
195 | end
196 |
197 | if $tab == 3
198 | then
199 | ImGui.Spacing()
200 | ImGui.Text("A little brown fox jumps over the lazy dog")
201 | ImGui.TextDisabled("A little brown fox jumps over the lazy dog")
202 | ImGui.TextColored("A little brown fox jumps over the lazy dog", 1.0, 0.0, 0.0, 1.0)
203 | ImGui.TextWithBullet("A little brown fox jumps over the lazy dog")
204 | ImGui.Spacing()
205 | ImGui.TextWrapped("A little brown fox jumps over the lazy dog. A little brown fox jumps over the lazy dog. A little brown fox jumps over the lazy dog")
206 | end
207 |
208 | if $tab == 4
209 | then
210 | ImGui.Spacing()
211 | ImGui.Text("Red checkbox")
212 | ImGui.Spacing()
213 | ImGui.PushStyleColor(ImGuiCol.FrameBg, 200, 0, 0, 255)
214 | ImGui.PushStyleColor(ImGuiCol.FrameBgActive, 90, 0, 0, 255)
215 | ImGui.PushStyleColor(ImGuiCol.FrameBgHovered, 120, 0, 0, 255)
216 | $gVersionInfo = ImGui.Checkbox("Show version info", $gVersionInfo)
217 | ImGui.PopStyleColor(3)
218 | ImGui.Spacing()
219 | ImGui.Text("Button with custom style")
220 | ImGui.Spacing()
221 |
222 | ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 10.0)
223 |
224 | float $szX = 0
225 | float $szY = 0
226 | $szX, $szY = ImGui.GetScalingSize("S012", 2, 0)
227 | if ImGui.Button("Rounded button", $szX, $szY)
228 | then
229 | Text.PrintString("Rounded button was pressed", 1000)
230 | end
231 | ImGui.PopStyleVar(1)
232 |
233 | ImGui.SameLine()
234 | if ImGui.Button("Regular button", $szX, $szY)
235 | then
236 | Text.PrintString("Regular button was pressed", 1000)
237 | end
238 | end
239 |
240 | ImGui.EndChild()
241 |
242 | ImGui.End()
243 | end
244 | ImGui.EndFrame()
245 |
246 |
247 | // Timer example
248 | // This code has 5 second delay
249 | float $delta = TIMERA - $gPrevTimer
250 | if and
251 | $gTimerExample > 0
252 | $delta > 5000
253 | then
254 | Text.PrintString("Timer test message", 1000)
255 | $gPrevTimer = TIMERA
256 | end
257 |
258 | if Pad.IsKeyPressed(TOGGLE_KEY)
259 | then
260 | while Pad.IsKeyPressed(TOGGLE_KEY)
261 | wait 0
262 | end
263 |
264 | if $gShowWindow == 1
265 | then
266 | $gShowWindow = 0
267 | else
268 | $gShowWindow = 1
269 | end
270 | end
271 | end
272 |
273 |
274 |
--------------------------------------------------------------------------------
/examples/redux/imgui_test/example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/user-grinch/ImGuiRedux/11604d4dc061ba8a9f4c4a41f65a84174b5d1223/examples/redux/imgui_test/example.jpg
--------------------------------------------------------------------------------
/examples/redux/imgui_test/index.js:
--------------------------------------------------------------------------------
1 | ///
2 | //
3 | // ImGuiRedux Example Script
4 | //
5 | import { ImGuiCol, ImGuiStyleVar } from "../.config/enums";
6 |
7 | const TOGGLE_KEY = 116 // F5
8 | var gShowWindow = 0
9 | var gVersionInfo = 0
10 | var gRadioBtn = 1
11 | var gTimerExample = 0
12 | var gPrevTimer = 0
13 | var gComboSelection = 1
14 | var gImage = ImGui.LoadImage("cleo/imgui_test/example.jpg")
15 |
16 | function textBox(text)
17 | {
18 | if (["gta3", "vc", "sa", "gta3_unreal", "vc_unreal", "sa_unreal"].includes(HOST))
19 | {
20 | showTextBox(text)
21 | }
22 | else
23 | {
24 | ImGui.SetMessage(text)
25 | }
26 | }
27 |
28 | while (true)
29 | {
30 | /*
31 | This must always be 0 to render ImGui each frame
32 | If you need to wait for something use timers instead,
33 | example below
34 | */
35 | wait(0)
36 |
37 |
38 | /*
39 | All ImGui code must be wrapped inside the BeginFrame() .. EndFrame()
40 | You need to pass a "UNIQUE ID" for the frame name.
41 | Use something that's unlikely to be used by any other scripts
42 | */
43 | ImGui.BeginFrame("IMGUI_DEMO")
44 | ImGui.SetCursorVisible(gShowWindow)
45 |
46 | if (gShowWindow)
47 | {
48 | ImGui.SetNextWindowSize(350.0, 600.0, 2) // 2 = ImGuiCond_Once
49 | gShowWindow = ImGui.Begin("ImGuiRedux Demo Window", gShowWindow, 0, 0, 0, 0)
50 |
51 | let reduxVer = ImGui.GetPluginVersion()
52 | let imguiVer = ImGui.GetVersion()
53 | let fps = Game.GetFramerate()
54 |
55 | ImGui.Spacing()
56 |
57 | if (gVersionInfo)
58 | {
59 | ImGui.Columns(2)
60 | ImGui.Text("ImGui: " + imguiVer)
61 | ImGui.Text("Framerate: " + fps)
62 | ImGui.NextColumn()
63 | ImGui.Text("Redux: " + reduxVer.toFixed(2))
64 | ImGui.Columns(1)
65 | ImGui.Spacing()
66 | }
67 |
68 | ImGui.BeginChild("WindowChild")
69 |
70 | let tab = ImGui.Tabs("TabBar", "Checkbox,Button,Input,Text,Styles")
71 |
72 | if (tab == 0)
73 | {
74 | ImGui.Spacing()
75 | ImGui.Columns(2)
76 | gVersionInfo = ImGui.Checkbox("Show version info", gVersionInfo)
77 | ImGui.NextColumn()
78 | gTimerExample = ImGui.Checkbox("Show timer example", gTimerExample)
79 | ImGui.Columns(1)
80 | ImGui.Spacing()
81 | }
82 |
83 |
84 | if (tab == 1)
85 | {
86 | ImGui.Spacing()
87 | if (ImGui.CollapsingHeader("Arrow buttons"))
88 | {
89 | ImGui.ButtonArrow("Left", 0)
90 | ImGui.SameLine()
91 | ImGui.ButtonArrow("Right", 1)
92 | ImGui.SameLine()
93 | ImGui.ButtonArrow("Up", 2)
94 | ImGui.SameLine()
95 | ImGui.ButtonArrow("Down", 3)
96 |
97 | ImGui.Separator()
98 | ImGui.Spacing()
99 | }
100 | if (ImGui.CollapsingHeader("Radio buttons"))
101 | {
102 | gRadioBtn = ImGui.RadioButton("RB1", gRadioBtn, 1)
103 | ImGui.SameLine()
104 | gRadioBtn = ImGui.RadioButton("RB2", gRadioBtn, 2)
105 | ImGui.SameLine()
106 | gRadioBtn = ImGui.RadioButton("RB3", gRadioBtn, 3)
107 | ImGui.Spacing()
108 | let str = "Current Button: " + gRadioBtn
109 | ImGui.Text(str)
110 |
111 | ImGui.Separator()
112 | ImGui.Spacing()
113 | }
114 | if (ImGui.CollapsingHeader("Regular buttons"))
115 | {
116 | let size = ImGui.GetScalingSize("S0", 2, 0)
117 | if (ImGui.Button("Normal button", size.x, size.y*2))
118 | {
119 | textBox("Normal button was pressed")
120 | }
121 | ImGui.SameLine()
122 | if (ImGui.ButtonImage("Image Button", gImage, size.x, size.y*2))
123 | {
124 | textBox("Image Button was pressed")
125 | }
126 |
127 | ImGui.Spacing()
128 |
129 | size = ImGui.GetScalingSize("S1", 3, 0)
130 | if (ImGui.ButtonColored("CB 1", 1.0, 0.0, 0.0, 1.0, size.x, size.y))
131 | {
132 | textBox("Color button 1 was pressed")
133 | }
134 | ImGui.SameLine()
135 | if (ImGui.ButtonColored("CB 2", 0.0, 1.0, 0.0, 1.0, size.x, size.y))
136 | {
137 | textBox("Color button 2 was pressed")
138 | }
139 | ImGui.SameLine()
140 | if (ImGui.ButtonColored("CB 3", 0.0, 0.0, 1.0, 1.0, size.x, size.y))
141 | {
142 | textBox("Color button 3 was pressed")
143 | }
144 |
145 | size = ImGui.GetScalingSize("S2", 1, 0)
146 | ImGui.Text("Tip:\n\tClick the below area")
147 | if (ImGui.ButtonInvisible("Invis button", size.x, size.y))
148 | {
149 | textBox("Invisible button was pressed")
150 | }
151 | if (ImGui.IsItemHovered("HOver"))
152 | {
153 | ImGui.Text("Hovering invisible button")
154 | }
155 |
156 | ImGui.Spacing()
157 | ImGui.Separator()
158 | }
159 | }
160 |
161 | ImGui.Spacing()
162 |
163 | // Input and Slider example
164 | if (tab == 2)
165 | {
166 | ImGui.Spacing()
167 | ImGui.InputInt("Int input", 420, 0, 1000)
168 | ImGui.InputFloat("Float input", 69.9, 0.0, 100.0)
169 | ImGui.Spacing()
170 | ImGui.SliderInt("Int slider", 5, 0, 10)
171 | ImGui.SliderFloat("Float slider", 5.0, 0.0, 10.0)
172 | ImGui.Spacing()
173 | let text = ImGui.InputText("Text input widget")
174 | ImGui.Spacing()
175 |
176 | let size = ImGui.GetScalingSize("S012", 2, 0)
177 | if (ImGui.Button("Rest Inputs", size.x, size.y))
178 | {
179 | ImGui.SetItemValueInt("Int input", 420)
180 | ImGui.SetItemValueInt("Int slider", 5)
181 | }
182 | ImGui.SameLine()
183 | if (ImGui.Button("Rest Sliders", size.x, size.y))
184 | {
185 | ImGui.SetItemValueFloat("Float input", 69.9)
186 | ImGui.SetItemValueFloat("Float slider", 5.0)
187 | }
188 |
189 | ImGui.Dummy(0, 20)
190 | var col = ImGui.ColorPicker("Color Picker", 0)
191 | ImGui.ButtonColored("COLORBTN", col.red, col.green, col.blue, col.alpha, 70.0, 30.0)
192 |
193 | ImGui.Dummy(0, 10)
194 | ImGui.Text("Text input: " + text)
195 |
196 | gComboSelection = ImGui.ComboBox("Combo", "Option1,Option2,Option3", gComboSelection)
197 | let str = "Selection: " + gComboSelection
198 | ImGui.Text(str)
199 | }
200 |
201 | if (tab == 3)
202 | {
203 | ImGui.Spacing()
204 | ImGui.Text("A little brown fox jumps over the lazy dog")
205 | ImGui.TextDisabled("A little brown fox jumps over the lazy dog")
206 | ImGui.TextColored("A little brown fox jumps over the lazy dog", 1.0, 0.0, 0.0, 1.0)
207 | ImGui.TextWithBullet("A little brown fox jumps over the lazy dog")
208 | ImGui.Spacing()
209 | ImGui.TextWrapped("A little brown fox jumps over the lazy dog. A little brown fox jumps over the lazy dog. A little brown fox jumps over the lazy dog")
210 | }
211 |
212 | if (tab == 4)
213 | {
214 | ImGui.Spacing()
215 | ImGui.Text("Red checkbox")
216 | ImGui.Spacing()
217 | ImGui.PushStyleColor(ImGuiCol.FrameBg, 200, 0, 0, 255)
218 | ImGui.PushStyleColor(ImGuiCol.FrameBgActive, 90, 0, 0, 255)
219 | ImGui.PushStyleColor(ImGuiCol.FrameBgHovered, 120, 0, 0, 255)
220 | gVersionInfo = ImGui.Checkbox("Show version info", gVersionInfo)
221 | ImGui.PopStyleColor(3)
222 | ImGui.Spacing()
223 | ImGui.Text("Button with custom style")
224 | ImGui.Spacing()
225 |
226 | ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 10)
227 | let size = ImGui.GetScalingSize("S012", 2, 0)
228 | if (ImGui.Button("Rounded button", size.x, size.y*2))
229 | {
230 | textBox("Rounded button was pressed")
231 | }
232 | ImGui.PopStyleVar(1)
233 |
234 | ImGui.SameLine()
235 | if (ImGui.Button("Regular button", size.x, size.y*2))
236 | {
237 | textBox("Regular button was pressed")
238 | }
239 | }
240 |
241 | ImGui.EndChild()
242 |
243 | ImGui.End()
244 | }
245 | ImGui.EndFrame()
246 |
247 |
248 | // Timer example
249 | // This code has 5 second delay
250 | if (gTimerExample && (TIMERA - gPrevTimer > 5000))
251 | {
252 | textBox("Timer test message")
253 | gPrevTimer = TIMERA
254 | }
255 |
256 | if (Pad.IsKeyDown(TOGGLE_KEY))
257 | {
258 | gShowWindow = !gShowWindow
259 | }
260 | }
261 |
262 |
263 |
--------------------------------------------------------------------------------
/include/cleo/CLEO.h:
--------------------------------------------------------------------------------
1 | /*
2 | CLEO 5 header file
3 | Copyright (c) 2023 Alien, Deji, Junior_Djjr, Miran, Seemann
4 | */
5 | #pragma once
6 |
7 | #ifdef __cplusplus
8 | #include
9 | #endif
10 | #include
11 |
12 | #define CLEO_VERSION_MAIN 5
13 | #define CLEO_VERSION_MAJOR 0
14 | #define CLEO_VERSION_MINOR 0
15 |
16 | #define CLEO_VERSION ((CLEO_VERSION_MAIN << 24)|(CLEO_VERSION_MAJOR << 16)|(CLEO_VERSION_MINOR << 8)) // 0x0v0v0v00
17 |
18 | #define __TO_STR(x) #x
19 | #define TO_STR(x) __TO_STR(x)
20 | #define CLEO_VERSION_STR "5.0.0-alpha.63"
21 |
22 | namespace CLEO
23 | {
24 | // result of CLEO_GetScriptVersion
25 | enum eCLEO_Version : DWORD
26 | {
27 | CLEO_VER_3 = 0x03000000,
28 | CLEO_VER_4_MIN = 0x04000000,
29 | CLEO_VER_4_2 = 0x04020000,
30 | CLEO_VER_4_3 = 0x04030000,
31 | CLEO_VER_4_4 = 0x04040000,
32 | CLEO_VER_4 = CLEO_VER_4_4,
33 | CLEO_VER_5 = 0x05000000,
34 | CLEO_VER_CUR = CLEO_VERSION
35 | };
36 |
37 | // result of CLEO_GetGameVersion
38 | enum eGameVersion : int
39 | {
40 | GV_US10 = 0, // 1.0 us
41 | GV_US11 = 1, // 1.01 us - not supported
42 | GV_EU10 = 2, // 1.0 eu
43 | GV_EU11 = 3, // 1.01 eu
44 | GV_STEAM,
45 | GV_TOTAL,
46 | GV_UNK = -1 // any other
47 | };
48 |
49 | // operand types
50 | enum eDataType : BYTE
51 | {
52 | DT_END, // variable args end marker
53 | DT_DWORD, // literal int 32
54 | DT_VAR, // globalVar $
55 | DT_LVAR, // localVar @
56 | DT_BYTE, // literal int 8
57 | DT_WORD, // literal int 16
58 | DT_FLOAT, // literal float 32
59 | DT_VAR_ARRAY, // globalArr $(,)
60 | DT_LVAR_ARRAY, // localArr @(,)
61 | DT_TEXTLABEL, // literal string up to 7 chars
62 | DT_VAR_TEXTLABEL, // globalVarSString s$
63 | DT_LVAR_TEXTLABEL, // localVarSString @s
64 | DT_VAR_TEXTLABEL_ARRAY, // globalVarSStringArr s$(,)
65 | DT_LVAR_TEXTLABEL_ARRAY, // localVarSStringArr @s(,)
66 | DT_VARLEN_STRING, // literal vstring ""
67 | DT_STRING, // literal string up to 15 chars
68 | DT_VAR_STRING, // globalVarVString v$
69 | DT_LVAR_STRING, // localVarVString @v
70 | DT_VAR_STRING_ARRAY, // globalVarStringArr v$(,)
71 | DT_LVAR_STRING_ARRAY, // localVarStringArr @v(,)
72 | DT_INVALID = 0xFF // CLEO internal
73 | };
74 |
75 | enum eArrayDataType : BYTE
76 | {
77 | ADT_INT, // variable with integer
78 | ADT_FLOAT, // variable with integer
79 | ADT_TEXTLABEL, // variable with short string (8 char)
80 | ADT_STRING, // variable with long string (16 char)
81 | ADT_NONE = 0xFF // CLEO internal
82 | };
83 | static const BYTE ArrayDataTypeMask = ADT_INT | ADT_FLOAT | ADT_TEXTLABEL | ADT_STRING; // array flags byte contains other info too. Type needs to be masked when read
84 |
85 | static const char* ToStr(eDataType type)
86 | {
87 | switch (type)
88 | {
89 | case DT_END: return "VArgEnd"; break;
90 | case DT_DWORD: return "Int32"; break;
91 | case DT_VAR: return "GlobVar"; break;
92 | case DT_LVAR: return "LocVar"; break;
93 | case DT_BYTE: return "Int8"; break;
94 | case DT_WORD: return "Int16"; break;
95 | case DT_FLOAT: return "Float32"; break;
96 | case DT_VAR_ARRAY: return "GlobVarArr"; break;
97 | case DT_LVAR_ARRAY: return "LocVarArr"; break;
98 | case DT_TEXTLABEL: return "STxt"; break;
99 | case DT_VAR_TEXTLABEL: return "GlobVarSTxt"; break;
100 | case DT_LVAR_TEXTLABEL: return "LocVarSTxt"; break;
101 | case DT_VAR_TEXTLABEL_ARRAY: return "GlobVarSTxtArr"; break;
102 | case DT_LVAR_TEXTLABEL_ARRAY: return "LocVarSTxtArr"; break;
103 | case DT_VARLEN_STRING: return "Txt"; break;
104 | case DT_STRING: return "LTxt"; break;
105 | case DT_VAR_STRING: return "GlobVarLTxt"; break;
106 | case DT_LVAR_STRING: return "LocVarLTxt"; break;
107 | case DT_VAR_STRING_ARRAY: return "GlobVarLTxtArr"; break;
108 | case DT_LVAR_STRING_ARRAY: return "LocVarLTxtArr"; break;
109 | default: return "corrupted";
110 | }
111 | }
112 | static bool IsImmInteger(eDataType type) // immediate/literal integer in code like 42
113 | {
114 | switch (type)
115 | {
116 | case DT_BYTE:
117 | case DT_WORD:
118 | case DT_DWORD:
119 | return true;
120 | }
121 | return false;
122 | }
123 | static bool IsImmFloat(eDataType type) // immediate/literal float in code like 42.0
124 | {
125 | return type == DT_FLOAT;
126 | }
127 | static bool IsImmString(eDataType type) // immediate/literal string in code like "text"
128 | {
129 | switch (type)
130 | {
131 | case DT_STRING:
132 | case DT_TEXTLABEL:
133 | case DT_VARLEN_STRING:
134 | return true;
135 | }
136 | return false;
137 | }
138 | static bool IsVarString(eDataType type) // string variable
139 | {
140 | switch (type)
141 | {
142 | case DT_LVAR_TEXTLABEL:
143 | case DT_LVAR_TEXTLABEL_ARRAY:
144 | case DT_LVAR_STRING:
145 | case DT_LVAR_STRING_ARRAY:
146 | case DT_VAR_TEXTLABEL:
147 | case DT_VAR_TEXTLABEL_ARRAY:
148 | case DT_VAR_STRING:
149 | case DT_VAR_STRING_ARRAY:
150 | return true;
151 | }
152 | return false;
153 | }
154 | static bool IsVariable(eDataType type) // can carry int, float, pointer to text
155 | {
156 | switch (type)
157 | {
158 | case DT_VAR:
159 | case DT_VAR_ARRAY:
160 | case DT_LVAR:
161 | case DT_LVAR_ARRAY:
162 | return true;
163 | }
164 | return false;
165 | }
166 | static bool IsArray(eDataType type)
167 | {
168 | switch (type)
169 | {
170 | case DT_LVAR_TEXTLABEL_ARRAY:
171 | case DT_LVAR_STRING_ARRAY:
172 | case DT_VAR_TEXTLABEL_ARRAY:
173 | case DT_VAR_STRING_ARRAY:
174 | case DT_VAR_ARRAY:
175 | case DT_LVAR_ARRAY:
176 | return true;
177 | }
178 | return false;
179 | }
180 | static const char* ToKindStr(eDataType type, eArrayDataType arrType = ADT_NONE)
181 | {
182 | switch (type)
183 | {
184 | case DT_BYTE:
185 | case DT_WORD:
186 | case DT_DWORD:
187 | return "int"; break;
188 |
189 | case DT_FLOAT:
190 | return "float"; break;
191 |
192 | case DT_STRING:
193 | case DT_TEXTLABEL:
194 | case DT_LVAR_TEXTLABEL:
195 | case DT_LVAR_TEXTLABEL_ARRAY:
196 | case DT_LVAR_STRING:
197 | case DT_LVAR_STRING_ARRAY:
198 | case DT_VAR_TEXTLABEL:
199 | case DT_VAR_TEXTLABEL_ARRAY:
200 | case DT_VAR_STRING:
201 | case DT_VAR_STRING_ARRAY:
202 | case DT_VARLEN_STRING:
203 | return "string"; break;
204 |
205 | case DT_VAR:
206 | case DT_LVAR:
207 | return "variable"; break;
208 |
209 | case DT_VAR_ARRAY:
210 | case DT_LVAR_ARRAY:
211 | switch(arrType)
212 | {
213 | case ADT_INT:
214 | return "int"; break;
215 |
216 | case ADT_FLOAT:
217 | return "float"; break;
218 |
219 | case ADT_TEXTLABEL:
220 | case ADT_STRING:
221 | return "string"; break;
222 |
223 | default: return "variable";
224 | }
225 |
226 | case DT_END:
227 | return "varArgEnd"; break;
228 |
229 | default:
230 | return "corrupted"; break;
231 | }
232 | }
233 |
234 | const size_t MAX_STR_LEN = 0xff; // max length of string type parameter
235 |
236 | union SCRIPT_VAR
237 | {
238 | DWORD dwParam;
239 | short wParam;
240 | WORD usParam;
241 | BYTE ucParam;
242 | char cParam;
243 | bool bParam;
244 | int nParam;
245 | float fParam;
246 | void* pParam;
247 | char* pcParam;
248 | };
249 |
250 | enum eLogicalOperation : WORD
251 | {
252 | NONE = 0, // just replace
253 |
254 | AND_2 = 1, // AND operation on results of next two conditional opcodes
255 | AND_3,
256 | AND_4,
257 | AND_5,
258 | AND_6,
259 | AND_7,
260 | AND_END,
261 |
262 | OR_2 = 21, // OR operation on results of next two conditional opcodes
263 | OR_3,
264 | OR_4,
265 | OR_5,
266 | OR_6,
267 | OR_7,
268 | OR_END,
269 | };
270 | static eLogicalOperation& operator--(eLogicalOperation& o)
271 | {
272 | if (o == eLogicalOperation::NONE) return o; // can not be decremented anymore
273 | if (o == eLogicalOperation::OR_2) return o = eLogicalOperation::NONE;
274 |
275 | auto val = static_cast(o); // to number
276 | val--;
277 | return o = static_cast(val);
278 | }
279 |
280 | // CLEO virtual path prefixes. Expandable with CLEO_ResolvePath
281 | const char DIR_GAME[] = "root:"; // game root directory
282 | const char DIR_USER[] = "userfiles:"; // game save directory
283 | const char DIR_SCRIPT[] = "."; // current script directory
284 | const char DIR_CLEO[] = "cleo:"; // game\cleo directory
285 | const char DIR_MODULES[] = "modules:"; // game\cleo\modules directory
286 |
287 | // argument of CLEO_RegisterCallback
288 | enum class eCallbackId : DWORD
289 | {
290 | GameBegin, // void WINAPI OnGameBegin(DWORD saveSlot); // -1 if not started from save
291 | GameProcess, // void WINAPI OnGameProcess(); // called once every frame during gameplay
292 | GameEnd, // void WINAPI OnGameEnd();
293 | ScriptsLoaded, // void WINAPI OnScriptsLoaded();
294 | ScriptsFinalize, // void WINAPI OnScriptsFinalize();
295 | ScriptRegister, // void WINAPI OnScriptRegister(CRunningScript* pScript); // called after script creation
296 | ScriptUnregister, // void WINAPI OnScriptUnregister(CRunningScript* pScript); // called before script deletion
297 | ScriptProcess, // bool WINAPI OnScriptProcess(CRunningScript* pScript); // return false to skip this script processing
298 | ScriptOpcodeProcess, // OpcodeResult WINAPI OnScriptOpcodeProcess(CRunningScript* pScript, DWORD opcode); // return other than OR_NONE to signal that opcode was handled in the callback
299 | ScriptOpcodeProcessFinished, // OpcodeResult WINAPI OnScriptOpcodeProcessFinished(CRunningScript* pScript, DWORD opcode, OpcodeResult result); // return other than OR_NONE to overwrite original result
300 | ScriptDraw, // void WINAPI OnScriptDraw(bool beforeFade);
301 | DrawingFinished, // void WINAPI OnDrawingFinished(); // called after game rendered everything and before presenting screen buffer
302 | Log, // void OnLog(eLogLevel level, const char* msg);
303 | MainWindowFocus, // void WINAPI OnMainWindowFocus(bool active); // called when game main window focus changes
304 | };
305 |
306 | // used by CLEO_Log and Log callback
307 | enum class eLogLevel : DWORD
308 | {
309 | None,
310 | Error, // errors and warnings
311 | Debug, // debug mode / user traces
312 | Default // all log messages
313 | };
314 |
315 | enum OpcodeResult : char
316 | {
317 | OR_NONE = -2,
318 | OR_ERROR = -1,
319 | OR_CONTINUE = 0,
320 | OR_INTERRUPT = 1,
321 | };
322 |
323 | typedef int SCRIPT_HANDLE;
324 | typedef SCRIPT_HANDLE HANDLE_ACTOR, ACTOR, HACTOR, PED, HPED, HANDLE_PED;
325 | typedef SCRIPT_HANDLE HANDLE_CAR, CAR, HCAR, VEHICLE, HVEHICLE, HANDLE_VEHICLE;
326 | typedef SCRIPT_HANDLE HANDLE_OBJECT, OBJECT, HOBJECT;
327 |
328 | #pragma pack(push,1)
329 | #ifdef __cplusplus
330 | class CRunningScript
331 | {
332 | public:
333 | #else
334 | struct CRunningScript
335 | {
336 | #endif
337 | CRunningScript* Next; // 0x00 next script in queue
338 | CRunningScript* Previous; // 0x04 previous script in queue
339 | char Name[8]; // 0x08 name of script, given by 03A4 opcode
340 | void* BaseIP; // 0x10 pointer to begin of script in memory
341 | BYTE* CurrentIP; // 0x14 current instruction pointer
342 | BYTE* Stack[8]; // 0x18 return stack for 0050, 0051
343 | WORD SP; // 0x38 current item in stack
344 | BYTE _pad3A[2]; // 0x3A padding
345 | SCRIPT_VAR LocalVar[32]; // 0x3C script's local variables
346 | DWORD Timers[2]; // 0xBC script's timers
347 | bool bIsActive; // 0xC4 is script active
348 | bool bCondResult; // 0xC5 condition result
349 | bool bUseMissionCleanup; // 0xC6 clean mission
350 | bool bIsExternal; // 0xC7 is thread external (from script.img)
351 | bool bTextBlockOverride; // 0xC8
352 | BYTE bExternalType; // 0xC9
353 | BYTE _padCA[2]; // 0xCA padding
354 | DWORD WakeTime; // 0xCC time, when script starts again after 0001 opcode
355 | eLogicalOperation LogicalOp;// 0xD0 opcode 00D6 parameter
356 | bool NotFlag; // 0xD2 opcode & 0x8000 != 0
357 | bool bWastedBustedCheck; // 0xD3 wasted_or_busted check flag
358 | bool bWastedOrBusted; // 0xD4 is player wasted or busted
359 | char _padD5[3]; // 0xD5 padding
360 | void* SceneSkipIP; // 0xD8 scene skip label ptr
361 | bool bIsMission; // 0xDC is this script mission
362 | WORD ScmFunction; // 0xDD CLEO's previous scmFunction id
363 | bool bIsCustom; // 0xDF is this CLEO script
364 |
365 | #ifdef __cplusplus
366 | public:
367 | CRunningScript()
368 | {
369 | strcpy(Name, "noname");
370 | BaseIP = 0;
371 | Previous = 0;
372 | Next = 0;
373 | CurrentIP = 0;
374 | memset(Stack, 0, sizeof(Stack));
375 | SP = 0;
376 | WakeTime = 0;
377 | bIsActive = 0;
378 | bCondResult = 0;
379 | bUseMissionCleanup = 0;
380 | bIsExternal = 0;
381 | bTextBlockOverride = 0;
382 | bExternalType = -1;
383 | memset(LocalVar, 0, sizeof(LocalVar));
384 | LogicalOp = eLogicalOperation::NONE;
385 | NotFlag = 0;
386 | bWastedBustedCheck = 1;
387 | bWastedOrBusted = 0;
388 | SceneSkipIP = 0;
389 | bIsMission = 0;
390 | ScmFunction = 0;
391 | bIsCustom = 0;
392 | }
393 |
394 | bool IsActive() const { return bIsActive; }
395 | bool IsExternal() const { return bIsExternal; }
396 | bool IsMission() const { return bIsMission; }
397 | bool IsCustom() const { return bIsCustom; } // is this CLEO Script?
398 | std::string GetName() const { auto str = std::string(Name, Name + 8); str.resize(strlen(str.c_str())); return str; } // make sure it is always null terminated
399 | BYTE* GetBasePointer() const { return (BYTE*)BaseIP; }
400 | BYTE* GetBytePointer() const { return CurrentIP; }
401 | void SetIp(void* ip) { CurrentIP = (BYTE*)ip; }
402 | void SetBaseIp(void* ip) { BaseIP = ip; }
403 | CRunningScript* GetNext() const { return Next; }
404 | CRunningScript* GetPrev() const { return Previous; }
405 | void SetIsExternal(bool b) { bIsExternal = b; }
406 | void SetActive(bool b) { bIsActive = b; }
407 | OpcodeResult Suspend() { WakeTime = 0xFFFFFFFF; return OpcodeResult::OR_INTERRUPT; } // suspend script execution forever
408 | void SetNext(CRunningScript* v) { Next = v; }
409 | void SetPrev(CRunningScript* v) { Previous = v; }
410 | SCRIPT_VAR* GetVarPtr() { return LocalVar; }
411 | SCRIPT_VAR* GetVarPtr(int i) { return &LocalVar[i]; }
412 | int* GetIntVarPtr(int i) { return (int*)&LocalVar[i].dwParam; }
413 | int GetIntVar(int i) const { return LocalVar[i].dwParam; }
414 | void SetIntVar(int i, int v) { LocalVar[i].dwParam = v; }
415 | void SetFloatVar(int i, float v) { LocalVar[i].fParam = v; }
416 | char GetByteVar(int i) const { return LocalVar[i].bParam; }
417 | bool GetConditionResult() const { return bCondResult != 0; }
418 | bool GetNotFlag() const { return NotFlag; }
419 | void SetNotFlag(bool state) { NotFlag = state; }
420 |
421 | eDataType PeekDataType() const { return *(eDataType*)CurrentIP; }
422 | eArrayDataType PeekArrayDataType() const { BYTE t = *(CurrentIP + 1 + 2 + 2 + 1); t &= ArrayDataTypeMask; return (eArrayDataType) t; } // result valid only for array type params
423 |
424 | eDataType ReadDataType() { return (eDataType)ReadDataByte(); }
425 | short ReadDataVarIndex() { return ReadDataWord(); }
426 | short ReadDataArrayOffset() { return ReadDataWord(); }
427 | short ReadDataArrayIndex() { return ReadDataWord(); }
428 | short ReadDataArraySize() { return ReadDataByte(); }
429 | short ReadDataArrayFlags() { return ReadDataByte(); }
430 |
431 | void IncPtr(int n = 1) { CurrentIP += n; }
432 | int ReadDataByte() { char b = *CurrentIP; ++CurrentIP; return b; }
433 | short ReadDataWord() { short v = *(short*)CurrentIP; CurrentIP += 2; return v; }
434 | int ReadDataInt() { int i = *(int*)CurrentIP; CurrentIP += 4; return i; }
435 |
436 | void PushStack(BYTE* ptr) { Stack[SP++] = ptr; }
437 | BYTE* PopStack() { return Stack[--SP]; }
438 |
439 | WORD GetScmFunction() const { return ScmFunction; }
440 | void SetScmFunction(WORD id) { ScmFunction = id; }
441 |
442 | #endif // __cplusplus
443 | };
444 | #pragma pack(pop)
445 | static_assert(sizeof(CRunningScript) == 0xE0, "Invalid size of CRunningScript!");
446 |
447 | // alias for legacy use
448 | #ifdef __cplusplus
449 | typedef class CRunningScript CScriptThread;
450 | #else
451 | typedef struct CRunningScript CScriptThread;
452 | #endif
453 |
454 | typedef OpcodeResult (CALLBACK* _pOpcodeHandler)(CRunningScript*);
455 | typedef void(*FuncScriptDeleteDelegateT) (CRunningScript*);
456 |
457 | #ifdef __cplusplus
458 | extern "C" {
459 | #endif //__cplusplus
460 |
461 | DWORD WINAPI CLEO_GetVersion();
462 | eGameVersion WINAPI CLEO_GetGameVersion();
463 |
464 | BOOL WINAPI CLEO_RegisterOpcode(WORD opcode, _pOpcodeHandler callback);
465 | BOOL WINAPI CLEO_RegisterCommand(const char* commandName, _pOpcodeHandler callback); // uses cleo\.CONFIG\sa.json to obtain opcode number from name
466 | void WINAPI CLEO_RegisterCallback(eCallbackId id, void* func);
467 |
468 |
469 | // script utils
470 | void WINAPI CLEO_GetScriptInfoStr(CRunningScript* thread, bool currLineInfo, char* buf, DWORD bufSize); // short text for displaying in error\log messages
471 | void WINAPI CLEO_GetScriptParamInfoStr(int idexOffset, char* buf, DWORD bufSize); // short text with current+offset opcode parameter info (index and name if available)
472 | eCLEO_Version WINAPI CLEO_GetScriptVersion(const CRunningScript* thread); // compatibility mode
473 | LPCSTR WINAPI CLEO_GetScriptFilename(const CRunningScript* thread); // returns nullptr if provided script ptr is not valid
474 |
475 | LPCSTR WINAPI CLEO_GetScriptWorkDir(const CRunningScript* thread);
476 | void WINAPI CLEO_SetScriptWorkDir(CRunningScript* thread, const char* path);
477 |
478 | void WINAPI CLEO_SetThreadCondResult(CRunningScript* thread, BOOL result);
479 | void WINAPI CLEO_ThreadJumpAtLabelPtr(CRunningScript* thread, int labelPtr);
480 |
481 | int WINAPI CLEO_GetOperandType(const CRunningScript* thread); // peek parameter data type. Returns int for legacy reason, should be eDataType.
482 | DWORD WINAPI CLEO_GetVarArgCount(CRunningScript* thread); // peek remaining var-args count
483 |
484 | extern SCRIPT_VAR* opcodeParams;
485 | extern SCRIPT_VAR* missionLocals;
486 |
487 | SCRIPT_VAR* WINAPI CLEO_GetOpcodeParamsArray(); // get pointer to 'SCRIPT_VAR[32] opcodeParams'. Used by Retrieve/Record opcode params functions
488 | BYTE WINAPI CLEO_GetParamsHandledCount(); // number of already read/written opcode parameters since current opcode handler was called
489 |
490 | // param read
491 | SCRIPT_VAR* WINAPI CLEO_GetPointerToScriptVariable(CRunningScript* thread); // get pointer to the variable's data, nullptr if parameter is not variable. Advances script to next param
492 | void WINAPI CLEO_RetrieveOpcodeParams(CRunningScript* thread, int count); // read multiple params. Stored in opcodeParams array
493 | DWORD WINAPI CLEO_GetIntOpcodeParam(CRunningScript* thread);
494 | float WINAPI CLEO_GetFloatOpcodeParam(CRunningScript* thread);
495 | LPCSTR WINAPI CLEO_ReadStringOpcodeParam(CRunningScript* thread, char* buff = nullptr, int buffSize = 0); // read always null-terminated string into buffer, clamped to its size. If no buffer provided then internal, globally shared by all CLEO_ReadStringOpcodeParam calls, is used. Returns pointer to the result buffer or nullptr on fail
496 | LPCSTR WINAPI CLEO_ReadStringPointerOpcodeParam(CRunningScript* thread, char* buff = nullptr, int buffSize = 0); // read always null-terminated string into buffer, clamped to its size. If no buffer provided then internal, globally shared by all CLEO_ReadStringPointerOpcodeParam calls, is used. WARNING: returned pointer may differ from buff and contain string longer than buffSize (ptr to original data source)
497 | void WINAPI CLEO_ReadStringParamWriteBuffer(CRunningScript* thread, char** outBuf, int* outBufSize, BOOL* outNeedsTerminator); // get info about the string opcode param, so it can be written latter. If outNeedsTerminator is not 0 then whole bufSize can be used as text characters. Advances script to next param
498 | char* WINAPI CLEO_ReadParamsFormatted(CRunningScript* thread, const char* format, char* buf = nullptr, int bufSize = 0); // consumes all var-arg params and terminator
499 | // get param value without advancing the script
500 | DWORD WINAPI CLEO_PeekIntOpcodeParam(CRunningScript* thread);
501 | float WINAPI CLEO_PeekFloatOpcodeParam(CRunningScript* thread);
502 | SCRIPT_VAR* WINAPI CLEO_PeekPointerToScriptVariable(CRunningScript* thread); // get pointer to the variable's data, nullptr if parameter is not variable
503 |
504 | // param skip without reading
505 | void WINAPI CLEO_SkipOpcodeParams(CRunningScript* thread, int count);
506 | void WINAPI CLEO_SkipUnusedVarArgs(CRunningScript* thread); // for var-args opcodes. Should be called even when all params were read (to skip var-arg terminator)
507 |
508 | // param write
509 | void WINAPI CLEO_RecordOpcodeParams(CRunningScript* thread, int count); // write multiple params from opcodeParams array
510 | void WINAPI CLEO_SetIntOpcodeParam(CRunningScript* thread, DWORD value);
511 | void WINAPI CLEO_SetFloatOpcodeParam(CRunningScript* thread, float value);
512 | void WINAPI CLEO_WriteStringOpcodeParam(CRunningScript* thread, const char* str);
513 |
514 |
515 | BOOL WINAPI CLEO_GetScriptDebugMode(const CRunningScript* thread); // debug mode features enabled for this script?
516 | void WINAPI CLEO_SetScriptDebugMode(CRunningScript* thread, BOOL enabled);
517 |
518 | CRunningScript* WINAPI CLEO_CreateCustomScript(CRunningScript* fromThread, const char* script_name, int label);
519 | CRunningScript* WINAPI CLEO_GetLastCreatedCustomScript();
520 | CRunningScript* WINAPI CLEO_GetScriptByName(const char* threadName, BOOL standardScripts, BOOL customScripts, DWORD resultIndex = 0); // can be called multiple times to find more scripts named threadName. resultIndex should be incremented until the method returns nullptr
521 | CRunningScript* WINAPI CLEO_GetScriptByFilename(const char* path, DWORD resultIndex = 0); // can be absolute, partial path or just filename
522 |
523 | // scripts deletion callback
524 | void WINAPI CLEO_AddScriptDeleteDelegate(FuncScriptDeleteDelegateT func);
525 | void WINAPI CLEO_RemoveScriptDeleteDelegate(FuncScriptDeleteDelegateT func);
526 |
527 | DWORD WINAPI CLEO_GetScriptTextureById(CRunningScript* thread, int id); // ret RwTexture *
528 |
529 | DWORD WINAPI CLEO_GetInternalAudioStream(CRunningScript* thread, DWORD stream); // arg CAudioStream *
530 |
531 | // Should be always used when working with files. Provides ModLoader compatibility
532 | void WINAPI CLEO_ResolvePath(CRunningScript* thread, char* inOutPath, DWORD pathMaxLen); // convert to absolute (file system) path
533 | struct DirectoryList{ DWORD count; char** paths; };
534 | DirectoryList WINAPI CLEO_ListDirectory(CRunningScript* thread, const char* searchPath, BOOL listDirs, BOOL listFiles); // thread can be null, searchPath can contain wildcards. After use CLEO_ListDirectoryFree must be called on returned DirectoryList to free allocated resources
535 | void WINAPI CLEO_ListDirectoryFree(DirectoryList list); // releases resources allocated by CLEO_ListDirectory
536 |
537 | void WINAPI CLEO_Log(eLogLevel level, const char* msg); // add message to log
538 |
539 | #ifdef __cplusplus
540 | }
541 | #endif //__cplusplus
542 |
543 | } // CLEO namespace
544 |
--------------------------------------------------------------------------------
/include/cleo/cleo_redux_sdk.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #define STR_MAX_LEN 128
5 |
6 | enum class HandlerResult
7 | {
8 | // Proceed to the next command
9 | CONTINUE = 0,
10 | // Pause the script and continue on the next game loop iteration
11 | BREAK = 1,
12 | // End the script gracefully
13 | TERMINATE = 2,
14 | // End the script and throw an error
15 | ERR = -1
16 | };
17 |
18 | enum class HostId
19 | {
20 | RE3 = 1,
21 | REVC = 2,
22 | GTA3 = 3,
23 | VC = 4,
24 | SA = 5,
25 | GTA3_UNREAL = 6,
26 | VC_UNREAL = 7,
27 | SA_UNREAL = 8,
28 | IV = 9,
29 | BULLY = 10,
30 | MANIFEST = 254,
31 | UNKNOWN = 255
32 | };
33 |
34 | enum class Directory
35 | {
36 | // /CLEO directory
37 | CLEO = 0,
38 | // /CLEO/.config
39 | CONFIG = 1,
40 | // /CLEO/CLEO_TEXT
41 | TEXT = 2,
42 | // /CLEO/CLEO_PLUGINS
43 | PLUGINS = 3,
44 | // Current working directory
45 | CWD = 4,
46 | // Host root directory
47 | HOST = 5,
48 | };
49 |
50 | typedef void* Context;
51 | typedef intptr_t isize;
52 |
53 | typedef HandlerResult (*CommandHandler)(Context);
54 | typedef void* (*CustomLoader)(const char*);
55 | typedef void (*OnTickCallback)(unsigned int current_time, int time_step);
56 | typedef void (*OnRuntimeInitCallback)();
57 | typedef void (*OnShowTextBoxCallback)(const char*);
58 |
59 | extern "C" {
60 | // since v1
61 | // Returns the current SDK version as an integer number.
62 | long GetSDKVersion();
63 | // since v1
64 | // Returns the current host (game) id
65 | HostId GetHostId();
66 | // since v1
67 | // Resolves a path to the absolute path
68 | void ResolvePath(const char* src, char* dest);
69 | // since v1
70 | // Returns the absolute path to the CLEO directory
71 | // deprecated: use GetDirectoryPath
72 | void GetCLEOFolder(char* dest);
73 | // since v1
74 | // Returns the absolute path to the current working directory (normally the game directory)
75 | void GetCwd(char* dest);
76 | // since v1
77 | // Prints a new entry to the cleo_redux.log
78 | void Log(const char* text);
79 | // since v1
80 | // Registers a new callback handler for the command with the given name. Permission token is required for unsafe operations interacting with the user environment (e.g. mem, fs, net)
81 | void RegisterCommand(const char* name, CommandHandler handler, const char* permission = nullptr);
82 | // since v1
83 | // Reads an integer argument (either 32 or 64 bit depending on the target platform) from the script input
84 | isize GetIntParam(Context ctx);
85 | // since v1
86 | // Reads a floating-point argument from the script input
87 | float GetFloatParam(Context ctx);
88 | // since v1
89 | // Copies atmost {maxlen} bytes of a UTF-8 encoded character sequence in the script input to {dest}
90 | void GetStringParam(Context ctx, char* dest, unsigned char maxlen);
91 | // since v1
92 | // Writes the integer {value} (either 32 or 64 bit depending on the target platform) to the script output
93 | void SetIntParam(Context ctx, isize value);
94 | // since v1
95 | // Writes the floating-point {value} to the script output
96 | void SetFloatParam(Context ctx, float value);
97 | // since v1
98 | // Copies a null-terminated UTF-8 encoded character sequence from {src} to the script output
99 | void SetStringParam(Context ctx, const char* src);
100 | // since v1
101 | // Sets the status of the current condition
102 | void UpdateCompareFlag(Context ctx, bool result);
103 | // since v2
104 | // Copies atmost {maxlen} bytes of a UTF-8 encoded host name to {dest}
105 | void GetHostName(char* dest, unsigned char maxlen);
106 | // since v2
107 | // Sets the new host name (available in scripts as the HOST constant)
108 | void SetHostName(const char* src);
109 | // since v2
110 | // Initializes or reloads CLEO runtime
111 | void RuntimeInit();
112 | // since v2
113 | // Iterates the main loop
114 | void RuntimeNextTick(unsigned int current_time, int time_step);
115 | // since v3
116 | // Registers a new loader for files matching a glob pattern
117 | void RegisterLoader(const char* glob, CustomLoader loader);
118 | // since v3
119 | // Allocates a memory chunk with size in bytes. Memory is guaranteed to be zero initialized
120 | void* AllocMem(size_t size);
121 | // since v3
122 | // Frees up the memory chunk allocated with AllocMem
123 | void FreeMem(void *ptr);
124 | // since v4
125 | // Registers a new callback invoked on each main loop iteration (before scripts are executed)
126 | void OnBeforeScripts(OnTickCallback callback);
127 | // since v4
128 | // Registers a new callback invoked on each main loop iteration (after scripts are executed)
129 | void OnAfterScripts(OnTickCallback callback);
130 | // since v4
131 | // Registers a new callback invoked on each runtime init event (new game, saved game load, or SDK's RuntimeInit)
132 | void OnRuntimeInit(OnRuntimeInitCallback callback);
133 | // since v5
134 | // Registers a new callback invoked on a ShowTextBox function call. Providing a callback shadows built-in ShowTextBox implementation.
135 | void OnShowTextBox(OnShowTextBoxCallback callback);
136 | /// since v6
137 | /// Returns the absolute path to the CLEO root directory or one of its sub-directories
138 | void GetDirectoryPath(Directory dir, char* dest);
139 | /// since v6
140 | /// Returns CLEO Redux version as a string
141 | void GetCLEOVersion(char* dest);
142 | /// since v6
143 | /// Returns a memory address for the given symbol, or 0 if not found
144 | void* GetSymbolAddress(const char* symbol);
145 | /// since v6
146 | /// Returns number of active CS scripts
147 | size_t GetNumberOfActiveCSScripts();
148 | /// since v6
149 | /// Returns number of active JS scripts
150 | size_t GetNumberOfActiveJSScripts();
151 | /// since v6
152 | /// Is end of arguments reached
153 | bool IsEndOfArguments(Context ctx);
154 | /// since v7
155 | /// Triggers an event with the given name and data
156 | void TriggerEvent(const char* name, const char* data);
157 | }
158 |
159 |
--------------------------------------------------------------------------------
/include/imgui/imconfig.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------------------
2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI
3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
5 | //-----------------------------------------------------------------------------
6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
8 | //-----------------------------------------------------------------------------
9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
13 | //-----------------------------------------------------------------------------
14 |
15 | #pragma once
16 |
17 | //---- Define assertion handler. Defaults to calling assert().
18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
21 |
22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
23 | // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
26 | //#define IMGUI_API __declspec( dllexport )
27 | //#define IMGUI_API __declspec( dllimport )
28 |
29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
31 | //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
32 |
33 | //---- Disable all of Dear ImGui or don't implement standard windows/tools.
34 | // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
35 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
36 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
37 | //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88).
38 |
39 | //---- Don't implement some functions to reduce linkage requirements.
40 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
41 | //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
42 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
43 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
44 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
45 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
46 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
47 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
48 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
49 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
50 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
51 |
52 | //---- Include imgui_user.h at the end of imgui.h as a convenience
53 | //#define IMGUI_INCLUDE_IMGUI_USER_H
54 |
55 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
56 | //#define IMGUI_USE_BGRA_PACKED_COLOR
57 |
58 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
59 | //#define IMGUI_USE_WCHAR32
60 |
61 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
62 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
63 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
64 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
65 | //#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled
66 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
67 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
68 |
69 | //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
70 | // Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
71 | //#define IMGUI_USE_STB_SPRINTF
72 |
73 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
74 | // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
75 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
76 | // #define IMGUI_ENABLE_FREETYPE
77 |
78 | //---- Use stb_truetype to build and rasterize the font atlas (default)
79 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
80 | //#define IMGUI_ENABLE_STB_TRUETYPE
81 |
82 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
83 | // This will be inlined as part of ImVec2 and ImVec4 class declarations.
84 | /*
85 | #define IM_VEC2_CLASS_EXTRA \
86 | constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
87 | operator MyVec2() const { return MyVec2(x,y); }
88 |
89 | #define IM_VEC4_CLASS_EXTRA \
90 | constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
91 | operator MyVec4() const { return MyVec4(x,y,z,w); }
92 | */
93 |
94 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
95 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
96 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
97 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
98 | //#define ImDrawIdx unsigned int
99 |
100 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
101 | //struct ImDrawList;
102 | //struct ImDrawCmd;
103 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
104 | //#define ImDrawCallback MyImDrawCallback
105 |
106 | //---- Debug Tools: Macro to break in Debugger
107 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
108 | //#define IM_DEBUG_BREAK IM_ASSERT(0)
109 | //#define IM_DEBUG_BREAK __debugbreak()
110 |
111 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
112 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
113 | // This adds a small runtime cost which is why it is not enabled by default.
114 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
115 |
116 | //---- Debug Tools: Enable slower asserts
117 | //#define IMGUI_DEBUG_PARANOID
118 |
119 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
120 | /*
121 | namespace ImGui
122 | {
123 | void MyFunction(const char* name, const MyMatrix44& v);
124 | }
125 | */
126 |
--------------------------------------------------------------------------------
/include/imgui/imgui_impl_dx11.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for DirectX11
2 | // This needs to be used along with a Platform Backend (e.g. Win32)
3 |
4 | // Implemented features:
5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
7 |
8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs
12 |
13 | #pragma once
14 | #include "imgui.h" // IMGUI_IMPL_API
15 |
16 | struct ID3D11Device;
17 | struct ID3D11DeviceContext;
18 |
19 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
20 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
21 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
22 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
23 |
24 | // Use if you want to reset your rendering device without losing Dear ImGui state.
25 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
26 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
27 |
--------------------------------------------------------------------------------
/include/imgui/imgui_impl_dx9.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for DirectX9
2 | // This needs to be used along with a Platform Backend (e.g. Win32)
3 |
4 | // Implemented features:
5 | // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
7 |
8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs
12 |
13 | // CHANGELOG
14 | // (minor and older changes stripped away, please see git history for details)
15 | // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
16 | // 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
17 | // 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
18 | // 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states.
19 | // 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857).
20 | // 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file.
21 | // 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer.
22 | // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
23 | // 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
24 | // 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects().
25 | // 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288.
26 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
27 | // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example.
28 | // 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
29 | // 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud.
30 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself.
31 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
32 |
33 | #include "imgui.h"
34 | #include "imgui_impl_dx9.h"
35 |
36 | // DirectX
37 | #include
38 |
39 | // DirectX data
40 | struct ImGui_ImplDX9_Data
41 | {
42 | LPDIRECT3DDEVICE9 pd3dDevice;
43 | LPDIRECT3DVERTEXBUFFER9 pVB;
44 | LPDIRECT3DINDEXBUFFER9 pIB;
45 | LPDIRECT3DTEXTURE9 FontTexture;
46 | int VertexBufferSize;
47 | int IndexBufferSize;
48 |
49 | ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
50 | };
51 |
52 | struct CUSTOMVERTEX
53 | {
54 | float pos[3];
55 | D3DCOLOR col;
56 | float uv[2];
57 | };
58 | #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
59 |
60 | #ifdef IMGUI_USE_BGRA_PACKED_COLOR
61 | #define IMGUI_COL_TO_DX9_ARGB(_COL) (_COL)
62 | #else
63 | #define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16))
64 | #endif
65 |
66 | // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
67 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
68 | static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
69 | {
70 | return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
71 | }
72 |
73 | // Functions
74 | static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
75 | {
76 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
77 |
78 | // Setup viewport
79 | D3DVIEWPORT9 vp;
80 | vp.X = vp.Y = 0;
81 | vp.Width = (DWORD)draw_data->DisplaySize.x;
82 | vp.Height = (DWORD)draw_data->DisplaySize.y;
83 | vp.MinZ = 0.0f;
84 | vp.MaxZ = 1.0f;
85 | bd->pd3dDevice->SetViewport(&vp);
86 |
87 | // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
88 | bd->pd3dDevice->SetPixelShader(NULL);
89 | bd->pd3dDevice->SetVertexShader(NULL);
90 | bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
91 | bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
92 | bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
93 | bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
94 | bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
95 | bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
96 | bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
97 | bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
98 | bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
99 | bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
100 | bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
101 | bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
102 | bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
103 | bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
104 | bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
105 | bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
106 | bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
107 | bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
108 | bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
109 | bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
110 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
111 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
112 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
113 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
114 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
115 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
116 | bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
117 | bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
118 | bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
119 | bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
120 |
121 | // Setup orthographic projection matrix
122 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
123 | // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
124 | {
125 | float L = draw_data->DisplayPos.x + 0.5f;
126 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
127 | float T = draw_data->DisplayPos.y + 0.5f;
128 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
129 | 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 } } };
130 | D3DMATRIX mat_projection =
131 | { { {
132 | 2.0f/(R-L), 0.0f, 0.0f, 0.0f,
133 | 0.0f, 2.0f/(T-B), 0.0f, 0.0f,
134 | 0.0f, 0.0f, 0.5f, 0.0f,
135 | (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
136 | } } };
137 | bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
138 | bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
139 | bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
140 | }
141 | }
142 |
143 | // Render function.
144 | void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
145 | {
146 | // Avoid rendering when minimized
147 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
148 | return;
149 |
150 | // Create and grow buffers if needed
151 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
152 | if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
153 | {
154 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
155 | bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
156 | if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, NULL) < 0)
157 | return;
158 | }
159 | if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
160 | {
161 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
162 | bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
163 | if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, NULL) < 0)
164 | return;
165 | }
166 |
167 | // Backup the DX9 state
168 | IDirect3DStateBlock9* d3d9_state_block = NULL;
169 | if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
170 | return;
171 | if (d3d9_state_block->Capture() < 0)
172 | {
173 | d3d9_state_block->Release();
174 | return;
175 | }
176 |
177 | // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
178 | D3DMATRIX last_world, last_view, last_projection;
179 | bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
180 | bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
181 | bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
182 |
183 | // Allocate buffers
184 | CUSTOMVERTEX* vtx_dst;
185 | ImDrawIdx* idx_dst;
186 | if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
187 | {
188 | d3d9_state_block->Release();
189 | return;
190 | }
191 | if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
192 | {
193 | bd->pVB->Unlock();
194 | d3d9_state_block->Release();
195 | return;
196 | }
197 |
198 | // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format.
199 | // FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
200 | // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
201 | // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
202 | for (int n = 0; n < draw_data->CmdListsCount; n++)
203 | {
204 | const ImDrawList* cmd_list = draw_data->CmdLists[n];
205 | const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
206 | for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
207 | {
208 | vtx_dst->pos[0] = vtx_src->pos.x;
209 | vtx_dst->pos[1] = vtx_src->pos.y;
210 | vtx_dst->pos[2] = 0.0f;
211 | vtx_dst->col = IMGUI_COL_TO_DX9_ARGB(vtx_src->col);
212 | vtx_dst->uv[0] = vtx_src->uv.x;
213 | vtx_dst->uv[1] = vtx_src->uv.y;
214 | vtx_dst++;
215 | vtx_src++;
216 | }
217 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
218 | idx_dst += cmd_list->IdxBuffer.Size;
219 | }
220 | bd->pVB->Unlock();
221 | bd->pIB->Unlock();
222 | bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
223 | bd->pd3dDevice->SetIndices(bd->pIB);
224 | bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
225 |
226 | // Setup desired DX state
227 | ImGui_ImplDX9_SetupRenderState(draw_data);
228 |
229 | // Render command lists
230 | // (Because we merged all buffers into a single one, we maintain our own offset into them)
231 | int global_vtx_offset = 0;
232 | int global_idx_offset = 0;
233 | ImVec2 clip_off = draw_data->DisplayPos;
234 | for (int n = 0; n < draw_data->CmdListsCount; n++)
235 | {
236 | const ImDrawList* cmd_list = draw_data->CmdLists[n];
237 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
238 | {
239 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
240 | if (pcmd->UserCallback != NULL)
241 | {
242 | // User callback, registered via ImDrawList::AddCallback()
243 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
244 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
245 | ImGui_ImplDX9_SetupRenderState(draw_data);
246 | else
247 | pcmd->UserCallback(cmd_list, pcmd);
248 | }
249 | else
250 | {
251 | // Project scissor/clipping rectangles into framebuffer space
252 | ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
253 | ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
254 | if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
255 | continue;
256 |
257 | // Apply Scissor/clipping rectangle, Bind texture, Draw
258 | const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
259 | const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
260 | bd->pd3dDevice->SetTexture(0, texture);
261 | bd->pd3dDevice->SetScissorRect(&r);
262 | bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
263 | }
264 | }
265 | global_idx_offset += cmd_list->IdxBuffer.Size;
266 | global_vtx_offset += cmd_list->VtxBuffer.Size;
267 | }
268 |
269 | // Restore the DX9 transform
270 | bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
271 | bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
272 | bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
273 |
274 | // Restore the DX9 state
275 | d3d9_state_block->Apply();
276 | d3d9_state_block->Release();
277 | }
278 |
279 | bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
280 | {
281 | ImGuiIO& io = ImGui::GetIO();
282 | IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
283 |
284 | // Setup backend capabilities flags
285 | ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)();
286 | io.BackendRendererUserData = (void*)bd;
287 | io.BackendRendererName = "imgui_impl_dx9";
288 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
289 |
290 | bd->pd3dDevice = device;
291 | bd->pd3dDevice->AddRef();
292 |
293 | return true;
294 | }
295 |
296 | void ImGui_ImplDX9_Shutdown()
297 | {
298 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
299 | IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
300 | ImGuiIO& io = ImGui::GetIO();
301 |
302 | ImGui_ImplDX9_InvalidateDeviceObjects();
303 | if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
304 | io.BackendRendererName = NULL;
305 | io.BackendRendererUserData = NULL;
306 | IM_DELETE(bd);
307 | }
308 |
309 | static bool ImGui_ImplDX9_CreateFontsTexture()
310 | {
311 | // Build texture atlas
312 | ImGuiIO& io = ImGui::GetIO();
313 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
314 | unsigned char* pixels;
315 | int width, height, bytes_per_pixel;
316 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
317 |
318 | // Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
319 | #ifndef IMGUI_USE_BGRA_PACKED_COLOR
320 | if (io.Fonts->TexPixelsUseColors)
321 | {
322 | ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
323 | for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
324 | *dst = IMGUI_COL_TO_DX9_ARGB(*src);
325 | pixels = (unsigned char*)dst_start;
326 | }
327 | #endif
328 |
329 | // Upload texture to graphics system
330 | bd->FontTexture = NULL;
331 | if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, NULL) < 0)
332 | return false;
333 | D3DLOCKED_RECT tex_locked_rect;
334 | if (bd->FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
335 | return false;
336 | for (int y = 0; y < height; y++)
337 | memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel);
338 | bd->FontTexture->UnlockRect(0);
339 |
340 | // Store our identifier
341 | io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
342 |
343 | #ifndef IMGUI_USE_BGRA_PACKED_COLOR
344 | if (io.Fonts->TexPixelsUseColors)
345 | ImGui::MemFree(pixels);
346 | #endif
347 |
348 | return true;
349 | }
350 |
351 | bool ImGui_ImplDX9_CreateDeviceObjects()
352 | {
353 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
354 | if (!bd || !bd->pd3dDevice)
355 | return false;
356 | if (!ImGui_ImplDX9_CreateFontsTexture())
357 | return false;
358 | return true;
359 | }
360 |
361 | void ImGui_ImplDX9_InvalidateDeviceObjects()
362 | {
363 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
364 | if (!bd || !bd->pd3dDevice)
365 | return;
366 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
367 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
368 | if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
369 | }
370 |
371 | void ImGui_ImplDX9_NewFrame()
372 | {
373 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
374 | IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX9_Init()?");
375 |
376 | if (!bd->FontTexture)
377 | ImGui_ImplDX9_CreateDeviceObjects();
378 | }
379 |
--------------------------------------------------------------------------------
/include/imgui/imgui_impl_dx9.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for DirectX9
2 | // This needs to be used along with a Platform Backend (e.g. Win32)
3 |
4 | // Implemented features:
5 | // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
7 |
8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs
12 |
13 | #pragma once
14 | #include "imgui.h" // IMGUI_IMPL_API
15 |
16 | struct IDirect3DDevice9;
17 |
18 | IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device);
19 | IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown();
20 | IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame();
21 | IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
22 |
23 | // Use if you want to reset your rendering device without losing Dear ImGui state.
24 | IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
25 | IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
26 |
--------------------------------------------------------------------------------
/include/imgui/imgui_impl_opengl3.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
2 | // - Desktop GL: 2.x 3.x 4.x
3 | // - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
4 | // This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
5 |
6 | // Implemented features:
7 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
8 | // [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
9 |
10 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
11 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
12 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
13 | // Read online: https://github.com/ocornut/imgui/tree/master/docs
14 |
15 | // About GLSL version:
16 | // The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string.
17 | // On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
18 | // Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
19 |
20 | #pragma once
21 | #include "imgui.h" // IMGUI_IMPL_API
22 |
23 | // Backend API
24 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL);
25 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
26 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
27 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
28 |
29 | // (Optional) Called by Init/NewFrame/Shutdown
30 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
31 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
32 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
33 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
34 |
35 | // Specific OpenGL ES versions
36 | //#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
37 | //#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
38 |
39 | // You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
40 | #if !defined(IMGUI_IMPL_OPENGL_ES2) \
41 | && !defined(IMGUI_IMPL_OPENGL_ES3)
42 |
43 | // Try to detect GLES on matching platforms
44 | #if defined(__APPLE__)
45 | #include
46 | #endif
47 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
48 | #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
49 | #elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
50 | #define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
51 | #else
52 | // Otherwise imgui_impl_opengl3_loader.h will be used.
53 | #endif
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/include/imgui/imgui_impl_win32.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
3 |
4 | // Implemented features:
5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
6 | // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
7 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
8 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
9 |
10 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
11 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
12 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
13 | // Read online: https://github.com/ocornut/imgui/tree/master/docs
14 |
15 | #pragma once
16 | #include "imgui.h" // IMGUI_IMPL_API
17 |
18 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
19 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
20 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
21 |
22 | // Win32 message handler your application need to call.
23 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper.
24 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
25 | // - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
26 |
27 | #if 0
28 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
29 | #endif
30 |
31 | // DPI-related helpers (optional)
32 | // - Use to enable DPI awareness without having to create an application manifest.
33 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
34 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
35 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
36 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
37 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
38 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
39 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
40 |
41 | // Transparency related helpers (optional) [experimental]
42 | // - Use to enable alpha compositing transparency with the desktop.
43 | // - Use together with e.g. clearing your framebuffer with zero-alpha.
44 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
45 |
--------------------------------------------------------------------------------
/include/imgui/imgui_stdlib.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
2 | // This is also an example of how you may wrap your own similar types.
3 |
4 | // Changelog:
5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
6 |
7 | #include "imgui.h"
8 | #include "imgui_stdlib.h"
9 |
10 | struct InputTextCallback_UserData
11 | {
12 | std::string* Str;
13 | ImGuiInputTextCallback ChainCallback;
14 | void* ChainCallbackUserData;
15 | };
16 |
17 | static int InputTextCallback(ImGuiInputTextCallbackData* data)
18 | {
19 | InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData;
20 | if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
21 | {
22 | // Resize string callback
23 | // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
24 | std::string* str = user_data->Str;
25 | IM_ASSERT(data->Buf == str->c_str());
26 | str->resize(data->BufTextLen);
27 | data->Buf = (char*)str->c_str();
28 | }
29 | else if (user_data->ChainCallback)
30 | {
31 | // Forward to user callback, if any
32 | data->UserData = user_data->ChainCallbackUserData;
33 | return user_data->ChainCallback(data);
34 | }
35 | return 0;
36 | }
37 |
38 | bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
39 | {
40 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
41 | flags |= ImGuiInputTextFlags_CallbackResize;
42 |
43 | InputTextCallback_UserData cb_user_data;
44 | cb_user_data.Str = str;
45 | cb_user_data.ChainCallback = callback;
46 | cb_user_data.ChainCallbackUserData = user_data;
47 | return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
48 | }
49 |
50 | bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
51 | {
52 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
53 | flags |= ImGuiInputTextFlags_CallbackResize;
54 |
55 | InputTextCallback_UserData cb_user_data;
56 | cb_user_data.Str = str;
57 | cb_user_data.ChainCallback = callback;
58 | cb_user_data.ChainCallbackUserData = user_data;
59 | return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
60 | }
61 |
62 | bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
63 | {
64 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
65 | flags |= ImGuiInputTextFlags_CallbackResize;
66 |
67 | InputTextCallback_UserData cb_user_data;
68 | cb_user_data.Str = str;
69 | cb_user_data.ChainCallback = callback;
70 | cb_user_data.ChainCallbackUserData = user_data;
71 | return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
72 | }
73 |
--------------------------------------------------------------------------------
/include/imgui/imgui_stdlib.h:
--------------------------------------------------------------------------------
1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
2 | // This is also an example of how you may wrap your own similar types.
3 |
4 | // Changelog:
5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | namespace ImGui
12 | {
13 | // ImGui::InputText() with std::string
14 | // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
15 | IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
16 | IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
17 | IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
18 | }
19 |
--------------------------------------------------------------------------------
/include/injector/assembly.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Injectors - Useful Assembly Stuff
3 | *
4 | * Copyright (C) 2012-2014 LINK/2012
5 | *
6 | * This software is provided 'as-is', without any express or implied
7 | * warranty. In no event will the authors be held liable for any damages
8 | * arising from the use of this software.
9 | *
10 | * Permission is granted to anyone to use this software for any purpose,
11 | * including commercial applications, and to alter it and redistribute it
12 | * freely, subject to the following restrictions:
13 | *
14 | * 1. The origin of this software must not be misrepresented; you must not
15 | * claim that you wrote the original software. If you use this software
16 | * in a product, an acknowledgment in the product documentation would be
17 | * appreciated but is not required.
18 | *
19 | * 2. Altered source versions must be plainly marked as such, and must not be
20 | * misrepresented as being the original software.
21 | *
22 | * 3. This notice may not be removed or altered from any source
23 | * distribution.
24 | *
25 | */
26 | #pragma once
27 |
28 | // This header is very restrict about compiler and architecture
29 | #ifndef _MSC_VER // MSVC is much more flexible when we're talking about inline assembly
30 | #error Cannot use this header in another compiler other than MSVC
31 | #endif
32 | #ifndef _M_IX86
33 | #error Supported only in x86
34 | #endif
35 |
36 | //
37 | #include "injector.hpp"
38 |
39 | namespace injector
40 | {
41 | struct reg_pack
42 | {
43 | // The ordering is very important, don't change
44 | // The first field is the last to be pushed and first to be poped
45 |
46 | // PUSHFD / POPFD
47 | uint32_t ef;
48 |
49 | // PUSHAD/POPAD -- must be the lastest fields (because of esp)
50 | union
51 | {
52 | uint32_t arr[8];
53 | struct { uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; };
54 | };
55 |
56 | enum reg_name {
57 | reg_edi, reg_esi, reg_ebp, reg_esp, reg_ebx, reg_edx, reg_ecx, reg_eax
58 | };
59 |
60 | enum ef_flag {
61 | carry_flag = 0, parity_flag = 2, adjust_flag = 4, zero_flag = 6, sign_flag = 7,
62 | direction_flag = 10, overflow_flag = 11
63 | };
64 |
65 | uint32_t& operator[](size_t i)
66 | { return this->arr[i]; }
67 | const uint32_t& operator[](size_t i) const
68 | { return this->arr[i]; }
69 |
70 | template // bit starts from 0, use ef_flag enum
71 | bool flag()
72 | {
73 | return (this->ef & (1 << bit)) != 0;
74 | }
75 |
76 | bool jnb()
77 | {
78 | return flag() == false;
79 | }
80 | };
81 |
82 | // Lowest level stuff (actual assembly) goes on the following namespace
83 | // PRIVATE! Skip this, not interesting for you.
84 | namespace injector_asm
85 | {
86 | // Wrapper functor, so the assembly can use some templating
87 | template
88 | struct wrapper
89 | {
90 | static void call(reg_pack* regs)
91 | {
92 | T fun; fun(*regs);
93 | }
94 | };
95 |
96 | // Constructs a reg_pack and calls the wrapper functor
97 | template // where W is of type wrapper
98 | inline void __declspec(naked) make_reg_pack_and_call()
99 | {
100 | _asm
101 | {
102 | // Construct the reg_pack structure on the stack
103 | pushad // Pushes general purposes registers to reg_pack
104 | add [esp+12], 4 // Add 4 to reg_pack::esp 'cuz of our return pointer, let it be as before this func is called
105 | pushfd // Pushes EFLAGS to reg_pack
106 |
107 | // Call wrapper sending reg_pack as parameter
108 | push esp
109 | call W::call
110 | add esp, 4
111 |
112 | // Destructs the reg_pack from the stack
113 | sub [esp+12+4], 4 // Fix reg_pack::esp before popping it (doesn't make a difference though) (+4 because eflags)
114 | popfd // Warning: Do not use any instruction that changes EFLAGS after this (-> sub affects EF!! <-)
115 | popad
116 |
117 | // Back to normal flow
118 | ret
119 | }
120 | }
121 | };
122 |
123 |
124 | /*
125 | * MakeInline
126 | * Makes inline assembly (but not assembly, an actual functor of type FuncT) at address
127 | */
128 | template
129 | void MakeInline(memory_pointer_tr at)
130 | {
131 | typedef injector_asm::wrapper functor;
132 | if(false) functor::call(nullptr); // To instantiate the template, if not done _asm will fail
133 | MakeCALL(at, injector_asm::make_reg_pack_and_call);
134 | }
135 |
136 | /*
137 | * MakeInline
138 | * Same as above, but it NOPs everything between at and end (exclusive), then performs MakeInline
139 | */
140 | template
141 | void MakeInline(memory_pointer_tr at, memory_pointer_tr end)
142 | {
143 | MakeRangedNOP(at, end);
144 | MakeInline(at);
145 | }
146 |
147 | /*
148 | * MakeInline
149 | * Same as above, but (at,end) are template parameters.
150 | * On this case the functor can be passed as argument since there will be one func instance for each at,end not just for each FuncT
151 | */
152 | template
153 | void MakeInline(FuncT func)
154 | {
155 | static std::unique_ptr static_func;
156 | static_func.reset(new FuncT(std::move(func)));
157 |
158 | // Encapsulates the call to static_func
159 | struct Caps
160 | {
161 | void operator()(reg_pack& regs)
162 | { (*static_func)(regs); }
163 | };
164 |
165 | // Does the actual MakeInline
166 | return MakeInline(lazy_pointer::get(), lazy_pointer::get());
167 | }
168 |
169 | /*
170 | * MakeInline
171 | * Same as above, but (end) is calculated by the length of a call instruction
172 | */
173 | template
174 | void MakeInline(FuncT func)
175 | {
176 | return MakeInline(func);
177 | }
178 | };
179 |
--------------------------------------------------------------------------------
/include/injector/calling.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Injectors - Function Calls Using Variadic Templates
3 | *
4 | * Copyright (C) 2014 LINK/2012
5 | *
6 | * This software is provided 'as-is', without any express or implied
7 | * warranty. In no event will the authors be held liable for any damages
8 | * arising from the use of this software.
9 | *
10 | * Permission is granted to anyone to use this software for any purpose,
11 | * including commercial applications, and to alter it and redistribute it
12 | * freely, subject to the following restrictions:
13 | *
14 | * 1. The origin of this software must not be misrepresented; you must not
15 | * claim that you wrote the original software. If you use this software
16 | * in a product, an acknowledgment in the product documentation would be
17 | * appreciated but is not required.
18 | *
19 | * 2. Altered source versions must be plainly marked as such, and must not be
20 | * misrepresented as being the original software.
21 | *
22 | * 3. This notice may not be removed or altered from any source
23 | * distribution.
24 | *
25 | */
26 | #pragma once
27 | #include "injector.hpp"
28 | #include
29 | #include
30 |
31 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013
32 | #else
33 | #error "This feature is not supported on this compiler"
34 | #endif
35 |
36 | namespace injector
37 | {
38 | template
39 | struct cstd;
40 |
41 | template
42 | struct cstd
43 | {
44 | // Call function at @p returning @Ret with args @Args
45 | static Ret call(memory_pointer_tr p, Args... a)
46 | {
47 | auto fn = (Ret(*)(Args...)) p.get();
48 | return fn(std::forward(a)...);
49 | }
50 |
51 | template // Uses lazy pointer
52 | static Ret call(Args... a)
53 | {
54 | return call(lazy_pointer::get(), std::forward(a)...);
55 | }
56 | };
57 |
58 | template
59 | struct stdcall;
60 |
61 | template
62 | struct stdcall
63 | {
64 | // Call function at @p returning @Ret with args @Args
65 | static Ret call(memory_pointer_tr p, Args... a)
66 | {
67 | auto fn = (Ret(__stdcall *)(Args...)) p.get();
68 | return fn(std::forward(a)...);
69 | }
70 |
71 | template // Uses lazy pointer
72 | static Ret call(Args... a)
73 | {
74 | return call(lazy_pointer::get(), std::forward(a)...);
75 | }
76 | };
77 |
78 | template
79 | struct fastcall;
80 |
81 | template
82 | struct fastcall
83 | {
84 | // Call function at @p returning @Ret with args @Args
85 | static Ret call(memory_pointer_tr p, Args... a)
86 | {
87 | auto fn = (Ret(__fastcall *)(Args...)) p.get();;
88 | return fn(std::forward(a)...);
89 | }
90 |
91 | template // Uses lazy pointer
92 | static Ret call(Args... a)
93 | {
94 | return call(lazy_pointer::get(), std::forward(a)...);
95 | }
96 | };
97 |
98 | template
99 | struct thiscall;
100 |
101 | template
102 | struct thiscall
103 | {
104 | // Call function at @p returning @Ret with args @Args
105 | static Ret call(memory_pointer_tr p, Args... a)
106 | {
107 | auto fn = (Ret(__thiscall *)(Args...)) p.get();
108 | return fn(std::forward(a)...);
109 | }
110 |
111 | // Call function at the index @i from the vtable of the object @a[0]
112 | template
113 | static Ret vtbl(Args... a)
114 | {
115 | auto obj = raw_ptr(std::get<0>(std::forward_as_tuple(a...)));
116 | auto p = raw_ptr( (*obj.template get()) [i] );
117 | return call(p, std::forward(a)...);
118 | }
119 |
120 | template // Uses lazy pointer
121 | static Ret call(Args... a)
122 | {
123 | return call(lazy_pointer::get(), std::forward(a)...);
124 | }
125 | };
126 | }
127 |
128 |
--------------------------------------------------------------------------------
/include/injector/gvm/gvm.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Injectors - Base Header
3 | *
4 | * Copyright (C) 2012-2014 LINK/2012
5 | *
6 | * This software is provided 'as-is', without any express or implied
7 | * warranty. In no event will the authors be held liable for any damages
8 | * arising from the use of this software.
9 | *
10 | * Permission is granted to anyone to use this software for any purpose,
11 | * including commercial applications, and to alter it and redistribute it
12 | * freely, subject to the following restrictions:
13 | *
14 | * 1. The origin of this software must not be misrepresented; you must not
15 | * claim that you wrote the original software. If you use this software
16 | * in a product, an acknowledgment in the product documentation would be
17 | * appreciated but is not required.
18 | *
19 | * 2. Altered source versions must be plainly marked as such, and must not be
20 | * misrepresented as being the original software.
21 | *
22 | * 3. This notice may not be removed or altered from any source
23 | * distribution.
24 | *
25 | */
26 | #pragma once
27 | #include
28 | #include
29 | #include
30 |
31 | namespace injector
32 | {
33 |
34 | #if 1 // GVM and Address Translator, Not very interesting for the users, so skip reading those...
35 |
36 | /*
37 | * game_version_manager
38 | * Detects the game, the game version and the game region
39 | * This assumes the executable is decrypted, so, Silent's ASI Loader is recommended.
40 | */
41 | #ifndef INJECTOR_OWN_GVM
42 | #ifndef INJECTOR_GVM_DUMMY
43 | class game_version_manager
44 | {
45 | public:
46 | // Set this if you would like that MessagesBox contain PluginName as caption
47 | const char* PluginName;
48 |
49 | private:
50 | char game, region, major, minor, majorRevision, minorRevision, cracker, steam;
51 |
52 | public:
53 | game_version_manager()
54 | {
55 | #ifdef INJECTOR_GVM_PLUGIN_NAME
56 | PluginName = INJECTOR_GVM_PLUGIN_NAME;
57 | #else
58 | PluginName = "Plugin-SDK Plugin";
59 | #endif
60 |
61 | this->Clear();
62 | }
63 |
64 |
65 | // Clear any information about game version
66 | void Clear()
67 | {
68 | game = region = major = minor = majorRevision = minorRevision = cracker = steam = 0;
69 | }
70 |
71 | // Checks if I don't know the game we are attached to
72 | bool IsUnknown() { return game == 0; }
73 | // Checks if this is the steam version
74 | bool IsSteam() { return steam != 0; }
75 | // Gets the game we are attached to (0, '3', 'V', 'S', 'I', 'E')
76 | char GetGame() { return game; }
77 | // Gets the region from the game we are attached to (0, 'U', 'E');
78 | char GetRegion() { return region; }
79 | // Get major and minor version of the game (e.g. [major = 1, minor = 0] = 1.0)
80 | int GetMajorVersion() { return major; }
81 | int GetMinorVersion() { return minor; }
82 | int GetMajorRevisionVersion() { return majorRevision; }
83 | int GetMinorRevisionVersion() { return minorRevision; }
84 |
85 | bool IsHoodlum() { return cracker == 'H'; }
86 |
87 | // Region conditions
88 | bool IsUS() { return region == 'U'; }
89 | bool IsEU() { return region == 'E'; }
90 |
91 | // Game Conditions
92 | bool IsIII() { return game == '3'; }
93 | bool IsVC () { return game == 'V'; }
94 | bool IsSA () { return game == 'S'; }
95 | bool IsIV () { return game == 'I'; }
96 | bool IsEFLC(){ return game == 'E'; }
97 |
98 | // Detects game, region and version; returns false if could not detect it
99 | bool Detect();
100 |
101 | // Gets the game version as text, the buffer must contain at least 32 bytes of space.
102 | char* GetVersionText(char* buffer)
103 | {
104 | if(this->IsUnknown())
105 | {
106 | strcpy(buffer, "UNKNOWN GAME");
107 | return buffer;
108 | }
109 |
110 | const char* g = this->IsIII() ? "III" : this->IsVC() ? "VC" : this->IsSA() ? "SA" : this->IsIV() ? "IV" : this->IsEFLC() ? "EFLC" : "UNK";
111 | const char* r = this->IsUS()? "US" : this->IsEU()? "EURO" : "UNK_REGION";
112 | const char* s = this->IsSteam()? "Steam" : "";
113 | sprintf(buffer, "GTA %s %d.%d.%d.%d %s%s", g, major, minor, majorRevision, minorRevision, r, s);
114 | return buffer;
115 | }
116 |
117 |
118 | public:
119 | // Raises a error saying that you could not detect the game version
120 | void RaiseCouldNotDetect()
121 | {
122 | MessageBoxA(0,
123 | "Could not detect the game version\nContact the mod creator!",
124 | PluginName, MB_ICONERROR
125 | );
126 | }
127 |
128 | // Raises a error saying that the exe version is incompatible (and output the exe name)
129 | void RaiseIncompatibleVersion()
130 | {
131 | char buf[128], v[32];
132 | sprintf(buf,
133 | "An incompatible exe version has been detected! (%s)\nContact the mod creator!",
134 | GetVersionText(v)
135 | );
136 | MessageBoxA(0, buf, PluginName, MB_ICONERROR);
137 | }
138 | };
139 | #else // INJECTOR_GVM_DUMMY
140 | class game_version_manager
141 | {
142 | public:
143 | bool Detect() { return true; }
144 | };
145 | #endif // INJECTOR_GVM_DUMMY
146 | #endif // INJECTOR_OWN_GVM
147 |
148 |
149 | /*
150 | * address_manager
151 | * Address translator from 1.0 executables to other executables offsets
152 | * Inherits from game_version_manager ;)
153 | */
154 | class address_manager : public game_version_manager
155 | {
156 | private:
157 | address_manager()
158 | {
159 | this->Detect();
160 | }
161 |
162 | // You could implement your translator for the address your plugin uses
163 | // If not implemented, the translator won't translate anything, just return the samething as before
164 | #ifdef INJECTOR_GVM_HAS_TRANSLATOR
165 | void* translator(void* p);
166 | #else
167 | void* translator(void* p) { return p; }
168 | #endif
169 |
170 | public:
171 | // Translates address p to the running executable pointer
172 | void* translate(void* p)
173 | {
174 | return translator(p);
175 | }
176 |
177 |
178 | public:
179 | // Address manager singleton
180 | static address_manager& singleton()
181 | {
182 | static address_manager m;
183 | return m;
184 | }
185 |
186 | // Static version of translate()
187 | static void* translate_address(void* p)
188 | {
189 | return singleton().translate(p);
190 | }
191 |
192 | //
193 | static void set_name(const char* modname)
194 | {
195 | singleton().PluginName = modname;
196 | }
197 |
198 | public:
199 | // Functors for memory translation:
200 |
201 | // Translates aslr translator
202 | struct fn_mem_translator_aslr
203 | {
204 | void* operator()(void* p) const
205 | {
206 | static uintptr_t module = (uintptr_t)GetModuleHandle(NULL);
207 | return (void*)((uintptr_t)(p)-(0x400000 - module));
208 | }
209 | };
210 |
211 | // Translates nothing translator
212 | struct fn_mem_translator_nop
213 | {
214 | void* operator()(void* p) const
215 | { return p; }
216 | };
217 |
218 | // Real translator
219 | struct fn_mem_translator
220 | {
221 | void* operator()(void* p) const
222 | { return translate_address(p); }
223 | };
224 | };
225 |
226 | #endif // #if 1
227 |
228 |
229 | }
--------------------------------------------------------------------------------
/include/injector/gvm/translator.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Injectors - Address Translation Management
3 | *
4 | * Copyright (C) 2014 LINK/2012
5 | *
6 | * This software is provided 'as-is', without any express or implied
7 | * warranty. In no event will the authors be held liable for any damages
8 | * arising from the use of this software.
9 | *
10 | * Permission is granted to anyone to use this software for any purpose,
11 | * including commercial applications, and to alter it and redistribute it
12 | * freely, subject to the following restrictions:
13 | *
14 | * 1. The origin of this software must not be misrepresented; you must not
15 | * claim that you wrote the original software. If you use this software
16 | * in a product, an acknowledgment in the product documentation would be
17 | * appreciated but is not required.
18 | *
19 | * 2. Altered source versions must be plainly marked as such, and must not be
20 | * misrepresented as being the original software.
21 | *
22 | * 3. This notice may not be removed or altered from any source
23 | * distribution.
24 | *
25 | */
26 | #pragma once
27 |
28 | #if !defined(INJECTOR_GVM_HAS_TRANSLATOR)
29 | #error Missing INJECTOR_GVM_HAS_TRANSLATOR on compiler definitions
30 | #endif
31 |
32 | /*
33 | * This is a quick solution for address translations if you're too lazy to implement a proper address_manager::translator by yourself
34 | * So, just call address_translator_manager::singleton().translate(p) from your address_manager::translator and that's it.
35 | * It'll translate addresses based on 'address_translator' objects, when one gets constructed it turns into a possible translator.
36 | * At the constructor of your derived 'address_translator' make the map object to have [addr_to_translate] = translated_addr;
37 | * There's also the virtual method 'fallback' that will get called when the translation wasn't possible, you can do some fallback stuff here
38 | * (such as return the pointer as is or output a error message)
39 | */
40 |
41 | #include "../injector.hpp"
42 | #include
43 | #include