diff --git a/src/blupi.cxx b/src/blupi.cxx index 51a1796..f55b511 100644 --- a/src/blupi.cxx +++ b/src/blupi.cxx @@ -994,14 +994,13 @@ DoInit (int argc, char * argv[], bool & exit) g_pEvent->Create (g_pPixmap, g_pDecor, g_pSound, g_pMovie); // Load all cursors - g_pPixmap->LoadCursors (g_zoom); + g_pPixmap->LoadCursors (); g_pPixmap->ChangeSprite (SPRITE_WAIT); g_updateThread = new std::thread (CheckForUpdates); - if (g_bFullScreen) - g_pEvent->SetFullScreen (true); - if (!g_bFullScreen && zoom != g_zoom) + if (zoom != g_zoom) g_pEvent->SetWindowSize (g_zoom); + g_pEvent->SetFullScreen (g_bFullScreen); g_pEvent->ChangePhase (EV_PHASE_INTRO1); g_bTermInit = true; diff --git a/src/def.h b/src/def.h index d8df274..f890532 100644 --- a/src/def.h +++ b/src/def.h @@ -25,7 +25,9 @@ // clang-format off #define _INTRO true // true for init screen -#define SCRFACTOR 4 / 3 +#define SCRNUM 4 +#define SCRDEN 3 +#define SCRFACTOR SCRNUM / SCRDEN #define LXIMAGE (480 * SCRFACTOR + (480 * SCRFACTOR) % 2) // window size #define LYIMAGE 480 diff --git a/src/event.cxx b/src/event.cxx index 57fcf29..736991b 100644 --- a/src/event.cxx +++ b/src/event.cxx @@ -1663,14 +1663,6 @@ CEvent::GetMousePos () void CEvent::SetFullScreen (bool bFullScreen) { - int x, y; - SDL_GetMouseState (&x, &y); - x /= g_zoom; - y /= g_zoom; - - g_zoom = 1; - SDL_SetWindowSize (g_window, LXIMAGE, LYIMAGE); - g_bFullScreen = bFullScreen; int displayIndex = 0; @@ -1678,7 +1670,7 @@ CEvent::SetFullScreen (bool bFullScreen) displayIndex = SDL_GetWindowDisplayIndex (g_window); #endif /* _WIN32 */ - if (g_bFullScreen) + if (g_bFullScreen && g_zoom == 2) { int displays = SDL_GetNumVideoDisplays (); @@ -1696,7 +1688,10 @@ CEvent::SetFullScreen (bool bFullScreen) g_window, displayBounds[displayIndex].x, displayBounds[displayIndex].y); } - SDL_SetWindowFullscreen (g_window, bFullScreen ? SDL_WINDOW_FULLSCREEN : 0); + SDL_SetWindowFullscreen ( + g_window, bFullScreen ? (g_zoom == 1 ? SDL_WINDOW_FULLSCREEN_DESKTOP + : SDL_WINDOW_FULLSCREEN) + : 0); SDL_SetWindowBordered (g_window, bFullScreen ? SDL_FALSE : SDL_TRUE); SDL_SetWindowGrab (g_window, bFullScreen ? SDL_TRUE : SDL_FALSE); @@ -1705,17 +1700,14 @@ CEvent::SetFullScreen (bool bFullScreen) g_window, SDL_WINDOWPOS_CENTERED_DISPLAY (displayIndex), SDL_WINDOWPOS_CENTERED_DISPLAY (displayIndex)); - m_pPixmap->LoadCursors (g_zoom); + m_pPixmap->LoadCursors (); - /* Force this update before otherwise the coordinates retrieved with - * the Warp SDL function are corresponding to the previous size. - */ - CEvent::PushUserEvent (EV_UPDATE); - - auto coord = new SDL_Point; // Released by the event handler. - coord->x = x; - coord->y = y; - CEvent::PushUserEvent (EV_WARPMOUSE, coord); + if (g_bFullScreen) + { + Sint32 w, h; + SDL_GetWindowSize (g_window, &w, &h); + SDL_WarpMouseGlobal (w / 2, h / 2); + } } /** @@ -1756,6 +1748,9 @@ CEvent::SetWindowSize (Uint8 prevScale, Uint8 newScale) int x, y; SDL_GetMouseState (&x, &y); + if (g_bFullScreen && newScale == 2) + newScale = 1; + SDL_SetWindowSize (g_window, LXIMAGE * newScale, LYIMAGE * newScale); int displayIndex = SDL_GetWindowDisplayIndex (g_window); @@ -1763,7 +1758,10 @@ CEvent::SetWindowSize (Uint8 prevScale, Uint8 newScale) g_window, SDL_WINDOWPOS_CENTERED_DISPLAY (displayIndex), SDL_WINDOWPOS_CENTERED_DISPLAY (displayIndex)); - m_pPixmap->LoadCursors (newScale); + m_pPixmap->LoadCursors (); + + if (prevScale == newScale) + return; /* Force this update before otherwise the coordinates retrieved with * the Warp SDL function are corresponding to the previous size. @@ -2121,8 +2119,8 @@ CEvent::DrawButtons () SetEnable (EV_BUTTON3, !g_bFullScreen); SetEnable (EV_BUTTON4, g_bFullScreen); - SetEnable (EV_BUTTON5, !g_bFullScreen && g_zoom > 1); - SetEnable (EV_BUTTON6, !g_bFullScreen && g_zoom < 2); + SetEnable (EV_BUTTON5, g_zoom > 1); + SetEnable (EV_BUTTON6, g_zoom < 2); SetEnable (EV_BUTTON7, g_restoreMidi && mid && ogg); SetEnable (EV_BUTTON8, !g_restoreMidi && mid && ogg); @@ -4164,10 +4162,16 @@ CEvent::ChangeButtons (Sint32 message) SetLanguage (); break; case EV_BUTTON3: + { + auto zoom = g_zoom; + g_zoom = 1; SetFullScreen (true); + SetWindowSize (zoom, 1); break; + } case EV_BUTTON4: SetFullScreen (false); + SetWindowSize (g_zoom, g_zoom); break; case EV_BUTTON5: { @@ -4175,6 +4179,7 @@ CEvent::ChangeButtons (Sint32 message) if (g_zoom > 1) --g_zoom; SetWindowSize (scale, g_zoom); + SetFullScreen (g_bFullScreen); break; } case EV_BUTTON6: @@ -4183,6 +4188,7 @@ CEvent::ChangeButtons (Sint32 message) if (g_zoom < 2) ++g_zoom; SetWindowSize (scale, g_zoom); + SetFullScreen (g_bFullScreen); break; } case EV_BUTTON7: @@ -5213,7 +5219,8 @@ CEvent::DemoStep () pos.y = event.motion.y; } - SDL_WarpMouseInWindow (g_window, pos.x * g_zoom, pos.y * g_zoom); + this->m_pPixmap->FromGameToDisplay (pos.x, pos.y); + SDL_WarpMouseInWindow (g_window, pos.x, pos.y); } if (m_pDemoBuffer) @@ -5265,6 +5272,7 @@ CEvent::DemoRecEvent (const SDL_Event & event) demoEvent.button = event.button.button; demoEvent.x = event.button.x; demoEvent.y = event.button.y; + this->m_pPixmap->FromDisplayToGame (demoEvent.x, demoEvent.y); break; case SDL_MOUSEMOTION: @@ -5272,6 +5280,7 @@ CEvent::DemoRecEvent (const SDL_Event & event) demoEvent.time = m_demoTime; demoEvent.x = event.motion.x; demoEvent.y = event.motion.y; + this->m_pPixmap->FromDisplayToGame (demoEvent.x, demoEvent.y); break; default: diff --git a/src/menu.cxx b/src/menu.cxx index 19a242a..53c7191 100644 --- a/src/menu.cxx +++ b/src/menu.cxx @@ -185,7 +185,9 @@ CMenu::Create ( pos = m_pos; pos.x += DIMBUTTONX / 2; pos.y += DIMBUTTONY / 2; - SDL_WarpMouseInWindow (g_window, pos.x * g_zoom, pos.y * g_zoom); + + this->m_pPixmap->FromGameToDisplay (pos.x, pos.y); + SDL_WarpMouseInWindow (g_window, pos.x, pos.y); } m_selRank = Detect (pos); diff --git a/src/pixmap.cxx b/src/pixmap.cxx index 9d1be99..6fdef85 100644 --- a/src/pixmap.cxx +++ b/src/pixmap.cxx @@ -796,7 +796,7 @@ CPixmap::GetCursorRect (MouseSprites sprite) } void -CPixmap::LoadCursors (Uint8 scale) +CPixmap::LoadCursors () { Uint32 rmask, gmask, bmask, amask; @@ -814,6 +814,8 @@ on the endianness (byte order) of the machine */ amask = 0xff000000; #endif + auto scale = this->GetDisplayScale (); + for (int i = SPRITE_BEGIN; i <= SPRITE_END; ++i) { MouseSprites sprite = static_cast (i); @@ -844,3 +846,58 @@ CPixmap::ChangeSprite (MouseSprites sprite) SDL_SetCursor (m_lpSDLCursors[sprite - 1]); m_lpCurrentCursor = m_lpSDLCursors[sprite - 1]; } + +double +CPixmap::GetDisplayScale () +{ + // SDL_DisplayMode displayMode; + // SDL_GetWindowDisplayMode (g_window, &displayMode); + Sint32 w, h; + SDL_GetWindowSize (g_window, &w, &h); + return static_cast (h / LYIMAGE); +} + +void +CPixmap::FromDisplayToGame (Sint32 & x, Sint32 & y) +{ + if (this->event->IsDemoPlaying ()) + return; + + SDL_DisplayMode displayMode; + SDL_GetWindowDisplayMode (g_window, &displayMode); + + if ( + static_cast (displayMode.w) / displayMode.h == + static_cast (SCRNUM) / SCRDEN) + return; + + double w = displayMode.w, h = displayMode.h; + double ratio = w * SCRDEN / SCRNUM; + + x = (x - (w - ratio) / 2) / (ratio / LXIMAGE); + y = y / (h / LYIMAGE); +} + +void +CPixmap::FromGameToDisplay (Sint32 & x, Sint32 & y) +{ + Sint32 w, h; + SDL_GetWindowSize (g_window, &w, &h); + + double factor = 1; + + if (!g_bFullScreen) + factor = g_zoom; + + x *= factor; + y *= factor; + + if (static_cast (w) / h == static_cast (SCRNUM) / SCRDEN) + return; + + double _w = w, _h = h; + double ratio = w * SCRDEN / SCRNUM; + + x = x * ratio / LXIMAGE + (_w - ratio) / 2; + y = y * _h / LYIMAGE; +} diff --git a/src/pixmap.h b/src/pixmap.h index ceeacc3..c25113e 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -84,9 +84,14 @@ public: void SetMouseSprite (MouseSprites sprite); void MouseShow (bool bShow); - void LoadCursors (Uint8 scale); + void LoadCursors (); void ChangeSprite (MouseSprites sprite); +public: + double GetDisplayScale (); + void FromDisplayToGame (Sint32 & x, Sint32 & y); + void FromGameToDisplay (Sint32 & x, Sint32 & y); + protected: Sint32 BltFast (Sint32 chDst, size_t channel, Point dst, Rect rcRect); Sint32 BltFast (