Decompiled source of Shader Studio v1.1.0

plugins/ShaderStudio.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ShaderStudio;

public enum CompileStatus
{
	NotCompiled,
	Waiting,
	Compiling,
	Ok,
	Error
}
public class EffectAsset
{
	public ShaderDef Def;

	public int[] Programs = new int[0];

	public CompileStatus Status;

	public string Errors = "";

	public string Warnings = "";

	public int Version;

	public int CompiledVersion = -1;

	public bool Wanted;

	public readonly Texture2D[] Textures = (Texture2D[])(object)new Texture2D[4];

	public readonly IntPtr[] TexturePtrs = new IntPtr[4];

	public readonly string[] TextureFiles = new string[4];

	public string Id => Def.Id;

	public bool Ready
	{
		get
		{
			if (Programs.Length == Def.Passes.Count && Programs.Length != 0)
			{
				return Programs.All((int p) => p > 0);
			}
			return false;
		}
	}
}
public class Library
{
	private struct Job
	{
		public EffectAsset Asset;

		public int Version;

		public string[] Sources;

		public string File;
	}

	private struct Result
	{
		public EffectAsset Asset;

		public int Version;

		public int[] Programs;

		public string Errors;

		public string Warnings;
	}

	public readonly Dictionary<string, EffectAsset> Assets = new Dictionary<string, EffectAsset>(StringComparer.OrdinalIgnoreCase);

	public string BuiltInDir;

	public string UserDir;

	public string Prelude = "";

	private float nextScan;

	private readonly Queue<Result> results = new Queue<Result>();

	private readonly object resultLock = new object();

	public IEnumerable<EffectAsset> Sorted => from a in Assets.Values
		orderby a.Def.Category, a.Def.Name
		select a;

	public void Init(string builtInDir, string userDir, string prelude)
	{
		BuiltInDir = builtInDir;
		UserDir = userDir;
		Prelude = prelude;
		Directory.CreateDirectory(UserDir);
		Scan(force: true);
	}

	public EffectAsset Get(string id)
	{
		if (id == null || !Assets.TryGetValue(id, out var value))
		{
			return null;
		}
		return value;
	}

	public void Scan(bool force)
	{
		if (!force && Time.unscaledTime < nextScan)
		{
			return;
		}
		nextScan = Time.unscaledTime + 1f;
		HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		List<KeyValuePair<string, bool>> list = new List<KeyValuePair<string, bool>>();
		try
		{
			if (Directory.Exists(BuiltInDir))
			{
				string[] files = Directory.GetFiles(BuiltInDir, "*.hlsl");
				foreach (string key in files)
				{
					list.Add(new KeyValuePair<string, bool>(key, value: true));
				}
			}
		}
		catch
		{
		}
		try
		{
			if (Directory.Exists(UserDir))
			{
				string[] files = Directory.GetFiles(UserDir, "*.hlsl");
				foreach (string key2 in files)
				{
					list.Add(new KeyValuePair<string, bool>(key2, value: false));
				}
			}
		}
		catch
		{
		}
		foreach (KeyValuePair<string, bool> item in list)
		{
			string key3 = item.Key;
			string fileName = Path.GetFileName(key3);
			if (fileName.StartsWith("_") || fileName.Equals("API_REFERENCE.hlsl", StringComparison.OrdinalIgnoreCase))
			{
				continue;
			}
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(key3);
			seen.Add(fileNameWithoutExtension);
			DateTime lastWriteTimeUtc;
			try
			{
				lastWriteTimeUtc = File.GetLastWriteTimeUtc(key3);
			}
			catch
			{
				continue;
			}
			if (Assets.TryGetValue(fileNameWithoutExtension, out var value))
			{
				bool flag = string.Equals(value.Def.Path, key3, StringComparison.OrdinalIgnoreCase);
				if ((flag && value.Def.LastWrite == lastWriteTimeUtc) || (!flag && !value.Def.BuiltIn && item.Value && File.Exists(value.Def.Path)))
				{
					continue;
				}
			}
			LoadFile(key3, item.Value, lastWriteTimeUtc);
		}
		foreach (string item2 in Assets.Keys.Where((string k) => !seen.Contains(k)).ToList())
		{
			ReleasePrograms(Assets[item2]);
			Assets.Remove(item2);
		}
	}

	private void LoadFile(string path, bool builtIn, DateTime mt)
	{
		string src;
		try
		{
			src = File.ReadAllText(path);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Could not read " + path + ": " + ex.Message));
			return;
		}
		SetSource(path, builtIn, src, mt);
	}

	public EffectAsset SetSource(string path, bool builtIn, string src, DateTime mt)
	{
		ShaderDef shaderDef = ShaderDef.Parse(src, path, builtIn);
		shaderDef.LastWrite = mt;
		if (!Assets.TryGetValue(shaderDef.Id, out var value))
		{
			value = new EffectAsset();
			Assets[shaderDef.Id] = value;
		}
		value.Def = shaderDef;
		value.Version++;
		value.Status = (value.Wanted ? CompileStatus.Waiting : CompileStatus.NotCompiled);
		LoadTextures(value);
		return value;
	}

	private void LoadTextures(EffectAsset a)
	{
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Expected O, but got Unknown
		foreach (UniformDef uniform in a.Def.Uniforms)
		{
			if (uniform.Type != UType.Texture)
			{
				continue;
			}
			string text = uniform.File ?? "";
			string path = Path.GetDirectoryName(a.Def.Path) ?? "";
			string text2 = (Path.IsPathRooted(text) ? text : Path.Combine(path, text));
			if (!File.Exists(text2))
			{
				string text3 = Path.Combine(UserDir, text);
				if (File.Exists(text3))
				{
					text2 = text3;
				}
			}
			if (a.TextureFiles[uniform.Slot] == text2 && (Object)(object)a.Textures[uniform.Slot] != (Object)null)
			{
				continue;
			}
			a.TextureFiles[uniform.Slot] = text2;
			if ((Object)(object)a.Textures[uniform.Slot] != (Object)null)
			{
				Object.Destroy((Object)(object)a.Textures[uniform.Slot]);
				a.Textures[uniform.Slot] = null;
				a.TexturePtrs[uniform.Slot] = IntPtr.Zero;
			}
			if (!File.Exists(text2))
			{
				continue;
			}
			try
			{
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, true);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(text2), false))
				{
					((Texture)val).wrapMode = (TextureWrapMode)0;
					((Texture)val).filterMode = (FilterMode)1;
					val.Apply(false, false);
					a.Textures[uniform.Slot] = val;
					a.TexturePtrs[uniform.Slot] = ((Texture)val).GetNativeTexturePtr();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Texture load failed " + text2 + ": " + ex.Message));
			}
		}
	}

	private static void ReleasePrograms(EffectAsset a)
	{
		if (Native.Loaded)
		{
			int[] programs = a.Programs;
			foreach (int num in programs)
			{
				if (num > 0)
				{
					Native.SS_Release(num);
				}
			}
		}
		a.Programs = new int[0];
	}

	public void Tick(bool nativeReady)
	{
		Scan(force: false);
		if (nativeReady)
		{
			foreach (EffectAsset value in Assets.Values)
			{
				if (!value.Wanted || value.CompiledVersion == value.Version || value.Status == CompileStatus.Compiling)
				{
					continue;
				}
				if (value.Def.ParseError != null)
				{
					value.Status = CompileStatus.Error;
					value.Errors = value.Def.ParseError;
					value.CompiledVersion = value.Version;
					continue;
				}
				Job job = new Job
				{
					Asset = value,
					Version = value.Version,
					File = value.Def.FileName,
					Sources = new string[value.Def.Passes.Count]
				};
				for (int i = 0; i < job.Sources.Length; i++)
				{
					job.Sources[i] = value.Def.Generate(i, Prelude, lineDirectives: true);
				}
				value.Status = CompileStatus.Compiling;
				ThreadPool.QueueUserWorkItem(delegate
				{
					RunJob(job);
				});
			}
		}
		lock (resultLock)
		{
			while (results.Count > 0)
			{
				Result result = results.Dequeue();
				EffectAsset asset = result.Asset;
				bool flag = result.Programs.All((int p) => p > 0);
				int[] programs;
				if (result.Version != asset.Version || !Assets.ContainsValue(asset))
				{
					programs = result.Programs;
					foreach (int num2 in programs)
					{
						if (num2 > 0)
						{
							Native.SS_Release(num2);
						}
					}
					continue;
				}
				asset.CompiledVersion = result.Version;
				asset.Warnings = result.Warnings;
				if (flag)
				{
					ReleasePrograms(asset);
					asset.Programs = result.Programs;
					asset.Status = CompileStatus.Ok;
					asset.Errors = "";
					continue;
				}
				programs = result.Programs;
				foreach (int num3 in programs)
				{
					if (num3 > 0)
					{
						Native.SS_Release(num3);
					}
				}
				asset.Status = CompileStatus.Error;
				asset.Errors = result.Errors;
				Plugin.Log.LogWarning((object)("Shader '" + asset.Def.Name + "' failed to compile:\n" + result.Errors));
			}
		}
	}

	private void RunJob(Job job)
	{
		int[] array = new int[job.Sources.Length];
		StringBuilder stringBuilder = new StringBuilder();
		StringBuilder stringBuilder2 = new StringBuilder();
		for (int i = 0; i < job.Sources.Length; i++)
		{
			string messages;
			try
			{
				array[i] = Native.Compile(job.Sources[i], job.File, out messages);
			}
			catch (Exception ex)
			{
				array[i] = 0;
				messages = ex.Message;
			}
			if (array[i] == 0)
			{
				stringBuilder.AppendLine("[pass " + job.Asset.Def.Passes[i].Entry + "]");
				stringBuilder.AppendLine(messages);
				break;
			}
			if (!string.IsNullOrEmpty(messages) && i == 0)
			{
				stringBuilder2.AppendLine(messages);
			}
		}
		lock (resultLock)
		{
			results.Enqueue(new Result
			{
				Asset = job.Asset,
				Version = job.Version,
				Programs = array,
				Errors = stringBuilder.ToString(),
				Warnings = stringBuilder2.ToString()
			});
		}
	}

	public void ForceRecompile(EffectAsset a)
	{
		a.Version++;
		a.Status = CompileStatus.Waiting;
	}

	public string UniqueUserPath(string baseId)
	{
		string text = SafeId(baseId);
		string text2 = Path.Combine(UserDir, text + ".hlsl");
		int num = 2;
		while (File.Exists(text2) || (Assets.ContainsKey(Path.GetFileNameWithoutExtension(text2)) && !string.Equals(Assets[Path.GetFileNameWithoutExtension(text2)].Def.Path, text2, StringComparison.OrdinalIgnoreCase)))
		{
			text2 = Path.Combine(UserDir, text + "_" + num + ".hlsl");
			num++;
		}
		return text2;
	}

	public static string SafeId(string s)
	{
		StringBuilder stringBuilder = new StringBuilder();
		string text = (s ?? "shader").Trim().ToLowerInvariant();
		foreach (char c in text)
		{
			stringBuilder.Append(char.IsLetterOrDigit(c) ? c : '_');
		}
		string text2 = stringBuilder.ToString().Trim('_');
		if (text2.Length != 0)
		{
			return text2;
		}
		return "shader";
	}
}
public class EffectInstance
{
	public string AssetId;

