Skip to content

Commit 9ff7ba2

Browse files
authored
[GEN][ZH] Fix Alt-tabbing crash (#846)
1 parent 5cd47af commit 9ff7ba2

File tree

4 files changed

+18
-66
lines changed

4 files changed

+18
-66
lines changed

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -489,34 +489,6 @@ void W3DDisplay::setGamma(Real gamma, Real bright, Real contrast, Bool calibrate
489489
DX8Wrapper::Set_Gamma(gamma,bright,contrast,calibrate, false);
490490
}
491491

492-
/*Giant hack in order to keep the game from getting stuck when alt-tabbing*/
493-
void Reset_D3D_Device(bool active)
494-
{
495-
if (TheDisplay && WW3D::Is_Initted() && !TheDisplay->getWindowed())
496-
{
497-
if (active)
498-
{
499-
//switch back to desired mode when user alt-tabs back into game
500-
WW3D::Set_Render_Device( WW3D::Get_Render_Device(),TheDisplay->getWidth(),TheDisplay->getHeight(),TheDisplay->getBitDepth(),TheDisplay->getWindowed(),true, true);
501-
OSVERSIONINFO osvi;
502-
osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
503-
if (GetVersionEx(&osvi))
504-
{ //check if we're running Win9x variant since they have buggy alt-tab that requires
505-
//reloading all textures.
506-
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
507-
{ //only do this on Win9x boxes because it makes alt-tab very slow.
508-
WW3D::_Invalidate_Textures();
509-
}
510-
}
511-
}
512-
else
513-
{
514-
//switch to windowed mode whenever the user alt-tabs out of game. Don't restore assets after reset since we'll do it when returning.
515-
WW3D::Set_Render_Device( WW3D::Get_Render_Device(),TheDisplay->getWidth(),TheDisplay->getHeight(),TheDisplay->getBitDepth(),TheDisplay->getWindowed(),true, true, false);
516-
}
517-
}
518-
}
519-
520492
/** Set resolution of display */
521493
//=============================================================================
522494
Bool W3DDisplay::setDisplayMode( UnsignedInt xres, UnsignedInt yres, UnsignedInt bitdepth, Bool windowed )

Generals/Code/Main/WinMain.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ const char *gAppPrefix = ""; /// So WB can have a different debug log file name.
8787
#define DEFAULT_XRESOLUTION 800
8888
#define DEFAULT_YRESOLUTION 600
8989

90-
extern void Reset_D3D_Device(bool active);
91-
9290
static Bool gInitializing = false;
9391
static Bool gDoPaint = true;
9492
static Bool isWinMainActive = false;
@@ -426,14 +424,20 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
426424
//-------------------------------------------------------------------------
427425
case WM_ACTIVATEAPP:
428426
{
429-
// DWORD threadId=GetCurrentThreadId();
430427
if ((bool) wParam != isWinMainActive)
431-
{ isWinMainActive = (BOOL) wParam;
428+
{
429+
// TheSuperHackers @bugfix xezon 11/05/2025 This event originally called DX8Wrapper::Reset_Device,
430+
// intended to clear resources on a lost device in fullscreen, but effectively also in
431+
// windowed mode, if the DXMaximizedWindowedMode shim was applied in newer versions of Windows,
432+
// which lead to unfortunate application crashing. Resetting the device on WM_ACTIVATEAPP instead
433+
// of TestCooperativeLevel() == D3DERR_DEVICENOTRESET is not a requirement. There are other code
434+
// paths that take care of that.
435+
436+
isWinMainActive = (BOOL) wParam;
432437

433438
if (TheGameEngine)
434439
TheGameEngine->setIsActive(isWinMainActive);
435440

436-
Reset_D3D_Device(isWinMainActive);
437441
if (isWinMainActive)
438442
{ //restore mouse cursor to our custom version.
439443
if (TheWin32Mouse)

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -555,34 +555,6 @@ void W3DDisplay::setGamma(Real gamma, Real bright, Real contrast, Bool calibrate
555555
DX8Wrapper::Set_Gamma(gamma,bright,contrast,calibrate, false);
556556
}
557557

558-
/*Giant hack in order to keep the game from getting stuck when alt-tabbing*/
559-
void Reset_D3D_Device(bool active)
560-
{
561-
if (TheDisplay && WW3D::Is_Initted() && !TheDisplay->getWindowed())
562-
{
563-
if (active)
564-
{
565-
//switch back to desired mode when user alt-tabs back into game
566-
WW3D::Set_Render_Device( WW3D::Get_Render_Device(),TheDisplay->getWidth(),TheDisplay->getHeight(),TheDisplay->getBitDepth(),TheDisplay->getWindowed(),true, true);
567-
OSVERSIONINFO osvi;
568-
osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
569-
if (GetVersionEx(&osvi))
570-
{ //check if we're running Win9x variant since they have buggy alt-tab that requires
571-
//reloading all textures.
572-
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
573-
{ //only do this on Win9x boxes because it makes alt-tab very slow.
574-
WW3D::_Invalidate_Textures();
575-
}
576-
}
577-
}
578-
else
579-
{
580-
//switch to windowed mode whenever the user alt-tabs out of game. Don't restore assets after reset since we'll do it when returning.
581-
WW3D::Set_Render_Device( WW3D::Get_Render_Device(),TheDisplay->getWidth(),TheDisplay->getHeight(),TheDisplay->getBitDepth(),TheDisplay->getWindowed(),true, true, false);
582-
}
583-
}
584-
}
585-
586558
/** Set resolution of display */
587559
//=============================================================================
588560
Bool W3DDisplay::setDisplayMode( UnsignedInt xres, UnsignedInt yres, UnsignedInt bitdepth, Bool windowed )

GeneralsMD/Code/Main/WinMain.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ const char *gAppPrefix = ""; /// So WB can have a different debug log file name.
9090
#define DEFAULT_XRESOLUTION 800
9191
#define DEFAULT_YRESOLUTION 600
9292

93-
extern void Reset_D3D_Device(bool active);
94-
9593
static Bool gInitializing = false;
9694
static Bool gDoPaint = true;
9795
static Bool isWinMainActive = false;
@@ -448,14 +446,20 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
448446
//-------------------------------------------------------------------------
449447
case WM_ACTIVATEAPP:
450448
{
451-
// DWORD threadId=GetCurrentThreadId();
452449
if ((bool) wParam != isWinMainActive)
453-
{ isWinMainActive = (BOOL) wParam;
450+
{
451+
// TheSuperHackers @bugfix xezon 11/05/2025 This event originally called DX8Wrapper::Reset_Device,
452+
// intended to clear resources on a lost device in fullscreen, but effectively also in
453+
// windowed mode, if the DXMaximizedWindowedMode shim was applied in newer versions of Windows,
454+
// which lead to unfortunate application crashing. Resetting the device on WM_ACTIVATEAPP instead
455+
// of TestCooperativeLevel() == D3DERR_DEVICENOTRESET is not a requirement. There are other code
456+
// paths that take care of that.
457+
458+
isWinMainActive = (BOOL) wParam;
454459

455460
if (TheGameEngine)
456461
TheGameEngine->setIsActive(isWinMainActive);
457462

458-
Reset_D3D_Device(isWinMainActive);
459463
if (isWinMainActive)
460464
{ //restore mouse cursor to our custom version.
461465
if (TheWin32Mouse)

0 commit comments

Comments
 (0)