JoyX/Y and JoyHat - ensuring it works for all?

BlitzPlus Forums/BlitzPlus Programming/JoyX/Y and JoyHat - ensuring it works for all?

David Boudreau(Posted 2009) [#1]
I made an input display program in BlitzPlus. It allows the user to choose Axis or POVhat, and displays the user's joystick input in a small window. It's primarily intended to be used by players of vs. fighting games (e.g. Street Fighter) to practice combos.

Some players report it not working with their joysticks, even the same model that other owners of that model report as having worked fine (the joysticks are generally nicer high end products like the Hori Real Arcade Pro 3 for example- for most people it works fine but two or three users say my program doesn't recognize anything). I don't have one to test but I can send these users diagnostic tests to try and figure out why this is occurring. I've had the users try all modes of their stick (it has the PS dualshock's mode switch function to switch from POVhat to Axis just like the Playstation controllers), and even tried pressing the "Home" key for 5 seconds (I read online that worked for some users of that model when using it on PC). These users seem to be able to use it perfectly fine on emulators that recognize it, eg nFBA.

In my program, I have a simple Diagnostics mode option in the menu that basically Texts out values for all the joystick commands I could find in the Command Reference, but they couldn't get any of the numbers to change by moving their joystick:

; Output joystick values
Text 0,15,"JoyHat():" + JoyHat()
Text 0,30,"JoyX,Y,Z:" + JoyX() + "," + JoyY() + "," + JoyZ()
Text 0,45,"JoyXYZDirs:" + JoyXDir() + "," + JoyYDir() + "," + JoyZDir()
Text 0,60,"JoyU,V,UDir:" + JoyU() + "," + JoyV() + "," + JoyUDir()
Text 0,70,"Yaw,Pitch,Roll:" + JoyYaw() + "," + JoyPitch() + "," + JoyRoll()
;Text 0,30,"JoyUDir(): "+judir
Text 150,15,"JoyPitch(): "+jpitch#
Text 150,45,"JoyRoll(): "+jroll#

So, I am confused, because they say they can use it fine with the games in the emulator on their PC. When they go into Control Panel, Gaming Options, properties button, they can get movement in the test boxes (I asked them about info in dxdiag but it didn't seem like anything was wrong there).

Normally, my program checks for Axis values (JoyX() and JoyY() ) of -1, or +1 each, and if POVhat then -1 for neutral, 0 for up, 45 for up-right, 90 for right, etc around to 315 for up-left. Could these occasional users have sticks calibrated to different values I could check for that are different from that standard? What are other likely/typical values for those command functions besides +1/-1 and -1,0,->315?

btw some sticks send out signals as both Axis _and_ POVhat. I know that because an earlier verison of my program just checked for both JoyX/Y as well as JoyHat and occasionally some users reported constant displays of top-left in my program. This was because POVhat's neutral, as -1, was picked up as Axis signals (and -1 is left/up in Axis-speak) so sending them a build that checked only POVhat fixed it for them.

Anyway, I'd like to have some way to ensure that, if anyone can use their joystick with an emulator on their PC (and it's recognized as a DirectX-compatible stick), then my program will also recognize it too.

Anyone have ideas or maybe some ranges to test for in a simple test diagnostics program for joysticks or what might explain this?


Ginger Tea(Posted 2009) [#2]
i know the wired 360 joypad and ps3 (well a generic clone) give out different button results under windows joyconfig and blitz afaik doesnt recognise the 360 dpad at all
i posted a comparison between the 360/ps3 pads in the hoverthing demo thread

360 triggers are the Z value iir but are independant buttons on the ps3

ive not tested a generic built for pc game pad but im guessing there are alot of discrepancies between makes, eg a saitek branded joy pad might be 75% compatible with a logic3 with similar buttons
pongo? (or someone else) has posted in the code archives a joypad config util, so if the end users pad isnt layed out like your game expects it can be configed just like keyboard controlls can be
its just a shame microsoft didnt put their foot down and insist on a joypad standard years ago


Sauer(Posted 2009) [#3]
I always wondered about that, since they come in so many varieties with different buttons and axis...


Matty(Posted 2009) [#4]
With multiple joysticks you have to use the 'port' argument when specifying the joystick polling commands, otherwise it only reads from the joystick at port '0'.


David Boudreau(Posted 2009) [#5]
Matty, that assumes there are multiple joysticks attached to more than one port. I asked my users if that was the case and they said no, it was the only joystick connected (and their dxdiag reported only one joystick present). So if only one joystick is connected, I think the default port 0 is what gets checked in any case. Unfortunately I think it's the non-standard nature of the joystick market as others mention (hope I'm wrong!). In that case I'd like to write a calibrator function for those users with non-standard setups.

Ginger Tea, I've seen Pongo's code in the archives, this is it I think?
http://www.blitzbasic.com/codearcs/codearcs.php?code=1592

It was a little hard for me to follow and I don't think it works for non-dual analog sticks. (It would hang on me when I tried it with at least one cheap joypad I have.) I can pore through it again but how is he getting the calibration basically?

btw there are some joystick setups that map joystick movements to keyboard keys (Korean manufacturer Saulabi makes something like this, and there is a product called iPAC). That kind of setup really surprised me, and I'm curious as to how that works exactly. One reason it surprised me was for example, some moves in fighting games require multiple inputs to be held pressed down at the same time, something a keyboard loses track of after 4 or so many keys (e.g. Zangief's lariat, 3 punches or 3 kicks at once, or Dhalsim's/Akuma's teleports).


Matty(Posted 2009) [#6]
Regarding thouse iPAC keyboards - they are built to get around the 3 button limit on usual keyboards. Someone around here a few years ago was into making custom arcade cabinets and mentioned them - I think the issue is called 'ghosting' and that there are keyboards specifically built to get around this problem.


_PJ_(Posted 2009) [#7]
This is something I am loooking into with B3D, but I've stumbled into a little difficulty with the WinAPI Joystick recognition right now. As those joystick commands outputs seem the same as the B3D ones, I reckon my b3D stuff should be B+ compatible here.


Pongo(Posted 2009) [#8]
I just skimmed through this, so sorry if I missed something.

It looks like your diagnostic in the first post is correct.

The issue is with the IPAC controller you mentioned. I use one on my arcade machine. What is happening is not a problem with the IPAC either, since it is a keyboard controller. That means that you will not get any joystick inputs,... only keyboard keys. By default the IPAC is mapped to MAME defaults, but you can change it to anything, even custom configurations per game.

What you will need to do is expand your diagnostic to scan keycodes and then use those as control inputs.

I've been meaning to re-do the joyconfig utility to include this kind of stuff as well as sensitivity curves.

Here is the basic idea though,...
Instead of using JoyX() to capture your X input, use a function to grab the value of X. If you look through my joyconfig code in the archives you will see one way of doing this.

To use keys instead, you simply need to map the left/right keys to a value of -1 to 1.

x = keydown(205) - keydown(203)

That example will return a value of -1 if the left arrow is held down, a 1 if the right arrow is held down, or a value of 0 if no keys are held down (or both cancel each other out)

Doing this will allow you to swap that code any place you would normally call a joystick.

Joyhat() is a completely different case, since it returns -1 or an angle value, but these can still be converted to a simple -1 to 1 range. Once this is all contained in a getInput function, it's as simple as calling the function for the appropriate value, whether the end user is using a stick/pad/keyboard,...whatever.


David Boudreau(Posted 2009) [#9]
Thanks Pongo- however I'm still not quite understanding your archive code
http://www.blitzbasic.com/codearcs/codearcs.php?code=1592 , particularly where it is that it checks for different values and why you chose those specific ranges for the values. My guess is it's here in the lines of the function getjoyaxis():

Repeat
If Abs(JoyX(Controller_port)) > .5 And Abs(JoyX(Controller_port)) < .9 Return 1

Is that the heart of it? Specifically, why is it .5 to .9, are those values going to catch just about any joystick's ranges for the left/right directions (and it would be rare/not possible to have them outside this range)? Sorry if I've got something basic wrong.

As for the IPAC and keyboard type setups for joysticks, that is good to know however I don't even plan to tackle that yet until I can get this figured out first (ie working for all standard joysticks like the odd HRAP3 that nFBA or MAME recognize but my program doesn't yet).

btw that's a neat trick with x = right - left, thanks for that. I take it, it would similarly be y = down - up?


Pongo(Posted 2009) [#10]
The reason for that range is quite simple really, but I can see why it may confuse.

Let's assume your joystick is at rest. In a perfect world it would be 0, but in reality it jumps around a bit. For that reason, you can't really be sure someone has moved the control until the value is a bit higher (.1 should be high enough) Some sticks, especially sliders may be in the reversed position, so they may read as 1 or -1 instead of 0. That is why the .9 value is there.

The reason I use .5 is to make sure of the direction being pressed. Since I am checking for the axis with movement, I don't want a slight inadvertent upward movement to register when the person is trying to assign a horizontal move. By making this value a bit higher (.5 in this case) they have to move the stick quite a bit before it registers, so it cuts out accidental bumps.

And yes, that trick will work with any set of keys, and makes a nice easy way to convert joystick code to keyboard code.


David Boudreau(Posted 2009) [#11]
I'm sorry but one basic thing is still not quite clear to me- is it possible to catch joystick X/Y values for standard directx-compatible sticks with your code in that archive? Let me take a step back and get the basic concept of what the code is doing here. Is it saying, for one of the analog sticks, the value to check for is not necessarily an integer whole number, so we need to check for values 0.0000 to 1.0000?

I wish I had the occasional stick that doesn't work with my program to test with. I did manage to round up a PC pad controller that is the Playstation 2 style with 2 analog sticks and an analog toggle button in the middle (w/LED). It works fine with my program and I can get my Diagnostics code to show values for JoyHat on Dpad, and these for X:

-1.0 for full Left
-1.52588e-005 for neutral
1.0 for full Right

(and various values in between full left/full right)

btw my program is demo'ed here:
http://www.youtube.com/watch?v=xi_BYZM1LsA
(download link in description on the right, scroll down after clicking it and then click download with FileFactory Basic)


Pongo(Posted 2009) [#12]
You should be able to catch any joystick with joyX() and JoyY(). That part is almost 100% the same on all joystick and pads. It is the second stick and buttons that are inconsistent among devices, even within the same company.

And yes, by their nature, an analogue stick is going to capture a range of numbers (-1.0 to 1.0 for joyX and JoyY, -180/180 for yaw pitch and roll), rather than a 1 or 0 like a button or key. For a fighting game, you may wish to trigger a "hit" at the .5 mark so that the user does not have to move the stick to the full extent before it registers movement.

I am starting to re-write my input code. Hopefully it will be a bit easier to read this time. Unfortunately, I don't know when it may be ready (Depends on how much free time I get at home) This quick chunk of code should check for every bit of input I could think of. It should detect Keyboard, Joysticks, Joystick buttons, JoyHat, Mouse movement including wheel and mouse buttons.