├── .github
└── workflows
│ └── build-check.yml
├── .gitignore
├── LICENSE
├── README.md
├── TempleWare-External.sln
├── TempleWare-External
├── TempleWare-External.filters
├── TempleWare-External.vcxproj
├── external
│ ├── imgui
│ │ ├── imconfig.h
│ │ ├── imgui.cpp
│ │ ├── imgui.h
│ │ ├── imgui_demo.cpp
│ │ ├── imgui_draw.cpp
│ │ ├── imgui_impl_dx9.cpp
│ │ ├── imgui_impl_dx9.h
│ │ ├── imgui_impl_win32.cpp
│ │ ├── imgui_impl_win32.h
│ │ ├── imgui_internal.h
│ │ ├── imgui_tables.cpp
│ │ ├── imgui_widgets.cpp
│ │ ├── imstb_rectpack.h
│ │ ├── imstb_textedit.h
│ │ └── imstb_truetype.h
│ └── json
│ │ └── json.hpp
└── source
│ ├── config
│ └── config.h
│ ├── features
│ ├── bhop.cpp
│ ├── bhop.h
│ ├── fov.cpp
│ ├── fov.h
│ ├── glow.cpp
│ ├── glow.h
│ ├── noflash.cpp
│ ├── noflash.h
│ ├── triggerbot.cpp
│ └── triggerbot.h
│ ├── globals
│ └── globals.h
│ ├── main.cpp
│ ├── memory
│ └── memory.h
│ ├── menu
│ ├── menu.cpp
│ └── menu.h
│ ├── offsets
│ ├── offsets.cpp
│ └── offsets.h
│ └── threads
│ ├── threads.cpp
│ └── threads.h
└── github
└── images
├── logo.png
├── menu.png
└── showcase.png
/.github/workflows/build-check.yml:
--------------------------------------------------------------------------------
1 | name: build-check x64 release
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | build:
11 | runs-on: windows-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v4
15 |
16 | - name: Setup MSVC
17 | uses: ilammy/msvc-dev-cmd@v1
18 |
19 | - name: Building project
20 | run: |
21 | msbuild TempleWare-External.sln -t:Rebuild -p:Configuration=Release -p:Platform=x64
22 |
23 | - name: Archive artifacts
24 | uses: actions/upload-artifact@v4
25 | with:
26 | name: Compiled-Binaries
27 | path: |
28 | D:\a\TempleWare-External\x64\Release\TempleWare-External.exe
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *psd
10 | old/
11 | built/
12 | *.user
13 | *.userosscache
14 | *.sln.docstates
15 | stable_release/
16 | # User-specific files (MonoDevelop/Xamarin Studio)
17 | *.userprefs
18 |
19 | # Mono auto generated files
20 | mono_crash.*
21 |
22 | # Build results
23 | [Dd]ebug/
24 | [Dd]ebugPublic/
25 | [Rr]elease/
26 | [Rr]eleases/
27 | x64/
28 | x86/
29 | [Ww][Ii][Nn]32/
30 | [Aa][Rr][Mm]/
31 | [Aa][Rr][Mm]64/
32 | bld/
33 | [Bb]in/
34 | [Oo]bj/
35 | bu/
36 | #The Blow-Eagle stealer console/dependencies/
37 | Images-GitHub/logo.psd
38 | [Ll]og/
39 | [Ll]ogs/
40 |
41 | # Visual Studio 2015/2017 cache/options directory
42 | .vs/
43 | # Uncomment if you have tasks that create the project's static files in wwwroot
44 | #wwwroot/
45 |
46 | # Visual Studio 2017 auto generated files
47 | Generated\ Files/
48 |
49 | # MSTest test Results
50 | [Tt]est[Rr]esult*/
51 | [Bb]uild[Ll]og.*
52 |
53 | # NUnit
54 | *.VisualState.xml
55 | TestResult.xml
56 | nunit-*.xml
57 |
58 | # Build Results of an ATL Project
59 | [Dd]ebugPS/
60 | [Rr]eleasePS/
61 | dlldata.c
62 |
63 | # Benchmark Results
64 | BenchmarkDotNet.Artifacts/
65 |
66 | # .NET Core
67 | project.lock.json
68 | project.fragment.lock.json
69 | artifacts/
70 |
71 | # ASP.NET Scaffolding
72 | ScaffoldingReadMe.txt
73 |
74 | # StyleCop
75 | StyleCopReport.xml
76 |
77 | # Files built by Visual Studio
78 | *_i.c
79 | *_p.c
80 | *_h.h
81 | *.ilk
82 | *.meta
83 | *.obj
84 | *.iobj
85 | *.pch
86 | *.pdb
87 | *.ipdb
88 | *.pgc
89 | *.pgd
90 | *.rsp
91 | *.sbr
92 | *.tlb
93 | *.tli
94 | *.tlh
95 | *.tmp
96 | *.tmp_proj
97 | *_wpftmp.csproj
98 | *.log
99 | *.tlog
100 | *.vspscc
101 | *.vssscc
102 | .builds
103 | *.pidb
104 | *.svclog
105 | *.scc
106 |
107 | # Chutzpah Test files
108 | _Chutzpah*
109 |
110 | # Visual C++ cache files
111 | ipch/
112 | *.aps
113 | *.ncb
114 | *.opendb
115 | *.opensdf
116 | *.sdf
117 | *.cachefile
118 | *.VC.db
119 | *.VC.VC.opendb
120 |
121 | # Visual Studio profiler
122 | *.psess
123 | *.vsp
124 | *.vspx
125 | *.sap
126 |
127 | # Visual Studio Trace Files
128 | *.e2e
129 |
130 | # TFS 2012 Local Workspace
131 | $tf/
132 |
133 | # Guidance Automation Toolkit
134 | *.gpState
135 |
136 | # ReSharper is a .NET coding add-in
137 | _ReSharper*/
138 | *.[Rr]e[Ss]harper
139 | *.DotSettings.user
140 |
141 | # TeamCity is a build add-in
142 | _TeamCity*
143 |
144 | # DotCover is a Code Coverage Tool
145 | *.dotCover
146 |
147 | # AxoCover is a Code Coverage Tool
148 | .axoCover/*
149 | !.axoCover/settings.json
150 |
151 | # Coverlet is a free, cross platform Code Coverage Tool
152 | coverage*.json
153 | coverage*.xml
154 | coverage*.info
155 |
156 | # Visual Studio code coverage results
157 | *.coverage
158 | *.coveragexml
159 |
160 | # NCrunch
161 | _NCrunch_*
162 | .*crunch*.local.xml
163 | nCrunchTemp_*
164 |
165 | # MightyMoose
166 | *.mm.*
167 | AutoTest.Net/
168 |
169 | # Web workbench (sass)
170 | .sass-cache/
171 |
172 | # Installshield output folder
173 | [Ee]xpress/
174 |
175 | # DocProject is a documentation generator add-in
176 | DocProject/buildhelp/
177 | DocProject/Help/*.HxT
178 | DocProject/Help/*.HxC
179 | DocProject/Help/*.hhc
180 | DocProject/Help/*.hhk
181 | DocProject/Help/*.hhp
182 | DocProject/Help/Html2
183 | DocProject/Help/html
184 |
185 | # Click-Once directory
186 | publish/
187 |
188 | # Publish Web Output
189 | *.[Pp]ublish.xml
190 | *.azurePubxml
191 | # Note: Comment the next line if you want to checkin your web deploy settings,
192 | # but database connection strings (with potential passwords) will be unencrypted
193 | *.pubxml
194 | *.publishproj
195 |
196 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
197 | # checkin your Azure Web App publish settings, but sensitive information contained
198 | # in these scripts will be unencrypted
199 | PublishScripts/
200 |
201 | # NuGet Packages
202 | *.nupkg
203 | # NuGet Symbol Packages
204 | *.snupkg
205 | # The packages folder can be ignored because of Package Restore
206 | **/[Pp]ackages/*
207 | # except build/, which is used as an MSBuild target.
208 | !**/[Pp]ackages/build/
209 | # Uncomment if necessary however generally it will be regenerated when needed
210 | #!**/[Pp]ackages/repositories.config
211 | # NuGet v3's project.json files produces more ignorable files
212 | *.nuget.props
213 | *.nuget.targets
214 |
215 | # Microsoft Azure Build Output
216 | csx/
217 | *.build.csdef
218 |
219 | # Microsoft Azure Emulator
220 | ecf/
221 | rcf/
222 |
223 | # Windows Store app package directories and files
224 | AppPackages/
225 | BundleArtifacts/
226 | Package.StoreAssociation.xml
227 | _pkginfo.txt
228 | *.appx
229 | *.appxbundle
230 | *.appxupload
231 |
232 | # Visual Studio cache files
233 | # files ending in .cache can be ignored
234 | *.[Cc]ache
235 | # but keep track of directories ending in .cache
236 | !?*.[Cc]ache/
237 |
238 | # Others
239 | ClientBin/
240 | ~$*
241 | *~
242 | *.dbmdl
243 | *.dbproj.schemaview
244 | *.jfm
245 | *.pfx
246 | *.publishsettings
247 | orleans.codegen.cs
248 |
249 | # Including strong name files can present a security risk
250 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
251 | #*.snk
252 |
253 | # Since there are multiple workflows, uncomment next line to ignore bower_components
254 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
255 | #bower_components/
256 |
257 | # RIA/Silverlight projects
258 | Generated_Code/
259 |
260 | # Backup & report files from converting an old project file
261 | # to a newer Visual Studio version. Backup files are not needed,
262 | # because we have git ;-)
263 | _UpgradeReport_Files/
264 | Backup*/
265 | UpgradeLog*.XML
266 | UpgradeLog*.htm
267 | ServiceFabricBackup/
268 | *.rptproj.bak
269 |
270 | # SQL Server files
271 | *.mdf
272 | *.ldf
273 | *.ndf
274 |
275 | # Business Intelligence projects
276 | *.rdl.data
277 | *.bim.layout
278 | *.bim_*.settings
279 | *.rptproj.rsuser
280 | *- [Bb]ackup.rdl
281 | *- [Bb]ackup ([0-9]).rdl
282 | *- [Bb]ackup ([0-9][0-9]).rdl
283 |
284 | # Microsoft Fakes
285 | FakesAssemblies/
286 |
287 | # GhostDoc plugin setting file
288 | *.GhostDoc.xml
289 |
290 | # Node.js Tools for Visual Studio
291 | .ntvs_analysis.dat
292 | node_modules/
293 |
294 | # Visual Studio 6 build log
295 | *.plg
296 |
297 | # Visual Studio 6 workspace options file
298 | *.opt
299 |
300 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
301 | *.vbw
302 |
303 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
304 | *.vbp
305 |
306 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
307 | *.dsw
308 | *.dsp
309 |
310 | # Visual Studio 6 technical files
311 | *.ncb
312 | *.aps
313 |
314 | # Visual Studio LightSwitch build output
315 | **/*.HTMLClient/GeneratedArtifacts
316 | **/*.DesktopClient/GeneratedArtifacts
317 | **/*.DesktopClient/ModelManifest.xml
318 | **/*.Server/GeneratedArtifacts
319 | **/*.Server/ModelManifest.xml
320 | _Pvt_Extensions
321 |
322 | # Paket dependency manager
323 | .paket/paket.exe
324 | paket-files/
325 |
326 | # FAKE - F# Make
327 | .fake/
328 |
329 | # CodeRush personal settings
330 | .cr/personal
331 |
332 | # Python Tools for Visual Studio (PTVS)
333 | __pycache__/
334 | *.pyc
335 |
336 | # Cake - Uncomment if you are using it
337 | # tools/**
338 | # !tools/packages.config
339 |
340 | # Tabs Studio
341 | *.tss
342 |
343 | # Telerik's JustMock configuration file
344 | *.jmconfig
345 |
346 | # BizTalk build output
347 | *.btp.cs
348 | *.btm.cs
349 | *.odx.cs
350 | *.xsd.cs
351 |
352 | # OpenCover UI analysis results
353 | OpenCover/
354 |
355 | # Azure Stream Analytics local run output
356 | ASALocalRun/
357 |
358 | # MSBuild Binary and Structured Log
359 | *.binlog
360 |
361 | # NVidia Nsight GPU debugger configuration file
362 | *.nvuser
363 |
364 | # MFractors (Xamarin productivity tool) working folder
365 | .mfractor/
366 |
367 | # Local History for Visual Studio
368 | .localhistory/
369 |
370 | # Visual Studio History (VSHistory) files
371 | .vshistory/
372 |
373 | # BeatPulse healthcheck temp database
374 | healthchecksdb
375 |
376 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
377 | MigrationBackup/
378 |
379 | # Ionide (cross platform F# VS Code tools) working folder
380 | .ionide/
381 |
382 | # Fody - auto-generated XML schema
383 | FodyWeavers.xsd
384 |
385 | # VS Code files for those working on multiple tools
386 | .vscode/*
387 | !.vscode/settings.json
388 | !.vscode/tasks.json
389 | !.vscode/launch.json
390 | !.vscode/extensions.json
391 | *.code-workspace
392 |
393 | # Local History for Visual Studio Code
394 | .history/
395 |
396 | # Windows Installer files from build outputs
397 | *.cab
398 | *.msi
399 | *.msix
400 | *.msm
401 | *.msp
402 |
403 | # JetBrains Rider
404 | *.sln.iml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Temple Enterprise LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ---
18 | ### TempleWare-External is a free C++-based external cheat for Counter-Strike 2.
19 | ---
20 |
21 | ### How to Build and Launch TempleWare-External
22 |
23 | 1. **Build the Executable:**
24 | - Open the project in Visual Studio.
25 | - Set the build configuration to **Release x64**.
26 | - Build the solution (`Build` > `Build Solution`).
27 | - Find the `TempleWare-External.exe` in the `\Release\x64\` folder.
28 |
29 | 2. **Run the Executable:**
30 | - Double-click the `TempleWare-External` file to launch it.
31 | - The tool will handle any necessary processes automatically.
32 |
33 | 3. **Play CS2:**
34 | - Launch `Counter-Strike 2` and start using TempleWare.
35 | - Use the `END` key to open the menu.
36 |
37 | ---
38 |
39 | ## Screenshots
40 |
41 | | Description | Image |
42 | |-------------|-------|
43 | | **Showcase** |
|
44 | | **Menu** |
|
45 |
46 |
47 |
--------------------------------------------------------------------------------
/TempleWare-External.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34728.123
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TempleWare-External", "TempleWare-External\TempleWare-External.vcxproj", "{19813B60-BD94-432A-A3B7-2A807D1A6DAF}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Debug|x64.ActiveCfg = Debug|x64
17 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Debug|x64.Build.0 = Debug|x64
18 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Debug|x86.ActiveCfg = Debug|Win32
19 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Debug|x86.Build.0 = Debug|Win32
20 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Release|x64.ActiveCfg = Release|x64
21 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Release|x64.Build.0 = Release|x64
22 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Release|x86.ActiveCfg = Release|Win32
23 | {19813B60-BD94-432A-A3B7-2A807D1A6DAF}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {704E2506-2A6E-4D2B-8D77-43B9F120E6D0}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/TempleWare-External/TempleWare-External.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Source Files
35 |
36 |
37 | Source Files
38 |
39 |
40 | Source Files
41 |
42 |
43 | Source Files
44 |
45 |
46 | Source Files
47 |
48 |
49 | Source Files
50 |
51 |
52 | Source Files
53 |
54 |
55 | Source Files
56 |
57 |
58 | Source Files
59 |
60 |
61 | Source Files
62 |
63 |
64 |
65 |
66 | Header Files
67 |
68 |
69 | Header Files
70 |
71 |
72 | Header Files
73 |
74 |
75 | Header Files
76 |
77 |
78 | Header Files
79 |
80 |
81 | Header Files
82 |
83 |
84 | Header Files
85 |
86 |
87 | Header Files
88 |
89 |
90 | Header Files
91 |
92 |
93 | Header Files
94 |
95 |
96 | Header Files
97 |
98 |
99 | Header Files
100 |
101 |
102 | Header Files
103 |
104 |
105 | Header Files
106 |
107 |
108 | Header Files
109 |
110 |
111 | Header Files
112 |
113 |
114 |
--------------------------------------------------------------------------------
/TempleWare-External/TempleWare-External.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 17.0
23 | Win32Proj
24 | {19813b60-bd94-432a-a3b7-2a807d1a6daf}
25 | TempleWare-External
26 | 10.0
27 |
28 |
29 |
30 | Application
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | Application
37 | false
38 | v143
39 | true
40 | MultiByte
41 |
42 |
43 | Application
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | Application
50 | false
51 | v143
52 | true
53 | MultiByte
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | external\json;$(IncludePath)
75 |
76 |
77 |
78 | Level3
79 | true
80 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
81 | true
82 |
83 |
84 | Console
85 | true
86 |
87 |
88 |
89 |
90 | Level3
91 | true
92 | true
93 | true
94 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
95 | true
96 | stdcpp20
97 |
98 |
99 | Windows
100 | true
101 | true
102 | true
103 | d3d9.lib;%(AdditionalDependencies)
104 |
105 |
106 |
107 |
108 | Level3
109 | true
110 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
111 | true
112 |
113 |
114 | Console
115 | true
116 |
117 |
118 |
119 |
120 | Level3
121 | true
122 | true
123 | true
124 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
125 | true
126 | stdcpp20
127 |
128 |
129 | Windows
130 | true
131 | true
132 | true
133 | d3d9.lib;%(AdditionalDependencies)
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/TempleWare-External/external/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 |
32 | //---- Disable all of Dear ImGui or don't implement standard windows.
33 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
34 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
35 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
36 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
37 |
38 | //---- Don't implement some functions to reduce linkage requirements.
39 | //#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)
40 | //#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)
41 | //#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)
42 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
43 | //#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).
44 | //#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)
45 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
46 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
47 | //#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.
48 | //#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().
49 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
50 |
51 | //---- Include imgui_user.h at the end of imgui.h as a convenience
52 | //#define IMGUI_INCLUDE_IMGUI_USER_H
53 |
54 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
55 | //#define IMGUI_USE_BGRA_PACKED_COLOR
56 |
57 | //---- 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...)
58 | //#define IMGUI_USE_WCHAR32
59 |
60 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
61 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
62 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
63 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
64 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
65 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
66 |
67 | //---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
68 | // Requires 'stb_sprintf.h' to be available in the include path. 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.
69 | // #define IMGUI_USE_STB_SPRINTF
70 |
71 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
72 | // 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).
73 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
74 | //#define IMGUI_ENABLE_FREETYPE
75 |
76 | //---- Use stb_truetype to build and rasterize the font atlas (default)
77 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
78 | //#define IMGUI_ENABLE_STB_TRUETYPE
79 |
80 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
81 | // This will be inlined as part of ImVec2 and ImVec4 class declarations.
82 | /*
83 | #define IM_VEC2_CLASS_EXTRA \
84 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
85 | operator MyVec2() const { return MyVec2(x,y); }
86 |
87 | #define IM_VEC4_CLASS_EXTRA \
88 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
89 | operator MyVec4() const { return MyVec4(x,y,z,w); }
90 | */
91 |
92 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
93 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
94 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
95 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
96 | //#define ImDrawIdx unsigned int
97 |
98 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
99 | //struct ImDrawList;
100 | //struct ImDrawCmd;
101 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
102 | //#define ImDrawCallback MyImDrawCallback
103 |
104 | //---- Debug Tools: Macro to break in Debugger
105 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
106 | //#define IM_DEBUG_BREAK IM_ASSERT(0)
107 | //#define IM_DEBUG_BREAK __debugbreak()
108 |
109 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
110 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
111 | // This adds a small runtime cost which is why it is not enabled by default.
112 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
113 |
114 | //---- Debug Tools: Enable slower asserts
115 | //#define IMGUI_DEBUG_PARANOID
116 |
117 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
118 | /*
119 | namespace ImGui
120 | {
121 | void MyFunction(const char* name, const MyMatrix44& v);
122 | }
123 | */
124 |
--------------------------------------------------------------------------------
/TempleWare-External/external/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(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)
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 |
--------------------------------------------------------------------------------
/TempleWare-External/external/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 |
--------------------------------------------------------------------------------
/TempleWare-External/external/imgui/imgui_impl_win32.cpp:
--------------------------------------------------------------------------------
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: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
9 |
10 | // 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 | #include "imgui.h"
16 | #include "imgui_impl_win32.h"
17 | #ifndef WIN32_LEAN_AND_MEAN
18 | #define WIN32_LEAN_AND_MEAN
19 | #endif
20 | #include
21 | #include
22 | #include
23 |
24 | // Configuration flags to add in your imconfig.h file:
25 | //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
26 |
27 | // Using XInput for gamepad (will load DLL dynamically)
28 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
29 | #include
30 | typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
31 | typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
32 | #endif
33 |
34 | // CHANGELOG
35 | // (minor and older changes stripped away, please see git history for details)
36 | // 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
37 | // 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host windo doesn't have focus.
38 | // 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAVE events).
39 | // 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).
40 | // 2021-06-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_GetDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per-monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1).
41 | // 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
42 | // 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
43 | // 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
44 | // 2021-01-25: Inputs: Dynamically loading XInput DLL.
45 | // 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed.
46 | // 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs)
47 | // 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions.
48 | // 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT.
49 | // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
50 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
51 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent.
52 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages.
53 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
54 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
55 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
56 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
57 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples.
58 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag.
59 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
60 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
61 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
62 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
63 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
64 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert.
65 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
66 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
67 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
68 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set.
69 |
70 | struct ImGui_ImplWin32_Data
71 | {
72 | HWND hWnd;
73 | HWND MouseHwnd;
74 | bool MouseTracked;
75 | INT64 Time;
76 | INT64 TicksPerSecond;
77 | ImGuiMouseCursor LastMouseCursor;
78 | bool HasGamepad;
79 | bool WantUpdateHasGamepad;
80 |
81 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
82 | HMODULE XInputDLL;
83 | PFN_XInputGetCapabilities XInputGetCapabilities;
84 | PFN_XInputGetState XInputGetState;
85 | #endif
86 |
87 | ImGui_ImplWin32_Data() { memset(this, 0, sizeof(*this)); }
88 | };
89 |
90 | // Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
91 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
92 | // FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
93 | // FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
94 | static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
95 | {
96 | return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : NULL;
97 | }
98 |
99 | // Functions
100 | bool ImGui_ImplWin32_Init(void* hwnd)
101 | {
102 | ImGuiIO& io = ImGui::GetIO();
103 | IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
104 |
105 | INT64 perf_frequency, perf_counter;
106 | if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency))
107 | return false;
108 | if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter))
109 | return false;
110 |
111 | // Setup backend capabilities flags
112 | ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)();
113 | io.BackendPlatformUserData = (void*)bd;
114 | io.BackendPlatformName = "imgui_impl_win32";
115 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
116 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
117 |
118 | bd->hWnd = (HWND)hwnd;
119 | bd->WantUpdateHasGamepad = true;
120 | bd->TicksPerSecond = perf_frequency;
121 | bd->Time = perf_counter;
122 | bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
123 |
124 | io.ImeWindowHandle = hwnd;
125 |
126 | // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
127 | io.KeyMap[ImGuiKey_Tab] = VK_TAB;
128 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
129 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
130 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
131 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
132 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
133 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
134 | io.KeyMap[ImGuiKey_Home] = VK_HOME;
135 | io.KeyMap[ImGuiKey_End] = VK_END;
136 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
137 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
138 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
139 | io.KeyMap[ImGuiKey_Space] = VK_SPACE;
140 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
141 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
142 | io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
143 | io.KeyMap[ImGuiKey_A] = 'A';
144 | io.KeyMap[ImGuiKey_C] = 'C';
145 | io.KeyMap[ImGuiKey_V] = 'V';
146 | io.KeyMap[ImGuiKey_X] = 'X';
147 | io.KeyMap[ImGuiKey_Y] = 'Y';
148 | io.KeyMap[ImGuiKey_Z] = 'Z';
149 |
150 | // Dynamically load XInput library
151 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
152 | const char* xinput_dll_names[] =
153 | {
154 | "xinput1_4.dll", // Windows 8+
155 | "xinput1_3.dll", // DirectX SDK
156 | "xinput9_1_0.dll", // Windows Vista, Windows 7
157 | "xinput1_2.dll", // DirectX SDK
158 | "xinput1_1.dll" // DirectX SDK
159 | };
160 | for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
161 | if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
162 | {
163 | bd->XInputDLL = dll;
164 | bd->XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities");
165 | bd->XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState");
166 | break;
167 | }
168 | #endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
169 |
170 | return true;
171 | }
172 |
173 | void ImGui_ImplWin32_Shutdown()
174 | {
175 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
176 | IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
177 | ImGuiIO& io = ImGui::GetIO();
178 |
179 | // Unload XInput library
180 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
181 | if (bd->XInputDLL)
182 | ::FreeLibrary(bd->XInputDLL);
183 | #endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
184 |
185 | io.BackendPlatformName = NULL;
186 | io.BackendPlatformUserData = NULL;
187 | IM_DELETE(bd);
188 | }
189 |
190 | static bool ImGui_ImplWin32_UpdateMouseCursor()
191 | {
192 | ImGuiIO& io = ImGui::GetIO();
193 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
194 | return false;
195 |
196 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
197 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
198 | {
199 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
200 | ::SetCursor(NULL);
201 | }
202 | else
203 | {
204 | // Show OS mouse cursor
205 | LPTSTR win32_cursor = IDC_ARROW;
206 | switch (imgui_cursor)
207 | {
208 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
209 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
210 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
211 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
212 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
213 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
214 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
215 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
216 | case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
217 | }
218 | ::SetCursor(::LoadCursor(NULL, win32_cursor));
219 | }
220 | return true;
221 | }
222 |
223 | static void ImGui_ImplWin32_UpdateMousePos()
224 | {
225 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
226 | ImGuiIO& io = ImGui::GetIO();
227 | IM_ASSERT(bd->hWnd != 0);
228 |
229 | const ImVec2 mouse_pos_prev = io.MousePos;
230 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
231 |
232 | // Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
233 | HWND focused_window = ::GetForegroundWindow();
234 | HWND hovered_window = bd->MouseHwnd;
235 | HWND mouse_window = NULL;
236 | if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd)))
237 | mouse_window = hovered_window;
238 | else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd)))
239 | mouse_window = focused_window;
240 | if (mouse_window == NULL)
241 | return;
242 |
243 | // Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
244 | if (io.WantSetMousePos)
245 | {
246 | POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y };
247 | if (::ClientToScreen(bd->hWnd, &pos))
248 | ::SetCursorPos(pos.x, pos.y);
249 | }
250 |
251 | // Set Dear ImGui mouse position from OS position
252 | POINT pos;
253 | if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos))
254 | io.MousePos = ImVec2((float)pos.x, (float)pos.y);
255 | }
256 |
257 | // Gamepad navigation mapping
258 | static void ImGui_ImplWin32_UpdateGamepads()
259 | {
260 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
261 | ImGuiIO& io = ImGui::GetIO();
262 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
263 | memset(io.NavInputs, 0, sizeof(io.NavInputs));
264 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
265 | return;
266 |
267 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
268 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
269 | if (bd->WantUpdateHasGamepad)
270 | {
271 | XINPUT_CAPABILITIES caps;
272 | bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
273 | bd->WantUpdateHasGamepad = false;
274 | }
275 |
276 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
277 | XINPUT_STATE xinput_state;
278 | if (bd->HasGamepad && bd->XInputGetState && bd->XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
279 | {
280 | const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
281 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
282 |
283 | #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
284 | #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
285 | MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
286 | MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
287 | MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
288 | MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
289 | MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
290 | MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
291 | MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
292 | MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
293 | MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
294 | MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
295 | MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
296 | MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
297 | MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
298 | MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
299 | MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
300 | MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
301 | #undef MAP_BUTTON
302 | #undef MAP_ANALOG
303 | }
304 | #endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
305 | }
306 |
307 | void ImGui_ImplWin32_NewFrame()
308 | {
309 | ImGuiIO& io = ImGui::GetIO();
310 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
311 | IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWin32_Init()?");
312 |
313 | // Setup display size (every frame to accommodate for window resizing)
314 | RECT rect = { 0, 0, 0, 0 };
315 | ::GetClientRect(bd->hWnd, &rect);
316 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
317 |
318 | // Setup time step
319 | INT64 current_time = 0;
320 | ::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time);
321 | io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
322 | bd->Time = current_time;
323 |
324 | // Update OS mouse position
325 | ImGui_ImplWin32_UpdateMousePos();
326 |
327 | // Update OS mouse cursor with the cursor requested by imgui
328 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
329 | if (bd->LastMouseCursor != mouse_cursor)
330 | {
331 | bd->LastMouseCursor = mouse_cursor;
332 | ImGui_ImplWin32_UpdateMouseCursor();
333 | }
334 |
335 | // Update game controllers (if enabled and available)
336 | ImGui_ImplWin32_UpdateGamepads();
337 | }
338 |
339 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
340 | #ifndef WM_MOUSEHWHEEL
341 | #define WM_MOUSEHWHEEL 0x020E
342 | #endif
343 | #ifndef DBT_DEVNODES_CHANGED
344 | #define DBT_DEVNODES_CHANGED 0x0007
345 | #endif
346 |
347 | // Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
348 | // Call from your application's message handler.
349 | // When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
350 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
351 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
352 | // Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
353 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
354 | // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
355 | #if 0
356 | // Copy this line into your .cpp file to forward declare the function.
357 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
358 | #endif
359 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
360 | {
361 | if (ImGui::GetCurrentContext() == NULL)
362 | return 0;
363 |
364 | ImGuiIO& io = ImGui::GetIO();
365 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
366 |
367 | switch (msg)
368 | {
369 | case WM_MOUSEMOVE:
370 | // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
371 | bd->MouseHwnd = hwnd;
372 | if (!bd->MouseTracked)
373 | {
374 | TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 };
375 | ::TrackMouseEvent(&tme);
376 | bd->MouseTracked = true;
377 | }
378 | break;
379 | case WM_MOUSELEAVE:
380 | if (bd->MouseHwnd == hwnd)
381 | bd->MouseHwnd = NULL;
382 | bd->MouseTracked = false;
383 | break;
384 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
385 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
386 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
387 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
388 | {
389 | int button = 0;
390 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
391 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
392 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
393 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
394 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
395 | ::SetCapture(hwnd);
396 | io.MouseDown[button] = true;
397 | return 0;
398 | }
399 | case WM_LBUTTONUP:
400 | case WM_RBUTTONUP:
401 | case WM_MBUTTONUP:
402 | case WM_XBUTTONUP:
403 | {
404 | int button = 0;
405 | if (msg == WM_LBUTTONUP) { button = 0; }
406 | if (msg == WM_RBUTTONUP) { button = 1; }
407 | if (msg == WM_MBUTTONUP) { button = 2; }
408 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
409 | io.MouseDown[button] = false;
410 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
411 | ::ReleaseCapture();
412 | return 0;
413 | }
414 | case WM_MOUSEWHEEL:
415 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
416 | return 0;
417 | case WM_MOUSEHWHEEL:
418 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
419 | return 0;
420 | case WM_KEYDOWN:
421 | case WM_KEYUP:
422 | case WM_SYSKEYDOWN:
423 | case WM_SYSKEYUP:
424 | {
425 | bool down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
426 | if (wParam < 256)
427 | io.KeysDown[wParam] = down;
428 | if (wParam == VK_CONTROL)
429 | io.KeyCtrl = down;
430 | if (wParam == VK_SHIFT)
431 | io.KeyShift = down;
432 | if (wParam == VK_MENU)
433 | io.KeyAlt = down;
434 | return 0;
435 | }
436 | case WM_SETFOCUS:
437 | case WM_KILLFOCUS:
438 | io.AddFocusEvent(msg == WM_SETFOCUS);
439 | return 0;
440 | case WM_CHAR:
441 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
442 | if (wParam > 0 && wParam < 0x10000)
443 | io.AddInputCharacterUTF16((unsigned short)wParam);
444 | return 0;
445 | case WM_SETCURSOR:
446 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
447 | return 1;
448 | return 0;
449 | case WM_DEVICECHANGE:
450 | if ((UINT)wParam == DBT_DEVNODES_CHANGED)
451 | bd->WantUpdateHasGamepad = true;
452 | return 0;
453 | }
454 | return 0;
455 | }
456 |
457 |
458 | //--------------------------------------------------------------------------------------------------------
459 | // DPI-related helpers (optional)
460 | //--------------------------------------------------------------------------------------------------------
461 | // - Use to enable DPI awareness without having to create an application manifest.
462 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
463 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
464 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
465 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
466 | //---------------------------------------------------------------------------------------------------------
467 | // This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable.
468 | // ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically.
469 | // If you are trying to implement your own backend for your own engine, you may ignore that noise.
470 | //---------------------------------------------------------------------------------------------------------
471 |
472 | // Perform our own check with RtlVerifyVersionInfo() instead of using functions from as they
473 | // require a manifest to be functional for checks above 8.1. See https://github.com/ocornut/imgui/issues/4200
474 | static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
475 | {
476 | typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
477 | static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = NULL;
478 | if (RtlVerifyVersionInfoFn == NULL)
479 | if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
480 | RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
481 | if (RtlVerifyVersionInfoFn == NULL)
482 | return FALSE;
483 |
484 | RTL_OSVERSIONINFOEXW versionInfo = { };
485 | ULONGLONG conditionMask = 0;
486 | versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
487 | versionInfo.dwMajorVersion = major;
488 | versionInfo.dwMinorVersion = minor;
489 | VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
490 | VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
491 | return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
492 | }
493 |
494 | #define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
495 | #define _IsWindows8OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8
496 | #define _IsWindows8Point1OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE
497 | #define _IsWindows10OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WINTHRESHOLD / _WIN32_WINNT_WIN10
498 |
499 | #ifndef DPI_ENUMS_DECLARED
500 | typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
501 | typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE;
502 | #endif
503 | #ifndef _DPI_AWARENESS_CONTEXTS_
504 | DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
505 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3
506 | #endif
507 | #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
508 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
509 | #endif
510 | typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
511 | typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
512 | typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
513 |
514 | // Helper function to enable DPI awareness without setting up a manifest
515 | void ImGui_ImplWin32_EnableDpiAwareness()
516 | {
517 | if (_IsWindows10OrGreater())
518 | {
519 | static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
520 | if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
521 | {
522 | SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
523 | return;
524 | }
525 | }
526 | if (_IsWindows8Point1OrGreater())
527 | {
528 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
529 | if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
530 | {
531 | SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE);
532 | return;
533 | }
534 | }
535 | #if _WIN32_WINNT >= 0x0600
536 | ::SetProcessDPIAware();
537 | #endif
538 | }
539 |
540 | #if defined(_MSC_VER) && !defined(NOGDI)
541 | #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32'
542 | #endif
543 |
544 | float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
545 | {
546 | UINT xdpi = 96, ydpi = 96;
547 | if (_IsWindows8Point1OrGreater())
548 | {
549 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
550 | static PFN_GetDpiForMonitor GetDpiForMonitorFn = NULL;
551 | if (GetDpiForMonitorFn == NULL && shcore_dll != NULL)
552 | GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
553 | if (GetDpiForMonitorFn != NULL)
554 | {
555 | GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
556 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
557 | return xdpi / 96.0f;
558 | }
559 | }
560 | #ifndef NOGDI
561 | const HDC dc = ::GetDC(NULL);
562 | xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
563 | ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
564 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
565 | ::ReleaseDC(NULL, dc);
566 | #endif
567 | return xdpi / 96.0f;
568 | }
569 |
570 | float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
571 | {
572 | HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST);
573 | return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
574 | }
575 |
576 | //---------------------------------------------------------------------------------------------------------
577 | // Transparency related helpers (optional)
578 | //--------------------------------------------------------------------------------------------------------
579 |
580 | #if defined(_MSC_VER)
581 | #pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi'
582 | #endif
583 |
584 | // [experimental]
585 | // Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c
586 | // (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
587 | void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
588 | {
589 | if (!_IsWindowsVistaOrGreater())
590 | return;
591 |
592 | BOOL composition;
593 | if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition)
594 | return;
595 |
596 | BOOL opaque;
597 | DWORD color;
598 | if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
599 | {
600 | HRGN region = ::CreateRectRgn(0, 0, -1, -1);
601 | DWM_BLURBEHIND bb = {};
602 | bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
603 | bb.hRgnBlur = region;
604 | bb.fEnable = TRUE;
605 | ::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
606 | ::DeleteObject(region);
607 | }
608 | else
609 | {
610 | DWM_BLURBEHIND bb = {};
611 | bb.dwFlags = DWM_BB_ENABLE;
612 | ::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
613 | }
614 | }
615 |
616 | //---------------------------------------------------------------------------------------------------------
617 |
--------------------------------------------------------------------------------
/TempleWare-External/external/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: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
9 |
10 | // 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 | #if 0
26 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
27 | #endif
28 |
29 | // DPI-related helpers (optional)
30 | // - Use to enable DPI awareness without having to create an application manifest.
31 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
32 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
33 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
34 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
35 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
36 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
37 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
38 |
39 | // Transparency related helpers (optional) [experimental]
40 | // - Use to enable alpha compositing transparency with the desktop.
41 | // - Use together with e.g. clearing your framebuffer with zero-alpha.
42 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
43 |
--------------------------------------------------------------------------------
/TempleWare-External/external/imgui/imstb_rectpack.h:
--------------------------------------------------------------------------------
1 | // [DEAR IMGUI]
2 | // This is a slightly modified version of stb_rect_pack.h 1.00.
3 | // Those changes would need to be pushed into nothings/stb:
4 | // - Added STBRP__CDECL
5 | // Grep for [DEAR IMGUI] to find the changes.
6 |
7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing
8 | // Sean Barrett 2014
9 | //
10 | // Useful for e.g. packing rectangular textures into an atlas.
11 | // Does not do rotation.
12 | //
13 | // Not necessarily the awesomest packing method, but better than
14 | // the totally naive one in stb_truetype (which is primarily what
15 | // this is meant to replace).
16 | //
17 | // Has only had a few tests run, may have issues.
18 | //
19 | // More docs to come.
20 | //
21 | // No memory allocations; uses qsort() and assert() from stdlib.
22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT.
23 | //
24 | // This library currently uses the Skyline Bottom-Left algorithm.
25 | //
26 | // Please note: better rectangle packers are welcome! Please
27 | // implement them to the same API, but with a different init
28 | // function.
29 | //
30 | // Credits
31 | //
32 | // Library
33 | // Sean Barrett
34 | // Minor features
35 | // Martins Mozeiko
36 | // github:IntellectualKitty
37 | //
38 | // Bugfixes / warning fixes
39 | // Jeremy Jaussaud
40 | // Fabian Giesen
41 | //
42 | // Version history:
43 | //
44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
45 | // 0.99 (2019-02-07) warning fixes
46 | // 0.11 (2017-03-03) return packing success/fail result
47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings
48 | // 0.09 (2016-08-27) fix compiler warnings
49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
52 | // 0.05: added STBRP_ASSERT to allow replacing assert
53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support
54 | // 0.01: initial release
55 | //
56 | // LICENSE
57 | //
58 | // See end of file for license information.
59 |
60 | //////////////////////////////////////////////////////////////////////////////
61 | //
62 | // INCLUDE SECTION
63 | //
64 |
65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H
66 | #define STB_INCLUDE_STB_RECT_PACK_H
67 |
68 | #define STB_RECT_PACK_VERSION 1
69 |
70 | #ifdef STBRP_STATIC
71 | #define STBRP_DEF static
72 | #else
73 | #define STBRP_DEF extern
74 | #endif
75 |
76 | #ifdef __cplusplus
77 | extern "C" {
78 | #endif
79 |
80 | typedef struct stbrp_context stbrp_context;
81 | typedef struct stbrp_node stbrp_node;
82 | typedef struct stbrp_rect stbrp_rect;
83 |
84 | #ifdef STBRP_LARGE_RECTS
85 | typedef int stbrp_coord;
86 | #else
87 | typedef unsigned short stbrp_coord;
88 | #endif
89 |
90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
91 | // Assign packed locations to rectangles. The rectangles are of type
92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there
93 | // are 'num_rects' many of them.
94 | //
95 | // Rectangles which are successfully packed have the 'was_packed' flag
96 | // set to a non-zero value and 'x' and 'y' store the minimum location
97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left
98 | // if you imagine y increasing downwards). Rectangles which do not fit
99 | // have the 'was_packed' flag set to 0.
100 | //
101 | // You should not try to access the 'rects' array from another thread
102 | // while this function is running, as the function temporarily reorders
103 | // the array while it executes.
104 | //
105 | // To pack into another rectangle, you need to call stbrp_init_target
106 | // again. To continue packing into the same rectangle, you can call
107 | // this function again. Calling this multiple times with multiple rect
108 | // arrays will probably produce worse packing results than calling it
109 | // a single time with the full rectangle array, but the option is
110 | // available.
111 | //
112 | // The function returns 1 if all of the rectangles were successfully
113 | // packed and 0 otherwise.
114 |
115 | struct stbrp_rect
116 | {
117 | // reserved for your use:
118 | int id;
119 |
120 | // input:
121 | stbrp_coord w, h;
122 |
123 | // output:
124 | stbrp_coord x, y;
125 | int was_packed; // non-zero if valid packing
126 |
127 | }; // 16 bytes, nominally
128 |
129 |
130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
131 | // Initialize a rectangle packer to:
132 | // pack a rectangle that is 'width' by 'height' in dimensions
133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long
134 | //
135 | // You must call this function every time you start packing into a new target.
136 | //
137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for
138 | // the following stbrp_pack_rects() call (or calls), but can be freed after
139 | // the call (or calls) finish.
140 | //
141 | // Note: to guarantee best results, either:
142 | // 1. make sure 'num_nodes' >= 'width'
143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
144 | //
145 | // If you don't do either of the above things, widths will be quantized to multiples
146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage.
147 | //
148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm
149 | // may run out of temporary storage and be unable to pack some rectangles.
150 |
151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
152 | // Optionally call this function after init but before doing any packing to
153 | // change the handling of the out-of-temp-memory scenario, described above.
154 | // If you call init again, this will be reset to the default (false).
155 |
156 |
157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
158 | // Optionally select which packing heuristic the library should use. Different
159 | // heuristics will produce better/worse results for different data sets.
160 | // If you call init again, this will be reset to the default.
161 |
162 | enum
163 | {
164 | STBRP_HEURISTIC_Skyline_default=0,
165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
166 | STBRP_HEURISTIC_Skyline_BF_sortHeight
167 | };
168 |
169 |
170 | //////////////////////////////////////////////////////////////////////////////
171 | //
172 | // the details of the following structures don't matter to you, but they must
173 | // be visible so you can handle the memory allocations for them
174 |
175 | struct stbrp_node
176 | {
177 | stbrp_coord x,y;
178 | stbrp_node *next;
179 | };
180 |
181 | struct stbrp_context
182 | {
183 | int width;
184 | int height;
185 | int align;
186 | int init_mode;
187 | int heuristic;
188 | int num_nodes;
189 | stbrp_node *active_head;
190 | stbrp_node *free_head;
191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
192 | };
193 |
194 | #ifdef __cplusplus
195 | }
196 | #endif
197 |
198 | #endif
199 |
200 | //////////////////////////////////////////////////////////////////////////////
201 | //
202 | // IMPLEMENTATION SECTION
203 | //
204 |
205 | #ifdef STB_RECT_PACK_IMPLEMENTATION
206 | #ifndef STBRP_SORT
207 | #include
208 | #define STBRP_SORT qsort
209 | #endif
210 |
211 | #ifndef STBRP_ASSERT
212 | #include
213 | #define STBRP_ASSERT assert
214 | #endif
215 |
216 | // [DEAR IMGUI] Added STBRP__CDECL
217 | #ifdef _MSC_VER
218 | #define STBRP__NOTUSED(v) (void)(v)
219 | #define STBRP__CDECL __cdecl
220 | #else
221 | #define STBRP__NOTUSED(v) (void)sizeof(v)
222 | #define STBRP__CDECL
223 | #endif
224 |
225 | enum
226 | {
227 | STBRP__INIT_skyline = 1
228 | };
229 |
230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
231 | {
232 | switch (context->init_mode) {
233 | case STBRP__INIT_skyline:
234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
235 | context->heuristic = heuristic;
236 | break;
237 | default:
238 | STBRP_ASSERT(0);
239 | }
240 | }
241 |
242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
243 | {
244 | if (allow_out_of_mem)
245 | // if it's ok to run out of memory, then don't bother aligning them;
246 | // this gives better packing, but may fail due to OOM (even though
247 | // the rectangles easily fit). @TODO a smarter approach would be to only
248 | // quantize once we've hit OOM, then we could get rid of this parameter.
249 | context->align = 1;
250 | else {
251 | // if it's not ok to run out of memory, then quantize the widths
252 | // so that num_nodes is always enough nodes.
253 | //
254 | // I.e. num_nodes * align >= width
255 | // align >= width / num_nodes
256 | // align = ceil(width/num_nodes)
257 |
258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes;
259 | }
260 | }
261 |
262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
263 | {
264 | int i;
265 | #ifndef STBRP_LARGE_RECTS
266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
267 | #endif
268 |
269 | for (i=0; i < num_nodes-1; ++i)
270 | nodes[i].next = &nodes[i+1];
271 | nodes[i].next = NULL;
272 | context->init_mode = STBRP__INIT_skyline;
273 | context->heuristic = STBRP_HEURISTIC_Skyline_default;
274 | context->free_head = &nodes[0];
275 | context->active_head = &context->extra[0];
276 | context->width = width;
277 | context->height = height;
278 | context->num_nodes = num_nodes;
279 | stbrp_setup_allow_out_of_mem(context, 0);
280 |
281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
282 | context->extra[0].x = 0;
283 | context->extra[0].y = 0;
284 | context->extra[0].next = &context->extra[1];
285 | context->extra[1].x = (stbrp_coord) width;
286 | #ifdef STBRP_LARGE_RECTS
287 | context->extra[1].y = (1<<30);
288 | #else
289 | context->extra[1].y = 65535;
290 | #endif
291 | context->extra[1].next = NULL;
292 | }
293 |
294 | // find minimum y position if it starts at x1
295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
296 | {
297 | stbrp_node *node = first;
298 | int x1 = x0 + width;
299 | int min_y, visited_width, waste_area;
300 |
301 | STBRP__NOTUSED(c);
302 |
303 | STBRP_ASSERT(first->x <= x0);
304 |
305 | #if 0
306 | // skip in case we're past the node
307 | while (node->next->x <= x0)
308 | ++node;
309 | #else
310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
311 | #endif
312 |
313 | STBRP_ASSERT(node->x <= x0);
314 |
315 | min_y = 0;
316 | waste_area = 0;
317 | visited_width = 0;
318 | while (node->x < x1) {
319 | if (node->y > min_y) {
320 | // raise min_y higher.
321 | // we've accounted for all waste up to min_y,
322 | // but we'll now add more waste for everything we've visted
323 | waste_area += visited_width * (node->y - min_y);
324 | min_y = node->y;
325 | // the first time through, visited_width might be reduced
326 | if (node->x < x0)
327 | visited_width += node->next->x - x0;
328 | else
329 | visited_width += node->next->x - node->x;
330 | } else {
331 | // add waste area
332 | int under_width = node->next->x - node->x;
333 | if (under_width + visited_width > width)
334 | under_width = width - visited_width;
335 | waste_area += under_width * (min_y - node->y);
336 | visited_width += under_width;
337 | }
338 | node = node->next;
339 | }
340 |
341 | *pwaste = waste_area;
342 | return min_y;
343 | }
344 |
345 | typedef struct
346 | {
347 | int x,y;
348 | stbrp_node **prev_link;
349 | } stbrp__findresult;
350 |
351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
352 | {
353 | int best_waste = (1<<30), best_x, best_y = (1 << 30);
354 | stbrp__findresult fr;
355 | stbrp_node **prev, *node, *tail, **best = NULL;
356 |
357 | // align to multiple of c->align
358 | width = (width + c->align - 1);
359 | width -= width % c->align;
360 | STBRP_ASSERT(width % c->align == 0);
361 |
362 | // if it can't possibly fit, bail immediately
363 | if (width > c->width || height > c->height) {
364 | fr.prev_link = NULL;
365 | fr.x = fr.y = 0;
366 | return fr;
367 | }
368 |
369 | node = c->active_head;
370 | prev = &c->active_head;
371 | while (node->x + width <= c->width) {
372 | int y,waste;
373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
375 | // bottom left
376 | if (y < best_y) {
377 | best_y = y;
378 | best = prev;
379 | }
380 | } else {
381 | // best-fit
382 | if (y + height <= c->height) {
383 | // can only use it if it first vertically
384 | if (y < best_y || (y == best_y && waste < best_waste)) {
385 | best_y = y;
386 | best_waste = waste;
387 | best = prev;
388 | }
389 | }
390 | }
391 | prev = &node->next;
392 | node = node->next;
393 | }
394 |
395 | best_x = (best == NULL) ? 0 : (*best)->x;
396 |
397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position
398 | //
399 | // e.g, if fitting
400 | //
401 | // ____________________
402 | // |____________________|
403 | //
404 | // into
405 | //
406 | // | |
407 | // | ____________|
408 | // |____________|
409 | //
410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
411 | //
412 | // This makes BF take about 2x the time
413 |
414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
415 | tail = c->active_head;
416 | node = c->active_head;
417 | prev = &c->active_head;
418 | // find first node that's admissible
419 | while (tail->x < width)
420 | tail = tail->next;
421 | while (tail) {
422 | int xpos = tail->x - width;
423 | int y,waste;
424 | STBRP_ASSERT(xpos >= 0);
425 | // find the left position that matches this
426 | while (node->next->x <= xpos) {
427 | prev = &node->next;
428 | node = node->next;
429 | }
430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
432 | if (y + height <= c->height) {
433 | if (y <= best_y) {
434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
435 | best_x = xpos;
436 | STBRP_ASSERT(y <= best_y);
437 | best_y = y;
438 | best_waste = waste;
439 | best = prev;
440 | }
441 | }
442 | }
443 | tail = tail->next;
444 | }
445 | }
446 |
447 | fr.prev_link = best;
448 | fr.x = best_x;
449 | fr.y = best_y;
450 | return fr;
451 | }
452 |
453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
454 | {
455 | // find best position according to heuristic
456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
457 | stbrp_node *node, *cur;
458 |
459 | // bail if:
460 | // 1. it failed
461 | // 2. the best node doesn't fit (we don't always check this)
462 | // 3. we're out of memory
463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
464 | res.prev_link = NULL;
465 | return res;
466 | }
467 |
468 | // on success, create new node
469 | node = context->free_head;
470 | node->x = (stbrp_coord) res.x;
471 | node->y = (stbrp_coord) (res.y + height);
472 |
473 | context->free_head = node->next;
474 |
475 | // insert the new node into the right starting point, and
476 | // let 'cur' point to the remaining nodes needing to be
477 | // stiched back in
478 |
479 | cur = *res.prev_link;
480 | if (cur->x < res.x) {
481 | // preserve the existing one, so start testing with the next one
482 | stbrp_node *next = cur->next;
483 | cur->next = node;
484 | cur = next;
485 | } else {
486 | *res.prev_link = node;
487 | }
488 |
489 | // from here, traverse cur and free the nodes, until we get to one
490 | // that shouldn't be freed
491 | while (cur->next && cur->next->x <= res.x + width) {
492 | stbrp_node *next = cur->next;
493 | // move the current node to the free list
494 | cur->next = context->free_head;
495 | context->free_head = cur;
496 | cur = next;
497 | }
498 |
499 | // stitch the list back in
500 | node->next = cur;
501 |
502 | if (cur->x < res.x + width)
503 | cur->x = (stbrp_coord) (res.x + width);
504 |
505 | #ifdef _DEBUG
506 | cur = context->active_head;
507 | while (cur->x < context->width) {
508 | STBRP_ASSERT(cur->x < cur->next->x);
509 | cur = cur->next;
510 | }
511 | STBRP_ASSERT(cur->next == NULL);
512 |
513 | {
514 | int count=0;
515 | cur = context->active_head;
516 | while (cur) {
517 | cur = cur->next;
518 | ++count;
519 | }
520 | cur = context->free_head;
521 | while (cur) {
522 | cur = cur->next;
523 | ++count;
524 | }
525 | STBRP_ASSERT(count == context->num_nodes+2);
526 | }
527 | #endif
528 |
529 | return res;
530 | }
531 |
532 | // [DEAR IMGUI] Added STBRP__CDECL
533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
534 | {
535 | const stbrp_rect *p = (const stbrp_rect *) a;
536 | const stbrp_rect *q = (const stbrp_rect *) b;
537 | if (p->h > q->h)
538 | return -1;
539 | if (p->h < q->h)
540 | return 1;
541 | return (p->w > q->w) ? -1 : (p->w < q->w);
542 | }
543 |
544 | // [DEAR IMGUI] Added STBRP__CDECL
545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b)
546 | {
547 | const stbrp_rect *p = (const stbrp_rect *) a;
548 | const stbrp_rect *q = (const stbrp_rect *) b;
549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
550 | }
551 |
552 | #ifdef STBRP_LARGE_RECTS
553 | #define STBRP__MAXVAL 0xffffffff
554 | #else
555 | #define STBRP__MAXVAL 0xffff
556 | #endif
557 |
558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
559 | {
560 | int i, all_rects_packed = 1;
561 |
562 | // we use the 'was_packed' field internally to allow sorting/unsorting
563 | for (i=0; i < num_rects; ++i) {
564 | rects[i].was_packed = i;
565 | }
566 |
567 | // sort according to heuristic
568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
569 |
570 | for (i=0; i < num_rects; ++i) {
571 | if (rects[i].w == 0 || rects[i].h == 0) {
572 | rects[i].x = rects[i].y = 0; // empty rect needs no space
573 | } else {
574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
575 | if (fr.prev_link) {
576 | rects[i].x = (stbrp_coord) fr.x;
577 | rects[i].y = (stbrp_coord) fr.y;
578 | } else {
579 | rects[i].x = rects[i].y = STBRP__MAXVAL;
580 | }
581 | }
582 | }
583 |
584 | // unsort
585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
586 |
587 | // set was_packed flags and all_rects_packed status
588 | for (i=0; i < num_rects; ++i) {
589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
590 | if (!rects[i].was_packed)
591 | all_rects_packed = 0;
592 | }
593 |
594 | // return the all_rects_packed status
595 | return all_rects_packed;
596 | }
597 | #endif
598 |
599 | /*
600 | ------------------------------------------------------------------------------
601 | This software is available under 2 licenses -- choose whichever you prefer.
602 | ------------------------------------------------------------------------------
603 | ALTERNATIVE A - MIT License
604 | Copyright (c) 2017 Sean Barrett
605 | Permission is hereby granted, free of charge, to any person obtaining a copy of
606 | this software and associated documentation files (the "Software"), to deal in
607 | the Software without restriction, including without limitation the rights to
608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
609 | of the Software, and to permit persons to whom the Software is furnished to do
610 | so, subject to the following conditions:
611 | The above copyright notice and this permission notice shall be included in all
612 | copies or substantial portions of the Software.
613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
616 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
619 | SOFTWARE.
620 | ------------------------------------------------------------------------------
621 | ALTERNATIVE B - Public Domain (www.unlicense.org)
622 | This is free and unencumbered software released into the public domain.
623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
624 | software, either in source code form or as a compiled binary, for any purpose,
625 | commercial or non-commercial, and by any means.
626 | In jurisdictions that recognize copyright laws, the author or authors of this
627 | software dedicate any and all copyright interest in the software to the public
628 | domain. We make this dedication for the benefit of the public at large and to
629 | the detriment of our heirs and successors. We intend this dedication to be an
630 | overt act of relinquishment in perpetuity of all present and future rights to
631 | this software under copyright law.
632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
635 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
638 | ------------------------------------------------------------------------------
639 | */
640 |
--------------------------------------------------------------------------------
/TempleWare-External/external/imgui/imstb_textedit.h:
--------------------------------------------------------------------------------
1 | // [DEAR IMGUI]
2 | // This is a slightly modified version of stb_textedit.h 1.13.
3 | // Those changes would need to be pushed into nothings/stb:
4 | // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
5 | // Grep for [DEAR IMGUI] to find the changes.
6 |
7 | // stb_textedit.h - v1.13 - public domain - Sean Barrett
8 | // Development of this library was sponsored by RAD Game Tools
9 | //
10 | // This C header file implements the guts of a multi-line text-editing
11 | // widget; you implement display, word-wrapping, and low-level string
12 | // insertion/deletion, and stb_textedit will map user inputs into
13 | // insertions & deletions, plus updates to the cursor position,
14 | // selection state, and undo state.
15 | //
16 | // It is intended for use in games and other systems that need to build
17 | // their own custom widgets and which do not have heavy text-editing
18 | // requirements (this library is not recommended for use for editing large
19 | // texts, as its performance does not scale and it has limited undo).
20 | //
21 | // Non-trivial behaviors are modelled after Windows text controls.
22 | //
23 | //
24 | // LICENSE
25 | //
26 | // See end of file for license information.
27 | //
28 | //
29 | // DEPENDENCIES
30 | //
31 | // Uses the C runtime function 'memmove', which you can override
32 | // by defining STB_TEXTEDIT_memmove before the implementation.
33 | // Uses no other functions. Performs no runtime allocations.
34 | //
35 | //
36 | // VERSION HISTORY
37 | //
38 | // 1.13 (2019-02-07) fix bug in undo size management
39 | // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
40 | // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
41 | // 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual
42 | // 1.9 (2016-08-27) customizable move-by-word
43 | // 1.8 (2016-04-02) better keyboard handling when mouse button is down
44 | // 1.7 (2015-09-13) change y range handling in case baseline is non-0
45 | // 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove
46 | // 1.5 (2014-09-10) add support for secondary keys for OS X
47 | // 1.4 (2014-08-17) fix signed/unsigned warnings
48 | // 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
49 | // 1.2 (2014-05-27) fix some RAD types that had crept into the new code
50 | // 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE )
51 | // 1.0 (2012-07-26) improve documentation, initial public release
52 | // 0.3 (2012-02-24) bugfixes, single-line mode; insert mode
53 | // 0.2 (2011-11-28) fixes to undo/redo
54 | // 0.1 (2010-07-08) initial version
55 | //
56 | // ADDITIONAL CONTRIBUTORS
57 | //
58 | // Ulf Winklemann: move-by-word in 1.1
59 | // Fabian Giesen: secondary key inputs in 1.5
60 | // Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
61 | //
62 | // Bugfixes:
63 | // Scott Graham
64 | // Daniel Keller
65 | // Omar Cornut
66 | // Dan Thompson
67 | //
68 | // USAGE
69 | //
70 | // This file behaves differently depending on what symbols you define
71 | // before including it.
72 | //
73 | //
74 | // Header-file mode:
75 | //
76 | // If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this,
77 | // it will operate in "header file" mode. In this mode, it declares a
78 | // single public symbol, STB_TexteditState, which encapsulates the current
79 | // state of a text widget (except for the string, which you will store
80 | // separately).
81 | //
82 | // To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a
83 | // primitive type that defines a single character (e.g. char, wchar_t, etc).
84 | //
85 | // To save space or increase undo-ability, you can optionally define the
86 | // following things that are used by the undo system:
87 | //
88 | // STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position
89 | // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow
90 | // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer
91 | //
92 | // If you don't define these, they are set to permissive types and
93 | // moderate sizes. The undo system does no memory allocations, so
94 | // it grows STB_TexteditState by the worst-case storage which is (in bytes):
95 | //
96 | // [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT
97 | // + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT
98 | //
99 | //
100 | // Implementation mode:
101 | //
102 | // If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it
103 | // will compile the implementation of the text edit widget, depending
104 | // on a large number of symbols which must be defined before the include.
105 | //
106 | // The implementation is defined only as static functions. You will then
107 | // need to provide your own APIs in the same file which will access the
108 | // static functions.
109 | //
110 | // The basic concept is that you provide a "string" object which
111 | // behaves like an array of characters. stb_textedit uses indices to
112 | // refer to positions in the string, implicitly representing positions
113 | // in the displayed textedit. This is true for both plain text and
114 | // rich text; even with rich text stb_truetype interacts with your
115 | // code as if there was an array of all the displayed characters.
116 | //
117 | // Symbols that must be the same in header-file and implementation mode:
118 | //
119 | // STB_TEXTEDIT_CHARTYPE the character type
120 | // STB_TEXTEDIT_POSITIONTYPE small type that is a valid cursor position
121 | // STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow
122 | // STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer
123 | //
124 | // Symbols you must define for implementation mode:
125 | //
126 | // STB_TEXTEDIT_STRING the type of object representing a string being edited,
127 | // typically this is a wrapper object with other data you need
128 | //
129 | // STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1))
130 | // STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters
131 | // starting from character #n (see discussion below)
132 | // STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character
133 | // to the xpos of the i+1'th char for a line of characters
134 | // starting at character #n (i.e. accounts for kerning
135 | // with previous char)
136 | // STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character
137 | // (return type is int, -1 means not valid to insert)
138 | // STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based
139 | // STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize
140 | // as manually wordwrapping for end-of-line positioning
141 | //
142 | // STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i
143 | // STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*)
144 | //
145 | // STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key
146 | //
147 | // STB_TEXTEDIT_K_LEFT keyboard input to move cursor left
148 | // STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right
149 | // STB_TEXTEDIT_K_UP keyboard input to move cursor up
150 | // STB_TEXTEDIT_K_DOWN keyboard input to move cursor down
151 | // STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
152 | // STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page
153 | // STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME
154 | // STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END
155 | // STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME
156 | // STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END
157 | // STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor
158 | // STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor
159 | // STB_TEXTEDIT_K_UNDO keyboard input to perform undo
160 | // STB_TEXTEDIT_K_REDO keyboard input to perform redo
161 | //
162 | // Optional:
163 | // STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode
164 | // STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'),
165 | // required for default WORDLEFT/WORDRIGHT handlers
166 | // STB_TEXTEDIT_MOVEWORDLEFT(obj,i) custom handler for WORDLEFT, returns index to move cursor to
167 | // STB_TEXTEDIT_MOVEWORDRIGHT(obj,i) custom handler for WORDRIGHT, returns index to move cursor to
168 | // STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT
169 | // STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT
170 | // STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line
171 | // STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line
172 | // STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
173 | // STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
174 | //
175 | // Keyboard input must be encoded as a single integer value; e.g. a character code
176 | // and some bitflags that represent shift states. to simplify the interface, SHIFT must
177 | // be a bitflag, so we can test the shifted state of cursor movements to allow selection,
178 | // i.e. (STB_TEXTEDIT_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow.
179 | //
180 | // You can encode other things, such as CONTROL or ALT, in additional bits, and
181 | // then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example,
182 | // my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN
183 | // bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit,
184 | // and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the
185 | // API below. The control keys will only match WM_KEYDOWN events because of the
186 | // keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN
187 | // bit so it only decodes WM_CHAR events.
188 | //
189 | // STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed
190 | // row of characters assuming they start on the i'th character--the width and
191 | // the height and the number of characters consumed. This allows this library
192 | // to traverse the entire layout incrementally. You need to compute word-wrapping
193 | // here.
194 | //
195 | // Each textfield keeps its own insert mode state, which is not how normal
196 | // applications work. To keep an app-wide insert mode, update/copy the
197 | // "insert_mode" field of STB_TexteditState before/after calling API functions.
198 | //
199 | // API
200 | //
201 | // void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line)
202 | //
203 | // void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
204 | // void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
205 | // int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
206 | // int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
207 | // void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
208 | //
209 | // Each of these functions potentially updates the string and updates the
210 | // state.
211 | //
212 | // initialize_state:
213 | // set the textedit state to a known good default state when initially
214 | // constructing the textedit.
215 | //
216 | // click:
217 | // call this with the mouse x,y on a mouse down; it will update the cursor
218 | // and reset the selection start/end to the cursor point. the x,y must
219 | // be relative to the text widget, with (0,0) being the top left.
220 | //
221 | // drag:
222 | // call this with the mouse x,y on a mouse drag/up; it will update the
223 | // cursor and the selection end point
224 | //
225 | // cut:
226 | // call this to delete the current selection; returns true if there was
227 | // one. you should FIRST copy the current selection to the system paste buffer.
228 | // (To copy, just copy the current selection out of the string yourself.)
229 | //
230 | // paste:
231 | // call this to paste text at the current cursor point or over the current
232 | // selection if there is one.
233 | //
234 | // key:
235 | // call this for keyboard inputs sent to the textfield. you can use it
236 | // for "key down" events or for "translated" key events. if you need to
237 | // do both (as in Win32), or distinguish Unicode characters from control
238 | // inputs, set a high bit to distinguish the two; then you can define the
239 | // various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit
240 | // set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is
241 | // clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
242 | // anything other type you wante before including.
243 | //
244 | //
245 | // When rendering, you can read the cursor position and selection state from
246 | // the STB_TexteditState.
247 | //
248 | //
249 | // Notes:
250 | //
251 | // This is designed to be usable in IMGUI, so it allows for the possibility of
252 | // running in an IMGUI that has NOT cached the multi-line layout. For this
253 | // reason, it provides an interface that is compatible with computing the
254 | // layout incrementally--we try to make sure we make as few passes through
255 | // as possible. (For example, to locate the mouse pointer in the text, we
256 | // could define functions that return the X and Y positions of characters
257 | // and binary search Y and then X, but if we're doing dynamic layout this
258 | // will run the layout algorithm many times, so instead we manually search
259 | // forward in one pass. Similar logic applies to e.g. up-arrow and
260 | // down-arrow movement.)
261 | //
262 | // If it's run in a widget that *has* cached the layout, then this is less
263 | // efficient, but it's not horrible on modern computers. But you wouldn't
264 | // want to edit million-line files with it.
265 |
266 |
267 | ////////////////////////////////////////////////////////////////////////////
268 | ////////////////////////////////////////////////////////////////////////////
269 | ////
270 | //// Header-file mode
271 | ////
272 | ////
273 |
274 | #ifndef INCLUDE_STB_TEXTEDIT_H
275 | #define INCLUDE_STB_TEXTEDIT_H
276 |
277 | ////////////////////////////////////////////////////////////////////////
278 | //
279 | // STB_TexteditState
280 | //
281 | // Definition of STB_TexteditState which you should store
282 | // per-textfield; it includes cursor position, selection state,
283 | // and undo state.
284 | //
285 |
286 | #ifndef STB_TEXTEDIT_UNDOSTATECOUNT
287 | #define STB_TEXTEDIT_UNDOSTATECOUNT 99
288 | #endif
289 | #ifndef STB_TEXTEDIT_UNDOCHARCOUNT
290 | #define STB_TEXTEDIT_UNDOCHARCOUNT 999
291 | #endif
292 | #ifndef STB_TEXTEDIT_CHARTYPE
293 | #define STB_TEXTEDIT_CHARTYPE int
294 | #endif
295 | #ifndef STB_TEXTEDIT_POSITIONTYPE
296 | #define STB_TEXTEDIT_POSITIONTYPE int
297 | #endif
298 |
299 | typedef struct
300 | {
301 | // private data
302 | STB_TEXTEDIT_POSITIONTYPE where;
303 | STB_TEXTEDIT_POSITIONTYPE insert_length;
304 | STB_TEXTEDIT_POSITIONTYPE delete_length;
305 | int char_storage;
306 | } StbUndoRecord;
307 |
308 | typedef struct
309 | {
310 | // private data
311 | StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
312 | STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
313 | short undo_point, redo_point;
314 | int undo_char_point, redo_char_point;
315 | } StbUndoState;
316 |
317 | typedef struct
318 | {
319 | /////////////////////
320 | //
321 | // public data
322 | //
323 |
324 | int cursor;
325 | // position of the text cursor within the string
326 |
327 | int select_start; // selection start point
328 | int select_end;
329 | // selection start and end point in characters; if equal, no selection.
330 | // note that start may be less than or greater than end (e.g. when
331 | // dragging the mouse, start is where the initial click was, and you
332 | // can drag in either direction)
333 |
334 | unsigned char insert_mode;
335 | // each textfield keeps its own insert mode state. to keep an app-wide
336 | // insert mode, copy this value in/out of the app state
337 |
338 | int row_count_per_page;
339 | // page size in number of row.
340 | // this value MUST be set to >0 for pageup or pagedown in multilines documents.
341 |
342 | /////////////////////
343 | //
344 | // private data
345 | //
346 | unsigned char cursor_at_end_of_line; // not implemented yet
347 | unsigned char initialized;
348 | unsigned char has_preferred_x;
349 | unsigned char single_line;
350 | unsigned char padding1, padding2, padding3;
351 | float preferred_x; // this determines where the cursor up/down tries to seek to along x
352 | StbUndoState undostate;
353 | } STB_TexteditState;
354 |
355 |
356 | ////////////////////////////////////////////////////////////////////////
357 | //
358 | // StbTexteditRow
359 | //
360 | // Result of layout query, used by stb_textedit to determine where
361 | // the text in each row is.
362 |
363 | // result of layout query
364 | typedef struct
365 | {
366 | float x0,x1; // starting x location, end x location (allows for align=right, etc)
367 | float baseline_y_delta; // position of baseline relative to previous row's baseline
368 | float ymin,ymax; // height of row above and below baseline
369 | int num_chars;
370 | } StbTexteditRow;
371 | #endif //INCLUDE_STB_TEXTEDIT_H
372 |
373 |
374 | ////////////////////////////////////////////////////////////////////////////
375 | ////////////////////////////////////////////////////////////////////////////
376 | ////
377 | //// Implementation mode
378 | ////
379 | ////
380 |
381 |
382 | // implementation isn't include-guarded, since it might have indirectly
383 | // included just the "header" portion
384 | #ifdef STB_TEXTEDIT_IMPLEMENTATION
385 |
386 | #ifndef STB_TEXTEDIT_memmove
387 | #include
388 | #define STB_TEXTEDIT_memmove memmove
389 | #endif
390 |
391 |
392 | /////////////////////////////////////////////////////////////////////////////
393 | //
394 | // Mouse input handling
395 | //
396 |
397 | // traverse the layout to locate the nearest character to a display position
398 | static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
399 | {
400 | StbTexteditRow r;
401 | int n = STB_TEXTEDIT_STRINGLEN(str);
402 | float base_y = 0, prev_x;
403 | int i=0, k;
404 |
405 | r.x0 = r.x1 = 0;
406 | r.ymin = r.ymax = 0;
407 | r.num_chars = 0;
408 |
409 | // search rows to find one that straddles 'y'
410 | while (i < n) {
411 | STB_TEXTEDIT_LAYOUTROW(&r, str, i);
412 | if (r.num_chars <= 0)
413 | return n;
414 |
415 | if (i==0 && y < base_y + r.ymin)
416 | return 0;
417 |
418 | if (y < base_y + r.ymax)
419 | break;
420 |
421 | i += r.num_chars;
422 | base_y += r.baseline_y_delta;
423 | }
424 |
425 | // below all text, return 'after' last character
426 | if (i >= n)
427 | return n;
428 |
429 | // check if it's before the beginning of the line
430 | if (x < r.x0)
431 | return i;
432 |
433 | // check if it's before the end of the line
434 | if (x < r.x1) {
435 | // search characters in row for one that straddles 'x'
436 | prev_x = r.x0;
437 | for (k=0; k < r.num_chars; ++k) {
438 | float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
439 | if (x < prev_x+w) {
440 | if (x < prev_x+w/2)
441 | return k+i;
442 | else
443 | return k+i+1;
444 | }
445 | prev_x += w;
446 | }
447 | // shouldn't happen, but if it does, fall through to end-of-line case
448 | }
449 |
450 | // if the last character is a newline, return that. otherwise return 'after' the last character
451 | if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE)
452 | return i+r.num_chars-1;
453 | else
454 | return i+r.num_chars;
455 | }
456 |
457 | // API click: on mouse down, move the cursor to the clicked location, and reset the selection
458 | static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
459 | {
460 | // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
461 | // goes off the top or bottom of the text
462 | if( state->single_line )
463 | {
464 | StbTexteditRow r;
465 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
466 | y = r.ymin;
467 | }
468 |
469 | state->cursor = stb_text_locate_coord(str, x, y);
470 | state->select_start = state->cursor;
471 | state->select_end = state->cursor;
472 | state->has_preferred_x = 0;
473 | }
474 |
475 | // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
476 | static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
477 | {
478 | int p = 0;
479 |
480 | // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
481 | // goes off the top or bottom of the text
482 | if( state->single_line )
483 | {
484 | StbTexteditRow r;
485 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
486 | y = r.ymin;
487 | }
488 |
489 | if (state->select_start == state->select_end)
490 | state->select_start = state->cursor;
491 |
492 | p = stb_text_locate_coord(str, x, y);
493 | state->cursor = state->select_end = p;
494 | }
495 |
496 | /////////////////////////////////////////////////////////////////////////////
497 | //
498 | // Keyboard input handling
499 | //
500 |
501 | // forward declarations
502 | static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
503 | static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
504 | static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
505 | static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
506 | static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
507 |
508 | typedef struct
509 | {
510 | float x,y; // position of n'th character
511 | float height; // height of line
512 | int first_char, length; // first char of row, and length
513 | int prev_first; // first char of previous row
514 | } StbFindState;
515 |
516 | // find the x/y location of a character, and remember info about the previous row in
517 | // case we get a move-up event (for page up, we'll have to rescan)
518 | static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
519 | {
520 | StbTexteditRow r;
521 | int prev_start = 0;
522 | int z = STB_TEXTEDIT_STRINGLEN(str);
523 | int i=0, first;
524 |
525 | if (n == z) {
526 | // if it's at the end, then find the last line -- simpler than trying to
527 | // explicitly handle this case in the regular code
528 | if (single_line) {
529 | STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
530 | find->y = 0;
531 | find->first_char = 0;
532 | find->length = z;
533 | find->height = r.ymax - r.ymin;
534 | find->x = r.x1;
535 | } else {
536 | find->y = 0;
537 | find->x = 0;
538 | find->height = 1;
539 | while (i < z) {
540 | STB_TEXTEDIT_LAYOUTROW(&r, str, i);
541 | prev_start = i;
542 | i += r.num_chars;
543 | }
544 | find->first_char = i;
545 | find->length = 0;
546 | find->prev_first = prev_start;
547 | }
548 | return;
549 | }
550 |
551 | // search rows to find the one that straddles character n
552 | find->y = 0;
553 |
554 | for(;;) {
555 | STB_TEXTEDIT_LAYOUTROW(&r, str, i);
556 | if (n < i + r.num_chars)
557 | break;
558 | prev_start = i;
559 | i += r.num_chars;
560 | find->y += r.baseline_y_delta;
561 | }
562 |
563 | find->first_char = first = i;
564 | find->length = r.num_chars;
565 | find->height = r.ymax - r.ymin;
566 | find->prev_first = prev_start;
567 |
568 | // now scan to find xpos
569 | find->x = r.x0;
570 | for (i=0; first+i < n; ++i)
571 | find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
572 | }
573 |
574 | #define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
575 |
576 | // make the selection/cursor state valid if client altered the string
577 | static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
578 | {
579 | int n = STB_TEXTEDIT_STRINGLEN(str);
580 | if (STB_TEXT_HAS_SELECTION(state)) {
581 | if (state->select_start > n) state->select_start = n;
582 | if (state->select_end > n) state->select_end = n;
583 | // if clamping forced them to be equal, move the cursor to match
584 | if (state->select_start == state->select_end)
585 | state->cursor = state->select_start;
586 | }
587 | if (state->cursor > n) state->cursor = n;
588 | }
589 |
590 | // delete characters while updating undo
591 | static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
592 | {
593 | stb_text_makeundo_delete(str, state, where, len);
594 | STB_TEXTEDIT_DELETECHARS(str, where, len);
595 | state->has_preferred_x = 0;
596 | }
597 |
598 | // delete the section
599 | static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
600 | {
601 | stb_textedit_clamp(str, state);
602 | if (STB_TEXT_HAS_SELECTION(state)) {
603 | if (state->select_start < state->select_end) {
604 | stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start);
605 | state->select_end = state->cursor = state->select_start;
606 | } else {
607 | stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end);
608 | state->select_start = state->cursor = state->select_end;
609 | }
610 | state->has_preferred_x = 0;
611 | }
612 | }
613 |
614 | // canoncialize the selection so start <= end
615 | static void stb_textedit_sortselection(STB_TexteditState *state)
616 | {
617 | if (state->select_end < state->select_start) {
618 | int temp = state->select_end;
619 | state->select_end = state->select_start;
620 | state->select_start = temp;
621 | }
622 | }
623 |
624 | // move cursor to first character of selection
625 | static void stb_textedit_move_to_first(STB_TexteditState *state)
626 | {
627 | if (STB_TEXT_HAS_SELECTION(state)) {
628 | stb_textedit_sortselection(state);
629 | state->cursor = state->select_start;
630 | state->select_end = state->select_start;
631 | state->has_preferred_x = 0;
632 | }
633 | }
634 |
635 | // move cursor to last character of selection
636 | static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
637 | {
638 | if (STB_TEXT_HAS_SELECTION(state)) {
639 | stb_textedit_sortselection(state);
640 | stb_textedit_clamp(str, state);
641 | state->cursor = state->select_end;
642 | state->select_start = state->select_end;
643 | state->has_preferred_x = 0;
644 | }
645 | }
646 |
647 | #ifdef STB_TEXTEDIT_IS_SPACE
648 | static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
649 | {
650 | return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
651 | }
652 |
653 | #ifndef STB_TEXTEDIT_MOVEWORDLEFT
654 | static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
655 | {
656 | --c; // always move at least one character
657 | while( c >= 0 && !is_word_boundary( str, c ) )
658 | --c;
659 |
660 | if( c < 0 )
661 | c = 0;
662 |
663 | return c;
664 | }
665 | #define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous
666 | #endif
667 |
668 | #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
669 | static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
670 | {
671 | const int len = STB_TEXTEDIT_STRINGLEN(str);
672 | ++c; // always move at least one character
673 | while( c < len && !is_word_boundary( str, c ) )
674 | ++c;
675 |
676 | if( c > len )
677 | c = len;
678 |
679 | return c;
680 | }
681 | #define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next
682 | #endif
683 |
684 | #endif
685 |
686 | // update selection and cursor to match each other
687 | static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
688 | {
689 | if (!STB_TEXT_HAS_SELECTION(state))
690 | state->select_start = state->select_end = state->cursor;
691 | else
692 | state->cursor = state->select_end;
693 | }
694 |
695 | // API cut: delete selection
696 | static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
697 | {
698 | if (STB_TEXT_HAS_SELECTION(state)) {
699 | stb_textedit_delete_selection(str,state); // implicitly clamps
700 | state->has_preferred_x = 0;
701 | return 1;
702 | }
703 | return 0;
704 | }
705 |
706 | // API paste: replace existing selection with passed-in text
707 | static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
708 | {
709 | // if there's a selection, the paste should delete it
710 | stb_textedit_clamp(str, state);
711 | stb_textedit_delete_selection(str,state);
712 | // try to insert the characters
713 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
714 | stb_text_makeundo_insert(state, state->cursor, len);
715 | state->cursor += len;
716 | state->has_preferred_x = 0;
717 | return 1;
718 | }
719 | // [DEAR IMGUI]
720 | //// remove the undo since we didn't actually insert the characters
721 | //if (state->undostate.undo_point)
722 | // --state->undostate.undo_point;
723 | // note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details)
724 | return 0;
725 | }
726 |
727 | #ifndef STB_TEXTEDIT_KEYTYPE
728 | #define STB_TEXTEDIT_KEYTYPE int
729 | #endif
730 |
731 | // API key: process a keyboard input
732 | static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
733 | {
734 | retry:
735 | switch (key) {
736 | default: {
737 | int c = STB_TEXTEDIT_KEYTOTEXT(key);
738 | if (c > 0) {
739 | STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
740 |
741 | // can't add newline in single-line mode
742 | if (c == '\n' && state->single_line)
743 | break;
744 |
745 | if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
746 | stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
747 | STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
748 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
749 | ++state->cursor;
750 | state->has_preferred_x = 0;
751 | }
752 | } else {
753 | stb_textedit_delete_selection(str,state); // implicitly clamps
754 | if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
755 | stb_text_makeundo_insert(state, state->cursor, 1);
756 | ++state->cursor;
757 | state->has_preferred_x = 0;
758 | }
759 | }
760 | }
761 | break;
762 | }
763 |
764 | #ifdef STB_TEXTEDIT_K_INSERT
765 | case STB_TEXTEDIT_K_INSERT:
766 | state->insert_mode = !state->insert_mode;
767 | break;
768 | #endif
769 |
770 | case STB_TEXTEDIT_K_UNDO:
771 | stb_text_undo(str, state);
772 | state->has_preferred_x = 0;
773 | break;
774 |
775 | case STB_TEXTEDIT_K_REDO:
776 | stb_text_redo(str, state);
777 | state->has_preferred_x = 0;
778 | break;
779 |
780 | case STB_TEXTEDIT_K_LEFT:
781 | // if currently there's a selection, move cursor to start of selection
782 | if (STB_TEXT_HAS_SELECTION(state))
783 | stb_textedit_move_to_first(state);
784 | else
785 | if (state->cursor > 0)
786 | --state->cursor;
787 | state->has_preferred_x = 0;
788 | break;
789 |
790 | case STB_TEXTEDIT_K_RIGHT:
791 | // if currently there's a selection, move cursor to end of selection
792 | if (STB_TEXT_HAS_SELECTION(state))
793 | stb_textedit_move_to_last(str, state);
794 | else
795 | ++state->cursor;
796 | stb_textedit_clamp(str, state);
797 | state->has_preferred_x = 0;
798 | break;
799 |
800 | case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT:
801 | stb_textedit_clamp(str, state);
802 | stb_textedit_prep_selection_at_cursor(state);
803 | // move selection left
804 | if (state->select_end > 0)
805 | --state->select_end;
806 | state->cursor = state->select_end;
807 | state->has_preferred_x = 0;
808 | break;
809 |
810 | #ifdef STB_TEXTEDIT_MOVEWORDLEFT
811 | case STB_TEXTEDIT_K_WORDLEFT:
812 | if (STB_TEXT_HAS_SELECTION(state))
813 | stb_textedit_move_to_first(state);
814 | else {
815 | state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
816 | stb_textedit_clamp( str, state );
817 | }
818 | break;
819 |
820 | case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT:
821 | if( !STB_TEXT_HAS_SELECTION( state ) )
822 | stb_textedit_prep_selection_at_cursor(state);
823 |
824 | state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
825 | state->select_end = state->cursor;
826 |
827 | stb_textedit_clamp( str, state );
828 | break;
829 | #endif
830 |
831 | #ifdef STB_TEXTEDIT_MOVEWORDRIGHT
832 | case STB_TEXTEDIT_K_WORDRIGHT:
833 | if (STB_TEXT_HAS_SELECTION(state))
834 | stb_textedit_move_to_last(str, state);
835 | else {
836 | state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
837 | stb_textedit_clamp( str, state );
838 | }
839 | break;
840 |
841 | case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT:
842 | if( !STB_TEXT_HAS_SELECTION( state ) )
843 | stb_textedit_prep_selection_at_cursor(state);
844 |
845 | state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
846 | state->select_end = state->cursor;
847 |
848 | stb_textedit_clamp( str, state );
849 | break;
850 | #endif
851 |
852 | case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
853 | stb_textedit_prep_selection_at_cursor(state);
854 | // move selection right
855 | ++state->select_end;
856 | stb_textedit_clamp(str, state);
857 | state->cursor = state->select_end;
858 | state->has_preferred_x = 0;
859 | break;
860 |
861 | case STB_TEXTEDIT_K_DOWN:
862 | case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT:
863 | case STB_TEXTEDIT_K_PGDOWN:
864 | case STB_TEXTEDIT_K_PGDOWN | STB_TEXTEDIT_K_SHIFT: {
865 | StbFindState find;
866 | StbTexteditRow row;
867 | int i, j, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
868 | int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGDOWN;
869 | int row_count = is_page ? state->row_count_per_page : 1;
870 |
871 | if (!is_page && state->single_line) {
872 | // on windows, up&down in single-line behave like left&right
873 | key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT);
874 | goto retry;
875 | }
876 |
877 | if (sel)
878 | stb_textedit_prep_selection_at_cursor(state);
879 | else if (STB_TEXT_HAS_SELECTION(state))
880 | stb_textedit_move_to_last(str, state);
881 |
882 | // compute current position of cursor point
883 | stb_textedit_clamp(str, state);
884 | stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
885 |
886 | for (j = 0; j < row_count; ++j) {
887 | float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
888 | int start = find.first_char + find.length;
889 |
890 | if (find.length == 0)
891 | break;
892 |
893 | // [DEAR IMGUI]
894 | // going down while being on the last line shouldn't bring us to that line end
895 | if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
896 | break;
897 |
898 | // now find character position down a row
899 | state->cursor = start;
900 | STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
901 | x = row.x0;
902 | for (i=0; i < row.num_chars; ++i) {
903 | float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
904 | #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
905 | if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
906 | break;
907 | #endif
908 | x += dx;
909 | if (x > goal_x)
910 | break;
911 | ++state->cursor;
912 | }
913 | stb_textedit_clamp(str, state);
914 |
915 | state->has_preferred_x = 1;
916 | state->preferred_x = goal_x;
917 |
918 | if (sel)
919 | state->select_end = state->cursor;
920 |
921 | // go to next line
922 | find.first_char = find.first_char + find.length;
923 | find.length = row.num_chars;
924 | }
925 | break;
926 | }
927 |
928 | case STB_TEXTEDIT_K_UP:
929 | case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
930 | case STB_TEXTEDIT_K_PGUP:
931 | case STB_TEXTEDIT_K_PGUP | STB_TEXTEDIT_K_SHIFT: {
932 | StbFindState find;
933 | StbTexteditRow row;
934 | int i, j, prev_scan, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
935 | int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGUP;
936 | int row_count = is_page ? state->row_count_per_page : 1;
937 |
938 | if (!is_page && state->single_line) {
939 | // on windows, up&down become left&right
940 | key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT);
941 | goto retry;
942 | }
943 |
944 | if (sel)
945 | stb_textedit_prep_selection_at_cursor(state);
946 | else if (STB_TEXT_HAS_SELECTION(state))
947 | stb_textedit_move_to_first(state);
948 |
949 | // compute current position of cursor point
950 | stb_textedit_clamp(str, state);
951 | stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
952 |
953 | for (j = 0; j < row_count; ++j) {
954 | float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
955 |
956 | // can only go up if there's a previous row
957 | if (find.prev_first == find.first_char)
958 | break;
959 |
960 | // now find character position up a row
961 | state->cursor = find.prev_first;
962 | STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
963 | x = row.x0;
964 | for (i=0; i < row.num_chars; ++i) {
965 | float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
966 | #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
967 | if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
968 | break;
969 | #endif
970 | x += dx;
971 | if (x > goal_x)
972 | break;
973 | ++state->cursor;
974 | }
975 | stb_textedit_clamp(str, state);
976 |
977 | state->has_preferred_x = 1;
978 | state->preferred_x = goal_x;
979 |
980 | if (sel)
981 | state->select_end = state->cursor;
982 |
983 | // go to previous line
984 | // (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
985 | prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
986 | while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE)
987 | --prev_scan;
988 | find.first_char = find.prev_first;
989 | find.prev_first = prev_scan;
990 | }
991 | break;
992 | }
993 |
994 | case STB_TEXTEDIT_K_DELETE:
995 | case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT:
996 | if (STB_TEXT_HAS_SELECTION(state))
997 | stb_textedit_delete_selection(str, state);
998 | else {
999 | int n = STB_TEXTEDIT_STRINGLEN(str);
1000 | if (state->cursor < n)
1001 | stb_textedit_delete(str, state, state->cursor, 1);
1002 | }
1003 | state->has_preferred_x = 0;
1004 | break;
1005 |
1006 | case STB_TEXTEDIT_K_BACKSPACE:
1007 | case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT:
1008 | if (STB_TEXT_HAS_SELECTION(state))
1009 | stb_textedit_delete_selection(str, state);
1010 | else {
1011 | stb_textedit_clamp(str, state);
1012 | if (state->cursor > 0) {
1013 | stb_textedit_delete(str, state, state->cursor-1, 1);
1014 | --state->cursor;
1015 | }
1016 | }
1017 | state->has_preferred_x = 0;
1018 | break;
1019 |
1020 | #ifdef STB_TEXTEDIT_K_TEXTSTART2
1021 | case STB_TEXTEDIT_K_TEXTSTART2:
1022 | #endif
1023 | case STB_TEXTEDIT_K_TEXTSTART:
1024 | state->cursor = state->select_start = state->select_end = 0;
1025 | state->has_preferred_x = 0;
1026 | break;
1027 |
1028 | #ifdef STB_TEXTEDIT_K_TEXTEND2
1029 | case STB_TEXTEDIT_K_TEXTEND2:
1030 | #endif
1031 | case STB_TEXTEDIT_K_TEXTEND:
1032 | state->cursor = STB_TEXTEDIT_STRINGLEN(str);
1033 | state->select_start = state->select_end = 0;
1034 | state->has_preferred_x = 0;
1035 | break;
1036 |
1037 | #ifdef STB_TEXTEDIT_K_TEXTSTART2
1038 | case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
1039 | #endif
1040 | case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT:
1041 | stb_textedit_prep_selection_at_cursor(state);
1042 | state->cursor = state->select_end = 0;
1043 | state->has_preferred_x = 0;
1044 | break;
1045 |
1046 | #ifdef STB_TEXTEDIT_K_TEXTEND2
1047 | case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT:
1048 | #endif
1049 | case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT:
1050 | stb_textedit_prep_selection_at_cursor(state);
1051 | state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
1052 | state->has_preferred_x = 0;
1053 | break;
1054 |
1055 |
1056 | #ifdef STB_TEXTEDIT_K_LINESTART2
1057 | case STB_TEXTEDIT_K_LINESTART2:
1058 | #endif
1059 | case STB_TEXTEDIT_K_LINESTART:
1060 | stb_textedit_clamp(str, state);
1061 | stb_textedit_move_to_first(state);
1062 | if (state->single_line)
1063 | state->cursor = 0;
1064 | else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
1065 | --state->cursor;
1066 | state->has_preferred_x = 0;
1067 | break;
1068 |
1069 | #ifdef STB_TEXTEDIT_K_LINEEND2
1070 | case STB_TEXTEDIT_K_LINEEND2:
1071 | #endif
1072 | case STB_TEXTEDIT_K_LINEEND: {
1073 | int n = STB_TEXTEDIT_STRINGLEN(str);
1074 | stb_textedit_clamp(str, state);
1075 | stb_textedit_move_to_first(state);
1076 | if (state->single_line)
1077 | state->cursor = n;
1078 | else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
1079 | ++state->cursor;
1080 | state->has_preferred_x = 0;
1081 | break;
1082 | }
1083 |
1084 | #ifdef STB_TEXTEDIT_K_LINESTART2
1085 | case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
1086 | #endif
1087 | case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT:
1088 | stb_textedit_clamp(str, state);
1089 | stb_textedit_prep_selection_at_cursor(state);
1090 | if (state->single_line)
1091 | state->cursor = 0;
1092 | else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
1093 | --state->cursor;
1094 | state->select_end = state->cursor;
1095 | state->has_preferred_x = 0;
1096 | break;
1097 |
1098 | #ifdef STB_TEXTEDIT_K_LINEEND2
1099 | case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
1100 | #endif
1101 | case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
1102 | int n = STB_TEXTEDIT_STRINGLEN(str);
1103 | stb_textedit_clamp(str, state);
1104 | stb_textedit_prep_selection_at_cursor(state);
1105 | if (state->single_line)
1106 | state->cursor = n;
1107 | else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
1108 | ++state->cursor;
1109 | state->select_end = state->cursor;
1110 | state->has_preferred_x = 0;
1111 | break;
1112 | }
1113 | }
1114 | }
1115 |
1116 | /////////////////////////////////////////////////////////////////////////////
1117 | //
1118 | // Undo processing
1119 | //
1120 | // @OPTIMIZE: the undo/redo buffer should be circular
1121 |
1122 | static void stb_textedit_flush_redo(StbUndoState *state)
1123 | {
1124 | state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
1125 | state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
1126 | }
1127 |
1128 | // discard the oldest entry in the undo list
1129 | static void stb_textedit_discard_undo(StbUndoState *state)
1130 | {
1131 | if (state->undo_point > 0) {
1132 | // if the 0th undo state has characters, clean those up
1133 | if (state->undo_rec[0].char_storage >= 0) {
1134 | int n = state->undo_rec[0].insert_length, i;
1135 | // delete n characters from all other records
1136 | state->undo_char_point -= n;
1137 | STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
1138 | for (i=0; i < state->undo_point; ++i)
1139 | if (state->undo_rec[i].char_storage >= 0)
1140 | state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
1141 | }
1142 | --state->undo_point;
1143 | STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
1144 | }
1145 | }
1146 |
1147 | // discard the oldest entry in the redo list--it's bad if this
1148 | // ever happens, but because undo & redo have to store the actual
1149 | // characters in different cases, the redo character buffer can
1150 | // fill up even though the undo buffer didn't
1151 | static void stb_textedit_discard_redo(StbUndoState *state)
1152 | {
1153 | int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
1154 |
1155 | if (state->redo_point <= k) {
1156 | // if the k'th undo state has characters, clean those up
1157 | if (state->undo_rec[k].char_storage >= 0) {
1158 | int n = state->undo_rec[k].insert_length, i;
1159 | // move the remaining redo character data to the end of the buffer
1160 | state->redo_char_point += n;
1161 | STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
1162 | // adjust the position of all the other records to account for above memmove
1163 | for (i=state->redo_point; i < k; ++i)
1164 | if (state->undo_rec[i].char_storage >= 0)
1165 | state->undo_rec[i].char_storage += n;
1166 | }
1167 | // now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
1168 | // [DEAR IMGUI]
1169 | size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
1170 | const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
1171 | const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
1172 | IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
1173 | IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
1174 | STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
1175 |
1176 | // now move redo_point to point to the new one
1177 | ++state->redo_point;
1178 | }
1179 | }
1180 |
1181 | static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars)
1182 | {
1183 | // any time we create a new undo record, we discard redo
1184 | stb_textedit_flush_redo(state);
1185 |
1186 | // if we have no free records, we have to make room, by sliding the
1187 | // existing records down
1188 | if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
1189 | stb_textedit_discard_undo(state);
1190 |
1191 | // if the characters to store won't possibly fit in the buffer, we can't undo
1192 | if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
1193 | state->undo_point = 0;
1194 | state->undo_char_point = 0;
1195 | return NULL;
1196 | }
1197 |
1198 | // if we don't have enough free characters in the buffer, we have to make room
1199 | while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
1200 | stb_textedit_discard_undo(state);
1201 |
1202 | return &state->undo_rec[state->undo_point++];
1203 | }
1204 |
1205 | static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
1206 | {
1207 | StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
1208 | if (r == NULL)
1209 | return NULL;
1210 |
1211 | r->where = pos;
1212 | r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
1213 | r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
1214 |
1215 | if (insert_len == 0) {
1216 | r->char_storage = -1;
1217 | return NULL;
1218 | } else {
1219 | r->char_storage = state->undo_char_point;
1220 | state->undo_char_point += insert_len;
1221 | return &state->undo_char[r->char_storage];
1222 | }
1223 | }
1224 |
1225 | static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
1226 | {
1227 | StbUndoState *s = &state->undostate;
1228 | StbUndoRecord u, *r;
1229 | if (s->undo_point == 0)
1230 | return;
1231 |
1232 | // we need to do two things: apply the undo record, and create a redo record
1233 | u = s->undo_rec[s->undo_point-1];
1234 | r = &s->undo_rec[s->redo_point-1];
1235 | r->char_storage = -1;
1236 |
1237 | r->insert_length = u.delete_length;
1238 | r->delete_length = u.insert_length;
1239 | r->where = u.where;
1240 |
1241 | if (u.delete_length) {
1242 | // if the undo record says to delete characters, then the redo record will
1243 | // need to re-insert the characters that get deleted, so we need to store
1244 | // them.
1245 |
1246 | // there are three cases:
1247 | // there's enough room to store the characters
1248 | // characters stored for *redoing* don't leave room for redo
1249 | // characters stored for *undoing* don't leave room for redo
1250 | // if the last is true, we have to bail
1251 |
1252 | if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
1253 | // the undo records take up too much character space; there's no space to store the redo characters
1254 | r->insert_length = 0;
1255 | } else {
1256 | int i;
1257 |
1258 | // there's definitely room to store the characters eventually
1259 | while (s->undo_char_point + u.delete_length > s->redo_char_point) {
1260 | // should never happen:
1261 | if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
1262 | return;
1263 | // there's currently not enough room, so discard a redo record
1264 | stb_textedit_discard_redo(s);
1265 | }
1266 | r = &s->undo_rec[s->redo_point-1];
1267 |
1268 | r->char_storage = s->redo_char_point - u.delete_length;
1269 | s->redo_char_point = s->redo_char_point - u.delete_length;
1270 |
1271 | // now save the characters
1272 | for (i=0; i < u.delete_length; ++i)
1273 | s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i);
1274 | }
1275 |
1276 | // now we can carry out the deletion
1277 | STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length);
1278 | }
1279 |
1280 | // check type of recorded action:
1281 | if (u.insert_length) {
1282 | // easy case: was a deletion, so we need to insert n characters
1283 | STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length);
1284 | s->undo_char_point -= u.insert_length;
1285 | }
1286 |
1287 | state->cursor = u.where + u.insert_length;
1288 |
1289 | s->undo_point--;
1290 | s->redo_point--;
1291 | }
1292 |
1293 | static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
1294 | {
1295 | StbUndoState *s = &state->undostate;
1296 | StbUndoRecord *u, r;
1297 | if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
1298 | return;
1299 |
1300 | // we need to do two things: apply the redo record, and create an undo record
1301 | u = &s->undo_rec[s->undo_point];
1302 | r = s->undo_rec[s->redo_point];
1303 |
1304 | // we KNOW there must be room for the undo record, because the redo record
1305 | // was derived from an undo record
1306 |
1307 | u->delete_length = r.insert_length;
1308 | u->insert_length = r.delete_length;
1309 | u->where = r.where;
1310 | u->char_storage = -1;
1311 |
1312 | if (r.delete_length) {
1313 | // the redo record requires us to delete characters, so the undo record
1314 | // needs to store the characters
1315 |
1316 | if (s->undo_char_point + u->insert_length > s->redo_char_point) {
1317 | u->insert_length = 0;
1318 | u->delete_length = 0;
1319 | } else {
1320 | int i;
1321 | u->char_storage = s->undo_char_point;
1322 | s->undo_char_point = s->undo_char_point + u->insert_length;
1323 |
1324 | // now save the characters
1325 | for (i=0; i < u->insert_length; ++i)
1326 | s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i);
1327 | }
1328 |
1329 | STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length);
1330 | }
1331 |
1332 | if (r.insert_length) {
1333 | // easy case: need to insert n characters
1334 | STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
1335 | s->redo_char_point += r.insert_length;
1336 | }
1337 |
1338 | state->cursor = r.where + r.insert_length;
1339 |
1340 | s->undo_point++;
1341 | s->redo_point++;
1342 | }
1343 |
1344 | static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length)
1345 | {
1346 | stb_text_createundo(&state->undostate, where, 0, length);
1347 | }
1348 |
1349 | static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
1350 | {
1351 | int i;
1352 | STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
1353 | if (p) {
1354 | for (i=0; i < length; ++i)
1355 | p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
1356 | }
1357 | }
1358 |
1359 | static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
1360 | {
1361 | int i;
1362 | STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
1363 | if (p) {
1364 | for (i=0; i < old_length; ++i)
1365 | p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
1366 | }
1367 | }
1368 |
1369 | // reset the state to default
1370 | static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line)
1371 | {
1372 | state->undostate.undo_point = 0;
1373 | state->undostate.undo_char_point = 0;
1374 | state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
1375 | state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
1376 | state->select_end = state->select_start = 0;
1377 | state->cursor = 0;
1378 | state->has_preferred_x = 0;
1379 | state->preferred_x = 0;
1380 | state->cursor_at_end_of_line = 0;
1381 | state->initialized = 1;
1382 | state->single_line = (unsigned char) is_single_line;
1383 | state->insert_mode = 0;
1384 | state->row_count_per_page = 0;
1385 | }
1386 |
1387 | // API initialize
1388 | static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line)
1389 | {
1390 | stb_textedit_clear_state(state, is_single_line);
1391 | }
1392 |
1393 | #if defined(__GNUC__) || defined(__clang__)
1394 | #pragma GCC diagnostic push
1395 | #pragma GCC diagnostic ignored "-Wcast-qual"
1396 | #endif
1397 |
1398 | static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
1399 | {
1400 | return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
1401 | }
1402 |
1403 | #if defined(__GNUC__) || defined(__clang__)
1404 | #pragma GCC diagnostic pop
1405 | #endif
1406 |
1407 | #endif//STB_TEXTEDIT_IMPLEMENTATION
1408 |
1409 | /*
1410 | ------------------------------------------------------------------------------
1411 | This software is available under 2 licenses -- choose whichever you prefer.
1412 | ------------------------------------------------------------------------------
1413 | ALTERNATIVE A - MIT License
1414 | Copyright (c) 2017 Sean Barrett
1415 | Permission is hereby granted, free of charge, to any person obtaining a copy of
1416 | this software and associated documentation files (the "Software"), to deal in
1417 | the Software without restriction, including without limitation the rights to
1418 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1419 | of the Software, and to permit persons to whom the Software is furnished to do
1420 | so, subject to the following conditions:
1421 | The above copyright notice and this permission notice shall be included in all
1422 | copies or substantial portions of the Software.
1423 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1424 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1425 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1426 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1427 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1428 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1429 | SOFTWARE.
1430 | ------------------------------------------------------------------------------
1431 | ALTERNATIVE B - Public Domain (www.unlicense.org)
1432 | This is free and unencumbered software released into the public domain.
1433 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
1434 | software, either in source code form or as a compiled binary, for any purpose,
1435 | commercial or non-commercial, and by any means.
1436 | In jurisdictions that recognize copyright laws, the author or authors of this
1437 | software dedicate any and all copyright interest in the software to the public
1438 | domain. We make this dedication for the benefit of the public at large and to
1439 | the detriment of our heirs and successors. We intend this dedication to be an
1440 | overt act of relinquishment in perpetuity of all present and future rights to
1441 | this software under copyright law.
1442 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1443 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1444 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1445 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1446 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1447 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1448 | ------------------------------------------------------------------------------
1449 | */
1450 |
--------------------------------------------------------------------------------
/TempleWare-External/source/config/config.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _CRT_SECURE_NO_WARNINGS
4 |
5 | #include
6 | #include
7 | #include "../globals/globals.h"
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | namespace config
15 | {
16 | class ConfigSystem
17 | {
18 | private:
19 | static std::filesystem::path GetConfigFolder()
20 | {
21 | char* userProfile = nullptr;
22 | size_t len = 0;
23 | errno_t err = _dupenv_s(&userProfile, &len, "USERPROFILE");
24 |
25 | std::filesystem::path folder;
26 | if (err != 0 || userProfile == nullptr || len == 0)
27 | {
28 | folder = ".templeware";
29 | }
30 | else
31 | {
32 | folder = userProfile;
33 | free(userProfile);
34 | folder /= ".templeware";
35 | }
36 |
37 | folder /= "external";
38 |
39 | std::error_code ec;
40 | std::filesystem::create_directories(folder, ec);
41 |
42 | return folder;
43 | }
44 |
45 | static std::filesystem::path GetConfigPath(const std::string& configName)
46 | {
47 | auto folder = GetConfigFolder();
48 | return folder / (configName + ".json");
49 | }
50 |
51 | public:
52 |
53 | static std::vector ListConfigs()
54 | {
55 | std::vector list;
56 | auto folder = GetConfigFolder();
57 |
58 | if (!std::filesystem::exists(folder))
59 | return list;
60 |
61 | for (auto& entry : std::filesystem::directory_iterator(folder))
62 | {
63 | if (entry.is_regular_file())
64 | {
65 | auto path = entry.path();
66 | if (path.extension() == ".json")
67 | {
68 | list.push_back(path.stem().string());
69 | }
70 | }
71 | }
72 | return list;
73 | }
74 |
75 | static void Save(const std::string& configName)
76 | {
77 | nlohmann::json j;
78 | j["TriggerBot"] = globals::TriggerBot;
79 | j["TriggerBotKey"] = globals::TriggerBotKey;
80 | j["TriggerBotKeyName"] = std::string(globals::TriggerBotKeyName);
81 | j["TriggerBotMode"] = globals::TriggerBotMode;
82 | j["TriggerBotDelay"] = globals::TriggerBotDelay;
83 | j["TriggerBotToggled"] = globals::TriggerBotToggled;
84 | j["TriggerBotTeamCheck"] = globals::TriggerBotTeamCheck;
85 | j["TriggerBotIgnoreFlash"] = globals::TriggerBotIgnoreFlash;
86 |
87 | j["FOV"] = globals::FOV;
88 | j["Glow"] = globals::Glow;
89 |
90 | j["GlowColor"] = {
91 | globals::GlowColor.x,
92 | globals::GlowColor.y,
93 | globals::GlowColor.z,
94 | globals::GlowColor.w
95 | };
96 |
97 | j["MenuAccentColor"] = {
98 | globals::MenuAccentColor.x,
99 | globals::MenuAccentColor.y,
100 | globals::MenuAccentColor.z,
101 | globals::MenuAccentColor.w
102 | };
103 |
104 | j["NoFlashEnabled"] = globals::NoFlashEnabled;
105 | j["BunnyHopEnabled"] = globals::BunnyHopEnabled;
106 |
107 | auto filePath = GetConfigPath(configName);
108 | std::ofstream ofs(filePath);
109 | if (ofs.is_open())
110 | {
111 | ofs << j.dump(4);
112 | ofs.close();
113 | }
114 | }
115 |
116 | static void Load(const std::string& configName)
117 | {
118 | auto filePath = GetConfigPath(configName);
119 | if (!std::filesystem::exists(filePath))
120 | return;
121 |
122 | std::ifstream ifs(filePath);
123 | if (!ifs.is_open())
124 | return;
125 |
126 | nlohmann::json j;
127 | ifs >> j;
128 |
129 | globals::TriggerBot = j.value("TriggerBot", false);
130 | globals::TriggerBotKey = j.value("TriggerBotKey", VK_LSHIFT);
131 | {
132 | auto keyNameString = j.value("TriggerBotKeyName", std::string("L-Shift"));
133 | std::snprintf(globals::TriggerBotKeyName, sizeof(globals::TriggerBotKeyName), "%s", keyNameString.c_str());
134 | }
135 | globals::TriggerBotMode = j.value("TriggerBotMode", 0);
136 | globals::TriggerBotDelay = j.value("TriggerBotDelay", 20);
137 | globals::TriggerBotToggled = j.value("TriggerBotToggled", false);
138 | globals::TriggerBotTeamCheck = j.value("TriggerBotTeamCheck", true);
139 | globals::TriggerBotIgnoreFlash = j.value("TriggerBotIgnoreFlash", false);
140 |
141 | globals::FOV = j.value("FOV", 90);
142 | globals::Glow = j.value("Glow", false);
143 |
144 | if (j.contains("GlowColor") && j["GlowColor"].is_array())
145 | {
146 | auto arr = j["GlowColor"];
147 | if (arr.size() == 4)
148 | {
149 | globals::GlowColor.x = arr[0].get();
150 | globals::GlowColor.y = arr[1].get();
151 | globals::GlowColor.z = arr[2].get();
152 | globals::GlowColor.w = arr[3].get();
153 | }
154 | }
155 | globals::NoFlashEnabled = j.value("NoFlashEnabled", false);
156 | globals::BunnyHopEnabled = j.value("BunnyHopEnabled", false);
157 |
158 | if (j.contains("MenuAccentColor") && j["MenuAccentColor"].is_array())
159 | {
160 | auto arr = j["MenuAccentColor"];
161 | if (arr.size() == 4)
162 | {
163 | globals::MenuAccentColor.x = arr[0].get();
164 | globals::MenuAccentColor.y = arr[1].get();
165 | globals::MenuAccentColor.z = arr[2].get();
166 | globals::MenuAccentColor.w = arr[3].get();
167 | }
168 | }
169 | ifs.close();
170 | }
171 |
172 | static void Remove(const std::string& configName)
173 | {
174 | auto filePath = GetConfigPath(configName);
175 | if (std::filesystem::exists(filePath))
176 | {
177 | std::error_code ec;
178 | std::filesystem::remove(filePath, ec);
179 | }
180 | }
181 | };
182 | }
183 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/bhop.cpp:
--------------------------------------------------------------------------------
1 | #include "bhop.h"
2 | #include "../offsets/offsets.h"
3 | #include "../globals/globals.h"
4 |
5 | namespace features
6 | {
7 | void Bhop::Run(const Memory& memory) noexcept
8 | {
9 | if (!globals::BunnyHopEnabled)
10 | return;
11 |
12 | std::uintptr_t localPlayer = memory.Read(globals::client + offsets::dwLocalPlayerPawn);
13 | if (localPlayer == 0)
14 | return;
15 |
16 | HWND hwnd_cs2 = FindWindowA(NULL, "Counter-Strike 2");
17 | if (hwnd_cs2 == NULL)
18 | hwnd_cs2 = FindWindowA(NULL, "Counter-Strike 2");
19 |
20 | bool spacePressed = GetAsyncKeyState(VK_SPACE);
21 | int flags = memory.Read(localPlayer + offsets::m_fFlags);
22 | bool isInAir = flags & (int)1 << 0;
23 |
24 | if (spacePressed && isInAir)
25 | {
26 | SendMessage(hwnd_cs2, WM_KEYUP, VK_SPACE, 0);
27 | SendMessage(hwnd_cs2, WM_KEYDOWN, VK_SPACE, 0);
28 | }
29 | else if (spacePressed && !isInAir)
30 | SendMessage(hwnd_cs2, WM_KEYUP, VK_SPACE, 0);
31 | else if (!spacePressed)
32 | SendMessage(hwnd_cs2, WM_KEYUP, VK_SPACE, 0);
33 | }
34 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/features/bhop.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../memory/memory.h"
3 | #include
4 | #include
5 | #include
6 |
7 | namespace features
8 | {
9 | class Bhop
10 | {
11 | public:
12 | static void Run(const Memory& memory) noexcept;
13 |
14 | };
15 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/features/fov.cpp:
--------------------------------------------------------------------------------
1 | #include "fov.h"
2 | #include "../globals/globals.h"
3 | #include "../offsets/offsets.h"
4 | #include
5 |
6 | namespace features
7 | {
8 | void FOVManager::AdjustFOV(const Memory& memory) noexcept
9 | {
10 | if (globals::lastFOV != globals::FOV)
11 | {
12 | std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 | }
14 |
15 | globals::lastFOV = globals::FOV;
16 |
17 | std::uintptr_t localPlayer = memory.Read(globals::client + offsets::dwLocalPlayerPawn);
18 | if (!localPlayer)
19 | return;
20 |
21 | std::uintptr_t cameraServices = memory.Read(localPlayer + offsets::m_pCameraServices);
22 | if (!cameraServices)
23 | return;
24 |
25 | std::uint16_t currentFov = memory.Read(cameraServices + offsets::m_iFOV);
26 | bool isScoped = memory.Read(localPlayer + offsets::m_bIsScoped);
27 | std::uint16_t desiredFov = static_cast(globals::lastFOV);
28 |
29 | if (!isScoped && currentFov != desiredFov)
30 | memory.Write(cameraServices + offsets::m_iFOV, desiredFov);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/fov.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../memory/Memory.h"
4 |
5 | namespace features
6 | {
7 | class FOVManager
8 | {
9 | public:
10 | static void AdjustFOV(const Memory& memory) noexcept;
11 |
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/glow.cpp:
--------------------------------------------------------------------------------
1 | #include "glow.h"
2 | #include "../globals/globals.h"
3 | #include "../offsets/offsets.h"
4 | #include
5 |
6 | namespace features {
7 | void Glow::Run(const Memory& memory) noexcept
8 | {
9 | if (!globals::Glow) return;
10 |
11 | const uintptr_t localPlayerController = memory.Read(globals::client + offsets::dwLocalPlayerController);
12 | if (!localPlayerController) return;
13 |
14 | const int localTeam = memory.Read(localPlayerController + offsets::m_iTeamNum);
15 | const uintptr_t entityList = memory.Read(globals::client + offsets::dwEntityList);
16 | if (!entityList) return;
17 |
18 | for (int i = 1; i < 64; ++i) {
19 | const uintptr_t listEntry = memory.Read(entityList + ((8 * (i & 0x7FFF)) >> 9) + 16);
20 | if (!listEntry) continue;
21 |
22 | const uintptr_t player = memory.Read(listEntry + 120 * (i & 0x1FF));
23 | if (!player) continue;
24 |
25 | const int playerTeam = memory.Read(player + offsets::m_iTeamNum);
26 | if (playerTeam == localTeam) continue;
27 |
28 | const uint32_t playerPawn = memory.Read(player + offsets::m_hPlayerPawn);
29 | if (!playerPawn) continue;
30 |
31 | const uintptr_t listEntry2 = memory.Read(entityList + ((8 * (playerPawn & 0x7FFF)) >> 9) + 16);
32 | if (!listEntry2) continue;
33 |
34 | const uintptr_t playerCsPawn = memory.Read(listEntry2 + 120 * (playerPawn & 0x1FF));
35 | if (!playerCsPawn) continue;
36 |
37 | const int health = memory.Read(playerCsPawn + offsets::m_iHealth);
38 | if (health < 1) continue;
39 |
40 | const ImVec4& color = globals::GlowColor;
41 | const DWORD colorArgb = (
42 | (static_cast(color.w * 255) << 24) |
43 | (static_cast(color.z * 255) << 16) |
44 | (static_cast(color.y * 255) << 8) |
45 | static_cast(color.x * 255)
46 | );
47 |
48 | const uintptr_t glowOffset = playerCsPawn + offsets::m_Glow;
49 | memory.Write(glowOffset + offsets::m_glowColorOverride, colorArgb);
50 | memory.Write(glowOffset + offsets::m_bGlowing, 1);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/glow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../memory/memory.h"
4 |
5 | namespace features
6 | {
7 | class Glow
8 | {
9 | public:
10 | static void Run(const Memory& memory) noexcept;
11 |
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/noflash.cpp:
--------------------------------------------------------------------------------
1 | #include "NoFlash.h"
2 | #include "../globals/globals.h"
3 | #include "../offsets/offsets.h"
4 |
5 | namespace features
6 | {
7 |
8 | void NoFlash::Run(const Memory& memory) noexcept
9 | {
10 | if (globals::NoFlashEnabled)
11 | {
12 | std::uintptr_t localPlayer = memory.Read(globals::client + offsets::dwLocalPlayerPawn);
13 |
14 | if (localPlayer)
15 | {
16 | float flashDuration = memory.Read(localPlayer + offsets::flFlashDuration);
17 | if (flashDuration > 0.0f)
18 | memory.Write(localPlayer + offsets::flFlashDuration, 0.0f);
19 | }
20 | }
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/noflash.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../memory/Memory.h"
4 |
5 | namespace features
6 | {
7 | class NoFlash
8 | {
9 | public:
10 | static void Run(const Memory& memory) noexcept;
11 |
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/TempleWare-External/source/features/triggerbot.cpp:
--------------------------------------------------------------------------------
1 | #include "TriggerBot.h"
2 | #include "../globals/globals.h"
3 | #include "../offsets/offsets.h"
4 | #include
5 | #include
6 |
7 | namespace features
8 | {
9 | void TriggerBot::Run(const Memory& memory) noexcept {
10 | while (globals::isRunning)
11 | {
12 | if (!globals::TriggerBot)
13 | {
14 | std::this_thread::sleep_for(std::chrono::milliseconds(20));
15 | continue;
16 | }
17 |
18 | bool keyDown = (GetAsyncKeyState(globals::TriggerBotKey) & 0x8000) != 0;
19 | if (globals::TriggerBotMode == 0)
20 | {
21 | if (!keyDown)
22 | {
23 | std::this_thread::sleep_for(std::chrono::milliseconds(10));
24 | continue;
25 | }
26 | }
27 | else if (globals::TriggerBotMode == 1)
28 | {
29 | if (keyDown)
30 | {
31 | globals::TriggerBotToggled = !globals::TriggerBotToggled;
32 | std::this_thread::sleep_for(std::chrono::milliseconds(200));
33 | }
34 |
35 | if (!globals::TriggerBotToggled)
36 | {
37 | std::this_thread::sleep_for(std::chrono::milliseconds(10));
38 | continue;
39 | }
40 | }
41 |
42 | std::uintptr_t localPlayer = memory.Read(globals::client + offsets::dwLocalPlayerPawn);
43 | BYTE team = memory.Read(localPlayer + offsets::m_iTeamNum);
44 |
45 | if (!globals::TriggerBotIgnoreFlash)
46 | {
47 | float flashDuration = memory.Read(localPlayer + offsets::flFlashDuration);
48 | if (flashDuration > 0.0f) {
49 | std::this_thread::sleep_for(std::chrono::milliseconds(10));
50 | continue;
51 | }
52 | }
53 |
54 | int crosshairEntityIndex = memory.Read(localPlayer + offsets::m_iIDEntIndex);
55 | if (crosshairEntityIndex == 0)
56 | continue;
57 |
58 | std::uintptr_t entityList = memory.Read(globals::client + offsets::dwEntityList);
59 | std::uintptr_t entity = memory.Read(memory.Read(entityList + 0x8 * (crosshairEntityIndex >> 9) + 0x10) + 120 * (crosshairEntityIndex & 0x1ff));
60 | if (!entity)
61 | continue;
62 |
63 | // Skip teammate or dead target (optional)
64 | if (globals::TriggerBotTeamCheck && team == memory.Read(entity + offsets::m_iTeamNum))
65 | continue;
66 |
67 | if (memory.Read(entity + offsets::m_iHealth) <= 0)
68 | continue;
69 |
70 | // Simulate shooting
71 | memory.Write(globals::client + offsets::attack, 65537); // Set attack command
72 | std::this_thread::sleep_for(std::chrono::milliseconds(globals::TriggerBotDelay));
73 | memory.Write(globals::client + offsets::attack, 256); // Clear attack command
74 | std::this_thread::sleep_for(std::chrono::milliseconds(globals::TriggerBotDelay));
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/features/triggerbot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../memory/Memory.h"
4 |
5 | namespace features
6 | {
7 | class TriggerBot
8 | {
9 | public:
10 | static void Run(const Memory& memory) noexcept;
11 |
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/TempleWare-External/source/globals/globals.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "../../external/imgui/imgui.h"
8 |
9 | namespace globals
10 | {
11 |
12 | // TriggerBot
13 | inline bool TriggerBot = false;
14 | inline int TriggerBotKey = VK_LSHIFT;
15 | inline char TriggerBotKeyName[64] = "L-Shift";
16 | inline int TriggerBotMode = 0;
17 | inline int TriggerBotDelay = 20;
18 | inline bool TriggerBotToggled = false;
19 | inline bool TriggerBotTeamCheck = true;
20 | inline bool TriggerBotIgnoreFlash = false;
21 |
22 | // Fov
23 | inline int FOV = 90;
24 | inline int lastFOV = 90;
25 |
26 | // Glow
27 | inline bool Glow = false;
28 | inline ImVec4 GlowColor = ImVec4(0.0f, 0.0f, 1.0f, 1.0f);
29 |
30 | // NoFlash
31 | inline bool NoFlashEnabled = false;
32 |
33 | // Application state
34 | inline bool isRunning = true;
35 | inline std::uintptr_t client = 0;
36 |
37 | // Misc
38 | inline bool BunnyHopEnabled = false;
39 |
40 | // Menu
41 | inline bool MenuVisible = true;
42 | inline int ShowMenuKey = VK_END;
43 | inline ImVec4 MenuAccentColor = ImVec4(0.0f, 0.4f, 1.0f, 1.0f);
44 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/main.cpp:
--------------------------------------------------------------------------------
1 | /************************************************************************************************
2 | * Temple Cheat *
3 | * (c) 2023-2024 Temple Client Cheats Team. All rights reserved. *
4 | ************************************************************************************************/
5 |
6 | #include "menu/menu.h"
7 | #include "memory/memory.h"
8 | #include "globals/globals.h"
9 | #include "threads/threads.h"
10 | #include "offsets/offsets.h"
11 |
12 | #include
13 |
14 | int __stdcall wWinMain(HINSTANCE instance, HINSTANCE previousInstance, PWSTR arguments, int commandShow)
15 | {
16 | if (!offsets::UpdateOffset())
17 | return EXIT_FAILURE;
18 |
19 | const auto memory = Memory("cs2.exe");
20 |
21 | globals::client = memory.GetModuleAddress("client.dll");
22 |
23 | std::thread(threads::RunMiscThread, std::ref(memory)).detach();
24 | std::thread(threads::RunVisualThread, std::ref(memory)).detach();
25 | std::thread(threads::RunAimThread, std::ref(memory)).detach();
26 |
27 | gui::CreateHWindow("templecheats.xyz");
28 | gui::CreateDevice();
29 | gui::CreateImGui();
30 |
31 | bool windowVisible = true;
32 |
33 | while (globals::isRunning)
34 | {
35 | if (GetAsyncKeyState(VK_END) & 0x8000)
36 | {
37 | windowVisible = !windowVisible;
38 | ShowWindow(gui::window, windowVisible ? SW_SHOW : SW_HIDE);
39 | std::this_thread::sleep_for(std::chrono::milliseconds(200));
40 | }
41 |
42 | if (windowVisible)
43 | {
44 | gui::BeginRender();
45 | gui::Render();
46 | gui::EndRender();
47 | }
48 | else
49 | std::this_thread::sleep_for(std::chrono::milliseconds(50));
50 | }
51 |
52 | gui::DestroyImGui();
53 | gui::DestroyDevice();
54 | gui::DestroyHWindow();
55 |
56 | return EXIT_SUCCESS;
57 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/memory/memory.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | class Memory {
9 | private:
10 | std::uintptr_t processId_;
11 | HANDLE processHandle_;
12 |
13 | public:
14 | Memory(const std::string& processName) noexcept
15 | {
16 | PROCESSENTRY32 entry = { sizeof(PROCESSENTRY32) };
17 | auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
18 |
19 | while (Process32Next(snapshot, &entry))
20 | {
21 | if (entry.szExeFile == processName)
22 | {
23 | processId_ = entry.th32ProcessID;
24 | processHandle_ = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId_);
25 | break;
26 | }
27 | }
28 |
29 | CloseHandle(snapshot);
30 | }
31 |
32 | ~Memory() noexcept
33 | {
34 | if (processHandle_)
35 | CloseHandle(processHandle_);
36 | }
37 |
38 | std::uintptr_t GetModuleAddress(const std::string& moduleName) const noexcept
39 | {
40 | MODULEENTRY32 entry = { sizeof(MODULEENTRY32) };
41 | auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId_);
42 | std::uintptr_t result = 0;
43 |
44 | while (Module32Next(snapshot, &entry))
45 | {
46 | if (entry.szModule == moduleName)
47 | {
48 | result = reinterpret_cast(entry.modBaseAddr);
49 | break;
50 | }
51 | }
52 |
53 | CloseHandle(snapshot);
54 | return result;
55 | }
56 |
57 | template
58 | T Read(const std::uintptr_t& address) const noexcept
59 | {
60 | T value;
61 | SIZE_T bytesRead;
62 | ReadProcessMemory(processHandle_, reinterpret_cast(address), &value, sizeof(T), &bytesRead);
63 | return value;
64 | }
65 |
66 | template
67 | void Write(const std::uintptr_t& address, const T& value) const noexcept
68 | {
69 | SIZE_T bytesWritten;
70 | WriteProcessMemory(processHandle_, reinterpret_cast(address), &value, sizeof(T), &bytesWritten);
71 | }
72 | };
--------------------------------------------------------------------------------
/TempleWare-External/source/menu/menu.cpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include "../globals/globals.h"
7 | #include "../config/config.h"
8 | #include "../../external/imgui/imgui.h"
9 | #include "../../external/imgui/imgui_impl_dx9.h"
10 | #include "../../external/imgui/imgui_impl_win32.h"
11 |
12 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(
13 | HWND, UINT, WPARAM, LPARAM
14 | );
15 |
16 | namespace gui
17 | {
18 |
19 | constexpr int WIDTH = 500;
20 | constexpr int HEIGHT = 300;
21 |
22 | inline bool isRunning = true;
23 | inline HWND window = nullptr;
24 | inline WNDCLASSEX windowClass = { };
25 | inline POINTS position = { };
26 |
27 | inline PDIRECT3D9 d3d = nullptr;
28 | inline LPDIRECT3DDEVICE9 device = nullptr;
29 | inline D3DPRESENT_PARAMETERS presentParameters = { };
30 |
31 | void CreateHWindow(const char* windowName) noexcept;
32 | void DestroyHWindow() noexcept;
33 | bool CreateDevice() noexcept;
34 | void ResetDevice() noexcept;
35 | void DestroyDevice() noexcept;
36 | void CreateImGui() noexcept;
37 | void DestroyImGui() noexcept;
38 | void BeginRender() noexcept;
39 | void EndRender() noexcept;
40 | void Render() noexcept;
41 |
42 | void SetupImGuiStyle() noexcept;
43 | void ApplyCustomStyle() noexcept;
44 |
45 | static std::string GetKeyName(int vk)
46 | {
47 | UINT scanCode = MapVirtualKeyA(vk, MAPVK_VK_TO_VSC);
48 | char keyName[128];
49 | if (GetKeyNameTextA(scanCode << 16, keyName, sizeof(keyName)) > 0)
50 | return std::string(keyName);
51 | return "Unknown";
52 | }
53 |
54 | LRESULT CALLBACK WindowProcess(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
55 | {
56 | if (ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam))
57 | return true;
58 |
59 | switch (msg)
60 | {
61 | case WM_SIZE:
62 | if (device && wParam != SIZE_MINIMIZED)
63 | {
64 | presentParameters.BackBufferWidth = LOWORD(lParam);
65 | presentParameters.BackBufferHeight = HIWORD(lParam);
66 | ResetDevice();
67 | }
68 | return 0;
69 | case WM_SYSCOMMAND:
70 |
71 | if ((wParam & 0xfff0) == SC_KEYMENU)
72 | return 0;
73 | break;
74 | case WM_DESTROY:
75 | PostQuitMessage(0);
76 | return 0;
77 | case WM_LBUTTONDOWN:
78 | position = MAKEPOINTS(lParam);
79 | return 0;
80 | case WM_MOUSEMOVE:
81 | if (wParam == MK_LBUTTON)
82 | {
83 | const auto points = MAKEPOINTS(lParam);
84 | RECT rect = { };
85 | GetWindowRect(window, &rect);
86 |
87 | rect.left += points.x - position.x;
88 | rect.top += points.y - position.y;
89 |
90 | if (position.x >= 0 && position.x <= WIDTH &&
91 | position.y >= 0 && position.y <= 19)
92 | {
93 | SetWindowPos(window, HWND_TOPMOST, rect.left, rect.top, 0, 0,
94 | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER);
95 | }
96 | }
97 | return 0;
98 | }
99 | return DefWindowProc(hwnd, msg, wParam, lParam);
100 | }
101 |
102 | void CreateHWindow(const char* windowName) noexcept
103 | {
104 | WNDCLASSEXA wc = { sizeof(WNDCLASSEXA), CS_CLASSDC, WindowProcess, 0L, 0L,
105 | GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr,
106 | "ObelusClass", nullptr };
107 | RegisterClassExA(&wc);
108 |
109 | window = CreateWindowExA(
110 | 0, "ObelusClass", windowName,
111 | WS_POPUP, 100, 100, WIDTH, HEIGHT,
112 | 0, 0, wc.hInstance, 0
113 | );
114 |
115 | SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0,
116 | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
117 |
118 | ShowWindow(window, SW_SHOWDEFAULT);
119 | UpdateWindow(window);
120 | }
121 |
122 | void DestroyHWindow() noexcept
123 | {
124 | DestroyWindow(window);
125 | UnregisterClassA("ObelusClass", GetModuleHandle(nullptr));
126 | }
127 |
128 | bool CreateDevice() noexcept
129 | {
130 | d3d = Direct3DCreate9(D3D_SDK_VERSION);
131 | if (!d3d) return false;
132 |
133 | ZeroMemory(&presentParameters, sizeof(presentParameters));
134 | presentParameters.Windowed = TRUE;
135 | presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
136 | presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
137 | presentParameters.EnableAutoDepthStencil = TRUE;
138 | presentParameters.AutoDepthStencilFormat = D3DFMT_D16;
139 | presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
140 |
141 | if (d3d->CreateDevice(D3DADAPTER_DEFAULT,
142 | D3DDEVTYPE_HAL,
143 | window,
144 | D3DCREATE_HARDWARE_VERTEXPROCESSING,
145 | &presentParameters,
146 | &device) < 0)
147 | {
148 | return false;
149 | }
150 | return true;
151 | }
152 |
153 | void ResetDevice() noexcept
154 | {
155 | ImGui_ImplDX9_InvalidateDeviceObjects();
156 | if (device->Reset(&presentParameters) == D3DERR_INVALIDCALL)
157 | IM_ASSERT(0);
158 | ImGui_ImplDX9_CreateDeviceObjects();
159 | }
160 |
161 | void DestroyDevice() noexcept
162 | {
163 | if (device) { device->Release(); device = nullptr; }
164 | if (d3d) { d3d->Release(); d3d = nullptr; }
165 | }
166 |
167 | void CreateImGui() noexcept
168 | {
169 | IMGUI_CHECKVERSION();
170 | ImGui::CreateContext();
171 | ImGuiIO& io = ImGui::GetIO();
172 | io.Fonts->AddFontDefault();
173 | (void)io;
174 |
175 | ImFontAtlas* fontAtlas = new ImFontAtlas();
176 | ImFontConfig arialConfig;
177 | arialConfig.FontDataOwnedByAtlas = false;
178 |
179 | const char* fontPath = "C:\\Windows\\Fonts\\segoeui.ttf";
180 | float fontSize = 18.0f;
181 | ImFont* arialFont = fontAtlas->AddFontFromFileTTF(fontPath,fontSize, &arialConfig);
182 | io.Fonts = fontAtlas;
183 |
184 | ImGui::StyleColorsDark();
185 |
186 | ImGui_ImplWin32_Init(window);
187 | ImGui_ImplDX9_Init(device);
188 |
189 | SetupImGuiStyle();
190 | }
191 |
192 | void DestroyImGui() noexcept
193 | {
194 | ImGui_ImplDX9_Shutdown();
195 | ImGui_ImplWin32_Shutdown();
196 | ImGui::DestroyContext();
197 | }
198 |
199 | void BeginRender() noexcept
200 | {
201 | MSG msg;
202 | while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
203 | {
204 | TranslateMessage(&msg);
205 | DispatchMessage(&msg);
206 |
207 | if (msg.message == WM_QUIT)
208 | {
209 | isRunning = false;
210 | return;
211 | }
212 | }
213 |
214 | ImGui_ImplDX9_NewFrame();
215 | ImGui_ImplWin32_NewFrame();
216 | ImGui::NewFrame();
217 | }
218 |
219 | void EndRender() noexcept
220 | {
221 | ImGui::EndFrame();
222 |
223 | device->SetRenderState(D3DRS_ZENABLE, FALSE);
224 | device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
225 | device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
226 |
227 | device->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
228 | D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0);
229 |
230 | if (device->BeginScene() >= 0)
231 | {
232 | ImGui::Render();
233 | ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
234 | device->EndScene();
235 | }
236 | device->Present(nullptr, nullptr, nullptr, nullptr);
237 | }
238 |
239 | void Render() noexcept
240 | {
241 |
242 | ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
243 | ImGui::SetNextWindowSize(ImVec2(static_cast(WIDTH), static_cast(HEIGHT)), ImGuiCond_Always);
244 |
245 | ImGui::Begin("TempleWare - External templecheats.xyz",
246 | &globals::isRunning,
247 | ImGuiWindowFlags_NoResize |
248 | ImGuiWindowFlags_NoSavedSettings |
249 | ImGuiWindowFlags_NoCollapse |
250 | ImGuiWindowFlags_NoMove |
251 | ImGuiWindowFlags_NoScrollbar
252 | );
253 |
254 | static int currentTab = 0;
255 | {
256 |
257 | if (ImGui::Button("Aim", ImVec2(80, 0))) currentTab = 0; ImGui::SameLine();
258 | if (ImGui::Button("Visuals", ImVec2(80, 0))) currentTab = 1; ImGui::SameLine();
259 | if (ImGui::Button("Misc", ImVec2(80, 0))) currentTab = 2; ImGui::SameLine();
260 | if (ImGui::Button("Config", ImVec2(80, 0))) currentTab = 3;
261 | }
262 |
263 | ImGui::Separator();
264 | ImGui::Spacing();
265 |
266 | ImGui::BeginChild("MainChild", ImGui::GetContentRegionAvail(), true);
267 |
268 | if (currentTab == 0)
269 | {
270 | ImGui::Text("Aimbot / TriggerBot");
271 | ImGui::Separator();
272 | ImGui::Checkbox("TriggerBot", &globals::TriggerBot);
273 |
274 | if (globals::TriggerBot)
275 | {
276 |
277 | ImGui::Text("Trigger Key: ");
278 | ImGui::SameLine();
279 | if (ImGui::Button(globals::TriggerBotKeyName))
280 | {
281 | ImGui::OpenPopup("##SelectTriggerKey");
282 | }
283 | if (ImGui::BeginPopup("##SelectTriggerKey"))
284 | {
285 | ImGuiIO& io = ImGui::GetIO();
286 | ImGui::Text("Press a key to select it...");
287 | for (int i = 0; i < 256; i++)
288 | {
289 | if (ImGui::IsKeyPressed(i))
290 | {
291 | globals::TriggerBotKey = i;
292 | std::string keyName = GetKeyName(i);
293 | snprintf(globals::TriggerBotKeyName, sizeof(globals::TriggerBotKeyName), "%s", keyName.c_str());
294 | ImGui::CloseCurrentPopup();
295 | }
296 | }
297 | ImGui::EndPopup();
298 | }
299 |
300 | const char* modeItems[] = { "Hold", "Toggle" };
301 | ImGui::Combo("Mode", &globals::TriggerBotMode, modeItems, IM_ARRAYSIZE(modeItems));
302 | ImGui::SliderInt("Delay (ms)", &globals::TriggerBotDelay, 1, 1000);
303 | ImGui::Checkbox("TeamCheck", &globals::TriggerBotTeamCheck);
304 | ImGui::Checkbox("IgnoreFlash", &globals::TriggerBotIgnoreFlash);
305 | }
306 | }
307 |
308 | else if (currentTab == 1)
309 | {
310 | ImGui::Text("Visuals");
311 | ImGui::Separator();
312 |
313 | ImGui::SliderInt("FOV", &globals::FOV, 60, 160);
314 | ImGui::Separator();
315 |
316 | ImGui::Checkbox("Glow##enable", &globals::Glow);
317 | if (globals::Glow)
318 | {
319 | ImGui::ColorEdit4("Glow Color", (float*)&globals::GlowColor, ImGuiColorEditFlags_NoInputs);
320 | }
321 | ImGui::Separator();
322 |
323 | ImGui::Checkbox("NoFlash", &globals::NoFlashEnabled);
324 | }
325 |
326 | else if (currentTab == 2)
327 | {
328 | ImGui::Text("Misc");
329 | ImGui::Separator();
330 | ImGui::Checkbox("BunnyHop", &globals::BunnyHopEnabled);
331 | ImGui::Separator();
332 |
333 | ImGui::Separator();
334 | ImGui::Text("Menu Color");
335 | ImGui::ColorEdit4("##MenuAccentColor",
336 | (float*)&globals::MenuAccentColor,
337 | ImGuiColorEditFlags_NoInputs);
338 | }
339 |
340 | else if (currentTab == 3)
341 | {
342 | ImGui::Text("Config");
343 | ImGui::Separator();
344 |
345 | static char configNameBuf[64] = "";
346 |
347 | static std::vector configs;
348 | static int selectedConfigIndex = -1;
349 |
350 | auto refreshConfigs = [&]()
351 | {
352 | configs = config::ConfigSystem::ListConfigs();
353 |
354 | selectedConfigIndex = -1;
355 | };
356 |
357 | if (ImGui::Button("Refresh Config List"))
358 | {
359 | refreshConfigs();
360 | }
361 |
362 | ImGui::Text("Available configs:");
363 | ImGui::SameLine();
364 | if (ImGui::BeginCombo("##ConfigList",
365 | (selectedConfigIndex >= 0 && selectedConfigIndex < (int)configs.size())
366 | ? configs[selectedConfigIndex].c_str()
367 | : "Select config"))
368 | {
369 | for (int i = 0; i < (int)configs.size(); i++)
370 | {
371 | bool isSelected = (selectedConfigIndex == i);
372 | if (ImGui::Selectable(configs[i].c_str(), isSelected))
373 | {
374 | selectedConfigIndex = i;
375 | }
376 | if (isSelected)
377 | ImGui::SetItemDefaultFocus();
378 | }
379 | ImGui::EndCombo();
380 | }
381 |
382 | if (selectedConfigIndex >= 0)
383 | {
384 |
385 | if (ImGui::Button("Load Config"))
386 | {
387 | config::ConfigSystem::Load(configs[selectedConfigIndex]);
388 | }
389 | ImGui::SameLine();
390 |
391 | if (ImGui::Button("Delete Config"))
392 | {
393 | config::ConfigSystem::Remove(configs[selectedConfigIndex]);
394 | refreshConfigs();
395 | }
396 | }
397 |
398 | ImGui::Separator();
399 |
400 | ImGui::Text("Create new config:");
401 | ImGui::InputText("##NewConfigName", configNameBuf, IM_ARRAYSIZE(configNameBuf));
402 | ImGui::SameLine();
403 | if (ImGui::Button("Save Config"))
404 | {
405 |
406 | if (std::strlen(configNameBuf) > 0)
407 | {
408 | config::ConfigSystem::Save(configNameBuf);
409 |
410 | refreshConfigs();
411 | }
412 | }
413 | }
414 |
415 | ImGui::EndChild();
416 | ImGui::End();
417 |
418 | ApplyCustomStyle();
419 | }
420 |
421 | void SetupImGuiStyle() noexcept
422 | {
423 | ImGuiStyle& style = ImGui::GetStyle();
424 |
425 | ImVec4* colors = style.Colors;
426 | colors[ImGuiCol_WindowBg] = ImVec4(0.09f, 0.09f, 0.09f, 1.0f);
427 | colors[ImGuiCol_Border] = ImVec4(0.30f, 0.30f, 0.30f, 1.0f);
428 | colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.16f, 0.16f, 1.0f);
429 | colors[ImGuiCol_FrameBgHovered] = ImVec4(0.24f, 0.24f, 0.24f, 1.0f);
430 | colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.0f);
431 | colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.09f, 0.09f, 1.0f);
432 | colors[ImGuiCol_TitleBgActive] = ImVec4(0.09f, 0.09f, 0.09f, 1.0f);
433 | colors[ImGuiCol_Button] = ImVec4(0.0f, 0.4f, 1.0f, 1.0f);
434 | colors[ImGuiCol_ButtonHovered] = ImVec4(0.0f, 0.5f, 1.0f, 1.0f);
435 | colors[ImGuiCol_ButtonActive] = ImVec4(0.0f, 0.6f, 1.0f, 1.0f);
436 | colors[ImGuiCol_CheckMark] = ImVec4(0.75f, 0.30f, 1.00f, 1.0f);
437 | colors[ImGuiCol_SliderGrab] = ImVec4(0.0f, 0.6f, 1.0f, 1.0f);
438 | colors[ImGuiCol_SliderGrabActive] = ImVec4(0.0f, 0.6f, 1.0f, 1.0f);
439 | colors[ImGuiCol_Header] = ImVec4(0.00f, 0.40f, 1.00f, 1.0f);
440 | colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.35f, 0.90f, 1.0f);
441 | colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.35f, 0.90f, 1.0f);
442 |
443 | }
444 |
445 | void ApplyCustomStyle() noexcept
446 | {
447 |
448 | ImGuiStyle& style = ImGui::GetStyle();
449 |
450 | style.Colors[ImGuiCol_Button] = globals::MenuAccentColor;
451 | style.Colors[ImGuiCol_ButtonHovered] = globals::MenuAccentColor;
452 | style.Colors[ImGuiCol_ButtonActive] = globals::MenuAccentColor;
453 | style.Colors[ImGuiCol_CheckMark] = globals::MenuAccentColor;
454 | style.Colors[ImGuiCol_SliderGrab] = globals::MenuAccentColor;
455 | style.Colors[ImGuiCol_SliderGrabActive] = globals::MenuAccentColor;
456 | style.Colors[ImGuiCol_Header] = globals::MenuAccentColor;
457 | style.Colors[ImGuiCol_HeaderHovered] = globals::MenuAccentColor;
458 | style.Colors[ImGuiCol_HeaderActive] = globals::MenuAccentColor;
459 | }
460 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/menu/menu.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace gui
5 | {
6 |
7 | constexpr int WIDTH = 500;
8 | constexpr int HEIGHT = 300;
9 | inline bool isRunning = true;
10 |
11 | inline HWND window = nullptr;
12 | inline WNDCLASSEX windowClass = {};
13 | inline POINTS position = { };
14 | inline PDIRECT3D9 d3d = nullptr;
15 | inline LPDIRECT3DDEVICE9 device = nullptr;
16 | inline D3DPRESENT_PARAMETERS presentParameters = {};
17 |
18 | void CreateHWindow(const char* windowName) noexcept;
19 | void DestroyHWindow() noexcept;
20 | bool CreateDevice() noexcept;
21 | void ResetDevice() noexcept;
22 | void DestroyDevice() noexcept;
23 |
24 | void CreateImGui() noexcept;
25 | void DestroyImGui() noexcept;
26 | void SetupImGuiStyle() noexcept;
27 | void SetupImGuiFonts() noexcept;
28 |
29 | void BeginRender() noexcept;
30 | void EndRender() noexcept;
31 | void Render() noexcept;
32 | void ApplyCustomStyle() noexcept;
33 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/offsets/offsets.cpp:
--------------------------------------------------------------------------------
1 | #include "offsets.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | bool Get(std::string url, std::string& response)
8 | {
9 | std::string cmd = "curl -s -X GET " + url;
10 |
11 | std::array buffer;
12 | std::unique_ptr pipe(_popen(cmd.c_str(), "r"), _pclose);
13 |
14 | if (!pipe)
15 | return false;
16 |
17 | while (fgets(buffer.data(), static_cast(buffer.size()), pipe.get()) != nullptr)
18 | response += buffer.data();
19 |
20 | std::regex pattern("\\d{3}:");
21 | if (std::regex_search(response, pattern))
22 | return false;
23 |
24 | return true;
25 | }
26 |
27 | bool offsets::UpdateOffset()
28 | {
29 | const std::string offsetsUrl = "https://raw.githubusercontent.com/a2x/cs2-dumper/main/output/offsets.json";
30 | const std::string buttonsUrl = "https://raw.githubusercontent.com/a2x/cs2-dumper/main/output/buttons.json";
31 | const std::string client_dllUrl = "https://raw.githubusercontent.com/a2x/cs2-dumper/main/output/client_dll.json";
32 | std::string offsetsData, buttonsData, client_dllData;
33 |
34 | if (!Get(offsetsUrl, offsetsData) || !Get(buttonsUrl, buttonsData) || !Get(client_dllUrl, client_dllData))
35 | return 0;
36 |
37 | json offsetsJson = json::parse(offsetsData);
38 | json client_dllJson = json::parse(client_dllData)["client.dll"]["classes"];
39 | json buttonsJson = json::parse(buttonsData);
40 |
41 | // Game offsets
42 | dwLocalPlayerPawn= offsetsJson["client.dll"]["dwLocalPlayerPawn"];
43 | dwLocalPlayerController= offsetsJson["client.dll"]["dwLocalPlayerController"];
44 | dwEntityList= offsetsJson["client.dll"]["dwEntityList"];
45 | dwViewMatrix= offsetsJson["client.dll"]["dwViewMatrix"];
46 | dwViewAngles= offsetsJson["client.dll"]["dwViewAngles"];
47 |
48 | // Player details
49 | m_pCameraServices= client_dllJson["C_BasePlayerPawn"]["fields"]["m_pCameraServices"];
50 | m_glowColorOverride= client_dllJson["CGlowProperty"]["fields"]["m_glowColorOverride"];
51 | m_iFOV= client_dllJson["CCSPlayerBase_CameraServices"]["fields"]["m_iFOV"];
52 | m_bGlowing= client_dllJson["CGlowProperty"]["fields"]["m_bGlowing"];
53 | m_bIsScoped= client_dllJson["C_CSPlayerPawn"]["fields"]["m_bIsScoped"];
54 | attack= buttonsJson["client.dll"]["attack"];
55 | m_iIDEntIndex= client_dllJson["C_CSPlayerPawnBase"]["fields"]["m_iIDEntIndex"];;
56 | flFlashDuration= client_dllJson["C_CSPlayerPawnBase"]["fields"]["m_flFlashDuration"];
57 | m_iShotsFired = client_dllJson["C_CSPlayerPawn"]["fields"]["m_iShotsFired"];
58 | m_aimPunchAngle = client_dllJson["C_CSPlayerPawn"]["fields"]["m_aimPunchAngle"];
59 |
60 | // Entity details
61 | m_hPawn= client_dllJson["CBasePlayerController"]["fields"]["m_hPawn"];
62 | m_hPlayerPawn= client_dllJson["CCSPlayerController"]["fields"]["m_hPlayerPawn"];
63 | m_Glow= client_dllJson["C_BaseModelEntity"]["fields"]["m_Glow"];
64 | m_iHealth= client_dllJson["C_BaseEntity"]["fields"]["m_iHealth"];
65 | m_iTeamNum= client_dllJson["C_BaseEntity"]["fields"]["m_iTeamNum"];;
66 | m_vOldOrigin= client_dllJson["C_BasePlayerPawn"]["fields"]["m_vOldOrigin"];
67 | m_entitySpottedState= client_dllJson["C_CSPlayerPawn"]["fields"]["m_entitySpottedState"];
68 | m_vecViewOffset= client_dllJson["C_BaseModelEntity"]["fields"]["m_vecViewOffset"];
69 | m_fFlags= client_dllJson["C_BaseEntity"]["fields"]["m_fFlags"];
70 |
71 | return 1;
72 |
73 | }
--------------------------------------------------------------------------------
/TempleWare-External/source/offsets/offsets.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | using json = nlohmann::json;
7 |
8 | namespace offsets
9 | {
10 | // Game offsets
11 | inline std::ptrdiff_t dwLocalPlayerPawn;
12 | inline std::ptrdiff_t dwLocalPlayerController;
13 | inline std::ptrdiff_t dwEntityList;
14 | inline std::ptrdiff_t dwViewMatrix;
15 | inline std::ptrdiff_t dwViewAngles;
16 |
17 | // Player details
18 | inline std::ptrdiff_t m_pCameraServices;
19 | inline std::ptrdiff_t m_glowColorOverride;
20 | inline std::ptrdiff_t m_iFOV;
21 | inline std::ptrdiff_t m_bGlowing;
22 | inline std::ptrdiff_t m_bIsScoped;
23 | inline std::ptrdiff_t attack;
24 | inline std::ptrdiff_t m_iIDEntIndex;
25 | inline std::ptrdiff_t flFlashDuration;
26 | inline std::ptrdiff_t m_iShotsFired;
27 | inline std::ptrdiff_t m_aimPunchAngle;
28 |
29 | // Entity details
30 | inline std::ptrdiff_t m_hPawn;
31 | inline std::ptrdiff_t m_hPlayerPawn;
32 | inline std::ptrdiff_t m_Glow;
33 | inline std::ptrdiff_t m_iHealth;
34 | inline std::ptrdiff_t m_iTeamNum;
35 | inline std::ptrdiff_t m_vOldOrigin;
36 | inline std::ptrdiff_t m_entitySpottedState;
37 | inline std::ptrdiff_t m_vecViewOffset;
38 | inline std::ptrdiff_t m_fFlags;
39 |
40 | bool UpdateOffset();
41 | }
42 |
--------------------------------------------------------------------------------
/TempleWare-External/source/threads/threads.cpp:
--------------------------------------------------------------------------------
1 | #include "threads.h"
2 | #include "../features/fov.h"
3 | #include "../features/noflash.h"
4 | #include "../features/triggerbot.h"
5 | #include "../menu/menu.h"
6 | #include "../features/bhop.h"
7 | #include "../features/glow.h"
8 |
9 | #include "../offsets/offsets.h"
10 | #include "../globals/globals.h"
11 |
12 | #include
13 |
14 | namespace threads {
15 | void RunMiscThread(const Memory& memory) noexcept
16 | {
17 | while (gui::isRunning)
18 | {
19 | features::FOVManager::AdjustFOV(memory);
20 | features::Bhop::Run(memory);
21 | std::this_thread::sleep_for(std::chrono::milliseconds(1));
22 | }
23 | }
24 |
25 | void RunVisualThread(const Memory& memory) noexcept
26 | {
27 | while (gui::isRunning)
28 | {
29 | features::NoFlash::Run(memory);
30 | features::Glow::Run(memory);
31 | std::this_thread::sleep_for(std::chrono::milliseconds(1));
32 | }
33 | }
34 |
35 | void RunAimThread(const Memory& memory) noexcept
36 | {
37 | while (gui::isRunning)
38 | {
39 | if (globals::TriggerBot)
40 | features::TriggerBot::Run(memory);
41 | std::this_thread::sleep_for(std::chrono::milliseconds(1));
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/TempleWare-External/source/threads/threads.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../memory/Memory.h"
4 |
5 | namespace threads
6 | {
7 | void RunMiscThread(const Memory& memory) noexcept;
8 | void RunVisualThread(const Memory& memory) noexcept;
9 | void RunAimThread(const Memory& memory) noexcept;
10 | }
11 |
--------------------------------------------------------------------------------
/github/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TempleDevelopment/TempleWare-External/30e4c795e414f6890456d899ba1d221bfc5f747b/github/images/logo.png
--------------------------------------------------------------------------------
/github/images/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TempleDevelopment/TempleWare-External/30e4c795e414f6890456d899ba1d221bfc5f747b/github/images/menu.png
--------------------------------------------------------------------------------
/github/images/showcase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TempleDevelopment/TempleWare-External/30e4c795e414f6890456d899ba1d221bfc5f747b/github/images/showcase.png
--------------------------------------------------------------------------------