Skip to content
Draft
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
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ class GlobalData : public SubsystemInterface
Bool m_languageFilterPref; ///< Bool if user wants to filter language
Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie
Bool m_disableRender; ///< if true, no rendering!
Bool m_anisotropicFiltering; ///< if true, enable anisotropic filtering

Bool m_saveCameraInReplay;
Bool m_useCameraInReplay;
Expand Down
7 changes: 7 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ GlobalData* GlobalData::m_theOriginal = nullptr;
{ "Windowed", INI::parseBool, nullptr, offsetof( GlobalData, m_windowed ) },
{ "XResolution", INI::parseInt, nullptr, offsetof( GlobalData, m_xResolution ) },
{ "YResolution", INI::parseInt, nullptr, offsetof( GlobalData, m_yResolution ) },
{ "AntiAliasing", INI::parseInt, nullptr, offsetof( GlobalData, m_antiAliasBoxValue ) },
{ "AnisotropicFiltering", INI::parseBool, nullptr, offsetof( GlobalData, m_anisotropicFiltering ) },
{ "MapName", INI::parseAsciiString,nullptr, offsetof( GlobalData, m_mapName ) },
{ "MoveHintName", INI::parseAsciiString,nullptr, offsetof( GlobalData, m_moveHintName ) },
{ "UseTrees", INI::parseBool, nullptr, offsetof( GlobalData, m_useTrees ) },
Expand Down Expand Up @@ -940,6 +942,7 @@ GlobalData::GlobalData()
m_firewallPortAllocationDelta = 0;
m_loadScreenDemo = FALSE;
m_disableRender = false;
m_anisotropicFiltering = false;

m_saveCameraInReplay = FALSE;
m_useCameraInReplay = FALSE;
Expand Down Expand Up @@ -1247,6 +1250,10 @@ void GlobalData::parseGameDataDefinition( INI* ini )

TheWritableGlobalData->m_xResolution = xres;
TheWritableGlobalData->m_yResolution = yres;

TheWritableGlobalData->m_antiAliasBoxValue = optionPref.getInt("AntiAliasing", 0);

TheWritableGlobalData->m_anisotropicFiltering = optionPref.getBool("AnisotropicFiltering", false);
}

void GlobalData::parseCustomDefinition()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ static void drawFramerateBar();
#include "WW3D2/part_emt.h"
#include "WW3D2/part_ldr.h"
#include "WW3D2/dx8caps.h"
#include "WW3D2/dx8wrapper.h"
#include "WW3D2/ww3dformat.h"
#include "WW3D2/agg_def.h"
#include "WW3D2/render2dsentence.h"
#include "WW3D2/sortingrenderer.h"
#include "WW3D2/textureloader.h"
#include "WW3D2/texturefilter.h"
#include "WW3D2/dx8webbrowser.h"
#include "WW3D2/mesh.h"
#include "WW3D2/hlod.h"
Expand Down Expand Up @@ -708,6 +710,16 @@ void W3DDisplay::init()
WW3D::Set_Screen_UV_Bias( TRUE ); ///< this makes text look good :)
WW3D::Set_Texture_Bitdepth(32);

D3DMULTISAMPLE_TYPE msType = D3DMULTISAMPLE_NONE;
switch (TheGlobalData->m_antiAliasBoxValue)
{
case 1: msType = D3DMULTISAMPLE_2_SAMPLES; break;
case 2: msType = D3DMULTISAMPLE_4_SAMPLES; break;
case 3: msType = D3DMULTISAMPLE_8_SAMPLES; break;
default: msType = D3DMULTISAMPLE_NONE; break;
}
DX8Wrapper::Set_MultiSample_Type(msType);
Comment on lines +713 to +721
Copy link

Choose a reason for hiding this comment

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

No hardware capability check before setting MSAA type

DX8Wrapper::Set_MultiSample_Type(msType) is called unconditionally without first verifying the hardware supports the requested sample count via IDirect3D8::CheckDeviceMultiSampleType. On hardware that doesn't support (for example) 8× MSAA, this will cause every call to Set_Render_Device to fail. Critically, the three-attempt fallback retry loop below (attempts 0-2) only changes the resolution and bit-depth — it never resets MultiSampleType back to D3DMULTISAMPLE_NONE. This means all three attempts will fail with the same unsupported MSAA type, causing the game to abort with ERROR_INVALID_D3D on startup for any user whose hardware doesn't support their configured MSAA level.

The fix should reset MultiSampleType to D3DMULTISAMPLE_NONE inside the retry loop when device creation fails, or validate the sample count against D3DInterface->CheckDeviceMultiSampleType before using it.

Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
Line: 713-721

Comment:
**No hardware capability check before setting MSAA type**

