Add Input.pressex?, Input.repeatex?, Input.triggerex?

This commit is contained in:
Inori 2019-09-02 11:16:38 -04:00 committed by Inori
parent 8f6b0775b6
commit ffec65b98f
7 changed files with 303 additions and 183 deletions

View file

@ -94,6 +94,36 @@ RB_METHOD(inputRepeat)
return rb_bool_new(shState->input().isRepeated(num));
}
RB_METHOD(inputPressEx)
{
RB_UNUSED_PARAM;
int num;
rb_get_args(argc, argv, "i", &num RB_ARG_END);
return rb_bool_new(shState->input().isPressedEx(num));
}
RB_METHOD(inputTriggerEx)
{
RB_UNUSED_PARAM;
int num;
rb_get_args(argc, argv, "i", &num RB_ARG_END);
return rb_bool_new(shState->input().isTriggeredEx(num));
}
RB_METHOD(inputRepeatEx)
{
RB_UNUSED_PARAM;
int num;
rb_get_args(argc, argv, "i", &num RB_ARG_END);
return rb_bool_new(shState->input().isRepeatedEx(num));
}
RB_METHOD(inputDir4)
{
RB_UNUSED_PARAM;
@ -171,6 +201,9 @@ inputBindingInit()
_rb_define_module_function(module, "press?", inputPress);
_rb_define_module_function(module, "trigger?", inputTrigger);
_rb_define_module_function(module, "repeat?", inputRepeat);
_rb_define_module_function(module, "pressex?", inputPressEx);
_rb_define_module_function(module, "triggerex?", inputTriggerEx);
_rb_define_module_function(module, "repeatex?", inputRepeatEx);
_rb_define_module_function(module, "dir4", inputDir4);
_rb_define_module_function(module, "dir8", inputDir8);

View file

@ -1,6 +1,6 @@
project('mkxp-z', 'cpp', 'c', version: '1.0', default_options: ['cpp_std=c++11'])
minimum_macos_version = '10.10'
minimum_macos_version = get_option('macos_min_version')
# The meson build is mostly directly copied from the old CMakeLists,
# it still needs to be cleaned up

View file

@ -1,10 +1,11 @@
option('shared_fluid', type: 'boolean', value: false, description: 'Dynamically link fluidsynth at build time')
option('mri_version', type: 'string', value: '1.8', description: 'Version of MRI to link with')
option('workdir_current', type: 'boolean', value: false, description: 'Keep current directory on startup')
option('ruby_lib', type: 'string', value: 'ruby', description: 'Name of the Ruby library')
option('console', type: 'boolean', value: true, description: 'Whether to debug information in the console')
option('macos_min_version', type: 'string', value: '10.10', description: 'Minimum macOS system version to support')
option('shared_fluid', type: 'boolean', value: false, description: 'Dynamically link fluidsynth at build time')
option('cjk_fallback_font', type: 'boolean', value: false, description: 'Use WenQuanYi Micro Hei as the fallback font')
option('use_fakeapi', type: 'boolean', value: false, description: 'Attempt to repair Win32API calls that do not work with MKXP')
option('default_framerate', type: 'boolean', value: false, description: 'Disable syncToRefreshrate and fixedFramerate configuration options')
option('no_preload_scripts', type: 'boolean', value: false, description: 'Disable the preloadScript configuration option')
option('no_preload_scripts', type: 'boolean', value: false, description: 'Disable the preloadScript configuration option')
option('workdir_current', type: 'boolean', value: false, description: 'Keep current directory on startup')

View file

@ -4,7 +4,6 @@
#include <windows.h>
#include <SDL_syswm.h>
#else
#include <map>
#include <cstring>
#include "iniconfig.h"
#endif
@ -50,178 +49,6 @@
// something instead of having to make a messy Win32API call
// that *now* has to run entirely different function to even work)
// macOS/Linux support WIP.
// ===============================================================
// This map is for converting Windows virtual keycodes to SDL's
// scancodes. Only needs to exist on macOS and Linux to allow
// getAsyncKeyState to work.
// ===============================================================
#ifndef __WIN32__
#define m(vk,sc) { vk, SDL_SCANCODE_##sc }
std::map<int, int> vKeyToScancode{
// 0x01 LEFT MOUSE
// 0x02 RIGHT MOUSE
m(0x03, CANCEL),
// 0x04 MIDDLE MOUSE
// 0x05 XBUTTON 1
// 0x06 XBUTTON 2
// 0x07 undef
m(0x08, BACKSPACE),
m(0x09, TAB),
// 0x0a reserved
// 0x0b reserved
m(0x0c, CLEAR),
m(0x0d, RETURN),
// 0x0e undefined
// 0x0f undefined
// 0x10 SHIFT (both)
// 0x11 CONTROL (both)
// 0x12 ALT (both)
m(0x13, PAUSE),
m(0x14, CAPSLOCK),
// 0x15 KANA, HANGUL
// 0x16 undefined
// 0x17 JUNJA
// 0x18 FINAL
// 0x19 HANJA, KANJI
// 0x1a undefined
m(0x1b, ESCAPE),
// 0x1c CONVERT
// 0x1d NONCONVERT
// 0x1e ACCEPT
// 0x1f MODECHANGE
m(0x20, SPACE),
m(0x21, PAGEUP),
m(0x22, PAGEDOWN),
m(0x23, END),
m(0x24, HOME),
m(0x25, LEFT),
m(0x26, UP),
m(0x27, RIGHT),
m(0x28, DOWN),
m(0x29, SELECT),
// 0x2A print
m(0x2b, EXECUTE),
m(0x2c, PRINTSCREEN),
m(0x2d, INSERT),
m(0x2e, DELETE),
m(0x2f, HELP),
m(0x30, 0), m(0x31, 1),
m(0x32, 2), m(0x33, 3),
m(0x34, 4), m(0x35, 5),
m(0x36, 6), m(0x37, 7),
m(0x38, 8), m(0x39, 9),
// 0x3a-0x40 undefined
m(0x41, A), m(0x42, B),
m(0x43, C), m(0x44, D),
m(0x45, E), m(0x46, F),
m(0x47, G), m(0x48, H),
m(0x49, I), m(0x4a, J),
m(0x4b, K), m(0x4c, L),
m(0x4d, M), m(0x4e, N),
m(0x4f, O), m(0x50, P),
m(0x51, Q), m(0x52, R),
m(0x53, S), m(0x54, T),
m(0x55, U), m(0x56, V),
m(0x57, W), m(0x58, X),
m(0x59, Y), m(0x5a, Z),
m(0x5b, LGUI), m(0x5c, RGUI),
m(0x5d, APPLICATION),
// 0x5e reserved
m(0x5f, SLEEP),
m(0x60, KP_0), m(0x61, KP_1),
m(0x62, KP_2), m(0x63, KP_3),
m(0x64, KP_4), m(0x65, KP_5),
m(0x66, KP_6), m(0x67, KP_7),
m(0x68, KP_8), m(0x69, KP_9),
m(0x6a, KP_MULTIPLY),
m(0x6b, KP_PLUS),
m(0x6c, RETURN), // SEPARATOR
m(0x6d, KP_MINUS),
m(0x6e, KP_DECIMAL),
m(0x6f, KP_DIVIDE),
m(0x70, F1), m(0x71, F2),
m(0x72, F3), m(0x73, F4),
m(0x74, F5), m(0x75, F6),
m(0x76, F7), m(0x77, F8),
m(0x78, F9), m(0x79, F10),
m(0x7a, F11), m(0x7b, F12),
m(0x7c, F13), m(0x7d, F14),
m(0x7e, F15), m(0x7f, F16),
m(0x80, F17), m(0x81, F18),
m(0x82, F19), m(0x83, F20),
m(0x84, F21), m(0x85, F22),
m(0x86, F23), m(0x87, F24),
// 0x88-0x8f unassigned
m(0x90, NUMLOCKCLEAR),
m(0x91, SCROLLLOCK),
// 0x92-0x96 oem specific
// 0x97-0x9f unassigned
m(0xa0, LSHIFT),
m(0xa1, RSHIFT),
m(0xa2, LCTRL),
m(0xa3, RCTRL),
m(0xa4, LALT),
m(0xa5, RALT),
m(0xa6, AC_BACK),
m(0xa7, AC_FORWARD),
m(0xa8, AC_REFRESH),
m(0xa9, AC_STOP),
m(0xaa, AC_SEARCH),
// 0xab BROWSER_FAVORITES
m(0xac, AC_HOME),
m(0xad, AUDIOMUTE),
m(0xae, VOLUMEDOWN),
m(0xaf, VOLUMEUP),
m(0xb0, AUDIONEXT),
m(0xb1, AUDIOPREV),
m(0xb2, AUDIOSTOP),
m(0xb3, AUDIOPLAY),
m(0xb4, MAIL),
m(0xb5, MEDIASELECT),
// 0xb6 LAUNCH_APP1
// 0xb7 LAUNCH_APP2
// 0xb8-0xb9 reserved
// Everything below here is OEM
// and can vary by country
m(0xba, SEMICOLON),
m(0xbb, EQUALS),
m(0xbc, COMMA),
m(0xbd, MINUS),
m(0xbe, PERIOD),
m(0xbf, SLASH),
m(0xc0, GRAVE),
// 0xc1-0xd7 reserved
// 0xd8-0xda unassigned
m(0xdb, LEFTBRACKET),
m(0xdc, BACKSLASH),
m(0xdd, RIGHTBRACKET),
m(0xde, APOSTROPHE),
// 0xdf OEM_8
// 0xe0 reserved
// 0xe1 oem-specific
// 0xe2 OEM_102
// 0xe3-0xe4 oem-specific
// 0xe5 PROCESSKEY
// 0xe6 oem-specific
// 0xe7 PACKET
// 0xe8 unassigned
// 0xe9-0xf5 oem_specific
// 0xf6 ATTN
m(0xf7, CRSEL),
m(0xf8, EXSEL),
// 0xf9 EREOF
m(0xfa, AUDIOPLAY), // PLAY, guessing
// 0xfb ZOOM
// 0xfc NONAME
// 0xfd PA1
m(0xfe, CLEAR)
};
#undef m
#endif
PREFABI DWORD
MKXP_GetCurrentThreadId(void)
NOP_VAL(DUMMY_VAL)
@ -440,10 +267,14 @@ MKXP_GetAsyncKeyState(int vKey)
break;
default:
try {
try
{
// Use EventThread instead of Input because
// Input.update typically gets overridden
result = shState->eThread().keyStates[vKeyToScancode[vKey]] << 15;
}
catch (...) {
catch (...)
{
result = 0;
}
break;

View file

@ -2,8 +2,6 @@
#ifdef __WIN32__
#include <windows.h>
#else
#include <map>
#endif
#define ABI(x) __attribute__((x))
@ -42,8 +40,6 @@ typedef struct {
DWORD BatteryLifeTime;
DWORD BatteryFullLifeTime;
} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
extern std::map<int, int> vKeyToScancode;
#endif
#define DUMMY_VAL 571

View file

@ -30,11 +30,177 @@
#include <SDL_mouse.h>
#include <vector>
#include <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{
// 0x01 LEFT MOUSE
// 0x02 RIGHT MOUSE
m(0x03, CANCEL),
// 0x04 MIDDLE MOUSE
// 0x05 XBUTTON 1
// 0x06 XBUTTON 2
// 0x07 undef
m(0x08, BACKSPACE),
m(0x09, TAB),
// 0x0a reserved
// 0x0b reserved
m(0x0c, CLEAR),
m(0x0d, RETURN),
// 0x0e undefined
// 0x0f undefined
// 0x10 SHIFT (both)
// 0x11 CONTROL (both)
// 0x12 ALT (both)
m(0x13, PAUSE),
m(0x14, CAPSLOCK),
// 0x15 KANA, HANGUL
// 0x16 undefined
// 0x17 JUNJA
// 0x18 FINAL
// 0x19 HANJA, KANJI
// 0x1a undefined
m(0x1b, ESCAPE),
// 0x1c CONVERT
// 0x1d NONCONVERT
// 0x1e ACCEPT
// 0x1f MODECHANGE
m(0x20, SPACE),
m(0x21, PAGEUP),
m(0x22, PAGEDOWN),
m(0x23, END),
m(0x24, HOME),
m(0x25, LEFT),
m(0x26, UP),
m(0x27, RIGHT),
m(0x28, DOWN),
m(0x29, SELECT),
// 0x2A print
m(0x2b, EXECUTE),
m(0x2c, PRINTSCREEN),
m(0x2d, INSERT),
m(0x2e, DELETE),
m(0x2f, HELP),
m(0x30, 0), m(0x31, 1),
m(0x32, 2), m(0x33, 3),
m(0x34, 4), m(0x35, 5),
m(0x36, 6), m(0x37, 7),
m(0x38, 8), m(0x39, 9),
// 0x3a-0x40 undefined
m(0x41, A), m(0x42, B),
m(0x43, C), m(0x44, D),
m(0x45, E), m(0x46, F),
m(0x47, G), m(0x48, H),
m(0x49, I), m(0x4a, J),
m(0x4b, K), m(0x4c, L),
m(0x4d, M), m(0x4e, N),
m(0x4f, O), m(0x50, P),
m(0x51, Q), m(0x52, R),
m(0x53, S), m(0x54, T),
m(0x55, U), m(0x56, V),
m(0x57, W), m(0x58, X),
m(0x59, Y), m(0x5a, Z),
m(0x5b, LGUI), m(0x5c, RGUI),
m(0x5d, APPLICATION),
// 0x5e reserved
m(0x5f, SLEEP),
m(0x60, KP_0), m(0x61, KP_1),
m(0x62, KP_2), m(0x63, KP_3),
m(0x64, KP_4), m(0x65, KP_5),
m(0x66, KP_6), m(0x67, KP_7),
m(0x68, KP_8), m(0x69, KP_9),
m(0x6a, KP_MULTIPLY),
m(0x6b, KP_PLUS),
m(0x6c, RETURN), // SEPARATOR
m(0x6d, KP_MINUS),
m(0x6e, KP_DECIMAL),
m(0x6f, KP_DIVIDE),
m(0x70, F1), m(0x71, F2),
m(0x72, F3), m(0x73, F4),
m(0x74, F5), m(0x75, F6),
m(0x76, F7), m(0x77, F8),
m(0x78, F9), m(0x79, F10),
m(0x7a, F11), m(0x7b, F12),
m(0x7c, F13), m(0x7d, F14),
m(0x7e, F15), m(0x7f, F16),
m(0x80, F17), m(0x81, F18),
m(0x82, F19), m(0x83, F20),
m(0x84, F21), m(0x85, F22),
m(0x86, F23), m(0x87, F24),
// 0x88-0x8f unassigned
m(0x90, NUMLOCKCLEAR),
m(0x91, SCROLLLOCK),
// 0x92-0x96 oem specific
// 0x97-0x9f unassigned
m(0xa0, LSHIFT),
m(0xa1, RSHIFT),
m(0xa2, LCTRL),
m(0xa3, RCTRL),
m(0xa4, LALT),
m(0xa5, RALT),
m(0xa6, AC_BACK),
m(0xa7, AC_FORWARD),
m(0xa8, AC_REFRESH),
m(0xa9, AC_STOP),
m(0xaa, AC_SEARCH),
// 0xab BROWSER_FAVORITES
m(0xac, AC_HOME),
m(0xad, AUDIOMUTE),
m(0xae, VOLUMEDOWN),
m(0xaf, VOLUMEUP),
m(0xb0, AUDIONEXT),
m(0xb1, AUDIOPREV),
m(0xb2, AUDIOSTOP),
m(0xb3, AUDIOPLAY),
m(0xb4, MAIL),
m(0xb5, MEDIASELECT),
// 0xb6 LAUNCH_APP1
// 0xb7 LAUNCH_APP2
// 0xb8-0xb9 reserved
// Everything below here is OEM
// and can vary by country
m(0xba, SEMICOLON),
m(0xbb, EQUALS),
m(0xbc, COMMA),
m(0xbd, MINUS),
m(0xbe, PERIOD),
m(0xbf, SLASH),
m(0xc0, GRAVE),
// 0xc1-0xd7 reserved
// 0xd8-0xda unassigned
m(0xdb, LEFTBRACKET),
m(0xdc, BACKSLASH),
m(0xdd, RIGHTBRACKET),
m(0xde, APOSTROPHE),
// 0xdf OEM_8
// 0xe0 reserved
// 0xe1 oem-specific
// 0xe2 OEM_102
// 0xe3-0xe4 oem-specific
// 0xe5 PROCESSKEY
// 0xe6 oem-specific
// 0xe7 PACKET
// 0xe8 unassigned
// 0xe9-0xf5 oem_specific
// 0xf6 ATTN
m(0xf7, CRSEL),
m(0xf8, EXSEL),
// 0xf9 EREOF
m(0xfa, AUDIOPLAY), // PLAY, guessing
// 0xfb ZOOM
// 0xfc NONAME
// 0xfd PA1
m(0xfe, CLEAR)
};
#undef m
struct ButtonState
{
bool pressed;
@ -280,6 +446,12 @@ struct InputPrivate
ButtonState *states;
ButtonState *statesOld;
// Raw keystates
uint8_t rawStateArray[SDL_NUM_SCANCODES*2];
uint8_t *rawStates;
uint8_t *rawStatesOld;
Input::ButtonCode repeating;
unsigned int repeatCount;
@ -306,6 +478,9 @@ struct InputPrivate
states = stateArray;
statesOld = stateArray + BUTTON_CODE_COUNT;
rawStates = rawStateArray;
rawStatesOld = rawStateArray + SDL_NUM_SCANCODES;
/* Clear buffers */
clearBuffer();
@ -342,18 +517,72 @@ struct InputPrivate
{
return statesOld[mapToIndex[code]];
}
inline ButtonState getStateRaw(int code)
{
ButtonState b;
int scancode = -1;
switch (code)
{
case 0x10:
return getState(Input::Shift);
break;
case 0x11:
return getState(Input::Ctrl);
break;
case 0x12:
return getState(Input::Alt);
break;
case 0x1:
return getState(Input::MouseLeft);
break;
case 0x2:
return getState(Input::MouseRight);
break;
case 0x4:
return getState(Input::MouseMiddle);
break;
default:
ButtonState b;
try
{
scancode = vKeyToScancode[code];
}
catch (...) {}
if (scancode == -1) return b;
b.pressed = rawStates[scancode];
b.triggered = (rawStates[scancode] && !rawStatesOld[scancode]);
b.repeated = (rawStates[scancode] && rawStatesOld[scancode]);
return b;
break;
}
}
void swapBuffers()
{
ButtonState *tmp = states;
states = statesOld;
statesOld = tmp;
uint8_t *tmpr = rawStates;
rawStates = rawStatesOld;
rawStatesOld = tmpr;
}
void clearBuffer()
{
const size_t size = sizeof(ButtonState) * BUTTON_CODE_COUNT;
memset(states, 0, size);
memset(rawStates, 0, SDL_NUM_SCANCODES);
}
void checkBindingChange(const RGSSThreadData &rtData)
@ -505,6 +734,11 @@ struct InputPrivate
repeating = Input::None;
}
}
void updateRaw()
{
memcpy(rawStates, shState->eThread().keyStates, SDL_NUM_SCANCODES);
}
void updateDir4()
{
@ -606,6 +840,9 @@ void Input::update()
/* Poll all bindings */
p->pollBindings(repeatCand);
// Get raw keystates
p->updateRaw();
/* Check for new repeating key */
if (repeatCand != None && repeatCand != p->repeating)
@ -651,6 +888,21 @@ bool Input::isRepeated(int button)
return p->getStateCheck(button).repeated;
}
bool Input::isPressedEx(int vKey)
{
return p->getStateRaw(vKey).pressed;
}
bool Input::isTriggeredEx(int vKey)
{
return p->getStateRaw(vKey).triggered;
}
bool Input::isRepeatedEx(int vKey)
{
return p->getStateRaw(vKey).repeated;
}
int Input::dir4Value()
{
return p->dir4Data.active;

View file

@ -22,6 +22,10 @@
#ifndef INPUT_H
#define INPUT_H
#include <map>
extern std::map<int, int> vKeyToScancode;
struct InputPrivate;
struct RGSSThreadData;
@ -51,6 +55,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);
int dir4Value();
int dir8Value();