using System;
using System.Collections;
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 UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("EasyDeliveryCoUltrawide")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EasyDeliveryCoUltrawide")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6D22F575-14EC-4621-BF89-59122F2F3F98")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 EasyDeliveryCoUltrawide
{
[BepInPlugin("shibe.easydeliveryco.ultrawide", "Ultrawide Mod", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
private struct PixelPerfectFields
{
public FieldInfo GameCamera;
public FieldInfo MenuWidth;
public FieldInfo MenuHeight;
}
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 struct MiniRendererFields
{
public FieldInfo Width;
public FieldInfo Height;
}
private struct SHudWorldToHudPointFields
{
public FieldInfo Navigation;
public FieldInfo R;
}
private struct HudNavigationFields
{
public FieldInfo Car;
}
private struct HudCarFields
{
public FieldInfo CarCamera;
}
private struct MiniRendererSizeFields
{
public FieldInfo Width;
public FieldInfo Height;
}
private const string PrefKeyFovLegacy = "UltrawideFovOverride";
internal const string PrefKeyFovThirdPerson = "UltrawideFovOverride_ThirdPerson";
internal const string PrefKeyFovFirstPerson = "UltrawideFovOverride_FirstPerson";
internal const string PrefKeyFogMultiplier = "UltrawideFogMultiplier";
internal const string PrefKeyPixelationMode = "UltrawidePixelationMode";
private const string PrefKeyPixelationModeVersion = "UltrawidePixelationModeVersion";
internal const string PrefKeyViewDistanceMode = "UltrawideViewDistanceMode";
private const string PrefKeyViewDistanceModeVersion = "UltrawideViewDistanceModeVersion";
private const float DefaultAspect = 1.7777778f;
private static ConfigEntry<bool> _enableMod;
private static ConfigEntry<bool> _debugMode;
private static ConfigEntry<bool> _perfLogging;
private static ConfigEntry<float> _perfLogIntervalSeconds;
private static ConfigEntry<string> _aspectRatio;
private static ConfigEntry<bool> _desktopMenuIconVisible;
private static ConfigEntry<string> _desktopMenuIconX;
private static ConfigEntry<string> _desktopMenuIconY;
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<Type, PixelPerfectFields> PixelPerfectFieldCache = new Dictionary<Type, PixelPerfectFields>();
private static readonly Dictionary<int, PixelPerfectState> PixelPerfectStates = new Dictionary<int, PixelPerfectState>();
private static readonly Dictionary<string, int> PerfCounts = new Dictionary<string, int>(StringComparer.Ordinal);
private static readonly Dictionary<Type, MiniRendererFields> MiniRendererFieldCache = new Dictionary<Type, MiniRendererFields>();
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 float _perfLastLogTime;
private static int _pixelationMode = -1;
private static int _viewDistanceMode = -1;
private static float _fogMultiplier = -1f;
private static bool _insideLookupInit;
private static Type _ambianceType;
private static FieldInfo _ambiancePlayerInsideField;
private static Object _ambianceInstance;
public const string PluginGuid = "shibe.easydeliveryco.ultrawide";
public const string PluginName = "Ultrawide Mod";
public const string PluginVersion = "1.2.0";
private static readonly Dictionary<int, Transform> HudDisplayTransforms = new Dictionary<int, Transform>();
private static readonly Dictionary<int, int> HudMiniRendererOriginalWidths = new Dictionary<int, int>();
private static readonly Dictionary<Type, SHudWorldToHudPointFields> SHudWorldToHudPointFieldCache = new Dictionary<Type, SHudWorldToHudPointFields>();
private static readonly Dictionary<Type, HudNavigationFields> HudNavigationFieldCache = new Dictionary<Type, HudNavigationFields>();
private static readonly Dictionary<Type, HudCarFields> HudCarFieldCache = new Dictionary<Type, HudCarFields>();
private static readonly Dictionary<Type, MiniRendererSizeFields> MiniRendererSizeFieldCache = new Dictionary<Type, MiniRendererSizeFields>();
private static readonly Dictionary<int, Transform> OverlayTransforms = new Dictionary<int, Transform>();
private static readonly Dictionary<int, Vector3> OverlayOriginalScales = new Dictionary<int, Vector3>();
private static Camera _pixelMainCamera;
private static MeshRenderer _pixelScreenRenderer;
private static RenderTexture _pixelDefaultRt;
private static RenderTexture _pixelCustomRt;
private static Camera _pixelRearCamera;
private static MeshRenderer _pixelRearRenderer;
private static RenderTexture _pixelDefaultRearRt;
private static RenderTexture _pixelCustomRearRt;
private static int _pixelLastMode = -1;
private static int _pixelLastW;
private static int _pixelLastH;
private static int _pixelLastRearW;
private static int _pixelLastRearH;
private static bool _viewDistanceBaseCaptured;
private static float _baseShadowDistance;
private static float _baseLodBias;
private static int _baseMaximumLodLevel;
private static bool ShouldApply()
{
if (_enableMod != null)
{
return _enableMod.Value;
}
return false;
}
private static bool ShouldApplyHudFix()
{
if (ShouldApply())
{
return IsUltrawide();
}
return false;
}
private static bool IsVanillaPresentation()
{
string text = ((_aspectRatio != null) ? _aspectRatio.Value : "auto");
string text2 = (string.IsNullOrWhiteSpace(text) ? "" : text.Trim().ToLowerInvariant());
if (!(text2 == "default") && !(text2 == "native"))
{
return text2 == "vanilla";
}
return true;
}
internal static bool GetEnableMod()
{
if (_enableMod != null)
{
return _enableMod.Value;
}
return false;
}
internal static void SetEnableMod(bool value)
{
if (_enableMod != null)
{
_enableMod.Value = value;
}
}
internal static bool GetDebugMode()
{
if (_debugMode != null)
{
return _debugMode.Value;
}
return false;
}
internal static void SetDebugMode(bool value)
{
if (_debugMode != null)
{
_debugMode.Value = value;
}
}
internal static void ApplySavedMenuSettings()
{
if (ShouldApply())
{
if (TryGetSavedFov(IsFirstPersonViewActive(), out var fov))
{
ApplyFovOverride(fov);
}
GetPixelationMode();
RefreshPixelation();
GetViewDistanceMode();
RefreshViewDistance();
GetFogMultiplier();
}
}
internal static float GetFogMultiplier()
{
if (_fogMultiplier >= 0f)
{
return _fogMultiplier;
}
_fogMultiplier = Mathf.Clamp(PlayerPrefs.GetFloat("UltrawideFogMultiplier", 1f), 0.1f, 5f);
return _fogMultiplier;
}
internal static void SaveFogMultiplier(float multiplier)
{
multiplier = Mathf.Clamp(multiplier, 0.1f, 5f);
_fogMultiplier = multiplier;
PlayerPrefs.SetFloat("UltrawideFogMultiplier", multiplier);
}
internal static int GetViewDistanceMode()
{
if (_viewDistanceMode >= 0)
{
return _viewDistanceMode;
}
int num = PlayerPrefs.GetInt("UltrawideViewDistanceMode", 1);
if (PlayerPrefs.GetInt("UltrawideViewDistanceModeVersion", 1) < 2 && PlayerPrefs.HasKey("UltrawideViewDistanceMode"))
{
num = num switch
{
1 => 0,
3 => 2,
4 => 3,
_ => 1,
};
PlayerPrefs.SetInt("UltrawideViewDistanceModeVersion", 2);
PlayerPrefs.SetInt("UltrawideViewDistanceMode", num);
}
_viewDistanceMode = Mathf.Clamp(num, 0, 3);
return _viewDistanceMode;
}
internal static void SaveViewDistanceMode(int mode)
{
mode = Mathf.Clamp(mode, 0, 3);
_viewDistanceMode = mode;
PlayerPrefs.SetInt("UltrawideViewDistanceModeVersion", 2);
PlayerPrefs.SetInt("UltrawideViewDistanceMode", mode);
RefreshViewDistance();
}
internal static int GetPixelationMode()
{
if (_pixelationMode >= 0)
{
return _pixelationMode;
}
int num = PlayerPrefs.GetInt("UltrawidePixelationMode", 3);
if (PlayerPrefs.GetInt("UltrawidePixelationModeVersion", 1) < 2 && PlayerPrefs.HasKey("UltrawidePixelationMode"))
{
int num2 = num;
switch (num)
{
case 0:
num2 = 0;
break;
case 1:
num2 = 2;
break;
case 2:
num2 = 3;
break;
case 3:
num2 = 4;
break;
}
num = num2;
PlayerPrefs.SetInt("UltrawidePixelationModeVersion", 2);
PlayerPrefs.SetInt("UltrawidePixelationMode", num);
}
_pixelationMode = Mathf.Clamp(num, 0, 4);
return _pixelationMode;
}
internal static void SavePixelationMode(int mode)
{
mode = Mathf.Clamp(mode, 0, 4);
_pixelationMode = mode;
PlayerPrefs.SetInt("UltrawidePixelationModeVersion", 2);
PlayerPrefs.SetInt("UltrawidePixelationMode", mode);
RefreshPixelation();
}
internal static int GetPixelationDivisor()
{
return GetPixelationMode() switch
{
0 => 1,
1 => 2,
2 => 3,
3 => 4,
4 => 5,
_ => 3,
};
}
internal static bool TryGetSavedFov(bool firstPerson, out float fov)
{
string text = (firstPerson ? "UltrawideFovOverride_FirstPerson" : "UltrawideFovOverride_ThirdPerson");
fov = PlayerPrefs.GetFloat(text, -1f);
if (fov >= 1f)
{
return true;
}
if (!firstPerson)
{
fov = PlayerPrefs.GetFloat("UltrawideFovOverride", -1f);
if (fov >= 1f)
{
return true;
}
}
fov = 0f;
return false;
}
internal static float GetSavedFovOrDefault(bool firstPerson, float fallback)
{
if (!TryGetSavedFov(firstPerson, out var fov))
{
return fallback;
}
return fov;
}
internal static void SaveFovOverride(bool firstPerson, float fov)
{
PlayerPrefs.SetFloat(firstPerson ? "UltrawideFovOverride_FirstPerson" : "UltrawideFovOverride_ThirdPerson", fov);
if (IsFirstPersonViewActive() == firstPerson)
{
ApplyFovOverride(fov);
}
}
internal static bool IsFirstPersonViewActive()
{
sCameraController val = Object.FindFirstObjectByType<sCameraController>();
if ((Object)(object)val != (Object)null && val.firstPerson)
{
return !val.fixedPerspective;
}
return false;
}
internal static void ApplyFovOverride(float fov)
{
if (IsPlayerInsideBuilding())
{
return;
}
PauseSystem pauseSystem = PauseSystem.pauseSystem;
if ((Object)(object)pauseSystem != (Object)null && (Object)(object)pauseSystem.mainCamera != (Object)null)
{
PauseSystem.FOV = fov;
pauseSystem.mainCamera.fieldOfView = fov;
return;
}
PauseSystem.FOV = fov;
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
main.fieldOfView = fov;
}
}
private static bool IsPlayerInsideBuilding()
{
try
{
if (!_insideLookupInit)
{
_insideLookupInit = true;
_ambianceType = AccessTools.TypeByName("sAmbiance");
_ambiancePlayerInsideField = ((_ambianceType != null) ? AccessTools.Field(_ambianceType, "playerInside") : null);
}
if (_ambianceType == null || _ambiancePlayerInsideField == null)
{
return false;
}
if (_ambianceInstance == (Object)null)
{
_ambianceInstance = Object.FindFirstObjectByType(_ambianceType);
}
if (_ambianceInstance == (Object)null)
{
return false;
}
object? value = _ambiancePlayerInsideField.GetValue(_ambianceInstance);
GameObject val = (GameObject)((value is GameObject) ? value : null);
return (Object)(object)val != (Object)null && val.activeSelf;
}
catch
{
return false;
}
}
private static float GetTargetAspect()
{
string text = ((_aspectRatio != null) ? _aspectRatio.Value : "auto");
string text2 = (string.IsNullOrWhiteSpace(text) ? "" : text.Trim().ToLowerInvariant());
if (text2 == "auto" || text2 == "match")
{
return Mathf.Round(GetWindowAspect() * 100f) / 100f;
}
if (!TryParseAspect(text, out var aspect, out var useWindow))
{
return GetDisplayAspect();
}
if (useWindow)
{
return GetWindowAspect();
}
if (aspect <= 0.1f)
{
return GetDisplayAspect();
}
return aspect;
}
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 TryParseAspect(string value, out float aspect, out bool useWindow)
{
aspect = 0f;
useWindow = false;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
string text = value.Trim().ToLowerInvariant();
switch (text)
{
case "display":
case "auto":
case "match":
return true;
case "default":
case "native":
case "vanilla":
aspect = 1.7777778f;
return true;
case "window":
useWindow = true;
return true;
default:
{
if (text.Contains(":"))
{
string[] array = text.Split(new char[1] { ':' });
if (array.Length == 2 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && result2 > 0.01f)
{
aspect = result / result2;
return true;
}
}
if (float.TryParse(text, out var result3) && result3 > 0.1f)
{
aspect = result3;
return true;
}
return false;
}
}
}
private static bool IsUltrawide()
{
if (IsVanillaPresentation())
{
return false;
}
return GetWindowAspect() > 1.7877778f;
}
private static Rect BuildFullRect()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
return new Rect(0f, 0f, 1f, 1f);
}
private static bool ShouldForceViewport(Camera camera, Rect rect)
{
if (!ShouldApply() || !IsUltrawide())
{
return false;
}
if (GetTargetAspect() <= 1.7877778f)
{
return false;
}
if ((Object)(object)camera == (Object)null)
{
return false;
}
if (!IsPrimaryGameplayCamera(camera))
{
return false;
}
if (((Rect)(ref rect)).width >= 0.99f && ((Rect)(ref rect)).height >= 0.99f)
{
return false;
}
bool num = ((Rect)(ref rect)).width >= 0.98f && ((Rect)(ref rect)).height < 0.98f && ((Rect)(ref rect)).x <= 0.01f;
bool flag = ((Rect)(ref rect)).height >= 0.98f && ((Rect)(ref rect)).width < 0.98f && ((Rect)(ref rect)).y <= 0.01f;
return num || flag;
}
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;
}
if (string.Equals(((Object)camera).name, "Camera", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (string.Equals(((Object)camera).name, "RearViewCam", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return (Object)(object)camera == (Object)(object)Camera.main;
}
private static void ApplyCameraViewport(Camera camera)
{
//IL_001c: 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)
if (!((Object)(object)camera == (Object)null) && ShouldApply() && IsUltrawide() && ShouldForceViewport(camera, camera.rect))
{
camera.rect = BuildFullRect();
LogDebug($"Resized viewport to full screen for {((Object)camera).name} ({((Object)camera).GetInstanceID()}).");
}
}
private static void ApplyCameraAspect(Camera camera)
{
if (!((Object)(object)camera == (Object)null) && ShouldApply() && IsUltrawide() && IsPrimaryGameplayCamera(camera))
{
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(Camera camera)
{
if (!((Object)(object)camera == (Object)null) && ShouldApply() && IsUltrawide())
{
float targetAspect = GetTargetAspect();
if (!(targetAspect <= 0.01f) && !(Mathf.Abs(camera.aspect - targetAspect) < 0.0001f))
{
camera.aspect = targetAspect;
LogDebug($"Forced menu aspect for {((Object)camera).name} ({((Object)camera).GetInstanceID()}) to {targetAspect:0.###}.");
}
}
}
private static void ApplyMenuCameraAspect(GameObject menuCameraObject)
{
if (!((Object)(object)menuCameraObject == (Object)null))
{
ApplyMenuCameraAspect(menuCameraObject.GetComponentInChildren<Camera>(true));
}
}
private static void ApplyAllCameras()
{
if (ShouldApply() && IsUltrawide())
{
Camera[] allCameras = Camera.allCameras;
foreach (Camera camera in allCameras)
{
ApplyCameraAspect(camera);
ApplyCameraViewport(camera);
}
}
}
private static void LogDebug(string message)
{
if (_debugMode != null && _debugMode.Value)
{
_log.LogInfo((object)message);
}
}
private static void PerfCount(string key)
{
if (_perfLogging == null || !_perfLogging.Value || string.IsNullOrEmpty(key))
{
return;
}
if (PerfCounts.TryGetValue(key, out var value))
{
PerfCounts[key] = value + 1;
}
else
{
PerfCounts[key] = 1;
}
float realtimeSinceStartup = Time.realtimeSinceStartup;
if (_perfLastLogTime <= 0f)
{
_perfLastLogTime = realtimeSinceStartup;
return;
}
float num = 2f;
if (_perfLogIntervalSeconds != null)
{
num = Mathf.Max(0.25f, _perfLogIntervalSeconds.Value);
}
if (realtimeSinceStartup - _perfLastLogTime < num)
{
return;
}
float num2 = Mathf.Max(0.0001f, realtimeSinceStartup - _perfLastLogTime);
foreach (KeyValuePair<string, int> perfCount in PerfCounts)
{
_log.LogInfo((object)$"Perf [{perfCount.Key}] calls in {num2:0.##}s: {perfCount.Value}.");
}
PerfCounts.Clear();
_perfLastLogTime = realtimeSinceStartup;
}
private static float ParseDesktopIconFloat(string value, float fallback, string label)
{
if (string.IsNullOrWhiteSpace(value))
{
return fallback;
}
string s = value.Trim();
if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
return result;
}
if (float.TryParse(s, out result))
{
return result;
}
LogDebug($"Failed to parse {label}='{value}', using {fallback:0.###}.");
return fallback;
}
private static void DesktopDotExe_Setup_Postfix(object __instance)
{
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Expected O, but got Unknown
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
if (__instance == null)
{
return;
}
DesktopDotExe val = (DesktopDotExe)((__instance is DesktopDotExe) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
return;
}
bool visible = _desktopMenuIconVisible == null || _desktopMenuIconVisible.Value;
float num = ParseDesktopIconFloat((_desktopMenuIconX != null) ? _desktopMenuIconX.Value : null, 5.5f, "ultrawide_menu_icon_x");
float num2 = ParseDesktopIconFloat((_desktopMenuIconY != null) ? _desktopMenuIconY.Value : null, 3.25f, "ultrawide_menu_icon_y");
Vector2 position = default(Vector2);
((Vector2)(ref position))..ctor(num, num2);
File val2 = null;
foreach (File file in val.files)
{
if (file != null && string.Equals(file.name, "wide", StringComparison.OrdinalIgnoreCase))
{
val2 = file;
break;
}
}
if (val2 == null)
{
File item = new File(((ScreenProgram)val).R, val)
{
name = "wide",
type = (FileType)1,
data = "listener_UltrawideMenu",
icon = 7,
iconHover = 7,
position = position,
visible = visible,
cantFolder = false
};
val.files.Add(item);
}
else
{
val2.icon = 7;
val2.iconHover = 7;
val2.position = position;
val2.visible = visible;
}
Transform transform = ((Component)val).transform;
if ((Object)(object)transform.Find("UltrawideMenu") == (Object)null)
{
GameObject val3 = new GameObject("UltrawideMenu");
val3.transform.SetParent(transform, false);
val3.AddComponent<UltrawideMenuWindow>();
}
}
private static float GetFogMultiplierClamped()
{
if (!ShouldApply())
{
return 1f;
}
return Mathf.Clamp(GetFogMultiplier(), 0.1f, 5f);
}
private static void SWeatherSystem_UpdateWeather_Postfix()
{
if (ShouldApply())
{
float fogMultiplierClamped = GetFogMultiplierClamped();
if (!(Mathf.Abs(fogMultiplierClamped - 1f) < 0.0001f))
{
RenderSettings.fogDensity = Mathf.Max(1E-06f, RenderSettings.fogDensity * fogMultiplierClamped);
}
}
}
private static void FogVolume_LateUpdate_Postfix(object __instance)
{
if (!ShouldApply() || __instance == null)
{
return;
}
float fogMultiplierClamped = GetFogMultiplierClamped();
if (Mathf.Abs(fogMultiplierClamped - 1f) < 0.0001f)
{
return;
}
try
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "p");
if (!(fieldInfo == null) && !(Mathf.Abs(Convert.ToSingle(fieldInfo.GetValue(__instance)) - 1f) < 0.0001f))
{
RenderSettings.fogDensity = Mathf.Max(1E-06f, RenderSettings.fogDensity * fogMultiplierClamped);
}
}
catch
{
}
}
internal static void RefreshHudDisplayScale()
{
if (!ShouldApplyHudFix())
{
return;
}
Type type = AccessTools.TypeByName("sHUD");
if (type == null)
{
return;
}
Object obj = Object.FindFirstObjectByType(type);
Component val = (Component)(object)((obj is Component) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
MonoBehaviour val2 = FindMiniRenderer(val);
if (!((Object)(object)val2 == (Object)null))
{
EnsureMiniRendererRenderTexture(val2);
ApplyHudDisplayScale(val2);
}
}
}
private static bool PixelPerfectView_AdjustViewPlane_Prefix(object __instance)
{
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
PerfCount("pixelPerfectView.AdjustViewPlane");
if (!ShouldApply() || IsVanillaPresentation())
{
return true;
}
if (__instance == null)
{
return true;
}
Component val = (Component)((__instance is Component) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
return true;
}
Type type = __instance.GetType();
if (!PixelPerfectFieldCache.TryGetValue(type, out var value))
{
PixelPerfectFields pixelPerfectFields = default(PixelPerfectFields);
pixelPerfectFields.GameCamera = AccessTools.Field(type, "gameCamera");
pixelPerfectFields.MenuWidth = AccessTools.Field(type, "menuWidth");
pixelPerfectFields.MenuHeight = AccessTools.Field(type, "menuHeight");
value = pixelPerfectFields;
PixelPerfectFieldCache[type] = value;
}
if (value.GameCamera == null || value.MenuWidth == null || value.MenuHeight == null)
{
return true;
}
object? value2 = value.GameCamera.GetValue(__instance);
Camera val2 = (Camera)((value2 is Camera) ? value2 : null);
if ((Object)(object)val2 == (Object)null)
{
return true;
}
float num = (float)value.MenuWidth.GetValue(__instance);
float num2 = (float)value.MenuHeight.GetValue(__instance);
if (num <= 0.01f || num2 <= 0.01f)
{
return true;
}
float num3 = num / num2;
if (!(num3 > 1.65f) || !(num3 < 1.9f))
{
LogPixelPerfectSkip(val, num3);
return true;
}
float num4 = 2f * val.transform.localPosition.z * Mathf.Tan(val2.fieldOfView * 0.5f * ((float)Math.PI / 180f));
float windowAspect = GetWindowAspect();
int instanceID = ((Object)val).GetInstanceID();
PixelPerfectState pixelPerfectState = default(PixelPerfectState);
pixelPerfectState.Width = Screen.width;
pixelPerfectState.Height = Screen.height;
pixelPerfectState.Aspect = windowAspect;
pixelPerfectState.Fov = val2.fieldOfView;
pixelPerfectState.Z = val.transform.localPosition.z;
PixelPerfectState pixelPerfectState2 = pixelPerfectState;
if (!PixelPerfectStates.TryGetValue(instanceID, out var value3) || !value3.Equals(pixelPerfectState2))
{
PixelPerfectStates[instanceID] = pixelPerfectState2;
val.transform.localScale = new Vector3(num4 * windowAspect, num4, 1f);
}
LogPixelPerfectScale(val, windowAspect, num3);
return false;
}
private static bool SHud_WorldToHUDPoint_Prefix(object __instance, Vector3 worldPoint, ref Vector2 __result)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: 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_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
if (!ShouldApply() || __instance == null)
{
return true;
}
try
{
if (!TryGetHudCarCamera(__instance, out var cam) || (Object)(object)cam == (Object)null)
{
return true;
}
Transform transform = ((Component)cam).transform;
if ((Object)(object)transform == (Object)null)
{
return true;
}
if (Vector3.Dot(transform.forward, worldPoint - transform.position) < 0f)
{
__result = new Vector2(-100f, -100f);
return false;
}
Vector3 val = cam.WorldToScreenPoint(worldPoint);
val.z = 0f;
float cameraPixelWidth = GetCameraPixelWidth(cam);
float cameraPixelHeight = GetCameraPixelHeight(cam);
if (cameraPixelWidth <= 0.01f || cameraPixelHeight <= 0.01f)
{
return true;
}
float num = cameraPixelWidth;
float num2 = cameraPixelHeight;
if ((Object)(object)_pixelDefaultRt != (Object)null && ((Texture)_pixelDefaultRt).width > 0 && ((Texture)_pixelDefaultRt).height > 0)
{
num = ((Texture)_pixelDefaultRt).width;
num2 = ((Texture)_pixelDefaultRt).height;
}
else
{
num = 456f;
num2 = 256f;
}
if (Mathf.Abs(cameraPixelWidth - num) < 0.5f && Mathf.Abs(cameraPixelHeight - num2) < 0.5f)
{
return true;
}
float num3 = val.x * (num / cameraPixelWidth);
float num4 = val.y * (num2 / cameraPixelHeight);
num4 = num2 - num4;
float num5 = num3 - num * 0.5f;
num4 -= num2 * 0.5f;
if (!TryGetHudMiniRendererSize(__instance, out var width, out var height))
{
width = cameraPixelWidth;
height = cameraPixelHeight;
}
float num6 = num5 + width * 0.5f;
float num7 = num4 + height * 0.5f;
__result = new Vector2(Mathf.Round(num6), Mathf.Round(num7));
return false;
}
catch
{
return true;
}
}
private static bool TryGetHudCarCamera(object hudInstance, out Camera cam)
{
cam = null;
if (hudInstance == null)
{
return false;
}
Type type = hudInstance.GetType();
if (!SHudWorldToHudPointFieldCache.TryGetValue(type, out var value))
{
SHudWorldToHudPointFields sHudWorldToHudPointFields = default(SHudWorldToHudPointFields);
sHudWorldToHudPointFields.Navigation = AccessTools.Field(type, "navigation");
sHudWorldToHudPointFields.R = AccessTools.Field(type, "R");
value = sHudWorldToHudPointFields;
SHudWorldToHudPointFieldCache[type] = value;
}
if (value.Navigation == null)
{
return false;
}
object value2 = value.Navigation.GetValue(hudInstance);
if (value2 == null)
{
return false;
}
Type type2 = value2.GetType();
if (!HudNavigationFieldCache.TryGetValue(type2, out var value3))
{
HudNavigationFields hudNavigationFields = default(HudNavigationFields);
hudNavigationFields.Car = AccessTools.Field(type2, "car");
value3 = hudNavigationFields;
HudNavigationFieldCache[type2] = value3;
}
if (value3.Car == null)
{
return false;
}
object value4 = value3.Car.GetValue(value2);
if (value4 == null)
{
return false;
}
Type type3 = value4.GetType();
if (!HudCarFieldCache.TryGetValue(type3, out var value5))
{
HudCarFields hudCarFields = default(HudCarFields);
hudCarFields.CarCamera = AccessTools.Field(type3, "carCamera");
value5 = hudCarFields;
HudCarFieldCache[type3] = value5;
}
if (value5.CarCamera == null)
{
return false;
}
object? value6 = value5.CarCamera.GetValue(value4);
cam = (Camera)((value6 is Camera) ? value6 : null);
return (Object)(object)cam != (Object)null;
}
private static bool TryGetHudMiniRendererSize(object hudInstance, out float width, out float height)
{
width = 0f;
height = 0f;
if (hudInstance == null)
{
return false;
}
Type type = hudInstance.GetType();
if (!SHudWorldToHudPointFieldCache.TryGetValue(type, out var value))
{
SHudWorldToHudPointFields sHudWorldToHudPointFields = default(SHudWorldToHudPointFields);
sHudWorldToHudPointFields.Navigation = AccessTools.Field(type, "navigation");
sHudWorldToHudPointFields.R = AccessTools.Field(type, "R");
value = sHudWorldToHudPointFields;
SHudWorldToHudPointFieldCache[type] = value;
}
if (value.R == null)
{
return false;
}
object value2 = value.R.GetValue(hudInstance);
if (value2 == null)
{
return false;
}
Type type2 = value2.GetType();
if (!MiniRendererSizeFieldCache.TryGetValue(type2, out var value3))
{
MiniRendererSizeFields miniRendererSizeFields = default(MiniRendererSizeFields);
miniRendererSizeFields.Width = AccessTools.Field(type2, "width");
miniRendererSizeFields.Height = AccessTools.Field(type2, "height");
value3 = miniRendererSizeFields;
MiniRendererSizeFieldCache[type2] = value3;
}
if (value3.Width == null || value3.Height == null)
{
return false;
}
width = Convert.ToSingle(value3.Width.GetValue(value2));
height = Convert.ToSingle(value3.Height.GetValue(value2));
if (width > 0.01f)
{
return height > 0.01f;
}
return false;
}
private static float GetCameraPixelWidth(Camera cam)
{
if ((Object)(object)cam == (Object)null)
{
return 0f;
}
RenderTexture targetTexture = cam.targetTexture;
if ((Object)(object)targetTexture != (Object)null && ((Texture)targetTexture).width > 0)
{
return ((Texture)targetTexture).width;
}
if (cam.pixelWidth > 0)
{
return cam.pixelWidth;
}
return Screen.width;
}
private static float GetCameraPixelHeight(Camera cam)
{
if ((Object)(object)cam == (Object)null)
{
return 0f;
}
RenderTexture targetTexture = cam.targetTexture;
if ((Object)(object)targetTexture != (Object)null && ((Texture)targetTexture).height > 0)
{
return ((Texture)targetTexture).height;
}
if (cam.pixelHeight > 0)
{
return cam.pixelHeight;
}
return Screen.height;
}
private static void MiniRenderer_Start_Postfix(object __instance)
{
if (ShouldApplyHudFix())
{
EnsureMiniRendererRenderTexture(__instance);
ApplyHudDisplayScale(__instance);
}
}
private static void EnsureMiniRendererRenderTexture(object renderer)
{
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
if (renderer == null)
{
return;
}
Type type = renderer.GetType();
FieldInfo fieldInfo = AccessTools.Field(type, "width");
FieldInfo fieldInfo2 = AccessTools.Field(type, "height");
FieldInfo fieldInfo3 = AccessTools.Field(type, "rt");
if (fieldInfo == null || fieldInfo2 == null || fieldInfo3 == null)
{
return;
}
int num = (int)fieldInfo.GetValue(renderer);
int num2 = (int)fieldInfo2.GetValue(renderer);
if (num <= 0 || num2 <= 0)
{
return;
}
object? value = fieldInfo3.GetValue(renderer);
RenderTexture val = (RenderTexture)((value is RenderTexture) ? value : null);
if ((Object)(object)val != (Object)null && ((Texture)val).width == num && ((Texture)val).height == num2)
{
return;
}
int num3 = (((Object)(object)val != (Object)null) ? val.depth : 32);
RenderTexture val2 = new RenderTexture(num, num2, num3);
if ((Object)(object)val != (Object)null)
{
((Texture)val2).filterMode = ((Texture)val).filterMode;
}
fieldInfo3.SetValue(renderer, val2);
UpdateMiniRendererTextures(renderer, val2);
FieldInfo fieldInfo4 = AccessTools.Field(type, "renderers");
FieldInfo fieldInfo5 = AccessTools.Field(type, "rendererName");
if (fieldInfo4 != null && fieldInfo5 != null)
{
IDictionary dictionary = fieldInfo4.GetValue(null) as IDictionary;
string text = fieldInfo5.GetValue(renderer) as string;
if (dictionary != null && !string.IsNullOrEmpty(text))
{
dictionary[text] = val2;
}
}
}
private static void UpdateMiniRendererTextures(object renderer, RenderTexture rt)
{
if (renderer == null || (Object)(object)rt == (Object)null)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(renderer.GetType(), "mat");
Material val = (Material)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val != (Object)null)
{
val.SetTexture(MainTexId, (Texture)(object)rt);
val.SetTexture(AlphaTexId, (Texture)(object)rt);
return;
}
Component val2 = (Component)((renderer is Component) ? renderer : null);
if (!((Object)(object)val2 == (Object)null))
{
Renderer component = val2.GetComponent<Renderer>();
if (!((Object)(object)component == (Object)null))
{
component.material.SetTexture(MainTexId, (Texture)(object)rt);
component.material.SetTexture(AlphaTexId, (Texture)(object)rt);
}
}
}
private static void UpdateHudRendererAspect(object hudInstance)
{
if (!ShouldApplyHudFix() || hudInstance == null)
{
return;
}
float windowAspect = GetWindowAspect();
if (windowAspect <= 0.01f)
{
return;
}
Component val = (Component)((hudInstance is Component) ? hudInstance : null);
if ((Object)(object)val == (Object)null)
{
return;
}
MonoBehaviour val2 = FindMiniRenderer(val);
if ((Object)(object)val2 == (Object)null)
{
return;
}
Type type = ((object)val2).GetType();
if (!MiniRendererFieldCache.TryGetValue(type, out var value))
{
MiniRendererFields miniRendererFields = default(MiniRendererFields);
miniRendererFields.Width = AccessTools.Field(type, "width");
miniRendererFields.Height = AccessTools.Field(type, "height");
value = miniRendererFields;
MiniRendererFieldCache[type] = value;
}
if (value.Width == null || value.Height == null)
{
return;
}
int num = (int)value.Width.GetValue(val2);
int num2 = (int)value.Height.GetValue(val2);
if (num > 0 && num2 > 0)
{
int instanceID = ((Object)val2).GetInstanceID();
if (!HudMiniRendererOriginalWidths.ContainsKey(instanceID))
{
HudMiniRendererOriginalWidths[instanceID] = num;
}
int num3 = Mathf.Clamp(Mathf.RoundToInt((float)num2 * windowAspect), 1, 8192);
if (num != num3)
{
value.Width.SetValue(val2, num3);
EnsureMiniRendererRenderTexture(val2);
LogDebug($"Adjusted HUD MiniRenderer width to {num3} for aspect {windowAspect:0.###}.");
}
}
}
private static void ApplyHudDisplayScale(object renderer)
{
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
if (!ShouldApplyHudFix() || renderer == null)
{
return;
}
Component val = (Component)((renderer is Component) ? renderer : null);
if ((Object)(object)val == (Object)null)
{
return;
}
Type type = renderer.GetType();
if (!MiniRendererFieldCache.TryGetValue(type, out var value))
{
MiniRendererFields miniRendererFields = default(MiniRendererFields);
miniRendererFields.Width = AccessTools.Field(type, "width");
miniRendererFields.Height = AccessTools.Field(type, "height");
value = miniRendererFields;
MiniRendererFieldCache[type] = value;
}
if (value.Width == null || value.Height == null)
{
return;
}
int num = (int)value.Width.GetValue(renderer);
int num2 = (int)value.Height.GetValue(renderer);
if (num <= 0 || num2 <= 0)
{
return;
}
MeshRenderer[] componentsInParent = val.GetComponentsInParent<MeshRenderer>(true);
if (componentsInParent == null || componentsInParent.Length == 0)
{
return;
}
Texture rendererTexture = GetRendererTexture(renderer);
MeshRenderer[] array = componentsInParent;
Vector3 localScale = default(Vector3);
foreach (MeshRenderer val2 in array)
{
if ((Object)(object)val2 == (Object)null)
{
continue;
}
Material sharedMaterial = ((Renderer)val2).sharedMaterial;
if (!((Object)(object)sharedMaterial == (Object)null) && (!((Object)(object)rendererTexture != (Object)null) || !((Object)(object)sharedMaterial.mainTexture != (Object)(object)rendererTexture) || !((Object)(object)sharedMaterial.GetTexture(MainTexId) != (Object)(object)rendererTexture)))
{
Transform transform = ((Component)val2).transform;
int instanceID = ((Object)transform).GetInstanceID();
if (!HudDisplayOriginalScales.TryGetValue(instanceID, out var value2))
{
value2 = transform.localScale;
HudDisplayOriginalScales[instanceID] = value2;
HudDisplayTransforms[instanceID] = transform;
}
float windowAspect = GetWindowAspect();
if (windowAspect <= 0.01f)
{
break;
}
float num3 = (float)num / (float)num2;
float num4 = windowAspect / num3;
((Vector3)(ref localScale))..ctor(value2.x * num4, value2.y, value2.z);
transform.localScale = localScale;
LogDebug($"Scaled HUD display to {num4:0.###}x (aspect {windowAspect:0.###}).");
}
}
}
private static Texture GetRendererTexture(object renderer)
{
FieldInfo fieldInfo = AccessTools.Field(renderer.GetType(), "rt");
if (fieldInfo == null)
{
return null;
}
object? value = fieldInfo.GetValue(renderer);
return (Texture)((value is Texture) ? value : null);
}
private static MonoBehaviour FindMiniRenderer(Component component)
{
if ((Object)(object)component == (Object)null)
{
return null;
}
MonoBehaviour val = null;
Transform val2 = component.transform;
while ((Object)(object)val2 != (Object)null)
{
MonoBehaviour[] components = ((Component)val2).GetComponents<MonoBehaviour>();
foreach (MonoBehaviour val3 in components)
{
if ((Object)(object)val3 != (Object)null && string.Equals(((object)val3).GetType().Name, "MiniRenderer", StringComparison.Ordinal))
{
val = val3;
break;
}
}
if ((Object)(object)val != (Object)null)
{
break;
}
val2 = val2.parent;
}
return val;
}
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.###}).");
}
}
}
internal static void RefreshHudBackdrop()
{
if (!ShouldApply() || !IsUltrawide())
{
return;
}
Type type = AccessTools.TypeByName("sHUD");
if (!(type == null))
{
Object val = Object.FindFirstObjectByType(type);
if (!(val == (Object)null))
{
ScaleBackdropFromField(val, "backdrop", Camera.main, "sHUD");
}
}
}
private static void ScaleOverlayBackdrops()
{
if (ShouldApply() && IsUltrawide())
{
Camera fallbackCamera = ResolveMenuCamera(null);
ScaleBackdropByTypeName("sHUD", "backdrop", Camera.main);
ScaleBackdropByTypeName("ScreenSystem", "backdrop", fallbackCamera);
ScaleBackdropByTypeName("MenuScreenTransition", "backdrop", fallbackCamera);
}
}
private static void ScaleBackdropByTypeName(string typeName, string fieldName, Camera fallbackCamera)
{
Type type = AccessTools.TypeByName(typeName);
if (type == null)
{
return;
}
Object[] array = Object.FindObjectsByType(type, (FindObjectsInactive)1, (FindObjectsSortMode)0);
if (array != null)
{
Object[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
ScaleBackdropFromField(array2[i], fieldName, fallbackCamera, typeName);
}
}
}
private static void ScaleBackdropFromField(object instance, string fieldName, Camera fallbackCamera, string label)
{
if (instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(instance.GetType(), fieldName);
if (!(fieldInfo == null))
{
object? value = fieldInfo.GetValue(instance);
ScaleSpriteToCamera((SpriteRenderer)((value is SpriteRenderer) ? value : null), fallbackCamera, label);
}
}
}
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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)spriteRenderer == (Object)null || (Object)(object)spriteRenderer.sprite == (Object)null || !ShouldApply() || !IsUltrawide())
{
return;
}
Camera val = fallbackCamera;
if ((Object)(object)val == (Object)null)
{
val = Camera.main;
}
if ((Object)(object)val == (Object)null)
{
return;
}
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;
int instanceID = ((Object)((Component)spriteRenderer).transform).GetInstanceID();
if (!OverlayOriginalScales.ContainsKey(instanceID))
{
OverlayOriginalScales[instanceID] = localScale;
OverlayTransforms[instanceID] = ((Component)spriteRenderer).transform;
}
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_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Expected O, but got Unknown
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Expected O, but got Unknown
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Expected O, but got Unknown
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Expected O, but got Unknown
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Expected O, but got Unknown
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01c9: Expected O, but got Unknown
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Expected O, but got Unknown
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Expected O, but got Unknown
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Expected O, but got Unknown
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Expected O, but got Unknown
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Expected O, but got Unknown
//IL_0237: Unknown result type (might be due to invalid IL or missing references)
//IL_024d: Expected O, but got Unknown
//IL_024d: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Expected O, but got Unknown
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_0279: Expected O, but got Unknown
//IL_0279: Unknown result type (might be due to invalid IL or missing references)
//IL_028f: Expected O, but got Unknown
//IL_028f: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: Expected O, but got Unknown
//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
//IL_02bb: Expected O, but got Unknown
//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Expected O, but got Unknown
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Expected O, but got Unknown
//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
//IL_02fd: Expected O, but got Unknown
//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0313: Expected O, but got Unknown
//IL_0313: Unknown result type (might be due to invalid IL or missing references)
//IL_0329: Expected O, but got Unknown
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_033f: Expected O, but got Unknown
//IL_0354: Expected O, but got Unknown
_log = ((BaseUnityPlugin)this).Logger;
_enableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "enable_mod", true, "Enables/disables the mod entirely.");
_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.");
_perfLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "perf_logging", false, "Log periodic performance counters (can be noisy).");
_perfLogIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Logging", "perf_log_interval_seconds", 10f, "How often to emit perf logs, in seconds.");
_desktopMenuIconVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Menu", "show_ultrawide_menu_icon", true, "Show/hide the Ultrawide Menu icon on the Main Menu.");
_desktopMenuIconX = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "ultrawide_menu_icon_x", "5.5", "Main Menu icon X position. Example: 5.5");
_desktopMenuIconY = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "ultrawide_menu_icon_y", "3.25", "Main Menu icon Y position. Example: 3.25");
if (!_enableMod.Value)
{
_log.LogInfo((object)"Ultrawide mod disabled via config.");
return;
}
Harmony val = new Harmony("shibe.easydeliveryco.ultrawide");
PatchByName(val, "PlayerManager", "SetupCameras", null, "PlayerManager_SetupCameras_Postfix");
PatchByName(val, "RaceManager", "StartingCutScene", "RaceManager_StartingCutScene_Prefix", "RaceManager_StartingCutScene_Postfix");
PatchByName(val, "PauseSystem", "Start", null, "PauseSystem_Start_Postfix");
PatchByName(val, "PauseSystem", "SetResolution", null, "PauseSystem_SetResolution_Postfix");
PatchByName(val, "PauseSystem", "SetFullscreen", null, "PauseSystem_SetFullscreen_Postfix");
PatchByName(val, "PauseSystem", "TogglePaused", null, "PauseSystem_TogglePaused_Postfix");
PatchByName(val, "sCameraController", "Update", null, "SCameraController_Update_Postfix");
PatchByName(val, "sCameraController", "LateUpdate", null, "SCameraController_LateUpdate_Postfix");
PatchByName(val, "IntroDotExe", "Setup", null, "IntroDotExe_Setup_Postfix");
PatchByName(val, "ChooseExe", "Setup", null, "ChooseExe_Setup_Postfix");
PatchByName(val, "CamDotExe", "Start", null, "CamDotExe_Start_Postfix");
PatchByName(val, "MiniRenderer", "Start", null, "MiniRenderer_Start_Postfix");
PatchByName(val, "pixelPerfectView", "AdjustViewPlane", "PixelPerfectView_AdjustViewPlane_Prefix");
PatchByName(val, "sHUD", "Init", null, "SHud_Init_Postfix");
PatchByName(val, "sHUD", "WorldToHUDPoint", "SHud_WorldToHUDPoint_Prefix");
PatchByName(val, "sHUD", "FadeToBlack", "SHud_FadeToBlack_Prefix");
PatchByName(val, "sHUD", "DipToBlack", "SHud_DipToBlack_Prefix");
PatchByName(val, "ScreenSystem", "Init", null, "ScreenSystem_Init_Postfix");
PatchByName(val, "ScreenSystem", "DoTransition", null, "ScreenSystem_DoTransition_Postfix");
PatchByName(val, "SceneTransition", "Start", null, "SceneTransition_Start_Postfix");
PatchByName(val, "sTeleporter", "Teleport", null, "Steleporter_Teleport_Postfix");
PatchByName(val, "DesktopDotExe", "Setup", null, "DesktopDotExe_Setup_Postfix");
PatchByName(val, "sWeatherSystem", "UpdateWeather", null, "SWeatherSystem_UpdateWeather_Postfix");
PatchByName(val, "FogVolume", "LateUpdate", null, "FogVolume_LateUpdate_Postfix");
}
private static bool ShouldOverrideSplitScreen()
{
if (ShouldApply())
{
return IsUltrawide();
}
return false;
}
private static void PlayerManager_SetupCameras_Postfix(object __instance)
{
if (!ShouldOverrideSplitScreen() || __instance == null)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "players");
if (fieldInfo == null || !(fieldInfo.GetValue(__instance) is IEnumerable enumerable))
{
return;
}
foreach (object item in enumerable)
{
GameObject val = (GameObject)((item is GameObject) ? item : null);
if (!((Object)(object)val == (Object)null))
{
Camera componentInChildren = val.GetComponentInChildren<Camera>();
ApplyCameraAspect(componentInChildren);
ApplyCameraViewport(componentInChildren);
}
}
}
private static void RaceManager_StartingCutScene_Prefix(object p, ref Rect __state)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
if (ShouldOverrideSplitScreen())
{
Camera racePlayerCamera = GetRacePlayerCamera(p);
if (!((Object)(object)racePlayerCamera == (Object)null))
{
__state = racePlayerCamera.rect;
racePlayerCamera.rect = BuildFullRect();
}
}
}
private static void RaceManager_StartingCutScene_Postfix(object p, Rect __state)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if (ShouldOverrideSplitScreen())
{
Camera racePlayerCamera = GetRacePlayerCamera(p);
if (!((Object)(object)racePlayerCamera == (Object)null))
{
racePlayerCamera.rect = __state;
}
}
}
private static void PauseSystem_Start_Postfix(object __instance)
{
if (ShouldApply())
{
if (__instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "mainCamera");
ApplyCameraAspect((Camera)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null));
}
ApplyAllCameras();
ScaleOverlayBackdrops();
ApplySavedMenuSettings();
}
}
private static void PauseSystem_SetResolution_Postfix()
{
if (ShouldApply())
{
ApplyAllCameras();
ScaleOverlayBackdrops();
ApplySavedMenuSettings();
}
}
private static void PauseSystem_SetFullscreen_Postfix()
{
if (ShouldApply())
{
ApplyAllCameras();
ScaleOverlayBackdrops();
ApplySavedMenuSettings();
}
}
private static void PauseSystem_TogglePaused_Postfix()
{
if (ShouldApply())
{
ApplySavedMenuSettings();
}
}
private static void SCameraController_LateUpdate_Postfix(object __instance)
{
if (ShouldApply() && !IsPlayerInsideBuilding())
{
sCameraController val = (sCameraController)((__instance is sCameraController) ? __instance : null);
if (val != null && !((Object)(object)val.cam == (Object)null) && TryGetSavedFov(val.firstPerson && !val.fixedPerspective, out var fov))
{
val.cam.fieldOfView = fov;
}
}
}
private static void SHud_Init_Postfix(object __instance)
{
if (ShouldApply())
{
if (ShouldApplyHudFix())
{
UpdateHudRendererAspect(__instance);
}
ScaleBackdropFromField(__instance, "backdrop", Camera.main, "sHUD");
}
}
private static void SHud_FadeToBlack_Prefix(object __instance)
{
if (ShouldApply())
{
ScaleBackdropFromField(__instance, "backdrop", Camera.main, "sHUD");
}
}
private static void SHud_DipToBlack_Prefix(object __instance)
{
if (ShouldApply())
{
ScaleBackdropFromField(__instance, "backdrop", Camera.main, "sHUD");
}
}
private static void ScreenSystem_Init_Postfix(object __instance)
{
if (ShouldApply() && __instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "menuCamera");
Camera menuCamera = (Camera)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
menuCamera = ResolveMenuCamera(menuCamera);
ScaleBackdropFromField(__instance, "backdrop", menuCamera, "ScreenSystem");
ScaleOverlaySprites((Component)((__instance is Component) ? __instance : null), menuCamera, "ScreenSystem");
RefreshPixelation();
}
}
private static void ScreenSystem_DoTransition_Postfix(object __instance)
{
if (ShouldApply() && __instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "menuCamera");
Camera menuCamera = (Camera)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
menuCamera = ResolveMenuCamera(menuCamera);
ScaleBackdropFromField(__instance, "backdrop", menuCamera, "ScreenSystem");
ScaleOverlaySprites((Component)((__instance is Component) ? __instance : null), menuCamera, "ScreenSystem");
RefreshPixelation();
}
}
private static void IntroDotExe_Setup_Postfix(object __instance)
{
if (ShouldApply() && __instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "menuCamera");
ApplyMenuCameraAspect((GameObject)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null));
}
}
private static void ChooseExe_Setup_Postfix(object __instance)
{
if (ShouldApply() && __instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "menuCamera");
ApplyMenuCameraAspect((GameObject)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null));
}
}
private static void CamDotExe_Start_Postfix(object __instance)
{
if (!ShouldApply() || __instance == null)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "freecam");
if (fieldInfo == null)
{
return;
}
object? value = fieldInfo.GetValue(__instance);
Component val = (Component)((value is Component) ? value : null);
if ((Object)(object)val == (Object)null)
{
return;
}
FieldInfo fieldInfo2 = AccessTools.Field(((object)val).GetType(), "cam");
if (!(fieldInfo2 == null))
{
object? value2 = fieldInfo2.GetValue(val);
Camera val2 = (Camera)((value2 is Camera) ? value2 : null);
if ((Object)(object)val2 == (Object)null)
{
LogDebug("CamDotExe freecam camera not found for aspect fix.");
return;
}
ApplyMenuCameraAspect(val2);
LogDebug($"Applied CamDotExe freecam aspect fix to {((Object)val2).name} ({((Object)val2).GetInstanceID()}).");
}
}
private static void SceneTransition_Start_Postfix(object __instance)
{
if (ShouldApply() && __instance != null)
{
FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "sr");
SpriteRenderer val = (SpriteRenderer)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val == (Object)null)
{
Component val2 = (Component)((__instance is Component) ? __instance : null);
val = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<SpriteRenderer>() : null);
}
ScaleSpriteToCamera(val, Camera.main, "SceneTransition");
ScaleOverlaySprites((Component)((__instance is Component) ? __instance : null), Camera.main, "SceneTransition");
}
}
private static void Steleporter_Teleport_Postfix()
{
if (!ShouldApply())
{
return;
}
Type type = AccessTools.TypeByName("sHUD");
if (!(type == null))
{
Object val = Object.FindFirstObjectByType(type);
if (!(val == (Object)null))
{
ScaleBackdropFromField(val, "backdrop", Camera.main, "sHUD");
}
}
}
internal static void RefreshPixelation()
{
if (!ShouldApply())
{
return;
}
try
{
EnsurePixelationTargets();
ApplyPixelation();
}
catch
{
}
}
private static void EnsurePixelationTargets()
{
if ((Object)(object)_pixelMainCamera == (Object)null)
{
sCameraController val = Object.FindFirstObjectByType<sCameraController>();
if ((Object)(object)val != (Object)null)
{
_pixelMainCamera = val.cam;
}
if ((Object)(object)_pixelMainCamera == (Object)null)
{
PauseSystem pauseSystem = PauseSystem.pauseSystem;
_pixelMainCamera = (((Object)(object)pauseSystem != (Object)null) ? pauseSystem.mainCamera : null);
}
if ((Object)(object)_pixelMainCamera == (Object)null)
{
_pixelMainCamera = Camera.main;
}
}
if ((Object)(object)_pixelScreenRenderer == (Object)null)
{
Type type = AccessTools.TypeByName("ScreenSystem");
if (type != null)
{
Object obj = Object.FindFirstObjectByType(type);
Component val2 = (Component)(object)((obj is Component) ? obj : null);
if ((Object)(object)val2 != (Object)null)
{
Transform val3 = val2.transform.Find("Camera Persp/ScreenPivot/Screen");
if ((Object)(object)val3 != (Object)null)
{
_pixelScreenRenderer = ((Component)val3).GetComponent<MeshRenderer>();
}
if ((Object)(object)_pixelScreenRenderer == (Object)null)
{
MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(true);
foreach (MeshRenderer val4 in componentsInChildren)
{
if ((Object)(object)val4 != (Object)null && string.Equals(((Object)val4).name, "Screen", StringComparison.OrdinalIgnoreCase))
{
_pixelScreenRenderer = val4;
break;
}
}
}
}
}
}
if ((Object)(object)_pixelRearCamera == (Object)null || (Object)(object)_pixelRearRenderer == (Object)null)
{
sCarController val5 = Object.FindFirstObjectByType<sCarController>();
if ((Object)(object)val5 != (Object)null)
{
if ((Object)(object)_pixelRearRenderer == (Object)null)
{
Transform val6 = ((Component)val5).transform.Find("carInt/RearViewMirror");
if ((Object)(object)val6 != (Object)null)
{
_pixelRearRenderer = ((Component)val6).GetComponent<MeshRenderer>();
}
}
if ((Object)(object)_pixelRearCamera == (Object)null)
{
Transform val7 = ((Component)val5).transform.Find("RearViewCam");
if ((Object)(object)val7 != (Object)null)
{
_pixelRearCamera = ((Component)val7).GetComponent<Camera>();
}
}
}
}
if ((Object)(object)_pixelDefaultRt == (Object)null && (Object)(object)_pixelMainCamera != (Object)null && (Object)(object)_pixelMainCamera.targetTexture != (Object)null)
{
_pixelDefaultRt = _pixelMainCamera.targetTexture;
}
if ((Object)(object)_pixelDefaultRearRt == (Object)null && (Object)(object)_pixelRearCamera != (Object)null && (Object)(object)_pixelRearCamera.targetTexture != (Object)null)
{
_pixelDefaultRearRt = _pixelRearCamera.targetTexture;
}
}
private static void ApplyPixelation()
{
int pixelationMode = GetPixelationMode();
ApplyPixelationMain(pixelationMode);
ApplyPixelationRear(pixelationMode);
_pixelLastMode = pixelationMode;
}
private static void ApplyPixelationMain(int mode)
{
if ((Object)(object)_pixelMainCamera == (Object)null || (Object)(object)_pixelScreenRenderer == (Object)null || (Object)(object)_pixelDefaultRt == (Object)null)
{
return;
}
if (mode == 3)
{
ReleaseCustomRt(ref _pixelCustomRt, _pixelDefaultRt);
_pixelMainCamera.targetTexture = _pixelDefaultRt;
SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelDefaultRt);
return;
}
GetMaxRtSizeForCurrentPresentation(out var width, out var height);
int num;
int num2;
switch (mode)
{
case 0:
num = width;
num2 = height;
break;
case 1:
num = Mathf.Min(width, Mathf.Max(1, Mathf.RoundToInt((float)((Texture)_pixelDefaultRt).width * 2.25f)));
num2 = Mathf.Min(height, Mathf.Max(1, Mathf.RoundToInt((float)((Texture)_pixelDefaultRt).height * 2.25f)));
break;
case 2:
num = Mathf.Min(width, Mathf.Max(1, Mathf.RoundToInt((float)((Texture)_pixelDefaultRt).width * 1.5f)));
num2 = Mathf.Min(height, Mathf.Max(1, Mathf.RoundToInt((float)((Texture)_pixelDefaultRt).height * 1.5f)));
break;
case 4:
num = Mathf.Max(1, Mathf.RoundToInt((float)((Texture)_pixelDefaultRt).width * 0.75f));
num2 = Mathf.Max(1, Mathf.RoundToInt((float)((Texture)_pixelDefaultRt).height * 0.75f));
break;
default:
num = ((Texture)_pixelDefaultRt).width;
num2 = ((Texture)_pixelDefaultRt).height;
break;
}
if ((Object)(object)_pixelCustomRt != (Object)null && ((Texture)_pixelCustomRt).width == num && ((Texture)_pixelCustomRt).height == num2 && _pixelLastMode == mode)
{
_pixelMainCamera.targetTexture = _pixelCustomRt;
SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelCustomRt);
return;
}
if (_pixelLastW == num && _pixelLastH == num2 && _pixelLastMode == mode && (Object)(object)_pixelMainCamera.targetTexture != (Object)null)
{
_pixelMainCamera.targetTexture = _pixelMainCamera.targetTexture;
}
_pixelLastW = num;
_pixelLastH = num2;
_pixelCustomRt = CreateLike(_pixelCustomRt, _pixelDefaultRt, num, num2);
_pixelMainCamera.targetTexture = _pixelCustomRt;
SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelCustomRt);
}
private static void ApplyPixelationRear(int mode)
{
if ((Object)(object)_pixelRearCamera == (Object)null || (Object)(object)_pixelRearRenderer == (Object)null || (Object)(object)_pixelDefaultRearRt == (Object)null)
{
return;
}
if (mode == 3)
{
ReleaseCustomRt(ref _pixelCustomRearRt, _pixelDefaultRearRt);
_pixelRearCamera.targetTexture = _pixelDefaultRearRt;
SetMainTexture(_pixelRearRenderer, (Texture)(object)_pixelDefaultRearRt);
return;
}
int fullWidth = GetFullWidth(_pixelRearCamera, _pixelDefaultRearRt);
int fullHeight = GetFullHeight(_pixelRearCamera, _pixelDefaultRearRt);
int width = ((Texture)_pixelDefaultRearRt).width;
int height = ((Texture)_pixelDefaultRearRt).height;
int num;
int num2;
switch (mode)
{
case 0:
num = Mathf.Min(fullWidth, width * 4);
num2 = Mathf.Min(fullHeight, height * 4);
break;
case 1:
num = Mathf.Min(fullWidth, Mathf.Max(1, Mathf.RoundToInt((float)width * 2.25f)));
num2 = Mathf.Min(fullHeight, Mathf.Max(1, Mathf.RoundToInt((float)height * 2.25f)));
break;
case 2:
num = Mathf.Min(fullWidth, Mathf.Max(1, Mathf.RoundToInt((float)width * 1.5f)));
num2 = Mathf.Min(fullHeight, Mathf.Max(1, Mathf.RoundToInt((float)height * 1.5f)));
break;
case 4:
num = Mathf.Max(1, Mathf.RoundToInt((float)width * 0.75f));
num2 = Mathf.Max(1, Mathf.RoundToInt((float)height * 0.75f));
break;
default:
num = width;
num2 = height;
break;
}
if ((Object)(object)_pixelCustomRearRt != (Object)null && ((Texture)_pixelCustomRearRt).width == num && ((Texture)_pixelCustomRearRt).height == num2 && _pixelLastMode == mode)
{
_pixelRearCamera.targetTexture = _pixelCustomRearRt;
SetMainTexture(_pixelRearRenderer, (Texture)(object)_pixelCustomRearRt);
return;
}
_pixelLastRearW = num;
_pixelLastRearH = num2;
_pixelCustomRearRt = CreateLike(_pixelCustomRearRt, _pixelDefaultRearRt, num, num2);
_pixelRearCamera.targetTexture = _pixelCustomRearRt;
SetMainTexture(_pixelRearRenderer, (Texture)(object)_pixelCustomRearRt);
}
private static int GetFullWidth()
{
//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)
int width;
if (Screen.width <= 0)
{
Resolution currentResolution = Screen.currentResolution;
width = ((Resolution)(ref currentResolution)).width;
}
else
{
width = Screen.width;
}
return Mathf.Max(1, width);
}
private static int GetFullHeight()
{
//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)
int height;
if (Screen.height <= 0)
{
Resolution currentResolution = Screen.currentResolution;
height = ((Resolution)(ref currentResolution)).height;
}
else
{
height = Screen.height;
}
return Mathf.Max(1, height);
}
private static int GetFullWidth(Camera cam, RenderTexture fallback)
{
if ((Object)(object)cam != (Object)null && cam.pixelWidth > 0)
{
return cam.pixelWidth;
}
if ((Object)(object)fallback != (Object)null && ((Texture)fallback).width > 0)
{
return ((Texture)fallback).width;
}
return GetFullWidth();
}
private static int GetFullHeight(Camera cam, RenderTexture fallback)
{
if ((Object)(object)cam != (Object)null && cam.pixelHeight > 0)
{
return cam.pixelHeight;
}
if ((Object)(object)fallback != (Object)null && ((Texture)fallback).height > 0)
{
return ((Texture)fallback).height;
}
return GetFullHeight();
}
private static void GetMaxRtSizeForCurrentPresentation(out int width, out int height)
{
int fullWidth = GetFullWidth();
int fullHeight = GetFullHeight();
width = fullWidth;
height = fullHeight;
float pixelationOutputAspect = GetPixelationOutputAspect();
if (fullWidth > 0 && fullHeight > 0 && !(pixelationOutputAspect <= 0.01f))
{
if ((float)fullWidth / (float)fullHeight >= pixelationOutputAspect)
{
height = fullHeight;
width = Mathf.Max(1, Mathf.RoundToInt((float)height * pixelationOutputAspect));
}
else
{
width = fullWidth;
height = Mathf.Max(1, Mathf.RoundToInt((float)width / pixelationOutputAspect));
}
width = Mathf.Clamp(width, 1, 16384);
height = Mathf.Clamp(height, 1, 16384);
}
}
private static float GetPixelationOutputAspect()
{
if (IsVanillaPresentation())
{
return 1.7777778f;
}
float targetAspect = GetTargetAspect();
if (targetAspect > 0.01f)
{
return targetAspect;
}
return GetWindowAspect();
}
private static void SetMainTexture(MeshRenderer renderer, Texture tex)
{
if (!((Object)(object)renderer == (Object)null) && !((Object)(object)tex == (Object)null))
{
Material material = ((Renderer)renderer).material;
if ((Object)(object)material != (Object)null)
{
material.mainTexture = tex;
}
}
}
private static RenderTexture CreateLike(RenderTexture existing, RenderTexture like, int width, int height)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Expected O, but got Unknown
if ((Object)(object)like == (Object)null)
{
return existing;
}
if ((Object)(object)existing != (Object)null && ((Texture)existing).width == width && ((Texture)existing).height == height)
{
return existing;
}
if ((Object)(object)existing != (Object)null && (Object)(object)existing != (Object)(object)like)
{
existing.Release();
}
RenderTexture val = new RenderTexture(width, height, like.depth)
{
format = like.format,
antiAliasing = like.antiAliasing,
filterMode = ((Texture)like).filterMode
};
val.Create();
return val;
}
private static void ReleaseCustomRt(ref RenderTexture custom, RenderTexture defaultRt)
{
if ((Object)(object)custom != (Object)null && (Object)(object)custom != (Object)(object)defaultRt)
{
custom.Release();
}
custom = null;
}
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;
}
private static Camera GetRacePlayerCamera(object racePlayer)
{
if (racePlayer == null)
{
return null;
}
FieldInfo fieldInfo = AccessTools.Field(racePlayer.GetType(), "cam");
if (fieldInfo == null)
{
return null;
}
object? value = fieldInfo.GetValue(racePlayer);
return (Camera)((value is Camera) ? value : null);
}
private static void PatchByName(Harmony harmony, string typeName, string methodName, string prefix = null, string postfix = null)
{
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Expected O, but got Unknown
Type type = AccessTools.TypeByName(typeName);
if (type == null)
{
if (_debugMode != null && _debugMode.Value)
{
_log.LogWarning((object)("Type '" + typeName + "' not found for patch " + methodName + "."));
}
return;
}
MethodInfo methodInfo;
try
{
methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
}
catch (AmbiguousMatchException)
{
methodInfo = ResolveAmbiguousMethod(type, methodName);
}
if (methodInfo == null)
{
if (_debugMode != null && _debugMode.Value)
{
_log.LogWarning((object)("Method '" + typeName + "." + methodName + "' not found for patch."));
}
return;
}
HarmonyMethod val = null;
HarmonyMethod val2 = null;
if (!string.IsNullOrWhiteSpace(prefix))
{
val = new HarmonyMethod(typeof(Plugin), prefix, (Type[])null);
}
if (!string.IsNullOrWhiteSpace(postfix))
{
val2 = new HarmonyMethod(typeof(Plugin), postfix, (Type[])null);
}
harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
private static MethodInfo ResolveAmbiguousMethod(Type type, string methodName)
{
MethodInfo methodInfo = null;
int num = int.MaxValue;
Type type2 = type;
while (type2 != null)
{
MethodInfo[] methods = type2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo2 in methods)
{
if (string.Equals(methodInfo2.Name, methodName, StringComparison.Ordinal))
{
int num2 = methodInfo2.GetParameters().Length;
if (num2 == 0)
{
return methodInfo2;
}
if (num2 < num)
{
num = num2;
methodInfo = methodInfo2;
}
}
}
type2 = type2.BaseType;
}
if (methodInfo == null && _debugMode != null && _debugMode.Value)
{
_log.LogWarning((object)("Ambiguous match for '" + type.Name + "." + methodName + "', but no overload resolved."));
}
return methodInfo;
}
internal static void RefreshViewDistance()
{
if (ShouldApply())
{
CaptureViewDistanceBaseValues();
ApplyViewDistanceQuality(GetViewDistanceMode());
}
}
private static void CaptureViewDistanceBaseValues()
{
if (!_viewDistanceBaseCaptured)
{
_baseShadowDistance = QualitySettings.shadowDistance;
_baseLodBias = QualitySettings.lodBias;
_baseMaximumLodLevel = QualitySettings.maximumLODLevel;
_viewDistanceBaseCaptured = true;
}
}
private static void ApplyViewDistanceQuality(int mode)
{
if (_viewDistanceBaseCaptured)
{
float shadowDistance;
float lodBias;
switch (mode)
{
case 1:
QualitySettings.shadowDistance = _baseShadowDistance;
QualitySettings.lodBias = _baseLodBias;
QualitySettings.maximumLODLevel = _baseMaximumLodLevel;
return;
case 0:
shadowDistance = 150f;
lodBias = 0.75f;
break;
case 2:
shadowDistance = 1200f;
lodBias = 3f;
break;
case 3:
shadowDistance = 3000f;
lodBias = 6f;
break;
default:
shadowDistance = _baseShadowDistance;
lodBias = _baseLodBias;
break;
}
QualitySettings.shadowDistance = shadowDistance;
QualitySettings.lodBias = lodBias;
QualitySettings.maximumLODLevel = 0;
}
}
private static void SCameraController_Update_Postfix(object __instance)
{
if (!ShouldApply())
{
return;
}
sCameraController val = (sCameraController)((__instance is sCameraController) ? __instance : null);
if (val != null && !((Object)(object)val.cam == (Object)null))
{
float num;
switch (GetViewDistanceMode())
{
case 1:
return;
case 0:
num = 3000f;
break;
case 2:
num = 25000f;
break;
case 3:
num = 100000f;
break;
default:
num = 10000f;
break;
}
if (num > val.cam.nearClipPlane + 1f)
{
val.cam.farClipPlane = num;
}
}
}
}
public class UIUtil
{
public DesktopDotExe M;
public GamepadNavigation Nav;
public MiniRenderer R;
public void Label(string name, float x, float y)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
name = LocalizationDictionary.Translate(name);
R.fontOptions.alignment = (Alignment)1;
R.fput(name, x, y, 0f, 13f, 0f, -1);
}
public void ValueLabel(string value, float x, float y)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
R.fontOptions.alignment = (Alignment)2;
R.fput(value, x, y, 0f, 13f, 0f, -1);
}
public bool Button(string name, float x, float y)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
name = LocalizationDictionary.Translate(name);
if (M.MouseOver((int)x - 2, (int)y, name.Length * 8 + 4, 8))
{
((ScreenProgram)M).mouseIcon = 128;
name = ">" + name;
if (((ScreenProgram)M).mouseButton)
{
((ScreenProgram)M).mouseIcon = 160;
}
if (((ScreenProgram)M).mouseButtonUp)
{
return true;
}
}
R.fontOptions.alignment = (Alignment)2;
R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
return false;
}
public bool? Toggle(string name, bool state, float x, float y)
{
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
name = LocalizationDictionary.Translate(name);
bool? result = null;
string text = "[" + (state ? "on" : "off") + "]";
R.put(text, x + 4f, y);
if (M.MouseOver((int)x - 2, (int)y, text.Length * 8 + 4, 8))
{
((ScreenProgram)M).mouseIcon = 128;
name = ">" + name;
if (((ScreenProgram)M).mouseButton)
{
((ScreenProgram)M).mouseIcon = 160;
}
if (((ScreenProgram)M).mouseButtonUp)
{
result = !state;
}
}
R.fontOptions.alignment = (Alignment)2;
R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
return result;
}
public float? Slider(string name, float value, float x, float y, ref float mouseYLock)
{
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
name = LocalizationDictionary.Translate(name);
float? result = null;
int num = 10;
for (int i = 0; i < num; i++)
{
R.spr(32f, 0f, x + 4f + (float)i * 8f, y, 8f, 8f);
}
float num2 = x + value * (float)num * 8f;
R.spr(0f, 24f, num2, y, 8f, 8f);
if (M.MouseOver((int)x - 8, (int)y, num * 8 + 16, 8))
{
((ScreenProgram)M).mouseIcon = 128;
name = ">" + name;
if (Nav != null && Nav.menuInput.x < 0f)
{
result = Mathf.Clamp01(value - Time.unscaledDeltaTime / 2f);
}
if (Nav != null && Nav.menuInput.x > 0f)
{
result = Mathf.Clamp01(value + Time.unscaledDeltaTime / 2f);
}
if (((ScreenProgram)M).mouseButton)
{
((ScreenProgram)M).mouseIcon = 160;
value = Mathf.InverseLerp(x + 4f, x + 4f + (float)num * 8f, ((ScreenProgram)M).mouse.x);
value = Mathf.Clamp01(value);
result = value;
if (mouseYLock == 0f)
{
mouseYLock = ((ScreenProgram)M).mouse.y;
}
}
}
R.fontOptions.alignment = (Alignment)2;
R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
return result;
}
}
public class UltrawideMenuWindow : MonoBehaviour
{
public const string FileName = "wide";
public const string ListenerName = "UltrawideMenu";
public const string ListenerData = "listener_UltrawideMenu";
private float _mouseYLock;
private UIUtil _util;
public void FrameUpdate(WindowView view)
{
//IL_0052: 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_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
if (view != null)
{
if (_util == null)
{
_util = new UIUtil();
}
_util.M = view.M;
_util.R = view.R;
_util.Nav = view.M.nav;
Rect p = default(Rect);
((Rect)(ref p))..ctor(view.position * 8f, view.size * 8f);
((Rect)(ref p)).position = ((Rect)(ref p)).position + new Vector2(8f, 8f);
if (((ScreenProgram)_util.M).mouseButtonUp)
{
_mouseYLock = 0f;
}
if (_mouseYLock > 0f)
{
((ScreenProgram)_util.M).mouse.y = _mouseYLock;
}
DrawMenu(p);
}
}
public void BackButtonPressed()
{
}
private void DrawMenu(Rect p)
{
float x = ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f - 16f;
float num = ((Rect)(ref p)).y + 10f;
float num2 = 12f;
float num3 = 4f;
_util.Label("Ultrawide Settings", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num);
num += num2 + num3;
_util.Label("FOV", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num);
num += num2;
GetFovRange(out var min, out var max);
float currentCameraFov = GetCurrentCameraFov();
float num4 = Mathf.Clamp(Plugin.GetSavedFovOrDefault(firstPerson: false, currentCameraFov), min, max);
float value = Mathf.InverseLerp(min, max, num4);
_util.ValueLabel($"{num4:0}", ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num);
float? num5 = _util.Slider("3rd Person", value, x, num, ref _mouseYLock);
if (num5.HasValue)
{
float fov = Mathf.Lerp(min, max, num5.Value);
Plugin.SaveFovOverride(firstPerson: false, fov);
}
num += num2;
float num6 = Mathf.Clamp(Plugin.GetSavedFovOrDefault(firstPerson: true, currentCameraFov), min, max);
float value2 = Mathf.InverseLerp(min, max, num6);
_util.ValueLabel($"{num6:0}", ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num);
float? num7 = _util.Slider("1st Person", value2, x, num, ref _mouseYLock);
if (num7.HasValue)
{
float fov2 = Mathf.Lerp(min, max, num7.Value);
Plugin.SaveFovOverride(firstPerson: true, fov2);
}
num += num2 + num3;
_util.Label("Renderer", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num);
num += num2;
int pixelationMode = Plugin.GetPixelationMode();
_util.ValueLabel(pixelationMode switch
{
0 => "None",
1 => "Finer",
2 => "Fine",
3 => "Default",
4 => "Large",
_ => "Default",
}, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num);
float value3 = Mathf.Clamp01((float)pixelationMode / 4f);
float? num8 = _util.Slider("Pixelation", value3, x, num, ref _mouseYLock);
if (num8.HasValue)
{
int num9 = Mathf.Clamp(Mathf.RoundToInt(num8.Value * 4f), 0, 4);
if (num9 != pixelationMode)
{
Plugin.SavePixelationMode(num9);
}
}
num += num2;
int viewDistanceMode = Plugin.GetViewDistanceMode();
_util.ValueLabel(viewDistanceMode switch
{
0 => "Near",
1 => "Default",
2 => "Far",
3 => "Max",
_ => "Default",
}, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num);
float value4 = Mathf.Clamp01((float)viewDistanceMode / 3f);
float? num10 = _util.Slider("View Distance", value4, x, num, ref _mouseYLock);
if (num10.HasValue)
{
int num11 = Mathf.Clamp(Mathf.RoundToInt(num10.Value * 3f), 0, 3);
if (num11 != viewDistanceMode)
{
Plugin.SaveViewDistanceMode(num11);
}
}
num += num2 + num3;
_util.Label("Atmosphere", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, num);
num += num2;
float fogMultiplier = Plugin.GetFogMultiplier();
float num12 = 0.25f;
float num13 = 2f;
fogMultiplier = Mathf.Clamp(fogMultiplier, num12, num13);
int num14 = Mathf.RoundToInt(fogMultiplier * 100f);
_util.ValueLabel($"{num14}%", ((Rect)(ref p)).x + ((Rect)(ref p)).width - 12f, num);
float value5 = Mathf.InverseLerp(num12, num13, fogMultiplier);
float? num15 = _util.Slider("Fog", value5, x, num, ref _mouseYLock);
if (num15.HasValue)
{
float num16 = Mathf.Lerp(num12, num13, num15.Value);
num16 = Mathf.Round(num16 * 100f) / 100f;
if (Mathf.Abs(num16 - fogMultiplier) > 0.001f)
{
Plugin.SaveFogMultiplier(num16);
}
}
}
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;
}
}
}