Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Date: Sun, 1 Jun 2003 15:38:45 -0700 (PDT)
From: Jeff Brown <jabrown@caida.org>
Subject: [patch] SDL-1.2.5 + FreeBSD joystick axes, hat fixes

Hello again!  When I sent in some SDL fixes last December, I found out
they'd already been fixed in the CVS version.  This time, I checked the
repository before bugging you.  =)

I'm using SDL-1.2.5 on a FreeBSD 4.6.2-RELEASE system, and in the course
of getting my multi-analog-axis USB controller (with a hat switch!)
working with d2x-sdl -- the SDL port of the Descent 2 engine -- I came
across a few problems:

1) The second analog stick is reported as a slider in one direction, and
"Rz" in the other.  SDL was ignoring the Rz axis, so I added Rx/Ry/Rz to
the set of things SDL considers to be axes.

2) After the above change, the set of JOYAXE_* axes for my gamepad was
{0,1,3,7}; however, d2x-sdl expects the axes to be contiguously numbered
from 0, which seems like a pretty reasonable expectation, rather than
having to scan the entire space of axes that SDL may or may not have.
So, I added a table lookup which maps the JOYAXE_* axis numbers to 0,1,...
in the order they're detected by SDL_SYS_JoystickOpen(), when reporting
them to the application.  I also added a function "usage_to_joyaxe()"
which maps the USB HUG_* usage values to JOYAXE_values, since the repeated
case statements testing for HUG_* were getting out of hand.

3) The BSD joystick driver had no hat support, so I added it.  It looks
like our USB library can only support one hat switch per device, which
makes life easy.

The patch against SDL-1.2.5 which implements these changes is at:

        http://www.caida.org/~jabrown/patches/sdl-1.2.5-bsdhat.diff

After applying, SDL's "testjoystick" reports all activity from my gamepad
correctly, and d2x works too (though it needed some other fixes).

Moving on...

There is also a problem with slightly different USBHID library interfaces
on different versions of FreeBSD. I wasn't going to mention this since the
FreeBSD port for SDL-1.2.5 (and not SDL itself) was doing the FreeBSD
version-specific patching, so I e-mailed the port maintainer with this
change.  However, I see that you've incorporated the FreeBSD
version-checking stuff into the CVS version of SDL, so now it's relevant
for you too.

The problem is, the FreeBSD #if tests don't work right for FreeBSD
4.6.2-RELEASE.  There may be other versions with this problem, but I've
only tested 4.6.2-R.  The following patch against your latest CVS version
fixes this:

--- SDL_sysjoystick.c-1.16      Tue Apr 15 09:02:08 2003
+++ SDL_sysjoystick.c   Sun Jun  1 15:10:28 2003
@@ -420,6 +420,8 @@
 #  else
        len = hid_report_size(rd, repinfo[repind].kind, r->rid);
 #  endif
+# elif (__FreeBSD_version == 460002)
+       len = hid_report_size(rd, r->rid, repinfo[repind].kind);
 # else
        len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
 #endif


I hope this is all useful to you.  I've been getting myself dizzy playing
Descent 2 with it, all morning!

        -Jeff Brown


P.S. My USB controller is a Thrustmaster Firestorm Dual Analog 2.  That's
probably irrelevant, but I threw it in for completeness.
  • Loading branch information
slouken committed Jun 2, 2003
1 parent 74475ac commit 97bd158
Showing 1 changed file with 82 additions and 46 deletions.
128 changes: 82 additions & 46 deletions src/joystick/bsd/SDL_sysjoystick.c
Expand Up @@ -100,7 +100,11 @@ enum {
JOYAXE_Y,
JOYAXE_Z,
JOYAXE_SLIDER,
JOYAXE_WHEEL
JOYAXE_WHEEL,
JOYAXE_RX,
JOYAXE_RY,
JOYAXE_RZ,
JOYAXE_count
};

struct joystick_hwdata {
Expand All @@ -112,10 +116,7 @@ struct joystick_hwdata {
} type;
struct report_desc *repdesc;
struct report inreport;
#if 0
int axismin[];
int axismax[];
#endif
int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,..*/
};

static char *joynames[MAX_JOYS];
Expand Down Expand Up @@ -180,6 +181,49 @@ SDL_SYS_JoystickName(int index)
return (joynames[index]);
}