	public bool Enabled = true;

	public float Mix = 1f;

	public bool Expanded;

	public readonly Dictionary<string, float[]> Values = new Dictionary<string, float[]>();

	public int Uid = ++uidCounter;

	private static int uidCounter;

	[NonSerialized]
	public float[] Packed = new float[128];

	public float[] Get(UniformDef u)
	{
		if (!Values.TryGetValue(u.Name, out var value) || value == null || value.Length < 4)
		{
			value = (float[])u.Default.Clone();
			Values[u.Name] = value;
		}
		return value;
	}

	public void ResetToDefaults(ShaderDef def)
	{
		Values.Clear();
		foreach (UniformDef uniform in def.Uniforms)
		{
			Get(uniform);
		}
	}

	public float[] Pack(ShaderDef def)
	{
		Array.Clear(Packed, 0, Packed.Length);
		foreach (UniformDef uniform in def.Uniforms)
		{
			if (uniform.Type != UType.Texture)
			{
				float[] array = Get(uniform);
				int num = uniform.Slot * 4;
				for (int i = 0; i < 4; i++)
				{
					Packed[num + i] = array[i];
				}
			}
		}
		return Packed;
	}

	public EffectInstance Clone()
	{
		EffectInstance effectInstance = new EffectInstance
		{
			AssetId = AssetId,
			Enabled = Enabled,
			Mix = Mix,
			Expanded = Expanded
		};
		foreach (KeyValuePair<string, float[]> value in Values)
		{
			effectInstance.Values[value.Key] = (float[])value.Value.Clone();
		}
		return effectInstance;
	}
}
internal static class Native
{
	private const string Dll = "ShaderStudioNative";

	public static bool Loaded { get; private set; }

	public static string LoadError { get; private set; }

	[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
	private static extern IntPtr LoadLibraryW(string path);

	[DllImport("ShaderStudioNative")]
	public static extern int SS_Init(IntPtr unityTexture);

	[DllImport("ShaderStudioNative")]
	public static extern int SS_IsReady();

	[DllImport("ShaderStudioNative")]
	private static extern int SS_Compile(byte[] source, byte[] entry, byte[] fileName, byte[] err, int errLen);

	[DllImport("ShaderStudioNative")]
	public static extern void SS_Release(int program);

	[DllImport("ShaderStudioNative")]
	public static extern void SS_BeginFrame(IntPtr src, IntPtr dst, IntPtr depth, int w, int h, float[] globals, int nGlobals);

	[DllImport("ShaderStudioNative")]
	public static extern void SS_SetUserTexture(int slot, IntPtr tex);

	[DllImport("ShaderStudioNative")]
	public static extern void SS_AddPass(int program, int w, int h, int isFinal, float mix, float[] parameters, int nParams);

	[DllImport("ShaderStudioNative")]
	public static extern void SS_EndFrame(int serial);

	[DllImport("ShaderStudioNative")]
	public static extern IntPtr SS_GetRenderEventFunc();

	[DllImport("ShaderStudioNative")]
	private static extern int SS_PopLog(byte[] buf, int len);

	public static bool Load(string dir)
	{
		string text = Path.Combine(dir, "ShaderStudioNative.dll");
		if (!File.Exists(text))
		{
			LoadError = "ShaderStudioNative.dll not found next to the plugin (" + text + ")";
			return false;
		}
		if (LoadLibraryW(text) == IntPtr.Zero)
		{
			LoadError = "Could not load ShaderStudioNative.dll (error " + Marshal.GetLastWin32Error() + ")";
			return false;
		}
		try
		{
			SS_IsReady();
		}
		catch (Exception ex)
		{
			LoadError = "Native entry points missing: " + ex.Message;
			return false;
		}
		Loaded = true;
		return true;
	}

	private static byte[] Z(string s)
	{
		return Encoding.UTF8.GetBytes(s + "\0");
	}

	public static int Compile(string source, string fileName, out string messages)
	{
		byte[] array = new byte[16384];
		int result = SS_Compile(Z(source), Z("_SS_Main"), Z(fileName), array, array.Length);
		int num = Array.IndexOf(array, (byte)0);
		if (num < 0)
		{
			num = array.Length;
		}
		messages = Encoding.UTF8.GetString(array, 0, num);
		return result;
	}

	public static string PopLog()
	{
		if (!Loaded)
		{
			return "";
		}
		byte[] array = new byte[8192];
		int num = SS_PopLog(array, array.Length);
		if (num <= 0)
		{
			return "";
		}
		return Encoding.UTF8.GetString(array, 0, num);
	}
}
[BepInPlugin("com.burak.shaderstudio", "Shader Studio", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	public const string GUID = "com.burak.shaderstudio";

	public const string NAME = "Shader Studio";

	public const string VERSION = "1.1.0";

	public static ManualLogSource Log;

	public static Plugin Instance;

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		GameObject val = new GameObject("ShaderStudio")
		{
			hideFlags = (HideFlags)61
		};
		Object.DontDestroyOnLoad((Object)val);
		Studio studio = val.AddComponent<Studio>();
		studio.Setup(((BaseUnityPlugin)this).Config, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
		Log.LogInfo((object)("Shader Studio 1.1.0 loaded. Press " + ((object)studio.MenuKey.Value/*cast due to .constrained prefix*/).ToString() + " to open the menu."));
	}
}
public class PresetEffect
{
	public string shader;

	public bool enabled = true;

	public float mix = 1f;

	public Dictionary<string, float[]> values = new Dictionary<string, float[]>();
}
public class FxParamData
{
	public bool o;

	public float[] v;
}
public class FxEffectData
{
	public bool enabled = true;

	public Dictionary<string, FxParamData> p = new Dictionary<string, FxParamData>();
}
public class PresetData
{
	public string name = "";

	public string description = "";

	public List<PresetEffect> effects = new List<PresetEffect>();

	public RenderingSettings rendering;

	public bool unityFxEnabled;

	public float unityFxWeight = 1f;

	public Dictionary<string, FxEffectData> unityFx;

	[JsonIgnore]
	public string Path;

	[JsonIgnore]
	public bool BuiltIn;
}
public class Studio : MonoBehaviour
{
	public static Studio I;

	public ConfigEntry<KeyCode> MenuKey;

	public ConfigEntry<KeyCode> ToggleKey;

	public ConfigEntry<float> UIScale;

	public ConfigEntry<bool> FlipY;

	public ConfigEntry<bool> EffectsOn;

	public ConfigEntry<bool> LockInputWhileOpen;

	public ConfigEntry<string> TargetCameraName;

	public ConfigEntry<int> EditorFontSize;

	public string PluginDir;

	public string ConfigDir;

	public string UserShaderDir;

	public string UserPresetDir;

	public string BuiltInShaderDir;

	public string BuiltInPresetDir;

	public string StatePath;

	public readonly Library Lib = new Library();

	public readonly List<EffectInstance> Stack = new List<EffectInstance>();

	public readonly List<PresetData> Presets = new List<PresetData>();

	public RenderingTweaks Rendering;

	public UnityFxController UnityFx;

	public StudioUI UI;

	public bool MenuOpen;

	public bool Dirty;

	public string EditorAssetId;

	public string NativeStatus = "Waiting for the first frame...";

	public bool NativeOk;

	public bool NativeFailed;

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

	public Camera TargetCamera;

	public float LastFrameMs;

	private RenderTexture inRT;

	private RenderTexture outRT;

	private RenderTexture depthRT;

	private IntPtr inPtr;

	private IntPtr outPtr;

	private IntPtr depthPtr;

	private IntPtr renderFunc;

	private int serial = 1;

	private readonly float[] globals = new float[96];

	private Matrix4x4 prevViewProj = Matrix4x4.identity;

	private bool havePrev;

	private Camera depthModeCam;

	private bool weAddedDepth;

	private Light sun;

	private float nextSunSearch;

	private float nextSave;

	private static readonly int DepthTexId = Shader.PropertyToID("_CameraDepthTexture");

	private bool loggedProcessError;

	private FieldInfo gManField;

	private FieldInfo lockInputField;

	private PropertyInfo showCursorProp;

	private bool weLockedInput;

	private bool prevShowCursor;

	private CursorLockMode prevLock;

	private bool prevVisible;

	private bool menuKeyHeld;

	private bool toggleKeyHeld;

	public void Setup(ConfigFile cfg, string pluginDir)
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		I = this;
		MenuKey = cfg.Bind<KeyCode>("Hotkeys", "OpenMenu", (KeyCode)289, "Opens / closes the Shader Studio menu.");
		ToggleKey = cfg.Bind<KeyCode>("Hotkeys", "ToggleEffects", (KeyCode)290, "Turns all custom shader effects on/off (quick before/after).");
		UIScale = cfg.Bind<float>("Interface", "UIScale", 1f, new ConfigDescription("Menu size multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2.5f), Array.Empty<object>()));
		EditorFontSize = cfg.Bind<int>("Interface", "EditorFontSize", 15, "Code editor font size.");
		LockInputWhileOpen = cfg.Bind<bool>("Interface", "LockPlayerWhileMenuOpen", true, "Stops the player from moving/looking around while the menu is open.");
		EffectsOn = cfg.Bind<bool>("Rendering", "EffectsEnabled", true, "Master switch for custom shader effects.");
		FlipY = cfg.Bind<bool>("Rendering", "FlipY", false, "Flip the vertical image axis for shaders (only if effects look upside down).");
		TargetCameraName = cfg.Bind<string>("Rendering", "TargetCamera", "", "Camera to apply effects to. Empty = the main camera.");
		PluginDir = pluginDir;
		ConfigDir = Path.Combine(Paths.ConfigPath, "ShaderStudio");
		UserShaderDir = Path.Combine(ConfigDir, "shaders");
		UserPresetDir = Path.Combine(ConfigDir, "presets");
		BuiltInShaderDir = Path.Combine(PluginDir, "shaders");
		BuiltInPresetDir = Path.Combine(PluginDir, "presets");
		StatePath = Path.Combine(ConfigDir, "current_setup.json");
		Directory.CreateDirectory(UserShaderDir);
		Directory.CreateDirectory(UserPresetDir);
		string prelude = LoadPrelude();
		WriteStarterFiles(prelude);
		if (!Native.Load(PluginDir))
		{
			NativeFailed = true;
			NativeStatus = Native.LoadError;
			Plugin.Log.LogError((object)NativeStatus);
		}
		else
		{
			renderFunc = Native.SS_GetRenderEventFunc();
		}
		Lib.Init(BuiltInShaderDir, UserShaderDir, prelude);
		Rendering = new RenderingTweaks();
		UnityFx = new UnityFxController();
		UI = new StudioUI(this);
		LoadPresetList();
		LoadState();
		Type type = Type.GetType("CL_GameManager, Assembly-CSharp");
		if (type != null)
		{
			gManField = type.GetField("gMan", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			lockInputField = type.GetField("lockPlayerInput", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			showCursorProp = type.GetProperty("showCursor", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		}
	}

	private string LoadPrelude()
	{
		using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ShaderStudio.Prelude.hlsl");
		using StreamReader streamReader = new StreamReader(stream);
		return streamReader.ReadToEnd();
	}

	private void WriteStarterFiles(string prelude)
	{
		try
		{
			File.WriteAllText(Path.Combine(UserShaderDir, "API_REFERENCE.hlsl"), "// This file is regenerated every launch. It shows everything your shaders can use.\n// (Files starting with _ and this file are not loaded as effects.)\n\n" + prelude);
			string path = Path.Combine(UserShaderDir, "my_first_shader.hlsl");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, ShaderDef.NewShaderTemplate("My First Shader"));
			}
			string path2 = Path.Combine(ConfigDir, "README.txt");
			if (!File.Exists(path2))
			{
				File.WriteAllText(path2, "Shader Studio user folder\n\nshaders/  - your .hlsl effects (hot-reloaded while the game runs)\npresets/  - your saved presets (.json)\ncurrent_setup.json - the stack you had last time\n\nSee shaders/API_REFERENCE.hlsl for every function and value you can use.\n");
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Could not write starter files: " + ex.Message));
		}
	}

	private void Update()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (!NativeFailed && (int)SystemInfo.graphicsDeviceType != 2)
		{
			NativeFailed = true;
			NativeStatus = "Custom shaders need DirectX 11, but the game is running on " + ((object)SystemInfo.graphicsDeviceType/*cast due to .constrained prefix*/).ToString() + ". Add  -force-d3d11  to White Knuckle's Steam launch options. (Unity FX and Rendering tabs still work.)";
			Plugin.Log.LogWarning((object)NativeStatus);
		}
		foreach (EffectAsset value in Lib.Assets.Values)
		{
			value.Wanted = false;
		}
		foreach (EffectInstance item in Stack)
		{
			EffectAsset effectAsset = Lib.Get(item.AssetId);
			if (effectAsset != null)
			{
				effectAsset.Wanted = true;
			}
		}
		EffectAsset effectAsset2 = Lib.Get(EditorAssetId);
		if (effectAsset2 != null)
		{
			effectAsset2.Wanted = true;
		}
		Lib.Tick(NativeOk);
		PumpNativeLog();
		FindCamera();
		Rendering.Tick(TargetCamera);
		UnityFx.Tick(TargetCamera);
		if (MenuOpen)
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
		if (Dirty && Time.unscaledTime > nextSave)
		{
			SaveState();
			Dirty = false;
			nextSave = Time.unscaledTime + 1.5f;
		}
	}

	private void LateUpdate()
	{
		if (MenuOpen)
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
	}

	private void OnApplicationQuit()
	{
		SaveState();
	}

	private void OnGUI()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Invalid comparison between Unknown and I4
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Invalid comparison between Unknown and I4
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Invalid comparison between Unknown and I4
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Invalid comparison between Unknown and I4
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		Event current = Event.current;
		if ((int)current.type == 4 && current.keyCode == MenuKey.Value)
		{
			if (!menuKeyHeld)
			{
				SetMenuOpen(!MenuOpen);
			}
			menuKeyHeld = true;
			current.Use();
		}
		else if ((int)current.type == 5 && current.keyCode == MenuKey.Value)
		{
			menuKeyHeld = false;
		}
		if ((int)current.type == 4 && current.keyCode == ToggleKey.Value)
		{
			if (!toggleKeyHeld)
			{
				EffectsOn.Value = !EffectsOn.Value;
			}
			toggleKeyHeld = true;
			current.Use();
		}
		else if ((int)current.type == 5 && current.keyCode == ToggleKey.Value)
		{
			toggleKeyHeld = false;
		}
		if (MenuOpen)
		{
			UI.Draw();
		}
	}

	public void SetMenuOpen(bool open)
	{
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (open == MenuOpen)
		{
			return;
		}
		MenuOpen = open;
		object obj = null;
		try
		{
			obj = ((gManField != null) ? gManField.GetValue(null) : null);
		}
		catch
		{
		}
		if (open)
		{
			prevLock = Cursor.lockState;
			prevVisible = Cursor.visible;
			if (!LockInputWhileOpen.Value || obj == null || !(lockInputField != null))
			{
				return;
			}
			try
			{
				if (!(bool)lockInputField.GetValue(obj))
				{
					lockInputField.SetValue(obj, true);
					weLockedInput = true;
				}
				if (showCursorProp != null)
				{
					prevShowCursor = (bool)showCursorProp.GetValue(null, null);
					showCursorProp.SetValue(null, true, null);
				}
				return;
			}
			catch
			{
				return;
			}
		}
		try
		{
			if (weLockedInput && obj != null && lockInputField != null)
			{
				lockInputField.SetValue(obj, false);
			}
			if (showCursorProp != null && LockInputWhileOpen.Value)
			{
				showCursorProp.SetValue(null, prevShowCursor, null);
			}
		}
		catch
		{
		}
		weLockedInput = false;
		Cursor.lockState = prevLock;
		Cursor.visible = prevVisible;
		SaveState();
	}

	private void PumpNativeLog()
	{
		if (!Native.Loaded)
		{
			return;
		}
		string text = Native.PopLog();
		if (string.IsNullOrEmpty(text))
		{
			return;
		}
		string[] array = text.Split('\n');
		foreach (string text2 in array)
		{
			if (text2.Trim().Length != 0)
			{
				Plugin.Log.LogInfo((object)("[native] " + text2));
				NativeLog.Add(text2);
			}
		}
		while (NativeLog.Count > 60)
		{
			NativeLog.RemoveAt(0);
		}
	}

	private void FindCamera()
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		Camera val = null;
		string value = TargetCameraName.Value;
		if (!string.IsNullOrEmpty(value))
		{
			Camera[] allCameras = Camera.allCameras;
			foreach (Camera val2 in allCameras)
			{
				if (((Object)val2).name == value)
				{
					val = val2;
					break;
				}
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Camera.main;
		}
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		if ((Object)(object)val != (Object)(object)TargetCamera)
		{
			if ((Object)(object)depthModeCam != (Object)null && weAddedDepth)
			{
				Camera obj = depthModeCam;
				obj.depthTextureMode = (DepthTextureMode)(obj.depthTextureMode & -2);
				weAddedDepth = false;
				depthModeCam = null;
			}
			TargetCamera = val;
			havePrev = false;
		}
		if ((Object)(object)((Component)val).GetComponent<StudioCamera>() == (Object)null)
		{
			((Component)val).gameObject.AddComponent<StudioCamera>();
		}
	}

	public List<EffectInstance> ActiveInstances()
	{
		List<EffectInstance> list = new List<EffectInstance>();
		if (!EffectsOn.Value)
		{
			return list;
		}
		foreach (EffectInstance item in Stack)
		{
			if (item.Enabled && !(item.Mix <= 0f))
			{
				EffectAsset effectAsset = Lib.Get(item.AssetId);
				if (effectAsset != null && effectAsset.Ready)
				{
					list.Add(item);
				}
			}
		}
		return list;
	}

	private static void EnsureRT(ref RenderTexture rt, ref IntPtr ptr, int w, int h, RenderTextureFormat fmt, string name)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected O, but got Unknown
		if (!((Object)(object)rt != (Object)null) || ((Texture)rt).width != w || ((Texture)rt).height != h || !rt.IsCreated())
		{
			if ((Object)(object)rt != (Object)null)
			{
				rt.Release();
				Object.Destroy((Object)(object)rt);
			}
			rt = new RenderTexture(w, h, 0, fmt, (RenderTextureReadWrite)1)
			{
				name = name,
				useMipMap = false,
				autoGenerateMips = false,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			rt.Create();
			ptr = ((Texture)rt).GetNativeTexturePtr();
		}
	}

	public void Process(Camera cam, RenderTexture src, RenderTexture dst)
	{
		List<EffectInstance> list = (((Object)(object)cam == (Object)(object)TargetCamera && !NativeFailed && Native.Loaded) ? ActiveInstances() : null);
		bool flag = false;
		if (list != null)
		{
			foreach (EffectInstance item in list)
			{
				if (Lib.Get(item.AssetId).Def.UsesDepth)
				{
					flag = true;
					break;
				}
			}
		}
		UpdateDepthMode(cam, flag);
		if (!NativeOk && !NativeFailed && Native.Loaded && (Object)(object)cam == (Object)(object)TargetCamera)
		{
			EnsureRT(ref inRT, ref inPtr, ((Texture)src).width, ((Texture)src).height, (RenderTextureFormat)2, "SS_In");
			if (Native.SS_Init(inPtr) == 1)
			{
				NativeOk = true;
				NativeStatus = "DirectX 11 shader compiler ready.";
			}
			else
			{
				NativeFailed = true;
				NativeStatus = "Native renderer failed to start: " + Native.PopLog();
				Plugin.Log.LogError((object)NativeStatus);
			}
		}
		if (list == null || list.Count == 0 || !NativeOk)
		{
			Graphics.Blit((Texture)(object)src, dst);
			return;
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		int width = ((Texture)src).width;
		int height = ((Texture)src).height;
		EnsureRT(ref inRT, ref inPtr, width, height, (RenderTextureFormat)2, "SS_In");
		EnsureRT(ref outRT, ref outPtr, width, height, (RenderTextureFormat)2, "SS_Out");
		Graphics.Blit((Texture)(object)src, inRT);
		bool flag2 = false;
		if (flag)
		{
			Texture globalTexture = Shader.GetGlobalTexture(DepthTexId);
			if ((Object)(object)globalTexture != (Object)null)
			{
				EnsureRT(ref depthRT, ref depthPtr, width, height, (RenderTextureFormat)14, "SS_Depth");
				Graphics.Blit(globalTexture, depthRT);
				flag2 = true;
			}
		}
		FillGlobals(cam, width, height, flag2);
		Native.SS_BeginFrame(inPtr, outPtr, flag2 ? depthPtr : IntPtr.Zero, width, height, globals, globals.Length);
		foreach (EffectInstance item2 in list)
		{
			EffectAsset effectAsset = Lib.Get(item2.AssetId);
			ShaderDef def = effectAsset.Def;
			for (int i = 0; i < 4; i++)
			{
				Native.SS_SetUserTexture(i, ((Object)(object)effectAsset.Textures[i] != (Object)null) ? effectAsset.TexturePtrs[i] : IntPtr.Zero);
			}
			float[] array = item2.Pack(def);
			for (int j = 0; j < def.Passes.Count; j++)
			{
				bool flag3 = def.IsFinalPass(j);
				float num = (flag3 ? 1f : def.Passes[j].Scale);
				int w = Mathf.Max(1, Mathf.RoundToInt((float)width * num));
				int h = Mathf.Max(1, Mathf.RoundToInt((float)height * num));
				Native.SS_AddPass(effectAsset.Programs[j], w, h, flag3 ? 1 : 0, Mathf.Clamp(item2.Mix, 0f, 1f), array, array.Length);
			}
		}
		Native.SS_EndFrame(serial);
		GL.IssuePluginEvent(renderFunc, serial);
		serial = ((serial >= 1073741824) ? 1 : (serial + 1));
		Graphics.Blit((Texture)(object)outRT, dst);
		LastFrameMs = (Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f;
	}

	private void UpdateDepthMode(Camera cam, bool need)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (need && (cam.depthTextureMode & 1) == 0)
		{
			cam.depthTextureMode = (DepthTextureMode)(cam.depthTextureMode | 1);
			weAddedDepth = true;
			depthModeCam = cam;
		}
		else if (!need && weAddedDepth && (Object)(object)depthModeCam == (Object)(object)cam)
		{
			cam.depthTextureMode = (DepthTextureMode)(cam.depthTextureMode & -2);
			weAddedDepth = false;
			depthModeCam = null;
		}
	}

	private static void PutMatrix(float[] g, int o, Matrix4x4 m)
	{
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 4; j++)
			{
				g[o + i * 4 + j] = ((Matrix4x4)(ref m))[j, i];
			}
		}
	}

	private void FillGlobals(Camera cam, int w, int h, bool hasDepth)
	{
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Invalid comparison between Unknown and I4
		//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_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		float[] array = globals;
		array[0] = Time.unscaledTime;
		array[1] = Time.unscaledDeltaTime;
		array[2] = Time.frameCount;
		array[3] = Random.value;
		array[4] = w;
		array[5] = h;
		array[6] = 1f / (float)w;
		array[7] = 1f / (float)h;
		float nearClipPlane = cam.nearClipPlane;
		float farClipPlane = cam.farClipPlane;
		float num;
		float num2;
		if (SystemInfo.usesReversedZBuffer)
		{
			num = -1f + farClipPlane / nearClipPlane;
			num2 = 1f;
		}
		else
		{
			num = 1f - farClipPlane / nearClipPlane;
			num2 = farClipPlane / nearClipPlane;
		}
		array[8] = num;
		array[9] = num2;
		array[10] = num / farClipPlane;
		array[11] = num2 / farClipPlane;
		float num3 = Mathf.Tan(cam.fieldOfView * 0.5f * ((float)Math.PI / 180f));
		array[12] = num3 * cam.aspect;
		array[13] = num3;
		array[14] = nearClipPlane;
		array[15] = farClipPlane;
		PutMatrix(array, 16, cam.cameraToWorldMatrix);
		PutMatrix(array, 32, cam.worldToCameraMatrix);
		Matrix4x4 val = cam.projectionMatrix * cam.worldToCameraMatrix;
		PutMatrix(array, 48, val);
		PutMatrix(array, 64, havePrev ? prevViewProj : val);
		prevViewProj = val;
		havePrev = true;
		Vector3 position = ((Component)cam).transform.position;
		array[80] = position.x;
		array[81] = position.y;
		array[82] = position.z;
		array[83] = 0f;
		array[84] = (hasDepth ? 1 : 0);
		array[85] = (((int)QualitySettings.activeColorSpace == 1) ? 1 : 0);
		array[86] = (FlipY.Value ? 1 : 0);
		array[87] = 0f;
		FindSun();
		if ((Object)(object)sun != (Object)null)
		{
			Vector3 forward = ((Component)sun).transform.forward;
			Color val2 = sun.color * sun.intensity;
			array[88] = forward.x;
			array[89] = forward.y;
			array[90] = forward.z;
			array[91] = 1f;
			array[92] = val2.r;
			array[93] = val2.g;
			array[94] = val2.b;
			array[95] = 1f;
		}
		else
		{
			Vector3 val3 = new Vector3(-0.35f, -1f, -0.25f);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			array[88] = normalized.x;
			array[89] = normalized.y;
			array[90] = normalized.z;
			array[91] = 0f;
			array[92] = (array[93] = (array[94] = 1f));
			array[95] = 0f;
		}
	}

	private void FindSun()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Invalid comparison between Unknown and I4
		if (Time.unscaledTime < nextSunSearch && ((Object)(object)sun == (Object)null || ((Behaviour)sun).isActiveAndEnabled))
		{
			return;
		}
		nextSunSearch = Time.unscaledTime + 2f;
		sun = null;
		float num = 0f;
		Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0);
		foreach (Light val in array)
		{
			if ((int)val.type == 1 && ((Behaviour)val).isActiveAndEnabled && val.intensity > num)
			{
				num = val.intensity;
				sun = val;
			}
		}
	}

