├── .gitattributes ├── .gitignore ├── .gitmodules ├── Extras ├── Bindings │ ├── actions.json │ ├── haloce.vrmanifest │ ├── icon.png │ ├── knuckles_left.json │ ├── knuckles_right.json │ ├── manifest.py │ ├── oculus_touch_left.json │ └── oculus_touch_right.json ├── Fonts │ ├── bold.ttf │ ├── bold_italics.ttf │ ├── italics.ttf │ └── normal.ttf └── Images │ ├── left.png │ ├── right.png │ └── settings.png ├── HaloCEVR.sln ├── HaloCEVR ├── Config │ └── Config.h ├── DirectXWrappers │ ├── IDirect3D9ExWrapper.cpp │ ├── IDirect3D9ExWrapper.h │ ├── IDirect3DDevice9ExWrapper.cpp │ └── IDirect3DDevice9ExWrapper.h ├── Game.cpp ├── Game.h ├── HaloCEVR.vcxproj ├── HaloCEVR.vcxproj.filters ├── Helpers │ ├── Assets.cpp │ ├── Assets.h │ ├── Camera.cpp │ ├── Camera.h │ ├── CmdLineArgs.cpp │ ├── CmdLineArgs.h │ ├── Controls.cpp │ ├── Controls.h │ ├── Cutscene.cpp │ ├── Cutscene.h │ ├── DX9.cpp │ ├── DX9.h │ ├── Maths.cpp │ ├── Maths.h │ ├── Menus.cpp │ ├── Menus.h │ ├── Objects.cpp │ ├── Objects.h │ ├── Player.cpp │ ├── Player.h │ ├── RenderTarget.cpp │ ├── RenderTarget.h │ ├── Renderer.cpp │ ├── Renderer.h │ ├── Version.cpp │ └── Version.h ├── Hooking │ ├── FunctionTypedefs.h │ ├── Hook.h │ ├── Hooks.cpp │ ├── Hooks.h │ ├── SigScanner.cpp │ └── SigScanner.h ├── InGameRenderer.cpp ├── InGameRenderer.h ├── InputHandler.cpp ├── InputHandler.h ├── Logger.h ├── Maths │ ├── Matrices.cpp │ ├── Matrices.h │ └── Vectors.h ├── Profiler.cpp ├── Profiler.h ├── UI │ ├── SettingsMenu.cpp │ ├── SettingsMenu.h │ ├── UIButton.cpp │ ├── UIButton.h │ ├── UICheckbox.cpp │ ├── UICheckbox.h │ ├── UIElement.cpp │ ├── UIElement.h │ ├── UIFloatBox.cpp │ ├── UIFloatBox.h │ ├── UIImageButton.cpp │ ├── UIImageButton.h │ ├── UIIntBox.cpp │ ├── UIIntBox.h │ ├── UILabel.cpp │ ├── UILabel.h │ ├── UIPanel.cpp │ ├── UIPanel.h │ ├── UIRenderer.cpp │ ├── UIRenderer.h │ ├── UITabPanel.cpp │ ├── UITabPanel.h │ ├── UITextBox.cpp │ ├── UITextBox.h │ ├── UITextButton.cpp │ └── UITextButton.h ├── VR │ ├── IVR.h │ ├── OpenVR.cpp │ ├── OpenVR.h │ ├── VREmulator.cpp │ └── VREmulator.h ├── WeaponHandler.cpp ├── WeaponHandler.h ├── cpp.hint └── dllmain.cpp ├── README.md ├── ThirdParty ├── OpenVR │ ├── include │ │ └── openvr.h │ └── lib │ │ └── openvr_api.lib └── stb │ ├── stb_image.h │ └── stb_truetype.h ├── initinstall.bat └── makerelease.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.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/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | [Ee]mulated-VR/ 36 | 37 | # Visual Studio 2015/2017 cache/options directory 38 | .vs/ 39 | # Uncomment if you have tasks that create the project's static files in wwwroot 40 | #wwwroot/ 41 | 42 | # Visual Studio 2017 auto generated files 43 | Generated\ Files/ 44 | 45 | # MSTest test Results 46 | [Tt]est[Rr]esult*/ 47 | [Bb]uild[Ll]og.* 48 | 49 | # NUnit 50 | *.VisualState.xml 51 | TestResult.xml 52 | nunit-*.xml 53 | 54 | # Build Results of an ATL Project 55 | [Dd]ebugPS/ 56 | [Rr]eleasePS/ 57 | dlldata.c 58 | 59 | # Benchmark Results 60 | BenchmarkDotNet.Artifacts/ 61 | 62 | # .NET Core 63 | project.lock.json 64 | project.fragment.lock.json 65 | artifacts/ 66 | 67 | # ASP.NET Scaffolding 68 | ScaffoldingReadMe.txt 69 | 70 | # StyleCop 71 | StyleCopReport.xml 72 | 73 | # Files built by Visual Studio 74 | *_i.c 75 | *_p.c 76 | *_h.h 77 | *.ilk 78 | *.meta 79 | *.obj 80 | *.iobj 81 | *.pch 82 | *.pdb 83 | *.ipdb 84 | *.pgc 85 | *.pgd 86 | *.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *_wpftmp.csproj 94 | *.log 95 | *.vspscc 96 | *.vssscc 97 | .builds 98 | *.pidb 99 | *.svclog 100 | *.scc 101 | 102 | # Chutzpah Test files 103 | _Chutzpah* 104 | 105 | # Visual C++ cache files 106 | ipch/ 107 | *.aps 108 | *.ncb 109 | *.opendb 110 | *.opensdf 111 | *.sdf 112 | *.cachefile 113 | *.VC.db 114 | *.VC.VC.opendb 115 | 116 | # Visual Studio profiler 117 | *.psess 118 | *.vsp 119 | *.vspx 120 | *.sap 121 | 122 | # Visual Studio Trace Files 123 | *.e2e 124 | 125 | # TFS 2012 Local Workspace 126 | $tf/ 127 | 128 | # Guidance Automation Toolkit 129 | *.gpState 130 | 131 | # ReSharper is a .NET coding add-in 132 | _ReSharper*/ 133 | *.[Rr]e[Ss]harper 134 | *.DotSettings.user 135 | 136 | # TeamCity is a build add-in 137 | _TeamCity* 138 | 139 | # DotCover is a Code Coverage Tool 140 | *.dotCover 141 | 142 | # AxoCover is a Code Coverage Tool 143 | .axoCover/* 144 | !.axoCover/settings.json 145 | 146 | # Coverlet is a free, cross platform Code Coverage Tool 147 | coverage*.json 148 | coverage*.xml 149 | coverage*.info 150 | 151 | # Visual Studio code coverage results 152 | *.coverage 153 | *.coveragexml 154 | 155 | # NCrunch 156 | _NCrunch_* 157 | .*crunch*.local.xml 158 | nCrunchTemp_* 159 | 160 | # MightyMoose 161 | *.mm.* 162 | AutoTest.Net/ 163 | 164 | # Web workbench (sass) 165 | .sass-cache/ 166 | 167 | # Installshield output folder 168 | [Ee]xpress/ 169 | 170 | # DocProject is a documentation generator add-in 171 | DocProject/buildhelp/ 172 | DocProject/Help/*.HxT 173 | DocProject/Help/*.HxC 174 | DocProject/Help/*.hhc 175 | DocProject/Help/*.hhk 176 | DocProject/Help/*.hhp 177 | DocProject/Help/Html2 178 | DocProject/Help/html 179 | 180 | # Click-Once directory 181 | publish/ 182 | 183 | # Publish Web Output 184 | *.[Pp]ublish.xml 185 | *.azurePubxml 186 | # Note: Comment the next line if you want to checkin your web deploy settings, 187 | # but database connection strings (with potential passwords) will be unencrypted 188 | *.pubxml 189 | *.publishproj 190 | 191 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 192 | # checkin your Azure Web App publish settings, but sensitive information contained 193 | # in these scripts will be unencrypted 194 | PublishScripts/ 195 | 196 | # NuGet Packages 197 | *.nupkg 198 | # NuGet Symbol Packages 199 | *.snupkg 200 | # The packages folder can be ignored because of Package Restore 201 | **/[Pp]ackages/* 202 | # except build/, which is used as an MSBuild target. 203 | !**/[Pp]ackages/build/ 204 | # Uncomment if necessary however generally it will be regenerated when needed 205 | #!**/[Pp]ackages/repositories.config 206 | # NuGet v3's project.json files produces more ignorable files 207 | *.nuget.props 208 | *.nuget.targets 209 | 210 | # Microsoft Azure Build Output 211 | csx/ 212 | *.build.csdef 213 | 214 | # Microsoft Azure Emulator 215 | ecf/ 216 | rcf/ 217 | 218 | # Windows Store app package directories and files 219 | AppPackages/ 220 | BundleArtifacts/ 221 | Package.StoreAssociation.xml 222 | _pkginfo.txt 223 | *.appx 224 | *.appxbundle 225 | *.appxupload 226 | 227 | # Visual Studio cache files 228 | # files ending in .cache can be ignored 229 | *.[Cc]ache 230 | # but keep track of directories ending in .cache 231 | !?*.[Cc]ache/ 232 | 233 | # Others 234 | ClientBin/ 235 | ~$* 236 | *~ 237 | *.dbmdl 238 | *.dbproj.schemaview 239 | *.jfm 240 | *.pfx 241 | *.publishsettings 242 | orleans.codegen.cs 243 | 244 | # Including strong name files can present a security risk 245 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 246 | #*.snk 247 | 248 | # Since there are multiple workflows, uncomment next line to ignore bower_components 249 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 250 | #bower_components/ 251 | 252 | # RIA/Silverlight projects 253 | Generated_Code/ 254 | 255 | # Backup & report files from converting an old project file 256 | # to a newer Visual Studio version. Backup files are not needed, 257 | # because we have git ;-) 258 | _UpgradeReport_Files/ 259 | Backup*/ 260 | UpgradeLog*.XML 261 | UpgradeLog*.htm 262 | ServiceFabricBackup/ 263 | *.rptproj.bak 264 | 265 | # SQL Server files 266 | *.mdf 267 | *.ldf 268 | *.ndf 269 | 270 | # Business Intelligence projects 271 | *.rdl.data 272 | *.bim.layout 273 | *.bim_*.settings 274 | *.rptproj.rsuser 275 | *- [Bb]ackup.rdl 276 | *- [Bb]ackup ([0-9]).rdl 277 | *- [Bb]ackup ([0-9][0-9]).rdl 278 | 279 | # Microsoft Fakes 280 | FakesAssemblies/ 281 | 282 | # GhostDoc plugin setting file 283 | *.GhostDoc.xml 284 | 285 | # Node.js Tools for Visual Studio 286 | .ntvs_analysis.dat 287 | node_modules/ 288 | 289 | # Visual Studio 6 build log 290 | *.plg 291 | 292 | # Visual Studio 6 workspace options file 293 | *.opt 294 | 295 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 296 | *.vbw 297 | 298 | # Visual Studio LightSwitch build output 299 | **/*.HTMLClient/GeneratedArtifacts 300 | **/*.DesktopClient/GeneratedArtifacts 301 | **/*.DesktopClient/ModelManifest.xml 302 | **/*.Server/GeneratedArtifacts 303 | **/*.Server/ModelManifest.xml 304 | _Pvt_Extensions 305 | 306 | # Paket dependency manager 307 | .paket/paket.exe 308 | paket-files/ 309 | 310 | # FAKE - F# Make 311 | .fake/ 312 | 313 | # CodeRush personal settings 314 | .cr/personal 315 | 316 | # Python Tools for Visual Studio (PTVS) 317 | __pycache__/ 318 | *.pyc 319 | 320 | # Cake - Uncomment if you are using it 321 | # tools/** 322 | # !tools/packages.config 323 | 324 | # Tabs Studio 325 | *.tss 326 | 327 | # Telerik's JustMock configuration file 328 | *.jmconfig 329 | 330 | # BizTalk build output 331 | *.btp.cs 332 | *.btm.cs 333 | *.odx.cs 334 | *.xsd.cs 335 | 336 | # OpenCover UI analysis results 337 | OpenCover/ 338 | 339 | # Azure Stream Analytics local run output 340 | ASALocalRun/ 341 | 342 | # MSBuild Binary and Structured Log 343 | *.binlog 344 | 345 | # NVidia Nsight GPU debugger configuration file 346 | *.nvuser 347 | 348 | # MFractors (Xamarin productivity tool) working folder 349 | .mfractor/ 350 | 351 | # Local History for Visual Studio 352 | .localhistory/ 353 | 354 | # BeatPulse healthcheck temp database 355 | healthchecksdb 356 | 357 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 358 | MigrationBackup/ 359 | 360 | # Ionide (cross platform F# VS Code tools) working folder 361 | .ionide/ 362 | 363 | # Fody - auto-generated XML schema 364 | FodyWeavers.xsd 365 | /HaloCEVR.zip 366 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ThirdParty/MinHook"] 2 | path = ThirdParty/MinHook 3 | url = https://github.com/TsudaKageyu/minhook.git 4 | -------------------------------------------------------------------------------- /Extras/Bindings/actions.json: -------------------------------------------------------------------------------- 1 | { 2 | "default_bindings": [ 3 | { 4 | "controller_type": "oculus_touch", 5 | "binding_url": "oculus_touch_right.json" 6 | }, 7 | { 8 | "controller_type": "knuckles", 9 | "binding_url": "knuckles_right.json" 10 | }, 11 | { 12 | "controller_type": "oculus_touch", 13 | "binding_url": "oculus_touch_left.json" 14 | }, 15 | { 16 | "controller_type": "knuckles", 17 | "binding_url": "knuckles_left.json" 18 | } 19 | ], 20 | "actions": [ 21 | { 22 | "name": "/actions/default/in/Jump", 23 | "requirement": "suggested", 24 | "type": "boolean" 25 | }, 26 | { 27 | "name": "/actions/left handed/in/Jump", 28 | "requirement": "suggested", 29 | "type": "boolean" 30 | }, 31 | { 32 | "name": "/actions/default/in/SwitchGrenades", 33 | "requirement": "suggested", 34 | "type": "boolean" 35 | }, 36 | { 37 | "name": "/actions/left handed/in/SwitchGrenades", 38 | "requirement": "suggested", 39 | "type": "boolean" 40 | }, 41 | { 42 | "name": "/actions/default/in/Interact", 43 | "requirement": "suggested", 44 | "type": "boolean" 45 | }, 46 | { 47 | "name": "/actions/left handed/in/Interact", 48 | "requirement": "suggested", 49 | "type": "boolean" 50 | }, 51 | { 52 | "name": "/actions/default/in/SwitchWeapons", 53 | "requirement": "suggested", 54 | "type": "boolean" 55 | }, 56 | { 57 | "name": "/actions/left handed/in/SwitchWeapons", 58 | "requirement": "suggested", 59 | "type": "boolean" 60 | }, 61 | { 62 | "name": "/actions/default/in/Melee", 63 | "requirement": "suggested", 64 | "type": "boolean" 65 | }, 66 | { 67 | "name": "/actions/left handed/in/Melee", 68 | "requirement": "suggested", 69 | "type": "boolean" 70 | }, 71 | { 72 | "name": "/actions/default/in/Flashlight", 73 | "requirement": "suggested", 74 | "type": "boolean" 75 | }, 76 | { 77 | "name": "/actions/left handed/in/Flashlight", 78 | "requirement": "suggested", 79 | "type": "boolean" 80 | }, 81 | { 82 | "name": "/actions/default/in/Grenade", 83 | "requirement": "suggested", 84 | "type": "boolean" 85 | }, 86 | { 87 | "name": "/actions/left handed/in/Grenade", 88 | "requirement": "suggested", 89 | "type": "boolean" 90 | }, 91 | { 92 | "name": "/actions/default/in/Fire", 93 | "requirement": "suggested", 94 | "type": "boolean" 95 | }, 96 | { 97 | "name": "/actions/left handed/in/Fire", 98 | "requirement": "suggested", 99 | "type": "boolean" 100 | }, 101 | { 102 | "name": "/actions/default/in/MenuForward", 103 | "requirement": "suggested", 104 | "type": "boolean" 105 | }, 106 | { 107 | "name": "/actions/left handed/in/MenuForward", 108 | "requirement": "suggested", 109 | "type": "boolean" 110 | }, 111 | { 112 | "name": "/actions/default/in/MenuBack", 113 | "requirement": "suggested", 114 | "type": "boolean" 115 | }, 116 | { 117 | "name": "/actions/left handed/in/MenuBack", 118 | "requirement": "suggested", 119 | "type": "boolean" 120 | }, 121 | { 122 | "name": "/actions/default/in/Crouch", 123 | "requirement": "suggested", 124 | "type": "boolean" 125 | }, 126 | { 127 | "name": "/actions/left handed/in/Crouch", 128 | "requirement": "suggested", 129 | "type": "boolean" 130 | }, 131 | { 132 | "name": "/actions/default/in/Zoom", 133 | "requirement": "suggested", 134 | "type": "boolean" 135 | }, 136 | { 137 | "name": "/actions/left handed/in/Zoom", 138 | "requirement": "suggested", 139 | "type": "boolean" 140 | }, 141 | { 142 | "name": "/actions/default/in/Reload", 143 | "requirement": "suggested", 144 | "type": "boolean" 145 | }, 146 | { 147 | "name": "/actions/left handed/in/Reload", 148 | "requirement": "suggested", 149 | "type": "boolean" 150 | }, 151 | { 152 | "name": "/actions/default/in/Recentre", 153 | "requirement": "suggested", 154 | "type": "boolean" 155 | }, 156 | { 157 | "name": "/actions/left handed/in/Recentre", 158 | "requirement": "suggested", 159 | "type": "boolean" 160 | }, 161 | { 162 | "name": "/actions/default/in/TwoHandGrip", 163 | "requirement": "suggested", 164 | "type": "boolean" 165 | }, 166 | { 167 | "name": "/actions/left handed/in/TwoHandGrip", 168 | "requirement": "suggested", 169 | "type": "boolean" 170 | }, 171 | { 172 | "name": "/actions/default/in/SwapWeaponHand", 173 | "requirement": "suggested", 174 | "type": "boolean" 175 | }, 176 | { 177 | "name": "/actions/left handed/in/SwapWeaponHand", 178 | "requirement": "suggested", 179 | "type": "boolean" 180 | }, 181 | { 182 | "name": "/actions/default/in/Look", 183 | "requirement": "suggested", 184 | "type": "vector2" 185 | }, 186 | { 187 | "name": "/actions/left handed/in/Look", 188 | "requirement": "suggested", 189 | "type": "vector2" 190 | }, 191 | { 192 | "name": "/actions/default/in/Move", 193 | "requirement": "suggested", 194 | "type": "vector2" 195 | }, 196 | { 197 | "name": "/actions/left handed/in/Move", 198 | "requirement": "suggested", 199 | "type": "vector2" 200 | }, 201 | { 202 | "name": "/actions/default/in/LeftTip", 203 | "requirement": "suggested", 204 | "type": "pose" 205 | }, 206 | { 207 | "name": "/actions/default/in/RightTip", 208 | "requirement": "suggested", 209 | "type": "pose" 210 | }, 211 | { 212 | "name": "/actions/default/in/LeftHand", 213 | "type": "skeleton", 214 | "skeleton": "/skeleton/hand/left" 215 | }, 216 | { 217 | "name": "/actions/default/in/RightHand", 218 | "type": "skeleton", 219 | "skeleton": "/skeleton/hand/right" 220 | } 221 | ], 222 | "action_sets": [ 223 | { 224 | "name": "/actions/default", 225 | "usage": "leftright" 226 | }, 227 | { 228 | "name": "/actions/left handed", 229 | "usage": "left" 230 | } 231 | ] 232 | } -------------------------------------------------------------------------------- /Extras/Bindings/haloce.vrmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "source" : "builtin", 3 | "applications": [{ 4 | "application_type": "vrgame", 5 | "app_key": "livingfray.haloce", 6 | "launch_type": "binary", 7 | "binary_path_windows": "../../halo.exe", 8 | "action_manifest_path": "actions.json", 9 | "image_path": "icon.png", 10 | "strings": { 11 | "en_us": { 12 | "name": "Halo: Combat Evolved" 13 | } 14 | } 15 | }] 16 | } -------------------------------------------------------------------------------- /Extras/Bindings/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Bindings/icon.png -------------------------------------------------------------------------------- /Extras/Bindings/knuckles_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/default": { 4 | "haptics": [], 5 | "poses": [ 6 | { 7 | "output": "/actions/default/in/LeftTip", 8 | "path": "/user/hand/left/pose/tip" 9 | }, 10 | { 11 | "output": "/actions/default/in/RightTip", 12 | "path": "/user/hand/right/pose/tip" 13 | } 14 | ], 15 | "sources": [ 16 | { 17 | "inputs": { 18 | "north": { 19 | "output": "/actions/default/in/Jump" 20 | }, 21 | "south": { 22 | "output": "/actions/default/in/Crouch" 23 | } 24 | }, 25 | "mode": "dpad", 26 | "path": "/user/hand/left/input/thumbstick", 27 | "parameters": { 28 | "sub_mode": "touch" 29 | } 30 | }, 31 | { 32 | "inputs": { 33 | "click": { 34 | "output": "/actions/default/in/TwoHandGrip" 35 | } 36 | }, 37 | "mode": "button", 38 | "path": "/user/hand/left/input/grip", 39 | "parameters": { 40 | "click_activate_threshold": 0.8, 41 | "click_deactivate_threshold": 0.7 42 | } 43 | }, 44 | { 45 | "inputs": { 46 | "click": { 47 | "output": "/actions/default/in/SwitchWeapons" 48 | } 49 | }, 50 | "mode": "button", 51 | "path": "/user/hand/right/input/trackpad", 52 | "parameters": {} 53 | }, 54 | { 55 | "inputs": { 56 | "click": { 57 | "output": "/actions/default/in/SwapWeaponHand" 58 | } 59 | }, 60 | "mode": "button", 61 | "path": "/user/hand/left/input/grip", 62 | "parameters": { 63 | "click_activate_threshold": 0.8, 64 | "click_deactivate_threshold": 0.7 65 | } 66 | }, 67 | { 68 | "inputs": { 69 | "click": { 70 | "output": "/actions/default/in/MenuBack" 71 | } 72 | }, 73 | "mode": "button", 74 | "path": "/user/hand/left/input/b", 75 | "parameters": {} 76 | }, 77 | { 78 | "inputs": { 79 | "click": { 80 | "output": "/actions/default/in/SwitchGrenades" 81 | } 82 | }, 83 | "mode": "button", 84 | "path": "/user/hand/left/input/a", 85 | "parameters": {} 86 | }, 87 | { 88 | "inputs": { 89 | "click": { 90 | "output": "/actions/default/in/Grenade" 91 | } 92 | }, 93 | "mode": "button", 94 | "path": "/user/hand/right/input/a", 95 | "parameters": {} 96 | }, 97 | { 98 | "inputs": { 99 | "click": { 100 | "output": "/actions/default/in/Reload" 101 | } 102 | }, 103 | "mode": "button", 104 | "path": "/user/hand/right/input/b", 105 | "parameters": {} 106 | }, 107 | { 108 | "inputs": { 109 | "click": { 110 | "output": "/actions/default/in/Interact" 111 | } 112 | }, 113 | "mode": "button", 114 | "path": "/user/hand/right/input/b", 115 | "parameters": {} 116 | }, 117 | { 118 | "inputs": { 119 | "click": { 120 | "output": "/actions/default/in/Zoom" 121 | } 122 | }, 123 | "mode": "button", 124 | "path": "/user/hand/left/input/trigger", 125 | "parameters": {} 126 | }, 127 | { 128 | "inputs": { 129 | "click": { 130 | "output": "/actions/default/in/Fire" 131 | } 132 | }, 133 | "mode": "button", 134 | "path": "/user/hand/right/input/trigger", 135 | "parameters": {} 136 | }, 137 | { 138 | "inputs": { 139 | "position": { 140 | "output": "/actions/default/in/Look" 141 | } 142 | }, 143 | "mode": "joystick", 144 | "path": "/user/hand/left/input/thumbstick", 145 | "parameters": {} 146 | }, 147 | { 148 | "inputs": { 149 | "position": { 150 | "output": "/actions/default/in/Move" 151 | } 152 | }, 153 | "mode": "joystick", 154 | "path": "/user/hand/right/input/thumbstick", 155 | "parameters": {} 156 | } 157 | ], 158 | "skeleton": [ 159 | { 160 | "output": "/actions/default/in/LeftHand", 161 | "path": "/user/hand/left/input/skeleton/left" 162 | }, 163 | { 164 | "output": "/actions/default/in/RightHand", 165 | "path": "/user/hand/right/input/skeleton/right" 166 | } 167 | ] 168 | }, 169 | "/actions/left handed": { 170 | "haptics": [], 171 | "poses": [], 172 | "sources": [ 173 | { 174 | "inputs": { 175 | "north": { 176 | "output": "/actions/left handed/in/Jump" 177 | } 178 | }, 179 | "mode": "dpad", 180 | "path": "/user/hand/left/input/thumbstick", 181 | "parameters": { 182 | "sub_mode": "touch" 183 | } 184 | }, 185 | { 186 | "inputs": { 187 | "click": { 188 | "output": "/actions/left handed/in/TwoHandGrip" 189 | } 190 | }, 191 | "mode": "button", 192 | "path": "/user/hand/right/input/grip", 193 | "parameters": { 194 | "click_activate_threshold": 0.8, 195 | "click_deactivate_threshold": 0.7 196 | } 197 | }, 198 | { 199 | "inputs": { 200 | "click": { 201 | "output": "/actions/left handed/in/SwitchWeapons" 202 | } 203 | }, 204 | "mode": "button", 205 | "path": "/user/hand/left/input/trackpad", 206 | "parameters": {} 207 | }, 208 | { 209 | "inputs": { 210 | "click": { 211 | "output": "/actions/left handed/in/SwapWeaponHand" 212 | } 213 | }, 214 | "mode": "button", 215 | "path": "/user/hand/right/input/grip", 216 | "parameters": { 217 | "click_activate_threshold": 0.8, 218 | "click_deactivate_threshold": 0.7 219 | } 220 | }, 221 | { 222 | "inputs": { 223 | "click": { 224 | "output": "/actions/left handed/in/MenuBack" 225 | } 226 | }, 227 | "mode": "button", 228 | "path": "/user/hand/right/input/b", 229 | "parameters": {} 230 | }, 231 | { 232 | "inputs": { 233 | "click": { 234 | "output": "/actions/left handed/in/SwitchGrenades" 235 | } 236 | }, 237 | "mode": "button", 238 | "path": "/user/hand/right/input/a", 239 | "parameters": {} 240 | }, 241 | { 242 | "inputs": { 243 | "click": { 244 | "output": "/actions/left handed/in/Grenade" 245 | } 246 | }, 247 | "mode": "button", 248 | "path": "/user/hand/left/input/a", 249 | "parameters": {} 250 | }, 251 | { 252 | "inputs": { 253 | "click": { 254 | "output": "/actions/left handed/in/Reload" 255 | } 256 | }, 257 | "mode": "button", 258 | "path": "/user/hand/left/input/b", 259 | "parameters": {} 260 | }, 261 | { 262 | "inputs": { 263 | "click": { 264 | "output": "/actions/left handed/in/Interact" 265 | } 266 | }, 267 | "mode": "button", 268 | "path": "/user/hand/left/input/b", 269 | "parameters": {} 270 | }, 271 | { 272 | "inputs": { 273 | "click": { 274 | "output": "/actions/left handed/in/Zoom" 275 | } 276 | }, 277 | "mode": "button", 278 | "path": "/user/hand/right/input/trigger", 279 | "parameters": {} 280 | }, 281 | { 282 | "inputs": { 283 | "click": { 284 | "output": "/actions/left handed/in/Fire" 285 | } 286 | }, 287 | "mode": "button", 288 | "path": "/user/hand/left/input/trigger", 289 | "parameters": {} 290 | }, 291 | { 292 | "inputs": { 293 | "position": { 294 | "output": "/actions/left handed/in/Look" 295 | } 296 | }, 297 | "mode": "joystick", 298 | "path": "/user/hand/left/input/thumbstick", 299 | "parameters": {} 300 | }, 301 | { 302 | "inputs": { 303 | "position": { 304 | "output": "/actions/left handed/in/Move" 305 | } 306 | }, 307 | "mode": "joystick", 308 | "path": "/user/hand/right/input/thumbstick", 309 | "parameters": {} 310 | } 311 | ], 312 | "skeleton": [] 313 | } 314 | }, 315 | "controller_type": "knuckles", 316 | "description": "(Left Handed) Autogenerated bindings for knuckles", 317 | "name": "(Left Handed) knuckles" 318 | } -------------------------------------------------------------------------------- /Extras/Bindings/knuckles_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/default": { 4 | "haptics": [], 5 | "poses": [ 6 | { 7 | "output": "/actions/default/in/LeftTip", 8 | "path": "/user/hand/left/pose/tip" 9 | }, 10 | { 11 | "output": "/actions/default/in/RightTip", 12 | "path": "/user/hand/right/pose/tip" 13 | } 14 | ], 15 | "sources": [ 16 | { 17 | "inputs": { 18 | "north": { 19 | "output": "/actions/default/in/Jump" 20 | }, 21 | "south": { 22 | "output": "/actions/default/in/Crouch" 23 | } 24 | }, 25 | "mode": "dpad", 26 | "path": "/user/hand/right/input/thumbstick", 27 | "parameters": { 28 | "sub_mode": "touch" 29 | } 30 | }, 31 | { 32 | "inputs": { 33 | "click": { 34 | "output": "/actions/default/in/TwoHandGrip" 35 | } 36 | }, 37 | "mode": "button", 38 | "path": "/user/hand/left/input/grip", 39 | "parameters": { 40 | "click_activate_threshold": 0.8, 41 | "click_deactivate_threshold": 0.7 42 | } 43 | }, 44 | { 45 | "inputs": { 46 | "click": { 47 | "output": "/actions/default/in/SwitchWeapons" 48 | } 49 | }, 50 | "mode": "button", 51 | "path": "/user/hand/right/input/trackpad", 52 | "parameters": {} 53 | }, 54 | { 55 | "inputs": { 56 | "click": { 57 | "output": "/actions/default/in/SwapWeaponHand" 58 | } 59 | }, 60 | "mode": "button", 61 | "path": "/user/hand/left/input/grip", 62 | "parameters": { 63 | "click_activate_threshold": 0.8, 64 | "click_deactivate_threshold": 0.7 65 | } 66 | }, 67 | { 68 | "inputs": { 69 | "click": { 70 | "output": "/actions/default/in/MenuBack" 71 | } 72 | }, 73 | "mode": "button", 74 | "path": "/user/hand/left/input/b", 75 | "parameters": {} 76 | }, 77 | { 78 | "inputs": { 79 | "click": { 80 | "output": "/actions/default/in/SwitchGrenades" 81 | } 82 | }, 83 | "mode": "button", 84 | "path": "/user/hand/left/input/a", 85 | "parameters": {} 86 | }, 87 | { 88 | "inputs": { 89 | "click": { 90 | "output": "/actions/default/in/Grenade" 91 | } 92 | }, 93 | "mode": "button", 94 | "path": "/user/hand/right/input/a", 95 | "parameters": {} 96 | }, 97 | { 98 | "inputs": { 99 | "click": { 100 | "output": "/actions/default/in/Reload" 101 | } 102 | }, 103 | "mode": "button", 104 | "path": "/user/hand/right/input/b", 105 | "parameters": {} 106 | }, 107 | { 108 | "inputs": { 109 | "click": { 110 | "output": "/actions/default/in/Interact" 111 | } 112 | }, 113 | "mode": "button", 114 | "path": "/user/hand/right/input/b", 115 | "parameters": {} 116 | }, 117 | { 118 | "inputs": { 119 | "click": { 120 | "output": "/actions/default/in/Zoom" 121 | } 122 | }, 123 | "mode": "button", 124 | "path": "/user/hand/left/input/trigger", 125 | "parameters": {} 126 | }, 127 | { 128 | "inputs": { 129 | "click": { 130 | "output": "/actions/default/in/Fire" 131 | } 132 | }, 133 | "mode": "button", 134 | "path": "/user/hand/right/input/trigger", 135 | "parameters": {} 136 | }, 137 | { 138 | "inputs": { 139 | "position": { 140 | "output": "/actions/default/in/Look" 141 | } 142 | }, 143 | "mode": "joystick", 144 | "path": "/user/hand/right/input/thumbstick", 145 | "parameters": {} 146 | }, 147 | { 148 | "inputs": { 149 | "position": { 150 | "output": "/actions/default/in/Move" 151 | } 152 | }, 153 | "mode": "joystick", 154 | "path": "/user/hand/left/input/thumbstick", 155 | "parameters": {} 156 | } 157 | ], 158 | "skeleton": [ 159 | { 160 | "output": "/actions/default/in/LeftHand", 161 | "path": "/user/hand/left/input/skeleton/left" 162 | }, 163 | { 164 | "output": "/actions/default/in/RightHand", 165 | "path": "/user/hand/right/input/skeleton/right" 166 | } 167 | ] 168 | }, 169 | "/actions/left handed": { 170 | "haptics": [], 171 | "poses": [], 172 | "sources": [ 173 | { 174 | "inputs": { 175 | "north": { 176 | "output": "/actions/left handed/in/Jump" 177 | } 178 | }, 179 | "mode": "dpad", 180 | "path": "/user/hand/right/input/thumbstick", 181 | "parameters": { 182 | "sub_mode": "touch" 183 | } 184 | }, 185 | { 186 | "inputs": { 187 | "click": { 188 | "output": "/actions/left handed/in/TwoHandGrip" 189 | } 190 | }, 191 | "mode": "button", 192 | "path": "/user/hand/right/input/grip", 193 | "parameters": { 194 | "click_activate_threshold": 0.8, 195 | "click_deactivate_threshold": 0.7 196 | } 197 | }, 198 | { 199 | "inputs": { 200 | "click": { 201 | "output": "/actions/left handed/in/SwitchWeapons" 202 | } 203 | }, 204 | "mode": "button", 205 | "path": "/user/hand/left/input/trackpad", 206 | "parameters": {} 207 | }, 208 | { 209 | "inputs": { 210 | "click": { 211 | "output": "/actions/left handed/in/SwapWeaponHand" 212 | } 213 | }, 214 | "mode": "button", 215 | "path": "/user/hand/right/input/grip", 216 | "parameters": { 217 | "click_activate_threshold": 0.8, 218 | "click_deactivate_threshold": 0.7 219 | } 220 | }, 221 | { 222 | "inputs": { 223 | "click": { 224 | "output": "/actions/left handed/in/MenuBack" 225 | } 226 | }, 227 | "mode": "button", 228 | "path": "/user/hand/right/input/b", 229 | "parameters": {} 230 | }, 231 | { 232 | "inputs": { 233 | "click": { 234 | "output": "/actions/left handed/in/SwitchGrenades" 235 | } 236 | }, 237 | "mode": "button", 238 | "path": "/user/hand/right/input/a", 239 | "parameters": {} 240 | }, 241 | { 242 | "inputs": { 243 | "click": { 244 | "output": "/actions/left handed/in/Grenade" 245 | } 246 | }, 247 | "mode": "button", 248 | "path": "/user/hand/left/input/a", 249 | "parameters": {} 250 | }, 251 | { 252 | "inputs": { 253 | "click": { 254 | "output": "/actions/left handed/in/Reload" 255 | } 256 | }, 257 | "mode": "button", 258 | "path": "/user/hand/left/input/b", 259 | "parameters": {} 260 | }, 261 | { 262 | "inputs": { 263 | "click": { 264 | "output": "/actions/left handed/in/Interact" 265 | } 266 | }, 267 | "mode": "button", 268 | "path": "/user/hand/left/input/b", 269 | "parameters": {} 270 | }, 271 | { 272 | "inputs": { 273 | "click": { 274 | "output": "/actions/left handed/in/Zoom" 275 | } 276 | }, 277 | "mode": "button", 278 | "path": "/user/hand/right/input/trigger", 279 | "parameters": {} 280 | }, 281 | { 282 | "inputs": { 283 | "click": { 284 | "output": "/actions/left handed/in/Fire" 285 | } 286 | }, 287 | "mode": "button", 288 | "path": "/user/hand/left/input/trigger", 289 | "parameters": {} 290 | }, 291 | { 292 | "inputs": { 293 | "position": { 294 | "output": "/actions/left handed/in/Look" 295 | } 296 | }, 297 | "mode": "joystick", 298 | "path": "/user/hand/right/input/thumbstick", 299 | "parameters": {} 300 | }, 301 | { 302 | "inputs": { 303 | "position": { 304 | "output": "/actions/left handed/in/Move" 305 | } 306 | }, 307 | "mode": "joystick", 308 | "path": "/user/hand/left/input/thumbstick", 309 | "parameters": {} 310 | } 311 | ], 312 | "skeleton": [] 313 | } 314 | }, 315 | "controller_type": "knuckles", 316 | "description": "(Right Handed) Autogenerated bindings for knuckles", 317 | "name": "(Right Handed) knuckles" 318 | } -------------------------------------------------------------------------------- /Extras/Bindings/manifest.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | controllers = ["oculus_touch", "knuckles"] 4 | boolActions = ["Jump","SwitchGrenades","Interact","SwitchWeapons","Melee","Flashlight","Grenade","Fire","MenuForward","MenuBack","Crouch","Zoom","Reload","Recentre","TwoHandGrip","SwapWeaponHand"] 5 | vec1Actions = [] 6 | vec2Actions = ["Look", "Move"] 7 | poseActions = ["Tip"] 8 | 9 | bindings = { 10 | "Jump" : { "h" : "right", "b" : "joystick|north", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : False}, 11 | "TwoHandGrip" : {"h" : "left", "b" : "grip", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 12 | "SwitchWeapons" : {"h" : "right", "b" : "grip", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 13 | "SwapWeaponHand" : {"h" : "left", "b" : "grip", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 14 | "MenuBack" : {"h" : "left", "b" : "y", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 15 | "SwitchGrenades" : {"h" : "left", "b" : "x", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 16 | "Grenade" : {"h" : "right", "b" : "a", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 17 | "Reload" : {"h" : "right", "b" : "b", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 18 | "Interact" : {"h" : "right", "b" : "b", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 19 | "Zoom" : {"h" : "left", "b" : "trigger", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 20 | "Fire" : {"h" : "right", "b" : "trigger", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 21 | "Crouch" : {"h" : "right", "b" : "joystick|south", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : True}, 22 | "Look" : {"h" : "right", "b" : "joystick", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : False}, 23 | "Move" : {"h" : "left", "b" : "joystick", "f" : True, "actionsets" : ["default", "left handed"], "swapActionSetHand" : False} 24 | } 25 | 26 | manifest = { 27 | "default_bindings" : [], 28 | "actions" : [], 29 | "action_sets" : [ 30 | { 31 | "name" : "/actions/default", 32 | "usage" : "leftright" 33 | }, 34 | { 35 | "name" : "/actions/left handed", 36 | "usage" : "left" 37 | } 38 | ] 39 | } 40 | 41 | poses = { 42 | "Tip" : "tip" 43 | } 44 | 45 | variants = ["Right Handed", "Left Handed"] 46 | 47 | for v in variants: 48 | for c in controllers: 49 | filename = c + "_"+v.split(' ', 1)[0].lower() 50 | manifest["default_bindings"].append({"controller_type" : c, "binding_url" : filename + ".json"}) 51 | 52 | for b in boolActions: 53 | manifest["actions"].append({"name" : "/actions/default/in/" + b, "requirement" : "suggested", "type" : "boolean"}) 54 | manifest["actions"].append({"name" : "/actions/left handed/in/" + b, "requirement" : "suggested", "type" : "boolean"}) 55 | 56 | for v in vec1Actions: 57 | manifest["actions"].append({"name" : "/actions/default/in/" + v, "requirement" : "suggested", "type" : "vector1"}) 58 | manifest["actions"].append({"name" : "/actions/left handed/in/" + v, "requirement" : "suggested", "type" : "vector1"}) 59 | 60 | for v in vec2Actions: 61 | manifest["actions"].append({"name" : "/actions/default/in/" + v, "requirement" : "suggested", "type" : "vector2"}) 62 | manifest["actions"].append({"name" : "/actions/left handed/in/" + v, "requirement" : "suggested", "type" : "vector2"}) 63 | 64 | for p in poseActions: 65 | manifest["actions"].append({"name" : "/actions/default/in/Left" + p, "requirement" : "suggested", "type" : "pose"}) 66 | manifest["actions"].append({"name" : "/actions/default/in/Right" + p, "requirement" : "suggested", "type" : "pose"}) 67 | 68 | manifest["actions"].append({"name" : "/actions/default/in/LeftHand", "type" : "skeleton", "skeleton": "/skeleton/hand/left"}) 69 | manifest["actions"].append({"name" : "/actions/default/in/RightHand", "type" : "skeleton", "skeleton": "/skeleton/hand/right"}) 70 | 71 | try: 72 | with open("actions.json", "w") as f: 73 | f.write(json.dumps(manifest, indent=4)) 74 | except: 75 | print ("failed to create manifest") 76 | else: 77 | print ("successfully created manifest") 78 | 79 | #todo: merge thumbstick dpad actions 80 | 81 | alternatives = { 82 | "knuckles" : { 83 | "SwitchWeapons" : "trackpad" 84 | } 85 | } 86 | 87 | swapmap = { 88 | "oculus_touch" : { 89 | "a" : "x", 90 | "b" : "y", 91 | "x" : "a", 92 | "y" : "b" 93 | } 94 | } 95 | 96 | for v in variants: 97 | for c in controllers: 98 | 99 | filename = c + "_"+v.split(' ', 1)[0].lower() 100 | 101 | controller = { 102 | "bindings" : { 103 | "/actions/default" : { 104 | "haptics" : [], 105 | "poses" : [], 106 | "sources" : [], 107 | "skeleton" : [] 108 | }, 109 | "/actions/left handed" : { 110 | "haptics" : [], 111 | "poses" : [], 112 | "sources" : [], 113 | "skeleton" : [] 114 | } 115 | }, 116 | "controller_type" : c, 117 | "description" : "(" + v + ") Autogenerated bindings for " + c, 118 | "name" : "(" + v + ") " + c 119 | } 120 | 121 | controller["bindings"]["/actions/default"]["skeleton"].append({"output" : "/actions/default/in/LeftHand", "path" : "/user/hand/left/input/skeleton/left"}) 122 | controller["bindings"]["/actions/default"]["skeleton"].append({"output" : "/actions/default/in/RightHand", "path" : "/user/hand/right/input/skeleton/right"}) 123 | 124 | for p in poses: 125 | controller["bindings"]["/actions/default"]["poses"].append({"output" : "/actions/default/in/Left"+p, "path" : "/user/hand/left/pose/"+poses[p]}); 126 | controller["bindings"]["/actions/default"]["poses"].append({"output" : "/actions/default/in/Right"+p, "path" : "/user/hand/right/pose/"+poses[p]}); 127 | 128 | for binding in bindings: 129 | b = bindings[binding] 130 | 131 | parameters = {} 132 | 133 | mode = "button" 134 | 135 | inputs = b["b"].split("|") 136 | 137 | if c in alternatives and binding in alternatives[c]: 138 | inputs = alternatives[c][binding].split("|") 139 | 140 | inputtype = "click" 141 | 142 | finalhand = b["h"] 143 | 144 | invertsticks = "left" in v.lower() and "joystick" in inputs[0] 145 | 146 | if invertsticks: 147 | if finalhand == "left": 148 | finalhand = "right" 149 | else: 150 | finalhand = "left" 151 | 152 | if inputs[0] == "joystick": 153 | if c == "knuckles": 154 | inputs[0] = "thumbstick" 155 | 156 | if len(inputs) > 1: 157 | mode = "dpad" 158 | parameters["sub_mode"] = "touch" 159 | inputtype = inputs[1] 160 | 161 | needsMerge = False 162 | 163 | for entry in controller["bindings"]["/actions/default"]["sources"]: 164 | if entry["mode"] == mode and entry["path"] == "/user/hand/" + finalhand + "/input/" + inputs[0]: 165 | needsMerge = True 166 | break 167 | 168 | if needsMerge: 169 | entry["inputs"][inputtype] = {"output" : "/actions/default/in/" + binding} 170 | continue 171 | else: 172 | mode = "joystick" 173 | inputtype = "position" 174 | elif inputs[0] == "grip": 175 | parameters["click_activate_threshold"] = 0.8 176 | parameters["click_deactivate_threshold"] = 0.7 177 | elif inputs[0] == "x": 178 | if c == "knuckles": 179 | inputs[0] = "a" 180 | elif inputs[0] == "y": 181 | if c == "knuckles": 182 | inputs[0] = "b" 183 | elif inputs[0] == "thumbrest": 184 | if c == "knuckles": 185 | inputs[0] = "trackpad" 186 | 187 | for actionset in b["actionsets"]: 188 | # Swap hands for left Hand action set 189 | actionsetHand = finalhand 190 | actionsetHandSwapped = False 191 | if not invertsticks and b["swapActionSetHand"] and actionset == "left handed": 192 | if finalhand == "right": 193 | actionsetHand = "left" 194 | actionsetHandSwapped = True 195 | if finalhand == "left": 196 | actionsetHand = "right" 197 | actionsetHandSwapped = True 198 | 199 | actionset = "/actions/" + actionset 200 | 201 | input = {} 202 | input[inputtype] = {"output" : actionset + "/in/" + binding} 203 | finalinput = inputs[0] 204 | 205 | if (invertsticks or actionsetHandSwapped == True) and b["f"] == True and c in swapmap and finalinput in swapmap[c]: 206 | finalinput = swapmap[c][finalinput] 207 | 208 | controller["bindings"][actionset]["sources"].append({"inputs" : input, "mode" : mode, "path" : "/user/hand/" + actionsetHand + "/input/" + finalinput, "parameters" : parameters}) 209 | 210 | try: 211 | with open(filename+".json", "w") as f: 212 | f.write(json.dumps(controller, indent=4)) 213 | except: 214 | print ("failed to create " + filename + ".json") 215 | else: 216 | print ("successfully created " + filename + ".json") 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /Extras/Bindings/oculus_touch_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/default": { 4 | "haptics": [], 5 | "poses": [ 6 | { 7 | "output": "/actions/default/in/LeftTip", 8 | "path": "/user/hand/left/pose/tip" 9 | }, 10 | { 11 | "output": "/actions/default/in/RightTip", 12 | "path": "/user/hand/right/pose/tip" 13 | } 14 | ], 15 | "sources": [ 16 | { 17 | "inputs": { 18 | "north": { 19 | "output": "/actions/default/in/Jump" 20 | }, 21 | "south": { 22 | "output": "/actions/default/in/Crouch" 23 | } 24 | }, 25 | "mode": "dpad", 26 | "path": "/user/hand/left/input/joystick", 27 | "parameters": { 28 | "sub_mode": "touch" 29 | } 30 | }, 31 | { 32 | "inputs": { 33 | "click": { 34 | "output": "/actions/default/in/TwoHandGrip" 35 | } 36 | }, 37 | "mode": "button", 38 | "path": "/user/hand/left/input/grip", 39 | "parameters": { 40 | "click_activate_threshold": 0.8, 41 | "click_deactivate_threshold": 0.7 42 | } 43 | }, 44 | { 45 | "inputs": { 46 | "click": { 47 | "output": "/actions/default/in/SwitchWeapons" 48 | } 49 | }, 50 | "mode": "button", 51 | "path": "/user/hand/right/input/grip", 52 | "parameters": { 53 | "click_activate_threshold": 0.8, 54 | "click_deactivate_threshold": 0.7 55 | } 56 | }, 57 | { 58 | "inputs": { 59 | "click": { 60 | "output": "/actions/default/in/SwapWeaponHand" 61 | } 62 | }, 63 | "mode": "button", 64 | "path": "/user/hand/left/input/grip", 65 | "parameters": { 66 | "click_activate_threshold": 0.8, 67 | "click_deactivate_threshold": 0.7 68 | } 69 | }, 70 | { 71 | "inputs": { 72 | "click": { 73 | "output": "/actions/default/in/MenuBack" 74 | } 75 | }, 76 | "mode": "button", 77 | "path": "/user/hand/left/input/y", 78 | "parameters": {} 79 | }, 80 | { 81 | "inputs": { 82 | "click": { 83 | "output": "/actions/default/in/SwitchGrenades" 84 | } 85 | }, 86 | "mode": "button", 87 | "path": "/user/hand/left/input/x", 88 | "parameters": {} 89 | }, 90 | { 91 | "inputs": { 92 | "click": { 93 | "output": "/actions/default/in/Grenade" 94 | } 95 | }, 96 | "mode": "button", 97 | "path": "/user/hand/right/input/a", 98 | "parameters": {} 99 | }, 100 | { 101 | "inputs": { 102 | "click": { 103 | "output": "/actions/default/in/Reload" 104 | } 105 | }, 106 | "mode": "button", 107 | "path": "/user/hand/right/input/b", 108 | "parameters": {} 109 | }, 110 | { 111 | "inputs": { 112 | "click": { 113 | "output": "/actions/default/in/Interact" 114 | } 115 | }, 116 | "mode": "button", 117 | "path": "/user/hand/right/input/b", 118 | "parameters": {} 119 | }, 120 | { 121 | "inputs": { 122 | "click": { 123 | "output": "/actions/default/in/Zoom" 124 | } 125 | }, 126 | "mode": "button", 127 | "path": "/user/hand/left/input/trigger", 128 | "parameters": {} 129 | }, 130 | { 131 | "inputs": { 132 | "click": { 133 | "output": "/actions/default/in/Fire" 134 | } 135 | }, 136 | "mode": "button", 137 | "path": "/user/hand/right/input/trigger", 138 | "parameters": {} 139 | }, 140 | { 141 | "inputs": { 142 | "position": { 143 | "output": "/actions/default/in/Look" 144 | } 145 | }, 146 | "mode": "joystick", 147 | "path": "/user/hand/left/input/joystick", 148 | "parameters": {} 149 | }, 150 | { 151 | "inputs": { 152 | "position": { 153 | "output": "/actions/default/in/Move" 154 | } 155 | }, 156 | "mode": "joystick", 157 | "path": "/user/hand/right/input/joystick", 158 | "parameters": {} 159 | } 160 | ], 161 | "skeleton": [ 162 | { 163 | "output": "/actions/default/in/LeftHand", 164 | "path": "/user/hand/left/input/skeleton/left" 165 | }, 166 | { 167 | "output": "/actions/default/in/RightHand", 168 | "path": "/user/hand/right/input/skeleton/right" 169 | } 170 | ] 171 | }, 172 | "/actions/left handed": { 173 | "haptics": [], 174 | "poses": [], 175 | "sources": [ 176 | { 177 | "inputs": { 178 | "north": { 179 | "output": "/actions/left handed/in/Jump" 180 | } 181 | }, 182 | "mode": "dpad", 183 | "path": "/user/hand/left/input/joystick", 184 | "parameters": { 185 | "sub_mode": "touch" 186 | } 187 | }, 188 | { 189 | "inputs": { 190 | "click": { 191 | "output": "/actions/left handed/in/TwoHandGrip" 192 | } 193 | }, 194 | "mode": "button", 195 | "path": "/user/hand/right/input/grip", 196 | "parameters": { 197 | "click_activate_threshold": 0.8, 198 | "click_deactivate_threshold": 0.7 199 | } 200 | }, 201 | { 202 | "inputs": { 203 | "click": { 204 | "output": "/actions/left handed/in/SwitchWeapons" 205 | } 206 | }, 207 | "mode": "button", 208 | "path": "/user/hand/left/input/grip", 209 | "parameters": { 210 | "click_activate_threshold": 0.8, 211 | "click_deactivate_threshold": 0.7 212 | } 213 | }, 214 | { 215 | "inputs": { 216 | "click": { 217 | "output": "/actions/left handed/in/SwapWeaponHand" 218 | } 219 | }, 220 | "mode": "button", 221 | "path": "/user/hand/right/input/grip", 222 | "parameters": { 223 | "click_activate_threshold": 0.8, 224 | "click_deactivate_threshold": 0.7 225 | } 226 | }, 227 | { 228 | "inputs": { 229 | "click": { 230 | "output": "/actions/left handed/in/MenuBack" 231 | } 232 | }, 233 | "mode": "button", 234 | "path": "/user/hand/right/input/b", 235 | "parameters": {} 236 | }, 237 | { 238 | "inputs": { 239 | "click": { 240 | "output": "/actions/left handed/in/SwitchGrenades" 241 | } 242 | }, 243 | "mode": "button", 244 | "path": "/user/hand/right/input/a", 245 | "parameters": {} 246 | }, 247 | { 248 | "inputs": { 249 | "click": { 250 | "output": "/actions/left handed/in/Grenade" 251 | } 252 | }, 253 | "mode": "button", 254 | "path": "/user/hand/left/input/x", 255 | "parameters": {} 256 | }, 257 | { 258 | "inputs": { 259 | "click": { 260 | "output": "/actions/left handed/in/Reload" 261 | } 262 | }, 263 | "mode": "button", 264 | "path": "/user/hand/left/input/y", 265 | "parameters": {} 266 | }, 267 | { 268 | "inputs": { 269 | "click": { 270 | "output": "/actions/left handed/in/Interact" 271 | } 272 | }, 273 | "mode": "button", 274 | "path": "/user/hand/left/input/y", 275 | "parameters": {} 276 | }, 277 | { 278 | "inputs": { 279 | "click": { 280 | "output": "/actions/left handed/in/Zoom" 281 | } 282 | }, 283 | "mode": "button", 284 | "path": "/user/hand/right/input/trigger", 285 | "parameters": {} 286 | }, 287 | { 288 | "inputs": { 289 | "click": { 290 | "output": "/actions/left handed/in/Fire" 291 | } 292 | }, 293 | "mode": "button", 294 | "path": "/user/hand/left/input/trigger", 295 | "parameters": {} 296 | }, 297 | { 298 | "inputs": { 299 | "position": { 300 | "output": "/actions/left handed/in/Look" 301 | } 302 | }, 303 | "mode": "joystick", 304 | "path": "/user/hand/left/input/joystick", 305 | "parameters": {} 306 | }, 307 | { 308 | "inputs": { 309 | "position": { 310 | "output": "/actions/left handed/in/Move" 311 | } 312 | }, 313 | "mode": "joystick", 314 | "path": "/user/hand/right/input/joystick", 315 | "parameters": {} 316 | } 317 | ], 318 | "skeleton": [] 319 | } 320 | }, 321 | "controller_type": "oculus_touch", 322 | "description": "(Left Handed) Autogenerated bindings for oculus_touch", 323 | "name": "(Left Handed) oculus_touch" 324 | } -------------------------------------------------------------------------------- /Extras/Fonts/bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Fonts/bold.ttf -------------------------------------------------------------------------------- /Extras/Fonts/bold_italics.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Fonts/bold_italics.ttf -------------------------------------------------------------------------------- /Extras/Fonts/italics.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Fonts/italics.ttf -------------------------------------------------------------------------------- /Extras/Fonts/normal.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Fonts/normal.ttf -------------------------------------------------------------------------------- /Extras/Images/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Images/left.png -------------------------------------------------------------------------------- /Extras/Images/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Images/right.png -------------------------------------------------------------------------------- /Extras/Images/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/Extras/Images/settings.png -------------------------------------------------------------------------------- /HaloCEVR.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.7.34202.233 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HaloCEVR", "HaloCEVR\HaloCEVR.vcxproj", "{4EE74470-E365-48E4-9920-237AA8B6F6D0}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "ThirdParty\MinHook\build\VC17\libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x86 = Debug|x86 13 | Emulated-VR|x86 = Emulated-VR|x86 14 | Release|x86 = Release|x86 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {4EE74470-E365-48E4-9920-237AA8B6F6D0}.Debug|x86.ActiveCfg = Debug|Win32 18 | {4EE74470-E365-48E4-9920-237AA8B6F6D0}.Debug|x86.Build.0 = Debug|Win32 19 | {4EE74470-E365-48E4-9920-237AA8B6F6D0}.Emulated-VR|x86.ActiveCfg = Emulated-VR|Win32 20 | {4EE74470-E365-48E4-9920-237AA8B6F6D0}.Emulated-VR|x86.Build.0 = Emulated-VR|Win32 21 | {4EE74470-E365-48E4-9920-237AA8B6F6D0}.Release|x86.ActiveCfg = Release|Win32 22 | {4EE74470-E365-48E4-9920-237AA8B6F6D0}.Release|x86.Build.0 = Release|Win32 23 | {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x86.ActiveCfg = Debug|Win32 24 | {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x86.Build.0 = Debug|Win32 25 | {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Emulated-VR|x86.ActiveCfg = Emulated-VR|Win32 26 | {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Emulated-VR|x86.Build.0 = Emulated-VR|Win32 27 | {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x86.ActiveCfg = Release|Win32 28 | {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x86.Build.0 = Release|Win32 29 | EndGlobalSection 30 | GlobalSection(SolutionProperties) = preSolution 31 | HideSolutionNode = FALSE 32 | EndGlobalSection 33 | GlobalSection(ExtensibilityGlobals) = postSolution 34 | SolutionGuid = {D58FE094-064C-4D8D-A57F-899541550F59} 35 | EndGlobalSection 36 | EndGlobal 37 | -------------------------------------------------------------------------------- /HaloCEVR/Config/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../Maths/Vectors.h" 7 | #include "../Logger.h" 8 | 9 | class Property { 10 | public: 11 | Property(const std::string& description) : description_(description), guid(-1) {} 12 | 13 | virtual ~Property() = default; 14 | 15 | std::string& GetDesc() { return description_; }; 16 | protected: 17 | std::string description_; 18 | int guid; 19 | friend class Config; 20 | }; 21 | 22 | class BoolProperty : public Property { 23 | public: 24 | BoolProperty(bool value, const std::string& description) : value_(value), default_(value), Property(description) {} 25 | bool Value() const { return value_; } 26 | void SetValue(bool newValue) { value_ = newValue; } 27 | bool DefaultValue() const { return default_; } 28 | private: 29 | bool value_; 30 | bool default_; 31 | friend class Config; 32 | }; 33 | 34 | class IntProperty : public Property { 35 | public: 36 | IntProperty(int value, const std::string& description) : value_(value), default_(value), Property(description) {} 37 | int Value() const { return value_; } 38 | void SetValue(int newValue) { value_ = newValue; } 39 | int DefaultValue() const { return default_; } 40 | private: 41 | int value_; 42 | int default_; 43 | friend class Config; 44 | }; 45 | 46 | class FloatProperty : public Property { 47 | public: 48 | FloatProperty(float value, const std::string& description) : value_(value), default_(value), Property(description) {} 49 | float Value() const { return value_; } 50 | void SetValue(float newValue) { value_ = newValue; } 51 | float DefaultValue() const { return default_; } 52 | private: 53 | float value_; 54 | float default_; 55 | friend class Config; 56 | }; 57 | 58 | class StringProperty : public Property { 59 | public: 60 | StringProperty(const std::string& value, const std::string& description) : value_(value), default_(value), Property(description) {} 61 | std::string Value() const { return value_; } 62 | void SetValue(const std::string& newValue) { value_ = newValue; } 63 | std::string DefaultValue() const { return default_; } 64 | private: 65 | std::string value_; 66 | std::string default_; 67 | friend class Config; 68 | }; 69 | 70 | class Vector3Property : public Property { 71 | public: 72 | Vector3Property(const Vector3& value, const std::string& description) : value_(value), default_(value), Property(description) {} 73 | Vector3 Value() const { return value_; } 74 | void SetValue(const Vector3& newValue) { value_ = newValue; } 75 | Vector3 DefaultValue() const { return default_; } 76 | private: 77 | Vector3 value_; 78 | Vector3 default_; 79 | friend class Config; 80 | }; 81 | 82 | class Config { 83 | public: 84 | BoolProperty* RegisterBool(const std::string& name, const std::string& description, bool defaultValue) { 85 | BoolProperty* newProp = new BoolProperty(defaultValue, description); 86 | newProp->guid = guid++; 87 | properties_[name] = newProp; 88 | return newProp; 89 | } 90 | 91 | IntProperty* RegisterInt(const std::string& name, const std::string& description, int defaultValue) { 92 | IntProperty* newProp = new IntProperty(defaultValue, description); 93 | newProp->guid = guid++; 94 | properties_[name] = newProp; 95 | return newProp; 96 | } 97 | 98 | FloatProperty* RegisterFloat(const std::string& name, const std::string& description, float defaultValue) { 99 | FloatProperty* newProp = new FloatProperty(defaultValue, description); 100 | newProp->guid = guid++; 101 | properties_[name] = newProp; 102 | return newProp; 103 | } 104 | 105 | StringProperty* RegisterString(const std::string& name, const std::string& description, const std::string& defaultValue) { 106 | StringProperty* newProp = new StringProperty(defaultValue, description); 107 | newProp->guid = guid++; 108 | properties_[name] = newProp; 109 | return newProp; 110 | } 111 | 112 | Vector3Property* RegisterVector3(const std::string& name, const std::string& description, const Vector3 defaultValue) { 113 | Vector3Property* newProp = new Vector3Property(defaultValue, description); 114 | newProp->guid = guid++; 115 | properties_[name] = newProp; 116 | return newProp; 117 | } 118 | 119 | bool sortProperties(std::pair a, std::pair b) 120 | { 121 | return a.second->guid < b.second->guid; 122 | } 123 | 124 | bool SaveToFile(const std::string& filename) const { 125 | std::ofstream file(filename); 126 | std::vector> sortedProperties(properties_.begin(), properties_.end()); 127 | std::sort(sortedProperties.begin(), sortedProperties.end(), [](std::pair a, std::pair b) { return a.second->guid < b.second->guid; }); 128 | for (const auto& pair : sortedProperties) { 129 | const std::string& name = pair.first; 130 | Property* prop = pair.second; 131 | if (BoolProperty* boolProp = dynamic_cast(prop)) { 132 | file << "//[Bool] " << boolProp->GetDesc() << " (Default Value: " << (boolProp->DefaultValue() ? "true" : "false") << ")\n"; 133 | file << name << " = " << (boolProp->Value() ? "true" : "false") << "\n\n"; 134 | } 135 | else if (IntProperty* intProp = dynamic_cast(prop)) { 136 | file << "//[Int] " << intProp->GetDesc() << " (Default Value: " << intProp->DefaultValue() << ")\n"; 137 | file << name << " = " << intProp->Value() << "\n\n"; 138 | } 139 | else if (FloatProperty* floatProp = dynamic_cast(prop)) { 140 | file << "//[Float] " << floatProp->GetDesc() << " (Default Value: " << floatProp->DefaultValue() << ")\n"; 141 | file << name << " = " << floatProp->Value() << "\n\n"; 142 | } 143 | else if (StringProperty* stringProp = dynamic_cast(prop)) { 144 | file << "//[String] " << stringProp->GetDesc() << " (Default Value: \"" << stringProp->DefaultValue() << "\")\n"; 145 | file << name << " = " << stringProp->Value() << "\n\n"; 146 | } 147 | else if (Vector3Property* vec3Prop = dynamic_cast(prop)) 148 | { 149 | file << "//[Vector3] " << vec3Prop->GetDesc() << " (Default Value: \"" << vec3Prop->DefaultValue() << "\")\n"; 150 | file << name << " = " << vec3Prop->Value() << "\n\n"; 151 | } 152 | } 153 | 154 | file.close(); 155 | 156 | return file.good(); 157 | } 158 | 159 | bool LoadFromFile(const std::string& filename) { 160 | std::ifstream file(filename); 161 | 162 | if (!file.good()) 163 | { 164 | return false; 165 | } 166 | 167 | std::string line; 168 | while (std::getline(file, line)) { 169 | // Ignore comments 170 | if (line.empty() || line[0] == '/') continue; 171 | 172 | // Split the line into name and value 173 | std::string::size_type pos = line.find('='); 174 | if (pos == std::string::npos) continue; // Invalid line 175 | 176 | std::string name = line.substr(0, pos); 177 | std::string value = line.substr(pos + 1); 178 | 179 | // Trim whitespace 180 | name.erase(name.begin(), std::find_if(name.begin(), name.end(), [](char ch){ 181 | return !std::isspace(ch); 182 | })); 183 | name.erase(std::find_if(name.rbegin(), name.rend(), [](char ch){ 184 | return !std::isspace(ch); 185 | }).base(), name.end()); 186 | 187 | value.erase(value.begin(), std::find_if(value.begin(), value.end(), [](char ch){ 188 | return !std::isspace(ch); 189 | })); 190 | value.erase(std::find_if(value.rbegin(), value.rend(), [](char ch){ 191 | return !std::isspace(ch); 192 | }).base(), value.end()); 193 | 194 | if (properties_.find(name) == properties_.end()) 195 | { 196 | Logger::log << "[Config] Found invalid property " << name << ", ignoring" << std::endl; 197 | continue; 198 | } 199 | 200 | // Update the corresponding property 201 | Property* prop = properties_[name]; 202 | if (dynamic_cast(prop)) { 203 | std::transform(value.begin(), value.end(), value.begin(), 204 | [](unsigned char c) { return std::tolower(c); }); 205 | BoolProperty* bProp = static_cast(prop); 206 | bProp->value_ = value == "true"; 207 | Logger::log << "[Config] " << name << " = " << (bProp->Value() ? "true" : "false") << ((bProp->Value() != bProp->DefaultValue()) ? "*" : "") << std::endl; 208 | } 209 | else if (dynamic_cast(prop)) { 210 | IntProperty* iProp = static_cast(prop); 211 | iProp->value_ = std::stoi(value); 212 | Logger::log << "[Config] " << name << " = " << iProp->Value() << ((iProp->Value() != iProp->DefaultValue()) ? "*" : "") << std::endl; 213 | } 214 | else if (dynamic_cast(prop)) { 215 | FloatProperty* fProp = static_cast(prop); 216 | fProp->value_ = std::stof(value); 217 | Logger::log << "[Config] " << name << " = " << fProp->Value() << ((std::abs(fProp->Value() - fProp->DefaultValue()) > 1e-8) ? "*" : "") << std::endl; 218 | } 219 | else if (dynamic_cast(prop)) { 220 | StringProperty* sProp = static_cast(prop); 221 | sProp->value_ = value; 222 | Logger::log << "[Config] " << name << " = " << sProp->Value() << ((sProp->Value() != sProp->DefaultValue()) ? "*" : "") << std::endl; 223 | } 224 | else if (dynamic_cast(prop)) { 225 | Vector3Property* vProp = static_cast(prop); 226 | // Find X 227 | value.erase(value.begin(), std::find_if(value.begin(), value.end(), [](char ch) { 228 | return !std::isspace(ch) && ch != '('; 229 | })); 230 | 231 | std::size_t len; 232 | float x = std::stof(value, &len); 233 | 234 | value.erase(value.begin(), value.begin() + len); 235 | 236 | // Find Y 237 | value.erase(value.begin(), std::find_if(value.begin(), value.end(), [](char ch) { 238 | return !std::isspace(ch) && ch != ','; 239 | })); 240 | 241 | float y = std::stof(value, &len); 242 | 243 | value.erase(value.begin(), value.begin() + len); 244 | 245 | // Find Z 246 | value.erase(value.begin(), std::find_if(value.begin(), value.end(), [](char ch) { 247 | return !std::isspace(ch) && ch != ','; 248 | })); 249 | 250 | float z = std::stof(value); 251 | 252 | vProp->value_ = Vector3(x, y, z); 253 | Logger::log << "[Config] " << name << " = " << vProp->Value() << ((vProp->Value() != vProp->DefaultValue()) ? "*" : "") << std::endl; 254 | } 255 | } 256 | 257 | return true; 258 | } 259 | 260 | std::vector GetAllSettings() const { 261 | std::vector outKeys; 262 | outKeys.reserve(properties_.size()); 263 | 264 | std::vector> sortedProperties(properties_.begin(), properties_.end()); 265 | std::sort(sortedProperties.begin(), sortedProperties.end(), [](std::pair a, std::pair b) { return a.second->guid < b.second->guid; }); 266 | for (const auto& pair : sortedProperties) 267 | { 268 | outKeys.push_back(pair.first); 269 | } 270 | 271 | return outKeys; 272 | } 273 | 274 | Property* Get(const std::string& name) const { 275 | try 276 | { 277 | return properties_.at(name); 278 | } 279 | catch (std::exception e) 280 | { 281 | return nullptr; 282 | } 283 | } 284 | 285 | BoolProperty* GetBool(const std::string& name) const { 286 | return dynamic_cast(properties_.at(name)); 287 | } 288 | 289 | IntProperty* GetInt(const std::string& name) const { 290 | return dynamic_cast(properties_.at(name)); 291 | } 292 | 293 | FloatProperty* GetFloat(const std::string& name) const { 294 | return dynamic_cast(properties_.at(name)); 295 | } 296 | 297 | StringProperty* GetString(const std::string& name) const { 298 | return dynamic_cast(properties_.at(name)); 299 | } 300 | 301 | private: 302 | std::unordered_map properties_; 303 | 304 | int guid = 0; 305 | }; -------------------------------------------------------------------------------- /HaloCEVR/DirectXWrappers/IDirect3D9ExWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "IDirect3D9ExWrapper.h" 2 | #include "IDirect3DDevice9ExWrapper.h" 3 | #include "../Logger.h" 4 | #include "../Game.h" 5 | 6 | HRESULT IDirect3D9ExWrapper::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) 7 | { 8 | Logger::log << "Intercepting CreateDevice, creating wrapped Ex version" << std::endl; 9 | 10 | Logger::log << "Given present params: " << pPresentationParameters->PresentationInterval << ", " << pPresentationParameters->BackBufferWidth << ", " << pPresentationParameters->BackBufferHeight << std::endl; 11 | pPresentationParameters->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 12 | 13 | // It should be possible to avoid this hack by using a similar approach to scope, but the code path is slightly different 14 | if (pPresentationParameters->BackBufferWidth != 1200 || pPresentationParameters->BackBufferHeight != 600) 15 | { 16 | pPresentationParameters->BackBufferWidth = Game::instance.backBufferWidth; 17 | pPresentationParameters->BackBufferHeight = Game::instance.backBufferHeight; 18 | Logger::log << "New dimensions: " << Game::instance.backBufferWidth << "x" << Game::instance.backBufferHeight << std::endl; 19 | } 20 | 21 | IDirect3DDevice9Ex* RealDevice = nullptr; 22 | HRESULT Result = Real->CreateDeviceEx(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, NULL, &RealDevice); 23 | 24 | if (SUCCEEDED(Result)) 25 | { 26 | *ppReturnedDeviceInterface = new IDirect3DDevice9ExWrapper(RealDevice); 27 | } 28 | else 29 | { 30 | *ppReturnedDeviceInterface = nullptr; 31 | } 32 | 33 | return Result; 34 | } 35 | 36 | HRESULT __stdcall IDirect3D9ExWrapper::QueryInterface(REFIID riid, void** ppvObj) 37 | { 38 | return Real->QueryInterface(riid, ppvObj); 39 | } 40 | 41 | ULONG __stdcall IDirect3D9ExWrapper::AddRef(void) 42 | { 43 | return Real->AddRef(); 44 | } 45 | 46 | ULONG __stdcall IDirect3D9ExWrapper::Release(void) 47 | { 48 | Game::instance.Shutdown(); 49 | return Real->Release(); 50 | } 51 | 52 | HRESULT __stdcall IDirect3D9ExWrapper::RegisterSoftwareDevice(void* pInitializeFunction) 53 | { 54 | return Real->RegisterSoftwareDevice(pInitializeFunction); 55 | } 56 | 57 | UINT __stdcall IDirect3D9ExWrapper::GetAdapterCount(void) 58 | { 59 | return Real->GetAdapterCount(); 60 | } 61 | 62 | HRESULT __stdcall IDirect3D9ExWrapper::GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) 63 | { 64 | return Real->GetAdapterIdentifier(Adapter, Flags, pIdentifier); 65 | } 66 | 67 | UINT __stdcall IDirect3D9ExWrapper::GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) 68 | { 69 | return Real->GetAdapterModeCount(Adapter, Format); 70 | } 71 | 72 | HRESULT __stdcall IDirect3D9ExWrapper::EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) 73 | { 74 | return Real->EnumAdapterModes(Adapter, Format, Mode, pMode); 75 | } 76 | 77 | HRESULT __stdcall IDirect3D9ExWrapper::GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) 78 | { 79 | HRESULT result = Real->GetAdapterDisplayMode(Adapter, pMode); 80 | 81 | if (SUCCEEDED(result)) 82 | { 83 | return result; 84 | } 85 | 86 | // There's a very weird bug on my Radeon machine where this call fails unless I swap the display's graphics format back and forth before launching 87 | // Hopefully if we just lie to halo about the result of this call nothing will break... 88 | Logger::log << "[D3D] WARNING! GetAdapterDisplayMode failed, lying about the results to shut up halo" << std::endl; 89 | 90 | pMode->Format = D3DFMT_X8R8G8B8; 91 | pMode->Width = 1080; 92 | pMode->Height = 1920; 93 | pMode->RefreshRate = 60; 94 | return S_OK; 95 | } 96 | 97 | HRESULT __stdcall IDirect3D9ExWrapper::CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) 98 | { 99 | return Real->CheckDeviceType(Adapter, DevType, AdapterFormat, BackBufferFormat, bWindowed); 100 | } 101 | 102 | HRESULT __stdcall IDirect3D9ExWrapper::CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) 103 | { 104 | return Real->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); 105 | } 106 | 107 | HRESULT __stdcall IDirect3D9ExWrapper::CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) 108 | { 109 | return Real->CheckDeviceMultiSampleType(Adapter, DeviceType, SurfaceFormat, Windowed, MultiSampleType, pQualityLevels); 110 | } 111 | 112 | HRESULT __stdcall IDirect3D9ExWrapper::CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) 113 | { 114 | return Real->CheckDepthStencilMatch(Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat); 115 | } 116 | 117 | HRESULT __stdcall IDirect3D9ExWrapper::CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) 118 | { 119 | return Real->CheckDeviceFormatConversion(Adapter, DeviceType, SourceFormat, TargetFormat); 120 | } 121 | 122 | HRESULT __stdcall IDirect3D9ExWrapper::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) 123 | { 124 | return Real->GetDeviceCaps(Adapter, DeviceType, pCaps); 125 | } 126 | 127 | HMONITOR __stdcall IDirect3D9ExWrapper::GetAdapterMonitor(UINT Adapter) 128 | { 129 | return Real->GetAdapterMonitor(Adapter); 130 | } 131 | 132 | UINT __stdcall IDirect3D9ExWrapper::GetAdapterModeCountEx(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter) 133 | { 134 | return Real->GetAdapterModeCountEx(Adapter, pFilter); 135 | } 136 | 137 | HRESULT __stdcall IDirect3D9ExWrapper::EnumAdapterModesEx(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter, UINT Mode, D3DDISPLAYMODEEX* pMode) 138 | { 139 | return Real->EnumAdapterModesEx(Adapter, pFilter, Mode, pMode); 140 | } 141 | 142 | HRESULT __stdcall IDirect3D9ExWrapper::GetAdapterDisplayModeEx(UINT Adapter, D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation) 143 | { 144 | return Real->GetAdapterDisplayModeEx(Adapter, pMode, pRotation); 145 | } 146 | 147 | HRESULT __stdcall IDirect3D9ExWrapper::CreateDeviceEx(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) 148 | { 149 | Logger::log << "Intercepting CreateDeviceEx, supplying wrapped version" << std::endl; 150 | IDirect3DDevice9Ex* RealDevice = nullptr; 151 | HRESULT Result = Real->CreateDeviceEx(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode, &RealDevice); 152 | 153 | if (SUCCEEDED(Result)) 154 | { 155 | *ppReturnedDeviceInterface = new IDirect3DDevice9ExWrapper(RealDevice); 156 | } 157 | else 158 | { 159 | *ppReturnedDeviceInterface = nullptr; 160 | } 161 | 162 | return Result; 163 | } 164 | 165 | HRESULT __stdcall IDirect3D9ExWrapper::GetAdapterLUID(UINT Adapter, LUID* pLUID) 166 | { 167 | return Real->GetAdapterLUID(Adapter, pLUID); 168 | } 169 | -------------------------------------------------------------------------------- /HaloCEVR/DirectXWrappers/IDirect3D9ExWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | class IDirect3D9ExWrapper : public IDirect3D9Ex 4 | { 5 | public: 6 | IDirect3D9ExWrapper(IDirect3D9Ex* RealInstance) { Real = RealInstance; } 7 | 8 | virtual __declspec(nothrow) HRESULT __stdcall CreateDevice(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface); 9 | 10 | // Inherited via IDirect3D9Ex 11 | virtual __declspec(nothrow)HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj) override; 12 | virtual __declspec(nothrow)ULONG __stdcall AddRef(void) override; 13 | virtual __declspec(nothrow)ULONG __stdcall Release(void) override; 14 | virtual __declspec(nothrow)HRESULT __stdcall RegisterSoftwareDevice(void* pInitializeFunction) override; 15 | virtual __declspec(nothrow)UINT __stdcall GetAdapterCount(void) override; 16 | virtual __declspec(nothrow)HRESULT __stdcall GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) override; 17 | virtual __declspec(nothrow)UINT __stdcall GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) override; 18 | virtual __declspec(nothrow)HRESULT __stdcall EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) override; 19 | virtual __declspec(nothrow)HRESULT __stdcall GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) override; 20 | virtual __declspec(nothrow)HRESULT __stdcall CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) override; 21 | virtual __declspec(nothrow)HRESULT __stdcall CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) override; 22 | virtual __declspec(nothrow)HRESULT __stdcall CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) override; 23 | virtual __declspec(nothrow)HRESULT __stdcall CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) override; 24 | virtual __declspec(nothrow)HRESULT __stdcall CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) override; 25 | virtual __declspec(nothrow)HRESULT __stdcall GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) override; 26 | virtual __declspec(nothrow)HMONITOR __stdcall GetAdapterMonitor(UINT Adapter) override; 27 | virtual __declspec(nothrow)UINT __stdcall GetAdapterModeCountEx(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter) override; 28 | virtual __declspec(nothrow)HRESULT __stdcall EnumAdapterModesEx(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter, UINT Mode, D3DDISPLAYMODEEX* pMode) override; 29 | virtual __declspec(nothrow)HRESULT __stdcall GetAdapterDisplayModeEx(UINT Adapter, D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation) override; 30 | virtual __declspec(nothrow)HRESULT __stdcall CreateDeviceEx(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) override; 31 | virtual __declspec(nothrow)HRESULT __stdcall GetAdapterLUID(UINT Adapter, LUID* pLUID) override; 32 | 33 | protected: 34 | IDirect3D9Ex* Real; 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /HaloCEVR/Game.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define WIN32_LEAN_AND_MEAN 3 | #define NOMINMAX 4 | #include 5 | #include 6 | #include "Config/Config.h" 7 | #include "VR/IVR.h" 8 | #include "Helpers/Renderer.h" 9 | #include "Helpers/RenderTarget.h" 10 | #include "Helpers/Objects.h" 11 | #include "Maths/Vectors.h" 12 | #include "WeaponHandler.h" 13 | #include "InputHandler.h" 14 | #include "InGameRenderer.h" 15 | #include "Profiler.h" 16 | #include "UI/UIRenderer.h" 17 | #include "UI/SettingsMenu.h" 18 | 19 | enum class ERenderState { UNKNOWN, LEFT_EYE, RIGHT_EYE, GAME, SCOPE}; 20 | 21 | class Game 22 | { 23 | public: 24 | static Game instance; 25 | 26 | void Init(); 27 | void Shutdown(); 28 | 29 | void OnInitDirectX(); 30 | void PreDrawFrame(struct Renderer* renderer, float deltaTime); 31 | void PreDrawEye(struct Renderer* renderer, float deltaTime, int eye); 32 | void PostDrawEye(struct Renderer* renderer, float deltaTime, int eye); 33 | bool PreDrawScope(struct Renderer* renderer, float deltaTime); 34 | void PostDrawScope(struct Renderer* renderer, float deltaTime); 35 | void PreDrawMirror(struct Renderer* renderer, float deltaTime); 36 | void PostDrawMirror(struct Renderer* renderer, float deltaTime); 37 | void PostDrawFrame(struct Renderer* renderer, float deltaTime); 38 | Vector3 GetSmoothedInput() const; 39 | 40 | bool PreDrawHUD(); 41 | void PostDrawHUD(); 42 | 43 | bool PreDrawMenu(); 44 | void PostDrawMenu(); 45 | 46 | bool PreDrawLoading(int param1, struct Renderer* renderer); 47 | void PostDrawLoading(int param1, struct Renderer* renderer); 48 | 49 | bool PreDrawCrosshair(short* anchorLocation); 50 | void PostDrawCrosshair(); 51 | 52 | void PreDrawImage(void* param1, void* param2); 53 | void PostDrawImage(void* param1, void* param2); 54 | 55 | void UpdateViewModel(HaloID& id, struct Vector3* pos, struct Vector3* facing, struct Vector3* up, struct TransformQuat* BoneTransforms, struct Transform* OutBoneTransforms); 56 | void PreFireWeapon(HaloID& WeaponID, short param2); 57 | void PostFireWeapon(HaloID& WeaponID, short param2); 58 | void PreThrowGrenade(HaloID& playerID); 59 | void PostThrowGrenade(HaloID& playerID); 60 | bool GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand); 61 | void ReloadStart(HaloID param1, short param2, bool param3); 62 | void ReloadEnd(short param1, HaloID param2); 63 | 64 | void UpdateInputs(); 65 | void CalculateSmoothedInput(); 66 | 67 | void UpdateCamera(float& yaw, float& pitch); 68 | void SetMousePosition(int& x, int& y); 69 | void UpdateMouseInfo(struct MouseInfo* mouseInfo); 70 | 71 | void SetViewportScale(struct Viewport* viewport); 72 | 73 | bool GetDrawMirror() const { return mirrorSource == ERenderState::GAME && c_DrawMirror->Value(); } 74 | 75 | ERenderState GetRenderState() const { return renderState; } 76 | 77 | float GetScopeSize() const { return c_ScopeScale->Value(); } 78 | 79 | float MetresToWorld(float m) const; 80 | float WorldToMetres(float w) const; 81 | 82 | inline IVR* GetVR() const { return vr; } 83 | 84 | UINT backBufferWidth = 600; 85 | UINT backBufferHeight = 600; 86 | 87 | // HACK: Some places it is hard to get the delta time (e.g. updating the camera) 88 | // Using the last known delta time should be good enough 89 | float lastDeltaTime = 0.0f; 90 | 91 | bool bNeedsRecentre = true; 92 | bool bUseTwoHandAim = false; 93 | bool bLeftHanded = false; 94 | 95 | Config config; 96 | 97 | InGameRenderer inGameRenderer; 98 | InGameRenderer scopeRenderer; 99 | UIRenderer* uiRenderer; 100 | SettingsMenu* settingsMenu; 101 | 102 | bool bDetectedChimera = false; 103 | Vector3 LastLookDir; 104 | 105 | bool bLoadedConfig = false; 106 | bool bSavedConfig = false; 107 | 108 | bool bIsCustom = false; 109 | 110 | UINT overlayWidth = 640; 111 | UINT overlayHeight = 640; 112 | 113 | #if USE_PROFILER 114 | Profiler profiler; 115 | #endif 116 | protected: 117 | 118 | void CreateConsole(); 119 | 120 | void PatchGame(); 121 | 122 | void SetupConfigs(); 123 | 124 | void CalcFPS(float deltaTime); 125 | #if USE_PROFILER 126 | void DumpProfilerData(); 127 | #endif 128 | 129 | void UpdateCrosshairAndScope(); 130 | void SetScopeTransform(Matrix4& newTransform, bool bIsVisible); 131 | 132 | void StoreRenderTargets(); 133 | void RestoreRenderTargets(); 134 | 135 | void CreateTextureAndSurface(UINT Width, UINT Height, DWORD Usage, D3DFORMAT Format, struct IDirect3DSurface9** OutSurface, struct IDirect3DTexture9** OutTexture); 136 | 137 | WeaponHandler weaponHandler; 138 | InputHandler inputHandler; 139 | 140 | struct FPSTracker 141 | { 142 | float timeSinceFPSUpdate = 0.0f; 143 | int framesSinceFPSUpdate = 0; 144 | 145 | int fps = 0; 146 | } fpsTracker; 147 | 148 | FILE* consoleOut = nullptr; 149 | 150 | IVR* vr; 151 | 152 | RenderTarget gameRenderTargets[8]; 153 | 154 | struct IDirect3DSurface9* uiSurface; 155 | struct IDirect3DSurface9* crosshairSurface; 156 | struct IDirect3DSurface9* uiRealSurface; 157 | struct IDirect3DSurface9* crosshairRealSurface; 158 | 159 | struct IDirect3DSurface9* scopeSurfaces[3]; 160 | struct IDirect3DTexture9* scopeTextures[3]; 161 | 162 | ERenderState renderState = ERenderState::UNKNOWN; 163 | 164 | CameraFrustum frustum1; 165 | CameraFrustum frustum2; 166 | 167 | short realZoom = -1; 168 | sRect realRect; 169 | sRect realLoadRect; 170 | UINT realUIWidth; 171 | UINT realUIHeight; 172 | 173 | DWORD realAlphaFunc; 174 | DWORD realAlphaSrc; 175 | DWORD realAlphaDest; 176 | 177 | bool bShowViewModel = false; 178 | 179 | bool bInVehicle = false; 180 | bool bHasWeapon = true; 181 | 182 | ERenderState mirrorSource; 183 | 184 | bool bHasShutdown = true; 185 | 186 | bool bWasLoading = false; 187 | 188 | //======Configs======// 189 | public: 190 | 191 | BoolProperty* c_ShowConsole = nullptr; 192 | BoolProperty* c_DrawMirror = nullptr; 193 | IntProperty* c_MirrorEye = nullptr; 194 | FloatProperty* c_CrosshairDistance = nullptr; 195 | FloatProperty* c_CrosshairScale = nullptr; 196 | FloatProperty* c_MenuOverlayDistance = nullptr; 197 | FloatProperty* c_UIOverlayDistance = nullptr; 198 | FloatProperty* c_UIOverlayScale = nullptr; 199 | FloatProperty* c_MenuOverlayScale = nullptr; 200 | FloatProperty* c_UIOverlayCurvature = nullptr; 201 | FloatProperty* c_UIOverlayRenderScale = nullptr; 202 | BoolProperty* c_ShowCrosshair = nullptr; 203 | BoolProperty* c_SnapTurn = nullptr; 204 | FloatProperty* c_SnapTurnAmount = nullptr; 205 | FloatProperty* c_SmoothTurnAmount = nullptr; 206 | IntProperty* c_HandRelativeMovement = nullptr; 207 | FloatProperty* c_HandRelativeOffsetRotation = nullptr; 208 | FloatProperty* c_HorizontalVehicleTurnAmount = nullptr; 209 | FloatProperty* c_VerticalVehicleTurnAmount = nullptr; 210 | BoolProperty* c_OffhandHandFlashlight = nullptr; 211 | FloatProperty* c_LeftHandFlashlightDistance = nullptr; 212 | FloatProperty* c_RightHandFlashlightDistance = nullptr; 213 | BoolProperty* c_EnableWeaponHolsters = nullptr; 214 | FloatProperty* c_LeftShoulderHolsterActivationDistance = nullptr; 215 | Vector3Property* c_LeftShoulderHolsterOffset = nullptr; 216 | FloatProperty* c_RightShoulderHolsterActivationDistance = nullptr; 217 | Vector3Property* c_RightShoulderHolsterOffset = nullptr; 218 | Vector3Property* c_ControllerOffset = nullptr; 219 | Vector3Property* c_ControllerRotation = nullptr; 220 | FloatProperty* c_ScopeRenderScale = nullptr; 221 | FloatProperty* c_ScopeScale = nullptr; 222 | BoolProperty* c_LockScopeRoll = nullptr; 223 | Vector3Property* c_ScopeOffsetPistol = nullptr; 224 | Vector3Property* c_ScopeOffsetSniper = nullptr; 225 | Vector3Property* c_ScopeOffsetRocket = nullptr; 226 | FloatProperty* c_LeftHandMeleeSwingSpeed = nullptr; 227 | FloatProperty* c_RightHandMeleeSwingSpeed = nullptr; 228 | FloatProperty* c_CrouchHeight = nullptr; 229 | BoolProperty* c_ShowRoomCentre = nullptr; 230 | BoolProperty* c_ToggleGrip = nullptr; 231 | FloatProperty* c_TwoHandDistance = nullptr; 232 | BoolProperty* c_LeftHanded = nullptr; 233 | FloatProperty* c_SwapHandDistance = nullptr; 234 | StringProperty* c_d3d9Path = nullptr; 235 | FloatProperty* c_WeaponSmoothingAmountNoZoom = nullptr; 236 | FloatProperty* c_WeaponSmoothingAmountOneZoom = nullptr; 237 | FloatProperty* c_WeaponSmoothingAmountTwoZoom = nullptr; 238 | FloatProperty* c_TEMPViewportLeft = nullptr; 239 | FloatProperty* c_TEMPViewportRight = nullptr; 240 | FloatProperty* c_TEMPViewportTop = nullptr; 241 | FloatProperty* c_TEMPViewportBottom = nullptr; 242 | }; 243 | 244 | -------------------------------------------------------------------------------- /HaloCEVR/HaloCEVR.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | 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 | Source Files 65 | 66 | 67 | Source Files 68 | 69 | 70 | Source Files 71 | 72 | 73 | Source Files 74 | 75 | 76 | Source Files 77 | 78 | 79 | Source Files 80 | 81 | 82 | Source Files 83 | 84 | 85 | Source Files 86 | 87 | 88 | Source Files 89 | 90 | 91 | Source Files 92 | 93 | 94 | Source Files 95 | 96 | 97 | Source Files 98 | 99 | 100 | Source Files 101 | 102 | 103 | Source Files 104 | 105 | 106 | Source Files 107 | 108 | 109 | Source Files 110 | 111 | 112 | Source Files 113 | 114 | 115 | Source Files 116 | 117 | 118 | Source Files 119 | 120 | 121 | Source Files 122 | 123 | 124 | Source Files 125 | 126 | 127 | Source Files 128 | 129 | 130 | Source Files 131 | 132 | 133 | Source Files 134 | 135 | 136 | 137 | 138 | Header Files 139 | 140 | 141 | Header Files 142 | 143 | 144 | Header Files 145 | 146 | 147 | Header Files 148 | 149 | 150 | Header Files 151 | 152 | 153 | Header Files 154 | 155 | 156 | Header Files 157 | 158 | 159 | Header Files 160 | 161 | 162 | Header Files 163 | 164 | 165 | Header Files 166 | 167 | 168 | Header Files 169 | 170 | 171 | Header Files 172 | 173 | 174 | Header Files 175 | 176 | 177 | Header Files 178 | 179 | 180 | Header Files 181 | 182 | 183 | Header Files 184 | 185 | 186 | Header Files 187 | 188 | 189 | Header Files 190 | 191 | 192 | Header Files 193 | 194 | 195 | Header Files 196 | 197 | 198 | Header Files 199 | 200 | 201 | Header Files 202 | 203 | 204 | Header Files 205 | 206 | 207 | Header Files 208 | 209 | 210 | Header Files 211 | 212 | 213 | Header Files 214 | 215 | 216 | Header Files 217 | 218 | 219 | Header Files 220 | 221 | 222 | Header Files 223 | 224 | 225 | Header Files 226 | 227 | 228 | Header Files 229 | 230 | 231 | Header Files 232 | 233 | 234 | Header Files 235 | 236 | 237 | Header Files 238 | 239 | 240 | Header Files 241 | 242 | 243 | Header Files 244 | 245 | 246 | Header Files 247 | 248 | 249 | Header Files 250 | 251 | 252 | Header Files 253 | 254 | 255 | Header Files 256 | 257 | 258 | Header Files 259 | 260 | 261 | Header Files 262 | 263 | 264 | Header Files 265 | 266 | 267 | Header Files 268 | 269 | 270 | 271 | 272 | 273 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Assets.cpp: -------------------------------------------------------------------------------- 1 | #include "Assets.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | Asset_Generic* Helpers::GetAssetArray() 5 | { 6 | return *reinterpret_cast(Hooks::o.AssetsArray); 7 | } 8 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Assets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Objects.h" 3 | 4 | struct Asset_Base 5 | { 6 | public: 7 | char GroupID[4]; 8 | }; 9 | 10 | 11 | struct Asset_Generic : public Asset_Base 12 | { 13 | char pad[28]; 14 | }; 15 | static_assert(sizeof(Asset_Generic) == 0x20); 16 | 17 | 18 | struct Sound 19 | { 20 | public: 21 | char* N00000551; //0x0000 22 | }; //Size: 0x0004 23 | 24 | struct Bone 25 | { 26 | public: 27 | char BoneName[32]; //0x0000 28 | int16_t LeftLeaf; //0x0020 29 | int16_t RightLeaf; //0x0022 30 | int16_t Parent; //0x0024 31 | char pad_0026[26]; //0x0026 32 | }; //Size: 0x0040 33 | 34 | struct Animation 35 | { 36 | public: 37 | char N00000429[32]; //0x0000 38 | char pad_0020[12]; //0x0020 39 | int32_t NumBones; //0x002C 40 | char pad_0030[20]; //0x0030 41 | float N00000433; //0x0044 42 | char pad_0048[108]; //0x0048 43 | }; //Size: 0x00B4 44 | 45 | struct AssetData_ModelAnimations 46 | { 47 | public: 48 | char pad_0000[76]; //0x0000 49 | void* N00000324; //0x004C 50 | char pad_0050[8]; //0x0050 51 | void* N00000327; //0x0058 52 | char pad_005C[12]; //0x005C 53 | int32_t NumBones; //0x0068 54 | Bone* BoneArray; //0x006C 55 | char pad_0070[4]; //0x0070 56 | int32_t NumAnimations; //0x0074 57 | Animation* AnimationArray; //0x0078 58 | char pad_007C[20]; //0x007C 59 | int32_t NumSounds; //0x0090 60 | Sound* Sounds; //0x0094 61 | char pad_0098[4]; //0x0098 62 | }; //Size: 0x161C 63 | 64 | struct Asset_ModelAnimations 65 | { 66 | public: 67 | char pad_0000[12]; //0x0000 68 | HaloID SelfID; //0x000C 69 | char* Shader; //0x0010 70 | AssetData_ModelAnimations* Data; //0x0014 71 | char pad_0018[8]; //0x0018 72 | }; 73 | 74 | struct AssetData_Weapon 75 | { 76 | char pad_0000[1128]; //0x0000 77 | HaloID ViewModelID; //0x0468 78 | char pad_046C[152]; //0x046C 79 | }; 80 | 81 | struct Asset_Weapon : public Asset_Base 82 | { 83 | char N00000D51[4]; //0x0004 84 | char N00000D52[4]; //0x0008 85 | char pad_000C[4]; //0x000C 86 | char* WeaponAsset; //0x0010 87 | AssetData_Weapon* WeaponData; //0x0014 88 | char pad_0018[8]; //0x0018 89 | }; 90 | 91 | struct GBXSocketTransform 92 | { 93 | char pad_0000[4]; //0x0000 94 | Vector3 Position; //0x0004 95 | Vector4 QRotation; //0x0010 96 | }; 97 | 98 | struct GBXSocket 99 | { 100 | char SocketName[52]; //0x0000 101 | int32_t NumTransforms; //0x0034 102 | GBXSocketTransform* Transforms; //0x0038 103 | char pad_003C[4]; //0x003C 104 | }; 105 | 106 | struct AssetData_GBXModel 107 | { 108 | char pad_0000[172]; //0x0000 109 | int32_t NumSockets; //0x00AC 110 | GBXSocket* Sockets; //0x00B0 111 | }; 112 | 113 | struct Asset_GBXModel : public Asset_Base 114 | { 115 | char pad_0004[12]; //0x0004 116 | char* ModelPath; //0x0010 117 | AssetData_GBXModel* ModelData; //0x0014 118 | char pad_0018[8]; //0x0018 119 | }; 120 | 121 | namespace Helpers 122 | { 123 | Asset_Generic* GetAssetArray(); 124 | 125 | template 126 | T* GetTypedAsset(HaloID ID) 127 | { 128 | if (ID.id == -1 || ID.index == -1) 129 | { 130 | return nullptr; 131 | } 132 | 133 | return reinterpret_cast(&GetAssetArray()[ID.index]); 134 | } 135 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Camera.cpp: -------------------------------------------------------------------------------- 1 | #include "Camera.h" 2 | #include "Player.h" 3 | #include "../Hooking/Hooks.h" 4 | 5 | Camera& Helpers::GetCamera() 6 | { 7 | return Helpers::GetPlayer().camera; 8 | } 9 | 10 | InputData& Helpers::GetInputData() 11 | { 12 | return **reinterpret_cast(Hooks::o.InputData); 13 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Camera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Maths/Vectors.h" 3 | #include 4 | 5 | struct InputData 6 | { 7 | char pad_0000[8]; //0x0000 8 | float N00000679; //0x0008 9 | float N0000067A; //0x000C 10 | uint16_t N0000067B; //0x0010 11 | uint16_t N00000696; //0x0012 12 | uint32_t jumpState; //0x0014 13 | uint16_t N0000067D; //0x0018 14 | uint16_t N00000693; //0x001A 15 | float yaw; //0x001C 16 | float pitch; //0x0020 17 | float forward; //0x0024 18 | float left; //0x0028 19 | float firing; //0x002C 20 | uint16_t N00000683; //0x0030 21 | uint16_t N00000690; //0x0032 22 | int16_t zoomLevel; //0x0034 23 | char pad_0036[6]; //0x0036 24 | float N00000686; //0x003C 25 | }; 26 | 27 | struct Camera 28 | { 29 | // Camera position 30 | Vector3 position; 31 | 32 | // Unknown 33 | std::uint8_t unk_0[20]; 34 | 35 | // Camera look/facing direction 36 | Vector3 lookDir; 37 | // Needs verifying, probably an up vector 38 | Vector3 lookDirUp; 39 | 40 | // Field of View in radians, typically 1.22 (70 deg) 41 | float fov; 42 | }; 43 | static_assert(sizeof(Camera) == 0x3c); 44 | 45 | namespace Helpers 46 | { 47 | Camera& GetCamera(); 48 | InputData& GetInputData(); 49 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/CmdLineArgs.cpp: -------------------------------------------------------------------------------- 1 | #include "CmdLineArgs.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | CmdLineArgs& Helpers::GetCmdLineArgs() 5 | { 6 | return *reinterpret_cast(Hooks::o.CmdLineArgs); 7 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/CmdLineArgs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CmdLineArgs 4 | { 5 | int NoSound; 6 | int NoVideo; 7 | int NoNetwork; 8 | int Width640; 9 | int SafeMode; 10 | int NoWinKey; 11 | }; 12 | 13 | namespace Helpers 14 | { 15 | CmdLineArgs& GetCmdLineArgs(); 16 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Controls.cpp: -------------------------------------------------------------------------------- 1 | #include "Controls.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | namespace Helpers 5 | { 6 | Controls& GetControls() 7 | { 8 | return *reinterpret_cast(Hooks::o.Controls); 9 | } 10 | 11 | Controls_Custom& GetControlsCustom() 12 | { 13 | return *reinterpret_cast(Hooks::o.Controls); 14 | } 15 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Controls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct Controls 4 | { 5 | unsigned char Jump; 6 | unsigned char SwitchGrenades; 7 | unsigned char Interact; 8 | unsigned char SwitchWeapons; 9 | unsigned char Melee; 10 | unsigned char Flashlight; 11 | unsigned char Grenade; 12 | unsigned char Fire; 13 | unsigned char MenuForward; 14 | unsigned char MenuBack; 15 | unsigned char Crouch; 16 | unsigned char Zoom; 17 | unsigned char ShowScores; 18 | unsigned char Reload; 19 | unsigned char PickupWeapon; 20 | unsigned char AllChat; 21 | unsigned char TeamChat; 22 | unsigned char VehicleChat; 23 | unsigned char unk_01; 24 | unsigned char unk_02; 25 | float Forwards; 26 | float Left; 27 | float Yaw; 28 | float Pitch; 29 | unsigned char ControllerAim; 30 | }; 31 | 32 | struct Controls_Custom 33 | { 34 | unsigned char Jump; 35 | unsigned char SwitchGrenades; 36 | unsigned char Interact; 37 | unsigned char SwitchWeapons; 38 | unsigned char Melee; 39 | unsigned char Flashlight; 40 | unsigned char Grenade; 41 | unsigned char Fire; 42 | unsigned char MenuForward; 43 | unsigned char MenuBack; 44 | unsigned char Crouch; 45 | unsigned char Zoom; 46 | unsigned char ShowScores; 47 | unsigned char Reload; 48 | unsigned char PickupWeapon; 49 | unsigned char AllChat; 50 | unsigned char TeamChat; 51 | unsigned char VehicleChat; 52 | unsigned char unk_01; 53 | unsigned char unk_02; 54 | unsigned char whygearboxwhy[12]; 55 | float Forwards; 56 | float Left; 57 | float Yaw; 58 | float Pitch; 59 | unsigned char ControllerAim; 60 | }; 61 | 62 | 63 | namespace Helpers 64 | { 65 | Controls& GetControls(); 66 | Controls_Custom& GetControlsCustom(); 67 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Cutscene.cpp: -------------------------------------------------------------------------------- 1 | #include "Cutscene.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | CutsceneData* Helpers::GetCutsceneData() 5 | { 6 | return *reinterpret_cast(Hooks::o.CutsceneData); 7 | } 8 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Cutscene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | struct CutsceneData 5 | { 6 | float progress; 7 | float lastUpdate; 8 | bool bHasCinematicBars; 9 | bool bInCutscene; 10 | uint8_t padding[2]; 11 | uint32_t data[4]; 12 | }; 13 | 14 | namespace Helpers 15 | { 16 | CutsceneData* GetCutsceneData(); 17 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/DX9.cpp: -------------------------------------------------------------------------------- 1 | #include "DX9.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | IDirect3D9* Helpers::GetDirect3D9() 5 | { 6 | return *reinterpret_cast(Hooks::o.DirectX9); 7 | } 8 | 9 | IDirect3DDevice9* Helpers::GetDirect3DDevice9() 10 | { 11 | return *reinterpret_cast(Hooks::o.DirectX9Device); 12 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/DX9.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Helpers 5 | { 6 | IDirect3D9* GetDirect3D9(); 7 | IDirect3DDevice9* GetDirect3DDevice9(); 8 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Maths.cpp: -------------------------------------------------------------------------------- 1 | #include "Maths.h" 2 | 3 | void Helpers::MakeTransformFromXZ(const Vector3* facingVector, const Vector3* upVector, Transform* outTransform) 4 | { 5 | outTransform->scale = 1.0; 6 | outTransform->rotation[0] = upVector->x; 7 | outTransform->rotation[1] = upVector->y; 8 | outTransform->rotation[2] = upVector->z; 9 | outTransform->rotation[3] = facingVector->y * upVector->z - facingVector->z * upVector->y; 10 | outTransform->rotation[4] = facingVector->z * upVector->x - upVector->z * facingVector->x; 11 | outTransform->rotation[5] = facingVector->x * upVector->y - facingVector->y * upVector->x; 12 | outTransform->rotation[6] = facingVector->x; 13 | outTransform->rotation[7] = facingVector->y; 14 | outTransform->rotation[8] = facingVector->z; 15 | (outTransform->translation).x = 0.0; 16 | (outTransform->translation).y = 0.0; 17 | (outTransform->translation).z = 0.0; 18 | } 19 | 20 | void Helpers::MakeTransformFromQuat(const Vector4* quaternion, Transform* outTransform) 21 | { 22 | float twoZZ; 23 | float twoXW; 24 | float twoYW; 25 | float twoZW; 26 | float twoXX; 27 | float twoXY; 28 | float twoXZ; 29 | float twoYY; 30 | float twoYZ; 31 | float twoOverLength; 32 | 33 | float len = quaternion->w * quaternion->w + quaternion->z * quaternion->z + quaternion->y * quaternion->y + quaternion->x * quaternion->x; 34 | if (len == 0.0f) { 35 | twoOverLength = 0.0f; 36 | } 37 | else { 38 | twoOverLength = 2.0f / len; 39 | } 40 | float twoX = twoOverLength * quaternion->x; 41 | float twoY = twoOverLength * quaternion->y; 42 | float twoZ = twoOverLength * quaternion->z; 43 | twoXW = twoX * quaternion->w; 44 | twoYW = twoY * quaternion->w; 45 | twoZW = twoZ * quaternion->w; 46 | twoXX = twoX * quaternion->x; 47 | twoXY = twoY * quaternion->x; 48 | twoXZ = twoZ * quaternion->x; 49 | twoYY = twoY * quaternion->y; 50 | twoYZ = twoZ * quaternion->y; 51 | twoZZ = twoZ * quaternion->z; 52 | outTransform->scale = 1.0f; 53 | (outTransform->translation).x = 0.0f; 54 | (outTransform->translation).y = 0.0f; 55 | (outTransform->translation).z = 0.0f; 56 | outTransform->rotation[0] = 1.0f - (twoYY + twoZZ); 57 | outTransform->rotation[1] = twoXY - twoZW; 58 | outTransform->rotation[2] = twoXZ + twoYW; 59 | outTransform->rotation[3] = twoXY + twoZW; 60 | outTransform->rotation[4] = 1.0f - (twoZZ + twoXX); 61 | outTransform->rotation[5] = twoYZ - twoXW; 62 | outTransform->rotation[6] = twoXZ - twoYW; 63 | outTransform->rotation[7] = twoYZ + twoXW; 64 | outTransform->rotation[8] = 1.0f - (twoYY + twoXX); 65 | } 66 | 67 | void Helpers::CombineTransforms(const Transform* transformA, const Transform* transformB, Transform* outTransform) 68 | { 69 | Transform tempTransform; 70 | 71 | if (transformA == outTransform) { 72 | tempTransform = *transformA; 73 | transformA = &tempTransform; 74 | } 75 | if (transformB == outTransform) { 76 | tempTransform = *transformB; 77 | transformB = &tempTransform; 78 | } 79 | outTransform->rotation[0] = 80 | transformB->rotation[2] * transformA->rotation[6] + 81 | transformA->rotation[0] * transformB->rotation[0] + transformA->rotation[3] * transformB->rotation[1]; 82 | outTransform->rotation[1] = 83 | transformA->rotation[4] * transformB->rotation[1] + 84 | transformA->rotation[1] * transformB->rotation[0] + transformA->rotation[7] * transformB->rotation[2]; 85 | outTransform->rotation[2] = 86 | transformA->rotation[5] * transformB->rotation[1] + 87 | transformA->rotation[2] * transformB->rotation[0] + transformA->rotation[8] * transformB->rotation[2]; 88 | outTransform->rotation[3] = 89 | transformA->rotation[3] * transformB->rotation[4] + 90 | transformB->rotation[5] * transformA->rotation[6] + transformA->rotation[0] * transformB->rotation[3]; 91 | outTransform->rotation[4] = 92 | transformA->rotation[1] * transformB->rotation[3] + 93 | transformA->rotation[4] * transformB->rotation[4] + transformA->rotation[7] * transformB->rotation[5]; 94 | outTransform->rotation[5] = 95 | transformA->rotation[2] * transformB->rotation[3] + 96 | transformA->rotation[5] * transformB->rotation[4] + transformA->rotation[8] * transformB->rotation[5]; 97 | outTransform->rotation[6] = 98 | transformA->rotation[3] * transformB->rotation[7] + 99 | transformA->rotation[0] * transformB->rotation[6] + transformB->rotation[8] * transformA->rotation[6]; 100 | outTransform->rotation[7] = 101 | transformB->rotation[7] * transformA->rotation[4] + 102 | transformB->rotation[8] * transformA->rotation[7] + transformA->rotation[1] * transformB->rotation[6]; 103 | outTransform->rotation[8] = 104 | transformB->rotation[7] * transformA->rotation[5] + 105 | transformB->rotation[8] * transformA->rotation[8] + transformA->rotation[2] * transformB->rotation[6]; 106 | (outTransform->translation).x = 107 | ((transformB->translation).z * transformA->rotation[6] + 108 | transformA->rotation[3] * (transformB->translation).y + transformA->rotation[0] * (transformB->translation).x) * transformA->scale + 109 | (transformA->translation).x; 110 | (outTransform->translation).y = 111 | ((transformB->translation).x * transformA->rotation[1] + 112 | (transformB->translation).y * transformA->rotation[4] + transformA->rotation[7] * (transformB->translation).z) * transformA->scale + 113 | (transformA->translation).y; 114 | (outTransform->translation).z = 115 | ((transformB->translation).x * transformA->rotation[2] + 116 | (transformB->translation).y * transformA->rotation[5] + transformA->rotation[8] * (transformB->translation).z) * transformA->scale + 117 | (transformA->translation).z; 118 | outTransform->scale = transformA->scale * transformB->scale; 119 | } 120 | 121 | 122 | Vector3 Helpers::Lerp(const Vector3& a, const Vector3& b, float t) 123 | { 124 | return a + t * (b - a); 125 | } 126 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Maths.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Maths/Matrices.h" 3 | 4 | struct Transform 5 | { 6 | float scale; 7 | float rotation[9]; 8 | Vector3 translation; 9 | }; 10 | 11 | struct TransformQuat 12 | { 13 | Vector4 rotation; // Quaternion 14 | Vector3 translation; 15 | float scale; 16 | }; 17 | 18 | namespace Helpers 19 | { 20 | void MakeTransformFromXZ(const Vector3* facingVector, const Vector3* upVector, Transform* outTransform); 21 | void MakeTransformFromQuat(const Vector4* quaternion, Transform* outTransform); 22 | void CombineTransforms(const Transform* transformA, const Transform* transformB, Transform* outTransform); 23 | Vector3 Lerp(const Vector3& a, const Vector3& b, float t); 24 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Menus.cpp: -------------------------------------------------------------------------------- 1 | #include "Menus.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | bool Helpers::IsMouseVisible() 5 | { 6 | return !*reinterpret_cast(Hooks::o.HideMouse); 7 | } 8 | 9 | bool Helpers::IsLoading() 10 | { 11 | return *reinterpret_cast(Hooks::o.LoadingState) != 0; 12 | } 13 | 14 | bool Helpers::IsCampaignLoading() 15 | { 16 | return *reinterpret_cast(Hooks::o.CampaignLoading); 17 | } 18 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Menus.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct MouseInfo 4 | { 5 | int x; 6 | int y; 7 | int z; 8 | char buttonState[8]; 9 | char buttonState2[8]; 10 | }; 11 | 12 | namespace Helpers 13 | { 14 | bool IsMouseVisible(); 15 | bool IsLoading(); 16 | bool IsCampaignLoading(); 17 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Objects.cpp: -------------------------------------------------------------------------------- 1 | #include "Objects.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | ObjectTable& Helpers::GetObjectTable() 5 | { 6 | return **reinterpret_cast(Hooks::o.ObjectTable); 7 | } 8 | 9 | PlayerTable& Helpers::GetPlayerTable() 10 | { 11 | return **reinterpret_cast(Hooks::o.PlayerTable); 12 | } 13 | 14 | BaseDynamicObject* Helpers::GetDynamicObject(HaloID& id) 15 | { 16 | ObjectTable& table = GetObjectTable(); 17 | 18 | if (id.index > table.currentSize) 19 | { 20 | return nullptr; 21 | } 22 | 23 | return table.elements[id.index].dynamicObject; 24 | } 25 | 26 | bool Helpers::GetLocalPlayerID(HaloID& outID) 27 | { 28 | PlayerTable& table = GetPlayerTable(); 29 | 30 | if (table.currentSize == 0) 31 | { 32 | return false; 33 | } 34 | 35 | outID = table.elements->objectID; 36 | return true; 37 | } 38 | 39 | BaseDynamicObject* Helpers::GetLocalPlayer() 40 | { 41 | // TODO: Test this in MP, it may not be that the first player is the local one 42 | 43 | HaloID playerID; 44 | if (!GetLocalPlayerID(playerID)) 45 | { 46 | return nullptr; 47 | } 48 | 49 | return GetDynamicObject(playerID); 50 | } 51 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Objects.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../Maths/Vectors.h" 5 | 6 | struct HaloID 7 | { 8 | uint16_t index; //0x0000 9 | uint16_t id; //0x0002 10 | }; 11 | 12 | inline std::ostream& operator<<(std::ostream& os, const HaloID& id) 13 | { 14 | os << "[ID: " << id.id << ", Index: " << id.index << "]"; 15 | return os; 16 | } 17 | 18 | inline bool operator==(HaloID& a, HaloID& b) 19 | { 20 | return a.id == b.id && a.index == b.index; 21 | } 22 | 23 | inline bool operator!=(HaloID& a, HaloID& b) 24 | { 25 | return a.id != b.id || a.index != b.index; 26 | } 27 | 28 | enum class ObjectProperties : uint16_t 29 | { 30 | NoCollision = 1 << 0, 31 | OnGround = 1 << 1, 32 | NoGravity = 1 << 2, 33 | Unk0 = 1 << 3, 34 | Unk1 = 1 << 4, 35 | Stationary = 1 << 5, 36 | Unk2 = 1 << 6, 37 | NoCollision2 = 1 << 7, 38 | Unk3 = 1 << 8, 39 | Unk4 = 1 << 9, 40 | Unk5 = 1 << 10, 41 | NoShadow = 1 << 11, 42 | Unk6 = 1 << 12, 43 | Unk7 = 1 << 13, 44 | OutOfBounds = 1 << 14, 45 | Unk8 = 1 << 15 46 | }; 47 | 48 | enum class ObjectType : uint16_t 49 | { 50 | BIPED, 51 | VEHICLE, 52 | WEAPON, 53 | EQUIPMENT, 54 | GARBAGE, 55 | PROJECTILE, 56 | SCENERY, 57 | DEVICE_MACHINE, 58 | DEVICE_CONTROL, 59 | DEVICE_LIGHT_FIXTURE, 60 | PLACEHOLDER, 61 | SOUND_SCENERY 62 | }; 63 | 64 | struct BaseTable 65 | { 66 | public: 67 | char name[32]; //0x0000 68 | uint16_t maxElements; //0x0020 69 | uint16_t elementSize; //0x0022 70 | uint32_t N00000198; //0x0024 71 | uint32_t N00000199; //0x0028 72 | uint16_t N000001B3; //0x002C 73 | uint16_t currentSize; //0x002E 74 | uint16_t count; //0x0030 75 | uint16_t nextID; //0x0032 76 | }; 77 | 78 | struct ObjectTable : public BaseTable 79 | { 80 | struct ObjectDatum* elements; //0x0034 81 | }; 82 | 83 | struct ObjectDatum 84 | { 85 | uint16_t id; //0x0000 86 | uint16_t N000001BD; //0x0002 87 | uint16_t N00000231; //0x0004 88 | uint16_t N00000233; //0x0006 89 | struct BaseDynamicObject* dynamicObject; //0x0008 90 | }; 91 | 92 | struct BaseDynamicObject 93 | { 94 | public: 95 | HaloID tagID; //0x0000 96 | uint32_t N0000025C; //0x0004 97 | uint32_t N0000025D; //0x0008 98 | int32_t age; //0x000C 99 | ObjectProperties N0000025F; //0x0010 100 | char pad_0012[2]; //0x0012 101 | float N00000260; //0x0014 102 | float N00000261; //0x0018 103 | float N00000262; //0x001C 104 | float N00000263; //0x0020 105 | float N00000264; //0x0024 106 | float N00000265; //0x0028 107 | float N00000266; //0x002C 108 | float N00000267; //0x0030 109 | float N00000268; //0x0034 110 | float N00000269; //0x0038 111 | float N0000026A; //0x003C 112 | float N0000026B; //0x0040 113 | float N0000026C; //0x0044 114 | float N0000026D; //0x0048 115 | float N0000026E; //0x004C 116 | float N0000026F; //0x0050 117 | float N00000270; //0x0054 118 | float N00000271; //0x0058 119 | Vector3 position; //0x005C 120 | Vector3 velocity; //0x0068 121 | Vector3 facingDir; //0x0074 122 | Vector3 upDirection; //0x0080 123 | float rotVelPitch; //0x008C 124 | float rotVelYaw; //0x0090 125 | float rotVelRoll; //0x0094 126 | uint32_t locationID; //0x0098 127 | char pad_009C[4]; //0x009C 128 | Vector3 centre; //0x00A0 129 | float N0000027C; //0x00AC 130 | float scale; //0x00B0 131 | ObjectType N0000027E; //0x00B4 132 | uint16_t N0000027F; //0x00B6 133 | char pad_00B8[20]; //0x00B8 134 | uint32_t animTagID; //0x00CC 135 | uint16_t animation; //0x00D0 136 | uint16_t animFrame; //0x00D2 137 | char pad_00D4[4]; //0x00D4 138 | float baseHealth; //0x00D8 139 | float baseShield; //0x00DC 140 | float health; //0x00E0 141 | float shield; //0x00E4 142 | float currentShieldDmg; //0x00E8 143 | float currentHealthDmg; //0x00EC 144 | char pad_00F0[4]; //0x00F0 145 | float recentShieldDmg; //0x00F4 146 | float recentHealthDmg; //0x00F8 147 | int32_t shieldDmgTime; //0x00FC 148 | int32_t healthDmgTime; //0x0100 149 | uint16_t shieldStunTime; //0x0104 150 | uint16_t N00000311; //0x0106 151 | char pad_0108[16]; //0x0108 152 | HaloID weapon; //0x0118 153 | HaloID parent; //0x011C 154 | uint32_t parentSeatIndex; //0x0120 155 | char pad_0124[208]; //0x0124 156 | }; 157 | 158 | struct UnitDynamicObject : public BaseDynamicObject 159 | { 160 | char pad_01F4[36]; //0x01F4 161 | HaloID playerID; //0x0218 162 | uint16_t N00000313; //0x021C 163 | uint16_t N0000034E; //0x021E 164 | uint32_t lastBulletTime; //0x0220 165 | Vector3 facing; //0x0224 166 | Vector3 desiredAim; //0x0230 167 | Vector3 aim; //0x023C 168 | Vector3 aimVelocity; //0x0248 169 | Vector3 aim2; //0x0254 170 | Vector3 aim3; //0x0260 171 | char pad_026C[12]; //0x026C 172 | float run; //0x0278 173 | float strafe; //0x027C 174 | float ascend; //0x0280 175 | float shooting; //0x0284 176 | char pad_0288[12]; //0x0288 177 | HaloID thrownGrenade; //0x0294 178 | char pad_0298[32]; //0x0298 179 | float N0000032E; //0x02B8 180 | float N0000032F; //0x02BC 181 | float N00000330; //0x02C0 182 | float N00000331; //0x02C4 183 | float N00000332; //0x02C8 184 | float N00000333; //0x02CC 185 | float N00000334; //0x02D0 186 | float N00000335; //0x02D4 187 | char pad_02D8[72]; //0x02D8 188 | int16_t zoom; //0x0320 189 | char pad_0322[6]; //0x0322 190 | }; 191 | 192 | struct PlayerTable : public BaseTable 193 | { 194 | struct PlayerDatum* elements; //0x0034 195 | }; 196 | 197 | struct PlayerDatum 198 | { 199 | public: 200 | uint16_t playerID; //0x0000 201 | uint16_t localID; //0x0002 202 | char name[24]; //0x0004 203 | char pad_001C[4]; //0x001C 204 | int8_t team; //0x0020 205 | char pad_0021[3]; //0x0021 206 | HaloID interactionObjectID; //0x0024 207 | uint16_t interactionObjectType; //0x0028 208 | uint16_t interactionObjectSeat; //0x002A 209 | uint32_t respawnTime; //0x002C 210 | uint32_t respawnTimeGrowth; //0x0030 211 | HaloID objectID; //0x0034 212 | char pad_0038[216]; //0x0038 213 | }; 214 | 215 | struct Weapon 216 | { 217 | public: 218 | uint16_t reloadState; 219 | uint16_t reloadRemaining; 220 | uint16_t reloadTime; 221 | uint16_t reserveAmmo; 222 | uint16_t ammo; 223 | uint16_t unk; 224 | }; 225 | 226 | struct WeaponDynamicObject : public BaseDynamicObject 227 | { 228 | public: 229 | char pad_01F4[188]; //0x01F4 230 | Weapon weaponData[4]; //0x02B0 231 | }; //Size: 0x0340 232 | 233 | namespace Helpers 234 | { 235 | ObjectTable& GetObjectTable(); 236 | PlayerTable& GetPlayerTable(); 237 | 238 | BaseDynamicObject* GetDynamicObject(HaloID& ID); 239 | bool GetLocalPlayerID(HaloID& OutID); 240 | BaseDynamicObject* GetLocalPlayer(); 241 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Player.cpp: -------------------------------------------------------------------------------- 1 | #include "Player.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | namespace Helpers 5 | { 6 | Player& GetPlayer() 7 | { 8 | return *reinterpret_cast(Hooks::o.LocalPlayer); 9 | } 10 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Player.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Camera.h" 3 | 4 | // The local player in campaign mode 5 | 6 | struct Player 7 | { 8 | float deltaTime; 9 | // Unknown 10 | uint8_t unk_0[116]; 11 | // Camera 12 | Camera camera; 13 | // Position 14 | Vector3 position; 15 | // Unknown 16 | uint8_t unk_1[20]; 17 | // Field of View in radians, typically 1.22 (70 deg) 18 | float fov; 19 | // Camera look/facing direction 20 | Vector3 lookDir; 21 | // Needs verifying, probably an up vector 22 | Vector3 lookDirUp; 23 | // Unknown 24 | uint8_t unk_2[440]; 25 | }; 26 | static_assert(sizeof(Player) == 0x2a8); 27 | 28 | namespace Helpers 29 | { 30 | Player& GetPlayer(); 31 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/RenderTarget.cpp: -------------------------------------------------------------------------------- 1 | #include "RenderTarget.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | RenderTarget* Helpers::GetRenderTargets() 5 | { 6 | // Source for this offset is accessing values in the middle of the struct 7 | return reinterpret_cast(Hooks::o.RenderTargets - 0xc); 8 | } 9 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/RenderTarget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // There's an array of 8 of these kept in global memory 5 | struct RenderTarget 6 | { 7 | UINT width; 8 | UINT height; 9 | D3DFORMAT format; 10 | IDirect3DSurface9* renderSurface; 11 | IDirect3DTexture9* renderTexture; 12 | }; 13 | static_assert(sizeof(RenderTarget) == 0x14); 14 | 15 | namespace Helpers 16 | { 17 | RenderTarget* GetRenderTargets(); 18 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Renderer.cpp: -------------------------------------------------------------------------------- 1 | #include "Renderer.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | namespace Helpers 5 | { 6 | sRect* GetWindowRect() 7 | { 8 | return reinterpret_cast(Hooks::o.WindowRect); 9 | } 10 | 11 | sRect* GetCurrentRect() 12 | { 13 | return reinterpret_cast(Hooks::o.CurrentRect); 14 | } 15 | 16 | CameraRenderMatrices* GetActiveCameraMatrices() 17 | { 18 | return reinterpret_cast(Hooks::o.CameraMatrices); 19 | } 20 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../Maths/Vectors.h" 5 | #include "Maths.h" 6 | 7 | struct Viewport 8 | { 9 | float left; 10 | float right; 11 | float top; 12 | float bottom; 13 | }; 14 | static_assert(sizeof(Viewport) == 0x10); 15 | 16 | struct sRect 17 | { 18 | short top; 19 | short left; 20 | short bottom; 21 | short right; 22 | }; 23 | static_assert(sizeof(sRect) == 0x8); 24 | 25 | struct CameraFrustum 26 | { 27 | Vector3 position; 28 | Vector3 facingDirection; 29 | Vector3 upDirection; 30 | // Maybe meant to control first vs third person? 31 | bool drawPlayer; 32 | std::uint8_t unk0[3]; 33 | float fov; 34 | sRect WindowViewport; 35 | sRect InnerViewport; 36 | // Not sure if these are the znear/far values, but they have values in the correct range 37 | float zNear; 38 | float zFar; 39 | Vector4 unk1; 40 | }; 41 | static_assert(sizeof(CameraFrustum) == 0x54); 42 | 43 | struct Renderer 44 | { 45 | short playerId; 46 | bool unk1; 47 | // Possibly just padding 48 | std::uint8_t unk2; 49 | // For reasons I've yet to decipher there are 2 nearly identical structs that both need setting 50 | // Maybe one does culling and one does rendering? Setting one of them doesn't seem to work 51 | CameraFrustum frustum; 52 | CameraFrustum frustum2; 53 | }; 54 | static_assert(sizeof(Renderer) == 0xac); 55 | 56 | struct CameraRenderMatrices 57 | { 58 | Viewport viewport; 59 | Transform viewMatrix; 60 | Transform matrix; 61 | Vector4 quaternions[6]; 62 | float zNear; 63 | float zFar; 64 | Vector3 frustumCorners[4]; 65 | Vector3 cameraPosition; 66 | Vector3 frustumCentre; 67 | float floats[6]; 68 | uint32_t unk0; 69 | D3DMATRIX projectionMatrix; 70 | float unk1; 71 | float unk2; 72 | }; 73 | 74 | namespace Helpers 75 | { 76 | sRect* GetWindowRect(); 77 | sRect* GetCurrentRect(); 78 | CameraRenderMatrices* GetActiveCameraMatrices(); 79 | } -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Version.cpp: -------------------------------------------------------------------------------- 1 | #include "Version.h" 2 | #include "../Hooking/Hooks.h" 3 | 4 | char* Helpers::GetGameTypeString() 5 | { 6 | return reinterpret_cast(Hooks::o.GameType); 7 | } 8 | 9 | char* Helpers::GetVersionString() 10 | { 11 | return reinterpret_cast(Hooks::o.GameVersion); 12 | } 13 | -------------------------------------------------------------------------------- /HaloCEVR/Helpers/Version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Helpers 4 | { 5 | char* GetGameTypeString(); 6 | char* GetVersionString(); 7 | } -------------------------------------------------------------------------------- /HaloCEVR/Hooking/FunctionTypedefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Helpers/Objects.h" 3 | 4 | typedef void(*Func_UpdateCameraRotation)(); 5 | typedef bool(*Func_InitDirectX)(); 6 | typedef void(__cdecl* Func_DrawFrame)(struct Renderer*, short, short*, float, float); 7 | typedef void(*Func_SetViewportSize)(); 8 | typedef void(__stdcall* Func_DrawHUD)(); 9 | typedef void(*Func_DrawMenu)(); 10 | typedef void(__stdcall* Func_DrawScope)(void*); 11 | typedef void(*Func_DrawLoadingScreen)(); 12 | typedef void(*Func_DrawCrosshair)(); 13 | typedef void(*Func_DrawImage)(); 14 | typedef void(*Func_SetViewModelPosition)(); 15 | typedef void(*Func_HandleInputs)(); 16 | typedef void(*Func_UpdatePitchYaw)(); 17 | typedef void(*Func_SetViewportScale)(); 18 | typedef void(*Func_SetMousePosition)(); 19 | typedef void(*Func_UpdateMouseInfo)(); 20 | typedef void(__cdecl* Func_FireWeapon)(HaloID, short); 21 | typedef void(__cdecl* Func_ThrowGrenade)(HaloID, bool); 22 | typedef void(*Func_SetCameraMatrices)(); 23 | typedef int(__cdecl* Func_MaybeNightVision)(float* param1); 24 | typedef void(__fastcall* Func_DrawLoadingScreen2)(void* parma1); 25 | typedef void(*Func_DrawCinematicBars)(); 26 | typedef void(*Func_DrawViewModel)(); 27 | typedef void(__cdecl* Func_ReloadStart)(HaloID, short, bool); 28 | typedef void(*Func_ReloadEnd)(); -------------------------------------------------------------------------------- /HaloCEVR/Hooking/Hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SigScanner.h" 3 | #include "MinHook.h" 4 | #include "../Logger.h" 5 | 6 | template 7 | class Hook 8 | { 9 | public: 10 | 11 | void CreateHook(std::string Name, Offset& FunctionOffset, LPVOID Func) 12 | { 13 | DebugName = Name; 14 | 15 | if (!Func) 16 | { 17 | Logger::log << "[Hook] Target Function pointer not provided to hook, skipping " << DebugName << std::endl; 18 | return; 19 | } 20 | 21 | if (SigScanner::UpdateOffset(FunctionOffset) < 0) 22 | { 23 | Logger::log << "[Hook] signature was invalid, skipping " << DebugName << std::endl; 24 | return; 25 | } 26 | 27 | MH_STATUS HookStatus = MH_CreateHook(reinterpret_cast(FunctionOffset.Address), Func, reinterpret_cast(&Original)); 28 | 29 | if (HookStatus != MH_OK) 30 | { 31 | Logger::log << "[Hook] Could not create hook for " << DebugName << " : " << MH_StatusToString(HookStatus) << std::endl; 32 | return; 33 | } 34 | 35 | TargetFunc = reinterpret_cast(FunctionOffset.Address); 36 | Logger::log << "[Hook] Created hook for " << DebugName << std::endl; 37 | } 38 | 39 | void EnableHook() 40 | { 41 | if (bIsEnabled) 42 | { 43 | Logger::log << "[Hook] cannot enable " << DebugName << " as it is already enabled" << std::endl; 44 | return; 45 | } 46 | 47 | if (!TargetFunc) 48 | { 49 | Logger::log << "[Hook] cannot enable " << DebugName << " as it is has not been successfully created" << std::endl; 50 | return; 51 | } 52 | 53 | MH_STATUS HookStatus = MH_EnableHook(TargetFunc); 54 | 55 | if (HookStatus != MH_OK) 56 | { 57 | Logger::log << "[Hook] Could not enable hook for " << DebugName << " : " << MH_StatusToString(HookStatus) << std::endl; 58 | return; 59 | } 60 | 61 | bIsEnabled = true; 62 | Logger::log << "[Hook] Enabled hook for " << DebugName << std::endl; 63 | } 64 | 65 | void DisableHook() 66 | { 67 | if (!bIsEnabled) 68 | { 69 | Logger::log << "[Hook] cannot disable " << DebugName << " as it is not enabled" << std::endl; 70 | return; 71 | } 72 | 73 | if (!TargetFunc) 74 | { 75 | Logger::log << "[Hook] cannot disable " << DebugName << " as the current target function is invalid" << std::endl; 76 | return; 77 | } 78 | 79 | MH_STATUS HookStatus = MH_DisableHook(TargetFunc); 80 | 81 | if (HookStatus != MH_OK) 82 | { 83 | Logger::log << "[Hook] Could not enable hook for " << DebugName << " : " << MH_StatusToString(HookStatus) << std::endl; 84 | } 85 | 86 | bIsEnabled = false; 87 | TargetFunc = nullptr; 88 | Logger::log << "[Hook] Disabled hook for " << DebugName << std::endl; 89 | } 90 | 91 | protected: 92 | T Original; 93 | 94 | private: 95 | bool bIsEnabled = false; 96 | LPVOID TargetFunc = 0; 97 | std::string DebugName = "??"; 98 | 99 | friend class Hooks; 100 | }; 101 | -------------------------------------------------------------------------------- /HaloCEVR/Hooking/Hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Hook.h" 4 | #include "SigScanner.h" 5 | #include "FunctionTypeDefs.h" 6 | #include "../Helpers/Renderer.h" 7 | #include "../Helpers/Objects.h" 8 | 9 | #define DEFINE_HOOK_FULL(Name, RetCall, ...) static inline Hook Name; static RetCall H_##Name(__VA_ARGS__) 10 | #define DEFINE_HOOK(Name, ...) DEFINE_HOOK_FULL(Name, void, __VA_ARGS__) 11 | 12 | class Hooks 13 | { 14 | public: 15 | static void InitHooks(); 16 | static void EnableAllHooks(); 17 | 18 | static void SetByte(long long Address, byte Byte); 19 | static void SetBytes(long long Address, int Length, byte* Bytes); 20 | static void NOPInstructions(long long Address, int Length); 21 | static bool Freeze(); 22 | static void Unfreeze(); 23 | static void ResolveIndirect(struct Offset& offset, long long& Address); 24 | 25 | // All Hooks go here: 26 | DEFINE_HOOK_FULL(InitDirectX, bool); 27 | DEFINE_HOOK_FULL(DrawFrame, void, Renderer* param1, short param2, short* param3, float param4, float deltaTime); 28 | DEFINE_HOOK(DrawHUD); 29 | DEFINE_HOOK(DrawMenu); 30 | DEFINE_HOOK(DrawLoadingScreen); 31 | DEFINE_HOOK(DrawCrosshair); 32 | DEFINE_HOOK(DrawImage); 33 | DEFINE_HOOK(SetViewModelPosition); 34 | DEFINE_HOOK(HandleInputs); 35 | DEFINE_HOOK(UpdatePitchYaw); 36 | DEFINE_HOOK(SetViewportScale); 37 | DEFINE_HOOK(SetMousePosition); 38 | DEFINE_HOOK(UpdateMouseInfo); 39 | DEFINE_HOOK_FULL(FireWeapon, void __cdecl, HaloID param1, short param2); 40 | DEFINE_HOOK_FULL(ThrowGrenade, void __cdecl, HaloID param1, bool param2); 41 | DEFINE_HOOK_FULL(DrawLoadingScreen2, void __fastcall, void* param1); 42 | DEFINE_HOOK(DrawCinematicBars); 43 | DEFINE_HOOK(DrawViewModel); 44 | DEFINE_HOOK_FULL(ReloadStart, void __cdecl, HaloID param1, short param2, bool param3); 45 | DEFINE_HOOK(ReloadEnd); 46 | 47 | // All direct patches go here: 48 | static void P_FixTabOut(); 49 | static void P_RemoveCutsceneFPSCap(); 50 | static void P_KeepViewModelVisible(bool bAlwaysShow); 51 | static void P_EnableUIAlphaWrite(); 52 | static void P_DisableCrouchCamera(); 53 | static void P_ForceCmdLineArgs(); 54 | static void P_RemoveCinematicBars(); 55 | 56 | static void P_DontStealMouse(); 57 | 58 | static void SetCameraMatrices(struct Viewport* viewport, struct CameraFrustum* frustum, struct CameraRenderMatrices* crm, bool bDoProjection); 59 | 60 | static inline Offsets o; 61 | 62 | protected: 63 | static inline Func_SetCameraMatrices oSetCameraMatrices = nullptr; 64 | }; 65 | 66 | #undef DEFINE_HOOK 67 | #undef DEFINE_HOOK_FULL -------------------------------------------------------------------------------- /HaloCEVR/Hooking/SigScanner.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "sigscanner.h" 5 | #include "../Logger.h" 6 | 7 | long long SigScanner::UpdateOffset(Offset& offset, bool bErrorOnFail) 8 | { 9 | std::vector Signature; 10 | 11 | HMODULE CurrentModule = GetModuleHandleA(nullptr); 12 | 13 | 14 | if (!CurrentModule) 15 | { 16 | if (bErrorOnFail) 17 | { 18 | Logger::err << "[SigScanner] [FAIL]:" << offset.DebugName << " can't be located as the default module could not be found!" << std::endl; 19 | } 20 | return -1; 21 | } 22 | 23 | MODULEINFO ModuleInfo; 24 | 25 | BOOL Res = GetModuleInformation(GetCurrentProcess(), CurrentModule, &ModuleInfo, sizeof(ModuleInfo)); 26 | 27 | if (!Res) 28 | { 29 | if (bErrorOnFail) 30 | { 31 | Logger::err << "[SigScanner] [FAIL]:" << offset.DebugName << " can't be validated as GetModuleInformation failed " << std::endl; 32 | } 33 | return -1; 34 | } 35 | 36 | if (offset.Signature.size() == 0) 37 | { 38 | offset.Address = (uintptr_t)CurrentModule + offset.Offset; 39 | Logger::log << "[SigScanner] [WARN]: Skipping signature check for " << offset.DebugName << " and using offset 0x" << std::hex << offset.Offset << std::dec << ", this should only be done during dev builds!" << std::endl; 40 | return 0; 41 | } 42 | 43 | std::stringstream SigStream(offset.Signature); 44 | std::string SigByte; 45 | while (SigStream >> SigByte) 46 | { 47 | if (SigByte == "?" || SigByte == "??") 48 | { 49 | Signature.push_back(-1); 50 | } 51 | else 52 | { 53 | Signature.push_back(strtoul(SigByte.c_str(), NULL, 16)); 54 | } 55 | } 56 | 57 | uint8_t* bytes = (uint8_t*)ModuleInfo.lpBaseOfDll; 58 | 59 | bool bNeedsUpdating = false; 60 | 61 | // Check if the current offset is fine 62 | for (size_t i = 0; i < Signature.size(); i++) 63 | { 64 | if (Signature[i] != -1 && bytes[offset.Offset + offset.SignatureOffset + i] != Signature[i]) 65 | { 66 | bNeedsUpdating = true; 67 | break; 68 | } 69 | } 70 | 71 | if (!bNeedsUpdating) 72 | { 73 | offset.Address = (uintptr_t)CurrentModule + offset.Offset; 74 | Logger::log << "[SigScanner] [PASS]: " << offset.DebugName << "(" + offset.Signature + ") - signature found at 0x" << std::hex << offset.Offset << std::dec << std::endl; 75 | return 0; 76 | } 77 | 78 | if (bErrorOnFail) 79 | { 80 | Logger::log << "[SigScanner] [WARN]: " << offset.DebugName << " is outdated, scanning from 0x" << 0 << " to 0x" << std::hex << ModuleInfo.SizeOfImage << std::dec << std::endl; 81 | } 82 | 83 | // Scan the dll for the signature 84 | for (DWORD i = 0; i < ModuleInfo.SizeOfImage; i++) 85 | { 86 | bool bFound = true; 87 | for (size_t j = 0; j < Signature.size(); j++) 88 | { 89 | if (Signature[j] != -1 && bytes[i + j] != Signature[j]) 90 | { 91 | bFound = false; 92 | break; 93 | } 94 | } 95 | if (bFound) 96 | { 97 | offset.Offset = i - offset.SignatureOffset; 98 | offset.Address = (uintptr_t)CurrentModule + offset.Offset; 99 | Logger::log << "[SigScanner] [PASS]: " << offset.DebugName << "(" + offset.Signature + ") found! New offset is 0x" << std::hex << offset.Offset << std::dec << std::endl; 100 | return offset.Offset; 101 | } 102 | } 103 | 104 | if (bErrorOnFail) 105 | { 106 | Logger::err << "Signature for code offset " << offset.DebugName << "(" + offset.Signature + ") could not be found!" << std::endl; 107 | } 108 | offset.Offset = -1; 109 | return -1; 110 | } 111 | -------------------------------------------------------------------------------- /HaloCEVR/Hooking/SigScanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | struct Offset 7 | { 8 | // Name (used for debugging only) 9 | std::string DebugName; 10 | // Offset of the function in memory 11 | long long Offset; 12 | // Hex Signature of the function (?/?? signifies an unknown value) 13 | std::string Signature; 14 | // Offset of the start of the signature from the function entry point 15 | long long SignatureOffset = 0; 16 | // The actual address, including the module offset 17 | long long Address; 18 | }; 19 | 20 | #define INDIRECT(Name, KnownOffset, ByteOffset, Signature) Offset I_##Name = {#Name, KnownOffset, Signature}; long long Name = ByteOffset 21 | #define OFFSET(Name, KnownOffset, Signature) Offset Name = {#Name, KnownOffset, Signature} 22 | 23 | class Offsets 24 | { 25 | public: 26 | INDIRECT(GameVersion, 0x138056, 0x01, "A1 ?? ?? ?? ?? 81 C2 04 01 00 00 89 02"); 27 | INDIRECT(GameType, 0x14192e, 0x05, "52 8d 75 d0"); 28 | INDIRECT(AssetsArray, 0x042455, 0x4B, "74 31 57 0f bf f8 69 ff 0c 08 00 00 81 c7 ?? ?? ?? ?? e8"); 29 | INDIRECT(Controls, 0x08cca0, 0x12, "a1 ?? ?? ?? ?? 83 ec ?? 53 55 56 57 b9 ?? ?? ?? ?? be"); 30 | INDIRECT(DirectX9, 0x1169c0, 0xE4, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); 31 | INDIRECT(DirectX9Device, 0x1169c0, 0x4B, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); 32 | INDIRECT(HideMouse, 0x045640, 0x23, "8a 0d ?? ?? ?? ?? 8b 44 24 04 8b 15 ?? ?? ?? ?? 81 ec 90 00 00 00"); 33 | INDIRECT(ObjectTable, 0x0f4ad0, 0x32, "51 53 56 57 e8 ?? ?? ?? ?? e8 ?? ?? ?? ?? e8 ?? ?? ?? ?? 68 00 08 00 00 68 ?? ?? ?? ?? bb 0c 00 00 00"); 34 | INDIRECT(PlayerTable, 0x0735b0, 0x21, "?? ?? ?? ?? ?? 68 ?? ?? ?? ?? bb 00 02 00 00 e8 ?? ?? ?? ?? 6a 10"); 35 | INDIRECT(LocalPlayer, 0x047880, 0x0F, "8b 44 24 04 8b 0d ?? ?? ?? ?? 83 ec 24 56 a3 ?? ?? ?? ?? 8b 71 04"); 36 | INDIRECT(WindowRect, 0x0ca1a0, 0x3E, "66 a1 ?? ?? ?? ?? 81 ec 18 03 00 00 66 3d 01 00 53 55 56 57"); 37 | INDIRECT(RenderTargets, 0x12ccc0, 0x1E, "83 ec 38 56 57 66 8b f0 33 ff 66 83 fe 09 ?? ?? 66 85 f6"); 38 | INDIRECT(CameraMatrices, 0x10bfb0, 0x5A, "81 ec a0 02 00 00 53 55 8b ac 24 ac 02 00 00 56 8b 35"); 39 | INDIRECT(InputData, 0x0735b0, 0xAD, "?? ?? ?? ?? ?? 68 ?? ?? ?? ?? bb 00 02 00 00 e8 ?? ?? ?? ?? 6a 10"); 40 | INDIRECT(CurrentRect, 0x12ccc0, 0x51, "83 ec 38 56 57 66 8b f0 33 ff 66 83 fe 09 ?? ?? 66 85 f6"); 41 | INDIRECT(LoadingState, 0x097410, 0x27, "83 ec 14 57 33 ff 2b c7 0f 84"); 42 | INDIRECT(CmdLineArgs, 0x140ee0, 0x5F, "53 57 6a 01 33 db ff 15 ?? ?? ?? ?? 68 ?? ?? ?? ?? ff 15 ?? ?? ?? ?? 33 c0 b9 41 00 00 00"); 43 | INDIRECT(IsWindowed, 0x1169c0, 0x0B, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); 44 | INDIRECT(CutsceneData, 0x07f8d5, 0x0D, "83 c4 10 85 c0 74 25 8a 00 84 c0"); 45 | INDIRECT(CampaignLoading, 0x0c7886, 0x02, "38 1d ?? ?? ?? ?? 74 ?? e8 ?? ?? ?? ?? 38 1d ?? ?? ?? ?? 74 ?? e8"); 46 | 47 | OFFSET(TabOutVideo, 0x0c7b74, "38 1D ?? ?? ?? ?? 74 0E 83 FD 01 74 09 83 FD 02 0F 85"); 48 | OFFSET(TabOutVideo2, 0x0c801c, "75 11 38 1D ?? ?? ?? ?? 75 04 3A C3 74 05 C6 44 24 17 01"); 49 | OFFSET(TabOutVideo3, 0x0c829c, "38 1D ?? ?? ?? ?? 74 29 0F BF 05 ?? ?? ?? ?? 3B C3 7E 0E"); 50 | OFFSET(CutsceneFPSCap, 0x0c9fb5, "b3 01 eb ?? 32 db 8b 2d ?? ?? ?? ?? 8d 4c"); 51 | OFFSET(CreateMouseDevice, 0x0919c0, "6a 17 ff 15 ?? ?? ?? ?? 85 c0 74 ?? 66 c7 05 ?? ?? ?? ?? 02 00"); 52 | OFFSET(SetViewModelVisible, 0x092430, "51 8b 0d ?? ?? ?? ?? 66 83 f9 ff 74 ?? 8b 15 ?? ?? ?? ?? 56 0f bf f1"); 53 | OFFSET(TextureAlphaWrite, 0x11c9d1, "6a 01 6a 16 33 ?? 50 89 ?? ?? ?? ff 91 e4 00 00 00 a1 ?? ?? ?? ?? 8b 10 6a 07 68 a8 00 00 00 50 ff 92 e4 00 00 00 a1 ?? ?? ?? ?? 8b 08 6a 01 6a 1b 50"); 54 | OFFSET(TextAlphaWrite, 0x131b80, "a0 ?? ?? ?? ?? 84 c0 0f 84 ?? ?? ?? ?? 66 83 ?? ?? ?? ?? 00 01 0f 85 ?? ?? ?? ?? 53 55 56"); 55 | OFFSET(CrouchHeight, 0x168ff0, "d9 86 0c 05 00 00 f6 86 cc 04 00 00 01 75 ?? d8 15"); 56 | OFFSET(CinematicBarDrawCall, 0x049b25, "e8 ?? ?? ?? ?? 0f bf 15 ?? ?? ?? ?? 89 54 24 18 db 44 24 18 d9 5c 24 18 d9 44 24 18"); 57 | 58 | OFFSET(InitDirectX, 0x1169c0, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); 59 | OFFSET(DrawFrame, 0x10bea0, "83 ec 14 8b 15 ?? ?? ?? ?? 8b 44 24 24 8b 4c 24 28 42"); 60 | OFFSET(DrawHUD, 0x094730, "83 ec 40 66 83 3d ?? ?? ?? ?? ff ?? ?? ?? ?? ?? ?? 8d 04 24"); 61 | OFFSET(DrawMenu, 0x0984c0, "33 c9 83 ec 14 66 3d ff ff 0f 94 c1 53 33 db 49 23 c8"); 62 | OFFSET(DrawLoadingScreen, 0x10bdc0, "55 8b ec 83 e4 f8 81 ec 5c 02 00 00 53 56 8b 75 08"); 63 | OFFSET(DrawFrameMPLoading, 0x10c590, "8b 15 ?? ?? ?? ?? 81 ec 70 02 00 00 53 56 42 57"); 64 | OFFSET(DrawCrosshair, 0x0acad0, "83 ec 28 84 db 55 8b 6c 24 38 56 8b 74 24 38 57 8b f8"); 65 | OFFSET(DrawImage, 0x11c9a0, "81 ec ?? ?? 00 00 56 8b f0 a0 ?? ?? ?? ?? 84 c0"); 66 | OFFSET(DrawLoadingScreen2, 0x097410, "?? ?? ?? ?? ?? 81 ec 18 04 00 00 57 33 ff 3b c7 0f 84 ?? ?? ?? ?? a1 ?? ?? ?? ?? 56 83 ce ff"); 67 | OFFSET(DrawCinematicBars, 0x0499c0, "8b 15 ?? ?? ?? ?? 8a 4a 08 83 ec 34 84 c9 53 55 56 57"); 68 | OFFSET(DrawViewModel, 0x0924b0, "66 8b 0d ?? ?? ?? ?? 81 ec 3c 0d 00 00 66 83 f9 ff 53 55 56 57"); 69 | 70 | OFFSET(SetViewModelPosition, 0x0d6880, "81 ec f0 00 00 00 53 55 25 ff ff 00 00 56 8b f1 8b 0d"); 71 | OFFSET(HandleInputs, 0x08b4b0, "83 ec 08 56 57 8d 44 24 08 50 ff 15 ?? ?? ?? ?? 8b 4c 24 0c"); 72 | OFFSET(UpdatePitchYaw, 0x072160, "81 ec a4 00 00 00 8b 15 ?? ?? ?? ?? 53 0f bf c8"); 73 | OFFSET(SetMousePosition, 0x097250, "56 8b 35 ?? ?? ?? ?? 33 d2 3b f0 75 ?? 39 0d"); 74 | OFFSET(UpdateMouseInfo, 0x091bc0, "8b 01 53 55 8b 6c 24 0c 89 45 00 8b 51 04 f7 da 56"); 75 | OFFSET(FireWeapon, 0x0c3f10, "81 ec 94 00 00 00 8b 84 24 98 00 00 00 8b 0d ?? ?? ?? ?? 8b 51 34 53"); 76 | OFFSET(ThrowGrenade, 0x16e440, "8b 44 24 04 8b 0d ?? ?? ?? ?? 8b 51 34 8b 0d ?? ?? ?? ?? 83 ec 3c"); 77 | OFFSET(ReloadStart, 0x0c35b0, "83 ec 0c 8b 54 24 10 53 55 0f bf 6c 24 1c 56 8b 35"); 78 | OFFSET(ReloadEnd, 0x0c3900, "8b 44 24 04 8b 15 ?? ?? ?? ?? 8b 52 34 53 8b 1d ?? ?? ?? ?? 25 ff ff 00 00 55 56"); 79 | 80 | OFFSET(SetViewportSize, 0x0c8da0, "83 ec 10 53 55 56 57 8b f8 33 c0 83 ff 01 0f 9e c0"); 81 | OFFSET(SetViewportScale, 0x10ca90, "51 0f bf 50 2e 56 0f bf 70 30 57 0f bf 78 2c 2b f7"); 82 | OFFSET(SetCameraMatrices, 0x10cc40, "83 ec 54 53 55 57 8b f9 0f bf 57 2e 0f bf 4f 32 2b ca"); 83 | }; 84 | 85 | class SigScanner 86 | { 87 | public: 88 | 89 | // Try to update the offset based on its signature 90 | // Returns -1 if unsuccessful, 0 if offset already matched, NewOffset if updated 91 | static long long UpdateOffset(struct Offset& Offset, bool bErrorOnFail = true); 92 | }; 93 | 94 | #undef OFFSET 95 | #undef INDIRECT -------------------------------------------------------------------------------- /HaloCEVR/InGameRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Maths/Vectors.h" 3 | #include "Maths/Matrices.h" 4 | #include 5 | #include 6 | 7 | 8 | class InGameRenderer 9 | { 10 | public: 11 | // Debug API functions 12 | void DrawLine2D(const struct Vector2& start, const struct Vector2& end, D3DCOLOR color); 13 | void DrawInvertedShape2D (const struct Vector2& centre, const struct Vector2& innerSize, const struct Vector2& size, int sides, float radius, D3DCOLOR color); 14 | void DrawLine3D(const struct Vector3& start, const struct Vector3& end, D3DCOLOR color, bool bRespectDepth = true, float thickness = 0.05f); 15 | void DrawPolygon(const struct Vector3& centre, const struct Vector3& facing, const struct Vector3& upVector, int sides, float radius, D3DCOLOR color, bool bRespectDepth = true, float angleAmount = 1.0f); 16 | void DrawCoordinate(const struct Vector3& pos, const class Matrix3& rot, float size = 0.05f, bool bRespectDepth = true); 17 | void DrawRenderTarget(struct IDirect3DTexture9* renderTarget, const struct Vector3& pos, const class Matrix3& rot, const struct Vector2& size, bool bRespectDepth = true, bool bRespectStencil = false); 18 | 19 | // Core functions 20 | void ExtractMatrices(struct Renderer* playerRenderer); 21 | void Render(struct IDirect3DDevice9* pDevice); 22 | void PostRender(); 23 | 24 | void ClearRenderTargets(); 25 | protected: 26 | 27 | void Draw2DLines(struct IDirect3DDevice9* pDevice); 28 | void Draw2DPolygons(struct IDirect3DDevice9* pDevice); 29 | void Draw3DLines(struct IDirect3DDevice9* pDevice); 30 | void DrawRenderTargets(struct IDirect3DDevice9* pDevice); 31 | void DrawPolygons(struct IDirect3DDevice9* pDevice); 32 | 33 | static constexpr int MAX_LINES = 32; 34 | 35 | struct VertexData2D 36 | { 37 | float x, y, z, rhw; 38 | DWORD color; 39 | }; 40 | 41 | struct VertexData3D 42 | { 43 | float x, y, z; 44 | DWORD color; 45 | }; 46 | 47 | struct VertexDataTex 48 | { 49 | float x, y, z; 50 | float u, v; 51 | }; 52 | 53 | struct RenderTarget 54 | { 55 | Vector3 pos; 56 | Matrix3 rot; 57 | Vector2 size; 58 | struct IDirect3DTexture9* texture; 59 | bool bRespectDepth; 60 | bool bRespectStencil; 61 | }; 62 | 63 | struct Polygon 64 | { 65 | bool bIsStencil; 66 | std::vector vertices; 67 | }; 68 | 69 | struct Polygon2D 70 | { 71 | std::vector vertices; 72 | }; 73 | 74 | VertexData2D vertices2D[MAX_LINES]; 75 | VertexData3D vertices3D[MAX_LINES]; 76 | int vertex2DCount = 0; 77 | int vertex3DCount = 0; 78 | 79 | std::vector lines2D; 80 | std::vector polygons2D; 81 | std::vector lines3D; 82 | std::vector depthLines3D; 83 | std::vector renderTargets; 84 | std::vector polygons; 85 | std::vector depthPolygons; 86 | 87 | // MVP matrices the current camera is using, must match exactly or 3D elements will be misaligned 88 | D3DMATRIX world; 89 | D3DMATRIX view; 90 | D3DMATRIX projection; 91 | }; 92 | -------------------------------------------------------------------------------- /HaloCEVR/InputHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "VR/IVR.h" 3 | #include 4 | 5 | class InputHandler 6 | { 7 | public: 8 | void RegisterInputs(); 9 | void UpdateRegisteredInputs(); 10 | void UpdateInputs(bool bInVehicle); 11 | void UpdateCamera(float& yaw, float& pitch); 12 | void UpdateCameraForVehicles(float& yaw, float& pitch); 13 | void SetMousePosition(int& x, int& y); 14 | void UpdateMouseInfo(struct MouseInfo* mouseInfo); 15 | bool GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand); 16 | void CalculateSmoothedInput(); 17 | 18 | Vector3 smoothedPosition = Vector3(0.0f, 0.0f, 0.0f); 19 | 20 | protected: 21 | 22 | 23 | unsigned char UpdateFlashlight(); 24 | unsigned char UpdateHolsterSwitchWeapons(); 25 | unsigned char UpdateMelee(); 26 | unsigned char UpdateCrouch(); 27 | 28 | // Update Controls that rely on the distance between hands 29 | void UpdateHandsProximity(); 30 | void CheckSwapWeaponHand(); 31 | void UpdateTwoHandedHold(float handDistance, bool handsWithinSwapWeaponDistance); 32 | 33 | char lastSnapState = 0; 34 | unsigned char mouseDownState = 0; 35 | 36 | bool bHoldingMenu = false; 37 | std::chrono::time_point menuHeldTime; 38 | 39 | bool bWasGripping = false; 40 | bool bWasSwappingHands = false; 41 | 42 | InputBindingID Jump = 0; 43 | InputBindingID SwitchGrenades = 0; 44 | InputBindingID Interact = 0; 45 | InputBindingID SwitchWeapons = 0; 46 | InputBindingID Melee = 0; 47 | InputBindingID Flashlight = 0; 48 | InputBindingID Grenade = 0; 49 | InputBindingID Fire = 0; 50 | InputBindingID MenuForward = 0; 51 | InputBindingID MenuBack = 0; 52 | InputBindingID Crouch = 0; 53 | InputBindingID Zoom = 0; 54 | InputBindingID Reload = 0; 55 | InputBindingID Move = 0; 56 | InputBindingID Look = 0; 57 | 58 | InputBindingID Recentre = 0; 59 | InputBindingID TwoHandGrip = 0; 60 | 61 | InputBindingID SwapWeaponHand = 0; 62 | InputBindingID OffhandSwapWeaponHand = 0; 63 | 64 | private: 65 | bool IsHandInHolster(const Vector3& handPos, const Vector3& holsterPos, const float& holsterActivationDistance); 66 | }; 67 | 68 | -------------------------------------------------------------------------------- /HaloCEVR/Logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define WIN32_LEAN_AND_MEAN 8 | #define NOMINMAX 9 | #include 10 | 11 | class Logger { 12 | std::ofstream logFile; 13 | std::mutex mtx; 14 | 15 | public: 16 | Logger(const std::string& filename) { 17 | logFile.open(filename, std::ios::out | std::ios::trunc); 18 | if (!logFile) { 19 | throw std::runtime_error("Unable to open log file"); 20 | } 21 | } 22 | 23 | ~Logger() { 24 | if (logFile) { 25 | logFile.close(); 26 | } 27 | } 28 | 29 | template 30 | Logger& operator<<(const T& msg) { 31 | std::lock_guard lock(mtx); 32 | if (logFile) { 33 | logFile << msg; 34 | std::cout << msg; 35 | } 36 | return *this; 37 | } 38 | 39 | Logger& operator<<(std::ostream& (*manip)(std::ostream&)) { 40 | std::lock_guard lock(mtx); 41 | if (logFile) { 42 | logFile << manip; 43 | std::cout << manip; 44 | } 45 | return *this; 46 | } 47 | 48 | 49 | class LoggerAlert { 50 | 51 | std::ostringstream buffer; 52 | std::string string; 53 | class Logger* logger; 54 | public: 55 | 56 | LoggerAlert(Logger* defaultLogger) 57 | { 58 | logger = defaultLogger; 59 | } 60 | 61 | template 62 | LoggerAlert& operator<<(const T& msg) { 63 | buffer << msg; 64 | (*logger) << msg; 65 | return *this; 66 | } 67 | 68 | LoggerAlert& operator<<(std::ostream& (*manip)(std::ostream&)) { 69 | buffer << manip; 70 | (*logger) << manip; 71 | 72 | // detect if endl has been passed into stream here: 73 | string = buffer.str(); 74 | 75 | if (string.find('\n') != std::string::npos) 76 | { 77 | MessageBoxA(GetActiveWindow(), string.c_str(), "HaloCEVR Error", MB_OK | MB_ICONERROR); 78 | } 79 | 80 | return *this; 81 | } 82 | 83 | }; 84 | 85 | static Logger log; 86 | static LoggerAlert err; 87 | }; 88 | -------------------------------------------------------------------------------- /HaloCEVR/Profiler.cpp: -------------------------------------------------------------------------------- 1 | #include "Profiler.h" 2 | 3 | void Profiler::Init() 4 | { 5 | NewFrame(); 6 | } 7 | 8 | void Profiler::Shutdown() 9 | { 10 | delete currentFrame; 11 | for (FrameTimings* frame : timings) 12 | { 13 | for (auto kv : frame->timings) 14 | { 15 | delete kv.second; 16 | } 17 | delete frame; 18 | } 19 | timings.clear(); 20 | } 21 | 22 | void Profiler::NewFrame() 23 | { 24 | time_point now = std::chrono::high_resolution_clock::now(); 25 | if (currentFrame) 26 | { 27 | currentFrame->frameEnd = now; 28 | timings.push_back(currentFrame); 29 | } 30 | 31 | currentFrame = new FrameTimings(); 32 | currentFrame->frameStart = std::chrono::high_resolution_clock::now(); 33 | } 34 | 35 | int Profiler::StartEvent(const char* id) 36 | { 37 | ActiveEvent& newEvent = activeEvents.emplace_back(); 38 | newEvent.id = id; 39 | newEvent.startTime = std::chrono::high_resolution_clock::now(); 40 | 41 | return activeEvents.size() - 1; 42 | } 43 | 44 | void Profiler::StopEvent(int eventId) 45 | { 46 | time_point now = std::chrono::high_resolution_clock::now(); 47 | 48 | ActiveEvent& e = activeEvents[eventId]; 49 | 50 | float duration = std::chrono::duration(now - e.startTime).count(); 51 | 52 | Timings*& timings = currentFrame->timings[e.id]; 53 | 54 | if (!timings) 55 | { 56 | timings = new Timings(); 57 | } 58 | 59 | timings->numHits++; 60 | timings->totalTime += duration; 61 | timings->minTime = (std::min)(timings->minTime, duration); 62 | timings->maxTime = (std::max)(timings->maxTime, duration); 63 | } 64 | 65 | void Profiler::GetTimings(std::vector& outTimings) const 66 | { 67 | outTimings = timings; 68 | } 69 | 70 | ProfilerScopeGuard::ProfilerScopeGuard(Profiler* profiler, const char* id) 71 | { 72 | this->id = profiler->StartEvent(id); 73 | this->profiler = profiler; 74 | } 75 | 76 | ProfilerScopeGuard::~ProfilerScopeGuard() 77 | { 78 | profiler->StopEvent(id); 79 | } 80 | -------------------------------------------------------------------------------- /HaloCEVR/Profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define USE_PROFILER 0 8 | 9 | #if USE_PROFILER 10 | #define VR_PROFILE_SCOPE(x) ProfilerScopeGuard profiler_##x(&Game::instance.profiler, #x); 11 | #define VR_PROFILE_START(x) int profiler_##x = Game::instance.profiler.StartEvent(#x); 12 | #define VR_PROFILE_STOP(x) Game::instance.profiler.StopEvent(profiler_##x); 13 | #else 14 | #define VR_PROFILE_SCOPE(x) 15 | #define VR_PROFILE_START(x) 16 | #define VR_PROFILE_STOP(x) 17 | #endif 18 | 19 | class ProfilerScopeGuard 20 | { 21 | public: 22 | ProfilerScopeGuard() = delete; 23 | ProfilerScopeGuard(class Profiler* profiler, const char* id); 24 | ~ProfilerScopeGuard(); 25 | 26 | protected: 27 | int id; 28 | class Profiler* profiler; 29 | }; 30 | 31 | class Profiler 32 | { 33 | public: 34 | typedef std::chrono::time_point time_point; 35 | 36 | struct Timings 37 | { 38 | int numHits = 0; 39 | float minTime = FLT_MAX; 40 | float maxTime = -FLT_MAX; 41 | float totalTime = 0.0f; 42 | }; 43 | 44 | struct FrameTimings 45 | { 46 | time_point frameStart; 47 | time_point frameEnd; 48 | std::unordered_map timings; 49 | }; 50 | 51 | 52 | void Init(); 53 | void Shutdown(); 54 | 55 | void NewFrame(); 56 | 57 | int StartEvent(const char* id); 58 | void StopEvent(int eventId); 59 | 60 | void GetTimings(std::vector& outTimings) const; 61 | 62 | protected: 63 | 64 | std::vector timings; 65 | FrameTimings* currentFrame = nullptr; 66 | 67 | struct ActiveEvent 68 | { 69 | time_point startTime; 70 | std::string id; 71 | }; 72 | 73 | std::vector activeEvents; 74 | }; 75 | 76 | -------------------------------------------------------------------------------- /HaloCEVR/UI/SettingsMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "UIRenderer.h" 5 | 6 | class SettingsMenu 7 | { 8 | public: 9 | SettingsMenu() = default; 10 | 11 | void CreateMenus(); 12 | 13 | void ShowMenus(bool bShow); 14 | 15 | void NextPage(std::vector& pages, int& currentPage); 16 | void PrevPage(std::vector& pages, int& currentPage); 17 | void SetPage(std::vector& pages, int& page); 18 | 19 | void ReloadSettingsPages(); 20 | 21 | bool bVisible = false; 22 | 23 | int basicSettingsPage = 0; 24 | std::vector basicSettingsPages; 25 | int allSettingsPage = 0; 26 | std::vector allSettingsPages; 27 | 28 | protected: 29 | 30 | static inline D3DCOLOR textLabelColour = D3DCOLOR_ARGB(255, 33, 150, 255); 31 | static inline D3DCOLOR textValueColour = D3DCOLOR_ARGB(255, 255, 255, 255); 32 | static inline D3DCOLOR backgroundColour = D3DCOLOR_ARGB(255, 0, 20, 35); 33 | static inline D3DCOLOR darkPanelColour = D3DCOLOR_ARGB(255, 3, 11, 44); 34 | static inline D3DCOLOR mediumPanelColour = D3DCOLOR_ARGB(255, 6, 21, 51); 35 | static inline D3DCOLOR lightPanelColour = D3DCOLOR_ARGB(255, 8, 29, 58); 36 | 37 | static inline float settingArrowWidth = 32.0f; 38 | static inline float settingPanelPaddingX = 10.0f; 39 | static inline float settingPanelPaddingY = 10.0f; 40 | static inline float settingPanelSaveButtonY = 50.0f; 41 | 42 | IDirect3DTexture9* settingsButtonImage = nullptr; 43 | IDirect3DTexture9* prevPageButtonImage = nullptr; 44 | IDirect3DTexture9* nextPageButtonImage = nullptr; 45 | 46 | class UIPanel* mainPanel = nullptr; 47 | class UIPanel* backgroundPanel = nullptr; 48 | class UITabPanel* settingsTabs = nullptr; 49 | class UIPanel* basicSettingsPanel = nullptr; 50 | class UIPanel* allSettingsPanel = nullptr; 51 | 52 | void GenerateSettingsTab(const std::vector& settingNames, class UIPanel* parentPanel, std::vector& pages); 53 | class UIPanel* GenerateSettingsPanel(std::string propertyName, class UIPanel* parentPanel, float y, float padding, float innerPadding); 54 | 55 | void PopulateBasicSettingsTab(); 56 | void PopulateAllSettingsTab(); 57 | void PopulateAboutTab(class UIPanel* aboutPanel); 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIButton.cpp: -------------------------------------------------------------------------------- 1 | #include "UIButton.h" 2 | #include "../Game.h" 3 | 4 | bool UIButton::Click(float mouseX, float mouseY) 5 | { 6 | const bool bOverlaps = InBounds(mouseX, mouseY, x, y, w, h); 7 | 8 | if (bOverlaps) 9 | { 10 | if (bToggle) 11 | { 12 | bIsActive ^= true; 13 | 14 | if (bIsActive) 15 | { 16 | Game::instance.uiRenderer->UpdateActiveButton(this); 17 | } 18 | else 19 | { 20 | Game::instance.uiRenderer->UpdateActiveButton(nullptr); 21 | } 22 | } 23 | else 24 | { 25 | Game::instance.uiRenderer->UpdateActiveButton(nullptr); 26 | } 27 | 28 | if (onClick) 29 | { 30 | onClick(); 31 | } 32 | } 33 | 34 | return bOverlaps; 35 | } 36 | 37 | void UIButton::Deactivate() 38 | { 39 | if (!bToggle) 40 | { 41 | bIsActive = false; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UIElement.h" 3 | #include 4 | class UIButton : public UIElement 5 | { 6 | public: 7 | float w; 8 | float h; 9 | 10 | bool bIsActive = false; 11 | bool bToggle = false; 12 | 13 | std::function onClick; 14 | 15 | virtual bool Click(float mouseX, float mouseY) override; 16 | virtual void Deactivate(); 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UICheckbox.cpp: -------------------------------------------------------------------------------- 1 | #include "UICheckbox.h" 2 | #include "UIRenderer.h" 3 | 4 | UICheckbox::UICheckbox(float x, float y, float size, bool bChecked, DWORD backgroundColour, DWORD checkColour) 5 | { 6 | this->x = x; 7 | this->y = y; 8 | this->w = size; 9 | this->h = size; 10 | this->bIsActive = bChecked; 11 | this->backgroundColour = backgroundColour; 12 | this->checkColour = checkColour; 13 | this->bToggle = true; 14 | } 15 | 16 | void UICheckbox::Draw(UIRenderer* renderer) 17 | { 18 | float pX, pY; 19 | GetScreenPosition(pX, pY); 20 | 21 | renderer->DrawRect(pX, pY, w, w, backgroundColour); 22 | 23 | if (bIsActive) 24 | { 25 | float buffer = w * 0.25f; 26 | float innerSize = w - buffer * 2.0f; 27 | renderer->DrawRect(pX + buffer, pY + buffer, innerSize, innerSize, checkColour); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UICheckbox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "UIButton.h" 4 | class UICheckbox : public UIButton 5 | { 6 | public: 7 | DWORD backgroundColour; 8 | DWORD checkColour; 9 | 10 | UICheckbox(float x, float y, float size, bool bChecked, DWORD backgroundColour, DWORD checkColour); 11 | 12 | virtual void Draw(class UIRenderer* renderer) override; 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIElement.cpp: -------------------------------------------------------------------------------- 1 | #include "UIElement.h" 2 | 3 | void UIElement::GetScreenPosition(float& outX, float& outY) const 4 | { 5 | if (!parent) 6 | { 7 | outX = x; 8 | outY = y; 9 | } 10 | else 11 | { 12 | float parentX, parentY; 13 | parent->GetScreenPosition(parentX, parentY); 14 | 15 | outX = parentX + x; 16 | outY = parentY + y; 17 | } 18 | } 19 | 20 | bool UIElement::InBounds(float posX, float posY, float boundsX, float boundsY, float width, float height) 21 | { 22 | const bool bInX = posX >= boundsX && posX <= boundsX + width; 23 | const bool bInY = posY >= boundsY && posY <= boundsY + height; 24 | 25 | return bInX && bInY; 26 | } 27 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIElement.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class UIElement 3 | { 4 | public: 5 | float x; 6 | float y; 7 | bool bVisible = true; 8 | UIElement* parent; 9 | 10 | virtual bool Click(float mouseX, float mouseY) = 0; 11 | virtual void Draw(class UIRenderer* renderer) = 0; 12 | 13 | void GetScreenPosition(float& outX, float& outY) const; 14 | 15 | protected: 16 | 17 | // Helper function, returns true if Pos is within the bounding box defined 18 | // by the provided x/y coordinates and width/height 19 | static bool InBounds(float posX, float posY, float boundsX, float boundsY, float width, float height); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIFloatBox.cpp: -------------------------------------------------------------------------------- 1 | #include "UIFloatBox.h" 2 | #include 3 | #include 4 | #include "../Game.h" 5 | 6 | UIFloatBox::UIFloatBox(float x, float y, float w, float h, float value, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour) 7 | : UITextBox(x, y, w, h, floatToString(value), font, inactiveColour, activeColour, textColour) 8 | { 9 | this->floatValue = value; 10 | } 11 | 12 | void UIFloatBox::ValidateText() 13 | { 14 | bool bIsNumeric = text.find_first_not_of("0123456789.-") == std::string::npos; 15 | bool bBadDecimal = std::count_if(text.begin(), text.end(), [](char c) { return c == '.'; }) > 1; 16 | bool bBadSign = text.find_first_of('-', 1) != std::string::npos; 17 | 18 | if (!bIsNumeric || bBadDecimal || bBadSign) 19 | { 20 | text = floatToString(floatValue); 21 | float textW = Game::instance.uiRenderer->CalculateStringWidth(*font, text.c_str()); 22 | textX = (w - textW) * 0.5f; 23 | } 24 | else 25 | { 26 | floatValue = static_cast(atof(text.c_str())); 27 | } 28 | } 29 | 30 | std::string UIFloatBox::floatToString(float v) const 31 | { 32 | std::stringstream ss{}; 33 | ss << v; 34 | return ss.str(); 35 | } 36 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIFloatBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UITextBox.h" 3 | class UIFloatBox : public UITextBox 4 | { 5 | public: 6 | 7 | UIFloatBox(float x, float y, float w, float h, float value, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour); 8 | 9 | float floatValue; 10 | protected: 11 | virtual void ValidateText() override; 12 | std::string floatToString(float v) const; 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIImageButton.cpp: -------------------------------------------------------------------------------- 1 | #include "UIImageButton.h" 2 | #include "UIRenderer.h" 3 | 4 | UIImageButton::UIImageButton(float x, float y, float w, float h, IDirect3DTexture9* image) 5 | { 6 | this->x = x; 7 | this->y = y; 8 | this->w = w; 9 | this->h = h; 10 | this->image = image; 11 | } 12 | 13 | void UIImageButton::Draw(UIRenderer* renderer) 14 | { 15 | float pX, pY; 16 | GetScreenPosition(pX, pY); 17 | renderer->DrawImage(pX, pY, w, h, image); 18 | } 19 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIImageButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "UIButton.h" 4 | class UIImageButton : public UIButton 5 | { 6 | public: 7 | IDirect3DTexture9* image; 8 | 9 | UIImageButton(float x, float y, float w, float h, IDirect3DTexture9* image); 10 | 11 | virtual void Draw(class UIRenderer* renderer) override; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIIntBox.cpp: -------------------------------------------------------------------------------- 1 | #include "UIIntBox.h" 2 | #include 3 | #include 4 | #include "../Game.h" 5 | 6 | UIIntBox::UIIntBox(float x, float y, float w, float h, int value, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour) 7 | : UITextBox(x, y, w, h, std::to_string(value), font, inactiveColour, activeColour, textColour) 8 | { 9 | this->intValue = value; 10 | } 11 | 12 | void UIIntBox::ValidateText() 13 | { 14 | bool bIsNumeric = text.find_first_not_of("0123456789-") == std::string::npos; 15 | bool bBadSign = text.find_first_of('-', 1) != std::string::npos; 16 | 17 | if (!bIsNumeric || bBadSign) 18 | { 19 | text = std::to_string(intValue); 20 | float textW = Game::instance.uiRenderer->CalculateStringWidth(*font, text.c_str()); 21 | textX = (w - textW) * 0.5f; 22 | } 23 | else 24 | { 25 | intValue = atoi(text.c_str()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIIntBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UITextBox.h" 3 | class UIIntBox : public UITextBox 4 | { 5 | public: 6 | 7 | UIIntBox(float x, float y, float w, float h, int value, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour); 8 | 9 | int intValue; 10 | protected: 11 | virtual void ValidateText() override; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UILabel.cpp: -------------------------------------------------------------------------------- 1 | #include "UILabel.h" 2 | 3 | UILabel::UILabel(float x, float y, std::string text, Font* font, DWORD color) 4 | { 5 | this->x = x; 6 | this->y = y; 7 | this->text = text; 8 | this->font = font; 9 | this->color = color; 10 | } 11 | 12 | bool UILabel::Click(float mouseX, float mouseY) 13 | { 14 | return false; 15 | } 16 | 17 | void UILabel::Draw(UIRenderer* renderer) 18 | { 19 | float pX, pY; 20 | GetScreenPosition(pX, pY); 21 | renderer->Print(*font, text.c_str(), pX, pY, color); 22 | } 23 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UILabel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UIElement.h" 3 | #include "UIRenderer.h" 4 | #include 5 | 6 | class UILabel : public UIElement 7 | { 8 | public: 9 | std::string text; 10 | struct Font* font; 11 | DWORD color; 12 | 13 | UILabel(float x, float y, std::string text, struct Font* font, DWORD color = D3DCOLOR_ARGB(255, 255, 255, 255)); 14 | 15 | virtual bool Click(float mouseX, float mouseY) override; 16 | virtual void Draw(class UIRenderer* renderer) override; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "UIPanel.h" 2 | 3 | UIPanel::UIPanel(float x, float y, float w, float h, DWORD color, bool bDrawBackground) 4 | { 5 | this->x = x; 6 | this->y = y; 7 | this->w = w; 8 | this->h = h; 9 | this->color = color; 10 | this->bDrawBackground = bDrawBackground; 11 | } 12 | 13 | bool UIPanel::Click(float mouseX, float mouseY) 14 | { 15 | mouseX -= x; 16 | mouseY -= y; 17 | for (UIElement* child : childElements) 18 | { 19 | if (child->bVisible) 20 | { 21 | if (child->Click(mouseX, mouseY)) 22 | { 23 | return true; 24 | } 25 | } 26 | } 27 | 28 | return false; 29 | } 30 | 31 | void UIPanel::Draw(UIRenderer* renderer) 32 | { 33 | if (bDrawBackground) 34 | { 35 | float pX, pY; 36 | GetScreenPosition(pX, pY); 37 | renderer->DrawRect(pX, pY, w, h, color); 38 | } 39 | 40 | for (UIElement* child : childElements) 41 | { 42 | if (child->bVisible) 43 | { 44 | child->Draw(renderer); 45 | } 46 | } 47 | } 48 | 49 | void UIPanel::AddElement(UIElement* element) 50 | { 51 | childElements.push_back(element); 52 | element->parent = this; 53 | } 54 | 55 | void UIPanel::RemoveElement(UIElement* element) 56 | { 57 | auto it = std::find(childElements.begin(), childElements.end(), element); 58 | if (it != childElements.end()) 59 | { 60 | childElements.erase(it); 61 | } 62 | } 63 | 64 | void UIPanel::DeleteChildren() 65 | { 66 | for (UIElement* child : childElements) 67 | { 68 | if (UIPanel* childPanel = dynamic_cast(child)) 69 | { 70 | childPanel->DeleteChildren(); 71 | } 72 | delete child; 73 | } 74 | childElements.clear(); 75 | } 76 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UIElement.h" 3 | #include "UIRenderer.h" 4 | class UIPanel : public UIElement 5 | { 6 | public: 7 | float w; 8 | float h; 9 | bool bDrawBackground = true; 10 | DWORD color; 11 | 12 | UIPanel(float x, float y, float w, float h, DWORD color, bool bDrawBackground = true); 13 | 14 | virtual bool Click(float mouseX, float mouseY) override; 15 | virtual void Draw(UIRenderer* renderer) override; 16 | 17 | void AddElement(class UIElement* element); 18 | void RemoveElement(class UIElement* element); 19 | void DeleteChildren(); 20 | 21 | protected: 22 | 23 | std::vector childElements; 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UIRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../ThirdParty/stb/stb_truetype.h" 3 | #include 4 | #include 5 | #include 6 | 7 | struct Font 8 | { 9 | IDirect3DTexture9* fontBitmap; 10 | stbtt_bakedchar cdata[96]; 11 | float offset; 12 | float fontSize; 13 | float lineHeight; 14 | }; 15 | 16 | class UIRenderer 17 | { 18 | public: 19 | void Init(IDirect3DDevice9* inDevice); 20 | bool InitFont(const char* fontPath, float fontSize, Font& outFont); 21 | IDirect3DTexture9* LoadTexture(const char* imagePath); 22 | void Shutdown(); 23 | 24 | void MoveCursor(float x, float y); 25 | void Click(); 26 | 27 | void AddElement(class UIElement* element); 28 | 29 | void Render(); 30 | 31 | void DrawRect(float x, float y, float w, float h, DWORD color) const; 32 | void DrawImage(float x, float y, float w, float h, IDirect3DTexture9* image) const; 33 | void Print(const Font& font, const char* text, float x, float y, DWORD color = D3DCOLOR_ARGB(255, 255, 255, 255)) const; 34 | 35 | float CalculateWrappedString(const Font& font, const char* text, float w, std::string& wrappedString) const; 36 | float CalculateStringWidth(const Font& font, const char* text) const; 37 | 38 | void UpdateActiveButton(class UIButton* button); 39 | 40 | Font* GetTitleFont() { return &fontTitle; } 41 | Font* GetLargeFont() { return &fontLarge; } 42 | Font* GetMediumFont() { return &fontMedium; } 43 | Font* GetSmallFont() { return &fontSmall; } 44 | Font* GetDescriptionFont() { return &fontDesc; } 45 | 46 | protected: 47 | 48 | // All UI elements to be rendered, will render in the order elements were added 49 | std::vector uiElements; 50 | 51 | class UIButton* activeButton = nullptr; 52 | 53 | float mouseX = 0.0f; 54 | float mouseY = 0.0f; 55 | 56 | IDirect3DDevice9* device; 57 | 58 | Font fontTitle; 59 | Font fontLarge; 60 | Font fontMedium; 61 | Font fontSmall; 62 | Font fontDesc; 63 | 64 | float widthScale, heightScale; 65 | 66 | struct VertexData2D 67 | { 68 | float x, y, z, rhw; 69 | DWORD color; 70 | }; 71 | 72 | struct VertexDataTex2D 73 | { 74 | float x, y, z, rhw; 75 | DWORD color; 76 | float u, v; 77 | }; 78 | }; 79 | 80 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UITabPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "UITabPanel.h" 2 | #include "UIButton.h" 3 | #include "UIPanel.h" 4 | #include "../Logger.h" 5 | 6 | UITabPanel::UITabPanel(float x, float y, float w, float h) 7 | { 8 | this->x = x; 9 | this->y = y; 10 | this->w = w; 11 | this->h = h; 12 | 13 | this->nextButtonPos = 0.0f; 14 | } 15 | 16 | void UITabPanel::AddTab(UIButton* button, UIPanel* panel) 17 | { 18 | button->parent = this; 19 | button->x = nextButtonPos; 20 | button->bToggle = true; 21 | nextButtonPos += button->w; 22 | 23 | size_t index = buttons.size(); 24 | 25 | button->onClick = [index,this]() { 26 | this->SetActiveTab(index); 27 | }; 28 | 29 | // Default to first panel being active 30 | panel->bVisible = buttons.empty(); 31 | button->bIsActive = buttons.empty(); 32 | 33 | buttons.push_back(button); 34 | panels.push_back(panel); 35 | } 36 | 37 | bool UITabPanel::Click(float mouseX, float mouseY) 38 | { 39 | mouseX -= x; 40 | mouseY -= y; 41 | 42 | for (class UIButton* button : buttons) 43 | { 44 | if (button->bVisible) 45 | { 46 | if (button->Click(mouseX, mouseY)) 47 | { 48 | return true; 49 | } 50 | } 51 | } 52 | 53 | return false; 54 | } 55 | 56 | void UITabPanel::Draw(UIRenderer* renderer) 57 | { 58 | for (UIButton* button : buttons) 59 | { 60 | if (button->bVisible) 61 | { 62 | button->Draw(renderer); 63 | } 64 | } 65 | } 66 | 67 | void UITabPanel::SetActiveTab(size_t index) 68 | { 69 | for (size_t i = 0; i < panels.size(); i++) 70 | { 71 | if (index == i) 72 | { 73 | panels[i]->bVisible = true; 74 | buttons[i]->bIsActive = true; 75 | } 76 | else 77 | { 78 | panels[i]->bVisible = false; 79 | buttons[i]->bIsActive = false; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UITabPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UIElement.h" 3 | #include 4 | class UITabPanel : public UIElement 5 | { 6 | public: 7 | float w; 8 | float h; 9 | 10 | UITabPanel(float x, float y, float w, float h); 11 | 12 | void AddTab(class UIButton* button, class UIPanel* panel); 13 | 14 | virtual bool Click(float mouseX, float mouseY) override; 15 | virtual void Draw(class UIRenderer* renderer) override; 16 | 17 | void SetActiveTab(size_t index); 18 | 19 | protected: 20 | 21 | int activeTab = 0; 22 | 23 | float nextButtonPos; 24 | 25 | std::vector buttons; 26 | std::vector panels; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UITextBox.cpp: -------------------------------------------------------------------------------- 1 | #include "UITextBox.h" 2 | #include "../Game.h" 3 | 4 | UITextBox::UITextBox(float x, float y, float w, float h, std::string text, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour) 5 | : UITextButton(x, y, w, h, text, font, inactiveColour, activeColour, textColour) 6 | { 7 | } 8 | 9 | bool UITextBox::Click(float mouseX, float mouseY) 10 | { 11 | const bool bOverlaps = InBounds(mouseX, mouseY, x, y, w, h); 12 | 13 | if (bOverlaps) 14 | { 15 | const bool bKeyboardUp = Game::instance.GetVR()->IsKeyboardVisible(); 16 | 17 | // Don't activate if another box has input 18 | if (!bIsActive && bKeyboardUp) 19 | { 20 | return true; 21 | } 22 | 23 | bIsActive ^= true; 24 | 25 | if (bIsActive) 26 | { 27 | Game::instance.uiRenderer->UpdateActiveButton(this); 28 | Game::instance.GetVR()->ShowKeyboard(text); 29 | } 30 | else 31 | { 32 | Game::instance.uiRenderer->UpdateActiveButton(nullptr); 33 | } 34 | } 35 | 36 | return bOverlaps; 37 | } 38 | 39 | void UITextBox::Draw(UIRenderer* renderer) 40 | { 41 | if (bIsActive) 42 | { 43 | text = Game::instance.GetVR()->GetKeyboardInput(); 44 | float textW = Game::instance.uiRenderer->CalculateStringWidth(*font, text.c_str()); 45 | textX = (w - textW) * 0.5f; 46 | } 47 | 48 | UITextButton::Draw(renderer); 49 | } 50 | 51 | void UITextBox::Deactivate() 52 | { 53 | bIsActive = false; 54 | text = Game::instance.GetVR()->GetKeyboardInput(); 55 | Game::instance.GetVR()->HideKeyboard(); 56 | ValidateText(); 57 | 58 | if (onClick) 59 | { 60 | onClick(); 61 | } 62 | 63 | Logger::log << "Deactivated" << std::endl; 64 | } 65 | 66 | void UITextBox::ValidateText() 67 | { 68 | } 69 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UITextBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UITextButton.h" 3 | class UITextBox : public UITextButton 4 | { 5 | public: 6 | 7 | UITextBox(float x, float y, float w, float h, std::string text, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour); 8 | 9 | virtual bool Click(float mouseX, float mouseY) override; 10 | virtual void Draw(class UIRenderer* renderer) override; 11 | virtual void Deactivate() override; 12 | 13 | protected: 14 | virtual void ValidateText(); 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UITextButton.cpp: -------------------------------------------------------------------------------- 1 | #include "UITextButton.h" 2 | #include "../Game.h" 3 | 4 | UITextButton::UITextButton(float x, float y, float w, float h, std::string text, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour) 5 | { 6 | this->x = x; 7 | this->y = y; 8 | this->w = w; 9 | this->h = h; 10 | this->text = text; 11 | this->font = font; 12 | this->inactiveColour = inactiveColour; 13 | this->activeColour = activeColour; 14 | this->textColour = textColour; 15 | 16 | float textW = Game::instance.uiRenderer->CalculateStringWidth(*font, text.c_str()); 17 | 18 | textX = (w - textW) * 0.5f; 19 | textY = (h - font->lineHeight) * 0.5f; 20 | } 21 | 22 | void UITextButton::Draw(UIRenderer* renderer) 23 | { 24 | float pX, pY; 25 | GetScreenPosition(pX, pY); 26 | renderer->DrawRect(pX, pY, w, h, bIsActive ? activeColour : inactiveColour); 27 | renderer->Print(*font, text.c_str(), pX + textX, pY + textY, textColour); 28 | } 29 | -------------------------------------------------------------------------------- /HaloCEVR/UI/UITextButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "UIButton.h" 3 | #include 4 | #include "UIRenderer.h" 5 | class UITextButton : public UIButton 6 | { 7 | public: 8 | std::string text; 9 | struct Font* font; 10 | DWORD inactiveColour; 11 | DWORD activeColour; 12 | DWORD textColour; 13 | 14 | UITextButton(float x, float y, float w, float h, std::string text, Font* font, DWORD inactiveColour, DWORD activeColour, DWORD textColour); 15 | 16 | virtual void Draw(class UIRenderer* renderer) override; 17 | 18 | protected: 19 | 20 | float textX; 21 | float textY; 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /HaloCEVR/VR/IVR.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Maths/Matrices.h" 3 | 4 | typedef uint64_t InputBindingID; 5 | 6 | enum class ControllerRole 7 | { 8 | Left, 9 | Right 10 | }; 11 | 12 | class IVR 13 | { 14 | public: 15 | virtual void Init() = 0; 16 | virtual void OnGameFinishInit() = 0; 17 | virtual void Shutdown() = 0; 18 | virtual void UpdatePoses() = 0; 19 | virtual void PreDrawFrame(struct Renderer* renderer, float deltaTime) = 0; 20 | virtual void PostDrawFrame(struct Renderer* renderer, float deltaTime) = 0; 21 | 22 | virtual void UpdateCameraFrustum(struct CameraFrustum* frustum, int eye) = 0; 23 | 24 | virtual int GetViewWidth() = 0; 25 | virtual int GetViewHeight() = 0; 26 | virtual float GetViewWidthStretch() = 0; 27 | virtual float GetViewHeightStretch() = 0; 28 | virtual float GetAspect() = 0; 29 | virtual int GetScopeWidth() = 0; 30 | virtual int GetScopeHeight() = 0; 31 | virtual void Recentre() = 0; 32 | virtual void SetLocationOffset(Vector3 newOffset) = 0; 33 | virtual Vector3 GetLocationOffset() = 0; 34 | virtual void SetYawOffset(float newOffset) = 0; 35 | virtual float GetYawOffset() = 0; 36 | virtual Matrix4 GetHMDTransform(bool bRenderPose = false) = 0; 37 | virtual Matrix4 GetRawControllerTransform(ControllerRole role, bool bRenderPose = false) = 0; 38 | virtual Matrix4 GetControllerTransform(ControllerRole role, bool bRenderPose = false) = 0; 39 | virtual Matrix4 GetControllerBoneTransform(ControllerRole role, int bone, bool bRenderPose = false) = 0; 40 | virtual Vector3 GetControllerVelocity(ControllerRole role, bool bRenderPose = false) = 0; 41 | virtual bool TryGetControllerFacing(ControllerRole role, Vector3& outDirection) = 0; 42 | virtual struct IDirect3DSurface9* GetRenderSurface(int eye) = 0; 43 | virtual struct IDirect3DTexture9* GetRenderTexture(int eye) = 0; 44 | virtual struct IDirect3DSurface9* GetUISurface() = 0; 45 | virtual struct IDirect3DSurface9* GetCrosshairSurface() = 0; 46 | virtual struct IDirect3DSurface9* GetScopeSurface() = 0; 47 | virtual struct IDirect3DTexture9* GetScopeTexture() = 0; 48 | 49 | virtual void SetMouseVisibility(bool bIsVisible) = 0; 50 | virtual void SetCrosshairTransform(class Matrix4& newTransform) = 0; 51 | virtual void UpdateInputs() = 0; 52 | virtual InputBindingID RegisterBoolInput(std::string set, std::string action) = 0; 53 | virtual InputBindingID RegisterVector2Input(std::string set, std::string action) = 0; 54 | virtual bool GetBoolInput(InputBindingID id) = 0; 55 | virtual bool GetBoolInput(InputBindingID id, bool &bHasChanged) = 0; 56 | virtual Vector2 GetVector2Input(InputBindingID id) = 0; 57 | virtual Vector2 GetMousePos() = 0; 58 | virtual bool GetMouseDown() = 0; 59 | virtual void ShowKeyboard(const std::string& textBuffer) = 0; 60 | virtual bool IsKeyboardVisible() = 0; 61 | virtual void HideKeyboard() = 0; 62 | virtual std::string GetKeyboardInput() = 0; 63 | 64 | virtual std::string GetDeviceName() = 0; 65 | }; 66 | -------------------------------------------------------------------------------- /HaloCEVR/VR/OpenVR.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IVR.h" 3 | #include 4 | #include 5 | #include 6 | #include "../../ThirdParty/OpenVR/include/openvr.h" 7 | 8 | class OpenVR : public IVR 9 | { 10 | public: 11 | // Start Interface IVR 12 | void Init() override; 13 | void OnGameFinishInit() override; 14 | void Shutdown() override; 15 | void UpdatePoses() override; 16 | void PreDrawFrame(Renderer* renderer, float deltaTime) override; 17 | void PostDrawFrame(Renderer* renderer, float deltaTime) override; 18 | void UpdateCameraFrustum(CameraFrustum* frustum, int eye) override; 19 | int GetViewWidth() override; 20 | int GetViewHeight() override; 21 | float GetViewWidthStretch() override; 22 | float GetViewHeightStretch() override; 23 | float GetAspect() override; 24 | int GetScopeWidth() override; 25 | int GetScopeHeight() override; 26 | void Recentre() override; 27 | void SetLocationOffset(Vector3 newOffset) override; 28 | Vector3 GetLocationOffset() override; 29 | void SetYawOffset(float newOffset) override; 30 | float GetYawOffset() override; 31 | Matrix4 GetHMDTransform(bool bRenderPose = false) override; 32 | Matrix4 GetRawControllerTransform(ControllerRole role, bool bRenderPose = false) override; 33 | Matrix4 GetControllerTransform(ControllerRole Role, bool bRenderPose = false) override; 34 | Matrix4 GetControllerBoneTransform(ControllerRole Role, int bone, bool bRenderPose = false) override; 35 | Vector3 GetControllerVelocity(ControllerRole Role, bool bRenderPose = false) override; 36 | bool TryGetControllerFacing(ControllerRole role, Vector3& outDirection) override; 37 | IDirect3DSurface9* GetRenderSurface(int eye) override; 38 | IDirect3DTexture9* GetRenderTexture(int eye) override; 39 | IDirect3DSurface9* GetUISurface() override; 40 | IDirect3DSurface9* GetCrosshairSurface() override; 41 | IDirect3DSurface9* GetScopeSurface() override; 42 | IDirect3DTexture9* GetScopeTexture() override; 43 | void SetMouseVisibility(bool bIsVisible) override; 44 | void SetCrosshairTransform(class Matrix4& newTransform) override; 45 | void UpdateInputs() override; 46 | InputBindingID RegisterBoolInput(std::string set, std::string action) override; 47 | InputBindingID RegisterVector2Input(std::string set, std::string action) override; 48 | bool GetBoolInput(InputBindingID id) override; 49 | bool GetBoolInput(InputBindingID id, bool& bHasChanged) override; 50 | Vector2 GetVector2Input(InputBindingID id) override; 51 | Vector2 GetMousePos() override; 52 | bool GetMouseDown() override; 53 | void ShowKeyboard(const std::string& textBuffer) override; 54 | bool IsKeyboardVisible() override; 55 | void HideKeyboard() override; 56 | std::string GetKeyboardInput() override; 57 | std::string GetDeviceName() override; 58 | // End Interface IVR 59 | 60 | protected: 61 | void CreateTexAndSurface(int index, UINT Width, UINT Height, DWORD Usage, D3DFORMAT Format); 62 | void PositionOverlay(); 63 | void UpdateSkeleton(ControllerRole hand); 64 | void UpdatePose(ControllerRole hand); 65 | 66 | Matrix4 GetControllerTransformInternal(ControllerRole role, int bone, bool bRenderPose); 67 | 68 | vr::IVRSystem* vrSystem; 69 | vr::IVRCompositor* vrCompositor; 70 | vr::IVRInput* vrInput; 71 | vr::IVROverlay* vrOverlay; 72 | 73 | vr::VRTextureBounds_t textureBounds[2]; 74 | uint32_t realWidth; 75 | uint32_t realHeight; 76 | uint32_t recommendedWidth; 77 | uint32_t recommendedHeight; 78 | float aspect; 79 | float fov; 80 | uint32_t scopeWidth; 81 | uint32_t scopeHeight; 82 | 83 | Vector3 positionOffset; 84 | float yawOffset; 85 | 86 | bool bMouseVisible; 87 | Vector2 mousePos; 88 | bool bMouseDown; 89 | 90 | vr::VRActiveActionSet_t actionSets[2]; 91 | void SetActiveActionSet(int index, const std::string& actionSetName); 92 | 93 | vr::VROverlayHandle_t uiOverlay; 94 | 95 | vr::TrackedDevicePose_t gamePoses[vr::k_unMaxTrackedDeviceCount]; 96 | vr::TrackedDevicePose_t renderPoses[vr::k_unMaxTrackedDeviceCount]; 97 | 98 | // Most recent skeletal data for hand pose 99 | vr::VRBoneTransform_t bones[2][31]; 100 | // Cached wrist offset for automatic hand offset calculation (known good location) 101 | vr::VRBoneTransform_t cachedWrists[2]; 102 | bool bHasCachedWrists[2] = { false, false }; 103 | 104 | static constexpr int uiSurface = 2; 105 | static constexpr int crosshairSurface = 3; 106 | static constexpr int scopeSurface = 4; 107 | 108 | IDirect3DSurface9* gameRenderSurface[5]; 109 | IDirect3DTexture9* gameRenderTexture[5]; 110 | 111 | ID3D11Device* d3dDevice; 112 | 113 | ID3D11Texture2D* vrRenderTexture[5]; 114 | 115 | vr::VRActionHandle_t leftHandSkeleton; 116 | vr::VRActionHandle_t rightHandSkeleton; 117 | 118 | vr::VRActionHandle_t leftHandTip; 119 | vr::VRActionHandle_t rightHandTip; 120 | vr::InputPoseActionData_t leftHandTipPose; 121 | vr::InputPoseActionData_t rightHandTipPose; 122 | bool bHasValidTipPoses = false; 123 | 124 | char* keyboardBuffer = nullptr; 125 | bool bKeyboardVisible = false; 126 | 127 | Matrix4 ConvertSteamVRMatrixToMatrix4(const vr::HmdMatrix34_t& matPose) 128 | { 129 | Matrix4 matrixObj( 130 | matPose.m[2][2], matPose.m[0][2], -matPose.m[1][2], 0.0, 131 | matPose.m[2][0], matPose.m[0][0], -matPose.m[1][0], 0.0, 132 | -matPose.m[2][1], -matPose.m[0][1], matPose.m[1][1], 0.0, 133 | -matPose.m[2][3], -matPose.m[0][3], matPose.m[1][3], 1.0f 134 | ); 135 | 136 | return matrixObj; 137 | } 138 | 139 | vr::HmdMatrix34_t ConvertMatrixToSteamVRMatrix4(const Matrix4& matPose) 140 | { 141 | vr::HmdMatrix34_t matrixObj; 142 | matrixObj.m[2][2] = matPose[0 * 4 + 0]; 143 | matrixObj.m[0][2] = matPose[0 * 4 + 1]; 144 | matrixObj.m[1][2] = -matPose[0 * 4 + 2]; 145 | matrixObj.m[2][0] = matPose[1 * 4 + 0]; 146 | matrixObj.m[0][0] = matPose[1 * 4 + 1]; 147 | matrixObj.m[1][0] = -matPose[1 * 4 + 2]; 148 | matrixObj.m[2][1] = -matPose[2 * 4 + 0]; 149 | matrixObj.m[0][1] = -matPose[2 * 4 + 1]; 150 | matrixObj.m[1][1] = matPose[2 * 4 + 2]; 151 | matrixObj.m[2][3] = -matPose[3 * 4 + 0]; 152 | matrixObj.m[0][3] = -matPose[3 * 4 + 1]; 153 | matrixObj.m[1][3] = matPose[3 * 4 + 2]; 154 | 155 | return matrixObj; 156 | } 157 | 158 | Matrix4 GetHMDMatrixPoseEye(vr::Hmd_Eye nEye) 159 | { 160 | if (!vrSystem) 161 | return Matrix4(); 162 | 163 | vr::HmdMatrix34_t matEyeRight = vrSystem->GetEyeToHeadTransform(nEye); 164 | 165 | Matrix4 matrixObj = ConvertSteamVRMatrixToMatrix4(matEyeRight); 166 | 167 | return matrixObj.invert(); 168 | } 169 | 170 | Matrix3 GetRotationMatrix(Matrix4& matrix) 171 | { 172 | return Matrix3( 173 | matrix[0], matrix[1], matrix[2], 174 | matrix[4], matrix[5], matrix[6], 175 | matrix[8], matrix[9], matrix[10] 176 | ); 177 | } 178 | 179 | Vector3 GetVector3(Vector4& v) 180 | { 181 | return Vector3(v.x, v.y, v.z); 182 | } 183 | }; 184 | 185 | -------------------------------------------------------------------------------- /HaloCEVR/VR/VREmulator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IVR.h" 3 | #include 4 | #include 5 | 6 | class VREmulator : public IVR 7 | { 8 | public: 9 | // Start Interface IVR 10 | void Init(); 11 | void OnGameFinishInit(); 12 | void Shutdown(); 13 | void UpdatePoses(); 14 | void PreDrawFrame(struct Renderer* renderer, float deltaTime); 15 | void PostDrawFrame(struct Renderer* renderer, float deltaTime); 16 | 17 | void UpdateCameraFrustum(struct CameraFrustum* frustum, int eye); 18 | 19 | int GetViewWidth() { return 1400; } 20 | int GetViewHeight() { return 1400; } 21 | float GetViewWidthStretch() { return 1.0f; } 22 | float GetViewHeightStretch() { return 1.0f; } 23 | float GetAspect() { return 1.0f; } 24 | int GetScopeWidth() { return 800; } 25 | int GetScopeHeight() { return 600; } 26 | void Recentre() {}; 27 | void SetLocationOffset(Vector3 newOffset) {} 28 | Vector3 GetLocationOffset() { return Vector3(0.0f, 0.0f, 0.0f); } 29 | void SetYawOffset(float newOffset) {} 30 | float GetYawOffset() { return 0.0f; } 31 | Matrix4 GetHMDTransform(bool bRenderPose = false) { return Matrix4(); } 32 | Matrix4 GetControllerTransform(ControllerRole role, bool bRenderPose = false); 33 | Matrix4 GetRawControllerTransform(ControllerRole role, bool bRenderPose = false); 34 | Matrix4 GetControllerBoneTransform(ControllerRole role, int bone, bool bRenderPose = false); 35 | Vector3 GetControllerVelocity(ControllerRole role, bool bRenderPose = false); 36 | bool TryGetControllerFacing(ControllerRole role, Vector3& outDirection); 37 | struct IDirect3DSurface9* GetRenderSurface(int eye); 38 | struct IDirect3DTexture9* GetRenderTexture(int eye); 39 | struct IDirect3DSurface9* GetUISurface(); 40 | struct IDirect3DSurface9* GetCrosshairSurface(); 41 | struct IDirect3DSurface9* GetScopeSurface(); 42 | struct IDirect3DTexture9* GetScopeTexture(); 43 | void SetMouseVisibility(bool bIsVisible) {} 44 | void SetCrosshairTransform(class Matrix4& newTransform); 45 | void UpdateInputs(); 46 | InputBindingID RegisterBoolInput(std::string set, std::string action); 47 | InputBindingID RegisterVector2Input(std::string set, std::string action); 48 | bool GetBoolInput(InputBindingID id); 49 | bool GetBoolInput(InputBindingID id, bool& bHasChanged); 50 | Vector2 GetVector2Input(InputBindingID id); 51 | Vector2 GetMousePos() { return Vector2(0.0f, 0.0f); } 52 | bool GetMouseDown() { return false; } 53 | void ShowKeyboard(const std::string& textBuffer); 54 | bool IsKeyboardVisible(); 55 | void HideKeyboard(); 56 | std::string GetKeyboardInput(); 57 | std::string GetDeviceName(); 58 | // End Interface IVR 59 | 60 | protected: 61 | void CreateSharedTarget(); 62 | 63 | void CreateTexAndSurface(int index, UINT width, UINT height, DWORD usage, D3DFORMAT format); 64 | 65 | void DrawEye(struct Renderer* renderer, float deltaTime, int eye); 66 | 67 | HWND hWnd; 68 | struct IDirect3DDevice9* mirrorDevice = nullptr; 69 | 70 | struct IDirect3DSurface9* uiSurface = nullptr; 71 | struct IDirect3DTexture9* uiTexture = nullptr; 72 | struct IDirect3DSurface9* crosshairSurface = nullptr; 73 | struct IDirect3DTexture9* crosshairTexture = nullptr; 74 | struct IDirect3DSurface9* scopeSurface = nullptr; 75 | struct IDirect3DTexture9* scopeTexture = nullptr; 76 | struct IDirect3DSurface9* eyeSurface_Game[2][2]; 77 | struct IDirect3DSurface9* eyeSurface_VR[2][2]; 78 | 79 | struct IDirect3DTexture9* eyeTexture_Game[2][2]; 80 | struct IDirect3DTexture9* eyeTexture_VR[2][2]; 81 | 82 | struct Binding 83 | { 84 | std::string bindingName; 85 | int virtualKey = 0; 86 | bool bHasChanged = false; 87 | bool bPressed = false; 88 | }; 89 | 90 | Binding bindings[13] = { 91 | {"Jump", VK_SPACE}, 92 | {"SwitchGrenades", 'G'}, 93 | {"Interact", 'E'}, 94 | {"SwitchWeapons", VK_TAB}, 95 | {"Melee", 'Q'}, 96 | {"Flashlight", 'F'}, 97 | {"Grenade", VK_RBUTTON}, 98 | {"Fire", VK_LBUTTON}, 99 | {"MenuBack", 'P'}, // Intentionally weird binding because we don't override this in the same way and it would conflict 100 | {"Crouch", VK_LCONTROL}, 101 | {"Zoom", 'Z'}, 102 | {"Reload", 'R'}, 103 | {"EMU_MoveHandSwap", 'H'} 104 | }; 105 | 106 | struct AxisBinding 107 | { 108 | int virtualKey = 0; 109 | int scale = 0; 110 | int axisId = 0; 111 | }; 112 | 113 | struct Axis2D 114 | { 115 | std::string axisName; 116 | int indexX = 0; 117 | int indexY = 0; 118 | }; 119 | 120 | float axes1D[6] = { 121 | 0.0f, 122 | 0.0f, 123 | 0.0f, 124 | 0.0f, 125 | 0.0f 126 | }; 127 | 128 | Axis2D axes2D[3] = 129 | { 130 | {"Move", 0, 1}, 131 | {"EMU_MoveHandFlat", 2, 3}, 132 | {"EMU_MoveHandVert", 4, 5} 133 | }; 134 | 135 | AxisBinding axisBindings[10] = 136 | { 137 | {'W', 1, 1}, 138 | {'S', -1, 1}, 139 | {'A', -1, 0}, 140 | {'D', 1, 0}, 141 | {'I', 1, 3}, 142 | {'K', -1, 3}, 143 | {'J', -1, 2}, 144 | {'L', 1, 2}, 145 | {'U', -1, 4}, 146 | {'O', 1, 4}, 147 | }; 148 | 149 | InputBindingID inputMoveHandFlat = 0; 150 | InputBindingID inputMoveHandVert = 0; 151 | InputBindingID inputMoveHandSwap = 0; 152 | bool bMoveHand = true; 153 | 154 | Vector3 mainHandOffset; 155 | Vector3 mainHandRot; 156 | 157 | bool bKeyboardActive = false; 158 | std::string keyboardBuffer; 159 | bool keystate[128]; 160 | }; 161 | 162 | -------------------------------------------------------------------------------- /HaloCEVR/WeaponHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Maths/Vectors.h" 3 | #include "Maths/Matrices.h" 4 | #include "Helpers/Objects.h" 5 | #define DRAW_DEBUG_AIM 0 6 | 7 | enum class ScopedWeaponType 8 | { 9 | Unknown, 10 | Pistol, 11 | Rocket, 12 | Sniper 13 | }; 14 | 15 | class WeaponHandler 16 | { 17 | public: 18 | void UpdateViewModel(struct HaloID& id, struct Vector3* pos, struct Vector3* facing, struct Vector3* up, struct TransformQuat* boneTransforms, struct Transform* outBoneTransforms); 19 | void PreFireWeapon(HaloID& weaponID, short param2); 20 | void PostFireWeapon(HaloID& weaponID, short param2); 21 | void PreThrowGrenade(HaloID& playerID); 22 | void PostThrowGrenade(HaloID& playerID); 23 | 24 | bool GetLocalWeaponAim(Vector3& outPosition, Vector3& outAim, Vector3& upDir) const; 25 | bool GetWorldWeaponAim(Vector3& outPosition, Vector3& outAim, Vector3& upDir) const; 26 | bool GetLocalWeaponScope(Vector3& outPosition, Vector3& outAim, Vector3& upDir) const; 27 | bool GetWorldWeaponScope(Vector3& outPosition, Vector3& outAim, Vector3& upDir) const; 28 | 29 | bool IsSniperScope() const; 30 | 31 | Vector3 localOffset; 32 | Vector3 localRotation; 33 | 34 | protected: 35 | void RelocatePlayer(HaloID& PlayerID); 36 | 37 | inline void CalculateBoneTransform(int boneIndex, struct Bone* boneArray, struct Transform& root, struct TransformQuat* boneTransforms, struct Transform& outTransform) const; 38 | inline void CalculateHandTransform(Vector3* pos, Matrix4& handTransform) const; 39 | inline void CreateEndCap(int boneIndex, const struct Bone& currentBone, struct Transform* outBoneTransforms) const; 40 | inline void MoveBoneToTransform(int boneIndex, const class Matrix4& newTransform, struct Transform* realTransforms, struct Transform* outBoneTransforms) const; 41 | inline void UpdateCache(struct HaloID& id, struct AssetData_ModelAnimations* animationData); 42 | 43 | inline void TransformToMatrix4(struct Transform& inTransform, class Matrix4& outMatrix) const; 44 | 45 | inline Vector3 GetScopeLocation(ScopedWeaponType Type) const; 46 | 47 | Matrix4 GetDominantHandTransform() const; 48 | 49 | struct ViewModelCache 50 | { 51 | HaloID currentAsset{ 0, 0 }; 52 | int leftWristIndex = -1; 53 | int rightWristIndex = -1; 54 | int gunIndex = -1; 55 | int displayIndex = -1; 56 | Vector3 cookedFireOffset; 57 | Matrix3 cookedFireRotation; 58 | Vector3 fireOffset; 59 | Vector3 gunOffset; 60 | Matrix3 fireRotation; 61 | ScopedWeaponType scopeType = ScopedWeaponType::Unknown; 62 | } cachedViewModel; 63 | 64 | UnitDynamicObject* weaponFiredPlayer = nullptr; 65 | Vector3 realPlayerPosition; 66 | Vector3 realPlayerAim; 67 | 68 | // Debug stuff for checking where bullets are coming from/going 69 | #if DRAW_DEBUG_AIM 70 | mutable Vector3 lastFireLocation; 71 | mutable Vector3 lastFireAim; 72 | #endif 73 | }; 74 | 75 | -------------------------------------------------------------------------------- /HaloCEVR/cpp.hint: -------------------------------------------------------------------------------- 1 | // Hint files help the Visual Studio IDE interpret Visual C++ identifiers 2 | // such as names of functions and macros. 3 | // For more information see https://go.microsoft.com/fwlink/?linkid=865984 4 | #define DEFINE_HOOK(Name, __VA_ARGS__) DEFINE_HOOK_FULL(Name, void, __VA_ARGS__) 5 | -------------------------------------------------------------------------------- /HaloCEVR/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #define NOMINMAX 3 | #include 4 | #include 5 | #include "Logger.h" 6 | #include "Game.h" 7 | #include "DirectXWrappers/IDirect3D9ExWrapper.h" 8 | 9 | #pragma comment(lib, "d3d9.lib") 10 | 11 | typedef IDirect3D9* (WINAPI *LPD3D_Direct3DCreate9)(UINT nSDKVersion); 12 | typedef HRESULT (WINAPI *LPD3D_Direct3DCreate9Ex)(UINT nSDKVersion, IDirect3D9Ex**); 13 | typedef void(WINAPI* LPD3D_Direct3DShaderValidatorCreate9)(void); 14 | 15 | bool bHasInit = false; 16 | HMODULE dllHandle; 17 | LPD3D_Direct3DCreate9 fnDirect3DCreate9 = nullptr; 18 | LPD3D_Direct3DCreate9Ex fnDirect3DCreate9Ex = nullptr; 19 | 20 | Logger Logger::log("VR/inject.log"); 21 | Logger::LoggerAlert Logger::err(&Logger::log); 22 | Game Game::instance; 23 | 24 | BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 25 | { 26 | switch (ul_reason_for_call) 27 | { 28 | case DLL_PROCESS_ATTACH: 29 | Logger::log << "[DLL] HaloCEVR attached" << std::endl; 30 | break; 31 | case DLL_THREAD_ATTACH: 32 | case DLL_THREAD_DETACH: 33 | break; 34 | case DLL_PROCESS_DETACH: 35 | Game::instance.Shutdown(); 36 | bHasInit = false; 37 | break; 38 | } 39 | return TRUE; 40 | } 41 | 42 | //==== DLL proxying stuff below ====// 43 | 44 | bool LoadRealDLL() 45 | { 46 | if (bHasInit) 47 | { 48 | Logger::log << "[DLL] Multiple calls to LoadRealDLL, returning existing handle: " << dllHandle << std::endl; 49 | return dllHandle != NULL; 50 | } 51 | bHasInit = true; 52 | Game::instance.Init(); 53 | 54 | if (Game::instance.c_d3d9Path->Value() != "") 55 | { 56 | dllHandle = LoadLibraryA(Game::instance.c_d3d9Path->Value().c_str()); 57 | 58 | if (dllHandle) 59 | { 60 | Logger::log << "[DLL] Loading real DirectX9 runtime from " << Game::instance.c_d3d9Path->Value() << std::endl; 61 | } 62 | else 63 | { 64 | Logger::log << "[DLL] Could not load real Directx9 runtime from '" << Game::instance.c_d3d9Path->Value() << "'. Falling back to System32's version" << std::endl; 65 | } 66 | } 67 | 68 | if (!dllHandle) 69 | { 70 | char buffer[MAX_PATH + 1]; 71 | 72 | GetSystemDirectoryA(buffer, sizeof(buffer)); 73 | buffer[MAX_PATH] = 0; 74 | std::string dllFileName = buffer; 75 | dllFileName += "\\d3d9.dll"; 76 | 77 | Logger::log << "[DLL] Loading real DirectX9 runtime from " << dllFileName << std::endl; 78 | 79 | dllHandle = LoadLibraryA(dllFileName.c_str()); 80 | } 81 | 82 | if (!dllHandle) 83 | { 84 | Logger::err << "Could not load the real d3d9.dll file from the system directory" << std::endl; 85 | return false; 86 | } 87 | 88 | fnDirect3DCreate9 = reinterpret_cast(GetProcAddress(dllHandle, "Direct3DCreate9")); 89 | fnDirect3DCreate9Ex = reinterpret_cast(GetProcAddress(dllHandle, "Direct3DCreate9Ex")); 90 | 91 | if (!fnDirect3DCreate9 || !fnDirect3DCreate9Ex) 92 | { 93 | FreeLibrary(dllHandle); 94 | dllHandle = nullptr; 95 | Logger::err << "Could not get create functions from real d3d9.dll" << std::endl; 96 | return false; 97 | } 98 | 99 | Logger::log << "[DLL] Loaded real d3d9.dll" << std::endl; 100 | return true; 101 | } 102 | 103 | #pragma comment(linker, "/export:Direct3DCreate9Ex=?H_Direct3DCreate9Ex@@YGJIPAPAUIDirect3D9Ex@@@Z") 104 | HRESULT WINAPI H_Direct3DCreate9Ex(UINT nSDKVersion, IDirect3D9Ex** outDirect3D9Ex) 105 | { 106 | Logger::log << "[DLL] Intercepting call to Direct3dCreate9Ex" << std::endl; 107 | if (!LoadRealDLL()) 108 | { 109 | Logger::err << "[DLL] Failed to load real d3d9.dll" << std::endl; 110 | return D3DERR_NOTAVAILABLE; 111 | } 112 | 113 | IDirect3D9Ex* RealD3D = nullptr; 114 | 115 | HRESULT result = fnDirect3DCreate9Ex(nSDKVersion, &RealD3D); 116 | 117 | if (FAILED(result)) 118 | { 119 | Logger::err << "Call to Direct3DCreate9Ex Failed: " << result << std::endl; 120 | return result; 121 | } 122 | 123 | *outDirect3D9Ex = new IDirect3D9ExWrapper(RealD3D); 124 | 125 | return S_OK; 126 | } 127 | 128 | #pragma comment(linker, "/export:Direct3DCreate9=?H_Direct3DCreate9@@YGPAUIDirect3D9@@I@Z") 129 | IDirect3D9* WINAPI H_Direct3DCreate9(UINT nSDKVersion) 130 | { 131 | Logger::log << "[DLL] Intercepting call to Direct3dCreate9" << std::endl; 132 | if (!LoadRealDLL()) 133 | { 134 | Logger::err << "[DLL] Failed to load real d3d9.dll" << std::endl; 135 | return nullptr; 136 | } 137 | 138 | IDirect3D9Ex* d3dEx; 139 | HRESULT result = H_Direct3DCreate9Ex(nSDKVersion, &d3dEx); 140 | 141 | if (SUCCEEDED(result)) 142 | { 143 | int numAdapters = d3dEx->GetAdapterCount(); 144 | Logger::log << "Adapters: " << numAdapters << std::endl; 145 | 146 | D3DDISPLAYMODE outMode; 147 | 148 | for (int i = 0; i < numAdapters; i++) 149 | { 150 | Logger::log << "Adapter " << i << ": " << (uint32_t) d3dEx->GetAdapterDisplayMode(i, &outMode) << " " << outMode.Width << "x" << outMode.Height << " " << (outMode.Format) << std::endl; 151 | } 152 | } 153 | 154 | return d3dEx; 155 | } 156 | -------------------------------------------------------------------------------- /ThirdParty/OpenVR/lib/openvr_api.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LivingFray/HaloCEVR/0b415fc9ea8b9c4deb97faaace00d60d8c6147d3/ThirdParty/OpenVR/lib/openvr_api.lib -------------------------------------------------------------------------------- /initinstall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Configuring halo install directory for HaloCEVR... 3 | set "DEFAULT_EXE=Halo.exe" 4 | set /p EXE_DIR="Enter Halo install folder (e.g. C:\Program Files (x86)\Halo Combat Evolved): " 5 | set /p EXE_NAME="Enter Halo executable name (default: %DEFAULT_EXE%): " 6 | if "%EXE_NAME%"=="" set "EXE_NAME=%DEFAULT_EXE%" 7 | 8 | echo Setting environment variables... 9 | setx HALOCEVR_DIR %EXE_DIR% 10 | setx HALOCEVR_EXE %EXE_NAME% 11 | 12 | echo Executable directory: %HALOCEVR_DIR% 13 | echo Executable name: %HALOCEVR_EXE% 14 | 15 | set "FULL_PATH=%HALOCEVR_DIR%\%HALOCEVR_EXE%" 16 | 17 | if exist "%FULL_PATH%" ( 18 | echo %FULL_PATH% is a valid halo installation. Builds should automatically launch halo once compiled. 19 | ) else ( 20 | echo Error: Can't find %FULL_PATH%! Builds will produce a valid d3d9.dll file, but will fail attempting to launch halo. 21 | ) 22 | 23 | pause -------------------------------------------------------------------------------- /makerelease.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: Remove old zip 3 | del HaloCEVR.zip 4 | :: Copy bindings/manifest files into correct subfolder 5 | xcopy "./Extras/Bindings" "./Output/VR/OpenVR/" /E /I 6 | :: Copy fonts into correct subfolder 7 | xcopy "./Extras/Fonts" "./Output/VR/Fonts/" /E /I 8 | :: Copy images into correct subfolder 9 | xcopy "./Extras/Images" "./Output/VR/Images/" /E /I 10 | :: Remove any dev files used to generate the bindings 11 | del ".\Output\VR\OpenVR\*.py" 12 | :: copy openvr_api.dll to top level 13 | xcopy "./ThirdParty/OpenVR/bin/openvr_api.dll" "./Output/" /F 14 | :: Copy .dlls to top level 15 | robocopy "./Release" "./Output" "*.dll" 16 | :: Zip everything 17 | tar -acf HaloCEVR.zip -C Output *.* 18 | :: Remove temp directory 19 | rmdir /s /q Output --------------------------------------------------------------------------------