Skip to content

Commit 8619fa8

Browse files
Maullerxezon
authored andcommitted
feat(options): Implement game option to set MSAA level (#2482)
1 parent 88bdb7c commit 8619fa8

13 files changed

Lines changed: 126 additions & 44 deletions

File tree

Core/GameEngine/Include/Common/OptionPreferences.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#pragma once
3232

33+
#include "ww3d.h"
3334
#include "Common/UserPreferences.h"
3435

3536
typedef UnsignedInt CursorCaptureMode;
@@ -44,8 +45,18 @@ class OptionPreferences : public UserPreferences
4445
OptionPreferences();
4546
virtual ~OptionPreferences() override;
4647

48+
enum AntiAliasingMode CPP_11(: Int)
49+
{
50+
AntiAliasingMode_OFF = 0,
51+
AntiAliasingMode_MSAA_2X,
52+
AntiAliasingMode_MSAA_4X,
53+
AntiAliasingMode_MSAA_8X,
54+
AntiAliasingMode_Count
55+
};
56+
4757
Bool loadFromIniFile();
4858

59+
WW3D::MultiSampleModeEnum getAntiAliasing() const;
4960
UnsignedInt getLANIPAddress();
5061
UnsignedInt getOnlineIPAddress();
5162
void setLANIPAddress(AsciiString IP);

Core/GameEngine/Source/Common/OptionPreferences.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ Bool OptionPreferences::loadFromIniFile()
6666
return load("Options.ini");
6767
}
6868

69+
WW3D::MultiSampleModeEnum OptionPreferences::getAntiAliasing() const
70+
{
71+
OptionPreferences::const_iterator it = find("AntiAliasing");
72+
if (it == end())
73+
return WW3D::MULTISAMPLE_MODE_NONE;
74+
75+
WW3D::MultiSampleModeEnum level = (WW3D::MultiSampleModeEnum)atoi(it->second.str());
76+
level = clamp(WW3D::MULTISAMPLE_MODE_NONE, level, WW3D::MULTISAMPLE_MODE_8X);
77+
level = highestBit(level);
78+
79+
return level;
80+
}
81+
6982
Int OptionPreferences::getCampaignDifficulty()
7083
{
7184
OptionPreferences::const_iterator it = find("CampaignDifficulty");

Core/Libraries/Include/Lib/BaseType.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ inline int sign(NUM x)
5858
else return 0;
5959
}
6060

61+
template <typename NUM>
62+
inline NUM highestBit(NUM x)
63+
{
64+
static_assert(sizeof(NUM) <= 8, "NUM must be 8 bytes or less");
65+
UnsignedInt64 y = static_cast<UnsignedInt64>(x);
66+
67+
y |= (y >> 1);
68+
y |= (y >> 2);
69+
y |= (y >> 4);
70+
y |= (y >> 8);
71+
y |= (y >> 16);
72+
y |= (y >> 32);
73+
74+
return static_cast<NUM>(y & ~(y >> 1));
75+
}
76+
6177
// TheSuperHackers @refactor JohnsterID 24/01/2026 Add lowercase min/max templates for GameEngine layer.
6278
// GameEngine code typically uses BaseType.h, but may include WWVegas headers (which define min/max in always.h).
6379
// Header guard prevents duplicate definitions. VC6's <algorithm> lacks std::min/std::max.

Generals/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ class GlobalData : public SubsystemInterface
397397
units will always keep their formation. If it's <1.0, then the user must click a
398398
smaller area within the rectangle to order the gather. */
399399

400-
Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu
400+
UnsignedInt m_antiAliasLevel; ///< value of selected antialias level in the game options
401401
Bool m_languageFilterPref; ///< Bool if user wants to filter language
402402
Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie
403403
Bool m_disableRender; ///< if true, no rendering!

Generals/Code/GameEngine/Source/Common/GlobalData.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
3333
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
3434

35+
#include "ww3d.h"
36+
3537
#include "Common/GlobalData.h"
3638