	public EffectInstance AddEffect(string assetId)
	{
		EffectAsset effectAsset = Lib.Get(assetId);
		if (effectAsset == null)
		{
			return null;
		}
		EffectInstance effectInstance = new EffectInstance
		{
			AssetId = assetId,
			Expanded = true
		};
		effectInstance.ResetToDefaults(effectAsset.Def);
		Stack.Add(effectInstance);
		Dirty = true;
		return effectInstance;
	}

	public PresetData CaptureState(string name, bool includeRendering, bool includeUnityFx)
	{
		PresetData presetData = new PresetData
		{
			name = name
		};
		foreach (EffectInstance item in Stack)
		{
			PresetEffect presetEffect = new PresetEffect
			{
				shader = item.AssetId,
				enabled = item.Enabled,
				mix = item.Mix
			};
			foreach (KeyValuePair<string, float[]> value in item.Values)
			{
				presetEffect.values[value.Key] = (float[])value.Value.Clone();
			}
			presetData.effects.Add(presetEffect);
		}
		if (includeRendering)
		{
			presetData.rendering = Rendering.Settings.Clone();
		}
		if (includeUnityFx)
		{
			presetData.unityFxEnabled = UnityFx.Enabled;
			presetData.unityFxWeight = UnityFx.Weight;
			presetData.unityFx = UnityFx.Capture();
		}
		return presetData;
	}

	public void ApplyPreset(PresetData p, bool append)
	{
		if (!append)
		{
			Stack.Clear();
		}
		List<string> list = new List<string>();
		foreach (PresetEffect effect in p.effects)
		{
			EffectAsset effectAsset = Lib.Get(effect.shader);
			if (effectAsset == null)
			{
				list.Add(effect.shader);
				continue;
			}
			EffectInstance effectInstance = new EffectInstance
			{
				AssetId = effect.shader,
				Enabled = effect.enabled,
				Mix = effect.mix
			};
			effectInstance.ResetToDefaults(effectAsset.Def);
			if (effect.values != null)
			{
				foreach (KeyValuePair<string, float[]> value in effect.values)
				{
					if (value.Value != null && effectInstance.Values.ContainsKey(value.Key))
					{
						float[] array = effectInstance.Values[value.Key];
						for (int i = 0; i < Math.Min(4, value.Value.Length); i++)
						{
							array[i] = value.Value[i];
						}
					}
				}
			}
			Stack.Add(effectInstance);
		}
		if (!append)
		{
			if (p.rendering != null)
			{
				Rendering.Settings = p.rendering.Clone();
			}
			if (p.unityFx != null)
			{
				UnityFx.Enabled = p.unityFxEnabled;
				UnityFx.Weight = p.unityFxWeight;
				UnityFx.Restore(p.unityFx);
			}
		}
		if (list.Count > 0)
		{
			UI.Toast("Missing shaders: " + string.Join(", ", list.ToArray()));
		}
		Dirty = true;
	}