`DX8Wrapper::Set_MultiSample_Type(msType)` is called unconditionally without first verifying the hardware supports the requested sample count via `IDirect3D8::CheckDeviceMultiSampleType`. On hardware that doesn't support (for example) 8× MSAA, this will cause every call to `Set_Render_Device` to fail. Critically, the three-attempt fallback retry loop below (attempts 0-2) only changes the resolution and bit-depth — it never resets `MultiSampleType` back to `D3DMULTISAMPLE_NONE`. This means all three attempts will fail with the same unsupported MSAA type, causing the game to abort with `ERROR_INVALID_D3D` on startup for any user whose hardware doesn't support their configured MSAA level.

The fix should reset `MultiSampleType` to `D3DMULTISAMPLE_NONE` inside the retry loop when device creation fails, or validate the sample count against `D3DInterface->CheckDeviceMultiSampleType` before using it.

How can I resolve this? If you propose a fix, please make it concise.


setWindowed( TheGlobalData->m_windowed );
Comment on lines +713 to 723
Copy link

Choose a reason for hiding this comment

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

MSAA set before windowed mode is determined

DX8Wrapper::Set_MultiSample_Type(msType) is called before setWindowed(TheGlobalData->m_windowed). In DirectX 8, MSAA in windowed mode is unsupported on most hardware (the API requires full-screen exclusive mode for MultiSampleType != D3DMULTISAMPLE_NONE). Setting a non-zero MSAA type and then requesting a windowed device will almost certainly cause CreateDevice/Reset to return D3DERR_INVALIDCALL.

The MSAA type should either be forced to D3DMULTISAMPLE_NONE when windowed mode is active, or the windowed state must be resolved before the multisampling type is set.

Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
Line: 713-723

Comment:
**MSAA set before windowed mode is determined**

`DX8Wrapper::Set_MultiSample_Type(msType)` is called before `setWindowed(TheGlobalData->m_windowed)`. In DirectX 8, MSAA in windowed mode is unsupported on most hardware (the API requires full-screen exclusive mode for `MultiSampleType != D3DMULTISAMPLE_NONE`). Setting a non-zero MSAA type and then requesting a windowed device will almost certainly cause `CreateDevice`/`Reset` to return `D3DERR_INVALIDCALL`.

The MSAA type should either be forced to `D3DMULTISAMPLE_NONE` when windowed mode is active, or the windowed state must be resolved before the multisampling type is set.

How can I resolve this? If you propose a fix, please make it concise.


// create a 2D renderer helper
Expand Down Expand Up @@ -782,6 +794,11 @@ void W3DDisplay::init()
return;
}

if (TheGlobalData->m_anisotropicFiltering)
{
WW3D::Set_Texture_Filter(TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC);
}

//Check if level was never set and default to setting most suitable for system.
if (TheGameLODManager->getStaticLODLevel() == STATIC_GAME_LOD_UNKNOWN)
{
Expand Down
6 changes: 2 additions & 4 deletions GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ const int DEFAULT_BIT_DEPTH = 32;
const int DEFAULT_TEXTURE_BIT_DEPTH = 16;

bool DX8Wrapper_IsWindowed = true;

// FPU_PRESERVE
D3DMULTISAMPLE_TYPE DX8Wrapper::MultiSampleType = D3DMULTISAMPLE_NONE;
int DX8Wrapper_PreserveFPU = 0;

/***********************************************************************************
Expand Down Expand Up @@ -1024,8 +1023,7 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
_PresentParameters.BackBufferWidth = ResolutionWidth;
_PresentParameters.BackBufferHeight = ResolutionHeight;
_PresentParameters.BackBufferCount = IsWindowed ? 1 : 2;

_PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
_PresentParameters.MultiSampleType = MultiSampleType;
//I changed this to discard all the time (even when full-screen) since that the most efficient. 07-16-03 MW:
_PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;//IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP?
_PresentParameters.hDeviceWindow = _Hwnd;
Expand Down
6 changes: 4 additions & 2 deletions GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ class DX8Wrapper
static void Invalidate_Cached_Render_States();

static void Set_Draw_Polygon_Low_Bound_Limit(unsigned n) { DrawPolygonLowBoundLimit=n; }
static void Set_MultiSample_Type(D3DMULTISAMPLE_TYPE type) { MultiSampleType = type; }

protected:

Expand Down Expand Up @@ -635,8 +636,9 @@ class DX8Wrapper
static int ResolutionHeight;
static int BitDepth;
static int TextureBitDepth;
static bool IsWindowed;
static D3DFORMAT DisplayFormat;
static bool IsWindowed;
static D3DMULTISAMPLE_TYPE MultiSampleType;
static D3DFORMAT DisplayFormat;

static D3DMATRIX old_world;
static D3DMATRIX old_view;
Expand Down
Loading