1010 *****************************************************************************/
1111
1212#include " StdInc.h"
13+ #include " CVideoModeManager.h"
1314#include < game/CGame.h>
1415#include < game/CSettings.h>
1516
@@ -26,21 +27,21 @@ class CVideoModeManager : public CVideoModeManagerInterface
2627 ~CVideoModeManager ();
2728
2829 // CVideoModeManagerInterface methods
29- virtual void PreCreateDevice (D3DPRESENT_PARAMETERS* pp);
30- virtual void PostCreateDevice (IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp);
31- virtual void PreReset (D3DPRESENT_PARAMETERS* pp);
32- virtual void PostReset (D3DPRESENT_PARAMETERS* pp);
33- virtual void GetNextVideoMode (int & iOutNextVideoMode, bool & bOutNextWindowed, bool & bOutNextFullScreenMinimize, int & iNextFullscreenStyle);
34- virtual bool SetVideoMode (int nextVideoMode, bool bNextWindowed, bool bNextFullScreenMinimize, int iNextFullscreenStyle);
35- virtual bool IsWindowed ();
36- virtual bool IsMultiMonitor ();
37- virtual bool IsMinimizeEnabled ();
38- virtual void OnGainFocus ();
39- virtual void OnLoseFocus ();
40- virtual void OnPaint ();
41- virtual bool GetRequiredDisplayResolution (int & iOutWidth, int & iOutHeight, int & iOutColorBits, int & iOutAdapterIndex);
42- virtual int GetFullScreenStyle () { return m_iCurrentFullscreenStyle; }
43- virtual bool IsDisplayModeWindowed ();
30+ virtual void PreCreateDevice (D3DPRESENT_PARAMETERS* pp) override ;
31+ virtual void PostCreateDevice (IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp) override ;
32+ virtual void PreReset (D3DPRESENT_PARAMETERS* pp) override ;
33+ virtual void PostReset (D3DPRESENT_PARAMETERS* pp) override ;
34+ virtual void GetNextVideoMode (int & iOutNextVideoMode, bool & bOutNextWindowed, bool & bOutNextFullScreenMinimize, int & iNextFullscreenStyle) override ;
35+ virtual bool SetVideoMode (int nextVideoMode, bool bNextWindowed, bool bNextFullScreenMinimize, int iNextFullscreenStyle) override ;
36+ virtual bool IsWindowed () override ;
37+ virtual bool IsMultiMonitor () override ;
38+ virtual bool IsMinimizeEnabled () override ;
39+ virtual void OnGainFocus () override ;
40+ virtual void OnLoseFocus () override ;
41+ virtual void OnPaint () override ;
42+ virtual bool GetRequiredDisplayResolution (int & iOutWidth, int & iOutHeight, int & iOutColorBits, int & iOutAdapterIndex) override ;
43+ virtual int GetFullScreenStyle () override { return m_iCurrentFullscreenStyle; }
44+ virtual bool IsDisplayModeWindowed () override ;
4445
4546 bool IsDisplayModeFullScreen ();
4647 bool IsDisplayModeFullScreenWindow ();
@@ -51,16 +52,16 @@ class CVideoModeManager : public CVideoModeManagerInterface
5152 void LoadCVars ();
5253 void SaveCVars ();
5354 bool GameResMatchesCurrentAdapter ();
54- SString MakeResolutionString (uint uiWidth, uint uiHeight, uint uiDepth, uint uiAdapter);
55+ SString MakeResolutionString (UINT uiWidth, UINT uiHeight, UINT uiDepth, UINT uiAdapter);
5556
5657 void UpdateMonitor ();
5758
58- unsigned long m_ulForceBackBufferWidth;
59- unsigned long m_ulForceBackBufferHeight;
60- unsigned long m_ulForceBackBufferColorDepth;
59+ ULONG m_ulForceBackBufferWidth;
60+ ULONG m_ulForceBackBufferHeight;
61+ ULONG m_ulForceBackBufferColorDepth;
6162 HWND m_hDeviceWindow;
6263 CGameSettings* m_pGameSettings;
63- unsigned long m_ulMonitorCount;
64+ ULONG m_ulMonitorCount;
6465
6566 int m_iCurrentVideoMode; // VideoMode this run
6667 int m_iCurrentAdapter;
@@ -87,7 +88,7 @@ CVideoModeManagerInterface* NewVideoModeManager()
8788 return new CVideoModeManager ();
8889}
8990
90- CVideoModeManagerInterface* g_pVideoModeManager = NULL ;
91+ CVideoModeManagerInterface* g_pVideoModeManager = nullptr ;
9192
9293CVideoModeManagerInterface* GetVideoModeManager ()
9394{
@@ -102,12 +103,26 @@ CVideoModeManagerInterface* GetVideoModeManager()
102103//
103104// /////////////////////////////////////////////////////////////
104105CVideoModeManager::CVideoModeManager ()
106+ : m_ulForceBackBufferWidth(0 ),
107+ m_ulForceBackBufferHeight(0 ),
108+ m_ulForceBackBufferColorDepth(32 ),
109+ m_hDeviceWindow(nullptr ),
110+ m_pGameSettings(nullptr ),
111+ m_ulMonitorCount(0 ),
112+ m_iCurrentVideoMode(1 ),
113+ m_iCurrentAdapter(0 ),
114+ m_bCurrentWindowed(false ),
115+ m_bCurrentFullScreenMinimize(false ),
116+ m_iCurrentFullscreenStyle(FULLSCREEN_STANDARD),
117+ m_iNextVideoMode(1 ),
118+ m_iNextAdapter(0 ),
119+ m_bNextWindowed(false ),
120+ m_iNextFullscreenStyle(FULLSCREEN_STANDARD),
121+ m_hCurrentMonitor(nullptr ),
122+ m_bPendingGainFocus(false ),
123+ m_bOriginalDesktopResMatches(false )
105124{
106125 m_pGameSettings = CCore::GetSingleton ().GetGame ()->GetSettings ();
107- m_iCurrentVideoMode = 1 ;
108- m_bCurrentWindowed = false ;
109- m_iNextVideoMode = 1 ;
110- m_bNextWindowed = false ;
111126}
112127
113128CVideoModeManager::~CVideoModeManager ()
@@ -123,6 +138,9 @@ CVideoModeManager::~CVideoModeManager()
123138// /////////////////////////////////////////////////////////////
124139void CVideoModeManager::PreCreateDevice (D3DPRESENT_PARAMETERS* pp)
125140{
141+ if (!pp)
142+ return ;
143+
126144 m_hDeviceWindow = pp->hDeviceWindow ;
127145
128146 // Load settings
@@ -140,20 +158,28 @@ void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp)
140158 if (IsDisplayModeWindowed ())
141159 {
142160 RECT rc;
143- GetCurrentAdapterRect (&rc);
144- int iPosX = (rc.left + rc.right ) / 2 - (pp->BackBufferWidth / 2 );
145- int iPosY = (rc.top + rc.bottom ) / 2 - (pp->BackBufferHeight / 2 );
146- SetWindowLong (m_hDeviceWindow, GWL_STYLE, WS_POPUP);
147- MoveWindow (m_hDeviceWindow, iPosX, iPosY, pp->BackBufferWidth , pp->BackBufferHeight , TRUE );
148- pp->Windowed = true ;
161+ if (GetCurrentAdapterRect (&rc))
162+ {
163+ int iPosX = (rc.left + rc.right ) / 2 - static_cast <int >(pp->BackBufferWidth ) / 2 ;
164+ int iPosY = (rc.top + rc.bottom ) / 2 - static_cast <int >(pp->BackBufferHeight ) / 2 ;
165+
166+ if (m_hDeviceWindow)
167+ {
168+ SetWindowLong (m_hDeviceWindow, GWL_STYLE, WS_POPUP);
169+ MoveWindow (m_hDeviceWindow, iPosX, iPosY, static_cast <int >(pp->BackBufferWidth ), static_cast <int >(pp->BackBufferHeight ), TRUE );
170+ }
171+ }
172+ pp->Windowed = TRUE ;
149173 }
150174 else if (IsDisplayModeFullScreenWindow ())
151175 {
152176 RECT rc;
153- GetCurrentAdapterRect (&rc);
154- SetWindowLong (m_hDeviceWindow, GWL_STYLE, WS_POPUP);
155- MoveWindow (m_hDeviceWindow, rc.left , rc.top , pp->BackBufferWidth , pp->BackBufferHeight , TRUE );
156- pp->Windowed = true ;
177+ if (GetCurrentAdapterRect (&rc) && m_hDeviceWindow)
178+ {
179+ SetWindowLong (m_hDeviceWindow, GWL_STYLE, WS_POPUP);
180+ MoveWindow (m_hDeviceWindow, rc.left , rc.top , static_cast <int >(pp->BackBufferWidth ), static_cast <int >(pp->BackBufferHeight ), TRUE );
181+ }
182+ pp->Windowed = TRUE ;
157183 }
158184
159185 if (pp->SwapEffect == D3DSWAPEFFECT_FLIP && IsDisplayModeWindowed ())
@@ -178,6 +204,9 @@ void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp)
178204// /////////////////////////////////////////////////////////////
179205void CVideoModeManager::PostCreateDevice (IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp)
180206{
207+ if (!pD3DDevice || !pp)
208+ return ;
209+
181210 if (IsDisplayModeWindowed () || IsDisplayModeFullScreenWindow ())
182211 pD3DDevice->Reset (pp);
183212}
@@ -191,6 +220,9 @@ void CVideoModeManager::PostCreateDevice(IDirect3DDevice9* pD3DDevice, D3DPRESEN
191220// /////////////////////////////////////////////////////////////
192221void CVideoModeManager::PreReset (D3DPRESENT_PARAMETERS* pp)
193222{
223+ if (!pp)
224+ return ;
225+
194226 if (IsDisplayModeWindowed () || IsDisplayModeFullScreenWindow ())
195227 {
196228 pp->Windowed = true ;
@@ -210,6 +242,9 @@ void CVideoModeManager::PreReset(D3DPRESENT_PARAMETERS* pp)
210242// /////////////////////////////////////////////////////////////
211243void CVideoModeManager::PostReset (D3DPRESENT_PARAMETERS* pp)
212244{
245+ if (!pp || !m_hDeviceWindow)
246+ return ;
247+
213248 if (pp->Windowed )
214249 {
215250 // Add frame
@@ -302,24 +337,26 @@ void CVideoModeManager::OnLoseFocus()
302337 if (!IsMultiMonitor () || IsMinimizeEnabled ())
303338 {
304339 HWND hWnd = CCore::GetSingleton ().GetHookedWindow ();
305- ShowWindow (hWnd, SW_MINIMIZE);
340+ if (hWnd)
341+ ShowWindow (hWnd, SW_MINIMIZE);
306342
307343 if (!m_bOriginalDesktopResMatches && (m_iCurrentFullscreenStyle == FULLSCREEN_BORDERLESS))
308344 {
309345 DEVMODE dmScreenSettings;
310346 memset (&dmScreenSettings, 0 , sizeof (dmScreenSettings));
311347 dmScreenSettings.dmSize = sizeof (dmScreenSettings);
312348
313- if (!EnumDisplaySettings (GetCurrentAdapterDeviceName (), ENUM_REGISTRY_SETTINGS, &dmScreenSettings))
349+ SString deviceName = GetCurrentAdapterDeviceName ();
350+ if (!EnumDisplaySettingsA (deviceName.c_str (), ENUM_REGISTRY_SETTINGS, &dmScreenSettings))
314351 {
315- AddReportLog (7340 , SString (" EnumDisplaySettings failed for %s" , * GetCurrentAdapterDeviceName ()));
352+ AddReportLog (7340 , SString (" EnumDisplaySettings failed for %s" , deviceName. c_str ()));
316353 return ;
317354 }
318355
319- int iChangeResult = ChangeDisplaySettingsEx ( GetCurrentAdapterDeviceName (), &dmScreenSettings, NULL , CDS_RESET, NULL );
356+ int iChangeResult = ChangeDisplaySettingsExA (deviceName. c_str (), &dmScreenSettings, nullptr , CDS_RESET, nullptr );
320357 if (iChangeResult != DISP_CHANGE_SUCCESSFUL)
321358 {
322- AddReportLog (7341 , SString (" ChangeDisplaySettingsEx failed for %s (%d)" , * GetCurrentAdapterDeviceName (), iChangeResult));
359+ AddReportLog (7341 , SString (" ChangeDisplaySettingsEx failed for %s (%d)" , deviceName. c_str (), iChangeResult));
323360 return ;
324361 }
325362 }
@@ -336,11 +373,13 @@ void CVideoModeManager::OnLoseFocus()
336373// /////////////////////////////////////////////////////////////
337374void CVideoModeManager::OnPaint ()
338375{
339- if (IsDisplayModeFullScreenWindow ())
376+ if (IsDisplayModeFullScreenWindow () && m_hDeviceWindow )
340377 {
341378 RECT rc;
342- GetCurrentAdapterRect (&rc);
343- MoveWindow (m_hDeviceWindow, rc.left , rc.top , m_ulForceBackBufferWidth, m_ulForceBackBufferHeight, FALSE );
379+ if (GetCurrentAdapterRect (&rc))
380+ {
381+ MoveWindow (m_hDeviceWindow, rc.left , rc.top , static_cast <int >(m_ulForceBackBufferWidth), static_cast <int >(m_ulForceBackBufferHeight), FALSE );
382+ }
344383 }
345384}
346385
@@ -371,7 +410,7 @@ bool CVideoModeManager::SetVideoMode(int iNextVideoMode, bool bNextWindowed, boo
371410 bool bRequiresRestart = false ;
372411
373412 // Resolution
374- if (iNextVideoMode > 0 && iNextVideoMode < ( int ) m_pGameSettings->GetNumVideoModes ())
413+ if (iNextVideoMode > 0 && m_pGameSettings && iNextVideoMode < static_cast < int >( m_pGameSettings->GetNumVideoModes () ))
375414 {
376415 if (m_iNextVideoMode != iNextVideoMode)
377416 {
@@ -459,16 +498,20 @@ void CVideoModeManager::LoadCVars()
459498// /////////////////////////////////////////////////////////////
460499void CVideoModeManager::SaveCVars ()
461500{
462- m_pGameSettings->SetCurrentVideoMode (m_iNextVideoMode, true );
501+ if (m_pGameSettings)
502+ {
503+ m_pGameSettings->SetCurrentVideoMode (m_iNextVideoMode, true );
504+
505+ VideoMode info;
506+ if (m_pGameSettings->GetVideoModeInfo (&info, m_iNextVideoMode))
507+ {
508+ CVARS_SET (" display_resolution" , MakeResolutionString (info.width , info.height , info.depth , static_cast <UINT>(m_iNextAdapter)));
509+ }
510+ }
511+
463512 CVARS_SET (" display_windowed" , m_bNextWindowed);
464513 CVARS_SET (" display_fullscreen_style" , m_iNextFullscreenStyle);
465514 CVARS_SET (" multimon_fullscreen_minimize" , m_bCurrentFullScreenMinimize);
466-
467- VideoMode info;
468- if (m_pGameSettings->GetVideoModeInfo (&info, m_iNextVideoMode))
469- {
470- CVARS_SET (" display_resolution" , MakeResolutionString (info.width , info.height , info.depth , m_iNextAdapter));
471- }
472515}
473516
474517// /////////////////////////////////////////////////////////////
@@ -501,13 +544,12 @@ bool CVideoModeManager::IsMultiMonitor()
501544 device.cb = sizeof (device);
502545
503546 // Get next DISPLAY_DEVICE from the system
504- if (!EnumDisplayDevicesA (NULL , i , &device, 0 ))
547+ if (!EnumDisplayDevicesA (nullptr , static_cast <DWORD>(i) , &device, 0 ))
505548 break ;
506549
507550 // Calc flags
508551 bool bAttachedToDesktop = (device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0 ;
509552 bool bMirroringDriver = (device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) != 0 ;
510- bool bPrimaryDevice = (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 ;
511553
512554 // Ignore devices that are not required
513555 if (!bAttachedToDesktop || bMirroringDriver)
@@ -578,15 +620,24 @@ bool CVideoModeManager::IsDisplayModeFullScreenWindow()
578620bool CVideoModeManager::GameResMatchesCurrentAdapter ()
579621{
580622 RECT rc;
581- GetCurrentAdapterRect (&rc);
623+ if (!GetCurrentAdapterRect (&rc))
624+ return false ;
625+
582626 int iAdapterResX = rc.right - rc.left ;
583627 int iAdapterResY = rc.bottom - rc.top ;
584628
585629 // Here we hope that the color depth is the same across all monitors
586- HDC hdcPrimaryMonitor = GetDC (NULL );
587- int iDesktopColorDepth = GetDeviceCaps (hdcPrimaryMonitor, BITSPIXEL);
630+ HDC hdcPrimaryMonitor = GetDC (nullptr );
631+ int iDesktopColorDepth = 32 ; // Default fallback
632+
633+ if (hdcPrimaryMonitor)
634+ {
635+ iDesktopColorDepth = GetDeviceCaps (hdcPrimaryMonitor, BITSPIXEL);
636+ ReleaseDC (nullptr , hdcPrimaryMonitor);
637+ }
588638
589- if (iAdapterResX == m_ulForceBackBufferWidth && iAdapterResY == m_ulForceBackBufferHeight && iDesktopColorDepth == m_ulForceBackBufferColorDepth)
639+ if (iAdapterResX == static_cast <int >(m_ulForceBackBufferWidth) && iAdapterResY == static_cast <int >(m_ulForceBackBufferHeight) &&
640+ iDesktopColorDepth == static_cast <int >(m_ulForceBackBufferColorDepth))
590641 {
591642 return true ;
592643 }
@@ -601,7 +652,7 @@ bool CVideoModeManager::GameResMatchesCurrentAdapter()
601652// Make a frendly string for saving to the config file
602653//
603654// /////////////////////////////////////////////////////////////
604- SString CVideoModeManager::MakeResolutionString (uint uiWidth, uint uiHeight, uint uiDepth, uint uiAdapter)
655+ SString CVideoModeManager::MakeResolutionString (UINT uiWidth, UINT uiHeight, UINT uiDepth, UINT uiAdapter)
605656{
606657 SString strRes (" %dx%dx%d" , uiWidth, uiHeight, uiDepth);
607658 if (uiAdapter > 0 )
@@ -619,7 +670,7 @@ SString CVideoModeManager::MakeResolutionString(uint uiWidth, uint uiHeight, uin
619670// /////////////////////////////////////////////////////////////
620671void CVideoModeManager::UpdateMonitor ()
621672{
622- if (IsDisplayModeFullScreenWindow ())
673+ if (IsDisplayModeFullScreenWindow () && m_hDeviceWindow )
623674 {
624675 m_hCurrentMonitor = MonitorFromWindow (m_hDeviceWindow, MONITOR_DEFAULTTONEAREST);
625676 }
@@ -645,18 +696,45 @@ bool CVideoModeManager::GetRequiredDisplayResolution(int& iOutWidth, int& iOutHe
645696 // Parse string from config
646697 std::vector<SString> parts;
647698 strResString.ToLower ().Replace (" " , " " ).Split (" x" , parts);
699+
648700 if (parts.size () > 1 )
649701 {
650- iOutWidth = atoi (parts[0 ]);
651- iOutHeight = atoi (parts[1 ]);
702+ const char * widthStr = parts[0 ].c_str ();
703+ const char * heightStr = parts[1 ].c_str ();
704+
705+ if (widthStr && heightStr)
706+ {
707+ long width = strtol (widthStr, nullptr , 10 );
708+ long height = strtol (heightStr, nullptr , 10 );
709+
710+ if (width > 0 && width <= 65535 && height > 0 && height <= 65535 )
711+ {
712+ iOutWidth = static_cast <int >(width);
713+ iOutHeight = static_cast <int >(height);
714+ }
715+ }
652716 }
717+
653718 if (parts.size () > 2 )
654719 {
655- iOutColorBits = atoi (parts[2 ]);
720+ const char * colorStr = parts[2 ].c_str ();
721+ if (colorStr)
722+ {
723+ long colorBits = strtol (colorStr, nullptr , 10 );
724+ if (colorBits == 16 || colorBits == 32 )
725+ iOutColorBits = static_cast <int >(colorBits);
726+ }
656727 }
728+
657729 if (parts.size () > 3 )
658730 {
659- iOutAdapterIndex = atoi (parts[3 ]);
731+ const char * adapterStr = parts[3 ].c_str ();
732+ if (adapterStr)
733+ {
734+ long adapter = strtol (adapterStr, nullptr , 10 );
735+ if (adapter >= 0 )
736+ iOutAdapterIndex = static_cast <int >(adapter);
737+ }
660738 }
661739
662740 return (iOutWidth > 0 ) && (iOutHeight > 0 ) && (iOutColorBits == 16 || iOutColorBits == 32 );
0 commit comments