Decompiled source of DSPAASR v1.1.0

DSPAAMod.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using BepInEx;
using BepInEx.Configuration;
using DSPAAMod.Core;
using DSPAAMod.Game;
using DSPAAMod.Interop;
using DSPAAMod.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Experimental.Rendering;
using UnityEngine.PostProcessing;
using UnityEngine.Rendering;
using UnityEngine.UI;
using UnityStandardAssets.ImageEffects;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("NordLandeW")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Anti-aliasing and super resolution for Dyson Sphere Program.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+35e9ca1fc42d1415477ffb386c310e4fb5df565a")]
[assembly: AssemblyProduct("DSPAASR")]
[assembly: AssemblyTitle("DSPAAMod")]
[assembly: AssemblyVersion("1.1.0.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 DSPAAMod
{
	[BepInPlugin("dspaa.mod", "DSPAASR", "1.1.0")]
	[BepInProcess("DSPGAME.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "dspaa.mod";

		private ConfigEntry<AaTechnique> technique;

		private ConfigEntry<ModelSelection> model;

		private ConfigEntry<ResolutionMode> resolution;

		private ConfigEntry<float> fsrSharpness;

		private ConfigEntry<KeyboardShortcut> captureShortcut;

		private NativeBridge native;

		private Harmony harmony;

		private bool stopped;

		internal static Plugin Instance { get; private set; }

		internal RenderController Renderer { get; private set; }

		internal SettingsSession Settings { get; private set; }

		internal GraphicsOptions Options { get; private set; }

		private void Awake()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			Instance = this;
			try
			{
				technique = ((BaseUnityPlugin)this).Config.Bind<AaTechnique>("Antialiasing", "Technique", AaTechnique.Original, "Original preserves game AA; Fxaa/Taa use the game's filters; Dlss/Fsr use the selected resolution mode. Legacy Dlaa migrates to Dlss with native-resolution DLAA. Changing this file requires restart.");
				model = ((BaseUnityPlugin)this).Config.Bind<ModelSelection>("Antialiasing", "Model", ModelSelection.Recommended, "Recommended: K for DLAA/Quality/Balanced, M for Performance, L for UltraPerformance. Explicit CNN/K/L/M overrides persist independently of resolution mode.");
				resolution = ((BaseUnityPlugin)this).Config.Bind<ResolutionMode>("Antialiasing", "Resolution", ResolutionMode.Dlaa, "DLSS/FSR resolution mode: Dlaa means native-resolution AA (DLAA or FSR Native AA); SR modes query the selected SDK for actual lower world-render dimensions. Model selection remains independent. Changing this file requires restart.");
				fsrSharpness = ((BaseUnityPlugin)this).Config.Bind<float>("FSR", "Sharpness", 0f, "FSR RCAS sharpening, 0 (disabled) to 1 (maximum). Independent of DLSS model. Changing this file requires restart.");
				captureShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Diagnostics", "CaptureShortcut", new KeyboardShortcut((KeyCode)291, (KeyCode[])(object)new KeyCode[2]
				{
					(KeyCode)306,
					(KeyCode)304
				}), "Explicitly trace two Unity frames in LogOutput.log and capture consecutive DLSS submissions (raw color/depth/motion/output) into BepInEx/cache/DSPAAMod/captures. An incomplete pair fails at the end of the trace window. Nothing runs until this shortcut is pressed; captures can be large. Changing this file requires restart.");
				AaSettings initial;
				try
				{
					initial = new AaSettings(technique.Value, model.Value, resolution.Value, fsrSharpness.Value);
				}
				catch (ArgumentOutOfRangeException)
				{
					initial = AaSettings.Default;
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Invalid settings; using safe defaults without overwriting the config.");
				}
				Settings = new SettingsSession(initial);
				Renderer = new RenderController(initial, AcquireNative, delegate(string text)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)text);
				}, delegate(string text)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)text);
				});
				Renderer.Capture = new FrameCapture(Path.Combine(Paths.CachePath, "DSPAAMod", "captures"), delegate(string text)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)text);
				});
				Options = new GraphicsOptions(this);
				harmony = new Harmony("dspaa.mod");
				harmony.PatchAll(typeof(Plugin).Assembly);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"DSPAASR loaded. DLSS and FSR use the selected AA/SR resolution mode; animated objects may exhibit visual artifacts. No driver settings are modified.");
			}
			catch (Exception ex2)
			{
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				Instance = null;
				((BaseUnityPlugin)this).Logger.LogError((object)ex2);
			}
		}

		private NativeBridge AcquireNative()
		{
			if (native == null)
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
				string dataDirectory = Path.Combine(Paths.CachePath, "DSPAAMod");
				native = new NativeBridge(directoryName, dataDirectory);
			}
			return native;
		}

		internal void ApplySettings()
		{
			Settings.Apply();
			technique.Value = Settings.Applied.Technique;
			model.Value = Settings.Applied.Model;
			resolution.Value = Settings.Applied.Resolution;
			fsrSharpness.Value = Settings.Applied.FsrSharpness;
			((BaseUnityPlugin)this).Config.Save();
			Renderer.Configure(Settings.Applied);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("AA settings applied: " + Settings.Applied.Technique.ToString() + ", resolution " + Settings.Applied.Resolution.ToString() + ", model " + Settings.Applied.Model));
		}

		internal void Guard(Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
		}

		private void Update()
		{
			if ((Object)(object)Instance != (Object)(object)this || stopped)
			{
				return;
			}
			Guard(delegate
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				Renderer.Update();
				Options.Update();
				KeyboardShortcut value = captureShortcut.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					if (Settings.Applied.Technique == AaTechnique.Dlss)
					{
						Renderer.RequestCapture();
					}
					else
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)"Select DLSS before requesting a frame capture.");
					}
				}
			});
		}

		private void OnDestroy()
		{
			if (!((Object)(object)Instance != (Object)(object)this) && !stopped)
			{
				stopped = true;
				Guard(delegate
				{
					Renderer.Shutdown();
				});
				Guard(delegate
				{
					Options.Dispose();
				});
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				Instance = null;
			}
		}
	}
}
namespace DSPAAMod.UI
{
	internal sealed class GraphicsOptions : IDisposable
	{
		private static readonly FieldInfo ItemButtonsField = AccessTools.Field(typeof(UIComboBox), "ItemButtons") ?? throw new MissingFieldException(typeof(UIComboBox).FullName, "ItemButtons");

		private readonly Plugin plugin;

		private UIOptionWindow window;

		private UIComboBox technique;

		private UIComboBox resolution;

		private UIComboBox configuration;

		private RectTransform layoutRoot;

		private Vector2 originalContentSize;

		private Vector2 configurationPosition;

		private Vector2 configurationLabelPosition;

		private Vector2 availabilityPosition;

		private Text availabilityLabel;

		private UpscalerAvailability shownAvailability;

		private UpscalerAvailability shownFsrAvailability;

		private float rowStep;

		private bool originalConfigurationLabelActive;

		private readonly Dictionary<RectTransform, Vector2> movedRows = new Dictionary<RectTransform, Vector2>();

		private AaMenuDraft draft;

		private Text aaLabel;

		private Text resolutionLabel;

		private Text configurationLabel;

		private Localizer aaLocalizer;

		private Localizer configurationLocalizer;

		private string originalAaLabel;

		private string originalConfigurationLabel;

		private bool originalAaActive;

		private bool originalFxaaActive;

		private bool originalAaLocalized;

		private bool originalConfigurationLocalized;

		private bool synchronizing;

		private int nativeRefreshMsaa;

		private bool nativeRefreshFxaa;

		private static bool Chinese => (Localization.CurrentLanguageLCID & 0x3FF) == 4;

		public GraphicsOptions(Plugin owner)
		{
			plugin = owner;
		}

		private static int MsaaFromIndex(int index)
		{
			return index switch
			{
				3 => 8, 
				2 => 4, 
				1 => 2, 
				_ => 0, 
			};
		}

		public void Open(UIOptionWindow value)
		{
			plugin.Settings.Open();
			plugin.Renderer.RequestUpscalerSupport();
			if ((Object)(object)window != (Object)(object)value)
			{
				Dispose();
				try
				{
					Install(value);
				}
				catch
				{
					Dispose();
					throw;
				}
			}
			draft = new AaMenuDraft(plugin.Settings.Draft, MsaaFromIndex(window.msaaComp.itemIndex), window.fxaaComp.isOn);
			Refresh();
		}

		private void Install(UIOptionWindow value)
		{
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Expected O, but got Unknown
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0587: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0616: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Expected O, but got Unknown
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Expected O, but got Unknown
			//IL_064e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0658: Expected O, but got Unknown
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			window = value;
			UIComboBox msaaComp = window.msaaComp;
			originalAaActive = ((Component)msaaComp).gameObject.activeSelf;
			originalFxaaActive = ((Component)window.fxaaComp).gameObject.activeSelf;
			if (msaaComp.Items.Count != 4)
			{
				throw new InvalidOperationException("Another mod changed the MSAA list; refusing to overwrite its controls.");
			}
			aaLabel = FindLabel(window, "MSAA");
			configurationLabel = FindLabel(window, "FXAA");
			if (!Object.op_Implicit((Object)(object)aaLabel) || !Object.op_Implicit((Object)(object)configurationLabel))
			{
				throw new InvalidOperationException("Cannot identify the native AA labels by their localization keys.");
			}
			originalAaLabel = aaLabel.text;
			originalConfigurationLabel = configurationLabel.text;
			originalConfigurationLabelActive = ((Component)configurationLabel).gameObject.activeSelf;
			aaLocalizer = ((Component)aaLabel).GetComponent<Localizer>();
			configurationLocalizer = ((Component)configurationLabel).GetComponent<Localizer>();
			if (Object.op_Implicit((Object)(object)aaLocalizer))
			{
				originalAaLocalized = ((Behaviour)aaLocalizer).enabled;
				((Behaviour)aaLocalizer).enabled = false;
			}
			if (Object.op_Implicit((Object)(object)configurationLocalizer))
			{
				originalConfigurationLocalized = ((Behaviour)configurationLocalizer).enabled;
				((Behaviour)configurationLocalizer).enabled = false;
			}
			Transform parent = ((Component)msaaComp).transform.parent;
			Transform parent2 = ((Component)aaLabel).transform.parent;
			if (!((Object)(object)((Component)configurationLabel).transform.parent != (Object)(object)parent2) && !((Object)(object)((Component)window.fxaaComp).transform.parent != (Object)(object)parent) && !((Object)(object)parent.parent != (Object)(object)parent2.parent))
			{
				Transform parent3 = parent.parent;
				RectTransform val = (RectTransform)(object)((parent3 is RectTransform) ? parent3 : null);
				if (val != null)
				{
					layoutRoot = val;
					originalContentSize = val.sizeDelta;
					RectTransform val2 = (RectTransform)((Component)aaLabel).transform;
					RectTransform val3 = (RectTransform)((Component)configurationLabel).transform;
					Rect rect = val2.rect;
					float y = ((Transform)val).InverseTransformPoint(((Transform)val2).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center))).y;
					rect = val3.rect;
					float y2 = ((Transform)val).InverseTransformPoint(((Transform)val3).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center))).y;
					float num = y - y2;
					if (num <= 0f)
					{
						throw new InvalidOperationException("Invalid graphics-row spacing.");
					}
					rowStep = num;
					ShiftRows(parent2, y2, num);
					ShiftRows(parent, y2, num);
					val.sizeDelta = originalContentSize + new Vector2(0f, num);
					technique = Clone(msaaComp, "DSPAAMod Antialiasing");
					resolution = Clone(msaaComp, "DSPAAMod Resolution");
					configuration = Clone(msaaComp, "DSPAAMod Configuration");
					Transform transform = ((Component)resolution).transform;
					transform.localPosition += new Vector3(0f, 0f - num, 0f);
					Transform transform2 = ((Component)configuration).transform;
					transform2.localPosition += new Vector3(0f, -2f * num, 0f);
					configurationPosition = ((RectTransform)((Component)configuration).transform).anchoredPosition;
					configurationLabelPosition = ((RectTransform)((Component)configurationLabel).transform).anchoredPosition;
					resolutionLabel = Object.Instantiate<Text>(configurationLabel, parent2);
					((Object)resolutionLabel).name = "DSPAAMod Resolution Label";
					Transform transform3 = ((Component)resolutionLabel).transform;
					transform3.localPosition += new Vector3(0f, num, 0f);
					Localizer[] components = ((Component)resolutionLabel).GetComponents<Localizer>();
					for (int i = 0; i < components.Length; i++)
					{
						((Behaviour)components[i]).enabled = false;
					}
					availabilityLabel = Object.Instantiate<Text>(aaLabel, (Transform)(object)layoutRoot);
					((Object)availabilityLabel).name = "DSPAASR Availability";
					components = ((Component)availabilityLabel).GetComponents<Localizer>();
					for (int i = 0; i < components.Length; i++)
					{
						((Behaviour)components[i]).enabled = false;
					}
					availabilityLabel.alignment = (TextAnchor)3;
					availabilityLabel.supportRichText = false;
					((Graphic)availabilityLabel).raycastTarget = false;
					availabilityLabel.horizontalOverflow = (HorizontalWrapMode)0;
					availabilityLabel.verticalOverflow = (VerticalWrapMode)0;
					availabilityLabel.resizeTextForBestFit = true;
					availabilityLabel.resizeTextMinSize = 11;
					availabilityLabel.resizeTextMaxSize = 14;
					((Graphic)availabilityLabel).color = new Color(1f, 0.82f, 0.55f, 1f);
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					float num2 = float.PositiveInfinity;
					float num3 = float.NegativeInfinity;
					RectTransform[] array2 = (RectTransform[])(object)new RectTransform[2]
					{
						val2,
						(RectTransform)((Component)technique).transform
					};
					for (int i = 0; i < array2.Length; i++)
					{
						array2[i].GetWorldCorners(array);
						Vector3[] array3 = array;
						foreach (Vector3 val4 in array3)
						{
							float x = ((Transform)layoutRoot).InverseTransformPoint(val4).x;
							num2 = Mathf.Min(num2, x);
							num3 = Mathf.Max(num3, x);
						}
					}
					RectTransform rectTransform = ((Graphic)availabilityLabel).rectTransform;
					Vector2 anchorMin = (rectTransform.anchorMax = layoutRoot.pivot);
					rectTransform.anchorMin = anchorMin;
					rectTransform.pivot = new Vector2(0f, 0.5f);
					((Transform)rectTransform).localScale = Vector3.one;
					rectTransform.sizeDelta = new Vector2(num3 - num2, 2f * num - 4f);
					availabilityPosition = new Vector2(num2, y);
					((Component)msaaComp).gameObject.SetActive(false);
					((Component)window.fxaaComp).gameObject.SetActive(false);
					((UnityEvent)technique.onItemIndexChange).AddListener(new UnityAction(TechniqueChanged));
					((UnityEvent)resolution.onItemIndexChange).AddListener(new UnityAction(ResolutionChanged));
					((UnityEvent)configuration.onItemIndexChange).AddListener(new UnityAction(ConfigurationChanged));
					return;
				}
			}
			throw new InvalidOperationException("Unexpected graphics-row hierarchy; refusing to shift unrelated controls.");
		}

		private void ShiftRows(Transform column, float fromCenter, float distance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0025: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			foreach (Transform item in column)
			{
				object obj = (object)item;
				RectTransform val = (RectTransform)((obj is RectTransform) ? obj : null);
				if (val != null)
				{
					RectTransform obj2 = layoutRoot;
					Rect rect = val.rect;
					if (!(((Transform)obj2).InverseTransformPoint(((Transform)val).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center))).y > fromCenter + 0.5f))
					{
						movedRows.Add(val, val.anchoredPosition);
						val.anchoredPosition += new Vector2(0f, 0f - distance);
					}
				}
			}
		}

		private static UIComboBox Clone(UIComboBox source, string name)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			UIComboBox val = Object.Instantiate<UIComboBox>(source, ((Component)source).transform.parent);
			try
			{
				((Object)val).name = name;
				val.InitItemIndexSelf = false;
				val.CanInput = false;
				val.translated = true;
				val.autoWidth = false;
				val.DoubleClickChange = false;
				val.isDroppedDown = false;
				val.onItemIndexChange = new ChangeEvent();
				val.onSubmit = new SubmitEvent();
				val.Items = new List<string>();
				val.ItemsData = new List<int>();
				Localizer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Localizer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
				foreach (Transform item in (Transform)val.m_DropDownContent)
				{
					Transform val2 = item;
					if (!((Object)(object)val2 == (Object)(object)((Component)val.m_ListItemRes).transform) && !((Object)(object)val2 == (Object)(object)((Component)val.m_EmptyItemRes).transform) && !((Object)(object)val2 == (Object)(object)((Component)val.m_SelectionBG).transform))
					{
						((Component)val2).gameObject.SetActive(false);
						Object.Destroy((Object)(object)((Component)val2).gameObject);
					}
				}
				((Component)val).gameObject.SetActive(true);
				return val;
			}
			catch
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
				throw;
			}
		}

		private static Text FindLabel(UIOptionWindow owner, string key)
		{
			Localizer[] componentsInChildren = ((Component)owner).GetComponentsInChildren<Localizer>(true);
			foreach (Localizer val in componentsInChildren)
			{
				if (AaLabels.Matches(val.stringKey, key) || AaLabels.Matches(((Object)val).name, key))
				{
					Text component = ((Component)val).GetComponent<Text>();
					if (Object.op_Implicit((Object)(object)component))
					{
						return component;
					}
				}
			}
			string text = Localization.Translate(key);
			Text[] componentsInChildren2 = ((Component)owner).GetComponentsInChildren<Text>(true);
			foreach (Text val2 in componentsInChildren2)
			{
				if (val2.text.Trim() == text || AaLabels.Matches(val2.text, key))
				{
					return val2;
				}
			}
			return null;
		}

		private static void SetItems(UIComboBox control, string[] items, int index)
		{
			control.isDroppedDown = false;
			control.Items = new List<string>(items);
			control.ItemsData = new List<int>();
			for (int i = 0; i < items.Length; i++)
			{
				control.ItemsData.Add(i);
			}
			control.UpdateItems();
			control.itemIndex = index;
		}

		private void TechniqueChanged()
		{
			if (!synchronizing && draft != null && Object.op_Implicit((Object)(object)technique) && technique.itemIndex >= 0 && technique.itemIndex <= 5)
			{
				if (!draft.TrySelectTechnique((AaChoice)technique.itemIndex, plugin.Renderer.GetAvailability((AaChoice)technique.itemIndex)))
				{
					Refresh();
					return;
				}
				plugin.Settings.Draft = draft.Settings;
				Refresh();
			}
		}

		private void ResolutionChanged()
		{
			if (!synchronizing && draft != null && Object.op_Implicit((Object)(object)resolution) && draft.ResolutionEnabled && plugin.Renderer.GetAvailability(draft.Choice).Available && resolution.itemIndex >= 0 && resolution.itemIndex <= 4)
			{
				draft.SelectResolution((ResolutionMode)resolution.itemIndex);
				plugin.Settings.Draft = draft.Settings;
			}
		}

		private void ConfigurationChanged()
		{
			if (!synchronizing && draft != null && Object.op_Implicit((Object)(object)configuration) && draft.ConfigurationEnabled && configuration.itemIndex >= 0 && (draft.Choice != AaChoice.Dlss || plugin.Renderer.Availability.Available))
			{
				draft.SelectConfiguration(configuration.itemIndex);
				plugin.Settings.Draft = draft.Settings;
			}
		}

		public void DropdownOpened(UIComboBox control)
		{
			if (Object.op_Implicit((Object)(object)window) && Object.op_Implicit((Object)(object)layoutRoot) && control.isDroppedDown && ((Component)control).transform.IsChildOf((Transform)(object)layoutRoot))
			{
				Transform val = ((Component)control).transform;
				while (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)layoutRoot)
				{
					val.SetAsLastSibling();
					val = val.parent;
				}
			}
		}

		public void BeginNativeRefresh()
		{
			synchronizing = true;
		}

		public void EndNativeRefresh()
		{
			if (Object.op_Implicit((Object)(object)window))
			{
				nativeRefreshMsaa = MsaaFromIndex(window.msaaComp.itemIndex);
				nativeRefreshFxaa = window.fxaaComp.isOn;
			}
			synchronizing = false;
			Refresh();
		}

		public void Update()
		{
			if (Object.op_Implicit((Object)(object)window) && draft != null && (shownAvailability != plugin.Renderer.Availability || shownFsrAvailability != plugin.Renderer.FsrAvailability))
			{
				Refresh();
			}
		}

		public void Refresh()
		{
			if (!Object.op_Implicit((Object)(object)window) || !Object.op_Implicit((Object)(object)technique) || !Object.op_Implicit((Object)(object)resolution) || !Object.op_Implicit((Object)(object)configuration) || draft == null)
			{
				return;
			}
			synchronizing = true;
			try
			{
				aaLabel.text = (Chinese ? "抗锯齿 / 超分辨率" : "AA / Super Resolution");
				resolutionLabel.text = (Chinese ? "超分辨率档位" : "Resolution mode");
				configurationLabel.text = (Chinese ? "配置" : "Configuration");
				shownAvailability = plugin.Renderer.Availability;
				shownFsrAvailability = plugin.Renderer.FsrAvailability;
				SetItems(technique, new string[6]
				{
					Chinese ? "关闭" : "Off",
					"MSAA",
					"FXAA",
					"TAA",
					CapabilityLabel(shownAvailability),
					CapabilityLabel(shownFsrAvailability)
				}, (int)draft.Choice);
				List<Button> obj = (List<Button>)ItemButtonsField.GetValue(technique);
				((Selectable)obj[4]).interactable = shownAvailability.Available;
				((Selectable)obj[5]).interactable = shownFsrAvailability.Available;
				string text = shownAvailability.Describe(Chinese);
				string text2 = shownFsrAvailability.Describe(Chinese);
				availabilityLabel.text = text + ((text.Length > 0 && text2.Length > 0) ? "\n" : "") + text2;
				SetItems(resolution, new string[5]
				{
					(draft.Choice == AaChoice.Fsr) ? "Native AA" : "DLAA",
					Chinese ? "质量" : "Quality",
					Chinese ? "平衡" : "Balanced",
					Chinese ? "性能" : "Performance",
					Chinese ? "超级性能" : "Ultra Performance"
				}, (int)draft.Settings.Resolution);
				string[] items = ((draft.Choice != AaChoice.Dlss) ? ((draft.Choice != AaChoice.Msaa) ? new string[1] { Chinese ? "无" : "None" } : new string[3] { "2×", "4×", "8×" }) : new string[5]
				{
					Chinese ? "推荐" : "Recommended",
					"CNN",
					"Transformer K",
					"Transformer L",
					"Transformer M"
				});
				SetItems(configuration, items, draft.ConfigurationIndex);
				RefreshLayout();
			}
			finally
			{
				synchronizing = false;
			}
		}

		private static string CapabilityLabel(UpscalerAvailability state)
		{
			return state.Name + (state.Available ? "" : ((!state.Pending) ? (Chinese ? "(不可用)" : " (unavailable)") : (Chinese ? "(检测中)" : " (checking)")));
		}

		private void RefreshLayout()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			int num = ((!plugin.Renderer.Availability.Available) ? 2 : 0) + ((!plugin.Renderer.FsrAvailability.Available) ? 2 : 0);
			bool active = num != 0;
			bool available = plugin.Renderer.GetAvailability(draft.Choice).Available;
			bool flag = draft.ResolutionEnabled && available;
			bool flag2 = draft.ConfigurationEnabled && (draft.Choice != AaChoice.Dlss || available);
			((Component)resolution).gameObject.SetActive(flag);
			((Component)resolutionLabel).gameObject.SetActive(flag);
			((Component)configuration).gameObject.SetActive(flag2);
			((Component)configurationLabel).gameObject.SetActive(flag2);
			int num2 = (flag ? 1 : 0) + (flag2 ? 1 : 0);
			int num3 = num2 + num;
			((Graphic)availabilityLabel).rectTransform.sizeDelta = new Vector2(((Graphic)availabilityLabel).rectTransform.sizeDelta.x, (float)Mathf.Max(1, num) * rowStep - 4f);
			((Component)availabilityLabel).gameObject.SetActive(active);
			((Transform)((Graphic)availabilityLabel).rectTransform).localPosition = new Vector3(availabilityPosition.x, availabilityPosition.y - rowStep * ((float)num2 + 0.5f + (float)num * 0.5f), 0f);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, rowStep * (float)(1 - num3));
			foreach (KeyValuePair<RectTransform, Vector2> movedRow in movedRows)
			{
				if (Object.op_Implicit((Object)(object)movedRow.Key))
				{
					movedRow.Key.anchoredPosition = movedRow.Value + val;
				}
			}
			((RectTransform)((Component)configuration).transform).anchoredPosition = configurationPosition + new Vector2(0f, flag ? 0f : rowStep);
			((RectTransform)((Component)configurationLabel).transform).anchoredPosition = configurationLabelPosition + new Vector2(0f, flag ? 0f : rowStep);
			layoutRoot.sizeDelta = originalContentSize - val;
		}

		public void Read(ref GameOption option)
		{
			if (draft != null && Object.op_Implicit((Object)(object)window))
			{
				option.msaa = draft.NativeMsaa;
				option.fxaa = draft.NativeFxaa;
				plugin.Settings.Draft = draft.Settings;
			}
		}

		public void Close()
		{
			plugin.Settings.Cancel();
			draft = null;
		}

		public void Defaults(int tab)
		{
			if (tab == 0)
			{
				plugin.Settings.Defaults();
				draft = new AaMenuDraft(plugin.Settings.Draft, nativeRefreshMsaa, nativeRefreshFxaa);
				Refresh();
			}
		}

		public void Dispose()
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)technique))
			{
				((Component)technique).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)technique).gameObject);
			}
			if (Object.op_Implicit((Object)(object)resolution))
			{
				((Component)resolution).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)resolution).gameObject);
			}
			if (Object.op_Implicit((Object)(object)resolutionLabel))
			{
				((Component)resolutionLabel).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)resolutionLabel).gameObject);
			}
			if (Object.op_Implicit((Object)(object)availabilityLabel))
			{
				((Component)availabilityLabel).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)availabilityLabel).gameObject);
			}
			availabilityLabel = null;
			shownAvailability = (shownFsrAvailability = null);
			foreach (KeyValuePair<RectTransform, Vector2> movedRow in movedRows)
			{
				if (Object.op_Implicit((Object)(object)movedRow.Key))
				{
					movedRow.Key.anchoredPosition = movedRow.Value;
				}
			}
			movedRows.Clear();
			if (Object.op_Implicit((Object)(object)layoutRoot))
			{
				layoutRoot.sizeDelta = originalContentSize;
			}
			layoutRoot = null;
			if (Object.op_Implicit((Object)(object)configuration))
			{
				((Component)configuration).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)configuration).gameObject);
			}
			if (Object.op_Implicit((Object)(object)window))
			{
				((Component)window.msaaComp).gameObject.SetActive(originalAaActive);
				((Component)window.fxaaComp).gameObject.SetActive(originalFxaaActive);
			}
			if (Object.op_Implicit((Object)(object)aaLabel) && originalAaLabel != null)
			{
				aaLabel.text = originalAaLabel;
			}
			if (Object.op_Implicit((Object)(object)configurationLabel) && originalConfigurationLabel != null)
			{
				configurationLabel.text = originalConfigurationLabel;
				((Component)configurationLabel).gameObject.SetActive(originalConfigurationLabelActive);
			}
			if (Object.op_Implicit((Object)(object)aaLocalizer))
			{
				((Behaviour)aaLocalizer).enabled = originalAaLocalized;
			}
			if (Object.op_Implicit((Object)(object)configurationLocalizer))
			{
				((Behaviour)configurationLocalizer).enabled = originalConfigurationLocalized;
			}
			window = null;
			technique = (resolution = (configuration = null));
			aaLabel = (resolutionLabel = (configurationLabel = null));
			aaLocalizer = (configurationLocalizer = null);
			draft = null;
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "_OnOpen")]
	internal static class OptionsOpenPatch
	{
		private static void Postfix(UIOptionWindow __instance)
		{
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.Open(__instance);
			});
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "_OnClose")]
	internal static class OptionsClosePatch
	{
		private static void Postfix()
		{
			Plugin.Instance?.Options.Close();
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "TempOptionToUI")]
	internal static class OptionsRefreshPatch
	{
		private static void Prefix()
		{
			Plugin.Instance?.Options.BeginNativeRefresh();
		}

		private static void Postfix()
		{
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.EndNativeRefresh();
			});
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "UIToTempOption")]
	internal static class OptionsReadPatch
	{
		private static void Postfix(ref GameOption ___tempOption)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			GameOption value = ___tempOption;
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.Read(ref value);
			});
			___tempOption = value;
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "ApplyOptions")]
	internal static class OptionsApplyPatch
	{
		private static void Prefix(ref GameOption ___tempOption)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			GameOption value = ___tempOption;
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.Read(ref value);
			});
			___tempOption = value;
		}

		private static void Postfix()
		{
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.ApplySettings();
			});
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "OnLanguageChange")]
	internal static class OptionsLanguagePatch
	{
		private static void Postfix()
		{
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.Refresh();
			});
		}
	}
	[HarmonyPatch(typeof(UIComboBox), "OnPopButtonClick")]
	internal static class AaDropdownPatch
	{
		private static void Postfix(UIComboBox __instance)
		{
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.DropdownOpened(__instance);
			});
		}
	}
	[HarmonyPatch(typeof(UIOptionWindow), "OnRevertButtonClick")]
	internal static class OptionsDefaultsPatch
	{
		private static void Postfix(int idx)
		{
			Plugin.Instance?.Guard(delegate
			{
				Plugin.Instance.Options.Defaults(idx);
			});
		}
	}
}
namespace DSPAAMod.Interop
{
	public struct NativeFrame
	{
		public uint Size;