	public void LoadPresetList()
	{
		Presets.Clear();
		string[] array = new string[2] { BuiltInPresetDir, UserPresetDir };
		foreach (string text in array)
		{
			if (!Directory.Exists(text))
			{
				continue;
			}
			foreach (string item in from x in Directory.GetFiles(text, "*.json")
				orderby x
				select x)
			{
				try
				{
					PresetData presetData = JsonConvert.DeserializeObject<PresetData>(File.ReadAllText(item));
					if (presetData != null)
					{
						presetData.Path = item;
						presetData.BuiltIn = text == BuiltInPresetDir;
						if (string.IsNullOrEmpty(presetData.name))
						{
							presetData.name = Path.GetFileNameWithoutExtension(item);
						}
						Presets.Add(presetData);
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Bad preset " + item + ": " + ex.Message));
				}
			}
		}
	}

	public string SavePreset(string name, string description, bool includeRendering, bool includeUnityFx)
	{
		PresetData presetData = CaptureState(name, includeRendering, includeUnityFx);
		presetData.description = description ?? "";
		string text = Path.Combine(UserPresetDir, Library.SafeId(name) + ".json");
		File.WriteAllText(text, JsonConvert.SerializeObject((object)presetData, (Formatting)1));
		LoadPresetList();
		return text;
	}

	public void SaveState()
	{
		try
		{
			PresetData presetData = CaptureState("current", includeRendering: true, includeUnityFx: true);
			File.WriteAllText(StatePath, JsonConvert.SerializeObject((object)presetData, (Formatting)1));
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Could not save state: " + ex.Message));
		}
	}

	private void LoadState()
	{
		try
		{
			if (File.Exists(StatePath))
			{
				PresetData presetData = JsonConvert.DeserializeObject<PresetData>(File.ReadAllText(StatePath));
				if (presetData != null)
				{
					ApplyPreset(presetData, append: false);
				}
				Dirty = false;
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Could not load last setup: " + ex.Message));
		}
	}

	public void LogProcessError(Exception e)
	{
		if (!loggedProcessError)
		{
			loggedProcessError = true;
			Plugin.Log.LogError((object)("Shader Studio render error (effects bypassed this frame): " + e));
		}
	}
}
public class StudioCamera : MonoBehaviour
{
	private Camera cam;

	private void Awake()
	{
		cam = ((Component)this).GetComponent<Camera>();
	}

	private void OnRenderImage(RenderTexture src, RenderTexture dst)
	{
		Studio i = Studio.I;
		if ((Object)(object)i == (Object)null)
		{
			Graphics.Blit((Texture)(object)src, dst);
			return;
		}
		try
		{
			i.Process(cam, src, dst);
		}
		catch (Exception e)
		{
			i.LogProcessError(e);
			Graphics.Blit((Texture)(object)src, dst);
		}
	}
}
public class RenderingSettings
{
	public bool shadowsOverride;

	public int shadowQuality = 2;

	public int shadowResolution = 3;

	public float shadowDistance = 120f;

	public int shadowCascades = 4;

	public int lightShadowMode;

	public bool lightShadowStrengthOverride;

	public float lightShadowStrength = 1f;

	public bool lightsOverride;

	public float lightIntensity = 1f;

	public float lightRange = 1f;

	public float[] lightTint = new float[4] { 1f, 1f, 1f, 1f };

	public bool ambientOverride;

	public float ambientMultiplier = 1f;

	public float[] ambientTint = new float[4] { 1f, 1f, 1f, 1f };

	public bool fogOverride;

	public bool fogEnabled = true;

	public float[] fogColor = new float[4] { 0.5f, 0.55f, 0.6f, 1f };

	public float fogDensity = 0.02f;

	public bool reflectionOverride;

	public float reflectionIntensity = 1f;

	public bool fovOverride;

	public float fov = 90f;

	public bool msaaOverride;

	public int msaa = 4;

	public bool hdrOverride;

	public bool hdr = true;

	public bool qualityOverride;

	public int pixelLightCount = 8;

	public int anisotropic = 2;

	public float lodBias = 2f;

	public RenderingSettings Clone()
	{
		RenderingSettings obj = (RenderingSettings)MemberwiseClone();
		obj.lightTint = (float[])lightTint.Clone();
		obj.ambientTint = (float[])ambientTint.Clone();
		obj.fogColor = (float[])fogColor.Clone();
		return obj;
	}
}
public class RenderingTweaks
{
	private struct LightOrig
	{
		public float intensity;

		public float range;

		public float shadowStrength;

		public LightShadows shadows;

		public Color color;
	}

	public RenderingSettings Settings = new RenderingSettings();

	private readonly Dictionary<Light, LightOrig> lights = new Dictionary<Light, LightOrig>();

	private float nextLightScan;

	private bool qsCaptured;

	private ShadowQuality oShadows;

	private ShadowResolution oShadowRes;

	private float oShadowDist;

	private int oCascades;

	private int oPixelLights;

	private AnisotropicFiltering oAniso;

	private float oLodBias;

	private int oAA;

	private bool rsCaptured;

	private Color oAmbient;

	private Color oAmbSky;

	private Color oAmbEq;

	private Color oAmbGround;

	private float oAmbIntensity;

	private bool oFog;

	private Color oFogColor;

	private float oFogDensity;

	private FogMode oFogMode;

	private float oRefl;

	private Camera camCaptured;

	private float oFov;

	private bool oHdr;

	private bool oMsaa;

	private bool fovHooked;

	private bool hdrWas;

	private bool msaaWas;

	private bool lightsWas;

	private bool shadowModeWas;

	private bool strengthWas;

	private Camera fovCam;

	public RenderingTweaks()
	{
		SceneManager.sceneLoaded += delegate
		{
			rsCaptured = false;
			lights.Clear();
		};
	}

	private static Color C(float[] a)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		return new Color(a[0], a[1], a[2], (a.Length > 3) ? a[3] : 1f);
	}

	public void Tick(Camera cam)
	{
		//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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: 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_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0363: 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_036e: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_038f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0444: Unknown result type (might be due to invalid IL or missing references)
		//IL_044f: Unknown result type (might be due to invalid IL or missing references)
		//IL_045a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0465: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0401: Unknown result type (might be due to invalid IL or missing references)
		//IL_040c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0411: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Unknown result type (might be due to invalid IL or missing references)
		//IL_041e: 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_0425: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0493: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: 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_06df: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ef: Expected O, but got Unknown
		//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f9: Expected O, but got Unknown
		//IL_061c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0626: Expected O, but got Unknown
		//IL_0626: Unknown result type (might be due to invalid IL or missing references)
		//IL_0630: Expected O, but got Unknown
		RenderingSettings settings = Settings;
		bool flag = settings.shadowsOverride || settings.qualityOverride || settings.msaaOverride;
		if (flag && !qsCaptured)
		{
			oShadows = QualitySettings.shadows;
			oShadowRes = QualitySettings.shadowResolution;
			oShadowDist = QualitySettings.shadowDistance;
			oCascades = QualitySettings.shadowCascades;
			oPixelLights = QualitySettings.pixelLightCount;
			oAniso = QualitySettings.anisotropicFiltering;
			oLodBias = QualitySettings.lodBias;
			oAA = QualitySettings.antiAliasing;
			qsCaptured = true;
		}
		if (qsCaptured)
		{
			if (settings.shadowsOverride)
			{
				Set(QualitySettings.shadows, (ShadowQuality)((settings.shadowQuality != 0) ? ((settings.shadowQuality == 1) ? 1 : 2) : 0), delegate(ShadowQuality v)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					QualitySettings.shadows = v;
				});
				Set(QualitySettings.shadowResolution, (ShadowResolution)Mathf.Clamp(settings.shadowResolution, 0, 3), delegate(ShadowResolution v)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					QualitySettings.shadowResolution = v;
				});
				if (!Mathf.Approximately(QualitySettings.shadowDistance, settings.shadowDistance))
				{
					QualitySettings.shadowDistance = settings.shadowDistance;
				}
				int num = ((settings.shadowCascades > 1) ? ((settings.shadowCascades <= 2) ? 2 : 4) : 0);
				if (QualitySettings.shadowCascades != num)
				{
					QualitySettings.shadowCascades = num;
				}
			}
			else
			{
				Set(QualitySettings.shadows, oShadows, delegate(ShadowQuality v)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					QualitySettings.shadows = v;
				});
				Set(QualitySettings.shadowResolution, oShadowRes, delegate(ShadowResolution v)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					QualitySettings.shadowResolution = v;
				});
				if (!Mathf.Approximately(QualitySettings.shadowDistance, oShadowDist))
				{
					QualitySettings.shadowDistance = oShadowDist;
				}
				if (QualitySettings.shadowCascades != oCascades)
				{
					QualitySettings.shadowCascades = oCascades;
				}
			}
			if (settings.qualityOverride)
			{
				if (QualitySettings.pixelLightCount != settings.pixelLightCount)
				{
					QualitySettings.pixelLightCount = settings.pixelLightCount;
				}
				Set(QualitySettings.anisotropicFiltering, (AnisotropicFiltering)Mathf.Clamp(settings.anisotropic, 0, 2), delegate(AnisotropicFiltering v)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					QualitySettings.anisotropicFiltering = v;
				});
				if (!Mathf.Approximately(QualitySettings.lodBias, settings.lodBias))
				{
					QualitySettings.lodBias = settings.lodBias;
				}
			}
			else
			{
				if (QualitySettings.pixelLightCount != oPixelLights)
				{
					QualitySettings.pixelLightCount = oPixelLights;
				}
				Set(QualitySettings.anisotropicFiltering, oAniso, delegate(AnisotropicFiltering v)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					QualitySettings.anisotropicFiltering = v;
				});
				if (!Mathf.Approximately(QualitySettings.lodBias, oLodBias))
				{
					QualitySettings.lodBias = oLodBias;
				}
			}
			int num2 = ((!settings.msaaOverride) ? oAA : ((settings.msaa >= 8) ? 8 : ((settings.msaa >= 4) ? 4 : ((settings.msaa >= 2) ? 2 : 0))));
			if (QualitySettings.antiAliasing != num2)
			{
				QualitySettings.antiAliasing = num2;
			}
			if (!flag)
			{
				qsCaptured = false;
			}
		}
		bool flag2 = settings.ambientOverride || settings.fogOverride || settings.reflectionOverride;
		if (flag2 && !rsCaptured)
		{
			oAmbient = RenderSettings.ambientLight;
			oAmbSky = RenderSettings.ambientSkyColor;
			oAmbEq = RenderSettings.ambientEquatorColor;
			oAmbGround = RenderSettings.ambientGroundColor;
			oAmbIntensity = RenderSettings.ambientIntensity;
			oFog = RenderSettings.fog;
			oFogColor = RenderSettings.fogColor;
			oFogDensity = RenderSettings.fogDensity;
			oFogMode = RenderSettings.fogMode;
			oRefl = RenderSettings.reflectionIntensity;
			rsCaptured = true;
		}
		if (rsCaptured)
		{
			if (settings.ambientOverride)
			{
				Color b = C(settings.ambientTint) * settings.ambientMultiplier;
				RenderSettings.ambientLight = Mul(oAmbient, b);
				RenderSettings.ambientSkyColor = Mul(oAmbSky, b);
				RenderSettings.ambientEquatorColor = Mul(oAmbEq, b);
				RenderSettings.ambientGroundColor = Mul(oAmbGround, b);
				RenderSettings.ambientIntensity = oAmbIntensity * settings.ambientMultiplier;
			}
			else
			{
				RenderSettings.ambientLight = oAmbient;
				RenderSettings.ambientSkyColor = oAmbSky;
				RenderSettings.ambientEquatorColor = oAmbEq;
				RenderSettings.ambientGroundColor = oAmbGround;
				RenderSettings.ambientIntensity = oAmbIntensity;
			}
			if (settings.fogOverride)
			{
				RenderSettings.fog = settings.fogEnabled;
				RenderSettings.fogColor = C(settings.fogColor);
				RenderSettings.fogMode = (FogMode)3;
				RenderSettings.fogDensity = settings.fogDensity;
			}
			else
			{
				RenderSettings.fog = oFog;
				RenderSettings.fogColor = oFogColor;
				RenderSettings.fogDensity = oFogDensity;
				RenderSettings.fogMode = oFogMode;
			}
			RenderSettings.reflectionIntensity = (settings.reflectionOverride ? settings.reflectionIntensity : oRefl);
			if (!flag2)
			{
				rsCaptured = false;
			}
		}
		if ((Object)(object)cam != (Object)null)
		{
			if ((Object)(object)camCaptured != (Object)(object)cam)
			{
				if ((Object)(object)camCaptured != (Object)null)
				{
					RestoreCam();
				}
				camCaptured = cam;
				oFov = cam.fieldOfView;
				oHdr = cam.allowHDR;
				oMsaa = cam.allowMSAA;
			}
			if (settings.hdrOverride)
			{
				cam.allowHDR = settings.hdr;
			}
			else if (hdrWas)
			{
				cam.allowHDR = oHdr;
			}
			if (settings.msaaOverride)
			{
				cam.allowMSAA = settings.msaa > 0;
			}
			else if (msaaWas)
			{
				cam.allowMSAA = oMsaa;
			}
			hdrWas = settings.hdrOverride;
			msaaWas = settings.msaaOverride;
			if (settings.fovOverride && !fovHooked)
			{
				Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnPreCull));
				fovHooked = true;
			}
			if (!settings.fovOverride && fovHooked)
			{
				Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnPreCull));
				fovHooked = false;
				if ((Object)(object)camCaptured != (Object)null)
				{
					camCaptured.fieldOfView = oFov;
				}
			}
			fovCam = cam;
		}
		if (Time.unscaledTime > nextLightScan)
		{
			nextLightScan = Time.unscaledTime + 1f;
			Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0);
			foreach (Light val in array)
			{
				if (!lights.ContainsKey(val))
				{
					lights[val] = new LightOrig
					{
						intensity = val.intensity,
						range = val.range,
						shadowStrength = val.shadowStrength,
						shadows = val.shadows,
						color = val.color
					};
				}
			}
			List<Light> list = new List<Light>();
			foreach (KeyValuePair<Light, LightOrig> light in lights)
			{
				if ((Object)(object)light.Key == (Object)null)
				{
					list.Add(light.Key);
				}
			}
			foreach (Light item in list)
			{
				lights.Remove(item);
			}
		}
		ApplyLights();
	}

	private void OnPreCull(Camera c)
	{
		if ((Object)(object)c == (Object)(object)fovCam && Settings.fovOverride)
		{
			c.fieldOfView = Settings.fov;
		}
	}

	private void RestoreCam()
	{
		if (!((Object)(object)camCaptured == (Object)null))
		{
			camCaptured.allowHDR = oHdr;
			camCaptured.allowMSAA = oMsaa;
			camCaptured.fieldOfView = oFov;
		}
	}

	private void ApplyLights()
	{
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		RenderingSettings settings = Settings;
		bool lightsOverride = settings.lightsOverride;
		bool flag = settings.lightShadowMode != 0;
		bool lightShadowStrengthOverride = settings.lightShadowStrengthOverride;
		if (!lightsOverride && !lightsWas && !flag && !shadowModeWas && !lightShadowStrengthOverride && !strengthWas)
		{
			return;
		}
		foreach (KeyValuePair<Light, LightOrig> light in lights)
		{
			Light key = light.Key;
			if ((Object)(object)key == (Object)null)
			{
				continue;
			}
			LightOrig value = light.Value;
			if (lightsOverride || lightsWas)
			{
				float num = (lightsOverride ? (value.intensity * settings.lightIntensity) : value.intensity);
				float num2 = (lightsOverride ? (value.range * settings.lightRange) : value.range);
				Color val = (lightsOverride ? Mul(value.color, C(settings.lightTint)) : value.color);
				if (!Mathf.Approximately(key.intensity, num))
				{
					key.intensity = num;
				}
				if (!Mathf.Approximately(key.range, num2))
				{
					key.range = num2;
				}
				if (key.color != val)
				{
					key.color = val;
				}
			}
			if (flag || shadowModeWas)
			{
				LightShadows val2 = (LightShadows)((settings.lightShadowMode == 1) ? 2 : ((settings.lightShadowMode == 2) ? 1 : ((settings.lightShadowMode != 3) ? ((int)value.shadows) : 0)));
				if (key.shadows != val2)
				{
					key.shadows = val2;
				}
			}
			if (lightShadowStrengthOverride || strengthWas)
			{
				float num3 = (lightShadowStrengthOverride ? settings.lightShadowStrength : value.shadowStrength);
				if (!Mathf.Approximately(key.shadowStrength, num3))
				{
					key.shadowStrength = num3;
				}
			}
		}
		lightsWas = lightsOverride;
		shadowModeWas = flag;
		strengthWas = lightShadowStrengthOverride;
	}

	private static Color Mul(Color a, Color b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: 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)
		return new Color(a.r * b.r, a.g * b.g, a.b * b.b, a.a);
	}

	private static void Set<T>(T cur, T want, Action<T> set)
	{
		if (!EqualityComparer<T>.Default.Equals(cur, want))
		{
			set(want);
		}
	}
}
public enum UType
{
	Float,
	Float2,
	Float3,
	Float4,
	Int,
	Bool,
	Texture
}
public class UniformDef
{
	public string Name;

