[AMSTREAM] We don't need to define WIDL_C_INLINE_WRAPPERS here anymore.
[reactos.git] / dll / directx / wine / dinput / joystick.c
index a67596f..ef21faf 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "dinput_private.h"
 
+#include <stdio.h>
+
 #include "joystick_private.h"
 
 static inline JoystickGenericImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
@@ -211,10 +213,14 @@ void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags)
             _dump_DIRAMPFORCE(eff->lpvTypeSpecificParams);
         }
     } else if (type == DIEFT_CONDITION) {
-        if (eff->cbTypeSpecificParams != sizeof(DICONDITION)) {
-            WARN("Effect claims to be a condition but the type-specific params are the wrong size!\n");
-        } else {
+        if (eff->cbTypeSpecificParams == sizeof(DICONDITION)) {
             _dump_DICONDITION(eff->lpvTypeSpecificParams);
+        } else if (eff->cbTypeSpecificParams == 2 * sizeof(DICONDITION)) {
+            DICONDITION *condition = eff->lpvTypeSpecificParams;
+            _dump_DICONDITION(&condition[0]);
+            _dump_DICONDITION(&condition[1]);
+        } else {
+            WARN("Effect claims to be a condition but the type-specific params are the wrong size!\n");
         }
     } else if (type == DIEFT_CUSTOMFORCE) {
         if (eff->cbTypeSpecificParams != sizeof(DICUSTOMFORCE)) {
@@ -287,6 +293,11 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF
         case (DWORD_PTR)DIPROP_RANGE: {
             LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
             if (ph->dwHow == DIPH_DEVICE) {
+
+                /* Many games poll the joystick immediately after setting the range
+                 * for calibration purposes, so the old values need to be remapped
+                 * to the new range before it does so */
+
                 TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax);
                 for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) {
 
@@ -320,8 +331,6 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF
                 TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax, obj);
                 if (obj >= 0) {
 
-                    /*ePSXe polls the joystick immediately after setting the range for calibration purposes, so the old values need to be remapped to the new range before it does so*/
-
                     remap_props.lDevMin = This->props[obj].lMin;
                     remap_props.lDevMax = This->props[obj].lMax;
 
@@ -331,7 +340,7 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF
                     remap_props.lMin = pr->lMin;
                     remap_props.lMax = pr->lMax;
 
-                    switch (ph->dwObj) {
+                    switch (This->base.data_format.wine_df->rgodf[obj].dwOfs) {
                     case DIJOFS_X        : This->js.lX  = joystick_map_axis(&remap_props, This->js.lX); break;
                     case DIJOFS_Y        : This->js.lY  = joystick_map_axis(&remap_props, This->js.lY); break;
                     case DIJOFS_Z        : This->js.lZ  = joystick_map_axis(&remap_props, This->js.lZ); break;
@@ -398,17 +407,40 @@ HRESULT WINAPI JoystickAGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, REF
     return JoystickWGenericImpl_SetProperty(IDirectInputDevice8W_from_impl(This), rguid, ph);
 }
 
+#define DEBUG_TYPE(x) case (x): str = #x; break
 void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
 {
+    int type = GET_DIDEVICE_TYPE(lpDIDevCaps->dwDevType);
+    const char *str, *hid = "";
     TRACE("dwSize: %d\n", lpDIDevCaps->dwSize);
     TRACE("dwFlags: %08x\n", lpDIDevCaps->dwFlags);
-    TRACE("dwDevType: %08x %s\n", lpDIDevCaps->dwDevType,
-          lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
-          lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
-          lpDIDevCaps->dwDevType == DIDEVTYPE_MOUSE ? "DIDEVTYPE_MOUSE" :
-          lpDIDevCaps->dwDevType == DIDEVTYPE_KEYBOARD ? "DIDEVTYPE_KEYBOARD" :
-          lpDIDevCaps->dwDevType == DIDEVTYPE_JOYSTICK ? "DIDEVTYPE_JOYSTICK" :
-          lpDIDevCaps->dwDevType == DIDEVTYPE_HID ? "DIDEVTYPE_HID" : "UNKNOWN");
+    switch(type)
+    {
+        /* Direct X <= 7 definitions */
+        DEBUG_TYPE(DIDEVTYPE_DEVICE);
+        DEBUG_TYPE(DIDEVTYPE_MOUSE);
+        DEBUG_TYPE(DIDEVTYPE_KEYBOARD);
+        DEBUG_TYPE(DIDEVTYPE_JOYSTICK);
+        /* Direct X >= 8 definitions */
+        DEBUG_TYPE(DI8DEVTYPE_DEVICE);
+        DEBUG_TYPE(DI8DEVTYPE_MOUSE);
+        DEBUG_TYPE(DI8DEVTYPE_KEYBOARD);
+        DEBUG_TYPE(DI8DEVTYPE_JOYSTICK);
+        DEBUG_TYPE(DI8DEVTYPE_GAMEPAD);
+        DEBUG_TYPE(DI8DEVTYPE_DRIVING);
+        DEBUG_TYPE(DI8DEVTYPE_FLIGHT);
+        DEBUG_TYPE(DI8DEVTYPE_1STPERSON);
+        DEBUG_TYPE(DI8DEVTYPE_DEVICECTRL);
+        DEBUG_TYPE(DI8DEVTYPE_SCREENPOINTER);
+        DEBUG_TYPE(DI8DEVTYPE_REMOTE);
+        DEBUG_TYPE(DI8DEVTYPE_SUPPLEMENTAL);
+        default: str = "UNKNOWN";
+    }
+
+    if (lpDIDevCaps->dwDevType & DIDEVTYPE_HID)
+        hid = " (HID)";
+
+    TRACE("dwDevType: %08x %s%s\n", lpDIDevCaps->dwDevType, str, hid);
     TRACE("dwAxes: %d\n", lpDIDevCaps->dwAxes);
     TRACE("dwButtons: %d\n", lpDIDevCaps->dwButtons);
     TRACE("dwPOVs: %d\n", lpDIDevCaps->dwPOVs);
@@ -420,6 +452,7 @@ void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
         TRACE("dwFFDriverVersion: %d\n", lpDIDevCaps->dwFFDriverVersion);
     }
 }
+#undef DEBUG_TYPE
 
 HRESULT WINAPI JoystickWGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, LPDIDEVCAPS lpDIDevCaps)
 {
@@ -469,9 +502,10 @@ HRESULT WINAPI JoystickWGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
     res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
     if (res != DI_OK) return res;
 
-    if      (pdidoi->dwType & DIDFT_AXIS)
+    if (pdidoi->dwType & DIDFT_AXIS) {
         sprintfW(pdidoi->tszName, axisW, DIDFT_GETINSTANCE(pdidoi->dwType));
-    else if (pdidoi->dwType & DIDFT_POV)
+        pdidoi->dwFlags |= DIDOI_ASPECTPOSITION;
+    } else if (pdidoi->dwType & DIDFT_POV)
         sprintfW(pdidoi->tszName, povW, DIDFT_GETINSTANCE(pdidoi->dwType));
     else if (pdidoi->dwType & DIDFT_BUTTON)
         sprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType));
@@ -551,6 +585,7 @@ HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF
             }
             break;
         }
+        case (DWORD_PTR) DIPROP_PRODUCTNAME:
         case (DWORD_PTR) DIPROP_INSTANCENAME: {
             DIPROPSTRING *ps = (DIPROPSTRING*) pdiph;
             DIDEVICEINSTANCEW didev;
@@ -558,7 +593,10 @@ HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF
             didev.dwSize = sizeof(didev);
 
             IDirectInputDevice_GetDeviceInfo(iface, &didev);
-            lstrcpynW(ps->wsz, didev.tszInstanceName, MAX_PATH);
+            if (LOWORD(rguid) == (DWORD_PTR) DIPROP_PRODUCTNAME)
+                lstrcpynW(ps->wsz, didev.tszProductName, MAX_PATH);
+            else
+                lstrcpynW(ps->wsz, didev.tszInstanceName, MAX_PATH);
 
             return DI_OK;
         }
@@ -584,6 +622,8 @@ HRESULT WINAPI JoystickAGenericImpl_GetDeviceInfo(
     LPDIDEVICEINSTANCEA pdidi)
 {
     JoystickGenericImpl *This = impl_from_IDirectInputDevice8A(iface);
+    DIPROPDWORD pd;
+    DWORD index = 0;
 
     TRACE("(%p,%p)\n", iface, pdidi);
 
@@ -598,12 +638,20 @@ HRESULT WINAPI JoystickAGenericImpl_GetDeviceInfo(
         return DIERR_INVALIDPARAM;
     }
 
+    /* Try to get joystick index */
+    pd.diph.dwSize = sizeof(pd);
+    pd.diph.dwHeaderSize = sizeof(pd.diph);
+    pd.diph.dwObj = 0;
+    pd.diph.dwHow = DIPH_DEVICE;
+    if (SUCCEEDED(IDirectInputDevice2_GetProperty(iface, DIPROP_JOYSTICKID, &pd.diph)))
+        index = pd.dwData;
+
     /* Return joystick */
     pdidi->guidInstance = This->guidInstance;
     pdidi->guidProduct = This->guidProduct;
     /* we only support traditional joysticks for now */
     pdidi->dwDevType = This->devcaps.dwDevType;
-    strcpy(pdidi->tszInstanceName, "Joystick");
+    snprintf(pdidi->tszInstanceName, MAX_PATH, "Joystick %d", index);
     strcpy(pdidi->tszProductName, This->name);
     if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3A)) {
         pdidi->guidFFDriver = GUID_NULL;
@@ -622,6 +670,9 @@ HRESULT WINAPI JoystickWGenericImpl_GetDeviceInfo(
     LPDIDEVICEINSTANCEW pdidi)
 {
     JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface);
+    CHAR buffer[MAX_PATH];
+    DIPROPDWORD pd;
+    DWORD index = 0;
 
     TRACE("(%p,%p)\n", iface, pdidi);
 
@@ -631,12 +682,21 @@ HRESULT WINAPI JoystickWGenericImpl_GetDeviceInfo(
         return DIERR_INVALIDPARAM;
     }
 
+    /* Try to get joystick index */
+    pd.diph.dwSize = sizeof(pd);
+    pd.diph.dwHeaderSize = sizeof(pd.diph);
+    pd.diph.dwObj = 0;
+    pd.diph.dwHow = DIPH_DEVICE;
+    if (SUCCEEDED(IDirectInputDevice2_GetProperty(iface, DIPROP_JOYSTICKID, &pd.diph)))
+        index = pd.dwData;
+
     /* Return joystick */
     pdidi->guidInstance = This->guidInstance;
     pdidi->guidProduct = This->guidProduct;
     /* we only support traditional joysticks for now */
     pdidi->dwDevType = This->devcaps.dwDevType;
-    MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, pdidi->tszInstanceName, MAX_PATH);
+    snprintf(buffer, sizeof(buffer), "Joystick %d", index);
+    MultiByteToWideChar(CP_ACP, 0, buffer, -1, pdidi->tszInstanceName, MAX_PATH);
     MultiByteToWideChar(CP_ACP, 0, This->name, -1, pdidi->tszProductName, MAX_PATH);
     if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3W)) {
         pdidi->guidFFDriver = GUID_NULL;
@@ -718,7 +778,7 @@ HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
         DWORD type = 0x000000ff & (lpdiaf->rgoAction[i].dwSemantic >> 8);
         DWORD genre = 0xff000000 & lpdiaf->rgoAction[i].dwSemantic;
 
-        /* Don't touch an user configured action */
+        /* Don't touch a user configured action */
         if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue;
 
         /* Only consider actions of the right genre */
@@ -728,7 +788,7 @@ HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
         {
             if (type & object_types[j])
             {
-                /* Assure that the object exists */
+                /* Ensure that the object exists */
                 LPDIOBJECTDATAFORMAT odf = dataformat_to_odf_by_type(This->base.data_format.wine_df, inst, object_types[j]);
 
                 if (odf != NULL)