From 192839a436fbf559812a2ee578eac1310527d5b0 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 29 Apr 2012 00:53:27 +0000 Subject: [PATCH] - 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) --- src/sdl/i_joystick.cpp | 97 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/src/sdl/i_joystick.cpp b/src/sdl/i_joystick.cpp index 44cbc08439..e39482c474 100644 --- a/src/sdl/i_joystick.cpp +++ b/src/sdl/i_joystick.cpp @@ -1,5 +1,6 @@ #include +#include "doomdef.h" #include "m_joy.h" class SDLInputJoystick: public IJoystickConfig @@ -9,7 +10,12 @@ public: { Device = SDL_JoystickOpen(DeviceIndex); if(Device != NULL) + { + NumAxes = SDL_JoystickNumAxes(Device); + NumHats = SDL_JoystickNumHats(Device); + SetDefaultConfig(); + } } ~SDLInputJoystick() { @@ -38,7 +44,7 @@ public: int GetNumAxes() { - return SDL_JoystickNumAxes(Device); + return NumAxes + NumHats*2; } float GetAxisDeadZone(int axis) { @@ -95,10 +101,14 @@ public: for(int i = 0;i < GetNumAxes();i++) { 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.Multiplier = 1.0f; info.Value = 0.0; + info.ButtonValue = 0; if(i >= 5) info.GameAxis = JOYAXIS_None; else @@ -125,10 +135,86 @@ public: 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 = 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; EJoyAxis GameAxis; double Value; + BYTE ButtonValue; }; static const EJoyAxis DefaultAxes[5]; @@ -148,6 +235,8 @@ protected: float Multiplier; TArray Axes; + int NumAxes; + int NumHats; }; const EJoyAxis SDLInputJoystick::DefaultAxes[5] = {JOYAXIS_Side, JOYAXIS_Forward, JOYAXIS_Pitch, JOYAXIS_Yaw, JOYAXIS_Up};