3739
#define DEFINE_TERRAIN_LOD_NAMES
@@ -927,7 +929,7 @@ GlobalData::GlobalData()
927929

928930
m_standardPublicBones.clear();
929931

930-
m_antiAliasBoxValue = 0;
932+
m_antiAliasLevel = WW3D::MultiSampleModeEnum::MULTISAMPLE_MODE_NONE;
931933

932934
// m_languageFilterPref = false;
933935
m_languageFilterPref = true;
@@ -1204,6 +1206,8 @@ void GlobalData::parseGameDataDefinition( INI* ini )
12041206
TheWritableGlobalData->m_playerInfoListFontSize = optionPref.getPlayerInfoListFontSize();
12051207
TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute();
12061208

1209+
TheWritableGlobalData->m_antiAliasLevel = optionPref.getAntiAliasing();
1210+
12071211
Int val=optionPref.getGammaValue();
12081212
//generate a value between 0.6 and 2.0.
12091213
if (val < 50)

Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,17 @@ static void saveOptions()
533533
//-------------------------------------------------------------------------------------------------
534534
// antialiasing
535535
GadgetComboBoxGetSelectedPos(comboBoxAntiAliasing, &index);
536-
if( index >= 0 && TheGlobalData->m_antiAliasBoxValue != index )
536+
if( index >= 0 )
537537
{
538-
TheWritableGlobalData->m_antiAliasBoxValue = index;
538+
Int mode = WW3D::MULTISAMPLE_MODE_NONE;
539+
540+
// TheSuperHackers @info We are converting comboBox entry position to MultiSampleModeEnum values
541+
index = clamp((int)OptionPreferences::AntiAliasingMode_OFF, index, (int)OptionPreferences::AntiAliasingMode_MSAA_8X);
542+
mode = (index > 0) ? 1 << index : 0;
543+
544+
TheWritableGlobalData->m_antiAliasLevel = mode;
539545
AsciiString prefString;
540-
prefString.format("%d", index);
546+
prefString.format("%d", mode);
541547
(*pref)["AntiAliasing"] = prefString;
542548
}
543549

@@ -992,14 +998,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
992998

993999
Color color = GameMakeColor(255,255,255,255);
9941000

995-
enum AliasingMode CPP_11(: Int)
996-
{
997-
OFF = 0,
998-
LOW,
999-
HIGH,
1000-
NUM_ALIASING_MODES
1001-
};
1002-
10031001
initLabelVersion();
10041002

10051003
// Choose an IP address, then initialize the IP combo box
@@ -1103,18 +1101,32 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
11031101
GadgetComboBoxReset(comboBoxAntiAliasing);
11041102
AsciiString temp;
11051103
Int i=0;
1106-
for (; i < NUM_ALIASING_MODES; ++i)
1104+
for (; i < OptionPreferences::AntiAliasingMode_Count; ++i)
11071105
{
11081106
temp.format("GUI:AntiAliasing%d", i);
11091107
str = TheGameText->fetch( temp );
11101108
index = GadgetComboBoxAddEntry(comboBoxAntiAliasing, str, color);
11111109
}
11121110
Int val = atoi(selectedAliasingMode.str());
1113-
if( val < 0 || val > NUM_ALIASING_MODES )
1111+
Int pos = 0;
1112+
1113+
// TheSuperHackers @info We are converting from human readable value to comboBox entry position
1114+
val = highestBit(val);
1115+
1116+
if (val == WW3D::MULTISAMPLE_MODE_NONE)
1117+
pos = OptionPreferences::AntiAliasingMode_OFF;
1118+
else if (val == WW3D::MULTISAMPLE_MODE_2X)
1119+
pos = OptionPreferences::AntiAliasingMode_MSAA_2X;
1120+
else if (val == WW3D::MULTISAMPLE_MODE_4X)
1121+
pos = OptionPreferences::AntiAliasingMode_MSAA_4X;
1122+
else if (val == WW3D::MULTISAMPLE_MODE_8X)
1123+
pos = OptionPreferences::AntiAliasingMode_MSAA_8X;
1124+
1125+
if (val < 0 || val > WW3D::MULTISAMPLE_MODE_8X)
11141126
{
1115-
TheWritableGlobalData->m_antiAliasBoxValue = val = 0;
1127+
TheWritableGlobalData->m_antiAliasLevel = pos = 0;
11161128
}
1117-
GadgetComboBoxSetSelectedPos(comboBoxAntiAliasing, val);
1129+
GadgetComboBoxSetSelectedPos(comboBoxAntiAliasing, pos);
11181130

