Skip to content
Merged
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
15 changes: 15 additions & 0 deletions Core/GameEngine/Include/Common/OptionPreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@

#pragma once

#include "ww3d.h"
#include "texturefilter.h"

#include "Common/UserPreferences.h"

typedef UnsignedInt CursorCaptureMode;
Expand All @@ -44,8 +47,20 @@ class OptionPreferences : public UserPreferences
OptionPreferences();
virtual ~OptionPreferences() override;

enum AntiAliasingMode CPP_11(: Int)
{
AntiAliasingMode_OFF = 0,
AntiAliasingMode_MSAA_2X,
AntiAliasingMode_MSAA_4X,
AntiAliasingMode_MSAA_8X,
AntiAliasingMode_Count
};

Bool loadFromIniFile();

WW3D::MultiSampleModeEnum getAntiAliasing() const;
TextureFilterClass::TextureFilterMode getTextureFilterMode() const;
TextureFilterClass::AnisotropicFilterMode getTextureAnisotropyLevel() const;
UnsignedInt getLANIPAddress();
UnsignedInt getOnlineIPAddress();
void setLANIPAddress(AsciiString IP);
Expand Down
35 changes: 35 additions & 0 deletions Core/GameEngine/Source/Common/OptionPreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,41 @@ Bool OptionPreferences::loadFromIniFile()
return load("Options.ini");
}

WW3D::MultiSampleModeEnum OptionPreferences::getAntiAliasing() const
{
OptionPreferences::const_iterator it = find("AntiAliasing");
if (it == end())
return WW3D::MULTISAMPLE_MODE_NONE;

WW3D::MultiSampleModeEnum level = (WW3D::MultiSampleModeEnum)atoi(it->second.str());
level = clamp(WW3D::MULTISAMPLE_MODE_NONE, level, WW3D::MULTISAMPLE_MODE_8X);
level = highestBit(level);

return level;
}

TextureFilterClass::TextureFilterMode OptionPreferences::getTextureFilterMode() const
{
OptionPreferences::const_iterator it = find("TextureFilter");
if (it == end())
return TextureFilterClass::TEXTURE_FILTER_BILINEAR;

return TextureFilterClass::getTextureFilterMode(it->second.str());
}

TextureFilterClass::AnisotropicFilterMode OptionPreferences::getTextureAnisotropyLevel() const
{
OptionPreferences::const_iterator it = find("AnisotropyLevel");
Comment thread
xezon marked this conversation as resolved.
if (it == end())
return TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X;

TextureFilterClass::AnisotropicFilterMode level = (TextureFilterClass::AnisotropicFilterMode)atoi(it->second.str());
level = clamp(TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X, level, TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X);
level = highestBit(level);

return level;
}

Int OptionPreferences::getCampaignDifficulty()
{
OptionPreferences::const_iterator it = find("CampaignDifficulty");
Expand Down
16 changes: 16 additions & 0 deletions Core/Libraries/Include/Lib/BaseType.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ inline int sign(NUM x)
else return 0;
}

template <typename NUM>
inline NUM highestBit(NUM x)
{
static_assert(sizeof(NUM) <= 8, "NUM must be 8 bytes or less");
UnsignedInt64 y = static_cast<UnsignedInt64>(x);

y |= (y >> 1);
y |= (y >> 2);
y |= (y >> 4);
y |= (y >> 8);
y |= (y >> 16);
y |= (y >> 32);

return static_cast<NUM>(y & ~(y >> 1));
}

