using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using MenuLib.MonoBehaviors; using Microsoft.CodeAnalysis; using REPOFidelity.Patches; using REPOFidelity.Shaders; using REPOFidelity.Upscalers; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.PostProcessing; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.XR; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Vippy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.7.7.0")] [assembly: AssemblyInformationalVersion("1.7.7+5818939011e81a6f3ed0365702faeca1d638ce3b")] [assembly: AssemblyProduct("REPOFidelity")] [assembly: AssemblyTitle("REPOFidelity")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.7.7.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 REPOFidelity { internal static class BuildInfo { public const string Version = "1.7.7"; } internal enum PerfMode { Auto = -1, Keep, Disable } internal static class ConfigIntegration { private static bool _syncing; private static readonly List _refreshers = new List(); internal static void Initialize(ConfigFile cfg) { BindInt(cfg, "Display", "Vertical FOV", 0, 110, () => Settings.VerticalFovOverride, delegate(int v) { Settings.VerticalFovOverride = v; }, "0 = game default. Vertical FOV; horizontal expands with aspect."); BindBool(cfg, "Display", "Ultra-Wide UI Fix", () => Settings.UltrawideUiFix, delegate(bool v) { Settings.UltrawideUiFix = v; }); BindBool(cfg, "Display", "Ultra-Wide HUD Unstretch", () => Settings.UltrawideHudUnstretch, delegate(bool v) { Settings.UltrawideHudUnstretch = v; }); BindEnum(cfg, "Quality", "Quality Preset", () => Settings.Preset, delegate(QualityPreset v) { Settings.Preset = v; }); BindEnum(cfg, "Upscaling", "Upscaler", () => Settings.UpscaleModeSetting, delegate(UpscaleMode v) { Settings.UpscaleModeSetting = v; }); BindInt(cfg, "Upscaling", "Render Scale", 33, 100, () => Settings.RenderScale, delegate(int v) { Settings.RenderScale = v; }); BindFloat(cfg, "Upscaling", "Sharpening", 0f, 1f, () => Settings.Sharpening, delegate(float v) { Settings.Sharpening = v; }); BindEnum(cfg, "Upscaling", "Anti-Aliasing", () => Settings.AntiAliasingMode, delegate(AAMode v) { Settings.AntiAliasingMode = v; }); BindEnum(cfg, "Shadows & Lighting", "Shadow Quality", () => Settings.ShadowQualitySetting, delegate(ShadowQuality v) { Settings.ShadowQualitySetting = v; }); BindFloat(cfg, "Shadows & Lighting", "Shadow Distance", 5f, 200f, () => Settings.ShadowDistance, delegate(float v) { Settings.ShadowDistance = v; }); BindInt(cfg, "Shadows & Lighting", "Shadow Limit", 0, 50, () => Settings.ResolvedShadowBudget, delegate(int v) { Settings.ShadowBudget = v; }, "0 = unlimited"); BindFloat(cfg, "Shadows & Lighting", "Light Distance", 10f, 100f, () => Settings.LightDistance, delegate(float v) { Settings.LightDistance = v; }); BindInt(cfg, "Shadows & Lighting", "Max Lights", 1, 16, () => Settings.PixelLightCount, delegate(int v) { Settings.PixelLightCount = v; }); BindEnum(cfg, "Textures & Detail", "Texture Quality", () => Settings.TextureQuality, delegate(TextureRes v) { Settings.TextureQuality = v; }); BindIntList(cfg, "Textures & Detail", "Texture Filtering", new int[5] { 0, 2, 4, 8, 16 }, () => Settings.AnisotropicFiltering, delegate(int v) { Settings.AnisotropicFiltering = v; }, "Anisotropic filtering"); BindFloat(cfg, "Textures & Detail", "Detail Distance", 0.5f, 4f, () => Settings.LODBias, delegate(float v) { Settings.LODBias = v; }, "LOD bias"); BindFloat(cfg, "Environment", "Fog Distance", 0.3f, 1.1f, () => Settings.FogDistanceMultiplier, delegate(float v) { Settings.FogDistanceMultiplier = v; }, "1.0 = vanilla; lower pulls fog closer"); BindFloat(cfg, "Environment", "Draw Distance", 0f, 500f, () => Settings.ViewDistance, delegate(float v) { Settings.ViewDistance = v; }, "0 = auto. Camera far clip in meters."); BindBool(cfg, "Post Processing", "Motion Blur", () => Settings.MotionBlurOverride, delegate(bool v) { Settings.MotionBlurOverride = v; }); BindBool(cfg, "Post Processing", "Chromatic Aberration", () => Settings.ChromaticAberration, delegate(bool v) { Settings.ChromaticAberration = v; }); BindBool(cfg, "Post Processing", "Lens Distortion", () => Settings.LensDistortion, delegate(bool v) { Settings.LensDistortion = v; }); BindBool(cfg, "Post Processing", "Film Grain", () => Settings.FilmGrain, delegate(bool v) { Settings.FilmGrain = v; }); BindBool(cfg, "Post Processing", "Pixelation", () => Settings.Pixelation, delegate(bool v) { Settings.Pixelation = v; }); BindPerf(cfg, "Performance", "Explosion Shadows", () => Settings.PerfExplosionShadows, delegate(int v) { Settings.PerfExplosionShadows = v; }); BindPerf(cfg, "Performance", "Item Light Shadows", () => Settings.PerfItemLightShadows, delegate(int v) { Settings.PerfItemLightShadows = v; }); BindPerf(cfg, "Performance", "Animated Light Shadows", () => Settings.PerfAnimatedLightShadows, delegate(int v) { Settings.PerfAnimatedLightShadows = v; }); BindPerf(cfg, "Performance", "Particle Shadows", () => Settings.PerfParticleShadows, delegate(int v) { Settings.PerfParticleShadows = v; }); BindPerf(cfg, "Performance", "Small Object Shadows", () => Settings.PerfTinyRendererCulling, delegate(int v) { Settings.PerfTinyRendererCulling = v; }); BindPerf(cfg, "Performance", "Point Light Shadows", () => Settings.PerfPointLightShadows, delegate(int v) { Settings.PerfPointLightShadows = v; }); BindBool(cfg, "Misc", "Fix Extraction Flicker", () => Settings.ExtractionPointFlicker, delegate(bool v) { Settings.ExtractionPointFlicker = v; }); BindBool(cfg, "Misc", "Debug Overlay", () => Settings.DebugOverlay, delegate(bool v) { Settings.DebugOverlay = v; }); BindKey(cfg, "Misc", "Mod Toggle Key", () => Settings.ToggleKey, delegate(KeyCode v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Settings.ToggleKey = v; }, "Disables mod for vanilla comparison"); BindEnum(cfg, "Misc", "F11 Target", () => Settings.F11TargetSetting, delegate(F11Target v) { Settings.F11TargetSetting = v; }); Refresh(); Settings.OnSettingsChanged += Refresh; } private static void Refresh() { _syncing = true; try { foreach (Action refresher in _refreshers) { refresher(); } } finally { _syncing = false; } } private static void BindBool(ConfigFile cfg, string section, string name, Func getter, Action setter, string desc = "") { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty())); e.SettingChanged += delegate { if (!_syncing) { setter(e.Value); } }; _refreshers.Add(delegate { e.Value = getter(); }); } private static void BindInt(ConfigFile cfg, string section, string name, int min, int max, Func getter, Action setter, string desc = "") { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)(object)new AcceptableValueRange(min, max), Array.Empty())); e.SettingChanged += delegate { if (!_syncing) { setter(e.Value); } }; _refreshers.Add(delegate { e.Value = getter(); }); } private static void BindFloat(ConfigFile cfg, string section, string name, float min, float max, Func getter, Action setter, string desc = "") { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)(object)new AcceptableValueRange(min, max), Array.Empty())); e.SettingChanged += delegate { if (!_syncing) { setter(e.Value); } }; _refreshers.Add(delegate { e.Value = getter(); }); } private static void BindEnum(ConfigFile cfg, string section, string name, Func getter, Action setter, string desc = "") where T : Enum { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty())); e.SettingChanged += delegate { if (!_syncing) { setter(e.Value); } }; _refreshers.Add(delegate { e.Value = getter(); }); } private static void BindKey(ConfigFile cfg, string section, string name, Func getter, Action setter, string desc = "") { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty())); e.SettingChanged += delegate { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!_syncing) { setter(e.Value); } }; _refreshers.Add(delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) e.Value = getter(); }); } private static void BindIntList(ConfigFile cfg, string section, string name, int[] values, Func getter, Action setter, string desc = "") { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)(object)new AcceptableValueList(values), Array.Empty())); e.SettingChanged += delegate { if (!_syncing) { setter(e.Value); } }; _refreshers.Add(delegate { e.Value = getter(); }); } private static void BindPerf(ConfigFile cfg, string section, string name, Func getter, Action setter, string desc = "") { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ConfigEntry e = cfg.Bind(section, name, (PerfMode)getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty())); e.SettingChanged += delegate { if (!_syncing) { setter((int)e.Value); } }; _refreshers.Add(delegate { e.Value = (PerfMode)getter(); }); } } internal static class DLSSDownloader { private const string DllName = "nvngx_dlss.dll"; private const int MinDllSize = 10000000; internal static string GetDllPath() { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "nvngx_dlss.dll"); } internal static bool EnsureAvailable() { string dllPath = GetDllPath(); int num; if (File.Exists(dllPath)) { num = ((new FileInfo(dllPath).Length >= 10000000) ? 1 : 0); if (num != 0) { Plugin.Log.LogDebug((object)$"DLSS DLL: {dllPath} ({new FileInfo(dllPath).Length / 1024 / 1024}MB)"); return (byte)num != 0; } } else { num = 0; } Plugin.Log.LogWarning((object)"nvngx_dlss.dll missing or invalid; DLSS/DLAA disabled. Reinstall the mod."); return (byte)num != 0; } } internal static class FrameTimeMeter { internal class Meter { public readonly string Name; public readonly string ShortName; private readonly float[] _samples; private int _index; private int _count; private float _sum; public float LastUs; public float AverageUs { get { if (_count <= 0) { return 0f; } return _sum / (float)_count; } } public float AverageMs => AverageUs / 1000f; public Meter(string name, string shortName, int windowSize = 120) { Name = name; ShortName = shortName; _samples = new float[windowSize]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Record(float microseconds) { LastUs = microseconds; _sum -= _samples[_index]; _samples[_index] = microseconds; _sum += microseconds; _index = (_index + 1) % _samples.Length; if (_count < _samples.Length) { _count++; } } } private static readonly Stopwatch _sw = Stopwatch.StartNew(); internal static readonly Meter EnemyDirector = new Meter("EnemyDirector Throttle", "EnemyDir"); internal static readonly Meter RoomVolumeCheck = new Meter("RoomVolume NonAlloc", "RoomVol"); internal static readonly Meter SemiFuncCache = new Meter("SemiFunc Cache", "SemiFunc"); internal static readonly Meter PhysGrabObjectFix = new Meter("PhysGrabObject Fix", "PhysGrab"); internal static readonly Meter LightManagerBatch = new Meter("LightManager Batch", "LightMgr"); internal static readonly Meter SceneApply = new Meter("SceneOptimizer Apply", "SceneApl"); internal static readonly Meter[] All = new Meter[6] { EnemyDirector, RoomVolumeCheck, SemiFuncCache, PhysGrabObjectFix, LightManagerBatch, SceneApply }; internal static bool Active { get { if (!Settings.DebugOverlay) { return OptimizerBenchmark.Running; } return true; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long Begin() { if (!Active) { return 0L; } return _sw.ElapsedTicks; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void End(Meter meter, long startTicks) { if (startTicks != 0L) { float microseconds = (float)((double)(_sw.ElapsedTicks - startTicks) / 10.0); meter.Record(microseconds); } } } internal enum GpuVendor { Nvidia, Amd, Intel, Apple, Unknown } internal enum GpuTier { High, Mid, Low } internal static class GPUDetector { private static readonly Regex ArcDiscretePattern = new Regex("\\b[AB]\\d{3}\\b", RegexOptions.Compiled); public static string GpuName { get; private set; } = "Unknown"; public static GpuVendor Vendor { get; private set; } = GpuVendor.Unknown; public static GpuTier Tier { get; private set; } = GpuTier.Low; public static bool DlssAvailable { get; private set; } public static int VramMb { get; private set; } public static bool IsD3D11 { get; private set; } public static bool IsIntegratedGpu { get; private set; } public static void Detect() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_00c4: Unknown result type (might be due to invalid IL or missing references) GpuName = SystemInfo.graphicsDeviceName ?? "Unknown"; VramMb = SystemInfo.graphicsMemorySize; Vendor = DetectVendor(GpuName, SystemInfo.graphicsDeviceVendor); Tier = DetectTier(VramMb); IsD3D11 = (int)SystemInfo.graphicsDeviceType == 2; IsIntegratedGpu = DetectIntegrated(GpuName, VramMb, Vendor); DlssAvailable = Vendor == GpuVendor.Nvidia && IsD3D11 && !IsIntegratedGpu && GpuName.ToUpperInvariant().Contains("RTX"); Plugin.Log.LogInfo((object)($"GPU: {GpuName} | Vendor: {Vendor} | VRAM: {VramMb}MB | " + $"API: {SystemInfo.graphicsDeviceType} | iGPU: {IsIntegratedGpu} | Tier: {Tier}")); } public static bool IsUpscalerSupported(UpscaleMode mode) { switch (mode) { case UpscaleMode.Auto: return true; case UpscaleMode.Off: return true; case UpscaleMode.DLAA: case UpscaleMode.DLSS: return DlssAvailable; case UpscaleMode.FSR_Temporal: return true; default: return false; } } public static string[] GetAvailableUpscalerNames() { List list = new List(); foreach (UpscaleMode value in Enum.GetValues(typeof(UpscaleMode))) { if (value != UpscaleMode.FSR && value != UpscaleMode.FSR4 && value != UpscaleMode.DLAA && IsUpscalerSupported(value)) { string item = ((value == UpscaleMode.FSR_Temporal) ? "FSR" : value.ToString()); list.Add(item); } } return list.ToArray(); } private static GpuVendor DetectVendor(string name, string vendorString) { string text = (name + " " + vendorString).ToUpperInvariant(); if (text.Contains("NVIDIA")) { return GpuVendor.Nvidia; } if (text.Contains("AMD") || text.Contains("ATI")) { return GpuVendor.Amd; } if (text.Contains("INTEL")) { return GpuVendor.Intel; } if (text.Contains("APPLE")) { return GpuVendor.Apple; } return GpuVendor.Unknown; } private static GpuTier DetectTier(int vramMb) { if (vramMb >= 8000) { return GpuTier.High; } if (vramMb >= 6000) { return GpuTier.Mid; } return GpuTier.Low; } private static bool DetectIntegrated(string name, int vramMb, GpuVendor vendor) { string text = name.ToUpperInvariant(); if (vendor == GpuVendor.Intel && (text.Contains("UHD") || text.Contains("IRIS") || text.Contains("HD GRAPHICS") || (text.Contains("ARC") && !ArcDiscretePattern.IsMatch(text)))) { return true; } if (vendor == GpuVendor.Amd && ((text.Contains("VEGA") && !text.Contains("VEGA 56") && !text.Contains("VEGA 64")) || (text.Contains("RADEON GRAPHICS") && !text.Contains("RX")))) { return true; } if (vramMb > 0 && vramMb < 2048) { return true; } return false; } } [HarmonyPatch] internal static class MenuIntegration { private class StatusTicker : MonoBehaviour { private float _t; private void Update() { _t += Time.unscaledDeltaTime; if (!(_t < 0.25f)) { _t = 0f; RefreshDynamicLabels(); } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ScrollViewBuilderDelegate <>9__72_0; public static Action <>9__72_1; public static Action <>9__72_42; public static Action <>9__72_2; public static Action <>9__72_3; public static Action <>9__72_43; public static Action <>9__72_4; public static Action <>9__72_5; public static Action <>9__72_44; public static Action <>9__72_6; public static Action <>9__72_7; public static Action <>9__72_8; public static Action <>9__72_9; public static Action <>9__72_10; public static Action <>9__72_11; public static Action <>9__72_12; public static Action <>9__72_13; public static Action <>9__72_14; public static Action <>9__72_15; public static Action <>9__72_16; public static Action <>9__72_17; public static Action <>9__72_18; public static Action <>9__72_19; public static Action <>9__72_20; public static Action <>9__72_21; public static Action <>9__72_22; public static Action <>9__72_23; public static Action <>9__72_24; public static Action <>9__72_25; public static Action <>9__72_26; public static Action <>9__72_27; public static Action <>9__72_28; public static Action <>9__72_66; public static Action <>9__72_29; public static Action <>9__72_67; public static Action <>9__72_30; public static Action <>9__72_31; public static Action <>9__72_32; public static Action <>9__72_33; public static Action <>9__72_34; public static Action <>9__72_35; public static Action <>9__72_36; public static Action <>9__72_37; public static Action <>9__72_38; public static Action <>9__72_39; public static Action <>9__72_40; public static Action <>9__72_41; internal RectTransform b__72_0(Transform sv) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) REPOLabel obj = MenuAPI.CreateREPOLabel("", sv, new Vector2(0f, 0f)); _statusText = ((Component)obj).GetComponentInChildren(); return ((REPOElement)obj).rectTransform; } internal void b__72_1() { Settings.Preset = QualityPreset.High; SyncAll(); } internal void b__72_2(string s) { GameSet((Setting)24, (s == "Windowed") ? 1 : 0, delegate { GraphicsManager.instance.UpdateWindowMode(true); }); } internal void b__72_42() { GraphicsManager.instance.UpdateWindowMode(true); } internal void b__72_3(string s) { if (!_syncing) { Settings.SetResolution(s); } } internal void b__72_4(bool b) { GameSet((Setting)12, b ? 1 : 0, delegate { GraphicsManager.instance.UpdateVsync(); }); } internal void b__72_43() { GraphicsManager.instance.UpdateVsync(); } internal void b__72_5(string s) { if (!_syncing) { int num = ((s == "Unlimited") ? (-1) : int.Parse(s)); DataDirector.instance.SettingValueSet((Setting)19, num); GraphicsManager.instance.UpdateMaxFPS(); DataDirector.instance.SaveSettings(); } } internal void b__72_6(int v) { GameSet((Setting)29, v, delegate { GraphicsManager.instance.UpdateGamma(); }); } internal void b__72_44() { GraphicsManager.instance.UpdateGamma(); } internal void b__72_7(int v) { ModSet(new <>c__DisplayClass72_1 { v = v }.b__45); } internal void b__72_8(bool b) { ModSet(new <>c__DisplayClass72_2 { b = b }.b__46); } internal void b__72_9(bool b) { ModSet(new <>c__DisplayClass72_3 { b = b }.b__47); } internal void b__72_10(string s) { if (!_syncing) { Settings.Preset = Enum.Parse(s); } } internal void b__72_11(string s) { ModSet(new <>c__DisplayClass72_4 { enumName = ((s == "FSR") ? "FSR_Temporal" : s) }.b__48); } internal void b__72_12(int v) { ModSet(new <>c__DisplayClass72_5 { v = v }.b__49); } internal void b__72_13(float v) { ModSet(new <>c__DisplayClass72_6 { v = v }.b__50); } internal void b__72_14(string s) { ModSet(new <>c__DisplayClass72_7 { s = s }.b__51); } internal void b__72_15(string s) { ModSet(new <>c__DisplayClass72_8 { s = s }.b__52); } internal void b__72_16(float v) { ModSet(new <>c__DisplayClass72_9 { v = v }.b__53); } internal void b__72_17(int v) { ModSet(new <>c__DisplayClass72_10 { v = v }.b__54); } internal void b__72_18(float v) { ModSet(new <>c__DisplayClass72_11 { v = v }.b__55); } internal void b__72_19(int v) { ModSet(new <>c__DisplayClass72_12 { v = v }.b__56); } internal void b__72_20(string s) { ModSet(new <>c__DisplayClass72_13 { s = s }.b__57); } internal void b__72_21(string s) { ModSet(new <>c__DisplayClass72_14 { s = s }.b__58); } internal void b__72_22(float v) { ModSet(new <>c__DisplayClass72_15 { v = v }.b__59); } internal void b__72_23(float v) { ModSet(new <>c__DisplayClass72_16 { v = v }.b__60); } internal void b__72_24(float v) { ModSet(new <>c__DisplayClass72_17 { v = v }.b__61); } internal void b__72_25(bool b) { ModSet(new <>c__DisplayClass72_18 { b = b }.b__62); } internal void b__72_26(bool b) { ModSet(new <>c__DisplayClass72_19 { b = b }.b__63); } internal void b__72_27(bool b) { ModSet(new <>c__DisplayClass72_20 { b = b }.b__64); } internal void b__72_28(bool b) { ModSet(new <>c__DisplayClass72_21 { b = b }.b__65); } internal void b__72_29(bool b) { GameSet((Setting)16, b ? 1 : 0, delegate { GraphicsManager.instance.UpdateBloom(); }); } internal void b__72_66() { GraphicsManager.instance.UpdateBloom(); } internal void b__72_30(bool b) { GameSet((Setting)26, b ? 1 : 0, delegate { GraphicsManager.instance.UpdateGlitchLoop(); }); } internal void b__72_67() { GraphicsManager.instance.UpdateGlitchLoop(); } internal void b__72_31(bool b) { ModSet(new <>c__DisplayClass72_22 { b = b }.b__68); } internal void b__72_32(bool b) { ModSet(new <>c__DisplayClass72_23 { b = b }.b__69); } internal void b__72_33() { if (_benchmarkQueued) { _benchmarkQueued = false; Settings.Preset = QualityPreset.High; RefreshDynamicLabels(); SyncAll(); return; } Settings.Preset = QualityPreset.Auto; if (SemiFunc.RunIsLevel()) { _page.ClosePage(false); if ((Object)(object)MenuManager.instance != (Object)null) { MenuManager.instance.PageCloseAllAddedOnTop(); } Settings.InvalidateAutoTune(); Settings.BenchmarkMode = true; } else { Settings.InvalidateAutoTune(); _benchmarkQueued = true; RefreshDynamicLabels(); } } internal void b__72_34(int v) { ModSet(new <>c__DisplayClass72_24 { v = v }.b__70); } internal void b__72_35(int v) { ModSet(new <>c__DisplayClass72_25 { v = v }.b__71); } internal void b__72_36(int v) { ModSet(new <>c__DisplayClass72_26 { v = v }.b__72); } internal void b__72_37(int v) { ModSet(new <>c__DisplayClass72_27 { v = v }.b__73); } internal void b__72_38(int v) { ModSet(new <>c__DisplayClass72_28 { v = v }.b__74); } internal void b__72_39(int v) { ModSet(new <>c__DisplayClass72_29 { v = v }.b__75); } internal void b__72_40(bool b) { ModSet(new <>c__DisplayClass72_30 { b = b }.b__76); } internal void b__72_41(bool b) { ModSet(new <>c__DisplayClass72_31 { b = b }.b__77); } } [CompilerGenerated] private sealed class <>c__DisplayClass72_1 { public int v; internal void b__45() { Settings.VerticalFovOverride = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_10 { public int v; internal void b__54() { Settings.ShadowBudget = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_11 { public float v; internal void b__55() { Settings.LightDistance = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_12 { public int v; internal void b__56() { Settings.PixelLightCount = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_13 { public string s; internal void b__57() { Settings.TextureQuality = TexValues[Array.IndexOf(TexOptions, s)]; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_14 { public string s; internal void b__58() { Settings.AnisotropicFiltering = AfValues[Array.IndexOf(AfOptions, s)]; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_15 { public float v; internal void b__59() { Settings.LODBias = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_16 { public float v; internal void b__60() { Settings.FogDistanceMultiplier = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_17 { public float v; internal void b__61() { Settings.ViewDistance = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_18 { public bool b; internal void b__62() { Settings.MotionBlurOverride = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_19 { public bool b; internal void b__63() { Settings.ChromaticAberration = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_2 { public bool b; internal void b__46() { Settings.UltrawideUiFix = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_20 { public bool b; internal void b__64() { Settings.LensDistortion = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_21 { public bool b; internal void b__65() { Settings.FilmGrain = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_22 { public bool b; internal void b__68() { Settings.Pixelation = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_23 { public bool b; internal void b__69() { Settings.SharpHud = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_24 { public int v; internal void b__70() { Settings.PerfExplosionShadows = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_25 { public int v; internal void b__71() { Settings.PerfItemLightShadows = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_26 { public int v; internal void b__72() { Settings.PerfAnimatedLightShadows = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_27 { public int v; internal void b__73() { Settings.PerfParticleShadows = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_28 { public int v; internal void b__74() { Settings.PerfTinyRendererCulling = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_29 { public int v; internal void b__75() { Settings.PerfPointLightShadows = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_3 { public bool b; internal void b__47() { Settings.UltrawideHudUnstretch = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_30 { public bool b; internal void b__76() { Settings.ExtractionPointFlicker = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_31 { public bool b; internal void b__77() { Settings.DebugOverlay = b; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_4 { public string enumName; internal void b__48() { Settings.UpscaleModeSetting = Enum.Parse(enumName); } } [CompilerGenerated] private sealed class <>c__DisplayClass72_5 { public int v; internal void b__49() { Settings.RenderScale = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_6 { public float v; internal void b__50() { Settings.Sharpening = v; } } [CompilerGenerated] private sealed class <>c__DisplayClass72_7 { public string s; internal void b__51() { Settings.AntiAliasingMode = Enum.Parse(s); } } [CompilerGenerated] private sealed class <>c__DisplayClass72_8 { public string s; internal void b__52() { Settings.ShadowQualitySetting = Enum.Parse(s); } } [CompilerGenerated] private sealed class <>c__DisplayClass72_9 { public float v; internal void b__53() { Settings.ShadowDistance = v; } } private static REPOPopupPage? _page; private static bool _initialized; private static bool _syncing; private static REPOSlider? _presetSlider; private static REPOSlider? _upscalerSlider; private static REPOSlider? _renderScaleSlider; private static REPOSlider? _sharpeningSlider; private static REPOSlider? _aaSlider; private static REPOToggle? _pixelationToggle; private static REPOSlider? _shadowQualitySlider; private static REPOSlider? _shadowDistanceSlider; private static REPOSlider? _shadowBudgetSlider; private static REPOSlider? _lodSlider; private static REPOSlider? _afSlider; private static REPOSlider? _lightsSlider; private static REPOSlider? _textureSlider; private static REPOSlider? _lightDistSlider; private static REPOSlider? _fogSlider; private static REPOSlider? _viewDistSlider; private static REPOToggle? _motionBlurToggle; private static REPOToggle? _caToggle; private static REPOToggle? _lensToggle; private static REPOToggle? _grainToggle; private static REPOToggle? _flickerToggle; private static REPOToggle? _overlayToggle; private static REPOToggle? _sharpHudToggle; private static REPOSlider? _windowModeSlider; private static REPOSlider? _resolutionSlider; private static REPOSlider? _fpsSlider; private static REPOSlider? _gammaSlider; private static REPOSlider? _fovSlider; private static REPOToggle? _ultrawideUiToggle; private static REPOToggle? _ultrawideHudToggle; private static REPOToggle? _vsyncToggle; private static REPOToggle? _bloomToggle; private static REPOToggle? _glitchToggle; private static REPOSlider? _perfExplosionSlider; private static REPOSlider? _perfItemLightSlider; private static REPOSlider? _perfAnimLightSlider; private static REPOSlider? _perfParticleSlider; private static REPOSlider? _perfTinySlider; private static REPOSlider? _perfPointLightSlider; private static Text? _statusText; private static Text? _autoTuneText; private static bool _benchmarkQueued; private static StatusTicker? _ticker; private static readonly string[] FpsOptions; private static readonly string[] PerfOptions; private static readonly int[] PerfValues; private static readonly string[] AfOptions; private static readonly int[] AfValues; private static readonly string[] TexOptions; private static readonly TextureRes[] TexValues; internal static bool IsGraphicsPageOpen { get; private set; } static MenuIntegration() { PerfOptions = new string[3] { "Auto", "Keep", "Disable" }; PerfValues = new int[3] { -1, 0, 1 }; AfOptions = new string[5] { "Off", "2x", "4x", "8x", "16x" }; AfValues = new int[5] { 0, 2, 4, 8, 16 }; TexOptions = new string[3] { "Quarter", "Half", "Full" }; TexValues = new TextureRes[3] { TextureRes.Quarter, TextureRes.Half, TextureRes.Full }; FpsOptions = new string[332]; for (int i = 0; i < 331; i++) { FpsOptions[i] = (30 + i).ToString(); } FpsOptions[331] = "Unlimited"; } internal static void Initialize() { _initialized = true; Settings.OnSettingsChanged += SyncModSettings; } [HarmonyPrefix] [HarmonyPatch(typeof(MenuPageSettings), "ButtonEventGraphics")] public static bool PrefixGraphics() { if (!_initialized) { return true; } MenuManager.instance.PageCloseAllAddedOnTop(); OpenPage(); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(MenuPageSettings), "ButtonEventAudio")] public static void PrefixAudio() { ClosePage(); } [HarmonyPrefix] [HarmonyPatch(typeof(MenuPageSettings), "ButtonEventGameplay")] public static void PrefixGameplay() { ClosePage(); } [HarmonyPrefix] [HarmonyPatch(typeof(MenuPageSettings), "ButtonEventControls")] public static void PrefixControls() { ClosePage(); } [HarmonyPrefix] [HarmonyPatch(typeof(MenuPageSettings), "ButtonEventBack")] public static void PrefixBack() { ClosePage(); } private static void ClosePage() { try { REPOPopupPage? page = _page; if (page != null) { page.ClosePage(true); } } catch { } StopTicker(); IsGraphicsPageOpen = false; } private static void OpenPage() { if ((Object)(object)_page == (Object)null) { CreatePage(); } _page.OpenPage(true); _page.menuPage.addedPageOnTop = true; SyncAll(); RefreshDynamicLabels(); StartTicker(); IsGraphicsPageOpen = true; } private static void StartTicker() { //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_001e: Expected O, but got Unknown if (!((Object)(object)_ticker != (Object)null)) { GameObject val = new GameObject("REPOFidelity_MenuStatus"); Object.DontDestroyOnLoad((Object)val); _ticker = val.AddComponent(); } } private static void StopTicker() { if (!((Object)(object)_ticker == (Object)null)) { Object.Destroy((Object)(object)((Component)_ticker).gameObject); _ticker = null; } } private static string BuildStatusLine() { int outputWidth = Settings.OutputWidth; int outputHeight = Settings.OutputHeight; int resolvedRenderScale = Settings.ResolvedRenderScale; int num = Mathf.Max(1, outputWidth * resolvedRenderScale / 100); int num2 = Mathf.Max(1, outputHeight * resolvedRenderScale / 100); string text = Settings.ResolvedUpscaleMode switch { UpscaleMode.DLAA => "DLAA", UpscaleMode.DLSS => "DLSS", UpscaleMode.FSR_Temporal => "FSR", UpscaleMode.Off => "native", _ => Settings.ResolvedUpscaleMode.ToString(), }; string text2 = ((resolvedRenderScale == 100) ? $"{outputWidth}×{outputHeight} {text}" : $"{outputWidth}×{outputHeight} → {num}×{num2} ({text} {resolvedRenderScale}%)"); float smoothFps = Overlay.SmoothFps; float smoothMs = Overlay.SmoothMs; string text3; if (!SemiFunc.RunIsLevel() || smoothFps < 1f) { text3 = "waiting for gameplay"; } else { string arg = (Settings.CpuBound ? "CPU-bound" : "GPU-bound"); text3 = $"{arg} • {smoothMs:F1} ms / {smoothFps:F0} fps"; } return text3 + " • " + text2; } private static string BuildAutoTuneLabel() { if (_benchmarkQueued) { return "AUTO-TUNE QUEUED (WILL RUN ON NEXT LEVEL)"; } if (SemiFunc.RunIsLevel()) { return "AUTO-TUNE BENCHMARK (15s)"; } return "AUTO-TUNE - WILL QUEUE (START A GAME)"; } private static void RefreshDynamicLabels() { if ((Object)(object)_statusText != (Object)null) { _statusText.text = " " + BuildStatusLine(); } if ((Object)(object)_autoTuneText != (Object)null) { _autoTuneText.text = BuildAutoTuneLabel(); } } private static void CreatePage() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0bd7: Unknown result type (might be due to invalid IL or missing references) _page = MenuAPI.CreateREPOPopupPage("Graphics", true, false, 2f, (Vector2?)new Vector2(0f, 0f)); REPOPopupPage? page = _page; object obj = <>c.<>9__72_0; if (obj == null) { ScrollViewBuilderDelegate val = delegate(Transform sv) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) REPOLabel obj2 = MenuAPI.CreateREPOLabel("", sv, new Vector2(0f, 0f)); _statusText = ((Component)obj2).GetComponentInChildren(); return ((REPOElement)obj2).rectTransform; }; <>c.<>9__72_0 = val; obj = (object)val; } page.AddElementToScrollView((ScrollViewBuilderDelegate)obj, 0f, 0f); AddButton("RESET TO DEFAULT SETTINGS", delegate { Settings.Preset = QualityPreset.High; SyncAll(); }); AddLabel("Display"); AddStringSlider("Window Mode", "", new string[2] { "Fullscreen", "Windowed" }, "Fullscreen", delegate(string s) { GameSet((Setting)24, (s == "Windowed") ? 1 : 0, delegate { GraphicsManager.instance.UpdateWindowMode(true); }); }, out _windowModeSlider); int currentIndex; string[] availableResolutions = Settings.GetAvailableResolutions(out currentIndex); AddStringSlider("Resolution", "", availableResolutions, availableResolutions[currentIndex], delegate(string s) { if (!_syncing) { Settings.SetResolution(s); } }, out _resolutionSlider); AddModToggle("VSync", def: false, delegate(bool b) { GameSet((Setting)12, b ? 1 : 0, delegate { GraphicsManager.instance.UpdateVsync(); }); }, out _vsyncToggle); int num = DataDirector.instance.SettingValueFetch((Setting)19); string def = ((num <= 0) ? "Unlimited" : Mathf.Clamp(num, 30, 360).ToString()); AddStringSlider("Max FPS", "", FpsOptions, def, delegate(string s) { if (!_syncing) { int num6 = ((s == "Unlimited") ? (-1) : int.Parse(s)); DataDirector.instance.SettingValueSet((Setting)19, num6); GraphicsManager.instance.UpdateMaxFPS(); DataDirector.instance.SaveSettings(); } }, out _fpsSlider); AddIntSlider("Gamma", "Brightness", 0, 100, 40, "", delegate(int v) { GameSet((Setting)29, v, delegate { GraphicsManager.instance.UpdateGamma(); }); }, out _gammaSlider); AddIntSlider("Vertical FOV (0 = game default)", "Higher = wider view; lower = zoomed in", 0, 110, Settings.VerticalFovOverride, "°", delegate(int v) { ModSet(delegate { Settings.VerticalFovOverride = v; }); }, out _fovSlider); AddModToggle("Ultra-Wide UI Fix", Settings.UltrawideUiFix, delegate(bool b) { ModSet(delegate { Settings.UltrawideUiFix = b; }); }, out _ultrawideUiToggle); AddModToggle("Ultra-Wide HUD Unstretch", Settings.UltrawideHudUnstretch, delegate(bool b) { ModSet(delegate { Settings.UltrawideHudUnstretch = b; }); }, out _ultrawideHudToggle); AddLabel("Quality"); string[] options = new string[7] { "Auto", "Potato", "Low", "Medium", "High", "Ultra", "Custom" }; AddStringSlider("Quality Preset", "Sets all options below", options, Settings.Preset.ToString(), delegate(string s) { if (!_syncing) { Settings.Preset = Enum.Parse(s); } }, out _presetSlider); AddLabel("Upscaling"); string[] availableUpscalerNames = GPUDetector.GetAvailableUpscalerNames(); string text = Settings.UpscaleModeSetting.ToString(); if (text == "DLAA") { text = "DLSS"; } if (text == "FSR_Temporal") { text = "FSR"; } if (Array.IndexOf(availableUpscalerNames, text) < 0) { text = "Auto"; } AddStringSlider("Upscaler", "DLSS at 100% = DLAA (native AA)", availableUpscalerNames, text, delegate(string s) { string enumName = ((s == "FSR") ? "FSR_Temporal" : s); ModSet(delegate { Settings.UpscaleModeSetting = Enum.Parse(enumName); }); }, out _upscalerSlider); AddIntSlider("Render Scale", "Resolution % before upscaling", 33, 100, Settings.RenderScale, "%", delegate(int v) { ModSet(delegate { Settings.RenderScale = v; }); }, out _renderScaleSlider); AddFloatSlider("Sharpening", "Post-upscale CAS", 0f, 1f, 2, Settings.Sharpening, "", delegate(float v) { ModSet(delegate { Settings.Sharpening = v; }); }, out _sharpeningSlider); string[] array = new string[4] { "Auto", "SMAA", "FXAA", "Off" }; string text2 = Settings.AntiAliasingMode.ToString(); if (Array.IndexOf(array, text2) < 0) { text2 = "Auto"; } AddStringSlider("Anti-Aliasing", "SMAA / FXAA", array, text2, delegate(string s) { ModSet(delegate { Settings.AntiAliasingMode = Enum.Parse(s); }); }, out _aaSlider); AddLabel("Shadows & Lighting"); AddStringSlider("Shadow Quality", "Shadow map resolution", Enum.GetNames(typeof(ShadowQuality)), Settings.ShadowQualitySetting.ToString(), delegate(string s) { ModSet(delegate { Settings.ShadowQualitySetting = Enum.Parse(s); }); }, out _shadowQualitySlider); AddFloatSlider("Shadow Distance", "", 5f, 200f, 0, Settings.ShadowDistance, "m", delegate(float v) { ModSet(delegate { Settings.ShadowDistance = v; }); }, out _shadowDistanceSlider); AddIntSlider("Shadow Limit (0 = unlimited)", "Caps nearby shadow-casting lights", 0, 50, Settings.ResolvedShadowBudget, "", delegate(int v) { ModSet(delegate { Settings.ShadowBudget = v; }); }, out _shadowBudgetSlider); AddFloatSlider("Light Distance", "", 10f, 100f, 0, Settings.LightDistance, "m", delegate(float v) { ModSet(delegate { Settings.LightDistance = v; }); }, out _lightDistSlider); AddIntSlider("Max Lights", "Per object", 1, 16, Settings.PixelLightCount, "", delegate(int v) { ModSet(delegate { Settings.PixelLightCount = v; }); }, out _lightsSlider); AddLabel("Textures & Detail"); int num2 = Array.IndexOf(TexValues, Settings.TextureQuality); if (num2 < 0) { num2 = 2; } AddStringSlider("Texture Quality", "", TexOptions, TexOptions[num2], delegate(string s) { ModSet(delegate { Settings.TextureQuality = TexValues[Array.IndexOf(TexOptions, s)]; }); }, out _textureSlider); int num3 = Array.IndexOf(AfValues, Settings.AnisotropicFiltering); if (num3 < 0) { num3 = 4; } AddStringSlider("Texture Filtering", "Anisotropic filtering", AfOptions, AfOptions[num3], delegate(string s) { ModSet(delegate { Settings.AnisotropicFiltering = AfValues[Array.IndexOf(AfOptions, s)]; }); }, out _afSlider); AddFloatSlider("Detail Distance", "LOD bias", 0.5f, 4f, 1, Settings.LODBias, "x", delegate(float v) { ModSet(delegate { Settings.LODBias = v; }); }, out _lodSlider); AddLabel("Environment"); AddFloatSlider("Fog Distance", "1.0 = vanilla; lower pulls fog closer for perf", 0.3f, 1.1f, 2, Settings.FogDistanceMultiplier, "x", delegate(float v) { ModSet(delegate { Settings.FogDistanceMultiplier = v; }); }, out _fogSlider); AddFloatSlider("Draw Distance (0 = auto)", "Camera far clip", 0f, 500f, 0, Settings.ViewDistance, "m", delegate(float v) { ModSet(delegate { Settings.ViewDistance = v; }); }, out _viewDistSlider); AddLabel("Post Processing"); AddModToggle("Motion Blur", Settings.MotionBlurOverride, delegate(bool b) { ModSet(delegate { Settings.MotionBlurOverride = b; }); }, out _motionBlurToggle); AddModToggle("Chromatic Aberration", Settings.ChromaticAberration, delegate(bool b) { ModSet(delegate { Settings.ChromaticAberration = b; }); }, out _caToggle); AddModToggle("Lens Distortion", Settings.LensDistortion, delegate(bool b) { ModSet(delegate { Settings.LensDistortion = b; }); }, out _lensToggle); AddModToggle("Film Grain", Settings.FilmGrain, delegate(bool b) { ModSet(delegate { Settings.FilmGrain = b; }); }, out _grainToggle); AddModToggle("Bloom", def: true, delegate(bool b) { GameSet((Setting)16, b ? 1 : 0, delegate { GraphicsManager.instance.UpdateBloom(); }); }, out _bloomToggle); AddModToggle("Glitch Loop", def: true, delegate(bool b) { GameSet((Setting)26, b ? 1 : 0, delegate { GraphicsManager.instance.UpdateGlitchLoop(); }); }, out _glitchToggle); AddModToggle("Pixelation (retro style)", Settings.Pixelation, delegate(bool b) { ModSet(delegate { Settings.Pixelation = b; }); }, out _pixelationToggle); AddModToggle("Sharp HUD", Settings.SharpHud, delegate(bool b) { ModSet(delegate { Settings.SharpHud = b; }); }, out _sharpHudToggle); AddLabel("Performance"); AddDynamicButton(BuildAutoTuneLabel(), delegate { if (_benchmarkQueued) { _benchmarkQueued = false; Settings.Preset = QualityPreset.High; RefreshDynamicLabels(); SyncAll(); } else { Settings.Preset = QualityPreset.Auto; if (SemiFunc.RunIsLevel()) { _page.ClosePage(false); if ((Object)(object)MenuManager.instance != (Object)null) { MenuManager.instance.PageCloseAllAddedOnTop(); } Settings.InvalidateAutoTune(); Settings.BenchmarkMode = true; } else { Settings.InvalidateAutoTune(); _benchmarkQueued = true; RefreshDynamicLabels(); } } }, out _autoTuneText); AddPerfSlider("Explosion Shadows", "Disable shadows on explosion lights", Settings.PerfExplosionShadows, delegate(int v) { ModSet(delegate { Settings.PerfExplosionShadows = v; }); }, out _perfExplosionSlider); AddPerfSlider("Item Light Shadows", "Disable shadows on handheld item lights", Settings.PerfItemLightShadows, delegate(int v) { ModSet(delegate { Settings.PerfItemLightShadows = v; }); }, out _perfItemLightSlider); AddPerfSlider("Animated Light Shadows", "Disable shadows on animated lights", Settings.PerfAnimatedLightShadows, delegate(int v) { ModSet(delegate { Settings.PerfAnimatedLightShadows = v; }); }, out _perfAnimLightSlider); AddPerfSlider("Particle Shadows", "Disable shadow casting on particles", Settings.PerfParticleShadows, delegate(int v) { ModSet(delegate { Settings.PerfParticleShadows = v; }); }, out _perfParticleSlider); AddPerfSlider("Small Object Shadows", "Disable shadows on tiny objects", Settings.PerfTinyRendererCulling, delegate(int v) { ModSet(delegate { Settings.PerfTinyRendererCulling = v; }); }, out _perfTinySlider); AddPerfSlider("Point Light Shadows", "Cull distant point-light shadows beyond fog", Settings.PerfPointLightShadows, delegate(int v) { ModSet(delegate { Settings.PerfPointLightShadows = v; }); }, out _perfPointLightSlider); AddModToggle("Fix Extraction Flicker", Settings.ExtractionPointFlicker, delegate(bool b) { ModSet(delegate { Settings.ExtractionPointFlicker = b; }); }, out _flickerToggle); AddModToggle("Debug Overlay", Settings.DebugOverlay, delegate(bool b) { ModSet(delegate { Settings.DebugOverlay = b; }); }, out _overlayToggle); string[] keyOpts = new string[6] { "F10", "F9", "F8", "F7", "F6", "F5" }; KeyCode[] array2 = new KeyCode[6]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); KeyCode[] keyVals = (KeyCode[])(object)array2; int num4 = Array.IndexOf(keyVals, Settings.ToggleKey); if (num4 < 0) { num4 = 0; } AddStringSlider("Mod Toggle Key", "Disables mod for vanilla comparison", keyOpts, keyOpts[num4], delegate(string s) { int num6 = Array.IndexOf(keyOpts, s); if (num6 >= 0) { Settings.ToggleKey = keyVals[num6]; } }, out REPOSlider r); string[] f11Opts = new string[2] { "Full Opt Layer", "CPU Patches" }; F11Target[] f11Vals = new F11Target[2] { F11Target.FullOptLayer, F11Target.CpuPatches }; int num5 = Array.IndexOf(f11Vals, Settings.F11TargetSetting); if (num5 < 0) { num5 = 0; } AddStringSlider("F11 Target", "Which feature F11 toggles for A/B", f11Opts, f11Opts[num5], delegate(string s) { int num6 = Array.IndexOf(f11Opts, s); if (num6 >= 0) { Settings.F11TargetSetting = f11Vals[num6]; } }, out r); } private static void ModSet(Action a) { if (!_syncing) { a(); } } private static void GameSet(Setting setting, int value, Action update) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!_syncing) { DataDirector.instance.SettingValueSet(setting, value); update(); DataDirector.instance.SaveSettings(); } } private static void AddLabel(string text) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown _page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform sv) => ((REPOElement)MenuAPI.CreateREPOLabel(text, sv, Vector2.zero)).rectTransform), 0f, 0f); } private static void AddButton(string text, Action onClick, float xOffset = 38f) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown _page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform sv) => ((REPOElement)MenuAPI.CreateREPOButton(text, onClick, sv, new Vector2(xOffset, 0f))).rectTransform), 0f, 0f); } private static void AddDynamicButton(string text, Action onClick, out Text? textOut, float xOffset = 38f) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown Text captured = null; _page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) REPOButton val = MenuAPI.CreateREPOButton(text, onClick, sv, new Vector2(xOffset, 0f)); captured = ((Component)val).GetComponentInChildren(); return ((REPOElement)val).rectTransform; }, 0f, 0f); textOut = captured; } private static void AddStringSlider(string text, string desc, string[] options, string def, Action cb, out REPOSlider? r) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown REPOSlider s = null; _page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) s = MenuAPI.CreateREPOSlider(text, desc, (Action)delegate(string v) { cb(v); }, sv, options, def, Vector2.zero, "", "", (BarBehavior)0); return ((REPOElement)s).rectTransform; }, 0f, 0f); r = s; } private static void AddIntSlider(string text, string desc, int min, int max, int def, string post, Action cb, out REPOSlider? r) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown REPOSlider s = null; _page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) s = MenuAPI.CreateREPOSlider(text, desc, (Action)delegate(int v) { cb(v); }, sv, Vector2.zero, min, max, def, "", post, (BarBehavior)0); return ((REPOElement)s).rectTransform; }, 0f, 0f); r = s; } private static void AddFloatSlider(string text, string desc, float min, float max, int prec, float def, string post, Action cb, out REPOSlider? r) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown REPOSlider s = null; _page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) s = MenuAPI.CreateREPOSlider(text, desc, (Action)delegate(float v) { cb(v); }, sv, Vector2.zero, min, max, prec, def, "", post, (BarBehavior)0); return ((REPOElement)s).rectTransform; }, 0f, 0f); r = s; } private static void AddPerfSlider(string text, string desc, int current, Action cb, out REPOSlider? r) { int num = Array.IndexOf(PerfValues, current); if (num < 0) { num = 0; } AddStringSlider(text, desc, PerfOptions, PerfOptions[num], delegate(string s) { int num2 = Array.IndexOf(PerfOptions, s); if (num2 >= 0) { cb(PerfValues[num2]); } }, out r); } private static void AddModToggle(string text, bool def, Action cb, out REPOToggle? r) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown REPOToggle t = null; _page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) t = MenuAPI.CreateREPOToggle(text, (Action)delegate(bool b) { cb(b); }, sv, Vector2.zero, "ON", "OFF", def); return ((REPOElement)t).rectTransform; }, 0f, 0f); r = t; } private static void SyncAll() { _syncing = true; try { SyncGame(); SyncMod(); } finally { _syncing = false; } } private static void SyncModSettings() { if ((Object)(object)_page == (Object)null) { return; } _syncing = true; try { SyncMod(); } finally { _syncing = false; } } private static void SyncGame() { int num = DataDirector.instance.SettingValueFetch((Setting)24); SetStr(_windowModeSlider, (num == 1) ? "Windowed" : "Fullscreen"); SetStr(_resolutionSlider, $"{Settings.OutputWidth}x{Settings.OutputHeight}"); REPOToggle? vsyncToggle = _vsyncToggle; if (vsyncToggle != null) { vsyncToggle.SetState(DataDirector.instance.SettingValueFetch((Setting)12) == 1, false); } int num2 = DataDirector.instance.SettingValueFetch((Setting)19); SetStr(_fpsSlider, (num2 <= 0) ? "Unlimited" : Mathf.Clamp(num2, 30, 360).ToString()); SetNum(_gammaSlider, DataDirector.instance.SettingValueFetch((Setting)29)); REPOToggle? bloomToggle = _bloomToggle; if (bloomToggle != null) { bloomToggle.SetState(DataDirector.instance.SettingValueFetch((Setting)16) == 1, false); } REPOToggle? glitchToggle = _glitchToggle; if (glitchToggle != null) { glitchToggle.SetState(DataDirector.instance.SettingValueFetch((Setting)26) == 1, false); } } private static void SyncMod() { SetStr(_presetSlider, Settings.Preset.ToString()); string text = Settings.UpscaleModeSetting.ToString(); if (text == "DLAA") { text = "DLSS"; } if (text == "FSR_Temporal") { text = "FSR"; } SetStr(_upscalerSlider, text); SetNum(_renderScaleSlider, Settings.ResolvedRenderScale); SetNum(_sharpeningSlider, Settings.Sharpening); string opt = ((Settings.AntiAliasingMode == AAMode.TAA) ? Settings.ResolvedAAMode.ToString() : Settings.AntiAliasingMode.ToString()); SetStr(_aaSlider, opt); REPOToggle? pixelationToggle = _pixelationToggle; if (pixelationToggle != null) { pixelationToggle.SetState(Settings.Pixelation, false); } SetStr(_shadowQualitySlider, Settings.ShadowQualitySetting.ToString()); SetNum(_shadowDistanceSlider, Settings.ShadowDistance); SetNum(_shadowBudgetSlider, Settings.ResolvedShadowBudget); SetNum(_lodSlider, Settings.LODBias); int num = Array.IndexOf(AfValues, Settings.AnisotropicFiltering); if (num >= 0) { SetStr(_afSlider, AfOptions[num]); } SetNum(_lightsSlider, Settings.PixelLightCount); int num2 = Array.IndexOf(TexValues, Settings.TextureQuality); if (num2 >= 0) { SetStr(_textureSlider, TexOptions[num2]); } SetNum(_lightDistSlider, Settings.LightDistance); SetNum(_fogSlider, Settings.FogDistanceMultiplier); SetNum(_viewDistSlider, Settings.ViewDistance); REPOToggle? motionBlurToggle = _motionBlurToggle; if (motionBlurToggle != null) { motionBlurToggle.SetState(Settings.MotionBlurOverride, false); } REPOToggle? caToggle = _caToggle; if (caToggle != null) { caToggle.SetState(Settings.ChromaticAberration, false); } REPOToggle? lensToggle = _lensToggle; if (lensToggle != null) { lensToggle.SetState(Settings.LensDistortion, false); } REPOToggle? grainToggle = _grainToggle; if (grainToggle != null) { grainToggle.SetState(Settings.FilmGrain, false); } REPOToggle? sharpHudToggle = _sharpHudToggle; if (sharpHudToggle != null) { sharpHudToggle.SetState(Settings.SharpHud, false); } REPOToggle? flickerToggle = _flickerToggle; if (flickerToggle != null) { flickerToggle.SetState(Settings.ExtractionPointFlicker, false); } REPOToggle? overlayToggle = _overlayToggle; if (overlayToggle != null) { overlayToggle.SetState(Settings.DebugOverlay, false); } SetNum(_fovSlider, Settings.VerticalFovOverride); REPOToggle? ultrawideUiToggle = _ultrawideUiToggle; if (ultrawideUiToggle != null) { ultrawideUiToggle.SetState(Settings.UltrawideUiFix, false); } REPOToggle? ultrawideHudToggle = _ultrawideHudToggle; if (ultrawideHudToggle != null) { ultrawideHudToggle.SetState(Settings.UltrawideHudUnstretch, false); } SyncPerf(_perfExplosionSlider, Settings.PerfExplosionShadows); SyncPerf(_perfItemLightSlider, Settings.PerfItemLightShadows); SyncPerf(_perfAnimLightSlider, Settings.PerfAnimatedLightShadows); SyncPerf(_perfParticleSlider, Settings.PerfParticleShadows); SyncPerf(_perfTinySlider, Settings.PerfTinyRendererCulling); SyncPerf(_perfPointLightSlider, Settings.PerfPointLightShadows); } private static void SyncPerf(REPOSlider? s, int value) { int num = Array.IndexOf(PerfValues, value); if (num >= 0) { SetStr(s, PerfOptions[num]); } } private static void SetNum(REPOSlider? s, float v) { if (s != null) { s.SetValue(v, false); } } private static void SetStr(REPOSlider? s, string opt) { if (((s != null) ? s.stringOptions : null) != null) { int num = Array.IndexOf(s.stringOptions, opt); if (num >= 0) { s.SetValue((float)num, false); } } } } internal class OptimizerBenchmark : MonoBehaviour { private class Result { public float AvgMs; public float AvgFps; public float P1Low; public readonly List Frames = new List(); public void Compute() { if (Frames.Count != 0) { float num = 0f; for (int i = 0; i < Frames.Count; i++) { num += Frames[i]; } AvgMs = num / (float)Frames.Count * 1000f; AvgFps = 1000f / AvgMs; Frames.Sort(); int num2 = Mathf.Max(1, Mathf.CeilToInt((float)Frames.Count * 0.01f)); float num3 = 0f; for (int num4 = Frames.Count - 1; num4 >= Frames.Count - num2; num4--) { num3 += Frames[num4]; } P1Low = 1f / (num3 / (float)num2); } } } private class Accum { private readonly List _all = new List(); public void Add(Result r) { _all.AddRange(r.Frames); } public Result Compute() { Result result = new Result(); result.Frames.AddRange(_all); result.Compute(); return result; } } internal static string Status = ""; internal static float Progress; private const float WarmupSeconds = 3f; private const float MeasureSeconds = 15f; private const int Passes = 2; private static bool _savedModEnabled; private static int _savedCpuMode; private float _benchStartTime; private float _benchExpectedDuration; internal static OptimizerBenchmark? Instance { get; private set; } internal static bool Running { get; private set; } private void Update() { if (Running && !(_benchExpectedDuration <= 0f)) { float num = Mathf.Clamp01((Time.unscaledTime - _benchStartTime) / _benchExpectedDuration); if (num > Progress) { Progress = num; } } } internal static void Launch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (!Running) { if ((Object)(object)Instance == (Object)null) { GameObject val = new GameObject("REPOFidelity_OptimizerBenchmark"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } ((MonoBehaviour)Instance).StartCoroutine(Instance.RunSafe()); } } internal static void Abort() { if (Running) { if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StopAllCoroutines(); } Restore(); Running = false; Status = "Aborted"; } } private static void Save() { _savedModEnabled = Settings.ModEnabled; _savedCpuMode = Settings.CpuPatchMode; } private static void Restore() { Settings.ModEnabled = _savedModEnabled; Settings.CpuPatchMode = _savedCpuMode; Settings.UpdateCpuGate(); } private static void ForceCpu(bool on) { Settings.CpuPatchMode = (on ? 1 : 0); Settings.UpdateCpuGate(); } private IEnumerator RunSafe() { IEnumerator inner = Run(); while (true) { bool flag; try { flag = inner.MoveNext(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Benchmark failed: {arg}"); Restore(); Running = false; Status = "ERROR"; break; } if (!flag) { break; } yield return inner.Current; } } private IEnumerator Run() { Running = true; Save(); Plugin.Log.LogInfo((object)$"=== FIDELITY BENCHMARK ({2}x {15f}s) ==="); Accum vanillaAccum = new Accum(); Accum gpuGcAccum = new Accum(); Accum allOnAccum = new Accum(); int totalPhases = 6; int phase = 0; _benchStartTime = Time.unscaledTime; _benchExpectedDuration = (float)totalPhases * 18f; for (int pass = 0; pass < 2; pass++) { string pl = $"Pass {pass + 1}/{2}"; Settings.ModEnabled = false; ForceCpu(on: false); SceneOptimizer.Apply(); Glitch(); Status = pl + ": Vanilla (mod OFF)"; Progress = (float)phase / (float)totalPhases; Plugin.Log.LogInfo((object)Status); yield return Settle(); Result r = new Result(); yield return Measure(r); vanillaAccum.Add(r); phase++; Settings.ModEnabled = true; ForceCpu(on: false); SceneOptimizer.Apply(); QualityPatch.ApplyQualitySettings(); Glitch(); Status = pl + ": GPU/GC only"; Progress = (float)phase / (float)totalPhases; Plugin.Log.LogInfo((object)Status); yield return Settle(); r = new Result(); yield return Measure(r); gpuGcAccum.Add(r); phase++; Settings.ModEnabled = true; ForceCpu(on: true); SceneOptimizer.Apply(); Glitch(); Status = pl + ": All ON"; Progress = (float)phase / (float)totalPhases; Plugin.Log.LogInfo((object)Status); yield return Settle(); r = new Result(); yield return Measure(r); allOnAccum.Add(r); phase++; } Restore(); SceneOptimizer.Apply(); if (Settings.ModEnabled) { QualityPatch.ApplyQualitySettings(); } Glitch(); Result vanilla = vanillaAccum.Compute(); Result gpuGc = gpuGcAccum.Compute(); Result allOn = allOnAccum.Compute(); string text = BuildReport(vanilla, gpuGc, allOn); string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "optimizer_benchmark.txt"); try { File.WriteAllText(path, text); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Report save failed: " + ex.Message)); } Plugin.Log.LogInfo((object)("\n" + text)); Status = "Done! optimizer_benchmark.txt"; Progress = 1f; Running = false; yield return (object)new WaitForSeconds(5f); Status = ""; } private static string BuildReport(Result vanilla, Result gpuGc, Result allOn) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("╔══════════════════════════════════════════════════════════════╗"); stringBuilder.AppendLine("║ REPO FIDELITY - FULL BENCHMARK REPORT ║"); stringBuilder.AppendLine("╚══════════════════════════════════════════════════════════════╝"); stringBuilder.AppendLine(); stringBuilder.AppendLine($" Date: {DateTime.Now:yyyy-MM-dd HH:mm:ss}"); stringBuilder.AppendLine(" GPU: " + SystemInfo.graphicsDeviceName); stringBuilder.AppendLine($" VRAM: {SystemInfo.graphicsMemorySize}MB"); stringBuilder.AppendLine($" API: {SystemInfo.graphicsDeviceType}"); stringBuilder.AppendLine($" CPU: {SystemInfo.processorType} ({SystemInfo.processorCount} threads)"); stringBuilder.AppendLine($" RAM: {SystemInfo.systemMemorySize}MB"); stringBuilder.AppendLine($" Platform: {Application.platform}"); stringBuilder.AppendLine($" Resolution: {Screen.width}x{Screen.height}"); stringBuilder.AppendLine($" Passes: {2} x {15f}s (warmup {3f}s)"); stringBuilder.AppendLine(" CPU gate: " + ((Settings.CpuPatchMode == -1) ? "Auto (>8ms)" : ((Settings.CpuPatchMode == 1) ? "Forced ON" : "Forced OFF"))); stringBuilder.AppendLine(); float num = vanilla.AvgMs - gpuGc.AvgMs; float num2 = gpuGc.AvgMs - allOn.AvgMs; float num3 = vanilla.AvgMs - allOn.AvgMs; float num4 = allOn.AvgFps - vanilla.AvgFps; float num5 = ((vanilla.AvgMs > 0f) ? (num3 / vanilla.AvgMs * 100f) : 0f); stringBuilder.AppendLine("──────────────────────────────────────────────────────────────"); stringBuilder.AppendLine(" RESULTS (averaged across passes)"); stringBuilder.AppendLine("──────────────────────────────────────────────────────────────"); stringBuilder.AppendLine($" Vanilla (mod OFF): {vanilla.AvgFps,6:F1} FPS {vanilla.AvgMs,7:F2}ms 1%low: {vanilla.P1Low,5:F1} N={vanilla.Frames.Count}"); stringBuilder.AppendLine($" GPU/GC only: {gpuGc.AvgFps,6:F1} FPS {gpuGc.AvgMs,7:F2}ms 1%low: {gpuGc.P1Low,5:F1} N={gpuGc.Frames.Count}"); stringBuilder.AppendLine($" All ON: {allOn.AvgFps,6:F1} FPS {allOn.AvgMs,7:F2}ms 1%low: {allOn.P1Low,5:F1} N={allOn.Frames.Count}"); stringBuilder.AppendLine(); stringBuilder.AppendLine($" GPU/GC savings: {num:+0.000;-0.000}ms ({vanilla.AvgFps:F1} -> {gpuGc.AvgFps:F1} FPS)"); stringBuilder.AppendLine($" CPU patch savings: {num2:+0.000;-0.000}ms ({gpuGc.AvgFps:F1} -> {allOn.AvgFps:F1} FPS)"); stringBuilder.AppendLine($" Total improvement: {num3:+0.000;-0.000}ms ({num4:+0.0;-0.0} FPS, {num5:+0.0;-0.0}%)"); stringBuilder.AppendLine(); stringBuilder.AppendLine("──────────────────────────────────────────────────────────────"); stringBuilder.AppendLine(" OPTIMIZATIONS INCLUDED"); stringBuilder.AppendLine("──────────────────────────────────────────────────────────────"); stringBuilder.AppendLine(" GPU/GC:"); stringBuilder.AppendLine(" GPU instancing, shadow culling, layer distance culling"); stringBuilder.AppendLine(" GrabberComponentCache, RayCheck/ForceGrab NonAlloc"); stringBuilder.AppendLine(" Quality overrides (shadows, LOD, AF, lights, fog)"); stringBuilder.AppendLine(" CPU (auto-enabled when frame time > 8ms):"); stringBuilder.AppendLine(" EnemyDirector throttle, RoomVolume NonAlloc"); stringBuilder.AppendLine(" SemiFunc cache, PhysGrab fix, LightManager batch"); stringBuilder.AppendLine(); return stringBuilder.ToString(); } private static void Glitch() { CameraGlitch instance = CameraGlitch.Instance; if (!((Object)(object)instance == (Object)null)) { if ((Object)(object)instance.ActiveParent != (Object)null) { instance.ActiveParent.SetActive(true); } instance.PlayShort(); } } private IEnumerator Settle() { for (int i = 0; i < 5; i++) { yield return null; } yield return (object)new WaitForSeconds(3f); } private IEnumerator Measure(Result result) { float elapsed = 0f; while (elapsed < 15f) { result.Frames.Add(Time.unscaledDeltaTime); elapsed += Time.unscaledDeltaTime; yield return null; } result.Compute(); } } internal static class Overlay { private struct NativeLine { public GameObject Go; public TextMeshProUGUI Text; public RectTransform Rt; public RectTransform? ScanRt; public float CurrentY; public float TargetY; public bool WasVisible; } private struct LineData { public string Text; public Col Color; public LineData(string text, Col color) { Text = text; Color = color; } } private enum Col { White, Title, Info, Warn, Dim } private static GameObject? _root; private static readonly List _nativeLines = new List(); private static RectTransform? _rootRt; private static RectTransform? _progressBgNative; private static RectTransform? _progressFillNative; private static Image? _progressFillImg; private static TMP_FontAsset? _gameFont; private static Sprite? _scanlineSprite; private static bool _nativeActive; private static readonly List _lines = new List(); private static bool _showProgress; private static float _progress; private static Color _progressColor; private static float _fpsAccum; private static float _fpsTimer; private static int _fpsFrames; private static float _smoothFps; private static float _smoothMs; private const float SlideSpeed = 6f; private const float HideOffsetY = -40f; private const float FontSize = 14f; private const float LineH = 20f; private const float TextWidth = 500f; private const float BaseX = 12f; private const float BaseY = 110f; private static GUIStyle? _styleTitle; private static GUIStyle? _shadowTitle; private static GUIStyle? _styleInfo; private static GUIStyle? _shadowInfo; private static GUIStyle? _styleWarn; private static GUIStyle? _shadowWarn; private static GUIStyle? _styleDim; private static GUIStyle? _shadowDim; private static int _lastScreenH; internal static float SmoothFps => _smoothFps; internal static float SmoothMs => _smoothMs; internal static void UpdateLines() { //IL_00d8: 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) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) _fpsAccum += Time.unscaledDeltaTime; _fpsFrames++; _fpsTimer += Time.unscaledDeltaTime; if (_fpsTimer >= 0.5f) { _smoothMs = _fpsAccum / (float)_fpsFrames * 1000f; _smoothFps = 1000f / Mathf.Max(_smoothMs, 0.001f); _fpsAccum = 0f; _fpsFrames = 0; _fpsTimer = 0f; } _lines.Clear(); _showProgress = false; if (UpscalerManager.RepoHdDetected) { _lines.Add(new LineData("REPO HD DETECTED - REMOVE", Col.Warn)); } if (UpscalerManager.BenchmarkActive) { _showProgress = true; _progress = UpscalerManager.BenchmarkProgress; _progressColor = new Color(0.9f, 0.35f, 0.35f); string text = (UpscalerManager.AutoBenchmarkRunning ? "AUTO-TUNING" : "BENCHMARKING"); _lines.Add(new LineData($"{text} {Mathf.RoundToInt(_progress * 100f)}% {_smoothFps:F0} FPS {_smoothMs:F1}ms", Col.Warn)); } if (OptimizerBenchmark.Running || !string.IsNullOrEmpty(OptimizerBenchmark.Status)) { _lines.Add(new LineData("OPTIMIZER " + OptimizerBenchmark.Status, Col.Info)); if (OptimizerBenchmark.Running) { _showProgress = true; _progress = OptimizerBenchmark.Progress; _progressColor = new Color(0.35f, 0.85f, 0.4f); } } if (!Settings.ModEnabled) { _lines.Add(new LineData($"FIDELITY OFF ({Settings.ToggleKey}) {_smoothFps:F0} FPS {_smoothMs:F1}ms", Col.Warn)); } else if (!Settings.OptimizationsEnabled) { _lines.Add(new LineData($"OPTIMIZATIONS OFF (F11) {_smoothFps:F0} FPS {_smoothMs:F1}ms", Col.Warn)); } else if (Settings.CpuPatchesF11Disabled) { _lines.Add(new LineData($"CPU PATCHES OFF (F11) {_smoothFps:F0} FPS {_smoothMs:F1}ms", Col.Warn)); } if (Settings.ModEnabled && Settings.DebugOverlay) { string text2 = Settings.Preset.ToString().ToUpper(); string text3 = Settings.ResolvedUpscaleMode.ToString(); string text4 = ((Settings.ResolvedAAMode != AAMode.Off) ? $" {Settings.ResolvedAAMode}" : ""); string text5 = ((UpscalerManager.BenchmarkActive || OptimizerBenchmark.Running) ? "" : $" {_smoothFps:F0} FPS {_smoothMs:F1}ms"); _lines.Add(new LineData("[" + text2 + "] " + text3 + text4 + text5, Col.Title)); string text6 = (Settings.CpuPatchesActive ? "ON" : "OFF"); string text7 = Settings.CpuPatchMode switch { 1 => "FORCED", 0 => "FORCED", _ => "AUTO", }; _lines.Add(new LineData($"SH:{Settings.ResolvedShadowQuality}/{Settings.ResolvedShadowDistance:F0}m " + $"L:{Settings.ResolvedPixelLightCount} LOD:{Settings.ResolvedLODBias:F1} CPU:{text6}({text7})", Col.Dim)); } _nativeActive = TryUpdateNative(); } internal static void Draw() { if (!_nativeActive && _lines.Count != 0) { DrawOnGUI(); } } private static bool TryUpdateNative() { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)HUDCanvas.instance == (Object)null) { ClearNative(); return false; } if ((Object)(object)_root == (Object)null) { _nativeLines.Clear(); BuildNative(); } if ((Object)(object)_root == (Object)null) { return false; } while (_nativeLines.Count < _lines.Count) { _nativeLines.Add(CreateNativeLine(_nativeLines.Count)); } float unscaledDeltaTime = Time.unscaledDeltaTime; float num = (_showProgress ? 10f : 0f); for (int i = 0; i < _nativeLines.Count; i++) { NativeLine value = _nativeLines[i]; bool num2 = i < _lines.Count; if (num2) { value.Go.SetActive(true); ((TMP_Text)value.Text).text = _lines[i].Text; ((Graphic)value.Text).color = GetColor(_lines[i].Color); float num3 = (value.TargetY = num + 110f + (float)(_lines.Count - 1 - i) * 20f); if (!value.WasVisible) { value.CurrentY = num3 + -40f; } value.WasVisible = true; } else { value.TargetY = value.CurrentY + -40f; if (value.WasVisible) { value.WasVisible = false; } } value.CurrentY = Mathf.Lerp(value.CurrentY, value.TargetY, unscaledDeltaTime * 6f); if (!num2 && Mathf.Abs(value.CurrentY - value.TargetY) < 0.5f) { value.Go.SetActive(false); continue; } value.Rt.anchoredPosition = new Vector2(0f, value.CurrentY); if ((Object)(object)value.ScanRt != (Object)null && ((TMP_Text)value.Text).preferredWidth > 0f) { value.ScanRt.sizeDelta = new Vector2(((TMP_Text)value.Text).preferredWidth + 4f, 0f); } _nativeLines[i] = value; } _root.SetActive(_lines.Count > 0 || AnyAnimating()); if ((Object)(object)_progressBgNative != (Object)null) { ((Component)_progressBgNative).gameObject.SetActive(_showProgress); if (_showProgress && (Object)(object)_progressFillNative != (Object)null && (Object)(object)_progressFillImg != (Object)null) { _progressFillNative.anchorMax = new Vector2(Mathf.Clamp01(_progress), 1f); ((Graphic)_progressFillImg).color = _progressColor; } } return true; } private static bool AnyAnimating() { for (int i = 0; i < _nativeLines.Count; i++) { if (_nativeLines[i].Go.activeSelf) { return true; } } return false; } private static void BuildNative() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)HUDCanvas.instance == (Object)null)) { FindGameAssets(); if (!((Object)(object)_gameFont == (Object)null)) { _root = new GameObject("FidelityOverlay"); _root.transform.SetParent((Transform)(object)HUDCanvas.instance.rect, false); _rootRt = _root.AddComponent(); _rootRt.anchorMin = Vector2.zero; _rootRt.anchorMax = Vector2.zero; _rootRt.pivot = Vector2.zero; _rootRt.anchoredPosition = new Vector2(12f, 0f); _rootRt.sizeDelta = new Vector2(520f, 200f); GameObject val = new GameObject("ProgressBg"); val.transform.SetParent((Transform)(object)_rootRt, false); _progressBgNative = val.AddComponent(); _progressBgNative.anchorMin = Vector2.zero; _progressBgNative.anchorMax = new Vector2(0f, 0f); _progressBgNative.pivot = Vector2.zero; _progressBgNative.anchoredPosition = new Vector2(0f, 102f); _progressBgNative.sizeDelta = new Vector2(220f, 3f); Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(0.15f, 0.15f, 0.15f, 0.5f); ((Graphic)obj).raycastTarget = false; val.SetActive(false); GameObject val2 = new GameObject("Fill"); val2.transform.SetParent((Transform)(object)_progressBgNative, false); _progressFillNative = val2.AddComponent(); _progressFillNative.anchorMin = Vector2.zero; _progressFillNative.anchorMax = new Vector2(0f, 1f); _progressFillNative.pivot = new Vector2(0f, 0.5f); _progressFillNative.offsetMin = Vector2.zero; _progressFillNative.offsetMax = Vector2.zero; _progressFillImg = val2.AddComponent(); ((Graphic)_progressFillImg).raycastTarget = false; Plugin.Log.LogDebug((object)"Overlay: native HUD created"); } } } private static NativeLine CreateNativeLine(int index) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"FidelityLine{index}"); val.transform.SetParent(_root.transform, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.zero; val2.pivot = new Vector2(0f, 0f); val2.anchoredPosition = new Vector2(0f, -40f); val2.sizeDelta = new Vector2(500f, 20f); TextMeshProUGUI val3 = val.AddComponent(); ((TMP_Text)val3).font = _gameFont; ((TMP_Text)val3).fontSize = 14f; ((TMP_Text)val3).fontStyle = (FontStyles)1; ((TMP_Text)val3).alignment = (TextAlignmentOptions)1025; ((TMP_Text)val3).overflowMode = (TextOverflowModes)0; ((Graphic)val3).raycastTarget = false; ((TMP_Text)val3).enableWordWrapping = false; RectTransform val4 = null; if ((Object)(object)_scanlineSprite != (Object)null) { GameObject val5 = new GameObject("Scanlines"); val5.transform.SetParent(val.transform, false); val4 = val5.AddComponent(); val4.anchorMin = Vector2.zero; val4.anchorMax = new Vector2(0f, 1f); val4.pivot = new Vector2(0f, 0.5f); val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; val4.sizeDelta = new Vector2(10f, 0f); Image obj = val5.AddComponent(); obj.sprite = _scanlineSprite; obj.type = (Type)2; ((Graphic)obj).raycastTarget = false; val5.AddComponent(); } return new NativeLine { Go = val, Text = val3, Rt = val2, ScanRt = val4, CurrentY = -40f, TargetY = -40f, WasVisible = false }; } private static void FindGameAssets() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_gameFont != (Object)null) { return; } TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll(); foreach (TextMeshProUGUI val in array) { if ((Object)(object)((TMP_Text)val).font != (Object)null) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).isLoaded) { _gameFont = ((TMP_Text)val).font; break; } } } UIScanlines[] array2 = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array2.Length; i++) { Image component = ((Component)array2[i]).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null) { _scanlineSprite = component.sprite; Plugin.Log.LogDebug((object)("Overlay: scanline sprite '" + ((Object)_scanlineSprite).name + "'")); break; } } if ((Object)(object)_gameFont != (Object)null) { Plugin.Log.LogDebug((object)("Overlay: game font '" + ((Object)_gameFont).name + "'")); } } private static void ClearNative() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _nativeLines.Clear(); } private static void DrawOnGUI() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) EnsureOnGUIStyles(); float num = Mathf.Max((float)Screen.height / 1080f, 0.5f); float num2 = 20f * num; float num3 = 28f * num; float num4 = 1.5f * num; float num5 = (float)_lines.Count * num3 + (_showProgress ? (10f * num) : 0f); float num6 = (float)Screen.height - num5 - 50f * num; Rect val = default(Rect); for (int i = 0; i < _lines.Count; i++) { GetOnGUIStyles(_lines[i].Color, out GUIStyle text, out GUIStyle shadow); ((Rect)(ref val))..ctor(num2, num6, (float)Screen.width * 0.5f, num3); GUI.Label(new Rect(((Rect)(ref val)).x + num4, ((Rect)(ref val)).y + num4, ((Rect)(ref val)).width, ((Rect)(ref val)).height), _lines[i].Text, shadow); GUI.Label(val, _lines[i].Text, text); num6 += num3; } if (_showProgress) { float num7 = 220f * num; GUI.DrawTexture(new Rect(num2, num6 + 4f * num, num7, 3f * num), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, false, 0f, new Color(0.1f, 0.1f, 0.1f, 0.5f), 0f, 0f); GUI.DrawTexture(new Rect(num2, num6 + 4f * num, num7 * Mathf.Clamp01(_progress), 3f * num), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, false, 0f, _progressColor, 0f, 0f); } } private static Color GetColor(Col c) { //IL_0029: 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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) return (Color)(c switch { Col.Title => new Color(0.3f, 0.92f, 0.4f), Col.Info => new Color(0.35f, 0.88f, 0.45f), Col.Warn => new Color(0.95f, 0.35f, 0.3f), Col.Dim => new Color(0.45f, 0.52f, 0.45f), _ => new Color(0.9f, 0.95f, 0.9f), }); } private static void EnsureOnGUIStyles() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (_styleTitle == null || _lastScreenH != Screen.height) { _lastScreenH = Screen.height; float num = Mathf.Max((float)Screen.height / 1080f, 0.5f); int size = Mathf.Max(Mathf.RoundToInt(16f * num), 11); int size2 = Mathf.Max(Mathf.RoundToInt(13f * num), 10); MakePair(size, GetColor(Col.Title), out _styleTitle, out _shadowTitle); MakePair(size, GetColor(Col.Info), out _styleInfo, out _shadowInfo); MakePair(size, GetColor(Col.Warn), out _styleWarn, out _shadowWarn); MakePair(size2, GetColor(Col.Dim), out _styleDim, out _shadowDim); } } private static void MakePair(int size, Color color, out GUIStyle text, out GUIStyle shadow) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) text = new GUIStyle { fontSize = size, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; text.normal.textColor = color; shadow = new GUIStyle(text); shadow.normal.textColor = new Color(0f, 0f, 0f, 0.55f); } private static void GetOnGUIStyles(Col c, out GUIStyle text, out GUIStyle shadow) { (text, shadow) = c switch { Col.Title => (_styleTitle, _shadowTitle), Col.Info => (_styleInfo, _shadowInfo), Col.Warn => (_styleWarn, _shadowWarn), Col.Dim => (_styleDim, _shadowDim), _ => (_styleTitle, _shadowTitle), }; } } [BepInPlugin("Vippy.REPOFidelity", "REPO Fidelity", "1.7.7")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "Vippy.REPOFidelity"; public const string PluginName = "REPO Fidelity"; internal static ManualLogSource Log; internal static Plugin Instance; private Harmony? _harmony; private void Awake() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //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) Log = ((BaseUnityPlugin)this).Logger; Instance = this; if (Chainloader.PluginInfos.ContainsKey("BlueAmulet.REPO_HD")) { Log.LogWarning((object)"REPO_HD detected! REPO Fidelity covers all REPO_HD features. Please remove REPO_HD to avoid conflicts."); } bool flag = Chainloader.PluginInfos.ContainsKey("nickklmao.menulib"); if (flag) { ((BaseUnityPlugin)this).Config.Bind("_", "Hidden", true, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); } ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; Settings.Init(); GPUDetector.Detect(); Settings.ResolveAutoDefaults(); ConfigIntegration.Initialize(((BaseUnityPlugin)this).Config); _harmony = new Harmony("Vippy.REPOFidelity"); Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { try { _harmony.CreateClassProcessor(type).Patch(); } catch (Exception arg) { Log.LogWarning((object)$"Harmony patch failed for {type.Name}: {arg}"); } } Log.LogInfo((object)"REPO Fidelity v1.7.7 loaded"); Log.LogInfo((object)$"GPU: {GPUDetector.GpuName} ({GPUDetector.Vendor}, Tier: {GPUDetector.Tier}, VRAM: {GPUDetector.VramMb}MB)"); Log.LogInfo((object)$"CPU: {SystemInfo.processorType} ({SystemInfo.processorCount} threads)"); Log.LogInfo((object)$"RAM: {SystemInfo.systemMemorySize}MB | Platform: {Application.platform} | API: {SystemInfo.graphicsDeviceType}"); Log.LogInfo((object)$"Display: {Screen.width}x{Screen.height} (aspect {(float)Screen.width / (float)Screen.height:F2})"); Log.LogInfo((object)$"DLSS Available: {GPUDetector.DlssAvailable}"); if (flag) { MenuIntegration.Initialize(); Log.LogInfo((object)"MenuLib detected, settings added to graphics menu"); } else { Log.LogInfo((object)"MenuLib not found, settings exposed via REPOConfig / config file"); } } private void LateUpdate() { Settings.UpdateCpuGate(); Overlay.UpdateLines(); } private void OnGUI() { Overlay.Draw(); } } internal enum QualityPreset { Potato, Low, Medium, High, Ultra, Custom, Auto } internal enum UpscaleMode { Auto, DLAA, DLSS, FSR4, FSR_Temporal, FSR, Off } internal enum AAMode { Auto, TAA, SMAA, FXAA, Off } internal enum ShadowQuality { Low, Medium, High, Ultra } internal enum TextureRes { Full, Half, Quarter } internal enum F11Target { FullOptLayer, CpuPatches } internal static class Settings { internal enum PerfOpt { ExplosionShadows, ParticleShadows, ItemLightShadows, TinyRendererCulling, AnimatedLightShadows, DistanceShadowCulling, FlashlightShadowBudget, PointLightShadows } private enum UpscaleTier { Budget, Quality, NativeAA } private static SettingsFile _file = null; private static bool _initComplete; internal static bool ModEnabled = true; internal static bool OptimizationsEnabled = true; internal static bool AllocationFixesEnabled = true; internal static bool CpuPatchesF11Disabled; private static bool _cpuPatchesActiveRaw = true; private static float _cpuGateTimer; private static float _cpuGateAccum; private static int _cpuGateFrames; private const float CpuGateThresholdMs = 8f; internal static int ResolvedShadowBudget; internal const float PlayableFogFloor = 0.5f; internal static UpscaleMode ResolvedUpscaleMode; internal static int ResolvedRenderScale; internal static AAMode ResolvedAAMode; internal static ShadowQuality ResolvedShadowQuality; internal static float ResolvedShadowDistance; internal static float ResolvedLODBias; internal static int ResolvedPixelLightCount; internal static float ResolvedLightDistance; internal static float ResolvedFogMultiplier; internal static float ResolvedEffectiveFogEnd; internal static float ResolvedViewDistance; internal static int ResolvedAnisotropicFiltering; internal static TextureRes ResolvedTextureQuality; private static AutoTuneData _autoTune = new AutoTuneData(); private static string _autoTunePath = ""; private static bool _pendingWindowReset; private static int _suppressTweakRevert; private static SettingsData D => _file.Data; internal static QualityPreset Preset { get { return (QualityPreset)D.preset; } set { D.preset = (int)value; _file.Save(); OnChanged(); } } internal static int OutputWidth { get { if (D.resWidth <= 0) { return Screen.width; } return D.resWidth; } set { D.resWidth = value; _file.Save(); OnChanged(); } } internal static int OutputHeight { get { if (D.resHeight <= 0) { return Screen.height; } return D.resHeight; } set { D.resHeight = value; _file.Save(); OnChanged(); } } internal static UpscaleMode UpscaleModeSetting { get { return (UpscaleMode)D.upscaler; } set { D.upscaler = (int)value; _file.Save(); OnSettingTweaked(); } } internal static int RenderScale { get { return D.renderScale; } set { D.renderScale = Mathf.Clamp(value, 33, 100); _file.Save(); OnSettingTweaked(); } } internal static float Sharpening { get { return D.sharpening; } set { D.sharpening = Mathf.Clamp(value, 0f, 1f); _file.Save(); if (_initComplete && Preset != QualityPreset.Custom) { _file.SuppressEvents(delegate { D.preset = 5; }); _file.Save(); } } } internal static AAMode AntiAliasingMode { get { return (AAMode)D.aaMode; } set { D.aaMode = (int)value; _file.Save(); OnSettingTweaked(); } } internal static bool Pixelation { get { return D.pixelation; } set { D.pixelation = value; _file.Save(); OnSettingTweaked(); } } internal static ShadowQuality ShadowQualitySetting { get { return (ShadowQuality)D.shadowQuality; } set { D.shadowQuality = (int)value; _file.Save(); OnSettingTweaked(); } } internal static float ShadowDistance { get { return D.shadowDistance; } set { D.shadowDistance = Mathf.Clamp(value, 5f, 200f); _file.Save(); OnSettingTweaked(); } } internal static float LODBias { get { return D.lodBias; } set { D.lodBias = Mathf.Clamp(value, 0.5f, 4f); _file.Save(); OnSettingTweaked(); } } internal static int AnisotropicFiltering { get { return D.anisotropicFiltering; } set { D.anisotropicFiltering = value; _file.Save(); OnSettingTweaked(); } } internal static int PixelLightCount { get { return D.pixelLightCount; } set { D.pixelLightCount = Mathf.Clamp(value, 1, 16); _file.Save(); OnSettingTweaked(); } } internal static TextureRes TextureQuality { get { return (TextureRes)D.textureQuality; } set { D.textureQuality = (int)value; _file.Save(); OnSettingTweaked(); } } internal static float LightDistance { get { return D.lightDistance; } set { D.lightDistance = Mathf.Clamp(value, 10f, 100f); _file.Save(); OnSettingTweaked(); } } internal static float FogDistanceMultiplier { get { return D.fogMultiplier; } set { D.fogMultiplier = Mathf.Clamp(value, 0.3f, 1.1f); _file.Save(); OnSettingTweaked(); } } internal static float ViewDistance { get { return D.viewDistance; } set { D.viewDistance = Mathf.Clamp(value, 0f, 500f); _file.Save(); OnSettingTweaked(); } } internal static bool MotionBlurOverride { get { return D.motionBlur; } set { D.motionBlur = value; _file.Save(); OnSettingTweaked(); } } internal static bool ChromaticAberration { get { return D.chromaticAberration; } set { D.chromaticAberration = value; _file.Save(); OnSettingTweaked(); } } internal static bool LensDistortion { get { return D.lensDistortion; } set { D.lensDistortion = value; _file.Save(); OnSettingTweaked(); } } internal static bool FilmGrain { get { return D.filmGrain; } set { D.filmGrain = value; _file.Save(); OnSettingTweaked(); } } internal static bool ExtractionPointFlicker { get { return D.extractionFlickerFix; } set { D.extractionFlickerFix = value; _file.Save(); OnSettingTweaked(); } } internal static int VerticalFovOverride { get { return D.verticalFovOverride; } set { D.verticalFovOverride = Mathf.Clamp(value, 0, 110); _file.Save(); OnSettingTweaked(); } } internal static bool UltrawideUiFix { get { return D.ultrawideUiFix; } set { D.ultrawideUiFix = value; _file.Save(); OnSettingTweaked(); } } internal static bool UltrawideHudUnstretch { get { return D.ultrawideHudUnstretch; } set { D.ultrawideHudUnstretch = value; _file.Save(); OnSettingTweaked(); } } internal static bool SharpHud { get { return D.sharpHud; } set { D.sharpHud = value; _file.Save(); OnSettingTweaked(); } } internal static KeyCode ToggleKey { get { return (KeyCode)D.toggleKey; } set { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected I4, but got Unknown D.toggleKey = (int)value; _file.Save(); } } internal static F11Target F11TargetSetting { get { F11Target f11Target = (F11Target)D.f11Target; if (!Enum.IsDefined(typeof(F11Target), f11Target)) { return F11Target.FullOptLayer; } return f11Target; } set { D.f11Target = (int)value; _file.Save(); } } internal static bool DebugOverlay { get { return D.debugOverlay; } set { D.debugOverlay = value; _file.Save(); } } internal static bool BenchmarkMode { get { return D.benchmark; } set { D.benchmark = value; _file.Save(); } } internal static bool AutoConfigured => !_autoTune.IsStale(); internal static bool OptimizationsActive { get { if (ModEnabled) { return OptimizationsEnabled; } return false; } } internal static bool CpuBound { get { if (!_autoTune.IsStale()) { return _autoTune.cpuBound; } return true; } } internal static int CpuPatchMode { get { return D.cpuPatchMode; } set { D.cpuPatchMode = value; _file.Save(); } } internal static bool CpuPatchesActive { get { if (_cpuPatchesActiveRaw && OptimizationsActive) { return !CpuPatchesF11Disabled; } return false; } } internal static int ShadowBudget { get { return D.shadowBudget; } set { D.shadowBudget = value; _file.Save(); OnSettingTweaked(); } } internal static int PerfExplosionShadows { get { return D.perfExplosionShadows; } set { D.perfExplosionShadows = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfItemLightShadows { get { return D.perfItemLightShadows; } set { D.perfItemLightShadows = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfAnimatedLightShadows { get { return D.perfAnimatedLightShadows; } set { D.perfAnimatedLightShadows = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfParticleShadows { get { return D.perfParticleShadows; } set { D.perfParticleShadows = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfTinyRendererCulling { get { return D.perfTinyRendererCulling; } set { D.perfTinyRendererCulling = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfDistanceShadowCulling { get { return D.perfDistanceShadowCulling; } set { D.perfDistanceShadowCulling = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfFlashlightShadowBudget { get { return D.perfFlashlightShadowBudget; } set { D.perfFlashlightShadowBudget = value; _file.Save(); _file.NotifyChanged(); } } internal static int PerfPointLightShadows { get { return D.perfPointLightShadows; } set { D.perfPointLightShadows = value; _file.Save(); _file.NotifyChanged(); } } internal static bool AutoTuneNeedsBenchmark => _autoTune.IsStale(); internal static bool AutoTuneNeedsInitialBenchmark { get { if (_autoTune.revision >= 7) { return _autoTune.gpuName != SystemInfo.graphicsDeviceName; } return true; } } internal static bool PresetRevertSuppressed => _suppressTweakRevert > 0; internal static event Action? OnSettingsChanged; internal static void InvalidateAutoTune() { _autoTune.version = ""; } internal static void UpdateCpuGate() { if (CpuPatchMode == 1) { _cpuPatchesActiveRaw = true; return; } if (CpuPatchMode == 0) { _cpuPatchesActiveRaw = false; return; } _cpuGateAccum += Time.unscaledDeltaTime; _cpuGateFrames++; _cpuGateTimer += Time.unscaledDeltaTime; if (_cpuGateTimer >= 0.5f && _cpuGateFrames > 0) { _cpuPatchesActiveRaw = _cpuGateAccum / (float)_cpuGateFrames * 1000f >= 8f; _cpuGateTimer = 0f; _cpuGateAccum = 0f; _cpuGateFrames = 0; } } internal static bool ShouldOptimize(PerfOpt opt) { if (!OptimizationsActive) { return false; } if (Preset == QualityPreset.Custom) { switch (opt switch { PerfOpt.ExplosionShadows => D.perfExplosionShadows, PerfOpt.ParticleShadows => D.perfParticleShadows, PerfOpt.ItemLightShadows => D.perfItemLightShadows, PerfOpt.TinyRendererCulling => D.perfTinyRendererCulling, PerfOpt.AnimatedLightShadows => D.perfAnimatedLightShadows, PerfOpt.DistanceShadowCulling => D.perfDistanceShadowCulling, PerfOpt.FlashlightShadowBudget => D.perfFlashlightShadowBudget, PerfOpt.PointLightShadows => D.perfPointLightShadows, _ => -1, }) { case 0: return false; case 1: return true; } } int num = Preset switch { QualityPreset.Ultra => 0, QualityPreset.High => 1, QualityPreset.Medium => 2, QualityPreset.Auto => _autoTune.perfLevel, QualityPreset.Custom => ResolvedShadowQuality switch { ShadowQuality.Ultra => 0, ShadowQuality.High => 1, ShadowQuality.Medium => 2, _ => 3, }, _ => 3, }; return opt switch { PerfOpt.ExplosionShadows => num >= 1, PerfOpt.ParticleShadows => num >= 1, PerfOpt.ItemLightShadows => num >= 2, PerfOpt.TinyRendererCulling => num >= 2, PerfOpt.AnimatedLightShadows => num >= 3, PerfOpt.DistanceShadowCulling => num >= 0, PerfOpt.FlashlightShadowBudget => num >= 0, PerfOpt.PointLightShadows => num >= 2, _ => false, }; } internal static void Init() { string? path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ""; _file = new SettingsFile(Path.Combine(path, "settings.json")); _file.Changed += delegate { ResolveAutoDefaults(); Settings.OnSettingsChanged?.Invoke(); }; _autoTunePath = Path.Combine(path, "autotune.json"); LoadAutoTune(); _initComplete = true; ValidateResolutionForCurrentMonitor(); ValidateMachineForSettings(); } private static void ValidateResolutionForCurrentMonitor() { int num = ((Display.main != null) ? Display.main.systemWidth : 0); int num2 = ((Display.main != null) ? Display.main.systemHeight : 0); if (num <= 0 || num2 <= 0) { return; } if (D.resWidth <= 0 || D.resHeight <= 0) { D.resWidth = num; D.resHeight = num2; _file.Save(); return; } float num3 = (float)D.resWidth / (float)D.resHeight; float num4 = (float)num / (float)num2; if (Mathf.Abs(num3 - num4) > 0.05f) { Plugin.Log.LogWarning((object)$"[settings] resolution {D.resWidth}x{D.resHeight} (aspect {num3:F2}) mismatches monitor {num}x{num2} (aspect {num4:F2}); resetting to native"); D.resWidth = num; D.resHeight = num2; _file.Save(); _pendingWindowReset = true; return; } long num5 = (long)D.resWidth * (long)D.resHeight; long num6 = (long)num * (long)num2; if (num5 < num6 / 2) { Plugin.Log.LogWarning((object)$"[settings] resolution {D.resWidth}x{D.resHeight} is <50% of monitor native {num}x{num2}; resetting to native"); D.resWidth = num; D.resHeight = num2; _file.Save(); _pendingWindowReset = true; } } internal static void TickDeferredWindowReset() { //IL_006e: 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) if (_pendingWindowReset && Time.frameCount >= 10 && !((Object)(object)GraphicsManager.instance == (Object)null)) { _pendingWindowReset = false; int num = ((Display.main != null) ? Display.main.systemWidth : 0); int num2 = ((Display.main != null) ? Display.main.systemHeight : 0); if (num > 0 && num2 > 0) { Plugin.Log.LogWarning((object)$"[settings] deferred native reset: {num}x{num2} ({Screen.fullScreenMode})"); Screen.SetResolution(num, num2, Screen.fullScreenMode); } } } private static void ValidateMachineForSettings() { string text = SystemInfo.graphicsDeviceName ?? ""; if (!(D.gpuName == text)) { if (!string.IsNullOrEmpty(D.gpuName) && D.preset != 6) { Plugin.Log.LogWarning((object)$"[settings] GPU changed ('{D.gpuName}' -> '{text}'); resetting preset {(QualityPreset)D.preset} -> Auto"); D.preset = 6; } D.gpuName = text; _file.Save(); } } private static void LoadAutoTune() { if (!File.Exists(_autoTunePath)) { return; } try { AutoTuneData autoTuneData = JsonUtility.FromJson(File.ReadAllText(_autoTunePath)); if (autoTuneData != null) { _autoTune = autoTuneData; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to load autotune: " + ex.Message)); } } internal static void SaveAutoTune(AutoTuneData data) { _autoTune = data; try { File.WriteAllText(_autoTunePath, JsonUtility.ToJson((object)data, true)); Plugin.Log.LogDebug((object)"Auto-tune profile saved"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to save autotune: " + ex.Message)); } if (Preset == QualityPreset.Auto) { ResolveAutoDefaults(); Settings.OnSettingsChanged?.Invoke(); } } private static void OnChanged() { if (_initComplete) { _file.NotifyChanged(); } } internal static void PushPresetRevertSuppression() { _suppressTweakRevert++; } internal static void PopPresetRevertSuppression() { _suppressTweakRevert = Math.Max(0, _suppressTweakRevert - 1); } private static void OnSettingTweaked() { if (!_initComplete) { return; } if (_suppressTweakRevert > 0) { _file.NotifyChanged(); return; } if (Preset != QualityPreset.Custom) { _file.SuppressEvents(delegate { D.preset = 5; }); _file.Save(); } _file.NotifyChanged(); } internal static void BatchUpdate(Action action) { _file.SuppressEvents(action); _file.Save(); ResolveAutoDefaults(); Settings.OnSettingsChanged?.Invoke(); } public static void ResolveAutoDefaults() { QualityPreset preset = Preset; if (preset != QualityPreset.Custom) { ApplyPreset(preset); SyncCustomToResolved(); } else { ResolvedUpscaleMode = UpscaleModeSetting switch { UpscaleMode.Auto => BestUpscaler(UpscaleTier.Quality), UpscaleMode.FSR => UpscaleMode.FSR_Temporal, UpscaleMode.FSR4 => UpscaleMode.FSR_Temporal, _ => UpscaleModeSetting, }; if (!GPUDetector.IsUpscalerSupported(ResolvedUpscaleMode)) { Plugin.Log.LogWarning((object)$"{ResolvedUpscaleMode} not supported, falling back to Auto"); ResolvedUpscaleMode = BestUpscaler(UpscaleTier.Quality); } int num = MinRenderScale(ResolvedUpscaleMode); if (ResolvedUpscaleMode == UpscaleMode.DLSS && RenderScale >= 100) { ResolvedUpscaleMode = UpscaleMode.DLAA; } if (ResolvedUpscaleMode == UpscaleMode.DLAA) { ResolvedRenderScale = 100; } else { ResolvedRenderScale = Mathf.Clamp(RenderScale, num, 100); } UpscaleMode resolvedUpscaleMode = ResolvedUpscaleMode; bool flag = (((uint)(resolvedUpscaleMode - 1) <= 1u || resolvedUpscaleMode == UpscaleMode.FSR_Temporal) ? true : false); bool flag2 = flag; if (AntiAliasingMode == AAMode.Auto) { ResolvedAAMode = (flag2 ? AAMode.Off : AAMode.SMAA); } else if (AntiAliasingMode == AAMode.TAA) { ResolvedAAMode = (flag2 ? AAMode.Off : AAMode.SMAA); } else { ResolvedAAMode = AntiAliasingMode; } ResolvedShadowQuality = ShadowQualitySetting; ResolvedShadowDistance = ShadowDistance; ResolvedLODBias = LODBias; ResolvedPixelLightCount = PixelLightCount; ResolvedLightDistance = LightDistance; ResolvedFogMultiplier = FogDistanceMultiplier; ResolvedViewDistance = ViewDistance; ResolvedAnisotropicFiltering = AnisotropicFiltering; ResolvedTextureQuality = TextureQuality; int resolvedShadowBudget = ((ShadowBudget != -1) ? ShadowBudget : (ResolvedShadowQuality switch { ShadowQuality.Ultra => 25, ShadowQuality.High => 20, ShadowQuality.Medium => 15, _ => 10, })); ResolvedShadowBudget = resolvedShadowBudget; } ApplyFogClamps(); Plugin.Log.LogDebug((object)($"Resolved [{preset}]: {ResolvedUpscaleMode} {ResolvedRenderScale}% " + $"AA={ResolvedAAMode} shadows={ResolvedShadowQuality}/{ResolvedShadowDistance}m " + $"LOD={ResolvedLODBias} lights={ResolvedPixelLightCount} " + $"fogEnd={ResolvedEffectiveFogEnd:F0}m lightDist={ResolvedLightDistance:F0}m")); } internal static void ApplyFogClamps() { if (UpscalerManager._vanillaSaved) { ResolvedEffectiveFogEnd = UpscalerManager._vanillaFogEnd * ResolvedFogMultiplier; } float resolvedEffectiveFogEnd = ResolvedEffectiveFogEnd; if (!(resolvedEffectiveFogEnd <= 0f)) { ResolvedShadowDistance = Mathf.Min(ResolvedShadowDistance, resolvedEffectiveFogEnd * 1.1f); ResolvedLightDistance = Mathf.Min(ResolvedLightDistance, resolvedEffectiveFogEnd * 1.2f); } } private static void SyncCustomToResolved() { _file.SuppressEvents(delegate { UpscaleMode upscaler = ((ResolvedUpscaleMode == UpscaleMode.DLAA) ? UpscaleMode.DLSS : ResolvedUpscaleMode); D.upscaler = (int)upscaler; D.renderScale = ResolvedRenderScale; D.aaMode = (int)ResolvedAAMode; D.shadowQuality = (int)ResolvedShadowQuality; D.shadowDistance = ResolvedShadowDistance; D.lodBias = ResolvedLODBias; D.pixelLightCount = ResolvedPixelLightCount; D.lightDistance = ResolvedLightDistance; D.fogMultiplier = ResolvedFogMultiplier; D.viewDistance = ResolvedViewDistance; SettingsData d = D; d.sharpening = Preset switch { QualityPreset.Potato => 0f, QualityPreset.Low => 0f, QualityPreset.Medium => 0f, QualityPreset.High => 0.5f, QualityPreset.Ultra => 0.3f, QualityPreset.Auto => _autoTune.sharpening, _ => D.sharpening, }; D.anisotropicFiltering = ResolvedAnisotropicFiltering; D.textureQuality = (int)ResolvedTextureQuality; D.shadowBudget = ResolvedShadowBudget; }); _file.Save(); } internal static string[] GetAvailableResolutions(out int currentIndex) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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) Resolution val; int num; if (Display.main == null || Display.main.systemWidth <= 0) { val = Screen.currentResolution; num = ((Resolution)(ref val)).width; } else { num = Display.main.systemWidth; } int width = num; int num2; if (Display.main == null || Display.main.systemHeight <= 0) { val = Screen.currentResolution; num2 = ((Resolution)(ref val)).height; } else { num2 = Display.main.systemHeight; } int height = num2; val = default(Resolution); ((Resolution)(ref val)).width = width; ((Resolution)(ref val)).height = height; Resolution val2 = val; float num3 = (float)((Resolution)(ref val2)).width / (float)((Resolution)(ref val2)).height; int num4 = 720; HashSet hashSet = new HashSet(); List list = new List(); Resolution[] resolutions = Screen.resolutions; for (int i = 0; i < resolutions.Length; i++) { Resolution val3 = resolutions[i]; if (((Resolution)(ref val3)).height >= num4 && !(Mathf.Abs((float)((Resolution)(ref val3)).width / (float)((Resolution)(ref val3)).height - num3) > 0.05f)) { string item = $"{((Resolution)(ref val3)).width}x{((Resolution)(ref val3)).height}"; if (hashSet.Add(item)) { list.Add(item); } } } float[] array = new float[4] { 0.5f, 0.6667f, 0.75f, 0.8333f }; foreach (float num5 in array) { int num6 = Mathf.RoundToInt((float)((Resolution)(ref val2)).width * num5 / 8f) * 8; int num7 = Mathf.RoundToInt((float)num6 / num3 / 8f) * 8; if (num7 >= num4) { string item2 = $"{num6}x{num7}"; if (hashSet.Add(item2)) { list.Add(item2); } } } string item3 = $"{((Resolution)(ref val2)).width}x{((Resolution)(ref val2)).height}"; if (!hashSet.Contains(item3)) { list.Add(item3); } list.Sort(delegate(string a, string b) { int num8 = int.Parse(a.Split('x')[0]); int value = int.Parse(b.Split('x')[0]); return num8.CompareTo(value); }); string item4 = $"{OutputWidth}x{OutputHeight}"; currentIndex = list.IndexOf(item4); if (currentIndex < 0) { currentIndex = 0; } return list.ToArray(); } internal static void SetResolution(string wxh) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) string[] array = wxh.Split('x'); if (array.Length == 2) { int num = int.Parse(array[0]); int num2 = int.Parse(array[1]); D.resWidth = num; D.resHeight = num2; _file.Save(); Screen.SetResolution(num, num2, Screen.fullScreenMode); Plugin.Log.LogDebug((object)$"Resolution: {num}x{num2}"); if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(WaitForResolutionThenChange(num, num2)); } else { OnChanged(); } } } private static IEnumerator WaitForResolutionThenChange(int targetW, int targetH) { for (int i = 0; i < 30; i++) { if (Screen.width == targetW && Screen.height == targetH) { break; } yield return null; } OnChanged(); } internal static int MinRenderScale(UpscaleMode mode) { return mode switch { UpscaleMode.DLSS => 33, UpscaleMode.DLAA => 100, UpscaleMode.FSR4 => 50, UpscaleMode.FSR_Temporal => 50, UpscaleMode.FSR => 50, UpscaleMode.Off => 50, _ => 50, }; } private static UpscaleMode BestUpscaler(UpscaleTier tier) { return tier switch { UpscaleTier.Budget => GPUDetector.IsIntegratedGpu ? UpscaleMode.Off : UpscaleMode.FSR_Temporal, UpscaleTier.NativeAA => GPUDetector.DlssAvailable ? UpscaleMode.DLAA : UpscaleMode.FSR_Temporal, _ => GPUDetector.DlssAvailable ? UpscaleMode.DLSS : UpscaleMode.FSR_Temporal, }; } internal static void ApplyPreset(QualityPreset preset) { bool cpuBound = CpuBound; switch (preset) { case QualityPreset.Potato: ResolvedUpscaleMode = UpscaleMode.Off; ResolvedRenderScale = 50; ResolvedAAMode = AAMode.Off; ResolvedShadowQuality = ShadowQuality.Low; ResolvedShadowDistance = 10f; ResolvedLODBias = 0.5f; ResolvedPixelLightCount = 2; ResolvedLightDistance = 10f; ResolvedFogMultiplier = 0.85f; ResolvedViewDistance = 0f; ResolvedAnisotropicFiltering = 2; ResolvedTextureQuality = TextureRes.Full; ResolvedShadowBudget = 5; break; case QualityPreset.Low: ResolvedUpscaleMode = UpscaleMode.Off; ResolvedRenderScale = (cpuBound ? 100 : 50); ResolvedAAMode = AAMode.SMAA; ResolvedShadowQuality = ShadowQuality.Low; ResolvedShadowDistance = 20f; ResolvedLODBias = 1f; ResolvedPixelLightCount = 4; ResolvedLightDistance = 20f; ResolvedFogMultiplier = 1f; ResolvedViewDistance = 0f; ResolvedAnisotropicFiltering = 4; ResolvedTextureQuality = TextureRes.Full; ResolvedShadowBudget = 10; break; case QualityPreset.Medium: ResolvedUpscaleMode = UpscaleMode.Off; ResolvedRenderScale = (cpuBound ? 100 : 75); ResolvedAAMode = AAMode.SMAA; ResolvedShadowQuality = ShadowQuality.Medium; ResolvedShadowDistance = 30f; ResolvedLODBias = 1.5f; ResolvedPixelLightCount = 6; ResolvedLightDistance = 25f; ResolvedFogMultiplier = 1f; ResolvedViewDistance = 0f; ResolvedAnisotropicFiltering = 8; ResolvedTextureQuality = TextureRes.Full; ResolvedShadowBudget = 15; break; case QualityPreset.High: if (cpuBound) { ResolvedUpscaleMode = (GPUDetector.DlssAvailable ? UpscaleMode.DLAA : UpscaleMode.Off); ResolvedRenderScale = 100; ResolvedAAMode = (GPUDetector.DlssAvailable ? AAMode.Off : AAMode.SMAA); } else { ResolvedUpscaleMode = BestUpscaler(UpscaleTier.Quality); ResolvedRenderScale = 75; ResolvedAAMode = AAMode.Off; } ResolvedShadowQuality = ShadowQuality.High; ResolvedShadowDistance = 85f; ResolvedLODBias = 3f; ResolvedPixelLightCount = 8; ResolvedLightDistance = 45f; ResolvedFogMultiplier = 1.1f; ResolvedViewDistance = 0f; ResolvedAnisotropicFiltering = 16; ResolvedTextureQuality = TextureRes.Full; ResolvedShadowBudget = 20; break; case QualityPreset.Ultra: if (cpuBound) { ResolvedUpscaleMode = (GPUDetector.DlssAvailable ? UpscaleMode.DLAA : UpscaleMode.Off); ResolvedRenderScale = 100; ResolvedAAMode = (GPUDetector.DlssAvailable ? AAMode.Off : AAMode.SMAA); } else { ResolvedUpscaleMode = BestUpscaler(UpscaleTier.NativeAA); ResolvedRenderScale = 100; ResolvedAAMode = AAMode.Off; } ResolvedShadowQuality = ShadowQuality.Ultra; ResolvedShadowDistance = 150f; ResolvedLODBias = 4f; ResolvedPixelLightCount = 16; ResolvedLightDistance = 75f; ResolvedFogMultiplier = 1.1f; ResolvedViewDistance = 0f; ResolvedAnisotropicFiltering = 16; ResolvedTextureQuality = TextureRes.Full; ResolvedShadowBudget = 25; break; case QualityPreset.Auto: ApplyAutoTune(); break; case QualityPreset.Custom: break; } } private static void ApplyAutoTune() { if (_autoTune.IsStale()) { QualityPreset qualityPreset = GPUDetector.Tier switch { GpuTier.High => QualityPreset.High, GpuTier.Mid => QualityPreset.Medium, _ => QualityPreset.Low, }; Plugin.Log.LogDebug((object)$"Auto: no valid autotune profile, using {qualityPreset} as fallback (GPU tier {GPUDetector.Tier})"); ApplyPreset(qualityPreset); return; } AutoTuneData autoTune = _autoTune; ResolvedUpscaleMode = (UpscaleMode)autoTune.upscaler; ResolvedRenderScale = autoTune.renderScale; ResolvedAAMode = (AAMode)autoTune.aaMode; ResolvedShadowQuality = (ShadowQuality)autoTune.shadowQuality; ResolvedShadowDistance = autoTune.shadowDistance; ResolvedLODBias = autoTune.lodBias; ResolvedPixelLightCount = autoTune.pixelLightCount; ResolvedLightDistance = autoTune.lightDistance; ResolvedFogMultiplier = autoTune.fogMultiplier; ResolvedViewDistance = autoTune.viewDistance; ResolvedAnisotropicFiltering = autoTune.anisotropicFiltering; ResolvedTextureQuality = TextureRes.Full; ResolvedShadowBudget = ResolvedShadowQuality switch { ShadowQuality.Ultra => 25, ShadowQuality.High => 20, ShadowQuality.Medium => 15, _ => 10, }; if (autoTune.cpuBound) { ResolvedShadowBudget = Mathf.Max(ResolvedShadowBudget - 7, 8); } } internal static void AutoSelectPreset(float avgFpsRaw, float low1Fps, float low01Fps, bool cpuBound = false) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Resolution currentResolution = Screen.currentResolution; RefreshRate refreshRateRatio = ((Resolution)(ref currentResolution)).refreshRateRatio; int num = Mathf.Max((int)Mathf.Round((float)((RefreshRate)(ref refreshRateRatio)).value), 60); float target = num; float num2 = ((low01Fps > 0f) ? low01Fps : low1Fps); float num3 = avgFpsRaw * 0.5f + low1Fps * 0.3f + num2 * 0.2f; int num4 = Object.FindObjectsOfType().Length; float num5 = Mathf.Clamp(3000f / Mathf.Max((float)num4, 1500f), 0.85f, 1f); float num6 = num3 * num5 * 0.92f; Plugin.Log.LogInfo((object)($"Auto-tune inputs: avg={avgFpsRaw:F0} 1%={low1Fps:F0} 0.1%={num2:F0} " + $"renderers={num4} weighted={num3:F0} sceneFactor={num5:F2} " + string.Format("primary={0:F0} target={1}Hz {2}", num6, target, cpuBound ? "CPU-BOUND" : "gpu-bound"))); int scale = 100; ShadowQuality shQ = ShadowQuality.Ultra; float shD = 150f; float lod = 4f; float lDist = 75f; float sharpening = 0.3f; float fog = 1.1f; int lights = 16; int af = 16; TextureRes tex = TextureRes.Full; UpscaleMode upscaleMode; AAMode aAMode; if (cpuBound) { if (GPUDetector.DlssAvailable) { upscaleMode = UpscaleMode.DLAA; aAMode = AAMode.Off; Plugin.Log.LogInfo((object)"CPU-bound + NVIDIA: using DLAA"); } else if (GPUDetector.IsUpscalerSupported(UpscaleMode.FSR_Temporal) && avgFpsRaw / target >= 1.1f) { upscaleMode = UpscaleMode.FSR_Temporal; aAMode = AAMode.Off; Plugin.Log.LogInfo((object)$"CPU-bound + headroom: using FSR Temporal (headroom={avgFpsRaw / target:F2})"); } else { upscaleMode = UpscaleMode.Off; aAMode = AAMode.SMAA; Plugin.Log.LogInfo((object)"CPU-bound: using SMAA"); } } else { upscaleMode = BestUpscaler(UpscaleTier.Quality); aAMode = AAMode.Off; } float ultraCost = GpuCost(scale, shQ, shD, lod, lights, lDist, af, tex, fog); float num7 = GpuCost(ResolvedRenderScale, ResolvedShadowQuality, ResolvedShadowDistance, ResolvedLODBias, ResolvedPixelLightCount, ResolvedLightDistance, ResolvedAnisotropicFiltering, ResolvedTextureQuality, ResolvedFogMultiplier); float estUltra = num6 * (num7 / ultraCost); float num8 = estUltra / target; int num9 = MinRenderScale(upscaleMode); if (cpuBound) { float num10 = num6 / target; Plugin.Log.LogInfo((object)$"CPU-bound: headroom={num10:F2} (avgFps={num6:F0} target={target:F0})"); if (num10 < 0.95f) { shD = 100f; if (num10 < 0.9f) { lDist = 50f; } if (num10 < 0.8f) { shD = 75f; lights = 12; } if (num10 < 0.7f) { shD = 50f; lights = 10; } if (num10 < 0.6f) { shD = 35f; lights = 8; lDist = 35f; } if (num10 < 0.5f) { shD = 25f; lights = 6; lDist = 25f; } if (num10 < 0.4f) { shD = 15f; lights = 4; lDist = 15f; shQ = ShadowQuality.High; lod = 2f; af = 8; } if (num10 < 0.3f) { shQ = ShadowQuality.Medium; lod = 1f; af = 4; } if (num10 < 0.2f) { shQ = ShadowQuality.Low; if (upscaleMode == UpscaleMode.Off || upscaleMode == UpscaleMode.DLAA) { upscaleMode = BestUpscaler(UpscaleTier.Quality); aAMode = AAMode.Off; num9 = MinRenderScale(upscaleMode); } scale = Mathf.Clamp(Mathf.RoundToInt(75f * Mathf.Sqrt(Mathf.Max(num10, 0.1f) / 0.2f)), num9, 80); } } else if (num10 > 1.15f) { sharpening = 0.4f; if (num10 > 1.3f) { lod = 5f; } if (num10 > 1.5f) { lod = 6f; shD = 175f; } if (num10 > 1.8f) { shD = 200f; } } } else { if (num8 < 1f) { af = 8; num8 = Rebudget(); } if (num8 < 1f) { fog = 1f; num8 = Rebudget(); } if (num8 < 1f) { lod = 2f; num8 = Rebudget(); } if (num8 < 1f) { lDist = 35f; num8 = Rebudget(); } if (num8 < 1f) { lights = 8; num8 = Rebudget(); } if (num8 < 1f) { shD = 50f; num8 = Rebudget(); } if (num8 < 1f) { shQ = ShadowQuality.High; num8 = Rebudget(); } if (num8 < 1f) { shQ = ShadowQuality.Medium; num8 = Rebudget(); } if (num8 < 1f) { if (upscaleMode == UpscaleMode.Off) { upscaleMode = BestUpscaler(UpscaleTier.Quality); aAMode = AAMode.Off; num9 = MinRenderScale(upscaleMode); } scale = Mathf.Clamp(Mathf.RoundToInt(100f * Mathf.Sqrt(num8)), num9, 100); num8 = Rebudget(); } if (num8 < 0.8f) { shQ = ShadowQuality.Low; shD = 25f; lights = 4; lDist = 15f; af = 4; lod = 1f; scale = Mathf.Clamp(Mathf.RoundToInt((float)scale * 0.8f), num9, 100); } if (num8 < 0.5f) { upscaleMode = BestUpscaler(UpscaleTier.Budget); num9 = MinRenderScale(upscaleMode); scale = Mathf.Clamp(Mathf.RoundToInt((float)scale * 0.7f), num9, 100); shQ = ShadowQuality.Low; shD = 10f; lights = 2; lDist = 10f; af = 2; lod = 0.5f; aAMode = AAMode.Off; sharpening = 0f; } if (scale >= 100) { upscaleMode = BestUpscaler(UpscaleTier.NativeAA); aAMode = AAMode.Off; } if (num8 > 1.3f) { shD = 200f; num8 = Rebudget(); } if (num8 > 1.3f) { lDist = 100f; num8 = Rebudget(); } if (num8 > 1.5f) { lod = 5f; num8 = Rebudget(); } if (num8 > 1.5f) { sharpening = 0.4f; } } int num11 = ((!cpuBound) ? (shQ switch { ShadowQuality.Ultra => 0, ShadowQuality.High => 1, ShadowQuality.Medium => 2, _ => 3, }) : 3); int num12 = num11; Plugin.Log.LogInfo((object)($"Auto-tune result: {upscaleMode} {scale}% AA={aAMode} shQ={shQ} shD={shD} " + $"lod={lod} lights={lights} lDist={lDist} af={af} tex={tex} fog={fog} perfLevel={num12}")); SaveAutoTune(new AutoTuneData { version = "1.7.7", revision = 7, gpuName = (SystemInfo.graphicsDeviceName ?? ""), resWidth = Screen.width, resHeight = Screen.height, cpuBound = cpuBound, upscaler = (int)upscaleMode, renderScale = scale, sharpening = sharpening, aaMode = (int)aAMode, shadowQuality = (int)shQ, shadowDistance = shD, lodBias = lod, pixelLightCount = lights, lightDistance = lDist, fogMultiplier = fog, anisotropicFiltering = af, perfLevel = num12 }); float Rebudget() { float num13 = GpuCost(scale, shQ, shD, lod, lights, lDist, af, tex, fog); return estUltra / (num13 / ultraCost) / target; } } private static float GpuCost(int scale, ShadowQuality shQ, float shD, float lod, int lights, float lDist, int af, TextureRes tex, float fog) { float num = (float)scale / 100f; float num2 = num * num * 0.45f; float num3 = num2 + shQ switch { ShadowQuality.Ultra => 0.25f, ShadowQuality.High => 0.15f, ShadowQuality.Medium => 0.08f, _ => 0.03f, } + Mathf.Min(shD, 150f) / 200f * 0.08f + (float)lights / 16f * 0.03f + lDist / 100f * 0.02f + lod / 4f * 0.02f; return Mathf.Max(num3 + tex switch { TextureRes.Full => 0.04f, TextureRes.Half => 0.02f, _ => 0.01f, } + (float)af / 16f * 0.01f + Mathf.Max(fog - 1f, 0f) / 4f * 0.03f, 0.05f); } } internal class SettingsFile { private readonly string _path; private SettingsData _data; private bool _suppressSave; internal SettingsData Data => _data; internal event Action? Changed; internal SettingsFile(string path) { _path = path; _data = new SettingsData(); Load(); } internal void Load() { if (!File.Exists(_path)) { return; } try { SettingsData settingsData = JsonUtility.FromJson(File.ReadAllText(_path)); if (settingsData != null) { _data = settingsData; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to load settings: " + ex.Message)); } } internal void Save() { if (_suppressSave) { return; } try { string directoryName = Path.GetDirectoryName(_path); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(_path, JsonUtility.ToJson((object)_data, true)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to save settings: " + ex.Message)); } } internal void NotifyChanged() { if (!_suppressSave) { this.Changed?.Invoke(); } } internal void SuppressEvents(Action action) { _suppressSave = true; try { action(); } finally { _suppressSave = false; } } } [Serializable] internal class AutoTuneData { public string version = ""; public string gpuName = ""; public int resWidth; public int resHeight; public bool cpuBound; public int upscaler; public int renderScale = 100; public float sharpening = 0.3f; public int aaMode = 4; public int shadowQuality = 3; public float shadowDistance = 150f; public float lodBias = 4f; public int pixelLightCount = 16; public float lightDistance = 75f; public float fogMultiplier = 1.1f; public float viewDistance; public int anisotropicFiltering = 16; public int perfLevel; internal const int AutoTuneRevision = 7; public int revision; internal bool IsStale() { if (revision >= 7 && !(gpuName != SystemInfo.graphicsDeviceName)) { if (resWidth > 0) { if (resWidth == Screen.width) { return resHeight != Screen.height; } return true; } return false; } return true; } } [Serializable] internal class SettingsData { public int preset = 6; public string gpuName = ""; public int resWidth; public int resHeight; public int upscaler; public int renderScale = 67; public float sharpening = 0.5f; public int aaMode; public bool pixelation; public int shadowQuality = 3; public float shadowDistance = 75f; public float lodBias = 3f; public int anisotropicFiltering = 16; public int pixelLightCount = 6; public int textureQuality; public float lightDistance = 30f; public float fogMultiplier = 1f; public float viewDistance; public bool motionBlur; public bool chromaticAberration; public bool lensDistortion; public bool filmGrain = true; public bool extractionFlickerFix = true; public bool sharpHud = true; public int verticalFovOverride; public bool ultrawideUiFix = true; public bool ultrawideHudUnstretch = true; public int shadowBudget = -1; public int perfExplosionShadows = -1; public int perfItemLightShadows = -1; public int perfAnimatedLightShadows = -1; public int perfParticleShadows = -1; public int perfTinyRendererCulling = -1; public int perfDistanceShadowCulling = -1; public int perfFlashlightShadowBudget = -1; public int perfPointLightShadows = -1; public bool cpuBound = true; public int cpuPatchMode = -1; public int toggleKey = 291; public int f11Target; public bool debugOverlay; public bool benchmark; public bool autoConfigured; public string autoConfigVersion = ""; } internal class UpscalerManager : MonoBehaviour { internal enum RenderTier { Passthrough, NativeScaling, Upscaler } private IUpscaler? _upscaler; private RenderTextureMain? _renderTextureMain; private Camera? _camera; private RenderTexture? _outputRT; private int _inputWidth; private int _inputHeight; private int _outputWidth; private int _outputHeight; private bool _useCameraCallback; private bool _repoHdDetected; private int _jitterIndex; private Matrix4x4 _savedProjectionMatrix; private bool _jitterApplied; private static readonly float[] HaltonX = GenerateHalton(2, 32); private static readonly float[] HaltonY = GenerateHalton(3, 32); private bool _togglePending; private bool _benchmarkActive; private bool _autoBenchmark; private float _benchmarkTimer; private float _benchmarkWarmup; private readonly List _benchmarkFrameTimes = new List(); private int _benchmarkVsyncPrev; private int _benchmarkPhase; private float _lowGpuFps; private int _savedRenderScale; private const float BenchmarkDuration = 15f; private const float AutoBenchmarkDuration = 12f; private const float Phase0Duration = 4f; private const float WarmupDuration = 3f; private const float ThermalSafetyFactor = 0.9f; private float _shadowBudgetTimer; private const float ShadowBudgetInterval = 0.1f; private int _benchmarkFpsPrev; internal static float _vanillaFogStart; internal static float _vanillaFogEnd; internal static bool _vanillaSaved; internal static int _environmentSetupCount; internal static float _lastEnvironmentSetupTime; internal static readonly Dictionary _vanillaFarClipByCam = new Dictionary(); internal RenderTier CurrentTier { get; private set; } internal static UpscalerManager? Instance { get; private set; } internal static bool RepoHdDetected { get { if ((Object)(object)Instance != (Object)null) { return Instance._repoHdDetected; } return false; } } internal static bool BenchmarkActive { get { if ((Object)(object)Instance != (Object)null) { return Instance._benchmarkActive; } return false; } } internal static bool AutoBenchmarkRunning { get { if ((Object)(object)Instance != (Object)null) { return Instance._autoBenchmark; } return false; } } internal static float BenchmarkProgress { get { if ((Object)(object)Instance == (Object)null || !Instance._benchmarkActive) { return 0f; } float num = 4f; float num2 = (Instance._autoBenchmark ? 12f : 15f); float num3 = 3f + num + 3f + num2; float num4 = ((Instance._benchmarkPhase != 0) ? (3f + num + (3f - Instance._benchmarkWarmup) + ((Instance._benchmarkWarmup > 0f) ? 0f : Instance._benchmarkTimer)) : (3f - Instance._benchmarkWarmup + ((Instance._benchmarkWarmup > 0f) ? 0f : Instance._benchmarkTimer))); return Mathf.Clamp01(num4 / num3); } } internal float JitterX { get; private set; } internal float JitterY { get; private set; } private void Awake() { Instance = this; Settings.OnSettingsChanged += Reinitialize; _repoHdDetected = Chainloader.PluginInfos.ContainsKey("BlueAmulet.REPO_HD"); } internal void Reinitialize() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown if (!((Object)(object)_renderTextureMain == (Object)null) && !((Object)(object)_camera == (Object)null)) { Plugin.Log.LogDebug((object)"Reinitializing upscaler pipeline..."); Camera.onPreRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(OnPreRenderJitter)); Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRenderRestore)); if (_useCameraCallback) { Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRenderCallback)); } _upscaler?.Dispose(); _upscaler = null; if ((Object)(object)_camera != (Object)null) { _camera.targetTexture = null; } ReleaseRT(ref _outputRT); _useCameraCallback = false; if ((Object)(object)_renderTextureMain != (Object)null && (Object)(object)_camera != (Object)null) { Setup(_renderTextureMain, _camera); } QualityPatch.ApplyQualitySettings(); RenderTexturePatch.ReapplyModCameraSettings(); } } internal void Setup(RenderTextureMain rtMain, Camera camera) { _renderTextureMain = rtMain; _camera = camera; _outputWidth = Settings.OutputWidth; _outputHeight = Settings.OutputHeight; _upscaler = Settings.ResolvedUpscaleMode switch { UpscaleMode.FSR_Temporal => new TemporalUpscaler(), UpscaleMode.DLSS => new DLSSUpscaler(), UpscaleMode.DLAA => new DLSSUpscaler(dlaaMode: true), _ => null, }; if (_upscaler != null && !_upscaler.IsAvailable) { Plugin.Log.LogWarning((object)(_upscaler.Name + " unavailable, falling back to FSR Temporal")); _upscaler = new TemporalUpscaler(); Settings.ResolvedUpscaleMode = UpscaleMode.FSR_Temporal; if (!_upscaler.IsAvailable) { Plugin.Log.LogWarning((object)"FSR also unavailable, no upscaling"); _upscaler = null; Settings.ResolvedUpscaleMode = UpscaleMode.Off; if (Settings.ResolvedRenderScale < 100) { Plugin.Log.LogWarning((object)"No upscaler available, forcing native render scale"); Settings.ResolvedRenderScale = 100; } } } bool flag = Settings.Sharpening > 0.01f; bool flag2 = Settings.ResolvedRenderScale < 100; if (_upscaler != null) { CurrentTier = RenderTier.Upscaler; } else if (flag || flag2) { CurrentTier = RenderTier.NativeScaling; } else { CurrentTier = RenderTier.Passthrough; } _useCameraCallback = _upscaler is DLSSUpscaler; switch (CurrentTier) { case RenderTier.Passthrough: SetupPassthrough(rtMain); break; case RenderTier.NativeScaling: SetupNativeScaling(rtMain); break; case RenderTier.Upscaler: SetupUpscaler(rtMain, camera); break; } } private void SetupPassthrough(RenderTextureMain rtMain) { if ((Object)(object)_camera != (Object)null && (Object)(object)rtMain.renderTexture != (Object)null) { _camera.targetTexture = rtMain.renderTexture; } } private void SetupNativeScaling(RenderTextureMain rtMain) { if ((Object)(object)_camera != (Object)null && (Object)(object)rtMain.renderTexture != (Object)null) { _camera.targetTexture = rtMain.renderTexture; } } private void SetupUpscaler(RenderTextureMain rtMain, Camera camera) { //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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown float renderScale = RenderTexturePatch.GetRenderScale(); _inputWidth = Mathf.Max(Mathf.RoundToInt((float)_outputWidth * renderScale), 1); _inputHeight = Mathf.Max(Mathf.RoundToInt((float)_outputHeight * renderScale), 1); RenderTexture renderTexture = rtMain.renderTexture; RenderTextureFormat val = (RenderTextureFormat)((!((Object)(object)renderTexture != (Object)null)) ? 9 : ((int)renderTexture.format)); _outputRT = new RenderTexture(_inputWidth, _inputHeight, 24, val) { filterMode = (FilterMode)1, enableRandomWrite = true }; _outputRT.Create(); camera.targetTexture = _outputRT; if ((Object)(object)renderTexture != (Object)null) { renderTexture.Release(); ((Texture)renderTexture).width = _outputWidth; ((Texture)renderTexture).height = _outputHeight; renderTexture.Create(); } Plugin.Log.LogDebug((object)$"Upscaler: {_inputWidth}x{_inputHeight} -> {_outputWidth}x{_outputHeight}"); if (_upscaler != null && (Object)(object)_camera != (Object)null) { _upscaler.Initialize(_camera, _inputWidth, _inputHeight, _outputWidth, _outputHeight); Plugin.Log.LogDebug((object)("Upscaler active: " + _upscaler.Name)); } if (_upscaler != null && (Object)(object)_camera != (Object)null) { Camera.onPreRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(OnPreRenderJitter)); Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRenderRestore)); } if (_useCameraCallback && (Object)(object)_camera != (Object)null) { Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRenderCallback)); } } private void OnPreRenderJitter(Camera cam) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam != (Object)(object)_camera) && _upscaler != null && Settings.ModEnabled && _inputWidth > 0 && _inputHeight > 0) { _jitterIndex = (_jitterIndex + 1) % HaltonX.Length; JitterX = (HaltonX[_jitterIndex] - 0.5f) / (float)_inputWidth; JitterY = (HaltonY[_jitterIndex] - 0.5f) / (float)_inputHeight; cam.ResetProjectionMatrix(); _savedProjectionMatrix = cam.projectionMatrix; cam.nonJitteredProjectionMatrix = _savedProjectionMatrix; Matrix4x4 savedProjectionMatrix = _savedProjectionMatrix; savedProjectionMatrix.m02 += JitterX * 2f; savedProjectionMatrix.m12 += JitterY * 2f; cam.projectionMatrix = savedProjectionMatrix; _jitterApplied = true; } } private void OnPostRenderRestore(Camera cam) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam != (Object)(object)_camera) && _jitterApplied) { cam.projectionMatrix = _savedProjectionMatrix; _jitterApplied = false; } } private void OnPostRenderCallback(Camera cam) { if (!((Object)(object)cam != (Object)(object)_camera)) { ProcessFrame(); } } private static float[] GenerateHalton(int baseVal, int count) { float[] array = new float[count]; for (int i = 0; i < count; i++) { float num = 1f; float num2 = 0f; for (int num3 = i + 1; num3 > 0; num3 /= baseVal) { num /= (float)baseVal; num2 += num * (float)(num3 % baseVal); } array[i] = num2; } return array; } private void LateUpdate() { if (!Settings.ModEnabled || (Object)(object)_renderTextureMain == (Object)null || CurrentTier == RenderTier.Passthrough) { return; } int outputWidth = Settings.OutputWidth; int outputHeight = Settings.OutputHeight; if (outputWidth != _outputWidth || outputHeight != _outputHeight) { _outputWidth = outputWidth; _outputHeight = outputHeight; HandleResolutionChange(); } if (CurrentTier == RenderTier.NativeScaling) { if (Settings.Sharpening > 0.01f) { RenderTexture renderTexture = _renderTextureMain.renderTexture; if ((Object)(object)renderTexture != (Object)null) { ApplyCAS(renderTexture); } } } else { if ((Object)(object)_camera != (Object)null && (Object)(object)_outputRT != (Object)null && (Object)(object)_camera.targetTexture != (Object)(object)_outputRT) { _camera.targetTexture = _outputRT; } if (!_useCameraCallback) { ProcessFrame(); } } } private void ProcessFrame() { if ((Object)(object)_renderTextureMain == (Object)null || _upscaler == null || (Object)(object)_outputRT == (Object)null || !_outputRT.IsCreated()) { return; } RenderTexture renderTexture = _renderTextureMain.renderTexture; if (!((Object)(object)renderTexture == (Object)null) && renderTexture.IsCreated()) { _upscaler.OnRenderImage(_outputRT, renderTexture); if (!(_upscaler is DLSSUpscaler) && Settings.Sharpening > 0.01f) { ApplyCAS(renderTexture); } } } private static void ApplyCAS(RenderTexture target) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && target.IsCreated()) { RenderTexture temporary = RenderTexture.GetTemporary(((Texture)target).width, ((Texture)target).height, 0, target.format); CASShader.Apply(target, temporary, Settings.Sharpening); Graphics.Blit((Texture)(object)temporary, target); RenderTexture.ReleaseTemporary(temporary); } } private void Update() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) _shadowBudgetTimer += Time.unscaledDeltaTime; if (_shadowBudgetTimer >= 0.1f) { _shadowBudgetTimer = 0f; SceneOptimizer.UpdateShadowBudget(_camera); SceneOptimizer.UpdateDistanceShadowCull(_camera); SceneOptimizer.UpdateFlashlightShadowBudget(_camera); SceneOptimizer.UpdatePlayerAvatarShadowCull(_camera); SceneOptimizer.UpdatePointLightShadowCull(_camera); } if (Input.GetKeyDown((KeyCode)292) && (int)Settings.ToggleKey != 292) { DispatchF11(); } Settings.TickDeferredWindowReset(); UltrawideCompareResolution.TickEnforcement(); UltrawideMenuTweaks.Tick(); UltrawideResolutionWatcher.Tick(); OverlayCameraWiden.Tick(); GameCameraAspectGuard.Tick(); if (!_benchmarkActive && !_togglePending && !MenuIntegration.IsGraphicsPageOpen && Input.GetKeyDown(Settings.ToggleKey)) { bool num = !Settings.ModEnabled; PlayGlitch(); if (!num) { Settings.ModEnabled = false; Plugin.Log.LogDebug((object)"Mod DISABLED"); SceneOptimizer.LogRestoreState("pre-disable"); SceneOptimizer.Apply(); _upscaler?.Dispose(); _upscaler = null; if ((Object)(object)_camera != (Object)null && (Object)(object)_renderTextureMain != (Object)null) { _camera.targetTexture = _renderTextureMain.renderTexture; } RenderTexturePatch.RestoreVanillaResolution(); RenderTexturePatch.RestoreVanillaCameraSettings(); RestoreVanillaSettings(); QualityPatch.RestoreVanillaQuality(); PlayerAvatarMenuAAPatch.RestoreAvatarRt(); if ((Object)(object)GraphicsManager.instance != (Object)null) { GraphicsManager.instance.UpdateAll(); } if ((Object)(object)_camera != (Object)null) { _camera.layerCullDistances = new float[32]; } UltrawideCompareResolution.HandleToggle(enabling: false); SceneOptimizer.LogRestoreState("post-disable"); } else { _togglePending = true; ((MonoBehaviour)this).StartCoroutine(DeferredEnable()); UltrawideCompareResolution.HandleToggle(enabling: true); } } if (_benchmarkActive && !IsInGameplayLevel()) { if (_benchmarkPhase == 0) { ApplyBenchmarkScale(_savedRenderScale); } _benchmarkActive = false; _autoBenchmark = false; QualitySettings.vSyncCount = _benchmarkVsyncPrev; Application.targetFrameRate = _benchmarkFpsPrev; Settings.BenchmarkMode = false; } if (Settings.ModEnabled && Settings.AutoTuneNeedsInitialBenchmark && !_benchmarkActive && !_autoBenchmark && _vanillaSaved && IsInGameplayLevel() && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated && Time.unscaledTime - _lastEnvironmentSetupTime >= 10f) { _autoBenchmark = true; StartBenchmark(); Plugin.Log.LogInfo((object)"=== AUTO-BENCHMARK: autotune profile stale, re-detecting ==="); } if (Settings.BenchmarkMode && !_benchmarkActive) { _autoBenchmark = false; StartBenchmark(); Plugin.Log.LogInfo((object)"=== BENCHMARK STARTED ==="); } if (!_benchmarkActive) { return; } if (_benchmarkWarmup > 0f) { _benchmarkWarmup -= Time.unscaledDeltaTime; return; } _benchmarkTimer += Time.unscaledDeltaTime; float num2 = Time.unscaledDeltaTime * 1000f; if (num2 > 0.01f && num2 < 500f) { _benchmarkFrameTimes.Add(num2); } if (_benchmarkPhase == 0) { bool num3 = _benchmarkTimer >= 4f && _benchmarkFrameTimes.Count > 30; bool flag = _benchmarkTimer >= 12f; if (num3 || flag) { FinishPhase0(); } return; } float num4 = (_autoBenchmark ? 12f : 15f); bool num5 = _benchmarkTimer >= num4 && _benchmarkFrameTimes.Count > 30; bool flag2 = _benchmarkTimer >= num4 * 2f; if (num5 || flag2) { FinishBenchmark(); } } private static void PlayGlitch() { CameraGlitch instance = CameraGlitch.Instance; if (!((Object)(object)instance == (Object)null)) { if ((Object)(object)instance.ActiveParent != (Object)null) { instance.ActiveParent.SetActive(true); } instance.PlayShort(); } } private static void DispatchF11() { switch (Settings.F11TargetSetting) { case F11Target.FullOptLayer: Settings.OptimizationsEnabled = !Settings.OptimizationsEnabled; Plugin.Log.LogDebug((object)("F11: Optimizations " + (Settings.OptimizationsEnabled ? "ENABLED" : "DISABLED"))); if (!Settings.OptimizationsEnabled) { SceneOptimizer.LogRestoreState("pre-opt-disable"); } SceneOptimizer.Apply(); QualityPatch.ApplyQualitySettings(); if (!Settings.OptimizationsEnabled) { SceneOptimizer.LogRestoreState("post-opt-disable"); } break; case F11Target.CpuPatches: Settings.CpuPatchesF11Disabled = !Settings.CpuPatchesF11Disabled; Plugin.Log.LogDebug((object)("F11: CPU patches " + (Settings.CpuPatchesF11Disabled ? "DISABLED" : "ENABLED"))); break; } } private IEnumerator DeferredEnable() { yield return null; yield return null; Settings.ModEnabled = true; Plugin.Log.LogDebug((object)"Mod ENABLED"); Reinitialize(); RenderTexturePatch.ReapplyModCameraSettings(); if ((Object)(object)_renderTextureMain != (Object)null) { _renderTextureMain.textureWidthOriginal = Settings.OutputWidth; _renderTextureMain.textureHeightOriginal = Settings.OutputHeight; RenderTexture renderTexture = _renderTextureMain.renderTexture; if ((Object)(object)renderTexture != (Object)null && CurrentTier != RenderTier.Upscaler && (((Texture)renderTexture).width != _outputWidth || ((Texture)renderTexture).height != _outputHeight)) { renderTexture.Release(); ((Texture)renderTexture).width = _outputWidth; ((Texture)renderTexture).height = _outputHeight; renderTexture.Create(); } } float resolvedFogMultiplier = Settings.ResolvedFogMultiplier; if (_vanillaSaved && resolvedFogMultiplier != 1f && !SemiFunc.MenuLevel()) { RenderSettings.fogStartDistance = _vanillaFogStart * resolvedFogMultiplier; RenderSettings.fogEndDistance = _vanillaFogEnd * resolvedFogMultiplier; SetModFarClip(_camera, RenderSettings.fogEndDistance + 10f); } if (_vanillaSaved) { Settings.ResolvedEffectiveFogEnd = _vanillaFogEnd * resolvedFogMultiplier; Settings.ApplyFogClamps(); } SceneOptimizer.Apply(); QualityPatch.ApplyQualitySettings(); PlayerAvatarMenuAAPatch.ReapplyAll(); _togglePending = false; if (Settings.UltrawideUiFix) { UltrawideCanvasFix.RefreshAll(); } } private void HandleResolutionChange() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown if (CurrentTier == RenderTier.Upscaler) { float renderScale = RenderTexturePatch.GetRenderScale(); _inputWidth = Mathf.Max(Mathf.RoundToInt((float)_outputWidth * renderScale), 1); _inputHeight = Mathf.Max(Mathf.RoundToInt((float)_outputHeight * renderScale), 1); RenderTexture val = _renderTextureMain?.renderTexture; ReleaseRT(ref _outputRT); RenderTextureFormat val2 = (RenderTextureFormat)((!((Object)(object)val != (Object)null)) ? 9 : ((int)val.format)); _outputRT = new RenderTexture(_inputWidth, _inputHeight, 24, val2) { filterMode = (FilterMode)1, enableRandomWrite = true }; _outputRT.Create(); if ((Object)(object)_camera != (Object)null) { _camera.targetTexture = _outputRT; } if ((Object)(object)val != (Object)null) { val.Release(); ((Texture)val).width = _outputWidth; ((Texture)val).height = _outputHeight; val.Create(); } if (_upscaler != null) { _upscaler.OnResolutionChanged(_inputWidth, _inputHeight, _outputWidth, _outputHeight); } } } private void StartBenchmark() { _benchmarkActive = true; _benchmarkTimer = 0f; _benchmarkWarmup = 3f; _benchmarkFrameTimes.Clear(); _benchmarkPhase = 0; _lowGpuFps = 0f; _benchmarkVsyncPrev = QualitySettings.vSyncCount; _benchmarkFpsPrev = Application.targetFrameRate; QualitySettings.vSyncCount = 0; Application.targetFrameRate = -1; _savedRenderScale = Settings.ResolvedRenderScale; ApplyBenchmarkScale(25); PlayGlitch(); } private void FinishPhase0() { _benchmarkFrameTimes.Sort(); int count = _benchmarkFrameTimes.Count; float median = _benchmarkFrameTimes[count / 2]; List list = _benchmarkFrameTimes.FindAll((float t) => t <= median * 3f); if (list.Count < 10) { _lowGpuFps = 0f; } else { float num = 0f; for (int num2 = 0; num2 < list.Count; num2++) { num += list[num2]; } _lowGpuFps = 1000f / (num / (float)list.Count); } Plugin.Log.LogInfo((object)$"Phase 0 (CPU ceiling): {_lowGpuFps:F0} FPS at 25% scale"); ApplyBenchmarkScale(_savedRenderScale); PlayGlitch(); _benchmarkPhase = 1; _benchmarkTimer = 0f; _benchmarkWarmup = 3f; _benchmarkFrameTimes.Clear(); } private void ApplyBenchmarkScale(int scale) { //IL_0095: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown Settings.ResolvedRenderScale = scale; int num = Mathf.Max(Mathf.RoundToInt((float)(_outputWidth * scale) / 100f), 1); int num2 = Mathf.Max(Mathf.RoundToInt((float)(_outputHeight * scale) / 100f), 1); if (num == _inputWidth && num2 == _inputHeight) { return; } _inputWidth = num; _inputHeight = num2; if (CurrentTier == RenderTier.Upscaler) { ReleaseRT(ref _outputRT); RenderTexture val = _renderTextureMain?.renderTexture; RenderTextureFormat val2 = (RenderTextureFormat)((!((Object)(object)val != (Object)null)) ? 9 : ((int)val.format)); _outputRT = new RenderTexture(num, num2, 24, val2) { filterMode = (FilterMode)1 }; _outputRT.Create(); if ((Object)(object)_camera != (Object)null) { _camera.targetTexture = _outputRT; } if (_upscaler != null) { _upscaler.OnResolutionChanged(num, num2, _outputWidth, _outputHeight); } } } private void FinishBenchmark() { //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Invalid comparison between Unknown and I4 //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Invalid comparison between Unknown and I4 //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) try { _benchmarkFrameTimes.Sort(); int count = _benchmarkFrameTimes.Count; float median = _benchmarkFrameTimes[count / 2]; List list = _benchmarkFrameTimes.FindAll((float t) => t <= median * 3f); int count2 = list.Count; if (count2 < 10) { Plugin.Log.LogWarning((object)"Benchmark: too few valid frames, skipping auto-tune"); return; } float num = 0f; for (int num2 = 0; num2 < count2; num2++) { num += list[num2]; } float num3 = num / (float)count2; float num4 = 1000f / num3; int num5 = Mathf.Max(count2 / 100, 1); float num6 = 0f; for (int num7 = count2 - num5; num7 < count2; num7++) { num6 += list[num7]; } float num8 = num6 / (float)num5; float num9 = 1000f / num8; float num10 = 0f; if (count2 >= 1000) { int num11 = Mathf.Max(count2 / 1000, 1); float num12 = 0f; for (int num13 = count2 - num11; num13 < count2; num13++) { num12 += list[num13]; } num10 = 1000f / (num12 / (float)num11); } string text = Settings.Preset.ToString(); string text2 = ((_upscaler != null) ? _upscaler.Name : "Off"); string text3 = ((CurrentTier == RenderTier.Upscaler) ? $"{_inputWidth}x{_inputHeight}" : "native"); int num14 = count - count2; bool flag = true; if (_lowGpuFps > 0f && num4 > 0f) { float num15 = num4 / _lowGpuFps; float num16 = ((num4 > 120f) ? 0.95f : 0.85f); flag = num15 >= num16; Plugin.Log.LogInfo((object)$" Ratio: {num15:P1}, threshold: {num16:P0} (fps={num4:F0})"); Resolution currentResolution = Screen.currentResolution; RefreshRate refreshRateRatio = ((Resolution)(ref currentResolution)).refreshRateRatio; float num17 = Mathf.Max((float)((RefreshRate)(ref refreshRateRatio)).value, 60f); bool flag2 = (int)Application.platform == 13 || (int)SystemInfo.graphicsDeviceType == 21; if (!flag && _lowGpuFps < num17) { flag = true; Plugin.Log.LogInfo((object)($" Bottleneck override: CPU ceiling ({_lowGpuFps:F0}) < target ({num17:F0}) " + "-> CPU-BOUND (CPU can't sustain target even at minimum GPU load)")); } else if (!flag && flag2 && num15 < 0.95f) { flag = true; Plugin.Log.LogInfo((object)(" Bottleneck override: translation layer detected " + $"({Application.platform}/{SystemInfo.graphicsDeviceType}), " + $"ratio {num15:P0} < 95% -> CPU-BOUND")); } Plugin.Log.LogInfo((object)($" Bottleneck: {num4:F0} / {_lowGpuFps:F0} ceiling = {num15:P0} " + "-> " + (flag ? "CPU-BOUND" : "GPU-bound"))); } Plugin.Log.LogInfo((object)"=== BENCHMARK RESULTS ==="); Plugin.Log.LogInfo((object)$" Preset: {text} | Upscaler: {text2} | Render: {text3} -> {_outputWidth}x{_outputHeight}"); Plugin.Log.LogInfo((object)$" CPU: {SystemInfo.processorType} ({SystemInfo.processorCount} threads)"); Plugin.Log.LogInfo((object)$" RAM: {SystemInfo.systemMemorySize}MB | Platform: {Application.platform} | API: {SystemInfo.graphicsDeviceType}"); Plugin.Log.LogInfo((object)$" Frames: {count2} measured, {num14} outliers discarded"); Plugin.Log.LogInfo((object)$" Avg: {num4:F1} FPS ({num3:F1}ms)"); Plugin.Log.LogInfo((object)$" 1% Low: {num9:F1} FPS ({num8:F1}ms)"); if (num10 > 0f) { Plugin.Log.LogInfo((object)$" 0.1% Low: {num10:F1} FPS"); } Plugin.Log.LogInfo((object)$" CPU ceiling (25% scale): {_lowGpuFps:F1} FPS | Full scale: {num4:F1} FPS | Ratio: {num4 / Mathf.Max(_lowGpuFps, 1f):P0}"); Plugin.Log.LogInfo((object)"========================="); Settings.AutoSelectPreset(num4, num9, num10, flag); PlayGlitch(); } finally { QualitySettings.vSyncCount = _benchmarkVsyncPrev; Application.targetFrameRate = _benchmarkFpsPrev; if (_autoBenchmark) { _autoBenchmark = false; } _benchmarkActive = false; Settings.BenchmarkMode = false; } } private static bool IsInGameplayLevel() { if ((Object)(object)RunManager.instance == (Object)null) { return false; } return SemiFunc.RunIsLevel(); } private static void ReleaseRT(ref RenderTexture? rt) { if ((Object)(object)rt != (Object)null) { rt.Release(); Object.Destroy((Object)(object)rt); rt = null; } } internal static void SetModFarClip(Camera? cam, float newValue) { if (!((Object)(object)cam == (Object)null) && (!((Object)(object)SpectateCamera.instance != (Object)null) || !SpectateCamera.instance.CheckState((State)0))) { if (!_vanillaFarClipByCam.ContainsKey(cam)) { _vanillaFarClipByCam[cam] = cam.farClipPlane; } cam.farClipPlane = newValue; } } internal static float GetVanillaFarClip(Camera? cam) { if ((Object)(object)cam == (Object)null) { return 0f; } if (!_vanillaFarClipByCam.TryGetValue(cam, out var value)) { return cam.farClipPlane; } return value; } internal static void SaveVanillaFog(EnvironmentDirector env) { _vanillaFogStart = env.FogStartDistance; _vanillaFogEnd = env.FogEndDistance; _vanillaSaved = true; _environmentSetupCount++; _lastEnvironmentSetupTime = Time.unscaledTime; Settings.ResolvedEffectiveFogEnd = _vanillaFogEnd * Settings.ResolvedFogMultiplier; Settings.ApplyFogClamps(); Plugin.Log.LogDebug((object)$"Vanilla fog: start={_vanillaFogStart:F0}m end={_vanillaFogEnd:F0}m (env #{_environmentSetupCount})"); } private void RestoreVanillaSettings() { if (_vanillaSaved) { RenderSettings.fogStartDistance = _vanillaFogStart; RenderSettings.fogEndDistance = _vanillaFogEnd; } foreach (KeyValuePair item in _vanillaFarClipByCam) { if ((Object)(object)item.Key != (Object)null) { item.Key.farClipPlane = item.Value; } } _vanillaFarClipByCam.Clear(); Plugin.Log.LogDebug((object)"Vanilla settings restored"); } private void OnDestroy() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown Settings.OnSettingsChanged -= Reinitialize; Camera.onPreRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(OnPreRenderJitter)); Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRenderRestore)); if (_useCameraCallback) { Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRenderCallback)); } _upscaler?.Dispose(); if ((Object)(object)_camera != (Object)null && (Object)(object)_renderTextureMain != (Object)null) { _camera.targetTexture = _renderTextureMain.renderTexture; } ReleaseRT(ref _outputRT); Instance = null; } } internal static class VRCompat { internal static bool Active { get { if (XRSettings.enabled) { return XRSettings.isDeviceActive; } return false; } } } } namespace REPOFidelity.Upscalers { internal class DLSSUpscaler : IUpscaler { [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void GetDeviceDelegate(IntPtr self, out IntPtr device); private readonly bool _dlaaMode; private bool _probed; private bool _available; private Camera? _camera; private IntPtr _dlssHandle; private IntPtr _evalParams; private int _inputWidth; private int _inputHeight; private int _outputWidth; private int _outputHeight; private RenderTexture? _dlssOutputRT; private RenderTexture? _depthRT; private RenderTexture? _motionVectorRT; private CommandBuffer? _depthCopyCmd; private CommandBuffer? _mvCopyCmd; private int _evalFailCount; private bool _needsReset; public string Name { get { if (!_dlaaMode) { return "DLSS"; } return "DLAA"; } } public bool IsAvailable { get { if (!_probed) { Probe(); } return _available; } } public DLSSUpscaler(bool dlaaMode = false) { _dlaaMode = dlaaMode; } private void Probe() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown if (_probed) { return; } _probed = true; try { if (!DLSSDownloader.EnsureAvailable()) { Plugin.Log.LogWarning((object)"DLSS: nvngx_dlss.dll not available; DLSS disabled"); return; } if (!NGXBridge.Preload()) { Plugin.Log.LogWarning((object)"DLSS: ngx_bridge.dll not available"); return; } NGXBridge.HookLog(); if (NGXBridge.NGXBridge_Load() == 0) { Plugin.Log.LogWarning((object)"DLSS: ngx_bridge failed to load _nvngx.dll"); return; } Texture2D val = new Texture2D(1, 1); IntPtr nativeTexturePtr = ((Texture)val).GetNativeTexturePtr(); Marshal.GetDelegateForFunctionPointer(Marshal.ReadIntPtr(Marshal.ReadIntPtr(nativeTexturePtr), 3 * IntPtr.Size))(nativeTexturePtr, out var device); Object.Destroy((Object)val); if (device == IntPtr.Zero) { Plugin.Log.LogWarning((object)"DLSS: Could not extract D3D11 device"); return; } Plugin.Log.LogDebug((object)$"DLSS: D3D11 device: 0x{device:X}"); if (NGXBridge.NGXBridge_InitD3D11(device) == 0) { Plugin.Log.LogWarning((object)"DLSS: NGX D3D11 base init failed"); return; } if (NGXBridge.NGXBridge_InitD3D12() == 0) { Plugin.Log.LogWarning((object)"DLSS: NGX D3D12 interop init failed"); return; } _available = NGXBridge.NGXBridge_IsDLSSAvailable_D3D12() != 0; Plugin.Log.LogDebug((object)$"DLSS: available = {_available}"); } catch (DllNotFoundException) { Plugin.Log.LogWarning((object)"DLSS: ngx_bridge.dll not found; DLSS disabled"); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("DLSS probe failed: " + ex2.GetType().Name + ": " + ex2.Message)); } } public void Initialize(Camera camera, int inputWidth, int inputHeight, int outputWidth, int outputHeight) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) _camera = camera; _inputWidth = (_dlaaMode ? outputWidth : inputWidth); _inputHeight = (_dlaaMode ? outputHeight : inputHeight); _outputWidth = outputWidth; _outputHeight = outputHeight; NGXBridge.NGXBridge_ClearSharedCache(); RenderTextureFormat val = (RenderTextureFormat)(((Object)(object)_camera != (Object)null && (Object)(object)_camera.targetTexture != (Object)null) ? ((int)_camera.targetTexture.format) : 0); if ((Object)(object)_dlssOutputRT != (Object)null) { _dlssOutputRT.Release(); Object.Destroy((Object)(object)_dlssOutputRT); } _dlssOutputRT = new RenderTexture(_outputWidth, _outputHeight, 0, val) { filterMode = (FilterMode)1, enableRandomWrite = true }; _dlssOutputRT.Create(); RenderTexture active = RenderTexture.active; RenderTexture.active = _dlssOutputRT; GL.Clear(false, true, Color.black); RenderTexture.active = active; SetupCapture(_inputWidth, _inputHeight); _evalParams = NGXBridge.NGXBridge_AllocParams_D3D12(); if (_evalParams == IntPtr.Zero) { Plugin.Log.LogError((object)"DLSS: params alloc failed"); return; } NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "Width", (uint)_inputWidth); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "Height", (uint)_inputHeight); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "OutWidth", (uint)_outputWidth); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "OutHeight", (uint)_outputHeight); NGXBridge.NGXBridge_ParamSetInt(_evalParams, "PerfQualityValue", GetQualityMode()); int val2 = ((!_dlaaMode) ? 2 : 0); NGXBridge.NGXBridge_ParamSetInt(_evalParams, "DLSS.Feature.Create.Flags", val2); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Hint.Render.Preset.DLAA", 5u); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Hint.Render.Preset.Quality", 5u); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Hint.Render.Preset.Balanced", 5u); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Hint.Render.Preset.Performance", 5u); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Hint.Render.Preset.UltraPerformance", 5u); _dlssHandle = NGXBridge.NGXBridge_CreateDLSS_D3D12(_evalParams); if (_dlssHandle == IntPtr.Zero) { Plugin.Log.LogError((object)"DLSS: Feature creation failed"); return; } _needsReset = true; Plugin.Log.LogDebug((object)$"DLSS initialized: {_inputWidth}x{_inputHeight} -> {_outputWidth}x{_outputHeight}"); } public void OnRenderImage(RenderTexture source, RenderTexture destination) { if (_dlssHandle == IntPtr.Zero || _evalParams == IntPtr.Zero) { Graphics.Blit((Texture)(object)source, destination); return; } if (((Texture)source).width != _inputWidth || ((Texture)source).height != _inputHeight) { Graphics.Blit((Texture)(object)source, destination); return; } NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Render.Subrect.Dimensions.Width", (uint)((Texture)source).width); NGXBridge.NGXBridge_ParamSetUInt(_evalParams, "DLSS.Render.Subrect.Dimensions.Height", (uint)((Texture)source).height); NGXBridge.NGXBridge_ParamSetFloat(_evalParams, "MV.Scale.X", 0f - (float)_inputWidth); NGXBridge.NGXBridge_ParamSetFloat(_evalParams, "MV.Scale.Y", 0f - (float)_inputHeight); NGXBridge.NGXBridge_ParamSetFloat(_evalParams, "Jitter.Offset.X", 0f); NGXBridge.NGXBridge_ParamSetFloat(_evalParams, "Jitter.Offset.Y", 0f); NGXBridge.NGXBridge_ParamSetFloat(_evalParams, "Sharpness", 0f); NGXBridge.NGXBridge_ParamSetFloat(_evalParams, "FrameTimeDeltaInMsec", Time.unscaledDeltaTime * 1000f); NGXBridge.NGXBridge_ParamSetInt(_evalParams, "Reset", _needsReset ? 1 : 0); RenderTexture val = _dlssOutputRT ?? destination; if (NGXBridge.NGXBridge_EvalDLSS_D3D12(_dlssHandle, _evalParams, ((Texture)source).GetNativeTexturePtr(), ((Object)(object)_depthRT != (Object)null) ? ((Texture)_depthRT).GetNativeTexturePtr() : IntPtr.Zero, ((Object)(object)_motionVectorRT != (Object)null) ? ((Texture)_motionVectorRT).GetNativeTexturePtr() : IntPtr.Zero, ((Texture)val).GetNativeTexturePtr()) == 0) { if (_evalFailCount++ < 5) { Plugin.Log.LogWarning((object)($"DLSS D3D12 eval failed (frame {_evalFailCount}) " + $"src={((Texture)source).width}x{((Texture)source).height} out={((Texture)val).width}x{((Texture)val).height}")); } Graphics.Blit((Texture)(object)source, destination); } else { _needsReset = false; if ((Object)(object)_dlssOutputRT != (Object)null) { Graphics.Blit((Texture)(object)_dlssOutputRT, destination); } } } public void OnResolutionChanged(int inputWidth, int inputHeight, int outputWidth, int outputHeight) { NGXBridge.NGXBridge_ClearSharedCache(); CleanupFeature(); if ((Object)(object)_camera != (Object)null) { Initialize(_camera, inputWidth, inputHeight, outputWidth, outputHeight); } } public void Dispose() { CleanupCapture(); CleanupFeature(); if ((Object)(object)_dlssOutputRT != (Object)null) { _dlssOutputRT.Release(); Object.Destroy((Object)(object)_dlssOutputRT); _dlssOutputRT = null; } if (_evalParams != IntPtr.Zero) { NGXBridge.NGXBridge_DestroyParams_D3D12(_evalParams); _evalParams = IntPtr.Zero; } } private void CleanupFeature() { if (_dlssHandle != IntPtr.Zero) { NGXBridge.NGXBridge_ReleaseDLSS_D3D12(_dlssHandle); _dlssHandle = IntPtr.Zero; } } private void SetupCapture(int width, int height) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0024: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00aa: 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) CleanupCapture(); _depthRT = new RenderTexture(width, height, 0, (RenderTextureFormat)14) { filterMode = (FilterMode)0, enableRandomWrite = true }; _depthRT.Create(); _depthCopyCmd = new CommandBuffer { name = "DLSS Depth" }; _depthCopyCmd.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)3), RenderTargetIdentifier.op_Implicit((Texture)(object)_depthRT)); _motionVectorRT = new RenderTexture(width, height, 0, (RenderTextureFormat)13) { filterMode = (FilterMode)0, enableRandomWrite = true }; _motionVectorRT.Create(); _mvCopyCmd = new CommandBuffer { name = "DLSS MV" }; _mvCopyCmd.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)15), RenderTargetIdentifier.op_Implicit((Texture)(object)_motionVectorRT)); if ((Object)(object)_camera != (Object)null) { _camera.AddCommandBuffer((CameraEvent)1, _depthCopyCmd); _camera.AddCommandBuffer((CameraEvent)20, _mvCopyCmd); } } private void CleanupCapture() { if ((Object)(object)_camera != (Object)null) { if (_depthCopyCmd != null) { _camera.RemoveCommandBuffer((CameraEvent)1, _depthCopyCmd); } if (_mvCopyCmd != null) { _camera.RemoveCommandBuffer((CameraEvent)20, _mvCopyCmd); } } CommandBuffer? depthCopyCmd = _depthCopyCmd; if (depthCopyCmd != null) { depthCopyCmd.Dispose(); } _depthCopyCmd = null; CommandBuffer? mvCopyCmd = _mvCopyCmd; if (mvCopyCmd != null) { mvCopyCmd.Dispose(); } _mvCopyCmd = null; if ((Object)(object)_depthRT != (Object)null) { _depthRT.Release(); Object.Destroy((Object)(object)_depthRT); _depthRT = null; } if ((Object)(object)_motionVectorRT != (Object)null) { _motionVectorRT.Release(); Object.Destroy((Object)(object)_motionVectorRT); _motionVectorRT = null; } } private int GetQualityMode() { if (_dlaaMode) { return 5; } int resolvedRenderScale = Settings.ResolvedRenderScale; if (resolvedRenderScale >= 59) { if (resolvedRenderScale >= 77) { return 2; } return 1; } if (resolvedRenderScale >= 45) { return 0; } return 3; } } internal interface IUpscaler { string Name { get; } bool IsAvailable { get; } void Initialize(Camera camera, int inputWidth, int inputHeight, int outputWidth, int outputHeight); void OnRenderImage(RenderTexture source, RenderTexture destination); void OnResolutionChanged(int inputWidth, int inputHeight, int outputWidth, int outputHeight); void Dispose(); } internal static class NGXBridge { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void LogCallbackDelegate([MarshalAs(UnmanagedType.LPStr)] string message); private const string DLL = "ngx_bridge"; internal const int DLSS_MaxPerf = 0; internal const int DLSS_Balanced = 1; internal const int DLSS_MaxQuality = 2; internal const int DLSS_UltraPerformance = 3; internal const int DLSS_UltraQuality = 4; internal const int DLSS_DLAA = 5; private static LogCallbackDelegate? _logDelegate; private static bool _logHooked; private static bool _preloaded; [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_SetLogCallback(LogCallbackDelegate cb); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern int NGXBridge_Load(); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern int NGXBridge_InitD3D11(IntPtr device); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern int NGXBridge_InitD3D12(); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_ParamSetInt(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string name, int val); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_ParamSetUInt(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string name, uint val); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_ParamSetFloat(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string name, float val); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_Shutdown(); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern int NGXBridge_IsDLSSAvailable_D3D12(); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr NGXBridge_AllocParams_D3D12(); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_DestroyParams_D3D12(IntPtr p); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr NGXBridge_CreateDLSS_D3D12(IntPtr parameters); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_ReleaseDLSS_D3D12(IntPtr handle); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern int NGXBridge_EvalDLSS_D3D12(IntPtr handle, IntPtr parameters, IntPtr color, IntPtr depth, IntPtr motion, IntPtr output); [DllImport("ngx_bridge", CallingConvention = CallingConvention.Cdecl)] internal static extern void NGXBridge_ClearSharedCache(); [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)] private static extern IntPtr LoadLibraryW(string path); internal static bool Preload() { if (_preloaded) { return true; } _preloaded = true; string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "ngx_bridge.dll"); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("ngx_bridge.dll not found at: " + text)); return false; } if (LoadLibraryW(text) == IntPtr.Zero) { Plugin.Log.LogWarning((object)$"Failed to preload ngx_bridge.dll (error {Marshal.GetLastWin32Error()})"); return false; } Plugin.Log.LogDebug((object)("Preloaded ngx_bridge.dll from: " + text)); return true; } internal static void HookLog() { if (!_logHooked) { _logHooked = true; _logDelegate = delegate(string msg) { Plugin.Log.LogDebug((object)("[NGX] " + msg)); }; NGXBridge_SetLogCallback(_logDelegate); } } } internal class TemporalUpscaler : IUpscaler { private bool _shaderChecked; private Material? _material; private Camera? _camera; private RenderTexture? _historyRT; private int _inputWidth; private int _inputHeight; private int _outputWidth; private int _outputHeight; private bool _needsReset = true; private RenderTexture? _motionVectorRT; private CommandBuffer? _mvCopyCmd; private static readonly int PrevTexId = Shader.PropertyToID("_PrevTex"); private static readonly int MotionVectorTexId = Shader.PropertyToID("_MotionVectorTex"); private static readonly int DepthTexId = Shader.PropertyToID("_DepthTex"); private static readonly int OutputSizeId = Shader.PropertyToID("_OutputSize"); private static readonly int InputSizeId = Shader.PropertyToID("_InputSize"); private static readonly int JitterId = Shader.PropertyToID("_Jitter"); private static readonly int ResetId = Shader.PropertyToID("_Reset"); public string Name => "FSR Temporal"; public bool IsAvailable { get { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if ((Object)(object)_material == (Object)null && !_shaderChecked) { _shaderChecked = true; Shader val = ShaderBundle.LoadShader("Hidden/REPOFidelity/FSR_Temporal"); if ((Object)(object)val != (Object)null && val.isSupported) { _material = new Material(val) { hideFlags = (HideFlags)61 }; } } return (Object)(object)_material != (Object)null; } } public void Initialize(Camera camera, int inputWidth, int inputHeight, int outputWidth, int outputHeight) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown _camera = camera; _inputWidth = inputWidth; _inputHeight = inputHeight; _outputWidth = outputWidth; _outputHeight = outputHeight; _needsReset = true; if ((Object)(object)_material == (Object)null) { Plugin.Log.LogWarning((object)"Temporal upscale shader not available"); return; } _historyRT = new RenderTexture(outputWidth, outputHeight, 0, (RenderTextureFormat)9) { filterMode = (FilterMode)1 }; _historyRT.Create(); SetupMotionVectorCapture(inputWidth, inputHeight); Plugin.Log.LogDebug((object)$"Temporal upscaler initialized: {inputWidth}x{inputHeight} -> {outputWidth}x{outputHeight}"); } public void OnRenderImage(RenderTexture source, RenderTexture destination) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_material == (Object)null || (Object)(object)_historyRT == (Object)null) { Graphics.Blit((Texture)(object)source, destination); return; } _material.SetTexture(PrevTexId, (Texture)(object)_historyRT); if ((Object)(object)_motionVectorRT != (Object)null) { _material.SetTexture(MotionVectorTexId, (Texture)(object)_motionVectorRT); } _material.SetVector(OutputSizeId, new Vector4((float)_outputWidth, (float)_outputHeight, 1f / (float)_outputWidth, 1f / (float)_outputHeight)); _material.SetVector(InputSizeId, new Vector4((float)_inputWidth, (float)_inputHeight, 1f / (float)_inputWidth, 1f / (float)_inputHeight)); UpscalerManager instance = UpscalerManager.Instance; float num = (((Object)(object)instance != (Object)null) ? (instance.JitterX * (float)_inputWidth) : 0f); float num2 = (((Object)(object)instance != (Object)null) ? (instance.JitterY * (float)_inputHeight) : 0f); _material.SetVector(JitterId, Vector4.op_Implicit(new Vector2(num, num2))); _material.SetFloat(ResetId, _needsReset ? 1f : 0f); _needsReset = false; Graphics.Blit((Texture)(object)source, destination, _material); Graphics.Blit((Texture)(object)destination, _historyRT); } public void OnResolutionChanged(int inputWidth, int inputHeight, int outputWidth, int outputHeight) { Dispose(); if ((Object)(object)_camera != (Object)null) { Initialize(_camera, inputWidth, inputHeight, outputWidth, outputHeight); } } public void Dispose() { CleanupMotionVectorCapture(); if ((Object)(object)_historyRT != (Object)null) { _historyRT.Release(); Object.Destroy((Object)(object)_historyRT); _historyRT = null; } } private void SetupMotionVectorCapture(int width, int height) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) CleanupMotionVectorCapture(); _motionVectorRT = new RenderTexture(width, height, 0, (RenderTextureFormat)12) { filterMode = (FilterMode)0 }; _motionVectorRT.Create(); _mvCopyCmd = new CommandBuffer { name = "FSR Temporal MV Copy" }; _mvCopyCmd.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)15), RenderTargetIdentifier.op_Implicit((Texture)(object)_motionVectorRT)); if ((Object)(object)_camera != (Object)null) { _camera.AddCommandBuffer((CameraEvent)20, _mvCopyCmd); } } private void CleanupMotionVectorCapture() { if ((Object)(object)_camera != (Object)null && _mvCopyCmd != null) { _camera.RemoveCommandBuffer((CameraEvent)20, _mvCopyCmd); } CommandBuffer? mvCopyCmd = _mvCopyCmd; if (mvCopyCmd != null) { mvCopyCmd.Dispose(); } _mvCopyCmd = null; if ((Object)(object)_motionVectorRT != (Object)null) { _motionVectorRT.Release(); Object.Destroy((Object)(object)_motionVectorRT); _motionVectorRT = null; } } } } namespace REPOFidelity.Shaders { internal static class CASShader { private static Material? _material; private static bool _initialized; private static readonly int SharpnessId = Shader.PropertyToID("_Sharpness"); private static void Init() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (!_initialized) { _initialized = true; Shader val = ShaderBundle.LoadShader("Hidden/REPOFidelity/CAS"); if ((Object)(object)val == (Object)null || !val.isSupported) { Plugin.Log.LogWarning((object)"CAS shader unavailable"); return; } _material = new Material(val) { hideFlags = (HideFlags)61 }; Plugin.Log.LogDebug((object)"CAS shader loaded"); } } public static void Apply(RenderTexture source, RenderTexture destination, float sharpness) { Init(); if ((Object)(object)_material == (Object)null) { Graphics.Blit((Texture)(object)source, destination); return; } _material.SetFloat(SharpnessId, sharpness); Graphics.Blit((Texture)(object)source, destination, _material); } } internal static class FSRShaders { private static Material? _easuMaterial; private static Material? _rcasMaterial; private static bool _initialized; private static void Init() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown if (!_initialized) { _initialized = true; Shader val = ShaderBundle.LoadShader("Hidden/REPOFidelity/FSR_EASU"); if ((Object)(object)val != (Object)null && val.isSupported) { _easuMaterial = new Material(val) { hideFlags = (HideFlags)61 }; } Shader val2 = ShaderBundle.LoadShader("Hidden/REPOFidelity/FSR_RCAS"); if ((Object)(object)val2 != (Object)null && val2.isSupported) { _rcasMaterial = new Material(val2) { hideFlags = (HideFlags)61 }; } if ((Object)(object)_easuMaterial != (Object)null) { Plugin.Log.LogDebug((object)"FSR shaders loaded from bundle"); } else { Plugin.Log.LogWarning((object)"FSR EASU shader unavailable; FSR upscaling disabled"); } } } public static Material? GetEASUMaterial() { Init(); return _easuMaterial; } public static Material? GetRCASMaterial() { Init(); return _rcasMaterial; } } internal static class ShaderBundle { private static AssetBundle? _bundle; private static bool _loadAttempted; private static Shader?[]? _allShaders; public static Shader? LoadShader(string name) { if (!_loadAttempted) { _loadAttempted = true; _bundle = TryLoadBundle(); if ((Object)(object)_bundle != (Object)null) { _allShaders = _bundle.LoadAllAssets(); Plugin.Log.LogDebug((object)$"Loaded {_allShaders.Length} shader(s) from bundle"); } } if (_allShaders == null) { return null; } Shader[] allShaders = _allShaders; foreach (Shader val in allShaders) { if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return val; } } Plugin.Log.LogWarning((object)("Shader '" + name + "' not found in bundle")); return null; } private static AssetBundle? TryLoadBundle() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (directoryName == null) { return null; } string text = Path.Combine(directoryName, "repofidelity_shaders"); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("Shader bundle not found at: " + text)); Plugin.Log.LogWarning((object)"FSR and CAS shaders unavailable. Build the shader bundle in Unity Editor."); return null; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Failed to load shader AssetBundle"); return null; } Plugin.Log.LogDebug((object)"Shader bundle loaded successfully"); return val; } } } namespace REPOFidelity.Patches { [HarmonyPatch(typeof(PhysGrabObjectGrabArea), "Update")] internal static class GrabAreaIdleSkipPatch { private static bool Prefix(PhysGrabObjectGrabArea __instance) { if (!Settings.ModEnabled || !Settings.AllocationFixesEnabled) { return true; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } List list = (((Object)(object)__instance.physGrabObject != (Object)null) ? __instance.physGrabObject.playerGrabbing : __instance.staticGrabObject?.playerGrabbing); if (list != null && list.Count > 0) { return true; } if (__instance.listOfAllGrabbers.Count > 0) { return true; } return false; } } [HarmonyPatch(typeof(AudioListenerFollow), "Update")] internal static class AudioListenerFollowNonAllocPatch { private static readonly Collider[] _buf = (Collider[])(object)new Collider[8]; private static int _triggerMask = -1; private static bool Prefix(AudioListenerFollow __instance) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ModEnabled || !Settings.AllocationFixesEnabled) { return true; } if (!Object.op_Implicit((Object)(object)__instance.TargetPositionTransform)) { return false; } bool num = Object.op_Implicit((Object)(object)SpectateCamera.instance) && SpectateCamera.instance.CheckState((State)0); Transform targetPositionTransform = __instance.TargetPositionTransform; if (num) { ((Component)__instance).transform.position = targetPositionTransform.position; } else { ((Component)__instance).transform.position = targetPositionTransform.position + targetPositionTransform.forward * AssetManager.instance.mainCamera.nearClipPlane; } Transform targetRotationTransform = __instance.TargetRotationTransform; if (!Object.op_Implicit((Object)(object)targetRotationTransform)) { return false; } ((Component)__instance).transform.rotation = targetRotationTransform.rotation; if (!GameDirector.instance.fpsImpulse15) { return false; } if (_triggerMask < 0) { _triggerMask = LayerMask.GetMask(new string[1] { "LowPassTrigger" }); } __instance.lowPassTrigger = null; if (Physics.OverlapSphereNonAlloc(((Component)__instance).transform.position, 0.1f, _buf, _triggerMask, (QueryTriggerInteraction)2) > 0) { Collider val = _buf[0]; __instance.lowPassTrigger = ((Component)val).GetComponent() ?? ((Component)val).GetComponentInParent(); } return false; } } [HarmonyPatch(typeof(EnemyDirector), "Update")] internal static class EnemyDirectorThrottlePatch { private static int _frameSkip; private static float _cachedActionDelta; private static bool Prefix(EnemyDirector __instance) { //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Invalid comparison between Unknown and I4 //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Invalid comparison between Unknown and I4 //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Invalid comparison between Unknown and I4 if (!Settings.ModEnabled || !Settings.CpuPatchesActive) { return true; } long startTicks = FrameTimeMeter.Begin(); if (LevelGenerator.Instance.Generated && __instance.spawnIdlePauseTimer > 0f) { bool flag = true; foreach (EnemyParent item in __instance.enemiesSpawned) { if (Object.op_Implicit((Object)(object)item) && !item.firstSpawnPointUsed) { flag = false; break; } } if (flag) { __instance.spawnIdlePauseTimer -= Time.deltaTime; } if (__instance.debugNoSpawnIdlePause) { __instance.spawnIdlePauseTimer = 0f; } } __instance.despawnedDecreaseTimer -= Time.deltaTime; if (__instance.despawnedDecreaseTimer <= 0f) { __instance.despawnedDecreaseMultiplier -= __instance.despawnedDecreasePercent; if (__instance.despawnedDecreaseMultiplier < 0f) { __instance.despawnedDecreaseMultiplier = 0f; } __instance.despawnedDecreaseTimer = 60f * __instance.despawnedDecreaseMinutes; } if (RoundDirector.instance.allExtractionPointsCompleted) { foreach (EnemyParent item2 in __instance.enemiesSpawned) { if (Object.op_Implicit((Object)(object)item2) && item2.DespawnedTimer > 30f) { item2.DespawnedTimerSet(0f, false); } } RunExtractionLogic(__instance); } _frameSkip = (_frameSkip + 1) % 3; if (_frameSkip == 0) { float num = 0f; foreach (EnemyParent item3 in __instance.enemiesSpawned) { if (Object.op_Implicit((Object)(object)item3) && item3.Spawned && item3.playerClose && !item3.forceLeave && CheckRoomOverlap(item3.currentRooms)) { Difficulty difficulty = item3.difficulty; float num2 = (((int)difficulty == 1) ? 1f : (((int)difficulty != 2) ? 0.5f : 2f)); float num3 = num2; num += num3 * item3.actionMultiplier; } } _cachedActionDelta = num; } if (_cachedActionDelta > 0f) { __instance.enemyActionAmount += _cachedActionDelta * Time.deltaTime; } else { __instance.enemyActionAmount -= 0.1f * Time.deltaTime; __instance.enemyActionAmount = Mathf.Max(0f, __instance.enemyActionAmount); } float num4 = (__instance.debugShortActionTimer ? 5f : 120f); if (__instance.enemyActionAmount > num4) { __instance.enemyActionAmount = 0f; LevelPoint val = SemiFunc.LevelPointGetFurthestFromPlayer(((Component)__instance).transform.position, 5f); if (Object.op_Implicit((Object)(object)val)) { __instance.SetInvestigate(((Component)val).transform.position, float.MaxValue, true); } if (RoundDirector.instance.allExtractionPointsCompleted && (int)__instance.extractionsDoneState == 1) { __instance.investigatePointTimer = 60f; } foreach (EnemyParent item4 in __instance.enemiesSpawned) { if (Object.op_Implicit((Object)(object)item4) && item4.Spawned) { item4.forceLeave = true; } } } FrameTimeMeter.End(FrameTimeMeter.EnemyDirector, startTicks); return false; } private static void RunExtractionLogic(EnemyDirector inst) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (inst.investigatePointTimer <= 0f) { if ((int)inst.extractionsDoneState == 0) { inst.enemyActionAmount = 0f; inst.despawnedDecreaseMultiplier = 0f; if (inst.extractionDoneStateImpulse) { inst.extractionDoneStateTimer = 10f; inst.extractionDoneStateImpulse = false; foreach (EnemyParent item in inst.enemiesSpawned) { if (Object.op_Implicit((Object)(object)item) && item.Spawned && !item.playerClose) { item.SpawnedTimerPause(0f); item.SpawnedTimerSet(0f); } } } inst.investigatePointTimer = inst.investigatePointTime; List list = SemiFunc.LevelPointsGetInStartRoom(); if (list.Count > 0) { SemiFunc.EnemyInvestigate(((Component)list[Random.Range(0, list.Count)]).transform.position, 100f, true); } inst.extractionDoneStateTimer -= inst.investigatePointTime; if (inst.extractionDoneStateTimer <= 0f) { inst.extractionsDoneState = (ExtractionsDoneState)1; } } else { List list2 = SemiFunc.LevelPointsGetInPlayerRooms(); if (list2.Count > 0) { SemiFunc.EnemyInvestigate(((Component)list2[Random.Range(0, list2.Count)]).transform.position, 100f, true); } inst.investigatePointTimer = inst.investigatePointTime; inst.investigatePointTime = Mathf.Min(inst.investigatePointTime + 2f, 30f); } } else { inst.investigatePointTimer -= Time.deltaTime; } } private static bool CheckRoomOverlap(List enemyRooms) { foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { foreach (RoomVolume currentRoom in item.RoomVolumeCheck.CurrentRooms) { foreach (RoomVolume enemyRoom in enemyRooms) { if ((Object)(object)currentRoom == (Object)(object)enemyRoom) { return true; } } } } return false; } internal static void ResetCache() { _cachedActionDelta = 0f; } } [HarmonyPatch(typeof(SemiFunc), "EnemyGetNearestPhysObject")] internal static class SemiFuncCachePatch { private static readonly Collider[] _buf = (Collider[])(object)new Collider[32]; private static int _mask = -1; private static readonly Dictionary _cache = new Dictionary(); private static bool Prefix(Enemy enemy, ref Vector3 __result) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ModEnabled || !Settings.CpuPatchesActive) { return true; } long startTicks = FrameTimeMeter.Begin(); int instanceID = ((Object)enemy).GetInstanceID(); float time = Time.time; if (_cache.TryGetValue(instanceID, out (Vector3, float) value) && time - value.Item2 < 0.25f) { (__result, _) = value; FrameTimeMeter.End(FrameTimeMeter.SemiFuncCache, startTicks); return false; } if (_mask < 0) { _mask = LayerMask.GetMask(new string[1] { "PhysGrabObject" }); } int num = Physics.OverlapSphereNonAlloc(enemy.CenterTransform.position, 3f, _buf, _mask); PhysGrabObject val = null; float num2 = 9999f; for (int i = 0; i < num; i++) { PhysGrabObject componentInParent = ((Component)_buf[i]).GetComponentInParent(); if (Object.op_Implicit((Object)(object)componentInParent) && !Object.op_Implicit((Object)(object)((Component)componentInParent).GetComponent())) { float num3 = Vector3.Distance(enemy.CenterTransform.position, componentInParent.centerPoint); if (num3 < num2) { num2 = num3; val = componentInParent; } } } __result = (((Object)(object)val != (Object)null) ? val.centerPoint : Vector3.zero); _cache[instanceID] = (__result, time); FrameTimeMeter.End(FrameTimeMeter.SemiFuncCache, startTicks); return false; } internal static void ClearCache() { _cache.Clear(); } } [HarmonyPatch(typeof(PhysGrabObject), "Update")] internal static class PhysGrabObjectFixPatch { private static readonly Dictionary _rbCache = new Dictionary(); internal static void ClearRbCache() { _rbCache.Clear(); } private static bool Prefix(PhysGrabObject __instance) { if (!Settings.ModEnabled || !Settings.CpuPatchesActive) { return true; } if (!__instance.grabbed) { if (!_rbCache.TryGetValue(__instance, out Rigidbody value)) { value = ((Component)__instance).GetComponent(); _rbCache[__instance] = value; } if ((Object)(object)value != (Object)null && value.IsSleeping()) { return false; } return true; } long startTicks = FrameTimeMeter.Begin(); for (int num = __instance.playerGrabbing.Count - 1; num >= 0; num--) { PhysGrabber val = __instance.playerGrabbing[num]; if (!Object.op_Implicit((Object)(object)val) || !val.grabbed) { __instance.playerGrabbing.RemoveAt(num); } } FrameTimeMeter.End(FrameTimeMeter.PhysGrabObjectFix, startTicks); return true; } } [HarmonyPatch(typeof(LightManager), "UpdateLights")] internal static class LightManagerBatchPatch { private static bool Prefix(LightManager __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ModEnabled || !Settings.CpuPatchesActive) { return true; } long startTicks = FrameTimeMeter.Begin(); __instance.lastCheckPos = __instance.lightCullTarget.position; List propLights = __instance.propLights; for (int num = propLights.Count - 1; num >= 0; num--) { PropLight val = propLights[num]; if (Object.op_Implicit((Object)(object)val)) { __instance.HandleLightActivation(val); } else { propLights.RemoveAt(num); } } List propEmissions = __instance.propEmissions; for (int num2 = propEmissions.Count - 1; num2 >= 0; num2--) { PropLightEmission val2 = propEmissions[num2]; if (Object.op_Implicit((Object)(object)val2)) { __instance.HandleEmissionActivation(val2); } else { propEmissions.RemoveAt(num2); } } FrameTimeMeter.End(FrameTimeMeter.LightManagerBatch, startTicks); return false; } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] internal static class ClearCpuCachesOnLevel { private static void Postfix() { SemiFuncCachePatch.ClearCache(); EnemyDirectorThrottlePatch.ResetCache(); PlayerCosmeticThrottle.ResetCamera(); PlayerCosmeticThrottle.ClearAvatarCache(); } } internal static class PlayerCosmeticThrottle { private static Camera? _cam; private static readonly Dictionary _isWorldAvatar = new Dictionary(); internal static bool ShouldSkip(Transform t) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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) if (!Settings.CpuPatchesActive) { return false; } if (!_isWorldAvatar.TryGetValue(t, out var value)) { value = (Object)(object)((Component)t).GetComponentInParent() != (Object)null; _isWorldAvatar[t] = value; } if (!value) { return false; } float resolvedEffectiveFogEnd = Settings.ResolvedEffectiveFogEnd; if (resolvedEffectiveFogEnd <= 0f) { return false; } if ((Object)(object)_cam == (Object)null || (Object)(object)((Component)_cam).transform == (Object)null) { _cam = Camera.main; } if ((Object)(object)_cam == (Object)null) { return false; } float num = resolvedEffectiveFogEnd * 1.1f; Vector3 val = t.position - ((Component)_cam).transform.position; return ((Vector3)(ref val)).sqrMagnitude > num * num; } internal static void ResetCamera() { _cam = null; } internal static void ClearAvatarCache() { _isWorldAvatar.Clear(); } } [HarmonyPatch(typeof(PlayerAvatarEyelids), "Update")] internal static class PlayerAvatarEyelidsThrottlePatch { private static bool Prefix(PlayerAvatarEyelids __instance) { return !PlayerCosmeticThrottle.ShouldSkip(((Component)__instance).transform); } } [HarmonyPatch(typeof(PlayerExpression), "Update")] internal static class PlayerExpressionThrottlePatch { private static bool Prefix(PlayerExpression __instance) { return !PlayerCosmeticThrottle.ShouldSkip(((Component)__instance).transform); } } [HarmonyPatch(typeof(PlayerAvatarOverchargeVisuals), "Update")] internal static class PlayerAvatarOverchargeVisualsThrottlePatch { private static bool Prefix(PlayerAvatarOverchargeVisuals __instance) { return !PlayerCosmeticThrottle.ShouldSkip(((Component)__instance).transform); } } [HarmonyPatch(typeof(AnimNoise), "Update")] internal static class AnimNoiseThrottlePatch { private static bool Prefix(AnimNoise __instance) { return !PlayerCosmeticThrottle.ShouldSkip(((Component)__instance).transform); } } [HarmonyPatch(typeof(FlashlightLightAim), "Update")] internal static class FlashlightLightAimThrottlePatch { private static bool Prefix(FlashlightLightAim __instance) { return !PlayerCosmeticThrottle.ShouldSkip(((Component)__instance).transform); } } [HarmonyPatch(typeof(FlashlightTilt), "Update")] internal static class FlashlightTiltThrottlePatch { private static bool Prefix(FlashlightTilt __instance) { return !PlayerCosmeticThrottle.ShouldSkip(((Component)__instance).transform); } } [HarmonyPatch(typeof(ExtractionPoint))] internal static class ExtractionPointPatch { [HarmonyPrefix] [HarmonyPatch("Start")] public static void PrefixStart(ExtractionPoint __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (Settings.ExtractionPointFlicker) { TextMeshPro haulGoalScreen = __instance.haulGoalScreen; if (!((Object)(object)((haulGoalScreen != null) ? haulGoalScreen.transform : null) == (Object)null)) { Transform transform = __instance.haulGoalScreen.transform; transform.localPosition += new Vector3(0f, 0f, -0.002f); } } } } internal static class PhysicsBuffers { internal static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[64]; internal static readonly RaycastHit[] Hits2 = (RaycastHit[])(object)new RaycastHit[32]; internal static readonly Collider[] Overlaps = (Collider[])(object)new Collider[32]; private static int _physGrabMask = -1; internal static int PhysGrabMask { get { if (_physGrabMask < 0) { _physGrabMask = LayerMask.GetMask(new string[1] { "PhysGrabObject" }); } return _physGrabMask; } } } [HarmonyPatch(typeof(PhysGrabber), "RayCheck")] internal static class RayCheckDiscoveryPatch { private static void Prefix(PhysGrabber __instance, bool _grab) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ModEnabled || _grab || __instance.playerAvatar.isDisabled || __instance.playerAvatar.deadSet) { return; } Transform transform = ((Component)__instance.playerCamera).transform; int num = Physics.SphereCastNonAlloc(transform.position, 1f, transform.forward, PhysicsBuffers.Hits, 10f, LayerMask.op_Implicit(__instance.mask), (QueryTriggerInteraction)2); for (int i = 0; i < num; i++) { ValuableObject component = ((Component)((RaycastHit)(ref PhysicsBuffers.Hits[i])).transform).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || (component.discovered && !component.discoveredReminder)) { continue; } Vector3 val = ((RaycastHit)(ref PhysicsBuffers.Hits[i])).point; int num2 = Physics.OverlapSphereNonAlloc(val, 0.01f, PhysicsBuffers.Overlaps, LayerMask.op_Implicit(__instance.mask)); bool flag = false; for (int j = 0; j < num2; j++) { if ((Object)(object)((Component)((Component)PhysicsBuffers.Overlaps[j]).transform).GetComponentInParent() != (Object)(object)component) { flag = true; break; } } if (flag && Object.op_Implicit((Object)(object)component.physGrabObject)) { val = Vector3.MoveTowards(val, component.physGrabObject.centerPoint, 0.1f); } Vector3 val2 = transform.position - val; if (!component.discovered) { int num3 = Physics.SphereCastNonAlloc(val, 0.01f, val2, PhysicsBuffers.Hits2, ((Vector3)(ref val2)).magnitude, LayerMask.op_Implicit(__instance.mask), (QueryTriggerInteraction)2); bool flag2 = true; for (int k = 0; k < num3; k++) { if (!((Component)((RaycastHit)(ref PhysicsBuffers.Hits2[k])).transform).CompareTag("Player") && (Object)(object)((RaycastHit)(ref PhysicsBuffers.Hits2[k])).transform != (Object)(object)((RaycastHit)(ref PhysicsBuffers.Hits[i])).transform) { flag2 = false; break; } } if (flag2) { component.Discover((State)0); } } else { if (!component.discoveredReminder) { continue; } int num4 = Physics.RaycastNonAlloc(val, val2, PhysicsBuffers.Hits2, ((Vector3)(ref val2)).magnitude, LayerMask.op_Implicit(__instance.mask), (QueryTriggerInteraction)2); bool flag3 = true; for (int l = 0; l < num4; l++) { if (((Component)((Component)((RaycastHit)(ref PhysicsBuffers.Hits2[l])).collider).transform).CompareTag("Wall")) { flag3 = false; break; } } if (flag3) { component.discoveredReminder = false; component.Discover((State)1); } } } } } [HarmonyPatch(typeof(PhysGrabber), "ForceGrabPhysObject")] internal static class ForceGrabPatch { private static bool Prefix(PhysGrabber __instance, PhysGrabObject _physObject) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ModEnabled) { return true; } if ((Object)(object)__instance.playerCamera == (Object)null || (Object)(object)_physObject == (Object)null) { return true; } Vector3 val = _physObject.midPoint - ((Component)__instance.playerCamera).transform.position; int num = Physics.RaycastNonAlloc(((Component)__instance.playerCamera).transform.position, ((Vector3)(ref val)).normalized, PhysicsBuffers.Hits, ((Vector3)(ref val)).magnitude, PhysicsBuffers.PhysGrabMask, (QueryTriggerInteraction)1); for (int i = 0; i < num; i++) { if (!Object.op_Implicit((Object)(object)_physObject)) { continue; } Collider collider = ((RaycastHit)(ref PhysicsBuffers.Hits[i])).collider; if ((Object)(object)((collider != null) ? ((Component)collider).GetComponentInParent() : null) == (Object)(object)_physObject) { if (__instance.grabbed) { __instance.ReleaseObject(-1, 0.1f); } __instance.StartGrabbingPhysObject(PhysicsBuffers.Hits[i], _physObject); if (!__instance.grabbed) { break; } __instance.toggleGrab = true; return false; } } return false; } } [HarmonyPatch(typeof(GraphicsManager))] internal static class GraphicsPatch { [HarmonyPrefix] [HarmonyPatch("UpdateRenderSize")] public static bool PrefixUpdateRenderSize() { if (!Settings.ModEnabled) { return true; } if (VRCompat.Active) { return true; } return Settings.Pixelation; } } [HarmonyPatch(typeof(ParticlePrefabExplosion), "Start")] internal static class ExplosionShadowPatch { private static void Postfix(ParticlePrefabExplosion __instance) { if (Settings.ShouldOptimize(Settings.PerfOpt.ExplosionShadows) && (Object)(object)__instance.light != (Object)null) { __instance.light.shadows = (LightShadows)0; } } } [HarmonyPatch(typeof(ItemLight), "Start")] internal static class ItemLightShadowPatch { private static void Postfix(ItemLight __instance) { if (Settings.ShouldOptimize(Settings.PerfOpt.ItemLightShadows) && (Object)(object)__instance.itemLight != (Object)null) { __instance.itemLight.shadows = (LightShadows)0; } } } [HarmonyPatch(typeof(SpectateCamera), "LateUpdate")] internal static class SpectateShadowPatch { private static void Postfix() { if (QualitySettings.shadowDistance > Settings.ResolvedShadowDistance) { QualitySettings.shadowDistance = Settings.ResolvedShadowDistance; } } } internal static class SceneOptimizer { private static readonly Dictionary _tinyRendererOrig = new Dictionary(); private static readonly Dictionary _animatedLightOrig = new Dictionary(); private static readonly Dictionary _zeroIntensityOrig = new Dictionary(); private static readonly Dictionary _gpuInstancingOrig = new Dictionary(); private static readonly Dictionary _particleCullOrig = new Dictionary(); private static readonly HashSet _localAvatarRendererSet = new HashSet(); private static readonly List _distanceCullWatchlist = new List(); private static readonly Dictionary _distanceCullOrig = new Dictionary(); private static readonly Dictionary _flashlightBudgetOrig = new Dictionary(); private static readonly List _flashlightControllers = new List(); private static readonly List _pointLightWatchlist = new List(); private static readonly Dictionary _pointLightShadowOrig = new Dictionary(); private static readonly List<(Light light, float distSq)> _flashlightSorted = new List<(Light, float)>(); private static readonly List _playerAvatarRenderers = new List(); private static readonly Dictionary _playerAvatarShadowOrig = new Dictionary(); private static readonly Dictionary _playerAvatarSmrUpdateOrig = new Dictionary(); private static int _distanceCullCursor; private const int DistanceCullChunkSize = 1000; private static readonly List _shadowBudgetWatchlist = new List(); private static readonly List<(Light light, float dist)> _budgetCandidates = new List<(Light, float)>(); private static readonly Dictionary _shadowStrengths = new Dictionary(); private const float FadeSpeed = 3f; internal static void Apply() { long startTicks = FrameTimeMeter.Begin(); _shadowStrengths.Clear(); ApplyGpuInstancing(Settings.OptimizationsActive); ApplyZeroIntensityShadows(Settings.OptimizationsActive); ApplyParticleAutoCull(Settings.OptimizationsActive); SetParticleShadows(!Settings.ShouldOptimize(Settings.PerfOpt.ParticleShadows)); ApplyTinyRendererCull(Settings.ShouldOptimize(Settings.PerfOpt.TinyRendererCulling)); ApplyAnimatedLightCull(Settings.ShouldOptimize(Settings.PerfOpt.AnimatedLightShadows)); SetItemLightShadows(!Settings.ShouldOptimize(Settings.PerfOpt.ItemLightShadows)); SetExplosionLightShadows(!Settings.ShouldOptimize(Settings.PerfOpt.ExplosionShadows)); ApplyPointLightShadowCull(Settings.ShouldOptimize(Settings.PerfOpt.PointLightShadows)); CaptureDistanceCullWatchlist(); CapturePlayerAvatarRenderers(); CaptureFlashlightControllers(); CaptureShadowBudgetWatchlist(); if (!Settings.ShouldOptimize(Settings.PerfOpt.FlashlightShadowBudget)) { RestoreFlashlightBudget(); } FrameTimeMeter.End(FrameTimeMeter.SceneApply, startTicks); } private static void CapturePlayerAvatarRenderers() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) RestorePlayerAvatarRenderers(); _playerAvatarRenderers.Clear(); if (!Settings.OptimizationsActive) { return; } int num = 0; PlayerAvatar[] array = Object.FindObjectsOfType(); foreach (PlayerAvatar val in array) { if (val.isLocal) { continue; } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if ((int)val2.shadowCastingMode != 0) { _playerAvatarShadowOrig[val2] = val2.shadowCastingMode; _playerAvatarRenderers.Add(val2); SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null); if (val3 != null && val3.updateWhenOffscreen) { _playerAvatarSmrUpdateOrig[val3] = true; val3.updateWhenOffscreen = false; num++; } } } } if (num > 0) { Plugin.Log.LogDebug((object)$"player avatar: forced updateWhenOffscreen=false on {num} skinned meshes"); } } internal static void UpdatePlayerAvatarShadowCull(Camera? cam) { //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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null || _playerAvatarRenderers.Count == 0 || !Settings.OptimizationsActive) { return; } float resolvedEffectiveFogEnd = Settings.ResolvedEffectiveFogEnd; if (resolvedEffectiveFogEnd <= 0f) { return; } float num = resolvedEffectiveFogEnd * 1.1f; float num2 = num * num; float num3 = num * 0.9f * (num * 0.9f); Vector3 position = ((Component)cam).transform.position; for (int i = 0; i < _playerAvatarRenderers.Count; i++) { Renderer val = _playerAvatarRenderers[i]; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; bool flag = (int)val.shadowCastingMode == 0; if (flag && sqrMagnitude < num3 && _playerAvatarShadowOrig.TryGetValue(val, out var value)) { val.shadowCastingMode = value; } else if (!flag && sqrMagnitude > num2) { val.shadowCastingMode = (ShadowCastingMode)0; } } } } private static void RestorePlayerAvatarRenderers() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _playerAvatarShadowOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.shadowCastingMode = item.Value; } } _playerAvatarShadowOrig.Clear(); foreach (KeyValuePair item2 in _playerAvatarSmrUpdateOrig) { if ((Object)(object)item2.Key != (Object)null) { item2.Key.updateWhenOffscreen = item2.Value; } } _playerAvatarSmrUpdateOrig.Clear(); } private static void RefreshLocalAvatarRendererSet() { _localAvatarRendererSet.Clear(); PlayerAvatar[] array = Object.FindObjectsOfType(); foreach (PlayerAvatar val in array) { if (val.isLocal) { PlayerAvatarVisuals playerAvatarVisuals = val.playerAvatarVisuals; AddRenderersFromRoot((playerAvatarVisuals != null) ? ((Component)playerAvatarVisuals).transform : null); FlashlightController flashlightController = val.flashlightController; AddRenderersFromRoot((flashlightController != null) ? ((Component)flashlightController).transform : null); PlayerCosmetics val2 = val.playerAvatarVisuals?.playerCosmetics; if ((Object)(object)val2 != (Object)null) { AddRenderersFromRoot(((Component)val2).transform); PlayerCrown playerCrown = val2.playerCrown; AddRenderersFromRoot((playerCrown != null) ? ((Component)playerCrown).transform : null); } } } } private static void AddRenderersFromRoot(Transform? root) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null) { _localAvatarRendererSet.Add(val); } } } private static int ResolveFlashlightBudgetN() { if (Settings.Preset != QualityPreset.Potato) { return 4; } return 0; } private static void CaptureDistanceCullWatchlist() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) RestoreDistanceCullWatchlist(); _distanceCullWatchlist.Clear(); _distanceCullCursor = 0; if (!Settings.ShouldOptimize(Settings.PerfOpt.DistanceShadowCulling)) { return; } float num = ((Settings.Preset == QualityPreset.Potato) ? 5f : 3f); RefreshLocalAvatarRendererSet(); int num2 = 0; MeshRenderer[] array = Object.FindObjectsOfType(); foreach (MeshRenderer val in array) { if ((int)((Renderer)val).shadowCastingMode != 0) { Bounds bounds = ((Renderer)val).bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).magnitude >= num) && !_localAvatarRendererSet.Contains((Renderer)(object)val)) { _distanceCullWatchlist.Add((Renderer)(object)val); _distanceCullOrig[(Renderer)(object)val] = ((Renderer)val).shadowCastingMode; num2++; } } } if (num2 > 0) { Plugin.Log.LogDebug((object)$"distance cull watchlist: {num2} small renderers"); } } internal static void UpdateDistanceShadowCull(Camera? cam) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Invalid comparison between Unknown and I4 //IL_0108: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null || _distanceCullWatchlist.Count == 0) { return; } if (!Settings.ShouldOptimize(Settings.PerfOpt.DistanceShadowCulling)) { RestoreDistanceCullWatchlist(); return; } float resolvedEffectiveFogEnd = Settings.ResolvedEffectiveFogEnd; if (resolvedEffectiveFogEnd <= 0f) { return; } float num = resolvedEffectiveFogEnd * ((Settings.Preset == QualityPreset.Potato) ? 1f : 1.1f); float num2 = num * num; float num3 = num * 0.9f; float num4 = num3 * num3; Vector3 position = ((Component)cam).transform.position; int count = _distanceCullWatchlist.Count; int num5 = Mathf.Min(1000, count); if (_distanceCullCursor >= count) { _distanceCullCursor = 0; } for (int i = 0; i < num5; i++) { int num6 = _distanceCullCursor + i; if (num6 >= count) { num6 -= count; } Renderer val = _distanceCullWatchlist[num6]; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; bool flag = (int)val.shadowCastingMode == 0; if (flag && sqrMagnitude < num4) { val.shadowCastingMode = (ShadowCastingMode)((!_distanceCullOrig.TryGetValue(val, out var value)) ? 1 : ((int)value)); } else if (!flag && sqrMagnitude > num2) { val.shadowCastingMode = (ShadowCastingMode)0; } } } _distanceCullCursor = (_distanceCullCursor + num5) % count; } private static void RestoreDistanceCullWatchlist() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _distanceCullWatchlist.Count; i++) { Renderer val = _distanceCullWatchlist[i]; if (!((Object)(object)val == (Object)null)) { val.shadowCastingMode = (ShadowCastingMode)((!_distanceCullOrig.TryGetValue(val, out var value)) ? 1 : ((int)value)); } } _distanceCullOrig.Clear(); } private static void ApplyPointLightShadowCull(bool enable) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) RestorePointLightShadows(); _pointLightWatchlist.Clear(); if (!enable) { return; } Light[] array = Object.FindObjectsOfType(); foreach (Light val in array) { if ((int)val.type == 2 && (int)val.shadows != 0 && !(val.range <= 3f)) { _pointLightWatchlist.Add(val); } } if (_pointLightWatchlist.Count > 0) { Plugin.Log.LogDebug((object)$"point-light watchlist: {_pointLightWatchlist.Count} shadowed point lights"); } } internal static void UpdatePointLightShadowCull(Camera? cam) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0095: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null || _pointLightWatchlist.Count == 0) { return; } if (!Settings.ShouldOptimize(Settings.PerfOpt.PointLightShadows)) { RestorePointLightShadows(); return; } float resolvedEffectiveFogEnd = Settings.ResolvedEffectiveFogEnd; if (resolvedEffectiveFogEnd <= 0f) { return; } Vector3 position = ((Component)cam).transform.position; for (int i = 0; i < _pointLightWatchlist.Count; i++) { Light val = _pointLightWatchlist[i]; if ((Object)(object)val == (Object)null) { continue; } float num = resolvedEffectiveFogEnd + val.range; float num2 = num * 0.9f; Vector3 val2 = ((Component)val).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; bool flag = (int)val.shadows == 0; if (flag && sqrMagnitude < num2 * num2) { if (_pointLightShadowOrig.TryGetValue(val, out var value)) { val.shadows = value; _pointLightShadowOrig.Remove(val); } } else if (!flag && sqrMagnitude > num * num) { _pointLightShadowOrig[val] = val.shadows; val.shadows = (LightShadows)0; } } } private static void RestorePointLightShadows() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _pointLightShadowOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.shadows = item.Value; } } _pointLightShadowOrig.Clear(); } internal static void UpdateFlashlightShadowBudget(Camera? cam) { //IL_0028: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null) { return; } if (!Settings.ShouldOptimize(Settings.PerfOpt.FlashlightShadowBudget)) { RestoreFlashlightBudget(); return; } _flashlightSorted.Clear(); Vector3 position = ((Component)cam).transform.position; for (int num = _flashlightControllers.Count - 1; num >= 0; num--) { FlashlightController val = _flashlightControllers[num]; if ((Object)(object)val == (Object)null) { _flashlightControllers.RemoveAt(num); } else { Light spotlight = val.spotlight; if (!((Object)(object)spotlight == (Object)null) && ((Behaviour)spotlight).isActiveAndEnabled) { Vector3 val2 = ((Component)spotlight).transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; _flashlightSorted.Add((spotlight, sqrMagnitude)); } } } _flashlightSorted.Sort(((Light light, float distSq) a, (Light light, float distSq) b) => a.distSq.CompareTo(b.distSq)); float resolvedEffectiveFogEnd = Settings.ResolvedEffectiveFogEnd; float num2 = ((resolvedEffectiveFogEnd > 0f) ? (resolvedEffectiveFogEnd * 1.1f * (resolvedEffectiveFogEnd * 1.1f)) : float.PositiveInfinity); int num3 = ResolveFlashlightBudgetN(); int num4 = 0; for (int num5 = 0; num5 < _flashlightSorted.Count; num5++) { (Light light, float distSq) tuple = _flashlightSorted[num5]; Light item = tuple.light; bool num6 = tuple.distSq > num2; bool flag = num4 < num3; if (!num6 && flag) { num4++; if (_flashlightBudgetOrig.TryGetValue(item, out var value)) { item.shadows = value; _flashlightBudgetOrig.Remove(item); } } else if ((int)item.shadows != 0) { if (!_flashlightBudgetOrig.ContainsKey(item)) { _flashlightBudgetOrig[item] = item.shadows; } item.shadows = (LightShadows)0; } } } private static void RestoreFlashlightBudget() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _flashlightBudgetOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.shadows = item.Value; } } _flashlightBudgetOrig.Clear(); } private static void CaptureFlashlightControllers() { _flashlightControllers.Clear(); FlashlightController[] array = Object.FindObjectsOfType(); foreach (FlashlightController item in array) { _flashlightControllers.Add(item); } } internal static void ResetShadowBudget() { _shadowStrengths.Clear(); } private static void CaptureShadowBudgetWatchlist() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 _shadowBudgetWatchlist.Clear(); if (!Settings.OptimizationsActive) { return; } Light[] array = Object.FindObjectsOfType(); foreach (Light val in array) { if ((int)val.type == 2 && !(val.intensity >= 1f) && !(val.range >= 5f)) { _shadowBudgetWatchlist.Add(val); } } if (_shadowBudgetWatchlist.Count > 0) { Plugin.Log.LogDebug((object)$"shadow budget watchlist: {_shadowBudgetWatchlist.Count} item glow lights"); } } internal static void UpdateShadowBudget(Camera? cam) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null) { return; } if (!Settings.OptimizationsActive) { RestoreManagedLights(); return; } int resolvedShadowBudget = Settings.ResolvedShadowBudget; if (resolvedShadowBudget <= 0) { RestoreManagedLights(); return; } Vector3 position = ((Component)cam).transform.position; float resolvedShadowDistance = Settings.ResolvedShadowDistance; float dt = 0.1f; _budgetCandidates.Clear(); for (int num = _shadowBudgetWatchlist.Count - 1; num >= 0; num--) { Light val = _shadowBudgetWatchlist[num]; if ((Object)(object)val == (Object)null) { _shadowBudgetWatchlist.RemoveAt(num); } else if (((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy && !(val.intensity <= 0f)) { float num2 = Vector3.Distance(position, ((Component)val).transform.position); if (num2 > resolvedShadowDistance) { FadeLight(val, 0f, dt); } else { _budgetCandidates.Add((val, num2)); } } } _budgetCandidates.Sort(((Light light, float dist) a, (Light light, float dist) b) => a.dist.CompareTo(b.dist)); for (int num3 = 0; num3 < _budgetCandidates.Count; num3++) { Light item = _budgetCandidates[num3].light; float target = ((num3 < resolvedShadowBudget) ? 1f : 0f); FadeLight(item, target, dt); } } private static void RestoreManagedLights() { if (_shadowStrengths.Count == 0) { return; } for (int num = _shadowBudgetWatchlist.Count - 1; num >= 0; num--) { Light val = _shadowBudgetWatchlist[num]; if ((Object)(object)val == (Object)null) { _shadowBudgetWatchlist.RemoveAt(num); } else if (((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy) { val.shadows = (LightShadows)2; val.shadowStrength = 1f; } } _shadowStrengths.Clear(); } private static void FadeLight(Light light, float target, float dt) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)light).GetInstanceID(); float value; float num = Mathf.MoveTowards(_shadowStrengths.TryGetValue(instanceID, out value) ? value : (((int)light.shadows != 0) ? 1f : 0f), target, 3f * dt); _shadowStrengths[instanceID] = num; if (num <= 0.01f) { if ((int)light.shadows != 0) { light.shadows = (LightShadows)0; } light.shadowStrength = 0f; } else { if ((int)light.shadows == 0) { light.shadows = (LightShadows)2; } light.shadowStrength = num; } } private static void ApplyZeroIntensityShadows(bool enable) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _zeroIntensityOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.shadows = item.Value; } } _zeroIntensityOrig.Clear(); if (!enable) { return; } HashSet hashSet = new HashSet(); FlashlightController[] array = Object.FindObjectsOfType(); foreach (FlashlightController val in array) { if ((Object)(object)val.spotlight != (Object)null) { hashSet.Add(val.spotlight); } } int num = 0; Light[] array2 = Object.FindObjectsOfType(); foreach (Light val2 in array2) { if (!hashSet.Contains(val2) && val2.intensity <= 0f && (int)val2.shadows != 0) { _zeroIntensityOrig[val2] = val2.shadows; val2.shadows = (LightShadows)0; num++; } } if (num > 0) { Plugin.Log.LogDebug((object)$"disabled shadows on {num} zero-intensity lights"); } } private static void SetParticleShadows(bool on) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) int num = 0; ParticleSystemRenderer[] array = Object.FindObjectsOfType(); foreach (ParticleSystemRenderer val in array) { if (on && (int)((Renderer)val).shadowCastingMode == 0) { ((Renderer)val).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val).receiveShadows = true; num++; } else if (!on && (int)((Renderer)val).shadowCastingMode != 0) { ((Renderer)val).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val).receiveShadows = false; num++; } } if (num > 0) { Plugin.Log.LogDebug((object)string.Format("{0} shadows on {1} particle renderers", on ? "restored" : "disabled", num)); } } private static void ApplyParticleAutoCull(bool enable) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _particleCullOrig) { if ((Object)(object)item.Key != (Object)null) { MainModule main = item.Key.main; ((MainModule)(ref main)).cullingMode = item.Value; } } _particleCullOrig.Clear(); if (!enable) { return; } int num = 0; ParticleSystem[] array = Object.FindObjectsOfType(); foreach (ParticleSystem val in array) { MainModule main2 = val.main; if ((int)((MainModule)(ref main2)).cullingMode != 0) { _particleCullOrig[val] = ((MainModule)(ref main2)).cullingMode; ((MainModule)(ref main2)).cullingMode = (ParticleSystemCullingMode)0; num++; } } if (num > 0) { Plugin.Log.LogDebug((object)$"particle auto-cull: enabled on {num} systems"); } } private static void ApplyGpuInstancing(bool enable) { foreach (KeyValuePair item in _gpuInstancingOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.enableInstancing = item.Value; } } _gpuInstancingOrig.Clear(); if (!enable) { return; } int num = 0; HashSet hashSet = new HashSet(); MeshRenderer[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { Material[] sharedMaterials = ((Renderer)array[i]).sharedMaterials; foreach (Material val in sharedMaterials) { if (!((Object)(object)val == (Object)null) && !hashSet.Contains(val)) { hashSet.Add(val); if ((Object)(object)val.shader != (Object)null && !val.enableInstancing) { _gpuInstancingOrig[val] = val.enableInstancing; val.enableInstancing = true; num++; } } } } if (num > 0) { Plugin.Log.LogDebug((object)$"enabled GPU instancing on {num} materials"); } } private static void ApplyTinyRendererCull(bool enable) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Invalid comparison between Unknown and I4 //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _tinyRendererOrig) { if ((Object)(object)item.Key != (Object)null) { ((Renderer)item.Key).shadowCastingMode = item.Value; } } _tinyRendererOrig.Clear(); if (!enable) { return; } float num = ((Settings.Preset == QualityPreset.Potato) ? 1f : 0.5f); RefreshLocalAvatarRendererSet(); int num2 = 0; MeshRenderer[] array = Object.FindObjectsOfType(); foreach (MeshRenderer val in array) { if ((int)((Renderer)val).shadowCastingMode != 0 && (int)((Renderer)val).shadowCastingMode != 3) { Bounds bounds = ((Renderer)val).bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).magnitude >= num) && !_localAvatarRendererSet.Contains((Renderer)(object)val)) { _tinyRendererOrig[val] = ((Renderer)val).shadowCastingMode; ((Renderer)val).shadowCastingMode = (ShadowCastingMode)0; num2++; } } } if (num2 > 0) { Plugin.Log.LogDebug((object)$"disabled shadow casting on {num2} tiny renderers"); } } private static void SetItemLightShadows(bool on) { ItemLight[] array = Object.FindObjectsOfType(); foreach (ItemLight val in array) { if (!((Object)(object)val.itemLight == (Object)null)) { val.itemLight.shadows = (LightShadows)(on ? 2 : 0); } } } private static void SetExplosionLightShadows(bool on) { ParticlePrefabExplosion[] array = Object.FindObjectsOfType(); foreach (ParticlePrefabExplosion val in array) { if (!((Object)(object)val.light == (Object)null)) { val.light.shadows = (LightShadows)(on ? 2 : 0); } } } private static void ApplyAnimatedLightCull(bool enable) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair item in _animatedLightOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.shadows = item.Value; } } _animatedLightOrig.Clear(); if (!enable) { return; } int num = 0; LightAnimator[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { Light component = ((Component)array[i]).GetComponent(); if ((Object)(object)component != (Object)null && (int)component.shadows != 0) { _animatedLightOrig[component] = component.shadows; component.shadows = (LightShadows)0; num++; } } if (num > 0) { Plugin.Log.LogDebug((object)$"disabled shadows on {num} animated lights"); } } internal static void LogRestoreState(string tag) { int shadowResOrigCount = QualityPatch.ShadowResOrigCount; int avatarRtOrigCount = PlayerAvatarMenuAAPatch.AvatarRtOrigCount; int avatarPplCount = PlayerAvatarMenuAAPatch.AvatarPplCount; int num = _tinyRendererOrig.Count + _animatedLightOrig.Count + _zeroIntensityOrig.Count + _gpuInstancingOrig.Count + _particleCullOrig.Count + shadowResOrigCount + avatarRtOrigCount + avatarPplCount + _flashlightBudgetOrig.Count + _pointLightShadowOrig.Count + _playerAvatarShadowOrig.Count + _playerAvatarSmrUpdateOrig.Count; string arg = ((num == 0) ? "OK" : "LEAK"); Plugin.Log.LogDebug((object)($"[restore-state:{tag}] {arg} mutations={num} " + $"tinyRend={_tinyRendererOrig.Count} " + $"animLight={_animatedLightOrig.Count} " + $"zeroInt={_zeroIntensityOrig.Count} " + $"gpuInst={_gpuInstancingOrig.Count} " + $"particleCull={_particleCullOrig.Count} " + $"shadowRes={shadowResOrigCount} " + $"avatarRt={avatarRtOrigCount} " + $"avatarPpl={avatarPplCount} " + $"flashBudget={_flashlightBudgetOrig.Count} " + $"pointLight={_pointLightShadowOrig.Count} " + $"playerShadow={_playerAvatarShadowOrig.Count} " + $"playerSmr={_playerAvatarSmrUpdateOrig.Count} " + $"watchlist={_distanceCullWatchlist.Count}")); } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] internal static class LevelOptimizationPatch { private static void Postfix() { SceneOptimizer.Apply(); PhysGrabObjectFixPatch.ClearRbCache(); } } [HarmonyPatch(typeof(PlayerAvatar), "Start")] internal static class PlayerAvatarStartPatch { private static void Postfix() { SceneOptimizer.Apply(); } } [HarmonyPatch(typeof(PlayerAvatarMenu), "Start")] internal static class PlayerAvatarMenuAAPatch { internal struct PplState { internal bool AttachedByUs; internal Antialiasing OriginalAa; } private const int TargetRtSize = 1024; private const int MaxLongDim = 2048; private const int TargetMsaa = 4; internal static readonly Dictionary _rtOrig = new Dictionary(); internal static readonly Dictionary _pplState = new Dictionary(); internal static int AvatarRtOrigCount => _rtOrig.Count; internal static int AvatarPplCount => _pplState.Count; private static void Postfix(PlayerAvatarMenu __instance) { if (Settings.ModEnabled) { ApplyToMenu(__instance); } } internal static void ApplyToMenu(PlayerAvatarMenu __instance) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) if (__instance.expressionAvatar) { return; } int num = 0; PlayerAvatarMenu[] array = Object.FindObjectsOfType(); foreach (PlayerAvatarMenu val in array) { if (!val.expressionAvatar && !val.worldAvatar && !val.iconMakerAvatar && !((Object)(object)val.parentPage == (Object)null) && ((Component)val.parentPage).gameObject.activeInHierarchy && ++num > 2) { return; } } if ((Object)(object)__instance.cameraAndStuff == (Object)null) { return; } Camera componentInChildren = ((Component)__instance.cameraAndStuff).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Log.LogDebug((object)("avatar preview: no Camera under cameraAndStuff on '" + ((Object)__instance).name + "'")); return; } componentInChildren.allowMSAA = true; PostProcessLayer component = ((Component)componentInChildren).GetComponent(); if ((Object)(object)component != (Object)null) { if (!_pplState.ContainsKey(componentInChildren)) { _pplState[componentInChildren] = new PplState { AttachedByUs = false, OriginalAa = component.antialiasingMode }; } component.antialiasingMode = (Antialiasing)2; component.fastApproximateAntialiasing.keepAlpha = true; } else { Camera main = Camera.main; PostProcessLayer val2 = ((main != null) ? ((Component)main).GetComponent() : null); if ((Object)(object)val2 != (Object)null) { object? obj = typeof(PostProcessLayer).GetField("m_Resources", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val2); PostProcessResources val3 = (PostProcessResources)((obj is PostProcessResources) ? obj : null); if ((Object)(object)val3 != (Object)null) { PostProcessLayer obj2 = ((Component)componentInChildren).gameObject.AddComponent(); obj2.Init(val3); obj2.volumeTrigger = ((Component)componentInChildren).transform; obj2.antialiasingMode = (Antialiasing)2; obj2.fastApproximateAntialiasing.keepAlpha = true; _pplState[componentInChildren] = new PplState { AttachedByUs = true, OriginalAa = (Antialiasing)0 }; Plugin.Log.LogDebug((object)("avatar preview: attached PostProcessLayer with SMAA to '" + ((Object)componentInChildren).name + "'")); } else { Plugin.Log.LogDebug((object)("avatar preview: main PPL has no resources; SMAA unavailable on '" + ((Object)componentInChildren).name + "'")); } } } RenderTexture targetTexture = componentInChildren.targetTexture; if ((Object)(object)targetTexture != (Object)null) { bool num2 = ((Texture)targetTexture).width < 1024 && ((Texture)targetTexture).height < 1024; bool flag = targetTexture.antiAliasing < 4; if ((num2 || flag) && !_rtOrig.ContainsKey(targetTexture)) { _rtOrig[targetTexture] = (((Texture)targetTexture).width, ((Texture)targetTexture).height, targetTexture.antiAliasing); int num3 = Mathf.Min(((Texture)targetTexture).width, ((Texture)targetTexture).height); float num4 = ((num3 < 1024) ? (1024f / (float)num3) : 1f); int num5 = Mathf.RoundToInt((float)((Texture)targetTexture).width * num4); int num6 = Mathf.RoundToInt((float)((Texture)targetTexture).height * num4); int num7 = Mathf.Max(num5, num6); if (num7 > 2048) { float num8 = 2048f / (float)num7; num5 = Mathf.RoundToInt((float)num5 * num8); num6 = Mathf.RoundToInt((float)num6 * num8); } bool num9 = targetTexture.IsCreated(); if (num9) { targetTexture.Release(); } ((Texture)targetTexture).width = num5; ((Texture)targetTexture).height = num6; targetTexture.antiAliasing = 4; if (num9) { targetTexture.Create(); } Plugin.Log.LogDebug((object)($"avatar preview: RT '{((Object)targetTexture).name}' bumped {_rtOrig[targetTexture].w}x{_rtOrig[targetTexture].h} " + $"aa={_rtOrig[targetTexture].aa} → {num5}x{num6} aa={4}")); } } AvatarCameraGate avatarCameraGate = ((Component)componentInChildren).gameObject.GetComponent(); if ((Object)(object)avatarCameraGate == (Object)null) { avatarCameraGate = ((Component)componentInChildren).gameObject.AddComponent(); } avatarCameraGate.menu = __instance; avatarCameraGate.cam = componentInChildren; } internal static void RestoreAvatarRt() { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) if (_rtOrig.Count == 0) { return; } List list = new List(); Camera[] array = Object.FindObjectsOfType(); foreach (Camera val in array) { if ((Object)(object)val.targetTexture != (Object)null && _rtOrig.ContainsKey(val.targetTexture)) { ((Behaviour)val).enabled = false; list.Add(val); } } foreach (KeyValuePair item in _rtOrig) { RenderTexture key = item.Key; if (!((Object)(object)key == (Object)null)) { bool num = key.IsCreated(); if (num) { key.Release(); } ((Texture)key).width = item.Value.Item1; ((Texture)key).height = item.Value.Item2; key.antiAliasing = item.Value.Item3; if (num) { key.Create(); } } } _rtOrig.Clear(); foreach (KeyValuePair item2 in _pplState) { Camera key2 = item2.Key; if ((Object)(object)key2 == (Object)null) { continue; } PostProcessLayer component = ((Component)key2).GetComponent(); if (!((Object)(object)component == (Object)null)) { if (item2.Value.AttachedByUs) { Object.Destroy((Object)(object)component); } else { component.antialiasingMode = item2.Value.OriginalAa; } } } _pplState.Clear(); foreach (Camera item3 in list) { ((Behaviour)item3).enabled = true; AvatarCameraGate component2 = ((Component)item3).GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } } internal static void ReapplyAll() { PlayerAvatarMenu[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { ApplyToMenu(array[i]); } } } internal class AvatarCameraGate : MonoBehaviour { internal PlayerAvatarMenu? menu; internal Camera? cam; private void LateUpdate() { if ((Object)(object)cam == (Object)null) { Object.Destroy((Object)(object)this); return; } if (!Settings.ModEnabled) { if (!((Behaviour)cam).enabled) { ((Behaviour)cam).enabled = true; } return; } bool flag = (Object)(object)menu != (Object)null && (Object)(object)menu.parentPage != (Object)null && ((Component)menu.parentPage).gameObject.activeInHierarchy; if (((Behaviour)cam).enabled != flag) { ((Behaviour)cam).enabled = flag; } } } internal static class PerfSettingsWatcher { private static bool _registered; private static int _lastPreset = -1; private static int _lastShadowQ = -1; private static int _lastShadowBudget; private static int _lastPerfExp; private static int _lastPerfItem; private static int _lastPerfAnim; private static int _lastPerfPart; private static int _lastPerfTiny; private static int _lastPerfDist; private static int _lastPerfFlash; private static bool _lastModEnabled = true; internal static void Register() { if (!_registered) { _registered = true; SnapshotState(); Settings.OnSettingsChanged += OnChanged; } } private static void OnChanged() { if (Settings.ModEnabled != _lastModEnabled || Settings.Preset != (QualityPreset)_lastPreset || Settings.ResolvedShadowQuality != (ShadowQuality)_lastShadowQ || Settings.ResolvedShadowBudget != _lastShadowBudget || Settings.PerfExplosionShadows != _lastPerfExp || Settings.PerfItemLightShadows != _lastPerfItem || Settings.PerfAnimatedLightShadows != _lastPerfAnim || Settings.PerfParticleShadows != _lastPerfPart || Settings.PerfTinyRendererCulling != _lastPerfTiny || Settings.PerfDistanceShadowCulling != _lastPerfDist || Settings.PerfFlashlightShadowBudget != _lastPerfFlash) { if (Settings.ResolvedShadowBudget != _lastShadowBudget) { SceneOptimizer.ResetShadowBudget(); } SnapshotState(); SceneOptimizer.Apply(); } } private static void SnapshotState() { _lastModEnabled = Settings.ModEnabled; _lastPreset = (int)Settings.Preset; _lastShadowQ = (int)Settings.ResolvedShadowQuality; _lastShadowBudget = Settings.ResolvedShadowBudget; _lastPerfExp = Settings.PerfExplosionShadows; _lastPerfItem = Settings.PerfItemLightShadows; _lastPerfAnim = Settings.PerfAnimatedLightShadows; _lastPerfPart = Settings.PerfParticleShadows; _lastPerfTiny = Settings.PerfTinyRendererCulling; _lastPerfDist = Settings.PerfDistanceShadowCulling; _lastPerfFlash = Settings.PerfFlashlightShadowBudget; } } internal static class GrabberComponentCache { private class CachedRenderers { public Material? beam; public Material? point1; public Material? point2; public Material? rotate; public Light? grabLight; public Material? orb0; public Material? orb1; public bool valid; } private static readonly ConditionalWeakTable _cache = new ConditionalWeakTable(); internal static void CacheFor(PhysGrabber g) { if (_cache.TryGetValue(g, out CachedRenderers _)) { return; } CachedRenderers cachedRenderers = new CachedRenderers(); try { if ((Object)(object)g.physGrabBeam != (Object)null) { LineRenderer component = g.physGrabBeam.GetComponent(); cachedRenderers.beam = ((component != null) ? ((Renderer)component).material : null); } if ((Object)(object)g.physGrabPointVisual1 != (Object)null) { MeshRenderer component2 = g.physGrabPointVisual1.GetComponent(); cachedRenderers.point1 = ((component2 != null) ? ((Renderer)component2).material : null); } if ((Object)(object)g.physGrabPointVisual2 != (Object)null) { MeshRenderer component3 = g.physGrabPointVisual2.GetComponent(); cachedRenderers.point2 = ((component3 != null) ? ((Renderer)component3).material : null); } if ((Object)(object)g.physGrabPointVisualRotate != (Object)null) { MeshRenderer component4 = ((Component)g.physGrabPointVisualRotate).GetComponent(); cachedRenderers.rotate = ((component4 != null) ? ((Renderer)component4).material : null); } PlayerAvatarRightArm val = g.playerAvatar?.playerAvatarVisuals?.playerAvatarRightArm; if ((Object)(object)val != (Object)null) { cachedRenderers.grabLight = val.grabberLight; if (val.grabberOrbSpheres != null && val.grabberOrbSpheres.Length >= 2) { GameObject obj = val.grabberOrbSpheres[0]; object orb; if (obj == null) { orb = null; } else { MeshRenderer component5 = obj.GetComponent(); orb = ((component5 != null) ? ((Renderer)component5).material : null); } cachedRenderers.orb0 = (Material?)orb; GameObject obj2 = val.grabberOrbSpheres[1]; object orb2; if (obj2 == null) { orb2 = null; } else { MeshRenderer component6 = obj2.GetComponent(); orb2 = ((component6 != null) ? ((Renderer)component6).material : null); } cachedRenderers.orb1 = (Material?)orb2; } } cachedRenderers.valid = true; } catch { cachedRenderers.valid = false; } _cache.AddOrUpdate(g, cachedRenderers); } internal static bool TryApplyColor(PhysGrabber g, Color main, Color emission) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_006a: Unknown result type (might be due to invalid IL or missing references) if (!_cache.TryGetValue(g, out CachedRenderers value)) { return false; } if (!value.valid) { return false; } g.currentBeamColor = main; SetColor(value.beam, main, emission); SetColor(value.point1, main, emission); SetColor(value.point2, main, emission); SetColor(value.rotate, main, emission); if ((Object)(object)value.grabLight != (Object)null) { value.grabLight.color = main; } SetColor(value.orb0, main, emission); SetColor(value.orb1, main, emission); return true; } private static void SetColor(Material? mat, Color main, Color emission) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mat == (Object)null)) { mat.color = main; mat.SetColor("_EmissionColor", emission); } } } [HarmonyPatch(typeof(PhysGrabber), "Start")] internal static class CacheGrabberOnStart { private static void Postfix(PhysGrabber __instance) { GrabberComponentCache.CacheFor(__instance); } } [HarmonyPatch(typeof(PhysGrabber), "ColorStateSetColor")] internal static class SkipGrabberGetComponent { private static bool Prefix(PhysGrabber __instance, Color mainColor, Color emissionColor) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!Settings.ModEnabled) { return true; } return !GrabberComponentCache.TryApplyColor(__instance, mainColor, emissionColor); } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] internal static class RegisterPerfWatcher { private static void Postfix() { PerfSettingsWatcher.Register(); } } [HarmonyPatch] internal static class QualityPatch { private static readonly HashSet _flashlightLights = new HashSet(); private static readonly Dictionary _shadowResOrig = new Dictionary(); private static ShadowResolution _vanillaShadowRes; private static float _vanillaShadowDist; private static float _vanillaLodBias; private static int _vanillaPixelLights; private static AnisotropicFiltering _vanillaAF; private static int _vanillaTexMip; private static bool _vanillaQualitySaved; private static int _lastFogStart = -1; private static int _lastFogEnd = -1; private static int _lastClip = -1; internal static int ShadowResOrigCount => _shadowResOrig.Count; internal static void SaveVanillaQuality() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0094: Unknown result type (might be due to invalid IL or missing references) if (!_vanillaQualitySaved) { _vanillaShadowRes = QualitySettings.shadowResolution; _vanillaShadowDist = QualitySettings.shadowDistance; _vanillaLodBias = QualitySettings.lodBias; _vanillaPixelLights = QualitySettings.pixelLightCount; _vanillaAF = QualitySettings.anisotropicFiltering; _vanillaTexMip = QualitySettings.globalTextureMipmapLimit; _vanillaQualitySaved = true; Plugin.Log.LogInfo((object)($"Vanilla defaults: shadows={_vanillaShadowRes}/{_vanillaShadowDist}m " + $"LOD={_vanillaLodBias} lights={_vanillaPixelLights} AF={_vanillaAF} texMip={_vanillaTexMip}")); } } internal static void RestoreVanillaQuality() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (_vanillaQualitySaved) { QualitySettings.shadowResolution = _vanillaShadowRes; QualitySettings.shadowDistance = _vanillaShadowDist; QualitySettings.lodBias = _vanillaLodBias; QualitySettings.pixelLightCount = _vanillaPixelLights; QualitySettings.anisotropicFiltering = _vanillaAF; QualitySettings.globalTextureMipmapLimit = _vanillaTexMip; if (UpscalerManager._vanillaSaved) { RenderSettings.fogStartDistance = UpscalerManager._vanillaFogStart; RenderSettings.fogEndDistance = UpscalerManager._vanillaFogEnd; } RestoreRangeTieredLightShadows(); } } private static void RestoreRangeTieredLightShadows() { foreach (KeyValuePair item in _shadowResOrig) { if ((Object)(object)item.Key != (Object)null) { item.Key.shadowCustomResolution = item.Value; } } _shadowResOrig.Clear(); } [HarmonyPostfix] [HarmonyPatch(typeof(GraphicsManager), "UpdateAll")] public static void PostfixUpdateAll() { ApplyQualitySettings(); } [HarmonyPostfix] [HarmonyPatch(typeof(GraphicsManager), "UpdateLightDistance")] public static void PostfixUpdateLightDistance(GraphicsManager __instance) { if (Settings.ModEnabled) { float lightDistance = __instance.lightDistance; __instance.lightDistance = Settings.ResolvedLightDistance; if (__instance.lightDistance > lightDistance && (Object)(object)LightManager.instance != (Object)null) { LightManager.instance.UpdateInstant(); } } } [HarmonyPostfix] [HarmonyPatch(typeof(GraphicsManager), "UpdateMotionBlur")] public static void PostfixUpdateMotionBlur() { if (Settings.ModEnabled && !Settings.MotionBlurOverride && (Object)(object)PostProcessing.Instance != (Object)null) { ((PostProcessEffectSettings)PostProcessing.Instance.motionBlur).active = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(GraphicsManager), "UpdateChromaticAberration")] public static void PostfixChromaticAberration() { if (Settings.ModEnabled && !Settings.ChromaticAberration && (Object)(object)PostProcessing.Instance != (Object)null) { ((PostProcessEffectSettings)PostProcessing.Instance.chromaticAberration).active = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(GraphicsManager), "UpdateLensDistortion")] public static void PostfixLensDistortion() { if (Settings.ModEnabled && !Settings.LensDistortion && (Object)(object)PostProcessing.Instance != (Object)null) { ((PostProcessEffectSettings)PostProcessing.Instance.lensDistortion).active = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(GraphicsManager), "UpdateGrain")] public static void PostfixGrain() { if (Settings.ModEnabled && !Settings.FilmGrain && (Object)(object)PostProcessing.Instance != (Object)null) { ((PostProcessEffectSettings)PostProcessing.Instance.grain).active = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(EnvironmentDirector), "Setup")] public static void PostfixEnvironmentSetup(EnvironmentDirector __instance) { UpscalerManager.SaveVanillaFog(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnvironmentDirector), "FogLogic")] public static void PostfixFogLogic(EnvironmentDirector __instance) { if (Settings.ModEnabled) { float resolvedFogMultiplier = Settings.ResolvedFogMultiplier; if (resolvedFogMultiplier != 1f) { RenderSettings.fogStartDistance *= resolvedFogMultiplier; RenderSettings.fogEndDistance *= resolvedFogMultiplier; } Settings.ResolvedEffectiveFogEnd = RenderSettings.fogEndDistance; Settings.ApplyFogClamps(); float resolvedViewDistance = Settings.ResolvedViewDistance; if (resolvedViewDistance > 0f) { UpscalerManager.SetModFarClip(__instance.MainCamera, resolvedViewDistance); } else { float num = RenderSettings.fogEndDistance + 10f; num = Mathf.Max(num, UpscalerManager.GetVanillaFarClip(__instance.MainCamera)); UpscalerManager.SetModFarClip(__instance.MainCamera, num); } int num2 = (int)RenderSettings.fogStartDistance; int num3 = (int)RenderSettings.fogEndDistance; int num4 = (int)__instance.MainCamera.farClipPlane; if (num2 != _lastFogStart || num3 != _lastFogEnd || num4 != _lastClip) { _lastFogStart = num2; _lastFogEnd = num3; _lastClip = num4; Plugin.Log.LogDebug((object)$"Fog: {num2}-{num3}m, clip: {num4}m"); } } } internal static void ApplyFogAndDrawDistance() { if (!Settings.ModEnabled || !UpscalerManager._vanillaSaved) { return; } float resolvedFogMultiplier = Settings.ResolvedFogMultiplier; RenderSettings.fogStartDistance = UpscalerManager._vanillaFogStart * resolvedFogMultiplier; RenderSettings.fogEndDistance = UpscalerManager._vanillaFogEnd * resolvedFogMultiplier; Settings.ResolvedEffectiveFogEnd = RenderSettings.fogEndDistance; Settings.ApplyFogClamps(); float resolvedViewDistance = Settings.ResolvedViewDistance; Camera main = Camera.main; if ((Object)(object)main != (Object)null) { if (resolvedViewDistance > 0f) { UpscalerManager.SetModFarClip(main, resolvedViewDistance); } else { float num = RenderSettings.fogEndDistance + 10f; num = Mathf.Max(num, UpscalerManager.GetVanillaFarClip(main)); UpscalerManager.SetModFarClip(main, num); } } if ((Object)(object)GraphicsManager.instance != (Object)null) { GraphicsManager.instance.lightDistance = Settings.ResolvedLightDistance; } if ((Object)(object)LightManager.instance != (Object)null) { LightManager.instance.UpdateInstant(); } ApplyLayerCulling(main); } private static void ApplyLayerCulling(Camera? cam) { if ((Object)(object)cam == (Object)null) { return; } float fogEndDistance = RenderSettings.fogEndDistance; float[] array = new float[32]; for (int i = 8; i < 32; i++) { string text = LayerMask.LayerToName(i); if (!string.IsNullOrEmpty(text) && !text.Contains("Player") && !text.Contains("Enemy") && !text.Contains("Interact") && !text.Contains("Trigger") && !text.Contains("PhysGrab") && !text.Contains("Valuable")) { array[i] = fogEndDistance + 5f; } } cam.layerCullDistances = array; } internal static void ApplyQualitySettings() { if (!Settings.ModEnabled) { return; } SaveVanillaQuality(); try { QualityPreset preset = Settings.Preset; ApplyShadowResolution(); QualitySettings.shadowDistance = Settings.ResolvedShadowDistance; QualitySettings.lodBias = Settings.ResolvedLODBias; QualitySettings.pixelLightCount = Settings.ResolvedPixelLightCount; int resolvedAnisotropicFiltering = Settings.ResolvedAnisotropicFiltering; int resolvedTextureQuality = (int)Settings.ResolvedTextureQuality; ApplyAnisotropicFiltering(resolvedAnisotropicFiltering); QualitySettings.globalTextureMipmapLimit = resolvedTextureQuality; if ((Object)(object)GraphicsManager.instance != (Object)null) { GraphicsManager.instance.lightDistance = Settings.ResolvedLightDistance; } ApplyFogAndDrawDistance(); Plugin.Log.LogDebug((object)($"[{preset}] shadows={Settings.ResolvedShadowQuality}/{Settings.ResolvedShadowDistance}m " + $"LOD={Settings.ResolvedLODBias} AF={resolvedAnisotropicFiltering} lights={Settings.ResolvedPixelLightCount} " + $"lightDist={Settings.ResolvedLightDistance}m tex={resolvedTextureQuality}")); } catch (Exception arg) { Plugin.Log.LogError((object)$"QualityPatch failed: {arg}"); } } private static void ApplyShadowResolution() { switch (Settings.ResolvedShadowQuality) { case ShadowQuality.Low: QualitySettings.shadowResolution = (ShadowResolution)0; QualitySettings.shadowCascades = 1; break; case ShadowQuality.Medium: QualitySettings.shadowResolution = (ShadowResolution)1; QualitySettings.shadowCascades = 2; break; case ShadowQuality.High: QualitySettings.shadowResolution = (ShadowResolution)2; QualitySettings.shadowCascades = 4; break; case ShadowQuality.Ultra: QualitySettings.shadowResolution = (ShadowResolution)3; QualitySettings.shadowCascades = 4; break; } ApplyRangeTieredLightShadows(); } private static void RefreshFlashlightLights() { _flashlightLights.Clear(); FlashlightController[] array = Object.FindObjectsOfType(); foreach (FlashlightController val in array) { if ((Object)(object)val.spotlight != (Object)null) { _flashlightLights.Add(val.spotlight); } } } private static void ApplyRangeTieredLightShadows() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 RestoreRangeTieredLightShadows(); if (!Settings.OptimizationsActive) { return; } RefreshFlashlightLights(); bool flag = Settings.ResolvedShadowQuality == ShadowQuality.Ultra; int num = ((Settings.Preset == QualityPreset.Potato) ? 1024 : 4096); int num2 = 0; Light[] array = Object.FindObjectsOfType(); foreach (Light val in array) { if ((int)val.type == 1) { _shadowResOrig[val] = val.shadowCustomResolution; val.shadowCustomResolution = 0; continue; } if (flag && _flashlightLights.Contains(val)) { _shadowResOrig[val] = val.shadowCustomResolution; val.shadowCustomResolution = 4096; num2++; continue; } float range = val.range; int num3 = ((range < 5f) ? 256 : ((range < 10f) ? 512 : ((!(range < 20f)) ? 2048 : 1024))); int num4 = num3; _shadowResOrig[val] = val.shadowCustomResolution; val.shadowCustomResolution = Mathf.Min(num4, num); num2++; } if (num2 > 0) { Plugin.Log.LogDebug((object)$"shadow-res: tiered {num2} lights (flashlights={_flashlightLights.Count}, cap={num})"); } } private static void ApplyAnisotropicFiltering(int level) { if (level <= 0) { QualitySettings.anisotropicFiltering = (AnisotropicFiltering)0; return; } QualitySettings.anisotropicFiltering = (AnisotropicFiltering)2; Texture.SetGlobalAnisotropicFilteringLimits(level, level); } } [HarmonyPatch(typeof(RenderTextureMain))] internal static class RenderTexturePatch { internal static DepthTextureMode OriginalDepthMode; internal static Antialiasing[] OriginalAAModes; internal static float VanillaWidthSmall; internal static float VanillaHeightSmall; private static bool _vrNoticeLogged; [HarmonyPostfix] [HarmonyPatch("Start")] public static void PostfixStart(RenderTextureMain __instance) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) if (VRCompat.Active) { if (!_vrNoticeLogged) { _vrNoticeLogged = true; Plugin.Log.LogInfo((object)"VR headset detected. HD render pipeline, FOV and ultrawide patches disabled; optimization layer still runs."); } return; } Camera val = null; if (__instance.cameras.Count > 0) { OriginalDepthMode = __instance.cameras[0].depthTextureMode; OriginalAAModes = (Antialiasing[])(object)new Antialiasing[__instance.cameras.Count]; for (int i = 0; i < __instance.cameras.Count; i++) { PostProcessLayer component = ((Component)__instance.cameras[i]).GetComponent(); OriginalAAModes[i] = (Antialiasing)(((Object)(object)component != (Object)null) ? ((int)component.antialiasingMode) : 0); } } for (int j = 0; j < __instance.cameras.Count; j++) { Camera val2 = __instance.cameras[j]; if (j == 0) { val = val2; UpscaleMode resolvedUpscaleMode = Settings.ResolvedUpscaleMode; if (((uint)(resolvedUpscaleMode - 1) <= 1u || resolvedUpscaleMode == UpscaleMode.FSR_Temporal) ? true : false) { val2.depthTextureMode = (DepthTextureMode)(val2.depthTextureMode | 1); val2.depthTextureMode = (DepthTextureMode)(val2.depthTextureMode | 4); } } PostProcessLayer component2 = ((Component)val2).GetComponent(); if ((Object)(object)component2 != (Object)null) { PostProcessLayer val3 = component2; val3.antialiasingMode = (Antialiasing)(Settings.ResolvedAAMode switch { AAMode.TAA => 2, AAMode.SMAA => 2, AAMode.FXAA => 1, AAMode.Off => 0, _ => component2.antialiasingMode, }); component2.fastApproximateAntialiasing.keepAlpha = true; Plugin.Log.LogDebug((object)$"AA on {((Object)val2).name}: {component2.antialiasingMode}"); } } VanillaWidthSmall = __instance.textureWidthSmall; VanillaHeightSmall = __instance.textureHeightSmall; int outputWidth = Settings.OutputWidth; int outputHeight = Settings.OutputHeight; __instance.textureWidthOriginal = outputWidth; __instance.textureHeightOriginal = outputHeight; __instance.textureWidth = outputWidth; __instance.textureHeight = outputHeight; if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.AddComponent().Setup(__instance, val); } } [HarmonyPrefix] [HarmonyPatch("Update")] public static void PrefixUpdate(RenderTextureMain __instance) { if (!Settings.ModEnabled || VRCompat.Active || Settings.Pixelation) { return; } UpscalerManager instance = UpscalerManager.Instance; float num = (((Object)(object)instance != (Object)null && instance.CurrentTier == UpscalerManager.RenderTier.NativeScaling) ? GetRenderScale() : 1f); int outputWidth = Settings.OutputWidth; int outputHeight = Settings.OutputHeight; __instance.textureWidthOriginal = Mathf.Max(Mathf.RoundToInt((float)outputWidth * num), 1); __instance.textureHeightOriginal = Mathf.Max(Mathf.RoundToInt((float)outputHeight * num), 1); if (__instance.cameras.Count > 0) { RenderTexture targetTexture = __instance.cameras[0].targetTexture; if ((Object)(object)targetTexture != (Object)null) { __instance.textureWidth = ((Texture)targetTexture).width; __instance.textureHeight = ((Texture)targetTexture).height; } else { __instance.textureWidth = outputWidth; __instance.textureHeight = outputHeight; } } } internal static void RestoreVanillaResolution() { if (!((Object)(object)RenderTextureMain.instance == (Object)null)) { RenderTextureMain instance = RenderTextureMain.instance; instance.textureWidthOriginal = VanillaWidthSmall; instance.textureHeightOriginal = VanillaHeightSmall; instance.textureWidth = VanillaWidthSmall; instance.textureHeight = VanillaHeightSmall; } } internal static void RestoreVanillaCameraSettings() { //IL_0029: 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) if ((Object)(object)RenderTextureMain.instance == (Object)null) { return; } List cameras = RenderTextureMain.instance.cameras; if (cameras.Count > 0) { cameras[0].depthTextureMode = OriginalDepthMode; } if (OriginalAAModes == null) { return; } for (int i = 0; i < cameras.Count && i < OriginalAAModes.Length; i++) { PostProcessLayer component = ((Component)cameras[i]).GetComponent(); if ((Object)(object)component != (Object)null) { component.antialiasingMode = OriginalAAModes[i]; } } } internal static void ReapplyModCameraSettings() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RenderTextureMain.instance == (Object)null) { return; } List cameras = RenderTextureMain.instance.cameras; if (cameras.Count > 0) { UpscaleMode resolvedUpscaleMode = Settings.ResolvedUpscaleMode; if (((uint)(resolvedUpscaleMode - 1) <= 1u || resolvedUpscaleMode == UpscaleMode.FSR_Temporal) ? true : false) { Camera obj = cameras[0]; obj.depthTextureMode = (DepthTextureMode)(obj.depthTextureMode | 1); Camera obj2 = cameras[0]; obj2.depthTextureMode = (DepthTextureMode)(obj2.depthTextureMode | 4); } } for (int i = 0; i < cameras.Count; i++) { PostProcessLayer component = ((Component)cameras[i]).GetComponent(); if ((Object)(object)component != (Object)null) { PostProcessLayer val = component; val.antialiasingMode = (Antialiasing)(Settings.ResolvedAAMode switch { AAMode.TAA => 2, AAMode.SMAA => 2, AAMode.FXAA => 1, AAMode.Off => 0, _ => component.antialiasingMode, }); component.fastApproximateAntialiasing.keepAlpha = true; } } } internal static float GetRenderScale() { return (float)Settings.ResolvedRenderScale / 100f; } } [HarmonyPatch(typeof(RoomVolumeCheck), "Check")] internal static class RoomVolumeCheckPatch { private const int StickyMaxTicks = 3; private static readonly Collider[] _overlapBuf = (Collider[])(object)new Collider[32]; private static readonly RaycastHit[] _sweepBuf = (RaycastHit[])(object)new RaycastHit[32]; private static bool Prefix(RoomVolumeCheck __instance, ref IEnumerator __result) { if (!Settings.ModEnabled) { return true; } __result = OptimizedCheck(__instance); return false; } private static IEnumerator OptimizedCheck(RoomVolumeCheck instance) { while (!LevelGenerator.Instance.Generated) { yield return (object)new WaitForSeconds(0.1f); } yield return (object)new WaitForSeconds(0.5f); Traverse val = Traverse.Create((object)instance); PlayerAvatar player = val.Field("player").Value; LayerMask mask = val.Field("Mask").Value; WaitForSeconds playerWait = new WaitForSeconds(0.1f); WaitForSeconds nonPlayerWait = new WaitForSeconds(0.5f); Vector3 lastPos = Vector3.zero; bool hasLastPos = false; int stickyTicks = 0; List cachedRooms = new List(4); while (true) { if (instance.PauseCheckTimer > 0f) { instance.PauseCheckTimer -= 0.5f; yield return nonPlayerWait; continue; } long startTicks = FrameTimeMeter.Begin(); RunCheck(instance, player, mask, ref lastPos, ref hasLastPos, ref stickyTicks, cachedRooms); FrameTimeMeter.End(FrameTimeMeter.RoomVolumeCheck, startTicks); if (!instance.Continuous) { break; } yield return Object.op_Implicit((Object)(object)player) ? playerWait : nonPlayerWait; } } private static void RunCheck(RoomVolumeCheck instance, PlayerAvatar player, LayerMask mask, ref Vector3 lastPos, ref bool hasLastPos, ref int stickyTicks, List cachedRooms) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = instance.currentSize; if (val == Vector3.zero) { val = ((Component)instance).transform.localScale; } Vector3 val2 = val * 0.5f; Vector3 val3 = ((Component)instance).transform.position + ((Component)instance).transform.rotation * instance.CheckPosition; Quaternion rotation = ((Component)instance).transform.rotation; if (hasLastPos && instance.wasInRoom && stickyTicks == 0) { Vector3 val4 = val3 - lastPos; if (((Vector3)(ref val4)).sqrMagnitude < 0.0001f) { ApplyGameLogicTail(instance, player); return; } } instance.inTruck = false; instance.inExtractionPoint = false; instance.CurrentRooms.Clear(); int num = Physics.OverlapBoxNonAlloc(val3, val2, _overlapBuf, rotation, LayerMask.op_Implicit(mask)); for (int i = 0; i < num; i++) { AddRoom(instance, _overlapBuf[i]); } if ((instance.CurrentRooms.Count == 0) & hasLastPos) { Vector3 val5 = val3 - lastPos; float magnitude = ((Vector3)(ref val5)).magnitude; if (magnitude > 0.01f) { int num2 = Physics.BoxCastNonAlloc(lastPos, val2, val5 / magnitude, _sweepBuf, rotation, magnitude, LayerMask.op_Implicit(mask)); for (int j = 0; j < num2; j++) { AddRoom(instance, ((RaycastHit)(ref _sweepBuf[j])).collider); } } } bool flag = false; if (instance.CurrentRooms.Count == 0 && instance.wasInRoom && stickyTicks < 3) { for (int k = 0; k < cachedRooms.Count; k++) { RoomVolume val6 = cachedRooms[k]; if (!((Object)(object)val6 == (Object)null)) { instance.CurrentRooms.Add(val6); if (val6.Truck) { instance.inTruck = true; } if (val6.Extraction) { instance.inExtractionPoint = true; } } } if (instance.CurrentRooms.Count > 0) { stickyTicks++; flag = true; } } if (!flag) { stickyTicks = 0; } if (!flag && instance.CurrentRooms.Count > 0) { cachedRooms.Clear(); for (int l = 0; l < instance.CurrentRooms.Count; l++) { cachedRooms.Add(instance.CurrentRooms[l]); } } ApplyGameLogicTail(instance, player); lastPos = val3; hasLastPos = true; } private static void AddRoom(RoomVolumeCheck instance, Collider col) { if ((Object)(object)col == (Object)null) { return; } RoomVolume val = ((Component)((Component)col).transform).GetComponent(); if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)((Component)col).transform).GetComponentInParent(); } if (Object.op_Implicit((Object)(object)val) && !instance.CurrentRooms.Contains(val)) { instance.CurrentRooms.Add(val); if (val.Truck) { instance.inTruck = true; } if (val.Extraction) { instance.inExtractionPoint = true; } } } private static void ApplyGameLogicTail(RoomVolumeCheck instance, PlayerAvatar player) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player) && instance.CurrentRooms.Count > 0) { bool flag = true; MapModule mapModule = instance.CurrentRooms[0].MapModule; for (int i = 1; i < instance.CurrentRooms.Count; i++) { if ((Object)(object)mapModule != (Object)(object)instance.CurrentRooms[i].MapModule) { flag = false; break; } } if (flag && instance.CurrentRooms[0].SetExplored() && player.isLocal && Object.op_Implicit((Object)(object)TruckSafetySpawnPoint.instance) && Object.op_Implicit((Object)(object)ProgressionManager.instance)) { float num = Vector3.Distance(player.playerTransform.position, ((Component)TruckSafetySpawnPoint.instance).transform.position) / 20f; ProgressionManager instance2 = ProgressionManager.instance; instance2.roundPointsScouting += 100f * num; } } instance.wasInRoom = instance.CurrentRooms.Count > 0; instance.TutorialExtractionReminderLogic(); } } internal static class CameraZoomFovOverride { private static readonly Dictionary _originals = new Dictionary(); private static readonly Dictionary _activeAnims = new Dictionary(); private const float AnimDuration = 0.25f; internal static void Apply(CameraZoom cz) { if ((Object)(object)cz == (Object)null || VRCompat.Active) { return; } if (!Settings.ModEnabled) { Restore(cz); return; } if (!_originals.ContainsKey(cz)) { _originals[cz] = cz.playerZoomDefault; } float num = ((Settings.VerticalFovOverride > 0) ? ((float)Settings.VerticalFovOverride) : ComputeAspectAwareDefault(_originals[cz])); float num2 = ((Screen.height > 0) ? ((float)Screen.width / (float)Screen.height) : 0f); float num3 = ((num2 > 0f) ? (2f * Mathf.Atan(Mathf.Tan(num * (MathF.PI / 180f) / 2f) * num2) * 57.29578f) : 0f); Plugin.Log.LogDebug((object)($"[fov] gameplay vFOV {_originals[cz]:F0} -> {num:F0} " + $"(slider={Settings.VerticalFovOverride}, aspect={num2:F3}, hFOV={num3:F0})")); StartFovAnim(cz, num); } internal static float ComputeAspectAwareDefault(float vanilla16x9Fov) { if (Screen.height == 0) { return vanilla16x9Fov; } float num = (float)Screen.width / (float)Screen.height; float num2 = vanilla16x9Fov * (MathF.PI / 180f); if (2f * Mathf.Atan(Mathf.Tan(num2 / 2f) * num) <= MathF.PI * 3f / 4f) { return vanilla16x9Fov; } return 2f * Mathf.Atan(Mathf.Tan(MathF.PI * 3f / 8f) / num) * 57.29578f; } internal static void Restore(CameraZoom cz) { if (!((Object)(object)cz == (Object)null) && _originals.TryGetValue(cz, out var value)) { StartFovAnim(cz, value); } } internal static void RestoreAll() { foreach (KeyValuePair original in _originals) { if ((Object)(object)original.Key != (Object)null) { StartFovAnim(original.Key, original.Value); } } } internal static void RefreshAll() { CameraZoom[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { Apply(array[i]); } } private static void StartFovAnim(CameraZoom cz, float targetFov) { if ((Object)(object)Plugin.Instance == (Object)null) { WriteFovImmediate(cz, targetFov); return; } if (_activeAnims.TryGetValue(cz, out Coroutine value) && value != null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(value); } float playerZoomDefault = cz.playerZoomDefault; if (!Mathf.Approximately(playerZoomDefault, targetFov)) { _activeAnims[cz] = ((MonoBehaviour)Plugin.Instance).StartCoroutine(AnimateFov(cz, playerZoomDefault, targetFov, 0.25f)); } } private static void WriteFovImmediate(CameraZoom cz, float fov) { cz.playerZoomDefault = fov; cz.zoomPrev = fov; cz.zoomNew = fov; cz.zoomLerp = 1f; } private static IEnumerator AnimateFov(CameraZoom cz, float startFov, float targetFov, float duration) { float t = 0f; while (t < duration && (Object)(object)cz != (Object)null) { t += Time.deltaTime; float num = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(t / duration)); WriteFovImmediate(cz, Mathf.Lerp(startFov, targetFov, num)); yield return null; } if ((Object)(object)cz != (Object)null) { WriteFovImmediate(cz, targetFov); _activeAnims.Remove(cz); } } } [HarmonyPatch(typeof(CameraZoom), "Awake")] internal static class CameraZoomAwakePatch { [HarmonyPostfix] private static void Postfix(CameraZoom __instance) { CameraZoomFovOverride.Apply(__instance); } } internal static class MenuCameraFovOverride { private static Camera? _trackedCam; private static float _vanillaFov; private static bool _captured; internal static void Apply() { if (VRCompat.Active) { return; } if (!Settings.ModEnabled) { Restore(); return; } CameraNoPlayerTarget instance = CameraNoPlayerTarget.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.cam == (Object)null) { return; } Camera cam = instance.cam; if (cam.fieldOfView < 5f) { return; } if (!_captured || (Object)(object)_trackedCam != (Object)(object)cam) { _trackedCam = cam; _vanillaFov = cam.fieldOfView; _captured = true; } float num = ApplyAspectCorrection(_vanillaFov); if (!Mathf.Approximately(cam.fieldOfView, num)) { cam.fieldOfView = num; } if (Screen.height != 0) { float num2 = (float)Screen.width / (float)Screen.height; if (num2 > 1.7877778f && !Mathf.Approximately(cam.aspect, num2)) { cam.aspect = num2; } } } internal static void Restore() { if (_captured && (Object)(object)_trackedCam != (Object)null) { _trackedCam.fieldOfView = _vanillaFov; _trackedCam.ResetAspect(); } _captured = false; _trackedCam = null; } private static float ApplyAspectCorrection(float baseFov) { return CameraZoomFovOverride.ComputeAspectAwareDefault(baseFov); } } [HarmonyPatch(typeof(CameraNoPlayerTarget), "Awake")] internal static class CameraNoPlayerTargetAwakePatch { [HarmonyPostfix] private static void Postfix() { MenuCameraFovOverride.Apply(); } } internal static class UltrawideMenuTweaks { private const float FogMult = 0.6f; private const int StabilizationFrames = 30; private static bool _applied; private static Camera? _trackedCam; private static float _vanillaFogStart; private static float _vanillaFogEnd; private static int _menuFrames; internal static void Tick() { CameraNoPlayerTarget instance = CameraNoPlayerTarget.instance; Camera val = (((Object)(object)instance != (Object)null) ? instance.cam : null); if (Settings.ModEnabled && Settings.UltrawideUiFix && Screen.height > 0 && (float)Screen.width / (float)Screen.height > 1.7877778f && SemiFunc.MenuLevel() && (Object)(object)val != (Object)null) { _menuFrames++; if (_menuFrames >= 30) { if (!_applied || (Object)(object)_trackedCam != (Object)(object)val) { ApplyOnce(val); } EnforceEachFrame(); } return; } _menuFrames = 0; if (_applied) { if (SemiFunc.MenuLevel() && (Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)_trackedCam) { Restore(); } else { ClearWithoutRestoringRenderSettings(); } } } private static void ApplyOnce(Camera cam) { float fogStartDistance = RenderSettings.fogStartDistance; float fogEndDistance = RenderSettings.fogEndDistance; if (!(fogEndDistance <= 1f)) { _trackedCam = cam; _vanillaFogStart = fogStartDistance; _vanillaFogEnd = fogEndDistance; _applied = true; } } private static void EnforceEachFrame() { RenderSettings.fogStartDistance = _vanillaFogStart * 0.6f; RenderSettings.fogEndDistance = _vanillaFogEnd * 0.6f; } private static void Restore() { RenderSettings.fogStartDistance = _vanillaFogStart; RenderSettings.fogEndDistance = _vanillaFogEnd; _applied = false; _trackedCam = null; } private static void ClearWithoutRestoringRenderSettings() { _applied = false; _trackedCam = null; } } internal static class UltrawideCompareResolution { private static bool _active; private static bool _savedUiFix; internal static bool IsCompareActive => _active; internal static void HandleToggle(bool enabling) { if (Screen.height <= 0) { return; } float num = (float)Screen.width / (float)Screen.height; if (!enabling) { if (!_active && !(num <= 1.7877778f)) { _savedUiFix = Settings.UltrawideUiFix; Settings.UltrawideUiFix = false; ApplyAspectOverrideToAllCameras(1.7777778f); _active = true; } } else if (_active) { ResetAspectOnAllCameras(); Settings.UltrawideUiFix = _savedUiFix; _active = false; } } internal static void TickEnforcement() { if (_active) { ApplyAspectOverrideToAllCameras(1.7777778f); } } private static void ApplyAspectOverrideToAllCameras(float aspect) { if ((Object)(object)Camera.main != (Object)null) { Camera.main.aspect = aspect; } RenderTextureMain instance = RenderTextureMain.instance; if ((Object)(object)instance != (Object)null && instance.cameras != null) { foreach (Camera camera in instance.cameras) { if ((Object)(object)camera != (Object)null) { camera.aspect = aspect; } } } CameraNoPlayerTarget instance2 = CameraNoPlayerTarget.instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.cam != (Object)null) { instance2.cam.aspect = aspect; } } private static void ResetAspectOnAllCameras() { if ((Object)(object)Camera.main != (Object)null) { Camera.main.ResetAspect(); } RenderTextureMain instance = RenderTextureMain.instance; if ((Object)(object)instance != (Object)null && instance.cameras != null) { foreach (Camera camera in instance.cameras) { if ((Object)(object)camera != (Object)null) { camera.ResetAspect(); } } } CameraNoPlayerTarget instance2 = CameraNoPlayerTarget.instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.cam != (Object)null) { instance2.cam.ResetAspect(); } } } internal static class HudCursorRemap { internal static bool Active; internal static Vector2 OverlayScale = Vector2.one; internal static Vector3 Correct(Vector3 screenPos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (Screen.height == 0) { return screenPos; } if (Active) { float num = (float)Screen.width / (float)Screen.height; if (num > 1.7877778f) { float num2 = (float)Screen.height * 1.7777778f; float num3 = ((float)Screen.width - num2) * 0.5f; screenPos.x = (screenPos.x - num3) * ((float)Screen.width / num2); } else if (num < 1.7677778f) { float num4 = (float)Screen.width / 1.7777778f; float num5 = ((float)Screen.height - num4) * 0.5f; screenPos.y = (screenPos.y - num5) * ((float)Screen.height / num4); } } if (OverlayScale.x != 1f) { screenPos.x *= OverlayScale.x; } if (OverlayScale.y != 1f) { screenPos.y *= OverlayScale.y; } return screenPos; } internal static Vector3 CorrectedMousePosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Correct(Input.mousePosition); } } [HarmonyPatch(typeof(SemiFunc), "UIMousePosToUIPos")] internal static class UIMousePosRemapPatch { private static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo getMouse = AccessTools.PropertyGetter(typeof(Input), "mousePosition"); MethodInfo corrected = AccessTools.Method(typeof(HudCursorRemap), "CorrectedMousePosition", (Type[])null, (Type[])null); int swapped = 0; foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Call && object.Equals(instruction.operand, getMouse)) { yield return new CodeInstruction(OpCodes.Call, (object)corrected) { labels = instruction.labels, blocks = instruction.blocks }; swapped++; } else { yield return instruction; } } if (swapped == 0) { Plugin.Log.LogWarning((object)"[ultrawide] UIMousePosToUIPos transpiler matched nothing; HUD-unstretch cursor remap is inactive this session. Report this if it appears after a game update."); } } } [HarmonyPatch(typeof(SemiFunc), "UIPositionToUIPosition")] internal static class UIPositionRemapPatch { private static void Prefix(ref Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) position = HudCursorRemap.Correct(position); } } [HarmonyPatch(typeof(SemiFunc), "UIWorldToCanvasPosition")] internal static class WorldToCanvasUltrawidePatch { private static void Postfix(ref Vector3 __result) { UltrawideWorldTrackScale.Apply(ref __result); } } [HarmonyPatch(typeof(ValuableDiscoverGraphic), "RendererBoundsInScreenSpace")] internal static class ValuableDiscoverUltrawidePatch { private static void Postfix(ref Rect __result) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (Settings.ModEnabled && Settings.UltrawideUiFix && !VRCompat.Active && UltrawideCanvasFix.RequiresAspectFix() && Screen.height != 0) { float num = (float)Screen.width / (float)Screen.height; float num2 = ((num > 1.7777778f) ? (num / 1.7777778f) : 1f); float num3 = ((num < 1.7777778f) ? (1.7777778f / num) : 1f); __result = Rect.MinMaxRect(0.5f + (((Rect)(ref __result)).xMin - 0.5f) * num2, 0.5f + (((Rect)(ref __result)).yMin - 0.5f) * num3, 0.5f + (((Rect)(ref __result)).xMax - 0.5f) * num2, 0.5f + (((Rect)(ref __result)).yMax - 0.5f) * num3); } } } internal static class UltrawideWorldTrackScale { internal static void Apply(ref Vector3 canvasPos) { if (Settings.ModEnabled && Settings.UltrawideUiFix && !VRCompat.Active && UltrawideCanvasFix.RequiresAspectFix() && Screen.height != 0) { float num = (float)Screen.width / (float)Screen.height; if (num > 1.7777778f) { canvasPos.x *= num / 1.7777778f; } else { canvasPos.y *= 1.7777778f / num; } } } } internal static class OverlayCameraWiden { private static Camera? _cam; private static float _vanillaSize; private static bool _applied; private static bool _panelLogged; private static float _lastHudAspect = -1f; private static RenderTexture? _overlayRT; private static int _overlayOrigW; private static int _overlayOrigH; private static bool _overlayDiagLogged; internal static void Tick() { //IL_00a8: 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) if (!_panelLogged && Screen.height > 0) { _panelLogged = true; Plugin.Log.LogInfo((object)($"[ultrawide] panel {Screen.width}x{Screen.height} " + $"aspect={(float)Screen.width / (float)Screen.height:F3} " + $"requiresFix={UltrawideCanvasFix.RequiresAspectFix()}")); } Camera val = (((Object)(object)CameraOverlay.instance != (Object)null) ? CameraOverlay.instance.overlayCamera : null); if ((Object)(object)val == (Object)null) { _cam = null; _applied = false; HudCursorRemap.Active = false; HudCursorRemap.OverlayScale = Vector2.one; return; } if ((Object)(object)_cam != (Object)(object)val) { _cam = val; _vanillaSize = val.orthographicSize; _applied = false; } if (Settings.ModEnabled && Settings.UltrawideUiFix && Settings.UltrawideHudUnstretch && !VRCompat.Active && !UltrawideCompareResolution.IsCompareActive && UltrawideCanvasFix.RequiresAspectFix() && UltrawideCanvasFix.UnderlayActive && Screen.height > 0) { float num = (float)Screen.width / (float)Screen.height; float num2 = Mathf.Max(_vanillaSize, _vanillaSize * 1.7777778f / num); if (!Mathf.Approximately(val.aspect, num)) { val.aspect = num; } if (!Mathf.Approximately(val.orthographicSize, num2)) { val.orthographicSize = num2; } _applied = true; } else if (_applied) { val.orthographicSize = _vanillaSize; val.ResetAspect(); _applied = false; } HudCursorRemap.Active = _applied; if (Settings.ModEnabled && Settings.SharpHud && !VRCompat.Active && !UltrawideCompareResolution.IsCompareActive && Screen.height > 0) { LiftOverlayResolution(val, _applied); } else { RestoreOverlayResolution(val); } float num3 = ((Screen.height > 0) ? ((float)Screen.width / (float)Screen.height) : 0f); if (Mathf.Abs(num3 - _lastHudAspect) > 0.01f) { _lastHudAspect = num3; HudCoverStretch.Tick(widenActive: false); MenuEdgeArtExtend.Tick(widenActive: false); HudParkedShift.Tick(widenActive: false); RevealGuard.Tick(widenActive: false); } HudCoverStretch.Tick(_applied); MenuEdgeArtExtend.Tick(_applied); HudParkedShift.Tick(_applied); RevealGuard.Tick(_applied); } private static void LiftOverlayResolution(Camera cam, bool widened) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) RenderTexture targetTexture = cam.targetTexture; if ((Object)(object)targetTexture == (Object)null) { return; } if ((Object)(object)_overlayRT != (Object)(object)targetTexture) { _overlayRT = targetTexture; _overlayOrigW = ((Texture)targetTexture).width; _overlayOrigH = ((Texture)targetTexture).height; } if (!_overlayDiagLogged) { _overlayDiagLogged = true; RenderTextureMain instance = RenderTextureMain.instance; Texture val = (((Object)(object)instance != (Object)null && (Object)(object)instance.overlayRawImage != (Object)null) ? instance.overlayRawImage.texture : null); Plugin.Log.LogInfo((object)($"[ultrawide] overlay RT {((Texture)targetTexture).width}x{((Texture)targetTexture).height} id={((Object)targetTexture).GetInstanceID()} " + "displayedTex=" + (((Object)(object)val != (Object)null) ? $"{val.width}x{val.height} id={((Object)val).GetInstanceID()}" : "null") + " " + $"screen={Screen.width}x{Screen.height} widened={widened}")); } int num; int height; if (widened) { num = Screen.width; height = Screen.height; } else { height = Screen.height; num = ((_overlayOrigH > 0) ? Mathf.Max(1, Mathf.RoundToInt((float)height * (float)_overlayOrigW / (float)_overlayOrigH)) : Screen.width); } if (num > 0 && height > 0) { HudCursorRemap.OverlayScale = (Vector2)((_overlayOrigW > 0 && _overlayOrigH > 0) ? new Vector2((float)num / (float)_overlayOrigW, (float)height / (float)_overlayOrigH) : Vector2.one); if (((Texture)targetTexture).width != num || ((Texture)targetTexture).height != height) { ResizeBoundRT(cam, targetTexture, num, height); } } } private static void RestoreOverlayResolution(Camera cam) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) HudCursorRemap.OverlayScale = Vector2.one; if (!((Object)(object)_overlayRT == (Object)null)) { if (((Texture)_overlayRT).width != _overlayOrigW || ((Texture)_overlayRT).height != _overlayOrigH) { ResizeBoundRT(cam, _overlayRT, _overlayOrigW, _overlayOrigH); } _overlayRT = null; } } private static void ResizeBoundRT(Camera cam, RenderTexture rt, int w, int h) { bool num = (Object)(object)cam.targetTexture == (Object)(object)rt; if (num) { cam.targetTexture = null; } rt.Release(); ((Texture)rt).width = w; ((Texture)rt).height = h; rt.Create(); if (num) { cam.targetTexture = rt; } } } internal static class HudCoverStretch { private static readonly List<(RectTransform Rect, Vector3 Vanilla)> _stretched = new List<(RectTransform, Vector3)>(); private static float _rescanTimer; private static bool _active; internal static void Tick(bool widenActive) { if (widenActive && !_active) { _active = true; _rescanTimer = 0f; Rescan(); } else if (!widenActive && _active) { _active = false; RestoreAll(); } else if (_active) { _rescanTimer += Time.unscaledDeltaTime; if (_rescanTimer >= 0.4f) { _rescanTimer = 0f; Rescan(); } } } internal static void Rescan() { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) if (!_active || Screen.height == 0) { return; } HUDCanvas instance = HUDCanvas.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.rect == (Object)null) { return; } float num = (float)Screen.width / (float)Screen.height; float num2 = ((num > 1.7777778f) ? (num / 1.7777778f) : 1f); float num3 = ((num < 1.7777778f) ? (1.7777778f / num) : 1f); if (num2 <= 1f && num3 <= 1f) { return; } Graphic[] componentsInChildren = ((Component)instance.rect).GetComponentsInChildren(true); foreach (Graphic val in componentsInChildren) { if (!(val is Image) && !(val is RawImage)) { continue; } RectTransform rectTransform = val.rectTransform; if (!IsCover(val, rectTransform)) { continue; } bool flag = false; foreach (var item in _stretched) { if ((Object)(object)item.Rect == (Object)(object)rectTransform) { flag = true; break; } } if (!flag) { Vector3 localScale = ((Transform)rectTransform).localScale; _stretched.Add((rectTransform, localScale)); ((Transform)rectTransform).localScale = new Vector3(localScale.x * num2, localScale.y * num3, localScale.z); Plugin.Log.LogDebug((object)("[ultrawide] cover stretched: " + ((Object)((Component)val).gameObject).name + " (" + ArtName(val) + ")")); } } } private static bool IsCover(Graphic g, RectTransform rt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0025: 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) Rect rect = rt.rect; float num = ((Rect)(ref rect)).width * Mathf.Abs(((Transform)rt).lossyScale.x); rect = rt.rect; float num2 = ((Rect)(ref rect)).height * Mathf.Abs(((Transform)rt).lossyScale.y); if (num < 600f || num2 < 290f) { return false; } string text = ArtName(g); if (text.Length == 0) { return true; } string text2 = (((Object)((Component)g).gameObject).name + "|" + text).ToLowerInvariant(); if (!text2.Contains("vignette") && !text2.Contains("fade") && !text2.Contains("background") && !text2.Contains("gradient") && !text2.Contains("dark")) { return text2.Contains("dim"); } return true; } private static string ArtName(Graphic g) { Image val = (Image)(object)((g is Image) ? g : null); if (val != null) { if (!((Object)(object)val.sprite != (Object)null)) { return ""; } return ((Object)val.sprite).name; } RawImage val2 = (RawImage)(object)((g is RawImage) ? g : null); if (val2 != null) { if (!((Object)(object)val2.texture != (Object)null)) { return ""; } return ((Object)val2.texture).name; } return ""; } internal static bool Manages(Transform t) { foreach (var item2 in _stretched) { RectTransform item = item2.Rect; if ((Object)(object)item != (Object)null && ((Object)(object)t == (Object)(object)item || t.IsChildOf((Transform)(object)item))) { return true; } } return false; } private static void RestoreAll() { //IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references) foreach (var (val, localScale) in _stretched) { if ((Object)(object)val != (Object)null) { ((Transform)val).localScale = localScale; } } _stretched.Clear(); } } internal static class MenuEdgeArtExtend { private static readonly List<(RectTransform Rect, Vector3 Scale, Vector2 Pos)> _extended = new List<(RectTransform, Vector3, Vector2)>(); private static float _rescanTimer; private static bool _active; internal static void Tick(bool widenActive) { if (widenActive && !_active) { _active = true; _rescanTimer = 0f; Rescan(); } else if (!widenActive && _active) { _active = false; RestoreAll(); } else if (_active) { _rescanTimer += Time.unscaledDeltaTime; if (_rescanTimer >= 0.4f) { _rescanTimer = 0f; Rescan(); } } } internal static void Rescan() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) if (!_active || Screen.height == 0) { return; } HUDCanvas instance = HUDCanvas.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.rect == (Object)null) { return; } float num = (float)Screen.width / (float)Screen.height; float num2 = ((num > 1.7777778f) ? (num / 1.7777778f) : 1f); float num3 = ((num < 1.7777778f) ? (1.7777778f / num) : 1f); if (num2 <= 1f && num3 <= 1f) { return; } float num4 = instance.rect.sizeDelta.x * 0.5f; float y = instance.rect.sizeDelta.y; float num5 = num4 * num2; Graphic[] componentsInChildren = ((Component)instance.rect).GetComponentsInChildren(true); foreach (Graphic val in componentsInChildren) { if (!(val is Image) && !(val is RawImage)) { continue; } RectTransform rectTransform = val.rectTransform; if (rectTransform.anchorMin.x != rectTransform.anchorMax.x || !Mathf.Approximately(rectTransform.pivot.x, 0.5f) || !Mathf.Approximately(rectTransform.pivot.y, 0.5f)) { continue; } Image val2 = (Image)(object)((val is Image) ? val : null); object obj; if (val2 != null) { obj = (((Object)(object)val2.sprite != (Object)null) ? ((Object)val2.sprite).name : ""); } else { RawImage val3 = (RawImage)(object)((val is RawImage) ? val : null); obj = ((val3 == null) ? "" : (((Object)(object)val3.texture != (Object)null) ? ((Object)val3.texture).name : "")); } string text = (string)obj; if (!(((Object)((Component)val).gameObject).name + "|" + text).ToLowerInvariant().Contains("gradient")) { continue; } Rect rect = rectTransform.rect; float num6 = ((Rect)(ref rect)).width * Mathf.Abs(((Transform)rectTransform).lossyScale.x); rect = rectTransform.rect; float num7 = ((Rect)(ref rect)).height * Mathf.Abs(((Transform)rectTransform).lossyScale.y); if (num6 < 100f || num6 >= 600f || num7 < y * 0.9f) { continue; } Transform parent = ((Transform)rectTransform).parent; RectTransform val4 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val4 != null && Mathf.Abs(((Transform)val4).lossyScale.x - 1f) > 0.05f) { continue; } Vector2 anchoredPosition = rectTransform.anchoredPosition; float num8 = anchoredPosition.x - num6 * 0.5f; float num9 = anchoredPosition.x + num6 * 0.5f; bool flag = num8 <= 0f - num4 + 8f; bool flag2 = num9 >= num4 - 8f; if (flag == flag2) { continue; } bool flag3 = false; foreach (var item in _extended) { if ((Object)(object)item.Rect == (Object)(object)rectTransform) { flag3 = true; break; } } if (!flag3) { Vector3 localScale = ((Transform)rectTransform).localScale; Vector2 anchoredPosition2 = rectTransform.anchoredPosition; _extended.Add((rectTransform, localScale, anchoredPosition2)); if (num2 > 1f) { float num10 = (flag ? ((num9 + num5 + 16f) / num6) : ((num5 + 16f - num8) / num6)); float num11 = (num10 - 1f) * num6 * 0.5f; ((Transform)rectTransform).localScale = new Vector3(localScale.x * num10, localScale.y * num3, localScale.z); rectTransform.anchoredPosition = new Vector2(anchoredPosition2.x + (flag ? (0f - num11) : num11), anchoredPosition2.y); } else { ((Transform)rectTransform).localScale = new Vector3(localScale.x, localScale.y * num3, localScale.z); } rect = rectTransform.rect; float num12 = ((Rect)(ref rect)).width * Mathf.Abs(((Transform)rectTransform).lossyScale.x); float x = rectTransform.anchoredPosition.x; Plugin.Log.LogDebug((object)("[ultrawide] edge art extended: " + ((Object)((Component)val).gameObject).name + " (" + text + ")" + $" span=[{x - num12 * 0.5f:F1},{x + num12 * 0.5f:F1}] capture=[{0f - num5:F1},{num5:F1}]")); } } } internal static bool Manages(Transform t) { foreach (var item2 in _extended) { RectTransform item = item2.Rect; if ((Object)(object)item != (Object)null && ((Object)(object)t == (Object)(object)item || t.IsChildOf((Transform)(object)item))) { return true; } } return false; } private static void RestoreAll() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) foreach (var (val, localScale, anchoredPosition) in _extended) { if (!((Object)(object)val == (Object)null)) { ((Transform)val).localScale = localScale; val.anchoredPosition = anchoredPosition; } } _extended.Clear(); } } internal static class HudParkedShift { private static readonly List<(SemiUI Ui, Vector2 Hide)> _shifted = new List<(SemiUI, Vector2)>(); private static readonly HashSet _classified = new HashSet(); private static readonly HashSet _pendingLogged = new HashSet(); private static bool _summaryLogged; private static float _rescanTimer; private static bool _active; internal static void Tick(bool widenActive) { if (widenActive && !_active) { _active = true; _rescanTimer = 0f; Rescan(); } else if (!widenActive && _active) { _active = false; RestoreAll(); } else if (_active) { _rescanTimer += Time.unscaledDeltaTime; if (_rescanTimer >= 0.4f) { _rescanTimer = 0f; Rescan(); } } } internal static void Rescan() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0585: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) if (!_active || Screen.height == 0) { return; } HUDCanvas instance = HUDCanvas.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.rect == (Object)null) { return; } float num = (float)Screen.width / (float)Screen.height; float num2 = ((num > 1.7777778f) ? (num / 1.7777778f) : 1f); float num3 = ((num < 1.7777778f) ? (1.7777778f / num) : 1f); if (num2 <= 1f && num3 <= 1f) { return; } float num4 = instance.rect.sizeDelta.x * 0.5f; float num5 = instance.rect.sizeDelta.y * 0.5f; float num6 = num4 * (num2 - 1f) + 8f; float num7 = num5 * (num3 - 1f) + 8f; if (!_summaryLogged) { _summaryLogged = true; Plugin.Log.LogInfo((object)($"[ultrawide] parked-shift scan: aspect={num:F3} " + $"xF={num2:F3} yF={num3:F3} canvas={instance.rect.sizeDelta.x:F0}x{instance.rect.sizeDelta.y:F0} " + $"ext=({num6:F1},{num7:F1})")); } SemiUI[] componentsInChildren = ((Component)instance.rect).GetComponentsInChildren(true); foreach (SemiUI val in componentsInChildren) { if (val.allChildren == null) { if (_pendingLogged.Add(val)) { Plugin.Log.LogInfo((object)("[ultrawide] parked-shift: " + ((Object)((Component)val).gameObject).name + " start pending")); } continue; } bool flag = false; foreach (var item in _shifted) { if ((Object)(object)item.Ui == (Object)(object)val) { flag = true; break; } } if (flag) { continue; } Transform val2 = (val.animateTheEntireObject ? ((Component)val).transform : val.textRectTransform); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.parent == (Object)null) { if (_classified.Add(val)) { Plugin.Log.LogInfo((object)("[ultrawide] parked-shift: " + ((Object)((Component)val).gameObject).name + " no mover " + $"(animateEntire={val.animateTheEntireObject})")); } continue; } Vector2 val3 = Vector2.op_Implicit(((Transform)instance.rect).InverseTransformPoint(val2.parent.TransformPoint(new Vector3(val.hidePosition.x, val.hidePosition.y, 0f)))); Vector2 val4 = Vector2.op_Implicit(((Transform)instance.rect).InverseTransformPoint(val2.parent.TransformPoint(new Vector3(val.showPosition.x, val.showPosition.y, 0f)))); Vector2 val5 = val3 - val4; float num8 = num4 * num2; float num9 = num5 * num3; Vector2 zero = Vector2.zero; if (num2 > 1f) { if (val3.x >= num4) { zero.x = num6; } else if (val3.x <= 0f - num4) { zero.x = 0f - num6; } else if (val5.x < -1f) { zero.x = 0f - (num8 + 120f) - val3.x; } else if (val5.x > 1f) { zero.x = num8 + 120f - val3.x; } } if (num3 > 1f) { if (val3.y >= num5) { zero.y = num7; } else if (val3.y <= 0f - num5) { zero.y = 0f - num7; } else if (val5.y < -1f) { zero.y = 0f - (num9 + 120f) - val3.y; } else if (val5.y > 1f) { zero.y = num9 + 120f - val3.y; } } if (zero == Vector2.zero) { if (_classified.Add(val)) { Plugin.Log.LogInfo((object)("[ultrawide] parked-shift: " + ((Object)((Component)val).gameObject).name + " inside " + $"parked=({val3.x:F1},{val3.y:F1}) half=({num4:F0},{num5:F0})")); } continue; } Vector2 val6 = Vector2.op_Implicit(val2.parent.InverseTransformVector(((Transform)instance.rect).TransformVector(new Vector3(zero.x, zero.y, 0f)))); _shifted.Add((val, val.hidePosition)); bool flag2 = val.hidePositionCurrent == val.hidePosition; val.hidePosition += val6; if (flag2) { val.hidePositionCurrent = val.hidePosition; } _classified.Add(val); Plugin.Log.LogInfo((object)("[ultrawide] parked-shift: " + ((Object)((Component)val).gameObject).name + " shifted " + $"push=({zero.x:F1},{zero.y:F1}) parked=({val3.x:F1},{val3.y:F1}) atPark={flag2}")); } } private static void RestoreAll() { //IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) foreach (var (val, val2) in _shifted) { if (!((Object)(object)val == (Object)null)) { bool num = val.hidePositionCurrent == val.hidePosition; val.hidePosition = val2; if (num) { val.hidePositionCurrent = val2; } } } _shifted.Clear(); _classified.Clear(); _pendingLogged.Clear(); _summaryLogged = false; } } internal static class RevealGuard { private static readonly List<(Graphic G, SemiUI? Semi)> _culled = new List<(Graphic, SemiUI)>(); private static readonly HashSet _logged = new HashSet(); private static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; private static float _timer; private static bool _active; internal static void Tick(bool widenActive) { if (widenActive && !_active) { _active = true; _timer = 0f; Scan(); } else if (!widenActive && _active) { _active = false; UncullAll(); } else if (_active) { WatchCulled(); _timer += Time.unscaledDeltaTime; if (_timer >= 0.2f) { _timer = 0f; Scan(); } } } private static SemiUI? HidingOwner(Graphic g) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) SemiUI[] componentsInParent = ((Component)g).GetComponentsInParent(true); foreach (SemiUI val in componentsInParent) { if (!(val.hidePosition == val.showPosition)) { Vector2 val2 = val.hidePositionCurrent - val.hidePosition; float sqrMagnitude = ((Vector2)(ref val2)).sqrMagnitude; val2 = val.hidePositionCurrent - val.showPosition; float sqrMagnitude2 = ((Vector2)(ref val2)).sqrMagnitude; if (sqrMagnitude <= sqrMagnitude2) { return val; } } } return null; } private static void WatchCulled() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0064: Unknown result type (might be due to invalid IL or missing references) //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_0074: Unknown result type (might be due to invalid IL or missing references) for (int num = _culled.Count - 1; num >= 0; num--) { var (val, val2) = _culled[num]; if ((Object)(object)val == (Object)null) { _culled.RemoveAt(num); } else { int num2; if (!((Object)(object)val2 == (Object)null)) { Vector2 val3 = val2.hidePositionCurrent - val2.showPosition; float sqrMagnitude = ((Vector2)(ref val3)).sqrMagnitude; val3 = val2.hidePositionCurrent - val2.hidePosition; num2 = ((sqrMagnitude < ((Vector2)(ref val3)).sqrMagnitude) ? 1 : 0); } else { num2 = 1; } bool flag = (byte)num2 != 0; if (!((Behaviour)val).isActiveAndEnabled || flag) { val.canvasRenderer.cull = false; _culled.RemoveAt(num); } } } } private static void Scan() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) HUDCanvas instance = HUDCanvas.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.rect == (Object)null || Screen.height == 0) { return; } float num = (float)Screen.width / (float)Screen.height; float num2 = ((num > 1.7777778f) ? (num / 1.7777778f) : 1f); float num3 = ((num < 1.7777778f) ? (1.7777778f / num) : 1f); if (num2 <= 1f && num3 <= 1f) { return; } float num4 = instance.rect.sizeDelta.x * 0.5f; float num5 = instance.rect.sizeDelta.y * 0.5f; float num6 = num4 * num2; float num7 = num5 * num3; Graphic[] componentsInChildren = ((Component)instance.rect).GetComponentsInChildren(false); Vector2 val2 = default(Vector2); Vector2 val3 = default(Vector2); foreach (Graphic val in componentsInChildren) { if (!((Behaviour)val).enabled || val.color.a < 0.01f) { continue; } RectTransform rectTransform = val.rectTransform; rectTransform.GetWorldCorners(_corners); ((Vector2)(ref val2))..ctor(float.MaxValue, float.MaxValue); ((Vector2)(ref val3))..ctor(float.MinValue, float.MinValue); for (int j = 0; j < 4; j++) { Vector2 val4 = Vector2.op_Implicit(((Transform)instance.rect).InverseTransformPoint(_corners[j])); val2 = Vector2.Min(val2, val4); val3 = Vector2.Max(val3, val4); } if (!(val2.x < 0f - num4 - 1f) && !(val3.x > num4 + 1f) && !(val2.y < 0f - num5 - 1f) && !(val3.y > num5 + 1f)) { continue; } bool flag = val2.x < num6 && val3.x > 0f - num6 && val2.y < num7 && val3.y > 0f - num7; if (HudCoverStretch.Manages((Transform)(object)rectTransform) || MenuEdgeArtExtend.Manages((Transform)(object)rectTransform) || (Object)(object)((Component)val).GetComponentInParent() != (Object)null || (Object)(object)((Component)val).GetComponentInParent() != (Object)null) { continue; } CanvasGroup componentInParent = ((Component)val).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && componentInParent.alpha < 0.01f) { continue; } SemiUI val5 = HidingOwner(val); bool flag2 = (Object)(object)val5 != (Object)null; int num8; if ((Object)(object)val5 != (Object)null) { Vector2 val6 = val5.hidePositionCurrent - val5.hidePosition; num8 = ((((Vector2)(ref val6)).sqrMagnitude < 1f) ? 1 : 0); } else { num8 = 0; } bool flag3 = (byte)num8 != 0; if (flag || flag3) { bool flag4 = val3.x <= 0f - num4 + 1f || val2.x >= num4 - 1f || val3.y <= 0f - num5 + 1f || val2.y >= num5 - 1f; if (flag2 && !val.canvasRenderer.cull) { val.canvasRenderer.cull = true; _culled.Add((val, val5)); } if (_logged.Add(((Object)val).GetInstanceID())) { string text = (((Object)(object)((Component)val).transform.parent != (Object)null) ? (((Object)((Component)val).transform.parent).name + "/" + ((Object)((Component)val).gameObject).name) : ((Object)((Component)val).gameObject).name); Plugin.Log.LogInfo((object)("[ultrawide] reveal: " + text + " <" + ((object)val).GetType().Name + "> " + (flag2 ? "hiding" : (flag4 ? "outside" : "spills")) + " " + $"rect=({val2.x:F0},{val2.y:F0})..({val3.x:F0},{val3.y:F0}) " + $"canvas=({num4:F0},{num5:F0}) cap=({num6:F0},{num7:F0}) a={val.color.a:F2}")); } } } } private static void UncullAll() { foreach (var item2 in _culled) { Graphic item = item2.G; if ((Object)(object)item != (Object)null) { item.canvasRenderer.cull = false; } } _culled.Clear(); } } internal static class GameCameraAspectGuard { internal static void Tick() { if (VRCompat.Active || UltrawideCompareResolution.IsCompareActive || !Settings.ModEnabled || !Settings.UltrawideUiFix || !UltrawideCanvasFix.RequiresAspectFix() || Screen.height == 0) { return; } RenderTextureMain instance = RenderTextureMain.instance; if ((Object)(object)instance == (Object)null || instance.cameras == null) { return; } foreach (Camera camera in instance.cameras) { if (!((Object)(object)camera == (Object)null)) { RenderTexture targetTexture = camera.targetTexture; float num = (((Object)(object)targetTexture != (Object)null) ? ((float)((Texture)targetTexture).width / (float)Mathf.Max(1, ((Texture)targetTexture).height)) : ((float)Screen.width / (float)Screen.height)); if (Mathf.Abs(camera.aspect - num) > 0.01f) { camera.ResetAspect(); } } } } } internal static class UltrawideResolutionWatcher { private static int _w; private static int _h; private static float _retryTimer; internal static void Tick() { if (Settings.ModEnabled && Settings.UltrawideUiFix && UltrawideCanvasFix.RequiresAspectFix() && !UltrawideCanvasFix.UnderlayActive) { _retryTimer += Time.unscaledDeltaTime; if (_retryTimer >= 0.5f) { _retryTimer = 0f; UltrawideCanvasFix.RefreshAll(); } } else { _retryTimer = 0f; } if (Screen.width != _w || Screen.height != _h) { bool num = _w == 0; _w = Screen.width; _h = Screen.height; if (!num) { Plugin.Log.LogDebug((object)$"[ultrawide] resolution change -> {_w}x{_h}, refreshing aspect state"); UltrawideCanvasFix.RefreshAll(); CameraZoomFovOverride.RefreshAll(); MenuCameraFovOverride.Apply(); } } } } internal static class UltrawideCanvasFix { private const float WideThreshold = 1.85f; private const float NarrowThreshold = 1.768f; private const float NarrowFloor = 1.4f; private static GameObject? _ultrawideUnderlay; private static GameObject? _underlayCanvasGo; private static RawImage? _underlayRawImage; private static RawImage? _hiddenMainImage; private static bool _hiddenMainImageWasEnabled; private static Image? _hiddenBackground; private static bool _hiddenBackgroundWasEnabled; private static RawImage? _hiddenOverlayRawImage; private static bool _hiddenOverlayWasEnabled; private static GameObject? _ultrawidePostFx; private static RawImage? _postFxRawImage; internal static bool UnderlayActive { get { if ((Object)(object)_underlayCanvasGo != (Object)null) { return (Object)(object)_postFxRawImage != (Object)null; } return false; } } internal static void RefreshAll() { if (!VRCompat.Active) { bool flag = (Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null && SemiFunc.IsSplashScreen(); if (!Settings.ModEnabled || !Settings.UltrawideUiFix || !RequiresAspectFix() || flag) { RestoreAll(); return; } EnsureUltrawideUnderlay(); GameCameraAspectGuard.Tick(); } } internal static bool IsUltrawide() { if (Screen.height > 0) { return (float)Screen.width / (float)Screen.height > 1.85f; } return false; } internal static bool RequiresAspectFix() { if (Screen.height == 0) { return false; } float num = (float)Screen.width / (float)Screen.height; if (!(num > 1.85f)) { if (num < 1.768f) { return num > 1.4f; } return false; } return true; } private static void EnsureUltrawideUnderlay() { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) RenderTextureMain instance = RenderTextureMain.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.overlayRawImage == (Object)null) { return; } Transform parent = ((Transform)((Graphic)instance.overlayRawImage).rectTransform).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return; } RawImage component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { return; } RenderTexture renderTexture = instance.renderTexture; if ((Object)(object)renderTexture == (Object)null) { return; } if ((Object)(object)_underlayCanvasGo != (Object)null && (Object)(object)_underlayRawImage != (Object)null) { if ((Object)(object)_underlayRawImage.texture != (Object)(object)renderTexture) { _underlayRawImage.texture = (Texture)(object)renderTexture; ((Graphic)_underlayRawImage).SetMaterialDirty(); } if (((Behaviour)component).enabled) { HideMainImage(component); } HideCanvasBackgroundIfPresent(component); RouteOverlayThroughUnderlay(instance); return; } _underlayCanvasGo = new GameObject("REPOFidelity Ultrawide Canvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)_underlayCanvasGo); Canvas component2 = _underlayCanvasGo.GetComponent(); component2.renderMode = (RenderMode)0; component2.sortingOrder = 0; _underlayCanvasGo.GetComponent().uiScaleMode = (ScaleMode)0; _ultrawideUnderlay = new GameObject("REPOFidelity Ultrawide Underlay", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); _ultrawideUnderlay.transform.SetParent(_underlayCanvasGo.transform, false); RectTransform component3 = _ultrawideUnderlay.GetComponent(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.pivot = new Vector2(0.5f, 0.5f); component3.anchoredPosition = Vector2.zero; component3.sizeDelta = Vector2.zero; _underlayRawImage = _ultrawideUnderlay.GetComponent(); _underlayRawImage.texture = (Texture)(object)renderTexture; ((Graphic)_underlayRawImage).color = Color.white; ((Graphic)_underlayRawImage).raycastTarget = false; HideMainImage(component); HideCanvasBackgroundIfPresent(component); RouteOverlayThroughUnderlay(instance); } private static void HideMainImage(RawImage mainImage) { if ((Object)(object)_hiddenMainImage != (Object)(object)mainImage) { _hiddenMainImage = mainImage; _hiddenMainImageWasEnabled = ((Behaviour)mainImage).enabled; } ((Behaviour)mainImage).enabled = false; } private static void HideCanvasBackgroundIfPresent(RawImage mainImage) { Canvas componentInParent = ((Component)mainImage).GetComponentInParent(); Transform val = ((componentInParent != null) ? ((Component)componentInParent).transform : null); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.Find("Background"); if ((Object)(object)val2 == (Object)null) { return; } Image component = ((Component)val2).GetComponent(); if (!((Object)(object)component == (Object)null)) { if ((Object)(object)_hiddenBackground != (Object)(object)component) { _hiddenBackground = component; _hiddenBackgroundWasEnabled = ((Behaviour)component).enabled; } if (((Behaviour)component).enabled) { ((Behaviour)component).enabled = false; } } } private static void RouteOverlayThroughUnderlay(RenderTextureMain rtm) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) RawImage overlayRawImage = rtm.overlayRawImage; if ((Object)(object)overlayRawImage == (Object)null) { return; } if ((Object)(object)_hiddenOverlayRawImage != (Object)(object)overlayRawImage) { _hiddenOverlayRawImage = overlayRawImage; _hiddenOverlayWasEnabled = ((Behaviour)overlayRawImage).enabled; } Texture texture = overlayRawImage.texture; Material material = ((Graphic)overlayRawImage).material; if (((Behaviour)overlayRawImage).enabled) { ((Behaviour)overlayRawImage).enabled = false; } if ((Object)(object)_underlayCanvasGo == (Object)null) { return; } if ((Object)(object)_ultrawidePostFx == (Object)null) { _ultrawidePostFx = new GameObject("REPOFidelity Ultrawide PostFx", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); _ultrawidePostFx.transform.SetParent(_underlayCanvasGo.transform, false); RectTransform component = _ultrawidePostFx.GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = Vector2.zero; _postFxRawImage = _ultrawidePostFx.GetComponent(); ((Graphic)_postFxRawImage).raycastTarget = false; ((Graphic)_postFxRawImage).color = Color.white; } if ((Object)(object)_postFxRawImage != (Object)null) { if ((Object)(object)_postFxRawImage.texture != (Object)(object)texture) { _postFxRawImage.texture = texture; } if ((Object)(object)((Graphic)_postFxRawImage).material != (Object)(object)material) { ((Graphic)_postFxRawImage).material = material; } } } internal static void RestoreAll() { if ((Object)(object)_hiddenMainImage != (Object)null) { ((Behaviour)_hiddenMainImage).enabled = _hiddenMainImageWasEnabled; _hiddenMainImage = null; } if ((Object)(object)_hiddenBackground != (Object)null) { ((Behaviour)_hiddenBackground).enabled = _hiddenBackgroundWasEnabled; _hiddenBackground = null; } if ((Object)(object)_hiddenOverlayRawImage != (Object)null) { ((Behaviour)_hiddenOverlayRawImage).enabled = _hiddenOverlayWasEnabled; _hiddenOverlayRawImage = null; } if ((Object)(object)_ultrawidePostFx != (Object)null) { Object.Destroy((Object)(object)_ultrawidePostFx); } if ((Object)(object)_underlayCanvasGo != (Object)null) { Object.Destroy((Object)(object)_underlayCanvasGo); } if ((Object)(object)_ultrawideUnderlay != (Object)null) { Object.Destroy((Object)(object)_ultrawideUnderlay); } _ultrawidePostFx = null; _postFxRawImage = null; _underlayCanvasGo = null; _ultrawideUnderlay = null; _underlayRawImage = null; } } [HarmonyPatch(typeof(MenuPage), "Start")] internal static class MenuPageStartUltrawidePatch { [HarmonyPostfix] private static void Postfix(MenuPage __instance) { UltrawideCanvasFix.RefreshAll(); MenuCameraFovOverride.Apply(); HudCoverStretch.Rescan(); MenuEdgeArtExtend.Rescan(); HudParkedShift.Rescan(); } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] internal static class LevelGeneratorUltrawidePatch { [HarmonyPostfix] private static void Postfix() { UltrawideCanvasFix.RefreshAll(); CameraZoomFovOverride.RefreshAll(); UltrawideSettingsWatcher.Register(); } } internal static class UltrawideSettingsWatcher { private static bool _registered; internal static void Register() { if (!_registered) { _registered = true; Settings.OnSettingsChanged += OnChanged; } } private static void OnChanged() { try { UltrawideCanvasFix.RefreshAll(); } catch (Exception arg) { Plugin.Log.LogError((object)$"[ultrawide] canvas RefreshAll threw: {arg}"); } try { CameraZoomFovOverride.RefreshAll(); } catch (Exception arg2) { Plugin.Log.LogError((object)$"[ultrawide] FOV RefreshAll threw: {arg2}"); } try { MenuCameraFovOverride.Apply(); } catch (Exception arg3) { Plugin.Log.LogError((object)$"[ultrawide] menu FOV Apply threw: {arg3}"); } } } }