static int
usage_to_joyaxe(unsigned usage)
{
int joyaxe;
switch (usage) {
case HUG_X:
joyaxe = JOYAXE_X; break;
case HUG_Y:
joyaxe = JOYAXE_Y; break;
case HUG_Z:
joyaxe = JOYAXE_Z; break;
case HUG_SLIDER:
joyaxe = JOYAXE_SLIDER; break;
case HUG_WHEEL:
joyaxe = JOYAXE_WHEEL; break;
case HUG_RX:
joyaxe = JOYAXE_RX; break;
case HUG_RY:
joyaxe = JOYAXE_RY; break;
case HUG_RZ:
joyaxe = JOYAXE_RZ; break;
default:
joyaxe = -1;
}
return joyaxe;
}

static unsigned
hatval_to_sdl(Sint32 hatval)
{
static const unsigned hat_dir_map[8] = {
SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN,
SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP
};
unsigned result;
if ((hatval & 7) == hatval)
result = hat_dir_map[hatval];
else
result = SDL_HAT_CENTERED;
return result;
}


int
SDL_SYS_JoystickOpen(SDL_Joystick *joy)
{
Expand All @@ -206,6 +250,11 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy)
hw->fd = fd;
hw->path = strdup(path);
hw->type = BSDJOY_UHID;
{
int ax;
for (ax = 0; ax < JOYAXE_count; ax++)
hw->axis_map[ax] = -1;
}
hw->repdesc = hid_get_report_desc(fd);
if (hw->repdesc == NULL) {
SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
Expand Down Expand Up @@ -259,23 +308,17 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy)
break;
case hid_input:
switch (HID_PAGE(hitem.usage)) {
case HUP_GENERIC_DESKTOP:
switch (HID_USAGE(hitem.usage)) {
case HUG_X:
case HUG_Y:
case HUG_Z:
case HUG_SLIDER:
case HUG_WHEEL:
#if 0
hw->axismin[joy->naxes] =
hitem.logical_minimum;
hw->axismax[joy->naxes] =
hitem.logical_maximum;
#endif
joy->naxes++;
break;
}
break;
case HUP_GENERIC_DESKTOP: {
unsigned usage = HID_USAGE(hitem.usage);
int joyaxe = usage_to_joyaxe(usage);
if (joyaxe >= 0) {
hw->axis_map[joyaxe] = joy->naxes;
joy->naxes++;
} else if (usage == HUG_HAT_SWITCH) {
joy->nhats++;
}
break;
}
case HUP_BUTTON:
joy->nbuttons++;
break;
Expand Down Expand Up @@ -329,35 +372,26 @@ SDL_SYS_JoystickUpdate(SDL_Joystick *joy)
switch (hitem.kind) {
case hid_input:
switch (HID_PAGE(hitem.usage)) {
case HUP_GENERIC_DESKTOP:
switch (HID_USAGE(hitem.usage)) {
case HUG_X:
naxe = JOYAXE_X;
goto scaleaxe;
case HUG_Y:
naxe = JOYAXE_Y;
goto scaleaxe;
case HUG_Z:
naxe = JOYAXE_Z;
goto scaleaxe;
case HUG_SLIDER:
naxe = JOYAXE_SLIDER;
goto scaleaxe;
case HUG_WHEEL:
naxe = JOYAXE_WHEEL;
goto scaleaxe;
default:
continue;
}
scaleaxe:
case HUP_GENERIC_DESKTOP: {
unsigned usage = HID_USAGE(hitem.usage);
int joyaxe = usage_to_joyaxe(usage);
if (joyaxe >= 0) {
naxe = joy->hwdata->axis_map[joyaxe];
/* scaleaxe */
v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
&hitem);
&hitem);
v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2;
v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2);
if (v != joy->axes[naxe]) {
SDL_PrivateJoystickAxis(joy, naxe, v);
SDL_PrivateJoystickAxis(joy, naxe, v);
}
break;
} else if (usage == HUG_HAT_SWITCH) {
v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
&hitem);
SDL_PrivateJoystickHat(joy, 0, hatval_to_sdl(v));
}
break;
}
case HUP_BUTTON:
v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
&hitem);
Expand Down Expand Up @@ -420,6 +454,8 @@ report_alloc(struct report *r, struct report_desc *rd, int repind)
# else
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
# endif
# elif (__FreeBSD_version == 460002)
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
# else
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
#endif
Expand Down

0 comments on commit 97bd158

Please sign in to comment.