[Qt] Joystick support!
This commit is contained in:
parent
463a326a44
commit
fe8a42b4b2
|
@ -1,12 +1,17 @@
|
|||
#include <QtWidgets>
|
||||
#include <QVector>
|
||||
#include "SDL.h"
|
||||
#include "qinputinterface.h"
|
||||
#include "burner.h"
|
||||
|
||||
QInputInterface *qInput = nullptr;
|
||||
|
||||
static QVector<SDL_Joystick*> qJoysticks;
|
||||
|
||||
int QtKToFBAK(int key);
|
||||
static char qKeyboardState[QINPUT_MAX_KEYS] = { 0 };
|
||||
static bool bKeyboardRead = false;
|
||||
static bool bJoystickRead = false;
|
||||
|
||||
int QtInputSetCooperativeLevel(bool bExclusive, bool)
|
||||
{
|
||||
|
@ -21,6 +26,7 @@ int QtInputExit()
|
|||
delete qInput;
|
||||
qInput = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -31,23 +37,29 @@ int QtInputInit()
|
|||
qInput->install();
|
||||
memset(qKeyboardState, 0, QINPUT_MAX_KEYS);
|
||||
bKeyboardRead = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QtInputStart()
|
||||
{
|
||||
bKeyboardRead = false;
|
||||
bJoystickRead = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ReadJoystick()
|
||||
{
|
||||
if (bJoystickRead)
|
||||
return 0;
|
||||
qInput->joystickUpdate();
|
||||
bJoystickRead = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QtInputJoyAxis(int i, int nAxis)
|
||||
{
|
||||
return 0;
|
||||
return qInput->joystickAxis(i, nAxis);
|
||||
}
|
||||
|
||||
static int ReadKeyboard()
|
||||
|
@ -71,7 +83,37 @@ int QtInputMouseAxis(int i, int nAxis)
|
|||
|
||||
static int JoystickState(int i, int nSubCode)
|
||||
{
|
||||
return 0;
|
||||
if (i >= qInput->joystickCount() || nSubCode < 0)
|
||||
return 0;
|
||||
|
||||
if (nSubCode < 0x10) {
|
||||
const int deadZone = 0x4000;
|
||||
|
||||
int axis = nSubCode / 2;
|
||||
int value = qInput->joystickAxis(i, axis);
|
||||
|
||||
if (nSubCode % 2)
|
||||
return value > deadZone;
|
||||
|
||||
return value < -deadZone;
|
||||
}
|
||||
|
||||
if (nSubCode < 0x20) {
|
||||
const static unsigned mask[4] = { SDL_HAT_LEFT,
|
||||
SDL_HAT_RIGHT,
|
||||
SDL_HAT_UP,
|
||||
SDL_HAT_DOWN };
|
||||
|
||||
int hat = (nSubCode & 0x0F) >> 2;
|
||||
return qInput->joystickHat(i, hat) & mask[nSubCode & 3];
|
||||
}
|
||||
|
||||
if (nSubCode < 0x80)
|
||||
return 0;
|
||||
|
||||
int button = nSubCode - 0x80;
|
||||
|
||||
return qInput->joystickButton(i, button);
|
||||
}
|
||||
|
||||
static int CheckMouseState(unsigned int nSubCode)
|
||||
|
@ -84,15 +126,23 @@ int QtInputState(int nCode)
|
|||
if (nCode < 0)
|
||||
return 0;
|
||||
|
||||
if (nCode < 256) {
|
||||
#if 1
|
||||
if (nCode < 0x100) {
|
||||
if (!bKeyboardRead)
|
||||
ReadKeyboard();
|
||||
return qKeyboardState[nCode & 0xFF];
|
||||
#else
|
||||
return qInput->state(nCode);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (nCode < 0x4000)
|
||||
return 0;
|
||||
|
||||
if (nCode < 0x8000) {
|
||||
if (!bJoystickRead)
|
||||
ReadJoystick();
|
||||
|
||||
int joystick = (nCode - 0x4000) >> 8;
|
||||
return JoystickState(joystick, nCode & 0xFF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -135,6 +185,89 @@ QInputInterface::QInputInterface(QObject *parent) :
|
|||
{
|
||||
memset(m_keys, 0, QINPUT_MAX_KEYS);
|
||||
m_isInitialized = false;
|
||||
joystickInit();
|
||||
}
|
||||
|
||||
bool QInputInterface::joystickInit()
|
||||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
|
||||
qDebug() << "SDL Joystick initialization error!" << SDL_GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
int nJoys = SDL_NumJoysticks();
|
||||
|
||||
m_joysticks.clear();
|
||||
m_joysticks.resize(nJoys);
|
||||
|
||||
for (int i = 0; i < nJoys; i++) {
|
||||
SDL_Joystick *joystick = SDL_JoystickOpen(i);
|
||||
if (joystick == nullptr)
|
||||
qDebug() << "joystick error:" << i;
|
||||
else
|
||||
m_joysticks[i] = joystick;
|
||||
}
|
||||
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QInputInterface::joystickExit()
|
||||
{
|
||||
foreach (SDL_Joystick *joystick, m_joysticks)
|
||||
SDL_JoystickClose(joystick);
|
||||
|
||||
m_joysticks.clear();
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
|
||||
void QInputInterface::joystickUpdate()
|
||||
{
|
||||
SDL_JoystickUpdate();
|
||||
}
|
||||
|
||||
int QInputInterface::joystickHat(int joy, int hat)
|
||||
{
|
||||
if (m_joysticks.empty())
|
||||
return 0;
|
||||
|
||||
if (joy >= m_joysticks.size() || joy < 0)
|
||||
return 0;
|
||||
|
||||
if (hat > SDL_JoystickNumHats(m_joysticks[joy]))
|
||||
return 0;
|
||||
|
||||
return SDL_JoystickGetHat(m_joysticks[joy], hat);
|
||||
}
|
||||
|
||||
int QInputInterface::joystickAxis(int joy, int axis)
|
||||
{
|
||||
if (m_joysticks.empty())
|
||||
return 0;
|
||||
|
||||
if (joy >= m_joysticks.size() || joy < 0)
|
||||
return 0;
|
||||
|
||||
if (axis > SDL_JoystickNumAxes(m_joysticks[joy]))
|
||||
return 0;
|
||||
|
||||
return SDL_JoystickGetAxis(m_joysticks[joy], axis);
|
||||
}
|
||||
|
||||
int QInputInterface::joystickButton(int joy, int button)
|
||||
{
|
||||
if (m_joysticks.empty())
|
||||
return 0;
|
||||
|
||||
if (joy >= m_joysticks.size() || joy < 0)
|
||||
return 0;
|
||||
|
||||
if (button > SDL_JoystickNumButtons(m_joysticks[joy]))
|
||||
return 0;
|
||||
|
||||
return SDL_JoystickGetButton(m_joysticks[joy], button);
|
||||
}
|
||||
|
||||
QInputInterface::~QInputInterface()
|
||||
|
@ -142,6 +275,7 @@ QInputInterface::~QInputInterface()
|
|||
if (m_isInitialized)
|
||||
uninstall();
|
||||
m_onlyInstance = nullptr;
|
||||
joystickExit();
|
||||
}
|
||||
|
||||
QInputInterface *QInputInterface::get(QObject *parent)
|
||||
|
@ -164,6 +298,11 @@ void QInputInterface::uninstall()
|
|||
m_isInitialized = false;
|
||||
}
|
||||
|
||||
int QInputInterface::joystickCount()
|
||||
{
|
||||
return m_joysticks.size();
|
||||
}
|
||||
|
||||
void QInputInterface::snapshot(char *buffer, int keys)
|
||||
{
|
||||
if (keys >= QINPUT_MAX_KEYS)
|
||||
|
@ -182,13 +321,11 @@ bool QInputInterface::eventFilter(QObject *obj, QEvent *event)
|
|||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
//qDebug() << m_timer.elapsed() << "pressed";
|
||||
int fbak = QtKToFBAK(keyEvent->key());
|
||||
if (fbak < QINPUT_MAX_KEYS)
|
||||
m_keys[fbak] = 1;
|
||||
}
|
||||
if (event->type() == QEvent::KeyRelease) {
|
||||
//qDebug() << m_timer.elapsed() << "released";
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
int fbak = QtKToFBAK(keyEvent->key());
|
||||
if (fbak < QINPUT_MAX_KEYS)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#define QINPUTINTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QElapsedTimer>
|
||||
#include <QVector>
|
||||
#include "SDL.h"
|
||||
|
||||
#define QINPUT_MAX_KEYS 256
|
||||
|
||||
|
@ -12,17 +13,22 @@ class QInputInterface : public QObject
|
|||
explicit QInputInterface(QObject *parent = 0);
|
||||
static QInputInterface *m_onlyInstance;
|
||||
char m_keys[QINPUT_MAX_KEYS];
|
||||
QElapsedTimer m_timer;
|
||||
bool m_isInitialized;
|
||||
QVector<SDL_Joystick*> m_joysticks;
|
||||
bool joystickInit();
|
||||
void joystickExit();
|
||||
public:
|
||||
~QInputInterface();
|
||||
static QInputInterface *get(QObject *parent=nullptr);
|
||||
void install();
|
||||
void uninstall();
|
||||
int joystickCount();
|
||||
void joystickUpdate();
|
||||
int joystickHat(int joy, int hat);
|
||||
int joystickAxis(int joy, int axis);
|
||||
int joystickButton(int joy, int button);
|
||||
void snapshot(char *buffer, int keys=QINPUT_MAX_KEYS);
|
||||
int state(int key);
|
||||
signals:
|
||||
public slots:
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue