using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("LaptopMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+82fe86414d94329a4ef0691cf8cb323e2592e157")]
[assembly: AssemblyProduct("LaptopMode")]
[assembly: AssemblyTitle("LaptopMode")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace LaptopMode
{
internal static class Engine
{
private static readonly Dictionary<string, object> orig = new Dictionary<string, object>();
private static readonly Dictionary<VolumeComponent, bool> volumeOrig = new Dictionary<VolumeComponent, bool>();
private static readonly Dictionary<UniversalAdditionalCameraData, AntialiasingMode> aaOrig = new Dictionary<UniversalAdditionalCameraData, AntialiasingMode>();
private static readonly Camera[] camBuf = (Camera[])(object)new Camera[32];
private static bool? decoApplied;
private static bool inGameShadowCall;
internal static Preset Current;
internal static bool GameSettingsSeen;
private static UniversalRenderPipelineAsset Urp
{
get
{
try
{
if ((Object)(object)GameInfo.UrpAsset != (Object)null)
{
return GameInfo.UrpAsset;
}
}
catch
{
}
RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
return (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
}
}
internal static float OriginalRenderScale
{
get
{
if (!orig.TryGetValue("renderScale", out var value))
{
return 1f;
}
return (float)value;
}
}
internal static float RenderScaleNow
{
get
{
if (!((Object)(object)Urp != (Object)null))
{
return -1f;
}
return Urp.renderScale;
}
}
internal static int ShadowmapResNow
{
get
{
if (!((Object)(object)Urp != (Object)null))
{
return -1;
}
return Urp.mainLightShadowmapResolution;
}
}
private static int GameShadowQuality => PlayerPrefs.GetInt("ShadowQuality", 2);
private static T Orig<T>(string key, T now)
{
if (!orig.TryGetValue(key, out var value))
{
orig[key] = now;
return now;
}
return (T)value;
}
private static void Set<T>(string key, T now, T? want, Action<T> set) where T : struct
{
T val = Orig(key, now);
T val2 = want ?? val;
if (!EqualityComparer<T>.Default.Equals(now, val2))
{
set(val2);
}
}
internal static void Apply(Preset p)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
Current = p;
UniversalRenderPipelineAsset urp = Urp;
if ((Object)(object)urp != (Object)null)
{
Set("renderScale", urp.renderScale, p.RenderScale, delegate(float v)
{
urp.renderScale = v;
});
UpscalingFilterSelection? want = ((p.Upscaling == null) ? ((UpscalingFilterSelection?)null) : new UpscalingFilterSelection?((UpscalingFilterSelection)Enum.Parse(typeof(UpscalingFilterSelection), p.Upscaling)));
Set<UpscalingFilterSelection>("upscaling", urp.upscalingFilter, want, (Action<UpscalingFilterSelection>)delegate(UpscalingFilterSelection v)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
urp.upscalingFilter = v;
});
Set("fsrOverride", urp.fsrOverrideSharpness, p.FsrSharpness.HasValue ? new bool?(true) : ((bool?)null), delegate(bool v)
{
urp.fsrOverrideSharpness = v;
});
Set("fsrSharpness", urp.fsrSharpness, p.FsrSharpness, delegate(float v)
{
urp.fsrSharpness = v;
});
Set("msaa", urp.msaaSampleCount, p.Msaa, delegate(int v)
{
urp.msaaSampleCount = v;
});
Set("hdr", urp.supportsHDR, p.Hdr, delegate(bool v)
{
urp.supportsHDR = v;
});
Set("maxAddLights", urp.maxAdditionalLightsCount, p.MaxAddLights.HasValue ? new int?(Math.Min(p.MaxAddLights.Value, Orig("maxAddLights", urp.maxAdditionalLightsCount))) : ((int?)null), delegate(int v)
{
urp.maxAdditionalLightsCount = v;
});
Set("shadowDistance", urp.shadowDistance, p.ShadowDistance.HasValue ? new float?(Math.Min(p.ShadowDistance.Value, Orig("shadowDistance", urp.shadowDistance))) : ((float?)null), delegate(float v)
{
urp.shadowDistance = v;
});
ApplyShadows(urp, p);
ApplySsao(urp, p);
}
Set("lodBias", QualitySettings.lodBias, p.LodBias, delegate(float v)
{
QualitySettings.lodBias = v;
});
Set("maxLodLevel", QualitySettings.maximumLODLevel, p.MaxLodLevel, delegate(int v)
{
QualitySettings.maximumLODLevel = v;
});
Set("textureMipLimit", QualitySettings.globalTextureMipmapLimit, p.TextureMipLimit, delegate(int v)
{
QualitySettings.globalTextureMipmapLimit = v;
});
Set<AnisotropicFiltering>("anisotropic", QualitySettings.anisotropicFiltering, (p.Anisotropic == false) ? new AnisotropicFiltering?((AnisotropicFiltering)0) : ((AnisotropicFiltering?)null), (Action<AnisotropicFiltering>)delegate(AnisotropicFiltering v)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
QualitySettings.anisotropicFiltering = v;
});
Set("softParticles", QualitySettings.softParticles, p.SoftParticles, delegate(bool v)
{
QualitySettings.softParticles = v;
});
Set("reflectionProbes", QualitySettings.realtimeReflectionProbes, p.ReflectionProbes, delegate(bool v)
{
QualitySettings.realtimeReflectionProbes = v;
});
Resolution currentResolution = Screen.currentResolution;
RefreshRate refreshRateRatio = ((Resolution)(ref currentResolution)).refreshRateRatio;
int num = PlayerPrefs.GetInt("MaxFPS", (int)((RefreshRate)(ref refreshRateRatio)).value);
int num2 = ((p.FpsCap.HasValue && (num <= 0 || num > p.FpsCap.Value)) ? p.FpsCap.Value : num);
if (Application.targetFrameRate != num2)
{
Application.targetFrameRate = num2;
}
bool flag = p.Decorations ?? (PlayerPrefs.GetInt("Decorations", 1) == 1);
if (decoApplied != flag)
{
try
{
DecorationManager.ToggleLevelDecorations(flag);
decoApplied = flag;
}
catch
{
}
}
ApplyVolumes(p);
ApplyCameras(p);
}
private static void ApplyShadows(UniversalRenderPipelineAsset urp, Preset p)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
if (!p.Shadows.HasValue)
{
if (orig.ContainsKey("shadowsTouched"))
{
orig.Remove("shadowsTouched");
CallGameShadowQuality();
}
return;
}
if (p.Shadows == false)
{
orig["shadowsTouched"] = true;
if ((int)QualitySettings.shadows != 0)
{
QualitySettings.shadows = (ShadowQuality)0;
}
try
{
Light mainLight = GameInfo.MainLight;
if ((Object)(object)mainLight != (Object)null && (int)mainLight.shadows != 0)
{
mainLight.shadows = (LightShadows)0;
}
return;
}
catch
{
return;
}
}
if (GameShadowQuality == 0)
{
return;
}
orig["shadowsTouched"] = true;
if ((int)QualitySettings.shadows == 0)
{
QualitySettings.shadows = (ShadowQuality)2;
}
try
{
Light mainLight2 = GameInfo.MainLight;
if ((Object)(object)mainLight2 != (Object)null && (int)mainLight2.shadows == 0)
{
mainLight2.shadows = (LightShadows)2;
}
}
catch
{
}
int num = ((GameShadowQuality == 1) ? 1024 : 8192);
int num2 = ((GameShadowQuality == 1) ? 1 : 4);
int num3 = (p.ShadowCascades.HasValue ? Math.Min(num2, p.ShadowCascades.Value) : num2);
int num4 = (p.ShadowmapRes.HasValue ? Math.Min(num, p.ShadowmapRes.Value) : num);
if (urp.shadowCascadeCount != num3)
{
urp.shadowCascadeCount = num3;
}
if (urp.mainLightShadowmapResolution != num4)
{
urp.mainLightShadowmapResolution = num4;
}
}
private static void CallGameShadowQuality()
{
try
{
object? obj = typeof(ButtonManager).GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);
ButtonManager val = (ButtonManager)((obj is ButtonManager) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
inGameShadowCall = true;
val.ChangeShadowQuality(0);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("restore shadows: " + ex.Message));
}
finally
{
inGameShadowCall = false;
}
}
private static void ApplySsao(UniversalRenderPipelineAsset urp, Preset p)
{
try
{
if (!(typeof(UniversalRenderPipelineAsset).GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(urp) is ScriptableRendererData[] array) || array.Length == 0 || (Object)(object)array[0] == (Object)null)
{
return;
}
foreach (ScriptableRendererFeature rendererFeature in array[0].rendererFeatures)
{
ScreenSpaceAmbientOcclusion val = (ScreenSpaceAmbientOcclusion)(object)((rendererFeature is ScreenSpaceAmbientOcclusion) ? rendererFeature : null);
if (val != null)
{
bool flag = p.Ssao ?? (PlayerPrefs.GetInt("AmbientOcclusion", 1) == 1);
if (((ScriptableRendererFeature)val).isActive != flag)
{
((ScriptableRendererFeature)val).SetActive(flag);
}
break;
}
}
}
catch
{
}
}
private static void ApplyVolumes(Preset p)
{
string[] postFxOff = p.PostFxOff;
Volume[] array = Object.FindObjectsByType<Volume>();
for (int i = 0; i < array.Length; i++)
{
VolumeProfile sharedProfile = array[i].sharedProfile;
if ((Object)(object)sharedProfile == (Object)null)
{
continue;
}
foreach (VolumeComponent component in sharedProfile.components)
{
if ((Object)(object)component == (Object)null)
{
continue;
}
bool value;
if (postFxOff != null && Array.IndexOf(postFxOff, ((object)component).GetType().Name) >= 0)
{
if (!volumeOrig.ContainsKey(component))
{
volumeOrig[component] = component.active;
}
if (component.active)
{
component.active = false;
}
}
else if (volumeOrig.TryGetValue(component, out value) && component.active != value)
{
component.active = value;
}
}
}
}
private static void ApplyCameras(Preset p)
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Invalid comparison between Unknown and I4
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
int allCameras = Camera.GetAllCameras(camBuf);
UniversalAdditionalCameraData val2 = default(UniversalAdditionalCameraData);
for (int i = 0; i < allCameras; i++)
{
Camera val = camBuf[i];
camBuf[i] = null;
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.targetTexture != (Object)null) && ((Component)val).TryGetComponent<UniversalAdditionalCameraData>(ref val2))
{
if (!aaOrig.ContainsKey(val2))
{
aaOrig[val2] = val2.antialiasing;
}
AntialiasingMode val3 = aaOrig[val2];
if (p.CameraAA == "None")
{
val3 = (AntialiasingMode)0;
}
else if (p.CameraAA == "FXAA" && (int)val3 > 1)
{
val3 = (AntialiasingMode)1;
}
if (val2.antialiasing != val3)
{
val2.antialiasing = val3;
}
}
}
}
internal static void AfterGameSettingsChanged(string what)
{
GameSettingsSeen = true;
if (!inGameShadowCall && Current != null)
{
if (what == "decorations")
{
decoApplied = null;
}
Apply(Current);
}
}
internal static string Describe(Preset p)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
UniversalRenderPipelineAsset urp = Urp;
if (!((Object)(object)urp == (Object)null))
{
return string.Format("{0}: scale {1:0.00} {2}, shadows {3}, lodBias {4:0.0}, fps cap {5}", p.Label, urp.renderScale, urp.upscalingFilter, ((int)QualitySettings.shadows == 0) ? "off" : (urp.mainLightShadowmapResolution + "px x" + urp.shadowCascadeCount), QualitySettings.lodBias, Application.targetFrameRate);
}
return p.Label;
}
}
[BepInPlugin("LaptopMode.HowToFish", "Laptop Mode", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "LaptopMode.HowToFish";
public const string Version = "1.0.0";
internal static ManualLogSource Log;
internal static ConfigEntry<string> PresetCfg;
internal static ConfigEntry<KeyCode> CycleKey;
internal static ConfigEntry<KeyCode> FpsKey;
internal static ConfigEntry<bool> ShowFps;
private void Awake()
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
PresetCfg = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Preset", "balanced", "Active preset: balanced, potato or off. F8 changes it in game.");
CycleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "CyclePreset", (KeyCode)289, "Cycle Balanced -> Potato -> Off.");
FpsKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "ToggleFps", (KeyCode)290, "Show or hide the FPS counter.");
ShowFps = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowFps", true, "Show a small FPS counter in the top-left corner.");
new Harmony("LaptopMode.HowToFish").PatchAll(typeof(GameHooks));
GameObject val = new GameObject("LaptopMode")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<Runner>();
Log.LogInfo((object)"Laptop Mode 1.0.0 loaded");
}
}
[HarmonyPatch]
internal static class GameHooks
{
[HarmonyPostfix]
[HarmonyPatch(typeof(ButtonManager), "ChangeShadowQuality")]
private static void Shadow()
{
Engine.AfterGameSettingsChanged("shadows");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ButtonManager), "AmbientOcclusionToggle")]
private static void Ao()
{
Engine.AfterGameSettingsChanged("ssao");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ButtonManager), "MaxFPSSliderChange")]
private static void Fps()
{
Engine.AfterGameSettingsChanged("fps");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ButtonManager), "MaxFPSInputFieldChange")]
private static void FpsField()
{
Engine.AfterGameSettingsChanged("fps");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ButtonManager), "DecorationsToggle")]
private static void Deco()
{
Engine.AfterGameSettingsChanged("decorations");
}
}
internal class Runner : MonoBehaviour
{
private int index;
private float nextWatch;
private float fpsWindowStart;
private float bannerUntil;
private float sumFps;
private int frames;
private int fpsSamples;
private int logSamples;
private float logSum;
private float nextLog = 30f;
private string fpsText = "";
private string banner = "";
private GUIStyle style;
private GUIStyle bannerStyle;
internal bool testing;
internal int Index => index;
internal float AverageFps
{
get
{
if (fpsSamples != 0)
{
return sumFps / (float)fpsSamples;
}
return 0f;
}
}
private unsafe static bool Pressed(KeyCode k)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(k))
{
return true;
}
try
{
Keyboard current = Keyboard.current;
if (current != null && Enum.TryParse<Key>(((object)(*(KeyCode*)(&k))/*cast due to .constrained prefix*/).ToString(), out Key result) && (int)result != 0)
{
return ((ButtonControl)current[result]).wasPressedThisFrame;
}
}
catch
{
}
return false;
}
private void Start()
{
index = Math.Max(0, Array.FindIndex(Presets.All, (Preset x) => x.Id == Plugin.PresetCfg.Value));
SceneManager.sceneLoaded += delegate
{
Engine.Apply(Presets.All[index]);
};
Engine.Apply(Presets.All[index]);
Plugin.Log.LogInfo((object)("applied " + Engine.Describe(Presets.All[index])));
fpsWindowStart = Time.unscaledTime;
}
internal void Select(int i, bool save)
{
index = (i + Presets.All.Length) % Presets.All.Length;
if (save)
{
Plugin.PresetCfg.Value = Presets.All[index].Id;
}
Engine.Apply(Presets.All[index]);
banner = "Laptop Mode: " + Presets.All[index].Label;
bannerUntil = Time.unscaledTime + 2.5f;
Plugin.Log.LogInfo((object)("applied " + Engine.Describe(Presets.All[index])));
}
private void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if (Pressed(Plugin.CycleKey.Value))
{
Select(index + 1, !testing);
}
if (Pressed(Plugin.FpsKey.Value))
{
Plugin.ShowFps.Value = !Plugin.ShowFps.Value;
}
frames++;
float unscaledTime = Time.unscaledTime;
float num = unscaledTime - fpsWindowStart;
if (num >= 0.5f)
{
float num2 = (float)frames / num;
fpsText = Mathf.RoundToInt(num2) + " FPS";
sumFps += num2;
fpsSamples++;
frames = 0;
fpsWindowStart = unscaledTime;
logSum += num2;
logSamples++;
}
if (unscaledTime >= nextLog)
{
if (logSamples > 0)
{
Plugin.Log.LogInfo((object)("fps avg " + (logSum / (float)logSamples).ToString("0.0") + " over 30 s (" + Presets.All[index].Id + ")"));
}
logSum = 0f;
logSamples = 0;
nextLog = unscaledTime + 30f;
}
if (unscaledTime >= nextWatch)
{
nextWatch = unscaledTime + 2f;
Engine.Apply(Presets.All[index]);
}
}
private void OnGUI()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
if (style == null)
{
style = new GUIStyle(GUI.skin.label)
{
fontSize = 16,
fontStyle = (FontStyle)1,
alignment = (TextAnchor)2
};
style.normal.textColor = Color.white;
bannerStyle = new GUIStyle(style)
{
fontSize = 22,
alignment = (TextAnchor)1
};
}
if (Plugin.ShowFps.Value)
{
GUI.color = new Color(0f, 0f, 0f, 0.6f);
GUI.Label(new Rect((float)(Screen.width - 111), 7f, 100f, 24f), fpsText, style);
GUI.color = Color.white;
GUI.Label(new Rect((float)(Screen.width - 112), 6f, 100f, 24f), fpsText, style);
}
if (Time.unscaledTime < bannerUntil)
{
Rect val = default(Rect);
((Rect)(ref val))..ctor(0f, (float)Screen.height * 0.12f, (float)Screen.width, 32f);
GUI.color = new Color(0f, 0f, 0f, 0.6f);
GUI.Label(new Rect(((Rect)(ref val)).x + 1f, ((Rect)(ref val)).y + 1f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), banner, bannerStyle);
GUI.color = Color.white;
GUI.Label(val, banner, bannerStyle);
}
}
}
public sealed class Preset
{
public string Id;
public string Label;
public float? RenderScale;
public string Upscaling;
public float? FsrSharpness;
public int? Msaa;
public bool? Hdr;
public bool? Shadows;
public float? ShadowDistance;
public int? ShadowCascades;
public int? ShadowmapRes;
public int? MaxAddLights;
public bool? Ssao;
public string[] PostFxOff;
public string CameraAA;
public float? LodBias;
public int? MaxLodLevel;
public int? TextureMipLimit;
public bool? Anisotropic;
public bool? SoftParticles;
public bool? ReflectionProbes;
public bool? Decorations;
public int? FpsCap;
}
public static class Presets
{
public static readonly Preset[] All = new Preset[3]
{
new Preset
{
Id = "balanced",
Label = "Balanced",
RenderScale = 0.75f,
Upscaling = "FSR",
FsrSharpness = 0.85f,
Msaa = 1,
Hdr = null,
Shadows = true,
ShadowDistance = 45f,
ShadowCascades = 1,
ShadowmapRes = 1024,
MaxAddLights = 4,
Ssao = false,
PostFxOff = new string[8] { "Bloom", "MotionBlur", "DepthOfField", "ChromaticAberration", "FilmGrain", "LensDistortion", "PaniniProjection", "ScreenSpaceLensFlare" },
CameraAA = "FXAA",
LodBias = 0.7f,
MaxLodLevel = 0,
TextureMipLimit = 0,
Anisotropic = false,
SoftParticles = false,
ReflectionProbes = false,
Decorations = null,
FpsCap = 60
},
new Preset
{
Id = "potato",
Label = "Potato",
RenderScale = 0.5f,
Upscaling = "Linear",
FsrSharpness = null,
Msaa = 1,
Hdr = false,
Shadows = false,
ShadowDistance = 20f,
ShadowCascades = 1,
ShadowmapRes = 512,
MaxAddLights = 1,
Ssao = false,
PostFxOff = new string[9] { "Bloom", "MotionBlur", "DepthOfField", "ChromaticAberration", "FilmGrain", "LensDistortion", "PaniniProjection", "ScreenSpaceLensFlare", "Vignette" },
CameraAA = "None",
LodBias = 0.4f,
MaxLodLevel = 1,
TextureMipLimit = 1,
Anisotropic = false,
SoftParticles = false,
ReflectionProbes = false,
Decorations = false,
FpsCap = 60
},
new Preset
{
Id = "off",
Label = "Off (game's own settings)",
RenderScale = null,
Upscaling = null,
FsrSharpness = null,
Msaa = null,
Hdr = null,
Shadows = null,
ShadowDistance = null,
ShadowCascades = null,
ShadowmapRes = null,
MaxAddLights = null,
Ssao = null,
PostFxOff = null,
CameraAA = null,
LodBias = null,
MaxLodLevel = null,
TextureMipLimit = null,
Anisotropic = null,
SoftParticles = null,
ReflectionProbes = null,
Decorations = null,
FpsCap = null
}
};
}
}