From a9aa06c58eea77c66417b48669a00d7b32b70c99 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 13 Nov 2021 18:41:08 +1100 Subject: [PATCH] Updated dinput-joy-mappings patchset --- patches/dinput-SetActionMap-genre/definition | 3 - ...input-Allow-empty-Joystick-mappings.patch} | 144 +++++++--------- ...t-Support-username-in-Config-dialog.patch} | 162 +++++------------- ...t-allow-Fixed-actions-to-be-changed.patch} | 8 +- ...ing-of-controls-based-of-Genre-type.patch} | 41 +++-- patches/dinput-joy-mappings/definition | 3 +- ...-Allow-remapping-of-joystick-buttons.patch | 137 --------------- patches/dinput-remap-joystick/definition | 2 - patches/patchinstall.sh | 23 ++- 9 files changed, 153 insertions(+), 370 deletions(-) delete mode 100644 patches/dinput-SetActionMap-genre/definition rename patches/dinput-joy-mappings/{0002-dinput-Allow-empty-Joystick-mappings.patch => 0001-dinput-Allow-empty-Joystick-mappings.patch} (59%) rename patches/dinput-joy-mappings/{0003-dinput-Support-username-in-Config-dialog.patch => 0002-dinput-Support-username-in-Config-dialog.patch} (69%) rename patches/dinput-joy-mappings/{0004-dinput-Dont-allow-Fixed-actions-to-be-changed.patch => 0003-dinput-Dont-allow-Fixed-actions-to-be-changed.patch} (86%) rename patches/{dinput-SetActionMap-genre/0001-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch => dinput-joy-mappings/0004-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch} (54%) delete mode 100644 patches/dinput-remap-joystick/0001-dinput-Allow-remapping-of-joystick-buttons.patch delete mode 100644 patches/dinput-remap-joystick/definition diff --git a/patches/dinput-SetActionMap-genre/definition b/patches/dinput-SetActionMap-genre/definition deleted file mode 100644 index 4e9387cf..00000000 --- a/patches/dinput-SetActionMap-genre/definition +++ /dev/null @@ -1,3 +0,0 @@ -Fixes: [47326] dinput: Allow mapping of controls based of genre type. -Depends: dinput-joy-mappings -Disabled: True diff --git a/patches/dinput-joy-mappings/0002-dinput-Allow-empty-Joystick-mappings.patch b/patches/dinput-joy-mappings/0001-dinput-Allow-empty-Joystick-mappings.patch similarity index 59% rename from patches/dinput-joy-mappings/0002-dinput-Allow-empty-Joystick-mappings.patch rename to patches/dinput-joy-mappings/0001-dinput-Allow-empty-Joystick-mappings.patch index 6f506bc3..253d8452 100644 --- a/patches/dinput-joy-mappings/0002-dinput-Allow-empty-Joystick-mappings.patch +++ b/patches/dinput-joy-mappings/0001-dinput-Allow-empty-Joystick-mappings.patch @@ -1,45 +1,33 @@ -From 2ff7da682aa87e09966fa0fb7c8846cd82bd1eea Mon Sep 17 00:00:00 2001 +From ef0da9342b0ced44da1ed8532941d53f48ead602 Mon Sep 17 00:00:00 2001 From: Jetro Jormalainen Date: Tue, 30 Apr 2019 09:20:54 +1000 Subject: [PATCH] dinput: Allow empty Joystick mappings. --- - dlls/dinput/device.c | 82 ++++++++++++++++++++++++++++++------- - dlls/dinput/joystick.c | 2 +- - dlls/dinput8/tests/device.c | 50 ++++++++++++++++++++++ - 3 files changed, 119 insertions(+), 15 deletions(-) + dlls/dinput/device.c | 77 ++++++++++++++++++++++++++++++------- + dlls/dinput8/tests/device.c | 50 ++++++++++++++++++++++++ + 2 files changed, 113 insertions(+), 14 deletions(-) diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c -index e99d14b4cff..540034de1e9 100644 +index b423337c9ce..c9466655ce4 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c -@@ -30,6 +30,7 @@ - #include - #include "wine/debug.h" - #include "wine/unicode.h" -+#include "wine/heap.h" - #include "windef.h" - #include "winbase.h" - #include "winreg.h" -@@ -655,12 +656,29 @@ static DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic) - return type | (0x0000ff00 & (obj_instance << 8)); +@@ -356,12 +356,26 @@ static DWORD semantic_to_obj_id( struct dinput_device *This, DWORD dwSemantic ) + return type | (0x0000ff00 & (instance << 8)); } +static void del_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid) { -+ static const WCHAR subkey[] = { -+ 'S','o','f','t','w','a','r','e','\\', -+ 'W','i','n','e','\\', -+ 'D','i','r','e','c','t','I','n','p','u','t','\\', -+ 'M','a','p','p','i','n','g','s','\\','%','s','\\','%','s','\\','%','s','\0'}; ++ static const WCHAR subkey[] = L"Software\\Wine\\DirectInput\\Mappings\\%s\\%s\\%s"; ++ DWORD len = wcslen(subkey) + wcslen(username) + wcslen(device) + wcslen(guid); + WCHAR *keyname; + -+ keyname = heap_alloc(sizeof(WCHAR) * (lstrlenW(subkey) + strlenW(username) + strlenW(device) + strlenW(guid))); -+ sprintfW(keyname, subkey, username, device, guid); ++ keyname = malloc(len * sizeof(WCHAR)); ++ swprintf(keyname, len, subkey, username, device, guid); + + /* Remove old key mappings so there will be no overlapping mappings */ + RegDeleteKeyW(HKEY_CURRENT_USER, keyname); + -+ heap_free(keyname); ++ free(keyname); +} + /* @@ -50,10 +38,10 @@ index e99d14b4cff..540034de1e9 100644 -static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid) +static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid, BOOL create) { - static const WCHAR subkey[] = { - 'S','o','f','t','w','a','r','e','\\', -@@ -675,8 +693,11 @@ static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WC - sprintfW(keyname, subkey, username, device, guid); + static const WCHAR *subkey = L"Software\\Wine\\DirectInput\\Mappings\\%s\\%s\\%s"; + HKEY hkey; +@@ -372,8 +386,11 @@ static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WC + swprintf( keyname, len, subkey, username, device, guid ); /* The key used is HKCU\Software\Wine\DirectInput\Mappings\[username]\[device]\[mapping_guid] */ - if (RegCreateKeyW(HKEY_CURRENT_USER, keyname, &hkey)) @@ -64,9 +52,9 @@ index e99d14b4cff..540034de1e9 100644 + } else if (RegOpenKeyW(HKEY_CURRENT_USER, keyname, &hkey)) + hkey = 0; - HeapFree(GetProcessHeap(), 0, keyname); + free( keyname ); -@@ -696,7 +717,9 @@ static HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORM +@@ -393,7 +410,9 @@ static HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORM if (StringFromCLSID(&lpdiaf->guidActionMap, &guid_str) != S_OK) return DI_SETTINGSNOTSAVED; @@ -77,7 +65,7 @@ index e99d14b4cff..540034de1e9 100644 if (!hkey) { -@@ -731,7 +754,7 @@ BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdia +@@ -428,7 +447,7 @@ static BOOL load_mapping_settings( struct dinput_device *This, LPDIACTIONFORMATW HKEY hkey; WCHAR *guid_str; DIDEVICEINSTANCEW didev; @@ -86,7 +74,7 @@ index e99d14b4cff..540034de1e9 100644 didev.dwSize = sizeof(didev); IDirectInputDevice8_GetDeviceInfo(&This->IDirectInputDevice8W_iface, &didev); -@@ -739,7 +762,7 @@ BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdia +@@ -436,7 +455,7 @@ static BOOL load_mapping_settings( struct dinput_device *This, LPDIACTIONFORMATW if (StringFromCLSID(&lpdiaf->guidActionMap, &guid_str) != S_OK) return FALSE; @@ -95,20 +83,19 @@ index e99d14b4cff..540034de1e9 100644 if (!hkey) { -@@ -760,15 +783,21 @@ BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdia +@@ -456,15 +475,20 @@ static BOOL load_mapping_settings( struct dinput_device *This, LPDIACTIONFORMATW { lpdiaf->rgoAction[i].dwObjID = id; lpdiaf->rgoAction[i].guidInstance = didev.guidInstance; - lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT; - mapped += 1; + lpdiaf->rgoAction[i].dwHow = DIAH_USERCONFIG; - } ++ } + else + { + memset(&lpdiaf->rgoAction[i].guidInstance, 0, sizeof(GUID)); + lpdiaf->rgoAction[i].dwHow = DIAH_UNMAPPED; -+ } -+ + } } RegCloseKey(hkey); @@ -119,96 +106,83 @@ index e99d14b4cff..540034de1e9 100644 + return TRUE; } - static BOOL set_app_data(IDirectInputDeviceImpl *dev, int offset, UINT_PTR app_data) -@@ -831,13 +860,18 @@ HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, - load_success = load_mapping_settings(This, lpdiaf, username); + static BOOL set_app_data( struct dinput_device *dev, int offset, UINT_PTR app_data ) +@@ -1607,13 +1631,18 @@ static HRESULT WINAPI dinput_device_BuildActionMap( IDirectInputDevice8W *iface, + load_success = load_mapping_settings( impl, format, username_buf ); } - if (load_success) return DI_OK; + if (load_success) { + /* Update dwCRC to track if action format has changed */ -+ for (i=0; i < lpdiaf->dwNumActions; i++) ++ for (i=0; i < format->dwNumActions; i++) + { -+ lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2)); -+ lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5))); ++ format->dwCRC ^= (format->rgoAction[i].dwObjID << i * 2) | (format->rgoAction[i].dwObjID >> (sizeof(format->dwCRC) * 8 - i * 2)); ++ format->dwCRC ^= (format->rgoAction[i].dwSemantic << (i * 2 + 5)) | (format->rgoAction[i].dwSemantic >> (sizeof(format->dwCRC) * 8 - (i * 2 + 5))); + } + return DI_OK; + } - for (i=0; i < lpdiaf->dwNumActions; i++) + for (i = 0; i < format->dwNumActions; i++) { - /* Don't touch a user configured action */ -- if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue; +- if (format->rgoAction[i].dwHow == DIAH_USERCONFIG) continue; - - if ((lpdiaf->rgoAction[i].dwSemantic & devMask) == devMask) + genre = format->rgoAction[i].dwSemantic & DIGENRE_ANY; + if (devMask == genre || (devMask == DIGENRE_ANY && genre != DIMOUSE_MASK && genre != DIKEYBOARD_MASK)) { - DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic); -@@ -868,6 +902,14 @@ HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, +@@ -1645,6 +1674,14 @@ static HRESULT WINAPI dinput_device_BuildActionMap( IDirectInputDevice8W *iface, } } + /* Update dwCRC to track if action format has changed */ -+ lpdiaf->dwCRC = 0; -+ for (i=0; i < lpdiaf->dwNumActions; i++) ++ format->dwCRC = 0; ++ for (i=0; i < format->dwNumActions; i++) + { -+ lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2)); -+ lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5))); ++ format->dwCRC ^= (format->rgoAction[i].dwObjID << i * 2) | (format->rgoAction[i].dwObjID >> (sizeof(format->dwCRC) * 8 - i * 2)); ++ format->dwCRC ^= (format->rgoAction[i].dwSemantic << (i * 2 + 5)) | (format->rgoAction[i].dwSemantic >> (sizeof(format->dwCRC) * 8 - (i * 2 + 5))); + } + if (!has_actions) return DI_NOEFFECT; - - return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags); -@@ -883,6 +925,7 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L + if (flags & (DIDBAM_DEFAULT|DIDBAM_PRESERVE|DIDBAM_INITIALIZE|DIDBAM_HWDEFAULTS)) + FIXME("Unimplemented flags %#x\n", flags); +@@ -1662,6 +1699,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D DIPROPSTRING dps; - WCHAR username[MAX_PATH]; - DWORD username_size = MAX_PATH; + WCHAR username_buf[MAX_PATH]; + DWORD username_len = MAX_PATH; + DWORD new_crc = 0; int i, action = 0, num_actions = 0; unsigned int offset = 0; - ActionMap *action_map; -@@ -894,12 +937,23 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L + const DIDATAFORMAT *df; +@@ -1694,12 +1732,23 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D data_format.dwFlags = DIDF_RELAXIS; - data_format.dwDataSize = lpdiaf->dwDataSize; + data_format.dwDataSize = format->dwDataSize; + /* Calculate checksum for actionformat */ -+ for (i=0; i < lpdiaf->dwNumActions; i++) ++ for (i=0; i < format->dwNumActions; i++) + { -+ new_crc ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2)); -+ new_crc ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5))); ++ new_crc ^= (format->rgoAction[i].dwObjID << i * 2) | (format->rgoAction[i].dwObjID >> (sizeof(format->dwCRC) * 8 - i * 2)); ++ new_crc ^= (format->rgoAction[i].dwSemantic << (i * 2 + 5)) | (format->rgoAction[i].dwSemantic >> (sizeof(format->dwCRC) * 8 - (i * 2 + 5))); + } + /* Count the actions */ - for (i=0; i < lpdiaf->dwNumActions; i++) - if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance)) + for (i = 0; i < format->dwNumActions; i++) + if (IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) num_actions++; - if (num_actions == 0) return DI_NOEFFECT; + /* Should return DI_NOEFFECT if we dont have any actions and actionformat has not changed */ -+ if (num_actions == 0 && lpdiaf->dwCRC == new_crc && !(dwFlags & DIDSAM_FORCESAVE)) return DI_NOEFFECT; ++ if (num_actions == 0 && format->dwCRC == new_crc && !(flags & DIDSAM_FORCESAVE)) return DI_NOEFFECT; + + /* update dwCRC to track if action format has changed */ -+ lpdiaf->dwCRC = new_crc; ++ format->dwCRC = new_crc; /* Construct the dataformat and actionmap */ - obj_df = HeapAlloc(GetProcessHeap(), 0, sizeof(DIOBJECTDATAFORMAT)*num_actions); -diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c -index 0cddfbc634b..93211ea13a6 100644 ---- a/dlls/dinput/joystick.c -+++ b/dlls/dinput/joystick.c -@@ -749,7 +749,7 @@ HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, - else - lstrcpynW(username, lpszUserName, size); - -- load_success = load_mapping_settings((IDirectInputDeviceImpl *) This, lpdiaf, username); -+ load_success = load_mapping_settings(&This->base, lpdiaf, username); - heap_free(username); - } - + obj_df = malloc( sizeof(DIOBJECTDATAFORMAT) * num_actions ); diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c -index 17deed193dd..3bfb34eb2ca 100644 +index 5ae9e225dc9..d3e86c68176 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c -@@ -38,6 +38,8 @@ struct enum_data { +@@ -48,6 +48,8 @@ struct enum_data { /* Dummy GUID */ static const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } }; @@ -217,7 +191,7 @@ index 17deed193dd..3bfb34eb2ca 100644 enum { DITEST_AXIS, DITEST_BUTTON, -@@ -429,6 +431,17 @@ static void test_action_mapping(void) +@@ -472,6 +474,17 @@ static void test_action_mapping(void) hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0); ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr); @@ -235,7 +209,7 @@ index 17deed193dd..3bfb34eb2ca 100644 af.dwDataSize = 4 * ARRAY_SIZE(actionMapping); af.dwNumActions = ARRAY_SIZE(actionMapping); -@@ -620,6 +633,43 @@ static void test_save_settings(void) +@@ -663,6 +676,43 @@ static void test_save_settings(void) "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[1], af.rgoAction[1].dwObjID); ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n"); @@ -280,5 +254,5 @@ index 17deed193dd..3bfb34eb2ca 100644 IDirectInput_Release(pDI); } -- -2.30.2 +2.33.0 diff --git a/patches/dinput-joy-mappings/0003-dinput-Support-username-in-Config-dialog.patch b/patches/dinput-joy-mappings/0002-dinput-Support-username-in-Config-dialog.patch similarity index 69% rename from patches/dinput-joy-mappings/0003-dinput-Support-username-in-Config-dialog.patch rename to patches/dinput-joy-mappings/0002-dinput-Support-username-in-Config-dialog.patch index d0b8c2eb..96ef4e74 100644 --- a/patches/dinput-joy-mappings/0003-dinput-Support-username-in-Config-dialog.patch +++ b/patches/dinput-joy-mappings/0002-dinput-Support-username-in-Config-dialog.patch @@ -1,77 +1,19 @@ -From c9ecf258a9186bb31a18f8a4728e20bb25b4e9cf Mon Sep 17 00:00:00 2001 +From 65e22e69bd660ff20cac0a83e3c1feb966a49646 Mon Sep 17 00:00:00 2001 From: Jetro Jormalainen Date: Tue, 30 Apr 2019 09:21:24 +1000 Subject: [PATCH] dinput: Support username in Config dialog. --- - dlls/dinput/ansi.c | 26 +++++ - dlls/dinput/config.c | 187 ++++++++++++++++++++++++----------- + dlls/dinput/config.c | 184 ++++++++++++++++++++++++----------- dlls/dinput/device.c | 2 +- - dlls/dinput/device_private.h | 1 + - dlls/dinput/dinput_main.c | 1 + - 5 files changed, 160 insertions(+), 57 deletions(-) + dlls/dinput/dinput_private.h | 1 + + 3 files changed, 130 insertions(+), 57 deletions(-) -diff --git a/dlls/dinput/ansi.c b/dlls/dinput/ansi.c -index 431b812aeb2..270fe6f1498 100644 ---- a/dlls/dinput/ansi.c -+++ b/dlls/dinput/ansi.c -@@ -840,11 +840,37 @@ static HRESULT WINAPI dinput8_a_ConfigureDevices( IDirectInput8A *iface_a, LPDIC - { - hr = diactionformat_atow( format_a, &format_w, TRUE ); - params_w.lprgFormats = &format_w; -+ params_w.dwcUsers = params_a->dwcUsers; -+ -+ if (params_a->lptszUserNames) { -+ char *start = params_a->lptszUserNames; -+ WCHAR *to = NULL; -+ int total_len = 0; -+ for (i = 0; i < params_a->dwcUsers; i++) -+ { -+ char *end = start + 1; -+ int len; -+ while (*(end++)); -+ len = MultiByteToWideChar(CP_ACP, 0, start, end - start, NULL, 0); -+ total_len += len + 2; /* length of string and two null char */ -+ if (to) -+ to = HeapReAlloc(GetProcessHeap(), 0, to, sizeof(WCHAR) * total_len); -+ else -+ to = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * total_len); -+ -+ MultiByteToWideChar(CP_ACP, 0, start, end - start, to + (total_len - len - 2), len); -+ to[total_len] = 0; -+ to[total_len - 1] = 0; -+ } -+ params_w.lptszUserNames = to; -+ } - - if (SUCCEEDED(hr)) hr = IDirectInput8_ConfigureDevices( iface_w, callback, ¶ms_w, flags, ref ); - - if (!format_w.hInstString) for (i = 0; i < format_w.dwNumActions; ++i) HeapFree( GetProcessHeap(), 0, (void *)format_w.rgoAction[i].lptszActionName ); - HeapFree( GetProcessHeap(), 0, format_w.rgoAction ); -+ HeapFree( GetProcessHeap(), 0, params_w.lptszUserNames); -+ - } - - HeapFree( GetProcessHeap(), 0, params_w.lptszUserNames ); diff --git a/dlls/dinput/config.c b/dlls/dinput/config.c -index bf448985893..c7a33d2da02 100644 +index 8cc73c80242..bb0b2c03c47 100644 --- a/dlls/dinput/config.c +++ b/dlls/dinput/config.c -@@ -18,17 +18,23 @@ - - #define NONAMELESSUNION - -+ - #include "wine/unicode.h" - #include "objbase.h" - #include "dinput_private.h" - #include "device_private.h" - #include "resource.h" - -+#include "wine/heap.h" -+ - typedef struct { - int nobjects; +@@ -29,6 +29,9 @@ typedef struct { IDirectInputDevice8W *lpdid; DIDEVICEINSTANCEW ddi; DIDEVICEOBJECTINSTANCEW ddo[256]; @@ -81,7 +23,7 @@ index bf448985893..c7a33d2da02 100644 } DeviceData; typedef struct { -@@ -38,10 +44,11 @@ typedef struct { +@@ -38,10 +41,11 @@ typedef struct { typedef struct { IDirectInput8W *lpDI; @@ -94,7 +36,7 @@ index bf448985893..c7a33d2da02 100644 } ConfigureDevicesData; /* -@@ -57,27 +64,42 @@ static BOOL CALLBACK collect_objects(LPCDIDEVICEOBJECTINSTANCEW lpddo, LPVOID pv +@@ -57,27 +61,42 @@ static BOOL CALLBACK collect_objects(LPCDIDEVICEOBJECTINSTANCEW lpddo, LPVOID pv return DIENUM_CONTINUE; } @@ -117,7 +59,7 @@ index bf448985893..c7a33d2da02 100644 - DeviceData *device = &data->devices[data->ndevices]; + /* alloc array for devices if this is our first device */ + if (!data->devices_data.ndevices) -+ data->devices_data.devices = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceData) * (dwRemaining + 1)); ++ data->devices_data.devices = malloc(sizeof(DeviceData) * (dwRemaining + 1)); + device = &data->devices_data.devices[data->devices_data.ndevices]; device->lpdid = lpdid; device->ddi = *lpddi; @@ -128,14 +70,14 @@ index bf448985893..c7a33d2da02 100644 IDirectInputDevice_EnumObjects(lpdid, collect_objects, (LPVOID) device, DIDFT_ALL); - data->ndevices++; -+ device->user_afs = heap_alloc(sizeof(*device->user_afs) * data->nusernames); ++ device->user_afs = malloc(sizeof(*device->user_afs) * data->nusernames); + memset(device->user_afs, 0, sizeof(*device->user_afs) * data->nusernames); + for (i = 0; i < data->nusernames; i++) + { + DIACTIONFORMATW *user_af = &device->user_afs[i]; + user_af->dwNumActions = data->original_lpdiaf->dwNumActions; + user_af->guidActionMap = data->original_lpdiaf->guidActionMap; -+ user_af->rgoAction = heap_alloc(sizeof(DIACTIONW) * data->original_lpdiaf->dwNumActions); ++ user_af->rgoAction = malloc(sizeof(DIACTIONW) * data->original_lpdiaf->dwNumActions); + memset(user_af->rgoAction, 0, sizeof(DIACTIONW) * data->original_lpdiaf->dwNumActions); + for (j = 0; j < user_af->dwNumActions; j++) + { @@ -149,7 +91,7 @@ index bf448985893..c7a33d2da02 100644 return DIENUM_CONTINUE; } -@@ -170,10 +192,18 @@ static DeviceData* get_cur_device(HWND dialog) +@@ -169,10 +188,18 @@ static DeviceData* get_cur_device(HWND dialog) return &data->devices_data.devices[sel]; } @@ -170,7 +112,7 @@ index bf448985893..c7a33d2da02 100644 } static int dialog_display_only(HWND dialog) -@@ -182,40 +212,36 @@ static int dialog_display_only(HWND dialog) +@@ -181,40 +208,36 @@ static int dialog_display_only(HWND dialog) return data->display_only; } @@ -184,7 +126,7 @@ index bf448985893..c7a33d2da02 100644 - IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, count_devices, (LPVOID) data, 0); - - /* Allocate devices */ -- data->devices = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceData) * data->ndevices); +- data->devices = malloc( sizeof(DeviceData) * data->ndevices ); - /* Collect and insert */ - data->ndevices = 0; @@ -212,19 +154,19 @@ index bf448985893..c7a33d2da02 100644 + { IDirectInputDevice8_Release(devices_data->devices[i].lpdid); + for (j=0; j < data->nusernames; j++) -+ heap_free(devices_data->devices[i].user_afs[j].rgoAction); -+ heap_free(devices_data->devices[i].user_afs); ++ free(devices_data->devices[i].user_afs[j].rgoAction); ++ free(devices_data->devices[i].user_afs); + } - HeapFree(GetProcessHeap(), 0, devices_data->devices); + free( devices_data->devices ); - - /* Free the backup LPDIACTIONFORMATW */ -- HeapFree(GetProcessHeap(), 0, data->original_lpdiaf->rgoAction); -- HeapFree(GetProcessHeap(), 0, data->original_lpdiaf); +- free( data->original_lpdiaf->rgoAction ); +- free( data->original_lpdiaf ); } static void fill_device_object_list(HWND dialog) -@@ -231,6 +257,7 @@ static void fill_device_object_list(HWND dialog) +@@ -230,6 +253,7 @@ static void fill_device_object_list(HWND dialog) /* Add each object */ for (i=0; i < device->nobjects; i++) { @@ -232,7 +174,7 @@ index bf448985893..c7a33d2da02 100644 int action = -1; item.mask = LVIF_TEXT | LVIF_PARAM; -@@ -241,12 +268,20 @@ static void fill_device_object_list(HWND dialog) +@@ -240,12 +264,20 @@ static void fill_device_object_list(HWND dialog) /* Add the item */ SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTITEMW, 0, (LPARAM) &item); @@ -255,7 +197,7 @@ index bf448985893..c7a33d2da02 100644 { action = j; break; -@@ -260,7 +295,7 @@ static void fill_device_object_list(HWND dialog) +@@ -259,7 +291,7 @@ static void fill_device_object_list(HWND dialog) static void show_suitable_actions(HWND dialog) { DeviceData *device = get_cur_device(dialog); @@ -264,7 +206,7 @@ index bf448985893..c7a33d2da02 100644 int i, added = 0; int obj = lv_get_cur_item(dialog); -@@ -329,24 +364,35 @@ static void assign_action(HWND dialog) +@@ -328,24 +360,35 @@ static void assign_action(HWND dialog) lv_set_action(dialog, obj, action, lpdiaf); } @@ -312,7 +254,7 @@ index bf448985893..c7a33d2da02 100644 } static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM wParam, LPARAM lParam) -@@ -358,21 +404,16 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w +@@ -357,21 +400,16 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w ConfigureDevicesData *data = (ConfigureDevicesData*) lParam; /* Initialize action format and enumerate devices */ @@ -325,9 +267,9 @@ index bf448985893..c7a33d2da02 100644 init_listview_columns(dialog); - /* Create a backup action format for CANCEL and RESET operations */ -- data->original_lpdiaf = HeapAlloc(GetProcessHeap(), 0, sizeof(*data->original_lpdiaf)); +- data->original_lpdiaf = malloc( sizeof(*data->original_lpdiaf) ); - data->original_lpdiaf->dwNumActions = data->lpdiaf->dwNumActions; -- data->original_lpdiaf->rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*data->lpdiaf->dwNumActions); +- data->original_lpdiaf->rgoAction = malloc( sizeof(DIACTIONW) * data->lpdiaf->dwNumActions ); - copy_actions(data->original_lpdiaf, data->lpdiaf); - /* Select the first device and show its actions */ @@ -336,7 +278,7 @@ index bf448985893..c7a33d2da02 100644 fill_device_object_list(dialog); ShowCursor(TRUE); -@@ -414,6 +455,7 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w +@@ -413,6 +451,7 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w break; case IDC_CONTROLLERCOMBO: @@ -344,7 +286,7 @@ index bf448985893..c7a33d2da02 100644 switch (HIWORD(wParam)) { -@@ -424,12 +466,12 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w +@@ -423,12 +462,12 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w break; case IDOK: @@ -358,7 +300,7 @@ index bf448985893..c7a33d2da02 100644 EndDialog(dialog, 0); destroy_data(dialog); break; -@@ -452,15 +494,48 @@ HRESULT _configure_devices(IDirectInput8W *iface, +@@ -451,15 +490,48 @@ HRESULT _configure_devices(IDirectInput8W *iface, LPVOID pvRefData ) { @@ -375,16 +317,16 @@ index bf448985893..c7a33d2da02 100644 + { + /* Get default user name */ + GetUserNameW(NULL, &size); -+ username = heap_alloc(size * sizeof(WCHAR) ); ++ username = malloc(size * sizeof(WCHAR) ); + GetUserNameW(username, &size); + data.nusernames = 1; -+ data.usernames = heap_alloc(sizeof(WCHAR *)); ++ data.usernames = malloc(sizeof(WCHAR *)); + data.usernames[0] = username; + } + else + { + WCHAR *p = lpdiCDParams->lptszUserNames; -+ data.usernames = heap_alloc(sizeof(WCHAR *) * data.nusernames); ++ data.usernames = malloc(sizeof(WCHAR *) * data.nusernames); + for (i = 0; i < data.nusernames; i++) + { + if (*p) @@ -403,16 +345,16 @@ index bf448985893..c7a33d2da02 100644 DialogBoxParamW(DINPUT_instance, (const WCHAR *)MAKEINTRESOURCE(IDD_CONFIGUREDEVICES), lpdiCDParams->hwnd, ConfigureDevicesDlgProc, (LPARAM)&data); -+ heap_free(username); -+ heap_free(data.usernames); ++ free(username); ++ free(data.usernames); + return DI_OK; } diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c -index 05a1dbbb2a1..daaaebdc0d0 100644 +index c9466655ce4..e826cc89c1e 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c -@@ -704,7 +704,7 @@ static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WC +@@ -397,7 +397,7 @@ static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WC return hkey; } @@ -421,30 +363,18 @@ index 05a1dbbb2a1..daaaebdc0d0 100644 { WCHAR *guid_str = NULL; DIDEVICEINSTANCEW didev; -diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h -index 8d3425483c2..a6f22b28bf3 100644 ---- a/dlls/dinput/device_private.h -+++ b/dlls/dinput/device_private.h -@@ -132,6 +132,7 @@ extern const char *_dump_dinput_GUID(const GUID *guid) DECLSPEC_HIDDEN; - - extern LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type) DECLSPEC_HIDDEN; +diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h +index a9777dc8dbb..b90c0bc5200 100644 +--- a/dlls/dinput/dinput_private.h ++++ b/dlls/dinput/dinput_private.h +@@ -76,6 +76,7 @@ extern void check_dinput_hooks( IDirectInputDevice8W *iface, BOOL acquired ) DEC + extern void check_dinput_events(void) DECLSPEC_HIDDEN; + extern HRESULT _configure_devices(IDirectInput8W *iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) DECLSPEC_HIDDEN; +extern HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUsername) DECLSPEC_HIDDEN; - extern BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdiaf, const WCHAR *username) DECLSPEC_HIDDEN; - extern HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, DWORD devMask, LPCDIDATAFORMAT df) DECLSPEC_HIDDEN; -diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c -index 85de9f79b81..2f40bfbca96 100644 ---- a/dlls/dinput/dinput_main.c -+++ b/dlls/dinput/dinput_main.c -@@ -39,6 +39,7 @@ - #define NONAMELESSUNION - - #include "wine/debug.h" -+#include "wine/heap.h" - #include "wine/unicode.h" - #include "wine/asm.h" - #include "windef.h" + extern WCHAR* get_mapping_path(const WCHAR *device, const WCHAR *username) DECLSPEC_HIDDEN; + extern DWORD get_device_type(DWORD version, BOOL is_joystick) DECLSPEC_HIDDEN; -- -2.30.2 +2.33.0 diff --git a/patches/dinput-joy-mappings/0004-dinput-Dont-allow-Fixed-actions-to-be-changed.patch b/patches/dinput-joy-mappings/0003-dinput-Dont-allow-Fixed-actions-to-be-changed.patch similarity index 86% rename from patches/dinput-joy-mappings/0004-dinput-Dont-allow-Fixed-actions-to-be-changed.patch rename to patches/dinput-joy-mappings/0003-dinput-Dont-allow-Fixed-actions-to-be-changed.patch index db00eb8d..7944a80a 100644 --- a/patches/dinput-joy-mappings/0004-dinput-Dont-allow-Fixed-actions-to-be-changed.patch +++ b/patches/dinput-joy-mappings/0003-dinput-Dont-allow-Fixed-actions-to-be-changed.patch @@ -1,4 +1,4 @@ -From 629a5f7eea3b17f56606d3b588a5fd96ded99fef Mon Sep 17 00:00:00 2001 +From 571d437192d553b7a8aac6908f10728cd4d1a257 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 4 Oct 2019 16:24:06 +1000 Subject: [PATCH] dinput: Dont allow Fixed actions to be changed. @@ -8,7 +8,7 @@ Subject: [PATCH] dinput: Dont allow Fixed actions to be changed. 1 file changed, 3 insertions(+) diff --git a/dlls/dinput/config.c b/dlls/dinput/config.c -index cd2c4b921e7..bfb535c9b2a 100644 +index bb0b2c03c47..4b6cba26843 100644 --- a/dlls/dinput/config.c +++ b/dlls/dinput/config.c @@ -91,6 +91,7 @@ static BOOL CALLBACK collect_devices(LPCDIDEVICEINSTANCEW lpddi, IDirectInputDev @@ -19,7 +19,7 @@ index cd2c4b921e7..bfb535c9b2a 100644 user_af->rgoAction[j].u.lptszActionName = data->original_lpdiaf->rgoAction[j].u.lptszActionName; } IDirectInputDevice8_BuildActionMap(lpdid, user_af, data->usernames[i], 0); -@@ -334,6 +335,8 @@ static void assign_action(HWND dialog) +@@ -333,6 +334,8 @@ static void assign_action(HWND dialog) if (old_action == action) return; if (obj < 0) return; @@ -29,5 +29,5 @@ index cd2c4b921e7..bfb535c9b2a 100644 /* Clear old action */ -- -2.23.0 +2.33.0 diff --git a/patches/dinput-SetActionMap-genre/0001-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch b/patches/dinput-joy-mappings/0004-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch similarity index 54% rename from patches/dinput-SetActionMap-genre/0001-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch rename to patches/dinput-joy-mappings/0004-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch index e2698e09..6191ab6f 100644 --- a/patches/dinput-SetActionMap-genre/0001-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch +++ b/patches/dinput-joy-mappings/0004-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch @@ -1,42 +1,41 @@ -From 75add3c0c65775eb3fa825aafbe46373c0bd08f1 Mon Sep 17 00:00:00 2001 +From 98a9b8337d40c1f6df21227dff3d993f270aef46 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 24 May 2019 16:16:13 +1000 -Subject: [PATCH] dinput: Allow mapping of controls based of Genre - type. +Subject: [PATCH] dinput: Allow mapping of controls based of Genre type. --- dlls/dinput/device.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c -index c7e585c50f4..84a41996700 100644 +index e826cc89c1e..a4815f24958 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c -@@ -893,8 +893,15 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L +@@ -1741,8 +1741,15 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D /* Count the actions */ - for (i=0; i < lpdiaf->dwNumActions; i++) -- if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance)) + for (i = 0; i < format->dwNumActions; i++) +- if (IsEqualGUID( &impl->guid, &format->rgoAction[i].guidInstance )) + { -+ if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance) || -+ (IsEqualGUID(&IID_NULL, &lpdiaf->rgoAction[i].guidInstance) && -+ ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre || -+ (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) )) ++ if (IsEqualGUID(&impl->guid, &format->rgoAction[i].guidInstance) || ++ (IsEqualGUID(&IID_NULL, &format->rgoAction[i].guidInstance) && ++ ((format->rgoAction[i].dwSemantic & format->dwGenre) == format->dwGenre || ++ (format->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) )) + { num_actions++; + } + } /* Should return DI_NOEFFECT if we dont have any actions and actionformat has not changed */ - if (num_actions == 0 && lpdiaf->dwCRC == new_crc && !(dwFlags & DIDSAM_FORCESAVE)) return DI_NOEFFECT; -@@ -934,7 +941,39 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L + if (num_actions == 0 && format->dwCRC == new_crc && !(flags & DIDSAM_FORCESAVE)) return DI_NOEFFECT; +@@ -1779,7 +1786,39 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D action++; } -+ else if ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre || -+ (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) ++ else if ((format->rgoAction[i].dwSemantic & format->dwGenre) == format->dwGenre || ++ (format->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) + { -+ DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic); ++ DWORD obj_id = semantic_to_obj_id(impl, format->rgoAction[i].dwSemantic); + DWORD type = DIDFT_GETTYPE(obj_id); + DWORD inst = DIDFT_GETINSTANCE(obj_id); + LPDIOBJECTDATAFORMAT obj; @@ -50,8 +49,8 @@ index c7e585c50f4..84a41996700 100644 + { + memcpy(&obj_df[action], obj, df->dwObjSize); + -+ This->action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData; -+ This->action_map[action].offset = offset; ++ impl->action_map[action].uAppData = format->rgoAction[i].uAppData; ++ impl->action_map[action].offset = offset; + obj_df[action].dwOfs = offset; + offset += (type & DIDFT_BUTTON) ? 1 : 4; + @@ -62,13 +61,13 @@ index c7e585c50f4..84a41996700 100644 + + if (action == 0) + { -+ HeapFree(GetProcessHeap(), 0, obj_df); ++ free( obj_df ); + return DI_NOEFFECT; } + data_format.dwNumObjs = action; - IDirectInputDevice8_SetDataFormat(iface, &data_format); + IDirectInputDevice8_SetDataFormat( iface, &data_format ); -- -2.24.1 +2.33.0 diff --git a/patches/dinput-joy-mappings/definition b/patches/dinput-joy-mappings/definition index 36ad28f0..f045cc56 100644 --- a/patches/dinput-joy-mappings/definition +++ b/patches/dinput-joy-mappings/definition @@ -1,2 +1,3 @@ Fixes: [34108] dinput: Improve support for user Joystick configuration. -Disabled: True +Fixes: [47326] dinput: Allow mapping of controls based of genre type. +Fixes: [35815] dinput: Allow remapping of joystick buttons. diff --git a/patches/dinput-remap-joystick/0001-dinput-Allow-remapping-of-joystick-buttons.patch b/patches/dinput-remap-joystick/0001-dinput-Allow-remapping-of-joystick-buttons.patch deleted file mode 100644 index 1a112d5b..00000000 --- a/patches/dinput-remap-joystick/0001-dinput-Allow-remapping-of-joystick-buttons.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 58773ad5cf6a79a6ec4fc2856aeb5fdf3f877368 Mon Sep 17 00:00:00 2001 -From: Andrew Church -Date: Mon, 25 Feb 2019 11:21:03 +1100 -Subject: [PATCH] dinput: Allow remapping of joystick buttons - -Changed -- Change the array to store the origial button. -- Remove lookup loops. -- Changed max Buttons to 128 to match DIJOYSTATE2 structure. - -Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=35815 ---- - dlls/dinput/joystick.c | 29 +++++++++++++++++++++++++++++ - dlls/dinput/joystick_linux.c | 7 +++++-- - dlls/dinput/joystick_linuxinput.c | 2 ++ - dlls/dinput/joystick_osx.c | 2 ++ - dlls/dinput/joystick_private.h | 4 ++++ - 5 files changed, 42 insertions(+), 2 deletions(-) - -diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c -index c85fda5cddb..21c81b0b683 100644 ---- a/dlls/dinput/joystick.c -+++ b/dlls/dinput/joystick.c -@@ -921,6 +921,7 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_ - int tokens = 0; - int axis = 0; - int pov = 0; -+ int button; - - get_app_key(&hkey, &appkey); - -@@ -932,6 +933,34 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_ - TRACE("setting default deadzone to: \"%s\" %d\n", buffer, This->deadzone); - } - -+ for (button = 0; button < MAX_MAP_BUTTONS; button++) -+ This->button_map[button] = button; -+ -+ if (!get_config_key(hkey, appkey, "ButtonMap", buffer, sizeof(buffer))) -+ { -+ static const char *delim = ","; -+ int button = 0; -+ char *token; -+ -+ TRACE("ButtonMap = \"%s\"\n", buffer); -+ for (token = strtok(buffer, delim); -+ token != NULL && button < MAX_MAP_BUTTONS; -+ token = strtok(NULL, delim), button++) -+ { -+ char *s; -+ int value = strtol(token, &s, 10); -+ if (value < 0 || *s != '\0') -+ { -+ ERR("invalid button number: \"%s\"", token); -+ } -+ else -+ { -+ TRACE("mapping physical button %d to DInput button %d", value, button); -+ This->button_map[value] = button; -+ } -+ } -+ } -+ - This->axis_map = HeapAlloc(GetProcessHeap(), 0, This->device_axis_count * sizeof(int)); - if (!This->axis_map) return DIERR_OUTOFMEMORY; - -diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c -index 5b54e352c20..7a7a59bcb58 100644 ---- a/dlls/dinput/joystick_linux.c -+++ b/dlls/dinput/joystick_linux.c -@@ -735,10 +735,13 @@ static void joy_polldev( IDirectInputDevice8W *iface ) - jse.type,jse.number,jse.value); - if (jse.type & JS_EVENT_BUTTON) - { -+ int button; - if (jse.number >= This->generic.devcaps.dwButtons) return; - -- inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON; -- This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00; -+ button = This->generic.button_map[jse.number]; -+ -+ inst_id = DIDFT_MAKEINSTANCE(button) | DIDFT_PSHBUTTON; -+ This->generic.js.rgbButtons[button] = value = jse.value ? 0x80 : 0x00; - } - else if (jse.type & JS_EVENT_AXIS) - { -diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c -index e3876a97b7f..aa56aa28d08 100644 ---- a/dlls/dinput/joystick_linuxinput.c -+++ b/dlls/dinput/joystick_linuxinput.c -@@ -820,6 +820,8 @@ static void joy_polldev( IDirectInputDevice8W *iface ) - if (btn & 0x80) - { - btn &= 0x7F; -+ btn = This->generic.button_map[btn]; -+ - inst_id = DIDFT_MAKEINSTANCE(btn) | DIDFT_PSHBUTTON; - This->generic.js.rgbButtons[btn] = value = ie.value ? 0x80 : 0x00; - } -diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c -index 9ee45e8a445..f88ee566781 100644 ---- a/dlls/dinput/joystick_osx.c -+++ b/dlls/dinput/joystick_osx.c -@@ -891,6 +891,8 @@ static void poll_osx_device_state( IDirectInputDevice8W *iface ) - TRACE("val %d oldVal %d newVal %d\n", val, oldVal, newVal); - if (oldVal != newVal) - { -+ button_idx = device->generic.button_map[button_idx]; -+ - inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON; - queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); - if (device->generic.base.hEvent) -diff --git a/dlls/dinput/joystick_private.h b/dlls/dinput/joystick_private.h -index 32265edef03..fb0edfa7878 100644 ---- a/dlls/dinput/joystick_private.h -+++ b/dlls/dinput/joystick_private.h -@@ -33,6 +33,9 @@ - #define MAX_PROPS 164 - struct JoystickGenericImpl; - -+/* Number of buttons for which to allow remapping */ -+#define MAX_MAP_BUTTONS 128 -+ - typedef void joy_polldev_handler( IDirectInputDevice8W *iface ); - - typedef struct JoystickGenericImpl -@@ -47,6 +50,7 @@ typedef struct JoystickGenericImpl - char *name; - int device_axis_count; /* Total number of axes in the device */ - int *axis_map; /* User axes remapping */ -+ int button_map[MAX_MAP_BUTTONS]; /* User button remapping */ - LONG deadzone; /* Default dead-zone */ - - joy_polldev_handler *joy_polldev; --- -2.33.0 - diff --git a/patches/dinput-remap-joystick/definition b/patches/dinput-remap-joystick/definition deleted file mode 100644 index a12dd830..00000000 --- a/patches/dinput-remap-joystick/definition +++ /dev/null @@ -1,2 +0,0 @@ -Fixes: [35815] dinput: Allow remapping of joystick buttons. -Disabled: True diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 0e3275af..e8686ad1 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -110,6 +110,7 @@ patch_enable_all () enable_ddraw_IDirect3DTexture2_Load="$1" enable_ddraw_Silence_FIXMEs="$1" enable_ddraw_version_check="$1" + enable_dinput_joy_mappings="$1" enable_dsound_EAX="$1" enable_dsound_Fast_Mixer="$1" enable_dwrite_FontFallback="$1" @@ -360,6 +361,9 @@ patch_enable () ddraw-version-check) enable_ddraw_version_check="$2" ;; + dinput-joy-mappings) + enable_dinput_joy_mappings="$2" + ;; dsound-EAX) enable_dsound_EAX="$2" ;; @@ -1741,6 +1745,23 @@ if test "$enable_ddraw_version_check" -eq 1; then patch_apply ddraw-version-check/0001-ddraw-Return-correct-devices-based-off-requested-Dir.patch fi +# Patchset dinput-joy-mappings +# | +# | This patchset fixes the following Wine bugs: +# | * [#34108] dinput: Improve support for user Joystick configuration. +# | * [#47326] dinput: Allow mapping of controls based of genre type. +# | * [#35815] dinput: Allow remapping of joystick buttons. +# | +# | Modified files: +# | * dlls/dinput/config.c, dlls/dinput/device.c, dlls/dinput/dinput_private.h, dlls/dinput8/tests/device.c +# | +if test "$enable_dinput_joy_mappings" -eq 1; then + patch_apply dinput-joy-mappings/0001-dinput-Allow-empty-Joystick-mappings.patch + patch_apply dinput-joy-mappings/0002-dinput-Support-username-in-Config-dialog.patch + patch_apply dinput-joy-mappings/0003-dinput-Dont-allow-Fixed-actions-to-be-changed.patch + patch_apply dinput-joy-mappings/0004-dinput-Allow-mapping-of-controls-based-of-Genre-type.patch +fi + # Patchset dsound-Fast_Mixer # | # | This patchset fixes the following Wine bugs: @@ -3106,7 +3127,7 @@ fi # Patchset stdole32.idl-Typelib # | # | Modified files: -# | * dlls/stdole32.tlb/std_ole_v1.idl +# | * dlls/stdole32.tlb/std_ole_v1.idl, include/stdole32.idl # | if test "$enable_stdole32_idl_Typelib" -eq 1; then patch_apply stdole32.idl-Typelib/0001-include-Make-stdole32.idl-a-public-component.patch