Joystick API preview

I’ve looked at the BeOS, Linux, and Win32 implementations, and the following
seems very reasonable:

/* Joystick axis motion event structure /
typedef struct {
Uint8 type; /
SDL_JOYMOTION /
Uint8 which; /
The joystick device index /
Uint8 index; /
The joystick axis index /
float tx; /
Translation in the X direction /
float ty; /
Translation in the Y direction /
float tz; /
Translation in the Z direction /
float rx; /
Rotation in the X direction /
float ry; /
Rotation in the Y direction /
float rz; /
Rotation in the Z direction */
} SDL_JoyMotionEvent;

/* Joystick button event structure /
typedef struct {
Uint8 type; /
SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP /
Uint8 which; /
The joystick device index /
Uint8 button; /
The joystick button index /
Uint8 state; /
SDL_PRESSED or SDL_RELEASED */
} SDL_JoyButtonEvent;

/* Function prototypes /
/

  • Count the number of joysticks attached to the system
    */
    extern DECLSPEC int SDL_NumJoysticks(void);

/*

  • Open a joystick for use - the index passed as an argument refers to
  • the N’th joystick on the system. This index is the value which will
  • identify this joystick in future joystick events.*
  • This function returns a joystick identifier, or NULL if an error occurred.
    */
    extern DECLSPEC SDL_Joystick *SDL_JoystickOpen(int index);

/*

  • Get the implementation dependent name of a joystick
    */
    extern DECLSPEC const char *SDL_JoystickName(SDL_Joystick *joystick);

/*

  • Get the device index of an opened joystick.
    */
    extern DECLSPEC int SDL_JoystickIndex(SDL_Joystick *joystick);

/*

  • Get the number of buttons on a joystick
    */
    extern DECLSPEC int SDL_JoystickNumButtons(SDL_Joystick *joystick);

/*

  • Get the number of multi-dimensional axes on a joystick
    */
    extern DECLSPEC int SDL_JoystickNumAxes(SDL_Joystick *joystick);

/*

  • Get the current state of a button on a joystick
    */
    extern DECLSPEC Uint8 SDL_GetJoystickButton(SDL_Joystick joystick, int button);
    /
  • Get the current state of an axis on a joystick
    */
    extern DECLSPEC const struct SDL_AxisState *SDL_GetJoystickAxis
    (SDL_Joystick *joystick, int axis);

/*

  • Close a joystick previously opened with SDL_JoystickOpen()
    */
    extern DECLSPEC void SDL_JoystickClose(SDL_Joystick *joystick);


This is just a preliminary API without any code. Comments are welcome.

See ya!
-Sam Lantinga (slouken at devolution.com)

Lead Programmer, Loki Entertainment Software

“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

I’ve looked at the BeOS, Linux, and Win32 implementations

So there will be support for Win32 joystick? I thought a previous post
only mentioned Linux. This is good because I don’t have the foggiest
idea how to code joysticks in windows. I already have support for Linux
in PowerPak, but need Win32 support as well.–
http://www.scinomaly.org : Science outside the norm.

Sam Lantinga wrote:

I’ve looked at the BeOS, Linux, and Win32 implementations

So there will be support for Win32 joystick? I thought a previous post
only mentioned Linux. This is good because I don’t have the foggiest
idea how to code joysticks in windows. I already have support for Linux
in PowerPak, but need Win32 support as well.

Yes. The joystick support will take a while to iron out on all platforms,
but it will be cross-platform.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

/* Joystick axis motion event structure /
typedef struct {
Uint8 type; /
SDL_JOYMOTION /
Uint8 which; /
The joystick device index /
Uint8 index; /
The joystick axis index /
float tx; /
Translation in the X direction /
float ty; /
Translation in the Y direction /
float tz; /
Translation in the Z direction /
float rx; /
Rotation in the X direction /
float ry; /
Rotation in the Y direction /
float rz; /
Rotation in the Z direction */
} SDL_JoyMotionEvent;

Doesn’t some joysticks have more axis than that? Like those with hats,
that makes for X1-Y1, X2-Y2, plus the rotations for some of them…
Isn’t DirectInput very generic, just saying “this joystick has 8 axis
and 4 buttons, do whatever you want with them” (with nothing labeled as
the “X direction”, but rather “axis 0” thru “axis 7” for example)?

The newer joystick driver for Linux also has an unspecified number of
unlabeled axis and buttons, right?

In a game, this would be handled like keybindings, binding axis #3 to
yaw, axis #2 to pitch, axis #0 to throttle, and so on… Descent was
like that if I remember correctly.–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/
“First they ignore you. Then they laugh at you.
Then they fight you. Then you win.” – Gandhi

