Decompiled source of REPOFidelity v1.7.1

REPOFidelity.dll

Decompiled 9 hours 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Vippy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.7.1.0")]
[assembly: AssemblyInformationalVersion("1.7.1+de6c02c7aa4b836f8443eb2eff84dbf5e8a977ea")]
[assembly: AssemblyProduct("REPOFidelity")]
[assembly: AssemblyTitle("REPOFidelity")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.1.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.1";
	}
	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();
			bool flag = File.Exists(dllPath) && new FileInfo(dllPath).Length >= 10000000;
			if (flag)
			{
				Plugin.Log.LogDebug((object)$"DLSS DLL: {dllPath} ({new FileInfo(dllPath).Length / 1024 / 1024}MB)");
			}
			else
			{
				Plugin.Log.LogWarning((object)"nvngx_dlss.dll missing or invalid; DLSS/DLAA disabled. Reinstall the mod.");
			}
			return flag;
		}
	}
	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 => (_count > 0) ? (_sum / (float)_count) : 0f;

			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 => Settings.DebugOverlay || OptimizerBenchmark.Running;

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

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void End(Meter meter, long startTicks)
		{
			if (startTicks != 0)
			{
				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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_00cc: 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)
		{
			if (1 == 0)
			{
			}
			bool result;
			switch (mode)
			{
			case UpscaleMode.Auto:
				result = true;
				break;
			case UpscaleMode.Off:
				result = true;
				break;
			case UpscaleMode.DLAA:
			case UpscaleMode.DLSS:
				result = DlssAvailable;
				break;
			case UpscaleMode.FSR_Temporal:
				result = true;
				break;
			default:
				result = false;
				break;
			}
			if (1 == 0)
			{
			}
			return result;
		}

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

			public static Action <>9__71_1;

			public static Action <>9__71_41;

			public static Action<string> <>9__71_2;

			public static Action<string> <>9__71_3;

			public static Action <>9__71_42;

			public static Action<bool> <>9__71_4;

			public static Action<string> <>9__71_5;

			public static Action <>9__71_43;

			public static Action<int> <>9__71_6;

			public static Action<int> <>9__71_7;

			public static Action<bool> <>9__71_8;

			public static Action<bool> <>9__71_9;

			public static Action<string> <>9__71_10;

			public static Action<string> <>9__71_11;

			public static Action<int> <>9__71_12;

			public static Action<float> <>9__71_13;

			public static Action<string> <>9__71_14;

			public static Action<string> <>9__71_15;

			public static Action<float> <>9__71_16;

			public static Action<int> <>9__71_17;

			public static Action<float> <>9__71_18;

			public static Action<int> <>9__71_19;

			public static Action<string> <>9__71_20;

			public static Action<string> <>9__71_21;

			public static Action<float> <>9__71_22;

			public static Action<float> <>9__71_23;

			public static Action<float> <>9__71_24;

			public static Action<bool> <>9__71_25;

			public static Action<bool> <>9__71_26;

			public static Action<bool> <>9__71_27;

			public static Action<bool> <>9__71_28;

			public static Action <>9__71_65;

			public static Action<bool> <>9__71_29;

			public static Action <>9__71_66;

			public static Action<bool> <>9__71_30;

			public static Action<bool> <>9__71_31;

			public static Action <>9__71_32;

			public static Action<int> <>9__71_33;

			public static Action<int> <>9__71_34;

			public static Action<int> <>9__71_35;

			public static Action<int> <>9__71_36;

			public static Action<int> <>9__71_37;

			public static Action<int> <>9__71_38;

			public static Action<bool> <>9__71_39;

			public static Action<bool> <>9__71_40;

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

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

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

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

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

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

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

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

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

			internal void <CreatePage>b__71_7(int v)
			{
				ModSet(new <>c__DisplayClass71_1
				{
					v = v
				}.<CreatePage>b__44);
			}

			internal void <CreatePage>b__71_8(bool b)
			{
				ModSet(new <>c__DisplayClass71_2
				{
					b = b
				}.<CreatePage>b__45);
			}

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

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

			internal void <CreatePage>b__71_11(string s)
			{
				ModSet(new <>c__DisplayClass71_4
				{
					enumName = ((s == "FSR") ? "FSR_Temporal" : s)
				}.<CreatePage>b__47);
			}

			internal void <CreatePage>b__71_12(int v)
			{
				ModSet(new <>c__DisplayClass71_5
				{
					v = v
				}.<CreatePage>b__48);
			}

			internal void <CreatePage>b__71_13(float v)
			{
				ModSet(new <>c__DisplayClass71_6
				{
					v = v
				}.<CreatePage>b__49);
			}

			internal void <CreatePage>b__71_14(string s)
			{
				ModSet(new <>c__DisplayClass71_7
				{
					s = s
				}.<CreatePage>b__50);
			}

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

			internal void <CreatePage>b__71_16(float v)
			{
				ModSet(new <>c__DisplayClass71_9
				{
					v = v
				}.<CreatePage>b__52);
			}

			internal void <CreatePage>b__71_17(int v)
			{
				ModSet(new <>c__DisplayClass71_10
				{
					v = v
				}.<CreatePage>b__53);
			}

			internal void <CreatePage>b__71_18(float v)
			{
				ModSet(new <>c__DisplayClass71_11
				{
					v = v
				}.<CreatePage>b__54);
			}

			internal void <CreatePage>b__71_19(int v)
			{
				ModSet(new <>c__DisplayClass71_12
				{
					v = v
				}.<CreatePage>b__55);
			}

			internal void <CreatePage>b__71_20(string s)
			{
				ModSet(new <>c__DisplayClass71_13
				{
					s = s
				}.<CreatePage>b__56);
			}

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

			internal void <CreatePage>b__71_22(float v)
			{
				ModSet(new <>c__DisplayClass71_15
				{
					v = v
				}.<CreatePage>b__58);
			}

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

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

			internal void <CreatePage>b__71_25(bool b)
			{
				ModSet(new <>c__DisplayClass71_18
				{
					b = b
				}.<CreatePage>b__61);
			}

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

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

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

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

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

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

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

			internal void <CreatePage>b__71_31(bool b)
			{
				ModSet(new <>c__DisplayClass71_22
				{
					b = b
				}.<CreatePage>b__67);
			}

			internal void <CreatePage>b__71_32()
			{
				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__71_33(int v)
			{
				ModSet(new <>c__DisplayClass71_23
				{
					v = v
				}.<CreatePage>b__68);
			}

			internal void <CreatePage>b__71_34(int v)
			{
				ModSet(new <>c__DisplayClass71_24
				{
					v = v
				}.<CreatePage>b__69);
			}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			internal void <CreatePage>b__52()
			{
				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 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_ticker != (Object)null))
			{
				GameObject val = new GameObject("REPOFidelity_MenuStatus");
				Object.DontDestroyOnLoad((Object)(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);
			UpscaleMode resolvedUpscaleMode = Settings.ResolvedUpscaleMode;
			if (1 == 0)
			{
			}
			string text = resolvedUpscaleMode switch
			{
				UpscaleMode.DLAA => "DLAA", 
				UpscaleMode.DLSS => "DLSS", 
				UpscaleMode.FSR_Temporal => "FSR", 
				UpscaleMode.Off => "native", 
				_ => Settings.ResolvedUpscaleMode.ToString(), 
			};
			if (1 == 0)
			{
			}
			string text2 = text;
			string text3 = ((resolvedRenderScale == 100) ? $"{outputWidth}×{outputHeight} {text2}" : $"{outputWidth}×{outputHeight} → {num}×{num2} ({text2} {resolvedRenderScale}%)");
			float smoothFps = Overlay.SmoothFps;
			float smoothMs = Overlay.SmoothMs;
			string text4;
			if (!SemiFunc.RunIsLevel() || smoothFps < 1f)
			{
				text4 = "waiting for gameplay";
			}
			else
			{
				string arg = (Settings.CpuBound ? "CPU-bound" : "GPU-bound");
				text4 = $"{arg} • {smoothMs:F1} ms / {smoothFps:F0} fps";
			}
			return text4 + "  •  " + text3;
		}

		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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0bf6: 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__71_0;
			if (obj == null)
			{
				ScrollViewBuilderDelegate val = delegate(Transform sv)
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					REPOLabel val2 = MenuAPI.CreateREPOLabel("", sv, new Vector2(0f, 0f));
					_statusText = ((Component)val2).GetComponentInChildren<Text>();
					return ((REPOElement)val2).rectTransform;
				};
				<>c.<>9__71_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);
			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_0011: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			Text captured = null;
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_0019: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			REPOSlider s = null;
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_003a: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			REPOSlider s = null;
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_002e: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			REPOSlider s = null;
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_002e: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			REPOToggle t = null;
			_page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform sv)
			{
				//IL_0028: 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? 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (!Running)
			{
				if ((Object)(object)Instance == (Object)null)
				{
					GameObject val = new GameObject("REPOFidelity_OptimizerBenchmark");
					Object.DontDestroyOnLoad((Object)(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 next;
				try
				{
					next = inner.MoveNext();
				}
				catch (Exception ex)
				{
					Exception ex2 = ex;
					Plugin.Log.LogError((object)$"Benchmark failed: {ex2}");
					Restore();
					Running = false;
					Status = "ERROR";
					break;
				}
				if (!next)
				{
					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 report = BuildReport(vanilla, gpuGc, allOn);
			string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "optimizer_benchmark.txt");
			try
			{
				File.WriteAllText(path, report);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Report save failed: " + ex.Message));
			}
			Plugin.Log.LogInfo((object)("\n" + report));
			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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			_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");
				int cpuPatchMode = Settings.CpuPatchMode;
				if (1 == 0)
				{
				}
				string text7 = cpuPatchMode switch
				{
					1 => "FORCED", 
					0 => "FORCED", 
					_ => "AUTO", 
				};
				if (1 == 0)
				{
				}
				string text8 = text7;
				_lines.Add(new LineData($"SH:{Settings.ResolvedShadowQuality}/{Settings.ResolvedShadowDistance:F0}m " + $"L:{Settings.ResolvedPixelLightCount} LOD:{Settings.ResolvedLODBias:F1} CPU:{text6}({text8})", Col.Dim));
			}
			_nativeActive = TryUpdateNative();
		}

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

		private static bool TryUpdateNative()
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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 flag = i < _lines.Count;
				if (flag)
				{
					value.Go.SetActive(true);
					((TMP_Text)value.Text).text = _lines[i].Text;
					((Graphic)value.Text).color = GetColor(_lines[i].Color);
					float num2 = (value.TargetY = num + 110f + (float)(_lines.Count - 1 - i) * 20f);
					if (!value.WasVisible)
					{
						value.CurrentY = num2 + -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 (!flag && 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00d9: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: 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 val2 = val.AddComponent<Image>();
					((Graphic)val2).color = new Color(0.15f, 0.15f, 0.15f, 0.5f);
					((Graphic)val2).raycastTarget = false;
					val.SetActive(false);
					GameObject val3 = new GameObject("Fill");
					val3.transform.SetParent((Transform)(object)_progressBgNative, false);
					_progressFillNative = val3.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 = val3.AddComponent<Image>();
					((Graphic)_progressFillImg).raycastTarget = false;
					Plugin.Log.LogDebug((object)"Overlay: native HUD created");
				}
			}
		}

		private static NativeLine CreateNativeLine(int index)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			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 val6 = val5.AddComponent<Image>();
				val6.sprite = _scanlineSprite;
				val6.type = (Type)2;
				((Graphic)val6).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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			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>();
			foreach (UIScanlines val2 in array2)
			{
				Image component = ((Component)val2).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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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)
			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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (1 == 0)
			{
			}
			Color result = (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), 
			});
			if (1 == 0)
			{
			}
			return result;
		}

		private static void EnsureOnGUIStyles()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0052: 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)
		{
			if (1 == 0)
			{
			}
			(GUIStyle, GUIStyle) tuple = c switch
			{
				Col.Title => (_styleTitle, _shadowTitle), 
				Col.Info => (_styleInfo, _shadowInfo), 
				Col.Warn => (_styleWarn, _shadowWarn), 
				Col.Dim => (_styleDim, _shadowDim), 
				_ => (_styleTitle, _shadowTitle), 
			};
			if (1 == 0)
			{
			}
			(text, shadow) = tuple;
		}
	}
	[BepInPlugin("Vippy.REPOFidelity", "REPO Fidelity", "1.7.1")]
	[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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			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.");
			}
			((BaseUnityPlugin)this).Config.Bind<bool>("_", "Hidden", true, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			Settings.Init();
			GPUDetector.Detect();
			Settings.ResolveAutoDefaults();
			_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.1 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 (Chainloader.PluginInfos.ContainsKey("nickklmao.menulib"))
			{
				MenuIntegration.Initialize();
				Log.LogInfo((object)"MenuLib detected, settings added to graphics menu");
			}
		}

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

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

		private enum UpscaleTier
		{
			Budget,
			Quality,
			NativeAA
		}

		private static SettingsFile _file = null;

		private static bool _initComplete;

		internal static bool ModEnabled = true;

		internal static bool OptimizationsEnabled = true;

		internal static bool AllocationFixesEnabled = true;

		internal static bool CpuPatchesF11Disabled;

		private static bool _cpuPatchesActiveRaw = true;

		private static float _cpuGateTimer;

		private static float _cpuGateAccum;

		private static int _cpuGateFrames;

		private const float CpuGateThresholdMs = 8f;

		internal static int ResolvedShadowBudget;

		internal const float PlayableFogFloor = 0.5f;

		internal static UpscaleMode ResolvedUpscaleMode;

		internal static int ResolvedRenderScale;

		internal static AAMode ResolvedAAMode;

		internal static ShadowQuality ResolvedShadowQuality;

		internal static float ResolvedShadowDistance;

		internal static float ResolvedLODBias;

		internal static int ResolvedPixelLightCount;

		internal static float ResolvedLightDistance;

		internal static float ResolvedFogMultiplier;

		internal static float ResolvedEffectiveFogEnd;

		internal static float ResolvedViewDistance;

		internal static int ResolvedAnisotropicFiltering;

		internal static TextureRes ResolvedTextureQuality;

		private static AutoTuneData _autoTune = new AutoTuneData();

		private static string _autoTunePath = "";

		private static bool _pendingWindowReset;

		private static int _suppressTweakRevert;

		private static SettingsData D => _file.Data;

		internal static QualityPreset Preset
		{
			get
			{
				return (QualityPreset)D.preset;
			}
			set
			{
				D.preset = (int)value;
				_file.Save();
				OnChanged();
			}
		}

		internal static int OutputWidth
		{
			get
			{
				return (D.resWidth > 0) ? D.resWidth : Screen.width;
			}
			set
			{
				D.resWidth = value;
				_file.Save();
				OnChanged();
			}
		}

		internal static int OutputHeight
		{
			get
			{
				return (D.resHeight > 0) ? D.resHeight : Screen.height;
			}
			set
			{
				D.resHeight = value;
				_file.Save();
				OnChanged();
			}
		}

		internal static UpscaleMode UpscaleModeSetting
		{
			get
			{
				return (UpscaleMode)D.upscaler;
			}
			set
			{
				D.upscaler = (int)value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static int RenderScale
		{
			get
			{
				return D.renderScale;
			}
			set
			{
				D.renderScale = Mathf.Clamp(value, 33, 100);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static float Sharpening
		{
			get
			{
				return D.sharpening;
			}
			set
			{
				D.sharpening = Mathf.Clamp(value, 0f, 1f);
				_file.Save();
				if (_initComplete && Preset != QualityPreset.Custom)
				{
					_file.SuppressEvents(delegate
					{
						D.preset = 5;
					});
					_file.Save();
				}
			}
		}

		internal static AAMode AntiAliasingMode
		{
			get
			{
				return (AAMode)D.aaMode;
			}
			set
			{
				D.aaMode = (int)value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool Pixelation
		{
			get
			{
				return D.pixelation;
			}
			set
			{
				D.pixelation = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static ShadowQuality ShadowQualitySetting
		{
			get
			{
				return (ShadowQuality)D.shadowQuality;
			}
			set
			{
				D.shadowQuality = (int)value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static float ShadowDistance
		{
			get
			{
				return D.shadowDistance;
			}
			set
			{
				D.shadowDistance = Mathf.Clamp(value, 5f, 200f);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static float LODBias
		{
			get
			{
				return D.lodBias;
			}
			set
			{
				D.lodBias = Mathf.Clamp(value, 0.5f, 4f);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static int AnisotropicFiltering
		{
			get
			{
				return D.anisotropicFiltering;
			}
			set
			{
				D.anisotropicFiltering = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static int PixelLightCount
		{
			get
			{
				return D.pixelLightCount;
			}
			set
			{
				D.pixelLightCount = Mathf.Clamp(value, 1, 16);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static TextureRes TextureQuality
		{
			get
			{
				return (TextureRes)D.textureQuality;
			}
			set
			{
				D.textureQuality = (int)value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static float LightDistance
		{
			get
			{
				return D.lightDistance;
			}
			set
			{
				D.lightDistance = Mathf.Clamp(value, 10f, 100f);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static float FogDistanceMultiplier
		{
			get
			{
				return D.fogMultiplier;
			}
			set
			{
				D.fogMultiplier = Mathf.Clamp(value, 0.3f, 1.1f);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static float ViewDistance
		{
			get
			{
				return D.viewDistance;
			}
			set
			{
				D.viewDistance = Mathf.Clamp(value, 0f, 500f);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool MotionBlurOverride
		{
			get
			{
				return D.motionBlur;
			}
			set
			{
				D.motionBlur = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool ChromaticAberration
		{
			get
			{
				return D.chromaticAberration;
			}
			set
			{
				D.chromaticAberration = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool LensDistortion
		{
			get
			{
				return D.lensDistortion;
			}
			set
			{
				D.lensDistortion = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool FilmGrain
		{
			get
			{
				return D.filmGrain;
			}
			set
			{
				D.filmGrain = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool ExtractionPointFlicker
		{
			get
			{
				return D.extractionFlickerFix;
			}
			set
			{
				D.extractionFlickerFix = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static int VerticalFovOverride
		{
			get
			{
				return D.verticalFovOverride;
			}
			set
			{
				D.verticalFovOverride = Mathf.Clamp(value, 0, 110);
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool UltrawideUiFix
		{
			get
			{
				return D.ultrawideUiFix;
			}
			set
			{
				D.ultrawideUiFix = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static bool UltrawideHudUnstretch
		{
			get
			{
				return D.ultrawideHudUnstretch;
			}
			set
			{
				D.ultrawideHudUnstretch = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static KeyCode ToggleKey
		{
			get
			{
				return (KeyCode)D.toggleKey;
			}
			set
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected I4, but got Unknown
				D.toggleKey = (int)value;
				_file.Save();
			}
		}

		internal static F11Target F11TargetSetting
		{
			get
			{
				F11Target f11Target = (F11Target)D.f11Target;
				return Enum.IsDefined(typeof(F11Target), f11Target) ? f11Target : F11Target.FullOptLayer;
			}
			set
			{
				D.f11Target = (int)value;
				_file.Save();
			}
		}

		internal static bool DebugOverlay
		{
			get
			{
				return D.debugOverlay;
			}
			set
			{
				D.debugOverlay = value;
				_file.Save();
			}
		}

		internal static bool BenchmarkMode
		{
			get
			{
				return D.benchmark;
			}
			set
			{
				D.benchmark = value;
				_file.Save();
			}
		}

		internal static bool AutoConfigured => !_autoTune.IsStale();

		internal static bool OptimizationsActive => ModEnabled && OptimizationsEnabled;

		internal static bool CpuBound => _autoTune.IsStale() || _autoTune.cpuBound;

		internal static int CpuPatchMode
		{
			get
			{
				return D.cpuPatchMode;
			}
			set
			{
				D.cpuPatchMode = value;
				_file.Save();
			}
		}

		internal static bool CpuPatchesActive => _cpuPatchesActiveRaw && OptimizationsActive && !CpuPatchesF11Disabled;

		internal static int ShadowBudget
		{
			get
			{
				return D.shadowBudget;
			}
			set
			{
				D.shadowBudget = value;
				_file.Save();
				OnSettingTweaked();
			}
		}

		internal static int PerfExplosionShadows
		{
			get
			{
				return D.perfExplosionShadows;
			}
			set
			{
				D.perfExplosionShadows = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfItemLightShadows
		{
			get
			{
				return D.perfItemLightShadows;
			}
			set
			{
				D.perfItemLightShadows = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfAnimatedLightShadows
		{
			get
			{
				return D.perfAnimatedLightShadows;
			}
			set
			{
				D.perfAnimatedLightShadows = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfParticleShadows
		{
			get
			{
				return D.perfParticleShadows;
			}
			set
			{
				D.perfParticleShadows = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfTinyRendererCulling
		{
			get
			{
				return D.perfTinyRendererCulling;
			}
			set
			{
				D.perfTinyRendererCulling = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfDistanceShadowCulling
		{
			get
			{
				return D.perfDistanceShadowCulling;
			}
			set
			{
				D.perfDistanceShadowCulling = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfFlashlightShadowBudget
		{
			get
			{
				return D.perfFlashlightShadowBudget;
			}
			set
			{
				D.perfFlashlightShadowBudget = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static int PerfPointLightShadows
		{
			get
			{
				return D.perfPointLightShadows;
			}
			set
			{
				D.perfPointLightShadows = value;
				_file.Save();
				_file.NotifyChanged();
			}
		}

		internal static bool AutoTuneNeedsBenchmark => _autoTune.IsStale();

		internal static bool AutoTuneNeedsInitialBenchmark => _autoTune.revision < 7 || _autoTune.gpuName != SystemInfo.graphicsDeviceName;

		internal static bool PresetRevertSuppressed => _suppressTweakRevert > 0;

		internal static event Action? OnSettingsChanged;

		internal static void InvalidateAutoTune()
		{
			_autoTune.version = "";
		}

		internal static void UpdateCpuGate()
		{
			if (CpuPatchMode == 1)
			{
				_cpuPatchesActiveRaw = true;
				return;
			}
			if (CpuPatchMode == 0)
			{
				_cpuPatchesActiveRaw = false;
				return;
			}
			_cpuGateAccum += Time.unscaledDeltaTime;
			_cpuGateFrames++;
			_cpuGateTimer += Time.unscaledDeltaTime;
			if (_cpuGateTimer >= 0.5f && _cpuGateFrames > 0)
			{
				float num = _cpuGateAccum / (float)_cpuGateFrames * 1000f;
				_cpuPatchesActiveRaw = num >= 8f;
				_cpuGateTimer = 0f;
				_cpuGateAccum = 0f;
				_cpuGateFrames = 0;
			}
		}

		internal static bool ShouldOptimize(PerfOpt opt)
		{
			if (!OptimizationsActive)
			{
				return false;
			}
			int num;
			if (Preset == QualityPreset.Custom)
			{
				if (1 == 0)
				{
				}
				num = opt switch
				{
					PerfOpt.ExplosionShadows => D.perfExplosionShadows, 
					PerfOpt.ParticleShadows => D.perfParticleShadows, 
					PerfOpt.ItemLightShadows => D.perfItemLightShadows, 
					PerfOpt.TinyRendererCulling => D.perfTinyRendererCulling, 
					PerfOpt.AnimatedLightShadows => D.perfAnimatedLightShadows, 
					PerfOpt.DistanceShadowCulling => D.perfDistanceShadowCulling, 
					PerfOpt.FlashlightShadowBudget => D.perfFlashlightShadowBudget, 
					PerfOpt.PointLightShadows => D.perfPointLightShadows, 
					_ => -1, 
				};
				if (1 == 0)
				{
				}
				switch (num)
				{
				case 0:
					return false;
				case 1:
					return true;
				}
			}
			QualityPreset preset = Preset;
			if (1 =