added SDL controller support
This commit is contained in:
parent
5f99c595af
commit
186dc1bfe9
10 changed files with 420 additions and 64 deletions
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include <SDL_messagebox.h>
|
||||
#include <SDL_timer.h>
|
||||
#include <SDL_thread.h>
|
||||
|
@ -40,6 +41,8 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
typedef void (ALC_APIENTRY *LPALCDEVICEPAUSESOFT) (ALCdevice *device);
|
||||
typedef void (ALC_APIENTRY *LPALCDEVICERESUMESOFT) (ALCdevice *device);
|
||||
|
||||
|
@ -70,6 +73,7 @@ initALCFunctions(ALCdevice *alcDev)
|
|||
#define HAVE_ALC_DEVICE_PAUSE alc.DevicePause
|
||||
|
||||
uint8_t EventThread::keyStates[];
|
||||
EventThread::ControllerState EventThread::gcState;
|
||||
EventThread::JoyState EventThread::joyState;
|
||||
EventThread::MouseState EventThread::mouseState;
|
||||
EventThread::TouchState EventThread::touchState;
|
||||
|
@ -131,9 +135,21 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
|
||||
bool terminate = false;
|
||||
|
||||
SDL_Joystick *js = 0;
|
||||
if (SDL_NumJoysticks() > 0)
|
||||
js = SDL_JoystickOpen(0);
|
||||
std::map<int, SDL_GameController*> controllers;
|
||||
std::map<int, SDL_Joystick*> joysticks;
|
||||
|
||||
for (int i = 0; i < SDL_NumJoysticks(); ++i) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
//Load as game controller
|
||||
SDL_GameController *gc = SDL_GameControllerOpen(i);
|
||||
int id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gc));
|
||||
controllers[id] = gc;
|
||||
} else {
|
||||
//Fall back to joystick
|
||||
SDL_Joystick *js = SDL_JoystickOpen(i);
|
||||
joysticks[SDL_JoystickInstanceID(js)] = js;
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
|
||||
|
@ -145,6 +161,12 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
int winW, winH;
|
||||
int i;
|
||||
|
||||
SDL_Joystick *js;
|
||||
SDL_GameController *gc;
|
||||
int id;
|
||||
std::map<int, SDL_Joystick*>::iterator jsit;
|
||||
std::map<int, SDL_GameController*>::iterator gcit;
|
||||
|
||||
SDL_GetWindowSize(win, &winW, &winH);
|
||||
|
||||
SettingsMenu *sMenu = 0;
|
||||
|
@ -157,7 +179,7 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
break;
|
||||
}
|
||||
|
||||
if (sMenu && sMenu->onEvent(event))
|
||||
if (sMenu && sMenu->onEvent(event, joysticks))
|
||||
{
|
||||
if (sMenu->destroyReq())
|
||||
{
|
||||
|
@ -330,31 +352,64 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
keyStates[event.key.keysym.scancode] = false;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
gcState.buttons[event.cbutton.button] = true;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
gcState.buttons[event.cbutton.button] = false;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
gcState.axes[event.caxis.axis] = event.caxis.value;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
gc = SDL_GameControllerOpen(event.jdevice.which);
|
||||
id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gc));
|
||||
controllers[id] = gc;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
gcit = controllers.find(event.jdevice.which);
|
||||
SDL_GameControllerClose(gcit->second);
|
||||
controllers.erase(gcit);
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN :
|
||||
joyState.buttons[event.jbutton.button] = true;
|
||||
if (joysticks.find(event.jbutton.which) != joysticks.end())
|
||||
joyState.buttons[event.jbutton.button] = true;
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONUP :
|
||||
joyState.buttons[event.jbutton.button] = false;
|
||||
if (joysticks.find(event.jbutton.which) != joysticks.end())
|
||||
joyState.buttons[event.jbutton.button] = false;
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION :
|
||||
joyState.hats[event.jhat.hat] = event.jhat.value;
|
||||
if (joysticks.find(event.jbutton.which) != joysticks.end())
|
||||
joyState.hats[event.jhat.hat] = event.jhat.value;
|
||||
break;
|
||||
|
||||
case SDL_JOYAXISMOTION :
|
||||
joyState.axes[event.jaxis.axis] = event.jaxis.value;
|
||||
if (joysticks.find(event.jbutton.which) != joysticks.end())
|
||||
joyState.axes[event.jaxis.axis] = event.jaxis.value;
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEADDED :
|
||||
if (event.jdevice.which > 0)
|
||||
if (SDL_IsGameController(event.jdevice.which))
|
||||
break;
|
||||
|
||||
js = SDL_JoystickOpen(0);
|
||||
js = SDL_JoystickOpen(event.jdevice.which);
|
||||
joysticks[SDL_JoystickInstanceID(js)] = js;
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEREMOVED :
|
||||
resetInputStates();
|
||||
jsit = joysticks.find(event.jdevice.which);
|
||||
if (jsit != joysticks.end()) {
|
||||
SDL_JoystickClose(jsit->second);
|
||||
joysticks.erase(jsit);
|
||||
resetInputStates();
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN :
|
||||
|
@ -442,8 +497,10 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
/* Just in case */
|
||||
rtData.syncPoint.resumeThreads();
|
||||
|
||||
if (SDL_JoystickGetAttached(js))
|
||||
SDL_JoystickClose(js);
|
||||
for (gcit = controllers.begin(); gcit != controllers.end(); ++gcit)
|
||||
SDL_GameControllerClose(gcit->second);
|
||||
for (jsit = joysticks.begin(); jsit != joysticks.end(); ++jsit)
|
||||
SDL_JoystickClose(jsit->second);
|
||||
|
||||
delete sMenu;
|
||||
}
|
||||
|
@ -514,6 +571,7 @@ void EventThread::cleanup()
|
|||
void EventThread::resetInputStates()
|
||||
{
|
||||
memset(&keyStates, 0, sizeof(keyStates));
|
||||
memset(&gcState, 0, sizeof(gcState));
|
||||
memset(&joyState, 0, sizeof(joyState));
|
||||
memset(&mouseState.buttons, 0, sizeof(mouseState.buttons));
|
||||
memset(&touchState, 0, sizeof(touchState));
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <SDL_scancode.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include <SDL_mouse.h>
|
||||
#include <SDL_mutex.h>
|
||||
|
||||
|
@ -46,6 +47,12 @@ union SDL_Event;
|
|||
class EventThread
|
||||
{
|
||||
public:
|
||||
struct ControllerState
|
||||
{
|
||||
int axes[SDL_CONTROLLER_AXIS_MAX];
|
||||
bool buttons[SDL_CONTROLLER_BUTTON_MAX];
|
||||
};
|
||||
|
||||
struct JoyState
|
||||
{
|
||||
int axes[256];
|
||||
|
@ -72,6 +79,7 @@ public:
|
|||
};
|
||||
|
||||
static uint8_t keyStates[SDL_NUM_SCANCODES];
|
||||
static ControllerState gcState;
|
||||
static JoyState joyState;
|
||||
static MouseState mouseState;
|
||||
static TouchState touchState;
|
||||
|
|
|
@ -100,6 +100,56 @@ struct KbBinding : public Binding
|
|||
SDL_Scancode source;
|
||||
};
|
||||
|
||||
/* Controller button binding */
|
||||
struct GcButtonBinding : public Binding
|
||||
{
|
||||
GcButtonBinding() {}
|
||||
|
||||
bool sourceActive() const
|
||||
{
|
||||
return EventThread::gcState.buttons[source];
|
||||
}
|
||||
|
||||
bool sourceRepeatable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t source;
|
||||
};
|
||||
|
||||
/* Controller axis binding */
|
||||
struct GcAxisBinding : public Binding
|
||||
{
|
||||
GcAxisBinding() {}
|
||||
|
||||
GcAxisBinding(uint8_t source,
|
||||
AxisDir dir,
|
||||
Input::ButtonCode target)
|
||||
: Binding(target),
|
||||
source(source),
|
||||
dir(dir)
|
||||
{}
|
||||
|
||||
bool sourceActive() const
|
||||
{
|
||||
int val = EventThread::gcState.axes[source];
|
||||
|
||||
if (dir == Negative)
|
||||
return val < -JAXIS_THRESHOLD;
|
||||
else /* dir == Positive */
|
||||
return val > JAXIS_THRESHOLD;
|
||||
}
|
||||
|
||||
bool sourceRepeatable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t source;
|
||||
AxisDir dir;
|
||||
};
|
||||
|
||||
/* Joystick button binding */
|
||||
struct JsButtonBinding : public Binding
|
||||
{
|
||||
|
@ -262,6 +312,8 @@ struct InputPrivate
|
|||
{
|
||||
std::vector<KbBinding> kbStatBindings;
|
||||
std::vector<KbBinding> kbBindings;
|
||||
std::vector<GcAxisBinding> gcABindings;
|
||||
std::vector<GcButtonBinding> gcBBindings;
|
||||
std::vector<JsAxisBinding> jsABindings;
|
||||
std::vector<JsHatBinding> jsHBindings;
|
||||
std::vector<JsButtonBinding> jsBBindings;
|
||||
|
@ -370,6 +422,8 @@ struct InputPrivate
|
|||
void applyBindingDesc(const BDescVec &d)
|
||||
{
|
||||
kbBindings.clear();
|
||||
gcABindings.clear();
|
||||
gcBBindings.clear();
|
||||
jsABindings.clear();
|
||||
jsHBindings.clear();
|
||||
jsBBindings.clear();
|
||||
|
@ -395,6 +449,25 @@ struct InputPrivate
|
|||
|
||||
break;
|
||||
}
|
||||
case CAxis :
|
||||
{
|
||||
GcAxisBinding bind;
|
||||
bind.source = src.d.ja.axis;
|
||||
bind.dir = src.d.ja.dir;
|
||||
bind.target = desc.target;
|
||||
gcABindings.push_back(bind);
|
||||
|
||||
break;
|
||||
}
|
||||
case CButton :
|
||||
{
|
||||
GcButtonBinding bind;
|
||||
bind.source = src.d.jb;
|
||||
bind.target = desc.target;
|
||||
gcBBindings.push_back(bind);
|
||||
|
||||
break;
|
||||
}
|
||||
case JAxis :
|
||||
{
|
||||
JsAxisBinding bind;
|
||||
|
@ -435,6 +508,8 @@ struct InputPrivate
|
|||
appendBindings(msBindings);
|
||||
|
||||
appendBindings(kbBindings);
|
||||
appendBindings(gcABindings);
|
||||
appendBindings(gcBBindings);
|
||||
appendBindings(jsABindings);
|
||||
appendBindings(jsHBindings);
|
||||
appendBindings(jsBBindings);
|
||||
|
|
|
@ -64,24 +64,38 @@ struct JsBindingData
|
|||
}
|
||||
};
|
||||
|
||||
struct GcBindingData
|
||||
{
|
||||
int source;
|
||||
Input::ButtonCode target;
|
||||
|
||||
void add(BDescVec &d) const
|
||||
{
|
||||
SourceDesc src;
|
||||
src.type = CButton;
|
||||
src.d.jb = source;
|
||||
|
||||
BindingDesc desc;
|
||||
desc.src = src;
|
||||
desc.target = target;
|
||||
|
||||
d.push_back(desc);
|
||||
}
|
||||
};
|
||||
|
||||
/* Common */
|
||||
static const KbBindingData defaultKbBindings[] =
|
||||
{
|
||||
{ SDL_SCANCODE_LEFT, Input::Left },
|
||||
{ SDL_SCANCODE_LEFT, Input::Left },
|
||||
{ SDL_SCANCODE_RIGHT, Input::Right },
|
||||
{ SDL_SCANCODE_UP, Input::Up },
|
||||
{ SDL_SCANCODE_DOWN, Input::Down },
|
||||
{ SDL_SCANCODE_H, Input::Left },
|
||||
{ SDL_SCANCODE_L, Input::Right },
|
||||
{ SDL_SCANCODE_K, Input::Up },
|
||||
{ SDL_SCANCODE_J, Input::Down },
|
||||
{ SDL_SCANCODE_Z, Input::Action },
|
||||
{ SDL_SCANCODE_SPACE, Input::Action },
|
||||
{ SDL_SCANCODE_RETURN, Input::Action },
|
||||
{ SDL_SCANCODE_SPACE, Input::Action },
|
||||
{ SDL_SCANCODE_X, Input::Cancel },
|
||||
{ SDL_SCANCODE_ESCAPE, Input::Cancel },
|
||||
{ SDL_SCANCODE_A, Input::Menu },
|
||||
{ SDL_SCANCODE_ESCAPE, Input::Menu },
|
||||
{ SDL_SCANCODE_KP_0, Input::Menu },
|
||||
{ SDL_SCANCODE_RETURN, Input::Menu },
|
||||
{ SDL_SCANCODE_S, Input::Items },
|
||||
{ SDL_SCANCODE_LSHIFT, Input::Run },
|
||||
{ SDL_SCANCODE_LCTRL, Input::Deactivate },
|
||||
|
@ -91,17 +105,28 @@ static const KbBindingData defaultKbBindings[] =
|
|||
|
||||
static elementsN(defaultKbBindings);
|
||||
|
||||
static const JsBindingData defaultJsBindings[] =
|
||||
static const GcBindingData defaultGcBindings[] =
|
||||
{
|
||||
{ 0, Input::Action },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_LEFT, Input::Left },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_RIGHT, Input::Right },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_UP, Input::Up },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_DOWN, Input::Down },
|
||||
{ SDL_CONTROLLER_BUTTON_A, Input::Action },
|
||||
{ SDL_CONTROLLER_BUTTON_B, Input::Cancel },
|
||||
{ SDL_CONTROLLER_BUTTON_X, Input::Run },
|
||||
{ SDL_CONTROLLER_BUTTON_Y, Input::Items },
|
||||
{ SDL_CONTROLLER_BUTTON_START, Input::Menu },
|
||||
{ SDL_CONTROLLER_BUTTON_BACK, Input::Deactivate },
|
||||
{ SDL_CONTROLLER_BUTTON_LEFTSHOULDER, Input::L },
|
||||
{ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, Input::R },
|
||||
};
|
||||
|
||||
static elementsN(defaultJsBindings);
|
||||
static elementsN(defaultGcBindings);
|
||||
|
||||
static void addAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::ButtonCode target)
|
||||
static void addGcAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::ButtonCode target)
|
||||
{
|
||||
SourceDesc src;
|
||||
src.type = JAxis;
|
||||
src.type = CAxis;
|
||||
src.d.ja.axis = axis;
|
||||
src.d.ja.dir = dir;
|
||||
|
||||
|
@ -112,20 +137,6 @@ static void addAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::Button
|
|||
d.push_back(desc);
|
||||
}
|
||||
|
||||
static void addHatBinding(BDescVec &d, uint8_t hat, uint8_t pos, Input::ButtonCode target)
|
||||
{
|
||||
SourceDesc src;
|
||||
src.type = JHat;
|
||||
src.d.jh.hat = hat;
|
||||
src.d.jh.pos = pos;
|
||||
|
||||
BindingDesc desc;
|
||||
desc.src = src;
|
||||
desc.target = target;
|
||||
|
||||
d.push_back(desc);
|
||||
}
|
||||
|
||||
BDescVec genDefaultBindings()
|
||||
{
|
||||
BDescVec d;
|
||||
|
@ -133,23 +144,20 @@ BDescVec genDefaultBindings()
|
|||
for (size_t i = 0; i < defaultKbBindingsN; ++i)
|
||||
defaultKbBindings[i].add(d);
|
||||
|
||||
for (size_t i = 0; i < defaultJsBindingsN; ++i)
|
||||
defaultJsBindings[i].add(d);
|
||||
for (size_t i = 0; i < defaultGcBindingsN; ++i)
|
||||
defaultGcBindings[i].add(d);
|
||||
|
||||
addAxisBinding(d, 0, Negative, Input::Left );
|
||||
addAxisBinding(d, 0, Positive, Input::Right);
|
||||
addAxisBinding(d, 1, Negative, Input::Up );
|
||||
addAxisBinding(d, 1, Positive, Input::Down );
|
||||
|
||||
addHatBinding(d, 0, SDL_HAT_LEFT, Input::Left );
|
||||
addHatBinding(d, 0, SDL_HAT_RIGHT, Input::Right);
|
||||
addHatBinding(d, 0, SDL_HAT_UP, Input::Up );
|
||||
addHatBinding(d, 0, SDL_HAT_DOWN, Input::Down );
|
||||
addGcAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTX, Negative, Input::Left );
|
||||
addGcAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTX, Positive, Input::Right );
|
||||
addGcAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTY, Negative, Input::Up );
|
||||
addGcAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTY, Positive, Input::Down );
|
||||
addGcAxisBinding(d, SDL_CONTROLLER_AXIS_TRIGGERLEFT, Positive, Input::Deactivate);
|
||||
addGcAxisBinding(d, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, Positive, Input::Run );
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
#define FORMAT_VER 3
|
||||
#define FORMAT_VER 0
|
||||
|
||||
struct Header
|
||||
{
|
||||
|
@ -239,12 +247,14 @@ static bool verifyDesc(const BindingDesc &desc)
|
|||
return true;
|
||||
case Key:
|
||||
return src.d.scan < SDL_NUM_SCANCODES;
|
||||
case CButton:
|
||||
case JButton:
|
||||
return true;
|
||||
case JHat:
|
||||
/* Only accept single directional binds */
|
||||
return src.d.jh.pos == SDL_HAT_LEFT || src.d.jh.pos == SDL_HAT_RIGHT ||
|
||||
src.d.jh.pos == SDL_HAT_UP || src.d.jh.pos == SDL_HAT_DOWN;
|
||||
case CAxis:
|
||||
case JAxis:
|
||||
return src.d.ja.dir == Negative || src.d.ja.dir == Positive;
|
||||
default:
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <SDL_scancode.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
@ -40,6 +41,8 @@ enum SourceType
|
|||
{
|
||||
Invalid,
|
||||
Key,
|
||||
CButton,
|
||||
CAxis,
|
||||
JButton,
|
||||
JAxis,
|
||||
JHat
|
||||
|
@ -82,8 +85,10 @@ struct SourceDesc
|
|||
return true;
|
||||
case Key:
|
||||
return d.scan == o.d.scan;
|
||||
case CButton:
|
||||
case JButton:
|
||||
return d.jb == o.d.jb;
|
||||
case CAxis:
|
||||
case JAxis:
|
||||
return (d.ja.axis == o.d.ja.axis) && (d.ja.dir == o.d.ja.dir);
|
||||
case JHat:
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "binding.h"
|
||||
|
||||
#include "icon.png.xxd"
|
||||
#include "gamecontrollerdb.txt.xxd"
|
||||
|
||||
static void
|
||||
rgssThreadError(RGSSThreadData *rtData, const std::string &msg)
|
||||
|
@ -172,7 +173,7 @@ int main(int argc, char *argv[])
|
|||
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
|
||||
|
||||
/* initialize SDL first */
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)
|
||||
{
|
||||
showInitError(std::string("Error initializing SDL: ") + SDL_GetError());
|
||||
return 0;
|
||||
|
@ -295,6 +296,11 @@ int main(int argc, char *argv[])
|
|||
RGSSThreadData rtData(&eventThread, argv[0], win,
|
||||
alcDev, mode.refresh_rate, conf);
|
||||
|
||||
/* Add controller bindings from embedded controller DB */
|
||||
SDL_RWops *controllerDB = SDL_RWFromConstMem(assets_gamecontrollerdb_txt,
|
||||
assets_gamecontrollerdb_txt_len);
|
||||
SDL_GameControllerAddMappingsFromRW(controllerDB, 1);
|
||||
|
||||
int winW, winH;
|
||||
SDL_GetWindowSize(win, &winW, &winH);
|
||||
rtData.windowSizeMsg.post(Vec2i(winW, winH));
|
||||
|
|
|
@ -81,6 +81,24 @@ static elementsN(vButtons);
|
|||
/* Human readable string representation */
|
||||
std::string sourceDescString(const SourceDesc &src)
|
||||
{
|
||||
static const char *const gcButtonNames[SDL_CONTROLLER_BUTTON_MAX] = {
|
||||
"A Button",
|
||||
"B Button",
|
||||
"X Button",
|
||||
"Y Button",
|
||||
"Back Button",
|
||||
"Guide Button",
|
||||
"Start Button",
|
||||
"Left Stick",
|
||||
"Right Stick",
|
||||
"Left Shoulder",
|
||||
"Right Shoulder",
|
||||
"D-Pad (Up)",
|
||||
"D-Pad (Down)",
|
||||
"D-Pad (Left)",
|
||||
"D-Pad (Right)",
|
||||
};
|
||||
|
||||
char buf[128];
|
||||
char pos;
|
||||
|
||||
|
@ -100,10 +118,44 @@ std::string sourceDescString(const SourceDesc &src)
|
|||
if (*str == '\0')
|
||||
return "Unknown key";
|
||||
else
|
||||
return str;
|
||||
return std::string(str) + " Key";
|
||||
}
|
||||
|
||||
case CButton:
|
||||
snprintf(buf, sizeof(buf), "%s", gcButtonNames[src.d.jb]);
|
||||
return buf;
|
||||
|
||||
case CAxis:
|
||||
switch (src.d.ja.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
if (src.d.ja.dir == Negative)
|
||||
return "Left Stick (Left)";
|
||||
else
|
||||
return "Left Stick (Right)";
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
if (src.d.ja.dir == Negative)
|
||||
return "Left Stick (Up)";
|
||||
else
|
||||
return "Left Stick (Down)";
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
if (src.d.ja.dir == Negative)
|
||||
return "Right Stick (Left)";
|
||||
else
|
||||
return "Right Stick (Right)";
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
if (src.d.ja.dir == Negative)
|
||||
return "Right Stick (Up)";
|
||||
else
|
||||
return "Right Stick (Down)";
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
return "Left Trigger";
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
return "Right Trigger";
|
||||
}
|
||||
return "";
|
||||
|
||||
case JButton:
|
||||
snprintf(buf, sizeof(buf), "JS %d", src.d.jb);
|
||||
snprintf(buf, sizeof(buf), "Joy Button %d", src.d.jb);
|
||||
return buf;
|
||||
|
||||
case JHat:
|
||||
|
@ -128,12 +180,12 @@ std::string sourceDescString(const SourceDesc &src)
|
|||
default:
|
||||
pos = '-';
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "Hat %d:%c",
|
||||
snprintf(buf, sizeof(buf), "Joy Hat %d:%c",
|
||||
src.d.jh.hat, pos);
|
||||
return buf;
|
||||
|
||||
case JAxis:
|
||||
snprintf(buf, sizeof(buf), "Axis %d%c",
|
||||
snprintf(buf, sizeof(buf), "Joy Axis %d%c",
|
||||
src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
|
||||
return buf;
|
||||
}
|
||||
|
@ -638,9 +690,28 @@ struct SettingsMenuPrivate
|
|||
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
desc.type = CButton;
|
||||
desc.d.jb = event.cbutton.button;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
{
|
||||
int v = event.caxis.value;
|
||||
|
||||
/* Only register if pushed halfway through */
|
||||
if (v > -JAXIS_THRESHOLD && v < JAXIS_THRESHOLD)
|
||||
return true;
|
||||
|
||||
desc.type = CAxis;
|
||||
desc.d.ja.axis = event.caxis.axis;
|
||||
desc.d.ja.dir = v < 0 ? Negative : Positive;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
desc.type = JButton;
|
||||
desc.d.jb = event.jbutton.button;
|
||||
desc.d.jb = event.cbutton.button;
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
|
@ -1011,7 +1082,7 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
|
|||
const char *info = "Use left click to bind a slot, right click to clear its binding";
|
||||
p->infoLabel = Label(p, IntRect(16, 16, winSize.x, 16), info, cText, cText, cText);
|
||||
|
||||
const char *warn = "Warning: Same physical key bound to multiple slots";
|
||||
const char *warn = "Warning: Same physical action bound to multiple slots";
|
||||
p->dupWarnLabel = Label(p, IntRect(16, 40, winSize.x, 16), warn, 255, 0, 0);
|
||||
|
||||
p->widgets.push_back(&p->infoLabel);
|
||||
|
@ -1034,7 +1105,8 @@ SettingsMenu::~SettingsMenu()
|
|||
delete p;
|
||||
}
|
||||
|
||||
bool SettingsMenu::onEvent(const SDL_Event &event)
|
||||
bool SettingsMenu::onEvent(const SDL_Event &event,
|
||||
const std::map<int, SDL_Joystick*> &joysticks)
|
||||
{
|
||||
/* First, check whether this event is for us */
|
||||
switch (event.type)
|
||||
|
@ -1051,6 +1123,9 @@ bool SettingsMenu::onEvent(const SDL_Event &event)
|
|||
return false;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
case SDL_JOYBUTTONDOWN :
|
||||
case SDL_JOYBUTTONUP :
|
||||
case SDL_JOYHATMOTION :
|
||||
|
@ -1129,11 +1204,29 @@ bool SettingsMenu::onEvent(const SDL_Event &event)
|
|||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
if (p->state != AwaitingInput)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
if (p->state != AwaitingInput)
|
||||
return true;
|
||||
if (joysticks.find(event.jbutton.which) == joysticks.end())
|
||||
return true;
|
||||
break;
|
||||
case SDL_JOYHATMOTION:
|
||||
if (p->state != AwaitingInput)
|
||||
return true;
|
||||
if (joysticks.find(event.jhat.which) == joysticks.end())
|
||||
return true;
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
if (p->state != AwaitingInput)
|
||||
return true;
|
||||
if (joysticks.find(event.jaxis.which) == joysticks.end())
|
||||
return true;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <SDL_joystick.h>
|
||||
|
||||
struct SettingsMenuPrivate;
|
||||
struct RGSSThreadData;
|
||||
union SDL_Event;
|
||||
|
@ -35,7 +38,8 @@ public:
|
|||
~SettingsMenu();
|
||||
|
||||
/* Returns true if the event was consumed */
|
||||
bool onEvent(const SDL_Event &event);
|
||||
bool onEvent(const SDL_Event &event,
|
||||
const std::map<int, SDL_Joystick*> &joysticks);
|
||||
void raise();
|
||||
bool destroyReq() const;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue