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" 
464513    CVARS_SET (" display_fullscreen_style" 
465514    CVARS_SET (" multimon_fullscreen_minimize" 
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" 
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" 
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