Skip to content

Commit 74cbc2b

Browse files
authored
Merge branch 'master' into fix/client-side-entity
2 parents eb7bde5 + 582b0c1 commit 74cbc2b

File tree

1 file changed

+141
-63
lines changed

1 file changed

+141
-63
lines changed

Client/core/Graphics/CVideoModeManager.cpp

Lines changed: 141 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
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

9293
CVideoModeManagerInterface* GetVideoModeManager()
9394
{
@@ -102,12 +103,26 @@ CVideoModeManagerInterface* GetVideoModeManager()
102103
//
103104
///////////////////////////////////////////////////////////////
104105
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)
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

113128
CVideoModeManager::~CVideoModeManager()
@@ -123,6 +138,9 @@ CVideoModeManager::~CVideoModeManager()
123138
///////////////////////////////////////////////////////////////
124139
void 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
///////////////////////////////////////////////////////////////
179205
void 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
///////////////////////////////////////////////////////////////
192221
void 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
///////////////////////////////////////////////////////////////
211243
void 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
///////////////////////////////////////////////////////////////
337374
void 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
///////////////////////////////////////////////////////////////
460499
void 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()
578620
bool 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
///////////////////////////////////////////////////////////////
620671
void 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

Comments
 (0)