From 1dcd252f4523d8847fbe2d1dbde3c32b0df9887d Mon Sep 17 00:00:00 2001 From: Inori Date: Mon, 16 Sep 2019 23:10:46 -0400 Subject: [PATCH] Add Input.joystick --- README.md | 4 ++-- binding/filesystem-binding.cpp | 16 ++++--------- binding/input-binding.cpp | 43 ++++++++++++++++++++++++++++++++++ src/eventthread.cpp | 17 ++++++++++++-- src/eventthread.h | 6 +++++ src/fake-api.cpp | 2 +- src/input.cpp | 19 +++++++++++++++ src/input.h | 4 ++++ 8 files changed, 95 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ba09440c..dca460d8 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/binding/filesystem-binding.cpp b/binding/filesystem-binding.cpp index 531a4903..db89efaf 100644 --- a/binding/filesystem-binding.cpp +++ b/binding/filesystem-binding.cpp @@ -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); } diff --git a/binding/input-binding.cpp b/binding/input-binding.cpp index 4ca484fd..044cdef9 100644 --- a/binding/input-binding.cpp +++ b/binding/input-binding.cpp @@ -25,6 +25,8 @@ #include "binding-util.h" #include "util.h" +#include + 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); diff --git a/src/eventthread.cpp b/src/eventthread.cpp index ba9cd806..d4894d4b 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -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) diff --git a/src/eventthread.h b/src/eventthread.h index 025300a3..a8de4160 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -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 diff --git a/src/fake-api.cpp b/src/fake-api.cpp index dbdaebaa..5316d0ad 100644 --- a/src/fake-api.cpp +++ b/src/fake-api.cpp @@ -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]); diff --git a/src/input.cpp b/src/input.cpp index 4af45ae1..42306839 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -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); diff --git a/src/input.h b/src/input.h index a64aaf1f..65762628 100644 --- a/src/input.h +++ b/src/input.h @@ -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();