├── .gitignore ├── LICENSE ├── README.md ├── RawMouse.sln └── RawMouse ├── MemoryMgr.h ├── MenuManager.h ├── RawMouse.def ├── RawMouse.rc ├── RawMouse.vcxproj ├── RawMouse.vcxproj.filters ├── dllmain.cpp ├── logitech ├── LogitechGkeyLib.h └── LogitechGkeyLib.lib └── resource.h /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | [Nn]ormal/ 14 | [Nn]ightly/ 15 | output/ 16 | symbols/ 17 | x64/ 18 | x86/ 19 | build/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | #NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | *.cso 33 | *_i.c 34 | *_p.c 35 | *_i.h 36 | *.ilk 37 | *.meta 38 | *.obj 39 | *.pch 40 | *.pdb 41 | *.pgc 42 | *.pgd 43 | *.rsp 44 | *.sbr 45 | *.tlb 46 | *.tli 47 | *.tlh 48 | *.tmp 49 | *.tmp_proj 50 | *.log 51 | *.vspscc 52 | *.vssscc 53 | .builds 54 | *.pidb 55 | *.svclog 56 | *.scc 57 | 58 | # Chutzpah Test files 59 | _Chutzpah* 60 | 61 | # Visual C++ cache files 62 | ipch/ 63 | *.aps 64 | *.ncb 65 | *.opensdf 66 | *.sdf 67 | *.db 68 | *.opendb 69 | *.cachefile 70 | 71 | # Visual Studio profiler 72 | *.psess 73 | *.vsp 74 | *.vspx 75 | 76 | # TFS 2012 Local Workspace 77 | $tf/ 78 | 79 | # Guidance Automation Toolkit 80 | *.gpState 81 | 82 | # ReSharper is a .NET coding add-in 83 | _ReSharper*/ 84 | *.[Rr]e[Ss]harper 85 | *.DotSettings.user 86 | 87 | # JustCode is a .NET coding addin-in 88 | .JustCode 89 | 90 | # TeamCity is a build add-in 91 | _TeamCity* 92 | 93 | # DotCover is a Code Coverage Tool 94 | *.dotCover 95 | 96 | # NCrunch 97 | *.ncrunch* 98 | _NCrunch_* 99 | .*crunch*.local.xml 100 | 101 | # MightyMoose 102 | *.mm.* 103 | AutoTest.Net/ 104 | 105 | # Web workbench (sass) 106 | .sass-cache/ 107 | 108 | # Installshield output folder 109 | [Ee]xpress/ 110 | 111 | # DocProject is a documentation generator add-in 112 | DocProject/buildhelp/ 113 | DocProject/Help/*.HxT 114 | DocProject/Help/*.HxC 115 | DocProject/Help/*.hhc 116 | DocProject/Help/*.hhk 117 | DocProject/Help/*.hhp 118 | DocProject/Help/Html2 119 | DocProject/Help/html 120 | 121 | # Click-Once directory 122 | publish/ 123 | 124 | # Publish Web Output 125 | *.[Pp]ublish.xml 126 | *.azurePubxml 127 | 128 | # NuGet Packages Directory 129 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 130 | #packages/* 131 | ## TODO: If the tool you use requires repositories.config, also uncomment the next line 132 | #!packages/repositories.config 133 | 134 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 135 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 136 | !packages/build/ 137 | 138 | # Windows Azure Build Output 139 | csx/ 140 | *.build.csdef 141 | 142 | # Windows Store app package directory 143 | AppPackages/ 144 | 145 | # Others 146 | sql/ 147 | *.Cache 148 | ClientBin/ 149 | [Ss]tyle[Cc]op.* 150 | ~$* 151 | *~ 152 | *.dbmdl 153 | *.dbproj.schemaview 154 | *.pfx 155 | *.publishsettings 156 | node_modules/ 157 | 158 | # RIA/Silverlight projects 159 | Generated_Code/ 160 | 161 | # Backup & report files from converting an old project file to a newer 162 | # Visual Studio version. Backup files are not needed, because we have git ;-) 163 | _UpgradeReport_Files/ 164 | Backup*/ 165 | UpgradeLog*.XML 166 | UpgradeLog*.htm 167 | 168 | # SQL Server files 169 | App_Data/*.mdf 170 | App_Data/*.ldf 171 | 172 | # Business Intelligence projects 173 | *.rdl.data 174 | *.bim.layout 175 | *.bim_*.settings 176 | 177 | # Microsoft Fakes 178 | FakesAssemblies/ 179 | 180 | # ========================= 181 | # Windows detritus 182 | # ========================= 183 | 184 | # Windows image file caches 185 | Thumbs.db 186 | ehthumbs.db 187 | 188 | # Folder config file 189 | Desktop.ini 190 | 191 | # Recycle Bin used on file shares 192 | $RECYCLE.BIN/ 193 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Adrian Zdanowicz (Silent) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RawMouse 2 | Raw Input mouse mod for GTA SA (and possibly GTA III and GTA VC) 3 | -------------------------------------------------------------------------------- /RawMouse.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RawMouse", "RawMouse\RawMouse.vcxproj", "{49574EBA-DCF8-448E-B798-9279FC8CC488}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {49574EBA-DCF8-448E-B798-9279FC8CC488}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {49574EBA-DCF8-448E-B798-9279FC8CC488}.Debug|Win32.Build.0 = Debug|Win32 16 | {49574EBA-DCF8-448E-B798-9279FC8CC488}.Release|Win32.ActiveCfg = Release|Win32 17 | {49574EBA-DCF8-448E-B798-9279FC8CC488}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /RawMouse/MemoryMgr.h: -------------------------------------------------------------------------------- 1 | #ifndef __MEMORYMGR 2 | #define __MEMORYMGR 3 | 4 | // Switches: 5 | // _MEMORY_NO_CRT - don't include anything "complex" like ScopedUnprotect or memset 6 | // _MEMORY_DECLS_ONLY - don't include anything but macroes 7 | 8 | #define WRAPPER __declspec(naked) 9 | #define DEPRECATED __declspec(deprecated) 10 | #define EAXJMP(a) { _asm mov eax, a _asm jmp eax } 11 | #define VARJMP(a) { _asm jmp a } 12 | #define WRAPARG(a) ((int)a) 13 | 14 | #define NOVMT __declspec(novtable) 15 | #define SETVMT(a) *((uintptr_t*)this) = (uintptr_t)a 16 | 17 | #ifndef _MEMORY_DECLS_ONLY 18 | 19 | #define WIN32_LEAN_AND_MEAN 20 | #include 21 | 22 | #include 23 | 24 | enum 25 | { 26 | PATCH_CALL, 27 | PATCH_JUMP 28 | }; 29 | 30 | inline signed char* GetVer() 31 | { 32 | static signed char bVer = -1; 33 | return &bVer; 34 | } 35 | 36 | inline bool* GetEuropean() 37 | { 38 | static bool bEuropean; 39 | return &bEuropean; 40 | } 41 | 42 | inline void* GetDummy() 43 | { 44 | static uintptr_t dwDummy; 45 | return &dwDummy; 46 | } 47 | 48 | template 49 | inline AT DynBaseAddress(AT address) 50 | { 51 | return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address; 52 | } 53 | 54 | #if defined _GTA_III 55 | 56 | inline void InitializeVersions() 57 | { 58 | signed char* bVer = GetVer(); 59 | 60 | if ( *bVer == -1 ) 61 | { 62 | if (*(uint32_t*)0x5C1E70 == 0x53E58955) *bVer = 0; 63 | else if (*(uint32_t*)0x5C2130 == 0x53E58955) *bVer = 1; 64 | else if (*(uint32_t*)0x5C6FD0 == 0x53E58955) *bVer = 2; 65 | } 66 | } 67 | 68 | // This function initially detects III version then chooses the address basing on game version 69 | template 70 | inline T AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam) 71 | { 72 | InitializeVersions(); 73 | 74 | signed char bVer = *GetVer(); 75 | 76 | switch ( bVer ) 77 | { 78 | case 1: 79 | #ifdef assert 80 | assert(address11); 81 | #endif 82 | return (T)address11; 83 | case 2: 84 | #ifdef assert 85 | assert(addressSteam); 86 | #endif 87 | return (T)addressSteam; 88 | default: 89 | #ifdef assert 90 | assert(address10); 91 | #endif 92 | return (T)address10; 93 | } 94 | } 95 | 96 | #elif defined _GTA_VC 97 | 98 | inline void InitializeVersions() 99 | { 100 | signed char* bVer = GetVer(); 101 | 102 | if ( *bVer == -1 ) 103 | { 104 | if (*(uint32_t*)0x667BF0 == 0x53E58955) *bVer = 0; 105 | else if (*(uint32_t*)0x667C40 == 0x53E58955) *bVer = 1; 106 | else if (*(uint32_t*)0x666BA0 == 0x53E58955) *bVer = 2; 107 | } 108 | } 109 | 110 | // This function initially detects VC version then chooses the address basing on game version 111 | template 112 | inline T AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam) 113 | { 114 | InitializeVersions(); 115 | 116 | signed char bVer = *GetVer(); 117 | 118 | switch ( bVer ) 119 | { 120 | case 1: 121 | #ifdef assert 122 | assert(address11); 123 | #endif 124 | return (T)address11; 125 | case 2: 126 | #ifdef assert 127 | assert(addressSteam); 128 | #endif 129 | return (T)addressSteam; 130 | default: 131 | #ifdef assert 132 | assert(address10); 133 | #endif 134 | return (T)address10; 135 | } 136 | } 137 | 138 | #elif defined _GTA_SA 139 | 140 | inline void InitializeVersions() 141 | { 142 | signed char* bVer = GetVer(); 143 | bool* bEuropean = GetEuropean(); 144 | 145 | if ( *bVer == -1 ) 146 | { 147 | if ( *(uint32_t*)DynBaseAddress(0x82457C) == 0x94BF ) 148 | { 149 | // 1.0 US 150 | *bVer = 0; 151 | *bEuropean = false; 152 | } 153 | else if ( *(uint32_t*)DynBaseAddress(0x8245BC) == 0x94BF ) 154 | { 155 | // 1.0 EU 156 | *bVer = 0; 157 | *bEuropean = true; 158 | } 159 | else if ( *(uint32_t*)DynBaseAddress(0x8252FC) == 0x94BF ) 160 | { 161 | // 1.01 US 162 | *bVer = 1; 163 | *bEuropean = false; 164 | } 165 | else if ( *(uint32_t*)DynBaseAddress(0x82533C) == 0x94BF ) 166 | { 167 | // 1.01 EU 168 | *bVer = 1; 169 | *bEuropean = true; 170 | } 171 | else if (*(uint32_t*)DynBaseAddress(0x85EC4A) == 0x94BF ) 172 | { 173 | // 3.0 174 | *bVer = 2; 175 | *bEuropean = false; 176 | } 177 | 178 | else if ( *(uint32_t*)DynBaseAddress(0x858D21) == 0x3539F633 ) 179 | { 180 | // newsteam r1 181 | *bVer = 3; 182 | *bEuropean = false; 183 | } 184 | else if ( *(uint32_t*)DynBaseAddress(0x858D51) == 0x3539F633 ) 185 | { 186 | // newsteam r2 187 | *bVer = 4; 188 | *bEuropean = false; 189 | } 190 | else if ( *(uint32_t*)DynBaseAddress(0x858C61) == 0x3539F633 ) 191 | { 192 | // newsteam r2 lv 193 | *bVer = 5; 194 | *bEuropean = false; 195 | } 196 | } 197 | } 198 | 199 | inline void InitializeRegion_10() 200 | { 201 | bool* bEuropean = GetEuropean(); 202 | signed char* bVer = GetVer(); 203 | 204 | if ( *bVer == -1 ) 205 | { 206 | if ( *(uint32_t*)0x82457C == 0x94BF ) 207 | { 208 | *bVer = 0; 209 | *bEuropean = false; 210 | } 211 | else if ( *(uint32_t*)0x8245BC == 0x94BF ) 212 | { 213 | *bVer = 0; 214 | *bEuropean = true; 215 | } 216 | else 217 | { 218 | #ifdef assert 219 | assert(!"AddressByRegion_10 on non-1.0 EXE!"); 220 | #endif 221 | } 222 | } 223 | } 224 | 225 | inline void InitializeRegion_11() 226 | { 227 | bool* bEuropean = GetEuropean(); 228 | signed char* bVer = GetVer(); 229 | 230 | if ( *bVer == -1 ) 231 | { 232 | if ( *(uint32_t*)0x8252FC == 0x94BF ) 233 | { 234 | *bVer = 1; 235 | *bEuropean = false; 236 | } 237 | else if ( *(uint32_t*)0x82533C == 0x94BF ) 238 | { 239 | *bVer = 1; 240 | *bEuropean = true; 241 | } 242 | else 243 | { 244 | #ifdef assert 245 | assert(!"AddressByRegion_11 on non-1.01 EXE!"); 246 | #endif 247 | } 248 | } 249 | } 250 | 251 | // This function initially detects SA version then chooses the address basing on game version 252 | template 253 | inline T AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam) 254 | { 255 | InitializeVersions(); 256 | 257 | signed char bVer = *GetVer(); 258 | bool bEuropean = *GetEuropean(); 259 | 260 | switch ( bVer ) 261 | { 262 | case 1: 263 | #ifdef assert 264 | assert(address11); 265 | #endif 266 | 267 | // Safety measures - if null, return dummy var pointer to prevent a crash 268 | if ( !address11 ) 269 | return (T)GetDummy(); 270 | 271 | // Adjust to US if needed 272 | if ( !bEuropean && address11 > 0x746FA0 ) 273 | { 274 | if ( address11 < 0x7BB240 ) 275 | address11 -= 0x50; 276 | else 277 | address11 -= 0x40; 278 | } 279 | return (T)address11; 280 | case 2: 281 | #ifdef assert 282 | assert(addressSteam); 283 | #endif 284 | // Safety measures - if null, return dummy var pointer to prevent a crash 285 | if ( !addressSteam ) 286 | return (T)GetDummy(); 287 | 288 | return (T)addressSteam; 289 | case 3: 290 | case 4: 291 | case 5: 292 | // TODO: DO 293 | return (T)GetDummy(); 294 | default: 295 | #ifdef assert 296 | assert(address10); 297 | #endif 298 | // Adjust to EU if needed 299 | if ( bEuropean && address10 > 0x7466D0 ) 300 | { 301 | if ( address10 < 0x7BA940 ) 302 | address10 += 0x50; 303 | else 304 | address10 += 0x40; 305 | } 306 | return (T)address10; 307 | } 308 | } 309 | 310 | template 311 | inline T AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam, uintptr_t addressNewsteamR2, uintptr_t addressNewsteamR2_LV) 312 | { 313 | InitializeVersions(); 314 | 315 | signed char bVer = *GetVer(); 316 | bool bEuropean = *GetEuropean(); 317 | 318 | switch ( bVer ) 319 | { 320 | case 1: 321 | #ifdef assert 322 | assert(address11); 323 | #endif 324 | 325 | // Safety measures - if null, return dummy var pointer to prevent a crash 326 | if ( !address11 ) 327 | return (T)GetDummy(); 328 | 329 | // Adjust to US if needed 330 | if ( bEuropean && address11 > 0x746FA0 ) 331 | { 332 | if ( address11 < 0x7BB240 ) 333 | address11 -= 0x50; 334 | else 335 | address11 -= 0x40; 336 | } 337 | return (T)address11; 338 | case 2: 339 | #ifdef assert 340 | assert(addressSteam); 341 | #endif 342 | // Safety measures - if null, return dummy var pointer to prevent a crash 343 | if ( !addressSteam ) 344 | return (T)GetDummy(); 345 | 346 | return (T)addressSteam; 347 | case 3: 348 | return (T)GetDummy(); 349 | case 4: 350 | #ifdef assert 351 | assert(addressNewsteamR2); 352 | #endif 353 | if ( !addressNewsteamR2 ) 354 | return (T)GetDummy(); 355 | 356 | return (T)DynBaseAddress(addressNewsteamR2); 357 | case 5: 358 | #ifdef assert 359 | assert(addressNewsteamR2_LV); 360 | #endif 361 | if ( !addressNewsteamR2_LV ) 362 | return (T)GetDummy(); 363 | 364 | return (T)DynBaseAddress(addressNewsteamR2_LV); 365 | default: 366 | #ifdef assert 367 | assert(address10); 368 | #endif 369 | // Adjust to EU if needed 370 | if ( bEuropean && address10 > 0x7466D0 ) 371 | { 372 | if ( address10 < 0x7BA940 ) 373 | address10 += 0x50; 374 | else 375 | address10 += 0x40; 376 | } 377 | return (T)address10; 378 | } 379 | } 380 | 381 | template 382 | inline T AddressByRegion_10(uintptr_t address10) 383 | { 384 | InitializeRegion_10(); 385 | 386 | bool bEuropean = *GetEuropean(); 387 | 388 | // Adjust to EU if needed 389 | if ( bEuropean && address10 > 0x7466D0 ) 390 | { 391 | if ( address10 < 0x7BA940 ) 392 | address10 += 0x50; 393 | else 394 | address10 += 0x40; 395 | } 396 | return (T)address10; 397 | } 398 | 399 | template 400 | inline T AddressByRegion_11(uintptr_t address11) 401 | { 402 | InitializeRegion_11(); 403 | 404 | bool bEuropean = *GetEuropean(); 405 | 406 | // Adjust to US if needed 407 | if ( !bEuropean && address11 > 0x746FA0 ) 408 | { 409 | if ( address11 < 0x7BB240 ) 410 | address11 -= 0x50; 411 | else 412 | address11 -= 0x40; 413 | } 414 | return (T)address11; 415 | } 416 | 417 | #endif 418 | 419 | namespace Memory 420 | { 421 | template 422 | inline void Patch(AT address, T value) 423 | {*(T*)address = value; } 424 | 425 | template 426 | inline void Nop(AT address, size_t count) 427 | #ifndef _MEMORY_NO_CRT 428 | { memset((void*)address, 0x90, count); } 429 | #else 430 | { do { 431 | *(uint8_t*)address++ = 0x90; 432 | } while ( --count != 0 ); } 433 | #endif 434 | 435 | template 436 | inline void InjectHook(AT address, HT hook) 437 | { 438 | intptr_t dwHook; 439 | _asm 440 | { 441 | mov eax, hook 442 | mov dwHook, eax 443 | } 444 | 445 | *(ptrdiff_t*)((intptr_t)address + 1) = dwHook - (intptr_t)address - 5; 446 | } 447 | 448 | template 449 | inline void InjectHook(AT address, HT hook, unsigned int nType) 450 | { 451 | intptr_t dwHook; 452 | _asm 453 | { 454 | mov eax, hook 455 | mov dwHook, eax 456 | } 457 | 458 | *(uint8_t*)address = nType == PATCH_JUMP ? 0xE9 : 0xE8; 459 | 460 | *(ptrdiff_t*)((intptr_t)address + 1) = dwHook - (intptr_t)address - 5; 461 | } 462 | 463 | template 464 | inline void ReadCall(AT address, Func& func) 465 | { 466 | func = Func(*(ptrdiff_t*)((intptr_t)address+1) + (intptr_t)address + 5); 467 | } 468 | 469 | namespace DynBase 470 | { 471 | template 472 | inline void Patch(AT address, T value) 473 | { 474 | Memory::Patch(DynBaseAddress(address), value); 475 | } 476 | 477 | template 478 | inline void Nop(AT address, size_t count) 479 | { 480 | Memory::Nop(DynBaseAddress(address), count); 481 | } 482 | 483 | template 484 | inline void InjectHook(AT address, HT hook) 485 | { 486 | Memory::InjectHook(DynBaseAddress(address), hook); 487 | } 488 | 489 | template 490 | inline void InjectHook(AT address, HT hook, unsigned int nType) 491 | { 492 | Memory::InjectHook(DynBaseAddress(address), hook, nType); 493 | } 494 | 495 | template 496 | inline void ReadCall(AT address, Func& func) 497 | { 498 | Memory::ReadCall(DynBaseAddress(address), func); 499 | } 500 | }; 501 | 502 | namespace VP 503 | { 504 | template 505 | inline void Patch(AT address, T value) 506 | { 507 | DWORD dwProtect[2]; 508 | VirtualProtect((void*)address, sizeof(T), PAGE_EXECUTE_READWRITE, &dwProtect[0]); 509 | Memory::Patch( address, value ); 510 | VirtualProtect((void*)address, sizeof(T), dwProtect[0], &dwProtect[1]); 511 | } 512 | 513 | template 514 | inline void Nop(AT address, size_t count) 515 | { 516 | DWORD dwProtect[2]; 517 | VirtualProtect((void*)address, count, PAGE_EXECUTE_READWRITE, &dwProtect[0]); 518 | Memory::Nop( address, count ); 519 | VirtualProtect((void*)address, count, dwProtect[0], &dwProtect[1]); 520 | } 521 | 522 | template 523 | inline void InjectHook(AT address, HT hook) 524 | { 525 | DWORD dwProtect[2]; 526 | 527 | VirtualProtect((void*)((DWORD)address + 1), 4, PAGE_EXECUTE_READWRITE, &dwProtect[0]); 528 | Memory::InjectHook( address, hook ); 529 | VirtualProtect((void*)((DWORD)address + 1), 4, dwProtect[0], &dwProtect[1]); 530 | } 531 | 532 | template 533 | inline void InjectHook(AT address, HT hook, unsigned int nType) 534 | { 535 | DWORD dwProtect[2]; 536 | 537 | VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect[0]); 538 | Memory::InjectHook( address, hook, nType ); 539 | VirtualProtect((void*)address, 5, dwProtect[0], &dwProtect[1]); 540 | } 541 | 542 | template 543 | inline void ReadCall(AT address, Func& func) 544 | { 545 | Memory::ReadCall(address, func); 546 | } 547 | 548 | namespace DynBase 549 | { 550 | template 551 | inline void Patch(AT address, T value) 552 | { 553 | VP::Patch(DynBaseAddress(address), value); 554 | } 555 | 556 | template 557 | inline void Nop(AT address, size_t count) 558 | { 559 | VP::Nop(DynBaseAddress(address), count); 560 | } 561 | 562 | template 563 | inline void InjectHook(AT address, HT hook) 564 | { 565 | VP::InjectHook(DynBaseAddress(address), hook); 566 | } 567 | 568 | template 569 | inline void InjectHook(AT address, HT hook, unsigned int nType) 570 | { 571 | VP::InjectHook(DynBaseAddress(address), hook, nType); 572 | } 573 | 574 | template 575 | inline void ReadCall(AT address, Func& func) 576 | { 577 | Memory::ReadCall(DynBaseAddress(address), func); 578 | } 579 | }; 580 | }; 581 | }; 582 | 583 | #ifndef _MEMORY_NO_CRT 584 | 585 | #include 586 | #include 587 | 588 | class ScopedUnprotect 589 | { 590 | public: 591 | class Section 592 | { 593 | public: 594 | Section( HINSTANCE hInstance, const char* name ) 595 | { 596 | IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((BYTE*)hInstance + ((IMAGE_DOS_HEADER*)hInstance)->e_lfanew); 597 | IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(ntHeader); 598 | 599 | DWORD VirtualAddress = MAXDWORD; 600 | SIZE_T VirtualSize = MAXDWORD; 601 | for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection ) 602 | { 603 | if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 ) 604 | { 605 | VirtualAddress = (DWORD)hInstance + pSection->VirtualAddress; 606 | VirtualSize = pSection->Misc.VirtualSize; 607 | break; 608 | } 609 | } 610 | 611 | if ( VirtualAddress == MAXDWORD ) 612 | return; 613 | 614 | SIZE_T QueriedSize = 0; 615 | while ( QueriedSize < VirtualSize ) 616 | { 617 | MEMORY_BASIC_INFORMATION MemoryInf; 618 | DWORD dwOldProtect; 619 | 620 | VirtualQuery( (LPCVOID)(VirtualAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) ); 621 | VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect ); 622 | m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect ); 623 | QueriedSize += MemoryInf.RegionSize; 624 | } 625 | }; 626 | 627 | ~Section() 628 | { 629 | for ( auto& it : m_queriedProtects ) 630 | { 631 | DWORD dwOldProtect; 632 | VirtualProtect( std::get<0>(it), std::get<1>(it), std::get<2>(it), &dwOldProtect ); 633 | } 634 | } 635 | 636 | private: 637 | std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects; 638 | }; 639 | }; 640 | 641 | #endif 642 | 643 | #endif 644 | 645 | #endif -------------------------------------------------------------------------------- /RawMouse/MenuManager.h: -------------------------------------------------------------------------------- 1 | #ifndef __CMENUMANAGER 2 | #define __CMENUMANAGER 3 | 4 | class CMenuManagerIII 5 | { 6 | public: 7 | BYTE bRadioStation; 8 | DWORD dwUnk; 9 | BYTE bUnk; 10 | bool bVibrationEnabled; 11 | bool bHudEnabled; 12 | int nRadarMode; 13 | BYTE __pad1[257]; 14 | bool bMenuActive; 15 | 16 | public: 17 | void MessageScreen(const char* pText); 18 | }; 19 | 20 | class CMenuManagerVC 21 | { 22 | public: 23 | BYTE bRadioStation; 24 | DWORD dwUnk; 25 | BYTE bUnk; 26 | bool bVibrationEnabled; 27 | bool bHudEnabled; 28 | int nRadarMode; 29 | BYTE __pad1[40]; 30 | bool bMenuActive; 31 | 32 | public: 33 | void MessageScreen(const char* pText, bool bFullscreen); 34 | }; 35 | 36 | class CMenuManagerSA 37 | { 38 | public: 39 | bool m_bStatScrollUp; 40 | float m_fStatsScrollSpeed; 41 | __int8 field_8; 42 | __int8 field_9[23]; 43 | bool bVibrationEnabled; 44 | unsigned char m_bHudOn; 45 | __int8 field_22[2]; 46 | __int32 m_dwRadarMode; 47 | __int8 field_28[4]; 48 | __int32 field_2C; 49 | __int8 field_30; 50 | __int8 field_31; 51 | bool m_bBackIntoGame; 52 | bool m_bActivateMenuNextFrame; 53 | bool m_bMenuAccessWidescreen; 54 | __int8 field_35; 55 | __int8 field_36[2]; 56 | __int32 field_38; 57 | __int32 m_dwBrightness; 58 | float m_fDrawDistance; 59 | bool m_bShowSubtitles; 60 | bool m_bMapShowLocations; 61 | bool m_bMapShowContacts; 62 | bool m_bMapShowMission; 63 | bool m_bMapShowOther; 64 | bool m_bMapShowGangArea; 65 | bool m_bMapLegend; 66 | unsigned char m_bAspectRatioMode; 67 | unsigned char m_bFrameLimiterMode; 68 | bool m_bRadioAutoSelect; 69 | __int8 field_4E; 70 | __int8 m_nSfxVolume; 71 | __int8 m_nRadioVolume; 72 | bool m_bRadioEq; 73 | signed char m_nRadioStation; 74 | __int8 field_53; 75 | unsigned int m_dwSelectedMenuItem; 76 | __int8 field_58; 77 | __int8 drawRadarOrMap; 78 | __int8 field_5A; 79 | __int8 field_5B; 80 | bool m_bMenuActive; 81 | __int8 doGameReload; 82 | __int8 field_5E; 83 | __int8 isSaveDone; 84 | bool m_bLoadingData; 85 | __int8 field_61[3]; 86 | float m_fMapZoom; 87 | float m_fMapBaseX; 88 | float m_fMapBaseY; 89 | float m_vMousePos[2]; 90 | bool m_bMapLoaded; 91 | __int8 field_79[3]; 92 | __int32 titleLanguage; 93 | __int32 textLanguage; 94 | unsigned char m_nLanguage; 95 | unsigned char m_nPrevLanguage; 96 | __int8 field_86[2]; 97 | __int32 field_88; 98 | bool m_bLanguageChanged; 99 | __int8 field_8D[3]; 100 | __int32 field_90; 101 | __int8 field_94[24]; 102 | __int32 field_AC; 103 | __int8 m_nRadioMode; 104 | __int8 invertPadX1; 105 | __int8 invertPadY1; 106 | __int8 invertPadX2; 107 | __int8 invertPadY2; 108 | __int8 swapPadAxis1; 109 | __int8 swapPadAxis2; 110 | bool m_bInVehicleControlsScreen; 111 | bool m_bDrawMouse; 112 | __int8 field_B9[3]; 113 | __int32 m_dwMousePosLeft; 114 | __int32 m_dwMousePosTop; 115 | bool m_bMipMapping; 116 | bool m_bTracksAutoScan; 117 | __int16 field_C6; 118 | __int32 m_dwAppliedAntiAliasingLevel; 119 | __int32 m_dwAntiAliasingLevel; 120 | __int8 m_nController; 121 | __int8 field_D1[3]; 122 | __int32 m_dwAppliedResolution; 123 | __int32 m_dwResolution; 124 | __int32 field_DC; 125 | __int32 mousePosLeftA; 126 | __int32 mousePosTopA; 127 | bool m_bSavePhotos; 128 | bool m_bMainMenuSwitch; 129 | __int8 m_nPlayerNumber; 130 | bool m_bReinitLanguageSettings; 131 | __int32 field_EC; 132 | void* field_F0; 133 | __int8 field_F4; 134 | __int8 field_F5[3]; 135 | union{ 136 | struct{ 137 | void** m_apTextures[25]; 138 | }; 139 | struct{ 140 | void** m_apRadioSprites[13]; 141 | void** m_apBackgroundTextures[8]; 142 | void** m_apAdditionalBackgroundTextures[2]; 143 | void** m_apMouseTextures[2]; 144 | }; 145 | }; 146 | bool m_bTexturesLoaded; 147 | signed char m_bCurrentMenuPage; 148 | signed char m_bLastMenuPage; 149 | unsigned char m_bSelectedSaveGame; 150 | unsigned char m_bSelectedMissionPack; 151 | __int8 field_161; 152 | char m_mpackName[8]; 153 | __int8 field_16A[6486]; 154 | __int32 field_1AC0; 155 | __int32 field_1AC4; 156 | __int32 field_1AC8; 157 | __int32 field_1ACC; 158 | __int32 field_1AD0; 159 | __int32 field_1AD4; 160 | __int32 field_1AD8; 161 | __int16 field_1ADC; 162 | bool m_bChangeVideoMode; 163 | __int8 field_1ADF; 164 | int m_PressedMouseButton; 165 | __int32 field_1AE4; 166 | __int8 field_1AE8; 167 | __int8 field_1AE9; 168 | __int8 field_1AEA; 169 | __int8 field_1AEB; 170 | __int32 field_1AEC; 171 | __int8 field_1AF0; 172 | __int8 field_1AF1; 173 | __int8 field_1AF2; 174 | __int8 field_1AF3; 175 | __int32 field_1AF4; 176 | __int32 field_1AF8; 177 | __int32 field_1AFC; 178 | int m_nHoverOption; 179 | __int32 field_1B04; 180 | __int8 field_1B08; 181 | __int8 field_1B09; 182 | __int8 field_1B0A; 183 | __int8 field_1B0B; 184 | __int32 field_1B0C; 185 | __int8 field_1B10; 186 | __int8 field_1B11; 187 | __int8 field_1B12; 188 | __int8 field_1B13; 189 | __int8 field_1B14; 190 | __int8 field_1B15; 191 | __int8 field_1B16; 192 | __int8 field_1B17; 193 | int m_nHelperTextIndex; 194 | __int32 field_1B1C; 195 | __int8 field_1B20; 196 | __int8 field_1B21; 197 | __int16 field_1B22; 198 | __int32 field_1B24; 199 | __int8 field_1B28; 200 | __int8 field_1B29; 201 | __int16 field_1B2A; 202 | __int32 field_1B2C; 203 | __int32 field_1B30; 204 | __int16 field_1B34; 205 | __int16 field_1B36; 206 | __int32 field_1B38; 207 | __int8 field_1B3C; 208 | __int8 field_1B3D; 209 | __int8 field_1B3E; 210 | __int8 field_1B3F; 211 | __int32 field_1B40; 212 | __int8 field_1B44; 213 | __int8 field_1B45; 214 | __int16 field_1B46; 215 | __int32 field_1B48; 216 | __int32 field_1B4C; 217 | __int8 m_nBackgroundSprite; 218 | __int8 field_1B51; 219 | __int16 field_1B52; 220 | __int32 field_1B54; 221 | __int32 field_1B58; 222 | __int8 field_1B5C; 223 | __int8 field_1B5D; 224 | __int16 field_1B5E; 225 | __int32 field_1B60; 226 | __int32 field_1B64; 227 | __int32 field_1B68; 228 | __int32 field_1B6C; 229 | __int32 field_1B70; 230 | __int32 field_1B74; 231 | 232 | public: 233 | void MessageScreen(const char* pText, bool bFullscreen, bool bWithinFrame); 234 | bool NeedsToRefreshHelps(); 235 | }; 236 | 237 | #if defined _GTA_III 238 | typedef CMenuManagerIII CMenuManager; 239 | #elif defined _GTA_VC 240 | typedef CMenuManagerVC CMenuManager; 241 | #elif defined _GTA_SA 242 | typedef CMenuManagerSA CMenuManager; 243 | #endif 244 | 245 | extern CMenuManager& FrontEndMenuManager; 246 | 247 | #endif -------------------------------------------------------------------------------- /RawMouse/RawMouse.def: -------------------------------------------------------------------------------- 1 | LIBRARY RawMouse.asi 2 | EXPORTS 3 | RawMouse_UsesGKeys @1 4 | RawMouse_GetNewGKeysState @2 5 | RawMouse_GetOldGKeysState @3 -------------------------------------------------------------------------------- /RawMouse/RawMouse.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CookiePLMonster/RawMouse/aa158f3003d8987b425e34afad9ef58ff1084118/RawMouse/RawMouse.rc -------------------------------------------------------------------------------- /RawMouse/RawMouse.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {49574EBA-DCF8-448E-B798-9279FC8CC488} 15 | RawMouse 16 | 7.0 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | v141_xp 23 | Unicode 24 | 25 | 26 | DynamicLibrary 27 | false 28 | v141_xp 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | .asi 44 | 45 | 46 | .asi 47 | 48 | 49 | 50 | Level4 51 | Disabled 52 | true 53 | _GTA_SA;%(PreprocessorDefinitions) 54 | MultiThreadedDebug 55 | NoExtensions 56 | Fast 57 | 58 | 59 | true 60 | Windows 61 | logitech/LogitechGkeyLib.lib;%(AdditionalDependencies) 62 | RawMouse.def 63 | 64 | 65 | 66 | if defined GTA_SA_ROOT ( 67 | copy /y "$(TargetPath)" "%GTA_SA_ROOT%\RawMouse.asi" 68 | ) 69 | 70 | 71 | 72 | 73 | Level4 74 | MaxSpeed 75 | true 76 | true 77 | true 78 | _GTA_SA;%(PreprocessorDefinitions) 79 | true 80 | MultiThreaded 81 | NoExtensions 82 | Fast 83 | 84 | 85 | true 86 | true 87 | true 88 | Windows 89 | logitech/LogitechGkeyLib.lib;%(AdditionalDependencies) 90 | RawMouse.def 91 | 92 | 93 | 94 | if defined GTA_SA_ROOT ( 95 | copy /y "$(TargetPath)" "%GTA_SA_ROOT%\RawMouse.asi" 96 | ) 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /RawMouse/RawMouse.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;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 | {d9317e76-755e-415c-9f40-83ac7732a85b} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files\logitech 34 | 35 | 36 | Header Files 37 | 38 | 39 | 40 | 41 | Resource Files 42 | 43 | 44 | -------------------------------------------------------------------------------- /RawMouse/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #define WINVER 0x0502 3 | #define _WIN32_WINNT 0x0502 4 | 5 | #include 6 | #include 7 | #include "MemoryMgr.h" 8 | #include "MenuManager.h" 9 | 10 | #include "logitech/LogitechGkeyLib.h" 11 | 12 | // GKey uniquefier for CControllerConfigManager 13 | #define GKEY_UID 0x4C470000 14 | 15 | struct PsGlobalType 16 | { 17 | HWND window; 18 | DWORD instance; 19 | DWORD fullscreen; 20 | DWORD lastMousePos_X; 21 | DWORD lastMousePos_Y; 22 | DWORD unk; 23 | DWORD diInterface; 24 | DWORD diMouse; 25 | void* diDevice1; 26 | void* diDevice2; 27 | }; 28 | 29 | struct RsGlobalType 30 | { 31 | const char* AppName; 32 | #ifndef _GTA_SA 33 | unsigned int unkWidth, unkHeight; 34 | #endif 35 | signed int MaximumWidth; 36 | signed int MaximumHeight; 37 | unsigned int frameLimit; 38 | BOOL quit; 39 | PsGlobalType* ps; 40 | void* keyboard; 41 | void* mouse; 42 | void* pad; 43 | }; 44 | 45 | // Logitech G Keys 46 | class CGKeysControllerState 47 | { 48 | public: 49 | bool MouseGKeyState[LOGITECH_MAX_MOUSE_BUTTONS]; 50 | bool KeyboardGKeyState[LOGITECH_MAX_M_STATES][LOGITECH_MAX_GKEYS]; 51 | 52 | public: 53 | bool CheckForInput() const 54 | { 55 | for ( ptrdiff_t i = 6; i <= LOGITECH_MAX_MOUSE_BUTTONS; ++i ) 56 | { 57 | if ( MouseGKeyState[i-1] ) 58 | return true; 59 | } 60 | for ( ptrdiff_t i = 0; i < LOGITECH_MAX_M_STATES; ++i ) 61 | { 62 | for ( ptrdiff_t j = 0; j < LOGITECH_MAX_GKEYS; ++j ) 63 | { 64 | if ( KeyboardGKeyState[i][j] ) 65 | return true; 66 | } 67 | } 68 | return false; 69 | } 70 | }; 71 | 72 | class CMouseControllerState 73 | { 74 | public: 75 | bool lmb; 76 | bool rmb; 77 | bool mmb; 78 | bool wheelUp; 79 | bool wheelDown; 80 | bool bmx1; 81 | bool bmx2; 82 | float Z; 83 | float X; 84 | float Y; 85 | 86 | public: 87 | inline bool CheckForInput() const 88 | { return lmb || rmb || mmb || wheelUp || wheelDown || bmx1 || bmx2 || X != 0.0f || Y != 0.0f; } 89 | }; 90 | 91 | class CMousePointerStateHelper 92 | { 93 | public: 94 | bool m_bVerticalInvert; 95 | bool m_bHorizontalInvert; 96 | 97 | public: 98 | CMouseControllerState* GetMouseSetUp( CMouseControllerState* mouseCaps ); 99 | }; 100 | 101 | class CControllerState 102 | { 103 | public: 104 | short LEFTSTICKX; 105 | short LEFTSTICKY; 106 | short RIGHTSTICKX; 107 | short RIGHTSTICKY; 108 | 109 | short LEFTSHOULDER1; 110 | short LEFTSHOULDER2; 111 | short RIGHTSHOULDER1; 112 | short RIGHTSHOULDER2; 113 | 114 | short DPADUP; 115 | short DPADDOWN; 116 | short DPADLEFT; 117 | short DPADRIGHT; 118 | 119 | short START; 120 | short SELECT; 121 | 122 | short SQUARE; 123 | short TRIANGLE; 124 | short CROSS; 125 | short CIRCLE; 126 | 127 | short LEFTSHOCK; 128 | short RIGHTSHOCK; 129 | 130 | short HOME; 131 | 132 | short m_bPedWalk; 133 | short m_bVehicleMouseLook; 134 | short m_bRadioTrackSkip; 135 | }; 136 | 137 | class CPad 138 | { 139 | public: 140 | CControllerState NewState; 141 | CControllerState OldState; 142 | WORD SteeringLeftRightBuffer[10]; 143 | DWORD DrunkDrivingBufferUsed; 144 | CControllerState PCTempKeyState; 145 | CControllerState PCTempJoyState; 146 | CControllerState PCTempMouseState; 147 | BYTE Phase; 148 | WORD Mode; 149 | short ShakeDur; 150 | WORD DisablePlayerControls; 151 | BYTE ShakeFreq; 152 | BYTE bHornHistory[5]; 153 | BYTE iCurrHornHistory; 154 | bool JustOutOfFrontEnd; 155 | bool bApplyBrakes; 156 | bool bDisablePlayerEnterCar; 157 | bool bDisablePlayerDuck; 158 | bool bDisablePlayerFireWeapon; 159 | bool bDisablePlayerFireWeaponWithL1; 160 | bool bDisablePlayerCycleWeapon; 161 | bool bDisablePlayerJump; 162 | bool bDisablePlayerDisplayVitalStats; 163 | int LastTimeTouched; 164 | DWORD AverageWeapon; 165 | DWORD AverageEntries; 166 | DWORD NoShakeBeforeThis; 167 | BYTE NoShakeFreq; 168 | 169 | private: 170 | static CMouseControllerState& PCTempMouseControllerState; 171 | static CMouseControllerState& NewMouseControllerState; 172 | static CMouseControllerState& OldMouseControllerState; 173 | 174 | static CGKeysControllerState NewGKeysState, OldGKeysState, TempGKeysState; 175 | 176 | public: 177 | static inline CMouseControllerState& GetMouseStateBuffer() { return PCTempMouseControllerState; } 178 | static inline const CGKeysControllerState* GetNewGKeysState() { return &NewGKeysState; } 179 | static inline const CGKeysControllerState* GetOldGKeysState() { return &OldGKeysState; } 180 | 181 | void UpdateMouse(); 182 | 183 | // Should be CControllerConfigManager 184 | static uint32_t GetMouseGKeyJustDown(); 185 | static bool GetIsMouseGKeyDown( uint32_t key ); 186 | static const char* GetGKeyTextMouse( uint32_t key ); 187 | 188 | static uint32_t GetKeyboardButtonJustDown(); 189 | static bool GetIsKeyboardGKeyDown( uint32_t key ); 190 | static const char* GetGKeyTextKeyboard( uint32_t key ); 191 | 192 | static constexpr uint32_t PackGKeySymbolMouse( int gkey ) 193 | { return GKEY_UID | 0x8000 | gkey; } // 'LG' | mouse bit | mode 0 | gkey 194 | static constexpr uint32_t PackGKeysSymbolKeyboard( int gkey, int mode ) 195 | { return GKEY_UID | (mode << 8) | gkey; } // 'LG' | mode | gkey 196 | 197 | static void UpdateGKeys(); 198 | static void ProcessGKeyInput( GkeyCode gkeyCode, const wchar_t* gkeyOrButtonString, void* context ); 199 | }; 200 | 201 | 202 | CGKeysControllerState CPad::NewGKeysState, CPad::OldGKeysState, CPad::TempGKeysState; 203 | 204 | CMouseControllerState& CPad::PCTempMouseControllerState = *(CMouseControllerState*)0xB73404; 205 | CMouseControllerState& CPad::NewMouseControllerState = *(CMouseControllerState*)0xB73418; 206 | CMouseControllerState& CPad::OldMouseControllerState = *(CMouseControllerState*)0xB7342C; 207 | 208 | CMousePointerStateHelper& MousePointerStateHelper = *(CMousePointerStateHelper*)0xBA6744; 209 | 210 | CMenuManager& FrontEndMenuManager = **AddressByVersion(0x4054DC, 0, 0); 211 | 212 | RsGlobalType& RsGlobal = **AddressByVersion(0x619604, 0, 0); 213 | 214 | int& snTimeInMilliseconds = **AddressByVersion(0x53F51C, 0, 0); 215 | 216 | static bool bUsesGKeys = false; // Are Logitech G Keys in use? 217 | 218 | static char gGKeyNameBuffer[16]; 219 | 220 | inline bool IsForeground() 221 | { 222 | return *(BOOL*)0x8D621C != FALSE; 223 | } 224 | 225 | CMouseControllerState* CMousePointerStateHelper::GetMouseSetUp( CMouseControllerState* mouseCaps ) 226 | { 227 | mouseCaps->lmb = false; 228 | mouseCaps->rmb = false; 229 | mouseCaps->mmb = false; 230 | mouseCaps->wheelUp = false; 231 | mouseCaps->wheelDown = false; 232 | mouseCaps->X = mouseCaps->Y = mouseCaps->Z = 0.0f; 233 | mouseCaps->bmx1 = false; 234 | mouseCaps->bmx2 = false; 235 | 236 | UINT numRIDevices = 0; 237 | GetRawInputDeviceList( nullptr, &numRIDevices, sizeof(RAWINPUTDEVICELIST) ); 238 | if ( numRIDevices > 0 ) 239 | { 240 | PRAWINPUTDEVICELIST pDevices = new RAWINPUTDEVICELIST[ numRIDevices ]; 241 | GetRawInputDeviceList( pDevices, &numRIDevices, sizeof(RAWINPUTDEVICELIST) ); 242 | for( size_t i = 0; i < numRIDevices; ++i ) 243 | { 244 | if ( pDevices[i].dwType == RIM_TYPEMOUSE ) 245 | { 246 | RID_DEVICE_INFO deviceInfo; 247 | UINT cbSize = sizeof(deviceInfo); 248 | GetRawInputDeviceInfo( pDevices[i].hDevice, RIDI_DEVICEINFO, &deviceInfo, &cbSize ); 249 | 250 | if ( !mouseCaps->lmb ) mouseCaps->lmb = deviceInfo.mouse.dwNumberOfButtons >= 1; 251 | if ( !mouseCaps->rmb ) mouseCaps->rmb = deviceInfo.mouse.dwNumberOfButtons >= 2; 252 | // Assume MMB is scroll - seems like there's no obvious way to check for the presence of scroll wheel so this has to suffice 253 | if ( !mouseCaps->mmb ) mouseCaps->mmb = mouseCaps->wheelDown = mouseCaps->wheelUp = deviceInfo.mouse.dwNumberOfButtons >= 3; 254 | if ( !mouseCaps->bmx1 ) mouseCaps->bmx1 = deviceInfo.mouse.dwNumberOfButtons >= 4; 255 | if ( !mouseCaps->bmx2 ) mouseCaps->bmx2 = deviceInfo.mouse.dwNumberOfButtons >= 5; 256 | } 257 | } 258 | delete[] pDevices; 259 | } 260 | 261 | return mouseCaps; 262 | } 263 | 264 | void CPad::UpdateMouse() 265 | { 266 | if ( IsForeground() ) 267 | { 268 | OldMouseControllerState = NewMouseControllerState; 269 | NewMouseControllerState = PCTempMouseControllerState; 270 | 271 | // As TempMouseControllerState contains only raw data now, handle movement inversion here 272 | if ( !FrontEndMenuManager.m_bMenuActive ) 273 | { 274 | if ( MousePointerStateHelper.m_bVerticalInvert ) 275 | NewMouseControllerState.X = -NewMouseControllerState.X; 276 | if ( MousePointerStateHelper.m_bHorizontalInvert ) 277 | NewMouseControllerState.Y = -NewMouseControllerState.Y; 278 | } 279 | 280 | // Update Logitech G Keys 281 | if ( bUsesGKeys ) 282 | UpdateGKeys(); 283 | 284 | if ( NewMouseControllerState.CheckForInput() || NewGKeysState.CheckForInput() ) 285 | LastTimeTouched = snTimeInMilliseconds; 286 | } 287 | 288 | // Clear mouse movement data and scroll data in temp buffer 289 | PCTempMouseControllerState.X = PCTempMouseControllerState.Y = PCTempMouseControllerState.Z = 0.0f; 290 | PCTempMouseControllerState.wheelDown = PCTempMouseControllerState.wheelUp = false; 291 | } 292 | 293 | uint32_t CPad::GetMouseGKeyJustDown() 294 | { 295 | for ( ptrdiff_t i = 6; i <= LOGITECH_MAX_MOUSE_BUTTONS; i++ ) 296 | { 297 | if ( NewGKeysState.MouseGKeyState[ i - 1 ] && !OldGKeysState.MouseGKeyState[ i - 1 ] ) 298 | return PackGKeySymbolMouse( i ); 299 | } 300 | return 0; 301 | } 302 | 303 | bool CPad::GetIsMouseGKeyDown( uint32_t keyID ) 304 | { 305 | // Is this mouse? 306 | if ( (keyID & 0x8000) != 0 ) 307 | { 308 | return NewGKeysState.MouseGKeyState[ (keyID & 0xFF) - 1 ]; 309 | } 310 | return false; 311 | } 312 | 313 | const char* CPad::GetGKeyTextMouse( uint32_t keyID ) 314 | { 315 | // Is this GKey? 316 | if ( (keyID & 0xFFFF0000) == GKEY_UID ) 317 | { 318 | keyID &= 0xFF; 319 | sprintf_s( gGKeyNameBuffer, "MOUSE BTN %d", keyID + 1 ); 320 | return gGKeyNameBuffer; 321 | } 322 | return nullptr; 323 | } 324 | 325 | uint32_t CPad::GetKeyboardButtonJustDown() 326 | { 327 | for ( ptrdiff_t i = 0; i < LOGITECH_MAX_M_STATES; ++i ) 328 | { 329 | for ( ptrdiff_t j = 0; j < LOGITECH_MAX_GKEYS; ++j ) 330 | { 331 | if ( NewGKeysState.KeyboardGKeyState[i][j] && !OldGKeysState.KeyboardGKeyState[i][j] ) 332 | return PackGKeysSymbolKeyboard( j + 1, i + 1 ); 333 | } 334 | } 335 | 336 | return 1056; // rsNULL 337 | } 338 | 339 | bool CPad::GetIsKeyboardGKeyDown( uint32_t keyID ) 340 | { 341 | // Is this NOT mouse? 342 | if ( (keyID & 0x8000) == 0 ) 343 | { 344 | return NewGKeysState.KeyboardGKeyState[ ((keyID>>8) & 0x7F) - 1 ][ (keyID & 0xFF) - 1 ]; 345 | } 346 | return false; 347 | } 348 | 349 | const char * CPad::GetGKeyTextKeyboard( uint32_t keyID ) 350 | { 351 | // Is this GKey? 352 | if ( (keyID & 0xFFFF0000) == GKEY_UID ) 353 | { 354 | const int mode = (keyID>>8) & 0x7F; 355 | const int key = keyID & 0xFF; 356 | sprintf_s( gGKeyNameBuffer, "G%d/M%d", key + 1, mode + 1 ); 357 | return gGKeyNameBuffer; 358 | } 359 | return nullptr; 360 | } 361 | 362 | void CPad::UpdateGKeys() 363 | { 364 | OldGKeysState = NewGKeysState; 365 | NewGKeysState = TempGKeysState; 366 | } 367 | 368 | void CPad::ProcessGKeyInput(GkeyCode gkeyCode, const wchar_t* gkeyOrButtonString, void* context) 369 | { 370 | if ( gkeyCode.mouse ) 371 | { 372 | TempGKeysState.MouseGKeyState[ gkeyCode.keyIdx - 1 ] = gkeyCode.keyDown == 1; 373 | } 374 | else 375 | { 376 | TempGKeysState.KeyboardGKeyState[ gkeyCode.mState - 1 ][ gkeyCode.keyIdx - 1 ] = gkeyCode.keyDown == 1; 377 | } 378 | } 379 | 380 | // RawInput mouse handler 381 | void RegisterRawInputMouse() 382 | { 383 | RAWINPUTDEVICE Rid[1]; 384 | Rid[0].usUsagePage = 1; 385 | Rid[0].usUsage = 2; 386 | Rid[0].dwFlags = RIDEV_INPUTSINK; 387 | Rid[0].hwndTarget = RsGlobal.ps->window; 388 | 389 | RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])); 390 | } 391 | 392 | void RegisterMouseMovement(RAWINPUT* raw) 393 | { 394 | // Interpret data 395 | CMouseControllerState& StateBuf = CPad::GetMouseStateBuffer(); 396 | 397 | // Movement 398 | StateBuf.X += static_cast(raw->data.mouse.lLastX); 399 | StateBuf.Y += static_cast(raw->data.mouse.lLastY); 400 | 401 | // LMB 402 | if ( !StateBuf.lmb ) 403 | StateBuf.lmb = (raw->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) != false; 404 | else 405 | StateBuf.lmb = (raw->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) == false; 406 | 407 | // RMB 408 | if ( !StateBuf.rmb ) 409 | StateBuf.rmb = (raw->data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) != false; 410 | else 411 | StateBuf.rmb = (raw->data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) == false; 412 | 413 | // MMB 414 | if ( !StateBuf.mmb ) 415 | StateBuf.mmb = (raw->data.mouse.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) != false; 416 | else 417 | StateBuf.mmb = (raw->data.mouse.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) == false; 418 | 419 | // 4th button 420 | if ( !StateBuf.bmx1 ) 421 | StateBuf.bmx1 = (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) != false; 422 | else 423 | StateBuf.bmx1 = (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) == false; 424 | 425 | // 5th button 426 | if ( !StateBuf.bmx2 ) 427 | StateBuf.bmx2 = (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) != false; 428 | else 429 | StateBuf.bmx2 = (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) == false; 430 | 431 | // Scroll 432 | if ( raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL ) 433 | { 434 | StateBuf.Z += static_cast(raw->data.mouse.usButtonData); 435 | if ( StateBuf.Z < 0.0f ) 436 | StateBuf.wheelDown = true; 437 | else if ( StateBuf.Z > 0.0f ) 438 | StateBuf.wheelUp = true; 439 | } 440 | } 441 | 442 | static LRESULT (CALLBACK **OldWndProc)(HWND, UINT, WPARAM, LPARAM); 443 | LRESULT CALLBACK CustomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 444 | { 445 | switch ( uMsg ) 446 | { 447 | case WM_INPUT: 448 | { 449 | UINT dwSize = 0; 450 | static UINT dwSavedSize = 0; 451 | static BYTE* pRawBuf = nullptr; 452 | 453 | GetRawInputData(reinterpret_cast(lParam), RID_INPUT, nullptr, &dwSize, sizeof(RAWINPUTHEADER)); 454 | if ( dwSize > dwSavedSize ) 455 | { 456 | delete[] pRawBuf; 457 | pRawBuf = new BYTE[dwSize]; 458 | dwSavedSize = dwSize; 459 | } 460 | 461 | RAWINPUT* raw = reinterpret_cast(pRawBuf); 462 | GetRawInputData(reinterpret_cast(lParam), RID_INPUT, raw, &dwSize, sizeof(RAWINPUTHEADER)); 463 | if ( raw->header.dwType == RIM_TYPEMOUSE ) 464 | { 465 | RegisterMouseMovement(raw); 466 | } 467 | break; 468 | } 469 | } 470 | 471 | return (*OldWndProc)(hwnd, uMsg, wParam, lParam); 472 | } 473 | static auto* pCustomWndProc = CustomWndProc; 474 | 475 | void __declspec(naked) GetGKeyJustDownHack() 476 | { 477 | _asm 478 | { 479 | call CPad::GetMouseGKeyJustDown 480 | mov [esi].m_PressedMouseButton, eax 481 | retn 482 | } 483 | } 484 | 485 | void __declspec(naked) GetGKeyTextMouseHack() 486 | { 487 | _asm 488 | { 489 | push eax 490 | call CPad::GetGKeyTextMouse 491 | add esp, 4 492 | retn 4 493 | } 494 | } 495 | 496 | void __declspec(naked) GetGKeyTextKeyboardHack() 497 | { 498 | _asm 499 | { 500 | push eax 501 | call CPad::GetGKeyTextKeyboard 502 | add esp, 0Ch 503 | retn 8 504 | } 505 | } 506 | 507 | static bool (__thiscall *varGetIsMouseButtonDown)(void*, uint32_t keyID ); 508 | bool __fastcall GetIsMouseButtonDown( void* confmgr, int, uint32_t keyID ) 509 | { 510 | if( varGetIsMouseButtonDown( confmgr, keyID ) ) 511 | return true; 512 | 513 | // Is this GKey? 514 | if ( (keyID & 0xFFFF0000) == GKEY_UID ) 515 | return CPad::GetIsMouseGKeyDown( keyID ); 516 | return false; 517 | } 518 | 519 | static bool (__thiscall *varGetIsMouseButtonUp)(void*, uint32_t keyID ); 520 | bool __fastcall GetIsMouseButtonUp( void* confmgr, int, uint32_t keyID ) 521 | { 522 | if( varGetIsMouseButtonUp( confmgr, keyID ) ) 523 | return true; 524 | 525 | // Is this GKey? 526 | if ( (keyID & 0xFFFF0000) == GKEY_UID ) 527 | return !CPad::GetIsMouseGKeyDown( keyID ); 528 | return false; 529 | } 530 | 531 | static bool (__thiscall *varGetIsKeyboardKeyDown)(void*, uint32_t keyID ); 532 | bool __fastcall GetIsKeyboardKeyDown( void* confmgr, int, uint32_t keyID ) 533 | { 534 | if ( varGetIsKeyboardKeyDown( confmgr, keyID) ) 535 | return true; 536 | 537 | // Is this GKey? 538 | if ( (keyID & 0xFFFF0000) == GKEY_UID ) 539 | return CPad::GetIsKeyboardGKeyDown( keyID ); 540 | return false; 541 | } 542 | 543 | 544 | const char* __stdcall GetMXB1Text( const char* ) 545 | { 546 | return "MOUSE BTN 4"; 547 | } 548 | 549 | const char* __stdcall GetMXB2Text( const char* ) 550 | { 551 | return "MOUSE BTN 5"; 552 | } 553 | 554 | 555 | static uint32_t (*orgEditCodesForControls)(uint32_t*, int); 556 | static uint32_t* EditCodesForControls_GKeys( uint32_t* pKey, int mode ) 557 | { 558 | orgEditCodesForControls( pKey, mode ); 559 | if ( *pKey != 1056 ) // rsNULL 560 | return pKey; 561 | 562 | *pKey = CPad::GetKeyboardButtonJustDown(); 563 | return pKey; 564 | } 565 | 566 | static BOOL (*IsAlreadyRunning)(); 567 | BOOL InjectDelayedPatches_SA_10() 568 | { 569 | if ( !IsAlreadyRunning() ) 570 | { 571 | logiGkeyCBContext context; 572 | context.gkeyCallBack = CPad::ProcessGKeyInput; 573 | context.gkeyContext = nullptr; 574 | bUsesGKeys = LogiGkeyInit( &context ) != FALSE; 575 | 576 | return FALSE; 577 | } 578 | return TRUE; 579 | } 580 | 581 | static void (*orgOnExit)(); 582 | void OnExit() 583 | { 584 | orgOnExit(); 585 | 586 | if ( bUsesGKeys ) 587 | { 588 | LogiGkeyShutdown(); 589 | bUsesGKeys = false; 590 | } 591 | } 592 | 593 | void Patch_SA_10() 594 | { 595 | using namespace Memory; 596 | 597 | InjectHook(0x53F3C0, &CPad::UpdateMouse, PATCH_JUMP); 598 | 599 | InjectHook(0x74880B, RegisterRawInputMouse); 600 | Patch(0x7469A0, 0xC3); 601 | 602 | // Mouse caps 603 | InjectHook( 0x53F2D0, &CMousePointerStateHelper::GetMouseSetUp, PATCH_JUMP ); 604 | 605 | OldWndProc = *(LRESULT (CALLBACK***)(HWND, UINT, WPARAM, LPARAM))AddressByRegion_10(0x748454); 606 | Patch(AddressByRegion_10(0x748454), &pCustomWndProc); 607 | 608 | // G Keys hacks 609 | InjectHook( 0x57E51A, GetGKeyJustDownHack ); 610 | 611 | ReadCall( 0x5314E0, varGetIsMouseButtonDown ); 612 | InjectHook( 0x5314E0, GetIsMouseButtonDown ); 613 | 614 | ReadCall( 0x5315F2, varGetIsMouseButtonUp ); 615 | InjectHook( 0x5315F2, GetIsMouseButtonUp ); 616 | 617 | InjectHook( 0x52F42E, GetGKeyTextMouseHack, PATCH_JUMP ); 618 | InjectHook( 0x52F417, GetMXB1Text ); 619 | InjectHook( 0x52F429, GetMXB2Text ); 620 | 621 | ReadCall( 0x57E502, orgEditCodesForControls ); 622 | InjectHook( 0x57E502, EditCodesForControls_GKeys ); 623 | 624 | ReadCall( 0x531194, varGetIsKeyboardKeyDown ); 625 | InjectHook( 0x531194, GetIsKeyboardKeyDown ); 626 | InjectHook( 0x5312A7, GetIsKeyboardKeyDown ); 627 | InjectHook( 0x5313BE, GetIsKeyboardKeyDown ); 628 | InjectHook( 0x531422, GetIsKeyboardKeyDown ); 629 | 630 | InjectHook( 0x5302E5, GetGKeyTextKeyboardHack, PATCH_JUMP ); 631 | 632 | int pIsAlreadyRunning = AddressByRegion_10(0x74872D); 633 | ReadCall( pIsAlreadyRunning, IsAlreadyRunning ); 634 | InjectHook(pIsAlreadyRunning, InjectDelayedPatches_SA_10); 635 | 636 | int pOnExit = AddressByRegion_10(0x748EDA); 637 | ReadCall( pOnExit, orgOnExit ); 638 | InjectHook(pOnExit, OnExit); 639 | } 640 | 641 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 642 | { 643 | UNREFERENCED_PARAMETER(lpvReserved); 644 | UNREFERENCED_PARAMETER(hinstDLL); 645 | 646 | if ( fdwReason == DLL_PROCESS_ATTACH ) 647 | { 648 | ScopedUnprotect::Section Protect( GetModuleHandle( nullptr ), ".text" ); 649 | 650 | if (*(DWORD*)DynBaseAddress(0x82457C) == 0x94BF || *(DWORD*)DynBaseAddress(0x8245BC) == 0x94BF) Patch_SA_10(); 651 | //else if (*(DWORD*)DynBaseAddress(0x8252FC) == 0x94BF || *(DWORD*)DynBaseAddress(0x82533C) == 0x94BF) Patch_SA_11(); 652 | //else if (*(DWORD*)DynBaseAddress(0x85EC4A) == 0x94BF) Patch_SA_Steam(); 653 | 654 | //else if ( *(DWORD*)DynBaseAddress(0x858D21) == 0x3539F633) Patch_SA_NewSteam_r1(); 655 | //else if ( *(DWORD*)DynBaseAddress(0x858D51) == 0x3539F633) Patch_SA_NewSteam_r2(); 656 | //else if ( *(DWORD*)DynBaseAddress(0x858C61) == 0x3539F633) Patch_SA_NewSteam_r2_lv(); 657 | 658 | else return FALSE; 659 | 660 | } 661 | return TRUE; 662 | } 663 | 664 | // Exports for mods/CLEO 665 | extern "C" { 666 | 667 | BOOL RawMouse_UsesGKeys() 668 | { 669 | return bUsesGKeys ? TRUE : FALSE; 670 | } 671 | 672 | const CGKeysControllerState* RawMouse_GetNewGKeysState() 673 | { 674 | return CPad::GetNewGKeysState(); 675 | } 676 | 677 | const CGKeysControllerState* RawMouse_GetOldGKeysState() 678 | { 679 | return CPad::GetOldGKeysState(); 680 | } 681 | 682 | } -------------------------------------------------------------------------------- /RawMouse/logitech/LogitechGkeyLib.h: -------------------------------------------------------------------------------- 1 | // 2 | // Logitech Gaming G-Key SDK 3 | // 4 | // Copyright (C) 2011-2014 Logitech. All rights reserved. 5 | // Author: Tiziano Pigliucci 6 | // Email: tpigliucci@logitech.com 7 | 8 | #pragma once 9 | #include 10 | 11 | #define LOGITECH_MAX_MOUSE_BUTTONS 20 12 | #define LOGITECH_MAX_GKEYS 29 13 | #define LOGITECH_MAX_M_STATES 3 14 | 15 | #pragma pack(push, 1) 16 | 17 | typedef struct 18 | { 19 | unsigned int keyIdx : 8; // index of the G key or mouse button, for example, 6 for G6 or Button 6 20 | unsigned int keyDown : 1; // key up or down, 1 is down, 0 is up 21 | unsigned int mState : 2; // mState (1, 2 or 3 for M1, M2 and M3) 22 | unsigned int mouse : 1; // indicate if the Event comes from a mouse, 1 is yes, 0 is no. 23 | unsigned int reserved1 : 4; // reserved1 24 | unsigned int reserved2 : 16; // reserved2 25 | } GkeyCode; 26 | 27 | // Callback used to allow client to react to the Gkey events. It is called in the context of another thread. 28 | typedef void (__cdecl *logiGkeyCB)(GkeyCode gkeyCode, const wchar_t* gkeyOrButtonString, void* context); 29 | 30 | typedef struct 31 | { 32 | logiGkeyCB gkeyCallBack; 33 | void* gkeyContext; 34 | } logiGkeyCBContext; 35 | 36 | // Enable the Gkey SDK by calling this function 37 | BOOL LogiGkeyInit(logiGkeyCBContext* gkeyCBContext); 38 | 39 | // Enable the Gkey SDK by calling this function if not using callback. Use this initialization if using Unreal Engine 40 | BOOL LogiGkeyInitWithoutCallback(); 41 | 42 | //Enable the Gkey SDK be calling this function if not using context. Use this initialization if working with Unity Engine 43 | BOOL LogiGkeyInitWithoutContext(logiGkeyCB gkeyCallBack); 44 | 45 | // Check if a mouse button is currently pressed 46 | BOOL LogiGkeyIsMouseButtonPressed(const int buttonNumber); 47 | 48 | // Get friendly name for mouse button 49 | wchar_t* LogiGkeyGetMouseButtonString(const int buttonNumber); 50 | 51 | // Check if a keyboard G-key is currently pressed 52 | BOOL LogiGkeyIsKeyboardGkeyPressed(const int gkeyNumber,const int modeNumber); 53 | 54 | // Get friendly name for G-key 55 | wchar_t* LogiGkeyGetKeyboardGkeyString(const int gkeyNumber,const int modeNumber); 56 | 57 | // Disable the Gkey SDK, free up all the resources. 58 | void LogiGkeyShutdown(); 59 | 60 | #pragma pack(pop) -------------------------------------------------------------------------------- /RawMouse/logitech/LogitechGkeyLib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CookiePLMonster/RawMouse/aa158f3003d8987b425e34afad9ef58ff1084118/RawMouse/logitech/LogitechGkeyLib.lib -------------------------------------------------------------------------------- /RawMouse/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by RawMouse.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | --------------------------------------------------------------------------------