├── exports.def ├── .gitattributes ├── exports.asm ├── LICENSE.txt ├── gtasa-dll-windowmode+mousefix.sln ├── dinput8.rc ├── README.md ├── INI.h ├── IProxyDirectInput8.h ├── gtasa-dll-windowmode+mousefix.vcxproj.filters ├── fixes.h ├── DINPUT8.cpp ├── IProxyDirectInputDevice8.h ├── IProxyDirectInput8.cpp ├── .gitignore ├── gtasa-dll-windowmode+mousefix.vcxproj ├── IProxyDirectInputDevice8.cpp ├── INI.cpp └── fixes.cpp /exports.def: -------------------------------------------------------------------------------- 1 | LIBRARY DINPUT8.dll 2 | EXPORTS 3 | DirectInput8Create = x_DirectInput8Create @1 4 | DllCanUnloadNow = x_DllCanUnloadNow PRIVATE 5 | DllGetClassObject = x_DllGetClassObject PRIVATE 6 | DllRegisterServer = x_DllRegisterServer PRIVATE 7 | DllUnregisterServer = x_DllUnregisterServer PRIVATE -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /exports.asm: -------------------------------------------------------------------------------- 1 | ifndef X64 2 | .386 3 | .model FLAT, C 4 | endif 5 | 6 | EXTRN g_pExports:PTR 7 | EXTRN Load:PROC 8 | 9 | .code 10 | 11 | x_DllCanUnloadNow proc 12 | call Load 13 | jmp g_pExports[1 * SIZEOF g_pExports] 14 | x_DllCanUnloadNow endp 15 | 16 | x_DllGetClassObject proc 17 | call Load 18 | jmp g_pExports[2 * SIZEOF g_pExports] 19 | x_DllGetClassObject endp 20 | 21 | x_DllRegisterServer proc 22 | call Load 23 | jmp g_pExports[3 * SIZEOF g_pExports] 24 | x_DllRegisterServer endp 25 | 26 | x_DllUnregisterServer proc 27 | call Load 28 | jmp g_pExports[4 * SIZEOF g_pExports] 29 | x_DllUnregisterServer endp 30 | 31 | end -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) bartekdvd, 2014 2 | 3 | This software is provided "as-is", without any express or implied warranty. 4 | In no event will the authors be held liable for any damages arising from 5 | the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software in 13 | a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /gtasa-dll-windowmode+mousefix.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtasa-dll-windowmode+mousefix", "gtasa-dll-windowmode+mousefix.vcxproj", "{A4CF0475-27F5-41B0-898D-A47821EE120D}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {A4CF0475-27F5-41B0-898D-A47821EE120D}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {A4CF0475-27F5-41B0-898D-A47821EE120D}.Debug|Win32.Build.0 = Debug|Win32 14 | {A4CF0475-27F5-41B0-898D-A47821EE120D}.Release|Win32.ActiveCfg = Release|Win32 15 | {A4CF0475-27F5-41B0-898D-A47821EE120D}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /dinput8.rc: -------------------------------------------------------------------------------- 1 | #include "windows.h" 2 | 3 | #define DLL_MAJOR 1 4 | #define DLL_MINOR 0 5 | #define DLL_BUILD 0 6 | #define DLL_REVISION 1 7 | 8 | #define STR(value) #value 9 | #define STRINGIZE(value) STR(value) 10 | 11 | #define DLL_VERSION_STR \ 12 | "v" STRINGIZE(DLL_MAJOR) \ 13 | "." STRINGIZE(DLL_MINOR) \ 14 | "." STRINGIZE(DLL_BUILD) \ 15 | "." STRINGIZE(DLL_REVISION) 16 | 17 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 18 | 19 | 1 VERSIONINFO 20 | FILEVERSION DLL_MAJOR,DLL_MINOR,DLL_BUILD,DLL_REVISION 21 | BEGIN 22 | BLOCK "StringFileInfo" 23 | BEGIN 24 | BLOCK "040904b0" 25 | BEGIN 26 | VALUE "FileDescription", "Gives you opportunity to run 'GTA: San Andreas' in windowed mode and provides you high-definition mouse fix." 27 | VALUE "LegalCopyright", "Copyright (C) 2014 bartekdvd" 28 | VALUE "OriginalFilename", "dinput8.dll" 29 | VALUE "ProductName", "Fixes for GTA: San Andreas" 30 | VALUE "ProductVersion", DLL_VERSION_STR 31 | END 32 | END 33 | BLOCK "VarFileInfo" 34 | BEGIN 35 | VALUE "Translation", 0x409, 1200 36 | END 37 | END 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [Fixes for GTA: San Andreas][github] 2 | ================ 3 | [![Build status - Windows][build_status_win]][build_win] 4 | 5 | - It gives you opportunity to run GTA: San Andreas in windowed mode. 6 | - This library provides you High Definition mouse fix for GTA: San Andreas. If you were experiencing problem with your mouse playing GTA:SA on Windows 7/8/8.1 this library is for you. It repleaces bugged DirectInput with High Definition RAWINPUT: http://msdn.microsoft.com/en-us/library/windows/desktop/ee418864(v=vs.85).aspx 7 | 8 | Installation 9 | ------------ 10 | Just copy dinput8.dll and fixes.ini to GTA San Andreas installation directory. 11 | 12 | Configuration is performed through the ini file. These are default settings: 13 | ``` 14 | [VIDEO] 15 | windowed=false 16 | 17 | [INPUT] 18 | hd_mouse=true 19 | ``` 20 | 21 | Additional info 22 | --------------- 23 | After applying my library you may experience mouse speedup. That's because HD input gets more information per second. You can change mouse sensitivity in GTA options through main menu. 24 | 25 | Credits 26 | ------- 27 | - bartekdvd for creating this project 28 | 29 | [github]: https://github.com/Jessyy/gtasa-dll-windowmode-mousefix 30 | [build_status_win]: https://ci.appveyor.com/api/projects/status/9i4i191lx2w86wk7/branch/master?svg=true 31 | [build_win]: https://ci.appveyor.com/project/Jessyy/gtasa-dll-windowmode-mousefix/branch/master -------------------------------------------------------------------------------- /INI.h: -------------------------------------------------------------------------------- 1 | /* INI C++ 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef _INI_H 23 | #define _INI_H 24 | 25 | #include 26 | #include 27 | 28 | class INI 29 | { 30 | public: 31 | INI(char* szFile); 32 | ~INI(); 33 | bool open(); 34 | void close(); 35 | bool GetValue(char* szKey, char* szValue, int maxcount); 36 | bool GoToSection(char* szSection); 37 | 38 | int GetIntegerValue(char* szKey); 39 | float GetFloatValue(char* szKey); 40 | 41 | bool SetValue(char* szKey, char* szValue); 42 | bool SetIntegerValue(char* szKey, int iValue); 43 | bool SetFloatValue(char* szKey, float fValue); 44 | private: 45 | std::ifstream fileRead; 46 | char* szFile; 47 | }; 48 | 49 | #endif -------------------------------------------------------------------------------- /IProxyDirectInput8.h: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef _IPROXYDIRECTINPUT8_H 23 | #define _IPROXYDIRECTINPUT8_H 24 | 25 | class IProxyDirectInput8 : public IDirectInput8 26 | { 27 | public: 28 | IProxyDirectInput8(IDirectInput8*); 29 | ~IProxyDirectInput8(); 30 | 31 | /*** IUnknown methods ***/ 32 | STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj); 33 | STDMETHOD_(ULONG, AddRef)(THIS); 34 | STDMETHOD_(ULONG, Release)(THIS); 35 | 36 | /*** IDirectInput8A methods ***/ 37 | STDMETHOD(CreateDevice)(THIS_ REFGUID, LPDIRECTINPUTDEVICE8A *, LPUNKNOWN); 38 | STDMETHOD(EnumDevices)(THIS_ DWORD, LPDIENUMDEVICESCALLBACKA, LPVOID, DWORD); 39 | STDMETHOD(GetDeviceStatus)(THIS_ REFGUID); 40 | STDMETHOD(RunControlPanel)(THIS_ HWND, DWORD); 41 | STDMETHOD(Initialize)(THIS_ HINSTANCE, DWORD); 42 | STDMETHOD(FindDevice)(THIS_ REFGUID, LPCSTR, LPGUID); 43 | STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCSTR, LPDIACTIONFORMATA, LPDIENUMDEVICESBYSEMANTICSCBA, LPVOID, DWORD); 44 | STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK, LPDICONFIGUREDEVICESPARAMSA, DWORD, LPVOID); 45 | private: 46 | IDirectInput8* pIDI8; 47 | }; 48 | 49 | #endif -------------------------------------------------------------------------------- /gtasa-dll-windowmode+mousefix.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;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 | 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 | Source Files 37 | 38 | 39 | 40 | 41 | Header Files 42 | 43 | 44 | Header Files 45 | 46 | 47 | Header Files 48 | 49 | 50 | Header Files 51 | 52 | 53 | 54 | 55 | Source Files 56 | 57 | 58 | 59 | 60 | Resource Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /fixes.h: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef _FIXES_H 23 | #define _FIXES_H 24 | 25 | #define DIRECTINPUT_VERSION 0x0800 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "IProxyDirectInput8.h" 33 | #include "IProxyDirectInputDevice8.h" 34 | #include "INI.h" 35 | 36 | #ifndef HID_USAGE_PAGE_GENERIC 37 | #define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01) 38 | #endif 39 | #ifndef HID_USAGE_GENERIC_MOUSE 40 | #define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02) 41 | #endif 42 | 43 | #define GTA_ADDR_WINDOWPROC 0x00747EB0 44 | #define GTA_ADDR_HWND 0x00C8CF88 45 | #define GTA_ADDR_D3DPP 0xC9C040 46 | #define GTA_ADDR_D3D 0xC97C20 47 | #define GTA_ADDR_D3DDEV 0xC97C28 48 | #define GTA_ADDR_GETPROCADDRESS 0x0085806C 49 | 50 | typedef LRESULT(CALLBACK* WindowProc_t)(HWND, UINT, WPARAM, LPARAM); 51 | typedef HRESULT(WINAPI* Reset_t)(IDirect3DDevice9 *, D3DPRESENT_PARAMETERS *); 52 | typedef IDirect3D9*(WINAPI* Direct3D9Create_t)(UINT); 53 | typedef HRESULT(WINAPI* CreateDevice_t)( 54 | IDirect3D9 *, 55 | UINT, 56 | D3DDEVTYPE, 57 | HWND, 58 | DWORD, 59 | D3DPRESENT_PARAMETERS *, 60 | IDirect3DDevice9 ** 61 | ); 62 | void SetUpFixes(LPVOID* ppIDI8); 63 | LRESULT CALLBACK WindowProc( 64 | HWND hwnd, 65 | UINT uMsg, 66 | WPARAM wParam, 67 | LPARAM lParam 68 | ); 69 | 70 | extern DIMOUSESTATE2 g_MouseState; 71 | 72 | #endif -------------------------------------------------------------------------------- /DINPUT8.cpp: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "fixes.h" 23 | 24 | HINSTANCE g_hInst = NULL; 25 | HMODULE g_hModule = NULL; 26 | extern "C" LPVOID g_pExports[5] = {0}; 27 | 28 | extern "C" void Load() 29 | { 30 | if (g_hModule != NULL) 31 | return; 32 | 33 | char szLibFile[264]; 34 | GetSystemDirectory(szLibFile, sizeof(szLibFile)); 35 | strcat_s(szLibFile, sizeof(szLibFile), "\\dinput8.dll"); 36 | g_hModule = LoadLibrary(szLibFile); 37 | if (g_hModule == NULL) 38 | { 39 | MessageBeep(MB_ICONERROR); 40 | MessageBox(0, "File not found.", szLibFile, MB_OK | MB_ICONERROR); 41 | return; 42 | } 43 | 44 | g_pExports[0] = GetProcAddress(g_hModule, "DirectInput8Create"); 45 | g_pExports[1] = GetProcAddress(g_hModule, "DllCanUnloadNow"); 46 | g_pExports[2] = GetProcAddress(g_hModule, "DllGetClassObject"); 47 | g_pExports[3] = GetProcAddress(g_hModule, "DllRegisterServer"); 48 | g_pExports[4] = GetProcAddress(g_hModule, "DllUnregisterServer"); 49 | } 50 | 51 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 52 | { 53 | switch(fdwReason) 54 | { 55 | case DLL_PROCESS_ATTACH: 56 | DisableThreadLibraryCalls(hinstDLL); 57 | g_hInst = hinstDLL; 58 | break; 59 | 60 | case DLL_PROCESS_DETACH: 61 | if (g_hModule != NULL) 62 | { 63 | FreeLibrary(g_hModule); 64 | g_hModule = NULL; 65 | } 66 | break; 67 | } 68 | 69 | return TRUE; 70 | } 71 | 72 | extern "C" HRESULT _stdcall x_DirectInput8Create( 73 | HINSTANCE hinst, 74 | DWORD dwVersion, 75 | REFIID riidltf, 76 | LPVOID * ppvOut, 77 | LPUNKNOWN punkOuter 78 | ) 79 | { 80 | Load(); 81 | HRESULT hres = ((HRESULT(_stdcall*)(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN))g_pExports[0])(hinst, dwVersion, riidltf, ppvOut, punkOuter); 82 | if (hres == 0) 83 | SetUpFixes(ppvOut); 84 | return hres; 85 | } 86 | 87 | extern "C" void _stdcall x_DllCanUnloadNow(); 88 | extern "C" void _stdcall x_DllGetClassObject(); 89 | extern "C" void _stdcall x_DllRegisterServer(); 90 | extern "C" void _stdcall x_DllUnregisterServer(); -------------------------------------------------------------------------------- /IProxyDirectInputDevice8.h: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef _IPROXYDIRECTINPUTDEVICE8_H 23 | #define _IPROXYDIRECTINPUTDEVICE8_H 24 | 25 | class IProxyDirectInputDevice8 : public IDirectInputDevice8 26 | { 27 | public: 28 | IProxyDirectInputDevice8(IDirectInputDevice8*); 29 | ~IProxyDirectInputDevice8(); 30 | 31 | /*** IUnknown methods ***/ 32 | STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj); 33 | STDMETHOD_(ULONG, AddRef)(THIS); 34 | STDMETHOD_(ULONG, Release)(THIS); 35 | 36 | /*** IDirectInputDevice8A methods ***/ 37 | STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS); 38 | STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA, LPVOID, DWORD); 39 | STDMETHOD(GetProperty)(THIS_ REFGUID, LPDIPROPHEADER); 40 | STDMETHOD(SetProperty)(THIS_ REFGUID, LPCDIPROPHEADER); 41 | STDMETHOD(Acquire)(THIS); 42 | STDMETHOD(Unacquire)(THIS); 43 | STDMETHOD(GetDeviceState)(THIS_ DWORD, LPVOID); 44 | STDMETHOD(GetDeviceData)(THIS_ DWORD, LPDIDEVICEOBJECTDATA, LPDWORD, DWORD); 45 | STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT); 46 | STDMETHOD(SetEventNotification)(THIS_ HANDLE); 47 | STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD); 48 | STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA, DWORD, DWORD); 49 | STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA); 50 | STDMETHOD(RunControlPanel)(THIS_ HWND, DWORD); 51 | STDMETHOD(Initialize)(THIS_ HINSTANCE, DWORD, REFGUID); 52 | STDMETHOD(CreateEffect)(THIS_ REFGUID, LPCDIEFFECT, LPDIRECTINPUTEFFECT *, LPUNKNOWN); 53 | STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA, LPVOID, DWORD); 54 | STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA, REFGUID); 55 | STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD); 56 | STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD); 57 | STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK, LPVOID, DWORD); 58 | STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE); 59 | STDMETHOD(Poll)(THIS); 60 | STDMETHOD(SendDeviceData)(THIS_ DWORD, LPCDIDEVICEOBJECTDATA, LPDWORD, DWORD); 61 | STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR, LPDIENUMEFFECTSINFILECALLBACK, LPVOID, DWORD); 62 | STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR, DWORD, LPDIFILEEFFECT, DWORD); 63 | STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATA, LPCSTR, DWORD); 64 | STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATA, LPCSTR, DWORD); 65 | STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERA); 66 | 67 | private: 68 | IDirectInputDevice8* pIDID8; 69 | }; 70 | 71 | #endif -------------------------------------------------------------------------------- /IProxyDirectInput8.cpp: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "fixes.h" 23 | 24 | IProxyDirectInput8::IProxyDirectInput8(IDirectInput8* p) 25 | { 26 | this->pIDI8 = p; 27 | } 28 | 29 | IProxyDirectInput8::~IProxyDirectInput8() 30 | { 31 | 32 | } 33 | 34 | HRESULT IProxyDirectInput8::QueryInterface(THIS_ REFIID riid, LPVOID * ppvObj) 35 | { 36 | if (riid == IID_IUnknown) 37 | { 38 | HRESULT hRes; 39 | if ((hRes = this->pIDI8->QueryInterface(riid, ppvObj)) == S_OK) 40 | { 41 | *ppvObj = this; 42 | } 43 | return hRes; 44 | } 45 | return this->pIDI8->QueryInterface(riid, ppvObj); 46 | } 47 | 48 | ULONG IProxyDirectInput8::AddRef() 49 | { 50 | return this->pIDI8->AddRef(); 51 | } 52 | 53 | ULONG IProxyDirectInput8::Release() 54 | { 55 | ULONG refcnt = this->pIDI8->Release(); 56 | if (refcnt == 0) 57 | { 58 | delete this; 59 | } 60 | return refcnt; 61 | } 62 | 63 | HRESULT IProxyDirectInput8::CreateDevice(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8A* lplpDirectInputDevice, LPUNKNOWN pUnkOuter) 64 | { 65 | if (rguid == GUID_SysMouse) 66 | { 67 | HRESULT hRes; 68 | if ((hRes = this->pIDI8->CreateDevice(rguid, lplpDirectInputDevice, pUnkOuter)) == DI_OK) 69 | { 70 | *lplpDirectInputDevice = new IProxyDirectInputDevice8(*lplpDirectInputDevice); 71 | } 72 | return hRes; 73 | } 74 | return this->pIDI8->CreateDevice(rguid, lplpDirectInputDevice, pUnkOuter); 75 | } 76 | 77 | HRESULT IProxyDirectInput8::EnumDevices( 78 | DWORD dwDevType, 79 | LPDIENUMDEVICESCALLBACK lpCallback, 80 | LPVOID pvRef, 81 | DWORD dwFlags 82 | ) 83 | { 84 | return this->pIDI8->EnumDevices(dwDevType, lpCallback, pvRef, dwFlags); 85 | } 86 | 87 | HRESULT IProxyDirectInput8::GetDeviceStatus( 88 | REFGUID rguidInstance 89 | ) 90 | { 91 | return this->pIDI8->GetDeviceStatus(rguidInstance); 92 | } 93 | 94 | HRESULT IProxyDirectInput8::RunControlPanel( 95 | HWND hwndOwner, 96 | DWORD dwFlags 97 | ) 98 | { 99 | return this->pIDI8->RunControlPanel(hwndOwner, dwFlags); 100 | } 101 | 102 | HRESULT IProxyDirectInput8::Initialize( 103 | HINSTANCE hinst, 104 | DWORD dwVersion 105 | ) 106 | { 107 | return this->pIDI8->Initialize(hinst, dwVersion); 108 | } 109 | 110 | HRESULT IProxyDirectInput8::FindDevice( 111 | REFGUID rguidClass, 112 | LPCTSTR ptszName, 113 | LPGUID pguidInstance 114 | ) 115 | { 116 | return this->pIDI8->FindDevice(rguidClass, ptszName, pguidInstance); 117 | } 118 | 119 | HRESULT IProxyDirectInput8::EnumDevicesBySemantics( 120 | LPCTSTR ptszUserName, 121 | LPDIACTIONFORMAT lpdiActionFormat, 122 | LPDIENUMDEVICESBYSEMANTICSCB lpCallback, 123 | LPVOID pvRef, 124 | DWORD dwFlags 125 | ) 126 | { 127 | return this->pIDI8->EnumDevicesBySemantics(ptszUserName, lpdiActionFormat, lpCallback, pvRef, dwFlags); 128 | } 129 | 130 | HRESULT IProxyDirectInput8::ConfigureDevices( 131 | LPDICONFIGUREDEVICESCALLBACK lpdiCallback, 132 | LPDICONFIGUREDEVICESPARAMS lpdiCDParams, 133 | DWORD dwFlags, 134 | LPVOID pvRefData 135 | ) 136 | { 137 | return this->pIDI8->ConfigureDevices(lpdiCallback, lpdiCDParams, dwFlags, pvRefData); 138 | } 139 | -------------------------------------------------------------------------------- /.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 | *.userosscache 8 | *.sln.docstates 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | x64/ 16 | x86/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Build Results of an ATL Project 34 | [Dd]ebugPS/ 35 | [Rr]eleasePS/ 36 | dlldata.c 37 | 38 | *_i.c 39 | *_p.c 40 | *_i.h 41 | *.ilk 42 | *.meta 43 | *.obj 44 | *.pch 45 | *.pdb 46 | *.pgc 47 | *.pgd 48 | *.rsp 49 | *.sbr 50 | *.tlb 51 | *.tli 52 | *.tlh 53 | *.tmp 54 | *.tmp_proj 55 | *.log 56 | *.vspscc 57 | *.vssscc 58 | .builds 59 | *.pidb 60 | *.svclog 61 | *.scc 62 | 63 | # Chutzpah Test files 64 | _Chutzpah* 65 | 66 | # Visual C++ cache files 67 | ipch/ 68 | *.aps 69 | *.ncb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | *.vspx 78 | 79 | # TFS 2012 Local Workspace 80 | $tf/ 81 | 82 | # Guidance Automation Toolkit 83 | *.gpState 84 | 85 | # ReSharper is a .NET coding add-in 86 | _ReSharper*/ 87 | *.[Rr]e[Ss]harper 88 | *.DotSettings.user 89 | 90 | # JustCode is a .NET coding addin-in 91 | .JustCode 92 | 93 | # TeamCity is a build add-in 94 | _TeamCity* 95 | 96 | # DotCover is a Code Coverage Tool 97 | *.dotCover 98 | 99 | # NCrunch 100 | _NCrunch_* 101 | .*crunch*.local.xml 102 | 103 | # MightyMoose 104 | *.mm.* 105 | AutoTest.Net/ 106 | 107 | # Web workbench (sass) 108 | .sass-cache/ 109 | 110 | # Installshield output folder 111 | [Ee]xpress/ 112 | 113 | # DocProject is a documentation generator add-in 114 | DocProject/buildhelp/ 115 | DocProject/Help/*.HxT 116 | DocProject/Help/*.HxC 117 | DocProject/Help/*.hhc 118 | DocProject/Help/*.hhk 119 | DocProject/Help/*.hhp 120 | DocProject/Help/Html2 121 | DocProject/Help/html 122 | 123 | # Click-Once directory 124 | publish/ 125 | 126 | # Publish Web Output 127 | *.[Pp]ublish.xml 128 | *.azurePubxml 129 | # TODO: Comment the next line if you want to checkin your web deploy settings 130 | # but database connection strings (with potential passwords) will be unencrypted 131 | *.pubxml 132 | *.publishproj 133 | 134 | # NuGet Packages 135 | *.nupkg 136 | # The packages folder can be ignored because of Package Restore 137 | **/packages/* 138 | # except build/, which is used as an MSBuild target. 139 | !**/packages/build/ 140 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 141 | #!**/packages/repositories.config 142 | 143 | # Windows Azure Build Output 144 | csx/ 145 | *.build.csdef 146 | 147 | # Windows Store app package directory 148 | AppPackages/ 149 | 150 | # Others 151 | sql/ 152 | *.Cache 153 | ClientBin/ 154 | [Ss]tyle[Cc]op.* 155 | ~$* 156 | *~ 157 | *.dbmdl 158 | *.dbproj.schemaview 159 | *.pfx 160 | *.publishsettings 161 | node_modules/ 162 | 163 | # RIA/Silverlight projects 164 | Generated_Code/ 165 | 166 | # Backup & report files from converting an old project file 167 | # to a newer Visual Studio version. Backup files are not needed, 168 | # because we have git ;-) 169 | _UpgradeReport_Files/ 170 | Backup*/ 171 | UpgradeLog*.XML 172 | UpgradeLog*.htm 173 | 174 | # SQL Server files 175 | *.mdf 176 | *.ldf 177 | 178 | # Business Intelligence projects 179 | *.rdl.data 180 | *.bim.layout 181 | *.bim_*.settings 182 | 183 | # Microsoft Fakes 184 | FakesAssemblies/ 185 | 186 | # ========================= 187 | # Operating System Files 188 | # ========================= 189 | 190 | # OSX 191 | # ========================= 192 | 193 | .DS_Store 194 | .AppleDouble 195 | .LSOverride 196 | 197 | # Thumbnails 198 | ._* 199 | 200 | # Files that might appear on external disk 201 | .Spotlight-V100 202 | .Trashes 203 | 204 | # Directories potentially created on remote AFP share 205 | .AppleDB 206 | .AppleDesktop 207 | Network Trash Folder 208 | Temporary Items 209 | .apdisk 210 | 211 | # Windows 212 | # ========================= 213 | 214 | # Windows image file caches 215 | Thumbs.db 216 | ehthumbs.db 217 | 218 | # Folder config file 219 | Desktop.ini 220 | 221 | # Recycle Bin used on file shares 222 | $RECYCLE.BIN/ 223 | 224 | # Windows Installer files 225 | *.cab 226 | *.msi 227 | *.msm 228 | *.msp 229 | 230 | # Windows shortcuts 231 | *.lnk 232 | -------------------------------------------------------------------------------- /gtasa-dll-windowmode+mousefix.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {A4CF0475-27F5-41B0-898D-A47821EE120D} 15 | gtasadllwindowmodemousefix 16 | 17 | 18 | 19 | DynamicLibrary 20 | true 21 | v110 22 | MultiByte 23 | 24 | 25 | DynamicLibrary 26 | false 27 | v110 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | dinput8 44 | bin\$(PlatformName)\$(Configuration)\ 45 | obj\$(PlatformName)\$(Configuration)\ 46 | 47 | 48 | dinput8 49 | bin\$(PlatformName)\$(Configuration)\ 50 | obj\$(PlatformName)\$(Configuration)\ 51 | 52 | 53 | 54 | Level3 55 | Disabled 56 | true 57 | 58 | 59 | true 60 | exports.def 61 | Windows 62 | 63 | 64 | 65 | 66 | Level3 67 | MaxSpeed 68 | true 69 | true 70 | true 71 | 72 | 73 | false 74 | true 75 | true 76 | exports.def 77 | Windows 78 | false 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Document 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /IProxyDirectInputDevice8.cpp: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "fixes.h" 23 | 24 | IProxyDirectInputDevice8::IProxyDirectInputDevice8(IDirectInputDevice8* p) 25 | { 26 | this->pIDID8 = p; 27 | } 28 | 29 | IProxyDirectInputDevice8::~IProxyDirectInputDevice8() 30 | { 31 | } 32 | 33 | HRESULT IProxyDirectInputDevice8::QueryInterface(THIS_ REFIID riid, LPVOID * ppvObj) 34 | { 35 | if (riid == IID_IUnknown) 36 | { 37 | HRESULT hRes; 38 | if ((hRes = this->pIDID8->QueryInterface(riid, ppvObj)) == S_OK) 39 | { 40 | *ppvObj = this; 41 | } 42 | return hRes; 43 | } 44 | return this->pIDID8->QueryInterface(riid, ppvObj); 45 | } 46 | 47 | ULONG IProxyDirectInputDevice8::AddRef() 48 | { 49 | return this->pIDID8->AddRef(); 50 | } 51 | 52 | ULONG IProxyDirectInputDevice8::Release() 53 | { 54 | ULONG refcnt = this->pIDID8->Release(); 55 | if (refcnt == 0) 56 | { 57 | delete this; 58 | } 59 | return refcnt; 60 | } 61 | 62 | HRESULT IProxyDirectInputDevice8::GetCapabilities( 63 | LPDIDEVCAPS lpDIDevCaps 64 | ) 65 | { 66 | return this->pIDID8->GetCapabilities(lpDIDevCaps); 67 | } 68 | 69 | HRESULT IProxyDirectInputDevice8::EnumObjects( 70 | LPDIENUMDEVICEOBJECTSCALLBACK lpCallback, 71 | LPVOID pvRef, 72 | DWORD dwFlags 73 | ) 74 | { 75 | return this->pIDID8->EnumObjects(lpCallback, pvRef, dwFlags); 76 | } 77 | 78 | HRESULT IProxyDirectInputDevice8::GetProperty( 79 | REFGUID rguidProp, 80 | LPDIPROPHEADER pdiph 81 | ) 82 | { 83 | return this->pIDID8->GetProperty(rguidProp, pdiph); 84 | } 85 | 86 | HRESULT IProxyDirectInputDevice8::SetProperty( 87 | REFGUID rguidProp, 88 | LPCDIPROPHEADER pdiph 89 | ) 90 | { 91 | return this->pIDID8->SetProperty(rguidProp, pdiph); 92 | } 93 | 94 | HRESULT IProxyDirectInputDevice8::Acquire() 95 | { 96 | return DI_OK; 97 | } 98 | 99 | HRESULT IProxyDirectInputDevice8::Unacquire() 100 | { 101 | return DI_OK; 102 | } 103 | 104 | HRESULT IProxyDirectInputDevice8::GetDeviceState( 105 | DWORD cbData, 106 | LPVOID lpvData 107 | ) 108 | 109 | { 110 | memcpy(lpvData, &g_MouseState, sizeof(DIMOUSESTATE2)); 111 | 112 | g_MouseState.lX = 0; 113 | g_MouseState.lY = 0; 114 | g_MouseState.lZ = 0; 115 | 116 | return DI_OK; 117 | } 118 | 119 | HRESULT IProxyDirectInputDevice8::GetDeviceData( 120 | DWORD cbObjectData, 121 | LPDIDEVICEOBJECTDATA rgdod, 122 | LPDWORD pdwInOut, 123 | DWORD dwFlags 124 | ) 125 | { 126 | return this->pIDID8->GetDeviceData(cbObjectData, rgdod, pdwInOut, dwFlags); 127 | } 128 | 129 | HRESULT IProxyDirectInputDevice8::SetDataFormat( 130 | LPCDIDATAFORMAT lpdf 131 | ) 132 | { 133 | return this->pIDID8->SetDataFormat(lpdf); 134 | } 135 | 136 | HRESULT IProxyDirectInputDevice8::SetEventNotification( 137 | HANDLE hEvent 138 | ) 139 | { 140 | return this->pIDID8->SetEventNotification(hEvent); 141 | } 142 | 143 | HRESULT IProxyDirectInputDevice8::SetCooperativeLevel( 144 | HWND hwnd, 145 | DWORD dwFlags 146 | ) 147 | { 148 | return this->pIDID8->SetCooperativeLevel(hwnd, dwFlags); 149 | } 150 | 151 | HRESULT IProxyDirectInputDevice8::GetObjectInfo( 152 | LPDIDEVICEOBJECTINSTANCE pdidoi, 153 | DWORD dwObj, 154 | DWORD dwHow 155 | ) 156 | { 157 | return this->pIDID8->GetObjectInfo(pdidoi, dwObj, dwHow); 158 | } 159 | 160 | HRESULT IProxyDirectInputDevice8::GetDeviceInfo( 161 | LPDIDEVICEINSTANCE pdidi 162 | ) 163 | 164 | { 165 | return this->pIDID8->GetDeviceInfo(pdidi); 166 | } 167 | 168 | HRESULT IProxyDirectInputDevice8::RunControlPanel( 169 | HWND hwndOwner, 170 | DWORD dwFlags 171 | ) 172 | { 173 | return this->pIDID8->RunControlPanel(hwndOwner, dwFlags); 174 | } 175 | 176 | HRESULT IProxyDirectInputDevice8::Initialize( 177 | HINSTANCE hinst, 178 | DWORD dwVersion, 179 | REFGUID rguid 180 | ) 181 | { 182 | return this->pIDID8->Initialize(hinst, dwVersion, rguid); 183 | } 184 | 185 | HRESULT IProxyDirectInputDevice8::CreateEffect( 186 | REFGUID rguid, 187 | LPCDIEFFECT lpeff, 188 | LPDIRECTINPUTEFFECT * ppdeff, 189 | LPUNKNOWN punkOuter 190 | ) 191 | { 192 | return this->pIDID8->CreateEffect(rguid, lpeff, ppdeff, punkOuter); 193 | } 194 | 195 | HRESULT IProxyDirectInputDevice8::EnumEffects( 196 | LPDIENUMEFFECTSCALLBACK lpCallback, 197 | LPVOID pvRef, 198 | DWORD dwEffType 199 | ) 200 | { 201 | return this->pIDID8->EnumEffects(lpCallback, pvRef, dwEffType); 202 | } 203 | 204 | HRESULT IProxyDirectInputDevice8::GetEffectInfo( 205 | LPDIEFFECTINFO pdei, 206 | REFGUID rguid 207 | ) 208 | { 209 | return this->pIDID8->GetEffectInfo(pdei, rguid); 210 | } 211 | 212 | HRESULT IProxyDirectInputDevice8::GetForceFeedbackState( 213 | LPDWORD pdwOut 214 | ) 215 | { 216 | return this->pIDID8->GetForceFeedbackState(pdwOut); 217 | } 218 | 219 | HRESULT IProxyDirectInputDevice8::SendForceFeedbackCommand( 220 | DWORD dwFlags 221 | ) 222 | { 223 | return this->pIDID8->SendForceFeedbackCommand(dwFlags); 224 | } 225 | 226 | HRESULT IProxyDirectInputDevice8::EnumCreatedEffectObjects( 227 | LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, 228 | LPVOID pvRef, 229 | DWORD fl 230 | ) 231 | { 232 | return this->pIDID8->EnumCreatedEffectObjects(lpCallback, pvRef, fl); 233 | } 234 | 235 | HRESULT IProxyDirectInputDevice8::Escape( 236 | LPDIEFFESCAPE pesc 237 | ) 238 | { 239 | return this->pIDID8->Escape(pesc); 240 | } 241 | 242 | HRESULT IProxyDirectInputDevice8::Poll() 243 | { 244 | return this->pIDID8->Poll(); 245 | } 246 | 247 | HRESULT IProxyDirectInputDevice8::SendDeviceData( 248 | DWORD cbObjectData, 249 | LPCDIDEVICEOBJECTDATA rgdod, 250 | LPDWORD pdwInOut, 251 | DWORD fl 252 | ) 253 | 254 | { 255 | return this->pIDID8->SendDeviceData(cbObjectData, rgdod, pdwInOut, fl); 256 | } 257 | 258 | HRESULT IProxyDirectInputDevice8::EnumEffectsInFile( 259 | LPCSTR lpszFileName, 260 | LPDIENUMEFFECTSINFILECALLBACK pec, 261 | LPVOID pvRef, 262 | DWORD dwFlags 263 | ) 264 | { 265 | return this->pIDID8->EnumEffectsInFile(lpszFileName, pec, pvRef, dwFlags); 266 | } 267 | 268 | HRESULT IProxyDirectInputDevice8::WriteEffectToFile( 269 | LPCSTR lpszFileName, 270 | DWORD dwEntries, 271 | LPDIFILEEFFECT rgDiFileEft, 272 | DWORD dwFlags 273 | ) 274 | { 275 | return this->pIDID8->WriteEffectToFile(lpszFileName, dwEntries, rgDiFileEft, dwFlags); 276 | } 277 | 278 | HRESULT IProxyDirectInputDevice8::BuildActionMap( 279 | LPDIACTIONFORMAT lpdiaf, 280 | LPCTSTR lpszUserName, 281 | DWORD dwFlags 282 | ) 283 | { 284 | return this->pIDID8->BuildActionMap(lpdiaf, lpszUserName, dwFlags); 285 | } 286 | 287 | HRESULT IProxyDirectInputDevice8::SetActionMap( 288 | LPDIACTIONFORMAT lpdiActionFormat, 289 | LPCTSTR lptszUserName, 290 | DWORD dwFlags 291 | ) 292 | 293 | { 294 | return this->pIDID8->SetActionMap(lpdiActionFormat, lptszUserName, dwFlags); 295 | } 296 | 297 | HRESULT IProxyDirectInputDevice8::GetImageInfo( 298 | LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader 299 | ) 300 | 301 | { 302 | return this->pIDID8->GetImageInfo(lpdiDevImageInfoHeader); 303 | } 304 | -------------------------------------------------------------------------------- /INI.cpp: -------------------------------------------------------------------------------- 1 | /* INI C++ 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "INI.h" 23 | 24 | INI::INI(char* szFile) 25 | { 26 | int array_size = strlen(szFile) + 1; 27 | this->szFile = new char[array_size]; 28 | memcpy(this->szFile, szFile, array_size); 29 | } 30 | 31 | INI::~INI() 32 | { 33 | this->close(); 34 | delete [] this->szFile; 35 | } 36 | 37 | bool INI::open() 38 | { 39 | this->fileRead.open(this->szFile); 40 | return this->fileRead.is_open(); 41 | } 42 | 43 | void INI::close() 44 | { 45 | if (this->fileRead.is_open()) 46 | { 47 | this->fileRead.clear(); 48 | this->fileRead.close(); 49 | } 50 | } 51 | 52 | bool INI::GetValue(char* szKey, char* szValue, int maxcount) 53 | { 54 | if (!this->fileRead.is_open() || !szKey || !szValue) 55 | { 56 | if (maxcount > 0 && szValue) 57 | szValue[0] = 0; 58 | return false; 59 | } 60 | 61 | unsigned long long seek_pos = this->fileRead.tellg(); 62 | char buff[1024]; 63 | bool success = false; 64 | 65 | while (!success && this->fileRead.good()) 66 | { 67 | this->fileRead.getline(buff, sizeof(buff)); 68 | int i = 0; 69 | while (buff[i] == ' ' || buff[i] == '\t') i++; 70 | int startpos = i; 71 | while (buff[i] && buff[i] != ';' && buff[i] != '=' && buff[i] != ' ' && buff[i] != '\n' && buff[i] != '\r' && buff[i] != '\t') i++; 72 | char tmp = buff[i]; 73 | buff[i] = 0; 74 | 75 | if (_stricmp(buff + startpos, szKey) == 0) 76 | { 77 | buff[i] = tmp; 78 | 79 | if (tmp != '=' && tmp) 80 | { 81 | i++; 82 | while (buff[i] != '=' && buff[i] && buff[i] != ';') i++; 83 | } 84 | 85 | if (buff[i] == '=') 86 | { 87 | i++; 88 | while (buff[i] == ' ' || buff[i] == '\t') 89 | i++; 90 | 91 | int j = 0; 92 | maxcount--; 93 | while (buff[i] != '\r' && buff[i] != '\n' && buff[i] != ';' && buff[i] && j < maxcount) 94 | { 95 | szValue[j] = buff[i]; 96 | j++; 97 | i++; 98 | } 99 | szValue[j] = 0; 100 | success = true; 101 | } 102 | } 103 | } 104 | 105 | this->fileRead.clear(); 106 | this->fileRead.seekg(seek_pos); 107 | return success; 108 | } 109 | 110 | bool INI::GoToSection(char* szSection) 111 | { 112 | if (!this->fileRead.is_open() || !szSection) 113 | return false; 114 | 115 | this->fileRead.clear(); 116 | this->fileRead.seekg(0); 117 | 118 | char buff[1024]; 119 | bool success = false; 120 | 121 | char section[256]; 122 | { 123 | int i = 0; 124 | int j = 0; 125 | while (szSection[i] && j < (sizeof(section) - 1)) 126 | { 127 | if (szSection[i] != '[' && szSection[i] != ']') 128 | { 129 | section[j] = szSection[i]; 130 | j++; 131 | } 132 | i++; 133 | } 134 | section[j] = 0; 135 | } 136 | 137 | while (!success && this->fileRead.good()) 138 | { 139 | this->fileRead.getline(buff, sizeof(buff)); 140 | int i = 0; 141 | while (buff[i] == ' ' || buff[i] == '\t') i++; 142 | if (buff[i] == '[') 143 | { 144 | i++; 145 | while (buff[i] == ' ' || buff[i] == '\t') i++; 146 | 147 | int j = 0; 148 | char sectiontmp[256]; 149 | while (buff[i] && buff[i] != ';' && buff[i] != ' ' && buff[i] != '\n' && buff[i] != '\r' && buff[i] != '\t' && buff[i] != ']') 150 | { 151 | sectiontmp[j] = buff[i]; 152 | j++; 153 | i++; 154 | } 155 | sectiontmp[j] = 0; 156 | 157 | while (buff[i] == ' ' || buff[i] == '\t') i++; 158 | 159 | if (buff[i] == ']') 160 | { 161 | buff[i] = 0; 162 | if (_stricmp(sectiontmp, section) == 0) 163 | success = true; 164 | } 165 | } 166 | } 167 | 168 | if (!success) 169 | { 170 | this->fileRead.clear(); 171 | this->fileRead.seekg(0); 172 | } 173 | 174 | return success; 175 | } 176 | 177 | int INI::GetIntegerValue(char* szKey) 178 | { 179 | char szValue[32]; 180 | this->GetValue(szKey, szValue, sizeof(szValue)); 181 | return atoi(szValue); 182 | } 183 | 184 | float INI::GetFloatValue(char* szKey) 185 | { 186 | char szValue[32]; 187 | this->GetValue(szKey, szValue, sizeof(szValue)); 188 | return (float)atof(szValue); 189 | } 190 | 191 | bool INI::SetValue(char* szKey, char* szValue) 192 | { 193 | if (!szKey || !szValue) 194 | return false; 195 | 196 | bool bOpened = true; 197 | 198 | if (!this->fileRead.is_open()) 199 | { 200 | bOpened = false; 201 | 202 | this->open(); 203 | 204 | if (!this->fileRead.is_open()) 205 | return false; 206 | } 207 | 208 | 209 | std::ofstream fileWrite; 210 | std::ifstream fileTmpRead; 211 | std::ofstream fileTmpWrite; 212 | 213 | int iTmpSize = strlen(this->szFile) + 32; 214 | char* szTmp = new char[iTmpSize]; 215 | szTmp[0] = 0; 216 | 217 | strcat_s(szTmp, iTmpSize, this->szFile); 218 | strcat_s(szTmp, iTmpSize, ".i.n.i.tmp"); 219 | 220 | fileTmpWrite.open(szTmp); 221 | 222 | if (!fileTmpWrite.is_open()) 223 | { 224 | if (!bOpened) 225 | this->close(); 226 | 227 | delete [] szTmp; 228 | return false; 229 | } 230 | 231 | unsigned long long seek_pos = this->fileRead.tellg(); 232 | this->fileRead.clear(); 233 | this->fileRead.seekg(0); 234 | 235 | char buff[4096]; 236 | bool success = false; 237 | 238 | while (this->fileRead.good()) 239 | { 240 | this->fileRead.getline(buff, sizeof(buff)); 241 | 242 | int i = 0; 243 | while (buff[i] == ' ' || buff[i] == '\t') i++; 244 | int startpos = i; 245 | while (buff[i] && buff[i] != ';' && buff[i] != '=' && buff[i] != ' ' && buff[i] != '\n' && buff[i] != '\r' && buff[i] != '\t') i++; 246 | char tmp = buff[i]; 247 | buff[i] = 0; 248 | 249 | if (!success && _stricmp(buff + startpos, szKey) == 0) 250 | { 251 | buff[i] = tmp; 252 | 253 | if (tmp != '=' && tmp) 254 | { 255 | i++; 256 | while (buff[i] != '=' && buff[i] && buff[i] != ';') i++; 257 | } 258 | 259 | if (buff[i] == '=') 260 | { 261 | i++; 262 | while (buff[i] == ' ' || buff[i] == '\t') 263 | i++; 264 | 265 | int n = sprintf_s(buff, sizeof(buff), "%s = %s", szKey, szValue); 266 | fileTmpWrite.write(buff, n); 267 | fileTmpWrite << std::endl; 268 | success = true; 269 | } 270 | } 271 | else 272 | { 273 | buff[i] = tmp; 274 | int len = strlen(buff); 275 | if (len > 0) 276 | fileTmpWrite.write(buff, len); 277 | 278 | if (this->fileRead.good()) 279 | fileTmpWrite << std::endl; 280 | } 281 | } 282 | 283 | fileTmpWrite.close(); 284 | 285 | if (success) 286 | { 287 | fileTmpRead.open(szTmp, std::ios_base::binary); 288 | 289 | if (fileTmpRead.is_open()) 290 | { 291 | this->close(); 292 | fileWrite.open(this->szFile, std::ios_base::binary); 293 | 294 | if (fileWrite.is_open()) 295 | { 296 | while (fileTmpRead.good()) 297 | { 298 | fileTmpRead.read(buff, sizeof(buff)); 299 | fileWrite.write(buff, fileTmpRead.gcount()); 300 | } 301 | 302 | fileWrite.close(); 303 | } 304 | 305 | fileTmpRead.close(); 306 | 307 | if (bOpened) 308 | this->open(); 309 | } 310 | } 311 | 312 | if (bOpened) 313 | { 314 | this->fileRead.clear(); 315 | this->fileRead.seekg(seek_pos); 316 | } 317 | else if (this->fileRead.is_open()) 318 | this->close(); 319 | 320 | remove(szTmp); 321 | delete [] szTmp; 322 | 323 | return success; 324 | } 325 | 326 | bool INI::SetIntegerValue(char* szKey, int iValue) 327 | { 328 | char szValue[64]; 329 | sprintf_s(szValue, "%d", iValue); 330 | return this->SetValue(szKey, szValue); 331 | } 332 | 333 | bool INI::SetFloatValue(char* szKey, float fValue) 334 | { 335 | char szValue[64]; 336 | sprintf_s(szValue, "%f", fValue); 337 | return this->SetValue(szKey, szValue); 338 | } -------------------------------------------------------------------------------- /fixes.cpp: -------------------------------------------------------------------------------- 1 | /* Fixes for GTA:SA 2 | * 3 | * Copyright (c) bartekdvd, 2014 4 | * 5 | * This software is provided "as-is", without any express or implied warranty. 6 | * In no event will the authors be held liable for any damages arising from 7 | * the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software in 15 | * a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 2. Altered source versions must be plainly marked as such, and must not be 18 | * misrepresented as being the original software. 19 | * 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "fixes.h" 23 | 24 | WindowProc_t GTAWindowProc = (WindowProc_t)GTA_ADDR_WINDOWPROC; 25 | 26 | HWND* phWnd = (HWND*)GTA_ADDR_HWND; 27 | D3DPRESENT_PARAMETERS* g_pGTAD3Dpp = (D3DPRESENT_PARAMETERS*)GTA_ADDR_D3DPP; 28 | DIMOUSESTATE2 g_MouseState = { 0 }; 29 | Direct3D9Create_t Direct3D9CreateOrigin = NULL; 30 | CreateDevice_t CreateDeviceOrigin = NULL; 31 | Reset_t ResetOrigin = NULL; 32 | int iWindowed = 0; 33 | int iHDMouse = 0; 34 | 35 | void VTableRedirect(LPVOID* vtbl, LPVOID hooked, LPVOID* origin, int idx) 36 | { 37 | DWORD dwProtOld; 38 | VirtualProtect(&vtbl[idx], sizeof(LPVOID), PAGE_EXECUTE_READWRITE, &dwProtOld); 39 | if (origin) 40 | *origin = vtbl[idx]; 41 | vtbl[idx] = hooked; 42 | } 43 | 44 | HRESULT WINAPI ResetHooked(IDirect3DDevice9* pDev, D3DPRESENT_PARAMETERS *pPresentationParameters) 45 | { 46 | pPresentationParameters->Windowed = 1; 47 | pPresentationParameters->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 48 | pPresentationParameters->Flags = 0; 49 | g_pGTAD3Dpp->Windowed = 1; 50 | g_pGTAD3Dpp->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 51 | g_pGTAD3Dpp->Flags = 0; 52 | 53 | HRESULT hRes = ResetOrigin(pDev, pPresentationParameters); 54 | if (hRes == D3D_OK) 55 | { 56 | if (pPresentationParameters->BackBufferWidth != 0 && pPresentationParameters->BackBufferHeight != 0) 57 | { 58 | int width, height; 59 | width = GetSystemMetrics(SM_CXSCREEN); 60 | height = GetSystemMetrics(SM_CYSCREEN); 61 | SetWindowLongPtr(pPresentationParameters->hDeviceWindow, GWL_STYLE, 62 | WS_POPUP | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE); 63 | SetWindowPos(pPresentationParameters->hDeviceWindow, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); 64 | RECT rect; 65 | GetClientRect(pPresentationParameters->hDeviceWindow, &rect); 66 | if (rect.right != pPresentationParameters->BackBufferWidth || rect.bottom != pPresentationParameters->BackBufferHeight) 67 | { 68 | SetWindowPos(pPresentationParameters->hDeviceWindow, HWND_NOTOPMOST, 69 | 0, 70 | 0, 71 | pPresentationParameters->BackBufferWidth + (pPresentationParameters->BackBufferWidth - rect.right), 72 | pPresentationParameters->BackBufferHeight + 73 | (pPresentationParameters->BackBufferHeight - rect.bottom), SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOMOVE); 74 | } 75 | } 76 | } 77 | return hRes; 78 | } 79 | 80 | HRESULT WINAPI CreateDeviceHooked( 81 | IDirect3D9* pD3D9, 82 | UINT Adapter, 83 | D3DDEVTYPE DeviceType, 84 | HWND hFocusWindow, 85 | DWORD BehaviorFlags, 86 | D3DPRESENT_PARAMETERS *pPresentationParameters, 87 | IDirect3DDevice9 **ppReturnedDeviceInterface 88 | ) 89 | { 90 | int width, height; 91 | width = GetSystemMetrics(SM_CXSCREEN); 92 | height = GetSystemMetrics(SM_CYSCREEN); 93 | SetWindowLong(pPresentationParameters->hDeviceWindow, GWL_STYLE, WS_POPUP); 94 | SetWindowPos(pPresentationParameters->hDeviceWindow, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); 95 | MoveWindow(pPresentationParameters->hDeviceWindow, (width / 2) - (pPresentationParameters->BackBufferWidth / 2), 96 | (height / 2) - (pPresentationParameters->BackBufferHeight / 2), pPresentationParameters->BackBufferWidth, 97 | pPresentationParameters->BackBufferHeight, TRUE); 98 | 99 | pPresentationParameters->Windowed = 1; 100 | pPresentationParameters->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 101 | pPresentationParameters->Flags = 0; 102 | g_pGTAD3Dpp->Windowed = 1; 103 | g_pGTAD3Dpp->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 104 | g_pGTAD3Dpp->Flags = 0; 105 | 106 | HRESULT hRes = CreateDeviceOrigin(pD3D9, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); 107 | if (hRes == D3D_OK) 108 | { 109 | static int done = 0; 110 | if (!done) 111 | { 112 | VTableRedirect(**(LPVOID***)ppReturnedDeviceInterface, ResetHooked, (LPVOID*)&ResetOrigin, 16); 113 | done = 1; 114 | } 115 | } 116 | return hRes; 117 | } 118 | 119 | IDirect3D9* WINAPI Direct3D9CreateHooked(UINT SDKVersion) 120 | { 121 | IDirect3D9* pD3D9 = Direct3D9CreateOrigin(SDKVersion); 122 | if (pD3D9 != NULL) 123 | { 124 | static int done = 0; 125 | if (!done) 126 | { 127 | VTableRedirect(*(LPVOID**)pD3D9, CreateDeviceHooked, (LPVOID*)&CreateDeviceOrigin, 16); 128 | done = 1; 129 | } 130 | } 131 | return pD3D9; 132 | } 133 | 134 | FARPROC WINAPI GetProcAddressHooked(HMODULE hModule, LPCSTR lpProcName) 135 | { 136 | if (hModule == GetModuleHandle("d3d9.dll") && _stricmp("Direct3DCreate9", lpProcName) == 0) 137 | { 138 | if ((Direct3D9CreateOrigin = (Direct3D9Create_t)GetProcAddress(hModule, lpProcName)) != NULL) 139 | return (FARPROC)Direct3D9CreateHooked; 140 | } 141 | 142 | return GetProcAddress(hModule, lpProcName); 143 | } 144 | 145 | void SetUpFixes(LPVOID* ppIDI8) 146 | { 147 | INI* ini = new INI("fixes.ini"); 148 | if (ini->open()) 149 | { 150 | if (ini->GoToSection("[VIDEO]")) 151 | { 152 | char buf[256]; 153 | ini->GetValue("windowed", buf, sizeof(buf)); 154 | if (_stricmp("true", buf) == 0) 155 | iWindowed = 1; 156 | else 157 | { 158 | if (_stricmp("false", buf) == 0) 159 | iWindowed = 0; 160 | else 161 | iWindowed = ini->GetIntegerValue("windowed"); 162 | } 163 | } 164 | 165 | if (ini->GoToSection("[INPUT]")) 166 | { 167 | char buf[256]; 168 | ini->GetValue("hd_mouse", buf, sizeof(buf)); 169 | if (_stricmp("true", buf) == 0) 170 | iHDMouse = 1; 171 | else 172 | { 173 | if (_stricmp("false", buf) == 0) 174 | iHDMouse = 0; 175 | else 176 | iHDMouse = ini->GetIntegerValue("hd_mouse"); 177 | } 178 | } 179 | 180 | ini->close(); 181 | } 182 | delete(ini); 183 | 184 | if (iHDMouse) 185 | { 186 | SetProcessAffinityMask(GetCurrentProcess(), 1); 187 | SetWindowLongPtr(phWnd[0], GWLP_WNDPROC, (LONG_PTR)WindowProc); 188 | 189 | *ppIDI8 = new IProxyDirectInput8((IProxyDirectInput8*)*ppIDI8); 190 | 191 | RAWINPUTDEVICE Rid[1]; 192 | Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC; 193 | Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE; 194 | Rid[0].dwFlags = 0; 195 | Rid[0].hwndTarget = phWnd[0]; 196 | RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])); 197 | } 198 | 199 | if (iWindowed) 200 | { 201 | VTableRedirect((LPVOID*)GTA_ADDR_GETPROCADDRESS, GetProcAddressHooked, NULL, 0); 202 | } 203 | } 204 | 205 | LRESULT CALLBACK WindowProc( 206 | HWND hwnd, 207 | UINT uMsg, 208 | WPARAM wParam, 209 | LPARAM lParam 210 | ) 211 | { 212 | if (uMsg == WM_MOUSEWHEEL) 213 | { 214 | g_MouseState.lZ += GET_WHEEL_DELTA_WPARAM(wParam); 215 | } 216 | 217 | if (uMsg == WM_INPUT) 218 | { 219 | UINT dwSize; 220 | GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, 221 | sizeof(RAWINPUTHEADER)); 222 | 223 | LPBYTE lpb = new BYTE[dwSize]; 224 | if (lpb == NULL) 225 | return 0; 226 | 227 | if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) 228 | return 0; 229 | 230 | RAWINPUT* raw = (RAWINPUT*)lpb; 231 | 232 | if (raw->header.dwType == RIM_TYPEMOUSE) 233 | { 234 | g_MouseState.lX += raw->data.mouse.lLastX; 235 | g_MouseState.lY += raw->data.mouse.lLastY; 236 | 237 | if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) 238 | { 239 | g_MouseState.rgbButtons[0] = 0x80; 240 | } 241 | else if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) 242 | { 243 | g_MouseState.rgbButtons[0] = 0x00; 244 | } 245 | if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) 246 | { 247 | g_MouseState.rgbButtons[1] = 0x80; 248 | } 249 | else if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) 250 | { 251 | g_MouseState.rgbButtons[1] = 0x00; 252 | } 253 | if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) 254 | { 255 | g_MouseState.rgbButtons[2] = 0x80; 256 | } 257 | else if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) 258 | { 259 | g_MouseState.rgbButtons[2] = 0x00; 260 | } 261 | if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) 262 | { 263 | g_MouseState.rgbButtons[3] = 0x80; 264 | } 265 | else if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) 266 | { 267 | g_MouseState.rgbButtons[3] = 0x00; 268 | } 269 | if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) 270 | { 271 | g_MouseState.rgbButtons[4] = 0x80; 272 | } 273 | else if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) 274 | { 275 | g_MouseState.rgbButtons[4] = 0x00; 276 | } 277 | } 278 | } 279 | 280 | return GTAWindowProc(hwnd, uMsg, wParam, lParam); 281 | } --------------------------------------------------------------------------------