]> Shamusworld >> Repos - virtualjaguar/commitdiff
Added analog axis support to Gamepad module.
authorShamus Hammons <jlhamm@acm.org>
Sun, 24 Feb 2013 03:31:41 +0000 (21:31 -0600)
committerShamus Hammons <jlhamm@acm.org>
Sun, 24 Feb 2013 03:31:41 +0000 (21:31 -0600)
This is necessary because some gamepads that have directional pads don't
report as a hat (which you would expect) but report themselves as
analog axes that provide only the extreme ends of each axis. Such
"digi-log" joysticks should now work and be configurable.

src/gui/controllerwidget.cpp
src/gui/controllerwidget.h
src/gui/gamepad.cpp
src/gui/gamepad.h
src/gui/keygrabber.cpp
src/gui/mainwin.cpp
src/settings.h

index 79e91b602859c25b345b4fe1405db8535e624f8d..0386334a92846cfc21e781c808b21f858101227e 100644 (file)
@@ -44,6 +44,8 @@ char ControllerWidget::keyName2[64][16] = {
 
 char ControllerWidget::hatName[4][16] = { "Up", "Rt", "Dn", "Lf" };
 
+char ControllerWidget::axisName[2][8] = { "+", "-" };
+
 // This is hard-coded crap. It's crap-tastic!
 // These are the positions to draw the button names at, ordered by the BUTTON_* sequence
 // found in joystick.h.
@@ -147,6 +149,11 @@ void ControllerWidget::paintEvent(QPaintEvent * /*event*/)
                        DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1],
                                QString("j%1").arg(hatName[keys[i] & JOY_BUTTON_MASK]));
                }
+               else if (keys[i] & JOY_AXIS)
+               {
+                       DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1],
+                               QString("JA%1%2").arg((keys[i] & JOY_AXISNUM_MASK) >> 1).arg(axisName[keys[i] & JOY_AXISDIR_MASK]));
+               }
 #endif
                else
                        DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], QString("???"));
index eada2d642a53908c97c729bb65624f014c2d91c2..b1065cdffe859b7f8ff25a4f98fbaa6b8e86a71a 100644 (file)
@@ -37,6 +37,7 @@ class ControllerWidget: public QWidget
                static char keyName1[96][16];
                static char keyName2[64][16];
                static char hatName[4][16];
+               static char axisName[2][8];
                static int buttonPos[21][2];
 };
 
index 1ef1a4e78fdd37877c4b26d4c9ac54b0f2810c5a..84307f8ea612e996d9ebcad2a58293efae2e7e23 100644 (file)
 /*static*/ SDL_Joystick * Gamepad::pad[8];
 /*static*/ int Gamepad::numButtons[8];
 /*static*/ int Gamepad::numHats[8];
+/*static*/ int Gamepad::numAxes[8];
 /*static*/ bool Gamepad::button[8][256];
 /*static*/ uint8_t Gamepad::hat[8][32];
+/*static*/ int32_t Gamepad::axis[8][32];
 
 
 Gamepad::Gamepad(void)//: numJoysticks(0)
@@ -54,6 +56,7 @@ void Gamepad::AllocateJoysticks(void)
                {
                        numButtons[i] = SDL_JoystickNumButtons(pad[i]);
                        numHats[i] = SDL_JoystickNumHats(pad[i]);
+                       numAxes[i] = SDL_JoystickNumAxes(pad[i]);
                }
        }
 
@@ -85,6 +88,20 @@ bool Gamepad::GetState(int joystickID, int buttonID)
                uint8_t hatDirection = hatMask[buttonID & JOY_HATBUT_MASK];
                return (hat[joystickID][hatNumber] & hatDirection ? true : false);
        }
+       else if (buttonID & JOY_AXIS)
+       {
+               int axisNum = (buttonID & JOY_AXISNUM_MASK) >> 1;
+               int direction = (buttonID & JOY_AXISDIR_MASK);
+
+               if (axis[joystickID][axisNum] != 0)
+               {
+                       if (axis[joystickID][axisNum] > 0 && (direction == 0))
+                               return true;
+
+                       if (axis[joystickID][axisNum] < 0 && (direction == 1))
+                               return true;
+               }
+       }
 
        // Default == failure
        return false;
@@ -111,6 +128,18 @@ int Gamepad::CheckButtonPressed(void)
                        if (hat[i][j])
                                return (JOY_HAT | hatNum[hat[i][j]]);
                }
