Shop OBEX P1 Docs P2 Docs Learn Events
USB Gamepad Implementation - Page 2 — Parallax Forums

USB Gamepad Implementation

24

Comments

  • While messing with XInput support some more, I figured out why the PS3 pad won't work: you do loc ptra, #@dev_desc_buff, but I'm pretty sure it needs to be loc ptra, #dev_desc_buff

  • Also, another strange finding in that regard - If I skip reading the descriptor for the XInput device, it goes into an infinite initialization loop. If I overwrite the descriptor after reading it, that's fine (???)

  • @Wuerfel_21 said:
    While messing with XInput support some more, I figured out why the PS3 pad won't work: you do loc ptra, #@dev_desc_buff, but I'm pretty sure it needs to be loc ptra, #dev_desc_buff

    I think you are right, I have updated the package in the post.

    Also, another strange finding in that regard - If I skip reading the descriptor for the XInput device, it goes into an infinite initialization loop. If I overwrite the descriptor after reading it, that's fine (???)

    Sometimes it is just a variable that is expected to be filled or cleared by a function call that is no longer called in the chain. Also there is a bit of "messing" with ptra/ptrb reading and writing that expects things in the right order, instead of using the dedicated pointer variable...

  • Wuerfel_21Wuerfel_21 Posts: 4,374
    edited 2022-04-13 15:31

    Anyways, here's the special case decoding for XInput implemented. There's a few quirks that are handled:
    - Y axes are inverted (so down is positive)
    - dpad button to hat angle conversion (idk though, most applications probably prefer getting direction buttons)
    - ordering reported buttons to sorta match DInput de-facto standard
    - digital press threshold for analog triggers (note: can't test how well 192 actually works as a threshold since the only controller I can get to connect doesn't actually have analog triggers)

    New pads will allegedly show up tomorrow, one of which should support all XInput features (analog triggers, stick clicks, rumble, LEDs)

    Speaking of, how does HID rumble work? Must be a bit funny, because I think I always needed a dedicated driver to get it working on windows.

  • RaymanRayman Posts: 13,805

    Sounds like you have XBox XInput capable controllers working with P2?
    That's great!

    Is there a wireless one that works?
    Are you able to control the rumble from the P2?

  • @Rayman said:
    Sounds like you have XBox XInput capable controllers working with P2?
    That's great!

    Is there a wireless one that works?

    I have one (1) XInput device working, which in my case is an 8bitdo Retro Receiver (whose main purpose is actually to connect bluetooth controllers to SNES consoles (or a P1...), but for some reason also exposes a full analog XInput device over the firmware upgrade USB port), so I guess that means it's wireless. But I think any XInput device should work. If you have one, try it.

    Are you able to control the rumble from the P2?

    In theory yes, but I haven't tried implementing it.

  • @Wuerfel_21 said:
    Anyways, here's the special case decoding for XInput implemented. There's a few quirks that are handled:

    Excellent, thanks!
    Will post a new package soon.

    Speaking of, how does HID rumble work? Must be a bit funny, because I think I always needed a dedicated driver to get it working on windows.

    There are few sources to check, the aformentioned Circle framework has a XBox One driver looks to have a primitive support, and today I discovered this https://github.com/quantus/xbox-one-controller-protocol that describe the protocol.

    I think we can use a spin object to hold the gamepad data, so it would also be possible to use all 4 ports of your gamecube adapter, or use two USB ports.
    Maybe also move the decoding methods to that objects.

  • @macca said:

    Speaking of, how does HID rumble work? Must be a bit funny, because I think I always needed a dedicated driver to get it working on windows.

    There are few sources to check, the aformentioned Circle framework has a XBox One driver looks to have a primitive support, and today I discovered this https://github.com/quantus/xbox-one-controller-protocol that describe the protocol.

    >
    I meant rumble on regular HID devices.
    (Also, here's the XBox360 protocol description I wrote the decoder off of: https://www.partsnotincluded.com/understanding-the-xbox-360-wired-controllers-usb-data/ )

    I think we can use a spin object to hold the gamepad data, so it would also be possible to use all 4 ports of your gamecube adapter, or use two USB ports.
    Maybe also move the decoding methods to that objects.

    Hmm. I'd kinda like to move most of the decoding to the PASM driver, for that's what I'd need for megayume (wherein as-is the USB driver has the keyboard-to-megadrive mapping bolted into it so the Spin cog can be free to handle SRAM flushing)

  • roglohrogloh Posts: 5,122
    edited 2022-04-14 03:30

    @macca said:
    Ok, let's try this.

    Also @rogloh 's PS3 controller above should report something now.

    Just gave your newer version a go, same problem (tried on both my PS/3 controllers). If you provide a version that enables whatever USB debug logging you need to figure out why, I can test again.

    Mini Client + USB low/full speed keyboard/mouse/gamepad v0.1.4+r1
    Sysclock: 180000000, Clkmode: $10008FB, Baud: 2000000
    P2RevB+ detected, USB driver version v0.1.4+r1
    PortA started: cogID 1, event pin# 40
    PortA device idVendor=054C, idProduct=0268, bcdDevice=0200
    PortA unknown device
    PortA device disconnected
    
  • @rogloh said:
    Just gave your newer version a go, same problem (tried on both my PS/3 controllers). If you provide a version that enables whatever USB debug logging you need to figure out why, I can test again.

    You can enable spin2 debug, this should give some informations about the usb device. I'll try to figure out if there are some issue with sending the packet itself, like wrong memory pointers or something, but I fear that the unknown device comes before sending the enable packet.

  • I built using flexspin with debug -gbrk enabled (if that's what you meant) and I got this additional output if it helps. Wasn't much more really, just the class, subclass and protocol values.

    $ loadp2 -T -b 2000000 MiniKbMObjDemo.binary 
    ( Entering terminal mode.  Press Ctrl-] or Ctrl-Z to exit. )
    Cog0  INIT $0000_0000 $0000_0000 load
    Cog0  INIT $0000_0404 $0000_0000 load
    Mini Client + USB low/full speed keyboard/mouse/gamepad v0.1.4+r1
    Sysclock: 180000000, Clkmode: $10008FB, Baud: 2000000
    Cog1  INIT $0000_3868 $0000_53E4 load
    P2RevB+ detected, USB driver version v0.1.4+r1
    PortA started: cogID 1, event pin# 40
    Cog1  class=$03, subclass=$00, protocol=$00
    PortA device idVendor=054C, idProduct=0268, bcdDevice=0200
    PortA unknown device
    PortA device disconnected
    
  • @rogloh said:
    I built using flexspin with debug -gbrk enabled (if that's what you meant) and I got this additional output if it helps. Wasn't much more really, just the class, subclass and protocol values.

    Yes, but that was enough, I figured out what's wrong.

    I forgot that my gamepad is actually a dual-mode pad, standard and PS3 ! Need to keep a button pressed while connecting to enable PS3 mode and this allowed me to reproduce and fix the issue.

    The USB driver assumed that the first endpoint was the IN endpoint, but I think this can't be assumed, so the fix was to continue the search for the correct endpoint. This may also fix other devices, I don't remember if there were problems with some keyboards or mouse, it is worth to try if now are working (this fix is not specific for gamepads).

    There was another issue sending the LEDs message that needs some investigation and is now disabled, also the report size is huge (49 bytes) and some bytes appears to change everytime so it always notify the updates, had to reduce the comparison to the first 10 byes which are the significat bytes. Need some flags for all these exceptions...

    @Wuerfel_21 check that this hasn't disrupted your Xinput code, please.

  • @macca said:

    There was another issue sending the LEDs message that needs some investigation and is now disabled, also the report size is huge (49 bytes) and some bytes appears to change everytime so it always notify the updates, had to reduce the comparison to the first 10 byes which are the significat bytes. Need some flags for all these exceptions...

    @Wuerfel_21 check that this hasn't disrupted your Xinput code, please.

    Yep, still works great.

    I guess all the noisy extra data in the PS3 report is gyro/accelerometer data?

  • maccamacca Posts: 708
    edited 2022-04-14 10:20

    @Wuerfel_21 said:
    Yep, still works great.

    Ok, good!

    I guess all the noisy extra data in the PS3 report is gyro/accelerometer data?

    Maybe, I haven't investigated... there 48 39 bytes defined as "Pointer" in the report (total size is 49 or 50 bytes, depending on don't know what... but if 50 the first byte must be skipped...).

    Anyway, this comparison is needed now for debugging, once the driver works fairly good, it can notify reports continuosly.

  • RaymanRayman Posts: 13,805

    So this is working in both the Xbox xinput mode and PS3 mode?

  • @Rayman said:
    So this is working in both the Xbox xinput mode and PS3 mode?

    Yes.

  • Just realized I have yet another controller available, a Speedlink SL-6698 force feedback steering wheel. (No, I don't know why I have so many Speedlink products)
    Sadly, it's another case of a virtual USB hub inside, but luckily it also has a Gamecube (and PS2 and Xboxhueg) end, so I guess it works that way.

  • @macca said:

    @rogloh said:
    I built using flexspin with debug -gbrk enabled (if that's what you meant) and I got this additional output if it helps. Wasn't much more really, just the class, subclass and protocol values.

    Yes, but that was enough, I figured out what's wrong.

    I forgot that my gamepad is actually a dual-mode pad, standard and PS3 ! Need to keep a button pressed while connecting to enable PS3 mode and this allowed me to reproduce and fix the issue.

    The USB driver assumed that the first endpoint was the IN endpoint, but I think this can't be assumed, so the fix was to continue the search for the correct endpoint. This may also fix other devices, I don't remember if there were problems with some keyboards or mouse, it is worth to try if now are working (this fix is not specific for gamepads).

    There was another issue sending the LEDs message that needs some investigation and is now disabled, also the report size is huge (49 bytes) and some bytes appears to change everytime so it always notify the updates, had to reduce the comparison to the first 10 byes which are the significat bytes. Need some flags for all these exceptions...

    @Wuerfel_21 check that this hasn't disrupted your Xinput code, please.

    Fantastic. This one worked nicely on the PS3 controller. Great to see all the 17 buttons and dual joystick XY axes working on this controller and the P2. Cheers! :smile:

    PS. I also have this little IR remote thing and it sort of works sporadically too acting as some gamepad switches etc but occasionally it disconnects from USB and reconnects. Might be bad batteries, as I've had it sitting around for ages not doing anything. Not caring much about it. The proper PS3 controller is what I'm interested in.
    https://www.mightyape.com.au/product/futuretronics-ps3-mini-remote-ps3/1559875

  • Okay, new pads I ordered arrived.

    The retrobit SEGA Saturn controller just works, in both HID and XInput modes, but HID mode gets the order of the axes wrong (I think @macca alluded to that issue before). I think it tries to imitate a Switch pro controller, so those will likely have the same issue. Will post descriptor later, don't have time RN.

    The 8bitdo SN30 USB is super busted. It seems to try some weird scheme to figure out wether to use XInput or HID mode. Holding X or Y on power-up forces it into either mode, but regardless, it doesn't actually seem to send any data. However, plugging it into my PC runs into the same issue (detects correctly, but no data is sent), soooooo, uhhhhhhh.... It does work on the Linux laptop! Yay Linux! But ye, shame, as the buttons feel really nice on this one.

  • Okay, so about the Saturn pad:

    Here's connecting it and pushing up once:

    Cog1  class=$03, subclass=$00, protocol=$00
    Cog1  Report Desc. $05, $01, $09, $04, $A1, $01, $A1, $02, $75, $08, $95, $05, $15, $00, $26, $FF, $00, $35, $00, $46, $FF, $00, $09, $30, $09, $30, $09, $30, $09, $30, $09, $31, $81, $02, $75, $04, $95, $01, $25, $07, $46, $3B, $01, $65, $14, $09, $00, $81, $42, $65, $00, $75, $01, $95, $0A, $25, $01, $45, $01, $05, $09, $19, $01, $29, $0A, $81, $02, $06, $00, $FF, $75, $01, $95, $0A, $25, $01, $45, $01, $09, $01, $81, $02, $C0, $A1, $02, $75, $08, $95, $04, $46, $FF, $00, $26, $FF, $00, $09, $02, $91, $02, $C0, $C0
    P2RevB+ detected, USB driver version v0.1.4+r1
    PortA started: cogID 1, event pin# 16
    PortA device idVendor=0079, idProduct=0011, bcdDevice=0200
    PortA gamepad configured, 5 axes, 0 hats, 10 buttons
    PortA [01 80 80 80 80 00 00 00] axes [1 128 128 128 128] hats [] btn [0000000000]
    PortA [01 80 80 80 00 00 00 00] axes [1 128 128 128 0] hats [] btn [0000000000]
    PortA [01 80 80 80 80 00 00 00] axes [1 128 128 128 128] hats [] btn [0000000000]
    

    As you can see, the Y axis comes out as the 5th axis (X as the 4th).

    Anyways, good controller.


    (Pictured: "Research" on adding a 9th cog to the P2 for increased gaming strength)


    Speaking of, the 8bitdo is very much a bad controller. Still unsuccessful at getting it under Windows even. But some observations:
    - If I force it into HID mode by holding Y, it also doesn't work under Linux
    - It seems to always use HID mode on Windows for some reason, even if I hold X. (WTF? I think working on Windows is like the entire reason this has an XInput mode)
    - I tried to see if sending it an LED set message will make it work (as Linux seems to set all the LEDs on, whereas on Win and P2, the Player 1 LED is lit), but I think I did it wrong and it just got stuck in a loop of configuring the device. @macca wanna try? It should send an OUT packet with the contents $01,$03,$03 (Set Player 2 LED) to the same endpoint that the input data comes from.

  • @Wuerfel_21 said:
    Okay, so about the Saturn pad:

    [...]

    PortA [01 80 80 80 80 00 00 00] axes [1 128 128 128 128] hats [] btn [0000000000]
    PortA [01 80 80 80 00 00 00 00] axes [1 128 128 128 0] hats [] btn [0000000000]
    PortA [01 80 80 80 80 00 00 00] axes [1 128 128 128 128] hats [] btn [0000000000]
    ```
    As you can see, the Y axis comes out as the 5th axis (X as the 4th).

    Interesting... the descriptor defines 5 axis but, from the picture, it appears to only have two...

    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x31,        //     Usage (Y)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    

    By setting the usage of the first 4 as X I guess that only the last two are the actual axis, right ?
    If that's true, maybe the idea I had to sort them may work... need to do some tests...

    Speaking of, the 8bitdo is very much a bad controller. Still unsuccessful at getting it under Windows even. But some observations:

    Did some searches on that controller, to know more, it appears to have a firmware update software, maybe it is worth a try ?

    • If I force it into HID mode by holding Y, it also doesn't work under Linux
    • It seems to always use HID mode on Windows for some reason, even if I hold X. (WTF? I think working on Windows is like the entire reason this has an XInput mode)

    From the searches I did, I understand that it has some "intelligence" to configure itself based on what is connected to... maybe it needs some teaching... :)

    • I tried to see if sending it an LED set message will make it work (as Linux seems to set all the LEDs on, whereas on Win and P2, the Player 1 LED is lit), but I think I did it wrong and it just got stuck in a loop of configuring the device. @macca wanna try? It should send an OUT packet with the contents $01,$03,$03 (Set Player 2 LED) to the same endpoint that the input data comes from.

    Hmm... if you tried the PS3 LED code, maybe try to change

    wrword  ##(TYPE_OUTPUT << 8) | $01, ptra[wValue]
    with
    wrword  ##(TYPE_OUTPUT << 8), ptra[wValue]
    

    See hset_kbdled_report.
    It should not loop anyway if you then jump to .notify_client

  • @macca said:

    @Wuerfel_21 said:
    Okay, so about the Saturn pad:

    [...]

    PortA [01 80 80 80 80 00 00 00] axes [1 128 128 128 128] hats [] btn [0000000000]
    PortA [01 80 80 80 00 00 00 00] axes [1 128 128 128 0] hats [] btn [0000000000]
    PortA [01 80 80 80 80 00 00 00] axes [1 128 128 128 128] hats [] btn [0000000000]
    ```
    As you can see, the Y axis comes out as the 5th axis (X as the 4th).

    Interesting... the descriptor defines 5 axis but, from the picture, it appears to only have two...

    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x31,        //     Usage (Y)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    

    By setting the usage of the first 4 as X I guess that only the last two are the actual axis, right ?
    If that's true, maybe the idea I had to sort them may work... need to do some tests...

    Oh wow, that's weird. Interestingly, it shows up with 4 axes on Windows, whereas Linux correctly detects that it really only has 2 (and in ideal world it'd have zero and a hat switch instead, but yet we are still haunted by the legacy of the gameport)

    Speaking of, the 8bitdo is very much a bad controller. Still unsuccessful at getting it under Windows even. But some observations:

    Did some searches on that controller, to know more, it appears to have a firmware update software, maybe it is worth a try ?

    Was already at the latest FW version, but flashed it, anyways. This one actually doesn't use the software, you hold L+R during power-up and it enumerates as a mass storage device and you copy the firmware onto it. Rather odd, but kinda cool, nicer than a proprietary flashing software.

    • If I force it into HID mode by holding Y, it also doesn't work under Linux
    • It seems to always use HID mode on Windows for some reason, even if I hold X. (WTF? I think working on Windows is like the entire reason this has an XInput mode)

    From the searches I did, I understand that it has some "intelligence" to configure itself based on what is connected to... maybe it needs some teaching... :)

    Yea, if you don't hold anything it'll do its autodetect thing. Looks like this (note: sometimes it also starts out in HID mode and only re-connects once. It always ends up in XInput mode...

    Cog0  INIT $0000_0000 $0000_0000 load
    Cog0  INIT $0000_0404 $0000_0000 load
    Mini Client + USB low/full speed keyboard/mouse/gamepad v0.1.4+r1
    Sysclock: 180000000, Clkmode: $10008FB, Baud: 2000000
    Cog1  INIT $0000_3970 $0000_5528 load
    P2RevB+ detected, USB driver version v0.1.4+r1
    PortA started: cogID 1, event pin# 16
    Cog1  class=$FF, subclass=$5D, protocol=$01
    Cog1  class=$FF, subclass=$5D, protocol=$03
    Cog1  class=$FF, subclass=$5D, protocol=$02
    Cog1  class=$FF, subclass=$FD, protocol=$13
    Cog1  Report Desc. $05, $01, $09, $05, $A1, $01, $A1, $00, $09, $30, $09, $31, $15, $00, $26, $FF, $FF, $35, $00, $46, $FF, $FF, $95, $02, $75, $10, $81, $02, $C0, $A1, $00, $09, $33, $09, $34, $15, $00, $26, $FF, $FF, $35, $00, $46, $FF, $FF, $95, $02, $75, $10, $81, $02, $C0, $A1, $00, $09, $32, $15, $00, $26, $FF, $FF, $35, $00, $46, $FF, $FF, $95, $01, $75, $10, $81, $02, $C0, $05, $09, $19, $01, $29, $0A, $95, $0A, $75, $01, $81, $02, $05, $01, $09, $39, $15, $01, $25, $08, $35, $00, $46, $3B, $10, $66, $0E, $00, $75, $04, $95, $01, $81, $42, $75, $02, $95, $01, $81, $03, $75, $08, $95, $02, $81, $03, $C0
    PortA device idVendor=045E, idProduct=028E, bcdDevice=0200
    PortA gamepad configured, 6 axes, 1 hats, 13 buttons
    
    PortA device disconnected
    Cog1  class=$03, subclass=$00, protocol=$00
    Cog1  Report Desc. $05, $01, $15, $00, $09, $04, $A1, $01, $85, $30, $05, $01, $05, $09, $19, $01, $29, $0A, $15, $00, $25, $01, $75, $01, $95, $0A, $55, $00, $65, $00, $81, $02, $05, $09, $19, $0B, $29, $0E, $15, $00, $25, $01, $75, $01, $95, $04, $81, $02, $75, $01, $95, $02, $81, $03, $0B, $01, $00, $01, $00, $A1, $00, $0B, $30, $00, $01, $00, $0B, $31, $00, $01, $00, $0B, $32, $00, $01, $00, $0B, $35, $00, $01, $00, $15, $00, $27, $FF, $FF, $00, $00, $75, $10, $95, $04, $81, $02, $C0, $0B, $39, $00, $01, $00, $15, $00, $25, $07, $35, $00, $46, $3B, $01, $65, $14, $75, $04, $95, $01, $81, $02, $05, $09, $19, $0F, $29, $12, $15, $00, $25, $01, $75, $01, $95, $04, $81, $02, $75, $08, $95, $34, $81, $03, $06, $00, $FF, $85, $21, $09, $01, $75, $08, $95, $3F, $81, $03, $85, $81, $09, $02, $75, $08, $95, $3F, $81, $03, $85, $01, $09, $03, $75, $08, $95, $3F, $91, $83, $85, $10, $09, $04, $75, $08, $95, $3F, $91, $83, $85, $80, $09, $05, $75, $08, $95, $3F, $91, $83, $85, $82, $09, $06, $75, $08, $95, $3F, $91, $83, $C0
    PortA device idVendor=057E, idProduct=2009, bcdDevice=0200
    PortA gamepad configured, 0 axes, 0 hats, 18 buttons
    
    PortA device disconnected
    Cog1  class=$FF, subclass=$5D, protocol=$01
    Cog1  class=$FF, subclass=$5D, protocol=$03
    Cog1  class=$FF, subclass=$5D, protocol=$02
    Cog1  class=$FF, subclass=$FD, protocol=$13
    Cog1  Report Desc. $05, $01, $09, $05, $A1, $01, $A1, $00, $09, $30, $09, $31, $15, $00, $26, $FF, $FF, $35, $00, $46, $FF, $FF, $95, $02, $75, $10, $81, $02, $C0, $A1, $00, $09, $33, $09, $34, $15, $00, $26, $FF, $FF, $35, $00, $46, $FF, $FF, $95, $02, $75, $10, $81, $02, $C0, $A1, $00, $09, $32, $15, $00, $26, $FF, $FF, $35, $00, $46, $FF, $FF, $95, $01, $75, $10, $81, $02, $C0, $05, $09, $19, $01, $29, $0A, $95, $0A, $75, $01, $81, $02, $05, $01, $09, $39, $15, $01, $25, $08, $35, $00, $46, $3B, $10, $66, $0E, $00, $75, $04, $95, $01, $81, $42, $75, $02, $95, $01, $81, $03, $75, $08, $95, $02, $81, $03, $C0
    PortA device idVendor=045E, idProduct=028E, bcdDevice=0200
    PortA gamepad configured, 6 axes, 1 hats, 13 buttons
    
    

    So it seems to correctly initialize, but doesn't actually send through any data. (same issue as the Windows PC)

    Also might want to investigate what is going on with that descriptor ("0 axes, 0 hats, 18 buttons"???).

    • I tried to see if sending it an LED set message will make it work (as Linux seems to set all the LEDs on, whereas on Win and P2, the Player 1 LED is lit), but I think I did it wrong and it just got stuck in a loop of configuring the device. @macca wanna try? It should send an OUT packet with the contents $01,$03,$03 (Set Player 2 LED) to the same endpoint that the input data comes from.

    Hmm... if you tried the PS3 LED code, maybe try to change

    wrword  ##(TYPE_OUTPUT << 8) | $01, ptra[wValue]
    with
    wrword  ##(TYPE_OUTPUT << 8), ptra[wValue]
    

    See hset_kbdled_report.
    It should not loop anyway if you then jump to .notify_client

    No, I didn't try the PS3 code, I tried something much dumber. Will try again, I guess.

  • Wuerfel_21Wuerfel_21 Posts: 4,374
    edited 2022-04-14 22:08

    ehhh, no dice.

                     rdbyte  htmp, gp_intf_num_p
                     loc     ptra, #set_report
                     wrword  ##(TYPE_OUTPUT << 8), ptra[wValue]
                     wrword  htmp, ptra[wIndex]
                     wrword  #3, ptra[wLength]
                     loc     pb, #xinput_led_cmd             ' set LEDs
                     call    #control_write
    

    this just hangs it until I unplug it (or it unplugs itself during the autodetect sequence). It doesn't hang the Retro Receiver or the Saturn pad, but those don't have LEDs, so IDK if it actually works.

    Sigh... Time to get a proper Xbox360-style pad (probably a cheapo one, since the real wired 360 pads are a bit expenso on ebay)

    EDIT: Also, I tried flashing an older firmware to the controller, but that didn't really do anything (It did successfully flash it, I checked).

    EDIT 2: WAIT IT DOES NOW WORK ON WINDOWS. What? How? I tried it immediately after the downgrade and it didn't do it. Connects in XInput mode and, well, just works. Still not on P2.

  • @Wuerfel_21 said:
    ehhh, no dice.

    Ok, tried to send the message to my controller, it doesn't light the leds but had an interesting effect (later), maybe you just need to send more than 3 bytes, try with:

                    rdbyte  htmp, gp_intf_num_p
                    loc     ptra, #set_report
                    wrword  ##(TYPE_OUTPUT << 8), ptra[wValue] ' Byte1 report type, byte0 reportID (0)
                    wrword  htmp, ptra[wIndex]
                    wrword  #8, ptra[wLength]
                    loc     pb, #@led_cmd
                    call    #control_write                  ' Execute ControlWrite(SET_REPORT) and back to caller
    
    led_cmd         byte    $01, $03, $03, $00, $00, $00, $00, $00
    

    This sends 8 bytes, place the code in .gamepad_config after reading the report descriptor.
    If you have some documentation about it I can try to see if there is something else to do.

    About the interesting effect: you asked how to enable rumble in HID controllers ?
    Well, it turned out that sending just the above message turned the motors on with my dual mode controller in HID mode :)
    I'm not sure but seems the that value of the first 2 or 3 bytes defines the intensity (with FF, FF, FF the controller walked by itself on the desk), 0 turns it off.
    I don't think it follows the PS3 scheme, because the "low" setting, AFAIK, actually is very high...

    EDIT 2: WAIT IT DOES NOW WORK ON WINDOWS. What? How? I tried it immediately after the downgrade and it didn't do it. Connects in XInput mode and, well, just works. Still not on P2.

    Told you, it needs some teaching :)

  • maccamacca Posts: 708
    edited 2022-04-15 09:14

    I think I have found a solution for the axis sort issue.
    Instead of trying to place the axis sequentially, the decoder now uses the usage setting to set the value in the expected place, so now the 6 axis elements are X, Y, Z, RX, RY and RZ (and are displayed all for debug purposes). There is an additional variable axes that defines, as a bitfield, what axes are actually defined, the application software can use HAS_X, HAS_Y, etc. to check if the value is valid.
    This for HID controllers, XInput have its own dedicated decoder so the application already know how to read the data.
    The connection message now display also the controller type.

    Speaking of dedicated decoders, I have added flags to define the kind of device that was detected so both the driver and the application software can take the appropriate actions. The byte[portptr][CON_FLGS] defines, as a bitfield, the detected device: GPCONF (HID gamepad), XINPCONF or PS3CONF (as well as the old KBCONF and MCONF for keyboard and mouse). The driver has the variable hdev_ready where the KB_READY, M_READY, KBM_READY, GP_READY, XINPUT_READY, PS3_READY value is set.

  • Wuerfel_21Wuerfel_21 Posts: 4,374
    edited 2022-04-15 08:56

    You've busted the XInput. The argument to the decodeXInput function I wrote is supposed to be the report data pointer and you're passing in the port pointer. Also, it should probably set axes. Speaking of, all the dual stick devices seem to use Z/RZ for the right stick's X/Y, so the XInput decoder should put it there, too. (And thus the triggers become RX/RY? That'd match the gamecube adapter (don't have anything else that reports analog trigger data))

    Should probably also record the range for each axis (or normalize it to 16 bit signed or smth while decoding)

  • (Also, before I forget, there were some trailing comma issues again. Perhaps helpful link.)

  • @Wuerfel_21 said:
    You've busted the XInput. The argument to the decodeXInput function I wrote is supposed to be the report data pointer and you're passing in the port pointer.

    Ops... sorry, updated.

    Also, it should probably set axes. Speaking of, all the dual stick devices seem to use Z/RZ for the right stick's X/Y, so the XInput decoder should put it there, too. (And thus the triggers become RX/RY? That'd match the gamecube adapter (don't have anything else that reports analog trigger data))

    Well, I haven't set axes because the they are not assigned in the "standard" way. This depends on what Xinput consider standard, since it can be detected by the application software it already know where they are, bit if you want to make it somewhat standard, then yes, probably Z/RX for the right stick is correct. There is also the buttons order that I'm not sure it matches something else, so the application should check the device type anyway.

    Should probably also record the range for each axis (or normalize it to 16 bit signed or smth while decoding)

    Yes, that's another thing to do.

    (Also, before I forget, there were some trailing comma issues again. Perhaps helpful link.)

    Should be fixed, my compiler is a bit less susceptible to these things... sometimes a bit too less (needs some work...).
    Funny thing: spinner2 (Linux) loops infinitely with "Opening jm_serial.spin2"...

  • @macca said:

    @Wuerfel_21 said:
    ehhh, no dice.

    Ok, tried to send the message to my controller, it doesn't light the leds but had an interesting effect (later), maybe you just need to send more than 3 bytes, try with:

                    rdbyte  htmp, gp_intf_num_p
                    loc     ptra, #set_report
                    wrword  ##(TYPE_OUTPUT << 8), ptra[wValue] ' Byte1 report type, byte0 reportID (0)
                    wrword  htmp, ptra[wIndex]
                    wrword  #8, ptra[wLength]
                    loc     pb, #@led_cmd
                    call    #control_write                  ' Execute ControlWrite(SET_REPORT) and back to caller
    
    led_cmd         byte    $01, $03, $03, $00, $00, $00, $00, $00
    

    This sends 8 bytes, place the code in .gamepad_config after reading the report descriptor.
    If you have some documentation about it I can try to see if there is something else to do.

    Same effect, just hangs on the SN30Pro and doesn't affect anything else (can't tell if it the command is valid because as said, I don't have anything else that responds to XInput LED commands to begin with)

    About the interesting effect: you asked how to enable rumble in HID controllers ?
    Well, it turned out that sending just the above message turned the motors on with my dual mode controller in HID mode :)
    I'm not sure but seems the that value of the first 2 or 3 bytes defines the intensity (with FF, FF, FF the controller walked by itself on the desk), 0 turns it off.
    I don't think it follows the PS3 scheme, because the "low" setting, AFAIK, actually is very high...

    Hmm, as far as I've been able to figure out, it's effectively device specific for HID. XInput rumble is standard, see earlier link. Need to find a controller that has rumble and that actually works though.

    EDIT 2: WAIT IT DOES NOW WORK ON WINDOWS. What? How? I tried it immediately after the downgrade and it didn't do it. Connects in XInput mode and, well, just works. Still not on P2.

    Told you, it needs some teaching :)

    Yep. Funnily enough, I wrote an email to customer support and got the amazing reply of "Win7 does not support XInput", which aside from being patently untrue contradicts the controller's manual explicitly claiming that it supports "Windows 7 or above" (Though something tells me it probably also works on XP, I think the XInput device driver is the same.)

    @macca said:

    Also, it should probably set axes. Speaking of, all the dual stick devices seem to use Z/RZ for the right stick's X/Y, so the XInput decoder should put it there, too. (And thus the triggers become RX/RY? That'd match the gamecube adapter (don't have anything else that reports analog trigger data))

    Well, I haven't set axes because the they are not assigned in the "standard" way. This depends on what Xinput consider standard, since it can be detected by the application software it already know where they are, bit if you want to make it somewhat standard, then yes, probably Z/RX for the right stick is correct. There is also the buttons order that I'm not sure it matches something else, so the application should check the device type anyway.

    Ye, it'd be better if the application doesn't have to think very much about pad differences. The axes in XInput don't really have a defined order. They just are. The HID-shaped shim Windows creates for XInput devices seems to map the right stick to RX/RY, but that also doesn't follow the universal standard of button 10 being start (and has a number of other stupid quirks), so I wouldn't place much value on that. I've tried all the HID gamepads on hand and they all use Z/ZR so that's where the XInput axes should go IMO

    (Also, before I forget, there were some trailing comma issues again. Perhaps helpful link.)

    Should be fixed, my compiler is a bit less susceptible to these things... sometimes a bit too less (needs some work...).
    Funny thing: spinner2 (Linux) loops infinitely with "Opening jm_serial.spin2"...

    uhhhhhhhhhhhhhhhhhhhhhh..... oopsie?

  • Wuerfel_21Wuerfel_21 Posts: 4,374
    edited 2022-04-15 10:07

    @Wuerfel_21 said:

    Should be fixed, my compiler is a bit less susceptible to these things... sometimes a bit too less (needs some work...).
    Funny thing: spinner2 (Linux) loops infinitely with "Opening jm_serial.spin2"...

    uhhhhhhhhhhhhhhhhhhhhhh..... oopsie?

    Indeed, very stupid issue. Have fixed it in git, try building. Will see if I can updated binaries, but I can't guarantee that my PC won't explode from booting the Linux VM (which is where I think I pulled the linux binary from last time? IDK it's been a while)

    EDIT: gotem, despite the computer exploding in the process.

Sign In or Register to comment.