Skip to content

[GEN][ZH] Fix crash when launching the game with an unsupported Display Resolution or when the graphics adapter does not support 800 x 600 #1055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ static void drawFramerateBar(void);
#endif

// DEFINE AND ENUMS ///////////////////////////////////////////////////////////
#define W3D_DISPLAY_DEFAULT_BIT_DEPTH 32

#define no_SAMPLE_DYNAMIC_LIGHT 1
#ifdef SAMPLE_DYNAMIC_LIGHT
Expand Down Expand Up @@ -668,38 +667,74 @@ void W3DDisplay::init( void )
m_2DRender = NEW Render2DClass;
DEBUG_ASSERTCRASH( m_2DRender, ("Cannot create Render2DClass") );

// set our default width and height and bit depth
/// @todo we should set this according to options read from a file
setWidth( TheGlobalData->m_xResolution );
setHeight( TheGlobalData->m_yResolution );
setBitDepth( W3D_DISPLAY_DEFAULT_BIT_DEPTH );

if( WW3D::Set_Render_Device( 0,
getWidth(),
getHeight(),
getBitDepth(),
getWindowed(),
true ) != WW3D_ERROR_OK )
WW3DErrorType renderDeviceError;
Int attempt = 0;
do
{
// Getting the device at the default bit depth (32) didn't work, so try
// getting a 16 bit display. (Voodoo 1-3 only supported 16 bit.) jba.
setBitDepth( 16 );
if( WW3D::Set_Render_Device( 0,
getWidth(),
getHeight(),
getBitDepth(),
getWindowed(),
true ) != WW3D_ERROR_OK )
switch (attempt)
{

WW3D::Shutdown();
WWMath::Shutdown();
throw ERROR_INVALID_D3D; //failed to initialize. User probably doesn't have DX 8.1
DEBUG_ASSERTCRASH( 0, ("Unable to set render device\n") );
return;
case 0:
// set our default width and height and bit depth
setWidth( TheGlobalData->m_xResolution );
setHeight( TheGlobalData->m_yResolution );
setBitDepth( 32 );
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setBitDepth(W3D_DISPLAY_DEFAULT_BIT_DEPTH);

break;
case 1:
// Getting the device at the default bit depth (32) didn't work, so try
// getting a 16 bit display. (Voodoo 1-3 only supported 16 bit.) jba.
setBitDepth( 16 );
break;
case 2:
{
// TheSuperHackers @bugfix xezon 11/06/2025 Now tries a safe default resolution
// if the custom resolution did not succeed. This is unlikely to happen but is possible
// if the user writes an unsupported resolution into to the Option Preferences or if the
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

into to

// graphics adapter does not support 800 x 600 to begin with.
const Int minW = 800;
const Int minH = 600;
Comment on lines +693 to +694
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minW = MIN_DISPLAY_RESOLUTION_X;
minH = MIN_DISPLAY_RESOLUTOIN_Y;

Int xres = minW;
Int yres = minH;
Int bitDepth = 32;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Int bitDepth = W3D_DISPLAY_DEFAULT_BIT_DEPTH;

Int displayModeCount = getDisplayModeCount();
Int displayModeIndex = 0;
for (; displayModeIndex < displayModeCount; ++displayModeIndex)
{
getDisplayModeDescription(0, &xres, &yres, &bitDepth);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDisplayModeDescription(displayModeIndex, &xres, &yres, &bitDepth);

if (xres * yres >= minW * minH)
break; // Is good enough. Use it.
}
TheWritableGlobalData->m_xResolution = xres;
TheWritableGlobalData->m_yResolution = yres;
setWidth( xres );
setHeight( yres );
setBitDepth( 32 );
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setBitDepth(bitDepth);

break;
}
case 3:
setBitDepth( 16 );
break;
}

} // end if
renderDeviceError = WW3D::Set_Render_Device(
0,
getWidth(),
getHeight(),
getBitDepth(),
getWindowed(),
true );

++attempt;
}
while (attempt < 4 && renderDeviceError != WW3D_ERROR_OK);

if (renderDeviceError != WW3D_ERROR_OK)
{
WW3D::Shutdown();
WWMath::Shutdown();
throw ERROR_INVALID_D3D; //failed to initialize. User probably doesn't have DX 8.1
DEBUG_ASSERTCRASH( 0, ("Unable to set render device\n") );
return;
}

