diff --git a/Makefile b/Makefile index 0e5b398..baab3fa 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ FILES = src/debug.c \ src/screenshot.c \ src/settings.c \ src/lodepng.c \ + src/dinput.c \ src/opengl.c all: diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj index 8cf55cb..e4f75cd 100644 --- a/cnc-ddraw.vcxproj +++ b/cnc-ddraw.vcxproj @@ -13,6 +13,7 @@ + diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters index 1819585..810b4c8 100644 --- a/cnc-ddraw.vcxproj.filters +++ b/cnc-ddraw.vcxproj.filters @@ -54,6 +54,9 @@ Source Files + + Source Files + diff --git a/src/dinput.c b/src/dinput.c new file mode 100644 index 0000000..155b1d9 --- /dev/null +++ b/src/dinput.c @@ -0,0 +1,71 @@ +#include +#include + +void HookIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction); + +typedef HRESULT (WINAPI *DInputCreateA)(HINSTANCE, DWORD, LPDIRECTINPUTA*, LPUNKNOWN); +typedef HRESULT (WINAPI *DICreateDevice)(IDirectInputA*, REFGUID, LPDIRECTINPUTDEVICEA *, LPUNKNOWN); +typedef HRESULT (WINAPI *DIDSetCooperativeLevel)(IDirectInputDeviceA *, HWND, DWORD); + +static DInputCreateA DInputCreateA_; +static DICreateDevice DICreateDevice_; +static DIDSetCooperativeLevel DIDSetCooperativeLevel_; + +static PROC HookFunc(PROC *orgFunc, PROC newFunc) +{ + PROC org = *orgFunc; + DWORD oldProtect; + MEMORY_BASIC_INFORMATION mbi; + + if (VirtualQuery(orgFunc, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) + { + if (VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &oldProtect)) + { + *orgFunc = newFunc; + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, oldProtect, &oldProtect); + return org; + } + } + return 0; +} + +static HRESULT WINAPI fake_DIDSetCooperativeLevel(IDirectInputDeviceA *This, HWND hwnd, DWORD dwFlags) +{ + return DIDSetCooperativeLevel_(This, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); +} + +static HRESULT WINAPI fake_DICreateDevice(IDirectInputA *This, REFGUID rguid, LPDIRECTINPUTDEVICEA * lplpDIDevice, LPUNKNOWN pUnkOuter) +{ + HRESULT result = DICreateDevice_(This, rguid, lplpDIDevice, pUnkOuter); + + if (SUCCEEDED(result) && !DIDSetCooperativeLevel_) + { + DIDSetCooperativeLevel_ = + (DIDSetCooperativeLevel)HookFunc( + (PROC *)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel, (PROC)fake_DIDSetCooperativeLevel); + } + + return result; +} + +static HRESULT WINAPI fake_DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* lplpDirectInput, LPUNKNOWN punkOuter) +{ + DInputCreateA_ = (DInputCreateA)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA"); + if (!DInputCreateA_) + return DIERR_GENERIC; + + HRESULT result = DInputCreateA_(hinst, dwVersion, lplpDirectInput, punkOuter); + + if (SUCCEEDED(result) && !DICreateDevice_) + { + DICreateDevice_ = + (DICreateDevice)HookFunc((PROC *)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_DICreateDevice); + } + + return result; +} + +void dinput_init() +{ + HookIAT(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA); +} diff --git a/src/main.c b/src/main.c index 9bdd0ab..9a8b4ae 100644 --- a/src/main.c +++ b/src/main.c @@ -30,16 +30,15 @@ #define IDR_MYMENU 93 -/* from mouse.c */ BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint); void mouse_init(); void mouse_lock(); void mouse_unlock(); -/* from screenshot.c */ BOOL screenshot(struct IDirectDrawSurfaceImpl *); void Settings_Load(); void Settings_Save(RECT *lpRect, int windowState); +void dinput_init(); IDirectDrawImpl *ddraw = NULL; @@ -89,6 +88,7 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) } timeBeginPeriod(1); + dinput_init(); break; } case DLL_PROCESS_DETACH: