Christoph Frick : dinput/joystick_linuxinput: Add POV detection and reporting.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Mar 13 08:46:44 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 034a030d374674b14a95a606f5348eb22db2e456
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=034a030d374674b14a95a606f5348eb22db2e456

Author: Christoph Frick <rid at zefix.tv>
Date:   Fri Mar 10 09:58:14 2006 +0100

dinput/joystick_linuxinput: Add POV detection and reporting.

Mapping of ABS_HAT[0-3][XY] to the four POV used by dinput.

---

 dlls/dinput/joystick_linuxinput.c |   75 +++++++++++++++++++++++++++++++++++++
 1 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 5530c16..7de164d 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,8 +149,9 @@ 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)))
+#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
 
 static int joydev_have(BOOL require_ff)
 {
@@ -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;
 




More information about the wine-cvs mailing list