11191131
// get resolution from saved preferences file
11201132
AsciiString selectedResolution = (*pref) ["Resolution"];

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ void W3DDisplay::init()
821821
}
822822

823823
// TheSuperHackers @feature Mauller 13/03/2026 Add native MSAA support, must be set before creating render device
824-
WW3D::Set_MSAA_Mode(WW3D::MULTISAMPLE_MODE_NONE);
824+
WW3D::Set_MSAA_Mode((WW3D::MultiSampleModeEnum)TheWritableGlobalData->m_antiAliasLevel);
825825

826826
renderDeviceError = WW3D::Set_Render_Device(
827827
0,
@@ -831,6 +831,11 @@ void W3DDisplay::init()
831831
getWindowed(),
832832
true );
833833

834+
// TheSuperHackers @info Update the MSAA mode that was set as some GPU's may not support certain levels
835+
if (renderDeviceError == WW3D_ERROR_OK) {
836+
TheWritableGlobalData->m_antiAliasLevel = (UnsignedInt)WW3D::Get_MSAA_Mode();
837+
}
838+
834839
++attempt;
835840
}
836841
while (attempt < 3 && renderDeviceError != WW3D_ERROR_OK);

Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ class WW3D
7373
public:
7474

7575
enum MultiSampleModeEnum {
76-
MULTISAMPLE_MODE_NONE,
77-
MULTISAMPLE_MODE_2X,
78-
MULTISAMPLE_MODE_4X,
79-
MULTISAMPLE_MODE_8X
76+
MULTISAMPLE_MODE_NONE = 0,
77+
MULTISAMPLE_MODE_2X = 2,
78+
MULTISAMPLE_MODE_4X = 4,
79+
MULTISAMPLE_MODE_8X = 8
8080
};
8181

8282
enum PrelitModeEnum {

GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ class GlobalData : public SubsystemInterface
398398
units will always keep their formation. If it's <1.0, then the user must click a
399399
smaller area within the rectangle to order the gather. */
400400

401-
Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu
401+
UnsignedInt m_antiAliasLevel; ///< value of selected antialias level in the game options
402402
Bool m_languageFilterPref; ///< Bool if user wants to filter language
403403
Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie
404404
Bool m_disableRender; ///< if true, no rendering!

GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
3333
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
3434

35+
#include "ww3d.h"
36+
3537
#include "Common/GlobalData.h"
3638

3739
#define DEFINE_TERRAIN_LOD_NAMES
@@ -934,7 +936,7 @@ GlobalData::GlobalData()
934936

935937
m_standardPublicBones.clear();
936938

937-
m_antiAliasBoxValue = 0;
939+
m_antiAliasLevel = WW3D::MultiSampleModeEnum::MULTISAMPLE_MODE_NONE;
938940

939941
// m_languageFilterPref = false;
940942
m_languageFilterPref = true;
@@ -1211,6 +1213,8 @@ void GlobalData::parseGameDataDefinition( INI* ini )
12111213
TheWritableGlobalData->m_playerInfoListFontSize = optionPref.getPlayerInfoListFontSize();
12121214
TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute();
12131215

1216+
TheWritableGlobalData->m_antiAliasLevel = optionPref.getAntiAliasing();
1217+
12141218
Int val=optionPref.getGammaValue();
12151219
//generate a value between 0.6 and 2.0.
12161220
if (val < 50)

0 commit comments

Comments
 (0)