1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-22 13:48:06 +02:00

Added key repeat on analog sticks and hats

This commit is contained in:
Paul Cercueil 2014-02-23 17:00:12 +01:00
parent c19e78951d
commit 7777b9edde
4 changed files with 93 additions and 31 deletions

View File

@ -257,7 +257,7 @@ GMenu2X::GMenu2X()
if (confInt["backlightTimeout"] > 0) if (confInt["backlightTimeout"] > 0)
PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] ); PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
setInputSpeed(); SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, INPUT_KEY_REPEAT_RATE);
#ifdef ENABLE_CPUFREQ #ifdef ENABLE_CPUFREQ
setClock(confInt["menuClock"]); setClock(confInt["menuClock"]);
#endif #endif
@ -1038,10 +1038,6 @@ typedef struct {
unsigned short remocon; unsigned short remocon;
} MMSP2ADC; } MMSP2ADC;
void GMenu2X::setInputSpeed() {
SDL_EnableKeyRepeat(250, 150);
}
#ifdef ENABLE_CPUFREQ #ifdef ENABLE_CPUFREQ
void GMenu2X::setClock(unsigned mhz) { void GMenu2X::setClock(unsigned mhz) {
mhz = constrain(mhz, cpuFreqMin, confInt["maxClock"]); mhz = constrain(mhz, cpuFreqMin, confInt["maxClock"]);

View File

@ -182,8 +182,6 @@ public:
unsigned getDefaultAppClock() { return cpuFreqAppDefault; } unsigned getDefaultAppClock() { return cpuFreqAppDefault; }
#endif #endif
void setInputSpeed();
/** /**
* Requests that the given application be launched. * Requests that the given application be launched.
* The launch won't happen immediately; it will happen after control * The launch won't happen immediately; it will happen after control

View File

@ -51,6 +51,7 @@ InputManager::InputManager()
for (i = 0; i < SDL_NumJoysticks(); i++) { for (i = 0; i < SDL_NumJoysticks(); i++) {
struct Joystick joystick = { struct Joystick joystick = {
SDL_JoystickOpen(i), false, false, false, false, SDL_JoystickOpen(i), false, false, false, false,
SDL_HAT_CENTERED, nullptr,
}; };
joysticks.push_back(joystick); joysticks.push_back(joystick);
} }
@ -151,22 +152,28 @@ bool InputManager::getButton(Button *button, bool wait) {
source = KEYBOARD; source = KEYBOARD;
break; break;
#ifndef SDL_JOYSTICK_DISABLED #ifndef SDL_JOYSTICK_DISABLED
case SDL_JOYHATMOTION: case SDL_JOYHATMOTION: {
switch (event.jhat.value) { Joystick *joystick = &joysticks[event.jaxis.which];
case SDL_HAT_CENTERED: joystick->hatState = event.jhat.value;
return false;
case SDL_HAT_UP: switch (event.jhat.value) {
*button = UP; case SDL_HAT_CENTERED:
break; stopTimer(joystick);
case SDL_HAT_DOWN: return false;
*button = DOWN; case SDL_HAT_UP:
break; *button = UP;
case SDL_HAT_LEFT: break;
*button = LEFT; case SDL_HAT_DOWN:
break; *button = DOWN;
case SDL_HAT_RIGHT: break;
*button = RIGHT; case SDL_HAT_LEFT:
break; *button = LEFT;
break;
case SDL_HAT_RIGHT:
*button = RIGHT;
break;
}
startTimer(joystick);
} }
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONDOWN:
source = JOYSTICK; source = JOYSTICK;
@ -179,7 +186,8 @@ bool InputManager::getButton(Button *button, bool wait) {
if (axis > 1) if (axis > 1)
return false; return false;
bool *axisState = joysticks[event.jaxis.which].axisState[axis]; Joystick *joystick = &joysticks[event.jaxis.which];
bool *axisState = joystick->axisState[axis];
if (event.jaxis.value < -20000) { if (event.jaxis.value < -20000) {
if (axisState[AXIS_STATE_NEGATIVE]) if (axisState[AXIS_STATE_NEGATIVE])
@ -194,9 +202,17 @@ bool InputManager::getButton(Button *button, bool wait) {
axisState[AXIS_STATE_POSITIVE] = true; axisState[AXIS_STATE_POSITIVE] = true;
*button = axis ? DOWN : RIGHT; *button = axis ? DOWN : RIGHT;
} else { } else {
bool *otherAxisState = joystick->axisState[!axis];
if (!otherAxisState[AXIS_STATE_NEGATIVE] &&
!otherAxisState[AXIS_STATE_POSITIVE] && (
axisState[AXIS_STATE_NEGATIVE] ||
axisState[AXIS_STATE_POSITIVE]))
stopTimer(joystick);
axisState[0] = axisState[1] = false; axisState[0] = axisState[1] = false;
return false; return false;
} }
startTimer(joystick);
break; break;
} }
#endif #endif
@ -259,3 +275,45 @@ bool InputManager::getButton(Button *button, bool wait) {
return true; return true;
} }
Uint32 keyRepeatCallback(Uint32 timeout __attribute__((unused)), void *d)
{
struct Joystick *joystick = (struct Joystick *) d;
Uint8 hatState = joystick->hatState;
if (joystick->axisState[1][AXIS_STATE_NEGATIVE])
hatState |= SDL_HAT_UP;
else if (joystick->axisState[1][AXIS_STATE_POSITIVE])
hatState |= SDL_HAT_DOWN;
if (joystick->axisState[0][AXIS_STATE_NEGATIVE])
hatState |= SDL_HAT_LEFT;
else if (joystick->axisState[0][AXIS_STATE_POSITIVE])
hatState |= SDL_HAT_RIGHT;
SDL_JoyHatEvent e = {
.type = SDL_JOYHATMOTION,
.which = (Uint8) SDL_JoystickIndex(joystick->joystick),
.hat = 0,
.value = hatState,
};
SDL_PushEvent((SDL_Event *) &e);
return INPUT_KEY_REPEAT_RATE;
}
void InputManager::startTimer(Joystick *joystick)
{
if (joystick->timer)
return;
joystick->timer = SDL_AddTimer(INPUT_KEY_REPEAT_DELAY,
keyRepeatCallback, joystick);
}
void InputManager::stopTimer(Joystick *joystick)
{
if (joystick->timer) {
SDL_RemoveTimer(joystick->timer);
joystick->timer = nullptr;
}
}

View File

@ -25,6 +25,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#define INPUT_KEY_REPEAT_DELAY 250
#define INPUT_KEY_REPEAT_RATE 150
class Menu; class Menu;
enum EventCode { enum EventCode {
@ -34,6 +37,17 @@ enum EventCode {
REPAINT_MENU, REPAINT_MENU,
}; };
#ifndef SDL_JOYSTICK_DISABLED
#define AXIS_STATE_POSITIVE 0
#define AXIS_STATE_NEGATIVE 1
struct Joystick {
SDL_Joystick *joystick;
bool axisState[2][2];
Uint8 hatState;
SDL_TimerID timer;
};
#endif
class InputManager { class InputManager {
public: public:
enum Button { enum Button {
@ -66,14 +80,10 @@ private:
ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE]; ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE];
#ifndef SDL_JOYSTICK_DISABLED #ifndef SDL_JOYSTICK_DISABLED
#define AXIS_STATE_POSITIVE 0
#define AXIS_STATE_NEGATIVE 1
struct Joystick {
SDL_Joystick *joystick;
bool axisState[2][2];
};
std::vector<Joystick> joysticks; std::vector<Joystick> joysticks;
void startTimer(Joystick *joystick);
void stopTimer(Joystick *joystick);
#endif #endif
}; };