// TheSuperHackers @refactor JohnsterID 24/01/2026 Add lowercase min/max templates for GameEngine layer.
// GameEngine code typically uses BaseType.h, but may include WWVegas headers (which define min/max in always.h).
// Header guard prevents duplicate definitions. VC6's <algorithm> lacks std::min/std::max.
Expand Down
5 changes: 4 additions & 1 deletion Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,10 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Inits()
** Initialize any other subsystems inside of WW3D
*/
MissingTexture::_Init();
TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter());
TextureFilterClass::_Init_Filters(
(TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter(),
(TextureFilterClass::AnisotropicFilterMode)WW3D::Get_Anisotropy_Level()
);
TheDX8MeshRenderer.Init();
SHD_INIT;
BoxRenderObjClass::Init();
Expand Down
26 changes: 22 additions & 4 deletions Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@
#include "texturefilter.h"
#include "dx8wrapper.h"

const char* const TextureFilterClass::TextureFilterModeString[TEXTURE_FILTER_COUNT] = {
"None",
"Point",
"Bilinear",
"Trilinear",
"Anisotropic"
};

TextureFilterClass::TextureFilterMode TextureFilterClass::getTextureFilterMode(const char* str) {
for (int i = 0; i < TextureFilterClass::TEXTURE_FILTER_COUNT; ++i) {
if (stricmp(str, TextureFilterClass::TextureFilterModeString[i]) == 0) {
return (TextureFilterClass::TextureFilterMode)i;
}
}

return TextureFilterClass::TEXTURE_FILTER_NONE;
}

unsigned _MinTextureFilters[MAX_TEXTURE_STAGES][TextureFilterClass::FILTER_TYPE_COUNT];
unsigned _MagTextureFilters[MAX_TEXTURE_STAGES][TextureFilterClass::FILTER_TYPE_COUNT];
unsigned _MipMapFilters[MAX_TEXTURE_STAGES][TextureFilterClass::FILTER_TYPE_COUNT];
Expand Down Expand Up @@ -100,7 +118,7 @@ void TextureFilterClass::Apply(unsigned int stage)
//! Init filters (legacy)
/*!
*/
void TextureFilterClass::_Init_Filters(TextureFilterMode filter_type)
void TextureFilterClass::_Init_Filters(TextureFilterMode texture_filter, AnisotropicFilterMode anisotropy_level)
{
const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps();

Expand All @@ -122,7 +140,7 @@ void TextureFilterClass::_Init_Filters(TextureFilterMode filter_type)
// TheSuperHackers @feature Mauller 08/03/2026 Add full support for all texture filtering modes;
// None, Point, Bilinear, Trilinear, Anisotropic.
BOOL FilterSupported = false;
switch (filter_type) {
switch (texture_filter) {

default:
// TheSuperHackers @info if we have an invalid filter_type, set the filtering to none
Expand Down Expand Up @@ -201,8 +219,8 @@ void TextureFilterClass::_Init_Filters(TextureFilterMode filter_type)
_MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC;
_MagTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC;

// Set the Anisotropic filtering level for all stages - 2X by default
_Set_Max_Anisotropy(TEXTURE_FILTER_ANISOTROPIC_2X);
// Set the Anisotropic filtering level for all stages
_Set_Max_Anisotropy(anisotropy_level);
}
else {
_MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_POINT;
Expand Down
9 changes: 7 additions & 2 deletions Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,14 @@ class TextureFilterClass
TEXTURE_FILTER_POINT,
TEXTURE_FILTER_BILINEAR,
TEXTURE_FILTER_TRILINEAR,
TEXTURE_FILTER_ANISOTROPIC
TEXTURE_FILTER_ANISOTROPIC,
TEXTURE_FILTER_COUNT
};

static const char* const TextureFilterModeString[TEXTURE_FILTER_COUNT];

static TextureFilterMode getTextureFilterMode(const char* str);

enum AnisotropicFilterMode
{
TEXTURE_FILTER_ANISOTROPIC_2X = 2,
Expand Down Expand Up @@ -124,7 +129,7 @@ class TextureFilterClass
void Set_V_Addr_Mode(TxtAddrMode mode) { VAddressMode=mode; }

// These need to be called after device has been created
static void _Init_Filters(TextureFilterMode texture_filter);
static void _Init_Filters(TextureFilterMode texture_filter, AnisotropicFilterMode anisotropy_level);
static void _Set_Max_Anisotropy(AnisotropicFilterMode mode);

static void _Set_Default_Min_Filter(FilterType filter);
Expand Down
5 changes: 4 additions & 1 deletion Generals/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,10 @@ class GlobalData : public SubsystemInterface
units will always keep their formation. If it's <1.0, then the user must click a
smaller area within the rectangle to order the gather. */

Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu
UnsignedInt m_antiAliasLevel; ///< value of selected antialias level in the game options
UnsignedInt m_textureFilteringMode; ///< value related to TextureFilterClass::TextureFilterModeEnum
UnsignedInt m_textureAnisotropyLevel; ///< value related to TextureFilterClass::AnisotropicFilterMode

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!
Expand Down
11 changes: 10 additions & 1 deletion Generals/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine

#include "ww3d.h"
#include "texturefilter.h"

#include "Common/GlobalData.h"

#define DEFINE_TERRAIN_LOD_NAMES
Expand Down Expand Up @@ -927,7 +930,9 @@ GlobalData::GlobalData()

m_standardPublicBones.clear();

m_antiAliasBoxValue = 0;
m_antiAliasLevel = WW3D::MultiSampleModeEnum::MULTISAMPLE_MODE_NONE;
m_textureFilteringMode = TextureFilterClass::TextureFilterMode::TEXTURE_FILTER_BILINEAR;
m_textureAnisotropyLevel = TextureFilterClass::AnisotropicFilterMode::TEXTURE_FILTER_ANISOTROPIC_2X;

// m_languageFilterPref = false;
m_languageFilterPref = true;
Expand Down Expand Up @@ -1204,6 +1209,10 @@ void GlobalData::parseGameDataDefinition( INI* ini )
TheWritableGlobalData->m_playerInfoListFontSize = optionPref.getPlayerInfoListFontSize();
TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute();

TheWritableGlobalData->m_antiAliasLevel = optionPref.getAntiAliasing();
TheWritableGlobalData->m_textureFilteringMode = optionPref.getTextureFilterMode();
TheWritableGlobalData->m_textureAnisotropyLevel = optionPref.getTextureAnisotropyLevel();

Int val=optionPref.getGammaValue();
//generate a value between 0.6 and 2.0.
if (val < 50)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include "GameClient/MessageBox.h"

#include "ww3d.h"
#include "texturefilter.h"

// This is for non-RC builds only!!!
#define VERBOSE_VERSION L"Release"
Expand Down Expand Up @@ -533,14 +534,45 @@ static void saveOptions()
//-------------------------------------------------------------------------------------------------
// antialiasing
GadgetComboBoxGetSelectedPos(comboBoxAntiAliasing, &index);
if( index >= 0 && TheGlobalData->m_antiAliasBoxValue != index )
if( index >= 0 )
{
TheWritableGlobalData->m_antiAliasBoxValue = index;
Int mode = WW3D::MULTISAMPLE_MODE_NONE;

// TheSuperHackers @info We are converting comboBox entry position to MultiSampleModeEnum values
index = clamp((int)OptionPreferences::AntiAliasingMode_OFF, index, (int)OptionPreferences::AntiAliasingMode_MSAA_8X);
mode = (index > 0) ? 1 << index : 0;

TheWritableGlobalData->m_antiAliasLevel = mode;
AsciiString prefString;
prefString.format("%d", index);
prefString.format("%d", mode);
(*pref)["AntiAliasing"] = prefString;
}

//-------------------------------------------------------------------------------------------------
// texture filter mode
val = pref->getTextureFilterMode();
if (val >= 0)
{
val = clamp((int)TextureFilterClass::TEXTURE_FILTER_NONE, val, (int)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC);

TheWritableGlobalData->m_textureFilteringMode = val;
AsciiString prefString;
prefString = TextureFilterClass::TextureFilterModeString[val];
(*pref)["TextureFilter"] = prefString;
}

//-------------------------------------------------------------------------------------------------
// anisotropy level
val = pref->getTextureAnisotropyLevel();
if (val >= 0)
{
val = clamp((int)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_2X, val, (int)TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC_16X);

TheWritableGlobalData->m_textureAnisotropyLevel = val;
AsciiString prefString;
prefString.format("%d", val);
(*pref)["AnisotropyLevel"] = prefString;
}

//-------------------------------------------------------------------------------------------------
// mouse mode
Expand Down Expand Up @@ -992,14 +1024,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )

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

enum AliasingMode CPP_11(: Int)
{
OFF = 0,
LOW,
HIGH,
NUM_ALIASING_MODES
};

initLabelVersion();

// Choose an IP address, then initialize the IP combo box
Expand Down Expand Up @@ -1103,18 +1127,32 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
GadgetComboBoxReset(comboBoxAntiAliasing);
AsciiString temp;
Int i=0;
for (; i < NUM_ALIASING_MODES; ++i)
for (; i < OptionPreferences::AntiAliasingMode_Count; ++i)
{
temp.format("GUI:AntiAliasing%d", i);
str = TheGameText->fetch( temp );
index = GadgetComboBoxAddEntry(comboBoxAntiAliasing, str, color);
}
Int val = atoi(selectedAliasingMode.str());
if( val < 0 || val > NUM_ALIASING_MODES )
Int pos = 0;

// TheSuperHackers @info We are converting from human readable value to comboBox entry position
val = highestBit(val);

if (val == WW3D::MULTISAMPLE_MODE_NONE)
pos = OptionPreferences::AntiAliasingMode_OFF;
else if (val == WW3D::MULTISAMPLE_MODE_2X)
pos = OptionPreferences::AntiAliasingMode_MSAA_2X;
else if (val == WW3D::MULTISAMPLE_MODE_4X)
pos = OptionPreferences::AntiAliasingMode_MSAA_4X;
else if (val == WW3D::MULTISAMPLE_MODE_8X)
pos = OptionPreferences::AntiAliasingMode_MSAA_8X;

if (val < 0 || val > WW3D::MULTISAMPLE_MODE_8X)
{
TheWritableGlobalData->m_antiAliasBoxValue = val = 0;
TheWritableGlobalData->m_antiAliasLevel = pos = 0;
}
GadgetComboBoxSetSelectedPos(comboBoxAntiAliasing, val);
GadgetComboBoxSetSelectedPos(comboBoxAntiAliasing, pos);

// get resolution from saved preferences file
AsciiString selectedResolution = (*pref) ["Resolution"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ void W3DDisplay::init()
}

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

renderDeviceError = WW3D::Set_Render_Device(
0,
Expand All @@ -726,6 +726,16 @@ void W3DDisplay::init()
getWindowed(),
true );

// TheSuperHackers @info Update the MSAA mode that was set as some GPU's may not support certain levels
// Texture filtering must also be updated after render device initialization
if (renderDeviceError == WW3D_ERROR_OK) {
TheWritableGlobalData->m_antiAliasLevel = (UnsignedInt)WW3D::Get_MSAA_Mode();
WW3D::Set_Texture_Filter(TheWritableGlobalData->m_textureFilteringMode);
TheWritableGlobalData->m_textureFilteringMode = WW3D::Get_Texture_Filter();
WW3D::Set_Anisotropy_Level(TheWritableGlobalData->m_textureAnisotropyLevel);
TheWritableGlobalData->m_textureAnisotropyLevel = WW3D::Get_Anisotropy_Level();
}

++attempt;
}
while (attempt < 3 && renderDeviceError != WW3D_ERROR_OK);
Expand Down
Loading
Loading