10
10
*****************************************************************************/
11
11
12
12
#include " StdInc.h"
13
+ #include " CVideoModeManager.h"
13
14
#include < game/CGame.h>
14
15
#include < game/CSettings.h>
15
16
@@ -26,21 +27,21 @@ class CVideoModeManager : public CVideoModeManagerInterface
26
27
~CVideoModeManager ();
27
28
28
29
// 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 ;
44
45
45
46
bool IsDisplayModeFullScreen ();
46
47
bool IsDisplayModeFullScreenWindow ();
@@ -51,16 +52,16 @@ class CVideoModeManager : public CVideoModeManagerInterface
51
52
void LoadCVars ();
52
53
void SaveCVars ();
53
54
bool GameResMatchesCurrentAdapter ();
54
- SString MakeResolutionString (uint uiWidth, uint uiHeight, uint uiDepth, uint uiAdapter);
55
+ SString MakeResolutionString (UINT uiWidth, UINT uiHeight, UINT uiDepth, UINT uiAdapter);
55
56
56
57
void UpdateMonitor ();
57
58
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;
61
62
HWND m_hDeviceWindow;
62
63
CGameSettings* m_pGameSettings;
63
- unsigned long m_ulMonitorCount;
64
+ ULONG m_ulMonitorCount;
64
65
65
66
int m_iCurrentVideoMode; // VideoMode this run
66
67
int m_iCurrentAdapter;
@@ -87,7 +88,7 @@ CVideoModeManagerInterface* NewVideoModeManager()
87
88
return new CVideoModeManager ();
88
89
}
89
90
90
- CVideoModeManagerInterface* g_pVideoModeManager = NULL ;
91
+ CVideoModeManagerInterface* g_pVideoModeManager = nullptr ;
91
92
92
93
CVideoModeManagerInterface* GetVideoModeManager ()
93
94
{
@@ -102,12 +103,26 @@ CVideoModeManagerInterface* GetVideoModeManager()
102
103
//
103
104
// /////////////////////////////////////////////////////////////
104
105
CVideoModeManager::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 )
105
124
{
106
125
m_pGameSettings = CCore::GetSingleton ().GetGame ()->GetSettings ();
107
- m_iCurrentVideoMode = 1 ;
108
- m_bCurrentWindowed = false ;
109
- m_iNextVideoMode = 1 ;
110
- m_bNextWindowed = false ;
111
126
}
112
127
113
128
CVideoModeManager::~CVideoModeManager ()
@@ -123,6 +138,9 @@ CVideoModeManager::~CVideoModeManager()
123
138
// /////////////////////////////////////////////////////////////
124
139
void CVideoModeManager::PreCreateDevice (D3DPRESENT_PARAMETERS* pp)
125
140
{
141
+ if (!pp)
142
+ return ;
143
+
126
144
m_hDeviceWindow = pp->hDeviceWindow ;
127
145
128
146
// Load settings
@@ -140,20 +158,28 @@ void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp)
140
158
if (IsDisplayModeWindowed ())
141
159
{
142
160
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 ;
149
173
}
150
174
else if (IsDisplayModeFullScreenWindow ())
151
175
{
152
176
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 ;
157
183
}
158
184
159
185
if (pp->SwapEffect == D3DSWAPEFFECT_FLIP && IsDisplayModeWindowed ())
@@ -178,6 +204,9 @@ void CVideoModeManager::PreCreateDevice(D3DPRESENT_PARAMETERS* pp)
178
204
// /////////////////////////////////////////////////////////////
179
205
void CVideoModeManager::PostCreateDevice (IDirect3DDevice9* pD3DDevice, D3DPRESENT_PARAMETERS* pp)
180
206
{
207
+ if (!pD3DDevice || !pp)
208
+ return ;
209
+
181
210
if (IsDisplayModeWindowed () || IsDisplayModeFullScreenWindow ())
182
211
pD3DDevice->Reset (pp);
183
212
}
@@ -191,6 +220,9 @@ void CVideoModeManager::PostCreateDevice(IDirect3DDevice9* pD3DDevice, D3DPRESEN
191
220
// /////////////////////////////////////////////////////////////
192
221
void CVideoModeManager::PreReset (D3DPRESENT_PARAMETERS* pp)
193
222
{
223
+ if (!pp)
224
+ return ;
225
+
194
226
if (IsDisplayModeWindowed () || IsDisplayModeFullScreenWindow ())
195
227
{
196
228
pp->Windowed = true ;
@@ -210,6 +242,9 @@ void CVideoModeManager::PreReset(D3DPRESENT_PARAMETERS* pp)
210
242
// /////////////////////////////////////////////////////////////
211
243
void CVideoModeManager::PostReset (D3DPRESENT_PARAMETERS* pp)
212
244
{
245
+ if (!pp || !m_hDeviceWindow)
246
+ return ;
247
+
213
248
if (pp->Windowed )
214
249
{
215
250
// Add frame
@@ -302,24 +337,26 @@ void CVideoModeManager::OnLoseFocus()
302
337
if (!IsMultiMonitor () || IsMinimizeEnabled ())
303
338
{
304
339
HWND hWnd = CCore::GetSingleton ().GetHookedWindow ();
305
- ShowWindow (hWnd, SW_MINIMIZE);
340
+ if (hWnd)
341
+ ShowWindow (hWnd, SW_MINIMIZE);
306
342
307
343
if (!m_bOriginalDesktopResMatches && (m_iCurrentFullscreenStyle == FULLSCREEN_BORDERLESS))
308
344
{
309
345
DEVMODE dmScreenSettings;
310
346
memset (&dmScreenSettings, 0 , sizeof (dmScreenSettings));
311
347
dmScreenSettings.dmSize = sizeof (dmScreenSettings);
312
348
313
- if (!EnumDisplaySettings (GetCurrentAdapterDeviceName (), ENUM_REGISTRY_SETTINGS, &dmScreenSettings))
349
+ SString deviceName = GetCurrentAdapterDeviceName ();
350
+ if (!EnumDisplaySettingsA (deviceName.c_str (), ENUM_REGISTRY_SETTINGS, &dmScreenSettings))
314
351
{
315
- AddReportLog (7340 , SString (" EnumDisplaySettings failed for %s" , * GetCurrentAdapterDeviceName ()));
352
+ AddReportLog (7340 , SString (" EnumDisplaySettings failed for %s" , deviceName. c_str ()));
316
353
return ;
317
354
}
318
355
319
- int iChangeResult = ChangeDisplaySettingsEx ( GetCurrentAdapterDeviceName (), &dmScreenSettings, NULL , CDS_RESET, NULL );
356
+ int iChangeResult = ChangeDisplaySettingsExA (deviceName. c_str (), &dmScreenSettings, nullptr , CDS_RESET, nullptr );
320
357
if (iChangeResult != DISP_CHANGE_SUCCESSFUL)
321
358
{
322
- AddReportLog (7341 , SString (" ChangeDisplaySettingsEx failed for %s (%d)" , * GetCurrentAdapterDeviceName (), iChangeResult));
359
+ AddReportLog (7341 , SString (" ChangeDisplaySettingsEx failed for %s (%d)" , deviceName. c_str (), iChangeResult));
323
360
return ;
324
361
}
325
362
}
@@ -336,11 +373,13 @@ void CVideoModeManager::OnLoseFocus()
336
373
// /////////////////////////////////////////////////////////////
337
374
void CVideoModeManager::OnPaint ()
338
375
{
339
- if (IsDisplayModeFullScreenWindow ())
376
+ if (IsDisplayModeFullScreenWindow () && m_hDeviceWindow )
340
377
{
341
378
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
+ }
344
383
}
345
384
}
346
385
@@ -371,7 +410,7 @@ bool CVideoModeManager::SetVideoMode(int iNextVideoMode, bool bNextWindowed, boo
371
410
bool bRequiresRestart = false ;
372
411
373
412
// Resolution
374
- if (iNextVideoMode > 0 && iNextVideoMode < ( int ) m_pGameSettings->GetNumVideoModes ())
413
+ if (iNextVideoMode > 0 && m_pGameSettings && iNextVideoMode < static_cast < int >( m_pGameSettings->GetNumVideoModes () ))
375
414
{
376
415
if (m_iNextVideoMode != iNextVideoMode)
377
416
{
@@ -459,16 +498,20 @@ void CVideoModeManager::LoadCVars()
459
498
// /////////////////////////////////////////////////////////////
460
499
void CVideoModeManager::SaveCVars ()
461
500
{
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
+
463
512
CVARS_SET (" display_windowed" , m_bNextWindowed);
464
513
CVARS_SET (" display_fullscreen_style" , m_iNextFullscreenStyle);
465
514
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
- }
472
515
}
473
516
474
517
// /////////////////////////////////////////////////////////////
@@ -501,13 +544,12 @@ bool CVideoModeManager::IsMultiMonitor()
501
544
device.cb = sizeof (device);
502
545
503
546
// Get next DISPLAY_DEVICE from the system
504
- if (!EnumDisplayDevicesA (NULL , i , &device, 0 ))
547
+ if (!EnumDisplayDevicesA (nullptr , static_cast <DWORD>(i) , &device, 0 ))
505
548
break ;
506
549
507
550
// Calc flags
508
551
bool bAttachedToDesktop = (device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0 ;
509
552
bool bMirroringDriver = (device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) != 0 ;
510
- bool bPrimaryDevice = (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 ;
511
553
512
554
// Ignore devices that are not required
513
555
if (!bAttachedToDesktop || bMirroringDriver)
@@ -578,15 +620,24 @@ bool CVideoModeManager::IsDisplayModeFullScreenWindow()
578
620
bool CVideoModeManager::GameResMatchesCurrentAdapter ()
579
621
{
580
622
RECT rc;
581
- GetCurrentAdapterRect (&rc);
623
+ if (!GetCurrentAdapterRect (&rc))
624
+ return false ;
625
+
582
626
int iAdapterResX = rc.right - rc.left ;
583
627
int iAdapterResY = rc.bottom - rc.top ;
584
628
585
629
// 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
+ }
588
638
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))
590
641
{
591
642
return true ;
592
643
}
@@ -601,7 +652,7 @@ bool CVideoModeManager::GameResMatchesCurrentAdapter()
601
652
// Make a frendly string for saving to the config file
602
653
//
603
654
// /////////////////////////////////////////////////////////////
604
- SString CVideoModeManager::MakeResolutionString (uint uiWidth, uint uiHeight, uint uiDepth, uint uiAdapter)
655
+ SString CVideoModeManager::MakeResolutionString (UINT uiWidth, UINT uiHeight, UINT uiDepth, UINT uiAdapter)
605
656
{
606
657
SString strRes (" %dx%dx%d" , uiWidth, uiHeight, uiDepth);
607
658
if (uiAdapter > 0 )
@@ -619,7 +670,7 @@ SString CVideoModeManager::MakeResolutionString(uint uiWidth, uint uiHeight, uin
619
670
// /////////////////////////////////////////////////////////////
620
671
void CVideoModeManager::UpdateMonitor ()
621
672
{
622
- if (IsDisplayModeFullScreenWindow ())
673
+ if (IsDisplayModeFullScreenWindow () && m_hDeviceWindow )
623
674
{
624
675
m_hCurrentMonitor = MonitorFromWindow (m_hDeviceWindow, MONITOR_DEFAULTTONEAREST);
625
676
}
@@ -645,18 +696,45 @@ bool CVideoModeManager::GetRequiredDisplayResolution(int& iOutWidth, int& iOutHe
645
696
// Parse string from config
646
697
std::vector<SString> parts;
647
698
strResString.ToLower ().Replace (" " , " " ).Split (" x" , parts);
699
+
648
700
if (parts.size () > 1 )
649
701
{
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
+ }
652
716
}
717
+
653
718
if (parts.size () > 2 )
654
719
{
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
+ }
656
727
}
728
+
657
729
if (parts.size () > 3 )
658
730
{
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
+ }
660
738
}
661
739
662
740
return (iOutWidth > 0 ) && (iOutHeight > 0 ) && (iOutColorBits == 16 || iOutColorBits == 32 );
0 commit comments