mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-10 12:02:53 +02:00
Test controller rumble support
This commit is contained in:
parent
8175a98cc2
commit
582eee853b
6 changed files with 93 additions and 3 deletions
|
@ -116,7 +116,12 @@ mkxp-z provides limited support for some WinAPI functions that would normally br
|
|||
|
||||
* 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?/trigger?/repeat? :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`.
|
||||
* The `Input` module has eight additional functions.
|
||||
+ `#mouse_x` and `#mouse_y` 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 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 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`.
|
||||
+ `#rumble` triggers a simple rumble effect on supported controllers. It has one required argument (the duration in ms), and three optional arguments (the strength from 0 to 100, the attack envelope duration in ms, and the fade envelope duration in ms)
|
||||
|
||||
### Graphics
|
||||
|
||||
|
|
|
@ -248,6 +248,22 @@ RB_METHOD(inputJoystickInfo)
|
|||
#undef POWERCASE
|
||||
#undef M_SYMBOL
|
||||
|
||||
RB_METHOD(inputRumble)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
VALUE duration, strength, attack, fade;
|
||||
rb_scan_args(argc, argv, "13", &duration, &strength, &attack, &fade);
|
||||
|
||||
int dur = NUM2INT(duration);
|
||||
int str = (NIL_P(strength)) ? 1 : NUM2INT(strength);
|
||||
int att = (NIL_P(attack)) ? 0 : NUM2INT(attack);
|
||||
int fad = (NIL_P(fade)) ? 0 : NUM2INT(fade);
|
||||
|
||||
shState->input().rumble(dur, str, att, fad);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
RB_METHOD(inputGetMode)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
@ -364,6 +380,7 @@ inputBindingInit()
|
|||
_rb_define_module_function(module, "mouse_y", inputMouseY);
|
||||
|
||||
_rb_define_module_function(module, "joystick", inputJoystickInfo);
|
||||
_rb_define_module_function(module, "rumble", inputRumble);
|
||||
|
||||
_rb_define_module_function(module, "text_input", inputGetMode);
|
||||
_rb_define_module_function(module, "text_input=", inputSetMode);
|
||||
|
|
|
@ -91,6 +91,8 @@ enum
|
|||
REQUEST_TEXTMODE,
|
||||
|
||||
REQUEST_SETTINGS,
|
||||
|
||||
REQUEST_RUMBLE,
|
||||
|
||||
UPDATE_FPS,
|
||||
UPDATE_SCREEN_RECT,
|
||||
|
@ -111,10 +113,12 @@ bool EventThread::allocUserEvents()
|
|||
}
|
||||
|
||||
EventThread::EventThread()
|
||||
: fullscreen(false),
|
||||
: js(0),
|
||||
hapt(0),
|
||||
fullscreen(false),
|
||||
showCursor(true),
|
||||
joystickConnected(false),
|
||||
js(0)
|
||||
hapticEffectId(0)
|
||||
{}
|
||||
|
||||
void EventThread::process(RGSSThreadData &rtData)
|
||||
|
@ -169,6 +173,8 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
|
||||
SDL_GetWindowSize(win, &winW, &winH);
|
||||
|
||||
SDL_Haptic *hap;
|
||||
memset(&hapticEffect, 0, sizeof(SDL_HapticEffect));
|
||||
textInputBuffer.clear();
|
||||
|
||||
SettingsMenu *sMenu = 0;
|
||||
|
@ -381,11 +387,17 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
|
||||
js = SDL_JoystickOpen(0);
|
||||
joystickConnected = true;
|
||||
|
||||
hap = SDL_HapticOpenFromJoystick(js);
|
||||
if (hap && (SDL_HapticQuery(hap) & SDL_HAPTIC_SINE))
|
||||
hapt = hap;
|
||||
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEREMOVED :
|
||||
resetInputStates();
|
||||
joystickConnected = false;
|
||||
hapt = 0;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN :
|
||||
|
@ -480,6 +492,21 @@ void EventThread::process(RGSSThreadData &rtData)
|
|||
}
|
||||
|
||||
sMenu->raise();
|
||||
break;
|
||||
|
||||
case REQUEST_RUMBLE :
|
||||
if (!hapt) break;
|
||||
if (!hapticEffect.type)
|
||||
{
|
||||
hapticEffect.type = SDL_HAPTIC_SINE;
|
||||
hapticEffect.constant.attack_level = 0;
|
||||
hapticEffect.constant.fade_level = 0;
|
||||
hapticEffectId = SDL_HapticNewEffect(hapt, &hapticEffect);
|
||||
}
|
||||
|
||||
SDL_HapticUpdateEffect(hapt, hapticEffectId, &hapticEffect);
|
||||
|
||||
SDL_HapticRunEffect(hapt, hapticEffectId, 1);
|
||||
break;
|
||||
|
||||
case UPDATE_FPS :
|
||||
|
@ -693,6 +720,19 @@ void EventThread::requestSettingsMenu()
|
|||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void EventThread::requestRumble(int duration, short strength, int attack, int fade)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = usrIdStart + REQUEST_RUMBLE;
|
||||
|
||||
hapticEffect.constant.length = duration;
|
||||
hapticEffect.constant.level = strength;
|
||||
hapticEffect.constant.attack_length = attack;
|
||||
hapticEffect.constant.fade_length = fade;
|
||||
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void EventThread::showMessageBox(const char *body, int flags)
|
||||
{
|
||||
msgBoxDone.clear();
|
||||
|
@ -729,6 +769,11 @@ SDL_Joystick *EventThread::joystick() const
|
|||
return (joystickConnected) ? js : 0;
|
||||
}
|
||||
|
||||
SDL_Haptic *EventThread::haptic() const
|
||||
{
|
||||
return hapt;
|
||||
}
|
||||
|
||||
void EventThread::notifyFrame()
|
||||
{
|
||||
if (!fps.sendUpdates)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <SDL_scancode.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_haptic.h>
|
||||
#include <SDL_mouse.h>
|
||||
#include <SDL_mutex.h>
|
||||
|
||||
|
@ -96,6 +97,8 @@ public:
|
|||
void requestTextInputMode(bool mode);
|
||||
|
||||
void requestSettingsMenu();
|
||||
|
||||
void requestRumble(int duration, short strength, int attack, int fade);
|
||||
|
||||
void requestTerminate();
|
||||
|
||||
|
@ -104,6 +107,7 @@ public:
|
|||
bool getJoystickConnected() const;
|
||||
|
||||
SDL_Joystick *joystick() const;
|
||||
SDL_Haptic *haptic() const;
|
||||
|
||||
void showMessageBox(const char *body, int flags = 0);
|
||||
|
||||
|
@ -126,6 +130,10 @@ private:
|
|||
bool showCursor;
|
||||
|
||||
SDL_Joystick *js;
|
||||
SDL_Haptic *hapt;
|
||||
SDL_HapticEffect hapticEffect;
|
||||
int hapticEffectId;
|
||||
|
||||
AtomicFlag msgBoxDone;
|
||||
|
||||
struct
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <SDL_keyboard.h>
|
||||
#include <SDL_mouse.h>
|
||||
#include <SDL_clipboard.h>
|
||||
#include <SDL_haptic.h>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
@ -1197,6 +1198,18 @@ int Input::getJoystickPowerLevel()
|
|||
SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
}
|
||||
|
||||
void Input::rumble(int duration, int strength, int attack, int fade)
|
||||
{
|
||||
duration = clamp(duration, 0, 10000);
|
||||
strength = clamp(strength, 1, 100);
|
||||
attack = clamp(attack, 0, 10000);
|
||||
fade = clamp(fade, 0, 10000);
|
||||
shState->eThread().requestRumble(duration,
|
||||
(short)((double)strength / 100 * 32767),
|
||||
attack,
|
||||
fade);
|
||||
}
|
||||
|
||||
bool Input::getTextInputMode()
|
||||
{
|
||||
return (SDL_IsTextInputActive() == SDL_TRUE);
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
const char *getJoystickName();
|
||||
int getJoystickPowerLevel();
|
||||
|
||||
void rumble(int duration, int strength, int attack, int fade);
|
||||
|
||||
bool getTextInputMode();
|
||||
void setTextInputMode(bool mode);
|
||||
const char *getText();
|
||||
|
|
Loading…
Add table
Reference in a new issue