Add Input.joystick

This commit is contained in:
Inori 2019-09-16 23:10:46 -04:00 committed by Inori
parent 3b71c1f501
commit 939c601aea
8 changed files with 95 additions and 16 deletions

View file

@ -117,8 +117,8 @@ 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` module has two additional property: `text_input` determines whether to accept text editing events. `clipboard` gets and sets the user's clipboard.
* The `Input` module has six 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.
* 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`.
### Graphics

View file

@ -32,6 +32,8 @@
#include "intern.h"
#endif
#include "debugwriter.h"
static void
fileIntFreeInstance(void *inst)
{
@ -151,16 +153,6 @@ kernelLoadDataInt(const char *filename, bool rubyExc)
VALUE port = fileIntForPath(filename, rubyExc);
// RGSS checks to see if a file is in the RGSSAD,
// and if it is, just passes a char* and the length
// of the file to rb_str_new and gives that back to
// Marshal. I haven't checked if the whole archive
// is kept decrypted in memory (probably, if the
// file is always locked), but either way, dumping
// the file to a string is much faster than faking
// the IO. Seems to cause a bit of startup lag,
// but that's no doubt fixable
VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal"));
// FIXME need to catch exceptions here with begin rescue
@ -189,13 +181,15 @@ RB_METHOD(kernelLoadData)
1,
rb_str_new2("Graphics"));
if (isGraphicsFile == Qtrue)
if (Qfalse == Qtrue)
{
VALUE f = rb_file_open_str(filename, "rb");
VALUE ret = rb_funcall(f, rb_intern("read"), 0);
rb_funcall(f, rb_intern("close"), 0);
return ret;
}
Debug() << "KernelLoadDataInt (" << RSTRING_PTR(filename) << ")";
return kernelLoadDataInt(RSTRING_PTR(filename), true);
}

View file

@ -25,6 +25,8 @@
#include "binding-util.h"
#include "util.h"
#include <SDL_joystick.h>
RB_METHOD(inputUpdate)
{
RB_UNUSED_PARAM;
@ -153,6 +155,45 @@ RB_METHOD(inputMouseY)
return rb_fix_new(shState->input().mouseY());
}
#define M_SYMBOL(x) ID2SYM(rb_intern(x))
#define POWERCASE(v,c) \
case SDL_JOYSTICK_POWER_##c: \
v = M_SYMBOL(#c); \
break;
RB_METHOD(inputJoystickInfo)
{
RB_UNUSED_PARAM;
if (!shState->input().getJoystickConnected())
return RUBY_Qnil;
VALUE ret = rb_hash_new();
rb_hash_aset(ret, M_SYMBOL("name"), rb_str_new_cstr(shState->input().getJoystickName()));
VALUE power;
switch (shState->input().getJoystickPowerLevel()) {
POWERCASE(power, MAX);
POWERCASE(power, WIRED);
POWERCASE(power, FULL);
POWERCASE(power, MEDIUM);
POWERCASE(power, LOW);
POWERCASE(power, EMPTY);
default:
power = M_SYMBOL("UNKNOWN");
break;
}
rb_hash_aset(ret, M_SYMBOL("power"), power);
return ret;
}
#undef POWERCASE
#undef M_SYMBOL
RB_METHOD(inputGetMode)
{
RB_UNUSED_PARAM;
@ -268,6 +309,8 @@ inputBindingInit()
_rb_define_module_function(module, "mouse_x", inputMouseX);
_rb_define_module_function(module, "mouse_y", inputMouseY);
_rb_define_module_function(module, "joystick", inputJoystickInfo);
_rb_define_module_function(module, "text_input", inputGetMode);
_rb_define_module_function(module, "text_input=", inputSetMode);
_rb_define_module_function(module, "gets", inputGets);

View file

@ -110,7 +110,9 @@ bool EventThread::allocUserEvents()
EventThread::EventThread()
: fullscreen(false),
showCursor(true)
showCursor(true),
joystickConnected(false),
js(0)
{}
void EventThread::process(RGSSThreadData &rtData)
@ -148,7 +150,6 @@ void EventThread::process(RGSSThreadData &rtData)
bool terminate = false;
SDL_Joystick *js = 0;
if (SDL_NumJoysticks() > 0)
js = SDL_JoystickOpen(0);
@ -377,10 +378,12 @@ void EventThread::process(RGSSThreadData &rtData)
break;
js = SDL_JoystickOpen(0);
joystickConnected = true;
break;
case SDL_JOYDEVICEREMOVED :
resetInputStates();
joystickConnected = false;
break;
case SDL_MOUSEBUTTONDOWN :
@ -697,6 +700,16 @@ bool EventThread::getShowCursor() const
return showCursor;
}
bool EventThread::getJoystickConnected() const
{
return joystickConnected;
}
SDL_Joystick *EventThread::joystick() const
{
return (joystickConnected) ? js : 0;
}
void EventThread::notifyFrame()
{
if (!fps.sendUpdates)

View file

@ -99,6 +99,9 @@ public:
bool getFullscreen() const;
bool getShowCursor() const;
bool getJoystickConnected() const;
SDL_Joystick *joystick() const;
void showMessageBox(const char *body, int flags = 0);
@ -117,7 +120,10 @@ private:
const SDL_Rect &screen);
bool fullscreen;
bool joystickConnected;
bool showCursor;
SDL_Joystick *js;
AtomicFlag msgBoxDone;
struct

View file

@ -463,7 +463,7 @@ MKXP_GetUserDefaultLangID(void)
PREFABI BOOL
MKXP_GetUserName(LPSTR lpBuffer, LPDWORD pcbBuffer)
{
if (*pcbBuffer < 2) return false;
if (*pcbBuffer < 1) return false;
char *username = getenv("USER");
strncpy(lpBuffer, (username) ? username : "ditto", *pcbBuffer);
lpBuffer[0] = toupper(lpBuffer[0]);

View file

@ -959,6 +959,25 @@ int Input::mouseY()
return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y;
}
bool Input::getJoystickConnected()
{
return shState->eThread().getJoystickConnected();
}
const char *Input::getJoystickName()
{
return (getJoystickConnected()) ?
SDL_JoystickName(shState->eThread().joystick()) :
0;
}
int Input::getJoystickPowerLevel()
{
return (getJoystickConnected()) ?
SDL_JoystickCurrentPowerLevel(shState->eThread().joystick()) :
SDL_JOYSTICK_POWER_UNKNOWN;
}
bool Input::getTextInputMode()
{
return (SDL_IsTextInputActive() == SDL_TRUE);

View file

@ -66,6 +66,10 @@ public:
int mouseX();
int mouseY();
bool getJoystickConnected();
const char *getJoystickName();
int getJoystickPowerLevel();
bool getTextInputMode();
void setTextInputMode(bool mode);
const char *getText();