From 75add3c0c65775eb3fa825aafbe46373c0bd08f1 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 24 May 2019 16:16:13 +1000
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
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -893,8 +893,15 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L
 
     /* Count the actions */
     for (i=0; i < lpdiaf->dwNumActions; i++)
-        if (IsEqualGUID(&This->guid, &lpdiaf->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 */) ))
+        {
             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
 
             action++;
         }
+        else if ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre ||
+                 (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */)
+        {
+            DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic);
+            DWORD type = DIDFT_GETTYPE(obj_id);
+            DWORD inst = DIDFT_GETINSTANCE(obj_id);
+            LPDIOBJECTDATAFORMAT obj;
+
+            if (type == DIDFT_PSHBUTTON) type = DIDFT_BUTTON;
+            else if (type == DIDFT_RELAXIS) type = DIDFT_AXIS;
+
+            obj = dataformat_to_odf_by_type(df, inst, type);
+            TRACE("obj %p, inst 0x%08x, type 0x%08x\n", obj, inst, type);
+            if(obj)
+            {
+                memcpy(&obj_df[action], obj, df->dwObjSize);
+
+                This->action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData;
+                This->action_map[action].offset = offset;
+                obj_df[action].dwOfs = offset;
+                offset += (type & DIDFT_BUTTON) ? 1 : 4;
+
+                action++;
+            }
+        }
+    }
+
+    if (action == 0)
+    {
+        HeapFree(GetProcessHeap(), 0, obj_df);
+        return DI_NOEFFECT;
     }
+    data_format.dwNumObjs = action;
 
     IDirectInputDevice8_SetDataFormat(iface, &data_format);
 
-- 
2.24.1

