xbox 360 emulation with logitech cordless and dinput joy disable
Giovanni Ongaro
giovanni.nicola at ticino.com
Tue Jun 12 16:48:53 CDT 2012
-------------- next part --------------
>From 30f04e23857310859e31a44e97425946c9d2edfc Mon Sep 17 00:00:00 2001
From: root <root at joe.(none)>
Date: Tue, 12 Jun 2012 23:36:36 +0200
Subject: patch emulation xbox360 joystick with logitech cordless rumblepad
also includes fix for disabling dinput joys
many times it is necessary for axis conflicts betwwen dinput and xinput1_3 to disable dinput joysticks this can be done by launching wine in such manner LINIXFORCENOJOY=yes wine <jour>program
---
dlls/dinput/joystick_linux.c | 78 ++++------
dlls/dinput/joystick_linuxinput.c | 9 -
dlls/xinput1_3/xinput1_3_main.c | 308 ++++++++++++++++++++++++++++++++-----
3 files changed, 300 insertions(+), 95 deletions(-)
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index 5afd07c..59662e5 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -43,6 +43,9 @@
# include <sys/ioctl.h>
#endif
#include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+# include <sys/errno.h>
+#endif
#ifdef HAVE_LINUX_IOCTL_H
# include <linux/ioctl.h>
#endif
@@ -212,6 +215,8 @@ static INT find_joystick_devices(void)
static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
+ if (getenv("LINIXFORCENOJOY") != NULL) return FALSE; /*JoeFix disable joystick*/
+
int fd = -1;
if (id >= find_joystick_devices()) return FALSE;
@@ -256,7 +261,8 @@ static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN
static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
int fd = -1;
-
+ if (getenv("LINIXFORCENOJOY") != NULL) return FALSE; /*JoeFix disable joystick*/
+
if (id >= find_joystick_devices()) return FALSE;
if (dwFlags & DIEDFL_FORCEFEEDBACK) {
@@ -542,42 +548,6 @@ static HRESULT WINAPI JoystickLinuxAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
}
/******************************************************************************
- * GetProperty : get input device properties
- */
-static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
- JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
- TRACE("(this=%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph);
- _dump_DIPROPHEADER(pdiph);
-
- if (!IS_DIPROP(rguid)) return DI_OK;
-
- switch (LOWORD(rguid)) {
-
- case (DWORD_PTR) DIPROP_JOYSTICKID:
- {
- LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
- pd->dwData = get_joystick_index(&This->generic.base.guid);
- TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
- break;
- }
-
- default:
- return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
- }
-
- return DI_OK;
-}
-
-static HRESULT WINAPI JoystickLinuxAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
- JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
- return JoystickLinuxWImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph);
-}
-
-/******************************************************************************
* Unacquire : frees the joystick
*/
static HRESULT WINAPI JoystickLinuxWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
@@ -607,7 +577,7 @@ static HRESULT WINAPI JoystickLinuxAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
return JoystickLinuxWImpl_Unacquire(IDirectInputDevice8W_from_impl(This));
}
-
+#define DEAD_AXIS 4096
static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
{
struct pollfd plfd;
@@ -633,7 +603,7 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
return;
}
- TRACE("js_event: type 0x%x, number %d, value %d\n",
+ FIXME("js_event: type 0x%x, number %d, value %d\n",
jse.type,jse.number,jse.value);
if (jse.type & JS_EVENT_BUTTON)
{
@@ -641,23 +611,38 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON;
This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00;
+ if (jse.value == 1) {
+ FIXME("Button %d pressed\n",jse.number);
+ }
+
}
else if (jse.type & JS_EVENT_AXIS)
{
- int number = This->generic.axis_map[jse.number]; /* wine format object index */
+ int number = This->generic.axis_map[jse.number];
+
if (number < 0) return;
inst_id = number < 8 ? DIDFT_MAKEINSTANCE(number) | DIDFT_ABSAXIS :
DIDFT_MAKEINSTANCE(number - 8) | DIDFT_POV;
- value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);
+ if ((jse.value < DEAD_AXIS && jse.value > 0) || (jse.value > -DEAD_AXIS && jse.value < 0)) { //JoeFix DEAD ZONE
+ value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], 0);
+ }
+ else if (jse.number == 1 && (getenv("LINIXFORCEJOYYSWAP") != NULL)){//JoeFix Y axis swapped for unreal engine
+ value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], -jse.value);
+ }
+ else {
+ value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);
+
+ }
+
TRACE("changing axis %d => %d\n", jse.number, number);
switch (number)
{
case 0: This->generic.js.lX = value; break;
case 1: This->generic.js.lY = value; break;
case 2: This->generic.js.lZ = value; break;
- case 3: This->generic.js.lRx = value; break;
+ case 3: This->generic.js.lRx = value; break;
case 4: This->generic.js.lRy = value; break;
case 5: This->generic.js.lRz = value; break;
case 6: This->generic.js.rglSlider[0] = value; break;
@@ -665,8 +650,9 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
case 8: case 9: case 10: case 11:
{
int idx = number - 8;
-
- if (jse.number % 2)
+ FIXME("IDX=%d\n",idx);
+;
+ if (jse.number % 2)
This->povs[idx].y = jse.value;
else
This->povs[idx].x = jse.value;
@@ -691,7 +677,7 @@ static const IDirectInputDevice8AVtbl JoystickAvt =
IDirectInputDevice2AImpl_Release,
JoystickAGenericImpl_GetCapabilities,
IDirectInputDevice2AImpl_EnumObjects,
- JoystickLinuxAImpl_GetProperty,
+ JoystickAGenericImpl_GetProperty,
JoystickAGenericImpl_SetProperty,
JoystickLinuxAImpl_Acquire,
JoystickLinuxAImpl_Unacquire,
@@ -727,7 +713,7 @@ static const IDirectInputDevice8WVtbl JoystickWvt =
IDirectInputDevice2WImpl_Release,
JoystickWGenericImpl_GetCapabilities,
IDirectInputDevice2WImpl_EnumObjects,
- JoystickLinuxWImpl_GetProperty,
+ JoystickWGenericImpl_GetProperty,
JoystickWGenericImpl_SetProperty,
JoystickLinuxWImpl_Acquire,
JoystickLinuxWImpl_Unacquire,
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 3cab015..2902f9f 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -965,15 +965,6 @@ static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF
break;
}
- case (DWORD_PTR) DIPROP_JOYSTICKID:
- {
- LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
- pd->dwData = get_joystick_index(&This->generic.base.guid);
- TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
- break;
- }
-
default:
return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
}
diff --git a/dlls/xinput1_3/xinput1_3_main.c b/dlls/xinput1_3/xinput1_3_main.c
index 2b3a5f7..171795e 100644
--- a/dlls/xinput1_3/xinput1_3_main.c
+++ b/dlls/xinput1_3/xinput1_3_main.c
@@ -15,6 +15,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ * ADAPTED FOR LOGITECH CORDLESS RUMBLEPAD BY JOE ON 11.08.11
*/
#include "config.h"
@@ -28,11 +29,33 @@
#include "winerror.h"
#include "xinput.h"
+#include <linux/joystick.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+XINPUT_STATE prev_pstate;
+const WORD buttonIDs[10] = {
+ XINPUT_GAMEPAD_A,
+ XINPUT_GAMEPAD_B,
+ XINPUT_GAMEPAD_X,
+ XINPUT_GAMEPAD_Y,
+ XINPUT_GAMEPAD_LEFT_SHOULDER,
+ XINPUT_GAMEPAD_RIGHT_SHOULDER,
+ XINPUT_GAMEPAD_BACK,
+ XINPUT_GAMEPAD_START,
+ XINPUT_GAMEPAD_LEFT_THUMB,
+ XINPUT_GAMEPAD_RIGHT_THUMB,
+};
+int fdJoy;
WINE_DEFAULT_DEBUG_CHANNEL(xinput);
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
+ fdJoy=open("/dev/input/js0",O_RDONLY | O_NONBLOCK);
+
switch(reason)
{
case DLL_WINE_PREATTACH:
@@ -55,58 +78,263 @@ void WINAPI XInputEnable(BOOL enable)
FIXME("(%d) Stub!\n", enable);
}
-DWORD WINAPI XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration)
-{
- FIXME("(%d %p) Stub!\n", dwUserIndex, pVibration);
-
- if (dwUserIndex < XUSER_MAX_COUNT)
- {
- return ERROR_DEVICE_NOT_CONNECTED;
- /* If controller exists then return ERROR_SUCCESS */
- }
- return ERROR_BAD_ARGUMENTS;
+DWORD WINAPI XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pstate)
+{ XINPUT_STATE *pState;
+// FIXME("IN XinputSetState\n");
+
+
+ return ERROR_SUCCESS;
}
+#define DEAD_ZONE 4096
+
+int dead_or_value(int value) {
+ if ((value > DEAD_ZONE && value > 0) || (value < -DEAD_ZONE && value < 0)) {
+ return value;
+ }
+ else {
+ return 0;
+} }
+
DWORD WINAPI XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState)
{
- static int warn_once;
+ struct js_event e;
+ int ret;
+ *pState =prev_pstate;
+ while (read(fdJoy,&e,sizeof(struct js_event)) != -1) {
+ // timestamp packet
+ //pState->Gamepad.wButtons=0;
+ pState->dwPacketNumber=GetTickCount();
+ //pState->dwPacketNumber=e.time;
- if (!warn_once++)
- FIXME("(%u %p)\n", dwUserIndex, pState);
+ if (e.type == JS_EVENT_BUTTON) {
- if (dwUserIndex < XUSER_MAX_COUNT)
- {
- return ERROR_DEVICE_NOT_CONNECTED;
- /* If controller exists then return ERROR_SUCCESS */
- }
- return ERROR_BAD_ARGUMENTS;
-}
+ if (e.number == 0) {
+ if (e.value == 1) {
+ FIXME("BUTTON X PRESSED\n");
-DWORD WINAPI XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserve, PXINPUT_KEYSTROKE pKeystroke)
-{
- FIXME("(%d %d %p) Stub!\n", dwUserIndex, dwReserve, pKeystroke);
+ pState->Gamepad.wButtons |= buttonIDs[2];//X
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[2];
+ }
+ }
+
+ if (e.number == 1) {
+ if (e.value == 1) {
+ FIXME("BUTTON A PRESSED\n");
- if (dwUserIndex < XUSER_MAX_COUNT)
- {
- return ERROR_DEVICE_NOT_CONNECTED;
- /* If controller exists then return ERROR_SUCCESS */
- }
- return ERROR_BAD_ARGUMENTS;
+ pState->Gamepad.wButtons |= buttonIDs[0];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[0];
+ }
+ }
+ if (e.number == 2) {
+ if (e.value == 1) {
+ FIXME("BUTTON B PRESSED\n");
+
+ pState->Gamepad.wButtons |= buttonIDs[1];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[1];
+ }
+ }
+ if (e.number == 3) {
+ if (e.value == 1) {
+ FIXME("BUTTON Y PRESSED\n");
+
+ pState->Gamepad.wButtons |= buttonIDs[3];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[3];
+ }
+ }
+
+ if (e.number == 4) {
+ if (e.value == 1) {
+ FIXME("TRIGGER LEFT PRESSED\n");
+ pState->Gamepad.bLeftTrigger=32767;
+ }
+ else {
+ pState->Gamepad.bLeftTrigger=0;
+ }
+
+ }
+ if (e.number == 5) {
+ if (e.value == 1) {
+ FIXME("TRIGGER RIGHT PRESSED\n");
+ pState->Gamepad.bRightTrigger=32767;
+ }
+
+ else {
+ pState->Gamepad.bRightTrigger=0;
+ }
+
+ }
+ if (e.number == 6) {
+ if (e.value == 1) {
+ FIXME("LEFT SHOULDER PRESSED\n");
+ pState->Gamepad.wButtons |= buttonIDs[4];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[4];
+ }
+
+
+
+ }
+ if (e.number == 7) {
+ if (e.value == 1) {
+ FIXME("RIGHT SHOULDER PRESSED\n");
+ pState->Gamepad.wButtons |= buttonIDs[5];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[5];
+ }
+
+
+ }
+
+ if (e.number == 8) {
+ if (e.value == 1) {
+ FIXME("BACK PRESSED\n");
+ pState->Gamepad.wButtons |= buttonIDs[6];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[6];
+ }
+
+
+ }
+
+ if (e.number == 9) {
+ if (e.value == 1) {
+
+ FIXME("START PRESSED\n");
+ pState->Gamepad.wButtons |= buttonIDs[7];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[7];
+ }
+
+
+ }
+ if (e.number == 10) {
+ if (e.value == 1) {
+
+ FIXME("LEFT THUMB PRESSED\n");
+ pState->Gamepad.wButtons |= buttonIDs[8];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[8];
+ }
+
+ }
+ if (e.number == 11) {
+ if (e.value == 1) {
+
+ FIXME("RIGHT THUMB PRESSED\n");
+ pState->Gamepad.wButtons |= buttonIDs[9];
+ }
+ else {
+ pState->Gamepad.wButtons &= ~buttonIDs[9];
+ }
+
+
+ }
+
+ }
+#define JOYMAX 30000
+#define JOYMIN -30000
+
+
+ if (e.type == JS_EVENT_AXIS) {
+ FIXME("AXIS %d VALUE=%d MOVED\n",e.number,e.value);
+ if (e.number == 0) {
+ pState->Gamepad.sThumbLX=dead_or_value(e.value);
+
+ }
+
+ if (e.number == 1) {
+ pState->Gamepad.sThumbLY=dead_or_value(-e.value);
+
+ }
+
+ if (e.number == 2) {
+ pState->Gamepad.sThumbRX=dead_or_value(e.value);;
+
+ }
+
+ if (e.number == 3) {
+ //if (e.value == 0) {
+ // pState->Gamepad.sThumbRY=-32768;
+ //}
+ pState->Gamepad.sThumbRY=dead_or_value(-e.value);
+
+ }
+
+ if (e.number == 4) {
+ if (e.value > JOYMAX) {
+ pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
+ }
+ else if (e.value < JOYMIN) {
+ pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
+ }
+ else {
+ pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_RIGHT ;
+ pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_LEFT ;
+
+ }
+
+
+ }
+ if (e.number == 5) {
+ if (e.value > JOYMAX) {
+ pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
+ }
+ else if (e.value < JOYMIN) {
+ pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP;
+ }
+ else {
+ pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_UP;
+ pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_DOWN ;
+ }
+
+ }
+ }
+ }
+ prev_pstate=*pState;
+
+ //FIXME("exiting XInputGetState\n");
+ //FIXME("InXinputgetState\n");
+ return ERROR_SUCCESS;
}
-DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
-{
- static int warn_once;
+DWORD WINAPI XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserve, PXINPUT_KEYSTROKE pKeyStroke)
+{ int ret;
+ FIXME("In XInputGetKeyStroke\n");
+ //FIXME("(%d %d %p) Stub!\n", dwUserIndex, dwReserve, pKeyStroke);
+ return ERROR_SUCCESS;
+}
- if (!warn_once++)
- FIXME("(%d %d %p)\n", dwUserIndex, dwFlags, pCapabilities);
+DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* xCaps)
+{
+ xCaps->Type = XINPUT_DEVTYPE_GAMEPAD;
+ xCaps->SubType = XINPUT_DEVSUBTYPE_GAMEPAD;
+ xCaps->Flags = 0; // we do not support sound
+ xCaps->Vibration.wLeftMotorSpeed = xCaps->Vibration.wRightMotorSpeed = 0xFF;
+ xCaps->Gamepad.bLeftTrigger = xCaps->Gamepad.bRightTrigger = 0xFF;
+
+ //MSDN lie, this is not range !
+ //Dumped from XInput device
+ xCaps->Gamepad.sThumbLX = (SHORT) -64;
+ xCaps->Gamepad.sThumbLY = (SHORT) -64;
+ xCaps->Gamepad.sThumbRX = (SHORT) -64;
+ xCaps->Gamepad.sThumbRY = (SHORT) -64;
+ xCaps->Gamepad.wButtons = (WORD) 0xF3FF;
+ return ERROR_SUCCESS;
- if (dwUserIndex < XUSER_MAX_COUNT)
- {
- return ERROR_DEVICE_NOT_CONNECTED;
- /* If controller exists then return ERROR_SUCCESS */
- }
- return ERROR_BAD_ARGUMENTS;
}
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid)
--
1.7.7.6
More information about the wine-patches
mailing list