1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-25 19:05:21 +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)
PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
setInputSpeed();
SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, INPUT_KEY_REPEAT_RATE);
#ifdef ENABLE_CPUFREQ
setClock(confInt["menuClock"]);
#endif
@ -1038,10 +1038,6 @@ typedef struct {
unsigned short remocon;
} MMSP2ADC;
void GMenu2X::setInputSpeed() {
SDL_EnableKeyRepeat(250, 150);
}
#ifdef ENABLE_CPUFREQ
void GMenu2X::setClock(unsigned mhz) {
mhz = constrain(mhz, cpuFreqMin, confInt["maxClock"]);

View File

@ -182,8 +182,6 @@ public:
unsigned getDefaultAppClock() { return cpuFreqAppDefault; }
#endif
void setInputSpeed();
/**
* Requests that the given application be launched.
* 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++) {
struct Joystick joystick = {
SDL_JoystickOpen(i), false, false, false, false,
SDL_HAT_CENTERED, nullptr,
};
joysticks.push_back(joystick);
}
@ -151,22 +152,28 @@ bool InputManager::getButton(Button *button, bool wait) {
source = KEYBOARD;
break;
#ifndef SDL_JOYSTICK_DISABLED
case SDL_JOYHATMOTION:
switch (event.jhat.value) {
case SDL_HAT_CENTERED:
return false;
case SDL_HAT_UP:
*button = UP;
break;
case SDL_HAT_DOWN:
*button = DOWN;
break;
case SDL_HAT_LEFT:
*button = LEFT;
break;
case SDL_HAT_RIGHT:
*button = RIGHT;
break;
case SDL_JOYHATMOTION: {
Joystick *joystick = &joysticks[event.jaxis.which];
joystick->hatState = event.jhat.value;
switch (event.jhat.value) {
case SDL_HAT_CENTERED:
stopTimer(joystick);
return false;
case SDL_HAT_UP:
*button = UP;
break;
case SDL_HAT_DOWN:
*button = DOWN;
break;
case SDL_HAT_LEFT:
*button = LEFT;
break;
case SDL_HAT_RIGHT:
*button = RIGHT;
break;
}
startTimer(joystick);
}
case SDL_JOYBUTTONDOWN:
source = JOYSTICK;
@ -179,7 +186,8 @@ bool InputManager::getButton(Button *button, bool wait) {
if (axis > 1)
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 (axisState[AXIS_STATE_NEGATIVE])
@ -194,9 +202,17 @@ bool InputManager::getButton(Button *button, bool wait) {
axisState[AXIS_STATE_POSITIVE] = true;
*button = axis ? DOWN : RIGHT;
} 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;
return false;
}
startTimer(joystick);
break;
}
#endif
@ -259,3 +275,45 @@ bool InputManager::getButton(Button *button, bool wait) {
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 <vector>
#define INPUT_KEY_REPEAT_DELAY 250
#define INPUT_KEY_REPEAT_RATE 150
class Menu;
enum EventCode {
@ -34,6 +37,17 @@ enum EventCode {
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 {
public:
enum Button {
@ -66,14 +80,10 @@ private:
ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE];
#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;
void startTimer(Joystick *joystick);
void stopTimer(Joystick *joystick);
#endif
};