diff --git a/README.md b/README.md index 5084a83..50c9291 100644 --- a/README.md +++ b/README.md @@ -100,4 +100,4 @@ To alleviate possible porting of heavily Win32API reliant scripts, I have added * 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 functions, `#mouse_x` and `#mouse_y` to query the mouse pointer position relative to the game window. -* The `Graphics` module has an additional property `fullscreen`, which represents the current fullscreen mode (`true` = fullscreen, `false` = windowed). +* The `Graphics` module has two additional properties: `fullscreen` represents the current fullscreen mode (`true` = fullscreen, `false` = windowed), `show_cursor` hides the system cursor inside the game window when `false`. diff --git a/binding-mri/graphics-binding.cpp b/binding-mri/graphics-binding.cpp index 48d551f..9df69eb 100644 --- a/binding-mri/graphics-binding.cpp +++ b/binding-mri/graphics-binding.cpp @@ -81,26 +81,26 @@ RB_METHOD(graphicsFrameReset) return rb_fix_new(value); \ } +#define DEF_GRA_PROP_B(PropName) \ + RB_METHOD(graphics##Get##PropName) \ + { \ + RB_UNUSED_PARAM; \ + return rb_bool_new(gState->graphics().get##PropName()); \ + } \ + RB_METHOD(graphics##Set##PropName) \ + { \ + RB_UNUSED_PARAM; \ + bool value; \ + rb_get_args(argc, argv, "b", &value); \ + gState->graphics().set##PropName(value); \ + return rb_bool_new(value); \ + } + DEF_GRA_PROP_I(FrameRate) DEF_GRA_PROP_I(FrameCount) -RB_METHOD(graphicsGetFullscreen) -{ - RB_UNUSED_PARAM; - return rb_bool_new(gState->graphics().getFullscreen()); -} - -RB_METHOD(graphicsSetFullscreen) -{ - RB_UNUSED_PARAM; - - bool mode; - rb_get_args(argc, argv, "b", &mode); - - gState->graphics().setFullscreen(mode); - - return rb_bool_new(mode); -} +DEF_GRA_PROP_B(Fullscreen) +DEF_GRA_PROP_B(ShowCursor) #define INIT_GRA_PROP_BIND(PropName, prop_name_s) \ { \ @@ -120,5 +120,6 @@ void graphicsBindingInit() INIT_GRA_PROP_BIND( FrameRate, "frame_rate" ); INIT_GRA_PROP_BIND( FrameCount, "frame_count" ); - INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" ); + INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" ); + INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" ); } diff --git a/binding-mruby/graphics-binding.cpp b/binding-mruby/graphics-binding.cpp index cecb698..3c92ad5 100644 --- a/binding-mruby/graphics-binding.cpp +++ b/binding-mruby/graphics-binding.cpp @@ -76,28 +76,28 @@ MRB_FUNCTION(graphicsFrameReset) mrb_int value; \ mrb_get_args(mrb, "i", &value); \ gState->graphics().set##PropName(value); \ - return mrb_nil_value(); \ + return mrb_fixnum_value(value); \ + } + +#define DEF_GRA_PROP_B(PropName) \ + MRB_FUNCTION(graphics##Get##PropName) \ + { \ + MRB_FUN_UNUSED_PARAM; \ + return mrb_bool_value(gState->graphics().get##PropName()); \ + } \ + MRB_FUNCTION(graphics##Set##PropName) \ + { \ + mrb_bool value; \ + mrb_get_args(mrb, "b", &value); \ + gState->graphics().set##PropName(value); \ + return mrb_bool_value(value); \ } DEF_GRA_PROP_I(FrameRate) DEF_GRA_PROP_I(FrameCount) -MRB_FUNCTION(graphicsGetFullscreen) -{ - MRB_FUN_UNUSED_PARAM; - - return mrb_bool_value(gState->graphics().getFullscreen()); -} - -MRB_FUNCTION(graphicsSetFullscreen) -{ - mrb_bool mode; - mrb_get_args(mrb, "b", &mode); - - gState->graphics().setFullscreen(mode); - - return mrb_bool_value(mode); -} +DEF_GRA_PROP_B(Fullscreen) +DEF_GRA_PROP_B(ShowCursor) #define INIT_GRA_PROP_BIND(PropName, prop_name_s) \ { \ @@ -117,5 +117,6 @@ void graphicsBindingInit(mrb_state *mrb) INIT_GRA_PROP_BIND( FrameRate, "frame_rate" ); INIT_GRA_PROP_BIND( FrameCount, "frame_count" ); - INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" ); + INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" ); + INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" ); } diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 26fec6b..d3e6cbd 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -53,11 +53,13 @@ enum REQUEST_TERMINATION, REQUEST_SETFULLSCREEN, REQUEST_WINRESIZE, - REQUEST_MESSAGEBOX + REQUEST_MESSAGEBOX, + REQUEST_SETCURSORVISIBLE }; EventThread::EventThread() - : fullscreen(false) + : fullscreen(false), + showCursor(false) {} void EventThread::process(RGSSThreadData &rtData) @@ -68,6 +70,8 @@ void EventThread::process(RGSSThreadData &rtData) fullscreen = rtData.config.fullscreen; + bool cursorInWindow = false; + bool terminate = false; SDL_Joystick *js = 0; @@ -92,11 +96,28 @@ void EventThread::process(RGSSThreadData &rtData) event.window.data2); break; + case SDL_WINDOWEVENT_ENTER : + cursorInWindow = true; + updateCursorState(cursorInWindow); + break; + + case SDL_WINDOWEVENT_LEAVE : + cursorInWindow = false; + updateCursorState(cursorInWindow); + break; + case SDL_WINDOWEVENT_CLOSE : terminate = true; break; + case SDL_WINDOWEVENT_FOCUS_GAINED : + cursorInWindow = true; + updateCursorState(cursorInWindow); + break; + case SDL_WINDOWEVENT_FOCUS_LOST : + cursorInWindow = false; + updateCursorState(cursorInWindow); resetInputStates(); break; } @@ -135,6 +156,11 @@ void EventThread::process(RGSSThreadData &rtData) msgBoxDone = true; break; + case REQUEST_SETCURSORVISIBLE : + showCursor = event.user.code; + updateCursorState(cursorInWindow); + break; + case SDL_KEYUP : keyStates[event.key.keysym.scancode] = false; break; @@ -214,6 +240,14 @@ void EventThread::setFullscreen(SDL_Window *win, bool mode) fullscreen = mode; } +void EventThread::updateCursorState(bool inWindow) +{ + if (inWindow) + SDL_ShowCursor(showCursor ? SDL_TRUE : SDL_FALSE); + else + SDL_ShowCursor(SDL_TRUE); +} + void EventThread::requestTerminate() { SDL_Event event; @@ -241,6 +275,14 @@ void EventThread::requestWindowResize(int width, int height) SDL_PushEvent(&event); } +void EventThread::requestShowCursor(bool mode) +{ + SDL_Event event; + event.type = REQUEST_SETCURSORVISIBLE; + event.user.code = mode; + SDL_PushEvent(&event); +} + void EventThread::showMessageBox(const char *body, int flags) { msgBoxDone = false; @@ -257,7 +299,12 @@ void EventThread::showMessageBox(const char *body, int flags) resetInputStates(); } -bool EventThread::getFullscreen() +bool EventThread::getFullscreen() const { return fullscreen; } + +bool EventThread::getShowCursor() const +{ + return showCursor; +} diff --git a/src/eventthread.h b/src/eventthread.h index c479a98..4a686d7 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -69,17 +69,21 @@ public: /* Called from rgss thread */ void requestFullscreenMode(bool mode); void requestWindowResize(int width, int height); + void requestShowCursor(bool mode); void requestTerminate(); - bool getFullscreen(); + bool getFullscreen() const; + bool getShowCursor() const; void showMessageBox(const char *body, int flags = 0); private: void resetInputStates(); void setFullscreen(SDL_Window *, bool mode); + void updateCursorState(bool inWindow); bool fullscreen; + bool showCursor; volatile bool msgBoxDone; }; diff --git a/src/graphics.cpp b/src/graphics.cpp index 28bfd08..7cf8bc0 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -869,6 +869,16 @@ void Graphics::setFullscreen(bool value) p->threadData->ethread->requestFullscreenMode(value); } +bool Graphics::getShowCursor() const +{ + return p->threadData->ethread->getShowCursor(); +} + +void Graphics::setShowCursor(bool value) +{ + p->threadData->ethread->requestShowCursor(value); +} + Scene *Graphics::getScreen() const { return &p->screen; diff --git a/src/graphics.h b/src/graphics.h index 72a1178..eb6de60 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -59,6 +59,7 @@ public: /* Non-standard extension */ DECL_ATTR( Fullscreen, bool ) + DECL_ATTR( ShowCursor, bool ) /* */ Scene *getScreen() const;