	public UType Type;

	public bool IsColor;

	public bool HasRange;

	public float Min;

	public float Max = 1f;

	public float Step;

	public string[] EnumNames;

	public float[] Default = new float[4];

	public string File;

	public string Tooltip;

	public int Slot;

	public int Components => Type switch
	{
		UType.Float2 => 2, 
		UType.Float3 => 3, 
		UType.Float4 => 4, 
		UType.Texture => 0, 
		_ => 1, 
	};
}
public class PassDef
{
	public string Entry;

	public float Scale = 1f;
}
public class ShaderDef
{
	public string Id;

	public string Name;

	public string Category = "Custom";

	public string Description = "";

	public string Author = "";

	public string Path;

	public bool BuiltIn;

	public string Source = "";

	public DateTime LastWrite;

	public readonly List<UniformDef> Uniforms = new List<UniformDef>();

	public readonly List<PassDef> Passes = new List<PassDef>();

	public bool UsesDepth;

	public string ParseError;

	public string Body = "";

	public string FileName = "shader.hlsl";

	private static readonly Regex RxUniform = new Regex("^\\s*uniform\\s+(\\w+)\\s+(\\w+)\\s*(?::\\s*(\\w+)\\s*(?:\\((.*?)\\))?)?\\s*(?:=\\s*(.*?))?\\s*;\\s*(?://\\s*(.*))?$", RegexOptions.Compiled);

	private static readonly Regex RxPass = new Regex("^\\s*#\\s*pass\\s+(\\w+)(?:\\s+(?:scale\\s*=\\s*)?([0-9]*\\.?[0-9]+))?", RegexOptions.Compiled);

	private static readonly Regex RxMeta = new Regex("^\\s*//\\s*@(\\w+)\\s+(.*)$", RegexOptions.Compiled);

	private static readonly Regex RxNumber = new Regex("[-+]?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?", RegexOptions.Compiled);

	private static readonly Regex RxDepth = new Regex("\\b(rawDepth|linearDepth|eyeDepth|isSky|viewPos|worldPos|viewNormal|worldNormal|_Depth)\\b", RegexOptions.Compiled);

	private static readonly Regex RxString = new Regex("\"([^\"]*)\"", RegexOptions.Compiled);

	public const int MaxUniformSlots = 32;

	public const int MaxTextures = 4;

	public const int MaxPasses = 17;

	private static float F(string s)
	{
		if (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
		{
			return 0f;
		}
		return result;
	}

	public static ShaderDef Parse(string source, string path, bool builtIn)
	{
		ShaderDef shaderDef = new ShaderDef();
		shaderDef.Path = path;
		shaderDef.BuiltIn = builtIn;
		shaderDef.Source = source ?? "";
		shaderDef.FileName = ((path != null) ? System.IO.Path.GetFileName(path) : "shader.hlsl");
		shaderDef.Id = ((path != null) ? System.IO.Path.GetFileNameWithoutExtension(path) : "shader");
		shaderDef.Name = shaderDef.Id;
		StringBuilder stringBuilder = new StringBuilder();
		string[] array = shaderDef.Source.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n');
		StringBuilder stringBuilder2 = new StringBuilder();
		int num = 0;
		int num2 = 0;
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i];
			Match match = RxMeta.Match(text);
			if (match.Success)
			{
				string text2 = match.Groups[1].Value.ToLowerInvariant();
				string text3 = match.Groups[2].Value.Trim();
				switch (text2)
				{
				case "name":
					shaderDef.Name = text3;
					break;
				case "category":
					shaderDef.Category = text3;
					break;
				case "description":
					shaderDef.Description = ((shaderDef.Description.Length > 0) ? (shaderDef.Description + " ") : "") + text3;
					break;
				case "author":
					shaderDef.Author = text3;
					break;
				}
			}
			Match match2 = RxPass.Match(text);
			if (match2.Success)
			{
				PassDef passDef = new PassDef
				{
					Entry = match2.Groups[1].Value
				};
				if (match2.Groups[2].Success)
				{
					passDef.Scale = Math.Max(0.001f, Math.Min(4f, F(match2.Groups[2].Value)));
				}
				shaderDef.Passes.Add(passDef);
				stringBuilder2.Append('\n');
			}
			else if (text.TrimStart().StartsWith("uniform ", StringComparison.Ordinal))
			{
				Match match3 = RxUniform.Match(text);
				if (!match3.Success)
				{
					stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): could not parse uniform declaration");
					stringBuilder2.Append('\n');
					continue;
				}
				UniformDef uniformDef = new UniformDef();
				uniformDef.Name = match3.Groups[2].Value;
				string text4 = match3.Groups[1].Value.ToLowerInvariant();
				string text5 = (match3.Groups[3].Success ? match3.Groups[3].Value.ToLowerInvariant() : "");
				string text6 = (match3.Groups[4].Success ? match3.Groups[4].Value : "");
				string text7 = (match3.Groups[5].Success ? match3.Groups[5].Value.Trim() : "");
				uniformDef.Tooltip = (match3.Groups[6].Success ? match3.Groups[6].Value.Trim() : null);
				switch (text4)
				{
				case "float":
				case "half":
					uniformDef.Type = UType.Float;
					break;
				case "half2":
				case "vec2":
				case "float2":
					uniformDef.Type = UType.Float2;
					break;
				case "half3":
				case "vec3":
				case "float3":
					uniformDef.Type = UType.Float3;
					break;
				case "half4":
				case "vec4":
				case "float4":
					uniformDef.Type = UType.Float4;
					break;
				case "color":
					uniformDef.Type = UType.Float4;
					uniformDef.IsColor = true;
					break;
				case "uint":
				case "int":
					uniformDef.Type = UType.Int;
					break;
				case "bool":
					uniformDef.Type = UType.Bool;
					break;
				case "sampler2d":
				case "texture2d":
				case "texture":
					uniformDef.Type = UType.Texture;
					break;
				default:
					stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): unsupported uniform type '" + text4 + "'");
					stringBuilder2.Append('\n');
					continue;
				}
				if (text5 == "color" || text5 == "source_color")
				{
					uniformDef.IsColor = true;
				}
				if (text5 == "range" || text5 == "hint_range")
				{
					MatchCollection matchCollection = RxNumber.Matches(text6);
					if (matchCollection.Count >= 2)
					{
						uniformDef.HasRange = true;
						uniformDef.Min = F(matchCollection[0].Value);
						uniformDef.Max = F(matchCollection[1].Value);
					}
					if (matchCollection.Count >= 3)
					{
						uniformDef.Step = F(matchCollection[2].Value);
					}
				}
				if (text5 == "enum")
				{
					List<string> list = new List<string>();
					foreach (Match item in RxString.Matches(text6))
					{
						list.Add(item.Groups[1].Value);
					}
					if (list.Count == 0)
					{
						string[] array2 = text6.Split(',');
						foreach (string text8 in array2)
						{
							if (text8.Trim().Length > 0)
							{
								list.Add(text8.Trim());
							}
						}
					}
					uniformDef.EnumNames = list.ToArray();
					uniformDef.Type = UType.Int;
					uniformDef.HasRange = true;
					uniformDef.Min = 0f;
					uniformDef.Max = Math.Max(0, list.Count - 1);
				}
				if (text5 == "file")
				{
					Match match5 = RxString.Match(text6);
					uniformDef.File = (match5.Success ? match5.Groups[1].Value : text6.Trim());
				}
				if (uniformDef.Type == UType.Texture)
				{
					if (num2 >= 4)
					{
						stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): too many textures (max 4)");
						stringBuilder2.Append('\n');
						continue;
					}
					uniformDef.Slot = num2++;
				}
				else
				{
					if (num >= 32)
					{
						stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): too many uniforms (max 32)");
						stringBuilder2.Append('\n');
						continue;
					}
					uniformDef.Slot = num++;
					if (uniformDef.IsColor)
					{
						uniformDef.Default[0] = (uniformDef.Default[1] = (uniformDef.Default[2] = (uniformDef.Default[3] = 1f)));
					}
					if (uniformDef.Type == UType.Bool)
					{
						uniformDef.Default[0] = ((text7.Trim().ToLowerInvariant() == "true" || text7.Trim() == "1") ? 1f : 0f);
					}
					else if (text7.Length > 0)
					{
						MatchCollection matchCollection2 = RxNumber.Matches(text7);
						string text9 = text7;
						int num3 = text7.IndexOf('(');
						if (num3 >= 0)
						{
							text9 = text7.Substring(num3 + 1);
							matchCollection2 = RxNumber.Matches(text9);
						}
						int num4 = Math.Min(4, matchCollection2.Count);
						for (int k = 0; k < num4; k++)
						{
							uniformDef.Default[k] = F(matchCollection2[k].Value);
						}
						if (num4 == 1 && uniformDef.Components > 1 && !uniformDef.IsColor)
						{
							for (int l = 1; l < 4; l++)
							{
								uniformDef.Default[l] = uniformDef.Default[0];
							}
						}
						if (num4 == 1 && uniformDef.IsColor)
						{
							uniformDef.Default[1] = (uniformDef.Default[2] = uniformDef.Default[0]);
						}
						if (num4 == 3 && uniformDef.IsColor)
						{
							uniformDef.Default[3] = 1f;
						}
					}
					if (!uniformDef.HasRange && uniformDef.Type == UType.Int)
					{
						uniformDef.Min = 0f;
						uniformDef.Max = 10f;
					}
					if (!uniformDef.HasRange && (uniformDef.Type == UType.Float || uniformDef.Type == UType.Float2 || uniformDef.Type == UType.Float3 || uniformDef.Type == UType.Float4) && !uniformDef.IsColor)
					{
						float num5 = 0f;
						for (int m = 0; m < uniformDef.Components; m++)
						{
							num5 = Math.Max(num5, Math.Abs(uniformDef.Default[m]));
						}
						uniformDef.Min = 0f;
						uniformDef.Max = ((num5 > 0f) ? (num5 * 2f) : 1f);
						for (int n = 0; n < uniformDef.Components; n++)
						{
							if (uniformDef.Default[n] < 0f)
							{
								uniformDef.Min = 0f - uniformDef.Max;
							}
						}
					}
				}
				shaderDef.Uniforms.Add(uniformDef);
				stringBuilder2.Append('\n');
			}
			else
			{
				stringBuilder2.Append(text).Append('\n');
			}
		}
		shaderDef.Body = stringBuilder2.ToString();
		if (shaderDef.Passes.Count == 0)
		{
			shaderDef.Passes.Add(new PassDef
			{
				Entry = "effect"
			});
		}
		if (shaderDef.Passes.Count > 17)
		{
			stringBuilder.AppendLine(shaderDef.FileName + ": too many passes (max " + 17 + ")");
		}
		shaderDef.UsesDepth = RxDepth.IsMatch(shaderDef.Body);
		shaderDef.ParseError = ((stringBuilder.Length > 0) ? stringBuilder.ToString() : null);
		return shaderDef;
	}

	public bool IsFinalPass(int i)
	{
		return i == Passes.Count - 1;
	}

	public string Generate(int passIndex, string prelude, bool lineDirectives)
	{
		StringBuilder stringBuilder = new StringBuilder(prelude.Length + Body.Length + 2048);
		stringBuilder.Append(prelude).Append('\n');
		foreach (UniformDef uniform in Uniforms)
		{
			switch (uniform.Type)
			{
			case UType.Float:
				stringBuilder.Append("static float ").Append(uniform.Name).Append(";\n");
				break;
			case UType.Float2:
				stringBuilder.Append("static float2 ").Append(uniform.Name).Append(";\n");
				break;
			case UType.Float3:
				stringBuilder.Append("static float3 ").Append(uniform.Name).Append(";\n");
				break;
			case UType.Float4:
				stringBuilder.Append("static float4 ").Append(uniform.Name).Append(";\n");
				break;
			case UType.Int:
				stringBuilder.Append("static int ").Append(uniform.Name).Append(";\n");
				break;
			case UType.Bool:
				stringBuilder.Append("static bool ").Append(uniform.Name).Append(";\n");
				break;
			case UType.Texture:
				stringBuilder.Append("#define ").Append(uniform.Name).Append(" _Tex")
					.Append(uniform.Slot)
					.Append('\n');
				break;
			}
		}
		if (lineDirectives)
		{
			stringBuilder.Append("#line 1 \"").Append(FileName.Replace("\"", "")).Append("\"\n");
		}
		stringBuilder.Append(Body);
		stringBuilder.Append("\nfloat4 _SS_Main(float4 _ss_pos : SV_Position) : SV_Target\n{\n");
		stringBuilder.Append("    float2 _ss_uv = _ss_pos.xy * _OutSize.zw;\n");
		stringBuilder.Append("    if (_Flags.z > 0.5) _ss_uv.y = 1.0 - _ss_uv.y;\n");
		stringBuilder.Append("    PIXEL = _ss_uv * _OutSize.xy;\n");
		foreach (UniformDef uniform2 in Uniforms)
		{
			string value = "P[" + uniform2.Slot + "]";
			switch (uniform2.Type)
			{
			case UType.Float:
				stringBuilder.Append("    ").Append(uniform2.Name).Append(" = ")
					.Append(value)
					.Append(".x;\n");
				break;
			case UType.Float2:
				stringBuilder.Append("    ").Append(uniform2.Name).Append(" = ")
					.Append(value)
					.Append(".xy;\n");
				break;
			case UType.Float3:
				stringBuilder.Append("    ").Append(uniform2.Name).Append(" = ")
					.Append(value)
					.Append(".xyz;\n");
				break;
			case UType.Float4:
				stringBuilder.Append("    ").Append(uniform2.Name).Append(" = ")
					.Append(value)
					.Append(";\n");
				break;
			case UType.Int:
				stringBuilder.Append("    ").Append(uniform2.Name).Append(" = (int)round(")
					.Append(value)
					.Append(".x);\n");
				break;
			case UType.Bool:
				stringBuilder.Append("    ").Append(uniform2.Name).Append(" = ")
					.Append(value)
					.Append(".x > 0.5;\n");
				break;
			}
		}
		stringBuilder.Append("    float4 _ss_c = _SS_ToF4(").Append(Passes[passIndex].Entry).Append("(_ss_uv));\n");
		if (IsFinalPass(passIndex))
		{
			stringBuilder.Append("    _ss_c = lerp(scene(_ss_uv), _ss_c, _Mix.x);\n");
		}
		stringBuilder.Append("    return _ss_c;\n}\n");
		return stringBuilder.ToString();
	}

	public static string NewShaderTemplate(string name)
	{
		return "// @name " + name + "\n// @category Custom\n// @description My own effect. Edit me, then press Save & Compile (Ctrl+S).\n\nuniform float strength : range(0, 1) = 0.5;     // how strong the effect is\nuniform float3 tint : color = float3(1.0, 0.7, 0.4);\nuniform float speed : range(0, 5) = 1.0;\n\nfloat4 effect(float2 uv)\n{\n    // wobble the image a little\n    float2 offset = float2(sin(uv.y * 30.0 + TIME * speed), cos(uv.x * 30.0 + TIME * speed)) * 0.003 * strength;\n    float3 col = scene(uv + offset).rgb;\n\n    // tint the shadows\n    float l = luma(col);\n    col = lerp(col, col * tint, strength * (1.0 - l));\n\n    return float4(col, 1.0);\n}\n";
	}
}
public class StudioUI
{
	private readonly Studio S;

