Lucas Fialho Zawacki : dinput: BuildActionMap for all joysticks. For the moment only for buttons and axis.

Alexandre Julliard julliard at winehq.org
Fri Jul 22 10:15:58 CDT 2011


Module: wine
Branch: master
Commit: 31fdae5b4cd0397107f3e32d9f2e073d12320c2d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=31fdae5b4cd0397107f3e32d9f2e073d12320c2d

Author: Lucas Fialho Zawacki <lfzawacki at gmail.com>
Date:   Thu Jul 21 15:36:31 2011 -0300

dinput: BuildActionMap for all joysticks. For the moment only for buttons and axis.

---

 dlls/dinput/device.c         |   23 +++++++++++++++++++++++
 dlls/dinput/device_private.h |    1 +
 dlls/dinput/dinput_private.h |    1 +
 dlls/dinput/joystick.c       |   40 +++++++++++++++++++++++++++++++++++++++-
 4 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 22632ea..2bd5d6c 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -366,6 +366,29 @@ static inline LPDIOBJECTDATAFORMAT dataformat_to_odf(LPCDIDATAFORMAT df, int idx
     return (LPDIOBJECTDATAFORMAT)((LPBYTE)df->rgodf + idx * df->dwObjSize);
 }
 
+/* dataformat_to_odf_by_type
+ *  Find the Nth object of the selected type in the DataFormat
+ */
+LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type)
+{
+    int i, nfound = 0;
+
+    for (i=0; i < df->dwNumObjs; i++)
+    {
+        LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(df, i);
+
+        if (odf->dwType & type)
+        {
+            if (n == nfound)
+                return odf;
+
+            nfound++;
+        }
+    }
+
+    return NULL;
+}
+
 static HRESULT create_DataFormat(LPCDIDATAFORMAT asked_format, DataFormat *format)
 {
     DataTransform *dt;
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 503698a..6c061b2 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -125,6 +125,7 @@ extern void _dump_DIDATAFORMAT(const DIDATAFORMAT *df)  DECLSPEC_HIDDEN;
 extern const char *_dump_dinput_GUID(const GUID *guid)  DECLSPEC_HIDDEN;
 
 extern DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic)  DECLSPEC_HIDDEN;
+extern LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type)   DECLSPEC_HIDDEN;
 
 /* And the stubs */
 extern HRESULT WINAPI IDirectInputDevice2AImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 6573de0..3c4776e 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -71,5 +71,6 @@ extern void _copy_diactionformatWtoA(LPDIACTIONFORMATA, LPDIACTIONFORMATW) DECLS
 
 #define DIKEYBOARD_MASK    0x81000000
 #define DIMOUSE_MASK       0x82000000
+#define DIGENRE_ANY        0xFF000000
 
 #endif /* __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H */
diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
index 68dcc6a..b5c028c 100644
--- a/dlls/dinput/joystick.c
+++ b/dlls/dinput/joystick.c
@@ -432,9 +432,47 @@ HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
                                                    LPCWSTR lpszUserName,
                                                    DWORD dwFlags)
 {
+    JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
+    int i, j, has_actions = 0;
+    DWORD object_types[] = { DIDFT_AXIS, DIDFT_BUTTON };
+    DWORD type_map[] = { DIDFT_RELAXIS, DIDFT_PSHBUTTON };
+
     FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
 
-    return DI_NOEFFECT;
+    for (i=0; i < lpdiaf->dwNumActions; i++)
+    {
+        DWORD inst = (0x000000ff & (lpdiaf->rgoAction[i].dwSemantic)) - 1;
+        DWORD type = 0x000000ff & (lpdiaf->rgoAction[i].dwSemantic >> 8);
+        DWORD genre = 0xff000000 & lpdiaf->rgoAction[i].dwSemantic;
+
+        /* Only consider actions of the right genre */
+        if (lpdiaf->dwGenre != genre && genre != DIGENRE_ANY) continue;
+
+        for (j=0; j < sizeof(object_types)/sizeof(object_types[0]); j++)
+        {
+            if (type & object_types[j])
+            {
+                /* Assure that the object exists */
+                LPDIOBJECTDATAFORMAT odf = dataformat_to_odf_by_type(This->base.data_format.wine_df, inst, DIDFT_BUTTON);
+
+                if (odf != NULL)
+                {
+                    lpdiaf->rgoAction[i].dwObjID = type_map[j] | (0x0000ff00 & (inst << 8));
+                    lpdiaf->rgoAction[i].guidInstance = This->base.guid;
+                    lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT;
+
+                    has_actions = 1;
+
+                    /* No need to try other types if the action was already mapped */
+                    break;
+                }
+            }
+        }
+    }
+
+    if (!has_actions) return DI_NOEFFECT;
+
+    return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags);
 }
 
 HRESULT WINAPI JoystickAGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,




More information about the wine-cvs mailing list