Detecting any joystick axis movement

Hi!

To let the player customise the controls of my game, I have written a class
for my GUI system that captures user input. The way I use it is pop up a
window with an instance of the capture class and a message telling the user
to press any key or button. The capture object then watches for key or
joybutton events and captures the first one it receives. This key or button
will then be assigned to the action the user is customising.

What’s still missing is support for joystick axes. I.e., if the user moves any
joystick axis of any joystick instead of pressing a key or button, I want the
capture class to recognise that and tell me which axis was used.

Now I can’t just accept the first joyaxis event I get, because it might just
be a small variation within the joystick’s dead zone. I could watch for
events representing axis changes greater than, e.g. 1000, but I assume doing
this every frame would mean that owners of very fast PCs might have to move
their axis extremely quickly. Perhaps I’m too careful here, but I’m afraid
this solution might be a bit too much of a hack.

So my current idea is this: On any joyaxis event, convert the current axis
position to a boolean value, true meaning that the position is greater than
16000 or smaller than -16000, i.e. that the axis is “on”. Then check a
std::map to see the last state of this axis. If it is different from the new
one, assume that the user has moved this axis, otherwise keep looking.

However, before I start implementing, I’d like to ask if there are
simpler/more elegant/more effective solutions? I’m sure this is a common
problem for user-friendly games, and I might have just overlooked the most
obvious & best way to do it.

Thx in advance,
Marian.–
Hofstadter’s law: “It always takes longer than you think, even when you take
account of Hofstadter’s law”.

Hi Marian.

I have written a similar class:
http://cmugcs.sourceforge.net/wiki/index.php/SDLCustomInput

I had the same idea you did. I haven’t updated that page in a while,
but I’ve been working on-and-off on this module for a couple months. I
have solved the two primary problems of interpreting joystick axes with
two simple methods:

Problem 1: Ignoring input "hiccups"
Solution 1: Each axis object has an accumulator which is used for
detecting and comparing consistent, deliberate movement of the axis.

Problem 2: Which axes are paired up as joysticks?
Solution 2: By turning down the accumulator decay a bit, you can detect
someone “circling” their joystick with no problem.

The only restriction on these methods is your user must be instructed
to not mess around with two joysticks simultaneously. They’d have to be
an idiot to do that on purpose, and if they do it on accident, they
probably dropped their joystick.

Good luck with your project. I hope to release my work under the GNU
LGPL before the year is over so that everyone can benefit from my
effort. But who knows how things will turn out in the future.On Sep 21, 2004, at 9:29 PM, Marian Schedenig wrote:

Hi!

To let the player customise the controls of my game, I have written a
class
for my GUI system that captures user input. The way I use it is pop up
a
window with an instance of the capture class and a message telling the
user
to press any key or button. The capture object then watches for key or
joybutton events and captures the first one it receives. This key or
button
will then be assigned to the action the user is customising.

What’s still missing is support for joystick axes. I.e., if the user
moves any
joystick axis of any joystick instead of pressing a key or button, I
want the
capture class to recognise that and tell me which axis was used.

Now I can’t just accept the first joyaxis event I get, because it
might just
be a small variation within the joystick’s dead zone. I could watch for
events representing axis changes greater than, e.g. 1000, but I assume
doing
this every frame would mean that owners of very fast PCs might have to
move
their axis extremely quickly. Perhaps I’m too careful here, but I’m
afraid
this solution might be a bit too much of a hack.

So my current idea is this: On any joyaxis event, convert the current
axis
position to a boolean value, true meaning that the position is greater
than
16000 or smaller than -16000, i.e. that the axis is “on”. Then check a
std::map to see the last state of this axis. If it is different from
the new
one, assume that the user has moved this axis, otherwise keep looking.

However, before I start implementing, I’d like to ask if there are
simpler/more elegant/more effective solutions? I’m sure this is a
common
problem for user-friendly games, and I might have just overlooked the
most
obvious & best way to do it.

Thx in advance,
Marian.


Hofstadter’s law: “It always takes longer than you think, even when
you take
account of Hofstadter’s law”.


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

I have written a similar class:
http://cmugcs.sourceforge.net/wiki/index.php/SDLCustomInput

Yeah, you may have to hit your browser’s refresh button a few times to
get SourceForge to actually display the page. It’s my fault for not
maintaining it properly. But I MediaWiki has all kinds of problems on
SourceForge.On Sep 22, 2004, at 2:52 AM, Donny Viszneki wrote:

I had the same idea you did. I haven’t updated that page in a while,
but I’ve been working on-and-off on this module for a couple months. I
have solved the two primary problems of interpreting joystick axes with
two simple methods:

Thanks for the info. I have now implemented it this way, and it seems to work
like a charm. I simply keep the current “direction” (-1, 0, or +1) for each
axis in a std::map and call a method when the axis changes.

This “digitisation” of joystick axis allowed me to easily implement joystick
menu navigation as well.

Problem 1: Ignoring input "hiccups"
Solution 1: Each axis object has an accumulator which is used for
detecting and comparing consistent, deliberate movement of the axis.

I’ll probably add a deadzone between -1 and 0 and between 0 and +1 so I don’t
get hiccups when the axis is held too close to the border value. Should work
fine for my purposes.

The only restriction on these methods is your user must be instructed
to not mess around with two joysticks simultaneously. They’d have to be
an idiot to do that on purpose, and if they do it on accident, they
probably dropped their joystick.

Since for me it’s only menu navigation and detecting a key/button/axis in a
popup menu, I can live with simply reacting to the first event I get. If it’s
the wrong one, the user can still reconfigure the axis again.

Thanks again,
Marian.On Wednesday 22 September 2004 08:52, Donny Viszneki wrote:


Hofstadter’s law: “It always takes longer than you think, even when you take
account of Hofstadter’s law”.

Problem 1: Ignoring input "hiccups"
Solution 1: Each axis object has an accumulator which is used for
detecting and comparing consistent, deliberate movement of the axis.

I’ll probably add a deadzone between -1 and 0 and between 0 and +1 so
I don’t
get hiccups when the axis is held too close to the border value.
Should work
fine for my purposes.

The only restriction on these methods is your user must be instructed
to not mess around with two joysticks simultaneously. They’d have to
be
an idiot to do that on purpose, and if they do it on accident, they
probably dropped their joystick.

Since for me it’s only menu navigation and detecting a key/button/axis
in a
popup menu, I can live with simply reacting to the first event I get.
If it’s
the wrong one, the user can still reconfigure the axis again.

I don’t know if this was my mistake or not - but I was referring
specifically to customizing your input configuration - I was probably
off in another world when I was answering your email.On Sep 25, 2004, at 9:50 PM, Marian Schedenig wrote: