Skip to content
Closed
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
10 changes: 7 additions & 3 deletions package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2731,11 +2731,13 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace)

# if defined(IBL)
if (SharedData::iblSettings.EnableDiffuseIBL) {
# if !defined(WORLD_MAP) || !defined(FWMF_DETECTED)
if (SharedData::iblSettings.UseStaticIBL && !inWorld && !inReflection) {
directionalAmbientColor = ImageBasedLighting::GetStaticDiffuseIBL(ambientNormal, SampColorSampler);
} else if (!SharedData::InInterior || SharedData::iblSettings.EnableInterior) {
directionalAmbientColor *= SharedData::iblSettings.DALCAmount;
}
# endif // !WORLD_MAP || !FWMF_DETECTED
}
# endif

Expand All @@ -2754,16 +2756,18 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace)
# if defined(IBL)
float3 iblColor = 0;
if (SharedData::iblSettings.EnableDiffuseIBL) {
# if !defined(WORLD_MAP) || !defined(FWMF_DETECTED)
if ((!SharedData::InInterior || SharedData::iblSettings.EnableInterior) && !(SharedData::iblSettings.UseStaticIBL && !inWorld && !inReflection))
{
# if defined(SKYLIGHTING)
# if defined(SKYLIGHTING)
iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-ambientNormal, skylightingDiffuse), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale;
# else
# else
iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-ambientNormal), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale;
# endif
# endif
iblColor = Color::LinearToGamma(iblColor);
directionalAmbientColor += iblColor;
}
# endif // !WORLD_MAP || !FWMF_DETECTED
}
# endif

Expand Down
89 changes: 89 additions & 0 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,34 @@ void State::Load(ConfigMode a_configMode, bool a_allowReload)
frameAnnotations = advanced["Frame Annotations"];
}

// Load incompatible mods configuration
if (settings["IncompatibleMods"].is_array()) {
incompatibleMods.clear();
int validCount = 0;
for (auto& modConfig : settings["IncompatibleMods"]) {
try {
IncompatibleMod mod;
if (modConfig["DLLNames"].is_array()) {
for (auto& dllName : modConfig["DLLNames"]) {
if (dllName.is_string())
mod.dllNames.push_back(dllName.get<std::string>());
}
}
if (modConfig["ShaderDefine"].is_string())
mod.shaderDefine = modConfig["ShaderDefine"].get<std::string>();
if (!mod.dllNames.empty() && !mod.shaderDefine.empty()) {
incompatibleMods.push_back(mod);
validCount++;
}
} catch (...) {
// Skip malformed entries silently
}
}
if (validCount > 0) {
logger::info("Loaded {} incompatible mod configuration(s)", validCount);
}
}

if (settings["General"].is_object()) {
logger::info("Loading 'General' settings");
json& general = settings["General"];
Expand Down Expand Up @@ -435,6 +463,14 @@ void State::Save(ConfigMode a_configMode)

settings["General"] = general;

// Initialize default incompatible mods configuration when saving DEFAULT config
if (a_configMode == ConfigMode::DEFAULT && incompatibleMods.empty()) {
IncompatibleMod fwmf;
fwmf.dllNames = { "BakaWorldMapSpeed.dll", "BakaWorldMapFOV.dll", "FlatMapMarkersSSE.dll" };
fwmf.shaderDefine = "FWMF_DETECTED";
incompatibleMods.push_back(fwmf);
}

auto& upscaling = globals::features::upscaling;
auto& upscalingJson = settings[upscaling.GetShortName()];
upscaling.SaveSettings(upscalingJson);
Expand All @@ -451,6 +487,18 @@ void State::Save(ConfigMode a_configMode)
}
settings["Disable at Boot"] = disabledFeaturesJson;

// Save incompatible mods configuration
if (!incompatibleMods.empty()) {
json incompatModsJson = json::array();
for (const auto& mod : incompatibleMods) {
json modConfig;
modConfig["DLLNames"] = mod.dllNames;
modConfig["ShaderDefine"] = mod.shaderDefine;
incompatModsJson.push_back(modConfig);
}
settings["IncompatibleMods"] = incompatModsJson;
}

