#include <SDL.h>
#include <QApplication>
+#include "gamepad.h"
#include "log.h"
#include "mainwin.h"
#include "settings.h"
{
WriteLog("VJ: SDL (joystick, audio) successfully initialized.\n");
App app(argc, argv); // Declare an instance of the application
+ Gamepad::AllocateJoysticks();
retVal = app.exec(); // And run it!
+ Gamepad::DeallocateJoysticks();
// Free SDL components last...!
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_AUDIO);
connect(redefineAll, SIGNAL(clicked()), this, SLOT(DefineAllKeys()));
}
+
ControllerTab::~ControllerTab()
{
}
+
void ControllerTab::DefineAllKeys(void)
{
// char jagButtonName[21][10] = { "Up", "Down", "Left", "Right",
controllerWidget->update();
}
}
+
#include "controllerwidget.h"
#include "joystick.h"
+#include "gamepad.h"
#include "keygrabber.h"
+
// These tables are used to convert Qt keycodes into human readable form. Note that
// a lot of these are just filler.
char ControllerWidget::keyName1[96][16] = {
"F14", "F15", "F16"
};
+char ControllerWidget::hatName[4][16] = { "Up", "Rt", "Dn", "Lf" };
+
// 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.
{ 234, 31 }, { 216, 51 }, { 199, 71 }, { 164-11, 101-30 }, { 141-11, 108+13-30 }
};
+
ControllerWidget::ControllerWidget(QWidget * parent/*= 0*/): QWidget(parent),
controllerPic(":/res/controller.png"), widgetSize(controllerPic.size()),
keyToHighlight(-1), mouseDown(false)
setMouseTracking(true);
}
+
ControllerWidget::~ControllerWidget()
{
}
+
QSize ControllerWidget::sizeHint(void) const
{
return widgetSize;
}
+
QSizePolicy ControllerWidget::sizePolicy(void) const
{
return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}
+
void ControllerWidget::paintEvent(QPaintEvent * /*event*/)
{
QPainter painter(this);
DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1],
QString(keyName2[keys[i] & 0x3F]));
}
+#if 1
+ else if (keys[i] & JOY_BUTTON)
+ {
+ DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1],
+ QString("JB%1").arg(keys[i] & JOY_BUTTON_MASK));
+ }
+ else if (keys[i] & JOY_HAT)
+ {
+ DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1],
+ QString("j%1").arg(hatName[keys[i] & JOY_BUTTON_MASK]));
+ }
+#endif
else
DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], QString("???"));
}
}
+
void ControllerWidget::mousePressEvent(QMouseEvent * /*event*/)
{
mouseDown = true;
update();
}
+
void ControllerWidget::mouseReleaseEvent(QMouseEvent * /*event*/)
{
mouseDown = false;
update();
}
+
void ControllerWidget::mouseMoveEvent(QMouseEvent * event)
{
if (mouseDown)
update();
}
+
void ControllerWidget::leaveEvent(QEvent * /*event*/)
{
keyToHighlight = -1;
update();
}
+
void ControllerWidget::DrawBorderedText(QPainter & painter, int x, int y, QString text)
{
// Text is drawn centered at (x, y) as well, using a bounding rect for the purpose.
rect.moveCenter(QPoint(x, y));
painter.drawText(rect, Qt::AlignCenter, text);
}
+
// Class data
static char keyName1[96][16];
static char keyName2[64][16];
+ static char hatName[4][16];
static int buttonPos[21][2];
};
// Need to set the size as well...
// resize(560, 480);
- QFont fixedFont("Lucida Console", 10, QFont::Normal);
+ QFont fixedFont("Lucida Console", 8, QFont::Normal);
text->setFont(fixedFont);
//// layout->setSizeConstraint(QLayout::SetFixedSize);
setLayout(layout);
//
#include "gamepad.h"
+#include "log.h"
+
+
+// Class member initialization
+/*static*/ int Gamepad::numJoysticks = 0;
+/*static*/ SDL_Joystick * Gamepad::pad[8];
+/*static*/ int Gamepad::numButtons[8];
+/*static*/ int Gamepad::numHats[8];
+/*static*/ bool Gamepad::button[8][256];
+/*static*/ uint8_t Gamepad::hat[8][32];
+
+
+Gamepad::Gamepad(void)//: numJoysticks(0)
+{
+ AllocateJoysticks();
+}
+
+
+Gamepad::~Gamepad(void)
+{
+ DeallocateJoysticks();
+}
+
+
+void Gamepad::AllocateJoysticks(void)
+{
+// DeallocateJoysticks();
+ numJoysticks = SDL_NumJoysticks();
+
+ // Sanity check
+ if (numJoysticks > 8)
+ numJoysticks = 8;
+
+ for(int i=0; i<numJoysticks; i++)
+ {
+ pad[i] = SDL_JoystickOpen(i);
+ numButtons[i] = numHats[i] = 0;
+
+ if (pad[i])
+ {
+ numButtons[i] = SDL_JoystickNumButtons(pad[i]);
+ numHats[i] = SDL_JoystickNumHats(pad[i]);
+ }
+ }
+
+ WriteLog("Gamepad: Found %u joystick%s.\n", numJoysticks, (numJoysticks == 1 ? "" : "s"));
+}
+
+
+void Gamepad::DeallocateJoysticks(void)
+{
+ for(int i=0; i<numJoysticks; i++)
+ SDL_JoystickClose(pad[i]);
+}
bool Gamepad::GetState(int joystickID, int buttonID)
{
+ uint8_t hatMask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+
if (buttonID & JOY_BUTTON)
{
// Handle SDL button
+ int buttonNum = (buttonID & JOY_BUTTON_MASK);
+// SDL_JoystickGetButton(pad[joystickID]);
+ return button[joystickID][buttonNum];
}
else if (buttonID & JOY_HAT)
{
// Handle SDL hats
int hatNumber = (buttonID & JOY_HATNUM_MASK) >> 3;
- int hatDirection = hatMask[buttonID & JOY_HATBUT_MASK];
+ uint8_t hatDirection = hatMask[buttonID & JOY_HATBUT_MASK];
+// uint8 direction = SDL_JoystickGetHat(pad[joystickID], hatNumber);
+// return (
+ return (hat[joystickID][hatNumber] & hatDirection ? true : false);
}
// Default == failure
}
+int Gamepad::CheckButtonPressed(void)
+{
+ // This translates the hat direction to a mask index.
+ int hatNum[16] = { -1, 0, 1, -1, 2, -1, -1, -1,
+ 3, -1, -1, -1, -1, -1, -1, -1 };
+
+ // Return single button ID being pressed (if any)
+ for(int i=0; i<numJoysticks; i++)
+ {
+ for(int j=0; j<numButtons[i]; j++)
+ {
+ if (button[i][j])
+ return (JOY_BUTTON | j);
+ }
+
+ for(int j=0; j<numHats[i]; j++)
+ {
+ if (hat[i][j])
+ return (JOY_HAT | hatNum[hat[i][j]]);
+ }
+ }
+
+ return -1;
+}
+
+
int Gamepad::GetButtonID(void)
{
// Return single button ID being pressed (if any)
+ return -1;
}
int Gamepad::GetJoystickID(void)
{
// Return joystick ID of button being pressed (if any)
+ return -1;
+}
+
+
+void Gamepad::Update(void)
+{
+// SDL_PollEvent(&event);
+ SDL_JoystickUpdate();
+
+ for(int i=0; i<numJoysticks; i++)
+ {
+ for(int j=0; j<numButtons[i]; j++)
+ button[i][j] = SDL_JoystickGetButton(pad[i], j);
+
+ for(int j=0; j<numHats[i]; j++)
+ hat[i][j] = SDL_JoystickGetHat(pad[i], j);
+ }
+}
+
+
+#if 0
+// Need to test this. It may be that the only time joysticks are detected is
+// when the program is first run. That would suck.
+void Gamepad::CheckConsistency(void)
+{
+ int currentNumJoysticks = SDL_NumJoysticks();
+
+ // Check to see if the # of joysticks reported by SDL changed
+ if (currentNumJoysticks == numJoysticks)
+ return;
+
+ // Either one or more joysticks were plugged in, or removed. Fix up our
+ // internal states to reflect this.
+
+
}
+#endif
#ifndef __GAMEPAD_H__
#define __GAMEPAD_H__
-#define JOY_BUTTON 0x0100
-#define JOY_HAT 0x0200
+#define JOY_KEY 0x000000
+#define JOY_BUTTON 0x010000
+#define JOY_HAT 0x020000
-#define JOY_TYPE_MASK 0xFF00
-#define JOY_HATNUM_MASK 0x00F8
-#define JOY_HATBUT_MASK 0x0007
+#define JOY_TYPE_MASK 0xFF0000
+#define JOY_BUTTON_MASK 0x00FFFF
+#define JOY_HATNUM_MASK 0x0000F8
+#define JOY_HATBUT_MASK 0x000007
#include <stdint.h>
-
-uint8_t hatMask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+#include "SDL.h"
// buttonID is the combination of the type (BUTTON, HAT) and the button #
// (0-255 for buttons, 0-31 for hats). Hats also have 0-7 for a button #
Gamepad();
~Gamepad();
- bool GetState(int joystickID, int buttonID);
- int GetButtonID(void);
- int GetJoystickID(void);
+ // Class methods...
+ static void AllocateJoysticks(void);
+ static void DeallocateJoysticks(void);
+ static bool GetState(int joystickID, int buttonID);
+ static int CheckButtonPressed(void);
+ static int GetButtonID(void);
+ static int GetJoystickID(void);
+ static void Update(void);
+
+ // Support up to 8 gamepads
+ static int numJoysticks;
+ static SDL_Joystick * pad[8];
+ static int numButtons[8];
+ static int numHats[8];
+ static bool button[8][256];
+ static uint8_t hat[8][32];
};
#endif // __GAMEPAD_H__
//
#include "keygrabber.h"
+#include "gamepad.h"
-KeyGrabber::KeyGrabber(QWidget * parent/*= 0*/): QDialog(parent)
+KeyGrabber::KeyGrabber(QWidget * parent/*= 0*/): QDialog(parent),
+ label(new QLabel), timer(new QTimer), buttonDown(false)
{
- label = new QLabel(this);
+// label = new QLabel(this);
QVBoxLayout * mainLayout = new QVBoxLayout;
mainLayout->addWidget(label);
setLayout(mainLayout);
setWindowTitle(tr("Grab"));
+ connect(timer, SIGNAL(timeout()), this, SLOT(CheckGamepad()));
+ timer->setInterval(100);
+ timer->start();
// Will this make Mac OSX work???
setFocusPolicy(Qt::StrongFocus);
}
+
KeyGrabber::~KeyGrabber()
{
+ timer->stop();
}
-//void KeyGrabber::SetText(QString keyText)
+
void KeyGrabber::SetKeyText(int keyNum)
{
char jagButtonName[21][10] = { "Up", "Down", "Left", "Right",
label->setText(text);
}
+
void KeyGrabber::keyPressEvent(QKeyEvent * e)
{
key = e->key();
if (key != Qt::Key_Alt)
accept();
}
+
+
+void KeyGrabber::CheckGamepad(void)
+{
+ // How do we determine which joystick it is, if more than one?
+ // Possibly by a combobox selecting the stick you want to configure...
+ Gamepad::Update();
+
+ if (!buttonDown)
+ {
+ button = Gamepad::CheckButtonPressed();
+
+ if (button == -1)
+ return;
+
+ buttonDown = true;
+ }
+ else
+ {
+ if (Gamepad::CheckButtonPressed() == button)
+ return;
+
+ key = button;
+ accept();
+ buttonDown = false;
+ }
+}
+
protected:
void keyPressEvent(QKeyEvent *);
-private:
+ private slots:
+ void CheckGamepad();
+
+ private:
QLabel * label;
+ QTimer * timer;
+ bool buttonDown;
+ int button;
public:
int key;
#include "SDL.h"
#include "app.h"
-#include "glwidget.h"
#include "about.h"
-#include "help.h"
-#include "settings.h"
-#include "filepicker.h"
#include "configdialog.h"
+#include "filepicker.h"
+#include "gamepad.h"
#include "generaltab.h"
+#include "glwidget.h"
+#include "help.h"
+#include "settings.h"
#include "version.h"
#include "debug/cpubrowser.h"
#include "debug/m68kdasmbrowser.h"
}
+void MainWin::HandleGamepads(void)
+{
+ Gamepad::Update();
+
+ for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)
+ {
+ if (vjs.p1KeyBindings[i] & (JOY_BUTTON | JOY_HAT))
+ joypad_0_buttons[i] = (Gamepad::GetState(0, vjs.p1KeyBindings[i]) ? 0x01 : 0x00);
+
+ if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT))
+ joypad_1_buttons[i] = (Gamepad::GetState(1, vjs.p2KeyBindings[i]) ? 0x01 : 0x00);
+ }
+}
+
+
void MainWin::Open(void)
{
}
else
{
// Otherwise, run the Jaguar simulation
+ HandleGamepads();
JaguarExecuteNew();
}
private:
void HandleKeys(QKeyEvent *, bool);
+ void HandleGamepads(void);
void SetFullScreen(bool state = true);
void ResizeMainWindow(void);
void ReadSettings(void);