Decompiled source of Gourdwell v1.0.16

BepInEx/plugins/BigWalk.Gourdwell/BigWalk.Gourdwell.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Mirror;
using Rewired;
using RewiredConsts;
using StbImageSharp;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("BigWalk.Gourdwell")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.16.0")]
[assembly: AssemblyInformationalVersion("1.0.16")]
[assembly: AssemblyProduct("Gourdwell")]
[assembly: AssemblyTitle("BigWalk.Gourdwell")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.16.0")]
[module: UnverifiableCode]
namespace BigWalk.Gourdwell;

internal static class BackProfile
{
	private const int Bins = 24;

	private const float SpineWidth = 0.35f;

	private static float[] _height;

	private static float _min;

	private static float _max;

	public static bool Ready => _height != null;

	public static float Min => _min;

	public static float Max => _max;

	public static void Build(Vector3[] verts, Vector3 forward, Vector3 up)
	{
		//IL_000e: 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_0010: 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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		_height = null;
		if (verts == null || verts.Length == 0)
		{
			return;
		}
		Vector3 val = Vector3.Cross(up, forward);
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		float num = float.MaxValue;
		float num2 = float.MinValue;
		float num3 = 0f;
		for (int i = 0; i < verts.Length; i++)
		{
			float num4 = Vector3.Dot(verts[i], forward);
			if (num4 < num)
			{
				num = num4;
			}
			if (num4 > num2)
			{
				num2 = num4;
			}
			num3 = Mathf.Max(num3, Mathf.Abs(Vector3.Dot(verts[i], normalized)));
		}
		if (num2 - num < 1E-05f)
		{
			return;
		}
		float num5 = num3 * 0.35f;
		float[] array = new float[24];
		bool[] array2 = new bool[24];
		float num6 = (num2 - num) / 24f;
		for (int j = 0; j < verts.Length; j++)
		{
			if (!(Mathf.Abs(Vector3.Dot(verts[j], normalized)) > num5))
			{
				int num7 = Mathf.Clamp(Mathf.FloorToInt((Vector3.Dot(verts[j], forward) - num) / num6), 0, 23);
				float num8 = Vector3.Dot(verts[j], up);
				if (!array2[num7] || num8 > array[num7])
				{
					array[num7] = num8;
					array2[num7] = true;
				}
			}
		}
		FillGaps(array, array2);
		Dilate(array);
		Smooth(array);
		_height = array;
		_min = num;
		_max = num2;
	}

	public static float HeightAt(float along)
	{
		if (_height == null)
		{
			return 0f;
		}
		float num = Mathf.Clamp01((along - _min) / (_max - _min)) * 23f;
		int num2 = Mathf.Clamp(Mathf.FloorToInt(num), 0, 23);
		int num3 = Mathf.Min(num2 + 1, 23);
		return Mathf.Lerp(_height[num2], _height[num3], num - (float)num2);
	}

	private static void FillGaps(float[] heights, bool[] seen)
	{
		int num = -1;
		for (int i = 0; i < 24; i++)
		{
			if (seen[i])
			{
				num = i;
			}
			else if (num >= 0)
			{
				heights[i] = heights[num];
			}
		}
		int num2 = -1;
		for (int num3 = 23; num3 >= 0; num3--)
		{
			if (seen[num3])
			{
				num2 = num3;
			}
			else if (num2 >= 0 && num < 0)
			{
				heights[num3] = heights[num2];
			}
		}
	}

	private static void Dilate(float[] heights)
	{
		float[] array = (float[])heights.Clone();
		for (int i = 0; i < 24; i++)
		{
			int num = Mathf.Max(i - 1, 0);
			int num2 = Mathf.Min(i + 1, 23);
			heights[i] = Mathf.Max(array[num], Mathf.Max(array[i], array[num2]));
		}
	}

	private static void Smooth(float[] heights)
	{
		float[] array = (float[])heights.Clone();
		for (int i = 1; i < 23; i++)
		{
			heights[i] = (array[i - 1] + array[i] * 2f + array[i + 1]) * 0.25f;
		}
	}
}
internal static class GourdAssets
{
	public static Mesh Mesh;

	public static Texture2D Texture;

	public static Material Material;

	public static AudioClip ThemeClip;

	public static AudioClip PurrClip;

	public static Texture2D WhiskerTexture;

	public static Material WhiskerMaterial;

	public static Material[] SubMeshMaterials;

	public static Vector3[] BaseVertices;

	public static Vector3[] BaseNormals;

	public static bool VisualsReady
	{
		get
		{
			if ((Object)(object)Mesh != (Object)null && (Object)(object)Material != (Object)null)
			{
				return (Object)(object)Texture != (Object)null;
			}
			return false;
		}
	}

	public static bool AudioReady => (Object)(object)ThemeClip != (Object)null;
}
internal static class GourdPet
{
	private struct Squish
	{
		public Transform Target;

		public Vector3 BaseScale;

		public Vector3 LocalUp;

		public float StartedAt;
	}

	public const float Duration = 0.5f;

	private const float SquashAmount = 0.16f;

	private const float BulgeAmount = 0.08f;

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

	public static void Pet(int gourdId, Transform visual, Vector3 localUp)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)visual == (Object)null))
		{
			if (!Active.TryGetValue(gourdId, out var value) || (Object)(object)value.Target != (Object)(object)visual)
			{
				value = new Squish
				{
					Target = visual,
					BaseScale = visual.localScale
				};
			}
			value.LocalUp = localUp;
			value.StartedAt = Time.unscaledTime;
			Active[gourdId] = value;
		}
	}

	public static void Tick()
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (Active.Count == 0)
		{
			return;
		}
		List<int> list = null;
		foreach (KeyValuePair<int, Squish> item in Active)
		{
			Squish value = item.Value;
			if ((Object)(object)value.Target == (Object)null)
			{
				if (list == null)
				{
					list = new List<int>();
				}
				list.Add(item.Key);
				continue;
			}
			float num = (Time.unscaledTime - value.StartedAt) / 0.5f;
			try
			{
				if (num >= 1f)
				{
					value.Target.localScale = value.BaseScale;
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(item.Key);
				}
				else
				{
					float k = Mathf.Sin(Mathf.Clamp01(num) * (float)Math.PI);
					value.Target.localScale = Vector3.Scale(value.BaseScale, Factor(value.LocalUp, k));
				}
			}
			catch
			{
				if (list == null)
				{
					list = new List<int>();
				}
				list.Add(item.Key);
			}
		}
		if (list != null)
		{
			for (int i = 0; i < list.Count; i++)
			{
				Active.Remove(list[i]);
			}
		}
	}

	private static Vector3 Factor(Vector3 localUp, float k)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		float num = 1f - 0.16f * k;
		float num2 = 1f + 0.08f * k;
		return new Vector3(Mathf.Lerp(num2, num, Mathf.Abs(localUp.x)), Mathf.Lerp(num2, num, Mathf.Abs(localUp.y)), Mathf.Lerp(num2, num, Mathf.Abs(localUp.z)));
	}
}
internal static class GourdVisual
{
	private struct Tracked
	{
		public Renderer Renderer;

		public Material[] Materials;
	}

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

	private static readonly MaterialPropertyBlock Block = new MaterialPropertyBlock();

	private static readonly string[] AlbedoProps = new string[2] { "_BaseMap", "_MainTex" };

	private static readonly string[] TintProps = new string[2] { "_BaseColor", "_Color" };

	public static Transform GetRoot(RewardGourd gourd)
	{
		if ((Object)(object)gourd == (Object)null)
		{
			return null;
		}
		try
		{
			Prop prop = gourd.prop;
			if ((Object)(object)prop != (Object)null && (Object)(object)((Component)prop).transform != (Object)null)
			{
				return ((Component)prop).transform;
			}
		}
		catch
		{
		}
		try
		{
			return ((Component)gourd).transform;
		}
		catch
		{
			return null;
		}
	}

	public static int SwapInPlace(RewardGourd gourd, Mesh maxwellMesh, Material fallbackMaterial, Texture2D texture, Material whiskerTemplate, out string detail)
	{
		detail = "init";
		if ((Object)(object)gourd == (Object)null || (Object)(object)maxwellMesh == (Object)null || (Object)(object)texture == (Object)null)
		{
			detail = "null-args";
			return 0;
		}
		Transform root = GetRoot(gourd);
		if ((Object)(object)root == (Object)null)
		{
			detail = "no-root";
			return 0;
		}
		detail = "root=" + ((Object)root).name;
		NeutralizePropertyBlockHelper(gourd);
		if (!TryFindTarget(root, out var meshFilter, out var skin, out var target, out var _, out var swapName, ref detail))
		{
			return 0;
		}
		try
		{
			if ((Object)(object)meshFilter != (Object)null)
			{
				meshFilter.sharedMesh = maxwellMesh;
			}
			else if ((Object)(object)skin != (Object)null)
			{
				skin.sharedMesh = maxwellMesh;
			}
		}
		catch (Exception ex)
		{
			detail = detail + " mesh-assign-failed:" + ex.Message;
			return 0;
		}
		Material val = CreateUvLitMaterial(fallbackMaterial, texture);
		if ((Object)(object)val == (Object)null)
		{
			detail += " no-material";
			return 0;
		}
		Material[] array = BuildMaterials(maxwellMesh, val, whiskerTemplate);
		Paint(target, array, texture);
		MeshRenderer val2 = (MeshRenderer)(object)((target is MeshRenderer) ? target : null);
		if (val2 != null)
		{
			HideOtherMeshRenderers(root, val2);
		}
		TrackedByGourd[((Object)gourd).GetInstanceID()] = new Tracked
		{
			Renderer = target,
			Materials = array
		};
		detail = detail + " swapped='" + swapName + "' shader='" + ((Object)val.shader).name + "' submeshes=" + array.Length;
		return 1;
	}

	private static Material[] BuildMaterials(Mesh mesh, Material body, Material whiskerTemplate)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		int num = 1;
		try
		{
			num = Mathf.Max(1, mesh.subMeshCount);
		}
		catch
		{
			num = 1;
		}
		Material[] array = (Material[])(object)new Material[num];
		array[0] = body;
		for (int i = 1; i < num; i++)
		{
			Material val = null;
			if ((Object)(object)whiskerTemplate != (Object)null)
			{
				try
				{
					val = new Material(whiskerTemplate)
					{
						name = "Gourdwell_Whiskers",
						hideFlags = (HideFlags)61
					};
				}
				catch
				{
					val = null;
				}
			}
			array[i] = val ?? body;
		}
		return array;
	}

	private static Material CreateUvLitMaterial(Material fallback, Texture2D texture)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		string[] array = new string[3] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Unlit" };
		Material val = null;
		for (int i = 0; i < array.Length; i++)
		{
			Shader val2 = Shader.Find(array[i]);
			if (!((Object)(object)val2 == (Object)null))
			{
				try
				{
					val = new Material(val2);
				}
				catch
				{
					val = null;
					continue;
				}
				break;
			}
		}
		if ((Object)(object)val == (Object)null && (Object)(object)fallback != (Object)null && (Object)(object)fallback.shader != (Object)null && ((Object)fallback.shader).name != null && ((Object)fallback.shader).name.IndexOf("Better Lit", StringComparison.OrdinalIgnoreCase) < 0)
		{
			try
			{
				val = new Material(fallback);
			}
			catch
			{
				val = null;
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		((Object)val).name = "Gourdwell_Dingus_UV";
		((Object)val).hideFlags = (HideFlags)61;
		try
		{
			if (val.HasProperty("_Surface"))
			{
				val.SetFloat("_Surface", 0f);
			}
			if (val.HasProperty("_Blend"))
			{
				val.SetFloat("_Blend", 0f);
			}
			if (val.HasProperty("_AlphaClip"))
			{
				val.SetFloat("_AlphaClip", 0f);
			}
			if (val.HasProperty("_ZWrite"))
			{
				val.SetFloat("_ZWrite", 1f);
			}
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", 2f);
			}
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", 0f);
			}
			if (val.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Smoothness", 0.35f);
			}
			val.renderQueue = 2000;
			val.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val.DisableKeyword("_ALPHATEST_ON");
		}
		catch
		{
		}
		ApplyDingus(val, texture);
		return val;
	}

	public static Transform GetVisual(RewardGourd gourd)
	{
		if ((Object)(object)gourd == (Object)null)
		{
			return null;
		}
		try
		{
			if (!TrackedByGourd.TryGetValue(((Object)gourd).GetInstanceID(), out var value))
			{
				return null;
			}
			if ((Object)(object)value.Renderer == (Object)null)
			{
				return null;
			}
			return ((Component)value.Renderer).transform;
		}
		catch
		{
			return null;
		}
	}

	public static void MaintainAll(Texture2D texture)
	{
		if (TrackedByGourd.Count == 0 || (Object)(object)texture == (Object)null)
		{
			return;
		}
		List<int> list = null;
		foreach (KeyValuePair<int, Tracked> item in TrackedByGourd)
		{
			Tracked value = item.Value;
			if ((Object)(object)value.Renderer == (Object)null || value.Materials == null || value.Materials.Length == 0 || (Object)(object)value.Materials[0] == (Object)null)
			{
				if (list == null)
				{
					list = new List<int>();
				}
				list.Add(item.Key);
			}
			else
			{
				try
				{
					Paint(value.Renderer, value.Materials, texture);
				}
				catch
				{
				}
			}
		}
		if (list != null)
		{
			for (int i = 0; i < list.Count; i++)
			{
				TrackedByGourd.Remove(list[i]);
			}
		}
	}

	private static bool TryFindTarget(Transform root, out MeshFilter meshFilter, out SkinnedMeshRenderer skin, out Renderer target, out Material donor, out string swapName, ref string detail)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		meshFilter = null;
		skin = null;
		target = null;
		donor = null;
		swapName = "?";
		MeshFilter val = null;
		float num = -1f;
		int num2 = 0;
		try
		{
			Il2CppArrayBase<MeshFilter> componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true);
			if (componentsInChildren != null)
			{
				num2 = componentsInChildren.Length;
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					MeshFilter val2 = componentsInChildren[i];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					float num3 = 0f;
					try
					{
						if ((Object)(object)val2.sharedMesh != (Object)null)
						{
							Bounds bounds = val2.sharedMesh.bounds;
							Vector3 size = ((Bounds)(ref bounds)).size;
							num3 = ((Vector3)(ref size)).sqrMagnitude;
						}
					}
					catch
					{
						num3 = 0f;
					}
					if ((Object)(object)val == (Object)null || num3 > num)
					{
						num = num3;
						val = val2;
					}
				}
			}
		}
		catch (Exception ex)
		{
			detail = detail + " filter-ex=" + ex.Message;
		}
		detail = detail + " filters=" + num2;
		if ((Object)(object)val != (Object)null)
		{
			meshFilter = val;
			target = (Renderer)(object)((Component)val).GetComponent<MeshRenderer>();
			if ((Object)(object)target != (Object)null)
			{
				donor = target.sharedMaterial;
			}
			swapName = ((Object)val).name;
			return (Object)(object)target != (Object)null;
		}
		try
		{
			Il2CppArrayBase<SkinnedMeshRenderer> componentsInChildren2 = ((Component)root).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			if (componentsInChildren2 != null && componentsInChildren2.Length > 0)
			{
				skin = componentsInChildren2[0];
				target = (Renderer)(object)componentsInChildren2[0];
				donor = ((Renderer)componentsInChildren2[0]).sharedMaterial;
				swapName = ((Object)componentsInChildren2[0]).name;
				return true;
			}
		}
		catch
		{
		}
		detail += " nothing-to-swap";
		return false;
	}

	private static void NeutralizePropertyBlockHelper(RewardGourd gourd)
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			PropertyBlockHelper propertyBlockHelper = gourd.propertyBlockHelper;
			if ((Object)(object)propertyBlockHelper == (Object)null)
			{
				return;
			}
			try
			{
				Il2CppReferenceArray<ColorSetting> colorSettings = propertyBlockHelper.colorSettings;
				if (colorSettings != null)
				{
					for (int i = 0; i < ((Il2CppArrayBase<ColorSetting>)(object)colorSettings).Length; i++)
					{
						ColorSetting val = ((Il2CppArrayBase<ColorSetting>)(object)colorSettings)[i];
						val.color = Color.white;
						((Il2CppArrayBase<ColorSetting>)(object)colorSettings)[i] = val;
					}
				}
			}
			catch
			{
			}
			try
			{
				propertyBlockHelper.Refresh();
			}
			catch
			{
			}
			((Behaviour)propertyBlockHelper).enabled = false;
			Object.Destroy((Object)(object)propertyBlockHelper);
		}
		catch
		{
		}
		try
		{
			gourd.variantChallengeColor = Color.white;
		}
		catch
		{
		}
	}

	private static void ApplyDingus(Material mat, Texture2D tex)
	{
		//IL_003b: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)mat == (Object)null || (Object)(object)tex == (Object)null)
		{
			return;
		}
		mat.mainTexture = (Texture)(object)tex;
		for (int i = 0; i < AlbedoProps.Length; i++)
		{
			string text = AlbedoProps[i];
			try
			{
				if (mat.HasProperty(text))
				{
					mat.SetTexture(text, (Texture)(object)tex);
					mat.SetTextureScale(text, Vector2.one);
					mat.SetTextureOffset(text, Vector2.zero);
				}
			}
			catch
			{
			}
		}
		for (int j = 0; j < TintProps.Length; j++)
		{
			string text2 = TintProps[j];
			try
			{
				if (mat.HasProperty(text2))
				{
					mat.SetColor(text2, Color.white);
				}
			}
			catch
			{
			}
		}
	}

	private static void Paint(Renderer r, Material[] mats, Texture2D tex)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		ApplyDingus(mats[0], tex);
		try
		{
			if (mats.Length > 1)
			{
				r.sharedMaterials = Il2CppReferenceArray<Material>.op_Implicit(mats);
			}
			else
			{
				r.sharedMaterial = mats[0];
			}
		}
		catch
		{
			try
			{
				r.sharedMaterial = mats[0];
			}
			catch
			{
			}
		}
		try
		{
			Block.Clear();
			for (int i = 0; i < TintProps.Length; i++)
			{
				try
				{
					Block.SetColor(TintProps[i], Color.white);
				}
				catch
				{
				}
			}
			r.SetPropertyBlock(Block);
		}
		catch
		{
			try
			{
				r.SetPropertyBlock((MaterialPropertyBlock)null);
			}
			catch
			{
			}
		}
		try
		{
			r.forceRenderingOff = false;
			r.enabled = true;
			r.shadowCastingMode = (ShadowCastingMode)1;
			r.receiveShadows = true;
		}
		catch
		{
		}
	}

	private static void HideOtherMeshRenderers(Transform root, MeshRenderer keep)
	{
		MeshRenderer[] array;
		try
		{
			array = Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)root).GetComponentsInChildren<MeshRenderer>(true));
		}
		catch
		{
			return;
		}
		if (array == null)
		{
			return;
		}
		foreach (MeshRenderer val in array)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)keep))
			{
				try
				{
					((Renderer)val).forceRenderingOff = true;
					((Renderer)val).enabled = false;
				}
				catch
				{
				}
			}
		}
	}

	public static void ApplyTexture(Material mat, Texture2D tex)
	{
		ApplyDingus(mat, tex);
	}
}
public sealed class GourdwellController : MonoBehaviour
{
	private const int StateLocked = 0;

	private const int StateLoose = 1;

	private static AudioSource _themeSource;

	private static AudioSource _purrSource;

	private const float PurrTail = 0.9f;

	private const float PurrFadeIn = 0.12f;

	private const float PurrFadeOut = 0.45f;

	private static Transform _purrFollow;

	private static float _purrUntil;

	private Transform _themeFollow;

	private float _nextVisualScan;

	private float _nextGourdCache;

	private float _nextConfigCheck;

	private DateTime _configStamp;

	private static string _appliedUpAxis;

	private static float _appliedSpin = float.NaN;

	private static float _appliedScale = float.NaN;

	private float _themeStopAt = -1f;

	private bool _themeFromRaise;

	private bool _localWasRaising;

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

	private static readonly HashSet<int> Applied = new HashSet<int>();

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

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

	private static readonly HashSet<int> ThemePlayed = new HashSet<int>();