	private Rect win = new Rect(60f, 60f, 1000f, 700f);

	private int tab;

	private static readonly string[] Tabs = new string[7] { "Effects", "Library", "Code Editor", "Presets", "Unity FX", "Rendering", "Settings & Help" };

	private GUISkin skin;

	private GUIStyle hStyle;

	private GUIStyle h2Style;

	private GUIStyle smallStyle;

	private GUIStyle dimStyle;

	private GUIStyle codeStyle;

	private GUIStyle lineNoStyle;

	private GUIStyle errStyle;

	private GUIStyle okStyle;

	private GUIStyle warnStyle;

	private GUIStyle tabOn;

	private GUIStyle tabOff;

	private GUIStyle panel;

	private GUIStyle card;

	private GUIStyle toastStyle;

	private GUIStyle titleStyle;

	private GUIStyle chipStyle;

	private Texture2D white;

	private Font mono;

	private int monoSize;

	private string toastText;

	private float toastUntil;

	private readonly Dictionary<string, string> numBuf = new Dictionary<string, string>();

	private Vector2 scStack;

	private Vector2 scLib;

	private Vector2 scEdit;

	private Vector2 scErr;

	private Vector2 scPresets;

	private Vector2 scFx;

	private Vector2 scRender;

	private Vector2 scHelp;

	private Vector2 scPick;

	private bool resizing;

	private Vector2 resizeStart;

	private Rect resizeWin;

	private string search = "";

	private string category = "All";

	private string newShaderName = "My Shader";

	private string confirmDelete;

	private float confirmUntil;

	private string edId;

	private string edText = "";

	private string edLineNumbers = "";

	private bool edDirty;

	private bool edPicker;

	private int edLineCount = -1;

	private float edMaxWidth = 600f;

	private string presetName = "My Preset";

	private string presetDesc = "";

	private bool presetIncRendering = true;

	private bool presetIncUnity = true;

	private readonly HashSet<string> fxExpanded = new HashSet<string>();

	private static readonly Regex RxErr = new Regex("^.*?\\((\\d+),(\\d+)(?:-\\d+)?\\):\\s*(error|warning)\\s*(\\w+)?:\\s*(.*)$", RegexOptions.Multiline);

	private const string HelpText = "Every effect is a plain HLSL file (DirectX shader code) - the same idea as Godot's shader language.\nWrite a function that returns the new color of a pixel:\n\n    float4 effect(float2 uv) { return scene(uv) * float4(1, 0.5, 0.5, 1); }\n\nuv goes from (0,0) bottom-left to (1,1) top-right.  scene(uv) reads the game image.\n\nSliders come from uniforms:\n    uniform float strength : range(0, 2) = 1.0;     // tooltip\n    uniform float3 tint : color = float3(1, 0.5, 0.2);\n    uniform int mode : enum(\"Soft\", \"Hard\") = 0;\n    uniform bool invert = false;\n    uniform texture2D lut : file(\"lut.png\");  then  tex(lut, uv)\n\nUseful built-ins: TIME, RES, TEXEL, PIXEL, scene(), history() (last frame), eyeDepth(uv), worldPos(uv), worldNormal(uv),\nviewNormal(uv), isSky(uv), luma(), rgb2hsv(), hsv2rgb(), valueNoise(), fbm(), voronoi(), hash12(), bayer8(), discBlur(), rot2().\n\nMulti-pass:  #pass Name 0.5  declares a pass at half resolution (function float4 Name(float2 uv)). The last #pass is the output.\nRead earlier passes with samplePass(index, uv).\n\nYour shaders live in BepInEx/config/ShaderStudio/shaders and hot-reload when you save them in any editor.\nBuilt-in shaders can be viewed; saving one creates your own copy.\nAvoid naming uniforms like built-in functions (scene, contrast, saturation, luma...) or HLSL keywords (line, point, sample, linear).";