		public uint Version;

		public ulong Camera;

		public ulong Frame;

		public IntPtr Color;

		public IntPtr Output;

		public IntPtr Depth;

		public IntPtr Motion;

		public uint Width;

		public uint Height;

		public uint Preset;

		public uint Flags;

		public float JitterX;

		public float JitterY;

		public float MotionScaleX;

		public float MotionScaleY;

		public float FrameTimeMilliseconds;

		public uint Reserved;

		public uint OutputWidth;

		public uint OutputHeight;

		public uint Quality;

		public uint Reserved2;
	}
	public struct NativeFsrParameters
	{
		public uint Size;

		public float CameraNear;

		public float CameraFar;

		public float VerticalFov;

		public float PreExposure;

		public float ViewSpaceToMeters;

		public float Sharpness;

		public uint Reserved;

		public IntPtr OpaqueColor;
	}
	public struct NativeFsrOptimalSettings
	{
		public NativeOptimalSettings Settings;

		public uint JitterPhases;
	}
	public struct NativeStatus
	{
		public uint Size;

		public int Result;

		public ulong Frame;

		public uint RequestedPreset;

		public uint ObservedPreset;

		public uint Verification;

		public uint Reserved;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
		public byte[] MessageBytes;

		public string Message
		{
			get
			{
				if (MessageBytes == null)
				{
					return string.Empty;
				}
				int num = Array.IndexOf(MessageBytes, (byte)0);
				return Encoding.UTF8.GetString(MessageBytes, 0, (num < 0) ? MessageBytes.Length : num);
			}
		}
	}
	public struct NativeOptimalSettings
	{
		public uint Size;

		public int Result;

		public uint OutputWidth;

		public uint OutputHeight;

		public uint Quality;

		public uint OptimalWidth;

		public uint OptimalHeight;

		public uint MinWidth;

		public uint MinHeight;

		public uint MaxWidth;

		public uint MaxHeight;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
		public byte[] MessageBytes;

		public string Message
		{
			get
			{
				if (MessageBytes == null)
				{
					return string.Empty;
				}
				int num = Array.IndexOf(MessageBytes, (byte)0);
				return Encoding.UTF8.GetString(MessageBytes, 0, (num < 0) ? MessageBytes.Length : num);
			}
		}
	}
	public struct NativeSupport
	{
		public uint Size;

		public int Result;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
		public byte[] MessageBytes;

		public string Message
		{
			get
			{
				if (MessageBytes == null)
				{
					return string.Empty;
				}
				int num = Array.IndexOf(MessageBytes, (byte)0);
				return Encoding.UTF8.GetString(MessageBytes, 0, (num < 0) ? MessageBytes.Length : num);
			}
		}
	}
	public sealed class NativeBridge
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate uint Abi();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
		private delegate int Initialize(string runtime, string data);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr GetEvent();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueFrame(ref NativeFrame frame);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueRelease(ulong camera);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueShutdown();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void CancelCommand(IntPtr token);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate int ReadStatus(ulong camera, ref NativeStatus status);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueOptimal(ulong camera, IntPtr deviceResource, uint width, uint height, uint quality);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate int ReadOptimal(ulong camera, ref NativeOptimalSettings settings);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueSupport(IntPtr deviceResource);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate int ReadSupport(IntPtr token, ref NativeSupport support);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueFsrFrame(ref NativeFrame frame, ref NativeFsrParameters parameters);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueBackendSupport(IntPtr resource, uint backend);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr QueueBackendOptimal(ulong camera, IntPtr resource, uint width, uint height, uint quality, uint backend);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate int ReadFsrOptimal(ulong camera, ref NativeFsrOptimalSettings result);

		private readonly IntPtr module;

		private readonly QueueFrame queueFrame;

		private readonly QueueRelease queueRelease;

		private readonly QueueShutdown queueShutdown;

		private readonly CancelCommand cancel;

		private readonly ReadStatus readStatus;

		private readonly QueueOptimal queueOptimal;

		private readonly ReadOptimal readOptimal;

		private readonly QueueSupport queueSupport;

		private readonly ReadSupport readSupport;

		private readonly QueueFsrFrame queueFsrFrame;

		private readonly QueueBackendSupport queueBackendSupport;

		private readonly QueueBackendOptimal queueBackendOptimal;

		private readonly ReadFsrOptimal readFsrOptimal;

		public IntPtr RenderEvent { get; }

		public static uint FrameSize => (uint)Marshal.SizeOf(typeof(NativeFrame));

		public static uint StatusSize => (uint)Marshal.SizeOf(typeof(NativeStatus));

		public static uint OptimalSize => (uint)Marshal.SizeOf(typeof(NativeOptimalSettings));

		public static uint SupportSize => (uint)Marshal.SizeOf(typeof(NativeSupport));

		public static uint FsrParametersSize => (uint)Marshal.SizeOf(typeof(NativeFsrParameters));

		public static uint FsrOptimalSize => (uint)Marshal.SizeOf(typeof(NativeFsrOptimalSettings));

		[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern IntPtr LoadLibraryEx(string name, IntPtr file, uint flags);

		[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
		private static extern IntPtr GetProcAddress(IntPtr module, string name);

		public NativeBridge(string directory, string dataDirectory)
		{
			if (!Environment.Is64BitProcess)
			{
				throw new PlatformNotSupportedException("DSPAAMod requires x64.");
			}
			module = LoadLibraryEx(Path.Combine(directory, "DSPAANative.dll"), IntPtr.Zero, 4352u);
			if (module == IntPtr.Zero)
			{
				throw new Win32Exception(Marshal.GetLastWin32Error(), "Cannot load DSPAANative.dll.");
			}
			if (Get<Abi>("DspAaGetAbiVersion")() != 2 || FrameSize != 112 || StatusSize != 288 || OptimalSize != 300 || SupportSize != 264 || FsrParametersSize != 40 || FsrOptimalSize != 304)
			{
				throw new InvalidOperationException("Native/managed DSPAAMod ABI mismatch.");
			}
			queueFrame = Get<QueueFrame>("DspAaQueueFrame");
			queueRelease = Get<QueueRelease>("DspAaQueueRelease");
			queueShutdown = Get<QueueShutdown>("DspAaQueueShutdown");
			cancel = Get<CancelCommand>("DspAaCancel");
			readStatus = Get<ReadStatus>("DspAaGetStatus");
			queueOptimal = Get<QueueOptimal>("DspAaQueueOptimalSettings");
			readOptimal = Get<ReadOptimal>("DspAaGetOptimalSettings");
			queueSupport = Get<QueueSupport>("DspAaQueueSupport");
			readSupport = Get<ReadSupport>("DspAaGetSupport");
			queueFsrFrame = Get<QueueFsrFrame>("DspAaQueueFsrFrame");
			queueBackendSupport = Get<QueueBackendSupport>("DspAaQueueSupportForBackend");
			queueBackendOptimal = Get<QueueBackendOptimal>("DspAaQueueOptimalSettingsForBackend");
			readFsrOptimal = Get<ReadFsrOptimal>("DspAaGetFsrOptimalSettings");
			RenderEvent = Get<GetEvent>("DspAaGetRenderEvent")();
			if (RenderEvent == IntPtr.Zero || Get<Initialize>("DspAaInitialize")(directory, dataDirectory) != 1)
			{
				throw new InvalidOperationException("Native bridge initialization failed; check runtime path and log permissions.");
			}
		}

		private T Get<T>(string name) where T : Delegate
		{
			IntPtr procAddress = GetProcAddress(module, name);
			if (procAddress == IntPtr.Zero)
			{
				throw new EntryPointNotFoundException(name);
			}
			return (T)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T));
		}

		public IntPtr Submit(ref NativeFrame frame)
		{
			frame.Size = FrameSize;
			frame.Version = 2u;
			return queueFrame(ref frame);
		}

		public IntPtr SubmitFsr(ref NativeFrame frame, ref NativeFsrParameters parameters)
		{
			frame.Size = FrameSize;
			frame.Version = 2u;
			parameters.Size = FsrParametersSize;
			return queueFsrFrame(ref frame, ref parameters);
		}

		public IntPtr RequestOptimal(ulong camera, IntPtr resource, uint width, uint height, uint quality, uint backend)
		{
			return queueBackendOptimal(camera, resource, width, height, quality, backend);
		}

		public bool TryGetFsrOptimal(ulong camera, out NativeFsrOptimalSettings result)
		{
			result = new NativeFsrOptimalSettings
			{
				Settings = new NativeOptimalSettings
				{
					Size = FsrOptimalSize,
					MessageBytes = new byte[256]
				}
			};
			return readFsrOptimal(camera, ref result) == 1;
		}

		public IntPtr RequestSupport(IntPtr resource, uint backend)
		{
			return queueBackendSupport(resource, backend);
		}

		public IntPtr RequestOptimal(ulong camera, IntPtr deviceResource, uint width, uint height, uint quality)
		{
			return queueOptimal(camera, deviceResource, width, height, quality);
		}

		public bool TryGetOptimal(ulong camera, out NativeOptimalSettings result)
		{
			result = new NativeOptimalSettings
			{
				Size = OptimalSize,
				MessageBytes = new byte[256]
			};
			return readOptimal(camera, ref result) == 1;
		}

		public IntPtr RequestSupport(IntPtr deviceResource)
		{
			return queueSupport(deviceResource);
		}

		public bool TryGetSupport(IntPtr token, out NativeSupport result)
		{
			result = new NativeSupport
			{
				Size = SupportSize,
				MessageBytes = new byte[256]
			};
			return readSupport(token, ref result) == 1;
		}

		public IntPtr Release(ulong camera)
		{
			return queueRelease(camera);
		}

		public IntPtr Shutdown()
		{
			return queueShutdown();
		}

		public void Cancel(IntPtr token)
		{
			if (token != IntPtr.Zero)
			{
				cancel(token);
			}
		}

		public bool TryGetStatus(ulong camera, out NativeStatus status)
		{
			status = new NativeStatus
			{
				Size = StatusSize,
				MessageBytes = new byte[256]
			};
			return readStatus(camera, ref status) == 1;
		}
	}
}
namespace DSPAAMod.Game
{
	internal sealed class FrameCapture
	{
		private sealed class Resource
		{
			public string Name;

			public string File;

			public string Error;

			public string Hash;

			public int Width;

			public int Height;

			public readonly Dictionary<string, string> Metadata = new Dictionary<string, string>();

			public byte[] Bytes;

			public bool Claimed;
		}

		private sealed class Frame
		{
			public NativeFrame Native;

			public int UnityFrame;

			public readonly Dictionary<string, string> Metadata = new Dictionary<string, string>();

			public readonly List<Resource> Resources = new List<Resource>();
		}

		private sealed class Group
		{
			public string Id;

			public string Directory;

			public RenderTargets Targets;

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

			public readonly List<string> Errors = new List<string>();

			public int Pending;

			public bool Sealed;

			public bool Writing;
		}

		private readonly string directory;

		private readonly Action<string> log;

		private readonly object gate = new object();

		private readonly Dictionary<RenderTargets, int> pending = new Dictionary<RenderTargets, int>();

		private Group active;

		public FrameCapture(string directory, Action<string> log)
		{
			this.directory = directory;
			this.log = log;
		}