//Check if level was never set and default to setting most suitable for system.
if (TheGameLODManager->getStaticLODLevel() == STATIC_GAME_LOD_UNKNOWN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ static void drawFramerateBar(void);
#endif

// DEFINE AND ENUMS ///////////////////////////////////////////////////////////
#define W3D_DISPLAY_DEFAULT_BIT_DEPTH 32

#define no_SAMPLE_DYNAMIC_LIGHT 1
#ifdef SAMPLE_DYNAMIC_LIGHT
Expand Down Expand Up @@ -735,38 +734,74 @@ void W3DDisplay::init( void )
m_2DRender = NEW Render2DClass;
DEBUG_ASSERTCRASH( m_2DRender, ("Cannot create Render2DClass") );

// set our default width and height and bit depth
/// @todo we should set this according to options read from a file
setWidth( TheGlobalData->m_xResolution );
setHeight( TheGlobalData->m_yResolution );
setBitDepth( W3D_DISPLAY_DEFAULT_BIT_DEPTH );

if( WW3D::Set_Render_Device( 0,
getWidth(),
getHeight(),
getBitDepth(),
getWindowed(),
true ) != WW3D_ERROR_OK )
WW3DErrorType renderDeviceError;
Int attempt = 0;
do
{
// Getting the device at the default bit depth (32) didn't work, so try
// getting a 16 bit display. (Voodoo 1-3 only supported 16 bit.) jba.
setBitDepth( 16 );
if( WW3D::Set_Render_Device( 0,
getWidth(),
getHeight(),
getBitDepth(),
getWindowed(),
true ) != WW3D_ERROR_OK )
switch (attempt)
{

WW3D::Shutdown();
WWMath::Shutdown();
throw ERROR_INVALID_D3D; //failed to initialize. User probably doesn't have DX 8.1
DEBUG_ASSERTCRASH( 0, ("Unable to set render device\n") );
return;
case 0:
// set our default width and height and bit depth
setWidth( TheGlobalData->m_xResolution );
setHeight( TheGlobalData->m_yResolution );
setBitDepth( 32 );
break;
case 1:
// Getting the device at the default bit depth (32) didn't work, so try
// getting a 16 bit display. (Voodoo 1-3 only supported 16 bit.) jba.
setBitDepth( 16 );
break;
case 2:
{
// TheSuperHackers @bugfix xezon 11/06/2025 Now tries a safe default resolution
// if the custom resolution did not succeed. This is unlikely to happen but is possible
// if the user writes an unsupported resolution into to the Option Preferences or if the
// graphics adapter does not support 800 x 600 to begin with.
const Int minW = 800;
const Int minH = 600;
Int xres = minW;
Int yres = minH;
Int bitDepth = 32;
Int displayModeCount = getDisplayModeCount();
Int displayModeIndex = 0;
for (; displayModeIndex < displayModeCount; ++displayModeIndex)
{
getDisplayModeDescription(0, &xres, &yres, &bitDepth);
if (xres * yres >= minW * minH)
break; // Is good enough. Use it.
}
TheWritableGlobalData->m_xResolution = xres;
TheWritableGlobalData->m_yResolution = yres;
setWidth( xres );
setHeight( yres );
setBitDepth( 32 );
break;
}
case 3:
setBitDepth( 16 );
break;
}

} // end if
renderDeviceError = WW3D::Set_Render_Device(
0,
getWidth(),
getHeight(),
getBitDepth(),
getWindowed(),
true );

++attempt;
}
while (attempt < 4 && renderDeviceError != WW3D_ERROR_OK);

if (renderDeviceError != WW3D_ERROR_OK)
{
WW3D::Shutdown();
WWMath::Shutdown();
throw ERROR_INVALID_D3D; //failed to initialize. User probably doesn't have DX 8.1
DEBUG_ASSERTCRASH( 0, ("Unable to set render device\n") );
return;
}

//Check if level was never set and default to setting most suitable for system.
if (TheGameLODManager->getStaticLODLevel() == STATIC_GAME_LOD_UNKNOWN)
Expand Down
Loading