Author Topic: _DEVICES and joystick glitched?  (Read 1099 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3206
    • Steve’s QB64 Archive Forum
_DEVICES and joystick glitched?
« on: November 26, 2020, 07:42:06 AM »
A little test code:

Code: QB64: [Select]
  1.     PRINT TIME$; " event -->";
  2.     Dev = _DEVICES
  3.     IF _DEVICEINPUT = 3 THEN
  4.         change = 0
  5.         IF _BUTTON(1) <> 0 THEN PRINT "BUTTON PUSHED": END
  6.         FOR i = 1 TO _LASTAXIS
  7.             IF _AXIS(i) <> 0 THEN
  8.                 change = SGN(_AXIS(i))
  9.                 PRINT "AXIS "; i; " changed"
  10.                 EXIT FOR
  11.             END IF
  12.         NEXT
  13.     ELSE
  14.         PRINT
  15.     END IF
  16.     _LIMIT 1

Now, without move any of the joysticks or directional pads, just click the buttons on your joystick.

The results I'm getting here are making this type routine worthless for my needs.  When I press the button, I get a result saying "AXIS 2 changed", rather than "BUTTON pushed". 

Anyone else able to duplicate this result, or should I look into investing in a new joystick, hoping that the one I have is glitching out?   It's older than heck, so I'm hoping the problem is with it and not with _DEVICES itself.  (Though I do know that _DEVICES is broken badly when it comes to keyboard responses, I thought it at least worked with joysticks for us??)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Cobalt

  • Forum Resident
  • Posts: 708
  • At 60 I become highly radioactive!
Re: _DEVICES and joystick glitched?
« Reply #1 on: November 26, 2020, 04:17:00 PM »
While working on the controls for Dragon Warrior Fellippe introduced me to a joystick that used button input for directions rather than axis.

Not sure if thats relevant to your situation but thought I might share.
Granted after becoming radioactive I only have a half-life!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1628
Re: _DEVICES and joystick glitched?
« Reply #2 on: November 27, 2020, 03:52:23 AM »
Hi Steve
here my two cents
I try the code on notebook Toshiba Windows 10 64 bits  QB64 1.4 64 bits  and as joystick a Geneic USB Wired Gamepad Joystick you can see the image here   https://www.amazon.it/Joystick-Vibrazione-Controller-Maniglia-Computer/dp/B08KHLF28S/ref=asc_df_B08KHLF28S/?tag=googshopit-21&linkCode=df0&hvadid=459286697270&hvpos=&hvnetw=g&hvrand=489339906717881003&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1008758&hvtargid=pla-1059099773167&psc=1

and these are the results
 


So as you can see the code recognizes button 1 but the other 3 button have been seen both as axis 1 both as button

 

with this code
Code: QB64: [Select]
  1.     PRINT TIME$; " event -->";
  2.     Dev = _DEVICES
  3.     IF _DEVICEINPUT = 3 THEN
  4.         change = 0
  5.         IF _BUTTON(1) <> 0 THEN PRINT "BUTTON PUSHED": END
  6.         IF _BUTTON(2) <> 0 THEN PRINT "Button 2"
  7.         IF _BUTTON(3) <> 0 THEN PRINT "button 3"
  8.         IF _BUTTON(4) <> 0 THEN PRINT "Button 4"
  9.         FOR i = 1 TO _LASTAXIS
  10.             IF _AXIS(i) <> 0 THEN
  11.                 change = SGN(_AXIS(i))
  12.                 PRINT "AXIS "; i; " changed"
  13.                 EXIT FOR
  14.             END IF
  15.         NEXT
  16.     ELSE
  17.         PRINT
  18.     END IF
  19.     _LIMIT 1
  20.  

What kind of joystick are you using?
If you find interesting I can test the code from into Ubuntu on VM.
Programming isn't difficult, only it's  consuming time and coffee

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3206
    • Steve’s QB64 Archive Forum
Re: _DEVICES and joystick glitched?
« Reply #3 on: November 27, 2020, 04:26:45 AM »
You’re getting the same results I was, Richard.  Pressing a button registers as an axis change, which it shouldn’t.  (At least it shouldn’t, in my opinion.). Your axis is the left joystick (or D-pad, depending on settings), and have nothing to do with a button press.

The only solution I found for the issue is to introduce a tolerance level to rule out false axis updates.  Each time it registers, the program only reports a change of 0.001, or so, from the axis being off center.  To get rid of the false positives, I no longer check for values <> 0, but instead:

 IF ABS(_AXIS(i)) > 0.1 THEN...

You can change the line and test it again, if you want, and I believe those false positives will go away.

The end result, with this change, makes the controller a little less sensitive, requiring a heavier push in any direction on the joystick to count as an event, but it eliminates the false positives with the buttons, for us. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1628
Re: _DEVICES and joystick glitched?
« Reply #4 on: November 27, 2020, 10:28:40 AM »
a bit further experience

with this code I got these results:
Code: QB64: [Select]
  1.     PRINT TIME$; " event -->";
  2.     Dev = _DEVICES
  3.     IF _DEVICEINPUT = 3 THEN
  4.         change = 0
  5.         IF _BUTTON(1) <> 0 THEN PRINT "BUTTON PUSHED": END
  6.         IF _BUTTON(2) <> 0 THEN PRINT "Button 2"
  7.         IF _BUTTON(3) <> 0 THEN PRINT "button 3"
  8.         IF _BUTTON(4) <> 0 THEN PRINT "Button 4"
  9.         FOR i = 1 TO _LASTAXIS
  10.             IF _AXIS(i) <> 0.2 THEN
  11.                 change = SGN(_AXIS(i))
  12.                 PRINT "AXIS "; i; " changed"
  13.                 EXIT FOR
  14.             END IF
  15.         NEXT
  16.     ELSE
  17.         PRINT
  18.     END IF
  19.     _LIMIT 1
  20.  

results ...

moving the L knob I got axis 1 detection, moving the D knob I got the buttons and axis detection.
Programming isn't difficult, only it's  consuming time and coffee

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3206
    • Steve’s QB64 Archive Forum
Re: _DEVICES and joystick glitched?
« Reply #5 on: November 27, 2020, 10:37:10 AM »
So moving the axis also counts as a button push?  That makes _DEVICES almost worthless to add into a program.  I’ll do you some testing later, and if I can duplicate the results, I’ll end up stripping joystick support out of my projects.  We really need a complete input overhaul for QB64.  :(
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Online SpriggsySpriggs

  • Forum Resident
  • Posts: 671
  • If you're API and you know it clap your hands
    • My GitHub
Re: _DEVICES and joystick glitched?
« Reply #6 on: November 27, 2020, 10:53:12 AM »
So moving the axis also counts as a button push?  That makes _DEVICES almost worthless to add into a program.  I’ll do you some testing later, and if I can duplicate the results, I’ll end up stripping joystick support out of my projects.  We really need a complete input overhaul for QB64.  :(
@SMcNeill
If the controller you are using uses XInput then you can use the library I made for XInput controllers in my API collection.

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2701
  • LET IT = BE
    • QB64.org
Re: _DEVICES and joystick glitched?
« Reply #7 on: November 27, 2020, 11:24:37 AM »
The project I wrote to which I added joystick support (i) works as expected (ii) required no complete overhaul. Maybe it's the way you're writing your routines?

https://fellippeheitor.itch.io/spaceship

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3206
    • Steve’s QB64 Archive Forum
Re: _DEVICES and joystick glitched?
« Reply #8 on: November 27, 2020, 11:50:39 AM »
The project I wrote to which I added joystick support (i) works as expected (ii) required no complete overhaul. Maybe it's the way you're writing your routines?

https://fellippeheitor.itch.io/spaceship
DO
    Dev = _DEVICES
    IF _DEVICEINPUT = 3 THEN
        IF _BUTTON(1) <> 0 THEN PRINT "BUTTON PUSHED"
        FOR i = 1 TO _LASTAXIS
            IF _AXIS(i) <> 0 THEN PRINT "AXIS "; i; " changed"
        NEXT
    END IF
    WHILE _DEVICEINPUT: WEND
    _LIMIT 1
LOOP

What’s wrong with the above?  We check _DEVICEINPUT for any updates.  If the result is from the joystick (3), then we check to see if a button was pressed or if an axis changed.  Pressing the button shouldn’t change the axis, and the axis shouldn’t change button status.  The WHILE - WEND then clears the buffer, so we only deal with one event and no more.

If you have a suggestion for a different way to read things, without the false results, I’d love to hear it.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2701
  • LET IT = BE
    • QB64.org
Re: _DEVICES and joystick glitched?
« Reply #9 on: November 27, 2020, 11:54:29 AM »
Check my code too while I don't have a chance to fix yours. It might help. The download in the link I posted contains the source.

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2701
  • LET IT = BE
    • QB64.org
Re: _DEVICES and joystick glitched?
« Reply #10 on: November 27, 2020, 01:38:44 PM »
Try this:

Code: QB64: [Select]
  1.  
  2. CONST True = -1, False = 0
  3.  
  4. DIM startTime#, x AS LONG, found AS LONG, i AS LONG
  5.  
  6. 'Detection routine:
  7. PRINT "Detecting your controller. Press any button on it..";
  8. startTime# = TIMER
  9.     x = _DEVICEINPUT
  10.     IF x > 2 THEN
  11.         'Keyboard is 1, Mouse is 2. Anything after that could be a controller.
  12.         found = x
  13.         EXIT DO
  14.     END IF
  15.     PRINT ".";
  16.     _LIMIT 15
  17. LOOP UNTIL TIMER - startTime# > 10
  18.  
  19. IF found = 0 THEN PRINT "No joystick detected.": END
  20.  
  21.     CLS
  22.     COLOR
  23.     PRINT "Controller in use:"
  24.     COLOR 14
  25.     PRINT SPACE$(4); _DEVICE$(found)
  26.     x = CSRLIN
  27.     COLOR 0, 7
  28.     LOCATE x, 1: PRINT SPACE$(80);
  29.     LOCATE x, 1
  30.     PRINT "Buttons:             Axis:"
  31.     COLOR 7, 0
  32.  
  33.     WHILE _DEVICEINPUT(found): WEND
  34.     FOR i = 1 TO _LASTBUTTON(found)
  35.         LOCATE x + i, 1
  36.         PRINT USING "##: ##"; i; _BUTTON(i)
  37.     NEXT
  38.  
  39.     FOR i = 1 TO _LASTAXIS(found)
  40.         LOCATE x + i, 20
  41.         PRINT USING "##: +#.##"; i; _AXIS(i)
  42.         LOCATE x + i, 30: PRINT STRING$(41, 176);
  43.         LOCATE x + i, 50 + INT(map(_AXIS(i), -1, 1, -20, 20)): PRINT CHR$(219);
  44.     NEXT
  45.  
  46.     _DISPLAY
  47.     _LIMIT 60
  48.  
  49. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  50.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  51.  

Hopefully it yields the same results I get:


All buttons detected and all axis properly responsive, just as expected.

Offline Cobalt

  • Forum Resident
  • Posts: 708
  • At 60 I become highly radioactive!
Re: _DEVICES and joystick glitched?
« Reply #11 on: November 27, 2020, 02:34:05 PM »
Dragon Warrior had no issues with joypad input. Least not my joypad or Fellippe's. I wonder if its something with what your using Steve? You might try Dragon Warrior with your controller and see if it acts up in the same way.

I did have some weird results at one time, but it was just before my old controller went belly up.

When I run your code I get exactly what I would expect, save for my joypad doesn't use button 1 so I had to change that. Uses 3 as the lowest button value for some reason.
Granted after becoming radioactive I only have a half-life!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3206
    • Steve’s QB64 Archive Forum
Re: _DEVICES and joystick glitched?
« Reply #12 on: November 27, 2020, 05:15:04 PM »
I get the same false results with your program Fellippe.



I start with all values equal to 0, and then when I press a button, I generate a value on the _AXIS(2) and (4) of -0.0078 -- and I continue to generate this negative value from that point onwards.

Until a button is pressed, all my _AXIS read 0, as they should.  The moment I press a button, I have a permanent input stuck on my controller.

I'd be tempted to think it was just my controller, except Tempodi is generating the exact same style results, with the same style gamepad as mine.  Click a button, and we read really low level _AXIS inputs from that point on. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2701
  • LET IT = BE
    • QB64.org
Re: _DEVICES and joystick glitched?
« Reply #13 on: November 27, 2020, 05:17:12 PM »
Tempodi got good results with my code (we were just discussing it at Discord). Your controller sure is requiring some calibration. But do not underestimate the fact that you are doing some weird ordering of commands to get input from joysticks, as opposed to treating it more like we treat _MOUSEINPUT, which is what I've offered.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3206
    • Steve’s QB64 Archive Forum
Re: _DEVICES and joystick glitched?
« Reply #14 on: November 27, 2020, 05:30:19 PM »
Tempodi got good results with my code (we were just discussing it at Discord). Your controller sure is requiring some calibration. But do not underestimate the fact that you are doing some weird ordering of commands to get input from joysticks, as opposed to treating it more like we treat _MOUSEINPUT, which is what I've offered.

It's not really that odd of an order.  What I'm doing is just basically a clearing of the buffer after reading it once, a lot like how we'd do a _KEYCLEAR to erase unwanted keystrokes.

Even if I change to a format which matches yours, I still generate the false results:

Code: QB64: [Select]
  1. Dev = _DEVICES
  2.     FOR i = 1 TO _LASTBUTTON(3)
  3.         IF _BUTTON(i) <> 0 THEN PRINT "Button"; i
  4.     NEXT
  5.     FOR i = 1 TO _LASTAXIS(3)
  6.         IF _AXIS(i) <> 0 THEN PRINT "AXIS "; i
  7.     NEXT
  8.     _LIMIT 1
  9.  

This completely follows your code:
Code: [Select]
    WHILE _DEVICEINPUT(found): WEND
    FOR i = 1 TO _LASTBUTTON(found)
        LOCATE x + i, 1: PRINT USING "##: ##"; i; _BUTTON(i)
    NEXT
 
    FOR i = 1 TO _LASTAXIS(found)
        LOCATE x + i, 20: PRINT USING "##: +#.##"; i; _AXIS(i)
        LOCATE x + i, 30: PRINT STRING$(41, 176);
        LOCATE x + i, 50 + INT(map(_AXIS(i), -1, 1, -20, 20)): PRINT CHR$(219);
    NEXT

And still, when I hit a button, I get an AXIS update rather than a button press.  Try the above little code of mine and see if it glitches on you, or if it works properly on your machine.  As it is, both programs are glitchy on my end.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!