[dinput/joystick_linuxinput] add POV detection and reporting

Christoph Frick frick at sc-networks.de
Fri Mar 10 02:58:14 CST 2006


License: LGPL

ChangeLog:
2006-03-09	Christoph Frick <rid at zefix.tv>
	* dlls/dinput/joystick_linuxinput.c
	mapping of ABS_HAT[0-3][XY] to the four POV used by dinput

-- 
cu

diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 5530c16..4f7d9f1 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -67,6 +67,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
 
 /* Wine joystick driver object instances */
 #define WINE_JOYSTICK_AXIS_BASE   0
+#define WINE_JOYSTICK_POV_BASE    6
 #define WINE_JOYSTICK_BUTTON_BASE 8
 
 typedef struct EffectListItem EffectListItem;
@@ -148,6 +149,7 @@ static GUID DInput_Wine_Joystick_GUID = 
 
 static void fake_current_js_state(JoystickImpl *ji);
 static int find_property_offset(JoystickImpl *This, LPCDIPROPHEADER ph);
+static DWORD map_pov(int event_value, int is_x);
 
 #define test_bit(arr,bit) (((BYTE*)arr)[bit>>3]&(1<<(bit&7)))
 
@@ -618,6 +620,8 @@ map_axis(JoystickImpl* This, int axis, i
  */
 static void fake_current_js_state(JoystickImpl *ji)
 {
+	int i;
+	/* center the axes */
 	ji->js.lX  = map_axis(ji, ABS_X,  ji->axes[ABS_X ][AXE_ABS]);
 	ji->js.lY  = map_axis(ji, ABS_Y,  ji->axes[ABS_Y ][AXE_ABS]);
 	ji->js.lZ  = map_axis(ji, ABS_Z,  ji->axes[ABS_Z ][AXE_ABS]);
@@ -626,6 +630,35 @@ static void fake_current_js_state(Joysti
 	ji->js.lRz = map_axis(ji, ABS_RZ, ji->axes[ABS_RZ][AXE_ABS]);
 	ji->js.rglSlider[0] = map_axis(ji, ABS_THROTTLE, ji->axes[ABS_THROTTLE][AXE_ABS]);
 	ji->js.rglSlider[1] = map_axis(ji, ABS_RUDDER,   ji->axes[ABS_RUDDER  ][AXE_ABS]);
+	/* POV center is -1 */
+	for (i=0; i<4; i++) {
+		ji->js.rgdwPOV[i] = -1;
+	}
+}
+
+/*
+ * Maps an event value to a DX "clock" position:
+ *           0
+ * 27000    -1 9000
+ *       18000
+ */
+static DWORD map_pov(int event_value, int is_x) 
+{
+	DWORD ret = -1;
+	if (is_x) {
+		if (event_value<0) {
+			ret = 27000;
+		} else if (event_value>0) {
+			ret = 9000;
+		}
+	} else {
+		if (event_value<0) {
+			ret = 0;
+		} else if (event_value>0) {
+			ret = 18000;
+		}
+	}
+	return ret;
 }
 
 static int find_property_offset(JoystickImpl *This, LPCDIPROPHEADER ph)
@@ -717,6 +750,26 @@ static void joy_polldev(JoystickImpl *Th
                 This->js.rglSlider[1] = map_axis(This,ABS_RUDDER,ie.value);
                 GEN_EVENT(DIJOFS_SLIDER(1),This->js.rglSlider[1],ie.time.tv_usec,(This->dinput->evsequence)++);
                 break;
+	    case ABS_HAT0X:
+	    case ABS_HAT0Y:
+                This->js.rgdwPOV[0] = map_pov(ie.value,ie.code==ABS_HAT0X);
+                GEN_EVENT(DIJOFS_POV(0),This->js.rgdwPOV[0],ie.time.tv_usec,(This->dinput->evsequence)++);
+                break;
+	    case ABS_HAT1X:
+	    case ABS_HAT1Y:
+                This->js.rgdwPOV[1] = map_pov(ie.value,ie.code==ABS_HAT1X);
+                GEN_EVENT(DIJOFS_POV(1),This->js.rgdwPOV[1],ie.time.tv_usec,(This->dinput->evsequence)++);
+                break;
+	    case ABS_HAT2X:
+	    case ABS_HAT2Y:
+                This->js.rgdwPOV[2] = map_pov(ie.value,ie.code==ABS_HAT2X);
+                GEN_EVENT(DIJOFS_POV(2),This->js.rgdwPOV[2],ie.time.tv_usec,(This->dinput->evsequence)++);
+                break;
+	    case ABS_HAT3X:
+	    case ABS_HAT3Y:
+                This->js.rgdwPOV[3] = map_pov(ie.value,ie.code==ABS_HAT3X);
+                GEN_EVENT(DIJOFS_POV(3),This->js.rgdwPOV[3],ie.time.tv_usec,(This->dinput->evsequence)++);
+                break;
 	    default:
 		FIXME("unhandled joystick axe event (code %d, value %d)\n",ie.code,ie.value);
 		break;
@@ -1078,6 +1131,26 @@ static HRESULT WINAPI JoystickAImpl_Enum
   }
 
   if ((dwFlags == DIDFT_ALL) ||
+      (dwFlags & DIDFT_POV)) {
+    int i;
+    ddoi.guidType = GUID_POV;
+    for (i=0; i<4; i++) {
+      if (test_bit(This->absbits,ABS_HAT0X+(i<<1)) && test_bit(This->absbits,ABS_HAT0Y+(i<<1))) {
+        ddoi.dwOfs = DIJOFS_POV(i);
+        ddoi.dwType = DIDFT_MAKEINSTANCE(i << WINE_JOYSTICK_POV_BASE) | DIDFT_POV;
+        sprintf(ddoi.tszName, "%d-POV", i);
+        _dump_OBJECTINSTANCEA(&ddoi);
+        if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) {
+          /* return to unaquired state if that's where we were */
+          if (xfd == -1)
+            IDirectInputDevice8_Unacquire(iface);
+          return DI_OK;
+        }
+      }
+    }
+  }
+
+  if ((dwFlags == DIDFT_ALL) ||
       (dwFlags & DIDFT_BUTTON)) {
     int i, btncount=0;
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 163 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20060310/8d959552/attachment.pgp


More information about the wine-patches mailing list