Decompiled source of REPOFidelity v1.8.2

REPOFidelity.dll

Decompiled 2 weeks ago
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.8.2.0")]
[assembly: AssemblyInformationalVersion("1.8.2+3e611081e258960123473281e202cf45f7b86142")]
[assembly: AssemblyProduct("REPOFidelity")]
[assembly: AssemblyTitle("REPOFidelity")]
[assembly: InternalsVisibleTo("REPOFidelity.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.2.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 Bootstrap
	{
		internal static bool HasPlugin(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		internal static void InitSettings(ConfigFile config, bool menuLib)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (menuLib)
			{
				config.Bind<bool>("_", "Hidden", true, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			}
			config.SaveOnConfigSet = true;
			Settings.Init();
			GPUDetector.Detect();
			Settings.ResolveAutoDefaults();
			ConfigIntegration.Initialize(config);
			Diagnostics.Init(config);
		}

		internal static void WarnIfRepoHd()
		{
			if (HasPlugin("BlueAmulet.REPO_HD"))
			{
				Plugin.Log.LogWarning((object)"REPO_HD detected! REPO Fidelity covers all REPO_HD features. Please remove REPO_HD to avoid conflicts.");
			}
		}

		internal static void PatchEachClass(Harmony harmony)
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"Harmony patch failed for {type.Name}: {arg}");
				}
			}
		}

		internal static void LogBanner(bool menuLib)
		{
			//IL_0046: 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)
			Plugin.Log.LogInfo((object)"REPO Fidelity v1.8.2 loaded");
			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)$"DLSS Available: {GPUDetector.DlssAvailable}");
			Plugin.Log.LogInfo((object)(menuLib ? "MenuLib detected, settings added to graphics menu" : "MenuLib not found, settings exposed via REPOConfig / config file"));
		}
	}
	internal static class BuildInfo
	{
		public const string Version = "1.8.2";
	}
	internal enum PerfMode
	{
		Auto = -1,
		Keep,
		Disable
	}
	internal static class ConfigIntegration
	{
		private static bool _syncing;

		private static readonly List<Action> _refreshers = new List<Action>();

		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;
			});
			BindBool(cfg, "Neural Rendering", "Enabled", () => Settings.NeuralRendering, delegate(bool v)
			{
				Settings.NeuralRendering = v;
			}, "DLSS 5 Neural Rendering over the final frame. RTX 50 series only.");
			BindEnum(cfg, "Neural Rendering", "Look", () => Settings.NeuralLookSetting, delegate(NeuralLook v)
			{
				Settings.NeuralLookSetting = v;
			});
			BindInt(cfg, "Neural Rendering", "Strength", 0, 200, () => Settings.NeuralStrength, delegate(int v)
			{
				Settings.NeuralStrength = v;
			}, "How much of the model's edit lands. The model itself tops out at 100; above that its edit is scaled up.");
			BindInt(cfg, "Neural Rendering", "Detail", 0, 200, () => Settings.NeuralDetail, delegate(int v)
			{
				Settings.NeuralDetail = v;
			});
			BindInt(cfg, "Neural Rendering", "Lighting", 0, 200, () => Settings.NeuralLighting, delegate(int v)
			{
				Settings.NeuralLighting = v;
			});
			BindInt(cfg, "Neural Rendering", "Resolution", 25, 100, () => Settings.NeuralResolution, delegate(int v)
			{
				Settings.NeuralResolution = v;
			}, "Fraction of the frame the model runs at. Half the size is a quarter of the cost; the edit is carried back onto the full frame.");
			BindFloat(cfg, "Neural Rendering", "Max Ratio", 1f, 16f, () => Settings.NeuralMaxRatio, delegate(float v)
			{
				Settings.NeuralMaxRatio = v;
			}, "How far the composite may brighten or darken a pixel when the model runs below full size.");
			BindBool(cfg, "Neural Rendering", "Model Log", () => Settings.NeuralModelLog, delegate(bool v)
			{
				Settings.NeuralModelLog = v;
			}, "Write the NGX runtime's own log beside LogOutput.log. Read at game start.");
			BindBool(cfg, "Neural Rendering", "Auto Skin Mask", () => Settings.NeuralAutoMask, delegate(bool v)
			{
				Settings.NeuralAutoMask = v;
			});
			BindEnum(cfg, "Neural Rendering", "Color Path", () => Settings.NeuralColorPathSetting, delegate(NeuralColorPath v)
			{
				Settings.NeuralColorPathSetting = v;
			}, "Auto hands the game's 8-bit frame over and falls back to 16-bit float if refused.");
			BindBool(cfg, "Neural Rendering", "Allow Any RTX", () => Settings.NeuralAnyRtx, delegate(bool v)
			{
				Settings.NeuralAnyRtx = v;
			}, "Offer the pass on RTX cards below the 50 series. The shipped model refuses them; for experiments only.");
			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;
			});
			BindBool(cfg, "Post Processing", "Sharp HUD", () => Settings.SharpHud, delegate(bool v)
			{
				Settings.SharpHud = 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;
			});
			BindKey(cfg, "Misc", "Neural Toggle Key", () => Settings.NeuralToggleKey, delegate(KeyCode v)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				Settings.NeuralToggleKey = v;
			}, "Holds the neural pass off while everything else keeps running, for an A/B against plain DLSS. None disables the key.");
			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<bool> getter, Action<bool> 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<bool> e = cfg.Bind<bool>(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty<object>()));
			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<int> getter, Action<int> 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<int> e = cfg.Bind<int>(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), Array.Empty<object>()));
			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<float> getter, Action<float> 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<float> e = cfg.Bind<float>(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
			e.SettingChanged += delegate
			{
				if (!_syncing)
				{
					setter(e.Value);
				}
			};
			_refreshers.Add(delegate
			{
				e.Value = getter();
			});
		}

		private static void BindEnum<T>(ConfigFile cfg, string section, string name, Func<T> getter, Action<T> 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<T> e = cfg.Bind<T>(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty<object>()));
			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<KeyCode> getter, Action<KeyCode> 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<KeyCode> e = cfg.Bind<KeyCode>(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty<object>()));
			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<int> getter, Action<int> 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<int> e = cfg.Bind<int>(section, name, getter(), new ConfigDescription(desc, (AcceptableValueBase)(object)new AcceptableValueList<int>(values), Array.Empty<object>()));
			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<int> getter, Action<int> 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<PerfMode> e = cfg.Bind<PerfMode>(section, name, (PerfMode)getter(), new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty<object>()));
			e.SettingChanged += delegate
			{
				if (!_syncing)
				{
					setter((int)e.Value);
				}
			};
			_refreshers.Add(delegate
			{
				e.Value = (PerfMode)getter();
			});
		}
	}
	internal static class Diagnostics
	{
		internal static ConfigEntry<bool> ParticleAutoCull;

		internal static ConfigEntry<bool> ParticleShadows;

		internal static ConfigEntry<bool> AvatarPreviewUpgrade;

		internal static void Init(ConfigFile cfg)
		{
			ParticleAutoCull = cfg.Bind<bool>("Diagnostics", "Particle Auto Cull", true, "Crash hunt switch, leave on unless asked to change it. Off = the mod no longer changes particle culling modes.");
			ParticleShadows = cfg.Bind<bool>("Diagnostics", "Particle Shadow Restore", true, "Crash hunt switch, leave on unless asked to change it. Off = the mod leaves particle shadow casting exactly as the game set it, on every preset.");
			AvatarPreviewUpgrade = cfg.Bind<bool>("Diagnostics", "Avatar Preview Upgrade", true, "Crash hunt switch, leave on unless asked to change it. Off = the menu avatar preview keeps its vanilla render texture.");
			Plugin.Log.LogInfo((object)($"Diagnostics: particleAutoCull={ParticleAutoCull.Value} " + $"particleShadows={ParticleShadows.Value} avatarPreview={AvatarPreviewUpgrade.Value}"));
		}
	}
	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 bool NeuralAvailable { 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_00e7: 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");
			NeuralAvailable = DlssAvailable && (NeuralSupport.IsSupportedGpu(GpuName) || Settings.NeuralAnyRtx);
			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<string> list = new List<string>();
			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()
			{
				if (_remeasureAt > 0f && Time.unscaledTime >= _remeasureAt)
				{
					_remeasureAt = 0f;
					RemeasureScroll();
				}
				_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__83_0;

			public static Action <>9__83_1;

			public static Action <>9__83_42;

			public static Action<string> <>9__83_2;

			public static Action<string> <>9__83_3;

			public static Action <>9__83_43;

			public static Action<bool> <>9__83_4;

			public static Action<string> <>9__83_5;

			public static Action <>9__83_44;

			public static Action<int> <>9__83_6;

			public static Action<int> <>9__83_7;

			public static Action<bool> <>9__83_8;

			public static Action<bool> <>9__83_9;

			public static Action<string> <>9__83_10;

			public static Action<string> <>9__83_11;

			public static Action<int> <>9__83_12;

			public static Action<float> <>9__83_13;

			public static Action<string> <>9__83_14;

			public static Action<bool> <>9__83_52;

			public static Action<string> <>9__83_53;

			public static Action<int> <>9__83_54;

			public static Action<string> <>9__83_15;

			public static Action<float> <>9__83_16;

			public static Action<int> <>9__83_17;

			public static Action<float> <>9__83_18;

			public static Action<int> <>9__83_19;

			public static Action<string> <>9__83_20;

			public static Action<string> <>9__83_21;

			public static Action<float> <>9__83_22;

			public static Action<float> <>9__83_23;

			public static Action<float> <>9__83_24;

			public static Action<bool> <>9__83_25;

			public static Action<bool> <>9__83_26;

			public static Action<bool> <>9__83_27;

			public static Action<bool> <>9__83_28;

			public static Action <>9__83_72;

			public static Action<bool> <>9__83_29;

			public static Action <>9__83_73;

			public static Action<bool> <>9__83_30;

			public static Action<bool> <>9__83_31;

			public static Action<bool> <>9__83_32;

			public static Action <>9__83_33;

			public static Action<int> <>9__83_34;

			public static Action<int> <>9__83_35;

			public static Action<int> <>9__83_36;

			public static Action<int> <>9__83_37;

			public static Action<int> <>9__83_38;

			public static Action<int> <>9__83_39;

			public static Action<bool> <>9__83_40;

			public static Action<bool> <>9__83_41;

			internal RectTransform <CreatePage>b__83_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));
				_fontSource = (TMP_Text?)(object)obj.labelTMP;
				_statusText = ((Component)obj).GetComponentInChildren<Text>();
				return ((REPOElement)obj).rectTransform;
			}

			internal void <CreatePage>b__83_1()
			{
				Settings.Preset = QualityPreset.High;
				SyncAll();
			}

			internal void <CreatePage>b__83_2(string s)
			{
				GameSet((Setting)24, (s == "Windowed") ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateWindowMode(true);
				});
			}

			internal void <CreatePage>b__83_42()
			{
				GraphicsManager.instance.UpdateWindowMode(true);
			}

			internal void <CreatePage>b__83_3(string s)
			{
				if (!_syncing)
				{
					Settings.SetResolution(s);
				}
			}

			internal void <CreatePage>b__83_4(bool b)
			{
				GameSet((Setting)12, b ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateVsync();
				});
			}

			internal void <CreatePage>b__83_43()
			{
				GraphicsManager.instance.UpdateVsync();
			}

			internal void <CreatePage>b__83_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 <CreatePage>b__83_6(int v)
			{
				GameSet((Setting)29, v, delegate
				{
					GraphicsManager.instance.UpdateGamma();
				});
			}

			internal void <CreatePage>b__83_44()
			{
				GraphicsManager.instance.UpdateGamma();
			}

			internal void <CreatePage>b__83_7(int v)
			{
				ModSet(new <>c__DisplayClass83_1
				{
					v = v
				}.<CreatePage>b__45);
			}

			internal void <CreatePage>b__83_8(bool b)
			{
				ModSet(new <>c__DisplayClass83_2
				{
					b = b
				}.<CreatePage>b__46);
			}

			internal void <CreatePage>b__83_9(bool b)
			{
				ModSet(new <>c__DisplayClass83_3
				{
					b = b
				}.<CreatePage>b__47);
			}

			internal void <CreatePage>b__83_10(string s)
			{
				if (!_syncing)
				{
					Settings.Preset = Enum.Parse<QualityPreset>(s);
				}
			}

			internal void <CreatePage>b__83_11(string s)
			{
				ModSet(new <>c__DisplayClass83_4
				{
					enumName = ((s == "FSR") ? "FSR_Temporal" : s)
				}.<CreatePage>b__48);
			}

			internal void <CreatePage>b__83_12(int v)
			{
				ModSet(new <>c__DisplayClass83_5
				{
					v = v
				}.<CreatePage>b__49);
			}

			internal void <CreatePage>b__83_13(float v)
			{
				ModSet(new <>c__DisplayClass83_6
				{
					v = v
				}.<CreatePage>b__50);
			}

			internal void <CreatePage>b__83_14(string s)
			{
				ModSet(new <>c__DisplayClass83_7
				{
					s = s
				}.<CreatePage>b__51);
			}

			internal void <CreatePage>b__83_52(bool b)
			{
				ModSet(new <>c__DisplayClass83_8
				{
					b = b
				}.<CreatePage>b__55);
			}

			internal void <CreatePage>b__83_53(string s)
			{
				<>c__DisplayClass83_9 CS$<>8__locals2 = new <>c__DisplayClass83_9
				{
					i = Array.IndexOf(NeuralLookOptions, s)
				};
				if (CS$<>8__locals2.i >= 0)
				{
					ModSet(delegate
					{
						Settings.NeuralLookSetting = NeuralLookValues[CS$<>8__locals2.i];
					});
				}
			}

			internal void <CreatePage>b__83_54(int v)
			{
				ModSet(new <>c__DisplayClass83_10
				{
					v = v
				}.<CreatePage>b__57);
			}

			internal void <CreatePage>b__83_15(string s)
			{
				ModSet(new <>c__DisplayClass83_11
				{
					s = s
				}.<CreatePage>b__58);
			}

			internal void <CreatePage>b__83_16(float v)
			{
				ModSet(new <>c__DisplayClass83_12
				{
					v = v
				}.<CreatePage>b__59);
			}

			internal void <CreatePage>b__83_17(int v)
			{
				ModSet(new <>c__DisplayClass83_13
				{
					v = v
				}.<CreatePage>b__60);
			}

			internal void <CreatePage>b__83_18(float v)
			{
				ModSet(new <>c__DisplayClass83_14
				{
					v = v
				}.<CreatePage>b__61);
			}

			internal void <CreatePage>b__83_19(int v)
			{
				ModSet(new <>c__DisplayClass83_15
				{
					v = v
				}.<CreatePage>b__62);
			}

			internal void <CreatePage>b__83_20(string s)
			{
				ModSet(new <>c__DisplayClass83_16
				{
					s = s
				}.<CreatePage>b__63);
			}

			internal void <CreatePage>b__83_21(string s)
			{
				ModSet(new <>c__DisplayClass83_17
				{
					s = s
				}.<CreatePage>b__64);
			}

			internal void <CreatePage>b__83_22(float v)
			{
				ModSet(new <>c__DisplayClass83_18
				{
					v = v
				}.<CreatePage>b__65);
			}

			internal void <CreatePage>b__83_23(float v)
			{
				ModSet(new <>c__DisplayClass83_19
				{
					v = v
				}.<CreatePage>b__66);
			}

			internal void <CreatePage>b__83_24(float v)
			{
				ModSet(new <>c__DisplayClass83_20
				{
					v = v
				}.<CreatePage>b__67);
			}

			internal void <CreatePage>b__83_25(bool b)
			{
				ModSet(new <>c__DisplayClass83_21
				{
					b = b
				}.<CreatePage>b__68);
			}

			internal void <CreatePage>b__83_26(bool b)
			{
				ModSet(new <>c__DisplayClass83_22
				{
					b = b
				}.<CreatePage>b__69);
			}

			internal void <CreatePage>b__83_27(bool b)
			{
				ModSet(new <>c__DisplayClass83_23
				{
					b = b
				}.<CreatePage>b__70);
			}

			internal void <CreatePage>b__83_28(bool b)
			{
				ModSet(new <>c__DisplayClass83_24
				{
					b = b
				}.<CreatePage>b__71);
			}

			internal void <CreatePage>b__83_29(bool b)
			{
				GameSet((Setting)16, b ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateBloom();
				});
			}

			internal void <CreatePage>b__83_72()
			{
				GraphicsManager.instance.UpdateBloom();
			}

			internal void <CreatePage>b__83_30(bool b)
			{
				GameSet((Setting)26, b ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateGlitchLoop();
				});
			}

			internal void <CreatePage>b__83_73()
			{
				GraphicsManager.instance.UpdateGlitchLoop();
			}

			internal void <CreatePage>b__83_31(bool b)
			{
				ModSet(new <>c__DisplayClass83_25
				{
					b = b
				}.<CreatePage>b__74);
			}

			internal void <CreatePage>b__83_32(bool b)
			{
				ModSet(new <>c__DisplayClass83_26
				{
					b = b
				}.<CreatePage>b__75);
			}

			internal void <CreatePage>b__83_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 <CreatePage>b__83_34(int v)
			{
				ModSet(new <>c__DisplayClass83_27
				{
					v = v
				}.<CreatePage>b__76);
			}

			internal void <CreatePage>b__83_35(int v)
			{
				ModSet(new <>c__DisplayClass83_28
				{
					v = v
				}.<CreatePage>b__77);
			}

			internal void <CreatePage>b__83_36(int v)
			{
				ModSet(new <>c__DisplayClass83_29
				{
					v = v
				}.<CreatePage>b__78);
			}

			internal void <CreatePage>b__83_37(int v)
			{
				ModSet(new <>c__DisplayClass83_30
				{
					v = v
				}.<CreatePage>b__79);
			}

			internal void <CreatePage>b__83_38(int v)
			{
				ModSet(new <>c__DisplayClass83_31
				{
					v = v
				}.<CreatePage>b__80);
			}

			internal void <CreatePage>b__83_39(int v)
			{
				ModSet(new <>c__DisplayClass83_32
				{
					v = v
				}.<CreatePage>b__81);
			}

			internal void <CreatePage>b__83_40(bool b)
			{
				ModSet(new <>c__DisplayClass83_33
				{
					b = b
				}.<CreatePage>b__82);
			}

			internal void <CreatePage>b__83_41(bool b)
			{
				ModSet(new <>c__DisplayClass83_34
				{
					b = b
				}.<CreatePage>b__83);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_1
		{
			public int v;

			internal void <CreatePage>b__45()
			{
				Settings.VerticalFovOverride = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_10
		{
			public int v;

			internal void <CreatePage>b__57()
			{
				Settings.NeuralStrength = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_11
		{
			public string s;

			internal void <CreatePage>b__58()
			{
				Settings.ShadowQualitySetting = Enum.Parse<ShadowQuality>(s);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_12
		{
			public float v;

			internal void <CreatePage>b__59()
			{
				Settings.ShadowDistance = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_13
		{
			public int v;

			internal void <CreatePage>b__60()
			{
				Settings.ShadowBudget = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_14
		{
			public float v;

			internal void <CreatePage>b__61()
			{
				Settings.LightDistance = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_15
		{
			public int v;

			internal void <CreatePage>b__62()
			{
				Settings.PixelLightCount = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_16
		{
			public string s;

			internal void <CreatePage>b__63()
			{
				Settings.TextureQuality = TexValues[Array.IndexOf(TexOptions, s)];
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_17
		{
			public string s;

			internal void <CreatePage>b__64()
			{
				Settings.AnisotropicFiltering = AfValues[Array.IndexOf(AfOptions, s)];
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_18
		{
			public float v;

			internal void <CreatePage>b__65()
			{
				Settings.LODBias = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_19
		{
			public float v;

			internal void <CreatePage>b__66()
			{
				Settings.FogDistanceMultiplier = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_2
		{
			public bool b;

			internal void <CreatePage>b__46()
			{
				Settings.UltrawideUiFix = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_20
		{
			public float v;

			internal void <CreatePage>b__67()
			{
				Settings.ViewDistance = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_21
		{
			public bool b;

			internal void <CreatePage>b__68()
			{
				Settings.MotionBlurOverride = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_22
		{
			public bool b;

			internal void <CreatePage>b__69()
			{
				Settings.ChromaticAberration = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_23
		{
			public bool b;

			internal void <CreatePage>b__70()
			{
				Settings.LensDistortion = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_24
		{
			public bool b;

			internal void <CreatePage>b__71()
			{
				Settings.FilmGrain = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_25
		{
			public bool b;

			internal void <CreatePage>b__74()
			{
				Settings.Pixelation = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_26
		{
			public bool b;

			internal void <CreatePage>b__75()
			{
				Settings.SharpHud = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_27
		{
			public int v;

			internal void <CreatePage>b__76()
			{
				Settings.PerfExplosionShadows = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_28
		{
			public int v;

			internal void <CreatePage>b__77()
			{
				Settings.PerfItemLightShadows = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_29
		{
			public int v;

			internal void <CreatePage>b__78()
			{
				Settings.PerfAnimatedLightShadows = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_3
		{
			public bool b;

			internal void <CreatePage>b__47()
			{
				Settings.UltrawideHudUnstretch = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_30
		{
			public int v;

			internal void <CreatePage>b__79()
			{
				Settings.PerfParticleShadows = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_31
		{
			public int v;

			internal void <CreatePage>b__80()
			{
				Settings.PerfTinyRendererCulling = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_32
		{
			public int v;

			internal void <CreatePage>b__81()
			{
				Settings.PerfPointLightShadows = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_33
		{
			public bool b;

			internal void <CreatePage>b__82()
			{
				Settings.ExtractionPointFlicker = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_34
		{
			public bool b;

			internal void <CreatePage>b__83()
			{
				Settings.DebugOverlay = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_4
		{
			public string enumName;

			internal void <CreatePage>b__48()
			{
				Settings.UpscaleModeSetting = Enum.Parse<UpscaleMode>(enumName);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_5
		{
			public int v;

			internal void <CreatePage>b__49()
			{
				Settings.RenderScale = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_6
		{
			public float v;

			internal void <CreatePage>b__50()
			{
				Settings.Sharpening = v;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_7
		{
			public string s;

			internal void <CreatePage>b__51()
			{
				Settings.AntiAliasingMode = Enum.Parse<AAMode>(s);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_8
		{
			public bool b;

			internal void <CreatePage>b__55()
			{
				Settings.NeuralRendering = b;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass83_9
		{
			public int i;

			internal void <CreatePage>b__56()
			{
				Settings.NeuralLookSetting = NeuralLookValues[i];
			}
		}

		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 REPOToggle? _neuralToggle;

		private static REPOSlider? _neuralLookSlider;

		private static REPOSlider? _neuralStrengthSlider;

		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 TMP_Text? _fontSource;

		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 string[] NeuralLookOptions;

		private static readonly NeuralLook[] NeuralLookValues;

		private static readonly TextureRes[] TexValues;

		private static float _remeasureAt;

		private const float NameRoom = 0.37f;

		private const float NameScale = 0.9f;

		private const float DescriptionSize = 13f;

		private static float _rowWidth;

		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" };
			NeuralLookOptions = new string[3] { "Natural", "Cinematic", "Default" };
			NeuralLookValues = new NeuralLook[3]
			{
				NeuralLook.Natural,
				NeuralLook.Cinematic,
				NeuralLook.Default
			};
			TexValues = new TextureRes[3]
			{
				TextureRes.Quarter,
				TextureRes.Half,
				TextureRes.Full
			};
			_rowWidth = 254f;
			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), "ButtonEventLanguage")]
		public static void PrefixLanguage()
		{
			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.menuPage.interactionPriority = 0;
			_page.OpenPage(true);
			_page.menuPage.addedPageOnTop = true;
			_page.menuPage.interactionPriority = MenuManager.instance.HighestOpenPriority();
			KeepRowsActive(_page);
			_remeasureAt = Time.unscaledTime + 0.6f;
			SyncAll();
			RefreshDynamicLabels();
			StartTicker();
			IsGraphicsPageOpen = true;
		}

		private static void KeepRowsActive(REPOPopupPage page)
		{
			((Behaviour)page.scrollView).enabled = false;
			REPOScrollViewElement[] componentsInChildren = ((Component)page.scrollView).GetComponentsInChildren<REPOScrollViewElement>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.SetActive(true);
			}
		}

		private static void RemeasureScroll()
		{
			if (!((Object)(object)_page == (Object)null))
			{
				_page.menuScrollBox.RecalculateScrollHeight(true);
				_page.scrollView.UpdateElements();
			}
		}

		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<StatusTicker>();
			}
		}

		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;
		}

		internal static void ClearQueuedBenchmark()
		{
			if (_benchmarkQueued)
			{
				_benchmarkQueued = false;
				RefreshDynamicLabels();
			}
		}

		private static string BuildAutoTuneLabel()
		{
			if (_benchmarkQueued)
			{
				return "QUEUED, CLICK TO CANCEL";
			}
			if (SemiFunc.RunIsLevel())
			{
				return "AUTO-TUNE (15s)";
			}
			return "AUTO-TUNE (RUNS IN-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_0cc4: 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__83_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));
					_fontSource = (TMP_Text?)(object)obj2.labelTMP;
					_statusText = ((Component)obj2).GetComponentInChildren<Text>();
					return ((REPOElement)obj2).rectTransform;
				};
				<>c.<>9__83_0 = val;
				obj = (object)val;
			}
			page.AddElementToScrollView((ScrollViewBuilderDelegate)obj, 0f, 0f);
			AddButton("RESET TO DEFAULTS", 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 num7 = ((s == "Unlimited") ? (-1) : int.Parse(s));
					DataDirector.instance.SettingValueSet((Setting)19, num7);
					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", 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<QualityPreset>(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<UpscaleMode>(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<AAMode>(s);
				});
			}, out _aaSlider);
			if (GPUDetector.NeuralAvailable)
			{
				AddLabel("DLSS 5");
				AddNote("RTX 50 only. About 5 ms a frame at 4K.\nA look, not a speed boost.");
				AddModToggle("Enabled", Settings.NeuralRendering, delegate(bool b)
				{
					ModSet(delegate
					{
						Settings.NeuralRendering = b;
					});
				}, out _neuralToggle);
				int num2 = Array.IndexOf(NeuralLookValues, Settings.NeuralLookSetting);
				if (num2 < 0)
				{
					num2 = 0;
				}
				AddStringSlider("Look", "", NeuralLookOptions, NeuralLookOptions[num2], delegate(string s)
				{
					int i = Array.IndexOf(NeuralLookOptions, s);
					if (i >= 0)
					{
						ModSet(delegate
						{
							Settings.NeuralLookSetting = NeuralLookValues[i];
						});
					}
				}, out _neuralLookSlider);
				AddIntSlider("Strength", "Past 100 goes beyond the model", 0, 200, Settings.NeuralStrength, "%", delegate(int v)
				{
					ModSet(delegate
					{
						Settings.NeuralStrength = v;
					});
				}, out _neuralStrengthSlider);
			}
			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<ShadowQuality>(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", 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 num3 = Array.IndexOf(TexValues, Settings.TextureQuality);
			if (num3 < 0)
			{
				num3 = 2;
			}
			AddStringSlider("Texture Quality", "", TexOptions, TexOptions[num3], delegate(string s)
			{
				ModSet(delegate
				{
					Settings.TextureQuality = TexValues[Array.IndexOf(TexOptions, s)];
				});
			}, out _textureSlider);
			int num4 = Array.IndexOf(AfValues, Settings.AnisotropicFiltering);
			if (num4 < 0)
			{
				num4 = 4;
			}
			AddStringSlider("Texture Filtering", "Anisotropic filtering", AfOptions, AfOptions[num4], 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 is closer", 0.3f, 1.1f, 2, Settings.FogDistanceMultiplier, "x", delegate(float v)
			{
				ModSet(delegate
				{
					Settings.FogDistanceMultiplier = v;
				});
			}, out _fogSlider);
			AddFloatSlider("Draw Distance", "0 = auto", 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", 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", "No shadows on explosions", Settings.PerfExplosionShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfExplosionShadows = v;
				});
			}, out _perfExplosionSlider);
			AddPerfSlider("Item Light Shadows", "No shadows on item lights", Settings.PerfItemLightShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfItemLightShadows = v;
				});
			}, out _perfItemLightSlider);
			AddPerfSlider("Animated Light Shadows", "No shadows on animated lights", Settings.PerfAnimatedLightShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfAnimatedLightShadows = v;
				});
			}, out _perfAnimLightSlider);
			AddPerfSlider("Particle Shadows", "No shadow casting particles", Settings.PerfParticleShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfParticleShadows = v;
				});
			}, out _perfParticleSlider);
			AddPerfSlider("Small Object Shadows", "No shadows on tiny objects", Settings.PerfTinyRendererCulling, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfTinyRendererCulling = v;
				});
			}, out _perfTinySlider);
			AddPerfSlider("Point Light Shadows", "Cull far point-light shadows", 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 num5 = Array.IndexOf(keyVals, Settings.ToggleKey);
			if (num5 < 0)
			{
				num5 = 0;
			}
			AddStringSlider("Mod Toggle Key", "Turns the mod off to compare", keyOpts, keyOpts[num5], delegate(string s)
			{
				int num7 = Array.IndexOf(keyOpts, s);
				if (num7 >= 0)
				{
					Settings.ToggleKey = keyVals[num7];
				}
			}, out REPOSlider r);
			string[] f11Opts = new string[2] { "Full Opt Layer", "CPU Patches" };
			F11Target[] f11Vals = new F11Target[2]
			{
				F11Target.FullOptLayer,
				F11Target.CpuPatches
			};
			int num6 = Array.IndexOf(f11Vals, Settings.F11TargetSetting);
			if (num6 < 0)
			{
				num6 = 0;
			}
			AddStringSlider("F11 Target", "What F11 toggles for A/B", f11Opts, f11Opts[num6], delegate(string s)
			{
				int num7 = Array.IndexOf(f11Opts, s);
				if (num7 >= 0)
				{
					Settings.F11TargetSetting = f11Vals[num7];
				}
			}, 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 FitText(TMP_Text text, float room, float minSize)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (!(room <= 0f))
			{
				float x = text.GetPreferredValues(text.text).x;
				if (x > room && x > 0f)
				{
					text.fontSize = Mathf.Max(minSize, text.fontSize * room / x);
				}
			}
		}

		private static void TidyToggle(REPOToggle t)
		{
			//IL_0006: 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)
			Rect rect = ((REPOElement)t).rectTransform.rect;
			float width = ((Rect)(ref rect)).width;
			if (width > 0f)
			{
				_rowWidth = width;
			}
			TextMeshProUGUI labelTMP = t.labelTMP;
			((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * 0.9f;
			FitText((TMP_Text)(object)t.labelTMP, width * 0.37f, 11f);
		}

		private static void TidySlider(REPOSlider s)
		{
			//IL_0006: 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)
			//IL_0071: 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)
			Rect rect = ((REPOElement)s).rectTransform.rect;
			float width = ((Rect)(ref rect)).width;
			if (width > 0f)
			{
				_rowWidth = width;
			}
			TextMeshProUGUI labelTMP = s.labelTMP;
			((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * 0.9f;
			FitText((TMP_Text)(object)s.labelTMP, width * 0.37f, 11f);
			((TMP_Text)s.descriptionTMP).fontSize = 13f;
			TextMeshProUGUI descriptionTMP = s.descriptionTMP;
			rect = ((TMP_Text)s.descriptionTMP).rectTransform.rect;
			FitText((TMP_Text)(object)descriptionTMP, ((Rect)(ref rect)).width - 14f, 9f);
		}

		private static void AddText(string text, float size, Color? color, TextAlignmentOptions align, float height, float topPadding, float bottomPadding)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0044: Expected O, but got Unknown
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_002c: 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_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Expected O, but got Unknown
				//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_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: 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_0080: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: 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_00db: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: 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_0106: 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_0182: Unknown result type (might be due to invalid IL or missing references)
				//IL_018e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				RectTransform val = (RectTransform)new GameObject("Label - " + text.Replace('\n', ' '), new Type[1] { typeof(RectTransform) })
				{
					layer = ((Component)sv).gameObject.layer
				}.transform;
				((Transform)val).SetParent(sv, false);
				Vector2 anchorMin = (val.anchorMax = Vector2.zero);
				val.anchorMin = anchorMin;
				val.pivot = Vector2.zero;
				val.sizeDelta = new Vector2(_rowWidth, height);
				((Transform)val).localPosition = Vector3.zero;
				GameObject val2 = new GameObject("Text", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				})
				{
					layer = ((Component)sv).gameObject.layer
				};
				RectTransform val3 = (RectTransform)val2.transform;
				((Transform)val3).SetParent((Transform)(object)val, false);
				val3.anchorMin = Vector2.zero;
				val3.anchorMax = Vector2.one;
				anchorMin = (val3.offsetMax = Vector2.zero);
				val3.offsetMin = anchorMin;
				TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>();
				if ((Object)(object)_fontSource != (Object)null)
				{
					((TMP_Text)component).font = _fontSource.font;
					((TMP_Text)component).fontSharedMaterial = _fontSource.fontSharedMaterial;
					((TMP_Text)component).fontStyle = _fontSource.fontStyle;
				}
				((Graphic)component).color = (Color)(((??)color) ?? (((Object)(object)_fontSource != (Object)null) ? ((Graphic)_fontSource).color : Color.white));
				((TMP_Text)component).alignment = align;
				((Graphic)component).raycastTarget = false;
				((TMP_Text)component).enableWordWrapping = false;
				((TMP_Text)component).overflowMode = (TextOverflowModes)0;
				((TMP_Text)component).margin = Vector4.zero;
				((TMP_Text)component).fontSize = size;
				((TMP_Text)component).text = text;
				FitText((TMP_Text)(object)component, _rowWidth - 14f, 9f);
				return val;
			}, topPadding, bottomPadding);
		}

		private static void AddLabel(string text)
		{
			AddText(text, 24f, null, (TextAlignmentOptions)4097, 34f, 10f, 2f);
		}

		private static void AddNote(string text)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			AddText(text, 13f, (Color?)new Color(1f, 0.55f, 0f), (TextAlignmentOptions)257, 4f + (float)text.Split('\n').Length * 16f, 0f, 4f);
		}

		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<Text>();
				return ((REPOElement)val).rectTransform;
			}, 0f, 0f);
			textOut = captured;
		}

		private static void AddStringSlider(string text, string desc, string[] options, string def, Action<string> 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<string>)delegate(string v)
				{
					cb(v);
				}, sv, options, def, Vector2.zero, "", "", (BarBehavior)0);
				TidySlider(s);
				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<int> 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<int>)delegate(int v)
				{
					cb(v);
				}, sv, Vector2.zero, min, max, def, "", post, (BarBehavior)0);
				TidySlider(s);
				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<float> 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<float>)delegate(float v)
				{
					cb(v);
				}, sv, Vector2.zero, min, max, prec, def, "", post, (BarBehavior)0);
				TidySlider(s);
				return ((REPOElement)s).rectTransform;
			}, 0f, 0f);
			r = s;
		}

		private static void AddPerfSlider(string text, string desc, int current, Action<int> 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<bool> 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<bool>)delegate(bool b)
				{
					cb(b);
				}, sv, Vector2.zero, "ON", "OFF", def);
				TidyToggle(t);
				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? neuralToggle = _neuralToggle;
			if (neuralToggle != null)
			{
				neuralToggle.SetState(Settings.NeuralRendering, false);
			}
			int num3 = Array.IndexOf(NeuralLookValues, Settings.NeuralLookSetting);
			if (num3 >= 0)
			{
				SetStr(_neuralLookSlider, NeuralLookOptions[num3]);
			}
			SetNum(_neuralStrengthSlider, Settings.NeuralStrength);
			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 enum NeuralLook
	{
		Natural,
		Cinematic,
		Default
	}
	internal enum NeuralColorPath
	{
		Auto,
		Direct,
		Half
	}
	internal static class NeuralSupport
	{
		private static readonly Regex Rtx50 = new Regex("\\bRTX\\s*5\\d{3}\\b", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		internal const long MinModelBytes = 100000000L;

		internal const int PercentMin = 0;

		internal const int PercentMax = 200;

		internal const int StrengthPercentMax = 200;

		internal const int ResolutionPercentMin = 25;

		internal const int ResolutionPercentMax = 100;

		internal const int ResolutionPercentDefault = 75;

		private const int WorkingMin = 64;

		internal const float MaxRatioMin = 1f;

		internal const float MaxRatioMax = 16f;

		internal const float MaxRatioDefault = 4f;

		internal const int GpuTimingDlss = 0;

		internal const int GpuTimingNeural = 1;

		internal const int ResultSuccess = 1;

		internal static bool IsSupportedGpu(string? gpuName)
		{
			if (!string.IsNullOrEmpty(gpuName))
			{
				return Rtx50.IsMatch(gpuName);
			}
			return false;
		}

		internal static float PercentToStrength(int percent)
		{
			return (float)Math.Max(0, Math.Min(200, percent)) / 100f;
		}

		internal static float PercentToIntensity(int percent)
		{
			return (float)Math.Max(0, Math.Min(100, percent)) / 100f;
		}

		internal static float PercentToGain(int percent)
		{
			return (float)Math.Max(100, Math.Min(200, percent)) / 100f;
		}

		internal static uint StyleValue(NeuralLook look)
		{
			return look switch
			{
				NeuralLook.Natural => 1u, 
				NeuralLook.Cinematic => 2u, 
				_ => 0u, 
			};
		}

		internal static (int width, int height) WorkingSize(int outputWidth, int outputHeight, int percent)
		{
			int num = Math.Max(25, Math.Min(100, percent));
			if (num >= 100)
			{
				return (width: Math.Max(outputWidth, 1), height: Math.Max(outputHeight, 1));
			}
			int val = Math.Max(64, (int)Math.Round((double)(outputWidth * num) / 100.0)) & -2;
			return new ValueTuple<int, int>(item2: Math.Min(Math.Max(64, (int)Math.Round((double)(outputHeight * num) / 100.0)) & -2, outputHeight), item1: Math.Min(val, outputWidth));
		}

		internal static bool IsFormatRejection(int result)
		{
			if (result != -1160773624)
			{
				return result == -1160773618;
			}
			return true;
		}

		internal static string ResultName(int result)
		{
			return (uint)result switch
			{
				1u => "Success", 
				0u => "BridgeUnavailable", 
				3134193664u => "Fail", 
				3134193665u => "FeatureNotSupported", 
				3134193666u => "PlatformError", 
				3134193667u => "FeatureAlreadyExists", 
				3134193668u => "FeatureNotFound", 
				3134193669u => "InvalidParameter", 
				3134193670u => "ScratchBufferTooSmall", 
				3134193671u => "NotInitialized", 
				3134193672u => "UnsupportedInputFormat", 
				3134193673u => "RWFlagMissing", 
				3134193674u => "MissingInput", 
				3134193675u => "UnableToInitializeFeature", 
				3134193676u => "OutOfDate", 
				3134193677u => "OutOfGPUMemory", 
				3134193678u => "UnsupportedFormat", 
				3134193679u => "UnableToWriteToAppDataPath", 
				3134193680u => "UnsupportedParameter", 
				3134193681u => "Denied", 
				3134193682u => "NotImplemented", 
				_ => $"0x{(uint)result:X8}", 
			};
		}
	}
	internal class OptimizerBenchmark : MonoBehaviour
	{
		private class Result
		{
			public float AvgMs;

			public float AvgFps;

			public float P1Low;

			public readonly List<float> Frames = new List<float>();

			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<float> _all = new List<float>();

			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<OptimizerBenchmark>();
				}
				((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<NativeLine> _nativeLines = new List<NativeLine>();

		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<LineData> _lines = new List<LineData>();

		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;

		private static float _nextAssetScan;

		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)
			//IL_0278: 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));
			}
			else if (Settings.NeuralBypassed && UpscalerManager.NeuralActive)
			{
				_lines.Add(new LineData($"NEURAL OFF ({Settings.NeuralToggleKey})  {_smoothFps:F0} FPS  {_smoothMs:F1}ms", Col.Warn));
			}
			if (Settings.ModEnabled && Settings.DebugOverlay)
			{
				string text2 = Settings.Preset.ToString().ToUpper();
				string text3 = Settings