+
+               for(int j=0; j<numAxes[i]; j++)
+               {
+                       // We encode these as axis # (in bits 1-15), up or down in bit 0.
+//                     if (axis[i][j] > 0)
+                       if (axis[i][j] > 32000)
+                               return (JOY_AXIS | (j << 1) | 0);
+
+//                     if (axis[i][j] < 0)
+                       if (axis[i][j] < -32000)
+                               return (JOY_AXIS | (j << 1) | 1);
+               }
        }
 
        return -1;
@@ -143,6 +172,9 @@ void Gamepad::Update(void)
 
                for(int j=0; j<numHats[i]; j++)
                        hat[i][j] = SDL_JoystickGetHat(pad[i], j);
+
+               for(int j=0; j<numAxes[i]; j++)
+                       axis[i][j] = SDL_JoystickGetAxis(pad[i], j);
        }
 }
 
index 6b4993a8d163be76ad7ae92f2c4d2e4dbdae3f7f..43779c150464c4c19f2c92cf87d8dac07adfd48f 100644 (file)
 #define JOY_KEY                        0x000000
 #define JOY_BUTTON             0x010000
 #define JOY_HAT                        0x020000
+#define JOY_AXIS               0x040000
 
-#define        JOY_TYPE_MASK   0xFF0000
-#define JOY_BUTTON_MASK 0x00FFFF
-#define JOY_HATNUM_MASK        0x0000F8
-#define JOY_HATBUT_MASK        0x000007
+#define        JOY_TYPE_MASK           0xFF0000
+#define JOY_BUTTON_MASK                0x00FFFF
+#define JOY_HATNUM_MASK                0x0000F8
+#define JOY_HATBUT_MASK                0x000007
+#define JOY_AXISNUM_MASK       0x00FFFE
+#define JOY_AXISDIR_MASK       0x000001
 
 #include <stdint.h>
 #include "SDL.h"
@@ -45,9 +48,11 @@ class Gamepad
                static int numJoysticks;
                static SDL_Joystick * pad[8];
                static int numButtons[8];
+               static int numAxes[8];
                static int numHats[8];
                static bool button[8][256];
                static uint8_t hat[8][32];
+               static int32_t axis[8][32];
 };
 
 #endif // __GAMEPAD_H__
index 7efe537b1f9a0ecb8e0b12aab446b7a6b00aee3d..b9b285c5248574f47355dfbfd14bbdb5942ddeb7 100644 (file)
@@ -70,7 +70,7 @@ void KeyGrabber::CheckGamepad(void)
        {
                button = Gamepad::CheckButtonPressed();
 
-               if  (button == -1)
+               if (button == -1)
                        return;
 
                buttonDown = true;
index 87e6e3fa16642e78b0cfb864c04961ec0ec6936b..0e19488f9eeed77ee44423c24be5a07ded56de65 100644 (file)
@@ -346,8 +346,6 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
                // Prevent the scanner from running...
                return;
        }
-//     else
-//             memcpy(jagMemSpace + 0xE00000, jaguarBootROM, 0x20000); // Otherwise, use the stock BIOS
 
        // Run the scanner if nothing passed in and *not* Alpine mode...
        // NB: Really need to look into caching the info scanned in here...
@@ -523,10 +521,10 @@ void MainWin::HandleGamepads(void)
 
        for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)
        {
-               if (vjs.p1KeyBindings[i] & (JOY_BUTTON | JOY_HAT))
+               if (vjs.p1KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))
                        joypad_0_buttons[i] = (Gamepad::GetState(0, vjs.p1KeyBindings[i]) ? 0x01 : 0x00);
 
-               if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT))
+               if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))
                        joypad_1_buttons[i] = (Gamepad::GetState(1, vjs.p2KeyBindings[i]) ? 0x01 : 0x00);
        }
 }
index bb160d5e9ee4c777f9f323a4b3d611b275dbe20e..9824e40a983c07e5c5afd13ac4b1a94440b982cf 100644 (file)
@@ -58,11 +58,6 @@ enum { RT_NORMAL = 0, RT_TV = 1 };
 
 enum { BT_K_SERIES, BT_M_SERIES, BT_STUBULATOR_1, BT_STUBULATOR_2 };
 
-// Exported functions
-
-//void LoadVJSettings(void);
-//void SaveVJSettings(void);
-
 // Exported variables
 
 extern VJSettings vjs;