From daf70260de42e98956d4ee3fea3f55b81fdd0fc0 Mon Sep 17 00:00:00 2001 From: Mathieu Schroeter Date: Wed, 13 Jun 2018 23:10:24 +0200 Subject: [PATCH 1/4] Pass the event manager to pixmap --- src/blupi.cxx | 18 +++++++++--------- src/pixmap.cxx | 4 +++- src/pixmap.h | 6 +++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/blupi.cxx b/src/blupi.cxx index 8c294ad..51a1796 100644 --- a/src/blupi.cxx +++ b/src/blupi.cxx @@ -779,8 +779,16 @@ DoInit (int argc, char * argv[], bool & exit) info.max_texture_height); } + // Create the event manager. + g_pEvent = new CEvent; + if (g_pEvent == nullptr) + { + InitFail ("New event"); + return EXIT_FAILURE; + } + // Create the main pixmap. - g_pPixmap = new CPixmap; + g_pPixmap = new CPixmap (g_pEvent); if (g_pPixmap == nullptr) { InitFail ("New pixmap"); @@ -981,14 +989,6 @@ DoInit (int argc, char * argv[], bool & exit) g_pDecor->Create (g_pSound, g_pPixmap); g_pDecor->MapInitColors (); - // Create the event manager. - g_pEvent = new CEvent; - if (g_pEvent == nullptr) - { - InitFail ("New event"); - return EXIT_FAILURE; - } - const bool zoom = g_zoom; g_pEvent->Create (g_pPixmap, g_pDecor, g_pSound, g_pMovie); diff --git a/src/pixmap.cxx b/src/pixmap.cxx index 58a766a..fea7c0d 100644 --- a/src/pixmap.cxx +++ b/src/pixmap.cxx @@ -33,6 +33,7 @@ #include "blupi.h" #include "def.h" +#include "event.h" #include "misc.h" #include "pixmap.h" @@ -40,7 +41,7 @@ // Constructeur. -CPixmap::CPixmap () +CPixmap::CPixmap (CEvent * event) { Sint32 i; @@ -56,6 +57,7 @@ CPixmap::CPixmap () m_lpSDLCursors[i] = nullptr; m_lpCurrentCursor = nullptr; + this->event = event; } // Destructeur. diff --git a/src/pixmap.h b/src/pixmap.h index 4f0950b..52abe0f 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -47,10 +47,12 @@ struct TextureInfo { } }; +class CEvent; + class CPixmap { public: - CPixmap (); + CPixmap (CEvent * event); ~CPixmap (); bool Create (Point dim); @@ -104,6 +106,8 @@ protected: MouseSprites m_mouseSprite; bool m_bBackDisplayed; + CEvent * event; + SDL_Cursor * m_lpCurrentCursor; SDL_Cursor * m_lpSDLCursors[MAXCURSORS]; SDL_Surface * m_lpSDLBlupi; From 967819a5b8a7b06746186f39279151d6e2a195fe Mon Sep 17 00:00:00 2001 From: Mathieu Schroeter Date: Wed, 13 Jun 2018 23:11:29 +0200 Subject: [PATCH 2/4] Add a method for testing if a demo is playing --- src/event.cxx | 6 ++++++ src/event.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/event.cxx b/src/event.cxx index 5201f93..57fcf29 100644 --- a/src/event.cxx +++ b/src/event.cxx @@ -1637,6 +1637,12 @@ CEvent::~CEvent () WriteInfo (); // lit le fichier "info.blp" } +bool +CEvent::IsDemoPlaying () +{ + return this->m_bDemoPlay; +} + // Retourne la position de la souris. Point diff --git a/src/event.h b/src/event.h index e177afb..64bbaf2 100644 --- a/src/event.h +++ b/src/event.h @@ -92,6 +92,7 @@ public: CEvent (); ~CEvent (); + bool IsDemoPlaying (); Point GetMousePos (); void Create (CPixmap * pPixmap, CDecor * pDecor, CSound * pSound, CMovie * pMovie); From 0289b0224ba4820cf07115aa7b8fb9a4a653d024 Mon Sep 17 00:00:00 2001 From: Mathieu Schroeter Date: Wed, 13 Jun 2018 23:15:23 +0200 Subject: [PATCH 3/4] WIP: add handling support for desktop fullscreen mode --- src/pixmap.cxx | 24 ++++++++++++++++++++++++ src/pixmap.h | 1 + 2 files changed, 25 insertions(+) diff --git a/src/pixmap.cxx b/src/pixmap.cxx index fea7c0d..9d1be99 100644 --- a/src/pixmap.cxx +++ b/src/pixmap.cxx @@ -57,6 +57,7 @@ CPixmap::CPixmap (CEvent * event) m_lpSDLCursors[i] = nullptr; m_lpCurrentCursor = nullptr; + this->mainTexture = nullptr; this->event = event; } @@ -85,6 +86,9 @@ CPixmap::~CPixmap () if (m_lpSDLBlupi) SDL_FreeSurface (m_lpSDLBlupi); + + if (this->mainTexture) + SDL_DestroyTexture (this->mainTexture); } // Cr�e l'objet DirectDraw principal. @@ -143,8 +147,24 @@ CPixmap::BltFast (Sint32 chDst, size_t channel, Point dst, Rect rcRect) dstRect.x = dst.x; dstRect.y = dst.y; + if (!this->mainTexture && g_bFullScreen && g_zoom == 1) + { + SDL_SetHint (SDL_HINT_RENDER_SCALE_QUALITY, "best"); + this->mainTexture = SDL_CreateTexture ( + g_renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, LXIMAGE, + LYIMAGE); + SDL_SetHint (SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); + } + else if (this->mainTexture && !(g_bFullScreen && g_zoom == 1)) + { + SDL_DestroyTexture (this->mainTexture); + this->mainTexture = nullptr; + } + + SDL_SetRenderTarget (g_renderer, this->mainTexture); res = SDL_RenderCopy ( g_renderer, m_SDLTextureInfo[channel].texture, &srcRect, &dstRect); + SDL_SetRenderTarget (g_renderer, nullptr); } else { @@ -602,6 +622,10 @@ bool CPixmap::Display () { m_bBackDisplayed = true; + + if (this->mainTexture) + SDL_RenderCopy (g_renderer, this->mainTexture, nullptr, nullptr); + SDL_RenderPresent (g_renderer); return true; } diff --git a/src/pixmap.h b/src/pixmap.h index 52abe0f..ceeacc3 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -111,5 +111,6 @@ protected: SDL_Cursor * m_lpCurrentCursor; SDL_Cursor * m_lpSDLCursors[MAXCURSORS]; SDL_Surface * m_lpSDLBlupi; + SDL_Texture * mainTexture; std::unordered_map m_SDLTextureInfo; }; From b3c6b536934b92b1d98f16335acb3e43441b0586 Mon Sep 17 00:00:00 2001 From: Mathieu Schroeter Date: Wed, 13 Jun 2018 23:16:59 +0200 Subject: [PATCH 4/4] WIP: add impl. of fullscreen desktop It's possible to switch between both mode (fullscreen 640x480 and fullscreen desktop). The zoom option is used for this switch in fullscreen. The textes must be adapted in this case. --- src/blupi.cxx | 7 +++--- src/def.h | 4 +++- src/event.cxx | 57 ++++++++++++++++++++++++++++-------------------- src/menu.cxx | 4 +++- src/pixmap.cxx | 59 +++++++++++++++++++++++++++++++++++++++++++++++++- src/pixmap.h | 7 +++++- 6 files changed, 106 insertions(+), 32 deletions(-) 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 (