procount / pinn

An enhanced Operating System installer for the Raspberry Pi
1.12k stars 123 forks source link

Add support for gamepad selection of OS #2

Closed colinchilds closed 4 years ago

colinchilds commented 8 years ago

For those of us who have Retropie installed, it would be awesome to be able to select the OS to boot into using the gamepad already plugged into the device, rather than having to plug in a keyboard or mouse.

procount commented 4 years ago

Sorry, it's been a while since I did this so I have to remember.... :wink: Did I put jstest in PINN? Or are you using it in Raspbian? If the xboxdrv detects your gamepad it should announce the type and capabilities in the debug log.

Norde commented 4 years ago

I understand, no problem :) But the fact that I misspoke didn't help ^^'

You've put jstest in joystick test release (33h here). In debug log only a "No joystick found" appears. Yet my gamepad device entry is under /dev/input/js0. When using jstest nothing more appears in the debug.

lurch commented 4 years ago

If the controller has a battery, then I'm guessing it's a wireless controller, which (presumably) connects to a special receiver USB dongle? I know noting about Xboxes :wink:

Perhaps there's a delay between the controller and/or the dongle powering up (you mentioned "not paired" earlier), and this delay is causing PINN to not see any joysticks when it tries looking for them? :man_shrugging: :man_shrugging:

Norde commented 4 years ago

There's no special usb dongle. The controller has native bluetooth and a usb port for wire connexion.

But you're right, there's a little delay between cable connection/powerup of the controller and the "ready status".

procount commented 4 years ago

What is the output from lsusb when your joystick is attached?

Norde commented 4 years ago

Bus 001 Devices 005: ID 0a12:0001 Bus 001 Devices 001: ID 1d6b:0002 Bus 001 Devices 009: ID 045e:02ea<- joystick (xbox one s controller) Bus 001 Devices 003: ID 0424:2514 Bus 001 Devices 002: ID 0424:2514 Bus 001 Devices 007: ID 0424:7800 Bus 001 Devices 004: ID 046d:c316

I've the got same output wether joystick is "charging" or "connected" (obtained after running jstest) state (only joystick Devices number change).

lurch commented 4 years ago

I think the Device number changing indicates that (from the Linux-side of the USB connection) the device appears to have been removed and reconnected (i.e. it's re-enumerated itself when the jstest switches its state).

It might be interesting to get the lsusb -v -d 045e:02ea output in both the "charging" and "connected" states?

procount commented 4 years ago

You'll get more comprehensive results from lsusb in Raspbian. The PINN version is rather limited. But it's enough to confirm that your controller should be supported:

0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE

So maybe it is a timing issue. I'll have to try re-establishing the joystick later on in the process, somehow....

Norde commented 4 years ago

I can't reproduce this bug under raspbian (the xbox one s controller is directly recognized, never only in "charging" state).

And I don't have enough knowledge yet to properly add a complete lsusb/usbutils to Pinn's buildroot, sorry :/

lurch commented 4 years ago

I didn't realise that lsusb in PINN is a limited version. Sorry for adding confusion to the conversation :confused:

procount commented 4 years ago

Not at all. I was going to ask for PID:VID anyway... lsusb symlinks to a busybox implementation in PINN.

procount commented 4 years ago

@Norde - I put a new beta version up on sourceforge at https://sourceforge.net/projects/pinn/files/testing/pinn-332b.zip/download

It repeatedly tries looking for a joystick over the first 30 seconds or so. Don't know if it will fix your problem, so please give it a go and let me know if it is any better.

The other minor change is that '+' and '-' keys on the main recovery menu will change the font size, although it is far from perfect yet.

Norde commented 4 years ago

@procount - This fix the problem for Xbox One S gamepad (and certainly for all the other gamepad with a connection delay), thanks a lot !

'+' and '-' keys works well. Although there's some text collision (for the "volume installation" area at the bottom of the recovery menu window)

However there is another problem with the Xbox One S gamepad (and maybe others too): the mouse is uncontrollable with analog sticks.

It's due to the behavior of analog sticks: They return a value different from 0 when they are in their initial position (checked under jstest). This value changes after each use of the joystick (probably due to small mechanical inaccuracies when returning to initial position) and seems to go from -2500 to +2500. The only way to avoid this problem is therefore to ignore the values between -3000 and -3000 (maybe 4000 to be sure).

procount commented 4 years ago

That's great to hear. How long does it take for the Joystick to be recognised? (Maybe you can take a look at /tmp/debug and see how many "Joystick not found" messages there are?)

The font size is just an experiment. It needs to be smarter.

I've not been able to try any analog joysticks because I don't have any, so it was just a guess. I will add some deadband in the middle and maybe you can help me parameterise it. I think I built in some calibration settings in the joy_keys.json file, so maybe I can add the deadband to that.

Norde commented 4 years ago

It's almost instantaneous. Only one "No Joystick found" in /tmp/debug and the controller is recognized just after "new drive selected" event.

Built in deadband calibration settings in the joy_keys.json file is a good idea. So everyone can adapt the deadband according to the used gamepad 👍

For the font size what type of graphical interface are you using? (depending on the limitations I can offer a redesigned graphical interface, but I think that PINN is not intended to embed an advanced graphical server)

procount commented 4 years ago

OK. I'll try some adaptions for the analog joystick so you can try them out.

NOOBS & PINN are based on Qt4.8. There are more capabilities in Qt5, but I'm not in a position to change to that yet.

procount commented 4 years ago

Actually, if you can edit joy_keys.json, just change the line: "threshold": 1, to "threshold": 3000, and it should give you the deadband you need.

Norde commented 4 years ago

It's works well, thanks :)

I just have strange behavior with the cursor. Sometimes it goes in one direction (with progressive acceleration). It cannot be canceled (using the analog stick in the opposite direction only blocks the cursor until we release the stick). You must wait until the cursor has reached one end of the screen to regain control.

Nothing in the values obtained under jstest or displacement method in "joystick.cpp" can explain this. I'll investigate further.

procount commented 4 years ago

Maybe PINN is not processing joystick analog events fast enough so they are building up in a queue. I'm not quite sure why it would be much slower than using a digital joystick though. I'll look into it.

Norde commented 4 years ago

This seems to be a good guess since this bug only occurs during a long press on the analog stick.

The difference may be due to the fact that an analog stick sends multiple values ​​(often on several axes) whereas a digital pad sends only one value on a single axis 😶

lurch commented 4 years ago

Sometimes it goes in one direction (with progressive acceleration). It cannot be canceled (using the analog stick in the opposite direction only blocks the cursor until we release the stick). You must wait until the cursor has reached one end of the screen to regain control.

This seems to be a good guess since this bug only occurs during a long press on the analog stick.

IIRC I used to get similar behaviour with the 'nipple mouse' joystick on a Windows7 Lenovo Thinkpad laptop I had. IIRC it was something to do with the zero-point auto-calibration getting confused when the joystick was held in the same direction for "too long" (which made the mouse cursor appear to move by itself), and (similarly) the only workaround was to not touch the joystick at all for a couple of seconds, and then it "sorted itself out" and started working again properly.