		public bool Request()
		{
			lock (gate)
			{
				if (active != null)
				{
					Log("Frame capture request ignored: a capture is already armed or in progress.");
					return false;
				}
				try
				{
					string id = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss-fff", CultureInfo.InvariantCulture) + "-" + Guid.NewGuid().ToString("N");
					Group obj = new Group
					{
						Id = id,
						Directory = Path.Combine(directory, id)
					};
					if (Directory.Exists(obj.Directory))
					{
						throw new IOException("Capture directory already exists.");
					}
					Directory.CreateDirectory(obj.Directory);
					WriteDocument(Path.Combine(obj.Directory, "request.xml"), "captureRequest", delegate(XmlWriter writer)
					{
						Value(writer, "id", id);
						Value(writer, "requestedUtc", DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture));
						Value(writer, "frameCount", 2);
						Value(writer, "state", "armed; result.xml is the terminal record");
					});
					active = obj;
					if (!SystemInfo.supportsAsyncGPUReadback)
					{
						Fail(obj, "AsyncGPUReadback is unsupported on this device.");
						FinishIfReady(obj);
					}
					else
					{
						Log("Frame capture armed for two consecutive submissions from the first captured camera: " + obj.Directory);
					}
					return true;
				}
				catch (Exception ex)
				{
					Log("Cannot arm frame capture: " + ex.Message);
					if (active != null)
					{
						Fail(active, "Cannot finish arming capture: " + ex.Message);
						FinishIfReady(active);
					}
					return false;
				}
			}
		}

		public bool IsBusy(RenderTargets targets)
		{
			lock (gate)
			{
				int value;
				return targets != null && pending.TryGetValue(targets, out value) && value != 0;
			}
		}

		public void Cancel(string reason)
		{
			lock (gate)
			{
				if (active != null && !active.Sealed)
				{
					Fail(active, "Capture cancelled: " + reason);
					FinishIfReady(active);
				}
			}
		}

		public void Cancel(RenderTargets targets, string reason)
		{
			lock (gate)
			{
				if (active != null && active.Targets == targets)
				{
					Cancel(reason);
				}
			}
		}

		public void EnqueueIfRequested(NativeFrame native, RenderTargets targets, Camera camera, Matrix4x4 renderedProjection, int deferredWorldTextCount)
		{
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_0525: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Expected I4, but got Unknown
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Invalid comparison between Unknown and I4
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			lock (gate)
			{
				Group group = active;
				if (group == null || group.Sealed)
				{
					return;
				}
				if (group.Frames.Count != 0)
				{
					Frame frame = group.Frames[0];
					int frameCount = Time.frameCount;
					if (native.Camera != frame.Native.Camera && frameCount <= frame.UnityFrame + 1)
					{
						return;
					}
					if (native.Camera != frame.Native.Camera || targets != group.Targets || native.Frame != frame.Native.Frame + 1 || frameCount != frame.UnityFrame + 1)
					{
						Fail(group, "Expected the same camera/targets on consecutive native and Unity frames; got native " + frame.Native.Frame + " -> " + native.Frame + ", Unity " + frame.UnityFrame + " -> " + frameCount + ".");
						FinishIfReady(group);
						return;
					}
				}
				try
				{
					if (targets == null || (Object)(object)camera == (Object)null)
					{
						throw new InvalidOperationException("Capture has no live targets/camera.");
					}
					Frame frame2 = new Frame
					{
						Native = native
					};
					SnapshotFrame(frame2, camera, renderedProjection, deferredWorldTextCount);
					RenderTexture[] array = (RenderTexture[])(object)new RenderTexture[4] { targets.Color, targets.Depth, targets.Motion, targets.Output };
					string[] array2 = new string[4] { "color", "depth", "motion", "output" };
					for (int i = 0; i < array.Length; i++)
					{
						RenderTexture val = array[i];
						if (!Object.op_Implicit((Object)(object)val) || !val.IsCreated())
						{
							throw new InvalidOperationException(array2[i] + " texture is not created.");
						}
						if (!SystemInfo.IsFormatSupported(val.graphicsFormat, (FormatUsage)9))
						{
							throw new NotSupportedException(array2[i] + " format does not support unconverted readback: " + ((object)val.graphicsFormat/*cast due to .constrained prefix*/).ToString());
						}
						Resource resource = new Resource();
						resource.Name = array2[i];
						resource.File = "frame-" + group.Frames.Count + "-" + array2[i] + ".raw";
						resource.Width = ((Texture)val).width;
						resource.Height = ((Texture)val).height;
						Resource resource2 = resource;
						Add(resource2.Metadata, "width", ((Texture)val).width);
						Add(resource2.Metadata, "height", ((Texture)val).height);
						Add(resource2.Metadata, "volumeDepth", val.volumeDepth);
						Add(resource2.Metadata, "dimension", ((Texture)val).dimension);
						Add(resource2.Metadata, "renderTextureFormat", val.format);
						Add(resource2.Metadata, "graphicsFormat", val.graphicsFormat);
						Add(resource2.Metadata, "graphicsFormatValue", (int)val.graphicsFormat);
						Add(resource2.Metadata, "antiAliasing", val.antiAliasing);
						Add(resource2.Metadata, "sRGB", val.sRGB);
						Add(resource2.Metadata, "mip", 0);
						if ((int)((Texture)val).dimension != 2 || val.volumeDepth != 1)
						{
							throw new NotSupportedException("Capture expects single-layer 2D render textures.");
						}
						frame2.Resources.Add(resource2);
					}
					group.Targets = targets;
					group.Frames.Add(frame2);
					group.Sealed = group.Frames.Count == 2;
					group.Pending += array.Length;
					pending.TryGetValue(targets, out var value);
					pending[targets] = value + array.Length;
					for (int j = 0; j < array.Length; j++)
					{
						Resource resource3 = frame2.Resources[j];
						try
						{
							AsyncGPUReadbackRequest request = AsyncGPUReadback.Request((Texture)(object)array[j], 0, (Action<AsyncGPUReadbackRequest>)delegate(AsyncGPUReadbackRequest completed)
							{
								//IL_0027: Unknown result type (might be due to invalid IL or missing references)
								Complete(group, targets, resource3, completed, null);
							});
							if (((AsyncGPUReadbackRequest)(ref request)).hasError)
							{
								Complete(group, targets, resource3, request, "GPU readback request failed.");
							}
						}
						catch (Exception ex)
						{
							Complete(group, targets, resource3, default(AsyncGPUReadbackRequest), "Cannot submit readback: " + ex.Message);
						}
					}
				}
				catch (Exception ex2)
				{
					Fail(group, "Cannot capture submitted frame: " + ex2.Message);
					FinishIfReady(group);
				}
			}
		}

