Decompiled source of REPOFidelity v1.7.7

REPOFidelity.dll

Decompiled 3 days 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.7.7.0")]
[assembly: AssemblyInformationalVersion("1.7.7+5818939011e81a6f3ed0365702faeca1d638ce3b")]
[assembly: AssemblyProduct("REPOFidelity")]
[assembly: AssemblyTitle("REPOFidelity")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOFidelity
{
	internal static class BuildInfo
	{
		public const string Version = "1.7.7";
	}
	internal enum PerfMode
	{
		Auto = -1,
		Keep,
		Disable
	}
	internal static class ConfigIntegration
	{
		private static bool _syncing;

		private static readonly List<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;
			});
			BindEnum(cfg, "Shadows & Lighting", "Shadow Quality", () => Settings.ShadowQualitySetting, delegate(ShadowQuality v)
			{
				Settings.ShadowQualitySetting = v;
			});
			BindFloat(cfg, "Shadows & Lighting", "Shadow Distance", 5f, 200f, () => Settings.ShadowDistance, delegate(float v)
			{
				Settings.ShadowDistance = v;
			});
			BindInt(cfg, "Shadows & Lighting", "Shadow Limit", 0, 50, () => Settings.ResolvedShadowBudget, delegate(int v)
			{
				Settings.ShadowBudget = v;
			}, "0 = unlimited");
			BindFloat(cfg, "Shadows & Lighting", "Light Distance", 10f, 100f, () => Settings.LightDistance, delegate(float v)
			{
				Settings.LightDistance = v;
			});
			BindInt(cfg, "Shadows & Lighting", "Max Lights", 1, 16, () => Settings.PixelLightCount, delegate(int v)
			{
				Settings.PixelLightCount = v;
			});
			BindEnum(cfg, "Textures & Detail", "Texture Quality", () => Settings.TextureQuality, delegate(TextureRes v)
			{
				Settings.TextureQuality = v;
			});
			BindIntList(cfg, "Textures & Detail", "Texture Filtering", new int[5] { 0, 2, 4, 8, 16 }, () => Settings.AnisotropicFiltering, delegate(int v)
			{
				Settings.AnisotropicFiltering = v;
			}, "Anisotropic filtering");
			BindFloat(cfg, "Textures & Detail", "Detail Distance", 0.5f, 4f, () => Settings.LODBias, delegate(float v)
			{
				Settings.LODBias = v;
			}, "LOD bias");
			BindFloat(cfg, "Environment", "Fog Distance", 0.3f, 1.1f, () => Settings.FogDistanceMultiplier, delegate(float v)
			{
				Settings.FogDistanceMultiplier = v;
			}, "1.0 = vanilla; lower pulls fog closer");
			BindFloat(cfg, "Environment", "Draw Distance", 0f, 500f, () => Settings.ViewDistance, delegate(float v)
			{
				Settings.ViewDistance = v;
			}, "0 = auto. Camera far clip in meters.");
			BindBool(cfg, "Post Processing", "Motion Blur", () => Settings.MotionBlurOverride, delegate(bool v)
			{
				Settings.MotionBlurOverride = v;
			});
			BindBool(cfg, "Post Processing", "Chromatic Aberration", () => Settings.ChromaticAberration, delegate(bool v)
			{
				Settings.ChromaticAberration = v;
			});
			BindBool(cfg, "Post Processing", "Lens Distortion", () => Settings.LensDistortion, delegate(bool v)
			{
				Settings.LensDistortion = v;
			});
			BindBool(cfg, "Post Processing", "Film Grain", () => Settings.FilmGrain, delegate(bool v)
			{
				Settings.FilmGrain = v;
			});
			BindBool(cfg, "Post Processing", "Pixelation", () => Settings.Pixelation, delegate(bool v)
			{
				Settings.Pixelation = v;
			});
			BindPerf(cfg, "Performance", "Explosion Shadows", () => Settings.PerfExplosionShadows, delegate(int v)
			{
				Settings.PerfExplosionShadows = v;
			});
			BindPerf(cfg, "Performance", "Item Light Shadows", () => Settings.PerfItemLightShadows, delegate(int v)
			{
				Settings.PerfItemLightShadows = v;
			});
			BindPerf(cfg, "Performance", "Animated Light Shadows", () => Settings.PerfAnimatedLightShadows, delegate(int v)
			{
				Settings.PerfAnimatedLightShadows = v;
			});
			BindPerf(cfg, "Performance", "Particle Shadows", () => Settings.PerfParticleShadows, delegate(int v)
			{
				Settings.PerfParticleShadows = v;
			});
			BindPerf(cfg, "Performance", "Small Object Shadows", () => Settings.PerfTinyRendererCulling, delegate(int v)
			{
				Settings.PerfTinyRendererCulling = v;
			});
			BindPerf(cfg, "Performance", "Point Light Shadows", () => Settings.PerfPointLightShadows, delegate(int v)
			{
				Settings.PerfPointLightShadows = v;
			});
			BindBool(cfg, "Misc", "Fix Extraction Flicker", () => Settings.ExtractionPointFlicker, delegate(bool v)
			{
				Settings.ExtractionPointFlicker = v;
			});
			BindBool(cfg, "Misc", "Debug Overlay", () => Settings.DebugOverlay, delegate(bool v)
			{
				Settings.DebugOverlay = v;
			});
			BindKey(cfg, "Misc", "Mod Toggle Key", () => Settings.ToggleKey, delegate(KeyCode v)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				Settings.ToggleKey = v;
			}, "Disables mod for vanilla comparison");
			BindEnum(cfg, "Misc", "F11 Target", () => Settings.F11TargetSetting, delegate(F11Target v)
			{
				Settings.F11TargetSetting = v;
			});
			Refresh();
			Settings.OnSettingsChanged += Refresh;
		}

		private static void Refresh()
		{
			_syncing = true;
			try
			{
				foreach (Action refresher in _refreshers)
				{
					refresher();
				}
			}
			finally
			{
				_syncing = false;
			}
		}

		private static void BindBool(ConfigFile cfg, string section, string name, Func<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 DLSSDownloader
	{
		private const string DllName = "nvngx_dlss.dll";

		private const int MinDllSize = 10000000;

		internal static string GetDllPath()
		{
			return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "nvngx_dlss.dll");
		}

		internal static bool EnsureAvailable()
		{
			string dllPath = GetDllPath();
			int num;
			if (File.Exists(dllPath))
			{
				num = ((new FileInfo(dllPath).Length >= 10000000) ? 1 : 0);
				if (num != 0)
				{
					Plugin.Log.LogDebug((object)$"DLSS DLL: {dllPath} ({new FileInfo(dllPath).Length / 1024 / 1024}MB)");
					return (byte)num != 0;
				}
			}
			else
			{
				num = 0;
			}
			Plugin.Log.LogWarning((object)"nvngx_dlss.dll missing or invalid; DLSS/DLAA disabled. Reinstall the mod.");
			return (byte)num != 0;
		}
	}
	internal static class FrameTimeMeter
	{
		internal class Meter
		{
			public readonly string Name;

			public readonly string ShortName;

			private readonly float[] _samples;

			private int _index;

			private int _count;

			private float _sum;

			public float LastUs;

			public float AverageUs
			{
				get
				{
					if (_count <= 0)
					{
						return 0f;
					}
					return _sum / (float)_count;
				}
			}

			public float AverageMs => AverageUs / 1000f;

			public Meter(string name, string shortName, int windowSize = 120)
			{
				Name = name;
				ShortName = shortName;
				_samples = new float[windowSize];
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public void Record(float microseconds)
			{
				LastUs = microseconds;
				_sum -= _samples[_index];
				_samples[_index] = microseconds;
				_sum += microseconds;
				_index = (_index + 1) % _samples.Length;
				if (_count < _samples.Length)
				{
					_count++;
				}
			}
		}

		private static readonly Stopwatch _sw = Stopwatch.StartNew();

		internal static readonly Meter EnemyDirector = new Meter("EnemyDirector Throttle", "EnemyDir");

		internal static readonly Meter RoomVolumeCheck = new Meter("RoomVolume NonAlloc", "RoomVol");

		internal static readonly Meter SemiFuncCache = new Meter("SemiFunc Cache", "SemiFunc");

		internal static readonly Meter PhysGrabObjectFix = new Meter("PhysGrabObject Fix", "PhysGrab");

		internal static readonly Meter LightManagerBatch = new Meter("LightManager Batch", "LightMgr");

		internal static readonly Meter SceneApply = new Meter("SceneOptimizer Apply", "SceneApl");

		internal static readonly Meter[] All = new Meter[6] { EnemyDirector, RoomVolumeCheck, SemiFuncCache, PhysGrabObjectFix, LightManagerBatch, SceneApply };

		internal static bool Active
		{
			get
			{
				if (!Settings.DebugOverlay)
				{
					return OptimizerBenchmark.Running;
				}
				return true;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static long Begin()
		{
			if (!Active)
			{
				return 0L;
			}
			return _sw.ElapsedTicks;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void End(Meter meter, long startTicks)
		{
			if (startTicks != 0L)
			{
				float microseconds = (float)((double)(_sw.ElapsedTicks - startTicks) / 10.0);
				meter.Record(microseconds);
			}
		}
	}
	internal enum GpuVendor
	{
		Nvidia,
		Amd,
		Intel,
		Apple,
		Unknown
	}
	internal enum GpuTier
	{
		High,
		Mid,
		Low
	}
	internal static class GPUDetector
	{
		private static readonly Regex ArcDiscretePattern = new Regex("\\b[AB]\\d{3}\\b", RegexOptions.Compiled);

		public static string GpuName { get; private set; } = "Unknown";

		public static GpuVendor Vendor { get; private set; } = GpuVendor.Unknown;

		public static GpuTier Tier { get; private set; } = GpuTier.Low;

		public static bool DlssAvailable { get; private set; }

		public static int VramMb { get; private set; }

		public static bool IsD3D11 { get; private set; }

		public static bool IsIntegratedGpu { get; private set; }

		public static void Detect()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			GpuName = SystemInfo.graphicsDeviceName ?? "Unknown";
			VramMb = SystemInfo.graphicsMemorySize;
			Vendor = DetectVendor(GpuName, SystemInfo.graphicsDeviceVendor);
			Tier = DetectTier(VramMb);
			IsD3D11 = (int)SystemInfo.graphicsDeviceType == 2;
			IsIntegratedGpu = DetectIntegrated(GpuName, VramMb, Vendor);
			DlssAvailable = Vendor == GpuVendor.Nvidia && IsD3D11 && !IsIntegratedGpu && GpuName.ToUpperInvariant().Contains("RTX");
			Plugin.Log.LogInfo((object)($"GPU: {GpuName} | Vendor: {Vendor} | VRAM: {VramMb}MB | " + $"API: {SystemInfo.graphicsDeviceType} | iGPU: {IsIntegratedGpu} | Tier: {Tier}"));
		}

		public static bool IsUpscalerSupported(UpscaleMode mode)
		{
			switch (mode)
			{
			case UpscaleMode.Auto:
				return true;
			case UpscaleMode.Off:
				return true;
			case UpscaleMode.DLAA:
			case UpscaleMode.DLSS:
				return DlssAvailable;
			case UpscaleMode.FSR_Temporal:
				return true;
			default:
				return false;
			}
		}

		public static string[] GetAvailableUpscalerNames()
		{
			List<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()
			{
				_t += Time.unscaledDeltaTime;
				if (!(_t < 0.25f))
				{
					_t = 0f;
					RefreshDynamicLabels();
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ScrollViewBuilderDelegate <>9__72_0;

			public static Action <>9__72_1;

			public static Action <>9__72_42;

			public static Action<string> <>9__72_2;

			public static Action<string> <>9__72_3;

			public static Action <>9__72_43;

			public static Action<bool> <>9__72_4;

			public static Action<string> <>9__72_5;

			public static Action <>9__72_44;

			public static Action<int> <>9__72_6;

			public static Action<int> <>9__72_7;

			public static Action<bool> <>9__72_8;

			public static Action<bool> <>9__72_9;

			public static Action<string> <>9__72_10;

			public static Action<string> <>9__72_11;

			public static Action<int> <>9__72_12;

			public static Action<float> <>9__72_13;

			public static Action<string> <>9__72_14;

			public static Action<string> <>9__72_15;

			public static Action<float> <>9__72_16;

			public static Action<int> <>9__72_17;

			public static Action<float> <>9__72_18;

			public static Action<int> <>9__72_19;

			public static Action<string> <>9__72_20;

			public static Action<string> <>9__72_21;

			public static Action<float> <>9__72_22;

			public static Action<float> <>9__72_23;

			public static Action<float> <>9__72_24;

			public static Action<bool> <>9__72_25;

			public static Action<bool> <>9__72_26;

			public static Action<bool> <>9__72_27;

			public static Action<bool> <>9__72_28;

			public static Action <>9__72_66;

			public static Action<bool> <>9__72_29;

			public static Action <>9__72_67;

			public static Action<bool> <>9__72_30;

			public static Action<bool> <>9__72_31;

			public static Action<bool> <>9__72_32;

			public static Action <>9__72_33;

			public static Action<int> <>9__72_34;

			public static Action<int> <>9__72_35;

			public static Action<int> <>9__72_36;

			public static Action<int> <>9__72_37;

			public static Action<int> <>9__72_38;

			public static Action<int> <>9__72_39;

			public static Action<bool> <>9__72_40;

			public static Action<bool> <>9__72_41;

			internal RectTransform <CreatePage>b__72_0(Transform sv)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				REPOLabel obj = MenuAPI.CreateREPOLabel("", sv, new Vector2(0f, 0f));
				_statusText = ((Component)obj).GetComponentInChildren<Text>();
				return ((REPOElement)obj).rectTransform;
			}

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

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

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

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

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

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

			internal void <CreatePage>b__72_5(string s)
			{
				if (!_syncing)
				{
					int num = ((s == "Unlimited") ? (-1) : int.Parse(s));
					DataDirector.instance.SettingValueSet((Setting)19, num);
					GraphicsManager.instance.UpdateMaxFPS();
					DataDirector.instance.SaveSettings();
				}
			}

			internal void <CreatePage>b__72_6(int v)
			{
				GameSet((Setting)29, v, delegate
				{
					GraphicsManager.instance.UpdateGamma();
				});
			}

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

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

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

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

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

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

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

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

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

			internal void <CreatePage>b__72_15(string s)
			{
				ModSet(new <>c__DisplayClass72_8
				{
					s = s
				}.<CreatePage>b__52);
			}

			internal void <CreatePage>b__72_16(float v)
			{
				ModSet(new <>c__DisplayClass72_9
				{
					v = v
				}.<CreatePage>b__53);
			}

			internal void <CreatePage>b__72_17(int v)
			{
				ModSet(new <>c__DisplayClass72_10
				{
					v = v
				}.<CreatePage>b__54);
			}

			internal void <CreatePage>b__72_18(float v)
			{
				ModSet(new <>c__DisplayClass72_11
				{
					v = v
				}.<CreatePage>b__55);
			}

			internal void <CreatePage>b__72_19(int v)
			{
				ModSet(new <>c__DisplayClass72_12
				{
					v = v
				}.<CreatePage>b__56);
			}

			internal void <CreatePage>b__72_20(string s)
			{
				ModSet(new <>c__DisplayClass72_13
				{
					s = s
				}.<CreatePage>b__57);
			}

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

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

			internal void <CreatePage>b__72_23(float v)
			{
				ModSet(new <>c__DisplayClass72_16
				{
					v = v
				}.<CreatePage>b__60);
			}

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

			internal void <CreatePage>b__72_25(bool b)
			{
				ModSet(new <>c__DisplayClass72_18
				{
					b = b
				}.<CreatePage>b__62);
			}

			internal void <CreatePage>b__72_26(bool b)
			{
				ModSet(new <>c__DisplayClass72_19
				{
					b = b
				}.<CreatePage>b__63);
			}

			internal void <CreatePage>b__72_27(bool b)
			{
				ModSet(new <>c__DisplayClass72_20
				{
					b = b
				}.<CreatePage>b__64);
			}

			internal void <CreatePage>b__72_28(bool b)
			{
				ModSet(new <>c__DisplayClass72_21
				{
					b = b
				}.<CreatePage>b__65);
			}

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

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

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

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

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

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

			internal void <CreatePage>b__72_33()
			{
				if (_benchmarkQueued)
				{
					_benchmarkQueued = false;
					Settings.Preset = QualityPreset.High;
					RefreshDynamicLabels();
					SyncAll();
					return;
				}
				Settings.Preset = QualityPreset.Auto;
				if (SemiFunc.RunIsLevel())
				{
					_page.ClosePage(false);
					if ((Object)(object)MenuManager.instance != (Object)null)
					{
						MenuManager.instance.PageCloseAllAddedOnTop();
					}
					Settings.InvalidateAutoTune();
					Settings.BenchmarkMode = true;
				}
				else
				{
					Settings.InvalidateAutoTune();
					_benchmarkQueued = true;
					RefreshDynamicLabels();
				}
			}

			internal void <CreatePage>b__72_34(int v)
			{
				ModSet(new <>c__DisplayClass72_24
				{
					v = v
				}.<CreatePage>b__70);
			}

			internal void <CreatePage>b__72_35(int v)
			{
				ModSet(new <>c__DisplayClass72_25
				{
					v = v
				}.<CreatePage>b__71);
			}

			internal void <CreatePage>b__72_36(int v)
			{
				ModSet(new <>c__DisplayClass72_26
				{
					v = v
				}.<CreatePage>b__72);
			}

			internal void <CreatePage>b__72_37(int v)
			{
				ModSet(new <>c__DisplayClass72_27
				{
					v = v
				}.<CreatePage>b__73);
			}

			internal void <CreatePage>b__72_38(int v)
			{
				ModSet(new <>c__DisplayClass72_28
				{
					v = v
				}.<CreatePage>b__74);
			}

			internal void <CreatePage>b__72_39(int v)
			{
				ModSet(new <>c__DisplayClass72_29
				{
					v = v
				}.<CreatePage>b__75);
			}

			internal void <CreatePage>b__72_40(bool b)
			{
				ModSet(new <>c__DisplayClass72_30
				{
					b = b
				}.<CreatePage>b__76);
			}

			internal void <CreatePage>b__72_41(bool b)
			{
				ModSet(new <>c__DisplayClass72_31
				{
					b = b
				}.<CreatePage>b__77);
			}
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private static REPOPopupPage? _page;

		private static bool _initialized;

		private static bool _syncing;

		private static REPOSlider? _presetSlider;

		private static REPOSlider? _upscalerSlider;

		private static REPOSlider? _renderScaleSlider;

		private static REPOSlider? _sharpeningSlider;

		private static REPOSlider? _aaSlider;

		private static REPOToggle? _pixelationToggle;

		private static REPOSlider? _shadowQualitySlider;

		private static REPOSlider? _shadowDistanceSlider;

		private static REPOSlider? _shadowBudgetSlider;

		private static REPOSlider? _lodSlider;

		private static REPOSlider? _afSlider;

		private static REPOSlider? _lightsSlider;

		private static REPOSlider? _textureSlider;

		private static REPOSlider? _lightDistSlider;

		private static REPOSlider? _fogSlider;

		private static REPOSlider? _viewDistSlider;

		private static REPOToggle? _motionBlurToggle;

		private static REPOToggle? _caToggle;

		private static REPOToggle? _lensToggle;

		private static REPOToggle? _grainToggle;

		private static REPOToggle? _flickerToggle;

		private static REPOToggle? _overlayToggle;

		private static REPOToggle? _sharpHudToggle;

		private static REPOSlider? _windowModeSlider;

		private static REPOSlider? _resolutionSlider;

		private static REPOSlider? _fpsSlider;

		private static REPOSlider? _gammaSlider;

		private static REPOSlider? _fovSlider;

		private static REPOToggle? _ultrawideUiToggle;

		private static REPOToggle? _ultrawideHudToggle;

		private static REPOToggle? _vsyncToggle;

		private static REPOToggle? _bloomToggle;

		private static REPOToggle? _glitchToggle;

		private static REPOSlider? _perfExplosionSlider;

		private static REPOSlider? _perfItemLightSlider;

		private static REPOSlider? _perfAnimLightSlider;

		private static REPOSlider? _perfParticleSlider;

		private static REPOSlider? _perfTinySlider;

		private static REPOSlider? _perfPointLightSlider;

		private static Text? _statusText;

		private static Text? _autoTuneText;

		private static bool _benchmarkQueued;

		private static StatusTicker? _ticker;

		private static readonly string[] FpsOptions;

		private static readonly string[] PerfOptions;

		private static readonly int[] PerfValues;

		private static readonly string[] AfOptions;

		private static readonly int[] AfValues;

		private static readonly string[] TexOptions;

		private static readonly TextureRes[] TexValues;

		internal static bool IsGraphicsPageOpen { get; private set; }

		static MenuIntegration()
		{
			PerfOptions = new string[3] { "Auto", "Keep", "Disable" };
			PerfValues = new int[3] { -1, 0, 1 };
			AfOptions = new string[5] { "Off", "2x", "4x", "8x", "16x" };
			AfValues = new int[5] { 0, 2, 4, 8, 16 };
			TexOptions = new string[3] { "Quarter", "Half", "Full" };
			TexValues = new TextureRes[3]
			{
				TextureRes.Quarter,
				TextureRes.Half,
				TextureRes.Full
			};
			FpsOptions = new string[332];
			for (int i = 0; i < 331; i++)
			{
				FpsOptions[i] = (30 + i).ToString();
			}
			FpsOptions[331] = "Unlimited";
		}

		internal static void Initialize()
		{
			_initialized = true;
			Settings.OnSettingsChanged += SyncModSettings;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MenuPageSettings), "ButtonEventGraphics")]
		public static bool PrefixGraphics()
		{
			if (!_initialized)
			{
				return true;
			}
			MenuManager.instance.PageCloseAllAddedOnTop();
			OpenPage();
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MenuPageSettings), "ButtonEventAudio")]
		public static void PrefixAudio()
		{
			ClosePage();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MenuPageSettings), "ButtonEventGameplay")]
		public static void PrefixGameplay()
		{
			ClosePage();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MenuPageSettings), "ButtonEventControls")]
		public static void PrefixControls()
		{
			ClosePage();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MenuPageSettings), "ButtonEventBack")]
		public static void PrefixBack()
		{
			ClosePage();
		}

		private static void ClosePage()
		{
			try
			{
				REPOPopupPage? page = _page;
				if (page != null)
				{
					page.ClosePage(true);
				}
			}
			catch
			{
			}
			StopTicker();
			IsGraphicsPageOpen = false;
		}

		private static void OpenPage()
		{
			if ((Object)(object)_page == (Object)null)
			{
				CreatePage();
			}
			_page.OpenPage(true);
			_page.menuPage.addedPageOnTop = true;
			SyncAll();
			RefreshDynamicLabels();
			StartTicker();
			IsGraphicsPageOpen = true;
		}

		private static void StartTicker()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)_ticker != (Object)null))
			{
				GameObject val = new GameObject("REPOFidelity_MenuStatus");
				Object.DontDestroyOnLoad((Object)val);
				_ticker = val.AddComponent<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;
		}

		private static string BuildAutoTuneLabel()
		{
			if (_benchmarkQueued)
			{
				return "AUTO-TUNE QUEUED (WILL RUN ON NEXT LEVEL)";
			}
			if (SemiFunc.RunIsLevel())
			{
				return "AUTO-TUNE BENCHMARK (15s)";
			}
			return "AUTO-TUNE - WILL QUEUE (START A GAME)";
		}

		private static void RefreshDynamicLabels()
		{
			if ((Object)(object)_statusText != (Object)null)
			{
				_statusText.text = "  " + BuildStatusLine();
			}
			if ((Object)(object)_autoTuneText != (Object)null)
			{
				_autoTuneText.text = BuildAutoTuneLabel();
			}
		}

		private static void CreatePage()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0bd7: Unknown result type (might be due to invalid IL or missing references)
			_page = MenuAPI.CreateREPOPopupPage("Graphics", true, false, 2f, (Vector2?)new Vector2(0f, 0f));
			REPOPopupPage? page = _page;
			object obj = <>c.<>9__72_0;
			if (obj == null)
			{
				ScrollViewBuilderDelegate val = delegate(Transform sv)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					REPOLabel obj2 = MenuAPI.CreateREPOLabel("", sv, new Vector2(0f, 0f));
					_statusText = ((Component)obj2).GetComponentInChildren<Text>();
					return ((REPOElement)obj2).rectTransform;
				};
				<>c.<>9__72_0 = val;
				obj = (object)val;
			}
			page.AddElementToScrollView((ScrollViewBuilderDelegate)obj, 0f, 0f);
			AddButton("RESET TO DEFAULT SETTINGS", delegate
			{
				Settings.Preset = QualityPreset.High;
				SyncAll();
			});
			AddLabel("Display");
			AddStringSlider("Window Mode", "", new string[2] { "Fullscreen", "Windowed" }, "Fullscreen", delegate(string s)
			{
				GameSet((Setting)24, (s == "Windowed") ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateWindowMode(true);
				});
			}, out _windowModeSlider);
			int currentIndex;
			string[] availableResolutions = Settings.GetAvailableResolutions(out currentIndex);
			AddStringSlider("Resolution", "", availableResolutions, availableResolutions[currentIndex], delegate(string s)
			{
				if (!_syncing)
				{
					Settings.SetResolution(s);
				}
			}, out _resolutionSlider);
			AddModToggle("VSync", def: false, delegate(bool b)
			{
				GameSet((Setting)12, b ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateVsync();
				});
			}, out _vsyncToggle);
			int num = DataDirector.instance.SettingValueFetch((Setting)19);
			string def = ((num <= 0) ? "Unlimited" : Mathf.Clamp(num, 30, 360).ToString());
			AddStringSlider("Max FPS", "", FpsOptions, def, delegate(string s)
			{
				if (!_syncing)
				{
					int num6 = ((s == "Unlimited") ? (-1) : int.Parse(s));
					DataDirector.instance.SettingValueSet((Setting)19, num6);
					GraphicsManager.instance.UpdateMaxFPS();
					DataDirector.instance.SaveSettings();
				}
			}, out _fpsSlider);
			AddIntSlider("Gamma", "Brightness", 0, 100, 40, "", delegate(int v)
			{
				GameSet((Setting)29, v, delegate
				{
					GraphicsManager.instance.UpdateGamma();
				});
			}, out _gammaSlider);
			AddIntSlider("Vertical FOV (0 = game default)", "Higher = wider view; lower = zoomed in", 0, 110, Settings.VerticalFovOverride, "°", delegate(int v)
			{
				ModSet(delegate
				{
					Settings.VerticalFovOverride = v;
				});
			}, out _fovSlider);
			AddModToggle("Ultra-Wide UI Fix", Settings.UltrawideUiFix, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.UltrawideUiFix = b;
				});
			}, out _ultrawideUiToggle);
			AddModToggle("Ultra-Wide HUD Unstretch", Settings.UltrawideHudUnstretch, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.UltrawideHudUnstretch = b;
				});
			}, out _ultrawideHudToggle);
			AddLabel("Quality");
			string[] options = new string[7] { "Auto", "Potato", "Low", "Medium", "High", "Ultra", "Custom" };
			AddStringSlider("Quality Preset", "Sets all options below", options, Settings.Preset.ToString(), delegate(string s)
			{
				if (!_syncing)
				{
					Settings.Preset = Enum.Parse<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);
			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)", "Caps nearby shadow-casting lights", 0, 50, Settings.ResolvedShadowBudget, "", delegate(int v)
			{
				ModSet(delegate
				{
					Settings.ShadowBudget = v;
				});
			}, out _shadowBudgetSlider);
			AddFloatSlider("Light Distance", "", 10f, 100f, 0, Settings.LightDistance, "m", delegate(float v)
			{
				ModSet(delegate
				{
					Settings.LightDistance = v;
				});
			}, out _lightDistSlider);
			AddIntSlider("Max Lights", "Per object", 1, 16, Settings.PixelLightCount, "", delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PixelLightCount = v;
				});
			}, out _lightsSlider);
			AddLabel("Textures & Detail");
			int num2 = Array.IndexOf(TexValues, Settings.TextureQuality);
			if (num2 < 0)
			{
				num2 = 2;
			}
			AddStringSlider("Texture Quality", "", TexOptions, TexOptions[num2], delegate(string s)
			{
				ModSet(delegate
				{
					Settings.TextureQuality = TexValues[Array.IndexOf(TexOptions, s)];
				});
			}, out _textureSlider);
			int num3 = Array.IndexOf(AfValues, Settings.AnisotropicFiltering);
			if (num3 < 0)
			{
				num3 = 4;
			}
			AddStringSlider("Texture Filtering", "Anisotropic filtering", AfOptions, AfOptions[num3], delegate(string s)
			{
				ModSet(delegate
				{
					Settings.AnisotropicFiltering = AfValues[Array.IndexOf(AfOptions, s)];
				});
			}, out _afSlider);
			AddFloatSlider("Detail Distance", "LOD bias", 0.5f, 4f, 1, Settings.LODBias, "x", delegate(float v)
			{
				ModSet(delegate
				{
					Settings.LODBias = v;
				});
			}, out _lodSlider);
			AddLabel("Environment");
			AddFloatSlider("Fog Distance", "1.0 = vanilla; lower pulls fog closer for perf", 0.3f, 1.1f, 2, Settings.FogDistanceMultiplier, "x", delegate(float v)
			{
				ModSet(delegate
				{
					Settings.FogDistanceMultiplier = v;
				});
			}, out _fogSlider);
			AddFloatSlider("Draw Distance (0 = auto)", "Camera far clip", 0f, 500f, 0, Settings.ViewDistance, "m", delegate(float v)
			{
				ModSet(delegate
				{
					Settings.ViewDistance = v;
				});
			}, out _viewDistSlider);
			AddLabel("Post Processing");
			AddModToggle("Motion Blur", Settings.MotionBlurOverride, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.MotionBlurOverride = b;
				});
			}, out _motionBlurToggle);
			AddModToggle("Chromatic Aberration", Settings.ChromaticAberration, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.ChromaticAberration = b;
				});
			}, out _caToggle);
			AddModToggle("Lens Distortion", Settings.LensDistortion, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.LensDistortion = b;
				});
			}, out _lensToggle);
			AddModToggle("Film Grain", Settings.FilmGrain, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.FilmGrain = b;
				});
			}, out _grainToggle);
			AddModToggle("Bloom", def: true, delegate(bool b)
			{
				GameSet((Setting)16, b ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateBloom();
				});
			}, out _bloomToggle);
			AddModToggle("Glitch Loop", def: true, delegate(bool b)
			{
				GameSet((Setting)26, b ? 1 : 0, delegate
				{
					GraphicsManager.instance.UpdateGlitchLoop();
				});
			}, out _glitchToggle);
			AddModToggle("Pixelation (retro style)", Settings.Pixelation, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.Pixelation = b;
				});
			}, out _pixelationToggle);
			AddModToggle("Sharp HUD", Settings.SharpHud, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.SharpHud = b;
				});
			}, out _sharpHudToggle);
			AddLabel("Performance");
			AddDynamicButton(BuildAutoTuneLabel(), delegate
			{
				if (_benchmarkQueued)
				{
					_benchmarkQueued = false;
					Settings.Preset = QualityPreset.High;
					RefreshDynamicLabels();
					SyncAll();
				}
				else
				{
					Settings.Preset = QualityPreset.Auto;
					if (SemiFunc.RunIsLevel())
					{
						_page.ClosePage(false);
						if ((Object)(object)MenuManager.instance != (Object)null)
						{
							MenuManager.instance.PageCloseAllAddedOnTop();
						}
						Settings.InvalidateAutoTune();
						Settings.BenchmarkMode = true;
					}
					else
					{
						Settings.InvalidateAutoTune();
						_benchmarkQueued = true;
						RefreshDynamicLabels();
					}
				}
			}, out _autoTuneText);
			AddPerfSlider("Explosion Shadows", "Disable shadows on explosion lights", Settings.PerfExplosionShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfExplosionShadows = v;
				});
			}, out _perfExplosionSlider);
			AddPerfSlider("Item Light Shadows", "Disable shadows on handheld item lights", Settings.PerfItemLightShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfItemLightShadows = v;
				});
			}, out _perfItemLightSlider);
			AddPerfSlider("Animated Light Shadows", "Disable shadows on animated lights", Settings.PerfAnimatedLightShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfAnimatedLightShadows = v;
				});
			}, out _perfAnimLightSlider);
			AddPerfSlider("Particle Shadows", "Disable shadow casting on particles", Settings.PerfParticleShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfParticleShadows = v;
				});
			}, out _perfParticleSlider);
			AddPerfSlider("Small Object Shadows", "Disable shadows on tiny objects", Settings.PerfTinyRendererCulling, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfTinyRendererCulling = v;
				});
			}, out _perfTinySlider);
			AddPerfSlider("Point Light Shadows", "Cull distant point-light shadows beyond fog", Settings.PerfPointLightShadows, delegate(int v)
			{
				ModSet(delegate
				{
					Settings.PerfPointLightShadows = v;
				});
			}, out _perfPointLightSlider);
			AddModToggle("Fix Extraction Flicker", Settings.ExtractionPointFlicker, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.ExtractionPointFlicker = b;
				});
			}, out _flickerToggle);
			AddModToggle("Debug Overlay", Settings.DebugOverlay, delegate(bool b)
			{
				ModSet(delegate
				{
					Settings.DebugOverlay = b;
				});
			}, out _overlayToggle);
			string[] keyOpts = new string[6] { "F10", "F9", "F8", "F7", "F6", "F5" };
			KeyCode[] array2 = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			KeyCode[] keyVals = (KeyCode[])(object)array2;
			int num4 = Array.IndexOf(keyVals, Settings.ToggleKey);
			if (num4 < 0)
			{
				num4 = 0;
			}
			AddStringSlider("Mod Toggle Key", "Disables mod for vanilla comparison", keyOpts, keyOpts[num4], delegate(string s)
			{
				int num6 = Array.IndexOf(keyOpts, s);
				if (num6 >= 0)
				{
					Settings.ToggleKey = keyVals[num6];
				}
			}, out REPOSlider r);
			string[] f11Opts = new string[2] { "Full Opt Layer", "CPU Patches" };
			F11Target[] f11Vals = new F11Target[2]
			{
				F11Target.FullOptLayer,
				F11Target.CpuPatches
			};
			int num5 = Array.IndexOf(f11Vals, Settings.F11TargetSetting);
			if (num5 < 0)
			{
				num5 = 0;
			}
			AddStringSlider("F11 Target", "Which feature F11 toggles for A/B", f11Opts, f11Opts[num5], delegate(string s)
			{
				int num6 = Array.IndexOf(f11Opts, s);
				if (num6 >= 0)
				{
					Settings.F11TargetSetting = f11Vals[num6];
				}
			}, out r);
		}

		private static void ModSet(Action a)
		{
			if (!_syncing)
			{
				a();
			}
		}

		private static void GameSet(Setting setting, int value, Action update)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (!_syncing)
			{
				DataDirector.instance.SettingValueSet(setting, value);
				update();
				DataDirector.instance.SaveSettings();
			}
		}

		private static void AddLabel(string text)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform sv) => ((REPOElement)MenuAPI.CreateREPOLabel(text, sv, Vector2.zero)).rectTransform), 0f, 0f);
		}

		private static void AddButton(string text, Action onClick, float xOffset = 38f)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform sv) => ((REPOElement)MenuAPI.CreateREPOButton(text, onClick, sv, new Vector2(xOffset, 0f))).rectTransform), 0f, 0f);
		}

		private static void AddDynamicButton(string text, Action onClick, out Text? textOut, float xOffset = 38f)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			Text captured = null;
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				REPOButton val = MenuAPI.CreateREPOButton(text, onClick, sv, new Vector2(xOffset, 0f));
				captured = ((Component)val).GetComponentInChildren<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);
				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);
				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);
				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);
				return ((REPOElement)t).rectTransform;
			}, 0f, 0f);
			r = t;
		}

		private static void SyncAll()
		{
			_syncing = true;
			try
			{
				SyncGame();
				SyncMod();
			}
			finally
			{
				_syncing = false;
			}
		}

		private static void SyncModSettings()
		{
			if ((Object)(object)_page == (Object)null)
			{
				return;
			}
			_syncing = true;
			try
			{
				SyncMod();
			}
			finally
			{
				_syncing = false;
			}
		}

		private static void SyncGame()
		{
			int num = DataDirector.instance.SettingValueFetch((Setting)24);
			SetStr(_windowModeSlider, (num == 1) ? "Windowed" : "Fullscreen");
			SetStr(_resolutionSlider, $"{Settings.OutputWidth}x{Settings.OutputHeight}");
			REPOToggle? vsyncToggle = _vsyncToggle;
			if (vsyncToggle != null)
			{
				vsyncToggle.SetState(DataDirector.instance.SettingValueFetch((Setting)12) == 1, false);
			}
			int num2 = DataDirector.instance.SettingValueFetch((Setting)19);
			SetStr(_fpsSlider, (num2 <= 0) ? "Unlimited" : Mathf.Clamp(num2, 30, 360).ToString());
			SetNum(_gammaSlider, DataDirector.instance.SettingValueFetch((Setting)29));
			REPOToggle? bloomToggle = _bloomToggle;
			if (bloomToggle != null)
			{
				bloomToggle.SetState(DataDirector.instance.SettingValueFetch((Setting)16) == 1, false);
			}
			REPOToggle? glitchToggle = _glitchToggle;
			if (glitchToggle != null)
			{
				glitchToggle.SetState(DataDirector.instance.SettingValueFetch((Setting)26) == 1, false);
			}
		}

		private static void SyncMod()
		{
			SetStr(_presetSlider, Settings.Preset.ToString());
			string text = Settings.UpscaleModeSetting.ToString();
			if (text == "DLAA")
			{
				text = "DLSS";
			}
			if (text == "FSR_Temporal")
			{
				text = "FSR";
			}
			SetStr(_upscalerSlider, text);
			SetNum(_renderScaleSlider, Settings.ResolvedRenderScale);
			SetNum(_sharpeningSlider, Settings.Sharpening);
			string opt = ((Settings.AntiAliasingMode == AAMode.TAA) ? Settings.ResolvedAAMode.ToString() : Settings.AntiAliasingMode.ToString());
			SetStr(_aaSlider, opt);
			REPOToggle? pixelationToggle = _pixelationToggle;
			if (pixelationToggle != null)
			{
				pixelationToggle.SetState(Settings.Pixelation, false);
			}
			SetStr(_shadowQualitySlider, Settings.ShadowQualitySetting.ToString());
			SetNum(_shadowDistanceSlider, Settings.ShadowDistance);
			SetNum(_shadowBudgetSlider, Settings.ResolvedShadowBudget);
			SetNum(_lodSlider, Settings.LODBias);
			int num = Array.IndexOf(AfValues, Settings.AnisotropicFiltering);
			if (num >= 0)
			{
				SetStr(_afSlider, AfOptions[num]);
			}
			SetNum(_lightsSlider, Settings.PixelLightCount);
			int num2 = Array.IndexOf(TexValues, Settings.TextureQuality);
			if (num2 >= 0)
			{
				SetStr(_textureSlider, TexOptions[num2]);
			}
			SetNum(_lightDistSlider, Settings.LightDistance);
			SetNum(_fogSlider, Settings.FogDistanceMultiplier);
			SetNum(_viewDistSlider, Settings.ViewDistance);
			REPOToggle? motionBlurToggle = _motionBlurToggle;
			if (motionBlurToggle != null)
			{
				motionBlurToggle.SetState(Settings.MotionBlurOverride, false);
			}
			REPOToggle? caToggle = _caToggle;
			if (caToggle != null)
			{
				caToggle.SetState(Settings.ChromaticAberration, false);
			}
			REPOToggle? lensToggle = _lensToggle;
			if (lensToggle != null)
			{
				lensToggle.SetState(Settings.LensDistortion, false);
			}
			REPOToggle? grainToggle = _grainToggle;
			if (grainToggle != null)
			{
				grainToggle.SetState(Settings.FilmGrain, false);
			}
			REPOToggle? sharpHudToggle = _sharpHudToggle;
			if (sharpHudToggle != null)
			{
				sharpHudToggle.SetState(Settings.SharpHud, false);
			}
			REPOToggle? flickerToggle = _flickerToggle;
			if (flickerToggle != null)
			{
				flickerToggle.SetState(Settings.ExtractionPointFlicker, false);
			}
			REPOToggle? overlayToggle = _overlayToggle;
			if (overlayToggle != null)
			{
				overlayToggle.SetState(Settings.DebugOverlay, false);
			}
			SetNum(_fovSlider, Settings.VerticalFovOverride);
			REPOToggle? ultrawideUiToggle = _ultrawideUiToggle;
			if (ultrawideUiToggle != null)
			{
				ultrawideUiToggle.SetState(Settings.UltrawideUiFix, false);
			}
			REPOToggle? ultrawideHudToggle = _ultrawideHudToggle;
			if (ultrawideHudToggle != null)
			{
				ultrawideHudToggle.SetState(Settings.UltrawideHudUnstretch, false);
			}
			SyncPerf(_perfExplosionSlider, Settings.PerfExplosionShadows);
			SyncPerf(_perfItemLightSlider, Settings.PerfItemLightShadows);
			SyncPerf(_perfAnimLightSlider, Settings.PerfAnimatedLightShadows);
			SyncPerf(_perfParticleSlider, Settings.PerfParticleShadows);
			SyncPerf(_perfTinySlider, Settings.PerfTinyRendererCulling);
			SyncPerf(_perfPointLightSlider, Settings.PerfPointLightShadows);
		}

		private static void SyncPerf(REPOSlider? s, int value)
		{
			int num = Array.IndexOf(PerfValues, value);
			if (num >= 0)
			{
				SetStr(s, PerfOptions[num]);
			}
		}

		private static void SetNum(REPOSlider? s, float v)
		{
			if (s != null)
			{
				s.SetValue(v, false);
			}
		}

		private static void SetStr(REPOSlider? s, string opt)
		{
			if (((s != null) ? s.stringOptions : null) != null)
			{
				int num = Array.IndexOf(s.stringOptions, opt);
				if (num >= 0)
				{
					s.SetValue((float)num, false);
				}
			}
		}
	}
	internal class OptimizerBenchmark : MonoBehaviour
	{
		private class Result
		{
			public float AvgMs;

			public float AvgFps;

			public float P1Low;

			public readonly List<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;

		internal static float SmoothFps => _smoothFps;

		internal static float SmoothMs => _smoothMs;

		internal static void UpdateLines()
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			_fpsAccum += Time.unscaledDeltaTime;
			_fpsFrames++;
			_fpsTimer += Time.unscaledDeltaTime;
			if (_fpsTimer >= 0.5f)
			{
				_smoothMs = _fpsAccum / (float)_fpsFrames * 1000f;
				_smoothFps = 1000f / Mathf.Max(_smoothMs, 0.001f);
				_fpsAccum = 0f;
				_fpsFrames = 0;
				_fpsTimer = 0f;
			}
			_lines.Clear();
			_showProgress = false;
			if (UpscalerManager.RepoHdDetected)
			{
				_lines.Add(new LineData("REPO HD DETECTED - REMOVE", Col.Warn));
			}
			if (UpscalerManager.BenchmarkActive)
			{
				_showProgress = true;
				_progress = UpscalerManager.BenchmarkProgress;
				_progressColor = new Color(0.9f, 0.35f, 0.35f);
				string text = (UpscalerManager.AutoBenchmarkRunning ? "AUTO-TUNING" : "BENCHMARKING");
				_lines.Add(new LineData($"{text}  {Mathf.RoundToInt(_progress * 100f)}%  {_smoothFps:F0} FPS  {_smoothMs:F1}ms", Col.Warn));
			}
			if (OptimizerBenchmark.Running || !string.IsNullOrEmpty(OptimizerBenchmark.Status))
			{
				_lines.Add(new LineData("OPTIMIZER  " + OptimizerBenchmark.Status, Col.Info));
				if (OptimizerBenchmark.Running)
				{
					_showProgress = true;
					_progress = OptimizerBenchmark.Progress;
					_progressColor = new Color(0.35f, 0.85f, 0.4f);
				}
			}
			if (!Settings.ModEnabled)
			{
				_lines.Add(new LineData($"FIDELITY OFF ({Settings.ToggleKey})  {_smoothFps:F0} FPS  {_smoothMs:F1}ms", Col.Warn));
			}
			else if (!Settings.OptimizationsEnabled)
			{
				_lines.Add(new LineData($"OPTIMIZATIONS OFF (F11)  {_smoothFps:F0} FPS  {_smoothMs:F1}ms", Col.Warn));
			}
			else if (Settings.CpuPatchesF11Disabled)
			{
				_lines.Add(new LineData($"CPU PATCHES OFF (F11)  {_smoothFps:F0} FPS  {_smoothMs:F1}ms", Col.Warn));
			}
			if (Settings.ModEnabled && Settings.DebugOverlay)
			{
				string text2 = Settings.Preset.ToString().ToUpper();
				string text3 = Settings.ResolvedUpscaleMode.ToString();
				string text4 = ((Settings.ResolvedAAMode != AAMode.Off) ? $" {Settings.ResolvedAAMode}" : "");
				string text5 = ((UpscalerManager.BenchmarkActive || OptimizerBenchmark.Running) ? "" : $"  {_smoothFps:F0} FPS  {_smoothMs:F1}ms");
				_lines.Add(new LineData("[" + text2 + "] " + text3 + text4 + text5, Col.Title));
				string text6 = (Settings.CpuPatchesActive ? "ON" : "OFF");
				string text7 = Settings.CpuPatchMode switch
				{
					1 => "FORCED", 
					0 => "FORCED", 
					_ => "AUTO", 
				};
				_lines.Add(new LineData($"SH:{Settings.ResolvedShadowQuality}/{Settings.ResolvedShadowDistance:F0}m " + $"L:{Settings.ResolvedPixelLightCount} LOD:{Settings.ResolvedLODBias:F1} CPU:{text6}({text7})", Col.Dim));
			}
			_nativeActive = TryUpdateNative();
		}

		internal static void Draw()
		{
			if (!_nativeActive && _lines.Count != 0)
			{
				DrawOnGUI();
			}
		}

		private static bool TryUpdateNative()
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)HUDCanvas.instance == (Object)null)
			{
				ClearNative();
				return false;
			}
			if ((Object)(object)_root == (Object)null)
			{
				_nativeLines.Clear();
				BuildNative();
			}
			if ((Object)(object)_root == (Object)null)
			{
				return false;
			}
			while (_nativeLines.Count < _lines.Count)
			{
				_nativeLines.Add(CreateNativeLine(_nativeLines.Count));
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			float num = (_showProgress ? 10f : 0f);
			for (int i = 0; i < _nativeLines.Count; i++)
			{
				NativeLine value = _nativeLines[i];
				bool num2 = i < _lines.Count;
				if (num2)
				{
					value.Go.SetActive(true);
					((TMP_Text)value.Text).text = _lines[i].Text;
					((Graphic)value.Text).color = GetColor(_lines[i].Color);
					float num3 = (value.TargetY = num + 110f + (float)(_lines.Count - 1 - i) * 20f);
					if (!value.WasVisible)
					{
						value.CurrentY = num3 + -40f;
					}
					value.WasVisible = true;
				}
				else
				{
					value.TargetY = value.CurrentY + -40f;
					if (value.WasVisible)
					{
						value.WasVisible = false;
					}
				}
				value.CurrentY = Mathf.Lerp(value.CurrentY, value.TargetY, unscaledDeltaTime * 6f);
				if (!num2 && Mathf.Abs(value.CurrentY - value.TargetY) < 0.5f)
				{
					value.Go.SetActive(false);
					continue;
				}
				value.Rt.anchoredPosition = new Vector2(0f, value.CurrentY);
				if ((Object)(object)value.ScanRt != (Object)null && ((TMP_Text)value.Text).preferredWidth > 0f)
				{
					value.ScanRt.sizeDelta = new Vector2(((TMP_Text)value.Text).preferredWidth + 4f, 0f);
				}
				_nativeLines[i] = value;
			}
			_root.SetActive(_lines.Count > 0 || AnyAnimating());
			if ((Object)(object)_progressBgNative != (Object)null)
			{
				((Component)_progressBgNative).gameObject.SetActive(_showProgress);
				if (_showProgress && (Object)(object)_progressFillNative != (Object)null && (Object)(object)_progressFillImg != (Object)null)
				{
					_progressFillNative.anchorMax = new Vector2(Mathf.Clamp01(_progress), 1f);
					((Graphic)_progressFillImg).color = _progressColor;
				}
			}
			return true;
		}

		private static bool AnyAnimating()
		{
			for (int i = 0; i < _nativeLines.Count; i++)
			{
				if (_nativeLines[i].Go.activeSelf)
				{
					return true;
				}
			}
			return false;
		}

		private static void BuildNative()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)HUDCanvas.instance == (Object)null))
			{
				FindGameAssets();
				if (!((Object)(object)_gameFont == (Object)null))
				{
					_root = new GameObject("FidelityOverlay");
					_root.transform.SetParent((Transform)(object)HUDCanvas.instance.rect, false);
					_rootRt = _root.AddComponent<RectTransform>();
					_rootRt.anchorMin = Vector2.zero;
					_rootRt.anchorMax = Vector2.zero;
					_rootRt.pivot = Vector2.zero;
					_rootRt.anchoredPosition = new Vector2(12f, 0f);
					_rootRt.sizeDelta = new Vector2(520f, 200f);
					GameObject val = new GameObject("ProgressBg");
					val.transform.SetParent((Transform)(object)_rootRt, false);
					_progressBgNative = val.AddComponent<RectTransform>();
					_progressBgNative.anchorMin = Vector2.zero;
					_progressBgNative.anchorMax = new Vector2(0f, 0f);
					_progressBgNative.pivot = Vector2.zero;
					_progressBgNative.anchoredPosition = new Vector2(0f, 102f);
					_progressBgNative.sizeDelta = new Vector2(220f, 3f);
					Image obj = val.AddComponent<Image>();
					((Graphic)obj).color = new Color(0.15f, 0.15f, 0.15f, 0.5f);
					((Graphic)obj).raycastTarget = false;
					val.SetActive(false);
					GameObject val2 = new GameObject("Fill");
					val2.transform.SetParent((Transform)(object)_progressBgNative, false);
					_progressFillNative = val2.AddComponent<RectTransform>();
					_progressFillNative.anchorMin = Vector2.zero;
					_progressFillNative.anchorMax = new Vector2(0f, 1f);
					_progressFillNative.pivot = new Vector2(0f, 0.5f);
					_progressFillNative.offsetMin = Vector2.zero;
					_progressFillNative.offsetMax = Vector2.zero;
					_progressFillImg = val2.AddComponent<Image>();
					((Graphic)_progressFillImg).raycastTarget = false;
					Plugin.Log.LogDebug((object)"Overlay: native HUD created");
				}
			}
		}

		private static NativeLine CreateNativeLine(int index)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"FidelityLine{index}");
			val.transform.SetParent(_root.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.zero;
			val2.pivot = new Vector2(0f, 0f);
			val2.anchoredPosition = new Vector2(0f, -40f);
			val2.sizeDelta = new Vector2(500f, 20f);
			TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val3).font = _gameFont;
			((TMP_Text)val3).fontSize = 14f;
			((TMP_Text)val3).fontStyle = (FontStyles)1;
			((TMP_Text)val3).alignment = (TextAlignmentOptions)1025;
			((TMP_Text)val3).overflowMode = (TextOverflowModes)0;
			((Graphic)val3).raycastTarget = false;
			((TMP_Text)val3).enableWordWrapping = false;
			RectTransform val4 = null;
			if ((Object)(object)_scanlineSprite != (Object)null)
			{
				GameObject val5 = new GameObject("Scanlines");
				val5.transform.SetParent(val.transform, false);
				val4 = val5.AddComponent<RectTransform>();
				val4.anchorMin = Vector2.zero;
				val4.anchorMax = new Vector2(0f, 1f);
				val4.pivot = new Vector2(0f, 0.5f);
				val4.offsetMin = Vector2.zero;
				val4.offsetMax = Vector2.zero;
				val4.sizeDelta = new Vector2(10f, 0f);
				Image obj = val5.AddComponent<Image>();
				obj.sprite = _scanlineSprite;
				obj.type = (Type)2;
				((Graphic)obj).raycastTarget = false;
				val5.AddComponent<UIScanlines>();
			}
			return new NativeLine
			{
				Go = val,
				Text = val3,
				Rt = val2,
				ScanRt = val4,
				CurrentY = -40f,
				TargetY = -40f,
				WasVisible = false
			};
		}

		private static void FindGameAssets()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_gameFont != (Object)null)
			{
				return;
			}
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val in array)
			{
				if ((Object)(object)((TMP_Text)val).font != (Object)null)
				{
					Scene scene = ((Component)val).gameObject.scene;
					if (((Scene)(ref scene)).isLoaded)
					{
						_gameFont = ((TMP_Text)val).font;
						break;
					}
				}
			}
			UIScanlines[] array2 = Resources.FindObjectsOfTypeAll<UIScanlines>();
			for (int i = 0; i < array2.Length; i++)
			{
				Image component = ((Component)array2[i]).GetComponent<Image>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null)
				{
					_scanlineSprite = component.sprite;
					Plugin.Log.LogDebug((object)("Overlay: scanline sprite '" + ((Object)_scanlineSprite).name + "'"));
					break;
				}
			}
			if ((Object)(object)_gameFont != (Object)null)
			{
				Plugin.Log.LogDebug((object)("Overlay: game font '" + ((Object)_gameFont).name + "'"));
			}
		}

		private static void ClearNative()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_nativeLines.Clear();
		}

		private static void DrawOnGUI()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			EnsureOnGUIStyles();
			float num = Mathf.Max((float)Screen.height / 1080f, 0.5f);
			float num2 = 20f * num;
			float num3 = 28f * num;
			float num4 = 1.5f * num;
			float num5 = (float)_lines.Count * num3 + (_showProgress ? (10f * num) : 0f);
			float num6 = (float)Screen.height - num5 - 50f * num;
			Rect val = default(Rect);
			for (int i = 0; i < _lines.Count; i++)
			{
				GetOnGUIStyles(_lines[i].Color, out GUIStyle text, out GUIStyle shadow);
				((Rect)(ref val))..ctor(num2, num6, (float)Screen.width * 0.5f, num3);
				GUI.Label(new Rect(((Rect)(ref val)).x + num4, ((Rect)(ref val)).y + num4, ((Rect)(ref val)).width, ((Rect)(ref val)).height), _lines[i].Text, shadow);
				GUI.Label(val, _lines[i].Text, text);
				num6 += num3;
			}
			if (_showProgress)
			{
				float num7 = 220f * num;
				GUI.DrawTexture(new Rect(num2, num6 + 4f * num, num7, 3f * num), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, false, 0f, new Color(0.1f, 0.1f, 0.1f, 0.5f), 0f, 0f);
				GUI.DrawTexture(new Rect(num2, num6 + 4f * num, num7 * Mathf.Clamp01(_progress), 3f * num), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, false, 0f, _progressColor, 0f, 0f);
			}
		}

		private static Color GetColor(Col c)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(c switch
			{
				Col.Title => new Color(0.3f, 0.92f, 0.4f), 
				Col.Info => new Color(0.35f, 0.88f, 0.45f), 
				Col.Warn => new Color(0.95f, 0.35f, 0.3f), 
				Col.Dim => new Color(0.45f, 0.52f, 0.45f), 
				_ => new Color(0.9f, 0.95f, 0.9f), 
			});
		}

		private static void EnsureOnGUIStyles()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (_styleTitle == null || _lastScreenH != Screen.height)
			{
				_lastScreenH = Screen.height;
				float num = Mathf.Max((float)Screen.height / 1080f, 0.5f);
				int size = Mathf.Max(Mathf.RoundToInt(16f * num), 11);
				int size2 = Mathf.Max(Mathf.RoundToInt(13f * num), 10);
				MakePair(size, GetColor(Col.Title), out _styleTitle, out _shadowTitle);
				MakePair(size, GetColor(Col.Info), out _styleInfo, out _shadowInfo);
				MakePair(size, GetColor(Col.Warn), out _styleWarn, out _shadowWarn);
				MakePair(size2, GetColor(Col.Dim), out _styleDim, out _shadowDim);
			}
		}

		private static void MakePair(int size, Color color, out GUIStyle text, out GUIStyle shadow)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			text = new GUIStyle
			{
				fontSize = size,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)3
			};
			text.normal.textColor = color;
			shadow = new GUIStyle(text);
			shadow.normal.textColor = new Color(0f, 0f, 0f, 0.55f);
		}

		private static void GetOnGUIStyles(Col c, out GUIStyle text, out GUIStyle shadow)
		{
			(text, shadow) = c switch
			{
				Col.Title => (_styleTitle, _shadowTitle), 
				Col.Info => (_styleInfo, _shadowInfo), 
				Col.Warn => (_styleWarn, _shadowWarn), 
				Col.Dim => (_styleDim, _shadowDim), 
				_ => (_styleTitle, _shadowTitle), 
			};
		}
	}
	[BepInPlugin("Vippy.REPOFidelity", "REPO Fidelity", "1.7.7")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "Vippy.REPOFidelity";

		public const string PluginName = "REPO Fidelity";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private Harmony? _harmony;

		private void Awake()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			if (Chainloader.PluginInfos.ContainsKey("BlueAmulet.REPO_HD"))
			{
				Log.LogWarning((object)"REPO_HD detected! REPO Fidelity covers all REPO_HD features. Please remove REPO_HD to avoid conflicts.");
			}
			bool flag = Chainloader.PluginInfos.ContainsKey("nickklmao.menulib");
			if (flag)
			{
				((BaseUnityPlugin)this).Config.Bind<bool>("_", "Hidden", true, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			}
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			Settings.Init();
			GPUDetector.Detect();
			Settings.ResolveAutoDefaults();
			ConfigIntegration.Initialize(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("Vippy.REPOFidelity");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				try
				{
					_harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					Log.LogWarning((object)$"Harmony patch failed for {type.Name}: {arg}");
				}
			}
			Log.LogInfo((object)"REPO Fidelity v1.7.7 loaded");
			Log.LogInfo((object)$"GPU: {GPUDetector.GpuName} ({GPUDetector.Vendor}, Tier: {GPUDetector.Tier}, VRAM: {GPUDetector.VramMb}MB)");
			Log.LogInfo((object)$"CPU: {SystemInfo.processorType} ({SystemInfo.processorCount} threads)");
			Log.LogInfo((object)$"RAM: {SystemInfo.systemMemorySize}MB | Platform: {Application.platform} | API: {SystemInfo.graphicsDeviceType}");
			Log.LogInfo((object)$"Display: {Screen.width}x{Screen.height} (aspect {(float)Screen.width / (float)Screen.height:F2})");
			Log.LogInfo((object)$"DLSS Available: {GPUDetector.DlssAvailable}");
			if (flag)
			{
				MenuIntegration.Initialize();
				Log.LogInfo((object)"MenuLib detected, settings added to graphics menu");
			}
			else
			{
				Log.LogInfo((object)"MenuLib not found, settings exposed via REPOConfig / config file");
			}
		}

		private void LateUpdate()
		{
			Settings.UpdateCpuGate();
			Overlay.UpdateLines();
		}

		private void OnGUI()
		{
			Overlay.Draw();
		}
	}
	internal enum QualityPreset
	{
		Potato,
		Low,
		Medium,
		High,
		Ultra,
		Custom,
		Auto
	}
	internal enum UpscaleMode
	{
		Auto,
		DLAA,
		DLSS,
		FSR4,
		FSR_Temporal,
		FSR,
		Off
	}
	internal enum AAMode
	{
		Auto,
		TAA,
		SMAA,
		FXAA,
		Off
	}
	internal enum ShadowQuality
	{
		Low,
		Medium,
		High,
		Ultra
	}
	internal enum TextureRes
	{
		Full,
		Half,
		Quarter
	}
	internal enum F11Target
	{
		FullOptLayer,
		CpuPatches
	}
	internal static class Settings
	{
		internal enum PerfOpt
		{
			ExplosionShadows,
			ParticleShadows,
			ItemLightShadows,
			TinyRendererCulling,
			AnimatedLightShadows,
			DistanceShadowCulling,
			FlashlightShadowBudget,
			PointLightShadows
		}

		private enum UpscaleTier
		{
			Budget,
			Quality,
			NativeAA
		}

		private s