diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 00c1b3e..42dab49 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -83,6 +83,7 @@ enum REQUEST_SETCURSORVISIBLE, UPDATE_FPS, + UPDATE_SCREEN_RECT, EVENT_COUNT }; @@ -131,6 +132,8 @@ void EventThread::process(RGSSThreadData &rtData) bool displayingFPS = false; bool cursorInWindow = false; + /* Will be updated eventually */ + SDL_Rect gameScreen = { 0, 0, 0, 0 }; /* SDL doesn't send an initial FOCUS_GAINED event */ bool windowFocused = true; @@ -170,7 +173,7 @@ void EventThread::process(RGSSThreadData &rtData) delete sMenu; sMenu = 0; - updateCursorState(cursorInWindow && windowFocused); + updateCursorState(cursorInWindow && windowFocused, gameScreen); } continue; @@ -211,14 +214,14 @@ void EventThread::process(RGSSThreadData &rtData) case SDL_WINDOWEVENT_ENTER : cursorInWindow = true; mouseState.inWindow = true; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); break; case SDL_WINDOWEVENT_LEAVE : cursorInWindow = false; mouseState.inWindow = false; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); break; @@ -229,13 +232,13 @@ void EventThread::process(RGSSThreadData &rtData) case SDL_WINDOWEVENT_FOCUS_GAINED : windowFocused = true; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); break; case SDL_WINDOWEVENT_FOCUS_LOST : windowFocused = false; - updateCursorState(cursorInWindow && windowFocused && !sMenu); + updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen); resetInputStates(); break; @@ -268,7 +271,7 @@ void EventThread::process(RGSSThreadData &rtData) if (!sMenu) { sMenu = new SettingsMenu(rtData); - updateCursorState(false); + updateCursorState(false, gameScreen); } sMenu->raise(); @@ -374,6 +377,7 @@ void EventThread::process(RGSSThreadData &rtData) case SDL_MOUSEMOTION : mouseState.x = event.motion.x; mouseState.y = event.motion.y; + updateCursorState(cursorInWindow, gameScreen); break; case SDL_FINGERDOWN : @@ -413,7 +417,7 @@ void EventThread::process(RGSSThreadData &rtData) case REQUEST_SETCURSORVISIBLE : showCursor = event.user.code; - updateCursorState(cursorInWindow); + updateCursorState(cursorInWindow, gameScreen); break; case UPDATE_FPS : @@ -438,6 +442,15 @@ void EventThread::process(RGSSThreadData &rtData) SDL_SetWindowTitle(win, buffer); break; + + case UPDATE_SCREEN_RECT : + gameScreen.x = event.user.windowID; + gameScreen.y = event.user.code; + gameScreen.w = reinterpret_cast(event.user.data1); + gameScreen.h = reinterpret_cast(event.user.data2); + updateCursorState(cursorInWindow, gameScreen); + + break; } } @@ -532,9 +545,13 @@ void EventThread::setFullscreen(SDL_Window *win, bool mode) fullscreen = mode; } -void EventThread::updateCursorState(bool inWindow) +void EventThread::updateCursorState(bool inWindow, + const SDL_Rect &screen) { - if (inWindow) + SDL_Point pos = { mouseState.x, mouseState.y }; + bool inScreen = inWindow && SDL_PointInRect(&pos, &screen); + + if (inScreen) SDL_ShowCursor(showCursor ? SDL_TRUE : SDL_FALSE); else SDL_ShowCursor(SDL_TRUE); @@ -640,6 +657,19 @@ void EventThread::notifyFrame() SDL_PushEvent(&event); } +void EventThread::notifyGameScreenChange(const SDL_Rect &screen) +{ + /* We have to get a bit hacky here to fit the rectangle + * data into the user event struct */ + SDL_Event event; + event.type = usrIdStart + UPDATE_SCREEN_RECT; + event.user.windowID = screen.x; + event.user.code = screen.y; + event.user.data1 = reinterpret_cast(screen.w); + event.user.data2 = reinterpret_cast(screen.h); + SDL_PushEvent(&event); +} + void SyncPoint::haltThreads() { if (mainSync.locked) diff --git a/src/eventthread.h b/src/eventthread.h index 46051f1..02a9ea1 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -98,12 +98,16 @@ public: /* RGSS thread calls this once per frame */ void notifyFrame(); + /* Called on game screen (size / offset) changes */ + void notifyGameScreenChange(const SDL_Rect &screen); + private: static int eventFilter(void *, SDL_Event*); void resetInputStates(); void setFullscreen(SDL_Window *, bool mode); - void updateCursorState(bool inWindow); + void updateCursorState(bool inWindow, + const SDL_Rect &screen); bool fullscreen; bool showCursor; diff --git a/src/graphics.cpp b/src/graphics.cpp index fe51f74..d205697 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -566,6 +566,9 @@ struct GraphicsPrivate glState.viewport.refresh(); recalculateScreenSize(threadData); updateScreenResoRatio(threadData); + + SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y }; + threadData->ethread->notifyGameScreenChange(screen); } }