		private void Complete(Group group, RenderTargets targets, Resource resource, AsyncGPUReadbackRequest request, string failure)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			lock (gate)
			{
				if (resource.Claimed)
				{
					return;
				}
				resource.Claimed = true;
			}
			try
			{
				if (failure != null)
				{
					throw new InvalidOperationException(failure);
				}
				if (!((AsyncGPUReadbackRequest)(ref request)).done || ((AsyncGPUReadbackRequest)(ref request)).hasError)
				{
					throw new InvalidOperationException("GPU readback did not complete successfully.");
				}
				Add(resource.Metadata, "readbackWidth", ((AsyncGPUReadbackRequest)(ref request)).width);
				Add(resource.Metadata, "readbackHeight", ((AsyncGPUReadbackRequest)(ref request)).height);
				Add(resource.Metadata, "readbackDepth", ((AsyncGPUReadbackRequest)(ref request)).depth);
				Add(resource.Metadata, "layerCount", ((AsyncGPUReadbackRequest)(ref request)).layerCount);
				Add(resource.Metadata, "layerDataSize", ((AsyncGPUReadbackRequest)(ref request)).layerDataSize);
				if (((AsyncGPUReadbackRequest)(ref request)).layerCount != 1 || ((AsyncGPUReadbackRequest)(ref request)).depth != 1 || ((AsyncGPUReadbackRequest)(ref request)).width != resource.Width || ((AsyncGPUReadbackRequest)(ref request)).height != resource.Height)
				{
					throw new InvalidOperationException("Readback dimensions do not match the snapshotted 2D texture.");
				}
				NativeArray<byte> data = ((AsyncGPUReadbackRequest)(ref request)).GetData<byte>(0);
				if (data.Length == 0)
				{
					throw new InvalidOperationException("Readback returned no bytes.");
				}
				resource.Bytes = new byte[data.Length];
				data.CopyTo(resource.Bytes);
			}
			catch (Exception ex)
			{
				resource.Error = ex.Message;
			}
			finally
			{
				lock (gate)
				{
					if (resource.Error != null)
					{
						Fail(group, resource.File + ": " + resource.Error);
					}
					group.Pending--;
					if (--pending[targets] == 0)
					{
						pending.Remove(targets);
					}
					FinishIfReady(group);
				}
			}
		}

		private void FinishIfReady(Group group)
		{
			if (!group.Sealed || group.Pending != 0 || group.Writing)
			{
				return;
			}
			group.Writing = true;
			group.Targets = null;
			try
			{
				Task.Run(delegate
				{
					Persist(group);
				});
			}
			catch (Exception ex)
			{
				Log("Cannot schedule capture persistence; request.xml remains incomplete: " + ex.Message);
				if (active == group)
				{
					active = null;
				}
			}
		}

		private void Persist(Group group)
		{
			try
			{
				for (int i = 0; i < group.Frames.Count; i++)
				{
					Frame frame = group.Frames[i];
					foreach (Resource resource in frame.Resources)
					{
						if (resource.Bytes == null)
						{
							continue;
						}
						try
						{
							using (FileStream fileStream = new FileStream(Path.Combine(group.Directory, resource.File), FileMode.CreateNew, FileAccess.Write, FileShare.Read))
							{
								fileStream.Write(resource.Bytes, 0, resource.Bytes.Length);
							}
							using (SHA256 sHA = SHA256.Create())
							{
								resource.Hash = BitConverter.ToString(sHA.ComputeHash(resource.Bytes)).Replace("-", "");
							}
							Add(resource.Metadata, "byteLength", resource.Bytes.Length);
						}
						catch (Exception ex)
						{
							resource.Error = "Cannot persist raw data: " + ex.Message;
							group.Errors.Add(resource.File + ": " + resource.Error);
						}
						finally
						{
							resource.Bytes = null;
						}
					}
					try
					{
						WriteDocument(Path.Combine(group.Directory, "frame-" + i + ".xml"), "submittedFrame", delegate(XmlWriter writer)
						{
							foreach (KeyValuePair<string, string> metadatum in frame.Metadata)
							{
								Value(writer, metadatum.Key, metadatum.Value);
							}
							foreach (Resource resource2 in frame.Resources)
							{
								writer.WriteStartElement("resource");
								writer.WriteAttributeString("name", resource2.Name);
								Value(writer, "file", resource2.File);
								Value(writer, "success", resource2.Error == null && resource2.Hash != null);
								Value(writer, "sha256", resource2.Hash ?? "");
								Value(writer, "error", resource2.Error ?? "");
								foreach (KeyValuePair<string, string> metadatum2 in resource2.Metadata)
								{
									Value(writer, metadatum2.Key, metadatum2.Value);
								}
								writer.WriteEndElement();
							}
						});
					}
					catch (Exception ex2)
					{
						group.Errors.Add("Cannot persist frame metadata: " + ex2.Message);
					}
				}
				bool success = group.Frames.Count == 2 && group.Errors.Count == 0;
				WriteDocument(Path.Combine(group.Directory, "result.xml"), "captureResult", delegate(XmlWriter writer)
				{
					Value(writer, "id", group.Id);
					Value(writer, "completedUtc", DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture));
					Value(writer, "success", success);
					Value(writer, "capturedFrames", group.Frames.Count);
					Value(writer, "expectedFrames", 2);
					Value(writer, "meaning", "Success means raw readback and persistence only; correlate NGX logs to verify evaluation/model.");
					foreach (string error in group.Errors)
					{
						Value(writer, "error", error);
					}
				});
				Log("Frame capture " + (success ? "complete: " : "failed; see result.xml: ") + group.Directory);
				foreach (string error2 in group.Errors)
				{
					Log("Frame capture: " + error2);
				}
			}
			catch (Exception ex3)
			{
				Log("Cannot write terminal capture result at " + group.Directory + ": " + ex3.Message);
			}
			finally
			{
				lock (gate)
				{
					if (active == group)
					{
						active = null;
					}
				}
			}
		}

		private static void SnapshotFrame(Frame frame, Camera camera, Matrix4x4 renderedProjection, int deferredWorldTextCount)
		{
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, string> metadata = frame.Metadata;
			NativeFrame native = frame.Native;
			Add(metadata, "capturedUtc", DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture));
			Add(metadata, "nativeAbiVersion", native.Version);
			Add(metadata, "nativeCameraId", native.Camera);
			Add(metadata, "nativeFrameId", native.Frame);
			frame.UnityFrame = Time.frameCount;
			Add(metadata, "unityFrameCount", frame.UnityFrame);
			Add(metadata, "unityTime", Time.time);
			Add(metadata, "unityUnscaledTime", Time.unscaledTime);
			Add(metadata, "unityRealtimeSinceStartup", Time.realtimeSinceStartup);
			Add(metadata, "unityUnscaledDeltaTime", Time.unscaledDeltaTime);
			Add(metadata, "deferredWorldTextCount", deferredWorldTextCount);
			Add(metadata, "worldTextObservation", "When deferredWorldTextCount is nonzero, navigation glyphs are excluded from these NGX inputs/output and drawn afterward into the temporal resolve destination.");
			Add(metadata, "cameraInstanceId", ((Object)camera).GetInstanceID());
			Add(metadata, "cameraName", ((Object)camera).name);
			Add(metadata, "inputWidth", native.Width);
			Add(metadata, "inputHeight", native.Height);
			Add(metadata, "outputWidth", native.OutputWidth);
			Add(metadata, "outputHeight", native.OutputHeight);
			Add(metadata, "requestedPresetValue", native.Preset);
			Add(metadata, "requestedPreset", (native.Preset >= 1 && native.Preset <= 26) ? ((char)(65 + native.Preset - 1)).ToString() : "unknown");
			Add(metadata, "observedModel", "unknown; correlate the NGX log, not the requested preset");
			Add(metadata, "qualityValue", native.Quality);
			Add(metadata, "flags", native.Flags);
			Add(metadata, "reset", (native.Flags & 4) != 0);
			Add(metadata, "jitterX", native.JitterX);
			Add(metadata, "jitterY", native.JitterY);
			Add(metadata, "motionScaleX", native.MotionScaleX);
			Add(metadata, "motionScaleY", native.MotionScaleY);
			Add(metadata, "frameTimeMilliseconds", native.FrameTimeMilliseconds);
			Add(metadata, "cameraPosition", Vector(((Component)camera).transform.position));
			Quaternion rotation = ((Component)camera).transform.rotation;
			Add(metadata, "cameraRotationXYZW", Join(rotation.x, rotation.y, rotation.z, rotation.w));
			Add(metadata, "worldToCameraMatrixRowMajor", Matrix(camera.worldToCameraMatrix));
			Add(metadata, "cameraToWorldMatrixRowMajor", Matrix(camera.cameraToWorldMatrix));
			Add(metadata, "projectionMatrixRowMajor", Matrix(camera.projectionMatrix));
			Add(metadata, "nonJitteredProjectionMatrixRowMajor", Matrix(camera.nonJitteredProjectionMatrix));
			Add(metadata, "renderProjectionMatrixRowMajor", Matrix(renderedProjection));
			Add(metadata, "gpuProjectionForRenderTextureRowMajor", Matrix(GL.GetGPUProjectionMatrix(renderedProjection, true)));
			Add(metadata, "projectionObservation", "Camera projection is snapshotted at submission after OnPostRender; renderProjection preserves the matrix used for this world draw.");
			Add(metadata, "rawEncoding", "Unconverted graphicsFormat bytes from mip0/layer0; no vertical flip or channel conversion.");
			Add(metadata, "littleEndianHost", BitConverter.IsLittleEndian);
		}

		private static string Vector(Vector3 value)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			return Join(value.x, value.y, value.z);
		}

		private static string Join(params float[] values)
		{
			return string.Join(" ", Array.ConvertAll(values, (float v) => v.ToString("R", CultureInfo.InvariantCulture)));
		}

		private static string Matrix(Matrix4x4 value)
		{
			float[] array = new float[16];
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 4; j++)
				{
					array[i * 4 + j] = ((Matrix4x4)(ref value))[i, j];
				}
			}
			return Join(array);
		}

		private static string Format(object value)
		{
			if (value is bool)
			{
				if (!(bool)value)
				{
					return "false";
				}
				return "true";
			}
			if (value is float num)
			{
				return num.ToString("R", CultureInfo.InvariantCulture);
			}
			if (value is double num2)
			{
				return num2.ToString("R", CultureInfo.InvariantCulture);
			}
			return Convert.ToString(value, CultureInfo.InvariantCulture);
		}

		private static void Add(IDictionary<string, string> data, string name, object value)
		{
			data.Add(name, Format(value));
		}

		private static void Value(XmlWriter writer, string name, object value)
		{
			writer.WriteElementString(name, Format(value));
		}

		private static void WriteDocument(string path, string root, Action<XmlWriter> write)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			using FileStream fileStream = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.Read);
			XmlWriter val = XmlWriter.Create((Stream)fileStream, new XmlWriterSettings
			{
				Indent = true,
				Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)
			});
			try
			{
				val.WriteStartDocument();
				val.WriteStartElement(root);
				write(val);
				val.WriteEndElement();
				val.WriteEndDocument();
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private void Fail(Group group, string error)
		{
			group.Errors.Add(error);
			group.Sealed = true;
			Log("Frame capture: " + error);
		}

		private void Log(string message)
		{
			try
			{
				log?.Invoke(message);
			}
			catch
			{
			}
		}
	}
	internal sealed class RenderController
	{
		internal sealed class CameraState
		{
			public Camera Camera;

			public PostProcessingBehaviour Behaviour;

			public ulong Key;

			public RenderTargets Targets;

			public RenderTexture SizingAnchor;

			public RenderTexture OriginalTarget;

			public RenderTexture ImageResult;

			public SrPresentation Presenter;

			public CommandBuffer OpaqueCapture;

			public readonly WorldTextOverlay WorldText = new WorldTextOverlay();

			public bool ReportedWorldText;

			public int WorldTextFrame = -1;

			public int RequestedWidth;

			public int RequestedHeight;

			public bool QueryIssued;

			public bool TargetOverridden;

			public bool SrThisRender;

			public bool InputsCopied;

			public Matrix4x4 AppliedProjection;

			public uint Phase;

			public ulong Frame;

			public uint ReportedPreset;

			public int LastFrame = -1;

			public int Scene = -1;

			public int Profile;

			public Vector3 Position;

			public Quaternion Rotation;

			public Matrix4x4 Projection;

			public JitterSample Jitter;

			public bool Reset = true;

			public bool Faulted;

			public bool Prepared;

			public bool JitterApplied;

			public bool Overridden;

			public bool OriginalMsaa;

			public bool OriginalTransparentJitter;

			public AntialiasingModel Model;

			public Settings OriginalSettings;

			public bool OriginalEnabled;
		}

		internal sealed class ImageScope
		{
			public CameraState State;

			public RenderTexture OriginalDestination;

			public RenderTexture Target;

			public RenderTexture Source;

			public bool TemporalStack;
		}

		private sealed class SupportQuery
		{
			public UpscalerAvailability Availability;

			public RenderTexture Anchor;

			public IntPtr Token;
		}

		private readonly Dictionary<RenderTexture, CameraState> imageSources = new Dictionary<RenderTexture, CameraState>();

		private readonly Dictionary<Camera, CameraState> cameras = new Dictionary<Camera, CameraState>();

		private readonly List<CameraState> retired = new List<CameraState>();

		private readonly Action<string> report;

		private readonly Action<string> information;

		private readonly Func<NativeBridge> acquireNative;

		private readonly Action<TaaComponent, Vector2> setJitter;

		private NativeBridge native;

		private readonly SupportQuery[] supportQueries = new SupportQuery[2];

		private bool supportRequested;

		private ulong nextKey;

		private AaSettings settings;

		private int diagnosticThrough = -1;

		private static readonly FieldInfo ContextField = AccessTools.Field(typeof(PostProcessingBehaviour), "m_Context");

		public FrameCapture Capture { get; set; }

		public UpscalerAvailability Availability => supportQueries[0].Availability;

		public UpscalerAvailability FsrAvailability => supportQueries[1].Availability;

		private bool FsrSelected => settings.Technique == AaTechnique.Fsr;

		private UpscalerAvailability ActiveAvailability
		{
			get
			{
				if (!FsrSelected)
				{
					return Availability;
				}
				return FsrAvailability;
			}
		}

		private string BackendName
		{
			get
			{
				if (!FsrSelected)
				{
					return "DLSS";
				}
				return "FSR";
			}
		}

		private bool DiagnosticActive
		{
			get
			{
				if (diagnosticThrough >= 0)
				{
					return Time.frameCount <= diagnosticThrough;
				}
				return false;
			}
		}

		public string Status { get; private set; } = "Original game AA; DLAA not enabled.";

		public UpscalerAvailability GetAvailability(AaChoice choice)
		{
			if (choice != AaChoice.Fsr)
			{
				return Availability;
			}
			return FsrAvailability;
		}

		public void RequestCapture()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			if (diagnosticThrough < 0 && Capture != null && Capture.Request())
			{
				diagnosticThrough = Time.frameCount + 1;
				Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(TraceCameraCull));
				Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(TraceCameraPost));
				TraceOverview("requested");
			}
		}

		private void TraceCameraCull(Camera camera)
		{
			TraceStage("camera.preCull", camera);
		}

		private void TraceCameraPost(Camera camera)
		{
			TraceStage("camera.postRender", camera);
		}

		private void FinishDiagnostic()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (diagnosticThrough >= 0)
			{
				Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(TraceCameraCull));
				Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(TraceCameraPost));
				diagnosticThrough = -1;
				TraceOverview("window-complete");
				Capture?.Cancel("The two-frame diagnostic window ended without two consecutive DLSS submissions; inspect PipelineTrace in LogOutput.log.");
			}
		}

		private void TraceOverview(string phase)
		{
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				information("PipelineTrace " + phase + " unityFrame=" + Time.frameCount + " scene=" + GameCamera.sceneIndex + " planet=" + ((GameMain.localPlanet == null) ? "space" : GameMain.localPlanet.id.ToString()) + " selected=" + settings.Technique.ToString() + "/" + settings.Resolution.ToString() + " status=" + Status);
				Camera[] allCameras = Camera.allCameras;
				foreach (Camera val in allCameras)
				{
					List<string> list = new List<string>();
					MonoBehaviour[] components = ((Component)val).GetComponents<MonoBehaviour>();
					foreach (MonoBehaviour val2 in components)
					{
						if (Object.op_Implicit((Object)(object)val2))
						{
							list.Add(((object)val2).GetType().FullName + ":enabled=" + ((Behaviour)val2).enabled);
						}
					}
					information("PipelineTrace camera=" + ((Object)val).GetInstanceID() + ":" + ((Object)val).name + " depth=" + val.depth + " mask=" + val.cullingMask + " viewport=" + ((object)val.pixelRect/*cast due to .constrained prefix*/).ToString() + " target=" + TextureDescription(val.targetTexture) + " components=" + string.Join(",", list));
					if (cameras.TryGetValue(val, out var value))
					{
						TraceNative(value);
					}
				}
			}
			catch (Exception ex)
			{
				report("PipelineTrace overview failed: " + ex.Message);
			}
		}

		private void TraceNative(CameraState state)
		{
			if (native != null && native.TryGetStatus(state.Key, out var status))
			{
				information("PipelineTrace nativeLatest cameraKey=" + state.Key + " submitted=" + state.Frame + " completed=" + status.Frame + " result=" + status.Result + " requested=" + status.RequestedPreset + " observed=" + status.ObservedPreset + " message=" + status.Message);
			}
			else
			{
				information("PipelineTrace nativeLatest cameraKey=" + state.Key + " submitted=" + state.Frame + " no-completion-record");
			}
		}

		private static string TextureDescription(RenderTexture texture)
		{
			if (!Object.op_Implicit((Object)(object)texture))
			{
				return "backbuffer";
			}
			return ((Object)texture).name + ":" + ((Texture)texture).width + "x" + ((Texture)texture).height;
		}

		private unsafe void TraceStage(string stage, Camera camera, PostProcessingContext context = null, RenderTexture source = null, RenderTexture destination = null)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (!DiagnosticActive)
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)camera))
				{
					information("PipelineTrace stage=" + stage + " no-camera");
					return;
				}
				PostProcessingBehaviour component = ((Component)camera).GetComponent<PostProcessingBehaviour>();
				if (context == null && Object.op_Implicit((Object)(object)component) && ContextField != null)
				{
					object? value = ContextField.GetValue(component);
					context = (PostProcessingContext)((value is PostProcessingContext) ? value : null);
				}
				PostProcessingProfile val = (Object.op_Implicit((Object)(object)component) ? component.profile : context?.profile);
				object obj;
				if (!Object.op_Implicit((Object)(object)val))
				{
					obj = " no-profile";
				}
				else
				{
					string[] obj2 = new string[8]
					{
						" profile=",
						((Object)val).GetInstanceID().ToString(),
						" enabled=",
						((PostProcessingModel)val.antialiasing).enabled.ToString(),
						" method=",
						null,
						null,
						null
					};
					Settings val2 = val.antialiasing.settings;
					obj2[5] = ((object)(*(Method*)(&val2.method))/*cast due to .constrained prefix*/).ToString();
					obj2[6] = " debugInterrupt=";
					obj2[7] = val.debugViews.willInterrupt.ToString();
					obj = string.Concat(obj2);
				}
				string text = (string)obj;
				text = text + " contextProfile=" + ((context != null && Object.op_Implicit((Object)(object)context.profile)) ? ((Object)context.profile).GetInstanceID().ToString() : "none");
				CameraState value2;
				string text2 = (cameras.TryGetValue(camera, out value2) ? (" key=" + value2.Key + " prepared=" + value2.Prepared + " faulted=" + value2.Faulted + " reset=" + value2.Reset + " jitterApplied=" + value2.JitterApplied + " submitted=" + value2.Frame) : " unregistered-camera");
				information("PipelineTrace frame=" + Time.frameCount + " stage=" + stage + " camera=" + ((Object)camera).GetInstanceID() + ":" + ((Object)camera).name + " postEnabled=" + (Object.op_Implicit((Object)(object)component) && ((Behaviour)component).enabled) + text + " interrupted=" + (context != null && context.interrupted) + text2 + " source=" + TextureDescription(source) + " destination=" + TextureDescription(destination));
			}
			catch (Exception ex)
			{
				report("PipelineTrace stage failed: " + ex.Message);
			}
		}

		public RenderController(AaSettings initial, Func<NativeBridge> acquire, Action<string> log, Action<string> info)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			settings = initial;
			acquireNative = acquire;
			report = log;
			information = info;
			setJitter = AccessTools.MethodDelegate<Action<TaaComponent, Vector2>>(AccessTools.PropertySetter(typeof(TaaComponent), "jitterVector"), (object)null, true);
			for (int i = 0; i < supportQueries.Length; i++)
			{
				supportQueries[i] = new SupportQuery
				{
					Availability = UpscalerAvailability.ForPlatform((int)SystemInfo.graphicsDeviceType == 2, SystemInfo.graphicsDeviceVendorID, SystemInfo.supportsMotionVectors, SystemInfo.supportsComputeShaders, (UpscalerBackend)i)
				};
			}
		}

		public void RequestUpscalerSupport()
		{
			supportRequested = true;
		}

		private void UpdateSupport(SupportQuery query)
		{
			//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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if (!query.Availability.Pending)
			{
				return;
			}
			try
			{
				NativeSupport result;
				if (query.Token == IntPtr.Zero)
				{
					if (native == null)
					{
						native = acquireNative();
					}
					query.Anchor = new RenderTexture(2, 2, 0, (RenderTextureFormat)0)
					{
						name = "DSPAASR capability device anchor",
						hideFlags = (HideFlags)61
					};
					if (!query.Anchor.Create())
					{
						throw new InvalidOperationException("Cannot allocate a graphics-device query anchor.");
					}
					IntPtr intPtr = native.RequestSupport(((Texture)query.Anchor).GetNativeTexturePtr(), (uint)query.Availability.Backend);
					if (intPtr == IntPtr.Zero)
					{
						throw new InvalidOperationException("Cannot queue the " + query.Availability.Name + " capability check.");
					}
					IssueControl(intPtr);
					query.Token = intPtr;
				}
				else if (native.TryGetSupport(query.Token, out result) && result.Result != 0)
				{
					query.Token = IntPtr.Zero;
					DestroyAnchor(query.Anchor);
					query.Anchor = null;
					query.Availability = query.Availability.Complete(result.Result == 1, result.Message);
					if (!query.Availability.Available)
					{
						report(query.Availability.Describe(chinese: false));
					}
				}
			}
			catch (Exception ex)
			{
				if (query.Token == IntPtr.Zero)
				{
					DestroyAnchor(query.Anchor);
					query.Anchor = null;
				}
				query.Availability = query.Availability.Complete(available: false, ex.Message);
				report(query.Availability.Describe(chinese: false));
			}
		}

		public void Configure(AaSettings value)
		{
			Capture?.Cancel("AA settings changed.");
			foreach (CameraState value2 in cameras.Values)
			{
				Restore(value2);
				if (Object.op_Implicit((Object)(object)value2.Behaviour))
				{
					value2.Behaviour.ResetTemporalEffects();
				}
				Retire(value2);
			}
			cameras.Clear();
			settings = value;
			Status = (value.Temporal ? "Waiting for a compatible camera." : ("Using " + value.Technique));
		}

		public void BeforeCull(PostProcessingBehaviour behaviour)
		{
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Invalid comparison between Unknown and I4
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0583: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Expected O, but got Unknown
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			if (DiagnosticActive && Object.op_Implicit((Object)(object)behaviour))
			{
				TraceStage("post.preCull-entry", ((Component)behaviour).GetComponent<Camera>());
			}
			if (!Object.op_Implicit((Object)(object)behaviour) || !Object.op_Implicit((Object)(object)behaviour.profile))
			{
				return;
			}
			Camera component = ((Component)behaviour).GetComponent<Camera>();
			if (!Object.op_Implicit((Object)(object)component) || settings.Technique == AaTechnique.Original)
			{
				return;
			}
			if (!cameras.TryGetValue(component, out var value))
			{
				bool flag = false;
				PostEffectController[] array = Object.FindObjectsOfType<PostEffectController>();
				for (int i = 0; i < array.Length; i++)
				{
					if ((Object)(object)array[i].postScript == (Object)(object)behaviour)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					return;
				}
				value = new CameraState
				{
					Camera = component,
					Behaviour = behaviour,
					Key = ++nextKey
				};
				cameras.Add(component, value);
			}
			Restore(value);
			value.Prepared = false;
			value.SrThisRender = false;
			value.InputsCopied = false;
			value.ImageResult = null;
			if (settings.Technique == AaTechnique.Original)
			{
				return;
			}
			if (settings.Temporal)
			{
				if (!ActiveAvailability.Available)
				{
					Status = ActiveAvailability.Describe(chinese: false);
					if (Object.op_Implicit((Object)(object)value.Presenter))
					{
						((Behaviour)value.Presenter).enabled = false;
					}
					return;
				}
				if (value.Faulted)
				{
					if (Object.op_Implicit((Object)(object)value.Presenter))
					{
						((Behaviour)value.Presenter).enabled = false;
					}
					return;
				}
				try
				{
					if ((int)SystemInfo.graphicsDeviceType != 2 || !SystemInfo.supportsMotionVectors || !SystemInfo.supportsComputeShaders || (!FsrSelected && SystemInfo.graphicsDeviceVendorID != 4318) || component.stereoEnabled)
					{
						throw new NotSupportedException(BackendName + " requires compatible D3D11, motion vectors, compute support and a non-stereo camera.");
					}
					if (FsrSelected && component.orthographic)
					{
						throw new NotSupportedException("FSR's depth reconstruction requires a perspective camera.");
					}
					if (behaviour.profile.debugViews.willInterrupt)
					{
						return;
					}
					if (native == null)
					{
						native = acquireNative();
					}
					if (native.TryGetStatus(value.Key, out var status))
					{
						if (status.Result < 0)
						{
							Fail(value, status.Message);
							return;
						}
						if (status.Result == 1)
						{
							string[] obj = new string[12]
							{
								BackendName,
								" ",
								settings.Resolution.ToString(),
								" | ",
								value.Targets.Width.ToString(),
								"x",
								value.Targets.Height.ToString(),
								" -> ",
								null,
								null,
								null,
								null
							};
							int i = value.Targets.Resolution.OutputWidth;
							obj[8] = i.ToString();
							obj[9] = "x";
							i = value.Targets.Resolution.OutputHeight;
							obj[10] = i.ToString();
							obj[11] = (FsrSelected ? (" | " + status.Message) : (" | requested " + (char)(65 + status.RequestedPreset - 1) + " | observed " + (char)status.ObservedPreset + " | runtime-log verified"));
							Status = string.Concat(obj);
							uint num = (FsrSelected ? 1u : status.ObservedPreset);
							if (value.ReportedPreset != num)
							{
								information(Status);
								value.ReportedPreset = num;
							}
						}
					}
					if ((settings.Resolution != ResolutionMode.Dlaa && Object.op_Implicit((Object)(object)component.targetTexture)) || component.pixelWidth <= 0 || component.pixelHeight <= 0)
					{
						return;
					}
					Matrix4x4 projectionMatrix = component.projectionMatrix;
					if (!PrepareTargets(value, component.pixelWidth, component.pixelHeight))
					{
						return;
					}
					if (!value.Targets.Resolution.IsNative)
					{
						if (component.rect != new Rect(0f, 0f, 1f, 1f))
						{
							value.Reset = true;
							Status = "Original AA for a partial camera viewport; SR resumes at full viewport.";
							return;
						}
						EnsurePresentation(value);
						value.OriginalTarget = component.targetTexture;
						value.TargetOverridden = true;
						value.SrThisRender = true;
						component.targetTexture = value.Targets.World;
						component.projectionMatrix = projectionMatrix;
					}
					int sceneIndex = GameCamera.sceneIndex;
					int instanceID = ((Object)behaviour.profile).GetInstanceID();
					if (value.LastFrame + 1 == Time.frameCount && value.Scene == sceneIndex && value.Profile == instanceID)
					{
						Vector3 val = value.Position - ((Component)component).transform.position;
						if (!(((Vector3)(ref val)).sqrMagnitude > 100f) && !(Quaternion.Angle(value.Rotation, ((Component)component).transform.rotation) > 30f) && !(value.Projection != projectionMatrix))
						{
							goto IL_0528;
						}
					}
					value.Reset = true;
					goto IL_0528;
					IL_0528:
					if (value.Reset)
					{
						value.Phase = 0u;
					}
					value.Jitter = Jitter.ForFrame(value.Phase++, value.Targets.Resolution.JitterPhases);
					value.Position = ((Component)component).transform.position;
					value.Rotation = ((Component)component).transform.rotation;
					value.Projection = projectionMatrix;
					value.Scene = sceneIndex;
					value.Profile = instanceID;
					value.LastFrame = Time.frameCount;
					if (FsrSelected)
					{
						value.OpaqueCapture = new CommandBuffer
						{
							name = "DSPAASR FSR opaque color"
						};
						value.OpaqueCapture.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2), RenderTargetIdentifier.op_Implicit((Texture)(object)value.Targets.OpaqueColor));
						component.AddCommandBuffer((CameraEvent)16, value.OpaqueCapture);
					}
					value.WorldText.Begin(component, projectionMatrix);
					value.WorldTextFrame = Time.frameCount;
				}
				catch (Exception ex)
				{
					Restore(value);
					value.SrThisRender = false;
					if (Object.op_Implicit((Object)(object)value.Presenter))
					{
						((Behaviour)value.Presenter).enabled = false;
					}
					Fail(value, ex.Message);
					return;
				}
			}
			value.Model = behaviour.profile.antialiasing;
			value.OriginalEnabled = ((PostProcessingModel)value.Model).enabled;
			value.OriginalSettings = value.Model.settings;
			value.OriginalMsaa = component.allowMSAA;
			value.OriginalTransparentJitter = component.useJitteredProjectionMatrixForTransparentRendering;
			value.Overridden = true;
			Settings originalSettings = value.OriginalSettings;
			originalSettings.method = (Method)(settings.Technique != AaTechnique.Fxaa);
			value.Model.settings = originalSettings;
			((PostProcessingModel)value.Model).enabled = true;
			if (settings.Temporal)
			{
				component.allowMSAA = false;
			}
			value.Prepared = settings.Temporal;
			TraceStage("post.preCull-prepared", component);
		}

		private bool PrepareTargets(CameraState state, int width, int height)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			if (state.RequestedWidth != width || state.RequestedHeight != height || (state.Targets != null && !state.Targets.Valid))
			{
				Retire(state);
				state.Key = ++nextKey;
				state.RequestedWidth = width;
				state.RequestedHeight = height;
				state.ReportedPreset = 0u;
				state.Reset = true;
			}
			if (state.Targets != null)
			{
				return true;
			}
			RenderResolution resolution = new RenderResolution(width, height, width, height);
			if (settings.Resolution != ResolutionMode.Dlaa || FsrSelected)
			{
				if (!state.QueryIssued)
				{
					state.SizingAnchor = new RenderTexture(2, 2, 0, (RenderTextureFormat)2, (RenderTextureReadWrite)1)
					{
						name = "DSPAAMod sizing device anchor",
						hideFlags = (HideFlags)61
					};
					if (!state.SizingAnchor.Create())
					{
						throw new InvalidOperationException("Cannot allocate reconstruction sizing anchor.");
					}
					IntPtr token = native.RequestOptimal(state.Key, ((Texture)state.SizingAnchor).GetNativeTexturePtr(), (uint)width, (uint)height, (uint)settings.Resolution, FsrSelected ? 1u : 0u);
					IssueControl(token);
					state.QueryIssued = true;
					Status = "Querying " + BackendName + " render size for " + settings.Resolution;
					return false;
				}
				uint num = 0u;
				NativeOptimalSettings result2;
				if (FsrSelected)
				{
					if (!native.TryGetFsrOptimal(state.Key, out var result) || result.Settings.Result == 0)
					{
						return false;
					}
					result2 = result.Settings;
					num = result.JitterPhases;
					if (result2.Result == 1 && num == 0)
					{
						throw new InvalidOperationException("FSR returned no jitter sequence.");
					}
				}
				else if (!native.TryGetOptimal(state.Key, out result2) || result2.Result == 0)
				{
					return false;
				}
				if (result2.Result < 0)
				{
					throw new InvalidOperationException(result2.Message);
				}
				if (result2.OutputWidth != (uint)width || result2.OutputHeight != (uint)height || result2.Quality != (uint)settings.Resolution)
				{
					throw new InvalidOperationException("Stale reconstruction resolution response.");
				}
				resolution = checked(new RenderResolution((int)result2.OptimalWidth, (int)result2.OptimalHeight, width, height, num));
				DestroyAnchor(state.SizingAnchor);
				state.SizingAnchor = null;
			}
			state.Targets = new RenderTargets(resolution, FsrSelected);
			Action<string> action = information;
			string[] obj = new string[13]
			{
				BackendName, " render targets: ", null, null, null, null, null, null, null, null,
				null, null, null
			};
			int inputWidth = resolution.InputWidth;
			obj[2] = inputWidth.ToString();
			obj[3] = "x";
			inputWidth = resolution.InputHeight;
			obj[4] = inputWidth.ToString();
			obj[5] = " world -> ";
			obj[6] = width.ToString();
			obj[7] = "x";
			obj[8] = height.ToString();
			obj[9] = " output/UI, mode ";
			obj[10] = settings.Resolution.ToString();
			obj[11] = ", jitter phases ";
			obj[12] = resolution.JitterPhases.ToString();
			action(string.Concat(obj));
			return true;
		}

		private static void EnsurePresentation(CameraState state)
		{
			if (!Object.op_Implicit((Object)(object)state.Presenter))
			{
				state.Presenter = ((Component)state.Camera).GetComponent<SrPresentation>();
			}
			if (!Object.op_Implicit((Object)(object)state.Presenter))
			{
				state.Presenter = ((Component)state.Camera).gameObject.AddComponent<SrPresentation>();
			}
			((Behaviour)state.Presenter).enabled = true;
			bool flag = false;
			bool flag2 = false;
			MonoBehaviour[] components = ((Component)state.Camera).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				if (Object.op_Implicit((Object)(object)val) && ((Behaviour)val).isActiveAndEnabled)
				{
					if ((Object)(object)val == (Object)(object)state.Behaviour)
					{
						flag = true;
					}
					if ((Object)(object)val == (Object)(object)state.Presenter)
					{
						flag2 = true;
					}
					else if (flag && HasImageEffect(((object)val).GetType()) && (flag2 || ((Object)(object)val != (Object)(object)state.Behaviour && !(val is TranslucentImageSource) && !(val is SunShafts))))
					{
						throw new NotSupportedException("Unintegrated image effect after the reconstruction stack: " + ((object)val).GetType().FullName);
					}
				}
			}
		}

		private static bool HasImageEffect(Type type)
		{
			Type[] types = new Type[2]
			{
				typeof(RenderTexture),
				typeof(RenderTexture)
			};
			while (type != null)
			{
				if (type.GetMethod("OnRenderImage", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, types, null) != null)
				{
					return true;
				}
				type = type.BaseType;
			}
			return false;
		}

		private static void RestoreTarget(CameraState state)
		{
			if (state.TargetOverridden)
			{
				if (Object.op_Implicit((Object)(object)state.Camera) && state.Targets != null && (Object)(object)state.Camera.targetTexture == (Object)(object)state.Targets.World)
				{
					state.Camera.targetTexture = state.OriginalTarget;
				}
				state.TargetOverridden = false;
			}
		}

		private static void DestroyA