	private void Start()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		if (!LoadVisualAssets())
		{
			Plugin.Log.LogError((object)"Maxwell mesh/texture failed to load. Expected assets/maxwell.obj and assets/dingus.jpg.");
		}
		else
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Asset statics ok: mesh=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)GourdAssets.Mesh != (Object)null);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" mat=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)GourdAssets.Material != (Object)null);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" tex=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)GourdAssets.Texture != (Object)null);
			}
			log.LogInfo(val);
		}
		if (!LoadAudioAsset())
		{
			Plugin.Log.LogError((object)"Maxwell theme failed to load. Expected assets/maxwell.wav.");
		}
		if (Plugin.PetHandAnimation.Value)
		{
			PetHandAnimator.Install();
		}
	}

	private void Update()
	{
		if (Plugin.Enabled.Value)
		{
			EnsureThemeSource();
			TickPurr();
			PollConfigFile();
			RefreshOrientationIfNeeded();
			RefreshGourdCacheIfNeeded();
			RememberHeldGourds();
			WatchGourdOpenings();
			WatchRaisedGourd();
			WatchPetting();
			UpdateThemePosition();
			StopThemeIfExpired();
			if (GourdAssets.VisualsReady && !(Time.unscaledTime < _nextVisualScan))
			{
				_nextVisualScan = Time.unscaledTime + Mathf.Min(Plugin.ScanInterval.Value, 0.5f);
				ApplyToAllGourds();
			}
		}
	}

	private void LateUpdate()
	{
		if (Plugin.Enabled.Value && GourdAssets.VisualsReady)
		{
			GourdVisual.MaintainAll(GourdAssets.Texture);
			GourdPet.Tick();
		}
	}

	private void WatchPetting()
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		if (!Plugin.PetEnabled.Value)
		{
			return;
		}
		try
		{
			PlayerCharacter val = FindLocalPlayer();
			if (!((Object)(object)val == (Object)null) && val.hands != null && val.hands.isHoldingSomething)
			{
				RewardGourd val2 = FindRewardGourd(val.hands.heldProp);
				if (!((Object)(object)val2 == (Object)null) && UsePressed(val) && !IsAimingAtSomething(val))
				{
					Pet(val2);
				}
			}
		}
		catch (Exception ex)
		{
			if (Plugin.LogVerbose.Value)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(18, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Pet watch failed: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val3);
			}
		}
	}

	private void Pet(RewardGourd gourd)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Expected O, but got Unknown
		Transform visual = GourdVisual.GetVisual(gourd);
		if ((Object)(object)visual == (Object)null)
		{
			return;
		}
		GourdPet.Pet(((Object)gourd).GetInstanceID(), visual, MeshOrientation.Up);
		if (Plugin.PetHandAnimation.Value)
		{
			PetHandAnimator.Begin(visual);
		}
		StartPurring(visual);
		if (Plugin.LogVerbose.Value)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Petted '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(SafeName(gourd));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
			}
			log.LogInfo(val);
		}
	}

	private static bool UsePressed(PlayerCharacter player)
	{
		try
		{
			Player inputPlayer = player.inputPlayer;
			if (inputPlayer != null)
			{
				return inputPlayer.GetButtonDown(Action.use);
			}
		}
		catch
		{
		}
		try
		{
			return Input.GetMouseButtonDown(0);
		}
		catch
		{
			return false;
		}
	}

	private static bool IsAimingAtSomething(PlayerCharacter player)
	{
		try
		{
			PlayerCaster caster = player.caster;
			if (caster == null)
			{
				return false;
			}
			if ((Object)(object)caster.castableTarget != (Object)null || (Object)(object)caster.castCharacter != (Object)null)
			{
				return true;
			}
			Prop castProp = caster.castProp;
			if ((Object)(object)castProp == (Object)null)
			{
				return false;
			}
			Prop val = ((player.hands != null) ? player.hands.heldProp : null);
			return (Object)(object)val == (Object)null || ((Object)castProp).GetInstanceID() != ((Object)val).GetInstanceID();
		}
		catch
		{
			return false;
		}
	}

	private void StartPurring(Transform visual)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		EnsurePurrSource();
		if ((Object)(object)_purrSource == (Object)null || (Object)(object)GourdAssets.PurrClip == (Object)null)
		{
			return;
		}
		try
		{
			_purrFollow = visual;
			_purrUntil = Time.unscaledTime + 0.9f;
			if (!_purrSource.isPlaying)
			{
				((Component)_purrSource).transform.position = visual.position;
				_purrSource.volume = 0f;
				_purrSource.time = Random.Range(0f, Mathf.Max(0f, GourdAssets.PurrClip.length - 1f));
				_purrSource.Play();
			}
		}
		catch
		{
		}
	}

	private void TickPurr()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_purrSource == (Object)null || !_purrSource.isPlaying)
		{
			return;
		}
		try
		{
			if ((Object)(object)_purrFollow != (Object)null)
			{
				((Component)_purrSource).transform.position = _purrFollow.position;
			}
			bool num = Time.unscaledTime < _purrUntil;
			float num2 = (num ? Mathf.Clamp01(Plugin.PetVolume.Value) : 0f);
			float num3 = (num ? 0.12f : 0.45f);
			_purrSource.volume = Mathf.MoveTowards(_purrSource.volume, num2, Time.unscaledDeltaTime / num3);
			if (!num && _purrSource.volume <= 0.001f)
			{
				_purrSource.Stop();
				_purrFollow = null;
			}
		}
		catch
		{
		}
	}

	private void EnsurePurrSource()
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Expected O, but got Unknown
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		if ((Object)(object)_purrSource != (Object)null)
		{
			return;
		}
		try
		{
			GameObject val = GameObject.Find("Gourdwell_PurrEmitter");
			if ((Object)(object)val == (Object)null)
			{
				val = new GameObject("Gourdwell_PurrEmitter");
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			_purrSource = val.GetComponent<AudioSource>();
			if ((Object)(object)_purrSource == (Object)null)
			{
				_purrSource = val.AddComponent<AudioSource>();
			}
			_purrSource.playOnAwake = false;
			_purrSource.loop = true;
			_purrSource.clip = GourdAssets.PurrClip;
			_purrSource.volume = 0f;
			_purrSource.spatialBlend = 1f;
			_purrSource.rolloffMode = (AudioRolloffMode)1;
			_purrSource.dopplerLevel = 0f;
			_purrSource.bypassReverbZones = true;
			_purrSource.minDistance = 1.5f;
			_purrSource.maxDistance = 12f;
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Purr source setup failed: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
			}
			log.LogWarning(val2);
		}
	}

	private void EnsureThemeSource()
	{
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Expected O, but got Unknown
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		if ((Object)(object)_themeSource != (Object)null || !GourdAssets.AudioReady)
		{
			return;
		}
		try
		{
			GameObject val = GameObject.Find("Gourdwell_ThemeEmitter");
			if ((Object)(object)val == (Object)null)
			{
				val = new GameObject("Gourdwell_ThemeEmitter");
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			_themeSource = val.GetComponent<AudioSource>();
			if ((Object)(object)_themeSource == (Object)null)
			{
				_themeSource = val.AddComponent<AudioSource>();
			}
			_themeSource.playOnAwake = false;
			_themeSource.loop = false;
			_themeSource.clip = GourdAssets.ThemeClip;
			ConfigureSpatialTheme(_themeSource);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Theme source rebind failed: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
			}
			log.LogWarning(val2);
		}
	}

	private void RefreshGourdCacheIfNeeded()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Expected O, but got Unknown
		if (Time.unscaledTime < _nextGourdCache)
		{
			return;
		}
		_nextGourdCache = Time.unscaledTime + Mathf.Min(Plugin.ScanInterval.Value, 0.5f);
		int count = KnownGourds.Count;
		bool flag = default(bool);
		try
		{
			Il2CppArrayBase<RewardGourd> val = Object.FindObjectsOfType<RewardGourd>(true);
			if (val != null)
			{
				for (int i = 0; i < val.Length; i++)
				{
					Remember(val[i]);
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("RewardGourd scan failed: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
			}
			log.LogWarning(val2);
		}
		try
		{
			Il2CppArrayBase<Prop> val3 = Object.FindObjectsOfType<Prop>(true);
			if (val3 != null)
			{
				for (int j = 0; j < val3.Length; j++)
				{
					Prop val4 = val3[j];
					if (!((Object)(object)val4 == (Object)null))
					{
						bool flag2 = false;
						try
						{
							flag2 = val4.MatchesGroup((PropGroup)19);
						}
						catch
						{
						}
						if (flag2)
						{
							Remember(FindRewardGourd(val4));
						}
					}
				}
			}
		}
		catch (Exception ex2)
		{
			ManualLogSource log2 = Plugin.Log;
			BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Prop/RewardGourd scan failed: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex2.Message);
			}
			log2.LogWarning(val2);
		}
		PruneKnownGourds();
		if (Plugin.LogVerbose.Value && (KnownGourds.Count != count || KnownGourds.Count == 0))
		{
			ManualLogSource log3 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Gourd cache: ");
				((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(KnownGourds.Count);
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" known. visualsReady=");
				((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(GourdAssets.VisualsReady);
			}
			log3.LogInfo(val5);
		}
	}

	private void RememberHeldGourds()
	{
		try
		{
			List<PlayerCharacter> allPlayerCharacters = PlayerCharacter.allPlayerCharacters;
			if (allPlayerCharacters == null)
			{
				return;
			}
			for (int i = 0; i < allPlayerCharacters.Count; i++)
			{
				PlayerCharacter val = allPlayerCharacters[i];
				if (!((Object)(object)val == (Object)null) && val.hands != null && val.hands.isHoldingSomething)
				{
					Remember(FindRewardGourd(val.hands.heldProp));
				}
			}
		}
		catch
		{
		}
	}

	private void Remember(RewardGourd gourd)
	{
		if ((Object)(object)gourd == (Object)null)
		{
			return;
		}
		try
		{
			int instanceID = ((Object)gourd).GetInstanceID();
			bool num = !KnownGourds.ContainsKey(instanceID);
			KnownGourds[instanceID] = gourd;
			if (num && GourdAssets.VisualsReady)
			{
				TryApplyOne(gourd, force: false);
			}
		}
		catch
		{
		}
	}

	private static void PruneKnownGourds()
	{
		List<int> list = null;
		foreach (KeyValuePair<int, RewardGourd> knownGourd in KnownGourds)
		{
			if ((Object)(object)knownGourd.Value == (Object)null)
			{
				if (list == null)
				{
					list = new List<int>();
				}
				list.Add(knownGourd.Key);
			}
		}
		if (list != null)
		{
			for (int i = 0; i < list.Count; i++)
			{
				KnownGourds.Remove(list[i]);
				Applied.Remove(list[i]);
			}
		}
	}

	private bool LoadVisualAssets()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Expected O, but got Unknown
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Expected O, but got Unknown
		if (GourdAssets.VisualsReady)
		{
			return true;
		}
		string path = Path.Combine(ObjLoader.PluginDir(), "assets");
		string text = Path.Combine(path, "maxwell.obj");
		string text2 = Path.Combine(path, "dingus.jpg");
		string text3 = Path.Combine(path, "dingus_whiskers.png");
		bool flag = default(bool);
		if (!ObjLoader.TryLoad(text, out var mesh, out var materialNames))
		{
			ManualLogSource log = Plugin.Log;
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(20, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not load OBJ: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
			}
			log.LogError(val);
			return false;
		}
		((Object)mesh).hideFlags = (HideFlags)61;
		GourdAssets.Mesh = mesh;
		CacheBaseGeometry(mesh);
		ApplyOrientation();
		if (!ObjLoader.TryLoadTexture(text2, out var tex))
		{
			ManualLogSource log2 = Plugin.Log;
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not load texture: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
			}
			log2.LogError(val);
			return false;
		}
		((Object)tex).hideFlags = (HideFlags)61;
		GourdAssets.Texture = tex;
		Material val2 = CreateMaterial(tex);
		if ((Object)(object)val2 == (Object)null)
		{
			return false;
		}
		((Object)val2).hideFlags = (HideFlags)61;
		GourdAssets.Material = val2;
		if (ObjLoader.TryLoadTexture(text3, out var tex2))
		{
			((Object)tex2).hideFlags = (HideFlags)61;
			GourdAssets.WhiskerTexture = tex2;
		}
		else
		{
			ManualLogSource log3 = Plugin.Log;
			BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(53, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("No whisker texture at ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text3);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("; whisker cards will be hidden.");
			}
			log3.LogWarning(val3);
		}
		Material val4 = CreateWhiskerMaterial(GourdAssets.WhiskerTexture);
		if ((Object)(object)val4 != (Object)null)
		{
			((Object)val4).hideFlags = (HideFlags)61;
			GourdAssets.WhiskerMaterial = val4;
		}
		GourdAssets.SubMeshMaterials = BuildSubMeshMaterials(materialNames, val2, val4);
		ManualLogSource log4 = Plugin.Log;
		BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(61, 4, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Maxwell visuals ready (verts=");
			((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(mesh.vertexCount);
			((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(", tris=");
			((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(((Il2CppArrayBase<int>)(object)mesh.triangles).Length / 3);
			((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(", ");
			((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("submeshes=");
			((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(mesh.subMeshCount);
			((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(", groups=[");
			((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(string.Join(", ", materialNames));
			((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("]).");
		}
		log4.LogInfo(val5);
		return true;
	}

	private static Material[] BuildSubMeshMaterials(string[] names, Material body, Material whiskers)
	{
		if (names == null || names.Length == 0)
		{
			return (Material[])(object)new Material[1] { body };
		}
		Material[] array = (Material[])(object)new Material[names.Length];
		for (int i = 0; i < names.Length; i++)
		{
			bool flag = names[i] != null && names[i].IndexOf("whisk", StringComparison.OrdinalIgnoreCase) >= 0;
			array[i] = ((flag && (Object)(object)whiskers != (Object)null) ? whiskers : body);
		}
		return array;
	}

	private static void CacheBaseGeometry(Mesh mesh)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		Il2CppStructArray<Vector3> vertices = mesh.vertices;
		Vector3[] array = (Vector3[])(object)new Vector3[((Il2CppArrayBase<Vector3>)(object)vertices).Length];
		for (int i = 0; i < ((Il2CppArrayBase<Vector3>)(object)vertices).Length; i++)
		{
			array[i] = ((Il2CppArrayBase<Vector3>)(object)vertices)[i];
		}
		GourdAssets.BaseVertices = array;
		Il2CppStructArray<Vector3> normals = mesh.normals;
		if (normals != null && ((Il2CppArrayBase<Vector3>)(object)normals).Length == ((Il2CppArrayBase<Vector3>)(object)vertices).Length)
		{
			Vector3[] array2 = (Vector3[])(object)new Vector3[((Il2CppArrayBase<Vector3>)(object)normals).Length];
			for (int j = 0; j < ((Il2CppArrayBase<Vector3>)(object)normals).Length; j++)
			{
				array2[j] = ((Il2CppArrayBase<Vector3>)(object)normals)[j];
			}
			GourdAssets.BaseNormals = array2;
		}
	}

	private static void ApplyOrientation()
	{
		//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)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_00ba: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Expected O, but got Unknown
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: 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_016d: Unknown result type (might be due to invalid IL or missing references)
		Mesh mesh = GourdAssets.Mesh;
		Vector3[] baseVertices = GourdAssets.BaseVertices;
		if ((Object)(object)mesh == (Object)null || baseVertices == null || baseVertices.Length == 0)
		{
			return;
		}
		Quaternion val = MeshOrientation.Rotation();
		Vector3[] array = (Vector3[])(object)new Vector3[baseVertices.Length];
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(float.MaxValue, float.MaxValue, float.MaxValue);
		Vector3 val3 = default(Vector3);
		((Vector3)(ref val3))..ctor(float.MinValue, float.MinValue, float.MinValue);
		for (int i = 0; i < baseVertices.Length; i++)
		{
			Vector3 val4 = (array[i] = val * baseVertices[i]);
			val2 = Vector3.Min(val2, val4);
			val3 = Vector3.Max(val3, val4);
		}
		Vector3 val5 = (val2 + val3) * 0.5f;
		Vector3 val6 = val3 - val2;
		float num = Mathf.Max(val6.x, Mathf.Max(val6.y, val6.z));
		if (num < 1E-05f)
		{
			num = 1f;
		}
		float num2 = Plugin.ScaleMultiplier.Value / num;
		for (int j = 0; j < array.Length; j++)
		{
			array[j] = (array[j] - val5) * num2;
		}
		mesh.SetVertices(Il2CppStructArray<Vector3>.op_Implicit(array));
		Vector3[] baseNormals = GourdAssets.BaseNormals;
		if (baseNormals != null && baseNormals.Length == baseVertices.Length)
		{
			Vector3[] array2 = (Vector3[])(object)new Vector3[baseNormals.Length];
			for (int k = 0; k < baseNormals.Length; k++)
			{
				array2[k] = val * baseNormals[k];
			}
			mesh.SetNormals(Il2CppStructArray<Vector3>.op_Implicit(array2));
		}
		mesh.RecalculateBounds();
		mesh.RecalculateTangents();
		BackProfile.Build(array, MeshOrientation.Forward, MeshOrientation.Up);
		_appliedUpAxis = Plugin.UpAxis.Value;
		_appliedSpin = Plugin.Spin.Value;
		_appliedScale = Plugin.ScaleMultiplier.Value;
		ManualLogSource log = Plugin.Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(39, 3, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("Maxwell orientation: up=");
			((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(_appliedUpAxis);
			((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" spin=");
			((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<float>(_appliedSpin, "0.#");
			((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("° scale=");
			((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<float>(_appliedScale, "0.##");
			((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(".");
		}
		log.LogInfo(val7);
	}

	private void RefreshOrientationIfNeeded()
	{
		if (!((Object)(object)GourdAssets.Mesh == (Object)null) && (!(_appliedUpAxis == Plugin.UpAxis.Value) || !Mathf.Approximately(_appliedSpin, Plugin.Spin.Value) || !Mathf.Approximately(_appliedScale, Plugin.ScaleMultiplier.Value)))
		{
			ApplyOrientation();
		}
	}

	private void PollConfigFile()
	{
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Expected O, but got Unknown
		if (Time.unscaledTime < _nextConfigCheck)
		{
			return;
		}
		_nextConfigCheck = Time.unscaledTime + 1f;
		try
		{
			string configFilePath = ((BasePlugin)Plugin.Instance).Config.ConfigFilePath;
			if (!File.Exists(configFilePath))
			{
				return;
			}
			DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(configFilePath);
			if (!(lastWriteTimeUtc == _configStamp))
			{
				bool num = _configStamp == default(DateTime);
				_configStamp = lastWriteTimeUtc;
				if (!num)
				{
					((BasePlugin)Plugin.Instance).Config.Reload();
				}
			}
		}
		catch (Exception ex)
		{
			if (Plugin.LogVerbose.Value)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Config reload check failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
	}

	private bool LoadAudioAsset()
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Expected O, but got Unknown
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Expected O, but got Unknown
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Expected O, but got Unknown
		bool flag = default(bool);
		if ((Object)(object)GourdAssets.PurrClip == (Object)null)
		{
			try
			{
				if (WavLoader.TryLoad(Path.Combine(ObjLoader.PluginDir(), "assets", "purr.wav"), out var clip))
				{
					((Object)clip).hideFlags = (HideFlags)61;
					GourdAssets.PurrClip = clip;
				}
				else
				{
					Plugin.Log.LogWarning((object)"assets/purr.wav missing; falling back to the synthesised purr.");
					AudioClip obj = PurrSynth.Create();
					((Object)obj).hideFlags = (HideFlags)61;
					GourdAssets.PurrClip = obj;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Purr load failed, petting will be silent: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
		if ((Object)(object)GourdAssets.ThemeClip == (Object)null)
		{
			string path = Path.Combine(ObjLoader.PluginDir(), "assets", "maxwell.wav");
			float value = Plugin.ThemeMaxSeconds.Value;
			if (!WavLoader.TryLoad(path, out var clip2, value))
			{
				return false;
			}
			((Object)clip2).hideFlags = (HideFlags)61;
			GourdAssets.ThemeClip = clip2;
		}
		GameObject val2 = new GameObject("Gourdwell_ThemeEmitter");
		Object.DontDestroyOnLoad((Object)val2);
		_themeSource = val2.AddComponent<AudioSource>();
		_themeSource.playOnAwake = false;
		_themeSource.loop = false;
		_themeSource.clip = GourdAssets.ThemeClip;
		ConfigureSpatialTheme(_themeSource);
		ManualLogSource log2 = Plugin.Log;
		BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Maxwell theme ready (");
			((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(GourdAssets.ThemeClip.length, "F1");
			((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("s, cap=");
			((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(Plugin.ThemeMaxSeconds.Value, "F1");
			((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("s, 3D local).");
		}
		log2.LogInfo(val3);
		return true;
	}

	private static void ConfigureSpatialTheme(AudioSource src)
	{
		src.spatialBlend = 1f;
		src.rolloffMode = (AudioRolloffMode)1;
		src.dopplerLevel = 0f;
		src.spread = 0f;
		src.bypassReverbZones = true;
		src.minDistance = Mathf.Max(0.5f, Plugin.ThemeMinDistance.Value);
		src.maxDistance = Mathf.Max(src.minDistance + 0.5f, Plugin.ThemeMaxDistance.Value);
	}

	private void WatchGourdOpenings()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected I4, but got Unknown
		if (!Plugin.PlayThemeOnOpen.Value || (Object)(object)_themeSource == (Object)null || !GourdAssets.AudioReady)
		{
			return;
		}
		float value = Plugin.MinLockedSeconds.Value;
		foreach (KeyValuePair<int, RewardGourd> knownGourd in KnownGourds)
		{
			RewardGourd value2 = knownGourd.Value;
			if ((Object)(object)value2 == (Object)null)
			{
				continue;
			}
			int num;
			try
			{
				num = (int)value2.gourdState;
			}
			catch
			{
				continue;
			}
			int key = knownGourd.Key;
			if (!LastState.TryGetValue(key, out var value3))
			{
				LastState[key] = num;
				if (num == 0)
				{
					LockedSince[key] = Time.unscaledTime;
				}
				continue;
			}
			if (num == 0 && !LockedSince.ContainsKey(key))
			{
				LockedSince[key] = Time.unscaledTime;
			}
			if (value3 == 0 && num == 1 && !ThemePlayed.Contains(key))
			{
				if (LockedSince.TryGetValue(key, out var value4) && Time.unscaledTime - value4 >= value)
				{
					PlayTheme(value2, "released from vice (Locked → Loose)", fromRaise: false);
					ThemePlayed.Add(key);
				}
				LockedSince.Remove(key);
			}
			if (num != 0)
			{
				LockedSince.Remove(key);
			}
			LastState[key] = num;
		}
	}

	private void WatchRaisedGourd()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		bool flag = false;
		RewardGourd val = null;
		try
		{
			PlayerCharacter val2 = FindLocalPlayer();
			if ((Object)(object)val2 != (Object)null && val2.gestures != null && val2.gestures.isHoldingRaised && val2.hands != null && val2.hands.isHoldingSomething)
			{
				val = FindRewardGourd(val2.hands.heldProp);
				flag = (Object)(object)val != (Object)null;
				if (flag)
				{
					Remember(val);
				}
			}
		}
		catch (Exception ex)
		{
			if (Plugin.LogVerbose.Value)
			{
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Raise watch failed: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val3);
			}
		}
		if (flag && !_localWasRaising)
		{
			if (Plugin.PlayThemeOnRaise.Value && (Object)(object)_themeSource != (Object)null && GourdAssets.AudioReady)
			{
				PlayTheme(val, "held over head", fromRaise: true);
			}
			TryApplyOne(val, force: false);
		}
		else if (!flag && _localWasRaising && _themeFromRaise)
		{
			StopTheme("lowered gourd");
		}
		_localWasRaising = flag;
	}

	private void UpdateThemePosition()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_themeSource == (Object)null) && _themeSource.isPlaying && !((Object)(object)_themeFollow == (Object)null))
		{
			((Component)_themeSource).transform.position = _themeFollow.position;
		}
	}

	private void StopThemeIfExpired()
	{
		if (!(_themeStopAt < 0f) && !((Object)(object)_themeSource == (Object)null) && !(Time.unscaledTime < _themeStopAt))
		{
			StopTheme("max duration");
		}
	}

	private void StopTheme(string reason)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		_themeStopAt = -1f;
		_themeFollow = null;
		_themeFromRaise = false;
		if (!((Object)(object)_themeSource != (Object)null) || !_themeSource.isPlaying)
		{
			return;
		}
		_themeSource.Stop();
		if (Plugin.LogVerbose.Value)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Stopped Maxwell theme (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(reason);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
			}
			log.LogInfo(val);
		}
	}

	private void PlayTheme(RewardGourd gourd, string reason, bool fromRaise)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: 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_0109: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		if ((Object)(object)gourd == (Object)null || (Object)(object)_themeSource == (Object)null)
		{
			return;
		}
		ConfigureSpatialTheme(_themeSource);
		Vector3 position = ((Component)gourd).transform.position;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val;
		if (!IsLocalListenerInRange(position))
		{
			if (Plugin.LogVerbose.Value)
			{
				ManualLogSource log = Plugin.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Skip theme for '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(SafeName(gourd));
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' — outside local hearing range.");
				}
				log.LogInfo(val);
			}
			return;
		}
		_themeFollow = ((Component)gourd).transform;
		_themeFromRaise = fromRaise;
		((Component)_themeSource).transform.position = position;
		_themeSource.volume = Mathf.Clamp01(Plugin.ThemeVolume.Value);
		if (_themeSource.isPlaying)
		{
			_themeSource.Stop();
		}
		_themeSource.Play();
		_themeStopAt = Time.unscaledTime + Mathf.Max(0.1f, Plugin.ThemeMaxSeconds.Value);
		ManualLogSource log2 = Plugin.Log;
		val = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Playing Maxwell theme (local 3D) — '");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(SafeName(gourd));
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(reason);
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
		}
		log2.LogInfo(val);
	}

	private static bool IsLocalListenerInRange(Vector3 origin)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Max(1f, Plugin.ThemeMaxDistance.Value);
		Vector3? localListenerPosition = GetLocalListenerPosition();
		if (!localListenerPosition.HasValue)
		{
			return true;
		}
		Vector3 val = localListenerPosition.Value - origin;
		return ((Vector3)(ref val)).sqrMagnitude <= num * num;
	}

	private static Vector3? GetLocalListenerPosition()
	{
		//IL_0015: 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)
		try
		{
			PlayerCharacter val = FindLocalPlayer();
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).transform.position;
			}
		}
		catch
		{
		}
		try
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				return ((Component)main).transform.position;
			}
		}
		catch
		{
		}
		return null;
	}

	private static PlayerCharacter FindLocalPlayer()
	{
		try
		{
			List<PlayerCharacter> allPlayerCharacters = PlayerCharacter.allPlayerCharacters;
			if (allPlayerCharacters == null)
			{
				return null;
			}
			for (int i = 0; i < allPlayerCharacters.Count; i++)
			{
				PlayerCharacter val = allPlayerCharacters[i];
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer)
				{
					return val;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static RewardGourd FindRewardGourd(Prop prop)
	{
		if ((Object)(object)prop == (Object)null)
		{
			return null;
		}
		try
		{
			RewardGourd component = ((Component)prop).GetComponent<RewardGourd>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			RewardGourd componentInParent = ((Component)prop).GetComponentInParent<RewardGourd>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			return ((Component)prop).GetComponentInChildren<RewardGourd>(true);
		}
		catch
		{
			return null;
		}
	}

	private static Material CreateMaterial(Texture2D tex)
	{
		//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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_00b8: Expected O, but got Unknown
		string[] array = new string[3] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Unlit" };
		Shader val = null;
		string text = null;
		for (int i = 0; i < array.Length; i++)
		{
			val = Shader.Find(array[i]);
			if ((Object)(object)val != (Object)null)
			{
				text = array[i];
				break;
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogError((object)"No usable shader found for Gourdwell material.");
			return null;
		}
		Material val2 = new Material(val)
		{
			name = "Gourdwell_Mat"
		};
		GourdVisual.ApplyTexture(val2, tex);
		ManualLogSource log = Plugin.Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Gourdwell material shader='");
			((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
			((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'.");
		}
		log.LogInfo(val3);
		return val2;
	}

	private static Material CreateWhiskerMaterial(Texture2D tex)
	{
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Expected O, but got Unknown
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Expected O, but got Unknown
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		string[] array = new string[3] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Unlit" };
		Shader val = null;
		for (int i = 0; i < array.Length; i++)
		{
			val = Shader.Find(array[i]);
			if ((Object)(object)val != (Object)null)
			{
				break;
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogWarning((object)"No shader available for whisker material.");
			return null;
		}
		if ((Object)(object)tex == (Object)null)
		{
			tex = new Texture2D(1, 1, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			tex.SetPixel(0, 0, new Color(1f, 1f, 1f, 0f));
			tex.Apply(false, false);
		}
		Material val2 = new Material(val)
		{
			name = "Gourdwell_Whiskers"
		};
		val2.mainTexture = (Texture)(object)tex;
		try
		{
			if (val2.HasProperty("_BaseMap"))
			{
				val2.SetTexture("_BaseMap", (Texture)(object)tex);
			}
			if (val2.HasProperty("_MainTex"))
			{
				val2.SetTexture("_MainTex", (Texture)(object)tex);
			}
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", Color.white);
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", Color.white);
			}
			if (val2.HasProperty("_Surface"))
			{
				val2.SetFloat("_Surface", 1f);
			}
			if (val2.HasProperty("_Blend"))
			{
				val2.SetFloat("_Blend", 0f);
			}
			if (val2.HasProperty("_AlphaClip"))
			{
				val2.SetFloat("_AlphaClip", 0f);
			}
			if (val2.HasProperty("_ZWrite"))
			{
				val2.SetFloat("_ZWrite", 0f);
			}
			if (val2.HasProperty("_Cull"))
			{
				val2.SetFloat("_Cull", 0f);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0f);
			}
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", 0f);
			}
			if (val2.HasProperty("_SrcBlend"))
			{
				val2.SetFloat("_SrcBlend", 5f);
			}
			if (val2.HasProperty("_DstBlend"))
			{
				val2.SetFloat("_DstBlend", 10f);
			}
			val2.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val2.DisableKeyword("_ALPHATEST_ON");
			val2.SetOverrideTag("RenderType", "Transparent");
			val2.renderQueue = 3000;
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Whisker material setup partially failed: ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
			}
			log.LogWarning(val3);
		}
		return val2;
	}

	private void ApplyToAllGourds()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		if (KnownGourds.Count == 0)
		{
			if (Plugin.LogVerbose.Value)
			{
				Plugin.Log.LogInfo((object)"Apply scan: no RewardGourd instances known yet.");
			}
			return;
		}
		if (Plugin.LogVerbose.Value)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Apply scan: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(KnownGourds.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" gourds, applied=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Applied.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
		}
		foreach (KeyValuePair<int, RewardGourd> knownGourd in KnownGourds)
		{
			TryApplyOne(knownGourd.Value, force: false);
		}
	}

	private void TryApplyOne(RewardGourd gourd, bool force)
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Expected O, but got Unknown
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Expected O, but got Unknown
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Expected O, but got Unknown
		if ((Object)(object)gourd == (Object)null)
		{
			return;
		}
		bool flag = default(bool);
		if (!GourdAssets.VisualsReady)
		{
			ManualLogSource log = Plugin.Log;
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(45, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TryApplyOne: assets not ready mesh=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)GourdAssets.Mesh != (Object)null);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" mat=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)GourdAssets.Material != (Object)null);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" tex=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)GourdAssets.Texture != (Object)null);
			}
			log.LogWarning(val);
			return;
		}
		int instanceID;
		try
		{
			instanceID = ((Object)gourd).GetInstanceID();
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = Plugin.Log;
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TryApplyOne: GetInstanceID failed: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
			}
			log2.LogWarning(val);
			return;
		}
		if (!force && Applied.Contains(instanceID))
		{
			return;
		}
		try
		{
			if (GourdVisual.SwapInPlace(gourd, GourdAssets.Mesh, GourdAssets.Material, GourdAssets.Texture, GourdAssets.WhiskerMaterial, out var detail) > 0)
			{
				Applied.Add(instanceID);
				ManualLogSource log3 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(33, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Applied Gourdwell visual to '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(SafeName(gourd));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(detail);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
				}
				log3.LogInfo(val2);
			}
			else
			{
				ManualLogSource log4 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Gourdwell: swap found nothing on '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(SafeName(gourd));
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(detail);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
				}
				log4.LogWarning(val);
			}
		}
		catch (Exception ex2)
		{
			ManualLogSource log5 = Plugin.Log;
			BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TryApplyOne threw on '");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(SafeName(gourd));
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex2);
			}
			log5.LogError(val3);
		}
	}

	private static string SafeName(RewardGourd gourd)
	{
		try
		{
			return ((Object)(object)gourd != (Object)null) ? ((Object)gourd).name : "(null)";
		}
		catch
		{
			return "(gourd)";
		}
	}
}
internal static class MeshOrientation
{
	private static readonly Vector3 ModelForward = new Vector3(-1f, 0f, 0f);

	public static Vector3 Up => ParseAxis(Plugin.UpAxis.Value);

	public static Vector3 Forward => Rotation() * ModelForward;

	public static Vector3 ParseAxis(string value)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		return (Vector3)((value ?? "+Y").Trim().ToUpperInvariant() switch
		{
			"+X" => Vector3.right, 
			"-X" => Vector3.left, 
			"-Y" => Vector3.down, 
			"+Z" => Vector3.forward, 
			"-Z" => Vector3.back, 
			_ => Vector3.up, 
		});
	}

	public static Quaternion Rotation()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: 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_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_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		Vector3 up = Up;
		return Quaternion.AngleAxis(Plugin.Spin.Value, up) * Quaternion.FromToRotation(Vector3.up, up);
	}
}
internal static class ObjLoader
{
	public static bool TryLoad(string objPath, out Mesh mesh, out string[] materialNames)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Expected O, but got Unknown
		//IL_017e: 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)
		mesh = null;
		materialNames = new string[0];
		if (!File.Exists(objPath))
		{
			return false;
		}
		List<Vector3> positions = new List<Vector3>();
		List<Vector2> uvs = new List<Vector2>();
		List<Vector3> normals = new List<Vector3>();
		List<Vector3> outPos = new List<Vector3>();
		List<Vector2> outUv = new List<Vector2>();
		List<Vector3> outNorm = new List<Vector3>();
		Dictionary<string, int> map = new Dictionary<string, int>();
		List<string> groupNames = new List<string>();
		List<List<int>> groupIndices = new List<List<int>>();
		List<int> indices = null;
		foreach (string item4 in File.ReadLines(objPath))
		{
			string text = item4.Trim();
			if (text.Length == 0 || text[0] == '#')
			{
				continue;
			}
			string[] array = text.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0)
			{
				continue;
			}
			switch (array[0])
			{
			case "v":
				if (array.Length >= 4)
				{
					positions.Add(new Vector3(0f - F(array[1]), F(array[2]), F(array[3])));
				}
				break;
			case "vt":
				if (array.Length >= 3)
				{
					uvs.Add(new Vector2(F(array[1]), F(array[2])));
				}
				break;
			case "vn":
				if (array.Length >= 4)
				{
					normals.Add(new Vector3(0f - F(array[1]), F(array[2]), F(array[3])));
				}
				break;
			case "usemtl":
				if (array.Length >= 2)
				{
					StartGroup(array[1]);
				}
				break;
			case "f":
				if (array.Length >= 4)
				{
					if (indices == null)
					{
						StartGroup("default");
					}
					for (int i = 1; i + 2 < array.Length; i++)
					{
						AddVert(array[1]);
						AddVert(array[i + 2]);
						AddVert(array[i + 1]);
					}
				}
				break;
			}
		}
		for (int num = groupIndices.Count - 1; num >= 0; num--)
		{
			if (groupIndices[num].Count == 0)
			{
				groupIndices.RemoveAt(num);
				groupNames.RemoveAt(num);
			}
		}
		if (outPos.Count == 0 || groupIndices.Count == 0)
		{
			return false;
		}
		mesh = new Mesh
		{
			name = Path.GetFileNameWithoutExtension(objPath)
		};
		mesh.SetVertices(Il2CppStructArray<Vector3>.op_Implicit(outPos.ToArray()));
		if (outUv.Count == outPos.Count)
		{
			mesh.SetUVs(0, Il2CppStructArray<Vector2>.op_Implicit(outUv.ToArray()));
		}
		if (outNorm.Count == outPos.Count)
		{
			mesh.SetNormals(Il2CppStructArray<Vector3>.op_Implicit(outNorm.ToArray()));
		}
		mesh.subMeshCount = groupIndices.Count;
		for (int j = 0; j < groupIndices.Count; j++)
		{
			mesh.SetTriangles(Il2CppStructArray<int>.op_Implicit(groupIndices[j].ToArray()), j);
		}
		if (outNorm.Count != outPos.Count)
		{
			mesh.RecalculateNormals();
		}
		mesh.RecalculateBounds();
		materialNames = groupNames.ToArray();
		return true;
		void AddVert(string token)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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)
			if (!map.TryGetValue(token, out var value))
			{
				string[] array2 = token.Split('/');
				int num2 = int.Parse(array2[0], CultureInfo.InvariantCulture);
				if (num2 < 0)
				{
					num2 = positions.Count + num2 + 1;
				}
				Vector3 item = positions[num2 - 1];
				Vector2 item2 = Vector2.zero;
				if (array2.Length > 1 && array2[1].Length > 0)
				{
					int num3 = int.Parse(array2[1], CultureInfo.InvariantCulture);
					if (num3 < 0)
					{
						num3 = uvs.Count + num3 + 1;
					}
					if (num3 > 0 && num3 <= uvs.Count)
					{
						item2 = uvs[num3 - 1];
					}
				}
				Vector3 item3 = Vector3.up;
				if (array2.Length > 2 && array2[2].Length > 0)
				{
					int num4 = int.Parse(array2[2], CultureInfo.InvariantCulture);
					if (num4 < 0)
					{
						num4 = normals.Count + num4 + 1;
					}
					if (num4 > 0 && num4 <= normals.Count)
					{
						item3 = normals[num4 - 1];
					}
				}
				value = outPos.Count;
				outPos.Add(item);
				outUv.Add(item2);
				outNorm.Add(item3);
				map[token] = value;
			}
			indices.Add(value);
		}
		void StartGroup(string name)
		{
			int num2 = groupNames.IndexOf(name);
			if (num2 >= 0)
			{
				indices = groupIndices[num2];
			}
			else
			{
				indices = new List<int>();
				groupNames.Add(name);
				groupIndices.Add(indices);
			}
		}
	}

	public static bool TryLoadTexture(string path, out Texture2D tex)
	{
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Expected O, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Expected O, but got Unknown
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		tex = null;
		if (!File.Exists(path))
		{
			return false;
		}
		bool flag = default(bool);
		try
		{
			ImageResult val = ImageResult.FromMemory(File.ReadAllBytes(path), (ColorComponents)4);
			if (val == null || val.Data == null || val.Width <= 0 || val.Height <= 0)
			{
				return false;
			}
			int width = val.Width;
			int height = val.Height;
			byte[] data = val.Data;
			byte[] array = new byte[width * height * 4];
			for (int i = 0; i < height; i++)
			{
				int srcOffset = i * width * 4;
				int dstOffset = (height - 1 - i) * width * 4;
				Buffer.BlockCopy(data, srcOffset, array, dstOffset, width * 4);
			}
			tex = new Texture2D(width, height, (TextureFormat)4, false);
			tex.LoadRawTextureData(Il2CppStructArray<byte>.op_Implicit(array));
			tex.Apply(false, false);
			((Object)tex).name = Path.GetFileNameWithoutExtension(path);
			((Texture)tex).wrapMode = (TextureWrapMode)0;
			((Texture)tex).filterMode = (FilterMode)1;
			((Texture)tex).anisoLevel = 4;
			ManualLogSource log = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(18, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Loaded texture ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)tex).name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(width);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("x");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(height);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
			}
			log.LogInfo(val2);
			return true;
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = Plugin.Log;
			BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(24, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Texture load failed (");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(path);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("): ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
			}
			log2.LogError(val3);
			if ((Object)(object)tex != (Object)null)
			{
				Object.Destroy((Object)(object)tex);
				tex = null;
			}
			return false;
		}
	}

	public static string PluginDir()
	{
		return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
	}

	private static float F(string s)
	{
		return float.Parse(s, CultureInfo.InvariantCulture);
	}
}
internal static class PetHandAnimator
{
	private static bool _patched;

	private static bool _active;

	private static float _startedAt;

	private static Transform _visual;

	private static Vector3 _localUp;

	private static Vector3 _localForward;

	private const float Clearance = 0.05f;

	public static void Install()
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if (_patched)
		{
			return;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(PlayerArms), "LateUpdate", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Plugin.Log.LogWarning((object)"PlayerArms.LateUpdate not found; pet hand animation disabled.");
				return;
			}
			HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(PetHandAnimator), "AfterArmsLateUpdate", (Type[])null, (Type[])null));
			new Harmony("BigWalk.Gourdwell").Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_patched = true;
			Plugin.Log.LogInfo((object)"Pet hand animation hooked into PlayerArms.LateUpdate.");
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(67, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not hook PlayerArms.LateUpdate; pet hand animation disabled: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
			}
			log.LogWarning(val2);
		}
	}

	public static void Begin(Transform visual)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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)
		if (_patched && !((Object)(object)visual == (Object)null) && BackProfile.Ready)
		{
			_visual = visual;
			_localUp = MeshOrientation.Up;
			_localForward = MeshOrientation.Forward;
			_startedAt = Time.unscaledTime;
			_active = true;
		}
	}

	private static void AfterArmsLateUpdate(PlayerArms __instance)
	{
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Expected O, but got Unknown
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: 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_00a5: 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)
		if (!_active)
		{
			return;
		}
		try
		{
			if (__instance == null || (Object)(object)_visual == (Object)null)
			{
				_active = false;
				return;
			}
			PlayerCharacter playerCharacter = __instance.playerCharacter;
			if ((Object)(object)playerCharacter == (Object)null || !((NetworkBehaviour)playerCharacter).isLocalPlayer)
			{
				return;
			}
			float num = (Time.unscaledTime - _startedAt) / 0.5f;
			if (num >= 1f)
			{
				_active = false;
				return;
			}
			float blend = Mathf.Sin((float)Math.PI * Mathf.Clamp01(num));
			Vector3 target = StrokePoint(num);
			if (!string.Equals(Plugin.PetHand.Value, "Left", StringComparison.OrdinalIgnoreCase))
			{
				Move(__instance.localRightHand, __instance.localRightArmSpline, target, blend);
				Move(__instance.rightHand, __instance.rightArmLimbSpline, target, blend);
			}
			else
			{
				Move(__instance.localLeftHand, __instance.localLeftArmSpline, target, blend);
				Move(__instance.leftHand, __instance.leftArmLimbSpline, target, blend);
			}
		}
		catch (Exception ex)
		{
			_active = false;
			if (Plugin.LogVerbose.Value)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Pet hand animation stopped: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
	}

	private static void Move(Transform hand, LimbSpline spline, Vector3 target, float blend)
	{
		//IL_000c: 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_0013: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)hand == (Object)null))
		{
			hand.position = Vector3.Lerp(hand.position, target, blend);
			if ((Object)(object)spline != (Object)null)
			{
				spline.Refresh();
			}
		}
	}

	private static Vector3 StrokePoint(float progress)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Lerp(BackProfile.Max * 0.75f, BackProfile.Min * 0.85f, progress);
		Vector3 val = _localForward * num + _localUp * (BackProfile.HeightAt(num) + 0.05f);
		return _visual.TransformPoint(val);
	}
}
[BepInPlugin("BigWalk.Gourdwell", "Gourdwell", "1.0.16")]
[BepInProcess("Big Walk.exe")]
public class Plugin : BasePlugin
{
	internal static Plugin Instance;

	internal static ManualLogSource Log;

	public static ConfigEntry<bool> Enabled;

	public static ConfigEntry<float> ScaleMultiplier;

	public static ConfigEntry<float> ScanInterval;

	public static ConfigEntry<string> UpAxis;

	public static ConfigEntry<float> Spin;

	public static ConfigEntry<bool> PetEnabled;

	public static ConfigEntry<float> PetVolume;

	public static ConfigEntry<bool> PetHandAnimation;

	public static ConfigEntry<string> PetHand;

	public static ConfigEntry<bool> PlayThemeOnOpen;

	public static ConfigEntry<bool> PlayThemeOnRaise;

	public static ConfigEntry<float> ThemeVolume;

	public static ConfigEntry<float> ThemeMaxSeconds;

	public static ConfigEntry<float> ThemeMinDistance;

	public static ConfigEntry<float> ThemeMaxDistance;

	public static ConfigEntry<float> MinLockedSeconds;

	public static ConfigEntry<bool> LogVerbose;

	public override void Load()
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Expected O, but got Unknown
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Expected O, but got Unknown
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Expected O, but got Unknown
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Expected O, but got Unknown
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Expected O, but got Unknown
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Expected O, but got Unknown
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Expected O, but got Unknown
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Expected O, but got Unknown
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Expected O, but got Unknown
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Expected O, but got Unknown
		Instance = this;
		Log = ((BasePlugin)this).Log;
		Enabled = ((BasePlugin)this).Config.Bind<bool>("Gourdwell", "Enabled", true, "Replace Reward Gourd visuals with Maxwell the cat.");
		ScaleMultiplier = ((BasePlugin)this).Config.Bind<float>("Gourdwell", "ScaleMultiplier", 1.15f, new ConfigDescription("Size relative to the original gourd bounds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>()));
		ScanInterval = ((BasePlugin)this).Config.Bind<float>("Gourdwell", "ScanInterval", 0.5f, new ConfigDescription("How often to look for new gourds (seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>()));
		UpAxis = ((BasePlugin)this).Config.Bind<string>("Orientation", "UpAxis", "+Z", new ConfigDescription("Which axis of the gourd prop points up in the world. Change this until Maxwell stands upright; if he is upside down, use the opposite sign.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[6] { "+X", "-X", "+Y", "-Y", "+Z", "-Z" }), Array.Empty<object>()));
		Spin = ((BasePlugin)this).Config.Bind<float>("Orientation", "Spin", -180f, new ConfigDescription("Degrees to turn Maxwell around UpAxis. Once he is upright, adjust this (try steps of 90) until he faces whoever is holding the gourd.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
		PetEnabled = ((BasePlugin)this).Config.Bind<bool>("Petting", "PetEnabled", true, "Left-click while holding Maxwell (and not aiming at anything interactable) to pet him.");
		PetVolume = ((BasePlugin)this).Config.Bind<float>("Petting", "PetVolume", 0.7f, new ConfigDescription("Purr volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		PetHandAnimation = ((BasePlugin)this).Config.Bind<bool>("Petting", "PetHandAnimation", true, "Stroke your hand along Maxwell's back when petting. Turn off if it fights the arm animation.");
		PetHand = ((BasePlugin)this).Config.Bind<string>("Petting", "PetHand", "Right", new ConfigDescription("Which hand does the petting.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Left", "Right" }), Array.Empty<object>()));
		PlayThemeOnOpen = ((BasePlugin)this).Config.Bind<bool>("Audio", "PlayThemeOnOpen", true, "Play the Maxwell theme when a gourd is released from a vice (Locked → Loose).");
		PlayThemeOnRaise = ((BasePlugin)this).Config.Bind<bool>("Audio", "PlayThemeOnRaise", true, "Play the Maxwell theme when the local player holds a Reward Gourd over their head.");
		ThemeVolume = ((BasePlugin)this).Config.Bind<float>("Audio", "ThemeVolume", 0.68f, new ConfigDescription("Theme volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		ThemeMaxSeconds = ((BasePlugin)this).Config.Bind<float>("Audio", "ThemeMaxSeconds", 10f, new ConfigDescription("How long the theme plays before stopping.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>()));
		ThemeMinDistance = ((BasePlugin)this).Config.Bind<float>("Audio", "ThemeMinDistance", 3f, new ConfigDescription("Full-volume radius for the theme (3D / local only — not lobby-wide).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>()));
		ThemeMaxDistance = ((BasePlugin)this).Config.Bind<float>("Audio", "ThemeMaxDistance", 18f, new ConfigDescription("Theme is silent beyond this distance from the gourd. Other clients only hear it if they are nearby.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 80f), Array.Empty<object>()));
		MinLockedSeconds = ((BasePlugin)this).Config.Bind<float>("Audio", "MinLockedSeconds", 1.5f, new ConfigDescription("Gourd must stay Locked at least this long before a Loose transition plays the theme. Prevents playing for gourds already on the ground at load.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
		LogVerbose = ((BasePlugin)this).Config.Bind<bool>("Gourdwell", "LogVerbose", false, "Extra logging.");
		((BasePlugin)this).AddComponent<GourdwellController>();
		ManualLogSource log = Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Gourdwell");
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.16");
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded — Reward Gourds become Maxwell.");
		}
		log.LogInfo(val);
	}
}
internal static class PurrSynth
{
	private const int SampleRate = 44100;

	private const float Seconds = 0.9f;

	private const float Fundamental = 27f;

	public static AudioClip Create()
	{
		int num = 39690;
		float[] array = new float[num];
		uint num2 = 2463534242u;
		float num3 = 0f;
		for (int i = 0; i < num; i++)
		{
			float num4 = (float)i / 44100f;
			float num5 = num4 * 27f;
			float num6 = Mathf.Exp((0f - (num5 - Mathf.Floor(num5))) * 7f) - 0.14f;
			num2 ^= num2 << 13;
			num2 ^= num2 >> 17;
			num2 ^= num2 << 5;
			float num7 = (float)(int)(num2 & 0xFFFFFF) / (26353588f / (float)Math.PI) - 1f;
			num3 += (num7 - num3) * 0.06f;
			float num8 = Mathf.Sin((float)Math.PI * Mathf.Clamp01(num4 / 0.9f));
			array[i] = (num6 * 0.75f + num3 * num6 * 0.9f) * num8 * 0.5f;
		}
		AudioClip obj = AudioClip.Create("Gourdwell_Purr", num, 1, 44100, false);
		obj.SetData(Il2CppStructArray<float>.op_Implicit(array), 0);
		return obj;
	}
}
internal static class WavLoader
{
	public static bool TryLoad(string path, out AudioClip clip, float maxSeconds = 0f)
	{
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Expected O, but got Unknown
		clip = null;
		if (!File.Exists(path))
		{
			return false;
		}
		byte[] array = File.ReadAllBytes(path);
		if (array.Length < 44)
		{
			return false;
		}
		if (array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70)
		{
			return false;
		}
		if (array[8] != 87 || array[9] != 65 || array[10] != 86 || array[11] != 69)
		{
			return false;
		}
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		int num4 = -1;
		int num5 = 0;
		int num6 = 12;
		bool flag = default(bool);
		while (num6 + 8 <= array.Length)
		{
			string text = Encoding.ASCII.GetString(array, num6, 4);
			int num7 = BitConverter.ToInt32(array, num6 + 4);
			int num8 = num6 + 8;
			if (text == "fmt ")
			{
				short num9 = BitConverter.ToInt16(array, num8);
				num = BitConverter.ToInt16(array, num8 + 2);
				num2 = BitConverter.ToInt32(array, num8 + 4);
				num3 = BitConverter.ToInt16(array, num8 + 14);
				if (num9 != 1 || num3 != 16)
				{
					ManualLogSource log = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(44, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("WAV must be PCM 16-bit (got format=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<short>(num9);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", bits=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num3);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
					}
					log.LogError(val);
					return false;
				}
			}
			else if (text == "data")
			{
				num4 = num8;
				num5 = num7;
				break;
			}
			num6 = num8 + num7 + (num7 & 1);
		}
		if (num4 < 0 || num <= 0 || num2 <= 0)
		{
			return false;
		}
		int num10 = num5 / (num3 / 8);
		int num11 = num10 / num;
		if (maxSeconds > 0f)
		{
			int num12 = Mathf.Max(1, Mathf.FloorToInt((float)num2 * maxSeconds));
			if (num11 > num12)
			{
				num11 = num12;
				num10 = num11 * num;
			}
		}
		float[] array2 = new float[num10];
		for (int i = 0; i < num10; i++)
		{
			int num13 = num4 + i * 2;
			if (num13 + 1 >= array.Length)
			{
				break;
			}
			short num14 = (short)(array[num13] | (array[num13 + 1] << 8));
			array2[i] = (float)num14 / 32768f;
		}
		clip = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num11, num, num2, false);
		clip.SetData(Il2CppStructArray<float>.op_Implicit(array2), 0);
		return true;
	}
}
public static class MyPluginInfo
{
	public const string PLUGIN_GUID = "BigWalk.Gourdwell";

	public const string PLUGIN_NAME = "Gourdwell";

	public const string PLUGIN_VERSION = "1.0.16";
}

BepInEx/plugins/BigWalk.Gourdwell/StbImageSharp.dll

Decompiled 14 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using Hebron.Runtime;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyCompany("StbImageSharpTeam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("C# port of the stb_image.h")]
[assembly: AssemblyFileVersion("2.27.13.0")]
[assembly: AssemblyInformationalVersion("2.27.13")]
[assembly: AssemblyProduct("StbImageSharp")]
[assembly: AssemblyTitle("StbImageSharp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.27.13.0")]
[module: UnverifiableCode]
namespace Hebron.Runtime
{
	internal static class CRuntime
	{
		private static readonly string numbers = "0123456789";

		public unsafe static void* malloc(ulong size)
		{
			return malloc((long)size);
		}

		public unsafe static void* malloc(long size)
		{
			IntPtr intPtr = Marshal.AllocHGlobal((int)size);
			MemoryStats.Allocated();
			return intPtr.ToPointer();
		}

		public unsafe static void free(void* a)
		{
			if (a != null)
			{
				Marshal.FreeHGlobal(new IntPtr(a));
				MemoryStats.Freed();
			}
		}

		public unsafe static void memcpy(void* a, void* b, long size)
		{
			byte* ptr = (byte*)a;
			byte* ptr2 = (byte*)b;
			for (long num = 0L; num < size; num++)
			{
				*(ptr++) = *(ptr2++);
			}
		}

		public unsafe static void memcpy(void* a, void* b, ulong size)
		{
			memcpy(a, b, (long)size);
		}

		public unsafe static void memmove(void* a, void* b, long size)
		{
			void* ptr = null;
			try
			{
				ptr = malloc(size);
				memcpy(ptr, b, size);
				memcpy(a, ptr, size);
			}
			finally
			{
				if (ptr != null)
				{
					free(ptr);
				}
			}
		}

		public unsafe static void memmove(void* a, void* b, ulong size)
		{
			memmove(a, b, (long)size);
		}

		public unsafe static int memcmp(void* a, void* b, long size)
		{
			int num = 0;
			byte* ptr = (byte*)a;
			byte* ptr2 = (byte*)b;
			for (long num2 = 0L; num2 < size; num2++)
			{
				if (*ptr != *ptr2)
				{
					num++;
				}
				ptr++;
				ptr2++;
			}
			return num;
		}

		public unsafe static int memcmp(void* a, void* b, ulong size)
		{
			return memcmp(a, b, (long)size);
		}

		public unsafe static int memcmp(byte* a, byte[] b, ulong size)
		{
			fixed (byte* ptr = b)
			{
				void* b2 = ptr;
				return memcmp(a, b2, (long)size);
			}
		}

		public unsafe static void memset(void* ptr, int value, long size)
		{
			byte* ptr2 = (byte*)ptr;
			byte b = (byte)value;
			for (long num = 0L; num < size; num++)
			{
				*(ptr2++) = b;
			}
		}

		public unsafe static void memset(void* ptr, int value, ulong size)
		{
			memset(ptr, value, (long)size);
		}

		public static uint _lrotl(uint x, int y)
		{
			return (x << y) | (x >> 32 - y);
		}

		public unsafe static void* realloc(void* a, long newSize)
		{
			if (a == null)
			{
				return malloc(newSize);
			}
			return Marshal.ReAllocHGlobal(new IntPtr(a), new IntPtr(newSize)).ToPointer();
		}

		public unsafe static void* realloc(void* a, ulong newSize)
		{
			return realloc(a, (long)newSize);
		}

		public static int abs(int v)
		{
			return Math.Abs(v);
		}

		public static double pow(double a, double b)
		{
			return Math.Pow(a, b);
		}

		public static void SetArray<T>(T[] data, T value)
		{
			for (int i = 0; i < data.Length; i++)
			{
				data[i] = value;
			}
		}

		public static double ldexp(double number, int exponent)
		{
			return number * Math.Pow(2.0, exponent);
		}

		public unsafe static int strcmp(sbyte* src, string token)
		{
			int num = 0;
			for (int i = 0; i < token.Length; i++)
			{
				if (src[i] != token[i])
				{
					num++;
				}
			}
			return num;
		}

		public unsafe static int strncmp(sbyte* src, string token, ulong size)
		{
			int num = 0;
			for (int i = 0; i < Math.Min(token.Length, (int)size); i++)
			{
				if (src[i] != token[i])
				{
					num++;
				}
			}
			return num;
		}

		public unsafe static long strtol(sbyte* start, sbyte** end, int radix)
		{
			int num = 0;
			sbyte* ptr = start;
			while (numbers.IndexOf((char)(*ptr)) != -1)
			{
				ptr++;
				num++;
			}
			long num2 = 0L;
			ptr = start;
			while (num > 0)
			{
				long num3 = numbers.IndexOf((char)(*ptr));
				long num4 = (long)Math.Pow(10.0, num - 1);
				num2 += num3 * num4;
				ptr++;
				num--;
			}
			if (end != null)
			{
				*end = ptr;
			}
			return num2;
		}
	}
	internal static class MemoryStats
	{
		private static int _allocations;

		public static int Allocations => _allocations;

		internal static void Allocated()
		{
			Interlocked.Increment(ref _allocations);
		}

		internal static void Freed()
		{
			Interlocked.Decrement(ref _allocations);
		}
	}
	internal class Utility
	{
		public static T[][] CreateArray<T>(int d1, int d2)
		{
			T[][] array = new T[d1][];
			for (int i = 0; i < d1; i++)
			{
				array[i] = new T[d2];
			}
			return array;
		}
	}
}
namespace StbImageSharp
{
	public class AnimatedFrameResult : ImageResult
	{
		public int DelayInMs { get; set; }
	}
	internal class AnimatedGifEnumerator : IEnumerator<AnimatedFrameResult>, IDisposable, IEnumerator
	{
		private readonly StbImage.stbi__context _context;

		private StbImage.stbi__gif _gif;

		public ColorComponents ColorComponents { get; }

		public AnimatedFrameResult Current { get; private set; }

		object IEnumerator.Current => Current;

		public AnimatedGifEnumerator(Stream input, ColorComponents colorComponents)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			_context = new StbImage.stbi__context(input);
			if (StbImage.stbi__gif_test(_context) == 0)
			{
				throw new Exception("Input stream is not GIF file.");
			}
			_gif = new StbImage.stbi__gif();
			ColorComponents = colorComponents;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		public unsafe bool MoveNext()
		{
			int num = default(int);
			byte b = default(byte);
			byte* ptr = StbImage.stbi__gif_load_next(_context, _gif, &num, (int)ColorComponents, &b);
			if (ptr == null)
			{
				return false;
			}
			if (Current == null)
			{
				Current = new AnimatedFrameResult
				{
					Width = _gif.w,
					Height = _gif.h,
					SourceComp = (ColorComponents)num,
					Comp = ((ColorComponents == ColorComponents.Default) ? ((ColorComponents)num) : ColorComponents)
				};
				Current.Data = new byte[Current.Width * Current.Height * (int)Current.Comp];
			}
			Current.DelayInMs = _gif.delay;
			Marshal.Copy(new IntPtr(ptr), Current.Data, 0, Current.Data.Length);
			return true;
		}

		public void Reset()
		{
			throw new NotImplementedException();
		}

		~AnimatedGifEnumerator()
		{
			Dispose(disposing: false);
		}

		protected unsafe virtual void Dispose(bool disposing)
		{
			if (disposing && _gif != null)
			{
				if (_gif._out_ != null)
				{
					CRuntime.free(_gif._out_);
					_gif._out_ = null;
				}
				if (_gif.history != null)
				{
					CRuntime.free(_gif.history);
					_gif.history = null;
				}
				if (_gif.background != null)
				{
					CRuntime.free(_gif.background);
					_gif.background = null;
				}
				_gif = null;
			}
		}
	}
	internal class AnimatedGifEnumerable : IEnumerable<AnimatedFrameResult>, IEnumerable
	{
		private readonly Stream _input;

		public ColorComponents ColorComponents { get; }

		public AnimatedGifEnumerable(Stream input, ColorComponents colorComponents)
		{
			_input = input;
			ColorComponents = colorComponents;
		}

		public IEnumerator<AnimatedFrameResult> GetEnumerator()
		{
			return new AnimatedGifEnumerator(_input, ColorComponents);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public enum ColorComponents
	{
		Default,
		Grey,
		GreyAlpha,
		RedGreenBlue,
		RedGreenBlueAlpha
	}
	public struct ImageInfo
	{
		public int Width;

		public int Height;

		public ColorComponents ColorComponents;

		public int BitsPerChannel;

		public unsafe static ImageInfo? FromStream(Stream stream)
		{
			StbImage.stbi__context s = new StbImage.stbi__context(stream);
			bool flag = StbImage.stbi__is_16_main(s) == 1;
			StbImage.stbi__rewind(s);
			int width = default(int);
			int height = default(int);
			int colorComponents = default(int);
			int num = StbImage.stbi__info_main(s, &width, &height, &colorComponents);
			StbImage.stbi__rewind(s);
			if (num == 0)
			{
				return null;
			}
			return new ImageInfo
			{
				Width = width,
				Height = height,
				ColorComponents = (ColorComponents)colorComponents,
				BitsPerChannel = (flag ? 16 : 8)
			};
		}
	}
	public class ImageResult
	{
		public int Width { get; set; }

		public int Height { get; set; }

		public ColorComponents SourceComp { get; set; }

		public ColorComponents Comp { get; set; }

		public byte[] Data { get; set; }

		internal unsafe static ImageResult FromResult(byte* result, int width, int height, ColorComponents comp, ColorComponents req_comp)
		{
			if (result == null)
			{
				throw new InvalidOperationException(StbImage.stbi__g_failure_reason);
			}
			ImageResult imageResult = new ImageResult
			{
				Width = width,
				Height = height,
				SourceComp = comp,
				Comp = ((req_comp == ColorComponents.Default) ? comp : req_comp)
			};
			imageResult.Data = new byte[width * height * (int)imageResult.Comp];
			Marshal.Copy(new IntPtr(result), imageResult.Data, 0, imageResult.Data.Length);
			return imageResult;
		}

		public unsafe static ImageResult FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default)
		{
			byte* ptr = null;
			try
			{
				int width = default(int);
				int height = default(int);
				int comp = default(int);
				ptr = StbImage.stbi__load_and_postprocess_8bit(new StbImage.stbi__context(stream), &width, &height, &comp, (int)requiredComponents);
				return FromResult(ptr, width, height, (ColorComponents)comp, requiredComponents);
			}
			finally
			{
				if (ptr != null)
				{
					CRuntime.free(ptr);
				}
			}
		}

		public static ImageResult FromMemory(byte[] data, ColorComponents requiredComponents = ColorComponents.Default)
		{
			using MemoryStream stream = new MemoryStream(data);
			return FromStream(stream, requiredComponents);
		}

		public static IEnumerable<AnimatedFrameResult> AnimatedGifFramesFromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default)
		{
			return new AnimatedGifEnumerable(stream, requiredComponents);
		}
	}
	public class ImageResultFloat
	{
		public int Width { get; set; }

		public int Height { get; set; }

		public ColorComponents SourceComp { get; set; }

		public ColorComponents Comp { get; set; }

		public float[] Data { get; set; }

		internal unsafe static ImageResultFloat FromResult(float* result, int width, int height, ColorComponents comp, ColorComponents req_comp)
		{
			if (result == null)
			{
				throw new InvalidOperationException(StbImage.stbi__g_failure_reason);
			}
			ImageResultFloat imageResultFloat = new ImageResultFloat
			{
				Width = width,
				Height = height,
				SourceComp = comp,
				Comp = ((req_comp == ColorComponents.Default) ? comp : req_comp)
			};
			imageResultFloat.Data = new float[width * height * (int)imageResultFloat.Comp];
			Marshal.Copy(new IntPtr(result), imageResultFloat.Data, 0, imageResultFloat.Data.Length);
			return imageResultFloat;
		}

		public unsafe static ImageResultFloat FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default)
		{
			float* ptr = null;
			try
			{
				int width = default(int);
				int height = default(int);
				int comp = default(int);
				ptr = StbImage.stbi__loadf_main(new StbImage.stbi__context(stream), &width, &height, &comp, (int)requiredComponents);
				return FromResult(ptr, width, height, (ColorComponents)comp, requiredComponents);
			}
			finally
			{
				if (ptr != null)
				{
					CRuntime.free(ptr);
				}
			}
		}

		public static ImageResultFloat FromMemory(byte[] data, ColorComponents requiredComponents = ColorComponents.Default)
		{
			using MemoryStream stream = new MemoryStream(data);
			return FromStream(stream, requiredComponents);
		}
	}
	public static class StbImage
	{
		public class stbi__context
		{
			public byte[] _tempBuffer;

			public int img_n;

			public int img_out_n;

			public uint img_x;

			public uint img_y;

			public Stream Stream { get; }

			public stbi__context(Stream stream)
			{
				if (stream == null)
				{
					throw new ArgumentNullException("stream");
				}
				Stream = stream;
			}
		}

		public struct stbi__bmp_data
		{
			public int bpp;

			public int offset;

			public int hsz;

			public uint mr;

			public uint mg;

			public uint mb;

			public uint ma;

			public uint all_a;

			public int extra_read;
		}

		public struct stbi__result_info
		{
			public int bits_per_channel;

			public int num_channels;

			public int channel_order;
		}

		public class stbi__gif
		{
			public unsafe byte* _out_;

			public unsafe byte* background;

			public int bgindex;

			public stbi__gif_lzw[] codes = new stbi__gif_lzw[8192];

			public byte[][] color_table;

			public int cur_x;

			public int cur_y;

			public int delay;

			public int eflags;

			public int flags;

			public int h;

			public unsafe byte* history;

			public int lflags;

			public int line_size;

			public byte[][] lpal = Utility.CreateArray<byte>(256, 4);

			public int max_x;

			public int max_y;

			public byte[][] pal = Utility.CreateArray<byte>(256, 4);

			public int parse;

			public int ratio;

			public int start_x;

			public int start_y;

			public int step;

			public int transparent;

			public int w;
		}

		public struct stbi__gif_lzw
		{
			public short prefix;

			public byte first;

			public byte suffix;
		}

		public unsafe delegate void delegate0(byte* arg0, int arg1, short* arg2);

		public unsafe delegate void delegate1(byte* arg0, byte* arg1, byte* arg2, byte* arg3, int arg4, int arg5);

		public unsafe delegate byte* delegate2(byte* arg0, byte* arg1, byte* arg2, int arg3, int arg4);

		public struct stbi__huffman
		{
			public unsafe fixed byte fast[512];

			public unsafe fixed ushort code[256];

			public unsafe fixed byte values[256];

			public unsafe fixed byte size[257];

			public unsafe fixed uint maxcode[18];

			public unsafe fixed int delta[17];
		}

		public class stbi__jpeg
		{
			public struct unnamed1
			{
				public int id;

				public int h;

				public int v;

				public int tq;

				public int hd;

				public int ha;

				public int dc_pred;

				public int x;

				public int y;

				public int w2;

				public int h2;

				public unsafe byte* data;

				public unsafe void* raw_data;

				public unsafe void* raw_coeff;

				public unsafe byte* linebuf;

				public unsafe short* coeff;

				public int coeff_w;

				public int coeff_h;
			}

			public int app14_color_transform;

			public int code_bits;

			public uint code_buffer;

			public ushort[][] dequant = Utility.CreateArray<ushort>(4, 64);

			public int eob_run;

			public short[][] fast_ac = Utility.CreateArray<short>(4, 512);

			public stbi__huffman[] huff_ac = new stbi__huffman[4];

			public stbi__huffman[] huff_dc = new stbi__huffman[4];

			public delegate0 idct_block_kernel;

			public unnamed1[] img_comp = new unnamed1[4];

			public int img_h_max;

			public int img_mcu_h;

			public int img_mcu_w;

			public int img_mcu_x;

			public int img_mcu_y;

			public int img_v_max;

			public int jfif;

			public byte marker;

			public int nomore;

			public int[] order = new int[4];

			public int progressive;

			public delegate2 resample_row_hv_2_kernel;

			public int restart_interval;

			public int rgb;

			public stbi__context s;

			public int scan_n;

			public int spec_end;

			public int spec_start;

			public int succ_high;

			public int succ_low;

			public int todo;

			public delegate1 YCbCr_to_RGB_kernel;
		}

		public class stbi__resample
		{
			public int hs;

			public unsafe byte* line0;

			public unsafe byte* line1;

			public delegate2 resample;

			public int vs;

			public int w_lores;

			public int ypos;

			public int ystep;
		}

		public class stbi__png
		{
			public unsafe byte* _out_;

			public int depth;

			public unsafe byte* expanded;

			public unsafe byte* idata;

			public stbi__context s;
		}

		public struct stbi__pngchunk
		{
			public uint length;

			public uint type;
		}

		public struct stbi__zbuf
		{
			public unsafe byte* zbuffer;

			public unsafe byte* zbuffer_end;

			public int num_bits;

			public uint code_buffer;

			public unsafe sbyte* zout;

			public unsafe sbyte* zout_start;

			public unsafe sbyte* zout_end;

			public int z_expandable;

			public stbi__zhuffman z_length;

			public stbi__zhuffman z_distance;
		}

		public struct stbi__zhuffman
		{
			public unsafe fixed ushort fast[512];

			public unsafe fixed ushort firstcode[16];

			public unsafe fixed int maxcode[17];

			public unsafe fixed ushort firstsymbol[16];

			public unsafe fixed byte size[288];

			public unsafe fixed ushort value[288];
		}

		public static string stbi__g_failure_reason;

		public static readonly char[] stbi__parse_png_file_invalid_chunk = new char[25];

		public const int STBI__SCAN_header = 2;

		public const int STBI__SCAN_load = 0;

		public const int STBI__SCAN_type = 1;

		public const int STBI_default = 0;

		public const int STBI_grey = 1;

		public const int STBI_grey_alpha = 2;

		public const int STBI_ORDER_BGR = 1;

		public const int STBI_ORDER_RGB = 0;

		public const int STBI_rgb = 3;

		public const int STBI_rgb_alpha = 4;

		public static byte[] stbi__compute_huffman_codes_length_dezigzag = new byte[19]
		{
			16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
			11, 4, 12, 3, 13, 2, 14, 1, 15
		};

		public static int stbi__de_iphone_flag_global;

		public static int stbi__de_iphone_flag_local;

		public static int stbi__de_iphone_flag_set;

		public static float stbi__h2l_gamma_i = 0.45454544f;

		public static float stbi__h2l_scale_i = 1f;

		public static float stbi__l2h_gamma = 2.2f;

		public static float stbi__l2h_scale = 1f;

		public static byte[] stbi__process_frame_header_rgb = new byte[3] { 82, 71, 66 };

		public static byte[] stbi__process_marker_tag = new byte[6] { 65, 100, 111, 98, 101, 0 };

		public static int[] stbi__shiftsigned_mul_table = new int[9] { 0, 255, 85, 73, 17, 33, 65, 129, 1 };

		public static int[] stbi__shiftsigned_shift_table = new int[9] { 0, 0, 0, 1, 0, 2, 4, 6, 0 };

		public static int stbi__unpremultiply_on_load_global;

		public static int stbi__unpremultiply_on_load_local;

		public static int stbi__unpremultiply_on_load_set;

		public static int stbi__vertically_flip_on_load_global;

		public static int stbi__vertically_flip_on_load_local;

		public static int stbi__vertically_flip_on_load_set;

		public static uint[] stbi__bmask = new uint[17]
		{
			0u, 1u, 3u, 7u, 15u, 31u, 63u, 127u, 255u, 511u,
			1023u, 2047u, 4095u, 8191u, 16383u, 32767u, 65535u
		};

		public static int[] stbi__jbias = new int[16]
		{
			0, -1, -3, -7, -15, -31, -63, -127, -255, -511,
			-1023, -2047, -4095, -8191, -16383, -32767
		};

		public static byte[] stbi__jpeg_dezigzag = new byte[79]
		{
			0, 1, 8, 16, 9, 2, 3, 10, 17, 24,
			32, 25, 18, 11, 4, 5, 12, 19, 26, 33,
			40, 48, 41, 34, 27, 20, 13, 6, 7, 14,
			21, 28, 35, 42, 49, 56, 57, 50, 43, 36,
			29, 22, 15, 23, 30, 37, 44, 51, 58, 59,
			52, 45, 38, 31, 39, 46, 53, 60, 61, 54,
			47, 55, 62, 63, 63, 63, 63, 63, 63, 63,
			63, 63, 63, 63, 63, 63, 63, 63, 63
		};

		public const int STBI__F_avg = 3;

		public const int STBI__F_avg_first = 5;

		public const int STBI__F_none = 0;

		public const int STBI__F_paeth = 4;

		public const int STBI__F_paeth_first = 6;

		public const int STBI__F_sub = 1;

		public const int STBI__F_up = 2;

		public static byte[] first_row_filter = new byte[5] { 0, 1, 0, 5, 6 };

		public static byte[] stbi__check_png_header_png_sig = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 };

		public static byte[] stbi__depth_scale_table = new byte[9] { 0, 255, 85, 0, 17, 0, 0, 0, 1 };

		public static byte[] stbi__zdefault_distance = new byte[32]
		{
			5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
			5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
			5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
			5, 5
		};

		public static byte[] stbi__zdefault_length = new byte[288]
		{
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 7, 7, 7, 7,
			7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
			7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
			8, 8, 8, 8, 8, 8, 8, 8
		};

		public static int[] stbi__zdist_base = new int[32]
		{
			1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
			33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
			1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,
			0, 0
		};

		public static int[] stbi__zdist_extra = new int[32]
		{
			0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
			4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
			9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
			0, 0
		};

		public static int[] stbi__zlength_base = new int[31]
		{
			3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
			15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
			67, 83, 99, 115, 131, 163, 195, 227, 258, 0,
			0
		};

		public static int[] stbi__zlength_extra = new int[31]
		{
			0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
			1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
			4, 4, 4, 4, 5, 5, 5, 5, 0, 0,
			0
		};

		public static int NativeAllocations => MemoryStats.Allocations;

		private static int stbi__err(string str)
		{
			stbi__g_failure_reason = str;
			return 0;
		}

		public static byte stbi__get8(stbi__context s)
		{
			int num = s.Stream.ReadByte();
			if (num == -1)
			{
				return 0;
			}
			return (byte)num;
		}

		public static void stbi__skip(stbi__context s, int skip)
		{
			s.Stream.Seek(skip, SeekOrigin.Current);
		}

		public static void stbi__rewind(stbi__context s)
		{
			s.Stream.Seek(0L, SeekOrigin.Begin);
		}

		public static int stbi__at_eof(stbi__context s)
		{
			if (s.Stream.Position != s.Stream.Length)
			{
				return 0;
			}
			return 1;
		}

		public unsafe static int stbi__getn(stbi__context s, byte* buf, int size)
		{
			if (s._tempBuffer == null || s._tempBuffer.Length < size)
			{
				s._tempBuffer = new byte[size * 2];
			}
			int num = s.Stream.Read(s._tempBuffer, 0, size);
			Marshal.Copy(s._tempBuffer, 0, new IntPtr(buf), num);
			return num;
		}

		public static int stbi__bmp_test(stbi__context s)
		{
			int result = stbi__bmp_test_raw(s);
			stbi__rewind(s);
			return result;
		}

		public unsafe static void* stbi__bmp_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri)
		{
			uint num = 0u;
			uint num2 = 0u;
			uint num3 = 0u;
			uint num4 = 0u;
			uint num5 = 0u;
			byte[][] array = Utility.CreateArray<byte>(256, 4);
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			int num9 = 0;
			int num10 = 0;
			int num11 = 0;
			int num12 = 0;
			stbi__bmp_data stbi__bmp_data = new stbi__bmp_data
			{
				all_a = 255u
			};
			if (stbi__bmp_parse_header(s, &stbi__bmp_data) == null)
			{
				return null;
			}
			num10 = (((int)s.img_y > 0) ? 1 : 0);
			s.img_y = (uint)CRuntime.abs((int)s.img_y);
			if (s.img_y > 16777216)
			{
				return (void*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
			}
			if (s.img_x > 16777216)
			{
				return (void*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
			}
			num = stbi__bmp_data.mr;
			num2 = stbi__bmp_data.mg;
			num3 = stbi__bmp_data.mb;
			num4 = stbi__bmp_data.ma;
			num5 = stbi__bmp_data.all_a;
			if (stbi__bmp_data.hsz == 12)
			{
				if (stbi__bmp_data.bpp < 24)
				{
					num6 = (stbi__bmp_data.offset - stbi__bmp_data.extra_read - 24) / 3;
				}
			}
			else if (stbi__bmp_data.bpp < 16)
			{
				num6 = stbi__bmp_data.offset - stbi__bmp_data.extra_read - stbi__bmp_data.hsz >> 2;
			}
			if (stbi__bmp_data.bpp == 24 && num4 == 4278190080u)
			{
				s.img_n = 3;
			}
			else
			{
				s.img_n = ((num4 != 0) ? 4 : 3);
			}
			num12 = ((req_comp == 0 || req_comp < 3) ? s.img_n : req_comp);
			if (stbi__mad3sizes_valid(num12, (int)s.img_x, (int)s.img_y, 0) == 0)
			{
				return (void*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
			}
			byte* ptr = (byte*)stbi__malloc_mad3(num12, (int)s.img_x, (int)s.img_y, 0);
			if (ptr == null)
			{
				return (void*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			if (stbi__bmp_data.bpp < 16)
			{
				int num13 = 0;
				if (num6 == 0 || num6 > 256)
				{
					CRuntime.free(ptr);
					return (void*)(int)((stbi__err("invalid") != 0) ? 0u : 0u);
				}
				for (num7 = 0; num7 < num6; num7++)
				{
					array[num7][2] = stbi__get8(s);
					array[num7][1] = stbi__get8(s);
					array[num7][0] = stbi__get8(s);
					if (stbi__bmp_data.hsz != 12)
					{
						stbi__get8(s);
					}
					array[num7][3] = byte.MaxValue;
				}
				stbi__skip(s, stbi__bmp_data.offset - stbi__bmp_data.extra_read - stbi__bmp_data.hsz - num6 * ((stbi__bmp_data.hsz == 12) ? 3 : 4));
				if (stbi__bmp_data.bpp == 1)
				{
					num9 = (int)(s.img_x + 7 >> 3);
				}
				else if (stbi__bmp_data.bpp == 4)
				{
					num9 = (int)(s.img_x + 1 >> 1);
				}
				else
				{
					if (stbi__bmp_data.bpp != 8)
					{
						CRuntime.free(ptr);
						return (void*)(int)((stbi__err("bad bpp") != 0) ? 0u : 0u);
					}
					num9 = (int)s.img_x;
				}
				num11 = -num9 & 3;
				if (stbi__bmp_data.bpp == 1)
				{
					for (num8 = 0; num8 < (int)s.img_y; num8++)
					{
						int num14 = 7;
						int num15 = stbi__get8(s);
						for (num7 = 0; num7 < (int)s.img_x; num7++)
						{
							int num16 = (num15 >> num14) & 1;
							ptr[num13++] = array[num16][0];
							ptr[num13++] = array[num16][1];
							ptr[num13++] = array[num16][2];
							if (num12 == 4)
							{
								ptr[num13++] = byte.MaxValue;
							}
							if (num7 + 1 == (int)s.img_x)
							{
								break;
							}
							if (--num14 < 0)
							{
								num14 = 7;
								num15 = stbi__get8(s);
							}
						}
						stbi__skip(s, num11);
					}
				}
				else
				{
					for (num8 = 0; num8 < (int)s.img_y; num8++)
					{
						for (num7 = 0; num7 < (int)s.img_x; num7 += 2)
						{
							int num17 = stbi__get8(s);
							int num18 = 0;
							if (stbi__bmp_data.bpp == 4)
							{
								num18 = num17 & 0xF;
								num17 >>= 4;
							}
							ptr[num13++] = array[num17][0];
							ptr[num13++] = array[num17][1];
							ptr[num13++] = array[num17][2];
							if (num12 == 4)
							{
								ptr[num13++] = byte.MaxValue;
							}
							if (num7 + 1 == (int)s.img_x)
							{
								break;
							}
							num17 = ((stbi__bmp_data.bpp == 8) ? stbi__get8(s) : num18);
							ptr[num13++] = array[num17][0];
							ptr[num13++] = array[num17][1];
							ptr[num13++] = array[num17][2];
							if (num12 == 4)
							{
								ptr[num13++] = byte.MaxValue;
							}
						}
						stbi__skip(s, num11);
					}
				}
			}
			else
			{
				int shift = 0;
				int shift2 = 0;
				int shift3 = 0;
				int shift4 = 0;
				int num19 = 0;
				int num20 = 0;
				int num21 = 0;
				int num22 = 0;
				int num23 = 0;
				int num24 = 0;
				stbi__skip(s, stbi__bmp_data.offset - stbi__bmp_data.extra_read - stbi__bmp_data.hsz);
				num9 = (int)((stbi__bmp_data.bpp == 24) ? (3 * s.img_x) : ((stbi__bmp_data.bpp == 16) ? (2 * s.img_x) : 0));
				num11 = -num9 & 3;
				if (stbi__bmp_data.bpp == 24)
				{
					num24 = 1;
				}
				else if (stbi__bmp_data.bpp == 32 && num3 == 255 && num2 == 65280 && num == 16711680 && num4 == 4278190080u)
				{
					num24 = 2;
				}
				if (num24 == 0)
				{
					if (num == 0 || num2 == 0 || num3 == 0)
					{
						CRuntime.free(ptr);
						return (void*)(int)((stbi__err("bad masks") != 0) ? 0u : 0u);
					}
					shift = stbi__high_bit(num) - 7;
					num19 = stbi__bitcount(num);
					shift2 = stbi__high_bit(num2) - 7;
					num20 = stbi__bitcount(num2);
					shift3 = stbi__high_bit(num3) - 7;
					num21 = stbi__bitcount(num3);
					shift4 = stbi__high_bit(num4) - 7;
					num22 = stbi__bitcount(num4);
					if (num19 > 8 || num20 > 8 || num21 > 8 || num22 > 8)
					{
						CRuntime.free(ptr);
						return (void*)(int)((stbi__err("bad masks") != 0) ? 0u : 0u);
					}
				}
				for (num8 = 0; num8 < (int)s.img_y; num8++)
				{
					if (num24 != 0)
					{
						for (num7 = 0; num7 < (int)s.img_x; num7++)
						{
							byte b = 0;
							ptr[num23 + 2] = stbi__get8(s);
							ptr[num23 + 1] = stbi__get8(s);
							ptr[num23] = stbi__get8(s);
							num23 += 3;
							b = ((num24 == 2) ? stbi__get8(s) : byte.MaxValue);
							num5 |= b;
							if (num12 == 4)
							{
								ptr[num23++] = b;
							}
						}
					}
					else
					{
						int bpp = stbi__bmp_data.bpp;
						for (num7 = 0; num7 < (int)s.img_x; num7++)
						{
							uint num25 = ((bpp == 16) ? ((uint)stbi__get16le(s)) : stbi__get32le(s));
							uint num26 = 0u;
							ptr[num23++] = (byte)(stbi__shiftsigned(num25 & num, shift, num19) & 0xFF);
							ptr[num23++] = (byte)(stbi__shiftsigned(num25 & num2, shift2, num20) & 0xFF);
							ptr[num23++] = (byte)(stbi__shiftsigned(num25 & num3, shift3, num21) & 0xFF);
							num26 = ((num4 != 0) ? ((uint)stbi__shiftsigned(num25 & num4, shift4, num22)) : 255u);
							num5 |= num26;
							if (num12 == 4)
							{
								ptr[num23++] = (byte)(num26 & 0xFF);
							}
						}
					}
					stbi__skip(s, num11);
				}
			}
			if (num12 == 4 && num5 == 0)
			{
				for (num7 = (int)(4 * s.img_x * s.img_y - 1); num7 >= 0; num7 -= 4)
				{
					ptr[num7] = byte.MaxValue;
				}
			}
			if (num10 != 0)
			{
				byte b2 = 0;
				for (num8 = 0; num8 < (int)s.img_y >> 1; num8++)
				{
					byte* ptr2 = ptr + num8 * s.img_x * num12;
					byte* ptr3 = ptr + (s.img_y - 1 - num8) * s.img_x * num12;
					for (num7 = 0; num7 < (int)s.img_x * num12; num7++)
					{
						b2 = ptr2[num7];
						ptr2[num7] = ptr3[num7];
						ptr3[num7] = b2;
					}
				}
			}
			if (req_comp != 0 && req_comp != num12)
			{
				ptr = stbi__convert_format(ptr, num12, req_comp, s.img_x, s.img_y);
				if (ptr == null)
				{
					return ptr;
				}
			}
			*x = (int)s.img_x;
			*y = (int)s.img_y;
			if (comp != null)
			{
				*comp = s.img_n;
			}
			return ptr;
		}

		public unsafe static int stbi__bmp_info(stbi__context s, int* x, int* y, int* comp)
		{
			stbi__bmp_data stbi__bmp_data = new stbi__bmp_data
			{
				all_a = 255u
			};
			if (stbi__bmp_parse_header(s, &stbi__bmp_data) == null)
			{
				stbi__rewind(s);
				return 0;
			}
			if (x != null)
			{
				*x = (int)s.img_x;
			}
			if (y != null)
			{
				*y = (int)s.img_y;
			}
			if (comp != null)
			{
				if (stbi__bmp_data.bpp == 24 && stbi__bmp_data.ma == 4278190080u)
				{
					*comp = 3;
				}
				else
				{
					*comp = ((stbi__bmp_data.ma != 0) ? 4 : 3);
				}
			}
			return 1;
		}

		public static int stbi__bmp_test_raw(stbi__context s)
		{
			int num = 0;
			if (stbi__get8(s) != 66)
			{
				return 0;
			}
			if (stbi__get8(s) != 77)
			{
				return 0;
			}
			stbi__get32le(s);
			stbi__get16le(s);
			stbi__get16le(s);
			stbi__get32le(s);
			num = (int)stbi__get32le(s);
			if (num != 12 && num != 40 && num != 56 && num != 108 && num != 124)
			{
				return 0;
			}
			return 1;
		}

		public unsafe static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress)
		{
			switch (compress)
			{
			case 3:
				return 1;
			case 0:
				if (info->bpp == 16)
				{
					info->mr = 31744u;
					info->mg = 992u;
					info->mb = 31u;
				}
				else if (info->bpp == 32)
				{
					info->mr = 16711680u;
					info->mg = 65280u;
					info->mb = 255u;
					info->ma = 4278190080u;
					info->all_a = 0u;
				}
				else
				{
					info->mr = (info->mg = (info->mb = (info->ma = 0u)));
				}
				return 1;
			default:
				return 0;
			}
		}

		public unsafe static void* stbi__bmp_parse_header(stbi__context s, stbi__bmp_data* info)
		{
			int num = 0;
			if (stbi__get8(s) != 66 || stbi__get8(s) != 77)
			{
				return (void*)(int)((stbi__err("not BMP") != 0) ? 0u : 0u);
			}
			stbi__get32le(s);
			stbi__get16le(s);
			stbi__get16le(s);
			info->offset = (int)stbi__get32le(s);
			num = (info->hsz = (int)stbi__get32le(s));
			info->mr = (info->mg = (info->mb = (info->ma = 0u)));
			info->extra_read = 14;
			if (info->offset < 0)
			{
				return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u);
			}
			if (num != 12 && num != 40 && num != 56 && num != 108 && num != 124)
			{
				return (void*)(int)((stbi__err("unknown BMP") != 0) ? 0u : 0u);
			}
			if (num == 12)
			{
				s.img_x = (uint)stbi__get16le(s);
				s.img_y = (uint)stbi__get16le(s);
			}
			else
			{
				s.img_x = stbi__get32le(s);
				s.img_y = stbi__get32le(s);
			}
			if (stbi__get16le(s) != 1)
			{
				return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u);
			}
			info->bpp = stbi__get16le(s);
			if (num != 12)
			{
				int num2 = (int)stbi__get32le(s);
				if (num2 == 1 || num2 == 2)
				{
					return (void*)(int)((stbi__err("BMP RLE") != 0) ? 0u : 0u);
				}
				if (num2 >= 4)
				{
					return (void*)(int)((stbi__err("BMP JPEG/PNG") != 0) ? 0u : 0u);
				}
				if (num2 == 3 && info->bpp != 16 && info->bpp != 32)
				{
					return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u);
				}
				stbi__get32le(s);
				stbi__get32le(s);
				stbi__get32le(s);
				stbi__get32le(s);
				stbi__get32le(s);
				if (num == 40 || num == 56)
				{
					if (num == 56)
					{
						stbi__get32le(s);
						stbi__get32le(s);
						stbi__get32le(s);
						stbi__get32le(s);
					}
					if (info->bpp == 16 || info->bpp == 32)
					{
						switch (num2)
						{
						case 0:
							stbi__bmp_set_mask_defaults(info, num2);
							break;
						case 3:
							info->mr = stbi__get32le(s);
							info->mg = stbi__get32le(s);
							info->mb = stbi__get32le(s);
							info->extra_read += 12;
							if (info->mr == info->mg && info->mg == info->mb)
							{
								return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u);
							}
							break;
						default:
							return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u);
						}
					}
				}
				else
				{
					int num3 = 0;
					if (num != 108 && num != 124)
					{
						return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u);
					}
					info->mr = stbi__get32le(s);
					info->mg = stbi__get32le(s);
					info->mb = stbi__get32le(s);
					info->ma = stbi__get32le(s);
					if (num2 != 3)
					{
						stbi__bmp_set_mask_defaults(info, num2);
					}
					stbi__get32le(s);
					for (num3 = 0; num3 < 12; num3++)
					{
						stbi__get32le(s);
					}
					if (num == 124)
					{
						stbi__get32le(s);
						stbi__get32le(s);
						stbi__get32le(s);
						stbi__get32le(s);
					}
				}
			}
			return (void*)1;
		}

		public static void stbi_hdr_to_ldr_gamma(float gamma)
		{
			stbi__h2l_gamma_i = 1f / gamma;
		}

		public static void stbi_hdr_to_ldr_scale(float scale)
		{
			stbi__h2l_scale_i = 1f / scale;
		}

		public static void stbi_ldr_to_hdr_gamma(float gamma)
		{
			stbi__l2h_gamma = gamma;
		}

		public static void stbi_ldr_to_hdr_scale(float scale)
		{
			stbi__l2h_scale = scale;
		}

		public static void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
		{
			stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply;
		}

		public static void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
		{
			stbi__de_iphone_flag_global = flag_true_if_should_convert;
		}

		public static void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
		{
			stbi__vertically_flip_on_load_global = flag_true_if_should_flip;
		}

		public static void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert)
		{
			stbi__de_iphone_flag_local = flag_true_if_should_convert;
			stbi__de_iphone_flag_set = 1;
		}

		public static void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip)
		{
			stbi__vertically_flip_on_load_local = flag_true_if_should_flip;
			stbi__vertically_flip_on_load_set = 1;
		}

		public unsafe static void* stbi__malloc(ulong size)
		{
			return CRuntime.malloc(size);
		}

		public static int stbi__addsizes_valid(int a, int b)
		{
			if (b < 0)
			{
				return 0;
			}
			if (a > int.MaxValue - b)
			{
				return 0;
			}
			return 1;
		}

		public static int stbi__mul2sizes_valid(int a, int b)
		{
			if (a < 0 || b < 0)
			{
				return 0;
			}
			if (b == 0)
			{
				return 1;
			}
			if (a > int.MaxValue / b)
			{
				return 0;
			}
			return 1;
		}

		public static int stbi__mad2sizes_valid(int a, int b, int add)
		{
			if (stbi__mul2sizes_valid(a, b) == 0 || stbi__addsizes_valid(a * b, add) == 0)
			{
				return 0;
			}
			return 1;
		}

		public static int stbi__mad3sizes_valid(int a, int b, int c, int add)
		{
			if (stbi__mul2sizes_valid(a, b) == 0 || stbi__mul2sizes_valid(a * b, c) == 0 || stbi__addsizes_valid(a * b * c, add) == 0)
			{
				return 0;
			}
			return 1;
		}

		public static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
		{
			if (stbi__mul2sizes_valid(a, b) == 0 || stbi__mul2sizes_valid(a * b, c) == 0 || stbi__mul2sizes_valid(a * b * c, d) == 0 || stbi__addsizes_valid(a * b * c * d, add) == 0)
			{
				return 0;
			}
			return 1;
		}

		public unsafe static void* stbi__malloc_mad2(int a, int b, int add)
		{
			if (stbi__mad2sizes_valid(a, b, add) == 0)
			{
				return null;
			}
			return stbi__malloc((ulong)(a * b + add));
		}

		public unsafe static void* stbi__malloc_mad3(int a, int b, int c, int add)
		{
			if (stbi__mad3sizes_valid(a, b, c, add) == 0)
			{
				return null;
			}
			return stbi__malloc((ulong)(a * b * c + add));
		}

		public unsafe static void* stbi__malloc_mad4(int a, int b, int c, int d, int add)
		{
			if (stbi__mad4sizes_valid(a, b, c, d, add) == 0)
			{
				return null;
			}
			return stbi__malloc((ulong)(a * b * c * d + add));
		}

		public unsafe static float* stbi__ldr_to_hdr(byte* data, int x, int y, int comp)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			if (data == null)
			{
				return null;
			}
			float* ptr = (float*)stbi__malloc_mad4(x, y, comp, 4, 0);
			if (ptr == null)
			{
				CRuntime.free(data);
				return (float*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			num3 = (((comp & 1) == 0) ? (comp - 1) : comp);
			for (num = 0; num < x * y; num++)
			{
				for (num2 = 0; num2 < num3; num2++)
				{
					ptr[num * comp + num2] = (float)(CRuntime.pow((float)(int)data[num * comp + num2] / 255f, stbi__l2h_gamma) * (double)stbi__l2h_scale);
				}
			}
			if (num3 < comp)
			{
				for (num = 0; num < x * y; num++)
				{
					ptr[num * comp + num3] = (float)(int)data[num * comp + num3] / 255f;
				}
			}
			CRuntime.free(data);
			return ptr;
		}

		public unsafe static void* stbi__load_main(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc)
		{
			CRuntime.memset(ri, 0, (ulong)sizeof(stbi__result_info));
			ri->bits_per_channel = 8;
			ri->channel_order = 0;
			ri->num_channels = 0;
			if (stbi__png_test(s) != 0)
			{
				return stbi__png_load(s, x, y, comp, req_comp, ri);
			}
			if (stbi__bmp_test(s) != 0)
			{
				return stbi__bmp_load(s, x, y, comp, req_comp, ri);
			}
			if (stbi__gif_test(s) != 0)
			{
				return stbi__gif_load(s, x, y, comp, req_comp, ri);
			}
			if (stbi__psd_test(s) != 0)
			{
				return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc);
			}
			if (stbi__jpeg_test(s) != 0)
			{
				return stbi__jpeg_load(s, x, y, comp, req_comp, ri);
			}
			if (stbi__hdr_test(s) != 0)
			{
				return stbi__hdr_to_ldr(stbi__hdr_load(s, x, y, comp, req_comp, ri), *x, *y, (req_comp != 0) ? req_comp : (*comp));
			}
			if (stbi__tga_test(s) != 0)
			{
				return stbi__tga_load(s, x, y, comp, req_comp, ri);
			}
			return (void*)(int)((stbi__err("unknown image type") != 0) ? 0u : 0u);
		}

		public unsafe static byte* stbi__convert_16_to_8(ushort* orig, int w, int h, int channels)
		{
			int num = 0;
			int num2 = w * h * channels;
			byte* ptr = (byte*)stbi__malloc((ulong)num2);
			if (ptr == null)
			{
				return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			for (num = 0; num < num2; num++)
			{
				ptr[num] = (byte)((orig[num] >> 8) & 0xFF);
			}
			CRuntime.free(orig);
			return ptr;
		}

		public unsafe static ushort* stbi__convert_8_to_16(byte* orig, int w, int h, int channels)
		{
			int num = 0;
			int num2 = w * h * channels;
			ushort* ptr = (ushort*)stbi__malloc((ulong)(num2 * 2));
			if (ptr == null)
			{
				return (ushort*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			for (num = 0; num < num2; num++)
			{
				ptr[num] = (ushort)((orig[num] << 8) + orig[num]);
			}
			CRuntime.free(orig);
			return ptr;
		}

		public unsafe static void stbi__vertical_flip(void* image, int w, int h, int bytes_per_pixel)
		{
			int num = 0;
			int num2 = w * bytes_per_pixel;
			byte* ptr = stackalloc byte[2048];
			for (num = 0; num < h >> 1; num++)
			{
				byte* ptr2 = (byte*)image + num * num2;
				byte* ptr3 = (byte*)image + (h - num - 1) * num2;
				ulong num3 = (ulong)num2;
				while (num3 != 0L)
				{
					ulong num4 = ((num3 < 2048) ? num3 : 2048);
					CRuntime.memcpy(ptr, ptr2, num4);
					CRuntime.memcpy(ptr2, ptr3, num4);
					CRuntime.memcpy(ptr3, ptr, num4);
					ptr2 += num4;
					ptr3 += num4;
					num3 -= num4;
				}
			}
		}

		public unsafe static void stbi__vertical_flip_slices(void* image, int w, int h, int z, int bytes_per_pixel)
		{
			int num = 0;
			int num2 = w * h * bytes_per_pixel;
			byte* ptr = (byte*)image;
			for (num = 0; num < z; num++)
			{
				stbi__vertical_flip(ptr, w, h, bytes_per_pixel);
				ptr += num2;
			}
		}

		public unsafe static byte* stbi__load_and_postprocess_8bit(stbi__context s, int* x, int* y, int* comp, int req_comp)
		{
			stbi__result_info stbi__result_info = default(stbi__result_info);
			void* ptr = stbi__load_main(s, x, y, comp, req_comp, &stbi__result_info, 8);
			if (ptr == null)
			{
				return null;
			}
			if (stbi__result_info.bits_per_channel != 8)
			{
				ptr = stbi__convert_16_to_8((ushort*)ptr, *x, *y, (req_comp == 0) ? (*comp) : req_comp);
				stbi__result_info.bits_per_channel = 8;
			}
			if (((stbi__vertically_flip_on_load_set != 0) ? stbi__vertically_flip_on_load_local : stbi__vertically_flip_on_load_global) != 0)
			{
				int bytes_per_pixel = ((req_comp != 0) ? req_comp : (*comp));
				stbi__vertical_flip(ptr, *x, *y, bytes_per_pixel);
			}
			return (byte*)ptr;
		}

		public unsafe static ushort* stbi__load_and_postprocess_16bit(stbi__context s, int* x, int* y, int* comp, int req_comp)
		{
			stbi__result_info stbi__result_info = default(stbi__result_info);
			void* ptr = stbi__load_main(s, x, y, comp, req_comp, &stbi__result_info, 16);
			if (ptr == null)
			{
				return null;
			}
			if (stbi__result_info.bits_per_channel != 16)
			{
				ptr = stbi__convert_8_to_16((byte*)ptr, *x, *y, (req_comp == 0) ? (*comp) : req_comp);
				stbi__result_info.bits_per_channel = 16;
			}
			if (((stbi__vertically_flip_on_load_set != 0) ? stbi__vertically_flip_on_load_local : stbi__vertically_flip_on_load_global) != 0)
			{
				int num = ((req_comp != 0) ? req_comp : (*comp));
				stbi__vertical_flip(ptr, *x, *y, num * 2);
			}
			return (ushort*)ptr;
		}

		public unsafe static void stbi__float_postprocess(float* result, int* x, int* y, int* comp, int req_comp)
		{
			if (((stbi__vertically_flip_on_load_set != 0) ? stbi__vertically_flip_on_load_local : stbi__vertically_flip_on_load_global) != 0 && result != null)
			{
				int num = ((req_comp != 0) ? req_comp : (*comp));
				stbi__vertical_flip(result, *x, *y, num * 4);
			}
		}

		public unsafe static float* stbi__loadf_main(stbi__context s, int* x, int* y, int* comp, int req_comp)
		{
			if (stbi__hdr_test(s) != 0)
			{
				stbi__result_info stbi__result_info = default(stbi__result_info);
				float* ptr = stbi__hdr_load(s, x, y, comp, req_comp, &stbi__result_info);
				if (ptr != null)
				{
					stbi__float_postprocess(ptr, x, y, comp, req_comp);
				}
				return ptr;
			}
			byte* ptr2 = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
			if (ptr2 != null)
			{
				return stbi__ldr_to_hdr(ptr2, *x, *y, (req_comp != 0) ? req_comp : (*comp));
			}
			return (float*)(int)((stbi__err("unknown image type") != 0) ? 0u : 0u);
		}

		public static int stbi__get16be(stbi__context s)
		{
			return (stbi__get8(s) << 8) + stbi__get8(s);
		}

		public static uint stbi__get32be(stbi__context s)
		{
			return (uint)((uint)(stbi__get16be(s) << 16) + stbi__get16be(s));
		}

		public static int stbi__get16le(stbi__context s)
		{
			return stbi__get8(s) + (stbi__get8(s) << 8);
		}

		public static uint stbi__get32le(stbi__context s)
		{
			return (uint)(stbi__get16le(s) + (stbi__get16le(s) << 16));
		}

		public static byte stbi__compute_y(int r, int g, int b)
		{
			return (byte)(r * 77 + g * 150 + 29 * b >> 8);
		}

		public unsafe static byte* stbi__convert_format(byte* data, int img_n, int req_comp, uint x, uint y)
		{
			int num = 0;
			int num2 = 0;
			if (req_comp == img_n)
			{
				return data;
			}
			byte* ptr = (byte*)stbi__malloc_mad3(req_comp, (int)x, (int)y, 0);
			if (ptr == null)
			{
				CRuntime.free(data);
				return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			for (num2 = 0; num2 < (int)y; num2++)
			{
				byte* ptr2 = data + num2 * x * img_n;
				byte* ptr3 = ptr + num2 * x * req_comp;
				switch (img_n * 8 + req_comp)
				{
				case 10:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						ptr3[1] = byte.MaxValue;
						num--;
						ptr2++;
						ptr3 += 2;
					}
					break;
				case 11:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						num--;
						ptr2++;
						ptr3 += 3;
					}
					break;
				case 12:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						ptr3[3] = byte.MaxValue;
						num--;
						ptr2++;
						ptr3 += 4;
					}
					break;
				case 17:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						num--;
						ptr2 += 2;
						ptr3++;
					}
					break;
				case 19:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						num--;
						ptr2 += 2;
						ptr3 += 3;
					}
					break;
				case 20:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						ptr3[3] = ptr2[1];
						num--;
						ptr2 += 2;
						ptr3 += 4;
					}
					break;
				case 28:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						ptr3[1] = ptr2[1];
						ptr3[2] = ptr2[2];
						ptr3[3] = byte.MaxValue;
						num--;
						ptr2 += 3;
						ptr3 += 4;
					}
					break;
				case 25:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]);
						num--;
						ptr2 += 3;
						ptr3++;
					}
					break;
				case 26:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]);
						ptr3[1] = byte.MaxValue;
						num--;
						ptr2 += 3;
						ptr3 += 2;
					}
					break;
				case 33:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]);
						num--;
						ptr2 += 4;
						ptr3++;
					}
					break;
				case 34:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]);
						ptr3[1] = ptr2[3];
						num--;
						ptr2 += 4;
						ptr3 += 2;
					}
					break;
				case 35:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						ptr3[1] = ptr2[1];
						ptr3[2] = ptr2[2];
						num--;
						ptr2 += 4;
						ptr3 += 3;
					}
					break;
				default:
					CRuntime.free(data);
					CRuntime.free(ptr);
					return (byte*)(int)((stbi__err("unsupported") != 0) ? 0u : 0u);
				}
			}
			CRuntime.free(data);
			return ptr;
		}

		public static ushort stbi__compute_y_16(int r, int g, int b)
		{
			return (ushort)(r * 77 + g * 150 + 29 * b >> 8);
		}

		public unsafe static ushort* stbi__convert_format16(ushort* data, int img_n, int req_comp, uint x, uint y)
		{
			int num = 0;
			int num2 = 0;
			if (req_comp == img_n)
			{
				return data;
			}
			ushort* ptr = (ushort*)stbi__malloc((ulong)(req_comp * x * y * 2));
			if (ptr == null)
			{
				CRuntime.free(data);
				return (ushort*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			for (num2 = 0; num2 < (int)y; num2++)
			{
				ushort* ptr2 = data + num2 * x * img_n;
				ushort* ptr3 = ptr + num2 * x * req_comp;
				switch (img_n * 8 + req_comp)
				{
				case 10:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						ptr3[1] = ushort.MaxValue;
						num--;
						ptr2++;
						ptr3 += 2;
					}
					break;
				case 11:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						num--;
						ptr2++;
						ptr3 += 3;
					}
					break;
				case 12:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						ptr3[3] = ushort.MaxValue;
						num--;
						ptr2++;
						ptr3 += 4;
					}
					break;
				case 17:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						num--;
						ptr2 += 2;
						ptr3++;
					}
					break;
				case 19:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						num--;
						ptr2 += 2;
						ptr3 += 3;
					}
					break;
				case 20:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = (ptr3[1] = (ptr3[2] = *ptr2));
						ptr3[3] = ptr2[1];
						num--;
						ptr2 += 2;
						ptr3 += 4;
					}
					break;
				case 28:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						ptr3[1] = ptr2[1];
						ptr3[2] = ptr2[2];
						ptr3[3] = ushort.MaxValue;
						num--;
						ptr2 += 3;
						ptr3 += 4;
					}
					break;
				case 25:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]);
						num--;
						ptr2 += 3;
						ptr3++;
					}
					break;
				case 26:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]);
						ptr3[1] = ushort.MaxValue;
						num--;
						ptr2 += 3;
						ptr3 += 2;
					}
					break;
				case 33:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]);
						num--;
						ptr2 += 4;
						ptr3++;
					}
					break;
				case 34:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]);
						ptr3[1] = ptr2[3];
						num--;
						ptr2 += 4;
						ptr3 += 2;
					}
					break;
				case 35:
					num = (int)(x - 1);
					while (num >= 0)
					{
						*ptr3 = *ptr2;
						ptr3[1] = ptr2[1];
						ptr3[2] = ptr2[2];
						num--;
						ptr2 += 4;
						ptr3 += 3;
					}
					break;
				default:
					CRuntime.free(data);
					CRuntime.free(ptr);
					return (ushort*)(int)((stbi__err("unsupported") != 0) ? 0u : 0u);
				}
			}
			CRuntime.free(data);
			return ptr;
		}

		public static byte stbi__clamp(int x)
		{
			if ((uint)x > 255u)
			{
				if (x < 0)
				{
					return 0;
				}
				if (x > 255)
				{
					return byte.MaxValue;
				}
			}
			return (byte)x;
		}

		public static byte stbi__blinn_8x8(byte x, byte y)
		{
			int num = x * y + 128;
			return (byte)((uint)(num + (num >>> 8)) >> 8);
		}

		public static int stbi__bitreverse16(int n)
		{
			n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1);
			n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
			n = ((n & 0xF0F0) >> 4) | ((n & 0xF0F) << 4);
			n = ((n & 0xFF00) >> 8) | ((n & 0xFF) << 8);
			return n;
		}

		public static int stbi__bit_reverse(int v, int bits)
		{
			return stbi__bitreverse16(v) >> 16 - bits;
		}

		public static int stbi__paeth(int a, int b, int c)
		{
			int num = a + b - c;
			int num2 = CRuntime.abs(num - a);
			int num3 = CRuntime.abs(num - b);
			int num4 = CRuntime.abs(num - c);
			if (num2 <= num3 && num2 <= num4)
			{
				return a;
			}
			if (num3 <= num4)
			{
				return b;
			}
			return c;
		}

		public static void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
		{
			stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
			stbi__unpremultiply_on_load_set = 1;
		}

		public static int stbi__high_bit(uint z)
		{
			int num = 0;
			if (z == 0)
			{
				return -1;
			}
			if (z >= 65536)
			{
				num += 16;
				z >>= 16;
			}
			if (z >= 256)
			{
				num += 8;
				z >>= 8;
			}
			if (z >= 16)
			{
				num += 4;
				z >>= 4;
			}
			if (z >= 4)
			{
				num += 2;
				z >>= 2;
			}
			if (z >= 2)
			{
				num++;
			}
			return num;
		}

		public static int stbi__bitcount(uint a)
		{
			a = (a & 0x55555555) + ((a >> 1) & 0x55555555);
			a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
			a = (a + (a >> 4)) & 0xF0F0F0F;
			a += a >> 8;
			a += a >> 16;
			return (int)(a & 0xFF);
		}

		public static int stbi__shiftsigned(uint v, int shift, int bits)
		{
			v = ((shift >= 0) ? (v >> shift) : (v << -shift));
			v >>= 8 - bits;
			return (int)(v * stbi__shiftsigned_mul_table[bits]) >> stbi__shiftsigned_shift_table[bits];
		}

		public unsafe static int stbi__info_main(stbi__context s, int* x, int* y, int* comp)
		{
			if (stbi__jpeg_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			if (stbi__png_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			if (stbi__gif_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			if (stbi__bmp_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			if (stbi__psd_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			if (stbi__hdr_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			if (stbi__tga_info(s, x, y, comp) != 0)
			{
				return 1;
			}
			return stbi__err("unknown image type");
		}

		public static int stbi__is_16_main(stbi__context s)
		{
			if (stbi__png_is16(s) != 0)
			{
				return 1;
			}
			if (stbi__psd_is16(s) != 0)
			{
				return 1;
			}
			return 0;
		}

		public static int stbi__gif_test(stbi__context s)
		{
			int result = stbi__gif_test_raw(s);
			stbi__rewind(s);
			return result;
		}

		public unsafe static void* stbi__gif_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri)
		{
			byte* ptr = null;
			stbi__gif stbi__gif = new stbi__gif();
			ptr = stbi__gif_load_next(s, stbi__gif, comp, req_comp, null);
			if (ptr != null)
			{
				*x = stbi__gif.w;
				*y = stbi__gif.h;
				if (req_comp != 0 && req_comp != 4)
				{
					ptr = stbi__convert_format(ptr, 4, req_comp, (uint)stbi__gif.w, (uint)stbi__gif.h);
				}
			}
			else if (stbi__gif._out_ != null)
			{
				CRuntime.free(stbi__gif._out_);
			}
			CRuntime.free(stbi__gif.history);
			CRuntime.free(stbi__gif.background);
			return ptr;
		}

		public unsafe static void* stbi__load_gif_main(stbi__context s, int** delays, int* x, int* y, int* z, int* comp, int req_comp)
		{
			if (stbi__gif_test(s) != 0)
			{
				int num = 0;
				byte* ptr = null;
				byte* ptr2 = null;
				byte* two_back = null;
				stbi__gif stbi__gif = new stbi__gif();
				int num2 = 0;
				if (delays != null)
				{
					*delays = null;
				}
				do
				{
					ptr = stbi__gif_load_next(s, stbi__gif, comp, req_comp, two_back);
					if (ptr == null)
					{
						continue;
					}
					*x = stbi__gif.w;
					*y = stbi__gif.h;
					num++;
					num2 = stbi__gif.w * stbi__gif.h * 4;
					if (ptr2 != null)
					{
						void* ptr3 = CRuntime.realloc(ptr2, (ulong)(num * num2));
						if (ptr3 == null)
						{
							return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays);
						}
						ptr2 = (byte*)ptr3;
						if (delays != null)
						{
							int* ptr4 = (int*)CRuntime.realloc(*delays, (ulong)(4 * num));
							if (ptr4 == null)
							{
								return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays);
							}
							*delays = ptr4;
						}
					}
					else
					{
						ptr2 = (byte*)stbi__malloc((ulong)(num * num2));
						if (ptr2 == null)
						{
							return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays);
						}
						if (delays != null)
						{
							*delays = (int*)stbi__malloc((ulong)(num * 4));
							if (*delays == null)
							{
								return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays);
							}
						}
					}
					CRuntime.memcpy(ptr2 + (num - 1) * num2, ptr, (ulong)num2);
					if (num >= 2)
					{
						two_back = ptr2 - 2 * num2;
					}
					if (delays != null)
					{
						(*delays)[(long)num - 1L] = stbi__gif.delay;
					}
				}
				while (ptr != null);
				CRuntime.free(stbi__gif._out_);
				CRuntime.free(stbi__gif.history);
				CRuntime.free(stbi__gif.background);
				if (req_comp != 0 && req_comp != 4)
				{
					ptr2 = stbi__convert_format(ptr2, 4, req_comp, (uint)(num * stbi__gif.w), (uint)stbi__gif.h);
				}
				*z = num;
				return ptr2;
			}
			return (void*)(int)((stbi__err("not GIF") != 0) ? 0u : 0u);
		}

		public unsafe static int stbi__gif_info(stbi__context s, int* x, int* y, int* comp)
		{
			return stbi__gif_info_raw(s, x, y, comp);
		}

		public static int stbi__gif_test_raw(stbi__context s)
		{
			int num = 0;
			if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56)
			{
				return 0;
			}
			num = stbi__get8(s);
			if (num != 57 && num != 55)
			{
				return 0;
			}
			if (stbi__get8(s) != 97)
			{
				return 0;
			}
			return 1;
		}

		public static void stbi__gif_parse_colortable(stbi__context s, byte[][] pal, int num_entries, int transp)
		{
			int num = 0;
			for (num = 0; num < num_entries; num++)
			{
				pal[num][2] = stbi__get8(s);
				pal[num][1] = stbi__get8(s);
				pal[num][0] = stbi__get8(s);
				pal[num][3] = (byte)((transp != num) ? 255u : 0u);
			}
		}

		public unsafe static int stbi__gif_header(stbi__context s, stbi__gif g, int* comp, int is_info)
		{
			byte b = 0;
			if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56)
			{
				return stbi__err("not GIF");
			}
			b = stbi__get8(s);
			if (b != 55 && b != 57)
			{
				return stbi__err("not GIF");
			}
			if (stbi__get8(s) != 97)
			{
				return stbi__err("not GIF");
			}
			stbi__g_failure_reason = "";
			g.w = stbi__get16le(s);
			g.h = stbi__get16le(s);
			g.flags = stbi__get8(s);
			g.bgindex = stbi__get8(s);
			g.ratio = stbi__get8(s);
			g.transparent = -1;
			if (g.w > 16777216)
			{
				return stbi__err("too large");
			}
			if (g.h > 16777216)
			{
				return stbi__err("too large");
			}
			if (comp != null)
			{
				*comp = 4;
			}
			if (is_info != 0)
			{
				return 1;
			}
			if ((g.flags & 0x80) != 0)
			{
				stbi__gif_parse_colortable(s, g.pal, 2 << (g.flags & 7), -1);
			}
			return 1;
		}

		public unsafe static int stbi__gif_info_raw(stbi__context s, int* x, int* y, int* comp)
		{
			stbi__gif stbi__gif = new stbi__gif();
			if (stbi__gif == null)
			{
				return stbi__err("outofmem");
			}
			if (stbi__gif_header(s, stbi__gif, comp, 1) == 0)
			{
				stbi__rewind(s);
				return 0;
			}
			if (x != null)
			{
				*x = stbi__gif.w;
			}
			if (y != null)
			{
				*y = stbi__gif.h;
			}
			return 1;
		}

		public unsafe static void stbi__out_gif_code(stbi__gif g, ushort code)
		{
			int num = 0;
			if (g.codes[code].prefix >= 0)
			{
				stbi__out_gif_code(g, (ushort)g.codes[code].prefix);
			}
			if (g.cur_y >= g.max_y)
			{
				return;
			}
			num = g.cur_x + g.cur_y;
			byte* ptr = g._out_ + num;
			g.history[num / 4] = 1;
			byte[] array = g.color_table[g.codes[code].suffix];
			if (array[3] > 128)
			{
				*ptr = array[2];
				ptr[1] = array[1];
				ptr[2] = array[0];
				ptr[3] = array[3];
			}
			g.cur_x += 4;
			if (g.cur_x >= g.max_x)
			{
				g.cur_x = g.start_x;
				g.cur_y += g.step;
				while (g.cur_y >= g.max_y && g.parse > 0)
				{
					g.step = (1 << g.parse) * g.line_size;
					g.cur_y = g.start_y + (g.step >> 1);
					g.parse--;
				}
			}
		}

		public unsafe static byte* stbi__process_gif_raster(stbi__context s, stbi__gif g)
		{
			byte b = 0;
			int num = 0;
			int num2 = 0;
			uint num3 = 0u;
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			int num9 = 0;
			int num10 = 0;
			b = stbi__get8(s);
			if (b > 12)
			{
				return null;
			}
			num10 = 1 << (int)b;
			num3 = 1u;
			num4 = b + 1;
			num5 = (1 << num4) - 1;
			num8 = 0;
			num9 = 0;
			for (num2 = 0; num2 < num10; num2++)
			{
				g.codes[num2].prefix = -1;
				g.codes[num2].first = (byte)num2;
				g.codes[num2].suffix = (byte)num2;
			}
			num6 = num10 + 2;
			num7 = -1;
			num = 0;
			while (true)
			{
				if (num9 < num4)
				{
					if (num == 0)
					{
						num = stbi__get8(s);
						if (num == 0)
						{
							return g._out_;
						}
					}
					num--;
					num8 |= stbi__get8(s) << num9;
					num9 += 8;
					continue;
				}
				int num11 = num8 & num5;
				num8 >>= num4;
				num9 -= num4;
				if (num11 == num10)
				{
					num4 = b + 1;
					num5 = (1 << num4) - 1;
					num6 = num10 + 2;
					num7 = -1;
					num3 = 0u;
					continue;
				}
				if (num11 == num10 + 1)
				{
					stbi__skip(s, num);
					while ((num = stbi__get8(s)) > 0)
					{
						stbi__skip(s, num);
					}
					return g._out_;
				}
				if (num11 > num6)
				{
					break;
				}
				if (num3 != 0)
				{
					return (byte*)(int)((stbi__err("no clear code") != 0) ? 0u : 0u);
				}
				if (num7 >= 0)
				{
					fixed (stbi__gif_lzw* ptr = &g.codes[num6++])
					{
						if (num6 > 8192)
						{
							return (byte*)(int)((stbi__err("too many codes") != 0) ? 0u : 0u);
						}
						ptr->prefix = (short)num7;
						ptr->first = g.codes[num7].first;
						ptr->suffix = ((num11 == num6) ? ptr->first : g.codes[num11].first);
					}
				}
				else if (num11 == num6)
				{
					return (byte*)(int)((stbi__err("illegal code in raster") != 0) ? 0u : 0u);
				}
				stbi__out_gif_code(g, (ushort)num11);
				if ((num6 & num5) == 0 && num6 <= 4095)
				{
					num4++;
					num5 = (1 << num4) - 1;
				}
				num7 = num11;
			}
			return (byte*)(int)((stbi__err("illegal code in raster") != 0) ? 0u : 0u);
		}

		public unsafe static byte* stbi__gif_load_next(stbi__context s, stbi__gif g, int* comp, int req_comp, byte* two_back)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			num2 = 0;
			if (g._out_ == null)
			{
				if (stbi__gif_header(s, g, comp, 0) == 0)
				{
					return null;
				}
				if (stbi__mad3sizes_valid(4, g.w, g.h, 0) == 0)
				{
					return (byte*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
				}
				num4 = g.w * g.h;
				g._out_ = (byte*)stbi__malloc((ulong)(4 * num4));
				g.background = (byte*)stbi__malloc((ulong)(4 * num4));
				g.history = (byte*)stbi__malloc((ulong)num4);
				if (g._out_ == null || g.background == null || g.history == null)
				{
					return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
				}
				CRuntime.memset(g._out_, 0, (ulong)(4 * num4));
				CRuntime.memset(g.background, 0, (ulong)(4 * num4));
				CRuntime.memset(g.history, 0, (ulong)num4);
				num2 = 1;
			}
			else
			{
				num = (g.eflags & 0x1C) >> 2;
				num4 = g.w * g.h;
				if (num == 3 && two_back == null)
				{
					num = 2;
				}
				switch (num)
				{
				case 3:
					for (num3 = 0; num3 < num4; num3++)
					{
						if (g.history[num3] != 0)
						{
							CRuntime.memcpy(g._out_ + num3 * 4, two_back + num3 * 4, 4uL);
						}
					}
					break;
				case 2:
					for (num3 = 0; num3 < num4; num3++)
					{
						if (g.history[num3] != 0)
						{
							CRuntime.memcpy(g._out_ + num3 * 4, g.background + num3 * 4, 4uL);
						}
					}
					break;
				}
				CRuntime.memcpy(g.background, g._out_, (ulong)(4 * g.w * g.h));
			}
			CRuntime.memset(g.history, 0, (ulong)(g.w * g.h));
			while (true)
			{
				switch (stbi__get8(s))
				{
				case 44:
				{
					int num6 = 0;
					int num7 = 0;
					int num8 = 0;
					int num9 = 0;
					num6 = stbi__get16le(s);
					num7 = stbi__get16le(s);
					num8 = stbi__get16le(s);
					num9 = stbi__get16le(s);
					if (num6 + num8 > g.w || num7 + num9 > g.h)
					{
						return (byte*)(int)((stbi__err("bad Image Descriptor") != 0) ? 0u : 0u);
					}
					g.line_size = g.w * 4;
					g.start_x = num6 * 4;
					g.start_y = num7 * g.line_size;
					g.max_x = g.start_x + num8 * 4;
					g.max_y = g.start_y + num9 * g.line_size;
					g.cur_x = g.start_x;
					g.cur_y = g.start_y;
					if (num8 == 0)
					{
						g.cur_y = g.max_y;
					}
					g.lflags = stbi__get8(s);
					if ((g.lflags & 0x40) != 0)
					{
						g.step = 8 * g.line_size;
						g.parse = 3;
					}
					else
					{
						g.step = g.line_size;
						g.parse = 0;
					}
					if ((g.lflags & 0x80) != 0)
					{
						stbi__gif_parse_colortable(s, g.lpal, 2 << (g.lflags & 7), ((g.eflags & 1) != 0) ? g.transparent : (-1));
						g.color_table = g.lpal;
					}
					else
					{
						if ((g.flags & 0x80) == 0)
						{
							return (byte*)(int)((stbi__err("missing color table") != 0) ? 0u : 0u);
						}
						g.color_table = g.pal;
					}
					byte* ptr = stbi__process_gif_raster(s, g);
					if (ptr == null)
					{
						return null;
					}
					num4 = g.w * g.h;
					if (num2 != 0 && g.bgindex > 0)
					{
						for (num3 = 0; num3 < num4; num3++)
						{
							if (g.history[num3] == 0)
							{
								g.pal[g.bgindex][3] = byte.MaxValue;
								fixed (byte* b = &g.pal[g.bgindex][0])
								{
									CRuntime.memcpy(g._out_ + num3 * 4, b, 4uL);
								}
							}
						}
					}
					return ptr;
				}
				case 33:
				{
					int num5 = 0;
					if (stbi__get8(s) == 249)
					{
						num5 = stbi__get8(s);
						if (num5 != 4)
						{
							stbi__skip(s, num5);
							break;
						}
						g.eflags = stbi__get8(s);
						g.delay = 10 * stbi__get16le(s);
						if (g.transparent >= 0)
						{
							g.pal[g.transparent][3] = byte.MaxValue;
						}
						if ((g.eflags & 1) != 0)
						{
							g.transparent = stbi__get8(s);
							if (g.transparent >= 0)
							{
								g.pal[g.transparent][3] = 0;
							}
						}
						else
						{
							stbi__skip(s, 1);
							g.transparent = -1;
						}
					}
					while ((num5 = stbi__get8(s)) != 0)
					{
						stbi__skip(s, num5);
					}
					break;
				}
				case 59:
					return null;
				default:
					return (byte*)(int)((stbi__err("unknown code") != 0) ? 0u : 0u);
				}
			}
		}

		public unsafe static void* stbi__load_gif_main_outofmem(stbi__gif g, byte* _out_, int** delays)
		{
			CRuntime.free(g._out_);
			CRuntime.free(g.history);
			CRuntime.free(g.background);
			if (_out_ != null)
			{
				CRuntime.free(_out_);
			}
			if (delays != null && *delays != null)
			{
				CRuntime.free(*delays);
			}
			return (void*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
		}

		public static int stbi__hdr_test(stbi__context s)
		{
			int num = stbi__hdr_test_core(s, "#?RADIANCE\n");
			stbi__rewind(s);
			if (num == 0)
			{
				num = stbi__hdr_test_core(s, "#?RGBE\n");
				stbi__rewind(s);
			}
			return num;
		}

		public unsafe static float* stbi__hdr_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri)
		{
			sbyte* buffer = stackalloc sbyte[1024];
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			byte b = 0;
			byte b2 = 0;
			int i = 0;
			int j = 0;
			int num5 = 0;
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			sbyte* src = stbi__hdr_gettoken(s, buffer);
			if (CRuntime.strcmp(src, "#?RADIANCE") != 0 && CRuntime.strcmp(src, "#?RGBE") != 0)
			{
				return (float*)(int)((stbi__err("not HDR") != 0) ? 0u : 0u);
			}
			sbyte* ptr;
			while (true)
			{
				ptr = stbi__hdr_gettoken(s, buffer);
				if (*ptr == 0)
				{
					break;
				}
				if (CRuntime.strcmp(ptr, "FORMAT=32-bit_rle_rgbe") == 0)
				{
					num = 1;
				}
			}
			if (num == 0)
			{
				return (float*)(int)((stbi__err("unsupported format") != 0) ? 0u : 0u);
			}
			ptr = stbi__hdr_gettoken(s, buffer);
			if (CRuntime.strncmp(ptr, "-Y ", 3uL) != 0)
			{
				return (float*)(int)((stbi__err("unsupported data layout") != 0) ? 0u : 0u);
			}
			ptr += 3;
			num3 = (int)CRuntime.strtol(ptr, &ptr, 10);
			for (; *ptr == 32; ptr++)
			{
			}
			if (CRuntime.strncmp(ptr, "+X ", 3uL) != 0)
			{
				return (float*)(int)((stbi__err("unsupported data layout") != 0) ? 0u : 0u);
			}
			ptr += 3;
			num2 = (int)CRuntime.strtol(ptr, null, 10);
			if (num3 > 16777216)
			{
				return (float*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
			}
			if (num2 > 16777216)
			{
				return (float*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
			}
			*x = num2;
			*y = num3;
			if (comp != null)
			{
				*comp = 3;
			}
			if (req_comp == 0)
			{
				req_comp = 3;
			}
			if (stbi__mad4sizes_valid(num2, num3, req_comp, 4, 0) == 0)
			{
				return (float*)(int)((stbi__err("too large") != 0) ? 0u : 0u);
			}
			float* ptr2 = (float*)stbi__malloc_mad4(num2, num3, req_comp, 4, 0);
			if (ptr2 == null)
			{
				return (float*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			while (true)
			{
				if (false)
				{
					for (; j < num3; j++)
					{
						for (; i < num2; i++)
						{
							byte* ptr3 = stackalloc byte[4];
							stbi__getn(s, ptr3, 4);
							stbi__hdr_convert(ptr2 + j * num2 * req_comp + i * req_comp, ptr3, req_comp);
						}
					}
					break;
				}
				if (num2 < 8 || num2 >= 32768)
				{
					i = (j = 0);
					continue;
				}
				byte* ptr4 = null;
				j = 0;
				while (j < num3)
				{
					num6 = stbi__get8(s);
					num7 = stbi__get8(s);
					num4 = stbi__get8(s);
					if (num6 == 2 && num7 == 2 && (num4 & 0x80) == 0)
					{
						num4 <<= 8;
						num4 |= stbi__get8(s);
						if (num4 != num2)
						{
							CRuntime.free(ptr2);
							CRuntime.free(ptr4);
							return (float*)(int)((stbi__err("invalid decoded scanline length") != 0) ? 0u : 0u);
						}
						if (ptr4 == null)
						{
							ptr4 = (byte*)stbi__malloc_mad2(num2, 4, 0);
							if (ptr4 == null)
							{
								CRuntime.free(ptr2);
								return (float*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
							}
						}
						for (num5 = 0; num5 < 4; num5++)
						{
							int num9 = 0;
							i = 0;
							while ((num9 = num2 - i) > 0)
							{
								b = stbi__get8(s);
								if (b > 128)
								{
									b2 = stbi__get8(s);
									b -= 128;
									if (b > num9)
									{
										CRuntime.free(ptr2);
										CRuntime.free(ptr4);
										return (float*)(int)((stbi__err("corrupt") != 0) ? 0u : 0u);
									}
									for (num8 = 0; num8 < b; num8++)
									{
										ptr4[i++ * 4 + num5] = b2;
									}
								}
								else
								{
									if (b > num9)
									{
										CRuntime.free(ptr2);
										CRuntime.free(ptr4);
										return (float*)(int)((stbi__err("corrupt") != 0) ? 0u : 0u);
									}
									for (num8 = 0; num8 < b; num8++)
									{
										ptr4[i++ * 4 + num5] = stbi__get8(s);
									}
								}
							}
						}
						for (i = 0; i < num2; i++)
						{
							stbi__hdr_convert(ptr2 + (j * num2 + i) * req_comp, ptr4 + i * 4, req_comp);
						}
						j++;
						continue;
					}
					goto IL_0241;
				}
				if (ptr4 != null)
				{
					CRuntime.free(ptr4);
				}
				break;
				IL_0241:
				byte* ptr5 = stackalloc byte[4];
				*ptr5 = (byte)num6;
				ptr5[1] = (byte)num7;
				ptr5[2] = (byte)num4;
				ptr5[3] = stbi__get8(s);
				stbi__hdr_convert(ptr2, ptr5, req_comp);
				i = 1;
				j = 0;
				CRuntime.free(ptr4);
			}
			return ptr2;
		}

		public unsafe static int stbi__hdr_info(stbi__context s, int* x, int* y, int* comp)
		{
			sbyte* buffer = stackalloc sbyte[1024];
			int num = 0;
			int num2 = 0;
			if (x == null)
			{
				x = &num2;
			}
			if (y == null)
			{
				y = &num2;
			}
			if (comp == null)
			{
				comp = &num2;
			}
			if (stbi__hdr_test(s) == 0)
			{
				stbi__rewind(s);
				return 0;
			}
			sbyte* ptr;
			while (true)
			{
				ptr = stbi__hdr_gettoken(s, buffer);
				if (*ptr == 0)
				{
					break;
				}
				if (CRuntime.strcmp(ptr, "FORMAT=32-bit_rle_rgbe") == 0)
				{
					num = 1;
				}
			}
			if (num == 0)
			{
				stbi__rewind(s);
				return 0;
			}
			ptr = stbi__hdr_gettoken(s, buffer);
			if (CRuntime.strncmp(ptr, "-Y ", 3uL) != 0)
			{
				stbi__rewind(s);
				return 0;
			}
			ptr += 3;
			*y = (int)CRuntime.strtol(ptr, &ptr, 10);
			for (; *ptr == 32; ptr++)
			{
			}
			if (CRuntime.strncmp(ptr, "+X ", 3uL) != 0)
			{
				stbi__rewind(s);
				return 0;
			}
			ptr += 3;
			*x = (int)CRuntime.strtol(ptr, null, 10);
			*comp = 3;
			return 1;
		}

		public unsafe static byte* stbi__hdr_to_ldr(float* data, int x, int y, int comp)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			if (data == null)
			{
				return null;
			}
			byte* ptr = (byte*)stbi__malloc_mad3(x, y, comp, 0);
			if (ptr == null)
			{
				CRuntime.free(data);
				return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			num3 = (((comp & 1) == 0) ? (comp - 1) : comp);
			for (num = 0; num < x * y; num++)
			{
				for (num2 = 0; num2 < num3; num2++)
				{
					float num4 = (float)CRuntime.pow(data[num * comp + num2] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255f + 0.5f;
					if (num4 < 0f)
					{
						num4 = 0f;
					}
					if (num4 > 255f)
					{
						num4 = 255f;
					}
					ptr[num * comp + num2] = (byte)(int)num4;
				}
				if (num2 < comp)
				{
					float num5 = data[num * comp + num2] * 255f + 0.5f;
					if (num5 < 0f)
					{
						num5 = 0f;
					}
					if (num5 > 255f)
					{
						num5 = 255f;
					}
					ptr[num * comp + num2] = (byte)(int)num5;
				}
			}
			CRuntime.free(data);
			return ptr;
		}

		public static int stbi__hdr_test_core(stbi__context s, string signature)
		{
			int num = 0;
			for (num = 0; num < signature.Length; num++)
			{
				if (stbi__get8(s) != signature[num])
				{
					return 0;
				}
			}
			stbi__rewind(s);
			return 1;
		}

		public unsafe static sbyte* stbi__hdr_gettoken(stbi__context z, sbyte* buffer)
		{
			int num = 0;
			sbyte b = 0;
			b = (sbyte)stbi__get8(z);
			while (stbi__at_eof(z) == 0 && b != 10)
			{
				buffer[num++] = b;
				if (num == 1023)
				{
					while (stbi__at_eof(z) == 0 && stbi__get8(z) != 10)
					{
					}
					break;
				}
				b = (sbyte)stbi__get8(z);
			}
			buffer[num] = 0;
			return buffer;
		}

		public unsafe static void stbi__hdr_convert(float* output, byte* input, int req_comp)
		{
			if (input[3] != 0)
			{
				float num = 0f;
				num = (float)CRuntime.ldexp(1.0, input[3] - 136);
				if (req_comp <= 2)
				{
					*output = (float)(*input + input[1] + input[2]) * num / 3f;
				}
				else
				{
					*output = (float)(int)(*input) * num;
					output[1] = (float)(int)input[1] * num;
					output[2] = (float)(int)input[2] * num;
				}
				if (req_comp == 2)
				{
					output[1] = 1f;
				}
				if (req_comp == 4)
				{
					output[3] = 1f;
				}
			}
			else if ((uint)(req_comp - 1) > 1u)
			{
				switch (req_comp)
				{
				case 4:
					output[3] = 1f;
					break;
				case 3:
					break;
				default:
					return;
				}
				*output = (output[1] = (output[2] = 0f));
			}
			else
			{
				if (req_comp == 2)
				{
					output[1] = 1f;
				}
				*output = 0f;
			}
		}

		public static int stbi__jpeg_test(stbi__context s)
		{
			stbi__jpeg stbi__jpeg = new stbi__jpeg();
			if (stbi__jpeg == null)
			{
				return stbi__err("outofmem");
			}
			stbi__jpeg.s = s;
			stbi__setup_jpeg(stbi__jpeg);
			int result = stbi__decode_jpeg_header(stbi__jpeg, 1);
			stbi__rewind(s);
			return result;
		}

		public unsafe static void* stbi__jpeg_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri)
		{
			stbi__jpeg stbi__jpeg = new stbi__jpeg();
			if (stbi__jpeg == null)
			{
				return (void*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u);
			}
			stbi__jpeg.s = s;
			stbi__setup_jpeg(stbi__jpeg);
			return load_jpeg_image(stbi__jpeg, x, y, comp, req_comp);
		}

		public unsafe static int stbi__jpeg_info(stbi__context s, int* x, int* y, int* comp)
		{
			stbi__jpeg stbi__jpeg = new stbi__jpeg();
			if (stbi__jpeg == null)
			{
				return stbi__err("outofmem");
			}
			stbi__jpeg.s = s;
			return stbi__jpeg_info_raw(stbi__jpeg, x, y, comp);
		}

		public unsafe static int stbi__build_huffman(stbi__huffman* h, int* count)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			uint num4 = 0u;
			for (num = 0; num < 16; num++)
			{
				for (num2 = 0; num2 < count[num]; num2++)
				{
					h->size[num3++] = (byte)(num + 1);
				}
			}
			h->size[num3] = 0;
			num4 = 0u;
			num3 = 0;
			for (num2 = 1; num2 <= 16; num2++)
			{
				h->delta[num2] = (int)(num3 - num4);
				if (h->size[num3] == num2)
				{
					while (h->size[num3] == num2)
					{
						h->code[num3++] = (ushort)num4++;
					}
					if (num4 - 1 >= (uint)(1 << num2))
					{
						return stbi__err("bad code lengths");
					}
				}
				h->maxcode[num2] = num4 << 16 - num2;
				num4 <<= 1;
			}
			h->maxcode[num2] = uint.MaxValue;
			CRuntime.memset(h->fast, 255, 512uL);
			for (num = 0; num < num3; num++)
			{
				int num5 = h->size[num];
				if (num5 <= 9)
				{
					int num6 = h->code[num] << 9 - num5;
					int num7 = 1 << 9 - num5;
					for (num2 = 0; num2 < num7; num2++)
					{
						h->fast[num6 + num2] = (byte)num;
					}
				}
			}
			return 1;
		}

		public unsafe static void stbi__build_fast_ac(short[] fast_ac, stbi__huffman* h)
		{
			int num = 0;
			for (num = 0; num < 512; num++)
			{
				byte b = h->fast[num];
				fast_ac[num] = 0;
				if (b >= byte.MaxValue)
				{
					continue;
				}
				byte num2 = h->values[(int)b];
				int num3 = (num2 >> 4) & 0xF;
				int num4 = num2 & 0xF;
				int num5 = h->size[(int)b];
				if (num4 != 0 && num5 + num4 <= 9)
				{
					int num6 = ((num << num5) & 0x1FF) >> 9 - num4;
					int num7 = 1 << num4 - 1;
					if (num6 < num7)
					{
						num6 += (-1 << num4) + 1;
					}
					if (num6 >= -128 && num6 <= 127)
					{
						fast_ac[num] = (short)(num6 * 256 + num3 * 16 + num5 + num4);
					}
				}
			}
		}

		public static void stbi__grow_buffer_unsafe(stbi__jpeg j)
		{
			do
			{
				uint num = (uint)((j.nomore == 0) ? stbi__get8(j.s) : 0);
				if (num == 255)
				{
					int num2 = stbi__get8(j.s);
					while (true)
					{
						switch (num2)
						{
						case 255:
							goto IL_002d;
						default:
							j.marker = (byte)num2;
							j.nomore = 1;
							return;
						case 0:
							break;
						}
						break;
						IL_002d:
						num2 = stbi__get8(j.s);
					}
				}
				j.code_buffer |= num << 24 - j.code_bits;
				j.code_bits += 8;
			}
			while (j.code_bits <= 24);
		}

		public unsafe static int stbi__jpeg_huff_decode(stbi__jpeg j, stbi__huffman* h)
		{
			uint num = 0u;
			int num2 = 0;
			int num3 = 0;
			if (j.code_bits < 16)
			{
				stbi__grow_buffer_unsafe(j);
			}
			num2 = (int)((j.code_buffer >> 23) & 0x1FF);
			num3 = h->fast[num2];
			if (num3 < 255)
			{
				int num4 = h->size[num3];
				if (num4 > j.code_bits)
				{
					return -1;
				}
				j.code_buffer <<= num4;
				j.code_bits -= num4;
				return h->values[num3];
			}
			num = j.code_buffer >> 16;
			for (num3 = 10; num >= h->maxcode[num3]; num3++)
			{
			}
			if (num3 == 17)
			{
				j.code_bits -= 16;
				return -1;
			}
			if (num3 > j.code_bits)
			{
				return -1;
			}
			num2 = (int)(((j.code_buffer >> 32 - num3) & stbi__bmask[num3]) + h->delta[num3]);
			j.code_bits -= num3;
			j.code_buffer <<= num3;
			return h->values[num2];
		}

		public static int stbi__extend_receive(stbi__jpeg j, int n)
		{
			uint num = 0u;
			int num2 = 0;
			if (j.code_bits < n)
			{
				stbi__grow_buffer_unsafe(j);
			}
			num2 = (int)(j.code_buffer >> 31);
			num = CRuntime._lrotl(j.code_buffer, n);
			j.code_buffer = num & ~stbi__bmask[n];
			num &= stbi__bmask[n];
			j.code_bits -= n;
			return (int)(num + (stbi__jbias[n] & (num2 - 1)));
		}

		public static int stbi__jpeg_get_bits(stbi__jpeg j, int n)
		{
			uint num = 0u;
			if (j.code_bits < n)
			{
				stbi__grow_buffer_unsafe(j);
			}
			num = CRuntime._lrotl(j.code_buffer, n);
			j.code_buffer = num & ~stbi__bmask[n];
			num &= stbi__bmask[n];
			j.code_bits -= n;
			return (int)num;
		}

		public static int stbi__jpeg_get_bit(stbi__jpeg j)
		{
			if (j.code_bits < 1)
			{
				stbi__grow_buffer_unsafe(j);
			}
			uint code_buffer = j.code_buffer;
			j.code_buffer <<= 1;
			j.code_bits--;
			return (int)code_buffer & int.MinValue;
		}

		public unsafe static int stbi__jpeg_decode_block(stbi__jpeg j, short* data, stbi__huffman* hdc, stbi__huffman* hac, short[] fac, int b, ushort[] dequant)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			if (j.code_bits < 16)
			{
				stbi__grow_buffer_unsafe(j);
			}
			num4 = stbi__jpeg_huff_decode(j, hdc);
			if (num4 < 0 || num4 > 15)
			{
				return stbi__err("bad huffman code");
			}
			CRuntime.memset(data, 0, 128uL);
			num = ((num4 != 0) ? stbi__extend_receive(j, num4) : 0);
			num2 = j.img_comp[b].dc_pred + num;
			j.img_comp[b].dc_pred = num2;
			*data = (short)(num2 * dequant[0]);
			num3 = 1;
			do
			{
				uint num5 = 0u;
				int num6 = 0;
				int num7 = 0;
				int num8 = 0;
				if (j.code_bits < 16)
				{
					stbi__grow_buffer_unsafe(j);
				}
				num6 = (int)((j.code_buffer >> 23) & 0x1FF);
				num7 = fac[num6];
				if (num7 != 0)
				{
					num3 += (num7 >> 4) & 0xF;
					num8 = num7 & 0xF;
					j.code_buffer <<= num8;
					j.code_bits -= num8;
					num5 = stbi__jpeg_dezigzag[num3++];
					data[num5] = (short)((num7 >> 8) * dequant[num5]);
					continue;
				}
				int num9 = stbi__jpeg_huff_decode(j, hac);
				if (num9 < 0)
				{
					return stbi__err("bad huffman code");
				}
				num8 = num9 & 0xF;
				num7 = num9 >> 4;
				if (num8 == 0)
				{
					if (num9 != 240)
					{
						break;
					}
					num3 += 16;
				}
				else
				{
					num3 += num7;
					num5 = stbi__jpeg_dezigzag[num3++];
					data[num5] = (short)(stbi__extend_receive(j, num8) * dequant[num5]);
				}
			}
			while (num3 < 64);
			return 1;
		}

		public unsafe static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg j, short* data, stbi__huffman* hdc, int b)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			if (j.spec_end != 0)
			{
				return stbi__err("can't merge dc and ac");
			}
			if (j.code_bits < 16)
			{
				stbi__grow_buffer_unsafe(j);
			}
			if (j.succ_high == 0)
			{
				CRuntime.memset(data, 0, 128uL);
				num3 = stbi__jpeg_huff_decode(j, hdc);
				int num4;
				switch (num3)
				{
				default:
					return stbi__err("can't merge dc and ac");
				case 0:
					num4 = 0;
					break;
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
				case 10:
				case 11:
				case 12:
				case 13:
				case 14:
				case 15:
					num4 = stbi__extend_receive(j, num3);
					break;
				}
				num = num4;
				num2 = j.img_comp[b].dc_pred + num;
				j.img_comp[b].dc_pred = num2;
				*data = (short)(num2 * (1 << j.succ_low));
			}
			else if (stbi__jpeg_get_bit(j) != 0)
			{
				*data += (short)(1 << j.succ_low);
			}
			return 1;
		}

		public unsafe static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg j, short* data, stbi__huffman* hac, short[] fac)
		{
			int num = 0;
			if (j.spec_start == 0)
			{
				return stbi__err("can't merge dc and ac");
			}
			if (j.succ_high == 0)
			{
				int succ_low = j.succ_low;
				if (j.eob_run != 0)
				{
					j.eob_run--;
					return 1;
				}
				num = j.spec_start;
				do
				{
					uint num2 = 0u;
					int num3 = 0;
					int num4 = 0;
					int num5 = 0;
					if (j.code_bits < 16)
					{
						stbi__grow_buffer_unsafe(j);
					}
					num3 = (int)((j.code_buffer >> 23) & 0x1FF);
					num4 = fac[num3];
					if (num4 != 0)
					{
						num += (num4 >> 4) & 0xF;
						num5 = num4 & 0xF;
						j.code_buffer <<= num5;
						j.code_bits -= num5;
						num2 = stbi__jpeg_dezigzag[num++];
						data[num2] = (short)((num4 >> 8) * (1 << succ_low));
						continue;
					}
					int num6 = stbi__jpeg_huff_decode(j, hac);
					if (num6 < 0)
					{
						return stbi__err("bad huffman code");
					}
					num5 = num6 & 0xF;
					num4 = num6 >> 4;
					if (num5 == 0)
					{
						if (num4 < 15)
						{
							j.eob_run = 1 << num4;
							if (num4 != 0)
							{
								j.eob_run += stbi__jpeg_get_bits(j, num4);
							}
							j.eob_run--;
							break;
						}
						num += 16;
					}
					else
					{
						num += num4;
						num2 = stbi__jpeg_dezigzag[num++];
						data[num2] = (short)(stbi__extend_receive(j, num5) * (1 << succ_low));
					}
				}
				while (num <= j.spec_end);
			}
			else
			{
				short num7 = (short)(1 << j.succ_low);
				if (j.eob_run != 0)
				{
					j.eob_run--;
					for (num = j.spec_start; num <= j.spec_end; num++)
					{
						short* ptr = data + (int)stbi__jpeg_dezigzag[num];
						if (*ptr != 0 && stbi__jpeg_get_bit(j) != 0 && (*ptr & num7) == 0)
						{
							if (*ptr > 0)
							{
								*ptr += num7;
							}
							else
							{
								*ptr -= num7;
							}
						}
					}
				}
				else
				{
					num = j.spec_start;
					do
					{
						int num8 = 0;
						int num9 = 0;
						int num10 = stbi__jpeg_huff_decode(j, hac);
						if (num10 < 0)
						{
							return stbi__err("bad huffman code");
						}
						num9 = num10 & 0xF;
						num8 = num10 >> 4;
						switch (num9)
						{
						case 0:
							if (num8 < 15)
							{
								j.eob_run = (1 << num8) - 1;
								if (num8 != 0)
								{
									j.eob_run += stbi__jpeg_get_bits(j, num8);
								}
								num8 = 64;
							}
							break;
						default:
							return stbi__err("bad huffman code");
						case 1:
							num9 = ((stbi__jpeg_get_bit(j) == 0) ? (-num7) : num7);
							break;
						}
						while (num <= j.spec_end)
						{
							short* ptr2 = data + (int)stbi__jpeg_dezigzag[num++];
							if (*ptr2 != 0)
							{
								if (stbi__jpeg_get_bit(j) != 0 && (*ptr2 & num7) == 0)
								{
									if (*ptr2 > 0)
									{
										*ptr2 += num7;
									}
									else
									{
										*ptr2 -= num7;
									}
								}
							}
							else
							{
								if (num8 == 0)
								{
									*ptr2 = (short)num9;
									break;
								}
								num8--;
							}
						}
					}
					while (num <= j.spec_end);
				}
			}
			return 1;
		}

		public unsafe static void stbi__idct_block(byte* _out_, int out_stride, short* data)
		{
			int num = 0;
			int* ptr = stackalloc int[64];
			int* ptr2 = ptr;
			short* ptr3 = data;
			num = 0;
			while (num < 8)
			{
				if (ptr3[8] == 0 && ptr3[16] == 0 && ptr3[24] == 0 && ptr3[32] == 0 && ptr3[40] == 0 && ptr3[48] == 0 && ptr3[56] == 0)
				{
					int num2 = *ptr3 * 4;
					*ptr2 = (ptr2[8] = (ptr2[16] = (ptr2[24] = (ptr2[32] = (ptr2[40] = (ptr2[48] = (ptr2[56] = num2)))))));
				}
				else
				{
					int num3 = 0;
					int num4 = 0;
					int num5 = 0;
					int num6 = 0;
					int num7 = 0;
					int num8 = 0;
					int num9 = 0;
					int num10 = 0;
					int num11 = 0;
					int num12 = 0;
					int num13 = 0;
					int num14 = 0;
					num8 = ptr3[16];
					num9 = ptr3[48];
					num7 = (num8 + num9) * 2217;
					num5 = num7 + num9 * -7567;
					num6 = num7 + num8 * 3135;
					num8 = *ptr3;
					num9 = ptr3[32];
					num3 = (num8 + num9) * 4096;
					num4 = (num8 - num9) * 4096;
					num11 = num3 + num6;
					num14 = num3 - num6;
					num12 = num4 + num5;
					num13 = num4 - num5;
					num3 = ptr3[56];
					num4 = ptr3[40];
					num5 = ptr3[24];
					num6 = ptr3[8];
					num9 = num3 + num5;
					num10 = num4 + num6;
					num7 = num3 + num6;
					num8 = num4 + num5;
					int num15 = (num9 + num10) * 4816;
					num3 *= 1223;
					num4 *= 8410;
					num5 *= 12586;
					num6 *= 6149;
					num7 = num15 + num7 * -3685;
					num8 = num15 + num8 * -10497;
					num9 *= -8034;
					num10 *= -1597;
					num6 += num7 + num10;
					num5 += num8 + num9;
					num4 += num8 + num10;
					num3 += num7 + num9;
					num11 += 512;
					num12 += 512;
					num13 += 512;
					num14 += 512;
					*ptr2 = num11 + num6 >> 10;
					ptr2[56] = num11 - num6 >> 10;
					ptr2[8] = num12 + num5 >> 10;
					ptr2[48] = num12 - num5 >> 10;
					ptr2[16] = num13 + num4 >> 10;
					ptr2[40] = num13 - num4 >> 10;
					ptr2[24] = num14 + num3 >> 10;
					ptr2[32] = num14 - num3 >> 10;
				}
				num++;
				ptr3++;
				ptr2++;
			}
			num = 0;
			ptr2 = ptr;
			byte* ptr4 = _out_;
			while (num < 8)
			{
				int num16 = 0;
				int num17 = 0;
				int num18 = 0;
				int num19 = 0;
				int num20 = 0;
				int num21 = 0;
				int num22 = 0;
				int num23 = 0;
				int num24 = 0;
				int num25 = 0;
				int num26 = 0;
				int num27 = 0;
				num21 = ptr2[2];
				num22 = ptr2[6];
				num20 = (num21 + num22) * 2217;
				num18 = num20 + num22 * -7567;
				num19 = num20 + num21 * 3135;
				num21 = *ptr2;
				num22 = ptr2[4];
				num16 = (num21 + num22) * 4096;
				num17 = (num21 - num22) * 4096;
				num24 = num16 + num19;
				num27 = num16 - num19;
				num25 = num17 + num18;
				num26 = num17 - num18;
				num16 = ptr2[7];
				num17 = ptr2[5];
				num18 = ptr2[3];
				num19 = ptr2[1];
				num22 = num16 + num18;
				num23 = num17 + num19;
				num20 = num16 + num19;
				num21 = num17 + num18;
				int num28 = (num22 + num23) * 4816;
				num16 *= 1223;
				num17 *= 8410;
				num18 *= 12586;
				num19 *= 6149;
				num20 = num28 + num20 * -3685;
				num21 = num28 + num21 * -10497;
				num22 *= -8034;
				num23 *= -1597;
				num19 += num20 + num23;
				num18 += num21 + num22;
				num17 += num21 + num23;
				num16 += num20 + num22;
				num24 += 16842752;
				num25 += 16842752;
				num26 += 16842752;
				num27 += 16842752;
				*ptr4 = stbi__clamp(num24 + num19 >> 17);
				ptr4[7] = stbi__clamp(num24 - num19 >> 17);
				ptr4[1] = stbi__clamp(num25 + num18 >> 17);
				ptr4[6] = stbi__clamp(num25 - num18 >> 17);
				ptr4[2] = stbi__clamp(num26 + num17 >> 17);
				ptr4[5] = stbi__clamp(num26 - num17 >> 17);
				ptr4[3] = stbi__clamp(num27 + num16 >> 17);
				ptr4[4] = stbi__clamp(num27 - num16 >> 17);
				num++;
				ptr2 += 8;
				ptr4 += out_stride;
			}
		}

		public static byte stbi__get_marker(stbi__jpeg j)
		{
			byte b = 0;
			if (j.marker != byte.MaxValue)
			{
				b = j.marker;
				j.marker = byte.MaxValue;
				return b;
			}
			b = stbi__get8(j.s);
			if (b != byte.MaxValue)
			{
				return byte.MaxValue;
			}
			while (b == byte.MaxValue)
			{
				b = stbi__get8(j.s);
			}
			return b;
		}

		public static void stbi__jpeg_reset(stbi__jpeg j)
		{
			j.code_bits = 0;
			j.code_buffer = 0u;
			j.nomore = 0;
			j.img_comp[0].dc_pred = (j.img_comp[1].dc_pred = (j.img_comp[2].dc_pred = (j.img_comp[3].dc_pred = 0)));
			j.marker = byte.MaxValue;
			j.todo = ((j.restart_interval != 0) ? j.restart_interval : int.MaxValue);
			j.eob_run = 0;
		}

		public unsafe static int stbi__parse_entropy_coded_data(stbi__jpeg z)
		{
			stbi__jpeg_reset(z);
			if (z.progressive == 0)
			{
				if (z.scan_n == 1)
				{
					int num = 0;
					int num2 = 0;
					short* ptr = stackalloc short[64];
					int num3 = z.order[0];
					int num4 = z.img_comp[num3].x + 7 >> 3;
					int num5 = z.img_comp[num3].y + 7 >> 3;
					for (num2 = 0; num2 < num5; num2++)
					{
						for (num = 0; num < num4; num++)
						{
							int ha = z.img_comp[num3].ha;
							fixed (stbi__huffman* hdc = &z.huff_dc[z.img_comp[num3].hd])
							{
								fixed (stbi__huffman* hac = &z.huff_ac[ha])
								{
									if (stbi__jpeg_decode_block(z, ptr, hdc, hac, z.fast_ac[ha], num3, z.dequant[z.img_comp[num3].tq]) == 0)
									{
										return 0;
									}
								}
							}
							z.idct_block_kernel(z.img_comp[num3].data + z.img_comp[num3].w2 * num2 * 8 + num * 8, z.img_comp[num3].w2, ptr);
							if (--z.todo <= 0)
							{
								if (z.code_bits < 24)
								{
									stbi__grow_buffer_unsafe(z);
								}
								if (z.marker < 208 || z.marker > 215)
								{
									return 1;
								}
								stbi__jpeg_reset(z);
							}
						}
					}
					return 1;
				}
				int num6 = 0;
				int num7 = 0;
				int num8 = 0;
				int num9 = 0;
				int num10 = 0;
				short* ptr2 = stackalloc short[64];
				for (num7 = 0; num7 < z.img_mcu_y; num7++)
				{
					for (num6 = 0; num6 < z.img_mcu_x; num6++)
					{
						for (num8 = 0; num8 < z.scan_n; num8++)
						{
							int num11 = z.order[num8];
							for (num10 = 0; num10 < z.img_comp[num11].v; num10++)
							{
								for (num9 = 0; num9 < z.img_comp[num11].h; num9++)
								{
									int num12 = (num6 * z.img_comp[num11].h + num9) * 8;
									int num13 = (num7 * z.img_comp[num11].v + num10) * 8;
									int ha2 = z.img_comp[num11].ha;
									fixed (stbi__huffman* hdc2 = &z.huff_dc[z.img_comp[num11].hd])
									{
										fixed (stbi__huffman* hac2 = &z.huff_ac[ha2])
										{
											if (stbi__jpeg_decode_block(z, ptr2, hdc2, hac2, z.fast_ac[ha2], num11, z.dequant[z.img_comp[num11].tq]) == 0)
											{
												return 0;
											}
										}
									}
									z.idct_block_kernel(z.img_comp[num11].data + z.img_comp[num11].w2 * num13 + num12, z.img_comp[num11].w2, ptr2);
								}
							}
						}
						if (--z.todo <= 0)
						{
							if (z.code_bits < 24)
							{
								stbi__grow_buffer_unsafe(z);
							}
							if (z.marker < 208 || z.marker > 215)
							{
								return 1;
							}
							stbi__jpeg_reset(z);
						}
					}
				}
				return 1;
			}
			if (z.scan_n == 1)
			{
				int num14 = 0;
				int num15 = 0;
				int num16 = z.order[0];
				int num17 = z.img_comp[num16].x + 7 >> 3;
				int num18 = z.img_comp[num16].y + 7 >> 3;
				for (num15 = 0; num15 < num18; num15++)
				{
					for (num14 = 0; num14 < num17; num14++)
					{
						short* data = z.img_comp[num16].coeff + 64 * (num14 + num15 * z.img_comp[num16].coeff_w);
						if (z.spec_start == 0)
						{
							fixed (stbi__huffman* hdc3 = &z.huff_dc[z.img_comp[num16].hd])
							{
								if (stbi__jpeg_decode_block_prog_dc(z, data, hdc3, num16) == 0)
								{
									return 0;
								}
							}
						}
						else
						{
							int ha3 = z.img_comp[num16].ha;
							fixed (stbi__huffman* hac3 = &z.huff_ac[ha3])
							{
								if (stbi__jpeg_decode_block_prog_ac(z, data, hac3, z.fast_ac[ha3]) == 0)
								{
									return 0;
								}
							}
						}
						if (--z.todo <= 0)
						{
							if (z.code_bits < 24)
							{
								stbi__grow_buffer_unsafe(z);
							}
							if (z.marker < 208 || z.marker > 215)
							{
								return 1;
							}
							stbi__jpeg_reset(z);
						}
					}
				}
				return 1;
			}
			int num19 = 0;
			int num20 = 0;
			int num21 = 0;
			int num22 = 0;
			int num23 = 0;
			for (num20 = 0; num20 < z.img_mcu_y; num20++)
			{
				for (num19 = 0; num19 < z.img_mcu_x; num19++)
				{
					for (num21 = 0; num21 < z.scan_n; num21++)
					{
						int num24 = z.order[num21];
						for (num23 = 0; num23 < z.img_comp[num24].v; num23++)
						{
							for (num22 = 0; num22 < z.img_comp[num24].h; num22++)
							{
								int num25 = num19 * z.img_comp[num24].h + num22;
								int num26 = num20 * z.img_comp[num24].v + num23;
								short* data2 = z.img_comp[num24].coeff + 64 * (num25 + num26 * z.img_comp[num24].coeff_w);
								fixed (stbi__huffman* hdc4 = &z.huff_dc[z.img_comp[num24].hd])
								{
									if (stbi__jpeg_decode_block_prog_dc(z, data2, hdc4, num24) == 0)
									{
										return 0;
									}
								}
							}
						}
					}
					if (--z.todo <= 0)
					{
						if (z.code_bits < 24)
						{
							stbi__grow_buffer_unsafe(z);
						}
						if (z.marker < 208 || z.marker > 215)
						{
							return 1;
						}
						stbi__jpeg_reset(z);
					}
				}
			}
			return 1;
		}

		public unsafe static void stbi__jpeg_dequantize(short* data, ushort[] dequant)
		{
			int num = 0;
			for (num = 0; num < 64; num++)
			{
				data[num] *= (short)dequant[num];
			}
		}

		public unsafe static void stbi__jpeg_finish(stbi__jpeg z)
		{
			if (z.progressive == 0)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			for (num3 = 0; num3 < z.s.img_n; num3++)
			{
				int num4 = z.img_comp[num3].x + 7 >> 3;
				int num5 = z.img_comp[num3].y + 7 >> 3;
				for (num2 = 0; num2 < num5; num2++)
				{
					for (num = 0; num < num4; num++)
					{
						short* ptr = z.img_comp[num3].coeff + 64 * (num + num2 * z.img_comp[num3].coeff_w);
						stbi__jpeg_dequantize(ptr, z.dequant[z.img_comp[num3].tq]);
						z.idct_block_kernel(z.img_comp[num3].data + z.img_comp[num3].w2 * num2 * 8 + num * 8, z.img_comp[num3].w2, ptr);
					}
				}
			}
		}

		public unsafe static int stbi__process_marker(stbi__jpeg z, int m)
		{
			int num = 0;
			switch (m)
			{
			case 255:
				return stbi__err("expected marker");
			case 221:
				if (stbi__get16be(z.s) != 4)
				{
					return stbi__err("bad DRI len");
				}
				z.restart_interval = stbi__get16be(z.s);
				return 1;
			case 219:
				num = stbi__get16be(z.s) - 2;
				while (num > 0)
				{
					byte num6 = stbi__get8(z.s);
					int num7 = num6 >> 4;
					int num8 = ((num7 != 0) ? 1 : 0);
					int num9 = num6 & 0xF;
					int num10 = 0;
					if (num7 != 0 && num7 != 1)
					{
						return stbi__err("bad DQT type");
					}
					if (num9 > 3)
					{
						return stbi__err("bad DQT table");
					}
					for (num10 = 0; num10 < 64; num10++)
					{
						z.dequant[num9][stbi__jpeg_dezigzag[num10]] = (ushort)((num8 != 0) ? stbi__get16be(z.s) : stbi__get8(z.s));
					}
					num -= ((num8 != 0) ? 129 : 65);
				}
				if (num != 0)
				{
					return 0;
				}
				return 1;
			case 196:
				num = stbi__get16be(z.s) - 2;
				while (num > 0)
				{
					int* ptr = stackalloc int[16];
					int num11 = 0;
					int num12 = 0;
					byte num13 = stbi__get8(z.s);
					int num14 = num13 >> 4;
					int num15 = num13 & 0xF;
					if (num14 > 1 || num15 > 3)
					{
						return stbi__err("bad DHT header");
					}
					for (num11 = 0; num11 < 16; num11++)
					{
						ptr[num11] = stbi__get8(z.s);
						num12 += ptr[num11];
					}
					num -= 17;
					if (num14 == 0)
					{
						fixed (stbi__huffman* ptr2 = &z.huff_dc[num15])
						{
							if (stbi__build_huffman(ptr2, ptr) == 0)
							{
								return 0;
							}
							byte* ptr3 = ptr2->values;
							for (num11 = 0; num11 < num12; num11++)
							{
								ptr3[num11] = stbi__get8(z.s);
							}
						}
					}
					else
					{
						fixed (stbi__huffman* ptr4 = &z.huff_ac[num15])
						{
							if (stbi__build_huffman(ptr4, ptr) == 0)
							{
								return 0;
							}
							byte* ptr5 = ptr4->values;
							for (num11 = 0; num11 < num12; num11++)
							{
								ptr5[num11] = stbi__get8(z.s);
							}
						}
					}
					if (num14 != 0)
					{
						fixed (stbi__huffman* h = &z.huff_ac[num15])
						{
							stbi__build_fast_ac(z.fast_ac[num15], h);
						}
					}
					num -= num12;
				}
				if (num != 0)
				{
					return 0;
				}
				return 1;
			default:
				if ((m >= 224 && m <= 239) || m == 254)
				{
					num = stbi__get16be(z.s);
					if (num < 2)
					{
						if (m == 254)
						{
							return stbi__err("bad COM len");
						}
						return stbi__err("bad APP len");
					}
					num -= 2;
					if (m == 224 && num >= 5)
					{
						int num2 = 1;
						int num3 = 0;
						for (num3 = 0; num3 < 5; num3++)
						{
							if (stbi__get8(z.s) != stbi__process_marker_tag[num3])
							{
								num2 = 0;
							}
						}
						num -= 5;
						if (num2 != 0)
						{
							z.jfif = 1;
						}
					}
					else if (m == 238 && num >= 12)
					{
						int num4 = 1;
						int num5 = 0;
						for (num5 = 0; num5 < 6; num5++)
						{
							if (stbi__get8(z.s) != stbi__process_marker_tag[num5])
							{
								num4 = 0;
							}
						}
						num -= 6;
						if (num4 != 0)
						{
							stbi__get8(z.s);
							stbi__get16be(z.s);
							stbi__get16be(z.s);
							z.app14_color_transform = stbi__get8(z.s);
							num -= 6;
						}
					}
					stbi__skip(z.s, num);
					return 1;
				}
				return stbi__err("unknown marker");
			}
		}

		public static int stbi__process_scan_header(stbi__jpeg z)
		{
			int num = 0;
			int num2 = stbi__get16be(z.s);
			z.scan_n = stbi__get8(z.s);
			if (z.scan_n < 1 || z.scan_n > 4 || z.scan_n > z.s.img_n)
			{
				return stbi__err("bad SOS component count");
			}
			if (num2 != 6 + 2 * z.scan_n)
			{
				return stbi__err("bad SOS len");
			}
			for (num = 0; num < z.scan_n; num++)
			{
				int num3 = stbi__get8(z.s);
				int num4 = 0;
				int num5 = stbi__get8(z.s);
				for (num4 = 0; num4 < z.s.img_n && z.img_comp[num4].id != num3; num4++)
				{
				}
				if (num4 == z.s.img_n)
				{
					return 0;
				}
				z.img_comp[num4].hd = num5 >> 4;
				if (z.img_comp[num4].hd > 3)
				{
					return stbi__err("bad DC huff");
				}
				z.img_comp[num4].ha = num5 & 0xF;
				if (z.img_comp[num4].ha > 3)
				{
					return stbi__err("bad AC huff");
				}
				z.order[num] = num4;
			}
			int num6 = 0;
			z.spec_start = stbi__get8(z.s);
			z.spec_end = stbi__get8(z.s);
			num6 = stbi__get8(z.s);
			z.succ_high = num6 >> 4;
			z.succ_low = num6 & 0xF;
			if (z.progressive != 0)
			{
				if (z.spec_start > 63 || z.spec_end > 63 || z.spec_start > z.spec_end || z.succ_high > 13 || z.succ_low > 13)
				{
					return stbi__err("bad SOS");
				}
			}
			else
			{
				if (z.spec_start != 0)
				{
					return stbi__err("bad SOS");
				}
				if (z.succ_high != 0 || z.succ_low != 0)
				{
					return stbi__err("bad SOS");
				}
				z.spec_end = 63;
			}
			return 1;
		}

		public unsafe static int stbi__free_jpeg_components(stbi__jpeg z,