This patch makes dinput8 behaviour more correct for mouse and keyboard.
Now, controls work in the Incoming Forces demo.
I suppose the game is playable. I didn't play too much since it's slow with my P2-400 / TNT2.
At the very least, this will give some material for Raphael and Jason.
Bye, Christian
Changelog : Make dinput8 behaviour more correct for mouse and keyboard. Fix small bug when keyboard buffer overflows. Use DI_OK instead of 0 for returned values.
Christian Costa titan.costa@wanadoo.fr
Index: dinput.h =================================================================== RCS file: /home/wine/wine/include/dinput.h,v retrieving revision 1.34 diff -u -r1.34 dinput.h --- dinput.h 11 Apr 2003 00:31:04 -0000 1.34 +++ dinput.h 9 Jun 2003 13:01:08 -0000 @@ -191,6 +191,25 @@ #define DIDEVTYPE_JOYSTICK 4 #define DIDEVTYPE_HID 0x00010000 +#define DI8DEVCLASS_ALL 0 +#define DI8DEVCLASS_DEVICE 1 +#define DI8DEVCLASS_POINTER 2 +#define DI8DEVCLASS_KEYBOARD 3 +#define DI8DEVCLASS_GAMECTRL 4 + +#define DI8DEVTYPE_DEVICE 0x11 +#define DI8DEVTYPE_MOUSE 0x12 +#define DI8DEVTYPE_KEYBOARD 0x13 +#define DI8DEVTYPE_JOYSTICK 0x14 +#define DI8DEVTYPE_GAMEPAD 0x15 +#define DI8DEVTYPE_DRIVING 0x16 +#define DI8DEVTYPE_FLIGHT 0x17 +#define DI8DEVTYPE_1STPERSON 0x18 +#define DI8DEVTYPE_DEVICECTRL 0x19 +#define DI8DEVTYPE_SCREENPOINTER 0x1A +#define DI8DEVTYPE_REMOTE 0x1B +#define DI8DEVTYPE_SUPPLEMENTAL 0x1C + #define DIDEVTYPEMOUSE_UNKNOWN 1 #define DIDEVTYPEMOUSE_TRADITIONAL 2 #define DIDEVTYPEMOUSE_FINGERSTICK 3 @@ -219,6 +238,76 @@ #define DIDEVTYPEJOYSTICK_WHEEL 6 #define DIDEVTYPEJOYSTICK_HEADTRACKER 7 +#define DI8DEVTYPEMOUSE_UNKNOWN 1 +#define DI8DEVTYPEMOUSE_TRADITIONAL 2 +#define DI8DEVTYPEMOUSE_FINGERSTICK 3 +#define DI8DEVTYPEMOUSE_TOUCHPAD 4 +#define DI8DEVTYPEMOUSE_TRACKBALL 5 +#define DI8DEVTYPEMOUSE_ABSOLUTE 6 + +#define DI8DEVTYPEKEYBOARD_UNKNOWN 0 +#define DI8DEVTYPEKEYBOARD_PCXT 1 +#define DI8DEVTYPEKEYBOARD_OLIVETTI 2 +#define DI8DEVTYPEKEYBOARD_PCAT 3 +#define DI8DEVTYPEKEYBOARD_PCENH 4 +#define DI8DEVTYPEKEYBOARD_NOKIA1050 5 +#define DI8DEVTYPEKEYBOARD_NOKIA9140 6 +#define DI8DEVTYPEKEYBOARD_NEC98 7 +#define DI8DEVTYPEKEYBOARD_NEC98LAPTOP 8 +#define DI8DEVTYPEKEYBOARD_NEC98106 9 +#define DI8DEVTYPEKEYBOARD_JAPAN106 10 +#define DI8DEVTYPEKEYBOARD_JAPANAX 11 +#define DI8DEVTYPEKEYBOARD_J3100 12 + +#define DI8DEVTYPE_LIMITEDGAMESUBTYPE 1 + +#define DI8DEVTYPEJOYSTICK_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEJOYSTICK_STANDARD 2 + +#define DI8DEVTYPEGAMEPAD_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEGAMEPAD_STANDARD 2 +#define DI8DEVTYPEGAMEPAD_TILT 3 + +#define DI8DEVTYPEDRIVING_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEDRIVING_COMBINEDPEDALS 2 +#define DI8DEVTYPEDRIVING_DUALPEDALS 3 +#define DI8DEVTYPEDRIVING_THREEPEDALS 4 +#define DI8DEVTYPEDRIVING_HANDHELD 5 + +#define DI8DEVTYPEFLIGHT_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPEFLIGHT_STICK 2 +#define DI8DEVTYPEFLIGHT_YOKE 3 +#define DI8DEVTYPEFLIGHT_RC 4 + +#define DI8DEVTYPE1STPERSON_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE +#define DI8DEVTYPE1STPERSON_UNKNOWN 2 +#define DI8DEVTYPE1STPERSON_SIXDOF 3 +#define DI8DEVTYPE1STPERSON_SHOOTER 4 + +#define DI8DEVTYPESCREENPTR_UNKNOWN 2 +#define DI8DEVTYPESCREENPTR_LIGHTGUN 3 +#define DI8DEVTYPESCREENPTR_LIGHTPEN 4 +#define DI8DEVTYPESCREENPTR_TOUCH 5 + +#define DI8DEVTYPEREMOTE_UNKNOWN 2 + +#define DI8DEVTYPEDEVICECTRL_UNKNOWN 2 +#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION 3 +#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED 4 + +#define DI8DEVTYPESUPPLEMENTAL_UNKNOWN 2 +#define DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER 3 +#define DI8DEVTYPESUPPLEMENTAL_HEADTRACKER 4 +#define DI8DEVTYPESUPPLEMENTAL_HANDTRACKER 5 +#define DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE 6 +#define DI8DEVTYPESUPPLEMENTAL_SHIFTER 7 +#define DI8DEVTYPESUPPLEMENTAL_THROTTLE 8 +#define DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE 9 +#define DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS 10 +#define DI8DEVTYPESUPPLEMENTAL_DUALPEDALS 11 +#define DI8DEVTYPESUPPLEMENTAL_THREEPEDALS 12 +#define DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS 13 + #define GET_DIDEVICE_TYPE(dwDevType) LOBYTE(dwDevType) #define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType) Index: device.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/device.c,v retrieving revision 1.11 diff -u -r1.11 device.c --- device.c 29 Apr 2003 22:47:04 -0000 1.11 +++ device.c 9 Jun 2003 12:58:54 -0000 @@ -291,7 +291,7 @@ TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); } - return 0; + return DI_OK; } HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel( @@ -303,7 +303,7 @@ TRACE(" cooperative level : "); _dump_cooperativelevel_DI(dwflags); } - return 0; + return DI_OK; } HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification( @@ -311,7 +311,7 @@ ) { ICOM_THIS(IDirectInputDevice2AImpl,iface); FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd); - return 0; + return DI_OK; } ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface) @@ -321,7 +321,7 @@ if (This->ref) return This->ref; HeapFree(GetProcessHeap(),0,This); - return 0; + return DI_OK; } HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface( @@ -334,17 +334,17 @@ if (IsEqualGUID(&IID_IUnknown,riid)) { IDirectInputDevice2_AddRef(iface); *ppobj = This; - return 0; + return DI_OK; } if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) { IDirectInputDevice2_AddRef(iface); *ppobj = This; - return 0; + return DI_OK; } if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) { IDirectInputDevice7_AddRef(iface); *ppobj = This; - return 0; + return DI_OK; } TRACE("Unsupported interface !\n"); return E_FAIL; Index: dinput_main.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/dinput_main.c,v retrieving revision 1.34 diff -u -r1.34 dinput_main.c --- dinput_main.c 29 Apr 2003 22:43:48 -0000 1.34 +++ dinput_main.c 9 Jun 2003 12:58:56 -0000 @@ -107,6 +107,7 @@ This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl)); This->lpVtbl = &ddi7avt; This->ref = 1; + This->version = 1; *ppDI = This; return DI_OK; @@ -117,6 +118,7 @@ This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl)); This->lpVtbl = &ddi8avt; This->ref = 1; + This->version = 8; *ppDI = This; return DI_OK; @@ -157,7 +159,7 @@ for (i = 0; i < nrof_dinput_devices; i++) { devInstance.dwSize = sizeof(devInstance); - if (dinput_devices[i]->enum_device(dwDevType, dwFlags, &devInstance)) { + if (dinput_devices[i]->enum_device(dwDevType, dwFlags, &devInstance, This->version)) { if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) return 0; } Index: dinput_private.h =================================================================== RCS file: /home/wine/wine/dlls/dinput/dinput_private.h,v retrieving revision 1.8 diff -u -r1.8 dinput_private.h --- dinput_private.h 11 Feb 2003 22:10:11 -0000 1.8 +++ dinput_private.h 9 Jun 2003 12:58:56 -0000 @@ -31,12 +31,14 @@ /* Used to have an unique sequence number for all the events */ DWORD evsequence; + + int version; }; /* Function called by all devices that Wine supports */ typedef struct dinput_device { INT pref; - BOOL (*enum_device)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi); + BOOL (*enum_device)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version); HRESULT (*create_device)(IDirectInputAImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev); } dinput_device; Index: joystick/linux.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/joystick/linux.c,v retrieving revision 1.14 diff -u -r1.14 linux.c --- joystick/linux.c 15 Mar 2003 00:12:43 -0000 1.14 +++ joystick/linux.c 9 Jun 2003 12:58:59 -0000 @@ -89,7 +89,7 @@ {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} }; -static BOOL joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi) +static BOOL joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) { int fd = -1; Index: joystick/linuxinput.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/joystick/linuxinput.c,v retrieving revision 1.14 diff -u -r1.14 linuxinput.c --- joystick/linuxinput.c 15 Mar 2003 00:12:43 -0000 1.14 +++ joystick/linuxinput.c 9 Jun 2003 12:58:59 -0000 @@ -122,7 +122,7 @@ #define test_bit(arr,bit) (((BYTE*)arr)[bit>>3]&(1<<(bit&7))) -static BOOL joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi) +static BOOL joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) { int i, fd, havejoy = 0; Index: keyboard/main.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/keyboard/main.c,v retrieving revision 1.23 diff -u -r1.23 main.c --- keyboard/main.c 4 Jun 2003 20:11:56 -0000 1.23 +++ keyboard/main.c 9 Jun 2003 12:58:59 -0000 @@ -117,7 +117,7 @@ if (current->count == current->buffersize) { - current->start++; + current->start = ++current->start % current->buffersize; current->overflow = TRUE; } else @@ -138,7 +138,7 @@ {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41} }; -static void fill_keyboard_dideviceinstancea(LPDIDEVICEINSTANCEA lpddi) { +static void fill_keyboard_dideviceinstancea(LPDIDEVICEINSTANCEA lpddi, int version) { DWORD dwSize; DIDEVICEINSTANCEA ddi; @@ -152,19 +152,24 @@ ddi.dwSize = dwSize; ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */ ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ - ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); + if (version >= 8) + ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); + else + ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); strcpy(ddi.tszInstanceName, "Keyboard"); strcpy(ddi.tszProductName, "Wine Keyboard"); memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static BOOL keyboarddev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi) +static BOOL keyboarddev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) { - if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) { + if ((dwDevType == 0) || + ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) || + ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) { TRACE("Enumerating the Keyboard device\n"); - fill_keyboard_dideviceinstancea(lpddi); + fill_keyboard_dideviceinstancea(lpddi, version); return TRUE; } @@ -239,7 +244,7 @@ DeleteCriticalSection(&(This->crit)); HeapFree(GetProcessHeap(),0,This); - return 0; + return DI_OK; } static HRESULT WINAPI SysKeyboardAImpl_SetProperty( @@ -270,13 +275,15 @@ break; } } - return 0; + return DI_OK; } static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState( LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr ) { + TRACE("(%p)->(%ld,%p)\n", iface, len, ptr); + /* Note: device does not need to be acquired */ if (len != 256) return DIERR_INVALIDPARAM; @@ -465,7 +472,10 @@ if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { lpDIDevCaps->dwFlags = DIDC_ATTACHED; - lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD; + if (This->dinput->version >= 8) + lpDIDevCaps->dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); + else + lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); lpDIDevCaps->dwAxes = 0; lpDIDevCaps->dwButtons = 256; lpDIDevCaps->dwPOVs = 0; @@ -536,7 +546,7 @@ return DI_OK; } - fill_keyboard_dideviceinstancea(pdidi); + fill_keyboard_dideviceinstancea(pdidi, This->dinput->version); return DI_OK; } @@ -578,3 +588,4 @@ IDirectInputDevice8AImpl_SetActionMap, IDirectInputDevice8AImpl_GetImageInfo }; + Index: mouse/main.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/mouse/main.c,v retrieving revision 1.22 diff -u -r1.22 main.c --- mouse/main.c 7 Jun 2003 00:36:51 -0000 1.22 +++ mouse/main.c 9 Jun 2003 12:59:01 -0000 @@ -146,7 +146,7 @@ {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} }; -static void fill_mouse_dideviceinstancea(LPDIDEVICEINSTANCEA lpddi) { +static void fill_mouse_dideviceinstancea(LPDIDEVICEINSTANCEA lpddi, int version) { DWORD dwSize; DIDEVICEINSTANCEA ddi; @@ -160,19 +160,24 @@ ddi.dwSize = dwSize; ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */ ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */ - ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8); + if (version >= 8) + ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8); + else + ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8); strcpy(ddi.tszInstanceName, "Mouse"); strcpy(ddi.tszProductName, "Wine Mouse"); memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static BOOL mousedev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi) +static BOOL mousedev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) { - if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) { + if ((dwDevType == 0) || + ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) || + ((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) { TRACE("Enumerating the mouse device\n"); - fill_mouse_dideviceinstancea(lpddi); + fill_mouse_dideviceinstancea(lpddi, version); return TRUE; } @@ -269,7 +274,7 @@ } HeapFree(GetProcessHeap(),0,This); - return 0; + return DI_OK; } @@ -296,7 +301,7 @@ This->win = hwnd; This->dwCoopLevel = dwflags; - return 0; + return DI_OK; } @@ -344,7 +349,7 @@ /* Prepare all the data-conversion filters */ This->wine_df = create_DataFormat(&(Wine_InternalMouseFormat), df, This->offset_array); - return 0; + return DI_OK; } /* low-level mouse hook */ @@ -639,7 +644,7 @@ This->m_state.lX, This->m_state.lY, This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); - return 0; + return DI_OK; } /****************************************************************************** @@ -716,7 +721,7 @@ This->need_warp = WARP_STARTED; #endif } - return 0; + return DI_OK; } /****************************************************************************** @@ -756,7 +761,7 @@ } } - return 0; + return DI_OK; } /****************************************************************************** @@ -848,7 +853,10 @@ if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { lpDIDevCaps->dwFlags = DIDC_ATTACHED; - lpDIDevCaps->dwDevType = DIDEVTYPE_MOUSE; + if (This->dinput->version >= 8) + lpDIDevCaps->dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8); + else + lpDIDevCaps->dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8); lpDIDevCaps->dwAxes = 3; lpDIDevCaps->dwButtons = 3; lpDIDevCaps->dwPOVs = 0; @@ -961,7 +969,7 @@ return DI_OK; } - fill_mouse_dideviceinstancea(pdidi); + fill_mouse_dideviceinstancea(pdidi, This->dinput->version); return DI_OK; }