	public StudioUI(Studio s)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		S = s;
	}

	public void Toast(string msg)
	{
		toastText = msg;
		toastUntil = Time.unscaledTime + 4f;
		Plugin.Log.LogInfo((object)msg);
	}

	private static Texture2D Tex(Color c)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false)
		{
			hideFlags = (HideFlags)61
		};
		val.SetPixel(0, 0, c);
		val.Apply();
		return val;
	}

	private void InitStyles()
	{
		//IL_08eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_08fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0908: Unknown result type (might be due to invalid IL or missing references)
		//IL_090f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0916: Unknown result type (might be due to invalid IL or missing references)
		//IL_091b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0925: Expected O, but got Unknown
		//IL_092a: Expected O, but got Unknown
		//IL_0944: Unknown result type (might be due to invalid IL or missing references)
		//IL_0968: Unknown result type (might be due to invalid IL or missing references)
		//IL_097e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0983: Unknown result type (might be due to invalid IL or missing references)
		//IL_098f: Unknown result type (might be due to invalid IL or missing references)
		//IL_099b: Unknown result type (might be due to invalid IL or missing references)
		//IL_09a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_09a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_09b1: Expected O, but got Unknown
		//IL_09b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_09bd: Expected O, but got Unknown
		//IL_09d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Expected O, but got Unknown
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: 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_023a: 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_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Expected O, but got Unknown
		//IL_0367: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_0432: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0538: Unknown result type (might be due to invalid IL or missing references)
		//IL_053d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0545: Unknown result type (might be due to invalid IL or missing references)
		//IL_0551: Expected O, but got Unknown
		//IL_056b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0581: Unknown result type (might be due to invalid IL or missing references)
		//IL_0586: Unknown result type (might be due to invalid IL or missing references)
		//IL_058e: Unknown result type (might be due to invalid IL or missing references)
		//IL_059a: Expected O, but got Unknown
		//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d4: Expected O, but got Unknown
		//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0604: Unknown result type (might be due to invalid IL or missing references)
		//IL_0609: Unknown result type (might be due to invalid IL or missing references)
		//IL_0611: Unknown result type (might be due to invalid IL or missing references)
		//IL_061d: Expected O, but got Unknown
		//IL_0637: Unknown result type (might be due to invalid IL or missing references)
		//IL_0648: Unknown result type (might be due to invalid IL or missing references)
		//IL_064d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0659: Expected O, but got Unknown
		//IL_0673: Unknown result type (might be due to invalid IL or missing references)
		//IL_0684: Unknown result type (might be due to invalid IL or missing references)
		//IL_068e: Expected O, but got Unknown
		//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c3: Expected O, but got Unknown
		//IL_06dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f8: Expected O, but got Unknown
		//IL_0712: Unknown result type (might be due to invalid IL or missing references)
		//IL_0728: Unknown result type (might be due to invalid IL or missing references)
		//IL_072d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0735: Unknown result type (might be due to invalid IL or missing references)
		//IL_0745: Expected O, but got Unknown
		//IL_074c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0756: Expected O, but got Unknown
		//IL_0785: Unknown result type (might be due to invalid IL or missing references)
		//IL_079b: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_07af: Expected O, but got Unknown
		//IL_07af: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_07be: Expected O, but got Unknown
		//IL_07c3: Expected O, but got Unknown
		//IL_07cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e3: Expected O, but got Unknown
		//IL_07e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f2: Expected O, but got Unknown
		//IL_07f7: Expected O, but got Unknown
		//IL_07fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0803: Unknown result type (might be due to invalid IL or missing references)
		//IL_0810: Expected O, but got Unknown
		//IL_082a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0840: Unknown result type (might be due to invalid IL or missing references)
		//IL_0845: Unknown result type (might be due to invalid IL or missing references)
		//IL_084d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0854: Unknown result type (might be due to invalid IL or missing references)
		//IL_085b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0865: Expected O, but got Unknown
		//IL_0865: Unknown result type (might be due to invalid IL or missing references)
		//IL_0871: Expected O, but got Unknown
		//IL_087c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)skin != (Object)null && (Object)(object)mono != (Object)null && monoSize == S.EditorFontSize.Value)
		{
			return;
		}
		if ((Object)(object)skin == (Object)null)
		{
			skin = Object.Instantiate<GUISkin>(GUI.skin);
			((Object)skin).hideFlags = (HideFlags)61;
			white = Tex(Color.white);
			Texture2D background = Tex(new Color(0.08f, 0.085f, 0.1f, 0.97f));
			Texture2D background2 = Tex(new Color(0.13f, 0.135f, 0.16f, 1f));
			Texture2D background3 = Tex(new Color(0.2f, 0.21f, 0.25f, 1f));
			Texture2D background4 = Tex(new Color(0.27f, 0.29f, 0.35f, 1f));
			Texture2D background5 = Tex(new Color(0.18f, 0.45f, 0.75f, 1f));
			Texture2D background6 = Tex(new Color(0.05f, 0.055f, 0.065f, 1f));
			Texture2D background7 = Tex(new Color(0.22f, 0.55f, 0.95f, 1f));
			skin.window.normal.background = background;
			skin.window.onNormal.background = background;
			skin.window.padding = new RectOffset(10, 10, 30, 10);
			skin.box.normal.background = background2;
			skin.box.normal.textColor = new Color(0.85f, 0.87f, 0.9f);
			GUIStyle[] array = (GUIStyle[])(object)new GUIStyle[2] { skin.button, skin.toggle };
			foreach (GUIStyle obj in array)
			{
				obj.normal.textColor = new Color(0.88f, 0.9f, 0.94f);
				obj.hover.textColor = Color.white;
				obj.active.textColor = Color.white;
				obj.onNormal.textColor = Color.white;
				obj.onHover.textColor = Color.white;
				obj.fontSize = 13;
			}
			skin.button.normal.background = background3;
			skin.button.hover.background = background4;
			skin.button.active.background = background5;
			skin.button.onNormal.background = background5;
			skin.button.onHover.background = background5;
			skin.button.border = new RectOffset(2, 2, 2, 2);
			skin.textField.normal.background = background6;
			skin.textField.focused.background = background6;
			skin.textField.hover.background = background6;
			skin.textField.normal.textColor = new Color(0.9f, 0.92f, 0.95f);
			skin.textField.focused.textColor = Color.white;
			skin.textArea.normal.background = background6;
			skin.textArea.focused.background = background6;
			skin.textArea.hover.background = background6;
			skin.textArea.normal.textColor = new Color(0.9f, 0.92f, 0.95f);
			skin.textArea.focused.textColor = Color.white;
			skin.label.normal.textColor = new Color(0.85f, 0.87f, 0.9f);
			skin.label.fontSize = 13;
			skin.label.wordWrap = false;
			skin.horizontalSlider.normal.background = background6;
			skin.horizontalSliderThumb.normal.background = background7;
			skin.horizontalSliderThumb.hover.background = background5;
			skin.horizontalSliderThumb.active.background = Tex(new Color(0.5f, 0.75f, 1f));
			skin.verticalScrollbar.normal.background = background6;
			skin.verticalScrollbarThumb.normal.background = background4;
			skin.horizontalScrollbar.normal.background = background6;
			skin.horizontalScrollbarThumb.normal.background = background4;
			titleStyle = new GUIStyle(skin.label)
			{
				fontSize = 15,
				fontStyle = (FontStyle)1
			};
			titleStyle.normal.textColor = new Color(0.55f, 0.8f, 1f);
			hStyle = new GUIStyle(skin.label)
			{
				fontSize = 14,
				fontStyle = (FontStyle)1
			};
			hStyle.normal.textColor = Color.white;
			h2Style = new GUIStyle(skin.label)
			{
				fontSize = 13,
				fontStyle = (FontStyle)1
			};
			h2Style.normal.textColor = new Color(0.75f, 0.85f, 1f);
			smallStyle = new GUIStyle(skin.label)
			{
				fontSize = 12,
				wordWrap = true
			};
			smallStyle.normal.textColor = new Color(0.7f, 0.72f, 0.76f);
			dimStyle = new GUIStyle(smallStyle)
			{
				wordWrap = false
			};
			dimStyle.normal.textColor = new Color(0.55f, 0.57f, 0.62f);
			errStyle = new GUIStyle(smallStyle);
			errStyle.normal.textColor = new Color(1f, 0.45f, 0.4f);
			okStyle = new GUIStyle(dimStyle);
			okStyle.normal.textColor = new Color(0.45f, 0.9f, 0.5f);
			warnStyle = new GUIStyle(smallStyle);
			warnStyle.normal.textColor = new Color(1f, 0.8f, 0.35f);
			tabOff = new GUIStyle(skin.button)
			{
				fontSize = 13,
				fixedHeight = 28f
			};
			tabOn = new GUIStyle(tabOff);
			tabOn.normal.background = background5;
			tabOn.hover.background = background5;
			tabOn.normal.textColor = Color.white;
			panel = new GUIStyle(skin.box)
			{
				padding = new RectOffset(8, 8, 6, 6),
				margin = new RectOffset(2, 2, 2, 4)
			};
			card = new GUIStyle(skin.box)
			{
				padding = new RectOffset(8, 8, 6, 8),
				margin = new RectOffset(0, 4, 2, 6)
			};
			chipStyle = new GUIStyle(dimStyle)
			{
				fontSize = 11
			};
			chipStyle.normal.textColor = new Color(0.6f, 0.75f, 0.95f);
			toastStyle = new GUIStyle(skin.box)
			{
				fontSize = 14,
				alignment = (TextAnchor)4,
				padding = new RectOffset(14, 14, 8, 8),
				wordWrap = true
			};
			toastStyle.normal.textColor = Color.white;
		}
		monoSize = S.EditorFontSize.Value;
		try
		{
			mono = Font.CreateDynamicFontFromOSFont(new string[4] { "Consolas", "Cascadia Mono", "Courier New", "Lucida Console" }, monoSize);
		}
		catch
		{
			mono = null;
		}
		codeStyle = new GUIStyle(skin.textArea)
		{
			font = mono,
			fontSize = monoSize,
			wordWrap = false,
			richText = false,
			padding = new RectOffset(6, 6, 4, 4)
		};
		codeStyle.normal.textColor = new Color(0.86f, 0.9f, 0.86f);
		codeStyle.focused.textColor = new Color(0.9f, 0.95f, 0.9f);
		lineNoStyle = new GUIStyle(skin.label)
		{
			font = mono,
			fontSize = monoSize,
			alignment = (TextAnchor)2,
			padding = new RectOffset(0, 6, 4, 4),
			wordWrap = false
		};
		lineNoStyle.normal.textColor = new Color(0.4f, 0.43f, 0.5f);
	}

	public void Draw()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Expected O, but got Unknown
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Expected O, but got Unknown
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		InitStyles();
		GUISkin obj = GUI.skin;
		Matrix4x4 matrix = GUI.matrix;
		GUI.skin = skin;
		float num = Mathf.Clamp(S.UIScale.Value, 0.6f, 2.5f);
		GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
		float num2 = (float)Screen.width / num;
		float num3 = (float)Screen.height / num;
		((Rect)(ref win)).width = Mathf.Clamp(((Rect)(ref win)).width, 640f, num2);
		((Rect)(ref win)).height = Mathf.Clamp(((Rect)(ref win)).height, 400f, num3);
		((Rect)(ref win)).x = Mathf.Clamp(((Rect)(ref win)).x, 0f, num2 - ((Rect)(ref win)).width);
		((Rect)(ref win)).y = Mathf.Clamp(((Rect)(ref win)).y, 0f, num3 - ((Rect)(ref win)).height);
		win = GUI.Window(23251, win, new WindowFunction(DrawWindow), "");
		if (!string.IsNullOrEmpty(GUI.tooltip))
		{
			Vector2 mousePosition = Event.current.mousePosition;
			GUIContent val = new GUIContent(GUI.tooltip);
			Vector2 val2 = toastStyle.CalcSize(val);
			val2.x = Mathf.Min(val2.x, 420f);
			float num4 = toastStyle.CalcHeight(val, val2.x);
			GUI.Box(new Rect(Mathf.Min(mousePosition.x + 16f, num2 - val2.x - 4f), mousePosition.y + 18f, val2.x, num4), val, toastStyle);
		}
		if (toastText != null && Time.unscaledTime < toastUntil)
		{
			GUI.Box(new Rect(num2 * 0.5f - 260f, num3 - 70f, 520f, 44f), toastText, toastStyle);
		}
		GUI.matrix = matrix;
		GUI.skin = obj;
	}

	private void DrawWindow(int id)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Expected O, but got Unknown
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Invalid comparison between Unknown and I4
		//IL_022a: Unknown result type (might be due to invalid IL or missing refe