- Added button mapping for the first 8 axes for SDL joysticks. The first two axes are assumed to be x/y.

- Added POV hat support for SDL.  (First 4 map to buttons, but all map to an x/y axis.)

SVN r3607 (trunk)
This commit is contained in:
Braden Obrzut 2012-04-29 00:53:27 +00:00
parent de43788c3a
commit 192839a436

View file

@ -1,5 +1,6 @@
#include <SDL_joystick.h> #include <SDL_joystick.h>
#include "doomdef.h"
#include "m_joy.h" #include "m_joy.h"
class SDLInputJoystick: public IJoystickConfig class SDLInputJoystick: public IJoystickConfig
@ -9,7 +10,12 @@ public:
{ {
Device = SDL_JoystickOpen(DeviceIndex); Device = SDL_JoystickOpen(DeviceIndex);
if(Device != NULL) if(Device != NULL)
{
NumAxes = SDL_JoystickNumAxes(Device);
NumHats = SDL_JoystickNumHats(Device);
SetDefaultConfig(); SetDefaultConfig();
}
} }
~SDLInputJoystick() ~SDLInputJoystick()
{ {
@ -38,7 +44,7 @@ public:
int GetNumAxes() int GetNumAxes()
{ {
return SDL_JoystickNumAxes(Device); return NumAxes + NumHats*2;
} }
float GetAxisDeadZone(int axis) float GetAxisDeadZone(int axis)
{ {
@ -95,10 +101,14 @@ public:
for(int i = 0;i < GetNumAxes();i++) for(int i = 0;i < GetNumAxes();i++)
{ {
AxisInfo info; AxisInfo info;
info.Name.Format("Axis %d", i); if(i < NumAxes)
info.Name.Format("Axis %d", i+1);
else
info.Name.Format("Hat %d (%c)", (i-NumAxes)/2 + 1, (i-NumAxes)%2 == 0 ? 'x' : 'y');
info.DeadZone = 0.0f; info.DeadZone = 0.0f;
info.Multiplier = 1.0f; info.Multiplier = 1.0f;
info.Value = 0.0; info.Value = 0.0;
info.ButtonValue = 0;
if(i >= 5) if(i >= 5)
info.GameAxis = JOYAXIS_None; info.GameAxis = JOYAXIS_None;
else else
@ -125,10 +135,86 @@ public:
void ProcessInput() void ProcessInput()
{ {
for (int i = 0; i < GetNumAxes(); ++i) BYTE buttonstate;
for (int i = 0; i < NumAxes; ++i)
{ {
buttonstate = 0;
Axes[i].Value = SDL_JoystickGetAxis(Device, i)/32768.0; Axes[i].Value = SDL_JoystickGetAxis(Device, i)/32768.0;
Axes[i].Value = Joy_RemoveDeadZone(Axes[i].Value, Axes[i].DeadZone, NULL); Axes[i].Value = Joy_RemoveDeadZone(Axes[i].Value, Axes[i].DeadZone, &buttonstate);
// Map button to axis
// X and Y are handled differently so if we have 2 or more axes then we'll use that code instead.
if (NumAxes == 1 || (i >= 2 && i < NUM_JOYAXISBUTTONS))
{
Joy_GenerateButtonEvents(Axes[i].ButtonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2);
Axes[i].ButtonValue = buttonstate;
}
}
if(NumAxes > 1)
{
buttonstate = Joy_XYAxesToButtons(Axes[0].Value, Axes[1].Value);
Joy_GenerateButtonEvents(Axes[0].ButtonValue, buttonstate, 4, KEY_JOYAXIS1PLUS);
Axes[0].ButtonValue = buttonstate;
}
// Map POV hats to buttons and axes. Why axes? Well apparently I have
// a gamepad where the left control stick is a POV hat (instead of the
// d-pad like you would expect, no that's pressure sensitive). Also
// KDE's joystick dialog maps them to axes as well.
for (int i = 0; i < NumHats; ++i)
{
AxisInfo &x = Axes[NumAxes + i*2];
AxisInfo &y = Axes[NumAxes + i*2 + 1];
buttonstate = SDL_JoystickGetHat(Device, i);
switch(buttonstate)
{
case SDL_HAT_LEFTUP:
x.Value = -1.0;
y.Value = -1.0;
break;
case SDL_HAT_LEFT:
x.Value = -1.0;
y.Value = 0.0;
break;
case SDL_HAT_LEFTDOWN:
x.Value = -1.0;
y.Value = 1.0;
break;
case SDL_HAT_RIGHTUP:
x.Value = 1.0;
y.Value = -1.0;
break;
case SDL_HAT_RIGHT:
x.Value = 1.0;
y.Value = 0.0;
break;
case SDL_HAT_RIGHTDOWN:
x.Value = 1.0;
y.Value = 1.0;
break;
case SDL_HAT_UP:
x.Value = 0.0;
y.Value = -1.0;
break;
case SDL_HAT_DOWN:
x.Value = 0.0;
y.Value = 1.0;
break;
default:
x.Value = 0.0;
y.Value = 0.0;
break;
}
if(i < 4)
{
Joy_GenerateButtonEvents(x.ButtonValue, buttonstate, 4, KEY_JOYPOV1_UP + i*4);
x.ButtonValue = buttonstate;
}
} }
} }
@ -140,6 +226,7 @@ protected:
float Multiplier; float Multiplier;
EJoyAxis GameAxis; EJoyAxis GameAxis;
double Value; double Value;
BYTE ButtonValue;
}; };
static const EJoyAxis DefaultAxes[5]; static const EJoyAxis DefaultAxes[5];
@ -148,6 +235,8 @@ protected:
float Multiplier; float Multiplier;
TArray<AxisInfo> Axes; TArray<AxisInfo> Axes;
int NumAxes;
int NumHats;
}; };
const EJoyAxis SDLInputJoystick::DefaultAxes[5] = {JOYAXIS_Side, JOYAXIS_Forward, JOYAXIS_Pitch, JOYAXIS_Yaw, JOYAXIS_Up}; const EJoyAxis SDLInputJoystick::DefaultAxes[5] = {JOYAXIS_Side, JOYAXIS_Forward, JOYAXIS_Pitch, JOYAXIS_Yaw, JOYAXIS_Up};