├── .gitattributes
├── .gitignore
├── DivaHook
├── DivaHook.vcxproj
├── DivaHook.vcxproj.filters
├── rom
│ ├── components.ini
│ ├── keyconfig.ini
│ └── playerdata.ini
└── src
│ ├── Components
│ ├── CameraController.cpp
│ ├── CameraController.h
│ ├── ComponentsManager.cpp
│ ├── ComponentsManager.h
│ ├── CustomPlayerData.h
│ ├── DebugComponent.cpp
│ ├── DebugComponent.h
│ ├── EmulatorComponent.cpp
│ ├── EmulatorComponent.h
│ ├── FastLoader.cpp
│ ├── FastLoader.h
│ ├── FrameRateManager.cpp
│ ├── FrameRateManager.h
│ ├── GameState.h
│ ├── Input
│ │ ├── InputBufferType.h
│ │ ├── InputEmulator.cpp
│ │ ├── InputEmulator.h
│ │ ├── InputState.cpp
│ │ ├── InputState.h
│ │ ├── JvsButtons.h
│ │ ├── TouchPanelEmulator.cpp
│ │ ├── TouchPanelEmulator.h
│ │ ├── TouchPanelState.h
│ │ ├── TouchSliderEmulator.cpp
│ │ ├── TouchSliderEmulator.h
│ │ ├── TouchSliderState.cpp
│ │ └── TouchSliderState.h
│ ├── PlayerData.h
│ ├── PlayerDataManager.cpp
│ ├── PlayerDataManager.h
│ ├── StageManager.cpp
│ ├── StageManager.h
│ ├── SysTimer.cpp
│ └── SysTimer.h
│ ├── Constants.h
│ ├── FileSystem
│ ├── ConfigFile.cpp
│ ├── ConfigFile.h
│ ├── TextFile.cpp
│ └── TextFile.h
│ ├── Input
│ ├── Bindings
│ │ ├── Binding.cpp
│ │ ├── Binding.h
│ │ ├── Ds4Binding.cpp
│ │ ├── Ds4Binding.h
│ │ ├── IInputBinding.h
│ │ ├── KeyboardBinding.cpp
│ │ ├── KeyboardBinding.h
│ │ ├── MouseBinding.cpp
│ │ └── MouseBinding.h
│ ├── DirectInput
│ │ ├── Controller.cpp
│ │ ├── Controller.h
│ │ ├── DirectInput.cpp
│ │ ├── DirectInput.h
│ │ ├── DirectInputDevice.cpp
│ │ ├── DirectInputDevice.h
│ │ ├── DirectInputMouse.cpp
│ │ ├── DirectInputMouse.h
│ │ └── Ds4
│ │ │ ├── Ds4Button.h
│ │ │ ├── Ds4State.cpp
│ │ │ ├── Ds4State.h
│ │ │ ├── DualShock4.cpp
│ │ │ └── DualShock4.h
│ ├── IInputDevice.h
│ ├── KeyConfig
│ │ ├── Config.cpp
│ │ ├── Config.h
│ │ ├── KeyString.cpp
│ │ ├── KeyString.h
│ │ ├── KeyStringHash.cpp
│ │ └── KeyStringHash.h
│ ├── Keyboard
│ │ ├── Keyboard.cpp
│ │ ├── Keyboard.h
│ │ ├── KeyboardState.cpp
│ │ └── KeyboardState.h
│ └── Mouse
│ │ ├── Mouse.cpp
│ │ ├── Mouse.h
│ │ └── MouseState.h
│ ├── MainModule.cpp
│ ├── MainModule.h
│ ├── Utilities
│ ├── EnumBitwiseOperations.h
│ ├── Math.cpp
│ ├── Math.h
│ ├── Operations.cpp
│ ├── Operations.h
│ ├── Stopwatch.cpp
│ ├── Stopwatch.h
│ ├── Vec2.cpp
│ ├── Vec2.h
│ ├── Vec3.cpp
│ └── Vec3.h
│ ├── dllmain.cpp
│ └── targetver.h
├── LICENSE
├── Prepatch
├── Prepatch.vcxproj
├── Prepatch.vcxproj.filters
├── rom
│ └── patch.txt
└── src
│ ├── Patch
│ ├── Patch.cpp
│ ├── Patch.h
│ ├── PatchData.cpp
│ ├── PatchData.h
│ ├── Patcher.cpp
│ └── Patcher.h
│ ├── StringOperations
│ ├── Operations.cpp
│ └── Operations.h
│ └── main.cpp
├── README.md
├── TotallyLegitArcadeController.sln
└── TotallyLegitArcadeController
├── TotallyLegitArcadeController.filters
├── TotallyLegitArcadeController.vcxproj
└── src
├── Injection
├── DllInjector.cpp
└── DllInjector.h
└── main.cpp
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Source files
2 | *.c text diff=cpp
3 | *.cc text diff=cpp
4 | *.cxx text diff=cpp
5 | *.cpp text diff=cpp
6 | *.c++ text diff=cpp
7 | *.hpp text diff=cpp
8 | *.h text diff=cpp
9 | *.h++ text diff=cpp
10 | *.hh text diff=cpp
11 |
12 | # Compiled Object files
13 | *.slo binary
14 | *.lo binary
15 | *.o binary
16 | *.obj binary
17 |
18 | # Precompiled Headers
19 | *.gch binary
20 | *.pch binary
21 |
--------------------------------------------------------------------------------
/.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 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | bin/
24 | bin-int/
25 | [Bb]in/
26 | [Oo]bj/
27 | [Ll]og/
28 |
29 | # Visual Studio 2015/2017 cache/options directory
30 | .vs/
31 | # Uncomment if you have tasks that create the project's static files in wwwroot
32 | #wwwroot/
33 |
34 | # Visual Studio 2017 auto generated files
35 | Generated\ Files/
36 |
37 | # MSTest test Results
38 | [Tt]est[Rr]esult*/
39 | [Bb]uild[Ll]og.*
40 |
41 | # NUNIT
42 | *.VisualState.xml
43 | TestResult.xml
44 |
45 | # Build Results of an ATL Project
46 | [Dd]ebugPS/
47 | [Rr]eleasePS/
48 | dlldata.c
49 |
50 | # Benchmark Results
51 | BenchmarkDotNet.Artifacts/
52 |
53 | # .NET Core
54 | project.lock.json
55 | project.fragment.lock.json
56 | artifacts/
57 | **/Properties/launchSettings.json
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_i.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *.log
83 | *.vspscc
84 | *.vssscc
85 | .builds
86 | *.pidb
87 | *.svclog
88 | *.scc
89 |
90 | # Chutzpah Test files
91 | _Chutzpah*
92 |
93 | # Visual C++ cache files
94 | ipch/
95 | *.aps
96 | *.ncb
97 | *.opendb
98 | *.opensdf
99 | *.sdf
100 | *.cachefile
101 | *.VC.db
102 | *.VC.VC.opendb
103 |
104 | # Visual Studio profiler
105 | *.psess
106 | *.vsp
107 | *.vspx
108 | *.sap
109 |
110 | # Visual Studio Trace Files
111 | *.e2e
112 |
113 | # TFS 2012 Local Workspace
114 | $tf/
115 |
116 | # Guidance Automation Toolkit
117 | *.gpState
118 |
119 | # ReSharper is a .NET coding add-in
120 | _ReSharper*/
121 | *.[Rr]e[Ss]harper
122 | *.DotSettings.user
123 |
124 | # JustCode is a .NET coding add-in
125 | .JustCode
126 |
127 | # TeamCity is a build add-in
128 | _TeamCity*
129 |
130 | # DotCover is a Code Coverage Tool
131 | *.dotCover
132 |
133 | # AxoCover is a Code Coverage Tool
134 | .axoCover/*
135 | !.axoCover/settings.json
136 |
137 | # Visual Studio code coverage results
138 | *.coverage
139 | *.coveragexml
140 |
141 | # NCrunch
142 | _NCrunch_*
143 | .*crunch*.local.xml
144 | nCrunchTemp_*
145 |
146 | # MightyMoose
147 | *.mm.*
148 | AutoTest.Net/
149 |
150 | # Web workbench (sass)
151 | .sass-cache/
152 |
153 | # Installshield output folder
154 | [Ee]xpress/
155 |
156 | # DocProject is a documentation generator add-in
157 | DocProject/buildhelp/
158 | DocProject/Help/*.HxT
159 | DocProject/Help/*.HxC
160 | DocProject/Help/*.hhc
161 | DocProject/Help/*.hhk
162 | DocProject/Help/*.hhp
163 | DocProject/Help/Html2
164 | DocProject/Help/html
165 |
166 | # Click-Once directory
167 | publish/
168 |
169 | # Publish Web Output
170 | *.[Pp]ublish.xml
171 | *.azurePubxml
172 | # Note: Comment the next line if you want to checkin your web deploy settings,
173 | # but database connection strings (with potential passwords) will be unencrypted
174 | *.pubxml
175 | *.publishproj
176 |
177 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
178 | # checkin your Azure Web App publish settings, but sensitive information contained
179 | # in these scripts will be unencrypted
180 | PublishScripts/
181 |
182 | # NuGet Packages
183 | *.nupkg
184 | # The packages folder can be ignored because of Package Restore
185 | **/[Pp]ackages/*
186 | # except build/, which is used as an MSBuild target.
187 | !**/[Pp]ackages/build/
188 | # Uncomment if necessary however generally it will be regenerated when needed
189 | #!**/[Pp]ackages/repositories.config
190 | # NuGet v3's project.json files produces more ignorable files
191 | *.nuget.props
192 | *.nuget.targets
193 |
194 | # Microsoft Azure Build Output
195 | csx/
196 | *.build.csdef
197 |
198 | # Microsoft Azure Emulator
199 | ecf/
200 | rcf/
201 |
202 | # Windows Store app package directories and files
203 | AppPackages/
204 | BundleArtifacts/
205 | Package.StoreAssociation.xml
206 | _pkginfo.txt
207 | *.appx
208 |
209 | # Visual Studio cache files
210 | # files ending in .cache can be ignored
211 | *.[Cc]ache
212 | # but keep track of directories ending in .cache
213 | !*.[Cc]ache/
214 |
215 | # Others
216 | ClientBin/
217 | ~$*
218 | *~
219 | *.dbmdl
220 | *.dbproj.schemaview
221 | *.jfm
222 | *.pfx
223 | *.publishsettings
224 | orleans.codegen.cs
225 |
226 | # Including strong name files can present a security risk
227 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
228 | #*.snk
229 |
230 | # Since there are multiple workflows, uncomment next line to ignore bower_components
231 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
232 | #bower_components/
233 |
234 | # RIA/Silverlight projects
235 | Generated_Code/
236 |
237 | # Backup & report files from converting an old project file
238 | # to a newer Visual Studio version. Backup files are not needed,
239 | # because we have git ;-)
240 | _UpgradeReport_Files/
241 | Backup*/
242 | UpgradeLog*.XML
243 | UpgradeLog*.htm
244 | ServiceFabricBackup/
245 | *.rptproj.bak
246 |
247 | # SQL Server files
248 | *.mdf
249 | *.ldf
250 | *.ndf
251 |
252 | # Business Intelligence projects
253 | *.rdl.data
254 | *.bim.layout
255 | *.bim_*.settings
256 | *.rptproj.rsuser
257 |
258 | # Microsoft Fakes
259 | FakesAssemblies/
260 |
261 | # GhostDoc plugin setting file
262 | *.GhostDoc.xml
263 |
264 | # Node.js Tools for Visual Studio
265 | .ntvs_analysis.dat
266 | node_modules/
267 |
268 | # Visual Studio 6 build log
269 | *.plg
270 |
271 | # Visual Studio 6 workspace options file
272 | *.opt
273 |
274 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
275 | *.vbw
276 |
277 | # Visual Studio LightSwitch build output
278 | **/*.HTMLClient/GeneratedArtifacts
279 | **/*.DesktopClient/GeneratedArtifacts
280 | **/*.DesktopClient/ModelManifest.xml
281 | **/*.Server/GeneratedArtifacts
282 | **/*.Server/ModelManifest.xml
283 | _Pvt_Extensions
284 |
285 | # Paket dependency manager
286 | .paket/paket.exe
287 | paket-files/
288 |
289 | # FAKE - F# Make
290 | .fake/
291 |
292 | # JetBrains Rider
293 | .idea/
294 | *.sln.iml
295 |
296 | # CodeRush
297 | .cr/
298 |
299 | # Python Tools for Visual Studio (PTVS)
300 | __pycache__/
301 | *.pyc
302 |
303 | # Cake - Uncomment if you are using it
304 | # tools/**
305 | # !tools/packages.config
306 |
307 | # Tabs Studio
308 | *.tss
309 |
310 | # Telerik's JustMock configuration file
311 | *.jmconfig
312 |
313 | # BizTalk build output
314 | *.btp.cs
315 | *.btm.cs
316 | *.odx.cs
317 | *.xsd.cs
318 |
319 | # OpenCover UI analysis results
320 | OpenCover/
321 |
322 | # Azure Stream Analytics local run output
323 | ASALocalRun/
324 |
325 | # MSBuild Binary and Structured Log
326 | *.binlog
327 |
328 | # NVidia Nsight GPU debugger configuration file
329 | *.nvuser
330 |
331 | # MFractors (Xamarin productivity tool) working folder
332 | .mfractor/
333 |
--------------------------------------------------------------------------------
/DivaHook/DivaHook.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | 15.0
15 | {69BCF67B-34D9-4424-A2A8-3A056E9D38A6}
16 | Win32Proj
17 | DivaHook
18 | 10.0.17763.0
19 |
20 |
21 |
22 | DynamicLibrary
23 | true
24 | v141
25 | Unicode
26 |
27 |
28 | DynamicLibrary
29 | false
30 | v141
31 | true
32 | Unicode
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | true
49 | divahook
50 | $(SolutionDir)bin\$(Platform)-$(Configuration)\
51 | $(SolutionDir)$(ProjectName)\bin-int\$(Platform)-$(Configuration)\
52 |
53 |
54 | false
55 | divahook
56 | $(SolutionDir)bin\$(Platform)-$(Configuration)\
57 | $(SolutionDir)$(ProjectName)\bin-int\$(Platform)-$(Configuration)\
58 |
59 |
60 |
61 | NotUsing
62 | Level3
63 | Disabled
64 | true
65 | WIN32;_DEBUG;DIVAHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
66 | true
67 |
68 |
69 | stdcpp17
70 |
71 |
72 | Windows
73 | true
74 | dinput8.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
75 |
76 |
77 |
78 |
79 | NotUsing
80 | Level3
81 | MaxSpeed
82 | true
83 | true
84 | true
85 | WIN32;NDEBUG;DIVAHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
86 | true
87 |
88 |
89 | stdcpp17
90 |
91 |
92 | Windows
93 | true
94 | true
95 | true
96 | dinput8.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
--------------------------------------------------------------------------------
/DivaHook/DivaHook.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;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 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | Header Files
38 |
39 |
40 | Header Files
41 |
42 |
43 | Header Files
44 |
45 |
46 | Header Files
47 |
48 |
49 | Header Files
50 |
51 |
52 | Header Files
53 |
54 |
55 | Header Files
56 |
57 |
58 | Header Files
59 |
60 |
61 | Header Files
62 |
63 |
64 | Header Files
65 |
66 |
67 | Header Files
68 |
69 |
70 | Header Files
71 |
72 |
73 | Header Files
74 |
75 |
76 | Header Files
77 |
78 |
79 | Header Files
80 |
81 |
82 | Header Files
83 |
84 |
85 | Header Files
86 |
87 |
88 | Header Files
89 |
90 |
91 | Header Files
92 |
93 |
94 | Header Files
95 |
96 |
97 | Header Files
98 |
99 |
100 | Header Files
101 |
102 |
103 | Header Files
104 |
105 |
106 | Header Files
107 |
108 |
109 | Header Files
110 |
111 |
112 | Header Files
113 |
114 |
115 | Header Files
116 |
117 |
118 | Header Files
119 |
120 |
121 | Header Files
122 |
123 |
124 | Header Files
125 |
126 |
127 | Header Files
128 |
129 |
130 | Header Files
131 |
132 |
133 | Header Files
134 |
135 |
136 | Header Files
137 |
138 |
139 | Header Files
140 |
141 |
142 | Header Files
143 |
144 |
145 | Header Files
146 |
147 |
148 | Header Files
149 |
150 |
151 | Header Files
152 |
153 |
154 | Header Files
155 |
156 |
157 | Header Files
158 |
159 |
160 | Header Files
161 |
162 |
163 | Header Files
164 |
165 |
166 | Header Files
167 |
168 |
169 |
170 |
171 | Source Files
172 |
173 |
174 | Source Files
175 |
176 |
177 | Source Files
178 |
179 |
180 | Source Files
181 |
182 |
183 | Source Files
184 |
185 |
186 | Source Files
187 |
188 |
189 | Source Files
190 |
191 |
192 | Source Files
193 |
194 |
195 | Source Files
196 |
197 |
198 | Source Files
199 |
200 |
201 | Source Files
202 |
203 |
204 | Source Files
205 |
206 |
207 | Source Files
208 |
209 |
210 | Source Files
211 |
212 |
213 | Source Files
214 |
215 |
216 | Source Files
217 |
218 |
219 | Source Files
220 |
221 |
222 | Source Files
223 |
224 |
225 | Source Files
226 |
227 |
228 | Source Files
229 |
230 |
231 | Source Files
232 |
233 |
234 | Source Files
235 |
236 |
237 | Source Files
238 |
239 |
240 | Source Files
241 |
242 |
243 | Source Files
244 |
245 |
246 | Source Files
247 |
248 |
249 | Source Files
250 |
251 |
252 | Source Files
253 |
254 |
255 | Source Files
256 |
257 |
258 | Source Files
259 |
260 |
261 | Source Files
262 |
263 |
264 | Source Files
265 |
266 |
267 | Source Files
268 |
269 |
270 | Source Files
271 |
272 |
273 | Source Files
274 |
275 |
276 | Source Files
277 |
278 |
279 | Source Files
280 |
281 |
282 | Source Files
283 |
284 |
285 | Source Files
286 |
287 |
288 | Source Files
289 |
290 |
291 |
292 |
293 |
294 |
--------------------------------------------------------------------------------
/DivaHook/rom/components.ini:
--------------------------------------------------------------------------------
1 | # components.ini
2 | # defines which components will be enabled
3 |
4 | # emulates game input through mouse and keyboard.
5 | # controls can be set inside the keyconfig.ini file.
6 | input_emulator = true
7 | touch_slider_emulator = true
8 | touch_panel_emulator = true
9 |
10 | # freezes the PV select timer at 39 seconds.
11 | sys_timer = true
12 |
13 | # loads user defined const values from the playerdata.ini config
14 | # and writes them to the game's PlayerData struct.
15 | player_data_manager = false
16 |
17 | # adjusts 2D and 3D animations to retain their original speed at different frame rates.
18 | # only use this component if you are running this game at higher than 60 FPS.
19 | frame_rate_manager = false
20 |
21 | # sets an unlimited per session play count for the normal game mode.
22 | # this means the player won't be sent back to the title screen after 2 plays.
23 | stage_manager = false
24 |
25 | # skip unnecessary DATA_INITIALIZE loading time, speed up SYSTEM_STARTUP and skip the startup WARNING message.
26 | # further improvements can be achieved by shortening the duration of the pv_999 script file as it's test loaded during the SYSTEM_STARTUP.
27 | fast_loader = true
28 |
29 | # allows for a user controllable camera which can be toggled using F3,
30 | # can be controlled using W/A/S/D to move, SPACE/CTRL to ascend/descend, Q/E to rotate, R/F to zoom in/out
31 | # and holding SHIFT/ALT to speed up or slow down these controls.
32 | camera_controller = false
33 |
34 | # lets the user change the current game state using the F4 - F8 keys, enable the dw_gui / DATA_TESTs
35 | # and speed up 2D animations / menu navigation by holding SHIFT + TAB.
36 | # enabling this component is not recommended for most users.
37 | debug_component = false
--------------------------------------------------------------------------------
/DivaHook/rom/keyconfig.ini:
--------------------------------------------------------------------------------
1 | # keyconfig.ini
2 | # defines the input_emulator key bindings
3 | # multiple keys are to be specified comma separated
4 |
5 | # Options:
6 |
7 | # allows the user to mouse wheel scroll through the PV selection list
8 | mouse_scroll_pv_selection = true
9 | # the interval it takes for the emulated slider touch points to move from one contact point to another.
10 | # in most cases this does not need editing.
11 | touch_slider_emulation_speed = 750.0
12 |
13 | # JVS Buttons:
14 | JVS_TEST = F1
15 | JVS_SERVICE = F2
16 |
17 | JVS_START = Enter, Ds4_Options
18 | JVS_TRIANGLE = W, I, Ds4_Triangle, Ds4_DPad_Up
19 | JVS_SQUARE = A, J, Ds4_Square, Ds4_DPad_Left
20 | JVS_CROSS = S, K, Ds4_Cross, Ds4_DPad_Down
21 | JVS_CIRCLE = D, L, Ds4_Circle, Ds4_DPad_Right
22 |
23 | JVS_LEFT = Q, U, Up, Ds4_L1, Ds4_L_Stick_Up, Ds4_R_Stick_Up
24 | JVS_RIGHT = E, O, Down, Ds4_R1, Ds4_L_Stick_Down, Ds4_R_Stick_Down
25 |
26 | # Touch Slider:
27 | LEFT_SIDE_SLIDE_LEFT = Q, Ds4_L_Stick_Left
28 | LEFT_SIDE_SLIDE_RIGHT = E, Ds4_L_Stick_Right
29 |
30 | RIGHT_SIDE_SLIDE_LEFT = U, Ds4_R_Stick_Left
31 | RIGHT_SIDE_SLIDE_RIGHT = O, Ds4_R_Stick_Right
32 |
33 | # --- KEYBOARD KEY NAMES: ---
34 |
35 | # - Standard Keys
36 | # uppercase "A" to "Z", "0" to "9"
37 |
38 | # - NumPad Keys
39 | # "NumPad0" to "NumPad9"
40 | # "Plus", "Minus", "Divide", "Multiply"
41 |
42 | # - Function Keys
43 | # "F1" to "F24"
44 |
45 | # - Shift Keys
46 | # "LeftShift", "RightShift"
47 |
48 | # - Control Keys
49 | # "LeftControl", "RightControl"
50 |
51 | # - Arrow Keys
52 | # "Up", "Down", "Left", "Right"
53 |
54 | # - Special Keys
55 | # "Enter", "Tab", "Backspace", "Insert", "Delete", "Home", "End", "PageUp", "PageDown", "Escape", "Comma", "Period", "Slash"
56 |
57 | # --- DUALSHOCK 4 BUTTON NAMES: ---
58 |
59 | # - Face Buttons
60 | # "Ds4_Square", "Ds4_Cross", "Ds4_Circle", "Ds4_Triangle"
61 |
62 | # - Standard Buttons
63 | # "Ds4_Share", "Ds4_Options", "Ds4_PS", "Ds4_Touch", "Ds4_L1", "Ds4_R1"
64 |
65 | # - D-Pad Directions
66 | # "Ds4_DPad_Up", "Ds4_DPad_Right", "Ds4_DPad_Down", "Ds4_DPad_Left"
67 |
68 | # - Trigger Buttons
69 | # "Ds4_L_Trigger", "Ds4_R_Trigger"
70 |
71 | # - Left Joystick
72 | # "Ds4_L_Stick_Up", "Ds4_L_Stick_Right", "Ds4_L_Stick_Down", "Ds4_L_Stick_Left", "Ds4_L3"
73 |
74 | # - Right Joystick
75 | # "Ds4_R_Stick_Up", "Ds4_R_Stick_Right", "Ds4_R_Stick_Down", "Ds4_R_Stick_Left", "Ds4_R3"
--------------------------------------------------------------------------------
/DivaHook/rom/playerdata.ini:
--------------------------------------------------------------------------------
1 | # playerdata.ini
2 | # defines constant values to be loaded into the PlayerData struct
3 | # this file has to be encoded using utf-8
4 |
5 | player_name = NO-NAME
6 |
7 | # IDs defined in rom/gm_plate_tbl.farc/gm_plate_id.bin
8 | level_plate_id = 0
9 |
10 | # IDs same as gam_skin%03d
11 | skin_equip = 0
12 |
13 | # IDs defined in rom/gm_btn_se_tbl.farc/gm_btn_se_id.bin
14 | btn_se_equip = -1
15 |
16 | # IDs defined in rom/gm_slide_se_tbl.farc/gm_slide_se_id.bin
17 | slide_se_equip = -1
18 |
19 | # IDs defined in rom/gm_chainslide_se_tbl.farc/gm_chainslide_se_id.bin
20 | chainslide_se_equip = -1
--------------------------------------------------------------------------------
/DivaHook/src/Components/CameraController.cpp:
--------------------------------------------------------------------------------
1 | #include "CameraController.h"
2 | #include
3 | #include "Input/InputState.h"
4 | #include "ComponentsManager.h"
5 | #include "../MainModule.h"
6 | #include "../Input/Mouse/Mouse.h"
7 | #include "../Input/Keyboard/Keyboard.h"
8 | #include "../Input/Bindings/KeyboardBinding.h"
9 |
10 | #define GLUT_CURSOR_RIGHT_ARROW 0x0000
11 | #define GLUT_CURSOR_NONE 0x0065
12 |
13 | using namespace DivaHook::Input;
14 | using namespace DivaHook::Utilities;
15 |
16 | namespace DivaHook::Components
17 | {
18 | CameraController::CameraController()
19 | {
20 | }
21 |
22 | CameraController::~CameraController()
23 | {
24 | delete ToggleBinding;
25 |
26 | delete ForwardBinding;
27 | delete BackwardBinding;
28 | delete LeftBinding;
29 | delete RightBinding;
30 |
31 | delete UpBinding;
32 | delete DownBinding;
33 | delete ClockwiseBinding;
34 | delete CounterClockwiseBinding;
35 | delete ZoomInBinding;
36 | delete ZoomOutBinding;
37 |
38 | delete FastBinding;
39 | delete SlowBinding;
40 | }
41 |
42 | const char* CameraController::GetDisplayName()
43 | {
44 | return "camera_controller";
45 | }
46 |
47 | void CameraController::Initialize(ComponentsManager* manager)
48 | {
49 | componentsManager = manager;
50 |
51 | printf("CameraController::Initialize(): Initialized\n");
52 |
53 | for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
54 | {
55 | DWORD oldProtect;
56 | VirtualProtect((void*)cameraSetterAddresses[i], sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
57 |
58 | originalSetterBytes[i] = *(uint8_t*)cameraSetterAddresses[i];
59 | }
60 |
61 | ToggleBinding = new Binding();
62 | ToggleBinding->AddBinding(new KeyboardBinding(VK_F3));
63 |
64 | ForwardBinding = new Binding();
65 | ForwardBinding->AddBinding(new KeyboardBinding('W'));
66 | BackwardBinding = new Binding();
67 | BackwardBinding->AddBinding(new KeyboardBinding('S'));
68 | LeftBinding = new Binding();
69 | LeftBinding->AddBinding(new KeyboardBinding('A'));
70 | RightBinding = new Binding();
71 | RightBinding->AddBinding(new KeyboardBinding('D'));
72 |
73 | UpBinding = new Binding();
74 | UpBinding->AddBinding(new KeyboardBinding(VK_SPACE));
75 | DownBinding = new Binding();
76 | DownBinding->AddBinding(new KeyboardBinding(VK_CONTROL));
77 |
78 | ClockwiseBinding = new Binding();
79 | ClockwiseBinding->AddBinding(new KeyboardBinding('E'));
80 | CounterClockwiseBinding = new Binding();
81 | CounterClockwiseBinding->AddBinding(new KeyboardBinding('Q'));
82 |
83 | ZoomInBinding = new Binding();
84 | ZoomInBinding->AddBinding(new KeyboardBinding('R'));
85 | ZoomOutBinding = new Binding();
86 | ZoomOutBinding->AddBinding(new KeyboardBinding('F'));
87 |
88 | FastBinding = new Binding();
89 | FastBinding->AddBinding(new KeyboardBinding(VK_SHIFT));
90 | SlowBinding = new Binding();
91 | SlowBinding->AddBinding(new KeyboardBinding(VK_MENU));
92 |
93 | camera = (Camera*)CAMERA_ADDRESS;
94 | }
95 |
96 | void CameraController::Update()
97 | {
98 | return;
99 | }
100 |
101 | void CameraController::UpdateInput()
102 | {
103 | if (ToggleBinding->AnyTapped())
104 | {
105 | SetControls(!GetIsEnabled());
106 | return;
107 | }
108 |
109 | if (!GetIsEnabled())
110 | return;
111 |
112 | auto keyboard = Keyboard::GetInstance();
113 | auto mouse = Mouse::GetInstance();
114 |
115 | bool forward = ForwardBinding->AnyDown();
116 | bool backward = BackwardBinding->AnyDown();
117 | bool left = LeftBinding->AnyDown();
118 | bool right = RightBinding->AnyDown();
119 |
120 | bool up = UpBinding->AnyDown();
121 | bool down = DownBinding->AnyDown();
122 |
123 | bool fast = FastBinding->AnyDown();
124 | bool slow = SlowBinding->AnyDown();
125 |
126 | bool clockwise = ClockwiseBinding->AnyDown();
127 | bool counterclockwise = CounterClockwiseBinding->AnyDown();
128 |
129 | bool zoomin = ZoomInBinding->AnyDown();
130 | bool zoomout = ZoomOutBinding->AnyDown();
131 |
132 | float speed = GetElapsedTime() * (fast ? fastSpeed : slow ? slowSpeed : normalSpeed);
133 |
134 | if (forward ^ backward)
135 | camera->Position += PointFromAngle(verticalRotation + (forward ? +0.0f : -180.0f), speed);
136 |
137 | if (left ^ right)
138 | camera->Position += PointFromAngle(verticalRotation + (right ? +90.0f : -90.0f), speed);
139 |
140 | if (up ^ down)
141 | camera->Position.Y += speed * (up ? +0.25f : -0.25f);
142 |
143 | if (clockwise ^ counterclockwise)
144 | camera->Rotation += speed * (clockwise ? -1.0f : +1.0f);
145 |
146 | if (zoomin ^ zoomout)
147 | {
148 | camera->HorizontalFov += speed * (zoomin ? -1.0f : +1.0f);
149 | camera->HorizontalFov = std::clamp(camera->HorizontalFov, +1.0f, +170.0f);
150 | }
151 |
152 | if (mouse->HasMoved())
153 | {
154 | SetMouseWindowCenter();
155 |
156 | auto delta = mouse->GetDeltaPosition();
157 |
158 | verticalRotation += delta.x * sensitivity;
159 | horizontalRotation -= delta.y * (sensitivity / 5.0f);
160 |
161 | horizontalRotation = std::clamp(horizontalRotation, -75.0f, +75.0f);
162 | }
163 |
164 | ((InputState*)*(uint64_t*)INPUT_STATE_PTR_ADDRESS)->HideCursor();
165 |
166 | Vec2 focus = PointFromAngle(verticalRotation, 1.0f);
167 | camera->Focus.X = camera->Position.X + focus.X;
168 | camera->Focus.Z = camera->Position.Z + focus.Y;
169 |
170 | camera->Focus.Y = camera->Position.Y + PointFromAngle(horizontalRotation, 5.0f).X;
171 | }
172 |
173 | void CameraController::SetControls(bool value)
174 | {
175 | if (GetIsEnabled() == value)
176 | return;
177 |
178 | SetIsEnabled(value);
179 | componentsManager->SetUpdateGameInput(!value);
180 |
181 | printf("CameraController::SetControls(): enabled = %s\n", GetIsEnabled() ? "true" : "false");
182 |
183 | typedef void __stdcall _glutSetCursor(int);
184 | auto glutSetCursor = (_glutSetCursor*)GLUT_SET_CURSOR_ADDRESS;
185 |
186 | // hide cursor
187 | glutSetCursor(value ? GLUT_CURSOR_NONE : GLUT_CURSOR_RIGHT_ARROW);
188 |
189 | if (value)
190 | {
191 | // disable camera setters
192 | for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
193 | *(uint8_t*)cameraSetterAddresses[i] = RET_OPCODE;
194 |
195 | // set initial camera angle
196 | Vec2 camXz = Vec2(camera->Position.X, camera->Position.Z);
197 | Vec2 focusXz = Vec2(camera->Focus.X, camera->Focus.Z);
198 | verticalRotation = AngleFromPoints(camXz, focusXz);
199 |
200 | horizontalRotation = 0;
201 | camera->Rotation = defaultRotation;
202 | camera->HorizontalFov = defaultFov;
203 | }
204 | else
205 | {
206 | // restore camera setters
207 | for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
208 | *(uint8_t*)cameraSetterAddresses[i] = originalSetterBytes[i];
209 | }
210 | }
211 |
212 | void CameraController::SetMouseWindowCenter()
213 | {
214 | RECT windowRect = MainModule::GetWindowBounds();
215 |
216 | int centerX = windowRect.left + (windowRect.right - windowRect.left) / 2;
217 | int centerY = windowRect.top + (windowRect.bottom - windowRect.top) / 2;
218 |
219 | Mouse::GetInstance()->SetPosition(centerX, centerY);
220 | }
221 |
222 | bool CameraController::GetIsEnabled()
223 | {
224 | return isEnabled;
225 | }
226 |
227 | void CameraController::SetIsEnabled(bool value)
228 | {
229 | isEnabled = value;
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/CameraController.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 | #include "../Constants.h"
4 | #include "../Input/Bindings/Binding.h"
5 | #include "../Utilities/Math.h"
6 |
7 | namespace DivaHook::Components
8 | {
9 | struct Camera
10 | {
11 | Utilities::Vec3 Position;
12 | Utilities::Vec3 Focus;
13 | float Rotation;
14 | float HorizontalFov;
15 | float VerticalFov;
16 | };
17 |
18 | class CameraController : public EmulatorComponent
19 | {
20 | public:
21 | Input::Binding* ToggleBinding;
22 |
23 | Input::Binding* ForwardBinding;
24 | Input::Binding* BackwardBinding;
25 | Input::Binding* LeftBinding;
26 | Input::Binding* RightBinding;
27 |
28 | Input::Binding* UpBinding;
29 | Input::Binding* DownBinding;
30 | Input::Binding* FastBinding;
31 | Input::Binding* SlowBinding;
32 |
33 | Input::Binding* ClockwiseBinding;
34 | Input::Binding* CounterClockwiseBinding;
35 |
36 | Input::Binding* ZoomInBinding;
37 | Input::Binding* ZoomOutBinding;
38 |
39 | CameraController();
40 | ~CameraController();
41 |
42 | virtual const char* GetDisplayName() override;
43 |
44 | virtual void Initialize(ComponentsManager*) override;
45 | virtual void Update() override;
46 | virtual void UpdateInput() override;
47 |
48 | void SetControls(bool value);
49 |
50 | bool GetIsEnabled();
51 |
52 | private:
53 | const float fastSpeed = 0.1f;
54 | const float slowSpeed = 0.0005f;
55 | const float normalSpeed = 0.005f;
56 |
57 | const float defaultRotation = 0.0f;
58 | const float defaultFov = 70.0f;
59 | const float sensitivity = 0.25f;
60 |
61 | ComponentsManager* componentsManager;
62 | float verticalRotation;
63 | float horizontalRotation;
64 |
65 | bool isEnabled;
66 | Camera* camera;
67 |
68 | uint8_t originalSetterBytes[4];
69 | void* cameraSetterAddresses[4] =
70 | {
71 | (void*)CAMERA_POS_SETTER_ADDRESS,
72 | (void*)CAMERA_INTR_SETTER_ADDRESS,
73 | (void*)CAMERA_ROT_SETTER_ADDRESS,
74 | (void*)CAMERA_PERS_SETTER_ADDRESS,
75 | };
76 |
77 | void SetMouseWindowCenter();
78 | void SetIsEnabled(bool value);
79 | };
80 | }
81 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/ComponentsManager.cpp:
--------------------------------------------------------------------------------
1 | #include "ComponentsManager.h"
2 | #include "../FileSystem/ConfigFile.h"
3 | #include "../MainModule.h"
4 | #include "Input/InputEmulator.h"
5 | #include "Input/TouchSliderEmulator.h"
6 | #include "Input/TouchPanelEmulator.h"
7 | #include "SysTimer.h"
8 | #include "PlayerDataManager.h"
9 | #include "FrameRateManager.h"
10 | #include "FastLoader.h"
11 | #include "StageManager.h"
12 | #include "CameraController.h"
13 | #include "DebugComponent.h"
14 |
15 | using ConfigFile = DivaHook::FileSystem::ConfigFile;
16 |
17 | namespace DivaHook::Components
18 | {
19 | typedef void EngineUpdateInput(void*);
20 |
21 | ComponentsManager::ComponentsManager()
22 | {
23 | }
24 |
25 | ComponentsManager::~ComponentsManager()
26 | {
27 | }
28 |
29 | void ComponentsManager::ParseAddComponents()
30 | {
31 | EmulatorComponent *allComponents[]
32 | {
33 | new InputEmulator(),
34 | new TouchSliderEmulator(),
35 | new TouchPanelEmulator(),
36 | new SysTimer(),
37 | new PlayerDataManager(),
38 | new FrameRateManager(),
39 | new FastLoader(),
40 | new StageManager(),
41 | new CameraController(),
42 | new DebugComponent(),
43 | };
44 |
45 | ConfigFile componentsConfig(MainModule::GetModuleDirectory(), COMPONENTS_CONFIG_FILE_NAME);
46 | bool success = componentsConfig.OpenRead();
47 |
48 | if (!success)
49 | {
50 | printf("ComponentsManager::ParseAddComponents(): Unable to parse %s\n", COMPONENTS_CONFIG_FILE_NAME.c_str());
51 | return;
52 | }
53 |
54 | size_t componentCount = sizeof(allComponents) / sizeof(EmulatorComponent*);
55 | components.reserve(componentCount);
56 |
57 | std::string trueString = "true", falseString = "false";
58 |
59 | for (int i = 0; i < componentCount; i++)
60 | {
61 | std::string *value;
62 |
63 | auto name = allComponents[i]->GetDisplayName();
64 | //printf("ComponentsManager::ParseAddComponents(): searching name: %s\n", name);
65 |
66 | if (componentsConfig.TryGetValue(name, &value))
67 | {
68 | //printf("ComponentsManager::ParseAddComponents(): %s found\n", name);
69 |
70 | if (*value == trueString)
71 | {
72 | //printf("ComponentsManager::ParseAddComponents(): enabling %s...\n", name);
73 | components.push_back(allComponents[i]);
74 | }
75 | else if (*value == falseString)
76 | {
77 | //printf("ComponentsManager::ParseAddComponents(): disabling %s...\n", name);
78 | }
79 | else
80 | {
81 | //printf("ComponentsManager::ParseAddComponents(): invalid value %s for component %s\n", value, name);
82 | }
83 |
84 | delete value;
85 | }
86 | else
87 | {
88 | //printf("ParseAddComponents(): component %s not found\n", name);
89 | delete allComponents[i];
90 | }
91 | }
92 | }
93 |
94 |
95 | void ComponentsManager::Initialize()
96 | {
97 | dwGuiDisplay = (DwGuiDisplay*)*(uint64_t*)DW_GUI_DISPLAY_INSTANCE_PTR_ADDRESS;
98 |
99 | ParseAddComponents();
100 | updateStopwatch.Start();
101 |
102 | for (auto& component : components)
103 | component->Initialize(this);
104 | }
105 |
106 | void ComponentsManager::Update()
107 | {
108 | elpasedTime = updateStopwatch.Restart();
109 |
110 | for (auto& component : components)
111 | {
112 | component->SetElapsedTime(elpasedTime);
113 | component->Update();
114 | }
115 | }
116 |
117 | void ComponentsManager::UpdateInput()
118 | {
119 | if (!GetIsInputEmulatorUsed())
120 | {
121 | uint64_t* inputStatePtr = (uint64_t*)INPUT_STATE_PTR_ADDRESS;
122 |
123 | // poll input using the original PollInput function we overwrote with the update hook instead
124 | if (inputStatePtr != nullptr)
125 | ((EngineUpdateInput*)ENGINE_UPDATE_INPUT_ADDRESS)((void*)*inputStatePtr);
126 | }
127 |
128 | for (auto& component : components)
129 | component->UpdateInput();
130 | }
131 |
132 | void ComponentsManager::OnFocusGain()
133 | {
134 | for (auto& component : components)
135 | component->OnFocusGain();
136 | }
137 |
138 | void ComponentsManager::OnFocusLost()
139 | {
140 | for (auto& component : components)
141 | component->OnFocusLost();
142 | }
143 |
144 | void ComponentsManager::Dispose()
145 | {
146 | for (auto& component : components)
147 | delete component;
148 | }
149 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/ComponentsManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 | #include "../Utilities/Stopwatch.h"
4 | #include
5 |
6 | namespace DivaHook::Components
7 | {
8 | const std::string COMPONENTS_CONFIG_FILE_NAME = "components.ini";
9 |
10 | // Incomplete type
11 | struct DwGuiDisplay
12 | {
13 | void* vftable;
14 | void* active;
15 | void* cap;
16 | void* on;
17 | void* move;
18 | void* widget;
19 | };
20 |
21 | class ComponentsManager
22 | {
23 | public:
24 | ComponentsManager();
25 | ~ComponentsManager();
26 | void Initialize();
27 | void Update();
28 | void UpdateInput();
29 | void OnFocusGain();
30 | void OnFocusLost();
31 | void Dispose();
32 |
33 | inline bool GetIsInputEmulatorUsed() { return isInputEmulatorUsed; };
34 | inline void SetIsInputEmulatorUsed(bool value) { isInputEmulatorUsed = value; };
35 |
36 | inline bool GetUpdateGameInput() { return updateGameInput; };
37 | inline void SetUpdateGameInput(bool value) { updateGameInput = value; }
38 |
39 | inline bool IsDwGuiActive() { return dwGuiDisplay->active != nullptr; };
40 | inline bool IsDwGuiHovered() { return dwGuiDisplay->on != nullptr; };
41 |
42 | private:
43 | DwGuiDisplay* dwGuiDisplay;
44 |
45 | bool isInputEmulatorUsed = false;
46 | bool updateGameInput = true;
47 |
48 | float elpasedTime;
49 | Utilities::Stopwatch updateStopwatch;
50 | std::vector components;
51 |
52 | void ParseAddComponents();
53 | };
54 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/CustomPlayerData.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace DivaHook::Components
5 | {
6 | struct CustomPlayerData
7 | {
8 | std::string *PlayerName;
9 | int LevelPlateId;
10 | int SkinEquip;
11 | int BtnSeEquip;
12 | int SlideSeEquip;
13 | int ChainslideSeEquip;
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/DebugComponent.cpp:
--------------------------------------------------------------------------------
1 | #include "DebugComponent.h"
2 | #include "../Constants.h"
3 |
4 | namespace DivaHook::Components
5 | {
6 | const char* GameStateNames[] =
7 | {
8 | "STARTUP",
9 | "ADVERTISE",
10 | "GAME",
11 | "DATA_TEST",
12 | "TEST_MODE",
13 | "APP_ERROR",
14 | "MAX",
15 | };
16 |
17 | const char* SubGameStateNames[] =
18 | {
19 | "DATA_INITIALIZE",
20 | "SYSTEM_STARTUP",
21 | "SYSTEM_STARTUP_ERROR",
22 | "WARNING",
23 | "LOGO",
24 | "RATING",
25 | "DEMO",
26 | "TITLE",
27 | "RANKING",
28 | "SCORE_RANKING",
29 | "CM",
30 | "PHOTO_MODE_DEMO",
31 | "SELECTOR",
32 | "GAME_MAIN",
33 | "GAME_SEL",
34 | "STAGE_RESULT",
35 | "SCREEN_SHOT_SEL",
36 | "SCREEN_SHOT_RESULT",
37 | "GAME_OVER",
38 | "DATA_TEST_MAIN",
39 | "DATA_TEST_MISC",
40 | "DATA_TEST_OBJ",
41 | "DATA_TEST_STG",
42 | "DATA_TEST_MOT",
43 | "DATA_TEST_COLLISION",
44 | "DATA_TEST_SPR",
45 | "DATA_TEST_AET",
46 | "DATA_TEST_AUTH_3D",
47 | "DATA_TEST_CHR",
48 | "DATA_TEST_ITEM",
49 | "DATA_TEST_PERF",
50 | "DATA_TEST_PVSCRIPT",
51 | "DATA_TEST_PRINT",
52 | "DATA_TEST_CARD",
53 | "DATA_TEST_OPD",
54 | "DATA_TEST_SLIDER",
55 | "DATA_TEST_GLITTER",
56 | "DATA_TEST_GRAPHICS",
57 | "DATA_TEST_COLLECTION_CARD",
58 | "TEST_MODE_MAIN",
59 | "APP_ERROR",
60 | "MAX",
61 | };
62 |
63 | const char* DataTestNames[] =
64 | {
65 | "MAIN TEST",
66 | "MISC TEST",
67 | "OBJECT TEST",
68 | "STAGE TEST",
69 | "MOTION TEST",
70 | "COLLISION TEST",
71 | "SPRITE TEST",
72 | "2DAUTH TEST",
73 | "3DAUTH TEST",
74 | "CHARA TEST",
75 | "ITEM TEST",
76 | "PERFORMANCE TEST",
77 | "PVSCRIPT TEST",
78 | "PRINT TEST",
79 | "CARD TEST",
80 | "OPD TEST",
81 | "SLIDER TEST",
82 | "GLITTER TEST",
83 | "GRAPHICS TEST",
84 | "COLLECTION CARD TEST",
85 | };
86 |
87 | typedef void ChangeGameState(GameState);
88 | ChangeGameState* changeGameState = (ChangeGameState*)CHANGE_MODE_ADDRESS;
89 |
90 | typedef void ChangeSubState(GameState, SubGameState);
91 | ChangeSubState* changeSubState = (ChangeSubState*)CHANGE_SUB_MODE_ADDRESS;
92 |
93 | DebugComponent::DebugComponent()
94 | {
95 | }
96 |
97 | DebugComponent::~DebugComponent()
98 | {
99 | }
100 |
101 | const char* DebugComponent::GetDisplayName()
102 | {
103 | return "debug_component";
104 | }
105 |
106 | void DebugComponent::Initialize(ComponentsManager*)
107 | {
108 | printf("DebugComponent::Initialize(): Initialized\n");
109 |
110 | InjectPatches();
111 |
112 | // In case the FrameRateManager isn't enabled
113 | DWORD oldProtect;
114 | VirtualProtect((void*)AET_FRAME_DURATION_ADDRESS, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
115 | }
116 |
117 | void DebugComponent::Update()
118 | {
119 | if (dataTestMain)
120 | {
121 | Input::Keyboard::GetInstance()->PollInput();
122 | UpdateDataTestMain();
123 | }
124 | }
125 |
126 | void DebugComponent::UpdateInput()
127 | {
128 | auto keyboard = Input::Keyboard::GetInstance();
129 |
130 | // fast forward menus
131 | if (keyboard->IsDown(VK_SHIFT))
132 | {
133 | float* frameDuration = (float*)AET_FRAME_DURATION_ADDRESS;
134 |
135 | if (keyboard->IsDown(VK_TAB))
136 | *frameDuration = 1.0f / (GetGameFrameRate() / aetSpeedUpFactor);
137 | else if (keyboard->IsReleased(VK_TAB))
138 | *frameDuration = 1.0f / 60.0f;
139 | }
140 |
141 | for (size_t i = 0; i < _countof(gameStateKeyMappings); i++)
142 | {
143 | if (keyboard->IsTapped(gameStateKeyMappings[i].KeyCode))
144 | InternalChangeGameState(gameStateKeyMappings[i].State);
145 | }
146 | }
147 |
148 | void DebugComponent::InjectPatches()
149 | {
150 | const struct { void* Address; std::initializer_list Data; } patches[] =
151 | {
152 | // Prevent the DATA_TEST game state from exiting on the first frame
153 | { (void*)0x0000000140284B01, { 0x00 } },
154 | // Enable dw_gui sprite draw calls
155 | { (void*)0x0000000140192601, { 0x00 } },
156 | // Update the dw_gui display
157 | { (void*)0x0000000140302600, { 0xB0, 0x01 } },
158 | // Draw the dw_gui display
159 | { (void*)0x0000000140302610, { 0xB0, 0x01 } },
160 | // Enable the dw_gui widgets
161 | { (void*)0x0000000140192D00, { 0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3 } },
162 | };
163 |
164 | for (size_t i = 0; i < _countof(patches); i++)
165 | InjectCode(patches[i].Address, patches[i].Data);
166 | }
167 |
168 | void DebugComponent::SetConsoleForeground()
169 | {
170 | HWND consoleHandle = GetConsoleWindow();
171 |
172 | if (consoleHandle == NULL)
173 | return;
174 |
175 | WINDOWPLACEMENT place = { sizeof(WINDOWPLACEMENT) };
176 | GetWindowPlacement(consoleHandle, &place);
177 |
178 | switch (place.showCmd)
179 | {
180 | case SW_SHOWMAXIMIZED:
181 | ShowWindow(consoleHandle, SW_SHOWMAXIMIZED);
182 | break;
183 | case SW_SHOWMINIMIZED:
184 | ShowWindow(consoleHandle, SW_RESTORE);
185 | break;
186 | default:
187 | ShowWindow(consoleHandle, SW_NORMAL);
188 | break;
189 | }
190 |
191 | SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
192 | SetForegroundWindow(consoleHandle);
193 | }
194 |
195 | void DebugComponent::PrintDataTestMain()
196 | {
197 | system("cls");
198 | printf(" DATA TEST MAIN:\n\n");
199 |
200 | for (int i = SUB_DATA_TEST_MISC; i <= SUB_DATA_TEST_COLLECTION_CARD; i++)
201 | printf("%s %s\n", i == selectionIndex ? "->" : " ", DataTestNames[i - SUB_DATA_TEST_MAIN]);
202 |
203 | printf("\n");
204 | SetConsoleForeground();
205 | }
206 |
207 | void DebugComponent::InternalChangeGameState(GameState state)
208 | {
209 | changeGameState(state);
210 | printDataTestMain = dataTestMain = (state == GS_DATA_TEST);
211 | }
212 |
213 | void DebugComponent::UpdateDataTestMain()
214 | {
215 | auto keyboard = Input::Keyboard::GetInstance();
216 |
217 | if (keyboard->IsIntervalTapped(VK_UP))
218 | {
219 | selectionIndex--;
220 | printDataTestMain = true;
221 | }
222 |
223 | if (keyboard->IsIntervalTapped(VK_DOWN))
224 | {
225 | selectionIndex++;
226 | printDataTestMain = true;
227 | }
228 |
229 | if (selectionIndex > SUB_DATA_TEST_COLLECTION_CARD)
230 | selectionIndex = SUB_DATA_TEST_MISC;
231 |
232 | if (selectionIndex < SUB_DATA_TEST_MISC)
233 | selectionIndex = SUB_DATA_TEST_COLLECTION_CARD;
234 |
235 | if (keyboard->IsTapped(VK_RETURN))
236 | {
237 | dataTestMain = false;
238 |
239 | printf("[%s] -> [%s]\n", SubGameStateNames[SUB_DATA_TEST_MAIN], SubGameStateNames[selectionIndex]);
240 | changeSubState(GS_DATA_TEST, (SubGameState)selectionIndex);
241 | }
242 |
243 | if (printDataTestMain)
244 | {
245 | PrintDataTestMain();
246 | printDataTestMain = false;
247 | }
248 | }
249 |
250 | void DebugComponent::InjectCode(void* address, const std::initializer_list &data)
251 | {
252 | const size_t byteCount = data.size() * sizeof(uint8_t);
253 |
254 | DWORD oldProtect;
255 | VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
256 |
257 | memcpy(address, data.begin(), byteCount);
258 | }
259 | }
260 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/DebugComponent.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 | #include "GameState.h"
4 | #include "../Input/Keyboard/Keyboard.h"
5 |
6 | namespace DivaHook::Components
7 | {
8 | class DebugComponent : public EmulatorComponent
9 | {
10 | public:
11 | DebugComponent();
12 | ~DebugComponent();
13 |
14 | virtual const char* GetDisplayName() override;
15 |
16 | virtual void Initialize(ComponentsManager*) override;
17 | virtual void Update() override;
18 | virtual void UpdateInput() override;
19 |
20 | private:
21 | const float aetSpeedUpFactor = 4.0f;
22 |
23 | bool dataTestMain = false;
24 | bool printDataTestMain = false;
25 | int selectionIndex = SUB_DATA_TEST_MISC;
26 |
27 | const struct { BYTE KeyCode; GameState State; } gameStateKeyMappings[5] =
28 | {
29 | { VK_F4, GS_ADVERTISE },
30 | { VK_F5, GS_GAME },
31 | { VK_F6, GS_DATA_TEST },
32 | { VK_F7, GS_TEST_MODE },
33 | { VK_F8, GS_APP_ERROR },
34 | };
35 |
36 | void InjectPatches();
37 | void SetConsoleForeground();
38 | void PrintDataTestMain();
39 | void InternalChangeGameState(GameState state);
40 | void UpdateDataTestMain();
41 | void InjectCode(void* address, const std::initializer_list &data);
42 | };
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/EmulatorComponent.cpp:
--------------------------------------------------------------------------------
1 | #include "EmulatorComponent.h"
2 | #include "../Constants.h"
3 |
4 | namespace DivaHook::Components
5 | {
6 | EmulatorComponent::EmulatorComponent()
7 | {
8 | }
9 |
10 | EmulatorComponent::~EmulatorComponent()
11 | {
12 | }
13 |
14 | void EmulatorComponent::SetElapsedTime(float value)
15 | {
16 | elapsedTime = value;
17 | }
18 |
19 | float EmulatorComponent::GetElapsedTime()
20 | {
21 | return elapsedTime == 0.0f ? (1000.0f / 60.0f) : elapsedTime;
22 | }
23 |
24 | float EmulatorComponent::GetFrameRate()
25 | {
26 | return 1000.0f / GetElapsedTime();
27 | }
28 |
29 | float EmulatorComponent::GetGameFrameRate()
30 | {
31 | return *(float*)FRAME_RATE_ADDRESS;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/EmulatorComponent.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Components
4 | {
5 | class ComponentsManager;
6 |
7 | class EmulatorComponent
8 | {
9 | public:
10 | EmulatorComponent();
11 | ~EmulatorComponent();
12 |
13 | virtual const char* GetDisplayName() = 0;
14 |
15 | virtual void Initialize(ComponentsManager*) = 0;
16 | virtual void Update() = 0;
17 |
18 | virtual void UpdateInput() {};
19 | virtual void OnFocusGain() {};
20 | virtual void OnFocusLost() {};
21 |
22 | void SetElapsedTime(float value);
23 | float GetElapsedTime();
24 | float GetFrameRate();
25 | float GetGameFrameRate();
26 |
27 | private:
28 | float elapsedTime;
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/FastLoader.cpp:
--------------------------------------------------------------------------------
1 | #include "FastLoader.h"
2 | #include "../Constants.h"
3 | #include
4 |
5 | namespace DivaHook::Components
6 | {
7 | FastLoader::FastLoader()
8 | {
9 | }
10 |
11 | FastLoader::~FastLoader()
12 | {
13 | }
14 |
15 | const char* FastLoader::GetDisplayName()
16 | {
17 | return "fast_loader";
18 | }
19 |
20 | void FastLoader::Initialize(ComponentsManager*)
21 | {
22 | }
23 |
24 | void FastLoader::Update()
25 | {
26 | if (dataInitialized)
27 | return;
28 |
29 | previousGameState = currentGameState;
30 | currentGameState = *(GameState*)CURRENT_GAME_STATE_ADDRESS;
31 |
32 | if (currentGameState == GS_STARTUP)
33 | {
34 | typedef void UpdateTask();
35 | UpdateTask* updateTask = (UpdateTask*)UPDATE_TASKS_ADDRESS;
36 |
37 | // speed up TaskSystemStartup
38 | for (int i = 0; i < updatesPerFrame; i++)
39 | updateTask();
40 |
41 | constexpr int DATA_INITIALIZED = 3;
42 |
43 | // skip TaskDataInit
44 | *(int*)(DATA_INIT_STATE_ADDRESS) = DATA_INITIALIZED;
45 |
46 | // skip TaskWarning
47 | *(int*)(SYSTEM_WARNING_ELAPSED_ADDRESS) = 3939;
48 | }
49 | else if (previousGameState == GS_STARTUP)
50 | {
51 | dataInitialized = true;
52 | printf("FastLoader::Update(): Data Initialized\n");
53 | }
54 | }
55 |
56 | void FastLoader::UpdateInput()
57 | {
58 | return;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/FastLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 | #include "GameState.h"
4 |
5 | namespace DivaHook::Components
6 | {
7 | class FastLoader : public EmulatorComponent
8 | {
9 | public:
10 | FastLoader();
11 | ~FastLoader();
12 |
13 | virtual const char* GetDisplayName() override;
14 |
15 | virtual void Initialize(ComponentsManager*) override;
16 | virtual void Update() override;
17 | virtual void UpdateInput() override;
18 |
19 | private:
20 | const int updatesPerFrame = 39;
21 |
22 | GameState currentGameState;
23 | GameState previousGameState;
24 | bool dataInitialized = false;
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/FrameRateManager.cpp:
--------------------------------------------------------------------------------
1 | #include "FrameRateManager.h"
2 | #include "../Constants.h"
3 | #include "GameState.h"
4 | #include
5 | #include
6 |
7 | namespace DivaHook::Components
8 | {
9 | FrameRateManager::FrameRateManager()
10 | {
11 | }
12 |
13 | FrameRateManager::~FrameRateManager()
14 | {
15 | }
16 |
17 | const char* FrameRateManager::GetDisplayName()
18 | {
19 | return "frame_rate_manager";
20 | }
21 |
22 | void FrameRateManager::Initialize(ComponentsManager*)
23 | {
24 | pvFrameRate = (float*)PV_FRAME_RATE_ADDRESS;
25 | frameSpeed = (float*)FRAME_SPEED_ADDRESS;
26 | aetFrameDuration = (float*)AET_FRAME_DURATION_ADDRESS;
27 |
28 | // The default is expected to be 1.0 / 60.0
29 | defaultAetFrameDuration = *aetFrameDuration;
30 |
31 | // This const variable is stored inside a data segment so we don't want to throw any access violations
32 | DWORD oldProtect;
33 | VirtualProtect((void*)AET_FRAME_DURATION_ADDRESS, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
34 | }
35 |
36 | void FrameRateManager::Update()
37 | {
38 | float frameRate = RoundFrameRate(GetGameFrameRate());
39 |
40 | *aetFrameDuration = 1.0f / frameRate;
41 | *pvFrameRate = frameRate;
42 |
43 | bool inGame = *(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME;
44 |
45 | if (inGame)
46 | {
47 | // During the GAME state the frame rate will be handled by the PvFrameRate instead
48 |
49 | constexpr float defaultFrameSpeed = 1.0f;
50 | constexpr float defaultFrameRate = 60.0f;
51 |
52 | // This PV struct creates a copy of the PvFrameRate & PvFrameSpeed during the loading screen
53 | // so we'll make sure to keep updating it as well.
54 | // Each new motion also creates its own copy of these values but keeping track of the active motions is annoying
55 | // and they usually change multiple times per PV anyway so this should suffice for now
56 | float* pvStructPvFrameRate = (float*)(0x0000000140CDD978 + 0x2BF98);
57 | float* pvStructPvFrameSpeed = (float*)(0x0000000140CDD978 + 0x2BF9C);
58 |
59 | *pvStructPvFrameRate = *pvFrameRate;
60 | *pvStructPvFrameSpeed = (defaultFrameRate / *pvFrameRate);
61 |
62 | *frameSpeed = defaultFrameSpeed;
63 | }
64 | else
65 | {
66 | *frameSpeed = *aetFrameDuration / defaultAetFrameDuration;
67 | }
68 | }
69 |
70 | float FrameRateManager::RoundFrameRate(float frameRate)
71 | {
72 | constexpr float roundingThreshold = 4.0f;
73 |
74 | for (int i = 0; i < sizeof(commonRefreshRates) / sizeof(float); i++)
75 | {
76 | float refreshRate = commonRefreshRates[i];
77 |
78 | if (frameRate > refreshRate - roundingThreshold && frameRate < refreshRate + roundingThreshold)
79 | frameRate = refreshRate;
80 | }
81 |
82 | return frameRate;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/FrameRateManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 |
4 | namespace DivaHook::Components
5 | {
6 | class FrameRateManager : public EmulatorComponent
7 | {
8 | public:
9 | FrameRateManager();
10 | ~FrameRateManager();
11 |
12 | virtual const char* GetDisplayName() override;
13 |
14 | virtual void Initialize(ComponentsManager*) override;
15 | virtual void Update() override;
16 |
17 | private:
18 | float *pvFrameRate;
19 | float *frameSpeed;
20 | float *aetFrameDuration;
21 | float defaultAetFrameDuration;
22 |
23 | float commonRefreshRates[5]
24 | {
25 | 60.0f,
26 | 75.0f,
27 | 120.0f,
28 | 144.0f,
29 | 240.0f,
30 | };
31 |
32 | float RoundFrameRate(float frameRate);
33 | };
34 | }
35 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/GameState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace DivaHook::Components
5 | {
6 | enum GameState : uint32_t
7 | {
8 | GS_STARTUP,
9 | GS_ADVERTISE,
10 | GS_GAME,
11 | GS_DATA_TEST,
12 | GS_TEST_MODE,
13 | GS_APP_ERROR,
14 | GS_MAX,
15 | };
16 |
17 | enum SubGameState : uint32_t
18 | {
19 | SUB_DATA_INITIALIZE,
20 | SUB_SYSTEM_STARTUP,
21 | SUB_SYSTEM_STARTUP_ERROR,
22 | SUB_WARNING,
23 | SUB_LOGO,
24 | SUB_RATING,
25 | SUB_DEMO,
26 | SUB_TITLE,
27 | SUB_RANKING,
28 | SUB_SCORE_RANKING,
29 | SUB_CM,
30 | SUB_PHOTO_MODE_DEMO,
31 | SUB_SELECTOR,
32 | SUB_GAME_MAIN,
33 | SUB_GAME_SEL,
34 | SUB_STAGE_RESULT,
35 | SUB_SCREEN_SHOT_SEL,
36 | SUB_SCREEN_SHOT_RESULT,
37 | SUB_GAME_OVER,
38 | SUB_DATA_TEST_MAIN,
39 | SUB_DATA_TEST_MISC,
40 | SUB_DATA_TEST_OBJ,
41 | SUB_DATA_TEST_STG,
42 | SUB_DATA_TEST_MOT,
43 | SUB_DATA_TEST_COLLISION,
44 | SUB_DATA_TEST_SPR,
45 | SUB_DATA_TEST_AET,
46 | SUB_DATA_TEST_AUTH_3D,
47 | SUB_DATA_TEST_CHR,
48 | SUB_DATA_TEST_ITEM,
49 | SUB_DATA_TEST_PERF,
50 | SUB_DATA_TEST_PVSCRIPT,
51 | SUB_DATA_TEST_PRINT,
52 | SUB_DATA_TEST_CARD,
53 | SUB_DATA_TEST_OPD,
54 | SUB_DATA_TEST_SLIDER,
55 | SUB_DATA_TEST_GLITTER,
56 | SUB_DATA_TEST_GRAPHICS,
57 | SUB_DATA_TEST_COLLECTION_CARD,
58 | SUB_TEST_MODE_MAIN,
59 | SUB_APP_ERROR,
60 | SUB_MAX,
61 | };
62 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/InputBufferType.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Components
4 | {
5 | enum InputBufferType
6 | {
7 | InputBufferType_Tapped,
8 | InputBufferType_Released,
9 | InputBufferType_Down,
10 | InputBufferType_DoubleTapped,
11 | InputBufferType_IntervalTapped,
12 | InputBufferType_Max,
13 | };
14 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/InputEmulator.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "windows.h"
3 | #include "InputEmulator.h"
4 | #include "../ComponentsManager.h"
5 | #include "../../Constants.h"
6 | #include "../../MainModule.h"
7 | #include "../../Input/Bindings/KeyboardBinding.h"
8 | #include "../../Input/Bindings/MouseBinding.h"
9 | #include "../../Input/Bindings/Ds4Binding.h"
10 | #include "../../Input/KeyConfig/Config.h"
11 | #include "../../Utilities/Operations.h"
12 | #include "../../Utilities/EnumBitwiseOperations.h"
13 | #include "../../FileSystem/ConfigFile.h"
14 |
15 | const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
16 |
17 | using namespace DivaHook::Input;
18 | using namespace DivaHook::Input::KeyConfig;
19 | using namespace DivaHook::Utilities;
20 |
21 | namespace DivaHook::Components
22 | {
23 | InputEmulator::InputEmulator()
24 | {
25 | }
26 |
27 | InputEmulator::~InputEmulator()
28 | {
29 | delete TestBinding;
30 | delete ServiceBinding;
31 |
32 | delete StartBinding;
33 | delete SankakuBinding;
34 | delete ShikakuBinding;
35 | delete BatsuBinding;
36 | delete MaruBinding;
37 |
38 | delete LeftBinding;
39 | delete RightBinding;
40 | }
41 |
42 | const char* InputEmulator::GetDisplayName()
43 | {
44 | return "input_emulator";
45 | }
46 |
47 | void InputEmulator::Initialize(ComponentsManager* manager)
48 | {
49 | componentsManager = manager;
50 | componentsManager->SetIsInputEmulatorUsed(true);
51 |
52 | inputState = GetInputStatePtr((void*)INPUT_STATE_PTR_ADDRESS);
53 | inputState->HideCursor();
54 |
55 | TestBinding = new Binding();
56 | ServiceBinding = new Binding();
57 | StartBinding = new Binding();
58 |
59 | SankakuBinding = new Binding();
60 | ShikakuBinding = new Binding();
61 | BatsuBinding = new Binding();
62 | MaruBinding = new Binding();
63 |
64 | LeftBinding = new Binding();
65 | RightBinding = new Binding();
66 |
67 | FileSystem::ConfigFile configFile(MainModule::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
68 | configFile.OpenRead();
69 |
70 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_TEST", *TestBinding, { "F1" });
71 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_SERVICE", *ServiceBinding, { "F2" });
72 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_START", *StartBinding, { "Enter" });
73 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_TRIANGLE", *SankakuBinding, { "W", "I" });
74 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_SQUARE", *ShikakuBinding, { "A", "J" });
75 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_CROSS", *BatsuBinding, { "S", "K" });
76 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_CIRCLE", *MaruBinding, { "D", "L" });
77 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_LEFT", *LeftBinding, { "Q", "U" });
78 | Config::BindConfigKeys(configFile.ConfigMap, "JVS_RIGHT", *RightBinding, { "E", "O" });
79 |
80 | mouseScrollPvSelection = configFile.GetBooleanValue("mouse_scroll_pv_selection");
81 | }
82 |
83 | void InputEmulator::Update()
84 | {
85 | return;
86 | }
87 |
88 | void InputEmulator::OnFocusLost()
89 | {
90 | // to prevent buttons from being "stuck"
91 | inputState->ClearState();
92 | inputState->HideCursor();
93 | }
94 |
95 | void InputEmulator::UpdateInput()
96 | {
97 | if (!componentsManager->GetUpdateGameInput())
98 | return;
99 |
100 | if (!componentsManager->IsDwGuiActive())
101 | {
102 | UpdateJvsInput();
103 |
104 | if (mouseScrollPvSelection && !componentsManager->IsDwGuiHovered())
105 | UpdateMousePvScroll();
106 | }
107 |
108 | UpdateDwGuiInput();
109 | }
110 |
111 | void InputEmulator::UpdateJvsInput()
112 | {
113 | auto tappedFunc = [](void* binding) { return ((Binding*)binding)->AnyTapped(); };
114 | auto releasedFunc = [](void* binding) { return ((Binding*)binding)->AnyReleased(); };
115 | auto downFunc = [](void* binding) { return ((Binding*)binding)->AnyDown(); };
116 |
117 | lastDownState = inputState->Down.Buttons;
118 |
119 | inputState->Tapped.Buttons = GetJvsButtonsState(tappedFunc);
120 | inputState->Released.Buttons = GetJvsButtonsState(releasedFunc);
121 | inputState->Down.Buttons = GetJvsButtonsState(downFunc);
122 | inputState->DoubleTapped.Buttons = GetJvsButtonsState(tappedFunc);
123 | inputState->IntervalTapped.Buttons = GetJvsButtonsState(tappedFunc);
124 |
125 | if ((lastDownState &= inputState->Tapped.Buttons) != 0)
126 | inputState->Down.Buttons ^= inputState->Tapped.Buttons;
127 |
128 | // repress held down buttons to not block input
129 | //inputState->Down.Buttons ^= inputState->Tapped.Buttons;
130 | }
131 |
132 | void InputEmulator::UpdateDwGuiInput()
133 | {
134 | auto keyboard = Keyboard::GetInstance();
135 | auto mouse = Mouse::GetInstance();
136 |
137 | auto pos = mouse->GetRelativePosition();
138 | inputState->MouseX = (int)pos.x;
139 | inputState->MouseY = (int)pos.y;
140 |
141 | auto deltaPos = mouse->GetDeltaPosition();
142 | inputState->MouseDeltaX = (int)deltaPos.x;
143 | inputState->MouseDeltaY = (int)deltaPos.y;
144 |
145 | inputState->Key = GetKeyState();
146 |
147 | for (int i = 0; i < sizeof(keyBits) / sizeof(KeyBit); i++)
148 | UpdateInputBit(keyBits[i].Bit, keyBits[i].KeyCode);
149 |
150 | for (int i = InputBufferType_Tapped; i < InputBufferType_Max; i++)
151 | {
152 | inputState->SetBit(scrollUpBit, mouse->GetIsScrolledUp(), (InputBufferType)i);
153 | inputState->SetBit(scrollDownBit, mouse->GetIsScrolledDown(), (InputBufferType)i);
154 | }
155 | }
156 |
157 | void InputEmulator::UpdateMousePvScroll()
158 | {
159 | // I originally wanted to use a MouseBinding set to JVS_LEFT / JVS_RIGHT
160 | // but that ended up being too slow because a PV slot can only be scrolled to once the scroll animation has finished playing
161 | int* slotsToScroll = (int*)PV_SEL_SLOTS_TO_SCROLL;
162 |
163 | auto mouse = Mouse::GetInstance();
164 | if (mouse->GetIsScrolledUp())
165 | *slotsToScroll -= 1;
166 | if (mouse->GetIsScrolledDown())
167 | *slotsToScroll += 1;
168 | }
169 |
170 | InputState* InputEmulator::GetInputStatePtr(void *address)
171 | {
172 | return (InputState*)(*(uint64_t*)address);
173 | }
174 |
175 | JvsButtons InputEmulator::GetJvsButtonsState(bool(*buttonTestFunc)(void*))
176 | {
177 | JvsButtons buttons = JVS_NONE;
178 |
179 | if (buttonTestFunc(TestBinding))
180 | buttons |= JVS_TEST;
181 | if (buttonTestFunc(ServiceBinding))
182 | buttons |= JVS_SERVICE;
183 |
184 | if (buttonTestFunc(StartBinding))
185 | buttons |= JVS_START;
186 |
187 | if (buttonTestFunc(SankakuBinding))
188 | buttons |= JVS_TRIANGLE;
189 | if (buttonTestFunc(ShikakuBinding))
190 | buttons |= JVS_SQUARE;
191 | if (buttonTestFunc(BatsuBinding))
192 | buttons |= JVS_CROSS;
193 | if (buttonTestFunc(MaruBinding))
194 | buttons |= JVS_CIRCLE;
195 |
196 | if (buttonTestFunc(LeftBinding))
197 | buttons |= JVS_L;
198 | if (buttonTestFunc(RightBinding))
199 | buttons |= JVS_R;
200 |
201 | return buttons;
202 | }
203 |
204 | char InputEmulator::GetKeyState()
205 | {
206 | auto keyboard = Keyboard::GetInstance();
207 |
208 | bool upper = keyboard->IsDown(VK_SHIFT);
209 | constexpr char caseDifference = 'A' - 'a';
210 |
211 | char inputKey = 0x00;
212 |
213 | for (char key = '0'; key < 'Z'; key++)
214 | {
215 | if (keyboard->IsIntervalTapped(key))
216 | inputKey = (upper || key < 'A') ? key : (key - caseDifference);
217 | }
218 |
219 | if (keyboard->IsIntervalTapped(VK_BACK))
220 | inputKey = 0x08;
221 |
222 | if (keyboard->IsIntervalTapped(VK_TAB))
223 | inputKey = 0x09;
224 |
225 | if (keyboard->IsIntervalTapped(VK_SPACE))
226 | inputKey = 0x20;
227 |
228 | return inputKey;
229 | }
230 |
231 | void InputEmulator::UpdateInputBit(uint32_t bit, uint8_t keycode)
232 | {
233 | auto keyboard = Keyboard::GetInstance();
234 |
235 | inputState->SetBit(bit, keyboard->IsTapped(keycode), InputBufferType_Tapped);
236 | inputState->SetBit(bit, keyboard->IsReleased(keycode), InputBufferType_Released);
237 | inputState->SetBit(bit, keyboard->IsDown(keycode), InputBufferType_Down);
238 | inputState->SetBit(bit, keyboard->IsDoubleTapped(keycode), InputBufferType_DoubleTapped);
239 | inputState->SetBit(bit, keyboard->IsIntervalTapped(keycode), InputBufferType_IntervalTapped);
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/InputEmulator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include "InputState.h"
5 | #include "../EmulatorComponent.h"
6 | #include "../../Input/Bindings/Binding.h"
7 |
8 | namespace DivaHook::Components
9 | {
10 | struct KeyBit
11 | {
12 | uint32_t Bit;
13 | uint8_t KeyCode;
14 | };
15 |
16 | class InputEmulator : public EmulatorComponent
17 | {
18 | public:
19 | Input::Binding* TestBinding;
20 | Input::Binding* ServiceBinding;
21 |
22 | Input::Binding* StartBinding;
23 | Input::Binding* SankakuBinding;
24 | Input::Binding* ShikakuBinding;
25 | Input::Binding* BatsuBinding;
26 | Input::Binding* MaruBinding;
27 |
28 | Input::Binding* LeftBinding;
29 | Input::Binding* RightBinding;
30 |
31 | InputEmulator();
32 | ~InputEmulator();
33 |
34 | virtual const char* GetDisplayName() override;
35 |
36 | virtual void Initialize(ComponentsManager*) override;
37 | virtual void Update() override;
38 | virtual void UpdateInput() override;
39 |
40 | virtual void OnFocusLost() override;
41 |
42 | private:
43 | ComponentsManager* componentsManager;
44 |
45 | bool mouseScrollPvSelection = false;
46 | const uint32_t scrollUpBit = 99;
47 | const uint32_t scrollDownBit = 100;
48 |
49 | KeyBit keyBits[20] =
50 | {
51 | { 5, VK_LEFT },
52 | { 6, VK_RIGHT },
53 |
54 | { 29, VK_SPACE },
55 | { 39, 'A' },
56 | { 43, 'E' },
57 | { 42, 'D' },
58 | { 55, 'Q' },
59 | { 57, 'S' }, // unsure
60 | { 61, 'W' },
61 | { 63, 'Y' },
62 | { 84, 'L' }, // unsure
63 |
64 | { 80, VK_RETURN },
65 | { 81, VK_SHIFT },
66 | { 82, VK_CONTROL },
67 | { 83, VK_MENU },
68 |
69 | { 91, VK_UP },
70 | { 93, VK_DOWN },
71 |
72 | { 96, MK_LBUTTON },
73 | { 97, VK_MBUTTON },
74 | { 98, MK_RBUTTON },
75 | };
76 |
77 | InputState* inputState;
78 | JvsButtons lastDownState;
79 |
80 | void UpdateJvsInput();
81 | void UpdateDwGuiInput();
82 | void UpdateMousePvScroll();
83 | InputState* GetInputStatePtr(void *address);
84 | JvsButtons GetJvsButtonsState(bool(*buttonTestFunc)(void*));
85 | char GetKeyState();
86 |
87 | void UpdateInputBit(uint32_t bit, uint8_t keycode);
88 | };
89 | }
90 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/InputState.cpp:
--------------------------------------------------------------------------------
1 | #include "InputState.h"
2 | #include
3 | #include
4 |
5 | namespace DivaHook::Components
6 | {
7 | void InputState::ClearState()
8 | {
9 | memset(this, 0, sizeof(InputState));
10 | }
11 |
12 | void InputState::HideCursor()
13 | {
14 | MouseX = INT32_MIN;
15 | MouseY = INT32_MIN;
16 | MouseDeltaX = 0;
17 | MouseDeltaY = 0;
18 | }
19 |
20 | void InputState::SetBit(uint32_t bit, bool value, InputBufferType inputType)
21 | {
22 | uint8_t* data = GetInputBuffer(inputType);
23 |
24 | if (data == nullptr || bit < 0 || bit >= MAX_BUTTON_BIT)
25 | return;
26 |
27 | int byteIndex = (bit / 8);
28 | int bitIndex = (bit % 8);
29 |
30 | BYTE mask = (1 << bitIndex);
31 |
32 | data[byteIndex] = value ? (data[byteIndex] | mask) : (data[byteIndex] & ~mask);
33 | }
34 |
35 | uint8_t* InputState::GetInputBuffer(InputBufferType inputType)
36 | {
37 | switch (inputType)
38 | {
39 | case InputBufferType_Tapped:
40 | return (uint8_t*)&Tapped;
41 |
42 | case InputBufferType_Released:
43 | return (uint8_t*)&Released;
44 |
45 | case InputBufferType_Down:
46 | return (uint8_t*)&Down;
47 |
48 | case InputBufferType_DoubleTapped:
49 | return (uint8_t*)&DoubleTapped;
50 |
51 | case InputBufferType_IntervalTapped:
52 | return (uint8_t*)&IntervalTapped;
53 |
54 | default:
55 | return nullptr;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/InputState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "JvsButtons.h"
3 | #include "InputBufferType.h"
4 |
5 | namespace DivaHook::Components
6 | {
7 | const int MAX_BUTTON_BIT = 0x6F;
8 |
9 | // The button state is larger than the size of a register
10 | // but only the first 32 bits are used during normal gameplay
11 | // so this will provide the convenience of still being able to access them through a bit field
12 | union ButtonState
13 | {
14 | JvsButtons Buttons;
15 | uint32_t State[4];
16 | };
17 |
18 | // total sizeof() == 0x20E0
19 | struct InputState
20 | {
21 | ButtonState Tapped;
22 | ButtonState Released;
23 |
24 | ButtonState Down;
25 | uint32_t Padding_20[4];
26 |
27 | ButtonState DoubleTapped;
28 | uint32_t Padding_30[4];
29 |
30 | ButtonState IntervalTapped;
31 | uint32_t Padding_38[12];
32 |
33 | int32_t MouseX;
34 | int32_t MouseY;
35 | int32_t MouseDeltaX;
36 | int32_t MouseDeltaY;
37 |
38 | uint32_t Padding_AC[8];
39 | uint8_t Padding_D0[3];
40 | char Key;
41 |
42 | void ClearState();
43 | void HideCursor();
44 | void SetBit(uint32_t bit, bool value, InputBufferType inputType);
45 | uint8_t* GetInputBuffer(InputBufferType inputType);
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/JvsButtons.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace DivaHook::Components
5 | {
6 | enum JvsButtons : uint32_t
7 | {
8 | JVS_NONE = 0 << 0x00, // 0x0
9 |
10 | JVS_TEST = 1 << 0x00, // 0x1
11 | JVS_SERVICE = 1 << 0x01, // 0x2
12 |
13 | JVS_START = 1 << 0x02, // 0x4
14 | JVS_TRIANGLE = 1 << 0x07, // 0x80
15 | JVS_SQUARE = 1 << 0x08, // 0x100
16 | JVS_CROSS = 1 << 0x09, // 0x200
17 | JVS_CIRCLE = 1 << 0x0A, // 0x400
18 | JVS_L = 1 << 0x0B, // 0x800
19 | JVS_R = 1 << 0x0C, // 0x1000
20 |
21 | JVS_SW1 = 1 << 0x12, // 0x40000
22 | JVS_SW2 = 1 << 0x13, // 0x80000
23 | };
24 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchPanelEmulator.cpp:
--------------------------------------------------------------------------------
1 | #include "TouchPanelEmulator.h"
2 | #include
3 | #include "../ComponentsManager.h"
4 | #include "../../Constants.h"
5 | #include "../../Input/Mouse/Mouse.h"
6 | #include "../../Input/Keyboard/Keyboard.h"
7 |
8 | using namespace DivaHook::Input;
9 |
10 | namespace DivaHook::Components
11 | {
12 | TouchPanelEmulator::TouchPanelEmulator()
13 | {
14 | }
15 |
16 | TouchPanelEmulator::~TouchPanelEmulator()
17 | {
18 | }
19 |
20 | const char* TouchPanelEmulator::GetDisplayName()
21 | {
22 | return "touch_panel_emulator";
23 | }
24 |
25 | void TouchPanelEmulator::Initialize(ComponentsManager* manager)
26 | {
27 | componentsManager = manager;
28 | state = GetTouchStatePtr((void*)TASK_TOUCH_ADDRESS);
29 | }
30 |
31 | void TouchPanelEmulator::Update()
32 | {
33 | state->ConnectionState = 1;
34 | }
35 |
36 | void TouchPanelEmulator::UpdateInput()
37 | {
38 | if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || componentsManager->IsDwGuiHovered())
39 | return;
40 |
41 | // TODO: rescale TouchReaction aet position
42 | auto keyboard = Keyboard::GetInstance();
43 | auto pos = Mouse::GetInstance()->GetRelativePosition();
44 |
45 | state->XPosition = (float)pos.x;
46 | state->YPosition = (float)pos.y;
47 |
48 | bool down = keyboard->IsDown(VK_LBUTTON);
49 | bool released = keyboard->IsReleased(VK_LBUTTON);
50 |
51 | state->ContactType = (down ? 0x2 : released ? 0x1 : 0x0);
52 | state->Pressure = (float)(state->ContactType != 0);
53 | }
54 |
55 | TouchPanelState* TouchPanelEmulator::GetTouchStatePtr(void *address)
56 | {
57 | return (TouchPanelState*)address;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchPanelEmulator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../EmulatorComponent.h"
3 | #include "TouchPanelState.h"
4 |
5 | namespace DivaHook::Components
6 | {
7 | class TouchPanelEmulator : public EmulatorComponent
8 | {
9 | public:
10 | TouchPanelEmulator();
11 | ~TouchPanelEmulator();
12 |
13 | virtual const char* GetDisplayName() override;
14 |
15 | virtual void Initialize(ComponentsManager*) override;
16 | virtual void Update() override;
17 | virtual void UpdateInput() override;
18 |
19 | private:
20 | ComponentsManager* componentsManager;
21 |
22 | TouchPanelState* state;
23 | TouchPanelState* GetTouchStatePtr(void *address);
24 | };
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchPanelState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Components
4 | {
5 | struct TouchPanelState
6 | {
7 | int Padding00[0x1E];
8 | int ConnectionState;
9 | int Padding01[0x06];
10 | float XPosition;
11 | float YPosition;
12 | float Pressure;
13 | int ContactType;
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchSliderEmulator.cpp:
--------------------------------------------------------------------------------
1 | #include "TouchSliderEmulator.h"
2 | #include "../ComponentsManager.h"
3 | #include "../../Constants.h"
4 | #include "../../MainModule.h"
5 | #include "../../Input/Mouse/Mouse.h"
6 | #include "../../Input/Keyboard/Keyboard.h"
7 | #include "../../Input/Bindings/KeyboardBinding.h"
8 | #include "../../Input/KeyConfig/Config.h"
9 | #include "../../FileSystem/ConfigFile.h"
10 | #include "../../Utilities/Math.h"
11 | #include
12 | #include
13 |
14 | using namespace DivaHook::Input;
15 | using namespace DivaHook::Input::KeyConfig;
16 | using namespace DivaHook::Utilities;
17 |
18 | namespace DivaHook::Components
19 | {
20 | const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
21 |
22 | TouchSliderEmulator::TouchSliderEmulator()
23 | {
24 | }
25 |
26 | TouchSliderEmulator::~TouchSliderEmulator()
27 | {
28 | delete LeftSideSlideLeft;
29 | delete LeftSideSlideRight;
30 |
31 | delete RightSideSlideLeft;
32 | delete RightSideSlideRight;
33 | }
34 |
35 | const char* TouchSliderEmulator::GetDisplayName()
36 | {
37 | return "touch_slider_emulator";
38 | }
39 |
40 | void TouchSliderEmulator::Initialize(ComponentsManager* manager)
41 | {
42 | componentsManager = manager;
43 | sliderState = (TouchSliderState*)SLIDER_CTRL_TASK_ADDRESS;
44 |
45 | LeftSideSlideLeft = new Binding();
46 | LeftSideSlideRight = new Binding();
47 |
48 | RightSideSlideLeft = new Binding();
49 | RightSideSlideRight = new Binding();
50 |
51 | FileSystem::ConfigFile configFile(MainModule::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
52 | configFile.OpenRead();
53 |
54 | Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" });
55 | Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
56 |
57 | Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" });
58 | Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" });
59 |
60 | float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed");
61 |
62 | if (touchSliderEmulationSpeed != 0.0f)
63 | sliderSpeed = touchSliderEmulationSpeed;
64 | }
65 |
66 | void TouchSliderEmulator::Update()
67 | {
68 | sliderState->State = SLIDER_OK;
69 | }
70 |
71 | void TouchSliderEmulator::UpdateInput()
72 | {
73 | if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive())
74 | return;
75 |
76 | sliderIncrement = GetElapsedTime() / sliderSpeed;
77 |
78 | constexpr float sensorStep = (1.0f / SLIDER_SENSORS);
79 |
80 | EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f);
81 | EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep);
82 |
83 | sliderState->ResetSensors();
84 |
85 | for (int i = 0; i < CONTACT_POINTS; i++)
86 | ApplyContactPoint(ContactPoints[i], i);
87 | }
88 |
89 | void TouchSliderEmulator::OnFocusLost()
90 | {
91 | sliderState->ResetSensors();
92 | }
93 |
94 | void TouchSliderEmulator::EmulateSliderInput(Binding *leftBinding, Binding *rightBinding, ContactPoint &contactPoint, float start, float end)
95 | {
96 | bool leftDown = leftBinding->AnyDown();
97 | bool rightDown = rightBinding->AnyDown();
98 |
99 | if (leftDown)
100 | contactPoint.Position -= sliderIncrement;
101 | else if (rightDown)
102 | contactPoint.Position += sliderIncrement;
103 |
104 | if (contactPoint.Position < start)
105 | contactPoint.Position = end;
106 |
107 | if (contactPoint.Position > end)
108 | contactPoint.Position = start;
109 |
110 | bool leftTapped = leftBinding->AnyTapped();
111 | bool rightTapped = rightBinding->AnyTapped();
112 |
113 | if (leftTapped || rightTapped)
114 | contactPoint.Position = (start + end) / 2.0f;
115 |
116 | contactPoint.InContact = leftDown || rightDown;
117 | }
118 |
119 | void TouchSliderEmulator::ApplyContactPoint(ContactPoint &contactPoint, int section)
120 | {
121 | sliderState->SectionTouched[section] = contactPoint.InContact;
122 |
123 | int pressure = contactPoint.InContact ? FULL_PRESSURE : NO_PRESSURE;
124 | float position = std::clamp(contactPoint.Position, 0.0f, 1.0f);
125 |
126 | if (contactPoint.InContact)
127 | {
128 | int sensor = (int)(position * (SLIDER_SENSORS - 1));
129 |
130 | sliderState->SetSensor(sensor, pressure);
131 | }
132 |
133 | constexpr float startRange = -1.0f;
134 | constexpr float endRange = +1.0f;
135 |
136 | sliderState->SectionPositions[section] = contactPoint.InContact ? (ConvertRange(0.0f, 1.0f, startRange, endRange, position)) : 0.0f;
137 | }
138 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchSliderEmulator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../EmulatorComponent.h"
3 | #include "TouchSliderState.h"
4 | #include "../../Input/Bindings/Binding.h"
5 |
6 | namespace DivaHook::Components
7 | {
8 | constexpr int SLIDER_INPUTS = 4;
9 | constexpr int CONTACT_POINTS = 2;
10 |
11 | struct ContactPoint
12 | {
13 | float Position;
14 | bool InContact;
15 | };
16 |
17 | class TouchSliderEmulator : public EmulatorComponent
18 | {
19 | public:
20 | Input::Binding* LeftSideSlideLeft;
21 | Input::Binding* LeftSideSlideRight;
22 |
23 | Input::Binding* RightSideSlideLeft;
24 | Input::Binding* RightSideSlideRight;
25 |
26 | TouchSliderEmulator();
27 | ~TouchSliderEmulator();
28 |
29 | virtual const char* GetDisplayName() override;
30 |
31 | virtual void Initialize(ComponentsManager*) override;
32 | virtual void Update() override;
33 | virtual void UpdateInput() override;
34 |
35 | virtual void OnFocusLost() override;
36 |
37 | private:
38 | ComponentsManager* componentsManager;
39 | float sliderSpeed = 750.0f;
40 | float sliderIncrement;
41 |
42 | TouchSliderState *sliderState;
43 | ContactPoint ContactPoints[CONTACT_POINTS];
44 |
45 | void EmulateSliderInput(Input::Binding *leftBinding, Input::Binding *rightBinding, ContactPoint &contactPoint, float start, float end);
46 | void ApplyContactPoint(ContactPoint &contactPoint, int section);
47 | };
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchSliderState.cpp:
--------------------------------------------------------------------------------
1 | #include "TouchSliderState.h"
2 |
3 | namespace DivaHook::Components
4 | {
5 | void TouchSliderState::SetSensor(int index, int value)
6 | {
7 | if (index < 0 || index >= SLIDER_SENSORS)
8 | return;
9 |
10 | SensorPressureLevels[index] = value;
11 | SensorTouched[index].IsTouched = value > 0;
12 | }
13 |
14 | void TouchSliderState::ResetSensors()
15 | {
16 | for (int i = 0; i < SLIDER_SENSORS; i++)
17 | SetSensor(i, NO_PRESSURE);
18 | }
19 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/Input/TouchSliderState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #define SLIDER_OK 3
5 | #define SLIDER_SECTIONS 4
6 | #define SLIDER_SENSORS 32
7 |
8 | #define NO_PRESSURE 0
9 | #define FULL_PRESSURE 180
10 |
11 | namespace DivaHook::Components
12 | {
13 | struct TouchSliderState
14 | {
15 | uint8_t Padding0000[112];
16 |
17 | int32_t State;
18 |
19 | uint8_t Padding0074[20 + 12];
20 |
21 | int32_t SensorPressureLevels[SLIDER_SENSORS];
22 |
23 | uint8_t Padding0108[52 - 12];
24 |
25 | float SectionPositions[SLIDER_SECTIONS];
26 | int SectionConnections[SLIDER_SECTIONS];
27 | uint8_t Padding015C[4];
28 | bool SectionTouched[SLIDER_SECTIONS];
29 |
30 | uint8_t Padding013C[3128 - 52 - 40];
31 |
32 | struct
33 | {
34 | uint8_t Padding00[2];
35 | bool IsTouched;
36 | uint8_t Padding[45];
37 | } SensorTouched[SLIDER_SENSORS];
38 |
39 | void SetSensor(int index, int value);
40 | void ResetSensors();
41 | };
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/PlayerData.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | struct PlayerData
5 | {
6 | int8_t use_card;
7 | int8_t freeplay;
8 | int8_t field_2;
9 | int8_t field_3;
10 | int32_t card_type;
11 | int32_t field_8;
12 | int32_t field_C;
13 | int32_t field_10;
14 | int32_t field_14;
15 | int32_t field_18;
16 | int32_t field_1C;
17 | int32_t field_20;
18 | int32_t field_24;
19 | int32_t field_28;
20 | int32_t field_2C;
21 | int32_t field_30;
22 | int32_t field_34;
23 | int32_t field_38;
24 | int32_t field_3C;
25 | int32_t field_40;
26 | int32_t field_44;
27 | int32_t field_48;
28 | int32_t field_4C;
29 | int32_t field_50;
30 | int32_t field_54;
31 | int32_t field_58;
32 | int32_t field_5C;
33 | int32_t field_60;
34 | int32_t field_64;
35 | int32_t field_68;
36 | int32_t field_6C;
37 | int32_t field_70;
38 | int32_t field_74;
39 | int32_t field_78;
40 | int32_t field_7C;
41 | int32_t field_80;
42 | int32_t field_84;
43 | int32_t field_88;
44 | int32_t field_8C;
45 | int32_t field_90;
46 | int32_t field_94;
47 | int32_t field_98;
48 | int32_t field_9C;
49 | int32_t field_A0;
50 | int32_t field_A4;
51 | int32_t field_A8;
52 | int32_t field_AC;
53 | int32_t field_B0;
54 | int32_t field_B4;
55 | int32_t field_B8;
56 | int32_t field_BC;
57 | int32_t field_C0;
58 | int32_t field_C4;
59 | int32_t field_C8;
60 | int32_t field_CC;
61 | int32_t play_data_id;
62 | int32_t accept_index;
63 | int32_t start_index;
64 | int32_t field_DC;
65 | char* player_name;
66 | int32_t field_E8;
67 | int32_t field_EC;
68 | int32_t field_F0;
69 | int32_t field_F4;
70 | int32_t field_F8;
71 | int32_t field_FC;
72 | char* level_name;
73 | int32_t field_108;
74 | int32_t field_10C;
75 | int32_t field_110;
76 | int32_t field_114;
77 | int32_t field_118;
78 | int32_t field_11C;
79 | int32_t field_120;
80 | int32_t level_plate_id;
81 | int32_t field_128;
82 | int32_t vocaloid_point;
83 | int32_t hp_vol;
84 | int32_t act_toggle;
85 | int32_t act_vol;
86 | int32_t act_slide_vol;
87 | int32_t field_140;
88 | int32_t field_144;
89 | int32_t field_148;
90 | int32_t field_14C;
91 | int32_t field_150;
92 | int32_t field_154;
93 | int32_t field_158;
94 | int32_t field_15C;
95 | int32_t field_160;
96 | int32_t field_164;
97 | int32_t field_168;
98 | int32_t field_16C;
99 | int32_t field_170;
100 | int32_t field_174;
101 | int32_t field_178;
102 | int32_t field_17C;
103 | int32_t field_180;
104 | int32_t field_184;
105 | int32_t field_188;
106 | int32_t field_18C;
107 | int32_t field_190;
108 | int32_t field_194;
109 | int32_t field_198;
110 | int32_t field_19C;
111 | int32_t field_1A0;
112 | int32_t field_1A4;
113 | int32_t field_1A8;
114 | int32_t field_1AC;
115 | int32_t field_1B0;
116 | int32_t field_1B4;
117 | int32_t field_1B8;
118 | int32_t field_1BC;
119 | int32_t field_1C0;
120 | int32_t field_1C4;
121 | int32_t field_1C8;
122 | int32_t field_1CC;
123 | int32_t field_1D0;
124 | int32_t field_1D4;
125 | int32_t field_1D8;
126 | int32_t field_1DC;
127 | int32_t field_1E0;
128 | int32_t field_1E4;
129 | int32_t field_1E8;
130 | int32_t field_1EC;
131 | int32_t field_1F0;
132 | int32_t field_1F4;
133 | int32_t field_1F8;
134 | int32_t field_1FC;
135 | int32_t field_200;
136 | int32_t field_204;
137 | int32_t field_208;
138 | int32_t field_20C;
139 | int32_t field_210;
140 | int32_t field_214;
141 | int32_t field_218;
142 | int32_t field_21C;
143 | int32_t field_220;
144 | int32_t field_224;
145 | int32_t field_228;
146 | int32_t field_22C;
147 | int32_t field_230;
148 | int32_t field_234;
149 | int32_t field_238;
150 | int32_t field_23C;
151 | int32_t field_240;
152 | int32_t field_244;
153 | int32_t field_248;
154 | int32_t field_24C;
155 | int32_t field_250;
156 | int32_t field_254;
157 | int32_t field_258;
158 | int32_t field_25C;
159 | int32_t field_260;
160 | int32_t field_264;
161 | int32_t field_268;
162 | int32_t field_26C;
163 | int32_t field_270;
164 | int32_t field_274;
165 | int32_t field_278;
166 | int32_t field_27C;
167 | int32_t field_280;
168 | int32_t field_284;
169 | int32_t field_288;
170 | int32_t field_28C;
171 | int32_t field_290;
172 | int32_t field_294;
173 | int32_t field_298;
174 | int32_t field_29C;
175 | int32_t field_2A0;
176 | int32_t field_2A4;
177 | int32_t field_2A8;
178 | int32_t field_2AC;
179 | int8_t use_pv_module_equip;
180 | int8_t ch_pv_module_equip;
181 | int8_t field_2B2;
182 | int8_t field_2B3;
183 | int32_t module_filter_kind;
184 | int32_t field_2B8;
185 | int32_t field_2BC;
186 | int32_t field_2C0;
187 | int32_t field_2C4;
188 | int32_t field_2C8;
189 | int32_t field_2CC;
190 | int32_t field_2D0;
191 | int32_t field_2D4;
192 | int32_t field_2D8;
193 | int32_t field_2DC;
194 | int32_t field_2E0;
195 | int32_t field_2E4;
196 | int32_t field_2E8;
197 | int32_t field_2EC;
198 | int32_t field_2F0;
199 | int32_t field_2F4;
200 | int32_t field_2F8;
201 | int32_t field_2FC;
202 | int32_t field_300;
203 | int32_t field_304;
204 | int32_t field_308;
205 | int32_t field_30C;
206 | int32_t field_310;
207 | int32_t field_314;
208 | int32_t field_318;
209 | int32_t field_31C;
210 | int32_t field_320;
211 | int32_t field_324;
212 | int32_t field_328;
213 | int32_t field_32C;
214 | int32_t field_330;
215 | int32_t field_334;
216 | int32_t field_338;
217 | int32_t field_33C;
218 | int32_t field_340;
219 | int32_t field_344;
220 | int32_t field_348;
221 | int32_t field_34C;
222 | int32_t field_350;
223 | int32_t field_354;
224 | int32_t field_358;
225 | int32_t field_35C;
226 | int32_t field_360;
227 | int32_t field_364;
228 | int32_t field_368;
229 | int32_t field_36C;
230 | int32_t field_370;
231 | int32_t field_374;
232 | int32_t field_378;
233 | int32_t field_37C;
234 | int32_t field_380;
235 | int32_t field_384;
236 | int32_t field_388;
237 | int32_t field_38C;
238 | int32_t field_390;
239 | int32_t field_394;
240 | int32_t field_398;
241 | int32_t field_39C;
242 | int32_t field_3A0;
243 | int32_t field_3A4;
244 | int32_t field_3A8;
245 | int32_t field_3AC;
246 | int32_t field_3B0;
247 | int32_t field_3B4;
248 | int32_t field_3B8;
249 | int32_t field_3BC;
250 | int32_t field_3C0;
251 | int32_t field_3C4;
252 | int32_t field_3C8;
253 | int32_t field_3CC;
254 | int32_t field_3D0;
255 | int32_t field_3D4;
256 | int32_t field_3D8;
257 | int32_t field_3DC;
258 | int32_t field_3E0;
259 | int32_t field_3E4;
260 | int32_t field_3E8;
261 | int32_t field_3EC;
262 | int32_t field_3F0;
263 | int32_t field_3F4;
264 | int32_t field_3F8;
265 | int32_t field_3FC;
266 | int32_t field_400;
267 | int32_t field_404;
268 | int32_t field_408;
269 | int32_t field_40C;
270 | int32_t field_410;
271 | int32_t field_414;
272 | int32_t field_418;
273 | int32_t field_41C;
274 | int32_t field_420;
275 | int32_t field_424;
276 | int32_t field_428;
277 | int32_t field_42C;
278 | int32_t field_430;
279 | int32_t field_434;
280 | int32_t field_438;
281 | int32_t field_43C;
282 | int32_t field_440;
283 | int32_t field_444;
284 | int32_t field_448;
285 | int32_t field_44C;
286 | int32_t field_450;
287 | int32_t field_454;
288 | int32_t field_458;
289 | int32_t field_45C;
290 | int32_t field_460;
291 | int32_t field_464;
292 | int32_t field_468;
293 | int32_t field_46C;
294 | int32_t field_470;
295 | int32_t field_474;
296 | int32_t field_478;
297 | int32_t field_47C;
298 | int32_t field_480;
299 | int32_t field_484;
300 | int32_t field_488;
301 | int32_t field_48C;
302 | int32_t field_490;
303 | int32_t field_494;
304 | int32_t field_498;
305 | int32_t field_49C;
306 | int32_t field_4A0;
307 | int32_t field_4A4;
308 | int32_t field_4A8;
309 | int32_t field_4AC;
310 | int32_t field_4B0;
311 | int32_t field_4B4;
312 | int32_t field_4B8;
313 | int32_t field_4BC;
314 | int32_t field_4C0;
315 | int32_t field_4C4;
316 | int32_t field_4C8;
317 | int32_t field_4CC;
318 | int32_t field_4D0;
319 | int32_t field_4D4;
320 | int32_t field_4D8;
321 | int32_t field_4DC;
322 | int32_t field_4E0;
323 | int32_t field_4E4;
324 | int32_t field_4E8;
325 | int32_t field_4EC;
326 | int32_t field_4F0;
327 | int32_t field_4F4;
328 | int32_t field_4F8;
329 | int32_t field_4FC;
330 | int32_t field_500;
331 | int32_t field_504;
332 | int32_t field_508;
333 | int32_t field_50C;
334 | int32_t field_510;
335 | int32_t field_514;
336 | int32_t field_518;
337 | int32_t field_51C;
338 | int32_t field_520;
339 | int32_t field_524;
340 | int32_t field_528;
341 | int32_t field_52C;
342 | int32_t field_530;
343 | int32_t field_534;
344 | int32_t field_538;
345 | int32_t field_53C;
346 | int32_t field_540;
347 | int32_t field_544;
348 | int32_t skin_equip;
349 | int32_t skin_equip_cmn;
350 | int32_t use_pv_skin_equip;
351 | int32_t btn_se_equip;
352 | int32_t btn_se_equip_cmn;
353 | int32_t use_pv_btn_se_equip;
354 | int32_t slide_se_equip;
355 | int32_t slide_se_equip_cmn;
356 | int32_t use_pv_slide_se_equip;
357 | int32_t chainslide_se_equip;
358 | int32_t chainslide_se_equip_cmn;
359 | int32_t use_pv_chainslide_se_equip;
360 | int32_t slidertouch_se_equip;
361 | int32_t slidertouch_se_equip_cmn;
362 | int32_t use_pv_slidertouch_se_equip;
363 | int32_t field_584;
364 | int32_t field_588;
365 | int32_t field_58C;
366 | int32_t field_590;
367 | int32_t field_594;
368 | int32_t field_598;
369 | int32_t field_59C;
370 | int32_t field_5A0;
371 | int32_t field_5A4;
372 | int32_t field_5A8;
373 | int32_t field_5AC;
374 | int32_t field_5B0;
375 | int32_t field_5B4;
376 | int32_t field_5B8;
377 | int32_t field_5BC;
378 | int32_t field_5C0;
379 | int32_t field_5C4;
380 | int32_t field_5C8;
381 | int32_t field_5CC;
382 | int32_t field_5D0;
383 | int32_t field_5D4;
384 | int32_t field_5D8;
385 | int32_t field_5DC;
386 | int32_t field_5E0;
387 | int32_t field_5E4;
388 | int32_t field_5E8;
389 | int32_t field_5EC;
390 | int32_t field_5F0;
391 | int32_t field_5F4;
392 | int32_t field_5F8;
393 | int32_t field_5FC;
394 | int32_t field_600;
395 | int32_t field_604;
396 | int32_t field_608;
397 | int32_t field_60C;
398 | int32_t field_610;
399 | int32_t field_614;
400 | int32_t field_618;
401 | int32_t field_61C;
402 | int32_t field_620;
403 | int32_t field_624;
404 | int32_t field_628;
405 | int32_t field_62C;
406 | int32_t field_630;
407 | };
--------------------------------------------------------------------------------
/DivaHook/src/Components/PlayerDataManager.cpp:
--------------------------------------------------------------------------------
1 | #include "PlayerDataManager.h"
2 | #include
3 | #include "../MainModule.h"
4 | #include "../Constants.h"
5 | #include "../Input/Keyboard/Keyboard.h"
6 | #include "../FileSystem/ConfigFile.h"
7 | #include "../Constants.h"
8 |
9 | const std::string PLAYER_DATA_FILE_NAME = "playerdata.ini";
10 |
11 | namespace DivaHook::Components
12 | {
13 | PlayerDataManager::PlayerDataManager()
14 | {
15 | }
16 |
17 | PlayerDataManager::~PlayerDataManager()
18 | {
19 | if (customPlayerData != nullptr)
20 | delete customPlayerData;
21 | }
22 |
23 | const char* PlayerDataManager::GetDisplayName()
24 | {
25 | return "player_data_manager";
26 | }
27 |
28 | void PlayerDataManager::Initialize(ComponentsManager*)
29 | {
30 | playerData = (PlayerData*)PLAYER_DATA_ADDRESS;
31 |
32 | ApplyPatch();
33 | LoadConfig();
34 | ApplyCustomData();
35 | }
36 |
37 | void PlayerDataManager::Update()
38 | {
39 | ApplyCustomData();
40 |
41 | if (false && Input::Keyboard::GetInstance()->IsTapped(VK_F12))
42 | {
43 | printf("PlayerDataManager::Update(): Loading config...\n");
44 | LoadConfig();
45 | }
46 | }
47 |
48 | void PlayerDataManager::ApplyPatch()
49 | {
50 | DWORD oldProtect;
51 | VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
52 | {
53 | // prevent the PlayerData from being reset
54 | *(uint8_t*)(SET_DEFAULT_PLAYER_DATA_ADDRESS) = RET_OPCODE;
55 | }
56 | VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), oldProtect, &oldProtect);
57 | }
58 |
59 | void PlayerDataManager::LoadConfig()
60 | {
61 | if (playerData == nullptr)
62 | return;
63 |
64 | FileSystem::ConfigFile config(MainModule::GetModuleDirectory(), PLAYER_DATA_FILE_NAME);
65 |
66 | if (!config.OpenRead())
67 | return;
68 |
69 | if (customPlayerData != nullptr)
70 | delete customPlayerData;
71 |
72 | customPlayerData = new CustomPlayerData();
73 | config.TryGetValue("player_name", &customPlayerData->PlayerName);
74 |
75 | customPlayerData->LevelPlateId = config.GetIntegerValue("level_plate_id");
76 | customPlayerData->SkinEquip = config.GetIntegerValue("skin_equip");
77 | customPlayerData->BtnSeEquip = config.GetIntegerValue("btn_se_equip");
78 | customPlayerData->SlideSeEquip = config.GetIntegerValue("slide_se_equip");
79 | customPlayerData->ChainslideSeEquip = config.GetIntegerValue("chainslide_se_equip");
80 | }
81 |
82 | void PlayerDataManager::ApplyCustomData()
83 | {
84 | // don't want to overwrite the default values
85 | auto setIfNotEqual = [](int *target, int value, int comparison)
86 | {
87 | if (value != comparison)
88 | *target = value;
89 | };
90 |
91 | setIfNotEqual(&playerData->level_plate_id, customPlayerData->LevelPlateId, 0);
92 | setIfNotEqual(&playerData->skin_equip, customPlayerData->SkinEquip, 0);
93 | setIfNotEqual(&playerData->btn_se_equip, customPlayerData->BtnSeEquip, -1);
94 | setIfNotEqual(&playerData->slide_se_equip, customPlayerData->SlideSeEquip, -1);
95 | setIfNotEqual(&playerData->chainslide_se_equip, customPlayerData->ChainslideSeEquip, -1);
96 |
97 | if (customPlayerData->PlayerName != nullptr)
98 | {
99 | playerData->field_DC = 0x10;
100 | playerData->player_name = (char*)customPlayerData->PlayerName->c_str();
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/PlayerDataManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 | #include "PlayerData.h"
4 | #include "CustomPlayerData.h"
5 | #include
6 |
7 | namespace DivaHook::Components
8 | {
9 | class PlayerDataManager : public EmulatorComponent
10 | {
11 | public:
12 | PlayerDataManager();
13 | ~PlayerDataManager();
14 |
15 | virtual const char* GetDisplayName() override;
16 |
17 | virtual void Initialize(ComponentsManager*) override;
18 | virtual void Update() override;
19 |
20 | private:
21 | PlayerData* playerData;
22 | CustomPlayerData* customPlayerData;
23 |
24 | void ApplyPatch();
25 | void LoadConfig();
26 | void ApplyCustomData();
27 | };
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/StageManager.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samyuu/TotallyLegitArcadeController/327265b0e9c6c7e26d1bc5516e7293b02b7fef0e/DivaHook/src/Components/StageManager.cpp
--------------------------------------------------------------------------------
/DivaHook/src/Components/StageManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 | #include
4 |
5 | namespace DivaHook::Components
6 | {
7 | class StageManager : public EmulatorComponent
8 | {
9 | public:
10 | StageManager();
11 | ~StageManager();
12 |
13 | virtual const char* GetDisplayName() override;
14 |
15 | virtual void Initialize(ComponentsManager*) override;
16 | virtual void Update() override;
17 |
18 | private:
19 | int32_t GetPlayCount();
20 | };
21 | }
--------------------------------------------------------------------------------
/DivaHook/src/Components/SysTimer.cpp:
--------------------------------------------------------------------------------
1 | #include "SysTimer.h"
2 | #include "../Constants.h"
3 |
4 | namespace DivaHook::Components
5 | {
6 | SysTimer::SysTimer()
7 | {
8 | }
9 |
10 | SysTimer::~SysTimer()
11 | {
12 | }
13 |
14 | const char* SysTimer::GetDisplayName()
15 | {
16 | return "sys_timer";
17 | }
18 |
19 | void SysTimer::Initialize(ComponentsManager*)
20 | {
21 | selPvTime = GetSysTimePtr((void*)SEL_PV_TIME_ADDRESS);
22 | }
23 |
24 | void SysTimer::Update()
25 | {
26 | // account for the decrement that occures during this frame
27 | *selPvTime = SEL_PV_FREEZE_TIME * SYS_TIME_FACTOR + 1;
28 | }
29 |
30 | int* SysTimer::GetSysTimePtr(void *address)
31 | {
32 | return (int*)address;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/DivaHook/src/Components/SysTimer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "EmulatorComponent.h"
3 |
4 | namespace DivaHook::Components
5 | {
6 | class SysTimer : public EmulatorComponent
7 | {
8 | const int SYS_TIME_FACTOR = 60;
9 | const int SEL_PV_FREEZE_TIME = 39;
10 |
11 | public:
12 | SysTimer();
13 | ~SysTimer();
14 |
15 | virtual const char* GetDisplayName() override;
16 |
17 | virtual void Initialize(ComponentsManager*) override;
18 | virtual void Update() override;
19 |
20 | private:
21 | int* selPvTime;
22 | int* GetSysTimePtr(void *address);
23 | };
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/DivaHook/src/Constants.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | constexpr uint8_t NOP_OPCODE = 0x90;
5 | constexpr uint8_t RET_OPCODE = 0xC3;
6 | constexpr uint8_t JMP_OPCODE = 0xE9;
7 |
8 | constexpr uint64_t ENGINE_UPDATE_HOOK_TARGET_ADDRESS = 0x000000014018CC40;
9 | constexpr uint64_t ENGINE_UPDATE_INPUT_ADDRESS = 0x000000014018CBB0;
10 |
11 | constexpr uint64_t CURRENT_GAME_STATE_ADDRESS = 0x0000000140EDA810;
12 | constexpr uint64_t RESOLUTION_WIDTH_ADDRESS = 0x0000000140EDA8BC;
13 | constexpr uint64_t RESOLUTION_HEIGHT_ADDRESS = 0x0000000140EDA8C0;
14 |
15 | constexpr uint64_t SYSTEM_WARNING_ELAPSED_ADDRESS = (0x00000001411A1430 + 0x68);
16 | constexpr uint64_t DATA_INIT_STATE_ADDRESS = 0x0000000140EDA7A8;
17 |
18 | constexpr uint64_t AET_FRAME_DURATION_ADDRESS = 0x00000001409A0A58;
19 | constexpr uint64_t PV_FRAME_RATE_ADDRESS = 0x0000000140EDA7CC;
20 | constexpr uint64_t FRAME_SPEED_ADDRESS = 0x0000000140EDA798;
21 | constexpr uint64_t FRAME_RATE_ADDRESS = 0x0000000140EDA6D0;
22 |
23 | constexpr uint64_t DW_GUI_DISPLAY_INSTANCE_PTR_ADDRESS = 0x0000000141190108;
24 | constexpr uint64_t INPUT_STATE_PTR_ADDRESS = 0x0000000140EDA330;
25 | constexpr uint64_t SLIDER_CTRL_TASK_ADDRESS = 0x000000014CC5DE40;
26 | constexpr uint64_t TASK_TOUCH_ADDRESS = 0x000000014CC9EC30;
27 | constexpr uint64_t SEL_PV_TIME_ADDRESS = 0x000000014CC12498;
28 | constexpr uint64_t PLAYER_DATA_ADDRESS = 0x00000001411A8850;
29 | constexpr uint64_t SET_DEFAULT_PLAYER_DATA_ADDRESS = 0x00000001404A7370;
30 | constexpr uint64_t PLAYS_PER_SESSION_GETTER_ADDRESS = 0x000000014038AEE0;
31 | constexpr uint64_t PV_SEL_SLOTS_TO_SCROLL = 0x000000014CC12470;
32 |
33 | constexpr uint64_t CAMERA_ADDRESS = 0x0000000140FBC2C0;
34 | constexpr uint64_t CAMERA_POS_SETTER_ADDRESS = 0x00000001401F9460;
35 | constexpr uint64_t CAMERA_INTR_SETTER_ADDRESS = 0x00000001401F93F0;
36 | constexpr uint64_t CAMERA_ROT_SETTER_ADDRESS = 0x00000001401F9480;
37 | constexpr uint64_t CAMERA_PERS_SETTER_ADDRESS = 0x00000001401F9430;
38 |
39 | constexpr uint64_t UPDATE_TASKS_ADDRESS = 0x000000014019B980;
40 | constexpr uint64_t GLUT_SET_CURSOR_ADDRESS = 0x00000001408B68E6;
41 | constexpr uint64_t CHANGE_MODE_ADDRESS = 0x00000001401953D0;
42 | constexpr uint64_t CHANGE_SUB_MODE_ADDRESS = 0x0000000140195260;
--------------------------------------------------------------------------------
/DivaHook/src/FileSystem/ConfigFile.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "ConfigFile.h"
3 | #include "../Utilities/Operations.h"
4 |
5 | namespace DivaHook::FileSystem
6 | {
7 | ConfigFile::ConfigFile(const std::string &path) : TextFile(path)
8 | {
9 | return;
10 | }
11 |
12 | ConfigFile::ConfigFile(const std::string &directory, const std::string &file) : TextFile(directory, file)
13 | {
14 | return;
15 | }
16 |
17 | bool ConfigFile::TryGetValue(const std::string &key, std::string **value)
18 | {
19 | auto pair = ConfigMap.find(key);
20 | bool found = pair != ConfigMap.end();
21 |
22 | *value = found ? new std::string(pair->second) : nullptr;
23 | return found;
24 | }
25 |
26 | int ConfigFile::GetIntegerValue(const std::string& key)
27 | {
28 | auto pair = ConfigMap.find(key);
29 | bool found = pair != ConfigMap.end();
30 |
31 | return found ? atoi(pair->second.c_str()) : 0;
32 | }
33 |
34 | bool ConfigFile::GetBooleanValue(const std::string& key)
35 | {
36 | auto pair = ConfigMap.find(key);
37 | bool found = pair != ConfigMap.end();
38 |
39 | return found ? pair->second == "true" : false;
40 | }
41 |
42 | float ConfigFile::GetFloatValue(const std::string & key)
43 | {
44 | auto pair = ConfigMap.find(key);
45 | bool found = pair != ConfigMap.end();
46 |
47 | return found ? (float)atof(pair->second.c_str()) : 0.0f;
48 | }
49 |
50 | void ConfigFile::Parse(std::ifstream &fileStream)
51 | {
52 | std::string line;
53 |
54 | while (std::getline(fileStream, line))
55 | {
56 | if (IsComment(line))
57 | continue;
58 |
59 | auto splitline = Utilities::Split(line, "=");
60 |
61 | for (auto &line : splitline)
62 | Utilities::Trim(line);
63 |
64 | ConfigMap.insert(std::make_pair(splitline[0], splitline[1]));
65 | }
66 | }
67 |
68 | bool ConfigFile::IsComment(const std::string &line)
69 | {
70 | return line.size() <= 0 || line[0] == '#' || line._Starts_with("//");
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/DivaHook/src/FileSystem/ConfigFile.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "TextFile.h"
4 | #include
5 |
6 | namespace DivaHook::FileSystem
7 | {
8 | class ConfigFile : public TextFile
9 | {
10 | public:
11 | ConfigFile(const std::string &path);
12 | ConfigFile(const std::string &directory, const std::string &file);
13 |
14 | std::unordered_map ConfigMap;
15 |
16 | bool TryGetValue(const std::string &key, std::string **value);
17 | int GetIntegerValue(const std::string& key);
18 | bool GetBooleanValue(const std::string& key);
19 | float GetFloatValue(const std::string& key);
20 |
21 | protected:
22 | virtual void Parse(std::ifstream &fileStream) override;
23 |
24 | private:
25 | bool IsComment(const std::string &line);
26 | };
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/DivaHook/src/FileSystem/TextFile.cpp:
--------------------------------------------------------------------------------
1 | #include "TextFile.h"
2 | #include
3 |
4 | namespace fs = std::filesystem;
5 |
6 | namespace DivaHook::FileSystem
7 | {
8 | TextFile::TextFile(const std::string &path)
9 | {
10 | FileName = path;
11 | }
12 |
13 | TextFile::TextFile(const std::string &directory, const std::string &file)
14 | {
15 | auto fullPath = directory + "/" + file;
16 | FileName = fullPath;
17 | }
18 |
19 | TextFile::~TextFile()
20 | {
21 | }
22 |
23 | bool TextFile::OpenRead()
24 | {
25 | fs::path configPath(FileName);
26 |
27 | if (!fs::exists(configPath))
28 | return false;
29 |
30 | std::ifstream fileStream(configPath.string().c_str());
31 |
32 | if (!fileStream.is_open())
33 | return false;
34 |
35 | Parse(fileStream);
36 |
37 | fileStream.close();
38 |
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/DivaHook/src/FileSystem/TextFile.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace DivaHook::FileSystem
7 | {
8 | class TextFile
9 | {
10 | public:
11 | std::string FileName;
12 |
13 | TextFile(const std::string &path);
14 | TextFile(const std::string &directory, const std::string &file);
15 | ~TextFile();
16 |
17 | bool OpenRead();
18 |
19 | protected:
20 | virtual void Parse(std::ifstream &fileStream) = 0;
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/Binding.cpp:
--------------------------------------------------------------------------------
1 | #include "Binding.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | Binding::Binding()
6 | {
7 | }
8 |
9 | Binding::~Binding()
10 | {
11 | for (auto& binding : InputBindings)
12 | delete binding;
13 | }
14 |
15 | void Binding::AddBinding(IInputBinding* inputBinding)
16 | {
17 | InputBindings.push_back(inputBinding);
18 | }
19 |
20 | bool Binding::AnyDown()
21 | {
22 | for (const auto& binding : InputBindings)
23 | {
24 | if (binding->IsDown())
25 | return true;
26 | }
27 |
28 | return false;
29 | }
30 |
31 | bool Binding::AnyTapped()
32 | {
33 | for (const auto& binding : InputBindings)
34 | {
35 | if (binding->IsTapped())
36 | return true;
37 | }
38 |
39 | return false;
40 | }
41 |
42 | bool Binding::AnyReleased()
43 | {
44 | for (const auto& binding : InputBindings)
45 | {
46 | if (binding->IsReleased())
47 | return true;
48 | }
49 |
50 | return false;
51 | }
52 |
53 | int Binding::GetDownCount()
54 | {
55 | int count = 0;
56 |
57 | for (const auto& binding : InputBindings)
58 | {
59 | if (binding->IsDown())
60 | count++;
61 | }
62 |
63 | return count;
64 | }
65 |
66 | int Binding::GetTappedCount()
67 | {
68 | int count = 0;
69 |
70 | for (const auto& binding : InputBindings)
71 | {
72 | if (binding->IsTapped())
73 | count++;
74 | }
75 |
76 | return count;
77 | }
78 |
79 | int Binding::GetReleasedCount()
80 | {
81 | int count = 0;
82 |
83 | for (const auto& binding : InputBindings)
84 | {
85 | if (binding->IsReleased())
86 | count++;
87 | }
88 |
89 | return count;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/Binding.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include "IInputBinding.h"
4 |
5 | namespace DivaHook::Input
6 | {
7 | class Binding
8 | {
9 | public:
10 | std::vector InputBindings;
11 |
12 | Binding();
13 | ~Binding();
14 |
15 | void AddBinding(IInputBinding* inputBinding);
16 |
17 | bool AnyDown();
18 | bool AnyTapped();
19 | bool AnyReleased();
20 |
21 | int GetDownCount();
22 | int GetTappedCount();
23 | int GetReleasedCount();
24 | };
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/Ds4Binding.cpp:
--------------------------------------------------------------------------------
1 | #include "Ds4Binding.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | #define Ds4InstanceCheckDefault(checkFunc) (DualShock4::InstanceInitialized() ? DualShock4::GetInstance()->checkFunc : false)
6 |
7 | Ds4Binding::Ds4Binding(Ds4Button button) : Button(button)
8 | {
9 | }
10 |
11 | Ds4Binding::~Ds4Binding()
12 | {
13 | }
14 |
15 | bool Ds4Binding::IsDown()
16 | {
17 | return Ds4InstanceCheckDefault(IsDown(Button));
18 | }
19 |
20 | bool Ds4Binding::IsTapped()
21 | {
22 | return Ds4InstanceCheckDefault(IsTapped(Button));
23 | }
24 |
25 | bool Ds4Binding::IsReleased()
26 | {
27 | return Ds4InstanceCheckDefault(IsReleased(Button));
28 | }
29 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/Ds4Binding.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "IInputBinding.h"
3 | #include "../DirectInput/Ds4/DualShock4.h"
4 |
5 | namespace DivaHook::Input
6 | {
7 | class Ds4Binding : public IInputBinding
8 | {
9 | public:
10 | Ds4Button Button;
11 |
12 | Ds4Binding(Ds4Button button);
13 | ~Ds4Binding();
14 |
15 | bool IsDown() override;
16 | bool IsTapped() override;
17 | bool IsReleased() override;
18 | };
19 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/IInputBinding.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Input
4 | {
5 | class IInputBinding
6 | {
7 | public:
8 | virtual bool IsDown() = 0;
9 | virtual bool IsTapped() = 0;
10 | virtual bool IsReleased() = 0;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/KeyboardBinding.cpp:
--------------------------------------------------------------------------------
1 | #include "KeyboardBinding.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | KeyboardBinding::KeyboardBinding(BYTE keycode) : Keycode(keycode)
6 | {
7 | }
8 |
9 | KeyboardBinding::~KeyboardBinding()
10 | {
11 | }
12 |
13 | bool KeyboardBinding::IsDown()
14 | {
15 | return Keyboard::GetInstance()->IsDown(Keycode);
16 | }
17 |
18 | bool KeyboardBinding::IsTapped()
19 | {
20 | return Keyboard::GetInstance()->IsTapped(Keycode);
21 | }
22 |
23 | bool KeyboardBinding::IsReleased()
24 | {
25 | return Keyboard::GetInstance()->IsReleased(Keycode);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/KeyboardBinding.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "IInputBinding.h"
3 | #include "../Keyboard/Keyboard.h"
4 |
5 | namespace DivaHook::Input
6 | {
7 | class KeyboardBinding : public IInputBinding
8 | {
9 | public:
10 | BYTE Keycode;
11 |
12 | KeyboardBinding(BYTE keycode);
13 | ~KeyboardBinding();
14 |
15 | bool IsDown() override;
16 | bool IsTapped() override;
17 | bool IsReleased() override;
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/MouseBinding.cpp:
--------------------------------------------------------------------------------
1 | #include "MouseBinding.h"
2 | #include "../Keyboard/Keyboard.h"
3 |
4 | namespace DivaHook::Input
5 | {
6 | MouseBinding::MouseBinding(MouseAction action) : Action(action)
7 | {
8 | }
9 |
10 | MouseBinding::~MouseBinding()
11 | {
12 | }
13 |
14 | bool MouseBinding::IsDown()
15 | {
16 | switch (Action)
17 | {
18 | case MouseAction_LeftButton:
19 | return Keyboard::GetInstance()->IsDown(MK_LBUTTON);
20 | case MouseAction_RightButton:
21 | return Keyboard::GetInstance()->IsDown(MK_RBUTTON);
22 | case MouseAction_MiddleButton:
23 | return Keyboard::GetInstance()->IsDown(MK_MBUTTON);
24 | case MouseAction_ScrollUp:
25 | return Mouse::GetInstance()->GetIsScrolledUp();
26 | case MouseAction_ScrollDown:
27 | return Mouse::GetInstance()->GetIsScrolledDown();
28 | default:
29 | return false;
30 | }
31 | }
32 |
33 | bool MouseBinding::IsTapped()
34 | {
35 | switch (Action)
36 | {
37 | case MouseAction_LeftButton:
38 | return Keyboard::GetInstance()->IsTapped(MK_LBUTTON);
39 | case MouseAction_RightButton:
40 | return Keyboard::GetInstance()->IsTapped(MK_RBUTTON);
41 | case MouseAction_MiddleButton:
42 | return Keyboard::GetInstance()->IsTapped(MK_MBUTTON);
43 | case MouseAction_ScrollUp:
44 | return Mouse::GetInstance()->GetIsScrolledUp();
45 | case MouseAction_ScrollDown:
46 | return Mouse::GetInstance()->GetIsScrolledDown();
47 | default:
48 | return false;
49 | }
50 | }
51 |
52 | bool MouseBinding::IsReleased()
53 | {
54 | switch (Action)
55 | {
56 | case MouseAction_LeftButton:
57 | return Keyboard::GetInstance()->IsReleased(MK_LBUTTON);
58 | case MouseAction_RightButton:
59 | return Keyboard::GetInstance()->IsReleased(MK_RBUTTON);
60 | case MouseAction_MiddleButton:
61 | return Keyboard::GetInstance()->IsReleased(MK_MBUTTON);
62 | case MouseAction_ScrollUp:
63 | return Mouse::GetInstance()->GetWasScrolledUp();
64 | case MouseAction_ScrollDown:
65 | return Mouse::GetInstance()->GetWasScrolledDown();
66 | default:
67 | return false;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Bindings/MouseBinding.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "IInputBinding.h"
3 | #include "../Mouse/Mouse.h"
4 |
5 | namespace DivaHook::Input
6 | {
7 | enum MouseAction
8 | {
9 | MouseAction_LeftButton,
10 | MouseAction_RightButton,
11 | MouseAction_MiddleButton,
12 | MouseAction_ScrollUp,
13 | MouseAction_ScrollDown,
14 | };
15 |
16 | class MouseBinding : public IInputBinding
17 | {
18 | public:
19 | MouseAction Action;
20 |
21 | MouseBinding(MouseAction action);
22 | ~MouseBinding();
23 |
24 | bool IsDown() override;
25 | bool IsTapped() override;
26 | bool IsReleased() override;
27 | };
28 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Controller.cpp:
--------------------------------------------------------------------------------
1 | #include "Controller.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | Controller::Controller()
6 | {
7 | }
8 |
9 | Controller::~Controller()
10 | {
11 |
12 | }
13 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Controller.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "DirectInputDevice.h"
3 |
4 | namespace DivaHook::Input
5 | {
6 | class Controller : public DirectInputDevice
7 | {
8 | protected:
9 | Controller();
10 | ~Controller();
11 | };
12 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/DirectInput.cpp:
--------------------------------------------------------------------------------
1 | #include "DirectInput.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | IDirectInput8 *IDirectInputInstance = nullptr;
6 |
7 | HRESULT InitializeDirectInput(HMODULE module)
8 | {
9 | HRESULT result = DirectInput8Create(module, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&IDirectInputInstance, nullptr);
10 | return result;
11 | }
12 |
13 | bool DirectInputInitialized()
14 | {
15 | return IDirectInputInstance != nullptr;
16 | }
17 |
18 | void DisposeDirectInput()
19 | {
20 | if (IDirectInputInstance == nullptr)
21 | return;
22 |
23 | IDirectInputInstance->Release();
24 | IDirectInputInstance = nullptr;
25 | }
26 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/DirectInput.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define DIRECTINPUT_VERSION 0x0800
3 | #include
4 |
5 | namespace DivaHook::Input
6 | {
7 | extern IDirectInput8 *IDirectInputInstance;
8 |
9 | HRESULT InitializeDirectInput(HMODULE module);
10 | bool DirectInputInitialized();
11 | void DisposeDirectInput();
12 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/DirectInputDevice.cpp:
--------------------------------------------------------------------------------
1 | #include "DirectInputDevice.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | HRESULT DirectInputDevice::DI_CreateDevice(const GUID &guid)
6 | {
7 | if (!DirectInputInitialized())
8 | return DIERR_NOTINITIALIZED;
9 |
10 | HRESULT result = IDirectInputInstance->CreateDevice(guid, &directInputdevice, NULL);
11 | return result;
12 | }
13 |
14 | HRESULT DirectInputDevice::DI_SetDataFormat(LPCDIDATAFORMAT dataFormat)
15 | {
16 | HRESULT result = directInputdevice->SetDataFormat(dataFormat);
17 | return result;
18 | }
19 |
20 | HRESULT DirectInputDevice::DI_SetCooperativeLevel(HWND windowHandle, DWORD flags)
21 | {
22 | HRESULT result = directInputdevice->SetCooperativeLevel(windowHandle, flags);
23 | return result;
24 | }
25 |
26 | HRESULT DirectInputDevice::DI_Acquire()
27 | {
28 | HRESULT result = directInputdevice->Acquire();
29 | return result;
30 | }
31 |
32 | HRESULT DirectInputDevice::DI_Unacquire()
33 | {
34 | HRESULT result = directInputdevice->Unacquire();
35 | return result;
36 | }
37 |
38 | HRESULT DirectInputDevice::DI_Release()
39 | {
40 | HRESULT result = directInputdevice->Release();
41 | return result;
42 | }
43 |
44 | HRESULT DirectInputDevice::DI_Poll()
45 | {
46 | HRESULT result = directInputdevice->Poll();
47 | return result;
48 | }
49 |
50 | HRESULT DirectInputDevice::DI_GetDeviceState(DWORD size, LPVOID data)
51 | {
52 | HRESULT result = directInputdevice->GetDeviceState(size, data);
53 | return result;
54 | }
55 |
56 | void DirectInputDevice::DI_Dispose()
57 | {
58 | if (directInputdevice == nullptr)
59 | return;
60 |
61 | HRESULT result = NULL;
62 |
63 | result = DI_Unacquire();
64 | result = DI_Release();
65 | }
66 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/DirectInputDevice.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "DirectInput.h"
3 |
4 | namespace DivaHook::Input
5 | {
6 | class DirectInputDevice
7 | {
8 | protected:
9 | IDirectInputDevice8 *directInputdevice;
10 |
11 | HRESULT DI_CreateDevice(const GUID& guid);
12 | HRESULT DI_SetDataFormat(LPCDIDATAFORMAT dataFormat);
13 | HRESULT DI_SetCooperativeLevel(HWND windowHandle, DWORD flags);
14 | HRESULT DI_Acquire();
15 | HRESULT DI_Unacquire();
16 | HRESULT DI_Release();
17 | HRESULT DI_Poll();
18 | HRESULT DI_GetDeviceState(DWORD size, LPVOID data);
19 |
20 | void DI_Dispose();
21 | };
22 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/DirectInputMouse.cpp:
--------------------------------------------------------------------------------
1 | #include "DirectInputMouse.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | DirectInputMouse::DirectInputMouse()
6 | {
7 | HRESULT result = NULL;
8 |
9 | result = DI_CreateDevice(GUID_SysMouse);
10 |
11 | if (FAILED(result))
12 | return;
13 |
14 | result = DI_SetDataFormat(&c_dfDIMouse);
15 | result = DI_Acquire();
16 | }
17 |
18 | DirectInputMouse::~DirectInputMouse()
19 | {
20 | DI_Dispose();
21 | }
22 |
23 | bool DirectInputMouse::Poll()
24 | {
25 | if (!DirectInputInitialized())
26 | return FALSE;
27 |
28 | HRESULT result = NULL;
29 |
30 | result = DI_Poll();
31 | result = DI_GetDeviceState(sizeof(mouseState), &mouseState);
32 |
33 | return !FAILED(result);
34 | }
35 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/DirectInputMouse.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "DirectInputDevice.h"
3 |
4 | namespace DivaHook::Input
5 | {
6 | class DirectInputMouse : public DirectInputDevice
7 | {
8 | public:
9 | DirectInputMouse();
10 | ~DirectInputMouse();
11 |
12 | bool Poll();
13 |
14 | inline long GetXPosition() { return mouseState.lX; };
15 | inline long GetYPosition() { return mouseState.lY; };
16 | inline long GetMouseWheel() { return mouseState.lZ; };
17 |
18 | private:
19 | DIMOUSESTATE mouseState;
20 | };
21 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Ds4/Ds4Button.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Input
4 | {
5 | enum Direction
6 | {
7 | DIR_UP,
8 | DIR_RIGHT,
9 | DIR_DOWN,
10 | DIR_LEFT
11 | };
12 |
13 | enum Ds4Button : int
14 | {
15 | DS4_SQUARE = 0,
16 | DS4_CROSS = 1,
17 | DS4_CIRCLE = 2,
18 | DS4_TRIANGLE = 3,
19 |
20 | DS4_L1 = 4,
21 | DS4_R1 = 5,
22 |
23 | DS4_L_TRIGGER = 6,
24 | DS4_R_TRIGGER = 7,
25 |
26 | DS4_SHARE = 8,
27 | DS4_OPTIONS = 9,
28 |
29 | DS4_L3 = 10,
30 | DS4_R3 = 11,
31 |
32 | DS4_PS = 12,
33 | DS4_TOUCH = 13,
34 |
35 | DS4_DPAD_UP,
36 | DS4_DPAD_RIGHT,
37 | DS4_DPAD_DOWN,
38 | DS4_DPAD_LEFT,
39 |
40 | DS4_L_STICK_UP,
41 | DS4_L_STICK_RIGHT,
42 | DS4_L_STICK_DOWN,
43 | DS4_L_STICK_LEFT,
44 |
45 | DS4_R_STICK_UP,
46 | DS4_R_STICK_RIGHT,
47 | DS4_R_STICK_DOWN,
48 | DS4_R_STICK_LEFT,
49 |
50 | DS4_BUTTON_MAX,
51 | };
52 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Ds4/Ds4State.cpp:
--------------------------------------------------------------------------------
1 | #include "Ds4State.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | Joystick::Joystick() : XAxis(0.0f), YAxis(0.0f)
6 | {
7 | return;
8 | };
9 |
10 | Joystick::Joystick(float xAxis, float yAxis) : XAxis(xAxis), YAxis(yAxis)
11 | {
12 | return;
13 | };
14 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Ds4/Ds4State.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../DirectInput.h"
3 | #include "Ds4Button.h"
4 |
5 | namespace DivaHook::Input
6 | {
7 | struct Joystick
8 | {
9 | FLOAT XAxis, YAxis;
10 |
11 | Joystick();
12 | Joystick(float xAxis, float yAxis);
13 | };
14 |
15 | struct Dpad
16 | {
17 | BOOL IsDown;
18 | FLOAT Angle;
19 | Joystick Stick;
20 | };
21 |
22 | struct Trigger
23 | {
24 | FLOAT Axis;
25 | };
26 |
27 | struct Ds4State
28 | {
29 | DIJOYSTATE2 DI_JoyState;
30 |
31 | BYTE Buttons[DS4_BUTTON_MAX];
32 |
33 | Dpad Dpad;
34 | Joystick LeftStick;
35 | Joystick RightStick;
36 | Trigger LeftTrigger;
37 | Trigger RightTrigger;
38 | };
39 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Ds4/DualShock4.cpp:
--------------------------------------------------------------------------------
1 | #include "DualShock4.h"
2 | #include "../../../Utilities/Math.h"
3 | #include "../../../MainModule.h"
4 | #include
5 |
6 | namespace DivaHook::Input
7 | {
8 | DualShock4* DualShock4::instance;
9 |
10 | DualShock4::DualShock4()
11 | {
12 | }
13 |
14 | DualShock4::~DualShock4()
15 | {
16 | DI_Dispose();
17 | }
18 |
19 | bool DualShock4::TryInitializeInstance()
20 | {
21 | if (InstanceInitialized())
22 | return true;
23 |
24 | if (!DirectInputInitialized())
25 | return false;
26 |
27 | DualShock4 *dualShock4 = new DualShock4();
28 |
29 | bool success = dualShock4->Initialize();
30 | instance = success ? dualShock4 : nullptr;
31 |
32 | if (!success)
33 | delete dualShock4;
34 |
35 | return success;
36 | }
37 |
38 | bool DualShock4::Initialize()
39 | {
40 | HRESULT result = NULL;
41 |
42 | const size_t guidCount = sizeof(GUID_Ds4) / sizeof(GUID);
43 | for (size_t i = 0; i < guidCount; i++)
44 | {
45 | result = DI_CreateDevice(GUID_Ds4[i]);
46 |
47 | if (!FAILED(result))
48 | break;
49 | else if (i == guidCount - 1)
50 | return false;
51 | }
52 |
53 | if (FAILED(result = DI_SetDataFormat(&c_dfDIJoystick2)))
54 | return false;
55 |
56 | result = DI_Acquire();
57 |
58 | return true;
59 | }
60 |
61 | bool DualShock4::PollInput()
62 | {
63 | lastState = currentState;
64 |
65 | HRESULT result = NULL;
66 | result = DI_Poll();
67 | result = DI_GetDeviceState(sizeof(DIJOYSTATE2), ¤tState.DI_JoyState);
68 |
69 | if (result != DI_OK)
70 | return false;
71 |
72 | UpdateInternalDs4State(currentState);
73 |
74 | for (int button = 0; button < DS4_BUTTON_MAX; button++)
75 | currentState.Buttons[button] = GetButtonState(currentState, (Ds4Button)button);
76 |
77 | return true;
78 | }
79 |
80 | void DualShock4::UpdateInternalDs4State(Ds4State &state)
81 | {
82 | if (state.Dpad.IsDown = state.DI_JoyState.rgdwPOV[0] != -1)
83 | {
84 | state.Dpad.Angle = (state.DI_JoyState.rgdwPOV[0] / 100.0f);
85 |
86 | auto direction = Utilities::GetDirection(state.Dpad.Angle);
87 | state.Dpad.Stick = { direction.Y, -direction.X };
88 | }
89 | else
90 | {
91 | state.Dpad.Angle = 0;
92 | state.Dpad.Stick = Joystick();
93 | }
94 |
95 | state.LeftStick = NormalizeStick(state.DI_JoyState.lX, state.DI_JoyState.lY);
96 | state.RightStick = NormalizeStick(state.DI_JoyState.lZ, state.DI_JoyState.lRz);
97 |
98 | state.LeftTrigger = { NormalizeTrigger(state.DI_JoyState.lRx) };
99 | state.RightTrigger = { NormalizeTrigger(state.DI_JoyState.lRy) };
100 | }
101 |
102 | bool DualShock4::IsDown(Ds4Button button)
103 | {
104 | return currentState.Buttons[button];
105 | }
106 |
107 | bool DualShock4::IsUp(Ds4Button button)
108 | {
109 | return !IsDown(button);
110 | }
111 |
112 | bool DualShock4::IsTapped(Ds4Button button)
113 | {
114 | return IsDown(button) && WasUp(button);
115 | }
116 |
117 | bool DualShock4::IsReleased(Ds4Button button)
118 | {
119 | return IsUp(button) && WasDown(button);
120 | }
121 |
122 | bool DualShock4::WasDown(Ds4Button button)
123 | {
124 | return lastState.Buttons[button];
125 | }
126 |
127 | bool DualShock4::WasUp(Ds4Button button)
128 | {
129 | return !WasDown(button);
130 | }
131 |
132 | bool DualShock4::MatchesDirection(Joystick joystick, Direction directionEnum, float threshold)
133 | {
134 | switch (directionEnum)
135 | {
136 | case DivaHook::Input::DIR_UP:
137 | return joystick.YAxis <= -threshold;
138 |
139 | case DivaHook::Input::DIR_RIGHT:
140 | return joystick.XAxis >= +threshold;
141 |
142 | case DivaHook::Input::DIR_DOWN:
143 | return joystick.YAxis >= +threshold;
144 |
145 | case DivaHook::Input::DIR_LEFT:
146 | return joystick.XAxis <= -threshold;
147 |
148 | default:
149 | return false;
150 | }
151 | }
152 |
153 | bool DualShock4::GetButtonState(Ds4State &state, Ds4Button button)
154 | {
155 | if (button >= DS4_SQUARE && button <= DS4_TOUCH)
156 | return state.DI_JoyState.rgbButtons[button];
157 |
158 | if (button >= DS4_DPAD_UP && button <= DS4_DPAD_LEFT)
159 | return state.Dpad.IsDown ? MatchesDirection(state.Dpad.Stick, (Direction)(button - DS4_DPAD_UP), dpadThreshold) : false;
160 |
161 | if (button >= DS4_L_STICK_UP && button <= DS4_L_STICK_LEFT)
162 | return MatchesDirection(state.LeftStick, (Direction)(button - DS4_L_STICK_UP), joystickThreshold);
163 |
164 | if (button >= DS4_R_STICK_UP && button <= DS4_R_STICK_LEFT)
165 | return MatchesDirection(state.RightStick, (Direction)(button - DS4_R_STICK_UP), joystickThreshold);
166 |
167 | return false;
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/DirectInput/Ds4/DualShock4.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../Controller.h"
3 | #include "../../IInputDevice.h"
4 | #include "Ds4State.h"
5 |
6 | namespace DivaHook::Input
7 | {
8 | // DualShock 4 Wireless Controller Product GUIDs:
9 | const GUID GUID_Ds4[2] =
10 | {
11 | // First Generation: {05C4054C-0000-0000-0000-504944564944}
12 | { 0x05C4054C, 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
13 | // Second Generation: {09CC054C-0000-0000-0000-504944564944}
14 | { 0x09CC054C, 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
15 | };
16 |
17 | class DualShock4 : public Controller, public IInputDevice
18 | {
19 | public:
20 | DualShock4();
21 | ~DualShock4();
22 |
23 | static bool TryInitializeInstance();
24 |
25 | bool Initialize();
26 | bool PollInput() override;
27 |
28 | bool IsDown(Ds4Button button);
29 | bool IsUp(Ds4Button button);
30 | bool IsTapped(Ds4Button button);
31 | bool IsReleased(Ds4Button button);
32 | bool WasDown(Ds4Button button);
33 | bool WasUp(Ds4Button button);
34 |
35 | inline Joystick GetLeftStick() { return currentState.LeftStick; };
36 | inline Joystick GetRightStick() { return currentState.RightStick; };
37 | inline Joystick GetDpad() { return currentState.Dpad.Stick; };
38 |
39 | static inline bool InstanceInitialized() { return instance != nullptr; };
40 | static inline DualShock4* GetInstance() { return instance; };
41 | static inline void DeleteInstance() { delete instance; instance = nullptr; };
42 |
43 | private:
44 | static DualShock4* instance;
45 |
46 | Ds4State lastState;
47 | Ds4State currentState;
48 |
49 | const float triggerThreshold = 0.5f;
50 | const float joystickThreshold = 0.5f;
51 | const float dpadThreshold = 0.5f;
52 |
53 | inline float NormalizeTrigger(long value) { return (float)value / USHRT_MAX; };
54 | inline float NormalizeStick(long value) { return (float)value / USHRT_MAX * 2.0f - 1.0f; };
55 | inline Joystick NormalizeStick(long x, long y) { return Joystick(NormalizeStick(x), NormalizeStick(y)); };
56 |
57 | void UpdateInternalDs4State(Ds4State &state);
58 |
59 | bool MatchesDirection(Joystick joystick, Direction directionEnum, float threshold);
60 | bool GetButtonState(Ds4State &state, Ds4Button button);
61 | };
62 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/IInputDevice.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Input
4 | {
5 | class IInputDevice
6 | {
7 | public:
8 | virtual bool PollInput() = 0;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/KeyConfig/Config.cpp:
--------------------------------------------------------------------------------
1 | #include "Config.h"
2 | #include "windows.h"
3 | #include "../Bindings/KeyboardBinding.h"
4 | #include "../Bindings/Ds4Binding.h"
5 | #include "../../Utilities/Operations.h"
6 |
7 | namespace DivaHook::Input::KeyConfig
8 | {
9 | KeycodeMap Config::Keymap =
10 | {
11 | // NumPad Keys
12 | { "NumPad0", VK_NUMPAD0 },
13 | { "NumPad1", VK_NUMPAD1 },
14 | { "NumPad2", VK_NUMPAD2 },
15 | { "NumPad3", VK_NUMPAD3 },
16 | { "NumPad4", VK_NUMPAD4 },
17 | { "NumPad5", VK_NUMPAD5 },
18 | { "NumPad6", VK_NUMPAD6 },
19 | { "NumPad7", VK_NUMPAD7 },
20 | { "NumPad8", VK_NUMPAD8 },
21 | { "NumPad9", VK_NUMPAD9 },
22 | { "Plus", VK_ADD },
23 | { "Minus", VK_SUBTRACT },
24 | { "Divide", VK_DIVIDE },
25 | { "Multiply", VK_MULTIPLY },
26 | // F-Keys
27 | { "F1", VK_F1 },
28 | { "F2", VK_F2 },
29 | { "F3", VK_F3 },
30 | { "F4", VK_F4 },
31 | { "F5", VK_F5 },
32 | { "F6", VK_F6 },
33 | { "F7", VK_F7 },
34 | { "F8", VK_F8 },
35 | { "F9", VK_F9 },
36 | { "F10", VK_F10 },
37 | { "F11", VK_F11 },
38 | { "F12", VK_F12 },
39 | { "F13", VK_F13 },
40 | { "F14", VK_F14 },
41 | { "F15", VK_F15 },
42 | { "F16", VK_F16 },
43 | { "F17", VK_F17 },
44 | { "F18", VK_F18 },
45 | { "F19", VK_F19 },
46 | { "F20", VK_F20 },
47 | { "F21", VK_F21 },
48 | { "F22", VK_F22 },
49 | { "F23", VK_F23 },
50 | { "F24", VK_F24 },
51 | // Shift Keys
52 | { "LeftShift", VK_LSHIFT },
53 | { "LShift", VK_LSHIFT },
54 | { "RightShift", VK_RSHIFT },
55 | { "RShift", VK_RSHIFT },
56 | // Control Keys
57 | { "LeftControl", VK_LCONTROL },
58 | { "LControl", VK_LCONTROL },
59 | { "LCtrl", VK_LCONTROL },
60 | { "RightControl", VK_RCONTROL },
61 | { "RControl", VK_RCONTROL },
62 | { "RCtrl", VK_RCONTROL },
63 | // Arrow Keys
64 | { "Up", VK_UP },
65 | { "Down", VK_DOWN },
66 | { "Left", VK_LEFT },
67 | { "Right", VK_RIGHT },
68 | // Special Keys
69 | { "Enter", VK_RETURN },
70 | { "Return", VK_RETURN },
71 | { "Tab", VK_TAB },
72 | { "Back", VK_BACK },
73 | { "Backspace", VK_BACK },
74 | { "Insert", VK_INSERT },
75 | { "Ins", VK_INSERT },
76 | { "Delete", VK_DELETE },
77 | { "Del", VK_DELETE },
78 | { "Home", VK_HOME },
79 | { "End", VK_END },
80 | { "PageUp", VK_PRIOR },
81 | { "PageDown", VK_NEXT },
82 | { "ESC", VK_ESCAPE },
83 | { "Escape", VK_ESCAPE },
84 | { "Comma", VK_OEM_COMMA },
85 | { "Period", VK_OEM_PERIOD },
86 | { "Slash", VK_OEM_2 },
87 | };
88 |
89 | Ds4ButtonMap Config::Ds4Map =
90 | {
91 | // Face Buttons
92 | { "DS4_SQUARE", DS4_SQUARE },
93 | { "Ds4_Square", DS4_SQUARE },
94 |
95 | { "DS4_CROSS", DS4_CROSS },
96 | { "Ds4_Cross", DS4_CROSS },
97 |
98 | { "DS4_CIRCLE", DS4_CIRCLE },
99 | { "Ds4_Circle", DS4_CIRCLE },
100 |
101 | { "DS4_TRIANGLE", DS4_TRIANGLE },
102 | { "Ds4_Triangle", DS4_TRIANGLE },
103 |
104 | // Standard Buttons
105 | { "DS4_SHARE", DS4_SHARE },
106 | { "Ds4_Share", DS4_SHARE },
107 |
108 | { "DS4_OPTIONS", DS4_OPTIONS },
109 | { "Ds4_Options", DS4_OPTIONS },
110 |
111 | { "DS4_PS", DS4_PS },
112 | { "Ds4_PS", DS4_PS },
113 |
114 | { "DS4_TOUCH", DS4_TOUCH },
115 | { "Ds4_Touch", DS4_TOUCH },
116 |
117 | { "DS4_L1", DS4_L1 },
118 | { "Ds4_L1", DS4_L1 },
119 |
120 | { "DS4_R1", DS4_R1 },
121 | { "Ds4_R1", DS4_R1 },
122 |
123 | // D-Pad Directions
124 | { "DS4_DPAD_UP", DS4_DPAD_UP },
125 | { "Ds4_DPad_Up", DS4_DPAD_UP },
126 |
127 | { "DS4_DPAD_RIGHT", DS4_DPAD_RIGHT },
128 | { "Ds4_DPad_Right", DS4_DPAD_RIGHT },
129 |
130 | { "DS4_DPAD_DOWN", DS4_DPAD_DOWN },
131 | { "Ds4_DPad_Down", DS4_DPAD_DOWN },
132 |
133 | { "DS4_DPAD_LEFT", DS4_DPAD_LEFT },
134 | { "Ds4_DPad_Left", DS4_DPAD_LEFT },
135 |
136 | // Trigger Buttons
137 | { "DS4_L_TRIGGER", DS4_L_TRIGGER },
138 | { "Ds4_L_Trigger", DS4_L_TRIGGER },
139 |
140 | { "DS4_R_TRIGGER", DS4_R_TRIGGER },
141 | { "Ds4_R_Trigger", DS4_R_TRIGGER },
142 |
143 | // Joystick Buttons
144 | { "DS4_L3", DS4_L3 },
145 | { "Ds4_L3", DS4_L3 },
146 |
147 | { "DS4_R3", DS4_R3 },
148 | { "Ds4_R3", DS4_R3 },
149 |
150 | // Left Joystick
151 | { "DS4_L_STICK_UP", DS4_L_STICK_UP },
152 | { "Ds4_L_Stick_Up", DS4_L_STICK_UP },
153 |
154 | { "DS4_L_STICK_RIGHT", DS4_L_STICK_RIGHT },
155 | { "Ds4_L_Stick_Right", DS4_L_STICK_RIGHT },
156 |
157 | { "DS4_L_STICK_DOWN", DS4_L_STICK_DOWN },
158 | { "Ds4_L_Stick_Down", DS4_L_STICK_DOWN },
159 |
160 | { "DS4_L_STICK_LEFT", DS4_L_STICK_LEFT },
161 | { "Ds4_L_Stick_Left", DS4_L_STICK_LEFT },
162 |
163 | // Right Joystick
164 | { "DS4_R_STICK_UP", DS4_R_STICK_UP },
165 | { "Ds4_R_Stick_Up", DS4_R_STICK_UP },
166 |
167 | { "DS4_R_STICK_RIGHT", DS4_R_STICK_RIGHT },
168 | { "Ds4_R_Stick_Right", DS4_R_STICK_RIGHT },
169 |
170 | { "DS4_R_STICK_DOWN", DS4_R_STICK_DOWN },
171 | { "Ds4_R_Stick_Down", DS4_R_STICK_DOWN },
172 |
173 | { "DS4_R_STICK_LEFT", DS4_R_STICK_LEFT },
174 | { "Ds4_R_Stick_Left", DS4_R_STICK_LEFT },
175 | };
176 |
177 | void Config::BindConfigKeys(std::unordered_map &configMap, const char *configKeyName, Binding &bindObj, std::vector defaultKeys)
178 | {
179 | std::vector keys;
180 |
181 | auto configPair = configMap.find(configKeyName);
182 |
183 | // config variable was found in the ini
184 | if (configPair != configMap.end())
185 | {
186 | keys = Utilities::Split(configPair->second, ",");
187 | }
188 | else
189 | {
190 | keys = defaultKeys;
191 | }
192 |
193 | for (std::string key : keys)
194 | {
195 | Utilities::Trim(key);
196 |
197 | // Applies only for Single-Character keys
198 | if (key.length() == 1)
199 | {
200 | bindObj.AddBinding(new KeyboardBinding(key[0]));
201 | }
202 | else // for special key names
203 | {
204 | auto keycode = Config::Keymap.find(key.c_str());
205 |
206 | // name is known in the special keys map
207 | if (keycode != Config::Keymap.end())
208 | {
209 | bindObj.AddBinding(new KeyboardBinding(keycode->second));
210 | }
211 | else
212 | {
213 | // just gonna be lazy for now and put this inside an else statement
214 | auto ds4Button = Config::Ds4Map.find(key.c_str());
215 |
216 | if (ds4Button != Config::Ds4Map.end())
217 | {
218 | bindObj.AddBinding(new Ds4Binding(ds4Button->second));
219 | }
220 | else
221 | {
222 | printf("Config::BindConfigKeys(): Unable to parse key: '%s'\n", key.c_str());
223 | }
224 | }
225 | }
226 | }
227 | }
228 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/KeyConfig/Config.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "KeyString.h"
5 | #include "KeyStringHash.h"
6 | #include "../Bindings/Binding.h"
7 | #include "../DirectInput/Ds4/Ds4Button.h"
8 |
9 | namespace DivaHook::Input::KeyConfig
10 | {
11 | typedef std::unordered_map KeycodeMap;
12 | typedef std::unordered_map Ds4ButtonMap;
13 |
14 | class Config
15 | {
16 | public:
17 | static KeycodeMap Keymap;
18 | static Ds4ButtonMap Ds4Map;
19 |
20 | static void BindConfigKeys(std::unordered_map &configMap, const char *configKeyName, Binding &bindObj, std::vector defaultKeys);
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/KeyConfig/KeyString.cpp:
--------------------------------------------------------------------------------
1 | #include "KeyString.h"
2 |
3 | namespace DivaHook::Input::KeyConfig
4 | {
5 | KeyString::KeyString(const char* str) : value(str)
6 | {
7 | }
8 |
9 | bool KeyString::operator==(const KeyString& rsv) const
10 | {
11 | return !_strcmpi(value.c_str(), rsv.value.c_str());
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/KeyConfig/KeyString.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace DivaHook::Input::KeyConfig
5 | {
6 | struct KeyString
7 | {
8 | std::string value;
9 |
10 | KeyString(const char* str);
11 | bool operator==(const KeyString& rsv) const;
12 | };
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/KeyConfig/KeyStringHash.cpp:
--------------------------------------------------------------------------------
1 | #include "KeyStringHash.h"
2 | #include
3 |
4 | namespace DivaHook::Input::KeyConfig
5 | {
6 | size_t KeyStringHash::operator()(const KeyString& key) const
7 | {
8 | std::string ret = key.value;
9 | std::transform(ret.begin(), ret.end(), ret.begin(),
10 | [](unsigned char c) { return std::tolower(c, std::locale()); });
11 | return std::hash()(ret);
12 | }
13 | }
--------------------------------------------------------------------------------
/DivaHook/src/Input/KeyConfig/KeyStringHash.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "KeyString.h"
3 |
4 | namespace DivaHook::Input::KeyConfig
5 | {
6 | struct KeyStringHash
7 | {
8 | size_t operator()(const KeyString& key) const;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Keyboard/Keyboard.cpp:
--------------------------------------------------------------------------------
1 | #include "Keyboard.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | Keyboard* Keyboard::instance;
6 |
7 | Keyboard::Keyboard()
8 | {
9 | }
10 |
11 | Keyboard* Keyboard::GetInstance()
12 | {
13 | if (instance == nullptr)
14 | instance = new Keyboard();
15 |
16 | return instance;
17 | }
18 |
19 | bool Keyboard::PollInput()
20 | {
21 | lastState = currentState;
22 |
23 | float elapsed = keyIntervalWatch.Restart();
24 |
25 | for (BYTE i = 0; i < KEYBOARD_KEYS; i++)
26 | {
27 | // DOWN
28 | bool isDown = GetAsyncKeyState(i) < 0;
29 | currentState.KeyStates[i] = isDown;
30 |
31 | // DOUBLE TAPPED
32 | bool isTapped = IsTapped(i);
33 | keyDoubleTapStates[i] = isTapped ? keyDoubleTapWatches[i].Restart() <= DOUBLE_TAP_THRESHOLD : false;
34 |
35 | // INTERVAL TAPPED
36 | keyIntervalTapStates[i] = isTapped;
37 |
38 | if (isTapped)
39 | {
40 | keyIntervalTapTimes[i] = 0;
41 | keyIntervalInitials[i] = true;
42 | }
43 | else if (isDown)
44 | {
45 | float threshold = keyIntervalInitials[i] ? INTERVAL_TAP_DELAY_THRESHOLD : INTERVAL_TAP_THRESHOLD;
46 |
47 | bool intervalTapped = (keyIntervalTapTimes[i] += elapsed) > threshold;
48 | keyIntervalTapStates[i] = intervalTapped;
49 |
50 | if (intervalTapped)
51 | {
52 | keyIntervalTapTimes[i] = 0;
53 | keyIntervalInitials[i] = false;
54 | }
55 | }
56 | }
57 |
58 | return true;
59 | }
60 |
61 | bool Keyboard::IsDown(BYTE keycode)
62 | {
63 | return currentState.IsDown(keycode);
64 | }
65 |
66 | bool Keyboard::IsUp(BYTE keycode)
67 | {
68 | return !IsDown(keycode);
69 | }
70 |
71 | bool Keyboard::IsTapped(BYTE keycode)
72 | {
73 | return IsDown(keycode) && WasUp(keycode);
74 | }
75 |
76 | bool Keyboard::IsDoubleTapped(BYTE keycode)
77 | {
78 | return keyDoubleTapStates[keycode];
79 | }
80 |
81 | bool Keyboard::IsReleased(BYTE keycode)
82 | {
83 | return IsUp(keycode) && WasDown(keycode);
84 | }
85 |
86 | inline bool Keyboard::WasDown(BYTE keycode)
87 | {
88 | return lastState.IsDown(keycode);
89 | }
90 |
91 | inline bool Keyboard::WasUp(BYTE keycode)
92 | {
93 | return !WasDown(keycode);
94 | }
95 |
96 | bool Keyboard::IsIntervalTapped(BYTE keycode)
97 | {
98 | return keyIntervalTapStates[keycode];
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Keyboard/Keyboard.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../IInputDevice.h"
3 | #include "KeyboardState.h"
4 | #include "../../Utilities/Stopwatch.h"
5 |
6 | using Stopwatch = DivaHook::Utilities::Stopwatch;
7 |
8 | namespace DivaHook::Input
9 | {
10 | constexpr float DOUBLE_TAP_THRESHOLD = 200.0f;
11 | constexpr float INTERVAL_TAP_DELAY_THRESHOLD = 500.0f;
12 | constexpr float INTERVAL_TAP_THRESHOLD = 75.0f;
13 |
14 | class Keyboard : public IInputDevice
15 | {
16 | public:
17 | static Keyboard* GetInstance();
18 |
19 | bool PollInput() override;
20 | bool IsDown(BYTE keycode);
21 | bool IsUp(BYTE keycode);
22 | bool IsTapped(BYTE keycode);
23 | bool IsDoubleTapped(BYTE keycode);
24 | bool IsReleased(BYTE keycode);
25 | bool IsIntervalTapped(BYTE keycode);
26 |
27 | bool WasDown(BYTE keycode);
28 | bool WasUp(BYTE keycode);
29 |
30 | private:
31 | Keyboard();
32 | KeyboardState lastState;
33 | KeyboardState currentState;
34 |
35 | Stopwatch keyIntervalWatch;
36 |
37 | BYTE keyDoubleTapStates[KEYBOARD_KEYS];
38 | Stopwatch keyDoubleTapWatches[KEYBOARD_KEYS];
39 |
40 | BOOL keyIntervalInitials[KEYBOARD_KEYS];
41 | BYTE keyIntervalTapStates[KEYBOARD_KEYS];
42 | FLOAT keyIntervalTapTimes[KEYBOARD_KEYS];
43 |
44 | static Keyboard* instance;
45 | };
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Keyboard/KeyboardState.cpp:
--------------------------------------------------------------------------------
1 | #include "KeyboardState.h"
2 |
3 | namespace DivaHook::Input
4 | {
5 | bool KeyboardState::IsDown(BYTE keycode)
6 | {
7 | return KeyStates[keycode];
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Keyboard/KeyboardState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace DivaHook::Input
5 | {
6 | const int KEYBOARD_KEYS = 0xFF;
7 |
8 | struct KeyboardState
9 | {
10 | BYTE KeyStates[KEYBOARD_KEYS];
11 |
12 | bool IsDown(BYTE keycode);
13 | };
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Mouse/Mouse.cpp:
--------------------------------------------------------------------------------
1 | #include "Mouse.h"
2 | #include "../../MainModule.h"
3 |
4 | namespace DivaHook::Input
5 | {
6 | Mouse* Mouse::instance;
7 |
8 | Mouse::Mouse()
9 | {
10 | directInputMouse = new DirectInputMouse();
11 | }
12 |
13 | Mouse::~Mouse()
14 | {
15 | if (directInputMouse != nullptr)
16 | delete directInputMouse;
17 | }
18 |
19 | Mouse* Mouse::GetInstance()
20 | {
21 | if (instance == nullptr)
22 | instance = new Mouse();
23 |
24 | return instance;
25 | }
26 |
27 | POINT Mouse::GetPosition()
28 | {
29 | return currentState.Position;
30 | }
31 |
32 | POINT Mouse::GetRelativePosition()
33 | {
34 | return currentState.RelativePosition;
35 | }
36 |
37 | POINT Mouse::GetDeltaPosition()
38 | {
39 | return
40 | {
41 | currentState.Position.x - lastState.Position.x,
42 | currentState.Position.y - lastState.Position.y
43 | };
44 | }
45 |
46 | long Mouse::GetMouseWheel()
47 | {
48 | return currentState.MouseWheel;
49 | }
50 |
51 | long Mouse::GetDeltaMouseWheel()
52 | {
53 | return currentState.MouseWheel - lastState.MouseWheel;
54 | }
55 |
56 | bool Mouse::HasMoved()
57 | {
58 | POINT delta = GetDeltaPosition();
59 | return delta.x != 0 || delta.y != 0;
60 | }
61 |
62 | bool Mouse::GetIsScrolledUp()
63 | {
64 | return currentState.ScrolledUp;
65 | }
66 |
67 | bool Mouse::GetIsScrolledDown()
68 | {
69 | return currentState.ScrolledDown;
70 | }
71 |
72 | bool Mouse::GetWasScrolledUp()
73 | {
74 | return lastState.ScrolledUp;
75 | }
76 |
77 | bool Mouse::GetWasScrolledDown()
78 | {
79 | return lastState.ScrolledDown;
80 | }
81 |
82 | void Mouse::SetPosition(int x, int y)
83 | {
84 | lastState.Position.x = x;
85 | lastState.Position.y = y;
86 | SetCursorPos(x, y);
87 | }
88 |
89 | bool Mouse::PollInput()
90 | {
91 | lastState = currentState;
92 |
93 | GetCursorPos(¤tState.Position);
94 | currentState.RelativePosition = currentState.Position;
95 |
96 | if (MainModule::DivaWindowHandle != NULL)
97 | ScreenToClient(MainModule::DivaWindowHandle, ¤tState.RelativePosition);
98 |
99 | if (directInputMouse != nullptr)
100 | {
101 | if (directInputMouse->Poll())
102 | currentState.MouseWheel += directInputMouse->GetMouseWheel();
103 |
104 | currentState.ScrolledUp = (GetDeltaMouseWheel() > 0);
105 | currentState.ScrolledDown = (GetDeltaMouseWheel() < 0);
106 | }
107 |
108 | return true;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Mouse/Mouse.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../IInputDevice.h"
3 | #include "../DirectInput/DirectInputMouse.h"
4 | #include "MouseState.h"
5 |
6 | namespace DivaHook::Input
7 | {
8 | class Mouse : public IInputDevice
9 | {
10 | public:
11 | ~Mouse();
12 |
13 | static Mouse* GetInstance();
14 |
15 | bool PollInput() override;
16 |
17 | POINT GetPosition();
18 | POINT GetRelativePosition();
19 | POINT GetDeltaPosition();
20 |
21 | long GetMouseWheel();
22 | long GetDeltaMouseWheel();
23 |
24 | bool HasMoved();
25 | bool GetIsScrolledUp();
26 | bool GetIsScrolledDown();
27 | bool GetWasScrolledUp();
28 | bool GetWasScrolledDown();
29 |
30 | void SetPosition(int x, int y);
31 |
32 | private:
33 | Mouse();
34 | MouseState lastState;
35 | MouseState currentState;
36 | DirectInputMouse* directInputMouse = nullptr;
37 |
38 | static Mouse* instance;
39 | };
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/DivaHook/src/Input/Mouse/MouseState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace DivaHook::Input
5 | {
6 | struct MouseState
7 | {
8 | POINT Position;
9 | POINT RelativePosition;
10 | long MouseWheel;
11 | bool ScrolledUp;
12 | bool ScrolledDown;
13 | };
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/DivaHook/src/MainModule.cpp:
--------------------------------------------------------------------------------
1 | #include "MainModule.h"
2 | #include
3 |
4 | namespace DivaHook
5 | {
6 | typedef std::filesystem::path fspath;
7 |
8 | std::string *MainModule::moduleDirectory;
9 |
10 | const wchar_t* MainModule::DivaWindowName = L"Hatsune Miku Project DIVA Arcade Future Tone";
11 | const wchar_t* MainModule::GlutDefaultName = L"GLUT";
12 |
13 | HWND MainModule::DivaWindowHandle;
14 | HMODULE MainModule::Module;
15 |
16 | std::string MainModule::GetModuleDirectory()
17 | {
18 | if (moduleDirectory == nullptr)
19 | {
20 | CHAR modulePathBuffer[MAX_PATH];
21 | GetModuleFileNameA(MainModule::Module, modulePathBuffer, MAX_PATH);
22 |
23 | fspath configPath = fspath(modulePathBuffer).parent_path();
24 | moduleDirectory = new std::string(configPath.u8string());
25 | }
26 |
27 | return *moduleDirectory;
28 | }
29 |
30 | RECT MainModule::GetWindowBounds()
31 | {
32 | RECT windowRect;
33 | GetWindowRect(DivaWindowHandle, &windowRect);
34 |
35 | return windowRect;
36 | }
37 | }
--------------------------------------------------------------------------------
/DivaHook/src/MainModule.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | namespace DivaHook
6 | {
7 | class MainModule
8 | {
9 | private:
10 | static std::string *moduleDirectory;
11 |
12 | public:
13 | static const wchar_t* DivaWindowName;
14 | static const wchar_t* GlutDefaultName;
15 |
16 | static HWND DivaWindowHandle;
17 | static HMODULE Module;
18 |
19 | static std::string GetModuleDirectory();
20 | static RECT GetWindowBounds();
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/EnumBitwiseOperations.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Utilities
4 | {
5 | template inline T operator~ (T a) { return (T)~(int)a; }
6 | template inline T operator| (T a, T b) { return (T)((int)a | (int)b); }
7 | template inline T operator& (T a, T b) { return (T)((int)a & (int)b); }
8 | template inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); }
9 | template inline T& operator|= (T& a, T b) { return (T&)((int&)a |= (int)b); }
10 | template inline T& operator&= (T& a, T b) { return (T&)((int&)a &= (int)b); }
11 | template inline T& operator^= (T& a, T b) { return (T&)((int&)a ^= (int)b); }
12 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Math.cpp:
--------------------------------------------------------------------------------
1 | #define _USE_MATH_DEFINES
2 | #include "Math.h"
3 |
4 | namespace DivaHook::Utilities
5 | {
6 | float ToDegrees(float radians)
7 | {
8 | return radians * (180.0f / M_PI);
9 | }
10 |
11 | float ToRadians(float degrees)
12 | {
13 | return (degrees * M_PI) / 180.0f;
14 | }
15 |
16 | Vec2 GetDirection(float degrees)
17 | {
18 | float radians = ToRadians(degrees);
19 | return Vec2(cos(radians), sin(radians));
20 | }
21 |
22 | Vec2 PointFromAngle(float degrees, float distance)
23 | {
24 | float radians = ToRadians(degrees + 90.0f);
25 | return Vec2(-1 * std::cos(radians) * distance, -1 * std::sin(radians) * distance);
26 | }
27 |
28 | float AngleFromPoints(Vec2 p0, Vec2 p1)
29 | {
30 | return (float)(std::atan2(p1.Y - p0.Y, p1.X - p0.X) * 180.0 / M_PI) + 90.0f;
31 | }
32 |
33 | float ConvertRange(float originalStart, float originalEnd, float newStart, float newEnd, float value)
34 | {
35 | return newStart + ((value - originalStart) * (newEnd - newStart) / (originalEnd - originalStart));
36 | }
37 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Math.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include "Vec2.h"
4 | #include "Vec3.h"
5 |
6 | namespace DivaHook::Utilities
7 | {
8 | float ToDegrees(float radians);
9 | float ToRadians(float degrees);
10 |
11 | Vec2 GetDirection(float degrees);
12 | Vec2 PointFromAngle(float degrees, float distance);
13 | float AngleFromPoints(Vec2 p0, Vec2 p1);
14 | float ConvertRange(float originalStart, float originalEnd, float newStart, float newEnd, float value);
15 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Operations.cpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Operations.h"
3 |
4 | namespace DivaHook::Utilities
5 | {
6 | std::vector Split(const std::string& str, const std::string& delim)
7 | {
8 | std::vector tokens;
9 | size_t prev = 0, pos = 0;
10 | do
11 | {
12 | pos = str.find(delim, prev);
13 | if (pos == std::string::npos)
14 | pos = str.length();
15 |
16 | std::string token = str.substr(prev, pos - prev);
17 |
18 | if (!token.empty())
19 | tokens.push_back(token);
20 |
21 | prev = pos + delim.length();
22 | } while (pos < str.length() && prev < str.length());
23 |
24 | return tokens;
25 | }
26 |
27 | void LeftTrim(std::string &s)
28 | {
29 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch)
30 | {
31 | return !std::isspace(ch);
32 | }));
33 | }
34 |
35 | void RightTrim(std::string &s)
36 | {
37 | s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch)
38 | {
39 | return !std::isspace(ch);
40 | }).base(), s.end());
41 | }
42 |
43 | void Trim(std::string &s)
44 | {
45 | s = trim(s);
46 | }
47 |
48 | std::string trim(const std::string& str, const std::string& whitespace)
49 | {
50 | const size_t strBegin = str.find_first_not_of(whitespace);
51 |
52 | if (strBegin == std::string::npos)
53 | return "";
54 |
55 | const size_t strEnd = str.find_last_not_of(whitespace);
56 | const size_t strRange = strEnd - strBegin + 1;
57 |
58 | return str.substr(strBegin, strRange);
59 | }
60 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Operations.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | namespace DivaHook::Utilities
8 | {
9 | std::vector Split(const std::string& str, const std::string& delim);
10 |
11 | void LeftTrim(std::string &s);
12 | void RightTrim(std::string &s);
13 | void Trim(std::string &s);
14 |
15 | std::string trim(const std::string& str, const std::string& whitespace = " \t");
16 | }
17 |
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Stopwatch.cpp:
--------------------------------------------------------------------------------
1 | #include "Stopwatch.h"
2 |
3 | namespace DivaHook::Utilities
4 | {
5 | Stopwatch::Stopwatch()
6 | {
7 | }
8 |
9 | Stopwatch::~Stopwatch()
10 | {
11 | }
12 |
13 | void Stopwatch::Start()
14 | {
15 | start = high_resolution_clock::now();
16 | }
17 |
18 | float Stopwatch::Stop()
19 | {
20 | end = high_resolution_clock::now();
21 | return GetElapsed();
22 | }
23 |
24 | float Stopwatch::Restart()
25 | {
26 | float elapsed = Stop();
27 | Start();
28 |
29 | return elapsed;
30 | }
31 |
32 | float Stopwatch::GetElapsed()
33 | {
34 | return (float)(chrono::duration_cast(end - start).count() / TIME_FACTOR);
35 | }
36 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Stopwatch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace chrono = std::chrono;
5 |
6 | typedef chrono::time_point steady_clock;
7 | typedef chrono::high_resolution_clock high_resolution_clock;
8 |
9 | namespace DivaHook::Utilities
10 | {
11 | class Stopwatch
12 | {
13 | const float TIME_FACTOR = 1000.0f;
14 |
15 | public:
16 | Stopwatch();
17 | ~Stopwatch();
18 |
19 | void Start();
20 | float Stop();
21 | float Restart();
22 |
23 | float GetElapsed();
24 |
25 | private:
26 | steady_clock start;
27 | steady_clock end;
28 | };
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Vec2.cpp:
--------------------------------------------------------------------------------
1 | #include "Vec2.h"
2 |
3 | namespace DivaHook::Utilities
4 | {
5 | Vec2::Vec2()
6 | {
7 | };
8 |
9 | Vec2::Vec2(float x, float y) : X(x), Y(y)
10 | {
11 | };
12 |
13 | Vec2 Vec2::operator+(Vec2 value)
14 | {
15 | return Vec2(X + value.X, Y + value.Y);
16 | }
17 |
18 | void Vec2::operator+=(const Vec2 &value)
19 | {
20 | X += value.X;
21 | Y += value.Y;
22 | }
23 |
24 | Vec2 Vec2::operator-(Vec2 value)
25 | {
26 | return Vec2(X - value.X, Y - value.Y);
27 | }
28 |
29 | void Vec2::operator-=(const Vec2 &value)
30 | {
31 | X -= value.X;
32 | Y -= value.Y;
33 | }
34 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Vec2.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace DivaHook::Utilities
4 | {
5 | struct Vec2
6 | {
7 | float X, Y;
8 |
9 | Vec2();
10 | Vec2(float x, float y);
11 |
12 | Vec2 operator+(Vec2 value);
13 | void operator+=(const Vec2 &value);
14 |
15 | Vec2 operator-(Vec2 value);
16 | void operator-=(const Vec2 &value);
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Vec3.cpp:
--------------------------------------------------------------------------------
1 | #include "Vec3.h"
2 |
3 | namespace DivaHook::Utilities
4 | {
5 | Vec3::Vec3()
6 | {
7 | };
8 |
9 | Vec3::Vec3(float x, float y, float z) : X(x), Y(y), Z(z)
10 | {
11 | };
12 |
13 | Vec3 Vec3::operator+(Vec2 value)
14 | {
15 | return Vec3(X + value.X, Y, Z + value.Y);
16 | }
17 |
18 | void Vec3::operator+=(const Vec2 &value)
19 | {
20 | X += value.X;
21 | Z += value.Y;
22 | }
23 |
24 | Vec3 Vec3::operator-(Vec2 value)
25 | {
26 | return Vec3(X - value.X, Y, Z - value.Y);
27 | }
28 |
29 | void Vec3::operator-=(const Vec2 &value)
30 | {
31 | X -= value.X;
32 | Z -= value.Y;
33 | }
34 |
35 | Vec3 Vec3::operator+(Vec3 value)
36 | {
37 | return Vec3(X + value.X, Y + value.Y, Z + value.Z);
38 | }
39 |
40 | void Vec3::operator+=(const Vec3 &value)
41 | {
42 | X += value.X;
43 | Y += value.Y;
44 | Z += value.Z;
45 | }
46 |
47 | Vec3 Vec3::operator-(Vec3 value)
48 | {
49 | return Vec3(X - value.X, Y - value.Y, Z - value.Z);
50 | }
51 |
52 | void Vec3::operator-=(const Vec3 &value)
53 | {
54 | X -= value.X;
55 | Y -= value.Y;
56 | Z -= value.Z;
57 | }
58 | }
--------------------------------------------------------------------------------
/DivaHook/src/Utilities/Vec3.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Vec2.h"
3 |
4 | namespace DivaHook::Utilities
5 | {
6 | struct Vec3
7 | {
8 | float X, Y, Z;
9 |
10 | Vec3();
11 | Vec3(float x, float y, float z);
12 |
13 | // Vec2
14 | Vec3 operator+(Vec2 value);
15 | void operator+=(const Vec2 &value);
16 |
17 | Vec3 operator-(Vec2 value);
18 | void operator-=(const Vec2 &value);
19 |
20 | // Vec3
21 | Vec3 operator+(Vec3 value);
22 | void operator+=(const Vec3 &value);
23 |
24 | Vec3 operator-(Vec3 value);
25 | void operator-=(const Vec3 &value);
26 | };
27 | }
--------------------------------------------------------------------------------
/DivaHook/src/dllmain.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "Constants.h"
4 | #include "MainModule.h"
5 | #include "Input/Mouse/Mouse.h"
6 | #include "Input/Keyboard/Keyboard.h"
7 | #include "Input/DirectInput/DirectInput.h"
8 | #include "Input/DirectInput/Ds4/DualShock4.h"
9 | #include "Components/ComponentsManager.h"
10 |
11 | LRESULT CALLBACK MessageWindowProcessCallback(HWND, UINT, WPARAM, LPARAM);
12 | DWORD WINAPI WindowMessageDispatcher(LPVOID);
13 | VOID RegisterMessageWindowClass();
14 |
15 | struct
16 | {
17 | DWORD ID = NULL;
18 | HANDLE Handle = NULL;
19 | } MessageThread;
20 |
21 | const wchar_t *MessageWindowClassName = TEXT("MessageWindowClass");
22 | const wchar_t *MessageWindowName = TEXT("MessageWindowTitle");
23 |
24 | namespace DivaHook
25 | {
26 | Components::ComponentsManager ComponentsManager;
27 | bool DeviceConnected = true;
28 | bool FirstUpdateTick = true;
29 | bool HasWindowFocus, HadWindowFocus;
30 |
31 | void* InstallHook(void* source, void* destination, int length)
32 | {
33 | const DWORD minLen = 0xE;
34 |
35 | if (length < minLen)
36 | return NULL;
37 |
38 | BYTE stub[] =
39 | {
40 | 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ?ptr [$+6]
41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ptr???
42 | };
43 |
44 | void* trampoline = VirtualAlloc(0, length + sizeof(stub), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
45 |
46 | DWORD oldProtect;
47 | VirtualProtect(source, length, PAGE_EXECUTE_READWRITE, &oldProtect);
48 |
49 | DWORD64 returnAddress = (DWORD64)source + length;
50 |
51 | // trampoline
52 | memcpy(stub + 6, &returnAddress, 8);
53 |
54 | memcpy((void*)((DWORD_PTR)trampoline), source, length);
55 | memcpy((void*)((DWORD_PTR)trampoline + length), stub, sizeof(stub));
56 |
57 | // orig
58 | memcpy(stub + 6, &destination, 8);
59 | memcpy(source, stub, sizeof(stub));
60 |
61 | for (int i = minLen; i < length; i++)
62 | *(BYTE*)((DWORD_PTR)source + i) = NOP_OPCODE;
63 |
64 | VirtualProtect(source, length, oldProtect, &oldProtect);
65 |
66 | return (void*)((DWORD_PTR)trampoline);
67 | }
68 |
69 | void InitializeTick()
70 | {
71 | RegisterMessageWindowClass();
72 | if ((MessageThread.Handle = CreateThread(0, 0, WindowMessageDispatcher, 0, 0, 0)) == NULL)
73 | printf("InitializeTick(): CreateThread() Error: %d\n", GetLastError());
74 |
75 | MainModule::DivaWindowHandle = FindWindow(0, MainModule::DivaWindowName);
76 | if (MainModule::DivaWindowHandle == NULL)
77 | MainModule::DivaWindowHandle = FindWindow(0, MainModule::GlutDefaultName);
78 |
79 | HRESULT diInitResult = Input::InitializeDirectInput(MainModule::Module);
80 | if (FAILED(diInitResult))
81 | printf("InitializeTick(): Failed to initialize DirectInput. Error: 0x%08X\n", diInitResult);
82 |
83 | ComponentsManager.Initialize();
84 | }
85 |
86 | void UpdateTick()
87 | {
88 | if (FirstUpdateTick)
89 | {
90 | FirstUpdateTick = false;
91 | InitializeTick();
92 | }
93 |
94 | if (DeviceConnected)
95 | {
96 | DeviceConnected = false;
97 |
98 | if (!Input::DualShock4::InstanceInitialized())
99 | {
100 | if (Input::DualShock4::TryInitializeInstance())
101 | printf("UpdateTick(): DualShock4 connected and initialized\n");
102 | }
103 | }
104 |
105 | ComponentsManager.Update();
106 |
107 | HadWindowFocus = HasWindowFocus;
108 | HasWindowFocus = MainModule::DivaWindowHandle == NULL || GetForegroundWindow() == MainModule::DivaWindowHandle;
109 |
110 | if (HasWindowFocus)
111 | {
112 | Input::Keyboard::GetInstance()->PollInput();
113 | Input::Mouse::GetInstance()->PollInput();
114 |
115 | if (Input::DualShock4::GetInstance() != nullptr)
116 | {
117 | if (!Input::DualShock4::GetInstance()->PollInput())
118 | {
119 | Input::DualShock4::DeleteInstance();
120 | printf("UpdateTick(): DualShock4 connection lost\n");
121 | }
122 | }
123 |
124 | ComponentsManager.UpdateInput();
125 | }
126 |
127 | if (HasWindowFocus && !HadWindowFocus)
128 | ComponentsManager.OnFocusGain();
129 |
130 | if (!HasWindowFocus && HadWindowFocus)
131 | ComponentsManager.OnFocusLost();
132 | }
133 |
134 | void InstallHooks()
135 | {
136 | InstallHook((void*)ENGINE_UPDATE_HOOK_TARGET_ADDRESS, (void*)UpdateTick, 0xE);
137 | }
138 |
139 | void Dispose()
140 | {
141 | ComponentsManager.Dispose();
142 |
143 | delete Input::Keyboard::GetInstance();
144 | delete Input::Mouse::GetInstance();
145 | delete Input::DualShock4::GetInstance();
146 |
147 | Input::DisposeDirectInput();
148 |
149 | PostThreadMessage(MessageThread.ID, WM_QUIT, 0, 0);
150 | }
151 | }
152 |
153 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
154 | {
155 | switch (ul_reason_for_call)
156 | {
157 | case DLL_PROCESS_ATTACH:
158 | printf("DllMain(): Installing hooks...\n");
159 |
160 | DivaHook::InstallHooks();
161 | DivaHook::MainModule::Module = hModule;
162 | break;
163 |
164 | case DLL_PROCESS_DETACH:
165 | DivaHook::Dispose();
166 | break;
167 | }
168 |
169 | return TRUE;
170 | }
171 |
172 | DWORD WINAPI WindowMessageDispatcher(LPVOID lpParam)
173 | {
174 | HWND windowHandle = CreateWindowW(
175 | MessageWindowClassName,
176 | MessageWindowName,
177 | WS_OVERLAPPEDWINDOW,
178 | CW_USEDEFAULT, CW_USEDEFAULT,
179 | CW_USEDEFAULT, CW_USEDEFAULT,
180 | NULL, NULL,
181 | DivaHook::MainModule::Module,
182 | NULL);
183 |
184 | if (!windowHandle)
185 | {
186 | printf("WindowMessageDispatcher(): CreateWindowW() Error: %d\n", GetLastError());
187 | return 1;
188 | }
189 |
190 | MessageThread.ID = GetCurrentThreadId();
191 |
192 | MSG message;
193 | DWORD returnValue;
194 |
195 | printf("WindowMessageDispatcher(): Entering message loop...\n");
196 |
197 | while (1)
198 | {
199 | returnValue = GetMessage(&message, NULL, 0, 0);
200 | if (returnValue != -1)
201 | {
202 | TranslateMessage(&message);
203 | DispatchMessage(&message);
204 | }
205 | else
206 | {
207 | printf("WindowMessageDispatcher(): GetMessage() Error: %d\n", returnValue);
208 | }
209 | }
210 |
211 | DestroyWindow(windowHandle);
212 | return 0;
213 | }
214 |
215 | BOOL RegisterDeviceInterface(HWND hWnd, HDEVNOTIFY *hDeviceNotify)
216 | {
217 | DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = {};
218 |
219 | NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
220 | NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
221 |
222 | *hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
223 |
224 | return *hDeviceNotify != NULL;
225 | }
226 |
227 | LRESULT CALLBACK MessageWindowProcessCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
228 | {
229 | switch (message)
230 | {
231 | case WM_CREATE:
232 | {
233 | HDEVNOTIFY hDevNotify = NULL;
234 |
235 | if (!RegisterDeviceInterface(hWnd, &hDevNotify))
236 | printf("MessageWindowProcessCallback(): RegisterDeviceInterface() Error: %d\n", GetLastError());
237 |
238 | break;
239 | }
240 |
241 | case WM_DEVICECHANGE:
242 | {
243 | switch (wParam)
244 | {
245 | case DBT_DEVICEARRIVAL:
246 | DivaHook::DeviceConnected = true;
247 | break;
248 |
249 | default:
250 | break;
251 | }
252 | }
253 |
254 | default:
255 | return DefWindowProc(hWnd, message, wParam, lParam);
256 | }
257 |
258 | return 0;
259 | }
260 |
261 | VOID RegisterMessageWindowClass()
262 | {
263 | WNDCLASS windowClass = { };
264 |
265 | windowClass.lpfnWndProc = MessageWindowProcessCallback;
266 | windowClass.hInstance = DivaHook::MainModule::Module;
267 | windowClass.lpszClassName = MessageWindowClassName;
268 |
269 | RegisterClass(&windowClass);
270 | }
271 |
--------------------------------------------------------------------------------
/DivaHook/src/targetver.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samyuu/TotallyLegitArcadeController/327265b0e9c6c7e26d1bc5516e7293b02b7fef0e/DivaHook/src/targetver.h
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 nop
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Prepatch/Prepatch.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | 15.0
15 | {79E6DFBD-EA77-4498-A306-9E0F13AA16A1}
16 | Prepatch
17 | 10.0.17763.0
18 |
19 |
20 |
21 | Application
22 | true
23 | v141
24 | MultiByte
25 |
26 |
27 | Application
28 | false
29 | v141
30 | true
31 | MultiByte
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | $(SolutionDir)$(ProjectName)\bin-int\$(Platform)-$(Configuration)\
47 | $(SolutionDir)bin\$(Platform)-$(Configuration)\
48 | prepatch
49 |
50 |
51 | $(SolutionDir)$(ProjectName)\bin-int\$(Platform)-$(Configuration)\
52 | $(SolutionDir)bin\$(Platform)-$(Configuration)\
53 | prepatch
54 |
55 |
56 |
57 | Level3
58 | Disabled
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | Level3
68 | MaxSpeed
69 | true
70 | true
71 | true
72 | true
73 |
74 |
75 |
76 |
77 | true
78 | true
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/Prepatch/Prepatch.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;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 |
35 |
36 | Header Files
37 |
38 |
39 | Header Files
40 |
41 |
42 | Header Files
43 |
44 |
45 | Header Files
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Prepatch/rom/patch.txt:
--------------------------------------------------------------------------------
1 | // patch.txt for Hatsune Miku Project DIVA Arcade Future Tone
2 | // Version 7.10.00 (VERSION B/REVISION 3)
3 | // 2018-09-14T 14:26:44+09:00
4 | # file: patch.txt
5 | # author: samyuu
6 | # version: 1.00.00
7 | # date: 2019/03/17
8 | # image_base: 0x140000C00
9 |
10 | // Address : Length : Original bytes : Patched bytes
11 |
12 | // Use GLUT_CURSOR_RIGHT_ARROW instead of GLUT_CURSOR_NONE
13 | 0x000000014019341B : 0x0001 : 65 : 00
14 |
15 | // Disable the keychip time bomb
16 | 0x0000000140210820 : 0x0006 : 40 53 48 83 EC 20 : B8 00 00 00 00 C3
17 |
18 | // Always return true for the SelCredit enter SelPv check
19 | 0x0000000140393610 : 0x0006 : 40 53 48 83 EC 20 : B0 01 C3 90 90 90
20 |
21 | // Just completely ignore all SYSTEM_STARTUP errors
22 | 0x00000001403F5080 : 0x0001 : 40 : C3
23 |
24 | // Always exit TASK_MODE_APP_ERROR on the first frame
25 | 0x00000001403F73A7 : 0x0002 : 74 26 : 90 90
26 | 0x00000001403F73C3 : 0x0003 : 0F 45 CA : 89 D1 90
27 |
28 | // Ignore the EngineClear variable to clear the framebuffer at all resolutions
29 | 0x0000000140501480 : 0x0002 : 74 0C : 90 90
30 | 0x0000000140501515 : 0x0002 : 74 2F : 90 90
31 |
32 | // Don't update the touch slider state so we can write our own
33 | 0x000000014061579B : 0x0009 : 89 41 F4 8B 42 E0 89 41 F8 : 90 90 90 8B 42 E0 90 90 90
34 |
35 | // Write ram files to the current directory instead of Y:/SBZV/ram
36 | 0x000000014066CF09 : 0x0003 : 0F 85 D7 : E9 D8 00
37 |
38 | // *But of course we have a valid keychip*, return true
39 | 0x000000014066E820 : 0x0006 : 0F B6 05 E3 65 62 : B8 01 00 00 00 C3
40 |
41 | // Skip parts of the network check state
42 | 0x00000001406717B1 : 0x0004 : 0F 85 21 03 : E9 22 03 00
43 |
44 | // Set the initial DHCP WAIT timer value to 0
45 | 0x00000001406724E7 : 0x0002 : A0 8C : 00 00
46 |
47 | // Ignore SYSTEM_STARTUP Location Server checks
48 | 0x00000001406732A2 : 0x0002 : 75 1E : 90 90
--------------------------------------------------------------------------------
/Prepatch/src/Patch/Patch.cpp:
--------------------------------------------------------------------------------
1 | #include "Patch.h"
2 | #include
3 | #include "../StringOperations/Operations.h"
4 |
5 | namespace Patch
6 | {
7 | Patch::Patch()
8 | {
9 | }
10 |
11 | Patch::~Patch()
12 | {
13 | for (auto& patchData : PatchDataVector)
14 | delete patchData;
15 | }
16 |
17 | bool Patch::ParseFile(const std::string& patchPath)
18 | {
19 | printf("Patch::ParseFile(): Opening patch file...\n");
20 |
21 | std::ifstream fileStream(patchPath);
22 |
23 | if (!fileStream.is_open())
24 | {
25 | printf("Patch::ParseFile(): Unable to open input file: %s\n", patchPath.c_str());
26 | return FALSE;
27 | }
28 |
29 | printf("Patch::ParseFile(): Parsing patch file...\n");
30 |
31 | std::string commentPrefix = "//";
32 | std::string headerPrefix = "#";
33 | std::string seperator = ":";
34 | std::string byteSeperator = " ";
35 |
36 | std::string line;
37 | while (getline(fileStream, line))
38 | {
39 | if (!line.compare(0, commentPrefix.size(), commentPrefix))
40 | continue;
41 |
42 | if (!line.compare(0, headerPrefix.size(), headerPrefix))
43 | {
44 | auto split = StringOperations::Split(line, seperator);
45 |
46 | if (split.size() != 2)
47 | continue;
48 |
49 | auto type = split[0].substr(1);
50 | auto value = split[1];
51 | StringOperations::Trim(type);
52 | StringOperations::Trim(value);
53 |
54 | if (type == "file")
55 | FileName = value;
56 | else if (type == "author")
57 | Author = value;
58 | else if (type == "version")
59 | Version = value;
60 | else if (type == "date")
61 | Date = value;
62 | else if (type == "image_base")
63 | ImageBase = _strtoi64(value.c_str(), nullptr, 16);
64 |
65 | continue;
66 | }
67 |
68 | auto valueSplit = StringOperations::Split(line, seperator);
69 |
70 | if (valueSplit.size() != 4)
71 | continue;
72 |
73 | for (auto& str : valueSplit)
74 | StringOperations::Trim(str);
75 |
76 | char* buffer;
77 | auto patchData = new PatchData();
78 |
79 | patchData->Address = _strtoi64(valueSplit[0].c_str(), &buffer, 16);
80 | if (buffer == nullptr)
81 | continue;
82 |
83 | patchData->Length = strtol(valueSplit[1].c_str(), &buffer, 16);
84 | if (buffer == nullptr)
85 | continue;
86 |
87 | auto originalBytesString = StringOperations::Split(valueSplit[2], byteSeperator);
88 | auto patchedBytesString = StringOperations::Split(valueSplit[3], byteSeperator);
89 |
90 | patchData->OriginalBytes = new BYTE[patchData->Length];
91 | for (int i = 0; i < patchData->Length; i++)
92 | patchData->OriginalBytes[i] = strtol(originalBytesString[i].c_str(), nullptr, 16);
93 |
94 | patchData->PatchedBytes = new BYTE[patchData->Length];
95 | for (int i = 0; i < patchData->Length; i++)
96 | patchData->PatchedBytes[i] = strtol(patchedBytesString[i].c_str(), nullptr, 16);
97 |
98 | PatchDataVector.push_back(patchData);
99 | }
100 |
101 | return TRUE;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Prepatch/src/Patch/Patch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include "PatchData.h"
6 |
7 | namespace Patch
8 | {
9 | class Patch
10 | {
11 | public:
12 | std::string FileName;
13 | std::string Author;
14 | std::string Version;
15 | std::string Date;
16 | DWORD64 ImageBase;
17 | std::vector PatchDataVector;
18 |
19 | Patch();
20 | ~Patch();
21 | bool ParseFile(const std::string& patchPath);
22 | };
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Prepatch/src/Patch/PatchData.cpp:
--------------------------------------------------------------------------------
1 | #include "PatchData.h"
2 |
3 | namespace Patch
4 | {
5 | Patch::PatchData::PatchData()
6 | {
7 | }
8 |
9 | Patch::PatchData::~PatchData()
10 | {
11 | if (OriginalBytes != nullptr)
12 | delete[] OriginalBytes;
13 |
14 | if (PatchedBytes != nullptr)
15 | delete[] PatchedBytes;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Prepatch/src/Patch/PatchData.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace Patch
5 | {
6 | struct PatchData
7 | {
8 | DWORD64 Address;
9 | DWORD Length;
10 | BYTE* OriginalBytes;
11 | BYTE* PatchedBytes;
12 |
13 | PatchData();
14 | ~PatchData();
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/Prepatch/src/Patch/Patcher.cpp:
--------------------------------------------------------------------------------
1 | #include "Patcher.h"
2 |
3 | namespace Patch
4 | {
5 | static bool EndsWith(const std::string& str, const std::string& suffix)
6 | {
7 | return str.size() >= suffix.size() && 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
8 | }
9 |
10 | Patcher::Patcher()
11 | {
12 | }
13 |
14 | Patcher::~Patcher()
15 | {
16 | if (patch != nullptr)
17 | delete patch;
18 | }
19 |
20 | bool Patcher::LoadPatchFile(std::string patchFile)
21 | {
22 | printf("Patcher::LoadPatchFile(): Opening patch file...\n");
23 |
24 | patch = new Patch();
25 | bool result = patch->ParseFile(patchFile);
26 |
27 | if (result)
28 | {
29 | printf("Patcher::LoadPatchFile(): Patch file loaded\n");
30 | }
31 | else
32 | {
33 | printf("Patcher::LoadPatchFile(): Failed to load patch file\n");
34 | }
35 |
36 | return result;
37 | }
38 |
39 | bool Patcher::PatchProgram(std::string executablePath)
40 | {
41 | if (patch == nullptr)
42 | {
43 | printf("Patcher::PatchProgram(): No patch has been loaded.\n");
44 | return FALSE;
45 | }
46 |
47 | if (!EndsWith(executablePath, ".exe"))
48 | {
49 | printf("Patcher::PatchProgram(): The input file is not an executable\n");
50 | return FALSE;
51 | }
52 |
53 | FILE* file = nullptr;
54 | auto error = fopen_s(&file, executablePath.c_str(), "rb");
55 |
56 | if (file == nullptr)
57 | {
58 | printf("Patcher::PatchProgram(): Unable to open input file %s. Error: 0x%X\n", executablePath.c_str(), error);
59 | return FALSE;
60 | }
61 |
62 | fseek(file, 0, SEEK_END);
63 | int fileSize = ftell(file);
64 | rewind(file);
65 |
66 | BYTE* buffer = new BYTE[fileSize];
67 |
68 | fread(buffer, 1, fileSize, file);
69 | fclose(file);
70 |
71 | fopen_s(&file, executablePath.c_str(), "wb");
72 | fwrite(buffer, 1, fileSize, file);
73 |
74 | for (auto& patchData : patch->PatchDataVector)
75 | {
76 | printf("Patcher::PatchProgram(): Patching - Address: 0x%016I64X Data: ", patchData->Address);
77 | for (int i = 0; i < patchData->Length; i++)
78 | printf("%02X", patchData->PatchedBytes[i]);
79 | printf("\n");
80 |
81 | auto fileAddress = patchData->Address - patch->ImageBase;
82 |
83 | fseek(file, fileAddress, SEEK_SET);
84 | fwrite(patchData->PatchedBytes, 1, patchData->Length, file);
85 | }
86 |
87 | printf("Patcher::PatchProgram(): Patches applied\n");
88 | printf("Patcher::PatchProgram(): Closing file...\n");
89 |
90 | fclose(file);
91 | delete[] buffer;
92 |
93 | return TRUE;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Prepatch/src/Patch/Patcher.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include "Patch.h"
5 |
6 | namespace Patch
7 | {
8 | class Patcher
9 | {
10 | public:
11 | Patcher();
12 | ~Patcher();
13 | bool LoadPatchFile(std::string patchFile);
14 | bool PatchProgram(std::string executablePath);
15 |
16 | private:
17 | Patch* patch;
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/Prepatch/src/StringOperations/Operations.cpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Operations.h"
3 |
4 | namespace StringOperations
5 | {
6 | std::vector Split(const std::string& str, const std::string& delim)
7 | {
8 | std::vector tokens;
9 | size_t prev = 0, pos = 0;
10 | do
11 | {
12 | pos = str.find(delim, prev);
13 | if (pos == std::string::npos)
14 | pos = str.length();
15 |
16 | std::string token = str.substr(prev, pos - prev);
17 |
18 | if (!token.empty())
19 | tokens.push_back(token);
20 |
21 | prev = pos + delim.length();
22 | } while (pos < str.length() && prev < str.length());
23 |
24 | return tokens;
25 | }
26 |
27 | void LeftTrim(std::string &s)
28 | {
29 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch)
30 | {
31 | return !std::isspace(ch);
32 | }));
33 | }
34 |
35 | void RightTrim(std::string &s)
36 | {
37 | s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch)
38 | {
39 | return !std::isspace(ch);
40 | }).base(), s.end());
41 | }
42 |
43 | void Trim(std::string &s)
44 | {
45 | LeftTrim(s);
46 | RightTrim(s);
47 | }
48 | }
--------------------------------------------------------------------------------
/Prepatch/src/StringOperations/Operations.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | namespace StringOperations
8 | {
9 | std::vector Split(const std::string& str, const std::string& delim);
10 |
11 | void LeftTrim(std::string &s);
12 | void RightTrim(std::string &s);
13 | void Trim(std::string &s);
14 | }
15 |
--------------------------------------------------------------------------------
/Prepatch/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "Patch/Patcher.h"
2 |
3 | const std::string PATCH_FILE_FILE_NAME = "patch.txt";
4 | const std::string DIVA_PROCESS_NAME = "diva.exe";
5 |
6 | int GetDirectorySeperatorPosition(std::string path)
7 | {
8 | for (int i = path.size() - 1; i >= 0; i--)
9 | {
10 | auto currentChar = path[i];
11 | if (currentChar == '\\' || currentChar == '/')
12 | return i;
13 | }
14 |
15 | return -1;
16 | }
17 |
18 | std::string GetModuleDirectory()
19 | {
20 | HMODULE module = GetModuleHandleW(NULL);
21 | CHAR modulePathBuffer[MAX_PATH];
22 | GetModuleFileName(module, modulePathBuffer, MAX_PATH);
23 |
24 | auto modulePath = std::string(modulePathBuffer);
25 | int seperatorPos = GetDirectorySeperatorPosition(modulePath);
26 |
27 | if (seperatorPos != -1)
28 | return std::string(modulePathBuffer).substr(0, seperatorPos);
29 |
30 | return NULL;
31 | }
32 |
33 | bool DoesFileExist(std::string filePath)
34 | {
35 | auto fileAttrib = GetFileAttributes(filePath.c_str());
36 | return fileAttrib != INVALID_FILE_ATTRIBUTES;
37 | }
38 |
39 | int main(int argc, char** argv)
40 | {
41 | printf("main(): Checking %s location...\n", PATCH_FILE_FILE_NAME.c_str());
42 |
43 | auto moduleDirectory = GetModuleDirectory();
44 | auto patchPath = moduleDirectory + "/" + PATCH_FILE_FILE_NAME;
45 |
46 | if (!DoesFileExist(patchPath))
47 | {
48 | printf("main(): Unable to locate %s\n", PATCH_FILE_FILE_NAME.c_str());
49 | printf("main(): Press enter to exit...");
50 | std::cin.get();
51 | return EXIT_FAILURE;
52 | }
53 | else
54 | {
55 | printf("main(): %s successfully located\n", PATCH_FILE_FILE_NAME.c_str());
56 | }
57 |
58 | printf("main(): Checking executable location...\n");
59 |
60 | if (argc < 2)
61 | {
62 | printf("main(): Insufficient number of arguments supplied\n");
63 | printf("main(): Please drag the target %s on top of this executable to apply the patches\n", DIVA_PROCESS_NAME.c_str());
64 | printf("main(): Press enter to exit...");
65 | std::cin.get();
66 | return EXIT_FAILURE;
67 | }
68 |
69 | std::string executablePath = std::string(argv[1]);
70 |
71 | if (!DoesFileExist(executablePath))
72 | {
73 | printf("main(): Unable to locate %s\n", executablePath.c_str());
74 | printf("main(): Press enter to exit...");
75 | std::cin.get();
76 | return EXIT_FAILURE;
77 | }
78 | else
79 | {
80 | printf("main(): %s successfully located\n", executablePath.c_str());
81 | }
82 |
83 | Patch::Patcher patcher;
84 | patcher.LoadPatchFile(patchPath);
85 | patcher.PatchProgram(executablePath);
86 |
87 | printf("main(): Press enter to exit...");
88 | std::cin.get();
89 | return EXIT_SUCCESS;
90 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Totally Legit Arcade Controller (TLAC)
2 | ELAC's reborn big brother
3 |
4 | # Description
5 | This program consists of three parts:
6 | ##### Prepatch:
7 | Used for applying the static patches from the `patch.txt` file to allow the game to successfully boot past all startup checks.
8 | ##### Divahook:
9 | Installs a hook on the game's update routine to update its components.
10 | ##### TLAC:
11 | Injects the divahook dll inside the game's process.
12 |
13 | ## Components
14 | The available components can be toggled inside the `components.ini` config file. Currently available are:
15 | * input_emulator
16 | * touch_slider_emulator
17 | * touch_panel_emulator
18 | * sys_timer
19 | * player_data_manager
20 | * frame_rate_manager
21 | * stage_manager
22 | * fast_loader
23 | * camera_controller
24 | * debug_component
25 |
26 | ## Controls
27 | Input bindings can be set inside the `keyconfig.ini` config file. Currently supported are keyboard and DualShock 4 controller input.
28 | Key and button names are listed inside this config.
29 |
30 | ## Player Data
31 | If enabled the PlayerDataManager writes constant values from the `playerdata.ini` config file to the game's memory.
32 | This allows the user to set their player name, a level plate ID to be shown during the song select, equip a skin to be loaded during gameplay and button / slide sounds to be applied to all songs played.
33 | This config file **must be** encoded using UTF-8.
34 |
35 | ## Debug Component
36 | This component enables diva's internal dw_gui and makes the hidden DATA_TESTs accessible.
37 | The current game state can be changed using the F4 - F8 keys with F6 being a recreation of the original DATA_TEST_MAIN inside the console which can be controlled using the up / down arrow + enter key.
38 |
39 | # Usage
40 | First **once per update** patch a clean `diva.exe` using the `prepatch.exe` program by passing the `diva.exe` path to it as its first command line argument; This can be done by dragging the diva executable on top of the prepatch executable inside the windows file explorer. It is strongly recommended to always create a backup of the original diva executable first.
41 |
42 | To start diva run `diva.exe` like normal, to enable the components start `tlac.exe` **while** diva is running.
43 | Do this **every time** you wish to run diva.
44 |
45 | Diva has a few notable command line arguments including `-w` to start in windowed mode and `-hdtv1080` to increase the resolution to 1920x1080.
46 |
47 | # Binaries
48 | Pre-compiled binaries for the latest major updates can be found under the [releases](https://github.com/samyuu/TotallyLegitArcadeController/releases) tab.
49 |
--------------------------------------------------------------------------------
/TotallyLegitArcadeController.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28010.2050
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DivaHook", "DivaHook\DivaHook.vcxproj", "{69BCF67B-34D9-4424-A2A8-3A056E9D38A6}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TotallyLegitArcadeController", "TotallyLegitArcadeController\TotallyLegitArcadeController.vcxproj", "{B50A691D-DDEC-46E0-90CE-A46EF190D2A3}"
9 | EndProject
10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Prepatch", "Prepatch\Prepatch.vcxproj", "{79E6DFBD-EA77-4498-A306-9E0F13AA16A1}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|x64 = Debug|x64
15 | Release|x64 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {69BCF67B-34D9-4424-A2A8-3A056E9D38A6}.Debug|x64.ActiveCfg = Debug|x64
19 | {69BCF67B-34D9-4424-A2A8-3A056E9D38A6}.Debug|x64.Build.0 = Debug|x64
20 | {69BCF67B-34D9-4424-A2A8-3A056E9D38A6}.Release|x64.ActiveCfg = Release|x64
21 | {69BCF67B-34D9-4424-A2A8-3A056E9D38A6}.Release|x64.Build.0 = Release|x64
22 | {B50A691D-DDEC-46E0-90CE-A46EF190D2A3}.Debug|x64.ActiveCfg = Debug|x64
23 | {B50A691D-DDEC-46E0-90CE-A46EF190D2A3}.Debug|x64.Build.0 = Debug|x64
24 | {B50A691D-DDEC-46E0-90CE-A46EF190D2A3}.Release|x64.ActiveCfg = Release|x64
25 | {B50A691D-DDEC-46E0-90CE-A46EF190D2A3}.Release|x64.Build.0 = Release|x64
26 | {79E6DFBD-EA77-4498-A306-9E0F13AA16A1}.Debug|x64.ActiveCfg = Debug|x64
27 | {79E6DFBD-EA77-4498-A306-9E0F13AA16A1}.Debug|x64.Build.0 = Debug|x64
28 | {79E6DFBD-EA77-4498-A306-9E0F13AA16A1}.Release|x64.ActiveCfg = Release|x64
29 | {79E6DFBD-EA77-4498-A306-9E0F13AA16A1}.Release|x64.Build.0 = Release|x64
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {41A2E0D2-365A-43B8-BA48-A9A9A4B78CFD}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/TotallyLegitArcadeController/TotallyLegitArcadeController.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;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 |
26 |
27 | Header Files
28 |
29 |
30 |
--------------------------------------------------------------------------------
/TotallyLegitArcadeController/TotallyLegitArcadeController.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | 15.0
15 | {B50A691D-DDEC-46E0-90CE-A46EF190D2A3}
16 | TotallyLegitArcadeController
17 | 10.0.17763.0
18 | TotallyLegitArcadeController
19 |
20 |
21 |
22 | Application
23 | true
24 | v141
25 | MultiByte
26 |
27 |
28 | Application
29 | false
30 | v141
31 | true
32 | MultiByte
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | tlac
48 | $(SolutionDir)bin\$(Platform)-$(Configuration)\
49 | $(SolutionDir)$(ProjectName)\bin-int\$(Platform)-$(Configuration)\
50 |
51 |
52 | tlac
53 | $(SolutionDir)bin\$(Platform)-$(Configuration)\
54 | $(SolutionDir)$(ProjectName)\bin-int\$(Platform)-$(Configuration)\
55 |
56 |
57 |
58 | Level3
59 | Disabled
60 | true
61 | true
62 |
63 |
64 |
65 |
66 | Level3
67 | MaxSpeed
68 | true
69 | true
70 | true
71 | true
72 |
73 |
74 | true
75 | true
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/TotallyLegitArcadeController/src/Injection/DllInjector.cpp:
--------------------------------------------------------------------------------
1 | #include "DllInjector.h"
2 |
3 | namespace Injection
4 | {
5 | int DllInjector::GetProcessID(const std::string& processName)
6 | {
7 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
8 | PROCESSENTRY32 structprocsnapshot = { 0 };
9 |
10 | structprocsnapshot.dwSize = sizeof(PROCESSENTRY32);
11 |
12 | if (snapshot == INVALID_HANDLE_VALUE || Process32First(snapshot, &structprocsnapshot) == FALSE)
13 | return NULL;
14 |
15 | while (Process32Next(snapshot, &structprocsnapshot))
16 | {
17 | if (!strcmp(structprocsnapshot.szExeFile, processName.c_str()))
18 | {
19 | CloseHandle(snapshot);
20 |
21 | printf("DllInjector::GetProcessID(): Process %s found. Process ID: %d\n", processName.c_str(), structprocsnapshot.th32ProcessID);
22 | return structprocsnapshot.th32ProcessID;
23 | }
24 | }
25 | CloseHandle(snapshot);
26 |
27 | printf("DllInjector::GetProcessID(): Process %s not found\n", processName.c_str());
28 | return NULL;
29 | }
30 |
31 | bool DllInjector::InjectDll(const int &processId, const std::string &dllPath)
32 | {
33 | long dllSize = dllPath.length() + 1;
34 | HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
35 |
36 | if (hProc == NULL)
37 | {
38 | printf("DllInjector::InjectDll(): Failed to OpenProcess() target. Error: 0x%X\n", GetLastError());
39 | return false;
40 | }
41 |
42 | printf("DllInjector::InjectDll(): Opening target process...\n");
43 |
44 | LPVOID myAlloc = VirtualAllocEx(hProc, NULL, dllSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
45 | if (myAlloc == NULL)
46 | {
47 | printf("DllInjector::InjectDll(): Failed to allocate memory in target process. Error: 0x%X\n", GetLastError());
48 | return false;
49 | }
50 |
51 | printf("DllInjector::InjectDll(): Allocating memory in targer process...\n");
52 |
53 | int isWriteOK = WriteProcessMemory(hProc, myAlloc, dllPath.c_str(), dllSize, 0);
54 | if (isWriteOK == 0)
55 | {
56 | printf("DllInjector::InjectDll(): Failed to WriteProcessMemory() in target. Error: 0x%X\n", GetLastError());
57 | return false;
58 | }
59 | printf("DllInjector::InjectDll(): Creating remote thread in target process...\n");
60 |
61 | DWORD threadId;
62 | LPTHREAD_START_ROUTINE addrLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("kernel32"), "LoadLibraryA");
63 | HANDLE threadReturn = CreateRemoteThread(hProc, NULL, 0, addrLoadLibrary, myAlloc, 0, &threadId);
64 |
65 | if (threadReturn == NULL)
66 | {
67 | printf("DllInjector::InjectDll(): Failed to CreateRemoteThread() in target. Error: 0x%X\n", GetLastError());
68 | return false;
69 | }
70 |
71 | if ((hProc != NULL) && (myAlloc != NULL) && (isWriteOK != ERROR_INVALID_HANDLE) && (threadReturn != NULL))
72 | {
73 | printf("DllInjector::InjectDll(): The Dll has been successfully injected\n");
74 | return true;
75 | }
76 |
77 | return false;
78 | }
79 |
80 | bool DllInjector::InjectDll(const std::string& processName, const std::string &dllPath)
81 | {
82 | return InjectDll(GetProcessID(processName), dllPath);
83 | }
84 | }
--------------------------------------------------------------------------------
/TotallyLegitArcadeController/src/Injection/DllInjector.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #pragma comment(lib, "Shlwapi.lib")
7 |
8 | namespace Injection
9 | {
10 | class DllInjector
11 | {
12 | public:
13 | int GetProcessID(const std::string& processName);
14 | bool InjectDll(const int &processId, const std::string &dllPath);
15 | bool InjectDll(const std::string& processName, const std::string &dllPath);
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/TotallyLegitArcadeController/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "Injection/DllInjector.h"
2 |
3 | const char* TLAC_VERSION = "2.00.00";
4 |
5 | const std::string DIVA_PROCESS_NAME = "diva.exe";
6 | const std::string DIVA_HOOK_DLL_NAME = "divahook.dll";
7 |
8 | char waitDisplayStrings[8][6] =
9 | {
10 | "o....",
11 | ".o...",
12 | "..o..",
13 | "...o.",
14 | "....o",
15 | "...o.",
16 | "..o..",
17 | ".o...",
18 | };
19 |
20 | int GetDirectorySeperatorPosition(std::string path)
21 | {
22 | for (int i = path.size() - 1; i >= 0; i--)
23 | {
24 | auto currentChar = path[i];
25 | if (currentChar == '\\' || currentChar == '/')
26 | return i;
27 | }
28 |
29 | return -1;
30 | }
31 |
32 | std::string GetModuleDirectory()
33 | {
34 | HMODULE module = GetModuleHandleW(NULL);
35 | CHAR modulePathBuffer[MAX_PATH];
36 | GetModuleFileName(module, modulePathBuffer, MAX_PATH);
37 |
38 | auto modulePath = std::string(modulePathBuffer);
39 | int seperatorPos = GetDirectorySeperatorPosition(modulePath);
40 |
41 | if (seperatorPos != -1)
42 | return std::string(modulePathBuffer).substr(0, seperatorPos);
43 |
44 | return NULL;
45 | }
46 |
47 | void PrintProgramInfo()
48 | {
49 | printf("// -------------------------------------------------\n");
50 |
51 | #ifdef _DEBUG
52 | printf("// -- DEBUG_BUILD: --\n//\n");
53 | #endif
54 |
55 | printf("// Totally Legit Arcade Controller (TLAC) \n");
56 | printf("// \n");
57 | printf("// v.%s -by samyuu \n", TLAC_VERSION);
58 | printf("// -------------------------------------------------\n");
59 | }
60 |
61 | COORD GetConsoleCursorPosition(HANDLE hConsoleOutput)
62 | {
63 | CONSOLE_SCREEN_BUFFER_INFO cbsi;
64 | GetConsoleScreenBufferInfo(hConsoleOutput, &cbsi);
65 | return cbsi.dwCursorPosition;
66 | }
67 |
68 | void WaitExit(int duration = 6000, int iterations = 32 + 1)
69 | {
70 | DWORD interval = duration / iterations;
71 |
72 | auto consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
73 |
74 | CONSOLE_CURSOR_INFO cursorInfo;
75 | GetConsoleCursorInfo(consoleHandle, &cursorInfo);
76 |
77 | cursorInfo.bVisible = false;
78 | SetConsoleCursorInfo(consoleHandle, &cursorInfo);
79 | {
80 | auto prerPos = GetConsoleCursorPosition(consoleHandle);
81 |
82 | for (int i = 0; i < iterations; i++)
83 | {
84 | SetConsoleCursorPosition(consoleHandle, prerPos);
85 | printf("%s", waitDisplayStrings[i % 8]);
86 | Sleep(interval);
87 | }
88 | }
89 | cursorInfo.bVisible = true;
90 | SetConsoleCursorInfo(consoleHandle, &cursorInfo);
91 | }
92 |
93 | bool DoesFileExist(std::string filePath)
94 | {
95 | auto fileAttrib = GetFileAttributes(filePath.c_str());
96 | return fileAttrib != INVALID_FILE_ATTRIBUTES;
97 | }
98 |
99 | int main(int argc, char** argv)
100 | {
101 | PrintProgramInfo();
102 |
103 | auto moduleDirectory = GetModuleDirectory();
104 | auto dllPath = moduleDirectory + "/" + DIVA_HOOK_DLL_NAME;
105 |
106 | if (!DoesFileExist(dllPath))
107 | {
108 | printf("main(): Unable to locate %s\n", DIVA_HOOK_DLL_NAME.c_str());
109 | printf("main(): Press enter to exit...");
110 | std::cin.get();
111 | return EXIT_FAILURE;
112 | }
113 | else
114 | {
115 | printf("main(): %s successfully located\n", DIVA_HOOK_DLL_NAME.c_str());
116 | }
117 |
118 | Injection::DllInjector injector;
119 | bool result = injector.InjectDll(DIVA_PROCESS_NAME, dllPath);
120 |
121 | if (!result)
122 | {
123 | printf("main(): Injection failed. Press enter to exit...");
124 | std::cin.get();
125 | return EXIT_FAILURE;
126 | }
127 |
128 | printf("main(): Exiting ");
129 |
130 | WaitExit();
131 | return EXIT_SUCCESS;
132 | }
133 |
--------------------------------------------------------------------------------