Doesn’t some joysticks have more axis than that? Like those with hats,
that makes for X1-Y1, X2-Y2, plus the rotations for some of them…
Isn’t DirectInput very generic, just saying “this joystick has 8 axis
and 4 buttons, do whatever you want with them” (with nothing labeled as
the “X direction”, but rather “axis 0” thru “axis 7” for example)?

Yes. I was trying to map generic axes into axes of motion.
i.e. axis 0 is X, axis 1 is Y, axis 2 is Z, axis 7 is hat-X, axis 8 is hat-Y,
etc., so it made more sense.

Hum.

The newer joystick driver for Linux also has an unspecified number of
unlabeled axis and buttons, right?

Yes, and it doesn’t specify hats separately either. hat1 is axis3,4
– if the hat in the upper left position, axis 3 is -32767 and axis 4
is -32767.

BeOS does specify hats separately, the hat can be in one of 9 positions.
The axis motion is represented as just a list of axis values, one per axis.
It’s actually a very nice joystick API.

DirectInput also specifies hats separately.

So basically, joysticks break down to:
N buttons
N axes
N hats (POV)

On Linux, BeOS, and Win32, you can determine the number of buttons and
axes, and map them accordingly. On BeOS and Win32, you can determine
the number of hats and map them accordingly. On BeOS and Win32 you can
also get the “name” of each of the objects on the joystick.

Linux has no way of identifying if a set of axes correspond to a hat,
and also has no way of “naming” a joystick control, which presumeably
is done by the driver under Win32 and BeOS.

sigh
-Sam Lantinga (slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Linux has no way of identifying if a set of axes correspond to a hat,
and also has no way of “naming” a joystick control, which presumeably
is done by the driver under Win32 and BeOS.

True, but this is going to change with the input device layer, now
present in the 2.3.36 kernel. As time goes, all joystick drivers will
be converted to use that. This allows to identify every axis/button.
See include/linux/input.hOn Wed, Jan 05, 2000 at 02:40:11PM -0800, Sam Lantinga wrote:


Vojtech Pavlik
SuSE Labs

Sam Lantinga wrote:

On Linux, BeOS, and Win32, you can determine the number of buttons and
axes, and map them accordingly. On BeOS and Win32, you can determine
the number of hats and map them accordingly. On BeOS and Win32 you can
also get the “name” of each of the objects on the joystick.

The “name” thing is only sugar coating, IMHO. Maybe useful sugar, but
still.

Linux has no way of identifying if a set of axes correspond to a hat,
and also has no way of “naming” a joystick control, which presumeably
is done by the driver under Win32 and BeOS.

Hmm, hats are not analog, are they? So they aren’t really axis, but a
group of buttons (four of them for a single hat). Knowing that a set of
buttons forms a single hat is akin to knowing which axis belong to a
single stick on the joystick, which is slightly higher level.

My .02 cents analysis:

Low-level:

Joysticks have an undefinite number of “buttons” and an undefinite
number of “axis”.

Higher-level:

A group of four “buttons” can be set apart as a “hat” and a group of
minimum 2 and maximum 6 “axis” can be set apart as a “stick”.

Comments:

Whether buttons part of a hat or axis part of a stick should still be
listed in the “buttons” or “axis” of the API is arguable. I would prefer
them not to appear in those list, as they are really a high-level
object, and lone buttons/axis are also high-level objects, albeit
simpler ones.

For example, a joystick with one twistable stick, a throttle, a hat and
three firing buttons would have those low-level objects:

  • 4 axis
  • 7 buttons

And those high level objects:

  • 1 stick (made of 3 axis, having X-Y-Z rotations, very few joysticks
    actually have translation to my knowledge)
  • 1 axis (the throttle)
  • 1 hat
  • 3 buttons

What I see of the difference between Linux and the other OS is that
Linux only provides low-level drivers, and in the others cases, we are
actually talking to a high-level game-oriented input library, which is
completely another story. Note that on Win32 and BeOS, the drivers have
a GUI, in the control panel, to let the user do high-level things like
calibration, and the driver is aware of the model of joystick, which
tells it the layout of low-level objects into high-level ones.

This is a touchy point, as I think this obviously doesn’t go in the game
(game should talk about what a “stick” does, not map individual axis).
Those settings are normally shared between games even (the joystick
isn’t different for one of them).

I think this could be a bit controversial, what do you think people?–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/
“First they ignore you. Then they laugh at you.
Then they fight you. Then you win.” – Gandhi