mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-04-29 19:44:49 +02:00
Finish moving to GameController API, other stuff
Namely: - moved raw input states from System to Input - Input.raw_key_states returns Array<Boolean> now - the Joystick hash has become an entire module - added manual input handling for controller buttons - Raw controller states for both buttons and axes can be polled - mouse and raw keys are now captured between Input updates
This commit is contained in:
parent
5f4b644bd0
commit
f839001be9
8 changed files with 399 additions and 101 deletions
|
@ -1,5 +1,6 @@
|
|||
embedded_assets = [
|
||||
'icon.png'
|
||||
'icon.png',
|
||||
'gamecontrollerdb.txt'
|
||||
]
|
||||
|
||||
if get_option('cjk_fallback_font') == true
|
||||
|
|
|
@ -112,8 +112,6 @@ RB_METHOD(mkxpSetTitle);
|
|||
RB_METHOD(mkxpGetTitle);
|
||||
RB_METHOD(mkxpDesensitize);
|
||||
RB_METHOD(mkxpPuts);
|
||||
RB_METHOD(mkxpRawKeyStates);
|
||||
RB_METHOD(mkxpMouseInWindow);
|
||||
|
||||
RB_METHOD(mkxpPlatform);
|
||||
RB_METHOD(mkxpIsMacHost);
|
||||
|
@ -137,7 +135,6 @@ RB_METHOD(mkxpAddPath);
|
|||
RB_METHOD(mkxpRemovePath);
|
||||
RB_METHOD(mkxpLaunch);
|
||||
|
||||
RB_METHOD(mkxpGetDefaultFontFamily);
|
||||
RB_METHOD(mkxpSetDefaultFontFamily);
|
||||
|
||||
RB_METHOD(mriRgssMain);
|
||||
|
@ -218,10 +215,6 @@ static void mriBindingInit() {
|
|||
_rb_define_module_function(mod, "show_settings", mkxpSettingsMenu);
|
||||
_rb_define_module_function(mod, "puts", mkxpPuts);
|
||||
_rb_define_module_function(mod, "desensitize", mkxpDesensitize);
|
||||
_rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates);
|
||||
_rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow);
|
||||
_rb_define_module_function(mod, "mouse_in_window?", mkxpMouseInWindow);
|
||||
|
||||
_rb_define_module_function(mod, "platform", mkxpPlatform);
|
||||
|
||||
_rb_define_module_function(mod, "is_mac?", mkxpIsMacHost);
|
||||
|
@ -380,22 +373,6 @@ RB_METHOD(mkxpPuts) {
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpRawKeyStates) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE str = rb_str_new(0, sizeof(EventThread::keyStates));
|
||||
memcpy(RSTRING_PTR(str), EventThread::keyStates,
|
||||
sizeof(EventThread::keyStates));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpMouseInWindow) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
return rb_bool_new(EventThread::mouseState.inWindow);
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpPlatform) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
|
|
@ -82,6 +82,18 @@ static int getScancodeArg(VALUE *argv) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int getControllerButtonArg(VALUE *argv) {
|
||||
const char *button = rb_id2name(SYM2ID(*argv));
|
||||
int btn{};
|
||||
try {
|
||||
btn = strToGCButton[button];
|
||||
} catch (...) {
|
||||
rb_raise(rb_eRuntimeError, "%s is not a valid name of an SDL Controller button.");
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
RB_METHOD(inputPress) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
@ -275,44 +287,197 @@ RB_METHOD(inputScrollV) {
|
|||
return rb_fix_new(shState->input().scrollV());
|
||||
}
|
||||
|
||||
RB_METHOD(inputMouseInWindow) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
return rb_bool_new(shState->input().mouseInWindow());
|
||||
}
|
||||
|
||||
RB_METHOD(inputRawKeyStates) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE ret = rb_ary_new();
|
||||
|
||||
uint8_t *states = shState->input().rawButtonStates();
|
||||
|
||||
for (int i = 0; i < shState->input().rawButtonStatesLength(); i++)
|
||||
rb_ary_push(ret, rb_bool_new(states[i]));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define M_SYMBOL(x) ID2SYM(rb_intern(x))
|
||||
#define POWERCASE(v, c) \
|
||||
case SDL_JOYSTICK_POWER_##c: \
|
||||
v = M_SYMBOL(#c); \
|
||||
break;
|
||||
|
||||
RB_METHOD(inputControllerInfo) {
|
||||
RB_METHOD(inputControllerConnected) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
return rb_bool_new(shState->input().getControllerConnected());
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerName) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
if (!shState->input().getControllerConnected())
|
||||
return RUBY_Qnil;
|
||||
return rb_utf8_str_new_cstr("");
|
||||
|
||||
VALUE ret = rb_hash_new();
|
||||
return rb_utf8_str_new_cstr(shState->input().getControllerName());
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerPowerLevel) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_hash_aset(ret, M_SYMBOL("name"),
|
||||
rb_utf8_str_new_cstr(shState->input().getControllerName()));
|
||||
VALUE ret;
|
||||
|
||||
VALUE power;
|
||||
if (!shState->input().getControllerConnected())
|
||||
ret = M_SYMBOL("UNKNOWN");
|
||||
|
||||
switch (shState->input().getControllerPowerLevel()) {
|
||||
POWERCASE(power, MAX);
|
||||
POWERCASE(power, WIRED);
|
||||
POWERCASE(power, FULL);
|
||||
POWERCASE(power, MEDIUM);
|
||||
POWERCASE(power, LOW);
|
||||
POWERCASE(power, EMPTY);
|
||||
POWERCASE(ret, MAX);
|
||||
POWERCASE(ret, WIRED);
|
||||
POWERCASE(ret, FULL);
|
||||
POWERCASE(ret, MEDIUM);
|
||||
POWERCASE(ret, LOW);
|
||||
POWERCASE(ret, EMPTY);
|
||||
|
||||
default:
|
||||
power = M_SYMBOL("UNKNOWN");
|
||||
ret = M_SYMBOL("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
|
||||
rb_hash_aset(ret, M_SYMBOL("power"), power);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define AXISFUNC(n, ax1, ax2) \
|
||||
RB_METHOD(inputControllerGet##n##Axis) {\
|
||||
RB_UNUSED_PARAM;\
|
||||
VALUE ret = rb_ary_new(); \
|
||||
if (!shState->eThread().getControllerConnected()) {\
|
||||
rb_ary_push(ret, rb_float_new(0)); rb_ary_push(ret, rb_float_new(0)); \
|
||||
}\
|
||||
rb_ary_push(ret, rb_float_new(shState->input().getControllerAxisValue(SDL_CONTROLLER_AXIS_##ax1) / 32767.0)); \
|
||||
rb_ary_push(ret, rb_float_new(shState->input().getControllerAxisValue(SDL_CONTROLLER_AXIS_##ax2) / 32767.0)); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
AXISFUNC(Left, LEFTX, LEFTY);
|
||||
AXISFUNC(Right, RIGHTX, RIGHTY);
|
||||
AXISFUNC(Trigger, TRIGGERLEFT, TRIGGERRIGHT);
|
||||
|
||||
#undef POWERCASE
|
||||
#undef M_SYMBOL
|
||||
|
||||
RB_METHOD(inputControllerPressEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
if (SYMBOL_P(button)) {
|
||||
int num = getControllerButtonArg(&button);
|
||||
return rb_bool_new(shState->input().controllerIsPressedEx(num));
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().controllerIsPressedEx(NUM2INT(button)));
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerTriggerEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
if (SYMBOL_P(button)) {
|
||||
int num = getControllerButtonArg(&button);
|
||||
return rb_bool_new(shState->input().controllerIsTriggeredEx(num));
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().controllerIsTriggeredEx(NUM2INT(button)));
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerRepeatEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
if (SYMBOL_P(button)) {
|
||||
int num = getControllerButtonArg(&button);
|
||||
return rb_bool_new(shState->input().controllerIsRepeatedEx(num));
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().controllerIsRepeatedEx(NUM2INT(button)));
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerReleaseEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
if (SYMBOL_P(button)) {
|
||||
int num = getControllerButtonArg(&button);
|
||||
return rb_bool_new(shState->input().controllerIsReleasedEx(num));
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().controllerIsReleasedEx(NUM2INT(button)));
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerCountEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
if (SYMBOL_P(button)) {
|
||||
int num = getControllerButtonArg(&button);
|
||||
return rb_bool_new(shState->input().controllerRepeatcount(num));
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().controllerRepeatcount(NUM2INT(button)));
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerRepeatTimeEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
if (SYMBOL_P(button)) {
|
||||
int num = getControllerButtonArg(&button);
|
||||
return rb_bool_new(shState->input().controllerRepeatTimeEx(num));
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().controllerRepeatTimeEx(NUM2INT(button)));
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerRawButtonStates) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE ret = rb_ary_new();
|
||||
uint8_t *states = shState->input().rawButtonStates();
|
||||
|
||||
for (int i = 0; i < shState->input().rawButtonStatesLength(); i++)
|
||||
rb_ary_push(ret, rb_bool_new(states[i]));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RB_METHOD(inputControllerRawAxes) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE ret = rb_ary_new();
|
||||
int16_t *states = shState->input().rawAxes();
|
||||
|
||||
for (int i = 0; i < shState->input().rawAxesLength(); i++)
|
||||
rb_ary_push(ret, rb_float_new(states[i] / 32767.0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RB_METHOD(inputGetMode) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
@ -422,9 +587,25 @@ void inputBindingInit() {
|
|||
_rb_define_module_function(module, "mouse_x", inputMouseX);
|
||||
_rb_define_module_function(module, "mouse_y", inputMouseY);
|
||||
_rb_define_module_function(module, "scroll_v", inputScrollV);
|
||||
_rb_define_module_function(module, "mouse_in_window", inputMouseInWindow);
|
||||
_rb_define_module_function(module, "mouse_in_window?", inputMouseInWindow);
|
||||
|
||||
_rb_define_module_function(module, "joystick", inputControllerInfo);
|
||||
_rb_define_module_function(module, "controller", inputControllerInfo);
|
||||
_rb_define_module_function(module, "raw_key_states", inputRawKeyStates);
|
||||
|
||||
VALUE submod = rb_define_module_under(module, "Controller");
|
||||
_rb_define_module_function(submod, "connected?", inputControllerConnected);
|
||||
_rb_define_module_function(submod, "name", inputControllerName);
|
||||
_rb_define_module_function(submod, "power_level", inputControllerPowerLevel);
|
||||
_rb_define_module_function(submod, "axes_left", inputControllerGetLeftAxis);
|
||||
_rb_define_module_function(submod, "axes_right", inputControllerGetRightAxis);
|
||||
_rb_define_module_function(submod, "axes_trigger", inputControllerGetTriggerAxis);
|
||||
_rb_define_module_function(submod, "raw_button_states", inputControllerRawButtonStates);
|
||||
_rb_define_module_function(submod, "raw_axes", inputControllerRawAxes);
|
||||
_rb_define_module_function(submod, "triggerex?", inputControllerTriggerEx);
|
||||
_rb_define_module_function(submod, "repeatex?", inputControllerRepeatEx);
|
||||
_rb_define_module_function(submod, "releaseex?", inputControllerReleaseEx);
|
||||
_rb_define_module_function(submod, "repeatcount", inputControllerCountEx);
|
||||
_rb_define_module_function(submod, "timeex?", inputControllerRepeatTimeEx);
|
||||
|
||||
_rb_define_module_function(module, "text_input", inputGetMode);
|
||||
_rb_define_module_function(module, "text_input=", inputSetMode);
|
||||
|
|
|
@ -522,6 +522,7 @@
|
|||
96573E82279152DC002C3E77 /* TouchBar.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96573E80279152DC002C3E77 /* TouchBar.xcassets */; };
|
||||
96573E83279152DC002C3E77 /* TouchBar.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96573E80279152DC002C3E77 /* TouchBar.xcassets */; };
|
||||
96573E84279152DC002C3E77 /* TouchBar.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96573E80279152DC002C3E77 /* TouchBar.xcassets */; };
|
||||
96D8EDD128728DCE00A331EA /* gamecontrollerdb.txt in Resources */ = {isa = PBXBuildFile; fileRef = 96D8EDD028728DCA00A331EA /* gamecontrollerdb.txt */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -1110,6 +1111,7 @@
|
|||
96573E7A27913B46002C3E77 /* TouchBar.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = TouchBar.mm; path = views/TouchBar.mm; sourceTree = "<group>"; };
|
||||
96573E7B27913B46002C3E77 /* TouchBar.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; name = TouchBar.h; path = views/TouchBar.h; sourceTree = "<group>"; };
|
||||
96573E80279152DC002C3E77 /* TouchBar.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = TouchBar.xcassets; path = views/TouchBar.xcassets; sourceTree = "<group>"; };
|
||||
96D8EDD028728DCA00A331EA /* gamecontrollerdb.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = gamecontrollerdb.txt; path = ../assets/gamecontrollerdb.txt; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -1813,6 +1815,7 @@
|
|||
3B10EC8B2568E79800372D13 /* Shaders */,
|
||||
3B10EC832568E78400372D13 /* icon.png */,
|
||||
3B10EC842568E78400372D13 /* liberation.ttf */,
|
||||
96D8EDD028728DCA00A331EA /* gamecontrollerdb.txt */,
|
||||
3B10EC852568E78400372D13 /* wqymicrohei.ttf */,
|
||||
);
|
||||
name = Assets;
|
||||
|
@ -2062,6 +2065,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3B10EC862568E78500372D13 /* icon.png in Resources */,
|
||||
96D8EDD128728DCE00A331EA /* gamecontrollerdb.txt in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -38,8 +38,10 @@
|
|||
|
||||
#ifndef MKXPZ_BUILD_XCODE
|
||||
#include "settingsmenu.h"
|
||||
#include "gamecontrollerdb.txt.xxd"
|
||||
#else
|
||||
#include "system/system.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#include "TouchBar.h"
|
||||
#endif
|
||||
|
||||
|
@ -163,8 +165,13 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
|
||||
bool terminate = false;
|
||||
|
||||
// debug, haven't actually added it to the build systems yet
|
||||
SDL_GameControllerAddMappingsFromFile("/Users/zorua/Documents/Source/mkxp-z/assets/gamecontrollerdb.txt");
|
||||
#ifdef MKXPZ_BUILD_XCODE
|
||||
SDL_GameControllerAddMappingsFromFile(mkxp_fs::getPathForAsset("gamecontrollerdb", "txt").c_str());
|
||||
#else
|
||||
SDL_GameControllerAddMappingsFromRW(
|
||||
SDL_RWFromConstMem(___assets_gamecontrollerdb_txt, ___assets_gamecontrollerdb_txt_len),
|
||||
1);
|
||||
#endif
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
if (SDL_NumJoysticks() > 0 && SDL_IsGameController(0)) {
|
||||
|
|
|
@ -421,6 +421,18 @@ std::unordered_map<std::string, int> strToScancode{
|
|||
m(NONUSHASH)
|
||||
};
|
||||
|
||||
#undef m
|
||||
#define m(ctrl) {#ctrl, SDL_CONTROLLER_BUTTON_##ctrl}
|
||||
|
||||
std::unordered_map<std::string, SDL_GameControllerButton> strToGCButton {
|
||||
m(A), m(B), m(X), m(Y),
|
||||
m(BACK), m(GUIDE), m(START),
|
||||
m(LEFTSTICK), m(RIGHTSTICK),
|
||||
m(LEFTSHOULDER), m(RIGHTSHOULDER),
|
||||
m(DPAD_UP), m(DPAD_DOWN), m(DPAD_LEFT), m(DPAD_RIGHT)
|
||||
|
||||
};
|
||||
|
||||
#undef m
|
||||
|
||||
const char *axisNames[] {
|
||||
|
@ -676,12 +688,28 @@ struct InputPrivate
|
|||
uint8_t *rawStates;
|
||||
uint8_t *rawStatesOld;
|
||||
|
||||
// Gamepad button states
|
||||
uint8_t rawButtonStateArray[SDL_CONTROLLER_BUTTON_MAX*2];
|
||||
|
||||
uint8_t *rawButtonStates;
|
||||
uint8_t *rawButtonStatesOld;
|
||||
|
||||
// Gamepad axes & mouse coordinates
|
||||
int16_t axisStateArray[SDL_CONTROLLER_AXIS_MAX];
|
||||
int mousePos[2];
|
||||
bool mouseInWindow;
|
||||
|
||||
Input::ButtonCode repeating;
|
||||
int rawRepeating;
|
||||
int buttonRepeating;
|
||||
|
||||
unsigned int repeatCount;
|
||||
unsigned int rawRepeatCount;
|
||||
unsigned int buttonRepeatCount;
|
||||
|
||||
unsigned long long repeatTime;
|
||||
unsigned long long rawRepeatTime;
|
||||
unsigned long long buttonRepeatTime;
|
||||
|
||||
unsigned int repeatStart;
|
||||
unsigned int repeatDelay;
|
||||
|
@ -732,6 +760,9 @@ struct InputPrivate
|
|||
rawStates = rawStateArray;
|
||||
rawStatesOld = rawStateArray + SDL_NUM_SCANCODES;
|
||||
|
||||
rawButtonStates = rawButtonStateArray;
|
||||
rawButtonStatesOld = rawButtonStateArray + SDL_CONTROLLER_BUTTON_MAX;
|
||||
|
||||
/* Clear buffers */
|
||||
clearBuffer();
|
||||
swapBuffers();
|
||||
|
@ -770,7 +801,7 @@ struct InputPrivate
|
|||
return statesOld[mapToIndex[code]];
|
||||
}
|
||||
|
||||
inline ButtonState getStateRaw(int code, bool useVKey)
|
||||
ButtonState getStateRaw(int code, bool useVKey)
|
||||
{
|
||||
ButtonState b;
|
||||
int scancode = (useVKey) ? -1 : code;
|
||||
|
@ -823,6 +854,18 @@ struct InputPrivate
|
|||
return b;
|
||||
}
|
||||
|
||||
ButtonState getControllerButtonState(int button) {
|
||||
ButtonState b;
|
||||
|
||||
b.pressed = rawButtonStates[button];
|
||||
b.triggered = (rawButtonStates[button] && !rawButtonStatesOld[button]);
|
||||
b.released = (!rawButtonStates[button] && rawButtonStatesOld[button]);
|
||||
|
||||
b.repeated = (buttonRepeating == button) && (buttonRepeatCount >= repeatStart && ((buttonRepeatCount+1) % repeatDelay) == 0);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
ButtonState *tmp = states;
|
||||
|
@ -832,6 +875,10 @@ struct InputPrivate
|
|||
uint8_t *tmpr = rawStates;
|
||||
rawStates = rawStatesOld;
|
||||
rawStatesOld = tmpr;
|
||||
|
||||
uint8_t *tmpb = rawButtonStates;
|
||||
rawButtonStates = rawButtonStatesOld;
|
||||
rawButtonStatesOld = tmpb;
|
||||
}
|
||||
|
||||
void clearBuffer()
|
||||
|
@ -840,6 +887,8 @@ struct InputPrivate
|
|||
memset(states, 0, size);
|
||||
|
||||
memset(rawStates, 0, SDL_NUM_SCANCODES);
|
||||
|
||||
memset(rawButtonStates, 0, SDL_CONTROLLER_BUTTON_MAX);
|
||||
}
|
||||
|
||||
void checkBindingChange(const RGSSThreadData &rtData)
|
||||
|
@ -995,6 +1044,7 @@ struct InputPrivate
|
|||
|
||||
void updateRaw()
|
||||
{
|
||||
|
||||
memcpy(rawStates, shState->eThread().keyStates, SDL_NUM_SCANCODES);
|
||||
|
||||
for (int i = 0; i < SDL_NUM_SCANCODES; i++)
|
||||
|
@ -1017,6 +1067,34 @@ struct InputPrivate
|
|||
}
|
||||
|
||||
rawRepeating = -1;
|
||||
|
||||
}
|
||||
|
||||
void updateControllerRaw()
|
||||
{
|
||||
for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++)
|
||||
axisStateArray[i] = shState->eThread().controllerState.axes[i];
|
||||
|
||||
memcpy(rawButtonStates, shState->eThread().controllerState.buttons, SDL_CONTROLLER_BUTTON_MAX);
|
||||
|
||||
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
|
||||
{
|
||||
if (rawButtonStates[i] && rawButtonStatesOld[i])
|
||||
{
|
||||
if (buttonRepeating == i)
|
||||
rawRepeatCount++;
|
||||
else
|
||||
{
|
||||
buttonRepeatCount = 0;
|
||||
buttonRepeatTime = shState->runTime();
|
||||
buttonRepeating = i;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buttonRepeating = -1;
|
||||
}
|
||||
|
||||
void updateDir4()
|
||||
|
@ -1128,8 +1206,15 @@ void Input::update()
|
|||
/* Poll all bindings */
|
||||
p->pollBindings(repeatCand);
|
||||
|
||||
// Get raw keystates
|
||||
// Update raw keys, controller buttons and axes
|
||||
p->updateRaw();
|
||||
p->updateControllerRaw();
|
||||
|
||||
// Record mouse positions
|
||||
p->mousePos[0] = shState->eThread().mouseState.x;
|
||||
p->mousePos[1] = shState->eThread().mouseState.y;
|
||||
p->mouseInWindow = shState->eThread().mouseState.inWindow;
|
||||
|
||||
|
||||
/* Check for new repeating key */
|
||||
if (repeatCand != None && repeatCand != p->repeating)
|
||||
|
@ -1243,6 +1328,22 @@ bool Input::isReleasedEx(int code, bool isVKey)
|
|||
return p->getStateRaw(code, isVKey).released;
|
||||
}
|
||||
|
||||
bool Input::controllerIsPressedEx(int button) {
|
||||
return p->getControllerButtonState(button).pressed;
|
||||
}
|
||||
|
||||
bool Input::controllerIsTriggeredEx(int button) {
|
||||
return p->getControllerButtonState(button).triggered;
|
||||
}
|
||||
|
||||
bool Input::controllerIsRepeatedEx(int button) {
|
||||
return p->getControllerButtonState(button).repeated;
|
||||
}
|
||||
|
||||
bool Input::controllerIsReleasedEx(int button) {
|
||||
return p->getControllerButtonState(button).released;
|
||||
}
|
||||
|
||||
unsigned int Input::repeatcount(int code, bool isVKey) {
|
||||
int c = code;
|
||||
if (isVKey) {
|
||||
|
@ -1259,6 +1360,13 @@ unsigned int Input::repeatcount(int code, bool isVKey) {
|
|||
return p->rawRepeatCount;
|
||||
}
|
||||
|
||||
unsigned int Input::controllerRepeatcount(int button) {
|
||||
if (button != p->buttonRepeating)
|
||||
return 0;
|
||||
|
||||
return p->buttonRepeatCount;
|
||||
}
|
||||
|
||||
unsigned long long Input::repeatTimeEx(int code, bool isVKey) {
|
||||
int c = code;
|
||||
if (isVKey) {
|
||||
|
@ -1272,6 +1380,48 @@ unsigned long long Input::repeatTimeEx(int code, bool isVKey) {
|
|||
return shState->runTime() - p->rawRepeatTime;
|
||||
}
|
||||
|
||||
unsigned long long Input::controllerRepeatTimeEx(int button) {
|
||||
if (button != p->buttonRepeating)
|
||||
return 0;
|
||||
|
||||
return shState->runTime() - p->buttonRepeatTime;
|
||||
}
|
||||
|
||||
uint8_t *Input::rawKeyStates(){
|
||||
return p->rawStates;
|
||||
}
|
||||
|
||||
unsigned int Input::rawKeyStatesLength() {
|
||||
return sizeof(p->rawStateArray) / 2;
|
||||
}
|
||||
|
||||
uint8_t *Input::rawButtonStates() {
|
||||
return p->rawButtonStates;
|
||||
}
|
||||
|
||||
unsigned int Input::rawButtonStatesLength() {
|
||||
return sizeof(p->rawButtonStateArray) / 2;
|
||||
}
|
||||
|
||||
int16_t *Input::rawAxes() {
|
||||
return p->axisStateArray;
|
||||
}
|
||||
|
||||
unsigned int Input::rawAxesLength() {
|
||||
return sizeof(p->axisStateArray) / sizeof(int16_t);
|
||||
}
|
||||
|
||||
short Input::getControllerAxisValue(SDL_GameControllerAxis axis) {
|
||||
if (axis < 0 || axis >= rawAxesLength())
|
||||
return 0;
|
||||
|
||||
return rawAxes()[axis];
|
||||
}
|
||||
|
||||
bool Input::mouseInWindow() {
|
||||
return p->mouseInWindow;
|
||||
}
|
||||
|
||||
int Input::dir4Value()
|
||||
{
|
||||
return p->dir4Data.active;
|
||||
|
@ -1286,14 +1436,14 @@ int Input::mouseX()
|
|||
{
|
||||
RGSSThreadData &rtData = shState->rtData();
|
||||
|
||||
return (EventThread::mouseState.x - rtData.screenOffset.x) * rtData.sizeResoRatio.x;
|
||||
return (p->mousePos[0] - rtData.screenOffset.x) * rtData.sizeResoRatio.x;
|
||||
}
|
||||
|
||||
int Input::mouseY()
|
||||
{
|
||||
RGSSThreadData &rtData = shState->rtData();
|
||||
|
||||
return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y;
|
||||
return (p->mousePos[1] - rtData.screenOffset.y) * rtData.sizeResoRatio.y;
|
||||
}
|
||||
|
||||
int Input::scrollV()
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
extern std::unordered_map<int, int> vKeyToScancode;
|
||||
extern std::unordered_map<std::string, int> strToScancode;
|
||||
extern std::unordered_map<std::string, SDL_GameControllerButton> strToGCButton;
|
||||
|
||||
struct InputPrivate;
|
||||
struct RGSSThreadData;
|
||||
|
@ -68,20 +69,37 @@ public:
|
|||
bool isReleased(int button);
|
||||
unsigned int count(int button);
|
||||
unsigned long long repeatTime(int button);
|
||||
|
||||
bool isPressedEx(int code, bool isVKey);
|
||||
bool isTriggeredEx(int code, bool isVKey);
|
||||
bool isRepeatedEx(int code, bool isVKey);
|
||||
bool isReleasedEx(int code, bool isVKey);
|
||||
unsigned int repeatcount(int code, bool isVKey);
|
||||
unsigned long long repeatTimeEx(int code, bool isVKey);
|
||||
|
||||
bool controllerIsPressedEx(int button);
|
||||
bool controllerIsTriggeredEx(int button);
|
||||
bool controllerIsRepeatedEx(int button);
|
||||
bool controllerIsReleasedEx(int button);
|
||||
unsigned int controllerRepeatcount(int button);
|
||||
unsigned long long controllerRepeatTimeEx(int button);
|
||||
|
||||
uint8_t *rawKeyStates();
|
||||
unsigned int rawKeyStatesLength();
|
||||
uint8_t *rawButtonStates();
|
||||
unsigned int rawButtonStatesLength();
|
||||
int16_t *rawAxes();
|
||||
unsigned int rawAxesLength();
|
||||
|
||||
short getControllerAxisValue(SDL_GameControllerAxis axis);
|
||||
|
||||
int dir4Value();
|
||||
int dir8Value();
|
||||
|
||||
/* Non-standard extensions */
|
||||
int mouseX();
|
||||
int mouseY();
|
||||
int scrollV();
|
||||
bool mouseInWindow();
|
||||
|
||||
bool getControllerConnected();
|
||||
const char *getControllerName();
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "keybindings.h"
|
||||
#include "eventthread.h"
|
||||
#include "sharedstate.h"
|
||||
#include "font.h"
|
||||
#include "input.h"
|
||||
#include "etc-internal.h"
|
||||
|
@ -102,39 +103,13 @@ std::string sourceDescString(const SourceDesc &src)
|
|||
else
|
||||
return str;
|
||||
}
|
||||
case JButton:
|
||||
snprintf(buf, sizeof(buf), "JS %d", src.d.jb);
|
||||
case CButton:
|
||||
snprintf(buf, sizeof(buf), "%s", shState->input().getButtonName(src.d.cb));
|
||||
return buf;
|
||||
|
||||
case JHat:
|
||||
switch(src.d.jh.pos)
|
||||
{
|
||||
case SDL_HAT_UP:
|
||||
pos = 'U';
|
||||
break;
|
||||
|
||||
case SDL_HAT_DOWN:
|
||||
pos = 'D';
|
||||
break;
|
||||
|
||||
case SDL_HAT_LEFT:
|
||||
pos = 'L';
|
||||
break;
|
||||
|
||||
case SDL_HAT_RIGHT:
|
||||
pos = 'R';
|
||||
break;
|
||||
|
||||
default:
|
||||
pos = '-';
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "Hat %d:%c",
|
||||
src.d.jh.hat, pos);
|
||||
return buf;
|
||||
|
||||
case JAxis:
|
||||
snprintf(buf, sizeof(buf), "Axis %d%c",
|
||||
src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
|
||||
case CAxis:
|
||||
snprintf(buf, sizeof(buf), "%s%c",
|
||||
shState->input().getAxisName(src.d.ca.axis), src.d.ca.dir == Negative ? '-' : '+');
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -640,37 +615,22 @@ struct SettingsMenuPrivate
|
|||
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
desc.type = JButton;
|
||||
desc.d.jb = event.jbutton.button;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
desc.type = CButton;
|
||||
desc.d.cb = event.cbutton.button;
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
{
|
||||
int v = event.jhat.value;
|
||||
|
||||
/* Only register if single directional input */
|
||||
if (v != SDL_HAT_LEFT && v != SDL_HAT_RIGHT &&
|
||||
v != SDL_HAT_UP && v != SDL_HAT_DOWN)
|
||||
return true;
|
||||
|
||||
desc.type = JHat;
|
||||
desc.d.jh.hat = event.jhat.hat;
|
||||
desc.d.jh.pos = v;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_JOYAXISMOTION:
|
||||
{
|
||||
int v = event.jaxis.value;
|
||||
int v = event.caxis.value;
|
||||
|
||||
/* Only register if pushed halfway through */
|
||||
if (v > -JAXIS_THRESHOLD && v < JAXIS_THRESHOLD)
|
||||
return true;
|
||||
|
||||
desc.type = JAxis;
|
||||
desc.d.ja.axis = event.jaxis.axis;
|
||||
desc.d.ja.dir = v < 0 ? Negative : Positive;
|
||||
desc.type = CAxis;
|
||||
desc.d.ca.axis = event.caxis.axis;
|
||||
desc.d.ca.dir = v < 0 ? Negative : Positive;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue