Decompiled source of SebUltrawide v1.1.3

BepInEx\plugins\SebUltrawide\SebUltrawide.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SebCore;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SebUltrawide")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SebUltrawide")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6D22F575-14EC-4621-BF89-59122F2F3F98")]
[assembly: AssemblyFileVersion("1.1.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SebUltrawide
{
	internal static class AspectRatioSetting
	{
		internal enum Kind
		{
			Vanilla,
			Auto,
			Window,
			Display,
			Fixed
		}

		internal static Kind Parse(string value, out float aspect)
		{
			aspect = 0f;
			string text = (string.IsNullOrWhiteSpace(value) ? "" : value.Trim().ToLowerInvariant());
			switch (text)
			{
			case "default":
			case "native":
			case "vanilla":
				return Kind.Vanilla;
			case "auto":
			case "match":
				return Kind.Auto;
			case "window":
				return Kind.Window;
			default:
			{
				string[] array = text.Split(new char[1] { ':' });
				float value4;
				if (array.Length == 2 && TryParseFloat(array[0], out var value2) && TryParseFloat(array[1], out var value3) && value3 > 0.01f)
				{
					aspect = value2 / value3;
				}
				else if (array.Length == 1 && TryParseFloat(text, out value4))
				{
					aspect = value4;
				}
				if (!(aspect > 0.1f))
				{
					return Kind.Display;
				}
				return Kind.Fixed;
			}
			}
		}

		private static bool TryParseFloat(string s, out float value)
		{
			return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out value);
		}
	}
	[BepInPlugin("shibe.easydeliveryco.sebultrawide", "SebUltrawide", "1.1.3")]
	[BepInDependency("shibe.easydeliveryco.sebcore", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		private struct PixelPerfectState
		{
			public int Width;

			public int Height;

			public float Aspect;

			public float Fov;

			public float Z;

			public bool Equals(PixelPerfectState other)
			{
				if (Width == other.Width && Height == other.Height && Mathf.Abs(Aspect - other.Aspect) < 0.0001f && Mathf.Abs(Fov - other.Fov) < 0.001f)
				{
					return Mathf.Abs(Z - other.Z) < 0.0001f;
				}
				return false;
			}
		}

		private const float DefaultAspect = 1.7777778f;

		private static ConfigEntry<bool> _debugMode;

		private static ConfigEntry<string> _aspectRatio;

		private static ManualLogSource _log;

		private static readonly Dictionary<int, Vector2> OverlayTargetSizes = new Dictionary<int, Vector2>();

		private static readonly Dictionary<int, float> PixelViewAspects = new Dictionary<int, float>();

		private static readonly Dictionary<int, float> PixelViewSkipAspects = new Dictionary<int, float>();

		private static readonly Dictionary<int, PixelPerfectState> PixelPerfectStates = new Dictionary<int, PixelPerfectState>();

		private static readonly Dictionary<int, Vector3> HudDisplayOriginalScales = new Dictionary<int, Vector3>();

		private static readonly int MainTexId = Shader.PropertyToID("_MainTex");

		private static readonly int AlphaTexId = Shader.PropertyToID("_AlphaTex");

		private static int _lastScreenWidth = -1;

		private static int _lastScreenHeight = -1;

		private static bool _lastScreenFullscreen;

		public const string PluginGuid = "shibe.easydeliveryco.sebultrawide";

		public const string PluginName = "SebUltrawide";

		public const string PluginVersion = "1.1.3";

		private static readonly Dictionary<int, int> HudMiniRendererOriginalWidths = new Dictionary<int, int>();

		private static AspectRatioSetting.Kind ParseAspectSetting(out float aspect)
		{
			return AspectRatioSetting.Parse((_aspectRatio != null) ? _aspectRatio.Value : "auto", out aspect);
		}

		private static bool IsVanillaPresentation()
		{
			float aspect;
			return ParseAspectSetting(out aspect) == AspectRatioSetting.Kind.Vanilla;
		}

		private static void RefreshPresentationIfChanged()
		{
			int width = Screen.width;
			int height = Screen.height;
			bool fullScreen = Screen.fullScreen;
			if (_lastScreenWidth != width || _lastScreenHeight != height || _lastScreenFullscreen != fullScreen)
			{
				_lastScreenWidth = width;
				_lastScreenHeight = height;
				_lastScreenFullscreen = fullScreen;
				ApplyAllCameras();
				ScaleOverlayBackdrops();
				RefreshHudRendererAspect();
				ModGraphics.ApplySaved();
				LogDebug($"Refreshed presentation after resolution/fullscreen change: {width}x{height}, fullscreen={fullScreen}.");
			}
		}

		private static float GetPixelationOutputAspect()
		{
			if (IsVanillaPresentation())
			{
				return 1.7777778f;
			}
			float targetAspect = GetTargetAspect();
			if (!(targetAspect > 0.01f))
			{
				return GetWindowAspect();
			}
			return targetAspect;
		}

		private static float GetTargetAspect()
		{
			float aspect;
			return ParseAspectSetting(out aspect) switch
			{
				AspectRatioSetting.Kind.Vanilla => 1.7777778f, 
				AspectRatioSetting.Kind.Auto => Mathf.Round(GetWindowAspect() * 100f) / 100f, 
				AspectRatioSetting.Kind.Window => GetWindowAspect(), 
				AspectRatioSetting.Kind.Fixed => aspect, 
				_ => GetDisplayAspect(), 
			};
		}

		private static float GetDisplayAspect()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Resolution currentResolution = Screen.currentResolution;
			if (((Resolution)(ref currentResolution)).height == 0)
			{
				return 1.7777778f;
			}
			currentResolution = Screen.currentResolution;
			float num = ((Resolution)(ref currentResolution)).width;
			currentResolution = Screen.currentResolution;
			return num / (float)((Resolution)(ref currentResolution)).height;
		}

		private static float GetWindowAspect()
		{
			if (Screen.height == 0)
			{
				return 1.7777778f;
			}
			return (float)Screen.width / (float)Screen.height;
		}

		private static bool IsUltrawide()
		{
			if (IsVanillaPresentation())
			{
				return false;
			}
			return GetWindowAspect() > 1.7877778f;
		}

		private static bool IsPrimaryGameplayCamera(Camera camera)
		{
			if ((Object)(object)camera == (Object)null)
			{
				return false;
			}
			if (string.Equals(((Object)camera).name, "Camera Persp", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return (Object)(object)camera == (Object)(object)Camera.main;
		}

		private static void ApplyCameraAspect(Camera camera)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!IsPrimaryGameplayCamera(camera))
			{
				return;
			}
			Rect rect = camera.rect;
			if (!(((Rect)(ref rect)).width < 0.99f))
			{
				rect = camera.rect;
				if (!(((Rect)(ref rect)).height < 0.99f))
				{
					ApplyAspect(camera);
				}
			}
		}

		private static void ApplyAspect(Camera camera)
		{
			if (!((Object)(object)camera == (Object)null) && IsUltrawide())
			{
				float targetAspect = GetTargetAspect();
				if (!(targetAspect <= 0.01f) && !(Mathf.Abs(camera.aspect - targetAspect) < 0.0001f))
				{
					camera.aspect = targetAspect;
					LogDebug($"Forced aspect for {((Object)camera).name} ({((Object)camera).GetInstanceID()}) to {targetAspect:0.###}.");
				}
			}
		}

		private static void ApplyMenuCameraAspect(GameObject menuCameraObject)
		{
			if (!((Object)(object)menuCameraObject == (Object)null))
			{
				ApplyAspect(menuCameraObject.GetComponentInChildren<Camera>(true));
			}
		}

		private static void ApplyAllCameras()
		{
			if (IsUltrawide())
			{
				Camera[] allCameras = Camera.allCameras;
				for (int i = 0; i < allCameras.Length; i++)
				{
					ApplyCameraAspect(allCameras[i]);
				}
			}
		}

		private static void LogDebug(string message)
		{
			if (_debugMode != null && _debugMode.Value)
			{
				_log.LogInfo((object)message);
			}
		}

		private static bool PixelPerfectView_AdjustViewPlane_Prefix(pixelPerfectView __instance, Camera ___gameCamera)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)___gameCamera == (Object)null || !IsUltrawide())
			{
				return true;
			}
			float menuWidth = __instance.menuWidth;
			float menuHeight = __instance.menuHeight;
			if (menuWidth <= 0.01f || menuHeight <= 0.01f)
			{
				return true;
			}
			float num = menuWidth / menuHeight;
			if (!(num > 1.65f) || !(num < 1.9f))
			{
				LogPixelPerfectSkip((Component)(object)__instance, num);
				return true;
			}
			Transform transform = ((Component)__instance).transform;
			float num2 = 2f * transform.localPosition.z * Mathf.Tan(___gameCamera.fieldOfView * 0.5f * ((float)Math.PI / 180f));
			float windowAspect = GetWindowAspect();
			int instanceID = ((Object)__instance).GetInstanceID();
			PixelPerfectState pixelPerfectState = new PixelPerfectState
			{
				Width = Screen.width,
				Height = Screen.height,
				Aspect = windowAspect,
				Fov = ___gameCamera.fieldOfView,
				Z = transform.localPosition.z
			};
			if (!PixelPerfectStates.TryGetValue(instanceID, out var value) || !value.Equals(pixelPerfectState))
			{
				PixelPerfectStates[instanceID] = pixelPerfectState;
				transform.localScale = new Vector3(num2 * windowAspect, num2, 1f);
			}
			LogPixelPerfectScale((Component)(object)__instance, windowAspect, num);
			return false;
		}

		private static void MiniRenderer_Start_Postfix(MiniRenderer __instance)
		{
			if (IsUltrawide())
			{
				EnsureMiniRendererRenderTexture(__instance);
				ApplyHudDisplayScale(__instance);
			}
		}

		private static void EnsureMiniRendererRenderTexture(MiniRenderer renderer)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)renderer == (Object)null || renderer.width <= 0 || renderer.height <= 0)
			{
				return;
			}
			RenderTexture rt = renderer.rt;
			if (!((Object)(object)rt != (Object)null) || ((Texture)rt).width != renderer.width || ((Texture)rt).height != renderer.height)
			{
				RenderTexture val = new RenderTexture(renderer.width, renderer.height, ((Object)(object)rt != (Object)null) ? rt.depth : 32);
				if ((Object)(object)rt != (Object)null)
				{
					((Texture)val).filterMode = ((Texture)rt).filterMode;
				}
				renderer.rt = val;
				UpdateMiniRendererTextures(renderer, val);
				if (MiniRenderer.renderers != null && !string.IsNullOrEmpty(renderer.rendererName))
				{
					MiniRenderer.renderers[renderer.rendererName] = val;
				}
			}
		}

		private static void UpdateMiniRendererTextures(MiniRenderer renderer, RenderTexture rt)
		{
			Material val = renderer.mat;
			if ((Object)(object)val == (Object)null)
			{
				Renderer component = ((Component)renderer).GetComponent<Renderer>();
				val = (((Object)(object)component != (Object)null) ? component.material : null);
			}
			if ((Object)(object)val != (Object)null)
			{
				val.SetTexture(MainTexId, (Texture)(object)rt);
				val.SetTexture(AlphaTexId, (Texture)(object)rt);
			}
		}

		private static void RefreshHudRendererAspect()
		{
			sHUD val = Object.FindFirstObjectByType<sHUD>();
			UpdateHudRendererAspect(((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<MiniRenderer>(true) : null);
		}

		private static void UpdateHudRendererAspect(MiniRenderer miniRenderer)
		{
			if ((Object)(object)miniRenderer == (Object)null || miniRenderer.width <= 0 || miniRenderer.height <= 0)
			{
				return;
			}
			bool flag = IsUltrawide();
			int instanceID = ((Object)miniRenderer).GetInstanceID();
			if (!HudMiniRendererOriginalWidths.TryGetValue(instanceID, out var value))
			{
				if (!flag)
				{
					return;
				}
				value = miniRenderer.width;
				HudMiniRendererOriginalWidths[instanceID] = value;
			}
			int num = (flag ? Mathf.Clamp(Mathf.RoundToInt((float)miniRenderer.height * GetWindowAspect()), 1, 8192) : value);
			if (miniRenderer.width != num)
			{
				miniRenderer.width = num;
				EnsureMiniRendererRenderTexture(miniRenderer);
				LogDebug($"Set HUD MiniRenderer width to {num} (window aspect {GetWindowAspect():0.###}).");
			}
		}

		private static void ApplyHudDisplayScale(MiniRenderer renderer)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)renderer == (Object)null || renderer.width <= 0 || renderer.height <= 0)
			{
				return;
			}
			float windowAspect = GetWindowAspect();
			if (windowAspect <= 0.01f)
			{
				return;
			}
			RenderTexture rt = renderer.rt;
			MeshRenderer[] componentsInParent = ((Component)renderer).GetComponentsInParent<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInParent)
			{
				Material val2 = (((Object)(object)val != (Object)null) ? ((Renderer)val).sharedMaterial : null);
				if (!((Object)(object)val2 == (Object)null) && (!((Object)(object)rt != (Object)null) || !((Object)(object)val2.mainTexture != (Object)(object)rt) || !((Object)(object)val2.GetTexture(MainTexId) != (Object)(object)rt)))
				{
					Transform transform = ((Component)val).transform;
					int instanceID = ((Object)transform).GetInstanceID();
					if (!HudDisplayOriginalScales.TryGetValue(instanceID, out var value))
					{
						value = transform.localScale;
						HudDisplayOriginalScales[instanceID] = value;
					}
					float num = windowAspect / ((float)renderer.width / (float)renderer.height);
					transform.localScale = new Vector3(value.x * num, value.y, value.z);
					LogDebug($"Scaled HUD display to {num:0.###}x (aspect {windowAspect:0.###}).");
				}
			}
		}

		private static void LogPixelPerfectScale(Component component, float aspect, float sourceAspect)
		{
			if (_debugMode != null && _debugMode.Value)
			{
				int instanceID = ((Object)component).GetInstanceID();
				if (!PixelViewAspects.TryGetValue(instanceID, out var value) || !(Mathf.Abs(value - aspect) < 0.001f))
				{
					PixelViewAspects[instanceID] = aspect;
					LogDebug($"Resized pixelPerfectView on {((Object)component).name} to aspect {aspect:0.###} (source {sourceAspect:0.###}).");
				}
			}
		}

		private static void LogPixelPerfectSkip(Component component, float sourceAspect)
		{
			if (_debugMode != null && _debugMode.Value)
			{
				int instanceID = ((Object)component).GetInstanceID();
				if (!PixelViewSkipAspects.TryGetValue(instanceID, out var value) || !(Mathf.Abs(value - sourceAspect) < 0.001f))
				{
					PixelViewSkipAspects[instanceID] = sourceAspect;
					LogDebug($"Skipped pixelPerfectView resize on {((Object)component).name} (source aspect {sourceAspect:0.###}).");
				}
			}
		}

		private static void ScaleOverlayBackdrops()
		{
			if (IsUltrawide())
			{
				Camera fallbackCamera = ResolveMenuCamera(null);
				sHUD[] array = Object.FindObjectsByType<sHUD>((FindObjectsInactive)1, (FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					ScaleSpriteToCamera(array[i].backdrop, Camera.main, "sHUD");
				}
				ScreenSystem[] array2 = Object.FindObjectsByType<ScreenSystem>((FindObjectsInactive)1, (FindObjectsSortMode)0);
				for (int i = 0; i < array2.Length; i++)
				{
					ScaleSpriteToCamera(array2[i].backdrop, fallbackCamera, "ScreenSystem");
				}
				MenuScreenTransition[] array3 = Object.FindObjectsByType<MenuScreenTransition>((FindObjectsInactive)1, (FindObjectsSortMode)0);
				for (int i = 0; i < array3.Length; i++)
				{
					ScaleSpriteToCamera(array3[i].backdrop, fallbackCamera, "MenuScreenTransition");
				}
			}
		}

		private static void ScaleOverlaySprites(Component owner, Camera fallbackCamera, string label)
		{
			if ((Object)(object)owner == (Object)null)
			{
				return;
			}
			SpriteRenderer[] componentsInChildren = owner.GetComponentsInChildren<SpriteRenderer>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				return;
			}
			SpriteRenderer[] array = componentsInChildren;
			foreach (SpriteRenderer val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sprite == (Object)null) && IsOverlaySprite(val))
				{
					ScaleSpriteToCamera(val, fallbackCamera, label);
				}
			}
		}

		private static bool IsOverlaySprite(SpriteRenderer spriteRenderer)
		{
			string name = ((Object)((Component)spriteRenderer).gameObject).name;
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			string text = name.ToLowerInvariant();
			if (text.Contains("backdrop") || text.Contains("overlay") || text.Contains("fade") || text.Contains("curtain") || text.Contains("black"))
			{
				return true;
			}
			if (text.Contains("square") || text.Contains("otherbackdrop"))
			{
				return true;
			}
			string text2 = GetHierarchyPath(((Component)spriteRenderer).transform).ToLowerInvariant();
			if (text2.Contains("pausemenuurp"))
			{
				if (!text2.Contains("menudisplay"))
				{
					return text2.Contains("scenetransition");
				}
				return true;
			}
			return false;
		}

		private static Camera ResolveMenuCamera(Camera menuCamera)
		{
			if ((Object)(object)menuCamera != (Object)null)
			{
				return menuCamera;
			}
			Camera[] allCameras = Camera.allCameras;
			foreach (Camera val in allCameras)
			{
				if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, "Camera Persp", StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			return Camera.main;
		}

		private static void ScaleSpriteToCamera(SpriteRenderer spriteRenderer, Camera fallbackCamera, string label)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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)
			if ((Object)(object)spriteRenderer == (Object)null || (Object)(object)spriteRenderer.sprite == (Object)null || !IsUltrawide())
			{
				return;
			}
			Camera val = fallbackCamera;
			if ((Object)(object)val == (Object)null)
			{
				val = Camera.main;
			}
			if (!((Object)(object)val == (Object)null))
			{
				Vector2 cameraWorldSize = GetCameraWorldSize(val, ((Component)spriteRenderer).transform.position);
				Bounds bounds = spriteRenderer.sprite.bounds;
				Vector2 val2 = Vector2.op_Implicit(((Bounds)(ref bounds)).size);
				if (!(val2.x <= 0.01f) && !(val2.y <= 0.01f))
				{
					Vector3 localScale = ((Component)spriteRenderer).transform.localScale;
					localScale.x = cameraWorldSize.x / val2.x;
					localScale.y = cameraWorldSize.y / val2.y;
					((Component)spriteRenderer).transform.localScale = localScale;
					LogOverlayScale(spriteRenderer, cameraWorldSize, val, label);
				}
			}
		}

		private static Vector2 GetCameraWorldSize(Camera cam, Vector3 worldPosition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (cam.orthographic)
			{
				float num = cam.orthographicSize * 2f;
				return new Vector2(num * cam.aspect, num);
			}
			float num2 = Vector3.Dot(worldPosition - ((Component)cam).transform.position, ((Component)cam).transform.forward);
			if (Mathf.Abs(num2) < 0.01f)
			{
				num2 = cam.nearClipPlane + 0.1f;
			}
			float num3 = num2 * Mathf.Tan(cam.fieldOfView * 0.5f * ((float)Math.PI / 180f)) * 2f;
			return new Vector2(num3 * cam.aspect, num3);
		}

		private static void LogOverlayScale(SpriteRenderer spriteRenderer, Vector2 targetSize, Camera cam, string label)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (_debugMode != null && _debugMode.Value)
			{
				int instanceID = ((Object)spriteRenderer).GetInstanceID();
				if (!OverlayTargetSizes.TryGetValue(instanceID, out var value) || !Approximately(value, targetSize))
				{
					OverlayTargetSizes[instanceID] = targetSize;
					LogDebug($"Resized {label} overlay to {targetSize.x:0.###}x{targetSize.y:0.###} using {((Object)cam).name}.");
				}
			}
		}

		private void Awake()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Expected O, but got Unknown
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Expected O, but got Unknown
			//IL_0283: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			ConfigUtil.CopyLegacyConfigIfNeeded("shibe.easydeliveryco.ultrawide", "shibe.easydeliveryco.sebultrawide");
			_aspectRatio = ((BaseUnityPlugin)this).Config.Bind<string>("General", "aspect_ratio", "auto", "Aspect ratio override.\n\nauto    - Automatically uses the current window aspect ratio (recommended).\ndefault - Use the game's original behavior (disables ultrawide fixes).\nw:h     - Manual ratio such as 21:9 or 32:9.\nnumber  - Decimal ratio such as 2.39 or 1.78.\n\nExamples:\n21:9\n32:9\n2.39");
			_debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "debug_logging", false, "Log debug information about applied adjustments.");
			Harmony val = new Harmony("shibe.easydeliveryco.sebultrawide");
			Patch(val, typeof(RaceManager), "StartRace", null, "ApplyAllCameras_Postfix");
			Patch(val, typeof(PauseSystem), "Start", null, "PauseSystem_Start_Postfix");
			Patch(val, typeof(PauseSystem), "SetResolution", null, "PresentationResized_Postfix");
			Patch(val, typeof(PauseSystem), "SetFullscreen", null, "PresentationResized_Postfix");
			Patch(val, typeof(sOptionsMenu), "FrameUpdate", null, "PresentationChange_Postfix");
			Patch(val, typeof(sEasyRally), "Update", null, "PresentationChange_Postfix");
			Patch(val, typeof(sFreeCam), "Start", null, "ApplyAllCameras_Postfix");
			Patch(val, typeof(sFreeCam), "ToggleFreeCam", null, "ApplyAllCameras_Postfix");
			Patch(val, typeof(IntroDotExe), "Setup", null, "IntroDotExe_Setup_Postfix");
			Patch(val, typeof(ChooseExe), "Setup", null, "ChooseExe_Setup_Postfix");
			Patch(val, typeof(CamDotExe), "Start", null, "CamDotExe_Start_Postfix");
			Patch(val, typeof(MiniRenderer), "Start", null, "MiniRenderer_Start_Postfix");
			Patch(val, typeof(pixelPerfectView), "AdjustViewPlane", "PixelPerfectView_AdjustViewPlane_Prefix");
			Patch(val, typeof(sHUD), "Init", null, "SHud_Init_Postfix");
			Patch(val, typeof(sHUD), "FadeToBlack", "SHud_Backdrop_Prefix");
			Patch(val, typeof(sHUD), "DipToBlack", "SHud_Backdrop_Prefix");
			Patch(val, typeof(ScreenSystem), "Init", null, "ScreenSystem_Postfix");
			Patch(val, typeof(ScreenSystem), "DoTransition", null, "ScreenSystem_Postfix");
			Patch(val, typeof(SceneTransition), "Start", null, "SceneTransition_Start_Postfix");
			Patch(val, typeof(sTeleporter), "Teleport", null, "STeleporter_Teleport_Postfix");
			ModGraphics.OutputAspect = GetPixelationOutputAspect;
			ModGraphics.FreeCamCamera = ApplyAspect;
			ModGraphics.Enable();
		}

		private static void Patch(Harmony harmony, Type type, string methodName, string prefix = null, string postfix = null)
		{
			HarmonyUtil.PatchByName(harmony, typeof(Plugin), type.FullName, methodName, prefix, postfix, (Action<string>)delegate(string m)
			{
				_log.LogWarning((object)m);
			});
		}

		private static void ApplyAllCameras_Postfix()
		{
			ApplyAllCameras();
		}

		private static void PauseSystem_Start_Postfix(PauseSystem __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				ApplyCameraAspect(__instance.mainCamera);
			}
			ApplyAllCameras();
			ScaleOverlayBackdrops();
		}

		private static void PresentationResized_Postfix()
		{
			ApplyAllCameras();
			ScaleOverlayBackdrops();
		}

		private static void PresentationChange_Postfix()
		{
			RefreshPresentationIfChanged();
		}

		private static void SHud_Init_Postfix(sHUD __instance, MiniRenderer R)
		{
			UpdateHudRendererAspect(R);
			ScaleSpriteToCamera(((Object)(object)__instance != (Object)null) ? __instance.backdrop : null, Camera.main, "sHUD");
		}

		private static void SHud_Backdrop_Prefix(sHUD __instance)
		{
			ScaleSpriteToCamera(((Object)(object)__instance != (Object)null) ? __instance.backdrop : null, Camera.main, "sHUD");
		}

		private static void ScreenSystem_Postfix(ScreenSystem __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				Camera fallbackCamera = ResolveMenuCamera(__instance.menuCamera);
				ScaleSpriteToCamera(__instance.backdrop, fallbackCamera, "ScreenSystem");
				ScaleOverlaySprites((Component)(object)__instance, fallbackCamera, "ScreenSystem");
			}
		}

		private static void IntroDotExe_Setup_Postfix(IntroDotExe __instance)
		{
			ApplyMenuCameraAspect(((Object)(object)__instance != (Object)null) ? __instance.menuCamera : null);
		}

		private static void ChooseExe_Setup_Postfix(ChooseExe __instance)
		{
			ApplyMenuCameraAspect(((Object)(object)__instance != (Object)null) ? __instance.menuCamera : null);
		}

		private static void CamDotExe_Start_Postfix(sFreeCam ___freecam)
		{
			Camera val = (((Object)(object)___freecam != (Object)null) ? ___freecam.cam : null);
			if ((Object)(object)val == (Object)null)
			{
				LogDebug("CamDotExe freecam camera not found for aspect fix.");
				return;
			}
			ApplyAspect(val);
			LogDebug($"Applied CamDotExe freecam aspect fix to {((Object)val).name} ({((Object)val).GetInstanceID()}).");
		}

		private static void SceneTransition_Start_Postfix(SceneTransition __instance, SpriteRenderer ___sr)
		{
			ScaleSpriteToCamera(___sr, Camera.main, "SceneTransition");
			ScaleOverlaySprites((Component)(object)__instance, Camera.main, "SceneTransition");
		}

		private static void STeleporter_Teleport_Postfix()
		{
			sHUD val = Object.FindFirstObjectByType<sHUD>();
			ScaleSpriteToCamera(((Object)(object)val != (Object)null) ? val.backdrop : null, Camera.main, "sHUD");
		}

		private static string GetHierarchyPath(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "(null)";
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static bool Approximately(Vector2 a, Vector2 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Abs(a.x - b.x) < 0.001f)
			{
				return Mathf.Abs(a.y - b.y) < 0.001f;
			}
			return false;
		}
	}
	public class UltrawideMenuWindow : CartridgeWindowBase
	{
		public const string FileName = "wide";

		public const string ListenerName = "UltrawideMenu";

		public const string ListenerData = "listener_UltrawideMenu";

		protected override void DrawWindow(Rect p)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			float num = ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f - 16f;
			float num2 = ((Rect)(ref p)).y + 10f;
			float num3 = 12f;
			float num4 = 4f;
			float num5 = ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f;
			float num6 = ((Rect)(ref p)).y + ((Rect)(ref p)).height - 18f - 12f;
			if (base.Util.SimpleButtonRaw("Reset Defaults", num5, num6))
			{
				ModGraphics.ResetDefaults();
				base.MouseYLock = 0f;
			}
			if ((int)base.Util.NavigationFooter(p, false, 40f) == 2)
			{
				((CartridgeWindowBase)this).BackButtonPressed();
				return;
			}
			base.Util.Label("Graphics", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num2);
			num2 += num3 + num4;
			base.Util.Label("FOV", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num2);
			num2 += num3;
			GetFovRange(out var min, out var max);
			float currentCameraFov = GetCurrentCameraFov();
			float num7 = Mathf.Clamp(ModGraphics.GetSavedFovOrDefault(false, currentCameraFov), min, max);
			float? num8 = base.Util.SliderRow("3rd Person", num7, min, max, $"{num7:0}", num, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num2, ref base.MouseYLock);
			if (num8.HasValue)
			{
				float value = num8.Value;
				ModGraphics.SaveFovOverride(false, value);
			}
			num2 += num3;
			float num9 = Mathf.Clamp(ModGraphics.GetSavedFovOrDefault(true, 90f), min, max);
			float? num10 = base.Util.SliderRow("1st Person", num9, min, max, $"{num9:0}", num, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num2, ref base.MouseYLock);
			if (num10.HasValue)
			{
				float value2 = num10.Value;
				ModGraphics.SaveFovOverride(true, value2);
			}
			num2 += num3 + num4;
			base.Util.Label("Renderer", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num2);
			num2 += num3;
			int pixelationMode = ModGraphics.GetPixelationMode();
			int? num11 = base.Util.ChoiceSliderRow("Pixelation", pixelationMode, 4, pixelationMode switch
			{
				0 => "None", 
				1 => "Finer", 
				2 => "Fine", 
				3 => "Default", 
				4 => "Large", 
				_ => "Default", 
			}, num, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num2, ref base.MouseYLock);
			if (num11.HasValue)
			{
				int value3 = num11.Value;
				if (value3 != pixelationMode)
				{
					ModGraphics.SavePixelationMode(value3);
				}
			}
			num2 += num3;
			int viewDistanceMode = ModGraphics.GetViewDistanceMode();
			int? num12 = base.Util.ChoiceSliderRow("View Distance", viewDistanceMode, 3, viewDistanceMode switch
			{
				0 => "Near", 
				1 => "Default", 
				2 => "Far", 
				3 => "Max", 
				_ => "Default", 
			}, num, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num2, ref base.MouseYLock);
			if (num12.HasValue)
			{
				int value4 = num12.Value;
				if (value4 != viewDistanceMode)
				{
					ModGraphics.SaveViewDistanceMode(value4);
				}
			}
			num2 += num3;
			bool? flag = base.Util.Toggle("VSync", ModGraphics.GetVsyncMode() == 1, num, num2);
			if (flag.HasValue)
			{
				ModGraphics.SetVsyncMode(flag.Value ? 1 : 0);
			}
			num2 += num3 + num4;
		}

		private static float GetCurrentCameraFov()
		{
			PauseSystem pauseSystem = PauseSystem.pauseSystem;
			if ((Object)(object)pauseSystem != (Object)null && (Object)(object)pauseSystem.mainCamera != (Object)null)
			{
				return pauseSystem.mainCamera.fieldOfView;
			}
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				return main.fieldOfView;
			}
			return 70f;
		}

		private static void GetFovRange(out float min, out float max)
		{
			min = 50f;
			max = 110f;
		}
	}
}