mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-26 08:43:44 +02:00
Accept scancodes with Input.press?/Input.trigger?/Input.repeat?
This commit is contained in:
parent
374891a82c
commit
bfa60cc065
4 changed files with 360 additions and 85 deletions
|
@ -116,7 +116,7 @@ To smooth over cross-platform compatibility, functionality that you won't find i
|
|||
|
||||
### Input
|
||||
|
||||
* The `Input.press?` family of functions accepts three additional button constants: `::MOUSELEFT`, `::MOUSEMIDDLE` and `::MOUSERIGHT` for the respective mouse buttons.
|
||||
* The `Input.press?` family of functions accepts three additional button constants: `::MOUSELEFT`, `::MOUSEMIDDLE` and `::MOUSERIGHT` for the respective mouse buttons. It will now also accept [SDL scancodes](https://wiki.libsdl.org/SDL_Scancode?highlight=%28%5CbCategoryEnum%5Cb%29%7C%28CategoryKeyboard%29) in the form of symbols corresponding to each scancode (e.g. `SDL_SCANCODE_RETURN` would be requested through `Input.press? :RETURN`)
|
||||
* The `Input` module has two additional properties: `text_input` determines whether to accept text editing events. `clipboard` gets and sets the user's clipboard.
|
||||
* The `Input` module has seven additional functions, `#mouse_x` and `#mouse_y` to query the mouse pointer position relative to the game screen. `#pressex?`, `#triggerex?` and `#repeatex?` provide input states for raw key codes, which are provided in the form of [Microsoft Virtual-Key Codes](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes). Only buttons which are also [tracked by SDL](https://wiki.libsdl.org/SDL_Scancode) are supported. `#gets` returns a UTF-8 string of any text that was input by the user since the last time `#gets` was called. The `text_input` property must be set to true for it to work. `#joystick` returns (if a joystick is connected) a hash containing the `:name` and `:power` entries, or `nil` if there is not a joystick connected. `:name` is a string corresponding to the joystick's name, and `:power` can be any from: `:MAX`, `:WIRED`, `:FULL`, `:MEDIUM`, `:LOW`, `:EMPTY`, and `:UNKNOWN`.
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "binding-util.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <string>
|
||||
#include <SDL_joystick.h>
|
||||
|
||||
RB_METHOD(inputUpdate)
|
||||
|
@ -36,23 +37,21 @@ RB_METHOD(inputUpdate)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static int getButtonArg(int argc, VALUE *argv)
|
||||
static int getButtonArg(VALUE *argv)
|
||||
{
|
||||
int num;
|
||||
|
||||
rb_check_argc(argc, 1);
|
||||
|
||||
if (FIXNUM_P(argv[0]))
|
||||
if (FIXNUM_P(*argv))
|
||||
{
|
||||
num = FIX2INT(argv[0]);
|
||||
num = FIX2INT(*argv);
|
||||
}
|
||||
else if (SYMBOL_P(argv[0]) && rgssVer >= 3)
|
||||
else if (SYMBOL_P(*argv) && rgssVer >= 3)
|
||||
{
|
||||
VALUE symHash = getRbData()->buttoncodeHash;
|
||||
#ifndef OLD_RUBY
|
||||
num = FIX2INT(rb_hash_lookup2(symHash, argv[0], INT2FIX(Input::None)));
|
||||
num = FIX2INT(rb_hash_lookup2(symHash, *argv, INT2FIX(Input::None)));
|
||||
#else
|
||||
VALUE res = rb_hash_aref(symHash, argv[0]);
|
||||
VALUE res = rb_hash_aref(symHash, *argv);
|
||||
if (!NIL_P(res))
|
||||
num = FIX2INT(res);
|
||||
else
|
||||
|
@ -69,11 +68,40 @@ static int getButtonArg(int argc, VALUE *argv)
|
|||
return num;
|
||||
}
|
||||
|
||||
static int getScancodeArg(VALUE *argv)
|
||||
{
|
||||
const char *scancode = rb_id2name(SYM2ID(argv));
|
||||
int code{};
|
||||
try
|
||||
{
|
||||
code = strToScancode[scancode];
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
rb_raise(rb_eRuntimeError, "%s is not a valid key.", scancode);
|
||||
}
|
||||
|
||||
return rb_bool_new(shState->input().isPressedEx(code, 0));
|
||||
}
|
||||
|
||||
RB_METHOD(inputPress)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
int num = getButtonArg(argc, argv);
|
||||
rb_check_argc(argc, 1);
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
int num{};
|
||||
|
||||
if (SYMBOL_P(button))
|
||||
{
|
||||
num = getScancodeArg(&button);
|
||||
return rb_bool_new(shState->input().isPressedEx(num, 0));
|
||||
}
|
||||
|
||||
num = getButtonArg(&button);
|
||||
|
||||
return rb_bool_new(shState->input().isPressed(num));
|
||||
}
|
||||
|
@ -82,7 +110,20 @@ RB_METHOD(inputTrigger)
|
|||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
int num = getButtonArg(argc, argv);
|
||||
rb_check_argc(argc, 1);
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
int num{};
|
||||
|
||||
if (SYMBOL_P(button))
|
||||
{
|
||||
num = getScancodeArg(&button);
|
||||
return rb_bool_new(shState->input().isTriggeredEx(num, 0));
|
||||
}
|
||||
|
||||
num = getButtonArg(&button);
|
||||
|
||||
return rb_bool_new(shState->input().isTriggered(num));
|
||||
}
|
||||
|
@ -91,7 +132,20 @@ RB_METHOD(inputRepeat)
|
|||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
int num = getButtonArg(argc, argv);
|
||||
rb_check_argc(argc, 1);
|
||||
|
||||
VALUE button;
|
||||
rb_scan_args(argc, argv, "1", &button);
|
||||
|
||||
int num{};
|
||||
|
||||
if (SYMBOL_P(button))
|
||||
{
|
||||
num = getScancodeArg(&button);
|
||||
return rb_bool_new(shState->input().isRepeatedEx(num, 0));
|
||||
}
|
||||
|
||||
num = getButtonArg(&button);
|
||||
|
||||
return rb_bool_new(shState->input().isRepeated(num));
|
||||
}
|
||||
|
@ -103,7 +157,7 @@ RB_METHOD(inputPressEx)
|
|||
int num;
|
||||
rb_get_args(argc, argv, "i", &num RB_ARG_END);
|
||||
|
||||
return rb_bool_new(shState->input().isPressedEx(num));
|
||||
return rb_bool_new(shState->input().isPressedEx(num, 1));
|
||||
}
|
||||
|
||||
RB_METHOD(inputTriggerEx)
|
||||
|
@ -113,7 +167,7 @@ RB_METHOD(inputTriggerEx)
|
|||
int num;
|
||||
rb_get_args(argc, argv, "i", &num RB_ARG_END);
|
||||
|
||||
return rb_bool_new(shState->input().isTriggeredEx(num));
|
||||
return rb_bool_new(shState->input().isTriggeredEx(num, 1));
|
||||
}
|
||||
|
||||
RB_METHOD(inputRepeatEx)
|
||||
|
@ -123,7 +177,7 @@ RB_METHOD(inputRepeatEx)
|
|||
int num;
|
||||
rb_get_args(argc, argv, "i", &num RB_ARG_END);
|
||||
|
||||
return rb_bool_new(shState->input().isRepeatedEx(num));
|
||||
return rb_bool_new(shState->input().isRepeatedEx(num, 1));
|
||||
}
|
||||
|
||||
RB_METHOD(inputDir4)
|
||||
|
|
249
src/input.cpp
249
src/input.cpp
|
@ -32,16 +32,14 @@
|
|||
#include <SDL_clipboard.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define BUTTON_CODE_COUNT 24
|
||||
|
||||
// Map of Windows virtualkey codes to SDL scancodes.
|
||||
// Used for pressex, triggerex and repeatex
|
||||
#define m(vk,sc) { vk, SDL_SCANCODE_##sc }
|
||||
std::map<int, int> vKeyToScancode{
|
||||
std::unordered_map<int, int> vKeyToScancode{
|
||||
// 0x01 LEFT MOUSE
|
||||
// 0x02 RIGHT MOUSE
|
||||
m(0x03, CANCEL),
|
||||
|
@ -201,6 +199,225 @@ std::map<int, int> vKeyToScancode{
|
|||
// 0xfd PA1
|
||||
m(0xfe, CLEAR)
|
||||
};
|
||||
#undef m
|
||||
#define m(keycode) { #keycode, SDL_SCANCODE_##keycode }
|
||||
std::unordered_map<std::string, int> strToScancode{
|
||||
m(0), m(1),
|
||||
m(2), m(3),
|
||||
m(4), m(5),
|
||||
m(6), m(7),
|
||||
m(8), m(9),
|
||||
m(A),
|
||||
m(AC_BACK),
|
||||
m(AC_BOOKMARKS),
|
||||
m(AC_FORWARD),
|
||||
m(AC_HOME),
|
||||
m(AC_REFRESH),
|
||||
m(AC_SEARCH),
|
||||
m(AC_STOP),
|
||||
m(AGAIN),
|
||||
m(ALTERASE),
|
||||
m(APOSTROPHE),
|
||||
m(APPLICATION),
|
||||
m(AUDIOMUTE),
|
||||
m(AUDIONEXT),
|
||||
m(AUDIOPLAY),
|
||||
m(AUDIOPREV),
|
||||
m(AUDIOSTOP),
|
||||
m(B),
|
||||
m(BACKSLASH),
|
||||
m(BACKSPACE),
|
||||
m(BRIGHTNESSDOWN),
|
||||
m(BRIGHTNESSUP),
|
||||
m(C),
|
||||
m(CALCULATOR),
|
||||
m(CANCEL),
|
||||
m(CAPSLOCK),
|
||||
m(CLEAR),
|
||||
m(CLEARAGAIN),
|
||||
m(COMMA),
|
||||
m(COMPUTER),
|
||||
m(COPY),
|
||||
m(CRSEL),
|
||||
m(CURRENCYSUBUNIT),
|
||||
m(CURRENCYUNIT),
|
||||
m(CUT),
|
||||
m(D),
|
||||
m(DECIMALSEPARATOR),
|
||||
m(DELETE),
|
||||
m(DISPLAYSWITCH),
|
||||
m(DOWN),
|
||||
m(E),
|
||||
m(EJECT),
|
||||
m(END),
|
||||
m(EQUALS),
|
||||
m(ESCAPE),
|
||||
m(EXECUTE),
|
||||
m(EXSEL),
|
||||
m(F),
|
||||
m(F1), m(F2),
|
||||
m(F3), m(F4),
|
||||
m(F5), m(F6),
|
||||
m(F7), m(F8),
|
||||
m(F9), m(F10),
|
||||
m(F11), m(F12),
|
||||
m(F13), m(F14),
|
||||
m(F15), m(F16),
|
||||
m(F17), m(F18),
|
||||
m(F19), m(F20),
|
||||
m(F21), m(F22),
|
||||
m(F23), m(F24),
|
||||
m(FIND),
|
||||
m(G),
|
||||
m(GRAVE),
|
||||
m(H),
|
||||
m(HELP),
|
||||
m(HOME),
|
||||
m(I),
|
||||
m(INSERT),
|
||||
m(J),
|
||||
m(K),
|
||||
m(KBDILLUMDOWN),
|
||||
m(KBDILLUMTOGGLE),
|
||||
m(KBDILLUMUP),
|
||||
m(KP_0),
|
||||
m(KP_00),
|
||||
m(KP_000),
|
||||
m(KP_1), m(KP_2),
|
||||
m(KP_3), m(KP_4),
|
||||
m(KP_5), m(KP_6),
|
||||
m(KP_7), m(KP_8),
|
||||
m(KP_9),
|
||||
m(KP_A),
|
||||
m(KP_AMPERSAND),
|
||||
m(KP_AT),
|
||||
m(KP_B),
|
||||
m(KP_BACKSPACE),
|
||||
m(KP_BINARY),
|
||||
m(KP_C),
|
||||
m(KP_CLEAR),
|
||||
m(KP_CLEARENTRY),
|
||||
m(KP_COLON),
|
||||
m(KP_COMMA),
|
||||
m(KP_D),
|
||||
m(KP_DBLAMPERSAND),
|
||||
m(KP_DBLVERTICALBAR),
|
||||
m(KP_DECIMAL),
|
||||
m(KP_DIVIDE),
|
||||
m(KP_E),
|
||||
m(KP_ENTER),
|
||||
m(KP_EQUALS),
|
||||
m(KP_EQUALSAS400),
|
||||
m(KP_EXCLAM),
|
||||
m(KP_F),
|
||||
m(KP_GREATER),
|
||||
m(KP_HASH),
|
||||
m(KP_HEXADECIMAL),
|
||||
m(KP_LEFTBRACE),
|
||||
m(KP_LEFTPAREN),
|
||||
m(KP_LESS),
|
||||
m(KP_MEMADD),
|
||||
m(KP_MEMCLEAR),
|
||||
m(KP_MEMDIVIDE),
|
||||
m(KP_MEMMULTIPLY),
|
||||
m(KP_MEMRECALL),
|
||||
m(KP_MEMSTORE),
|
||||
m(KP_MEMSUBTRACT),
|
||||
m(KP_MINUS),
|
||||
m(KP_MULTIPLY),
|
||||
m(KP_OCTAL),
|
||||
m(KP_PERCENT),
|
||||
m(KP_PERIOD),
|
||||
m(KP_PLUS),
|
||||
m(KP_PLUSMINUS),
|
||||
m(KP_POWER),
|
||||
m(KP_RIGHTBRACE),
|
||||
m(KP_RIGHTPAREN),
|
||||
m(KP_SPACE),
|
||||
m(KP_TAB),
|
||||
m(KP_VERTICALBAR),
|
||||
m(KP_XOR),
|
||||
m(L),
|
||||
m(LALT),
|
||||
m(LCTRL),
|
||||
m(LEFT),
|
||||
m(LEFTBRACKET),
|
||||
m(LGUI),
|
||||
m(LSHIFT),
|
||||
m(M),
|
||||
m(MAIL),
|
||||
m(MEDIASELECT),
|
||||
m(MENU),
|
||||
m(MINUS),
|
||||
m(MODE),
|
||||
m(MUTE),
|
||||
m(N),
|
||||
m(NUMLOCKCLEAR),
|
||||
m(O),
|
||||
m(OPER),
|
||||
m(OUT),
|
||||
m(P),
|
||||
m(PAGEDOWN),
|
||||
m(PAGEUP),
|
||||
m(PASTE),
|
||||
m(PAUSE),
|
||||
m(PERIOD),
|
||||
m(POWER),
|
||||
m(PRINTSCREEN),
|
||||
m(PRIOR),
|
||||
m(Q),
|
||||
m(R),
|
||||
m(RALT),
|
||||
m(RCTRL),
|
||||
m(RETURN),
|
||||
m(RETURN2),
|
||||
m(RGUI),
|
||||
m(RIGHT),
|
||||
m(RIGHTBRACKET),
|
||||
m(RSHIFT),
|
||||
m(S),
|
||||
m(SCROLLLOCK),
|
||||
m(SELECT),
|
||||
m(SEMICOLON),
|
||||
m(SEPARATOR),
|
||||
m(SLASH),
|
||||
m(SLEEP),
|
||||
m(SPACE),
|
||||
m(STOP),
|
||||
m(SYSREQ),
|
||||
m(T),
|
||||
m(TAB),
|
||||
m(THOUSANDSSEPARATOR),
|
||||
m(U),
|
||||
m(UNDO),
|
||||
m(UNKNOWN),
|
||||
m(UP),
|
||||
m(V),
|
||||
m(VOLUMEDOWN),
|
||||
m(VOLUMEUP),
|
||||
m(W),
|
||||
m(WWW),
|
||||
m(X),
|
||||
m(Y),
|
||||
m(Z),
|
||||
m(INTERNATIONAL1),
|
||||
m(INTERNATIONAL2),
|
||||
m(INTERNATIONAL3),
|
||||
m(INTERNATIONAL4),
|
||||
m(INTERNATIONAL5),
|
||||
m(INTERNATIONAL6),
|
||||
m(INTERNATIONAL7),
|
||||
m(INTERNATIONAL8),
|
||||
m(INTERNATIONAL9),
|
||||
m(LANG1), m(LANG2),
|
||||
m(LANG3), m(LANG4),
|
||||
m(LANG5), m(LANG6),
|
||||
m(LANG7), m(LANG8),
|
||||
m(LANG9),
|
||||
m(NONUSBACKSLASH),
|
||||
m(NONUSHASH)
|
||||
};
|
||||
|
||||
#undef m
|
||||
|
||||
struct ButtonState
|
||||
|
@ -522,11 +739,12 @@ struct InputPrivate
|
|||
return statesOld[mapToIndex[code]];
|
||||
}
|
||||
|
||||
inline ButtonState getStateRaw(int code)
|
||||
inline ButtonState getStateRaw(int code, bool useVKey)
|
||||
{
|
||||
ButtonState b;
|
||||
int scancode = -1;
|
||||
|
||||
int scancode = (useVKey) ? -1 : code;
|
||||
if (scancode < 0)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 0x10:
|
||||
|
@ -561,6 +779,9 @@ struct InputPrivate
|
|||
}
|
||||
catch (...) {}
|
||||
if (scancode == -1) return b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
b.pressed = rawStates[scancode];
|
||||
b.triggered = (rawStates[scancode] && !rawStatesOld[scancode]);
|
||||
|
@ -576,8 +797,6 @@ struct InputPrivate
|
|||
b.repeated = repeated;
|
||||
|
||||
return b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
|
@ -920,19 +1139,19 @@ bool Input::isRepeated(int button)
|
|||
return p->getStateCheck(button).repeated;
|
||||
}
|
||||
|
||||
bool Input::isPressedEx(int vKey)
|
||||
bool Input::isPressedEx(int code, bool isVKey)
|
||||
{
|
||||
return p->getStateRaw(vKey).pressed;
|
||||
return p->getStateRaw(code, isVKey).pressed;
|
||||
}
|
||||
|
||||
bool Input::isTriggeredEx(int vKey)
|
||||
bool Input::isTriggeredEx(int code, bool isVKey)
|
||||
{
|
||||
return p->getStateRaw(vKey).triggered;
|
||||
return p->getStateRaw(code, isVKey).triggered;
|
||||
}
|
||||
|
||||
bool Input::isRepeatedEx(int vKey)
|
||||
bool Input::isRepeatedEx(int code, bool isVKey)
|
||||
{
|
||||
return p->getStateRaw(vKey).repeated;
|
||||
return p->getStateRaw(code, isVKey).repeated;
|
||||
}
|
||||
|
||||
int Input::dir4Value()
|
||||
|
|
12
src/input.h
12
src/input.h
|
@ -22,9 +22,11 @@
|
|||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
extern std::map<int, int> vKeyToScancode;
|
||||
extern std::unordered_map<int, int> vKeyToScancode;
|
||||
extern std::unordered_map<std::string, int> strToScancode;
|
||||
|
||||
struct InputPrivate;
|
||||
struct RGSSThreadData;
|
||||
|
@ -55,9 +57,9 @@ public:
|
|||
bool isPressed(int button);
|
||||
bool isTriggered(int button);
|
||||
bool isRepeated(int button);
|
||||
bool isPressedEx(int vKey);
|
||||
bool isTriggeredEx(int vKey);
|
||||
bool isRepeatedEx(int vKey);
|
||||
bool isPressedEx(int code, bool isVKey);
|
||||
bool isTriggeredEx(int code, bool isVKey);
|
||||
bool isRepeatedEx(int code, bool isVKey);
|
||||
|
||||
int dir4Value();
|
||||
int dir8Value();
|
||||
|
|
Loading…
Add table
Reference in a new issue