mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-03-28 14:56:22 +01:00
switch to a (mostly) functioning GameController API
This commit is contained in:
parent
342f30069f
commit
5f4b644bd0
10 changed files with 1910 additions and 278 deletions
1678
assets/gamecontrollerdb.txt
Normal file
1678
assets/gamecontrollerdb.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -281,20 +281,20 @@ case SDL_JOYSTICK_POWER_##c: \
|
|||
v = M_SYMBOL(#c); \
|
||||
break;
|
||||
|
||||
RB_METHOD(inputJoystickInfo) {
|
||||
RB_METHOD(inputControllerInfo) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
if (!shState->input().getJoystickConnected())
|
||||
if (!shState->input().getControllerConnected())
|
||||
return RUBY_Qnil;
|
||||
|
||||
VALUE ret = rb_hash_new();
|
||||
|
||||
rb_hash_aset(ret, M_SYMBOL("name"),
|
||||
rb_utf8_str_new_cstr(shState->input().getJoystickName()));
|
||||
rb_utf8_str_new_cstr(shState->input().getControllerName()));
|
||||
|
||||
VALUE power;
|
||||
|
||||
switch (shState->input().getJoystickPowerLevel()) {
|
||||
switch (shState->input().getControllerPowerLevel()) {
|
||||
POWERCASE(power, MAX);
|
||||
POWERCASE(power, WIRED);
|
||||
POWERCASE(power, FULL);
|
||||
|
@ -423,7 +423,8 @@ void inputBindingInit() {
|
|||
_rb_define_module_function(module, "mouse_y", inputMouseY);
|
||||
_rb_define_module_function(module, "scroll_v", inputScrollV);
|
||||
|
||||
_rb_define_module_function(module, "joystick", inputJoystickInfo);
|
||||
_rb_define_module_function(module, "joystick", inputControllerInfo);
|
||||
_rb_define_module_function(module, "controller", inputControllerInfo);
|
||||
|
||||
_rb_define_module_function(module, "text_input", inputGetMode);
|
||||
_rb_define_module_function(module, "text_input=", inputSetMode);
|
||||
|
|
|
@ -158,8 +158,8 @@ typedef NSMutableArray<NSNumber*> BindingIndexArray;
|
|||
#define checkButtonEnd else { return; }
|
||||
#define checkButtonElement(e, b, n, min) \
|
||||
else if (sysver >= min && element == gamepad.e && gamepad.b.isPressed) { \
|
||||
s.type = JButton; \
|
||||
s.d.jb = n; \
|
||||
s.type = CButton; \
|
||||
s.d.cb = n; \
|
||||
}
|
||||
|
||||
#define checkButtonAlt(b, n, min) checkButtonElement(b, b, n, min)
|
||||
|
@ -168,9 +168,9 @@ s.d.jb = n; \
|
|||
|
||||
#define setAxisData(a, n) \
|
||||
GCControllerAxisInput *axis = gamepad.a; \
|
||||
s.type = JAxis; \
|
||||
s.d.ja.axis = n; \
|
||||
s.d.ja.dir = (axis.value >= 0) ? AxisDir::Positive : AxisDir::Negative;
|
||||
s.type = CAxis; \
|
||||
s.d.ca.axis = n; \
|
||||
s.d.ca.dir = (axis.value >= 0) ? AxisDir::Positive : AxisDir::Negative;
|
||||
|
||||
#define checkAxis(el, a, n) else if (element == gamepad.el && (gamepad.el.a.value >= 0.5 || gamepad.el.a.value <= -0.5)) { setAxisData(el.a, n); }
|
||||
|
||||
|
@ -184,43 +184,43 @@ s.d.ja.dir = (axis.value >= 0) ? AxisDir::Positive : AxisDir::Negative;
|
|||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
checkButtonStart
|
||||
checkButton(A, 0, 12)
|
||||
checkButton(B, 1, 12)
|
||||
checkButton(X, 2, 12)
|
||||
checkButton(Y, 3, 12)
|
||||
checkButtonElement(dpad, dpad.up, 11, 12)
|
||||
checkButtonElement(dpad, dpad.down, 12, 12)
|
||||
checkButtonElement(dpad, dpad.left, 13, 12)
|
||||
checkButtonElement(dpad, dpad.right, 14, 12)
|
||||
checkButtonAlt(leftShoulder, 9, 12)
|
||||
checkButtonAlt(rightShoulder, 10, 12)
|
||||
checkButton(A, SDL_CONTROLLER_BUTTON_A, 12)
|
||||
checkButton(B, SDL_CONTROLLER_BUTTON_B, 12)
|
||||
checkButton(X, SDL_CONTROLLER_BUTTON_X, 12)
|
||||
checkButton(Y, SDL_CONTROLLER_BUTTON_Y, 12)
|
||||
checkButtonElement(dpad, dpad.up, SDL_CONTROLLER_BUTTON_DPAD_UP, 12)
|
||||
checkButtonElement(dpad, dpad.down, SDL_CONTROLLER_BUTTON_DPAD_DOWN, 12)
|
||||
checkButtonElement(dpad, dpad.left, SDL_CONTROLLER_BUTTON_DPAD_LEFT, 12)
|
||||
checkButtonElement(dpad, dpad.right, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 12)
|
||||
checkButtonAlt(leftShoulder, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, 12)
|
||||
checkButtonAlt(rightShoulder, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, 12)
|
||||
|
||||
// Requires macOS 10.14.1+
|
||||
checkButtonAlt(leftThumbstickButton, 7, 14)
|
||||
checkButtonAlt(rightThumbstickButton, 8, 14)
|
||||
checkButtonAlt(leftThumbstickButton, SDL_CONTROLLER_BUTTON_LEFTSTICK, 14)
|
||||
checkButtonAlt(rightThumbstickButton, SDL_CONTROLLER_BUTTON_RIGHTSTICK, 14)
|
||||
|
||||
// Requires macOS 10.15+
|
||||
checkButton(Menu, 6, 15)
|
||||
checkButton(Options, 4, 15)
|
||||
checkButton(Menu, SDL_CONTROLLER_BUTTON_START, 15)
|
||||
checkButton(Options, SDL_CONTROLLER_BUTTON_BACK, 15)
|
||||
|
||||
// Requires macOS 11.0+
|
||||
checkButton(Home, 5, 16)
|
||||
checkButton(Home, SDL_CONTROLLER_BUTTON_GUIDE, 16)
|
||||
|
||||
checkAxis(leftThumbstick, xAxis, 0)
|
||||
checkAxis(leftThumbstick, yAxis, 1)
|
||||
checkAxis(rightThumbstick, xAxis, 2)
|
||||
checkAxis(rightThumbstick, yAxis, 3)
|
||||
checkAxis(leftThumbstick, xAxis, SDL_CONTROLLER_AXIS_LEFTX)
|
||||
checkAxis(leftThumbstick, yAxis, SDL_CONTROLLER_AXIS_LEFTY)
|
||||
checkAxis(rightThumbstick, xAxis, SDL_CONTROLLER_AXIS_RIGHTX)
|
||||
checkAxis(rightThumbstick, yAxis, SDL_CONTROLLER_AXIS_RIGHTY)
|
||||
|
||||
else if (element == gamepad.leftTrigger && (gamepad.leftTrigger.value >= 0.5 || gamepad.leftTrigger.value <= -0.5)) {
|
||||
s.type = JAxis;
|
||||
s.d.ja.axis = 4;
|
||||
s.d.ja.dir = AxisDir::Positive;
|
||||
s.type = CAxis;
|
||||
s.d.ca.axis = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
|
||||
s.d.ca.dir = AxisDir::Positive;
|
||||
}
|
||||
|
||||
else if (element == gamepad.rightTrigger && (gamepad.rightTrigger.value >= 0.5 || gamepad.rightTrigger.value <= -0.5)) {
|
||||
s.type = JAxis;
|
||||
s.d.ja.axis = 5;
|
||||
s.d.ja.dir = AxisDir::Positive;
|
||||
s.type = CAxis;
|
||||
s.d.ca.axis = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
|
||||
s.d.ca.dir = AxisDir::Positive;
|
||||
}
|
||||
|
||||
checkButtonEnd;
|
||||
|
@ -236,30 +236,11 @@ s.d.ja.dir = (axis.value >= 0) ? AxisDir::Positive : AxisDir::Negative;
|
|||
case Key:
|
||||
if (desc.d.scan == SDL_SCANCODE_LSHIFT) return @"Shift";
|
||||
return @(SDL_GetScancodeName(desc.d.scan));
|
||||
case JHat:
|
||||
const char *dir;
|
||||
switch (desc.d.jh.pos) {
|
||||
case SDL_HAT_UP:
|
||||
dir = "Up";
|
||||
break;
|
||||
case SDL_HAT_DOWN:
|
||||
dir = "Down";
|
||||
break;
|
||||
case SDL_HAT_LEFT:
|
||||
dir = "Left";
|
||||
break;
|
||||
case SDL_HAT_RIGHT:
|
||||
dir = "Right";
|
||||
break;
|
||||
default:
|
||||
dir = "-";
|
||||
break;
|
||||
}
|
||||
return [NSString stringWithFormat:@"JS Hat %d:%s", desc.d.jh.hat, dir];
|
||||
case JAxis:
|
||||
return [NSString stringWithFormat:@"JS Axis %d%s", desc.d.ja.axis, desc.d.ja.dir == Negative ? "-" : "+"];
|
||||
case JButton:
|
||||
return [NSString stringWithFormat:@"JS Button %i", desc.d.jb];
|
||||
case CAxis:
|
||||
return [NSString stringWithFormat:@"%s%s",
|
||||
shState->input().getAxisName(desc.d.ca.axis), desc.d.ca.dir == Negative ? "-" : "+"];
|
||||
case CButton:
|
||||
return @(shState->input().getButtonName(desc.d.cb));
|
||||
default:
|
||||
return @"Invalid";
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "eventthread.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_messagebox.h>
|
||||
#include <SDL_timer.h>
|
||||
#include <SDL_thread.h>
|
||||
|
@ -83,7 +82,7 @@ initALCFunctions(ALCdevice *alcDev)
|
|||
#define HAVE_ALC_DEVICE_PAUSE alc.DevicePause
|
||||
|
||||
uint8_t EventThread::keyStates[];
|
||||
EventThread::JoyState EventThread::joyState;
|
||||
EventThread::ControllerState EventThread::controllerState;
|
||||
EventThread::MouseState EventThread::mouseState;
|
||||
EventThread::TouchState EventThread::touchState;
|
||||
SDL_atomic_t EventThread::verticalScrollDistance;
|
||||
|
@ -122,7 +121,7 @@ bool EventThread::allocUserEvents()
|
|||
}
|
||||
|
||||
EventThread::EventThread()
|
||||
: js(0),
|
||||
: ctrl(0),
|
||||
fullscreen(false),
|
||||
showCursor(true)
|
||||
{
|
||||
|
@ -164,8 +163,13 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
|
||||
bool terminate = false;
|
||||
|
||||
if (SDL_NumJoysticks() > 0)
|
||||
js = SDL_JoystickOpen(0);
|
||||
// debug, haven't actually added it to the build systems yet
|
||||
SDL_GameControllerAddMappingsFromFile("/Users/zorua/Documents/Source/mkxp-z/assets/gamecontrollerdb.txt");
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
if (SDL_NumJoysticks() > 0 && SDL_IsGameController(0)) {
|
||||
ctrl = SDL_GameControllerOpen(0);
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
|
||||
|
@ -387,32 +391,28 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
keyStates[event.key.keysym.scancode] = false;
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN :
|
||||
joyState.buttons[event.jbutton.button] = true;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
controllerState.buttons[event.cbutton.button] = true;
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONUP :
|
||||
joyState.buttons[event.jbutton.button] = false;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
controllerState.buttons[event.cbutton.button] = false;
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION :
|
||||
joyState.hats[event.jhat.hat] = event.jhat.value;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
controllerState.axes[event.caxis.axis] = event.caxis.value;
|
||||
break;
|
||||
|
||||
case SDL_JOYAXISMOTION :
|
||||
joyState.axes[event.jaxis.axis] = event.jaxis.value;
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
if (event.cdevice.which > 0)
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEADDED :
|
||||
if (event.jdevice.which > 0)
|
||||
ctrl = SDL_GameControllerOpen(0);
|
||||
break;
|
||||
|
||||
js = SDL_JoystickOpen(0);
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEREMOVED :
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
resetInputStates();
|
||||
js = 0;
|
||||
ctrl = 0;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN :
|
||||
|
@ -575,8 +575,8 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
/* Just in case */
|
||||
rtData.syncPoint.resumeThreads();
|
||||
|
||||
if (SDL_JoystickGetAttached(js))
|
||||
SDL_JoystickClose(js);
|
||||
if (SDL_GameControllerGetAttached(ctrl))
|
||||
SDL_GameControllerClose(ctrl);
|
||||
|
||||
#ifndef MKXPZ_BUILD_XCODE
|
||||
delete sMenu;
|
||||
|
@ -649,7 +649,7 @@ void EventThread::cleanup()
|
|||
void EventThread::resetInputStates()
|
||||
{
|
||||
memset(&keyStates, 0, sizeof(keyStates));
|
||||
memset(&joyState, 0, sizeof(joyState));
|
||||
memset(&controllerState, 0, sizeof(controllerState));
|
||||
memset(&mouseState.buttons, 0, sizeof(mouseState.buttons));
|
||||
memset(&touchState, 0, sizeof(touchState));
|
||||
}
|
||||
|
@ -778,14 +778,14 @@ bool EventThread::getShowCursor() const
|
|||
return showCursor;
|
||||
}
|
||||
|
||||
bool EventThread::getJoystickConnected() const
|
||||
bool EventThread::getControllerConnected() const
|
||||
{
|
||||
return js != 0;
|
||||
return ctrl != 0;
|
||||
}
|
||||
|
||||
SDL_Joystick *EventThread::joystick() const
|
||||
SDL_GameController *EventThread::controller() const
|
||||
{
|
||||
return js;
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
void EventThread::notifyFrame()
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
#define EVENTTHREAD_H
|
||||
|
||||
#include <SDL_scancode.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_mouse.h>
|
||||
#include <SDL_mutex.h>
|
||||
#include <SDL_atomic.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -47,11 +47,10 @@ union SDL_Event;
|
|||
class EventThread
|
||||
{
|
||||
public:
|
||||
struct JoyState
|
||||
{
|
||||
int axes[256];
|
||||
uint8_t hats[256];
|
||||
bool buttons[256];
|
||||
|
||||
struct ControllerState {
|
||||
int axes[SDL_CONTROLLER_AXIS_MAX];
|
||||
bool buttons[SDL_CONTROLLER_BUTTON_MAX];
|
||||
};
|
||||
|
||||
struct MouseState
|
||||
|
@ -73,7 +72,7 @@ public:
|
|||
};
|
||||
|
||||
static uint8_t keyStates[SDL_NUM_SCANCODES];
|
||||
static JoyState joyState;
|
||||
static ControllerState controllerState;
|
||||
static MouseState mouseState;
|
||||
static TouchState touchState;
|
||||
static SDL_atomic_t verticalScrollDistance;
|
||||
|
@ -106,9 +105,9 @@ public:
|
|||
|
||||
bool getFullscreen() const;
|
||||
bool getShowCursor() const;
|
||||
bool getJoystickConnected() const;
|
||||
bool getControllerConnected() const;
|
||||
|
||||
SDL_Joystick *joystick() const;
|
||||
SDL_GameController *controller() const;
|
||||
|
||||
void showMessageBox(const char *body, int flags = 0);
|
||||
|
||||
|
@ -129,7 +128,7 @@ private:
|
|||
bool fullscreen;
|
||||
bool showCursor;
|
||||
|
||||
SDL_Joystick *js;
|
||||
SDL_GameController *ctrl;
|
||||
|
||||
AtomicFlag msgBoxDone;
|
||||
|
||||
|
|
|
@ -423,6 +423,39 @@ std::unordered_map<std::string, int> strToScancode{
|
|||
|
||||
#undef m
|
||||
|
||||
const char *axisNames[] {
|
||||
"LStick X",
|
||||
"LStick Y",
|
||||
"RStick X",
|
||||
"RStick Y",
|
||||
"LTrigger",
|
||||
"RTrigger"
|
||||
};
|
||||
|
||||
const char *buttonNames[] {
|
||||
"Pad A",
|
||||
"Pad B",
|
||||
"Pad X",
|
||||
"Pad Y",
|
||||
"Pad Back",
|
||||
"Pad Guide",
|
||||
"Pad Start",
|
||||
"Pad LS",
|
||||
"Pad RS",
|
||||
"Pad LB",
|
||||
"Pad RB",
|
||||
"Pad Up",
|
||||
"Pad Down",
|
||||
"Pad Left",
|
||||
"Pad Right",
|
||||
"Pad Misc",
|
||||
"Pad Paddle1",
|
||||
"Pad Paddle2",
|
||||
"Pad Paddle3",
|
||||
"Pad Paddle4",
|
||||
"Pad Touchpad"
|
||||
};
|
||||
|
||||
struct ButtonState
|
||||
{
|
||||
bool pressed;
|
||||
|
@ -493,14 +526,13 @@ struct KbBinding : public Binding
|
|||
SDL_Scancode source;
|
||||
};
|
||||
|
||||
/* Joystick button binding */
|
||||
struct JsButtonBinding : public Binding
|
||||
struct CtrlButtonBinding : public Binding
|
||||
{
|
||||
JsButtonBinding() {}
|
||||
CtrlButtonBinding() {}
|
||||
|
||||
bool sourceActive() const
|
||||
{
|
||||
return EventThread::joyState.buttons[source];
|
||||
return EventThread::controllerState.buttons[source];
|
||||
}
|
||||
|
||||
bool sourceRepeatable() const
|
||||
|
@ -508,34 +540,27 @@ struct JsButtonBinding : public Binding
|
|||
return true;
|
||||
}
|
||||
|
||||
uint8_t source;
|
||||
SDL_GameControllerButton source;
|
||||
};
|
||||
|
||||
/* Joystick axis binding */
|
||||
struct JsAxisBinding : public Binding
|
||||
struct CtrlAxisBinding : public Binding
|
||||
{
|
||||
JsAxisBinding() {}
|
||||
CtrlAxisBinding() {}
|
||||
|
||||
JsAxisBinding(uint8_t source,
|
||||
AxisDir dir,
|
||||
Input::ButtonCode target)
|
||||
: Binding(target),
|
||||
source(source),
|
||||
dir(dir)
|
||||
{}
|
||||
CtrlAxisBinding(uint8_t source, AxisDir dir, Input::ButtonCode target)
|
||||
: Binding(target), source(source), dir(dir) {}
|
||||
|
||||
bool sourceActive() const
|
||||
{
|
||||
int val = EventThread::joyState.axes[source];
|
||||
float val = EventThread::controllerState.axes[source];
|
||||
|
||||
if (dir == Negative)
|
||||
return val < -JAXIS_THRESHOLD;
|
||||
else /* dir == Positive */
|
||||
else
|
||||
return val > JAXIS_THRESHOLD;
|
||||
}
|
||||
|
||||
bool sourceRepeatable() const
|
||||
{
|
||||
bool sourceRepeatable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -543,34 +568,6 @@ struct JsAxisBinding : public Binding
|
|||
AxisDir dir;
|
||||
};
|
||||
|
||||
/* Joystick hat binding */
|
||||
struct JsHatBinding : public Binding
|
||||
{
|
||||
JsHatBinding() {}
|
||||
|
||||
JsHatBinding(uint8_t source,
|
||||
uint8_t pos,
|
||||
Input::ButtonCode target)
|
||||
: Binding(target),
|
||||
source(source),
|
||||
pos(pos)
|
||||
{}
|
||||
|
||||
bool sourceActive() const
|
||||
{
|
||||
/* For a diagonal input accept it as an input for both the axes */
|
||||
return (pos & EventThread::joyState.hats[source]) != 0;
|
||||
}
|
||||
|
||||
bool sourceRepeatable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t source;
|
||||
uint8_t pos;
|
||||
};
|
||||
|
||||
/* Mouse button binding */
|
||||
struct MsBinding : public Binding
|
||||
{
|
||||
|
@ -661,9 +658,8 @@ struct InputPrivate
|
|||
{
|
||||
std::vector<KbBinding> kbStatBindings;
|
||||
std::vector<KbBinding> kbBindings;
|
||||
std::vector<JsAxisBinding> jsABindings;
|
||||
std::vector<JsHatBinding> jsHBindings;
|
||||
std::vector<JsButtonBinding> jsBBindings;
|
||||
std::vector<CtrlAxisBinding> ctrlABindings;
|
||||
std::vector<CtrlButtonBinding> ctrlBBindings;
|
||||
std::vector<MsBinding> msBindings;
|
||||
|
||||
/* Collective binding array */
|
||||
|
@ -866,9 +862,8 @@ struct InputPrivate
|
|||
void applyBindingDesc(const BDescVec &d)
|
||||
{
|
||||
kbBindings.clear();
|
||||
jsABindings.clear();
|
||||
jsHBindings.clear();
|
||||
jsBBindings.clear();
|
||||
ctrlABindings.clear();
|
||||
ctrlBBindings.clear();
|
||||
|
||||
for (size_t i = 0; i < d.size(); ++i)
|
||||
{
|
||||
|
@ -891,32 +886,22 @@ struct InputPrivate
|
|||
|
||||
break;
|
||||
}
|
||||
case JAxis :
|
||||
case CAxis :
|
||||
{
|
||||
JsAxisBinding bind;
|
||||
bind.source = src.d.ja.axis;
|
||||
bind.dir = src.d.ja.dir;
|
||||
CtrlAxisBinding bind;
|
||||
bind.source = src.d.ca.axis;
|
||||
bind.dir = src.d.ca.dir;
|
||||
bind.target = desc.target;
|
||||
jsABindings.push_back(bind);
|
||||
ctrlABindings.push_back(bind);
|
||||
|
||||
break;
|
||||
}
|
||||
case JHat :
|
||||
case CButton :
|
||||
{
|
||||
JsHatBinding bind;
|
||||
bind.source = src.d.jh.hat;
|
||||
bind.pos = src.d.jh.pos;
|
||||
CtrlButtonBinding bind;
|
||||
bind.source = src.d.cb;
|
||||
bind.target = desc.target;
|
||||
jsHBindings.push_back(bind);
|
||||
|
||||
break;
|
||||
}
|
||||
case JButton :
|
||||
{
|
||||
JsButtonBinding bind;
|
||||
bind.source = src.d.jb;
|
||||
bind.target = desc.target;
|
||||
jsBBindings.push_back(bind);
|
||||
ctrlBBindings.push_back(bind);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -931,9 +916,8 @@ struct InputPrivate
|
|||
appendBindings(msBindings);
|
||||
|
||||
appendBindings(kbBindings);
|
||||
appendBindings(jsABindings);
|
||||
appendBindings(jsHBindings);
|
||||
appendBindings(jsBBindings);
|
||||
appendBindings(ctrlABindings);
|
||||
appendBindings(ctrlBBindings);
|
||||
}
|
||||
|
||||
void initStaticKbBindings()
|
||||
|
@ -1193,19 +1177,14 @@ std::vector<std::string> Input::getBindings(ButtonCode code) {
|
|||
ret.push_back(SDL_GetScancodeName(b.source));
|
||||
}
|
||||
|
||||
for (const auto &b : p->jsBBindings) {
|
||||
for (const auto &b : p->ctrlBBindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(std::string("JSBUTTON") + std::to_string(b.source));
|
||||
ret.push_back(std::string("CBUTTON") + std::to_string(b.source));
|
||||
}
|
||||
|
||||
for (const auto &b : p->jsABindings) {
|
||||
for (const auto &b : p->ctrlABindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(std::string("JSAXIS") + std::to_string(b.source));
|
||||
}
|
||||
|
||||
for (const auto &b : p->jsHBindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(std::string("JSHAT") + std::to_string(b.source));
|
||||
ret.push_back(std::string("CAXIS") + std::to_string(b.source));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1322,23 +1301,25 @@ int Input::scrollV()
|
|||
return p->vScrollDistance;
|
||||
}
|
||||
|
||||
bool Input::getJoystickConnected()
|
||||
bool Input::getControllerConnected()
|
||||
{
|
||||
return shState->eThread().getJoystickConnected();
|
||||
return shState->eThread().getControllerConnected();
|
||||
}
|
||||
|
||||
const char *Input::getJoystickName()
|
||||
const char *Input::getControllerName()
|
||||
{
|
||||
return (getJoystickConnected()) ?
|
||||
SDL_JoystickName(shState->eThread().joystick()) :
|
||||
return (getControllerConnected()) ?
|
||||
SDL_GameControllerName(shState->eThread().controller()) :
|
||||
0;
|
||||
}
|
||||
|
||||
int Input::getJoystickPowerLevel()
|
||||
int Input::getControllerPowerLevel()
|
||||
{
|
||||
return (getJoystickConnected()) ?
|
||||
SDL_JoystickCurrentPowerLevel(shState->eThread().joystick()) :
|
||||
SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
if (!getControllerConnected())
|
||||
return SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
|
||||
SDL_Joystick *js = SDL_GameControllerGetJoystick(shState->eThread().controller());
|
||||
return SDL_JoystickCurrentPowerLevel(js);
|
||||
}
|
||||
|
||||
bool Input::getTextInputMode()
|
||||
|
@ -1375,6 +1356,20 @@ void Input::setClipboardText(char *text)
|
|||
throw Exception(Exception::SDLError, "Failed to set clipboard text: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
const char *Input::getAxisName(SDL_GameControllerAxis axis) {
|
||||
if (axis < 0 || axis >= SDL_CONTROLLER_AXIS_MAX)
|
||||
return "Invalid";
|
||||
|
||||
return axisNames[axis];
|
||||
}
|
||||
|
||||
const char *Input::getButtonName(SDL_GameControllerButton button) {
|
||||
if (button < 0 || button >= SDL_CONTROLLER_BUTTON_MAX)
|
||||
return "Invalid";
|
||||
|
||||
return buttonNames[button];
|
||||
}
|
||||
|
||||
Input::~Input()
|
||||
{
|
||||
delete p;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define INPUT_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -82,9 +83,9 @@ public:
|
|||
int mouseY();
|
||||
int scrollV();
|
||||
|
||||
bool getJoystickConnected();
|
||||
const char *getJoystickName();
|
||||
int getJoystickPowerLevel();
|
||||
bool getControllerConnected();
|
||||
const char *getControllerName();
|
||||
int getControllerPowerLevel();
|
||||
|
||||
bool getTextInputMode();
|
||||
void setTextInputMode(bool mode);
|
||||
|
@ -94,6 +95,9 @@ public:
|
|||
char *getClipboardText();
|
||||
void setClipboardText(char *text);
|
||||
|
||||
const char *getAxisName(SDL_GameControllerAxis axis);
|
||||
const char *getButtonName(SDL_GameControllerButton button);
|
||||
|
||||
private:
|
||||
Input(const RGSSThreadData &rtData);
|
||||
~Input();
|
||||
|
|
|
@ -45,16 +45,16 @@ struct KbBindingData
|
|||
}
|
||||
};
|
||||
|
||||
struct JsBindingData
|
||||
struct CtrlBindingData
|
||||
{
|
||||
int source;
|
||||
SDL_GameControllerButton source;
|
||||
Input::ButtonCode target;
|
||||
|
||||
void add(BDescVec &d) const
|
||||
{
|
||||
SourceDesc src;
|
||||
src.type = JButton;
|
||||
src.d.jb = source;
|
||||
src.type = CButton;
|
||||
src.d.cb = source;
|
||||
|
||||
BindingDesc desc;
|
||||
desc.src = src;
|
||||
|
@ -102,40 +102,31 @@ static elementsN(defaultKbBindings);
|
|||
static elementsN(defaultKbBindings1);
|
||||
static elementsN(defaultKbBindings2);
|
||||
|
||||
static const JsBindingData defaultJsBindings[] =
|
||||
static const CtrlBindingData defaultCtrlBindings[] =
|
||||
{
|
||||
{ 3, Input::A },
|
||||
{ 0, Input::B },
|
||||
{ 1, Input::C },
|
||||
{ 2, Input::X },
|
||||
{ 4, Input::Y },
|
||||
{ 5, Input::Z },
|
||||
{ 9, Input::L },
|
||||
{ 10, Input::R }
|
||||
{ SDL_CONTROLLER_BUTTON_X, Input::A },
|
||||
{ SDL_CONTROLLER_BUTTON_B, Input::B },
|
||||
{ SDL_CONTROLLER_BUTTON_A, Input::C },
|
||||
{ SDL_CONTROLLER_BUTTON_Y, Input::X },
|
||||
{ SDL_CONTROLLER_BUTTON_LEFTSTICK, Input::Y },
|
||||
{ SDL_CONTROLLER_BUTTON_RIGHTSTICK, Input::Z },
|
||||
{ SDL_CONTROLLER_BUTTON_LEFTSHOULDER, Input::L },
|
||||
{ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, Input::R },
|
||||
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_UP, Input::Up },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_DOWN, Input::Down },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_LEFT, Input::Left },
|
||||
{ SDL_CONTROLLER_BUTTON_DPAD_RIGHT, Input::Right }
|
||||
};
|
||||
|
||||
static elementsN(defaultJsBindings);
|
||||
static elementsN(defaultCtrlBindings);
|
||||
|
||||
static void addAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::ButtonCode target)
|
||||
static void addAxisBinding(BDescVec &d, SDL_GameControllerAxis axis, AxisDir dir, Input::ButtonCode target)
|
||||
{
|
||||
SourceDesc src;
|
||||
src.type = JAxis;
|
||||
src.d.ja.axis = axis;
|
||||
src.d.ja.dir = dir;
|
||||
|
||||
BindingDesc desc;
|
||||
desc.src = src;
|
||||
desc.target = target;
|
||||
|
||||
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;
|
||||
src.type = CAxis;
|
||||
src.d.ca.axis = axis;
|
||||
src.d.ca.dir = dir;
|
||||
|
||||
BindingDesc desc;
|
||||
desc.src = src;
|
||||
|
@ -158,23 +149,18 @@ BDescVec genDefaultBindings(const Config &conf)
|
|||
for (size_t i = 0; i < defaultKbBindings2N; ++i)
|
||||
defaultKbBindings2[i].add(d);
|
||||
|
||||
for (size_t i = 0; i < defaultJsBindingsN; ++i)
|
||||
defaultJsBindings[i].add(d);
|
||||
for (size_t i = 0; i < defaultCtrlBindingsN; ++i)
|
||||
defaultCtrlBindings[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 );
|
||||
addAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTX, Negative, Input::Left );
|
||||
addAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTX, Positive, Input::Right);
|
||||
addAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTY, Negative, Input::Up );
|
||||
addAxisBinding(d, SDL_CONTROLLER_AXIS_LEFTY, Positive, Input::Down );
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
#define FORMAT_VER 2
|
||||
#define FORMAT_VER 3
|
||||
|
||||
struct Header
|
||||
{
|
||||
|
@ -265,14 +251,12 @@ static bool verifyDesc(const BindingDesc &desc)
|
|||
return true;
|
||||
case Key:
|
||||
return src.d.scan < SDL_NUM_SCANCODES;
|
||||
case JButton:
|
||||
|
||||
case CButton:
|
||||
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 JAxis:
|
||||
return src.d.ja.dir == Negative || src.d.ja.dir == Positive;
|
||||
|
||||
case CAxis:
|
||||
return src.d.ca.dir == Negative || src.d.ca.dir == Positive;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "input.h"
|
||||
|
||||
#include <SDL_scancode.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
@ -40,9 +40,8 @@ enum SourceType
|
|||
{
|
||||
Invalid,
|
||||
Key,
|
||||
JButton,
|
||||
JAxis,
|
||||
JHat
|
||||
CButton,
|
||||
CAxis
|
||||
};
|
||||
|
||||
struct SourceDesc
|
||||
|
@ -54,21 +53,14 @@ struct SourceDesc
|
|||
/* Keyboard scancode */
|
||||
SDL_Scancode scan;
|
||||
/* Joystick button index */
|
||||
uint8_t jb;
|
||||
SDL_GameControllerButton cb;
|
||||
struct
|
||||
{
|
||||
/* Joystick axis index */
|
||||
uint8_t axis;
|
||||
SDL_GameControllerAxis axis;
|
||||
/* Joystick axis direction */
|
||||
AxisDir dir;
|
||||
} ja;
|
||||
struct
|
||||
{
|
||||
/* Joystick axis index */
|
||||
uint8_t hat;
|
||||
/* Joystick axis direction */
|
||||
uint8_t pos;
|
||||
} jh;
|
||||
} ca;
|
||||
} d;
|
||||
|
||||
bool operator==(const SourceDesc &o) const
|
||||
|
@ -82,12 +74,10 @@ struct SourceDesc
|
|||
return true;
|
||||
case Key:
|
||||
return d.scan == o.d.scan;
|
||||
case JButton:
|
||||
return d.jb == o.d.jb;
|
||||
case JAxis:
|
||||
return (d.ja.axis == o.d.ja.axis) && (d.ja.dir == o.d.ja.dir);
|
||||
case JHat:
|
||||
return (d.jh.hat == o.d.jh.hat) && (d.jh.pos == o.d.jh.pos);
|
||||
case CButton:
|
||||
return d.cb == o.d.cb;
|
||||
case CAxis:
|
||||
return (d.ca.axis == o.d.ca.axis) && (d.ca.dir == o.d.ca.dir);
|
||||
default:
|
||||
assert(!"unreachable");
|
||||
return false;
|
||||
|
|
|
@ -210,7 +210,7 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
|
||||
/* initialize SDL first */
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) {
|
||||
showInitError(std::string("Error initializing SDL: ") + SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue