00cpxxx / wine-xinput

XInput support to play games in Wine
The Unlicense
24 stars 3 forks source link

Input Issues with Sonic & All-Stars Racing Transformed #3

Open Enverex opened 7 years ago

Enverex commented 7 years ago

The devices are correctly showing up, but the triggers don't appear to work in-game. Trying to remap controls is impossible as the moment you try and redefine one, it gets set to either "Analog Channel 3+" or "Analog Channel 3-" which I guess are the two triggers which it seems to think are being held down.

I have SDL_GAMECONTROLLERCONFIG set to a local copy of this file - https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt - and I'm using xboxdrv (with real XBox 360 controllers and mimic-xpad = true).

00cpxxx commented 7 years ago

Can you give URLs for the games so I can see if I can check myself?

Are the games made using SDL? Otherwise there is no point in trying to use SDL_GAMECONTROLLERCONFIG.

Enverex commented 7 years ago

Ah sorry, SDL_GAMECONTROLLERCONFIG was a leftover from something else I was trying. I thought this patch used it to translate the Linux controller buttons to XInput, if not, you can ignore that part of the report.

This is the game on Steam - http://store.steampowered.com/app/212480/ and in the AppDB - https://appdb.winehq.org/objectManager.php?sClass=version&iId=28613

I'm not aware of a demo being available unfortunately.

00cpxxx commented 7 years ago

Please get a +xinput log so I can check if I see something, read for more instructions at https://wiki.winehq.org/FAQ#How_do_I_get_a_debug_trace.3F but basically you will do as explained below. Then use pastebin or any other place you can put the log so I can take a look.

First CD into Steam directory, run the command below, inside Steam run the game and get to the point it supposed to work but don't.

WINEDEBUG=+xinput wine Steam > /tmp/log.txt

The resulting file is the /tmp/log.txt and should have a bunch .lines starting with "xinput:"

Enverex commented 7 years ago

Here's the output. 1.4MB in total - https://emerald.xnode.org/Sonic.log

00cpxxx commented 7 years ago

Hi, I tried download the file but it always timeout connecting, I also tried using a proxy in the US and the result is the same.

Enverex commented 7 years ago

Weird, I've mirrored it here for now then - https://xnode.org/files/Sonic.log

00cpxxx commented 7 years ago

Thanks, now I can see it. The game calls XInputGetCapabilities, the issue is probably there. By the way there are these lines in the log:

fixme:xinput:dinput_is_good This is not a known xbox controller, using anyway. Expect problems! trace:xinput:dinput_is_good This controller has the same number of buttons/axes from xbox 360, should work... trace:xinput:dinput_is_good This controller has the same number of buttons/axes from xbox 360, should work... trace:xinput:dinput_is_good This controller has the same number of buttons/axes from xbox 360, should work...

How many controllers do you have connected and what brand are they? Can you paste the output of lsusb, please?

Enverex commented 7 years ago

They're official XBox 360 controllers connected via an official XBox 360 Wireless adapter, but I'm using xboxdrv (with mimic-xpad) rather than the kernel module. Here's the extended lsusb output in case it's useful:

Bus 003 Device 002: ID 045e:0719 Microsoft Corp. Xbox 360 Wireless Adapter
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass       255 Vendor Specific Subclass
  bDeviceProtocol       255 Vendor Specific Protocol
  bMaxPacketSize0         8
  idVendor           0x045e Microsoft Corp.
  idProduct          0x0719 Xbox 360 Wireless Adapter
  bcdDevice            1.00
  iManufacturer           1 ©Microsoft
  iProduct                2 Xbox 360 Wireless Receiver for Windows
  iSerial                 3 FFEE5C80
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          321
    bNumInterfaces          8
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              260mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    129
      iInterface              0
      ** UNRECOGNIZED:  14 22 00 01 13 81 1d 00 17 01 02 08 13 01 0c 00 0c 01 02 08
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    130
      iInterface              0
      ** UNRECOGNIZED:  0c 22 00 01 01 82 00 40 01 02 20 00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    129
      iInterface              0
      ** UNRECOGNIZED:  14 22 00 01 13 83 1d 00 17 01 02 08 13 03 0c 00 0c 01 02 08
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    130
      iInterface              0
      ** UNRECOGNIZED:  0c 22 00 01 01 84 00 40 01 04 20 00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    129
      iInterface              0
      ** UNRECOGNIZED:  14 22 00 01 13 85 1d 00 17 01 02 08 13 05 0c 00 0c 01 02 08
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        5
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    130
      iInterface              0
      ** UNRECOGNIZED:  0c 22 00 01 01 86 00 40 01 06 20 00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x06  EP 6 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        6
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    129
      iInterface              0
      ** UNRECOGNIZED:  14 22 00 01 13 87 1d 00 17 01 02 08 13 07 0c 00 0c 01 02 08
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x07  EP 7 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        7
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93
      bInterfaceProtocol    130
      iInterface              0
      ** UNRECOGNIZED:  0c 22 00 01 01 88 00 40 01 08 20 00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x88  EP 8 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x08  EP 8 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               4
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0002
  (Bus Powered)
  Remote Wakeup Enabled
00cpxxx commented 7 years ago

Please get a new +xinput with the following patch if it does not work: https://github.com/00cpxxx/wine-xinput/blob/master/xinput_quigon.patch

Enverex commented 7 years ago

Recompiling now and will report back tomorrow.

00cpxxx commented 7 years ago

I have updated the patch again with some new stuff. If possible try the newer one.

00cpxxx commented 7 years ago

After reading your first comment here again I'm sure this is fixed with the today's patch.

Enverex commented 7 years ago

Hi @00cpxxx, sorry, completely forgot about this. I'll actually set a reminder to try this when I'm home later.

00cpxxx commented 7 years ago

Absolutely no problem, I can wait as long as needed =)

Enverex commented 7 years ago

No dice unfortunately. Same behavior. In game the controls all seem fine except that the triggers don't do anything (thus you can't accelerate or reverse).

Going into the reconfiguration interface ends up with everything immediately trying to rebind to what I assume is one of the triggers.

Note that it did say: fixme:xinput:dinput_is_good This is not a known xbox controller (6 10 1), using anyway. Expect problems!

00cpxxx commented 7 years ago

Your controller has 1 button less than expected, 360 has 11 buttons. Can you attach the +xinput log, please? I need to see the values of the buttons/triggers, please. I tried the game but it crashes right away here, I believe due to deficiencies in the onboard graphic card.

Enverex commented 7 years ago

I wonder if that's because I've mapped the "Guide" button of the controller to a command in xboxdrv (I wasn't aware it no-longer exposed the button to the system when you did that, if that's the case). Shouldn't affect the triggers though.

I can see a value in this trace incrementing from 0 to 255 as I pull the triggers though so that looks ok. sonic+xinput.zip

00cpxxx commented 7 years ago

Thanks again, I think I see what is happening. The game is not using xinput for all controllers, it is actually using dinput and Wine differs from Windows in how the L/R triggers are outputted. In Windows both triggers show as Axis 3 (Z) where 0 is not pressed, negative means left is pressed and positive means right is pressed. Pressing both results in non distinguishable action, this was a design decision back when they added the Xbox controller to dinput to make games think the Axis is "centered". On Wine the triggers are represented as lZ and rZ (left/right Z), where the not pressed state for each is -32767. The game is expecting zero so when it sees the negative value it thinks the value is pressed. This requires fixing dinput in Wine to merge both axes in a single axis.

Enverex commented 7 years ago

So the game supports both XInput and DInput (apparently its DInput support is sketchy). Is it possible to disable one when using the other? The game does specifically support XInput, so how Wine handles DInput I guess shouldn't really matter (at least when explicitly trying to use XInput alone).

00cpxxx commented 7 years ago

According to the log the game is using the method described at https://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx which explains how to check if the controller is dinput or xinput. Wine does not support joystick enumaration in wbemprox so it fallsback to dinput. I'll see what I can do.

00cpxxx commented 7 years ago

Please attach a +dinput,+xinput so I can see how the game is making the enumeration, then I can make it not find any dinput controllers while still allowing xinput to find the controller.

Enverex commented 7 years ago

Sorry for the delay, got sidetracked. Attached.

sonic-dinput+xinput.zip

00cpxxx commented 7 years ago

Thanks for the log, I tried making dinput not return anything hoping the game would jump to Xinput but it depends on the Microsoft recipe of enumerating the devices from Dinput and then checking if they are Xinput using wbemprox. I cannot fix this bug in short term, ideally dinput should be fixed to mix the shoulder triggers and make the game work on dinput.

Enverex commented 7 years ago

I'm almost certain that the game worked when using X360CE without seeing 2 devices, but X360CE uses a fake dinput8 DLL to disable dinput devices to make this work. I'll double check later that this does indeed work in case I'm wrongly remembering.

Anyway, assuming it does work, would it be possible to harvest some of the logic used in that "blocker" DLL until wbemprox is properly implemented?

00cpxxx commented 7 years ago

Currently Aric Stewart is working hard in getting proper HID and proper enumeration support to devices, X360CE uses a similar approach to [1] where they catch the calls to wbemprox and change the controller in order for it to be detected by Xinput only.

[1] https://github.com/KoKuToru/koku-xinput-wine