settings["Version"] = Plugin::VERSION.string();

for (auto* feature : Feature::GetFeatureList())
Expand Down Expand Up @@ -833,6 +881,47 @@ float State::GetTotalSmoothedDrawCalls() const
return static_cast<float>(smoothDrawCalls[magic_enum::enum_integer(RE::BSShader::Type::Total)]);
}

void State::DetectIncompatibleMods()
{
int detectedCount = 0;
for (auto& mod : incompatibleMods) {
for (const auto& dllName : mod.dllNames) {
if (GetModuleHandleA(dllName.c_str()) != nullptr) {
mod.detected = true;
if (!mod.shaderDefine.empty()) {
SetDefines(mod.shaderDefine);
}
detectedCount++;
break;
}
}
}
if (detectedCount > 0) {
logger::info("Detected {} incompatible mod(s)", detectedCount);
}
}

std::vector<std::string> State::GetDetectedIncompatibleMods() const
{
std::vector<std::string> detected;
for (const auto& mod : incompatibleMods) {
if (mod.detected) {
detected.push_back(mod.shaderDefine);
}
}
return detected;
}

bool State::HasIncompatibleModDefine(const std::string& define) const
{
for (const auto& mod : incompatibleMods) {
if (mod.detected && mod.shaderDefine == define) {
return true;
}
}
return false;
}

void State::LoadTheme()
{
// Don't override if a theme preset is already selected (e.g., first-time Default Dark setup)
Expand Down
53 changes: 53 additions & 0 deletions src/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ using json = nlohmann::json;
#include <Hooks.h>
#include <mutex>

/**
* @brief Represents an incompatible mod that requires conditional shader compilation.
*
* Detects problematic DLLs at startup and sets shader defines for conditional compilation.
* Configured via IncompatibleMods array in settings file.
*/
struct IncompatibleMod
{
/**
* @brief DLL filename(s) to detect (e.g., "BakaWorldMapSpeed.dll")
*/
std::vector<std::string> dllNames;

/**
* @brief Shader define to set when detected (e.g., "FWMF_DETECTED")
*/
std::string shaderDefine;

/**
* @brief Runtime flag indicating if this mod was detected
*/
bool detected = false;
};

class State
{
public:
Expand Down Expand Up @@ -93,6 +117,35 @@ class State
void SetDefines(std::string defines);
std::vector<std::pair<std::string, std::string>>* GetDefines();

/**
* @brief Detect incompatible mods from configuration and set shader defines.
*
* Scans for configured DLLs using GetModuleHandleA() and sets shader defines
* for conditional compilation. Shaders can check defines like FWMF_DETECTED to
* conditionally disable features.
*
* Called during plugin initialization in XSEPlugin.cpp.
*/
void DetectIncompatibleMods();

/**
* @brief Get list of all detected incompatible mods.
* @return Vector of detected mod shader defines (e.g., "FWMF_DETECTED")
*/
std::vector<std::string> GetDetectedIncompatibleMods() const;

/**
* @brief Check if a specific shader define is active from incompatible mod detection.
* @param define The define name to check (e.g., "FWMF_DETECTED")
* @return True if the define is active
*/
bool HasIncompatibleModDefine(const std::string& define) const;

/**
* @brief Incompatible mods configuration loaded from settings
*/
std::vector<IncompatibleMod> incompatibleMods;

/*
* Whether a_type is currently enabled in Community Shaders
*
Expand Down
11 changes: 11 additions & 0 deletions src/XSEPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ bool Load()
}
}

/**
* @brief Detect incompatible mods at startup using GetModuleHandleA().
*
* Checks for configured .dll files (e.g., Flat World Map Framework) and sets shader
* defines for conditional compilation. DLL names are read from IncompatibleMods array
* in CommunityShaders.json (prepopulated in default config, user-extensible).
*
* Each detected mod can trigger shader defines and optionally disable specific features.
*/
globals::state->DetectIncompatibleMods();

if (errors.empty()) {
Hooks::InstallEarlyHooks();
logger::info("Calling feature Load methods");
Expand Down
Loading