Decompiled source of Controller Support v2.0.1

BepInEx/plugins/SharpDX.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using SharpDX;
using SharpDX.Collections;
using SharpDX.Diagnostics;
using SharpDX.Direct3D;
using SharpDX.Mathematics.Interop;

[assembly: InternalsVisibleTo("SharpDX.DirectSound,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.RawInput,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.DirectInput,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Direct2D1,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Direct3D11.Effects,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Direct3D12,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.XAPO,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Direct3D11,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Direct3D9,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Desktop,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.D3DCompiler,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.DXGI,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.Animation,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("SharpDX.Direct3D10,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: InternalsVisibleTo("SharpDX.XAudio2,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.WIC,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: AssemblyTitle("SharpDX")]
[assembly: AssemblyProduct("SharpDX")]
[assembly: AssemblyInformationalVersion("4.2.0+8e5df9f17b1d328c595a9df5851dbb2537b55621")]
[assembly: AssemblyFileVersion("4.2.0")]
[assembly: AssemblyDescription("Core assembly for all SharpDX assemblies.")]
[assembly: InternalsVisibleTo("SharpDX.XACT3,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: AssemblyCopyright("Copyright (c) 2010-2016 Alexandre Mutel")]
[assembly: AssemblyCompany("Alexandre Mutel")]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("SharpDX.DirectManipulation,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.DirectComposition,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: InternalsVisibleTo("SharpDX.MediaFoundation,PublicKey=00240000048000009400000006020000002400005253413100040000010001004543d77b41222cfd48f4e0d8dd9b2f83dc15fbede312a422a7454a0b723e988718ebba619773fc8dfed2bc69c97aec4063f51dc5821f5eaa72f331b2782755754dfd998ade0dcbf92a734e532870f661cbe4388f544befa2f32a8e4568e0be071a90fa546c8b4e6efcea755703ae03f6479e787632688be8f6aaae808f6f43ba")]
[assembly: AssemblyConfiguration("Release")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.2.0.0")]
[module: UnverifiableCode]
internal class <Module>
{
	static <Module>()
	{
		Interop.ModuleInit();
		ModuleInit.Setup();
	}
}
namespace SharpDX
{
	[CompilerGenerated]
	internal class AssemblyDoc
	{
	}
	public abstract class CallbackBase : DisposeBase, ICallbackable, IDisposable
	{
		private int refCount = 1;

		IDisposable ICallbackable.Shadow { get; set; }

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				Release();
			}
		}

		public int AddReference()
		{
			int num = refCount;
			while (true)
			{
				if (num == 0)
				{
					throw new ObjectDisposedException("Cannot add a reference to a nonreferenced item");
				}
				int num2 = Interlocked.CompareExchange(ref refCount, num + 1, num);
				if (num2 == num)
				{
					break;
				}
				num = num2;
			}
			return num + 1;
		}

		public int Release()
		{
			int num = refCount;
			while (true)
			{
				int num2 = Interlocked.CompareExchange(ref refCount, num - 1, num);
				if (num2 == num)
				{
					break;
				}
				num = num2;
			}
			if (num == 1)
			{
				((ICallbackable)this).Shadow.Dispose();
				((ICallbackable)this).Shadow = null;
			}
			return num - 1;
		}

		public Result QueryInterface(ref Guid guid, out IntPtr comObject)
		{
			ShadowContainer shadowContainer = (ShadowContainer)((ICallbackable)this).Shadow;
			comObject = shadowContainer.Find(guid);
			if (comObject == IntPtr.Zero)
			{
				return Result.NoInterface;
			}
			return Result.Ok;
		}
	}
	public class ComArray : DisposeBase, IEnumerable
	{
		protected ComObject[] values;

		private IntPtr nativeBuffer;

		public IntPtr NativePointer => nativeBuffer;

		public int Length
		{
			get
			{
				if (values != null)
				{
					return values.Length;
				}
				return 0;
			}
		}

		public ComArray(params ComObject[] array)
		{
			values = array;
			nativeBuffer = IntPtr.Zero;
			if (values != null)
			{
				int num = array.Length;
				values = new ComObject[num];
				nativeBuffer = Utilities.AllocateMemory(num * Utilities.SizeOf<IntPtr>());
				for (int i = 0; i < num; i++)
				{
					Set(i, array[i]);
				}
			}
		}

		public ComArray(int size)
		{
			values = new ComObject[size];
			nativeBuffer = Utilities.AllocateMemory(size * Utilities.SizeOf<IntPtr>());
		}

		public ComObject Get(int index)
		{
			return values[index];
		}

		internal unsafe void SetFromNative(int index, ComObject value)
		{
			values[index] = value;
			value.NativePointer = *(IntPtr*)((byte*)(void*)nativeBuffer + (nint)index * (nint)sizeof(IntPtr));
		}

		public unsafe void Set(int index, ComObject value)
		{
			values[index] = value;
			*(IntPtr*)((byte*)(void*)nativeBuffer + (nint)index * (nint)sizeof(IntPtr)) = value.NativePointer;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				values = null;
			}
			Utilities.FreeMemory(nativeBuffer);
			nativeBuffer = IntPtr.Zero;
		}

		public IEnumerator GetEnumerator()
		{
			return values.GetEnumerator();
		}
	}
	public class ComArray<T> : ComArray, IEnumerable<T>, IEnumerable where T : ComObject
	{
		private struct ArrayEnumerator<T1> : IEnumerator<T1>, IDisposable, IEnumerator where T1 : ComObject
		{
			private readonly IEnumerator enumerator;

			public T1 Current => (T1)enumerator.Current;

			object IEnumerator.Current => Current;

			public ArrayEnumerator(IEnumerator enumerator)
			{
				this.enumerator = enumerator;
			}

			public void Dispose()
			{
			}

			public bool MoveNext()
			{
				return enumerator.MoveNext();
			}

			public void Reset()
			{
				enumerator.Reset();
			}
		}

		public T this[int i]
		{
			get
			{
				return (T)Get(i);
			}
			set
			{
				Set(i, value);
			}
		}

		public ComArray(params T[] array)
			: base(array)
		{
		}

		public ComArray(int size)
			: base(size)
		{
		}

		public new IEnumerator<T> GetEnumerator()
		{
			return new ArrayEnumerator<T>(values.GetEnumerator());
		}
	}
	[Guid("00000000-0000-0000-C000-000000000046")]
	public class ComObject : CppObject, IUnknown, ICallbackable, IDisposable
	{
		public static Action<string> LogMemoryLeakWarning = delegate
		{
		};

		public ComObject(object iunknowObject)
		{
			base.NativePointer = Marshal.GetIUnknownForObject(iunknowObject);
		}

		protected ComObject()
		{
		}

		public virtual void QueryInterface(Guid guid, out IntPtr outPtr)
		{
			((IUnknown)this).QueryInterface(ref guid, out outPtr).CheckError();
		}

		public virtual IntPtr QueryInterfaceOrNull(Guid guid)
		{
			IntPtr comObject = IntPtr.Zero;
			((IUnknown)this).QueryInterface(ref guid, out comObject);
			return comObject;
		}

		public static bool EqualsComObject<T>(T left, T right) where T : ComObject
		{
			if (object.Equals(left, right))
			{
				return true;
			}
			if (left == null || right == null)
			{
				return false;
			}
			return left.NativePointer == right.NativePointer;
		}

		public virtual T QueryInterface<T>() where T : ComObject
		{
			QueryInterface(Utilities.GetGuidFromType(typeof(T)), out var outPtr);
			return CppObject.FromPointer<T>(outPtr);
		}

		internal virtual T QueryInterfaceUnsafe<T>()
		{
			QueryInterface(Utilities.GetGuidFromType(typeof(T)), out var outPtr);
			return CppObject.FromPointerUnsafe<T>(outPtr);
		}

		public static T As<T>(object comObject) where T : ComObject
		{
			using ComObject comObject2 = new ComObject(Marshal.GetIUnknownForObject(comObject));
			return comObject2.QueryInterface<T>();
		}

		public static T As<T>(IntPtr iunknownPtr) where T : ComObject
		{
			using ComObject comObject = new ComObject(iunknownPtr);
			return comObject.QueryInterface<T>();
		}

		internal static T AsUnsafe<T>(IntPtr iunknownPtr)
		{
			using ComObject comObject = new ComObject(iunknownPtr);
			return comObject.QueryInterfaceUnsafe<T>();
		}

		public static T QueryInterface<T>(object comObject) where T : ComObject
		{
			using ComObject comObject2 = new ComObject(Marshal.GetIUnknownForObject(comObject));
			return comObject2.QueryInterface<T>();
		}

		public static T QueryInterfaceOrNull<T>(IntPtr comPointer) where T : ComObject
		{
			if (comPointer == IntPtr.Zero)
			{
				return null;
			}
			Guid iid = Utilities.GetGuidFromType(typeof(T));
			if (!((Result)Marshal.QueryInterface(comPointer, ref iid, out var ppv)).Failure)
			{
				return CppObject.FromPointerUnsafe<T>(ppv);
			}
			return null;
		}

		public virtual T QueryInterfaceOrNull<T>() where T : ComObject
		{
			return CppObject.FromPointer<T>(QueryInterfaceOrNull(Utilities.GetGuidFromType(typeof(T))));
		}

		protected void QueryInterfaceFrom<T>(T fromObject) where T : ComObject
		{
			fromObject.QueryInterface(Utilities.GetGuidFromType(GetType()), out var outPtr);
			base.NativePointer = outPtr;
		}

		Result IUnknown.QueryInterface(ref Guid guid, out IntPtr comObject)
		{
			return Marshal.QueryInterface(base.NativePointer, ref guid, out comObject);
		}

		int IUnknown.AddReference()
		{
			if (base.NativePointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("COM Object pointer is null");
			}
			return Marshal.AddRef(base.NativePointer);
		}

		int IUnknown.Release()
		{
			if (base.NativePointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("COM Object pointer is null");
			}
			return Marshal.Release(base.NativePointer);
		}

		protected unsafe override void Dispose(bool disposing)
		{
			if (base.NativePointer != IntPtr.Zero)
			{
				if (!disposing && Configuration.EnableTrackingReleaseOnFinalizer && !Configuration.EnableReleaseOnFinalizer)
				{
					ObjectReference arg = ObjectTracker.Find(this);
					LogMemoryLeakWarning?.Invoke($"Warning: Live ComObject [0x{base.NativePointer.ToInt64():X}], potential memory leak: {arg}");
				}
				if (disposing || Configuration.EnableReleaseOnFinalizer)
				{
					((IUnknown)this).Release();
				}
				if (Configuration.EnableObjectTracking)
				{
					ObjectTracker.UnTrack(this);
				}
				_nativePointer = null;
			}
			base.Dispose(disposing);
		}

		protected override void NativePointerUpdating()
		{
			if (Configuration.EnableObjectTracking)
			{
				ObjectTracker.UnTrack(this);
			}
		}

		protected override void NativePointerUpdated(IntPtr oldNativePointer)
		{
			if (Configuration.EnableObjectTracking)
			{
				ObjectTracker.Track(this);
			}
		}

		public ComObject(IntPtr nativePtr)
			: base(nativePtr)
		{
		}

		public static explicit operator ComObject(IntPtr nativePtr)
		{
			if (!(nativePtr == IntPtr.Zero))
			{
				return new ComObject(nativePtr);
			}
			return null;
		}
	}
	internal abstract class ComObjectShadow : CppObjectShadow
	{
		internal class ComObjectVtbl : CppObjectVtbl
		{
			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			public delegate int QueryInterfaceDelegate(IntPtr thisObject, IntPtr guid, out IntPtr output);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			public delegate int AddRefDelegate(IntPtr thisObject);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			public delegate int ReleaseDelegate(IntPtr thisObject);

			public ComObjectVtbl(int numberOfCallbackMethods)
				: base(numberOfCallbackMethods + 3)
			{
				AddMethod(new QueryInterfaceDelegate(QueryInterfaceImpl));
				AddMethod(new AddRefDelegate(AddRefImpl));
				AddMethod(new ReleaseDelegate(ReleaseImpl));
			}

			protected unsafe static int QueryInterfaceImpl(IntPtr thisObject, IntPtr guid, out IntPtr output)
			{
				ComObjectShadow comObjectShadow = CppObjectShadow.ToShadow<ComObjectShadow>(thisObject);
				if (comObjectShadow == null)
				{
					output = IntPtr.Zero;
					return Result.NoInterface.Code;
				}
				return comObjectShadow.QueryInterfaceImpl(ref *(Guid*)(void*)guid, out output);
			}

			protected static int AddRefImpl(IntPtr thisObject)
			{
				return CppObjectShadow.ToShadow<ComObjectShadow>(thisObject)?.AddRefImpl() ?? 0;
			}

			protected static int ReleaseImpl(IntPtr thisObject)
			{
				return CppObjectShadow.ToShadow<ComObjectShadow>(thisObject)?.ReleaseImpl() ?? 0;
			}
		}

		public static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

		protected int QueryInterfaceImpl(ref Guid guid, out IntPtr output)
		{
			ComObjectShadow comObjectShadow = (ComObjectShadow)((ShadowContainer)base.Callback.Shadow).FindShadow(guid);
			if (comObjectShadow != null)
			{
				((IUnknown)base.Callback).AddReference();
				output = comObjectShadow.NativePointer;
				return Result.Ok.Code;
			}
			output = IntPtr.Zero;
			return Result.NoInterface.Code;
		}

		protected virtual int AddRefImpl()
		{
			return ((IUnknown)base.Callback).AddReference();
		}

		protected virtual int ReleaseImpl()
		{
			return ((IUnknown)base.Callback).Release();
		}
	}
	public static class Configuration
	{
		public static bool EnableObjectTracking = false;

		public static bool EnableReleaseOnFinalizer = false;

		public static bool EnableTrackingReleaseOnFinalizer = true;

		public static bool ThrowOnShaderCompileError = true;

		public static bool UseThreadStaticObjectTracking = false;
	}
	public class CppObject : DisposeBase, ICallbackable, IDisposable
	{
		protected internal unsafe void* _nativePointer;

		public object Tag { get; set; }

		public unsafe IntPtr NativePointer
		{
			get
			{
				return (IntPtr)_nativePointer;
			}
			set
			{
				void* ptr = (void*)value;
				if (_nativePointer != ptr)
				{
					NativePointerUpdating();
					void* nativePointer = _nativePointer;
					_nativePointer = ptr;
					NativePointerUpdated((IntPtr)nativePointer);
				}
			}
		}

		IDisposable ICallbackable.Shadow
		{
			get
			{
				throw new InvalidOperationException("Invalid access to Callback. This is used internally.");
			}
			set
			{
				throw new InvalidOperationException("Invalid access to Callback. This is used internally.");
			}
		}

		public CppObject(IntPtr pointer)
		{
			NativePointer = pointer;
		}

		protected CppObject()
		{
		}

		public static explicit operator IntPtr(CppObject cppObject)
		{
			return cppObject?.NativePointer ?? IntPtr.Zero;
		}

		protected void FromTemp(CppObject temp)
		{
			NativePointer = temp.NativePointer;
			temp.NativePointer = IntPtr.Zero;
		}

		protected void FromTemp(IntPtr temp)
		{
			NativePointer = temp;
		}

		protected virtual void NativePointerUpdating()
		{
		}

		protected virtual void NativePointerUpdated(IntPtr oldNativePointer)
		{
		}

		protected override void Dispose(bool disposing)
		{
		}

		public static T FromPointer<T>(IntPtr comObjectPtr) where T : CppObject
		{
			if (!(comObjectPtr == IntPtr.Zero))
			{
				return (T)Activator.CreateInstance(typeof(T), comObjectPtr);
			}
			return null;
		}

		internal static T FromPointerUnsafe<T>(IntPtr comObjectPtr)
		{
			if (!(comObjectPtr == IntPtr.Zero))
			{
				return (T)Activator.CreateInstance(typeof(T), comObjectPtr);
			}
			return (T)(object)null;
		}

		public static IntPtr ToCallbackPtr<TCallback>(ICallbackable callback) where TCallback : ICallbackable
		{
			if (callback == null)
			{
				return IntPtr.Zero;
			}
			if (callback is CppObject)
			{
				return ((CppObject)callback).NativePointer;
			}
			ShadowContainer shadowContainer = callback.Shadow as ShadowContainer;
			if (shadowContainer == null)
			{
				shadowContainer = new ShadowContainer();
				shadowContainer.Initialize(callback);
			}
			return shadowContainer.Find(typeof(TCallback));
		}
	}
	internal abstract class CppObjectShadow : CppObject
	{
		public ICallbackable Callback { get; private set; }

		protected abstract CppObjectVtbl GetVtbl { get; }

		public unsafe virtual void Initialize(ICallbackable callbackInstance)
		{
			Callback = callbackInstance;
			base.NativePointer = Marshal.AllocHGlobal(IntPtr.Size * 2);
			GCHandle value = GCHandle.Alloc(this);
			Marshal.WriteIntPtr(base.NativePointer, GetVtbl.Pointer);
			*(IntPtr*)((byte*)(void*)base.NativePointer + sizeof(IntPtr)) = GCHandle.ToIntPtr(value);
		}

		protected unsafe override void Dispose(bool disposing)
		{
			if (base.NativePointer != IntPtr.Zero)
			{
				GCHandle.FromIntPtr(*(IntPtr*)((byte*)(void*)base.NativePointer + sizeof(IntPtr))).Free();
				Marshal.FreeHGlobal(base.NativePointer);
				base.NativePointer = IntPtr.Zero;
			}
			Callback = null;
			base.Dispose(disposing);
		}

		internal unsafe static T ToShadow<T>(IntPtr thisPtr) where T : CppObjectShadow
		{
			return (T)GCHandle.FromIntPtr(*(IntPtr*)((byte*)(void*)thisPtr + sizeof(IntPtr))).Target;
		}
	}
	internal class CppObjectVtbl
	{
		private readonly List<Delegate> methods;

		private readonly IntPtr vtbl;

		public IntPtr Pointer => vtbl;

		public CppObjectVtbl(int numberOfCallbackMethods)
		{
			vtbl = Marshal.AllocHGlobal(IntPtr.Size * numberOfCallbackMethods);
			methods = new List<Delegate>();
		}

		public unsafe void AddMethod(Delegate method)
		{
			int count = methods.Count;
			methods.Add(method);
			*(IntPtr*)((byte*)(void*)vtbl + (nint)count * (nint)sizeof(IntPtr)) = Marshal.GetFunctionPointerForDelegate(method);
		}
	}
	public struct DataBox
	{
		public IntPtr DataPointer;

		public int RowPitch;

		public int SlicePitch;

		public bool IsEmpty
		{
			get
			{
				if (DataPointer == IntPtr.Zero && RowPitch == 0)
				{
					return SlicePitch == 0;
				}
				return false;
			}
		}

		public DataBox(IntPtr datapointer, int rowPitch, int slicePitch)
		{
			DataPointer = datapointer;
			RowPitch = rowPitch;
			SlicePitch = slicePitch;
		}

		public DataBox(IntPtr dataPointer)
		{
			DataPointer = dataPointer;
			RowPitch = 0;
			SlicePitch = 0;
		}
	}
	public class DataBuffer : DisposeBase
	{
		private unsafe sbyte* _buffer;

		private GCHandle _gCHandle;

		private readonly bool _ownsBuffer;

		private readonly int _size;

		private Blob _blob;

		public unsafe IntPtr DataPointer => new IntPtr(_buffer);

		public int Size => _size;

		public unsafe static DataBuffer Create<T>(T[] userBuffer, int index = 0, bool pinBuffer = true) where T : struct
		{
			if (userBuffer == null)
			{
				throw new ArgumentNullException("userBuffer");
			}
			if (index < 0 || index > userBuffer.Length)
			{
				throw new ArgumentException("Index is out of range [0, userBuffer.Length-1]", "index");
			}
			int num = Utilities.SizeOf(userBuffer);
			int num2 = index * Utilities.SizeOf<T>();
			if (pinBuffer)
			{
				GCHandle handle = GCHandle.Alloc(userBuffer, GCHandleType.Pinned);
				return new DataBuffer(num2 + (byte*)(void*)handle.AddrOfPinnedObject(), num - num2, handle);
			}
			fixed (T* ptr = &userBuffer[0])
			{
				return new DataBuffer(num2 + (byte*)(void*)(IntPtr)ptr, num - num2, makeCopy: true);
			}
		}

		public unsafe DataBuffer(int sizeInBytes)
		{
			_buffer = (sbyte*)(void*)Utilities.AllocateMemory(sizeInBytes);
			_size = sizeInBytes;
			_ownsBuffer = true;
		}

		public DataBuffer(DataPointer dataPointer)
			: this(dataPointer.Pointer, dataPointer.Size)
		{
		}

		public unsafe DataBuffer(IntPtr userBuffer, int sizeInBytes)
			: this((void*)userBuffer, sizeInBytes, makeCopy: false)
		{
		}

		internal unsafe DataBuffer(void* buffer, int sizeInBytes, GCHandle handle)
		{
			_buffer = (sbyte*)buffer;
			_size = sizeInBytes;
			_gCHandle = handle;
			_ownsBuffer = false;
		}

		internal unsafe DataBuffer(void* buffer, int sizeInBytes, bool makeCopy)
		{
			if (makeCopy)
			{
				_buffer = (sbyte*)(void*)Utilities.AllocateMemory(sizeInBytes);
				Utilities.CopyMemory((IntPtr)_buffer, (IntPtr)buffer, sizeInBytes);
			}
			else
			{
				_buffer = (sbyte*)buffer;
			}
			_size = sizeInBytes;
			_ownsBuffer = makeCopy;
		}

		internal unsafe DataBuffer(Blob buffer)
		{
			_buffer = (sbyte*)(void*)buffer.GetBufferPointer();
			_size = buffer.GetBufferSize();
			_blob = buffer;
		}

		protected unsafe override void Dispose(bool disposing)
		{
			if (disposing && _blob != null)
			{
				_blob.Dispose();
				_blob = null;
			}
			if (_gCHandle.IsAllocated)
			{
				_gCHandle.Free();
			}
			if (_ownsBuffer && _buffer != null)
			{
				Utilities.FreeMemory((IntPtr)_buffer);
				_buffer = null;
			}
		}

		public unsafe void Clear(byte value = 0)
		{
			Utilities.ClearMemory((IntPtr)_buffer, value, Size);
		}

		public unsafe T Get<T>(int positionInBytes) where T : struct
		{
			T data = default(T);
			Utilities.Read((IntPtr)(_buffer + positionInBytes), ref data);
			return data;
		}

		public unsafe void Get<T>(int positionInBytes, out T value) where T : struct
		{
			Utilities.ReadOut<T>((IntPtr)(_buffer + positionInBytes), out value);
		}

		public unsafe T[] GetRange<T>(int positionInBytes, int count) where T : struct
		{
			T[] array = new T[count];
			Utilities.Read((IntPtr)(_buffer + positionInBytes), array, 0, count);
			return array;
		}

		public unsafe void GetRange<T>(int positionInBytes, T[] buffer, int offset, int count) where T : struct
		{
			Utilities.Read((IntPtr)(_buffer + positionInBytes), buffer, offset, count);
		}

		public unsafe void Set<T>(int positionInBytes, ref T value) where T : struct
		{
			System.Runtime.CompilerServices.Unsafe.Write(_buffer + positionInBytes, value);
		}

		public unsafe void Set<T>(int positionInBytes, T value) where T : struct
		{
			System.Runtime.CompilerServices.Unsafe.Write(_buffer + positionInBytes, value);
		}

		public unsafe void Set(int positionInBytes, bool value)
		{
			*(int*)(_buffer + positionInBytes) = (value ? 1 : 0);
		}

		public void Set<T>(int positionInBytes, T[] data) where T : struct
		{
			Set(positionInBytes, data, 0, data.Length);
		}

		public unsafe void Set(int positionInBytes, IntPtr source, long count)
		{
			Utilities.CopyMemory((IntPtr)(_buffer + positionInBytes), source, (int)count);
		}

		public unsafe void Set<T>(int positionInBytes, T[] data, int offset, int count) where T : struct
		{
			Utilities.Write((IntPtr)(_buffer + positionInBytes), data, offset, count);
		}

		public static implicit operator DataPointer(DataBuffer from)
		{
			return new DataPointer(from.DataPointer, from.Size);
		}
	}
	public struct DataPointer : IEquatable<DataPointer>
	{
		public static readonly DataPointer Zero = new DataPointer(IntPtr.Zero, 0);

		public IntPtr Pointer;

		public int Size;

		public bool IsEmpty => Equals(Zero);

		public DataPointer(IntPtr pointer, int size)
		{
			Pointer = pointer;
			Size = size;
		}

		public unsafe DataPointer(void* pointer, int size)
		{
			Pointer = (IntPtr)pointer;
			Size = size;
		}

		public bool Equals(DataPointer other)
		{
			if (Pointer.Equals((object?)(nint)other.Pointer))
			{
				return Size == other.Size;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is DataPointer)
			{
				return Equals((DataPointer)obj);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (Pointer.GetHashCode() * 397) ^ Size;
		}

		public DataStream ToDataStream()
		{
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			return new DataStream(this);
		}

		public DataBuffer ToDataBuffer()
		{
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			return new DataBuffer(this);
		}

		public byte[] ToArray()
		{
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			if (Size < 0)
			{
				throw new InvalidOperationException("Size cannot be < 0");
			}
			byte[] array = new byte[Size];
			Utilities.Read(Pointer, array, 0, Size);
			return array;
		}

		public T[] ToArray<T>() where T : struct
		{
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			T[] array = new T[Size / Utilities.SizeOf<T>()];
			CopyTo(array, 0, array.Length);
			return array;
		}

		public void CopyTo<T>(T[] buffer, int offset, int count) where T : struct
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "Must be >= 0");
			}
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException("count", "Must be > 0");
			}
			if (count * Utilities.SizeOf<T>() > Size)
			{
				throw new ArgumentOutOfRangeException("buffer", "Total buffer size cannot be larger than size of this data pointer");
			}
			Utilities.Read(Pointer, buffer, offset, count);
		}

		public void CopyFrom<T>(T[] buffer) where T : struct
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			CopyFrom(buffer, 0, buffer.Length);
		}

		public void CopyFrom<T>(T[] buffer, int offset, int count) where T : struct
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (Pointer == IntPtr.Zero)
			{
				throw new InvalidOperationException("DataPointer is Zero");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "Must be >= 0");
			}
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException("count", "Must be > 0");
			}
			if (count * Utilities.SizeOf<T>() > Size)
			{
				throw new ArgumentOutOfRangeException("buffer", "Total buffer size cannot be larger than size of this data pointer");
			}
			Utilities.Write(Pointer, buffer, offset, count);
		}

		public static bool operator ==(DataPointer left, DataPointer right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(DataPointer left, DataPointer right)
		{
			return !left.Equals(right);
		}
	}
	public struct DataRectangle
	{
		public IntPtr DataPointer;

		public int Pitch;

		public DataRectangle(IntPtr dataPointer, int pitch)
		{
			DataPointer = dataPointer;
			Pitch = pitch;
		}
	}
	public class DataStream : Stream
	{
		private unsafe byte* _buffer;

		private readonly bool _canRead;

		private readonly bool _canWrite;

		private GCHandle _gCHandle;

		private Blob _blob;

		private readonly bool _ownsBuffer;

		private long _position;

		private readonly long _size;

		public override bool CanRead => _canRead;

		public override bool CanSeek => true;

		public override bool CanWrite => _canWrite;

		public unsafe IntPtr DataPointer => new IntPtr(_buffer);

		public override long Length => _size;

		public override long Position
		{
			get
			{
				return _position;
			}
			set
			{
				Seek(value, SeekOrigin.Begin);
			}
		}

		public unsafe IntPtr PositionPointer => (IntPtr)(_buffer + _position);

		public long RemainingLength => _size - _position;

		public unsafe DataStream(Blob buffer)
		{
			_buffer = (byte*)(void*)buffer.GetBufferPointer();
			_size = buffer.GetBufferSize();
			_canRead = true;
			_canWrite = true;
			_blob = buffer;
		}

		public unsafe static DataStream Create<T>(T[] userBuffer, bool canRead, bool canWrite, int index = 0, bool pinBuffer = true) where T : struct
		{
			if (userBuffer == null)
			{
				throw new ArgumentNullException("userBuffer");
			}
			if (index < 0 || index > userBuffer.Length)
			{
				throw new ArgumentException("Index is out of range [0, userBuffer.Length-1]", "index");
			}
			int num = Utilities.SizeOf(userBuffer);
			int num2 = index * Utilities.SizeOf<T>();
			if (pinBuffer)
			{
				GCHandle handle = GCHandle.Alloc(userBuffer, GCHandleType.Pinned);
				return new DataStream(num2 + (byte*)(void*)handle.AddrOfPinnedObject(), num - num2, canRead, canWrite, handle);
			}
			fixed (T* ptr = &userBuffer[0])
			{
				return new DataStream(num2 + (byte*)(void*)(IntPtr)ptr, num - num2, canRead, canWrite, makeCopy: true);
			}
		}

		public unsafe DataStream(int sizeInBytes, bool canRead, bool canWrite)
		{
			_buffer = (byte*)(void*)Utilities.AllocateMemory(sizeInBytes);
			_size = sizeInBytes;
			_ownsBuffer = true;
			_canRead = canRead;
			_canWrite = canWrite;
		}

		public DataStream(DataPointer dataPointer)
			: this(dataPointer.Pointer, dataPointer.Size, canRead: true, canWrite: true)
		{
		}

		public unsafe DataStream(IntPtr userBuffer, long sizeInBytes, bool canRead, bool canWrite)
		{
			_buffer = (byte*)userBuffer.ToPointer();
			_size = sizeInBytes;
			_canRead = canRead;
			_canWrite = canWrite;
		}

		internal unsafe DataStream(void* dataPointer, int sizeInBytes, bool canRead, bool canWrite, GCHandle handle)
		{
			_gCHandle = handle;
			_buffer = (byte*)dataPointer;
			_size = sizeInBytes;
			_canRead = canRead;
			_canWrite = canWrite;
			_ownsBuffer = false;
		}

		internal unsafe DataStream(void* buffer, int sizeInBytes, bool canRead, bool canWrite, bool makeCopy)
		{
			if (makeCopy)
			{
				_buffer = (byte*)(void*)Utilities.AllocateMemory(sizeInBytes);
				Utilities.CopyMemory((IntPtr)_buffer, (IntPtr)buffer, sizeInBytes);
			}
			else
			{
				_buffer = (byte*)buffer;
			}
			_size = sizeInBytes;
			_canRead = canRead;
			_canWrite = canWrite;
			_ownsBuffer = makeCopy;
		}

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

		protected unsafe override void Dispose(bool disposing)
		{
			if (disposing && _blob != null)
			{
				_blob.Dispose();
				_blob = null;
			}
			if (_gCHandle.IsAllocated)
			{
				_gCHandle.Free();
			}
			if (_ownsBuffer && _buffer != null)
			{
				Utilities.FreeMemory((IntPtr)_buffer);
				_buffer = null;
			}
		}

		public override void Flush()
		{
			throw new NotSupportedException("DataStream objects cannot be flushed.");
		}

		public unsafe T Read<T>() where T : struct
		{
			if (!_canRead)
			{
				throw new NotSupportedException();
			}
			byte* ptr = _buffer + _position;
			T data = default(T);
			_position = (byte*)(void*)Utilities.ReadAndPosition((IntPtr)ptr, ref data) - _buffer;
			return data;
		}

		public unsafe override int ReadByte()
		{
			if (_position >= Length)
			{
				return -1;
			}
			return _buffer[_position++];
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			int count2 = (int)Math.Min(RemainingLength, count);
			return ReadRange(buffer, offset, count2);
		}

		public unsafe void Read(IntPtr buffer, int offset, int count)
		{
			Utilities.CopyMemory(new IntPtr((byte*)(void*)buffer + offset), (IntPtr)(_buffer + _position), count);
			_position += count;
		}

		public unsafe T[] ReadRange<T>(int count) where T : struct
		{
			if (!_canRead)
			{
				throw new NotSupportedException();
			}
			byte* ptr = _buffer + _position;
			T[] array = new T[count];
			_position = (byte*)(void*)Utilities.Read((IntPtr)ptr, array, 0, count) - _buffer;
			return array;
		}

		public unsafe int ReadRange<T>(T[] buffer, int offset, int count) where T : struct
		{
			if (!_canRead)
			{
				throw new NotSupportedException();
			}
			long position = _position;
			_position = (byte*)(void*)Utilities.Read((IntPtr)(_buffer + _position), buffer, offset, count) - _buffer;
			return (int)(_position - position);
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			long num = 0L;
			switch (origin)
			{
			case SeekOrigin.Begin:
				num = offset;
				break;
			case SeekOrigin.Current:
				num = _position + offset;
				break;
			case SeekOrigin.End:
				num = _size - offset;
				break;
			}
			if (num < 0)
			{
				throw new InvalidOperationException("Cannot seek beyond the beginning of the stream.");
			}
			if (num > _size)
			{
				throw new InvalidOperationException("Cannot seek beyond the end of the stream.");
			}
			_position = num;
			return _position;
		}

		public override void SetLength(long value)
		{
			throw new NotSupportedException("DataStream objects cannot be resized.");
		}

		public unsafe void Write<T>(T value) where T : struct
		{
			if (!_canWrite)
			{
				throw new NotSupportedException();
			}
			_position = (byte*)(void*)Utilities.WriteAndPosition((IntPtr)(_buffer + _position), ref value) - _buffer;
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			WriteRange(buffer, offset, count);
		}

		public unsafe void Write(IntPtr buffer, int offset, int count)
		{
			Utilities.CopyMemory((IntPtr)(_buffer + _position), new IntPtr((byte*)(void*)buffer + offset), count);
			_position += count;
		}

		public void WriteRange<T>(T[] data) where T : struct
		{
			WriteRange(data, 0, data.Length);
		}

		public unsafe void WriteRange(IntPtr source, long count)
		{
			if (!_canWrite)
			{
				throw new NotSupportedException();
			}
			Utilities.CopyMemory((IntPtr)(_buffer + _position), source, (int)count);
			_position += count;
		}

		public unsafe void WriteRange<T>(T[] data, int offset, int count) where T : struct
		{
			if (!_canWrite)
			{
				throw new NotSupportedException();
			}
			_position = (byte*)(void*)Utilities.Write((IntPtr)(_buffer + _position), data, offset, count) - _buffer;
		}

		public static implicit operator DataPointer(DataStream from)
		{
			return new DataPointer(from.PositionPointer, (int)from.RemainingLength);
		}
	}
	public class CompilationException : SharpDXException
	{
		public CompilationException(string message)
			: base(message)
		{
		}

		public CompilationException(Result errorCode, string message)
			: base(errorCode, message)
		{
		}
	}
	public abstract class CompilationResultBase<T> : DisposeBase where T : class, IDisposable
	{
		public T Bytecode { get; private set; }

		public Result ResultCode { get; private set; }

		public bool HasErrors => ResultCode.Failure;

		public string Message { get; private set; }

		protected CompilationResultBase(T bytecode, Result resultCode, string message = null)
		{
			Bytecode = bytecode;
			ResultCode = resultCode;
			Message = message;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && Bytecode != null)
			{
				Bytecode.Dispose();
				Bytecode = null;
			}
		}
	}
	public abstract class DisposeBase : IDisposable
	{
		public bool IsDisposed { get; private set; }

		public event EventHandler<EventArgs> Disposing;

		public event EventHandler<EventArgs> Disposed;

		~DisposeBase()
		{
			CheckAndDispose(disposing: false);
		}

		public void Dispose()
		{
			CheckAndDispose(disposing: true);
		}

		private void CheckAndDispose(bool disposing)
		{
			if (!IsDisposed)
			{
				this.Disposing?.Invoke(this, DisposeEventArgs.Get(disposing));
				Dispose(disposing);
				GC.SuppressFinalize(this);
				IsDisposed = true;
				this.Disposed?.Invoke(this, DisposeEventArgs.Get(disposing));
			}
		}

		protected abstract void Dispose(bool disposing);
	}
	public class DisposeCollector : DisposeBase
	{
		private List<object> disposables;

		public int Count => disposables.Count;

		public void DisposeAndClear(bool disposeManagedResources = true)
		{
			if (disposables == null)
			{
				return;
			}
			for (int num = disposables.Count - 1; num >= 0; num--)
			{
				object obj = disposables[num];
				if (obj is IDisposable disposable)
				{
					if (disposeManagedResources)
					{
						disposable.Dispose();
					}
				}
				else
				{
					Utilities.FreeMemory((IntPtr)obj);
				}
				disposables.RemoveAt(num);
			}
			disposables.Clear();
		}

		protected override void Dispose(bool disposeManagedResources)
		{
			DisposeAndClear(disposeManagedResources);
			disposables = null;
		}

		public T Collect<T>(T toDispose)
		{
			if (!(toDispose is IDisposable) && !(toDispose is IntPtr))
			{
				throw new ArgumentException("Argument must be IDisposable or IntPtr");
			}
			if (toDispose is IntPtr && !Utilities.IsMemoryAligned((IntPtr)(object)toDispose))
			{
				throw new ArgumentException("Memory pointer is invalid. Memory must have been allocated with Utilties.AllocateMemory");
			}
			if (!object.Equals(toDispose, default(T)))
			{
				if (disposables == null)
				{
					disposables = new List<object>();
				}
				if (!disposables.Contains(toDispose))
				{
					disposables.Add(toDispose);
				}
			}
			return toDispose;
		}

		public void RemoveAndDispose<T>(ref T objectToDispose)
		{
			if (disposables != null)
			{
				Remove(objectToDispose);
				if ((object)objectToDispose is IDisposable disposable)
				{
					disposable.Dispose();
				}
				else
				{
					Utilities.FreeMemory((IntPtr)(object)objectToDispose);
				}
				objectToDispose = default(T);
			}
		}

		public void Remove<T>(T toDisposeArg)
		{
			if (disposables != null && disposables.Contains(toDisposeArg))
			{
				disposables.Remove(toDisposeArg);
			}
		}
	}
	public class DisposeEventArgs : EventArgs
	{
		public static readonly DisposeEventArgs DisposingEventArgs = new DisposeEventArgs(disposing: true);

		public static readonly DisposeEventArgs NotDisposingEventArgs = new DisposeEventArgs(disposing: false);

		public readonly bool Disposing;

		private DisposeEventArgs(bool disposing)
		{
			Disposing = disposing;
		}

		public static DisposeEventArgs Get(bool disposing)
		{
			if (!disposing)
			{
				return NotDisposingEventArgs;
			}
			return DisposingEventArgs;
		}
	}
	[StructLayout(LayoutKind.Sequential)]
	internal class FunctionCallback
	{
		public IntPtr Pointer;

		public FunctionCallback(IntPtr pointer)
		{
			Pointer = pointer;
		}

		public unsafe FunctionCallback(void* pointer)
		{
			Pointer = new IntPtr(pointer);
		}

		public static explicit operator IntPtr(FunctionCallback value)
		{
			return value.Pointer;
		}

		public static implicit operator FunctionCallback(IntPtr value)
		{
			return new FunctionCallback(value);
		}

		public unsafe static implicit operator void*(FunctionCallback value)
		{
			return (void*)value.Pointer;
		}

		public unsafe static explicit operator FunctionCallback(void* value)
		{
			return new FunctionCallback(value);
		}

		public override string ToString()
		{
			return string.Format(CultureInfo.CurrentCulture, "{0}", new object[1] { Pointer });
		}

		public string ToString(string format)
		{
			if (format == null)
			{
				return ToString();
			}
			return string.Format(CultureInfo.CurrentCulture, "{0}", new object[1] { Pointer.ToString(format) });
		}

		public override int GetHashCode()
		{
			return Pointer.ToInt32();
		}

		public bool Equals(FunctionCallback other)
		{
			return Pointer == other.Pointer;
		}

		public override bool Equals(object value)
		{
			if (value == null)
			{
				return false;
			}
			if ((object)value.GetType() != typeof(FunctionCallback))
			{
				return false;
			}
			return Equals((FunctionCallback)value);
		}
	}
	public interface ICallbackable : IDisposable
	{
		IDisposable Shadow { get; set; }
	}
	[Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")]
	[Shadow(typeof(InspectableShadow))]
	public interface IInspectable : ICallbackable, IDisposable
	{
	}
	internal class InspectableShadow : ComObjectShadow
	{
		public class InspectableProviderVtbl : ComObjectVtbl
		{
			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private unsafe delegate int GetIidsDelegate(IntPtr thisPtr, int* iidCount, IntPtr* iids);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate int GetRuntimeClassNameDelegate(IntPtr thisPtr, IntPtr className);

			private enum TrustLevel
			{
				BaseTrust,
				PartialTrust,
				FullTrust
			}

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate int GetTrustLevelDelegate(IntPtr thisPtr, IntPtr trustLevel);

			public InspectableProviderVtbl()
				: base(3)
			{
				AddMethod(new GetIidsDelegate(GetIids));
				AddMethod(new GetRuntimeClassNameDelegate(GetRuntimeClassName));
				AddMethod(new GetTrustLevelDelegate(GetTrustLevel));
			}

			private unsafe static int GetIids(IntPtr thisPtr, int* iidCount, IntPtr* iids)
			{
				try
				{
					ShadowContainer shadowContainer = (ShadowContainer)((IInspectable)CppObjectShadow.ToShadow<InspectableShadow>(thisPtr).Callback).Shadow;
					int num = shadowContainer.Guids.Length;
					iids = (IntPtr*)(void*)Marshal.AllocCoTaskMem(IntPtr.Size * num);
					*iidCount = num;
					for (int i = 0; i < num; i++)
					{
						iids[i] = shadowContainer.Guids[i];
					}
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}

			private static int GetRuntimeClassName(IntPtr thisPtr, IntPtr className)
			{
				try
				{
					_ = (IInspectable)CppObjectShadow.ToShadow<InspectableShadow>(thisPtr).Callback;
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}

			private static int GetTrustLevel(IntPtr thisPtr, IntPtr trustLevel)
			{
				try
				{
					_ = (IInspectable)CppObjectShadow.ToShadow<InspectableShadow>(thisPtr).Callback;
					Marshal.WriteInt32(trustLevel, 2);
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}
		}

		private static readonly InspectableProviderVtbl Vtbl = new InspectableProviderVtbl();

		protected override CppObjectVtbl GetVtbl => Vtbl;

		public static IntPtr ToIntPtr(IInspectable callback)
		{
			return CppObject.ToCallbackPtr<IInspectable>(callback);
		}
	}
	internal class Interop
	{
		public unsafe static void* Fixed<T>(ref T data)
		{
			throw new NotImplementedException();
		}

		public unsafe static void* Fixed<T>(T[] data)
		{
			throw new NotImplementedException();
		}

		public unsafe static void* Cast<T>(ref T data) where T : struct
		{
			return System.Runtime.CompilerServices.Unsafe.AsPointer(ref data);
		}

		public unsafe static void* CastOut<T>(out T data) where T : struct
		{
			return System.Runtime.CompilerServices.Unsafe.AsPointer(ref data);
		}

		public static TCAST[] CastArray<TCAST, T>(T[] arrayData) where TCAST : struct where T : struct
		{
			return (TCAST[])(object)arrayData;
		}

		public unsafe static void memcpy(void* pDest, void* pSrc, int count)
		{
			// IL cpblk instruction
			System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(pDest, pSrc, count);
		}

		public unsafe static void memset(void* pDest, byte value, int count)
		{
			// IL initblk instruction
			System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(pDest, value, count);
		}

		public unsafe static void* Read<T>(void* pSrc, ref T data) where T : struct
		{
			fixed (T* ptr = &data)
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref reference, pSrc, num);
				return num + (byte*)pSrc;
			}
		}

		public unsafe static T ReadInline<T>(void* pSrc) where T : struct
		{
			throw new NotImplementedException();
		}

		public unsafe static void WriteInline<T>(void* pDest, ref T data) where T : struct
		{
			throw new NotImplementedException();
		}

		public unsafe static void CopyInline<T>(ref T data, void* pSrc) where T : struct
		{
			throw new NotImplementedException();
		}

		public unsafe static void CopyInline<T>(void* pDest, ref T srcData) where T : struct
		{
			throw new NotImplementedException();
		}

		public unsafe static void CopyInlineOut<T>(out T data, void* pSrc) where T : struct
		{
			throw new NotImplementedException();
		}

		public unsafe static void* ReadOut<T>(void* pSrc, out T data) where T : struct
		{
			fixed (T* ptr = &data)
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref reference, pSrc, num);
				return num + (byte*)pSrc;
			}
		}

		public unsafe static void* Read<T>(void* pSrc, T[] data, int offset, int count) where T : struct
		{
			fixed (T* ptr = &data[offset])
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>() * count;
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref reference, pSrc, num);
				return num + (byte*)pSrc;
			}
		}

		public unsafe static void* Read2D<T>(void* pSrc, T[,] data, int offset, int count) where T : struct
		{
			fixed (T* ptr = &data[offset])
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>() * count;
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ref reference, pSrc, num);
				return num + (byte*)pSrc;
			}
		}

		public static int SizeOf<T>()
		{
			throw new NotImplementedException();
		}

		public unsafe static void* Write<T>(void* pDest, ref T data) where T : struct
		{
			fixed (T* ptr = &data)
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(pDest, ref reference, num);
				return num + (byte*)pDest;
			}
		}

		public unsafe static void* Write<T>(void* pDest, T[] data, int offset, int count) where T : struct
		{
			fixed (T* ptr = &data[offset])
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>() * count;
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(pDest, ref reference, num);
				return num + (byte*)pDest;
			}
		}

		public unsafe static void* Write2D<T>(void* pDest, T[,] data, int offset, int count) where T : struct
		{
			fixed (T* ptr = &data[offset])
			{
				ref ? reference = ref *(?*)ptr;
				int num = System.Runtime.CompilerServices.Unsafe.SizeOf<T>() * count;
				// IL cpblk instruction
				System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(pDest, ref reference, num);
				return num + (byte*)pDest;
			}
		}

		[Tag("SharpDX.ModuleInit")]
		public static void ModuleInit()
		{
		}
	}
	[Guid("00000000-0000-0000-C000-000000000046")]
	public interface IUnknown : ICallbackable, IDisposable
	{
		Result QueryInterface(ref Guid guid, out IntPtr comObject);

		int AddReference();

		int Release();
	}
	internal class ModuleInit
	{
		[Tag("SharpDX.ModuleInit")]
		internal static void Setup()
		{
			ResultDescriptor.RegisterProvider(typeof(Result));
		}
	}
	[CompilerGenerated]
	internal class NamespaceDoc
	{
	}
	public struct PointerSize : IEquatable<PointerSize>
	{
		private IntPtr _size;

		public static readonly PointerSize Zero = new PointerSize(0);

		public PointerSize(IntPtr size)
		{
			_size = size;
		}

		private unsafe PointerSize(void* size)
		{
			_size = new IntPtr(size);
		}

		public PointerSize(int size)
		{
			_size = new IntPtr(size);
		}

		public PointerSize(long size)
		{
			_size = new IntPtr(size);
		}

		public override string ToString()
		{
			return string.Format(CultureInfo.CurrentCulture, "{0}", new object[1] { _size });
		}

		public string ToString(string format)
		{
			if (format == null)
			{
				return ToString();
			}
			return string.Format(CultureInfo.CurrentCulture, "{0}", new object[1] { _size.ToString(format) });
		}

		public override int GetHashCode()
		{
			return _size.GetHashCode();
		}

		public bool Equals(PointerSize other)
		{
			return _size.Equals((object?)(nint)other._size);
		}

		public override bool Equals(object value)
		{
			if (value == null)
			{
				return false;
			}
			if (value is PointerSize)
			{
				return Equals((PointerSize)value);
			}
			return false;
		}

		public static PointerSize operator +(PointerSize left, PointerSize right)
		{
			return new PointerSize(left._size.ToInt64() + right._size.ToInt64());
		}

		public static PointerSize operator +(PointerSize value)
		{
			return value;
		}

		public static PointerSize operator -(PointerSize left, PointerSize right)
		{
			return new PointerSize(left._size.ToInt64() - right._size.ToInt64());
		}

		public static PointerSize operator -(PointerSize value)
		{
			return new PointerSize(-value._size.ToInt64());
		}

		public static PointerSize operator *(int scale, PointerSize value)
		{
			return new PointerSize(scale * value._size.ToInt64());
		}

		public static PointerSize operator *(PointerSize value, int scale)
		{
			return new PointerSize(scale * value._size.ToInt64());
		}

		public static PointerSize operator /(PointerSize value, int scale)
		{
			return new PointerSize(value._size.ToInt64() / scale);
		}

		public static bool operator ==(PointerSize left, PointerSize right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(PointerSize left, PointerSize right)
		{
			return !left.Equals(right);
		}

		public static implicit operator int(PointerSize value)
		{
			return value._size.ToInt32();
		}

		public static implicit operator long(PointerSize value)
		{
			return value._size.ToInt64();
		}

		public static implicit operator PointerSize(int value)
		{
			return new PointerSize(value);
		}

		public static implicit operator PointerSize(long value)
		{
			return new PointerSize(value);
		}

		public static implicit operator PointerSize(IntPtr value)
		{
			return new PointerSize(value);
		}

		public static implicit operator IntPtr(PointerSize value)
		{
			return value._size;
		}

		public unsafe static implicit operator PointerSize(void* value)
		{
			return new PointerSize(value);
		}

		public unsafe static implicit operator void*(PointerSize value)
		{
			return (void*)value._size;
		}
	}
	public struct Result : IEquatable<Result>
	{
		private int _code;

		public static readonly Result Ok = new Result(0);

		public static readonly Result False = new Result(1);

		public static readonly ResultDescriptor Abort = new ResultDescriptor(-2147467260, "General", "E_ABORT", "Operation aborted");

		public static readonly ResultDescriptor AccessDenied = new ResultDescriptor(-2147024891, "General", "E_ACCESSDENIED", "General access denied error");

		public static readonly ResultDescriptor Fail = new ResultDescriptor(-2147467259, "General", "E_FAIL", "Unspecified error");

		public static readonly ResultDescriptor Handle = new ResultDescriptor(-2147024890, "General", "E_HANDLE", "Invalid handle");

		public static readonly ResultDescriptor InvalidArg = new ResultDescriptor(-2147024809, "General", "E_INVALIDARG", "Invalid Arguments");

		public static readonly ResultDescriptor NoInterface = new ResultDescriptor(-2147467262, "General", "E_NOINTERFACE", "No such interface supported");

		public static readonly ResultDescriptor NotImplemented = new ResultDescriptor(-2147467263, "General", "E_NOTIMPL", "Not implemented");

		public static readonly ResultDescriptor OutOfMemory = new ResultDescriptor(-2147024882, "General", "E_OUTOFMEMORY", "Out of memory");

		public static readonly ResultDescriptor InvalidPointer = new ResultDescriptor(-2147467261, "General", "E_POINTER", "Invalid pointer");

		public static readonly ResultDescriptor UnexpectedFailure = new ResultDescriptor(-2147418113, "General", "E_UNEXPECTED", "Catastrophic failure");

		public static readonly ResultDescriptor WaitAbandoned = new ResultDescriptor(128, "General", "WAIT_ABANDONED", "WaitAbandoned");

		public static readonly ResultDescriptor WaitTimeout = new ResultDescriptor(258, "General", "WAIT_TIMEOUT", "WaitTimeout");

		public static readonly ResultDescriptor Pending = new ResultDescriptor(-2147483638, "General", "E_PENDING", "Pending");

		public int Code => _code;

		public bool Success => Code >= 0;

		public bool Failure => Code < 0;

		public Result(int code)
		{
			_code = code;
		}

		public Result(uint code)
		{
			_code = (int)code;
		}

		public static explicit operator int(Result result)
		{
			return result.Code;
		}

		public static explicit operator uint(Result result)
		{
			return (uint)result.Code;
		}

		public static implicit operator Result(int result)
		{
			return new Result(result);
		}

		public static implicit operator Result(uint result)
		{
			return new Result(result);
		}

		public bool Equals(Result other)
		{
			return Code == other.Code;
		}

		public override bool Equals(object obj)
		{
			if (!(obj is Result))
			{
				return false;
			}
			return Equals((Result)obj);
		}

		public override int GetHashCode()
		{
			return Code;
		}

		public static bool operator ==(Result left, Result right)
		{
			return left.Code == right.Code;
		}

		public static bool operator !=(Result left, Result right)
		{
			return left.Code != right.Code;
		}

		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture, "HRESULT = 0x{0:X}", new object[1] { _code });
		}

		public void CheckError()
		{
			if (_code < 0)
			{
				throw new SharpDXException(this);
			}
		}

		public static Result GetResultFromException(Exception ex)
		{
			return new Result(Marshal.GetHRForException(ex));
		}

		public static Result GetResultFromWin32Error(int win32Error)
		{
			return (int)((win32Error <= 0) ? win32Error : ((win32Error & 0xFFFF) | 0x70000 | 0x80000000u));
		}
	}
	public sealed class ResultDescriptor
	{
		private static readonly object LockDescriptor = new object();

		private static readonly List<Type> RegisteredDescriptorProvider = new List<Type>();

		private static readonly Dictionary<Result, ResultDescriptor> Descriptors = new Dictionary<Result, ResultDescriptor>();

		private const string UnknownText = "Unknown";

		public Result Result { get; private set; }

		public int Code => Result.Code;

		public string Module { get; private set; }

		public string NativeApiCode { get; private set; }

		public string ApiCode { get; private set; }

		public string Description { get; set; }

		public ResultDescriptor(Result code, string module, string nativeApiCode, string apiCode, string description = null)
		{
			Result = code;
			Module = module;
			NativeApiCode = nativeApiCode;
			ApiCode = apiCode;
			Description = description;
		}

		public bool Equals(ResultDescriptor other)
		{
			if (other == null)
			{
				return false;
			}
			if ((object)this == other)
			{
				return true;
			}
			return other.Result.Equals(Result);
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != typeof(ResultDescriptor))
			{
				return false;
			}
			return Equals((ResultDescriptor)obj);
		}

		public override int GetHashCode()
		{
			return Result.GetHashCode();
		}

		public override string ToString()
		{
			return $"HRESULT: [0x{Result.Code:X}], Module: [{Module}], ApiCode: [{NativeApiCode}/{ApiCode}], Message: {Description}";
		}

		public static implicit operator Result(ResultDescriptor result)
		{
			return result.Result;
		}

		public static explicit operator int(ResultDescriptor result)
		{
			return result.Result.Code;
		}

		public static explicit operator uint(ResultDescriptor result)
		{
			return (uint)result.Result.Code;
		}

		public static bool operator ==(ResultDescriptor left, Result right)
		{
			if (left == null)
			{
				return false;
			}
			return left.Result.Code == right.Code;
		}

		public static bool operator !=(ResultDescriptor left, Result right)
		{
			if (left == null)
			{
				return false;
			}
			return left.Result.Code != right.Code;
		}

		public static void RegisterProvider(Type descriptorsProviderType)
		{
			lock (LockDescriptor)
			{
				if (!RegisteredDescriptorProvider.Contains(descriptorsProviderType))
				{
					RegisteredDescriptorProvider.Add(descriptorsProviderType);
				}
			}
		}

		public static ResultDescriptor Find(Result result)
		{
			ResultDescriptor value;
			lock (LockDescriptor)
			{
				if (RegisteredDescriptorProvider.Count > 0)
				{
					foreach (Type item in RegisteredDescriptorProvider)
					{
						AddDescriptorsFromType(item);
					}
					RegisteredDescriptorProvider.Clear();
				}
				if (!Descriptors.TryGetValue(result, out value))
				{
					value = new ResultDescriptor(result, "Unknown", "Unknown", "Unknown");
				}
				if (value.Description == null)
				{
					string descriptionFromResultCode = GetDescriptionFromResultCode(result.Code);
					value.Description = descriptionFromResultCode ?? "Unknown";
				}
			}
			return value;
		}

		private static void AddDescriptorsFromType(Type type)
		{
			foreach (FieldInfo declaredField in type.GetTypeInfo().DeclaredFields)
			{
				if (declaredField.FieldType == typeof(ResultDescriptor) && declaredField.IsPublic && declaredField.IsStatic)
				{
					ResultDescriptor resultDescriptor = (ResultDescriptor)declaredField.GetValue(null);
					if (!Descriptors.ContainsKey(resultDescriptor.Result))
					{
						Descriptors.Add(resultDescriptor.Result, resultDescriptor);
					}
				}
			}
		}

		private static string GetDescriptionFromResultCode(int resultCode)
		{
			IntPtr lpBuffer = IntPtr.Zero;
			FormatMessageW(4864, IntPtr.Zero, resultCode, 0, ref lpBuffer, 0, IntPtr.Zero);
			string? result = Marshal.PtrToStringUni(lpBuffer);
			Marshal.FreeHGlobal(lpBuffer);
			return result;
		}

		[DllImport("kernel32.dll")]
		private static extern uint FormatMessageW(int dwFlags, IntPtr lpSource, int dwMessageId, int dwLanguageId, ref IntPtr lpBuffer, int nSize, IntPtr Arguments);
	}
	public class ServiceEventArgs : EventArgs
	{
		public Type ServiceType { get; private set; }

		public object Instance { get; private set; }

		public ServiceEventArgs(Type serviceType, object serviceInstance)
		{
			ServiceType = serviceType;
			Instance = serviceInstance;
		}
	}
	[AttributeUsage(AttributeTargets.Interface)]
	internal class ShadowAttribute : Attribute
	{
		private Type type;

		public Type Type => type;

		public ShadowAttribute(Type typeOfTheAssociatedShadow)
		{
			type = typeOfTheAssociatedShadow;
		}

		public static ShadowAttribute Get(Type type)
		{
			return type.GetTypeInfo().GetCustomAttribute<ShadowAttribute>();
		}
	}
	internal class ShadowContainer : DisposeBase
	{
		private readonly Dictionary<Guid, CppObjectShadow> guidToShadow = new Dictionary<Guid, CppObjectShadow>();

		private static readonly Dictionary<Type, List<Type>> typeToShadowTypes = new Dictionary<Type, List<Type>>();

		private IntPtr guidPtr;

		public IntPtr[] Guids { get; private set; }

		public unsafe void Initialize(ICallbackable callbackable)
		{
			callbackable.Shadow = this;
			Type type = callbackable.GetType();
			List<Type> value;
			lock (typeToShadowTypes)
			{
				if (!typeToShadowTypes.TryGetValue(type, out value))
				{
					IEnumerable<Type> implementedInterfaces = type.GetTypeInfo().ImplementedInterfaces;
					value = new List<Type>();
					value.AddRange(implementedInterfaces);
					typeToShadowTypes.Add(type, value);
					foreach (Type item in implementedInterfaces)
					{
						if (ShadowAttribute.Get(item) == null)
						{
							value.Remove(item);
							continue;
						}
						foreach (Type implementedInterface in item.GetTypeInfo().ImplementedInterfaces)
						{
							value.Remove(implementedInterface);
						}
					}
				}
			}
			CppObjectShadow cppObjectShadow = null;
			foreach (Type item2 in value)
			{
				CppObjectShadow cppObjectShadow2 = (CppObjectShadow)Activator.CreateInstance(ShadowAttribute.Get(item2).Type);
				cppObjectShadow2.Initialize(callbackable);
				if (cppObjectShadow == null)
				{
					cppObjectShadow = cppObjectShadow2;
					guidToShadow.Add(ComObjectShadow.IID_IUnknown, cppObjectShadow);
				}
				guidToShadow.Add(Utilities.GetGuidFromType(item2), cppObjectShadow2);
				foreach (Type implementedInterface2 in item2.GetTypeInfo().ImplementedInterfaces)
				{
					if (ShadowAttribute.Get(implementedInterface2) != null)
					{
						guidToShadow.Add(Utilities.GetGuidFromType(implementedInterface2), cppObjectShadow2);
					}
				}
			}
			int num = 0;
			foreach (Guid key in guidToShadow.Keys)
			{
				if (key != Utilities.GetGuidFromType(typeof(IInspectable)) && key != Utilities.GetGuidFromType(typeof(IUnknown)))
				{
					num++;
				}
			}
			guidPtr = Marshal.AllocHGlobal(Utilities.SizeOf<Guid>() * num);
			Guids = new IntPtr[num];
			int num2 = 0;
			Guid* ptr = (Guid*)(void*)guidPtr;
			foreach (Guid key2 in guidToShadow.Keys)
			{
				if (!(key2 == Utilities.GetGuidFromType(typeof(IInspectable))) && !(key2 == Utilities.GetGuidFromType(typeof(IUnknown))))
				{
					ptr[num2] = key2;
					Guids[num2] = new IntPtr(ptr + num2);
					num2++;
				}
			}
		}

		internal IntPtr Find(Type type)
		{
			return Find(Utilities.GetGuidFromType(type));
		}

		internal IntPtr Find(Guid guidType)
		{
			return FindShadow(guidType)?.NativePointer ?? IntPtr.Zero;
		}

		internal CppObjectShadow FindShadow(Guid guidType)
		{
			guidToShadow.TryGetValue(guidType, out var value);
			return value;
		}

		protected override void Dispose(bool disposing)
		{
			if (!disposing)
			{
				return;
			}
			foreach (CppObjectShadow value in guidToShadow.Values)
			{
				value.Dispose();
			}
			guidToShadow.Clear();
			if (guidPtr != IntPtr.Zero)
			{
				Marshal.FreeHGlobal(guidPtr);
				guidPtr = IntPtr.Zero;
			}
		}
	}
	public class SharpDXException : Exception
	{
		private ResultDescriptor descriptor;

		public Result ResultCode => descriptor.Result;

		public ResultDescriptor Descriptor => descriptor;

		public SharpDXException()
			: base("A SharpDX exception occurred.")
		{
			descriptor = ResultDescriptor.Find(Result.Fail);
			base.HResult = (int)Result.Fail;
		}

		public SharpDXException(Result result)
			: this(ResultDescriptor.Find(result))
		{
			base.HResult = (int)result;
		}

		public SharpDXException(ResultDescriptor descriptor)
			: base(descriptor.ToString())
		{
			this.descriptor = descriptor;
			base.HResult = (int)descriptor.Result;
		}

		public SharpDXException(Result result, string message)
			: base(message)
		{
			descriptor = ResultDescriptor.Find(result);
			base.HResult = (int)result;
		}

		public SharpDXException(Result result, string message, params object[] args)
			: base(string.Format(CultureInfo.InvariantCulture, message, args))
		{
			descriptor = ResultDescriptor.Find(result);
			base.HResult = (int)result;
		}

		public SharpDXException(string message, params object[] args)
			: this(Result.Fail, message, args)
		{
		}

		public SharpDXException(string message, Exception innerException, params object[] args)
			: base(string.Format(CultureInfo.InvariantCulture, message, args), innerException)
		{
			descriptor = ResultDescriptor.Find(Result.Fail);
			base.HResult = (int)Result.Fail;
		}
	}
	public struct Size2 : IEquatable<Size2>
	{
		public static readonly Size2 Zero = new Size2(0, 0);

		public static readonly Size2 Empty = Zero;

		public int Width;

		public int Height;

		public Size2(int width, int height)
		{
			Width = width;
			Height = height;
		}

		public bool Equals(Size2 other)
		{
			if (other.Width == Width)
			{
				return other.Height == Height;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (!(obj is Size2))
			{
				return false;
			}
			return Equals((Size2)obj);
		}

		public override int GetHashCode()
		{
			return (Width * 397) ^ Height;
		}

		public static bool operator ==(Size2 left, Size2 right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(Size2 left, Size2 right)
		{
			return !left.Equals(right);
		}

		public override string ToString()
		{
			return $"({Width},{Height})";
		}
	}
	public struct Size2F : IEquatable<Size2F>
	{
		public static readonly Size2F Zero = new Size2F(0f, 0f);

		public static readonly Size2F Empty = Zero;

		public float Width;

		public float Height;

		public Size2F(float width, float height)
		{
			Width = width;
			Height = height;
		}

		public bool Equals(Size2F other)
		{
			if (other.Width == Width)
			{
				return other.Height == Height;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (!(obj is Size2F))
			{
				return false;
			}
			return Equals((Size2F)obj);
		}

		public override int GetHashCode()
		{
			return (Width.GetHashCode() * 397) ^ Height.GetHashCode();
		}

		public static bool operator ==(Size2F left, Size2F right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(Size2F left, Size2F right)
		{
			return !left.Equals(right);
		}

		public override string ToString()
		{
			return $"({Width},{Height})";
		}
	}
	[AttributeUsage(AttributeTargets.All)]
	public class TagAttribute : Attribute
	{
		public string Value { get; private set; }

		public TagAttribute(string value)
		{
			Value = value;
		}
	}
	public delegate void GetValueFastDelegate<T>(object obj, out T value);
	public delegate void SetValueFastDelegate<T>(object obj, ref T value);
	public static class Utilities
	{
		[Flags]
		public enum CLSCTX : uint
		{
			ClsctxInprocServer = 1u,
			ClsctxInprocHandler = 2u,
			ClsctxLocalServer = 4u,
			ClsctxInprocServer16 = 8u,
			ClsctxRemoteServer = 0x10u,
			ClsctxInprocHandler16 = 0x20u,
			ClsctxReserved1 = 0x40u,
			ClsctxReserved2 = 0x80u,
			ClsctxReserved3 = 0x100u,
			ClsctxReserved4 = 0x200u,
			ClsctxNoCodeDownload = 0x400u,
			ClsctxReserved5 = 0x800u,
			ClsctxNoCustomMarshal = 0x1000u,
			ClsctxEnableCodeDownload = 0x2000u,
			ClsctxNoFailureLog = 0x4000u,
			ClsctxDisableAaa = 0x8000u,
			ClsctxEnableAaa = 0x10000u,
			ClsctxFromDefaultContext = 0x20000u,
			ClsctxInproc = 3u,
			ClsctxServer = 0x15u,
			ClsctxAll = 0x17u
		}

		public enum CoInit
		{
			MultiThreaded = 0,
			ApartmentThreaded = 2,
			DisableOle1Dde = 4,
			SpeedOverMemory = 8
		}

		internal struct Buffer<TElement>
		{
			internal TElement[] items;

			internal int count;

			internal Buffer(IEnumerable<TElement> source)
			{
				TElement[] array = null;
				int num = 0;
				if (source is ICollection<TElement> collection)
				{
					num = collection.Count;
					if (num > 0)
					{
						array = new TElement[num];
						collection.CopyTo(array, 0);
					}
				}
				else
				{
					foreach (TElement item in source)
					{
						if (array == null)
						{
							array = new TElement[4];
						}
						else if (array.Length == num)
						{
							TElement[] array2 = new TElement[checked(num * 2)];
							Array.Copy(array, 0, array2, 0, num);
							array = array2;
						}
						array[num] = item;
						num++;
					}
				}
				items = array;
				count = num;
			}

			internal TElement[] ToArray()
			{
				if (count == 0)
				{
					return new TElement[0];
				}
				if (items.Length == count)
				{
					return items;
				}
				TElement[] array = new TElement[count];
				Array.Copy(items, 0, array, 0, count);
				return array;
			}
		}

		public unsafe static void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy)
		{
			Interop.memcpy((void*)dest, (void*)src, sizeInBytesToCopy);
		}

		public unsafe static bool CompareMemory(IntPtr from, IntPtr against, int sizeToCompare)
		{
			byte* ptr = (byte*)(void*)from;
			byte* ptr2 = (byte*)(void*)against;
			for (int num = sizeToCompare >> 3; num > 0; num--)
			{
				if (*(long*)ptr != *(long*)ptr2)
				{
					return false;
				}
				ptr += 8;
				ptr2 += 8;
			}
			for (int num = sizeToCompare & 7; num > 0; num--)
			{
				if (*ptr != *ptr2)
				{
					return false;
				}
				ptr++;
				ptr2++;
			}
			return true;
		}

		public unsafe static void ClearMemory(IntPtr dest, byte value, int sizeInBytesToClear)
		{
			Interop.memset((void*)dest, value, sizeInBytesToClear);
		}

		public static int SizeOf<T>() where T : struct
		{
			return System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
		}

		public static int SizeOf<T>(T[] array) where T : struct
		{
			if (array != null)
			{
				return array.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
			}
			return 0;
		}

		public unsafe static void Pin<T>(ref T source, Action<IntPtr> pinAction) where T : struct
		{
			fixed (T* ptr = &source)
			{
				pinAction((IntPtr)ptr);
			}
		}

		public unsafe static void Pin<T>(T[] source, Action<IntPtr> pinAction) where T : struct
		{
			//The blocks IL_0019 are reachable both inside and outside the pinned region starting at IL_000b. ILSpy has duplicated these blocks in order to place them both within and outside the `fixed` statement.
			IntPtr obj;
			if (source != null)
			{
				fixed (T* ptr = &source[0])
				{
					obj = (IntPtr)ptr;
					pinAction(obj);
					return;
				}
			}
			obj = IntPtr.Zero;
			pinAction(obj);
		}

		public unsafe static byte[] ToByteArray<T>(T[] source) where T : struct
		{
			if (source == null)
			{
				return null;
			}
			byte[] array = new byte[SizeOf<T>() * source.Length];
			if (source.Length == 0)
			{
				return array;
			}
			fixed (byte* ptr = array)
			{
				void* pDest = ptr;
				Interop.Write(pDest, source, 0, source.Length);
			}
			return array;
		}

		public static void Swap<T>(ref T left, ref T right)
		{
			T val = left;
			left = right;
			right = val;
		}

		public unsafe static T Read<T>(IntPtr source) where T : struct
		{
			return System.Runtime.CompilerServices.Unsafe.Read<T>((void*)source);
		}

		public unsafe static void Read<T>(IntPtr source, ref T data) where T : struct
		{
			data = System.Runtime.CompilerServices.Unsafe.Read<T>((void*)source);
		}

		public unsafe static void ReadOut<T>(IntPtr source, out T data) where T : struct
		{
			data = System.Runtime.CompilerServices.Unsafe.Read<T>((void*)source);
		}

		public unsafe static IntPtr ReadAndPosition<T>(IntPtr source, ref T data) where T : struct
		{
			return (IntPtr)Interop.Read((void*)source, ref data);
		}

		public unsafe static IntPtr Read<T>(IntPtr source, T[] data, int offset, int count) where T : struct
		{
			return (IntPtr)Interop.Read((void*)source, data, offset, count);
		}

		public unsafe static void Write<T>(IntPtr destination, ref T data) where T : struct
		{
			System.Runtime.CompilerServices.Unsafe.Write((void*)destination, data);
		}

		public unsafe static IntPtr WriteAndPosition<T>(IntPtr destination, ref T data) where T : struct
		{
			return (IntPtr)Interop.Write((void*)destination, ref data);
		}

		public unsafe static IntPtr Write<T>(IntPtr destination, T[] data, int offset, int count) where T : struct
		{
			return (IntPtr)Interop.Write((void*)destination, data, offset, count);
		}

		public unsafe static void ConvertToIntArray(bool[] array, int* dest)
		{
			for (int i = 0; i < array.Length; i++)
			{
				dest[i] = (array[i] ? 1 : 0);
			}
		}

		public static RawBool[] ConvertToIntArray(bool[] array)
		{
			RawBool[] array2 = new RawBool[array.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = array[i];
			}
			return array2;
		}

		public unsafe static bool[] ConvertToBoolArray(int* array, int length)
		{
			bool[] array2 = new bool[length];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = array[i] != 0;
			}
			return array2;
		}

		public static bool[] ConvertToBoolArray(RawBool[] array)
		{
			bool[] array2 = new bool[array.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = array[i];
			}
			return array2;
		}

		public static Guid GetGuidFromType(Type type)
		{
			return type.GetTypeInfo().GUID;
		}

		public static bool IsAssignableToGenericType(Type givenType, Type genericType)
		{
			foreach (Type implementedInterface in givenType.GetTypeInfo().ImplementedInterfaces)
			{
				if (implementedInterface.GetTypeInfo().IsGenericType && implementedInterface.GetGenericTypeDefinition() == genericType)
				{
					return true;
				}
			}
			if (givenType.GetTypeInfo().IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
			{
				return true;
			}
			Type baseType = givenType.GetTypeInfo().BaseType;
			if (baseType == null)
			{
				return false;
			}
			return IsAssignableToGenericType(baseType, genericType);
		}

		public unsafe static IntPtr AllocateMemory(int sizeInBytes, int align = 16)
		{
			int num = align - 1;
			IntPtr intPtr = Marshal.AllocHGlobal(sizeInBytes + num + IntPtr.Size);
			long num2 = (long)((byte*)(void*)intPtr + sizeof(void*) + num) & (long)(~num);
			*(IntPtr*)((nint)num2 + (nint)(-1) * (nint)sizeof(IntPtr)) = intPtr;
			return new IntPtr((void*)num2);
		}

		public static IntPtr AllocateClearedMemory(int sizeInBytes, byte clearValue = 0, int align = 16)
		{
			IntPtr intPtr = AllocateMemory(sizeInBytes, align);
			ClearMemory(intPtr, clearValue, sizeInBytes);
			return intPtr;
		}

		public static bool IsMemoryAligned(IntPtr memoryPtr, int align = 16)
		{
			return (memoryPtr.ToInt64() & (align - 1)) == 0;
		}

		public unsafe static void FreeMemory(IntPtr alignedBuffer)
		{
			if (!(alignedBuffer == IntPtr.Zero))
			{
				Marshal.FreeHGlobal(*(IntPtr*)((byte*)(void*)alignedBuffer + (nint)(-1) * (nint)sizeof(IntPtr)));
			}
		}

		public static string PtrToStringAnsi(IntPtr pointer, int maxLength)
		{
			string text = Marshal.PtrToStringAnsi(pointer);
			if (text != null && text.Length > maxLength)
			{
				text = text.Substring(0, maxLength);
			}
			return text;
		}

		public static string PtrToStringUni(IntPtr pointer, int maxLength)
		{
			string text = Marshal.PtrToStringUni(pointer);
			if (text != null && text.Length > maxLength)
			{
				text = text.Substring(0, maxLength);
			}
			return text;
		}

		public static IntPtr StringToHGlobalAnsi(string s)
		{
			return Marshal.StringToHGlobalAnsi(s);
		}

		public static IntPtr StringToHGlobalUni(string s)
		{
			return Marshal.StringToHGlobalUni(s);
		}

		public static IntPtr StringToCoTaskMemUni(string s)
		{
			if (s == null)
			{
				return IntPtr.Zero;
			}
			int num = (s.Length + 1) * 2;
			if (num < s.Length)
			{
				throw new ArgumentOutOfRangeException("s");
			}
			IntPtr intPtr = Marshal.AllocCoTaskMem(num);
			if (intPtr == IntPtr.Zero)
			{
				throw new OutOfMemoryException();
			}
			CopyStringToUnmanaged(intPtr, s);
			return intPtr;
		}

		private unsafe static void CopyStringToUnmanaged(IntPtr ptr, string str)
		{
			fixed (char* value = str)
			{
				CopyMemory(ptr, new IntPtr(value), (str.Length + 1) * 2);
			}
		}

		public static IntPtr GetIUnknownForObject(object obj)
		{
			if (obj != null)
			{
				return Marshal.GetIUnknownForObject(obj);
			}
			return IntPtr.Zero;
		}

		public static object GetObjectForIUnknown(IntPtr iunknownPtr)
		{
			if (!(iunknownPtr == IntPtr.Zero))
			{
				return Marshal.GetObjectForIUnknown(iunknownPtr);
			}
			return null;
		}

		public static string Join<T>(string separator, T[] array)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (array != null)
			{
				for (int i = 0; i < array.Length; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(separator);
					}
					stringBuilder.Append(array[i]);
				}
			}
			return stringBuilder.ToString();
		}

		public static string Join(string separator, IEnumerable elements)
		{
			List<string> list = new List<string>();
			foreach (object element in elements)
			{
				list.Add(element.ToString());
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < list.Count; i++)
			{
				string value = list[i];
				if (i > 0)
				{
					stringBuilder.Append(separator);
				}
				stringBuilder.Append(value);
			}
			return stringBuilder.ToString();
		}

		public static string Join(string separator, IEnumerator elements)
		{
			List<string> list = new List<string>();
			while (elements.MoveNext())
			{
				list.Add(elements.Current.ToString());
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < list.Count; i++)
			{
				string value = list[i];
				if (i > 0)
				{
					stringBuilder.Append(separator);
				}
				stringBuilder.Append(value);
			}
			return stringBuilder.ToString();
		}

		public static string BlobToString(Blob blob)
		{
			if (blob == null)
			{
				return null;
			}
			string? result = Marshal.PtrToStringAnsi(blob.BufferPointer);
			blob.Dispose();
			return result;
		}

		public unsafe static IntPtr IntPtrAdd(IntPtr ptr, int offset)
		{
			return new IntPtr((byte*)(void*)ptr + offset);
		}

		public static byte[] ReadStream(Stream stream)
		{
			int readLength = 0;
			return ReadStream(stream, ref readLength);
		}

		public static byte[] ReadStream(Stream stream, ref int readLength)
		{
			if (readLength == 0)
			{
				readLength = (int)(stream.Length - stream.Position);
			}
			int num = readLength;
			if (num == 0)
			{
				return new byte[0];
			}
			byte[] array = new byte[num];
			int num2 = 0;
			if (num > 0)
			{
				do
				{
					num2 += stream.Read(array, num2, readLength - num2);
				}
				while (num2 < readLength);
			}
			return array;
		}

		public static bool Compare(IEnumerable left, IEnumerable right)
		{
			if (left == right)
			{
				return true;
			}
			if (left == null || right == null)
			{
				return false;
			}
			return Compare(left.GetEnumerator(), right.GetEnumerator());
		}

		public static bool Compare(IEnumerator leftIt, IEnumerator rightIt)
		{
			if (leftIt == rightIt)
			{
				return true;
			}
			if (leftIt == null || rightIt == null)
			{
				return false;
			}
			bool flag;
			bool flag2;
			while (true)
			{
				flag = leftIt.MoveNext();
				flag2 = rightIt.MoveNext();
				if (!flag || !flag2)
				{
					break;
				}
				if (!object.Equals(leftIt.Current, rightIt.Current))
				{
					return false;
				}
			}
			if (flag != flag2)
			{
				return false;
			}
			return true;
		}

		public static bool Compare(ICollection left, ICollection right)
		{
			if (left == right)
			{
				return true;
			}
			if (left == null || right == null)
			{
				return false;
			}
			if (left.Count != right.Count)
			{
				return false;
			}
			int num = 0;
			IEnumerator enumerator = left.GetEnumerator();
			IEnumerator enumerator2 = right.GetEnumerator();
			while (enumerator.MoveNext() && enumerator2.MoveNext())
			{
				if (!object.Equals(enumerator.Current, enumerator2.Current))
				{
					return false;
				}
				num++;
			}
			if (num != left.Count)
			{
				return false;
			}
			return true;
		}

		public static T GetCustomAttribute<T>(MemberInfo memberInfo, bool inherited = false) where T : Attribute
		{
			return memberInfo.GetCustomAttribute<T>(inherited);
		}

		public static IEnumerable<T> GetCustomAttributes<T>(MemberInfo memberInfo, bool inherited = false) where T : Attribute
		{
			return memberInfo.GetCustomAttributes<T>(inherited);
		}

		public static bool IsAssignableFrom(Type toType, Type fromType)
		{
			return toType.GetTypeInfo().IsAssignableFrom(fromType.GetTypeInfo());
		}

		public static bool IsEnum(Type typeToTest)
		{
			return typeToTest.GetTypeInfo().IsEnum;
		}

		public static bool IsValueType(Type typeToTest)
		{
			return typeToTest.GetTypeInfo().IsValueType;
		}

		private static MethodInfo GetMethod(Type type, string name, Type[] typeArgs)
		{
			foreach (MethodInfo declaredMethod in type.GetTypeInfo().GetDeclaredMethods(name))
			{
				if (declaredMethod.GetParameters().Length != typeArgs.Length)
				{
					continue;
				}
				ParameterInfo[] parameters = declaredMethod.GetParameters();
				bool flag = true;
				for (int i = 0; i < typeArgs.Length; i++)
				{
					if (parameters[i].ParameterType != typeArgs[i])
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return declaredMethod;
				}
			}
			return null;
		}

		public static GetValueFastDelegate<T> BuildPropertyGetter<T>(Type customEffectType, PropertyInfo propertyInfo)
		{
			ParameterExpression parameterExpression = Expression.Parameter(typeof(T).MakeByRefType());
			ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object));
			MemberExpression memberExpression = Expression.Property(Expression.Convert(parameterExpression2, customEffectType), propertyInfo);
			Expression right = ((!(propertyInfo.PropertyType == typeof(bool))) ? ((Expression)Expression.Convert(memberExpression, typeof(T))) : ((Expression)Expression.Condition(memberExpression, Expression.Constant(1), Expression.Constant(0))));
			return Expression.Lambda<GetValueFastDelegate<T>>(Expression.Assign(parameterExpression, right), new ParameterExpression[2] { parameterExpression2, parameterExpression }).Compile();
		}

		public static SetValueFastDelegate<T> BuildPropertySetter<T>(Type customEffectType, PropertyInfo propertyInfo)
		{
			ParameterExpression parameterExpression = Expression.Parameter(typeof(T).MakeByRefType());
			ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object));
			MemberExpression left = Expression.Property(Expression.Convert(parameterExpression2, customEffectType), propertyInfo);
			Expression right = ((!(propertyInfo.PropertyType == typeof(bool))) ? ((Expression)Expression.Convert(parameterExpression, propertyInfo.PropertyType)) : ((Expression)Expression.NotEqual(parameterExpression, Expression.Constant(0))));
			return Expression.Lambda<SetValueFastDelegate<T>>(Expression.Assign(left, right), new ParameterExpression[2] { parameterExpression2, parameterExpression }).Compile();
		}

		private static MethodInfo FindExplicitConverstion(Type sourceType, Type targetType)
		{
			if (sourceType == targetType)
			{
				return null;
			}
			List<MethodInfo> list = new List<MethodInfo>();
			Type type = sourceType;
			while (type != null)
			{
				list.AddRange(type.GetTypeInfo().DeclaredMethods);
				type = type.GetTypeInfo().BaseType;
			}
			type = targetType;
			while (type != null)
			{
				list.AddRange(type.GetTypeInfo().DeclaredMethods);
				type = type.GetTypeInfo().BaseType;
			}
			foreach (MethodInfo item in list)
			{
				if (item.Name == "op_Explicit" && item.ReturnType == targetType && IsAssignableFrom(item.GetParameters()[0].ParameterType, sourceType))
				{
					return item;
				}
			}
			return null;
		}

		[DllImport("ole32.dll", ExactSpelling = true)]
		private static extern Result CoCreateInstance([In][MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, IntPtr pUnkOuter, CLSCTX dwClsContext, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr comObject);

		internal static void CreateComInstance(Guid clsid, CLSCTX clsctx, Guid riid, ComObject comObject)
		{
			CoCreateInstance(clsid, IntPtr.Zero, clsctx, riid, out var comObject2).CheckError();
			comObject.NativePointer = comObject2;
		}

		internal static bool TryCreateComInstance(Guid clsid, CLSCTX clsctx, Guid riid, ComObject comObject)
		{
			IntPtr comObject2;
			Result result = CoCreateInstance(clsid, IntPtr.Zero, clsctx, riid, out comObject2);
			comObject.NativePointer = comObject2;
			return result.Success;
		}

		[DllImport("kernel32.dll", SetLastError = true)]
		internal static extern bool CloseHandle(IntPtr handle);

		public static IntPtr GetProcAddress(IntPtr handle, string dllFunctionToImport)
		{
			IntPtr procAddress_ = GetProcAddress_(handle, dllFunctionToImport);
			if (procAddress_ == IntPtr.Zero)
			{
				throw new SharpDXException(dllFunctionToImport);
			}
			return procAddress_;
		}

		[DllImport("kernel32", CharSet = CharSet.Ansi, EntryPoint = "GetProcAddress", ExactSpelling = true, SetLastError = true)]
		private static extern IntPtr GetProcAddress_(IntPtr hModule, string procName);

		public static int ComputeHashFNVModified(byte[] data)
		{
			uint num = 2166136261u;
			foreach (byte b in data)
			{
				num = (num ^ b) * 16777619;
			}
			num += num << 13;
			num ^= num >> 7;
			num += num << 3;
			num ^= num >> 17;
			return (int)(num + (num << 5));
		}

		public static void Dispose<T>(ref T comObject) where T : class, IDisposable
		{
			if (comObject != null)
			{
				comObject.Dispose();
				comObject = null;
			}
		}

		public static T[] ToArray<T>(IEnumerable<T> source)
		{
			return new Buffer<T>(source).ToArray();
		}

		public static bool Any<T>(IEnumerable<T> source)
		{
			return source.GetEnumerator().MoveNext();
		}

		public static IEnumerable<TResult> SelectMany<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
		{
			foreach (TSource item in source)
			{
				foreach (TResult item2 in selector(item))
				{
					yield return item2;
				}
			}
		}

		public static IEnumerable<TSource> Distinct<TSource>(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer = null)
		{
			if (comparer == null)
			{
				comparer = EqualityComparer<TSource>.Default;
			}
			Dictionary<TSource, object> values = new Dictionary<TSource, object>(comparer);
			foreach (TSource item in source)
			{
				if (!values.ContainsKey(item))
				{
					values.Add(item, null);
					yield return item;
				}
			}
		}

		public static bool IsTypeInheritFrom(Type type, string parentType)
		{
			while (type != null)
			{
				if (type.FullName == parentType)
				{
					return true;
				}
				type = type.GetTypeInfo().BaseType;
			}
			return false;
		}
	}
}
namespace SharpDX.Win32
{
	public struct BitmapInfoHeader
	{
		public int SizeInBytes;

		public int Width;

		public int Height;

		public short PlaneCount;

		public short BitCount;

		public int Compression;

		public int SizeImage;

		public int XPixelsPerMeter;

		public int YPixelsPerMeter;

		public int ColorUsedCount;

		public int ColorImportantCount;
	}
	public class ComBaseStreamNative
	{
		public IDisposable Callback { get; set; }
	}
	internal class ComStreamBaseShadow : ComObjectShadow
	{
		internal class ComStreamBaseVtbl : ComObjectVtbl
		{
			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate int ReadDelegate(IntPtr thisPtr, IntPtr buffer, int sizeOfBytes, out int bytesRead);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate int WriteDelegate(IntPtr thisPtr, IntPtr buffer, int sizeOfBytes, out int bytesWrite);

			public ComStreamBaseVtbl(int numberOfMethods)
				: base(numberOfMethods + 2)
			{
				AddMethod(new ReadDelegate(ReadImpl));
				AddMethod(new WriteDelegate(WriteImpl));
			}

			private static int ReadImpl(IntPtr thisPtr, IntPtr buffer, int sizeOfBytes, out int bytesRead)
			{
				bytesRead = 0;
				try
				{
					IStream stream = (IStream)CppObjectShadow.ToShadow<ComStreamBaseShadow>(thisPtr).Callback;
					bytesRead = stream.Read(buffer, sizeOfBytes);
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}

			private static int WriteImpl(IntPtr thisPtr, IntPtr buffer, int sizeOfBytes, out int bytesWrite)
			{
				bytesWrite = 0;
				try
				{
					IStream stream = (IStream)CppObjectShadow.ToShadow<ComStreamBaseShadow>(thisPtr).Callback;
					bytesWrite = stream.Write(buffer, sizeOfBytes);
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}
		}

		private static readonly ComStreamBaseVtbl Vtbl = new ComStreamBaseVtbl(0);

		protected override CppObjectVtbl GetVtbl => Vtbl;
	}
	[Guid("0000000c-0000-0000-C000-000000000046")]
	internal class ComStreamProxy : CallbackBase, IStream, IStreamBase, IUnknown, ICallbackable, IDisposable
	{
		private Stream sourceStream;

		private byte[] tempBuffer = new byte[4096];

		public ComStreamProxy(Stream sourceStream)
		{
			this.sourceStream = sourceStream;
		}

		public unsafe int Read(IntPtr buffer, int numberOfBytesToRead)
		{
			int num = 0;
			while (numberOfBytesToRead > 0)
			{
				int count = Math.Min(numberOfBytesToRead, tempBuffer.Length);
				int num2 = sourceStream.Read(tempBuffer, 0, count);
				if (num2 == 0)
				{
					return num;
				}
				Utilities.Write(new IntPtr(num + (byte*)(void*)buffer), tempBuffer, 0, num2);
				numberOfBytesToRead -= num2;
				num += num2;
			}
			return num;
		}

		public unsafe int Write(IntPtr buffer, int numberOfBytesToWrite)
		{
			int num = 0;
			while (numberOfBytesToWrite > 0)
			{
				int num2 = Math.Min(numberOfBytesToWrite, tempBuffer.Length);
				Utilities.Read(new IntPtr(num + (byte*)(void*)buffer), tempBuffer, 0, num2);
				sourceStream.Write(tempBuffer, 0, num2);
				numberOfBytesToWrite -= num2;
				num += num2;
			}
			return num;
		}

		public long Seek(long offset, SeekOrigin origin)
		{
			return sourceStream.Seek(offset, origin);
		}

		public void SetSize(long newSize)
		{
		}

		public unsafe long CopyTo(IStream streamDest, long numberOfBytesToCopy, out long bytesWritten)
		{
			bytesWritten = 0L;
			fixed (byte* ptr = tempBuffer)
			{
				void* ptr2 = ptr;
				while (numberOfBytesToCopy > 0)
				{
					int count = (int)Math.Min(numberOfBytesToCopy, tempBuffer.Length);
					int num = sourceStream.Read(tempBuffer, 0, count);
					if (num == 0)
					{
						break;
					}
					streamDest.Write((IntPtr)ptr2, num);
					numberOfBytesToCopy -= num;
					bytesWritten += num;
				}
			}
			return bytesWritten;
		}

		public void Commit(CommitFlags commitFlags)
		{
			sourceStream.Flush();
		}

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

		public void LockRegion(long offset, long numberOfBytesToLock, LockType dwLockType)
		{
			throw new NotImplementedException();
		}

		public void UnlockRegion(long offset, long numberOfBytesToLock, LockType dwLockType)
		{
			throw new NotImplementedException();
		}

		public StorageStatistics GetStatistics(StorageStatisticsFlags storageStatisticsFlags)
		{
			long num = sourceStream.Length;
			if (num == 0L)
			{
				num = 2147483647L;
			}
			StorageStatistics result = default(StorageStatistics);
			result.Type = 2;
			result.CbSize = num;
			result.GrfLocksSupported = 2;
			result.GrfMode = 2;
			return result;
		}

		public IStream Clone()
		{
			return new ComStreamProxy(sourceStream);
		}

		protected override void Dispose(bool disposing)
		{
			sourceStream = null;
			base.Dispose(disposing);
		}
	}
	internal class ComStreamShadow : ComStreamBaseShadow
	{
		private class ComStreamVtbl : ComStreamBaseVtbl
		{
			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate int SeekDelegate(IntPtr thisPtr, long offset, SeekOrigin origin, IntPtr newPosition);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result SetSizeDelegate(IntPtr thisPtr, long newSize);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate int CopyToDelegate(IntPtr thisPtr, IntPtr streamPointer, long numberOfBytes, out long numberOfBytesRead, out long numberOfBytesWritten);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result CommitDelegate(IntPtr thisPtr, CommitFlags flags);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result RevertDelegate(IntPtr thisPtr);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result LockRegionDelegate(IntPtr thisPtr, long offset, long numberOfBytes, LockType lockType);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result UnlockRegionDelegate(IntPtr thisPtr, long offset, long numberOfBytes, LockType lockType);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result StatDelegate(IntPtr thisPtr, ref StorageStatistics.__Native statisticsPtr, StorageStatisticsFlags flags);

			[UnmanagedFunctionPointer(CallingConvention.StdCall)]
			private delegate Result CloneDelegate(IntPtr thisPtr, out IntPtr streamPointer);

			public ComStreamVtbl()
				: base(9)
			{
				AddMethod(new SeekDelegate(SeekImpl));
				AddMethod(new SetSizeDelegate(SetSizeImpl));
				AddMethod(new CopyToDelegate(CopyToImpl));
				AddMethod(new CommitDelegate(CommitImpl));
				AddMethod(new RevertDelegate(RevertImpl));
				AddMethod(new LockRegionDelegate(LockRegionImpl));
				AddMethod(new UnlockRegionDelegate(UnlockRegionImpl));
				AddMethod(new StatDelegate(StatImpl));
				AddMethod(new CloneDelegate(CloneImpl));
			}

			private unsafe static int SeekImpl(IntPtr thisPtr, long offset, SeekOrigin origin, IntPtr newPosition)
			{
				try
				{
					long num = ((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).Seek(offset, origin);
					if (newPosition != IntPtr.Zero)
					{
						*(long*)(void*)newPosition = num;
					}
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}

			private static Result SetSizeImpl(IntPtr thisPtr, long newSize)
			{
				Result result = Result.Ok;
				try
				{
					((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).SetSize(newSize);
				}
				catch (SharpDXException ex)
				{
					result = ex.ResultCode;
				}
				catch (Exception)
				{
					result = Result.Fail.Code;
				}
				return result;
			}

			private static int CopyToImpl(IntPtr thisPtr, IntPtr streamPointer, long numberOfBytes, out long numberOfBytesRead, out long numberOfBytesWritten)
			{
				numberOfBytesRead = 0L;
				numberOfBytesWritten = 0L;
				try
				{
					IStream stream = (IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback;
					numberOfBytesRead = stream.CopyTo(new ComStream(streamPointer), numberOfBytes, out numberOfBytesWritten);
				}
				catch (Exception ex)
				{
					return (int)Result.GetResultFromException(ex);
				}
				return Result.Ok.Code;
			}

			private static Result CommitImpl(IntPtr thisPtr, CommitFlags flags)
			{
				Result result = Result.Ok;
				try
				{
					((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).Commit(flags);
				}
				catch (SharpDXException ex)
				{
					result = ex.ResultCode;
				}
				catch (Exception)
				{
					result = Result.Fail.Code;
				}
				return result;
			}

			private static Result RevertImpl(IntPtr thisPtr)
			{
				Result result = Result.Ok;
				try
				{
					((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).Revert();
				}
				catch (SharpDXException ex)
				{
					result = ex.ResultCode;
				}
				catch (Exception)
				{
					result = Result.Fail.Code;
				}
				return result;
			}

			private static Result LockRegionImpl(IntPtr thisPtr, long offset, long numberOfBytes, LockType lockType)
			{
				Result result = Result.Ok;
				try
				{
					((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).LockRegion(offset, numberOfBytes, lockType);
				}
				catch (SharpDXException ex)
				{
					result = ex.ResultCode;
				}
				catch (Exception)
				{
					result = Result.Fail.Code;
				}
				return result;
			}

			private static Result UnlockRegionImpl(IntPtr thisPtr, long offset, long numberOfBytes, LockType lockType)
			{
				Result result = Result.Ok;
				try
				{
					((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).UnlockRegion(offset, numberOfBytes, lockType);
				}
				catch (SharpDXException ex)
				{
					result = ex.ResultCode;
				}
				catch (Exception)
				{
					result = Result.Fail.Code;
				}
				return result;
			}

			private static Result StatImpl(IntPtr thisPtr, ref StorageStatistics.__Native statisticsPtr, StorageStatisticsFlags flags)
			{
				try
				{
					((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).GetStatistics(flags).__MarshalTo(ref statisticsPtr);
				}
				catch (SharpDXException ex)
				{
					return ex.ResultCode;
				}
				catch (Exception)
				{
					return Result.Fail.Code;
				}
				return Result.Ok;
			}

			private static Result CloneImpl(IntPtr thisPtr, out IntPtr streamPointer)
			{
				streamPointer = IntPtr.Zero;
				Result result = Result.Ok;
				try
				{
					IStream stream = ((IStream)CppObjectShadow.ToShadow<ComStreamShadow>(thisPtr).Callback).Clone();
					streamPointer = ToIntPtr(stream);
				}
				catch (SharpDXException ex)
				{
					result = ex.ResultCode;
				}
				catch (Exception)
				{
					result = Result.Fail.Code;
				}
				return result;
			}
		}

		private static readonly ComStreamVtbl Vtbl = new ComStreamVtbl();

		protected override CppObjectVtbl GetVtbl => Vtbl;

		public static IntPtr ToIntPtr(IS

BepInEx/plugins/ControllerSupport.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using SharpDX.XInput;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.LowLevel;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ControllerSupport")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7b336df3d9ee6ee5b96127d759c5284f2f9b670b")]
[assembly: AssemblyProduct("ControllerSupport")]
[assembly: AssemblyTitle("ControllerSupport")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ControllerSupport
{
	public class ConfigManager
	{
		private ConfigFile _config;

		private ConfigEntry<float> _scrollSpeedConfig;

		private ConfigEntry<float> _deadZoneRadiusConfig;

		private ConfigEntry<float> _diagonalZoneSizeConfig;

		public float MouseSensitivity { get; private set; }

		public float ScrollSpeed { get; private set; }

		public float DeadZoneRadius { get; private set; }

		public float DiagonalZoneSize { get; private set; }

		public bool EnableTabToggle { get; private set; }

		public bool EnableCtrlToggle { get; private set; }

		public bool EnableShiftToggle { get; private set; }

		public bool ReleaseTabOnShift { get; private set; }

		public bool ReleaseCtrlOnShift { get; private set; }

		public bool ReleaseCtrlOnA { get; private set; }

		public bool AutoReleaseShiftAfterWASD { get; private set; }

		public float ShiftReleaseDelay { get; private set; }

		public bool DebugOutput { get; private set; }

		public bool DevMode { get; private set; }

		public float CurrentJoystickX { get; set; }

		public float CurrentJoystickY { get; set; }

		public float CurrentJoystickAngle { get; set; }

		public ConfigManager(ConfigFile config)
		{
			_config = config;
			string configFilePath = config.ConfigFilePath;
			MouseSensitivity = config.Bind<float>("Mouse Controls", "MouseSensitivity", 10f, "Sensitivity of the right stick for mouse movement. Higher values make the mouse move faster.").Value;
			_scrollSpeedConfig = config.Bind<float>("Mouse Controls", "ScrollSpeed", 0.0021f, "Adjust the scroll speed for bumper buttons (RB/LB). Lower values result in slower scrolling, higher values in faster scrolling.");
			ScrollSpeed = _scrollSpeedConfig.Value;
			_deadZoneRadiusConfig = config.Bind<float>("Movement Controls", "DeadZoneRadius", 0.25f, "Radius of the center dead zone for the left joystick (0.0 to 1.0). Higher values require more joystick movement before keys are pressed.");
			_diagonalZoneSizeConfig = config.Bind<float>("Movement Controls", "DiagonalZoneSize", 0.7071f, "Size of the diagonal zones for the left joystick (0.5 to 1.0). Higher values make diagonal movement more likely.");
			DeadZoneRadius = _deadZoneRadiusConfig.Value;
			DiagonalZoneSize = _diagonalZoneSizeConfig.Value;
			EnableTabToggle = config.Bind<bool>("Toggle Controls", "EnableMapToggle", true, "Enable toggle functionality for the Map key (Back button).").Value;
			EnableCtrlToggle = config.Bind<bool>("Toggle Controls", "EnableCrouchToggle", true, "Enable toggle functionality for the Crouch key (B button).").Value;
			EnableShiftToggle = config.Bind<bool>("Toggle Controls", "EnableRunToggle", false, "Enable toggle functionality for the Run key (L3 button).").Value;
			ReleaseTabOnShift = config.Bind<bool>("Key Interactions", "ReleaseMapOnRun", true, "When enabled, pressing Run will automatically release Map if active.").Value;
			ReleaseCtrlOnShift = config.Bind<bool>("Key Interactions", "ReleaseCrouchOnRun", true, "When enabled, activating Run will automatically release Crouch.").Value;
			ReleaseCtrlOnA = config.Bind<bool>("Key Interactions", "ReleaseCrouchOnJump", true, "When enabled, pressing Jump will automatically release Crouch.").Value;
			AutoReleaseShiftAfterWASD = config.Bind<bool>("Key Interactions", "AutoReleaseRunAfterWASD", true, "Automatically release Run after WASD inactivity.").Value;
			ShiftReleaseDelay = config.Bind<float>("Key Interactions", "RunReleaseDelay", 0.5f, "Delay before auto-releasing Run (seconds).").Value;
			DebugOutput = config.Bind<bool>("Debug", "EnableDebugOutput", false, "Enable detailed debug logging.").Value;
			DevMode = config.Bind<bool>("Debug", "DevMode", false, "Enable developer tools with numpad controls.").Value;
			InjectAboutSection(configFilePath);
		}

		private void InjectAboutSection(string configPath)
		{
			string[] source = new string[16]
			{
				"5b41626f75745d", "2323204e65787573204d6f6473204c696e6b2e", "232053657474696e6720747970653a20537472696e67", "232044656661756c742076616c75653a2068747470733a2f2f7777772e6e657875736d6f64732e636f6d2f7265706f2f6d6f64732f3439", "4e65787573203d2068747470733a2f2f7777772e6e657875736d6f64732e636f6d2f7265706f2f6d6f64732f3439", "", "2323205468756e64657273746f7265204c696e6b2e", "232053657474696e6720747970653a20537472696e67", "232044656661756c742076616c75653a2068747470733a2f2f7468756e64657273746f72652e696f2f632f7265706f2f702f5061636d616e6e696e6a613939382f436f6e74726f6c6c65725f537570706f72742f", "5468756e64657273746f7265203d2068747470733a2f2f7468756e64657273746f72652e696f2f632f7265706f2f702f5061636d616e6e696e6a613939382f436f6e74726f6c6c65725f537570706f72742f",
				"", "232320476974687562204c696e6b2e", "232053657474696e6720747970653a20537472696e67", "232044656661756c742076616c75653a2068747470733a2f2f6769746875622e636f6d2f5061636d616e6e696e6a612f522e452e502e4f2e436f6e74726f6c6c6572537570706f7274", "476974687562203d2068747470733a2f2f6769746875622e636f6d2f5061636d616e6e696e6a612f522e452e502e4f2e436f6e74726f6c6c6572537570706f7274", ""
			};
			try
			{
				if (!File.Exists(configPath))
				{
					return;
				}
				List<string> list = File.ReadAllLines(configPath).ToList();
				int num = list.FindIndex((string l) => l.Trim().Equals("[About]", StringComparison.OrdinalIgnoreCase));
				if (num != -1)
				{
					int num2 = list.FindIndex(num + 1, (string l) => l.StartsWith("[") && !l.Trim().Equals("[About]", StringComparison.OrdinalIgnoreCase));
					if (num2 == -1)
					{
						num2 = list.Count;
					}
					list.RemoveRange(num, num2 - num);
				}
				int i;
				for (i = 0; i < list.Count && (list[i].StartsWith("##") || string.IsNullOrWhiteSpace(list[i])); i++)
				{
				}
				list.InsertRange(i, source.Select(DecodeHexLine));
				File.WriteAllLines(configPath, list);
			}
			catch (Exception)
			{
				_ = Debugger.IsAttached;
			}
		}

		private static string DecodeHexLine(string hex)
		{
			if (string.IsNullOrWhiteSpace(hex))
			{
				return "";
			}
			byte[] array = new byte[hex.Length / 2];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
			}
			return Encoding.UTF8.GetString(array);
		}

		public float IncreaseScrollSpeed()
		{
			ScrollSpeed += 0.0001f;
			_scrollSpeedConfig.Value = ScrollSpeed;
			return ScrollSpeed;
		}

		public float DecreaseScrollSpeed()
		{
			ScrollSpeed -= 0.0001f;
			if (ScrollSpeed < 0.0001f)
			{
				ScrollSpeed = 0.0001f;
			}
			_scrollSpeedConfig.Value = ScrollSpeed;
			return ScrollSpeed;
		}

		public float UpdateDeadZoneRadius(float magnitude)
		{
			DeadZoneRadius = magnitude;
			_deadZoneRadiusConfig.Value = DeadZoneRadius;
			return DeadZoneRadius;
		}

		public float UpdateDiagonalZoneSize(float angle)
		{
			DiagonalZoneSize = angle;
			_diagonalZoneSizeConfig.Value = DiagonalZoneSize;
			return DiagonalZoneSize;
		}
	}
	[BepInPlugin("pacmanninja998.nexus.ControllerSupport", "Controller Support", "1.0.0")]
	public class ControllerSupportPlugin : BaseUnityPlugin
	{
		private ManualLogSource _logger;

		private InputManager _inputManager;

		private ConfigManager _configManager;

		private void Awake()
		{
			_logger = ((BaseUnityPlugin)this).Logger;
			_logger.LogInfo((object)"Controller Support plugin loaded!");
			_configManager = new ConfigManager(((BaseUnityPlugin)this).Config);
			_inputManager = new InputManager(_logger, _configManager);
			InputSystem.onBeforeUpdate += OnInputSystemUpdate;
		}

		private void Update()
		{
			_inputManager.Update();
		}

		private void OnInputSystemUpdate()
		{
			if (_inputManager != null)
			{
				_inputManager.Update();
			}
		}

		private void OnDestroy()
		{
			if (Keyboard.current != null && _inputManager != null)
			{
				_inputManager.ReleaseAllKeys();
			}
		}
	}
	public class InputManager
	{
		private readonly ManualLogSource _logger;

		private readonly ConfigManager _configManager;

		private readonly Controller _controller;

		private readonly KeyboardSimulator _keyboardSimulator;

		private readonly MouseSimulator _mouseSimulator;

		private readonly JoystickZoneHandler _joystickZoneHandler;

		private State _previousState;

		private bool _isControllerConnected;

		[DllImport("user32.dll")]
		private static extern bool SetForegroundWindow(IntPtr hWnd);

		[DllImport("user32.dll")]
		private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);

		[DllImport("user32.dll")]
		private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

		[DllImport("user32.dll")]
		private static extern IntPtr GetForegroundWindow();

		[DllImport("user32.dll")]
		private static extern uint GetCurrentThreadId();

		[DllImport("user32.dll")]
		private static extern bool BringWindowToTop(IntPtr hWnd);

		[DllImport("user32.dll")]
		private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

		public InputManager(ManualLogSource logger, ConfigManager configManager)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			_logger = logger;
			_configManager = configManager;
			_controller = new Controller((UserIndex)0);
			_keyboardSimulator = new KeyboardSimulator(logger, configManager);
			_mouseSimulator = new MouseSimulator(logger, configManager);
			_joystickZoneHandler = new JoystickZoneHandler(logger, configManager, _keyboardSimulator);
			_isControllerConnected = _controller.IsConnected;
			if (_isControllerConnected)
			{
				_logger.LogInfo((object)"Controller connected!");
				_previousState = _controller.GetState();
			}
			else
			{
				_logger.LogWarning((object)"No controller connected. Waiting for connection...");
			}
		}

		public void Update()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			ProcessDevInputs();
			bool isControllerConnected = _isControllerConnected;
			_isControllerConnected = _controller.IsConnected;
			if (_isControllerConnected && !isControllerConnected)
			{
				_logger.LogInfo((object)"Controller connected!");
				_previousState = _controller.GetState();
			}
			if (!_isControllerConnected && isControllerConnected)
			{
				_logger.LogWarning((object)"Controller disconnected!");
				ReleaseAllKeys();
			}
			else
			{
				if (!_isControllerConnected)
				{
					return;
				}
				try
				{
					State state = _controller.GetState();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)$"Left Stick: X={state.Gamepad.LeftThumbX}, Y={state.Gamepad.LeftThumbY}");
						_logger.LogInfo((object)$"Right Stick: X={state.Gamepad.RightThumbX}, Y={state.Gamepad.RightThumbY}");
						_logger.LogInfo((object)$"Triggers: Left={state.Gamepad.LeftTrigger}, Right={state.Gamepad.RightTrigger}");
						_logger.LogInfo((object)$"Buttons: {state.Gamepad.Buttons}");
					}
					ProcessButtonInputs(state);
					ProcessJoystickInputs(state);
					ProcessTriggerInputs(state);
					_previousState = state;
					if (!_configManager.AutoReleaseShiftAfterWASD || !_keyboardSimulator.IsShiftPressed || !(Time.realtimeSinceStartup - _joystickZoneHandler.LastWASDActivityTime > _configManager.ShiftReleaseDelay))
					{
						return;
					}
					if (_configManager.EnableShiftToggle)
					{
						if (_keyboardSimulator.IsShiftPressed)
						{
							_keyboardSimulator.ToggleShift();
							if (_configManager.DebugOutput)
							{
								_logger.LogInfo((object)"Auto-released Shift after WASD inactivity");
							}
						}
					}
					else
					{
						_keyboardSimulator.SendKeyEvent((Key)51, isPressed: false);
						if (_configManager.DebugOutput)
						{
							_logger.LogInfo((object)"Auto-released Shift after WASD inactivity");
						}
					}
				}
				catch (Exception ex)
				{
					_logger.LogError((object)("Error reading controller: " + ex.Message));
					_isControllerConnected = false;
					ReleaseAllKeys();
				}
			}
		}

		private void ForceForegroundWindow(IntPtr hWnd)
		{
			if (!(hWnd == IntPtr.Zero))
			{
				uint windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
				uint currentThreadId = GetCurrentThreadId();
				if (windowThreadProcessId != currentThreadId)
				{
					AttachThreadInput(windowThreadProcessId, currentThreadId, fAttach: true);
					BringWindowToTop(hWnd);
					ShowWindow(hWnd, 5);
					AttachThreadInput(windowThreadProcessId, currentThreadId, fAttach: false);
				}
				else
				{
					BringWindowToTop(hWnd);
					ShowWindow(hWnd, 5);
				}
			}
		}

		private bool ActivateREPOProcess()
		{
			try
			{
				Process[] processesByName = Process.GetProcessesByName("REPO");
				if (processesByName.Length == 0)
				{
					if (_configManager.DebugOutput)
					{
						_logger.LogWarning((object)"No REPO.exe process found.");
					}
					return false;
				}
				Process process = null;
				process = processesByName.OrderByDescending((Process p) => p.WorkingSet64).FirstOrDefault((Process p) => p.MainWindowHandle != IntPtr.Zero);
				if (process != null)
				{
					ForceForegroundWindow(process.MainWindowHandle);
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)$"Activated main REPO.exe process (PID: {process.Id}, Memory: {process.WorkingSet64 / 1024 / 1024} MB)");
					}
					return true;
				}
				process = processesByName.FirstOrDefault((Process p) => p.MainWindowHandle != IntPtr.Zero);
				if (process != null)
				{
					ForceForegroundWindow(process.MainWindowHandle);
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)$"Activated REPO.exe process (PID: {process.Id})");
					}
					return true;
				}
				if (_configManager.DebugOutput)
				{
					_logger.LogWarning((object)"Could not find a valid window handle for any REPO.exe process.");
				}
				return false;
			}
			catch (Exception ex)
			{
				_logger.LogError((object)("Error activating REPO.exe process: " + ex.Message));
				return false;
			}
		}

		private void ProcessDevInputs()
		{
			if (_configManager.DevMode)
			{
				if (((ButtonControl)Keyboard.current[(Key)80]).wasPressedThisFrame)
				{
					float num = _configManager.IncreaseScrollSpeed();
					_logger.LogInfo((object)$"Increased ScrollSpeed to {num:F6}");
				}
				if (((ButtonControl)Keyboard.current[(Key)81]).wasPressedThisFrame)
				{
					float num2 = _configManager.DecreaseScrollSpeed();
					_logger.LogInfo((object)$"Decreased ScrollSpeed to {num2:F6}");
				}
				if (((ButtonControl)Keyboard.current[(Key)91]).wasPressedThisFrame)
				{
					float magnitude = (float)Math.Sqrt(_configManager.CurrentJoystickX * _configManager.CurrentJoystickX + _configManager.CurrentJoystickY * _configManager.CurrentJoystickY);
					float num3 = _configManager.UpdateDeadZoneRadius(magnitude);
					_logger.LogInfo((object)$"Updated DeadZoneRadius to {num3:F4} based on current joystick position");
				}
				if (((ButtonControl)Keyboard.current[(Key)88]).wasPressedThisFrame)
				{
					float num4 = _configManager.UpdateDiagonalZoneSize(_configManager.CurrentJoystickAngle);
					_logger.LogInfo((object)$"Updated DiagonalZoneSize to {num4:F4} based on current joystick angle");
				}
			}
		}

		private void ProcessButtonInputs(State state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0610: Unknown result type (might be due to invalid IL or missing references)
			//IL_0615: Unknown result type (might be due to invalid IL or missing references)
			//IL_061b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0640: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_064c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0629: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_069c: Unknown result type (might be due to invalid IL or missing references)
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0660: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0713: Unknown result type (might be due to invalid IL or missing references)
			//IL_0714: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_0720: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0746: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_074c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0753: Unknown result type (might be due to invalid IL or missing references)
			//IL_072e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0735: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0800: Unknown result type (might be due to invalid IL or missing references)
			//IL_0764: Unknown result type (might be due to invalid IL or missing references)
			//IL_076b: Unknown result type (might be due to invalid IL or missing references)
			//IL_080e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0815: Unknown result type (might be due to invalid IL or missing references)
			if ((state.Gamepad.Buttons & 0x1000) != 0 && (_previousState.Gamepad.Buttons & 0x1000) == 0)
			{
				if (_configManager.ReleaseCtrlOnA && _keyboardSimulator.IsCtrlToggled)
				{
					_keyboardSimulator.ToggleCtrl();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)"Released Ctrl due to A button press");
					}
				}
				_keyboardSimulator.SendKeyEvent((Key)1, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"A pressed - Space");
				}
			}
			else if ((state.Gamepad.Buttons & 0x1000) == 0 && (_previousState.Gamepad.Buttons & 0x1000) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)1, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 0x4000) != 0 && (_previousState.Gamepad.Buttons & 0x4000) == 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)19, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"X pressed - E");
				}
			}
			else if ((state.Gamepad.Buttons & 0x4000) == 0 && (_previousState.Gamepad.Buttons & 0x4000) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)19, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 0x2000) != 0 && (_previousState.Gamepad.Buttons & 0x2000) == 0)
			{
				if (_configManager.EnableCtrlToggle)
				{
					_keyboardSimulator.ToggleCtrl();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)("B pressed - Ctrl " + (_keyboardSimulator.IsCtrlToggled ? "ON" : "OFF")));
					}
				}
				else
				{
					_keyboardSimulator.SendKeyEvent((Key)55, isPressed: true);
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)"B pressed - Ctrl");
					}
				}
			}
			else if ((state.Gamepad.Buttons & 0x2000) == 0 && (_previousState.Gamepad.Buttons & 0x2000) != 0 && !_configManager.EnableCtrlToggle)
			{
				_keyboardSimulator.SendKeyEvent((Key)55, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 0x8000) != 0 && (_previousState.Gamepad.Buttons & 0x8000) == 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)31, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"Y pressed - Q");
				}
			}
			else if ((state.Gamepad.Buttons & 0x8000) == 0 && (_previousState.Gamepad.Buttons & 0x8000) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)31, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 0x40) != 0 && (_previousState.Gamepad.Buttons & 0x40) == 0)
			{
				if (_configManager.ReleaseCtrlOnShift && _keyboardSimulator.IsCtrlToggled)
				{
					_keyboardSimulator.ToggleCtrl();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)"Released Ctrl due to Shift activation");
					}
				}
				if (_configManager.ReleaseTabOnShift && _keyboardSimulator.IsTabToggled)
				{
					_keyboardSimulator.ToggleTab();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)"Released Tab due to Shift activation");
					}
				}
				if (_configManager.EnableShiftToggle)
				{
					_keyboardSimulator.ToggleShift();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)("L3 pressed - Shift " + (_keyboardSimulator.IsShiftPressed ? "ON" : "OFF")));
					}
				}
				else
				{
					_keyboardSimulator.SendKeyEvent((Key)51, isPressed: true);
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)"L3 pressed - Shift ON");
					}
				}
			}
			else if ((state.Gamepad.Buttons & 0x40) == 0 && (_previousState.Gamepad.Buttons & 0x40) != 0 && !_configManager.EnableShiftToggle)
			{
				_keyboardSimulator.SendKeyEvent((Key)51, isPressed: false);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"L3 released - Shift OFF");
				}
			}
			if ((state.Gamepad.Buttons & 0x200) != 0)
			{
				_mouseSimulator.Scroll(_configManager.ScrollSpeed);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)$"RB held - Scroll Up ({_configManager.ScrollSpeed})");
				}
			}
			if ((state.Gamepad.Buttons & 0x100) != 0)
			{
				_mouseSimulator.Scroll(0f - _configManager.ScrollSpeed);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)$"LB held - Scroll Down ({0f - _configManager.ScrollSpeed})");
				}
			}
			if ((state.Gamepad.Buttons & 4) != 0 && (_previousState.Gamepad.Buttons & 4) == 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)41, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"D-Pad Left - 1");
				}
			}
			else if ((state.Gamepad.Buttons & 4) == 0 && (_previousState.Gamepad.Buttons & 4) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)41, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 1) != 0 && (_previousState.Gamepad.Buttons & 1) == 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)42, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"D-Pad Up - 2");
				}
			}
			else if ((state.Gamepad.Buttons & 1) == 0 && (_previousState.Gamepad.Buttons & 1) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)42, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 8) != 0 && (_previousState.Gamepad.Buttons & 8) == 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)43, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"D-Pad Right - 3");
				}
			}
			else if ((state.Gamepad.Buttons & 8) == 0 && (_previousState.Gamepad.Buttons & 8) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)43, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 0x10) != 0 && (_previousState.Gamepad.Buttons & 0x10) == 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)60, isPressed: true);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"Start pressed - Escape");
				}
			}
			else if ((state.Gamepad.Buttons & 0x10) == 0 && (_previousState.Gamepad.Buttons & 0x10) != 0)
			{
				_keyboardSimulator.SendKeyEvent((Key)60, isPressed: false);
			}
			if ((state.Gamepad.Buttons & 0x20) != 0 && (_previousState.Gamepad.Buttons & 0x20) == 0)
			{
				if (_configManager.EnableTabToggle)
				{
					_keyboardSimulator.ToggleTab();
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)("Back pressed - Tab " + (_keyboardSimulator.IsTabToggled ? "ON" : "OFF")));
					}
				}
				else
				{
					_keyboardSimulator.SendKeyEvent((Key)3, isPressed: true);
					if (_configManager.DebugOutput)
					{
						_logger.LogInfo((object)"Back pressed - Tab");
					}
				}
			}
			else if ((state.Gamepad.Buttons & 0x20) == 0 && (_previousState.Gamepad.Buttons & 0x20) != 0 && !_configManager.EnableTabToggle)
			{
				_keyboardSimulator.SendKeyEvent((Key)3, isPressed: false);
			}
		}

		private void ProcessJoystickInputs(State state)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			_joystickZoneHandler.ProcessLeftJoystick(state.Gamepad.LeftThumbX, state.Gamepad.LeftThumbY);
			_mouseSimulator.MoveMouse(state.Gamepad.RightThumbX, state.Gamepad.RightThumbY);
		}

		private void ProcessTriggerInputs(State state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			if (state.Gamepad.RightTrigger > 128 && _previousState.Gamepad.RightTrigger <= 128)
			{
				ActivateREPOProcess();
				Thread.Sleep(10);
				_mouseSimulator.LeftMouseDown();
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"RT pressed - Left Mouse Down (after activating REPO)");
				}
			}
			else if (state.Gamepad.RightTrigger <= 128 && _previousState.Gamepad.RightTrigger > 128)
			{
				_mouseSimulator.LeftMouseUp();
			}
			if (state.Gamepad.LeftTrigger > 128 && _previousState.Gamepad.LeftTrigger <= 128)
			{
				_mouseSimulator.RightMouseDown();
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)"LT pressed - Right Mouse Down");
				}
			}
			else if (state.Gamepad.LeftTrigger <= 128 && _previousState.Gamepad.LeftTrigger > 128)
			{
				_mouseSimulator.RightMouseUp();
			}
		}

		public void ReleaseAllKeys()
		{
			_keyboardSimulator.ReleaseAllKeys();
			_mouseSimulator.ReleaseAllButtons();
		}
	}
	public class JoystickZoneHandler
	{
		private readonly ManualLogSource _logger;

		private readonly ConfigManager _configManager;

		private readonly KeyboardSimulator _keyboardSimulator;

		private float _lastX;

		private float _lastY;

		private bool _lastWPressed;

		private bool _lastAPressed;

		private bool _lastSPressed;

		private bool _lastDPressed;

		private float _lastWASDActivityTime;

		public float LastWASDActivityTime => _lastWASDActivityTime;

		public JoystickZoneHandler(ManualLogSource logger, ConfigManager configManager, KeyboardSimulator keyboardSimulator)
		{
			_logger = logger;
			_configManager = configManager;
			_keyboardSimulator = keyboardSimulator;
			_lastWASDActivityTime = Time.realtimeSinceStartup;
		}

		public void ProcessLeftJoystick(short x, short y)
		{
			float num = (float)x / 32768f;
			float num2 = (float)y / 32768f;
			_configManager.CurrentJoystickX = num;
			_configManager.CurrentJoystickY = num2;
			bool flag = Math.Abs(num - _lastX) > 0.01f || Math.Abs(num2 - _lastY) > 0.01f;
			_lastX = num;
			_lastY = num2;
			float num3 = (float)Math.Sqrt(num * num + num2 * num2);
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			bool flag5 = false;
			if (!(num3 < _configManager.DeadZoneRadius))
			{
				float num4 = (float)Math.Atan2(num2, num) * 180f / (float)Math.PI;
				if (num4 < 0f)
				{
					num4 += 360f;
				}
				_configManager.CurrentJoystickAngle = num4;
				if (num4 > 45f && num4 < 135f)
				{
					flag2 = true;
				}
				else if (num4 > 225f && num4 < 315f)
				{
					flag4 = true;
				}
				else if (num4 > 135f && num4 < 225f)
				{
					flag3 = true;
				}
				else if (num4 < 45f || num4 > 315f)
				{
					flag5 = true;
				}
				if (num4 > 45f && num4 < 75f)
				{
					flag2 = true;
					flag5 = true;
				}
				else if (num4 > 105f && num4 < 135f)
				{
					flag2 = true;
					flag3 = true;
				}
				else if (num4 > 225f && num4 < 255f)
				{
					flag4 = true;
					flag3 = true;
				}
				else if (num4 > 285f && num4 < 315f)
				{
					flag4 = true;
					flag5 = true;
				}
				if (flag && _configManager.DebugOutput)
				{
					_logger.LogInfo((object)$"Joystick: X={num:F2}, Y={num2:F2}, Angle={num4:F1}, Magnitude={num3:F2}");
				}
			}
			if (flag2 || flag3 || flag4 || flag5)
			{
				_lastWASDActivityTime = Time.realtimeSinceStartup;
			}
			if (flag2 != _lastWPressed)
			{
				_keyboardSimulator.SendKeyEvent((Key)37, flag2);
				_lastWPressed = flag2;
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)("W key " + (flag2 ? "pressed" : "released")));
				}
			}
			if (flag3 != _lastAPressed)
			{
				_keyboardSimulator.SendKeyEvent((Key)15, flag3);
				_lastAPressed = flag3;
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)("A key " + (flag3 ? "pressed" : "released")));
				}
			}
			if (flag4 != _lastSPressed)
			{
				_keyboardSimulator.SendKeyEvent((Key)33, flag4);
				_lastSPressed = flag4;
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)("S key " + (flag4 ? "pressed" : "released")));
				}
			}
			if (flag5 != _lastDPressed)
			{
				_keyboardSimulator.SendKeyEvent((Key)18, flag5);
				_lastDPressed = flag5;
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)("D key " + (flag5 ? "pressed" : "released")));
				}
			}
		}

		public void ReleaseAllDirectionKeys()
		{
			if (Keyboard.current != null)
			{
				if (_lastWPressed)
				{
					_keyboardSimulator.SendKeyEvent((Key)37, isPressed: false);
				}
				if (_lastAPressed)
				{
					_keyboardSimulator.SendKeyEvent((Key)15, isPressed: false);
				}
				if (_lastSPressed)
				{
					_keyboardSimulator.SendKeyEvent((Key)33, isPressed: false);
				}
				if (_lastDPressed)
				{
					_keyboardSimulator.SendKeyEvent((Key)18, isPressed: false);
				}
				_lastWPressed = false;
				_lastAPressed = false;
				_lastSPressed = false;
				_lastDPressed = false;
			}
		}
	}
	public class KeyboardSimulator
	{
		private readonly ManualLogSource _logger;

		private readonly ConfigManager _configManager;

		private bool _wPressed;

		private bool _aPressed;

		private bool _sPressed;

		private bool _dPressed;

		private bool _shiftPressed;

		private bool _ctrlToggled;

		private bool _tabToggled;

		public bool IsWPressed => _wPressed;

		public bool IsAPressed => _aPressed;

		public bool IsSPressed => _sPressed;

		public bool IsDPressed => _dPressed;

		public bool IsShiftPressed => _shiftPressed;

		public bool IsCtrlToggled => _ctrlToggled;

		public bool IsTabToggled => _tabToggled;

		public KeyboardSimulator(ManualLogSource logger, ConfigManager configManager)
		{
			_logger = logger;
			_configManager = configManager;
		}

		public void ToggleCtrl()
		{
			_ctrlToggled = !_ctrlToggled;
			SendKeyEvent((Key)55, _ctrlToggled);
		}

		public void ToggleTab()
		{
			_tabToggled = !_tabToggled;
			SendKeyEvent((Key)3, _tabToggled);
		}

		public void ToggleShift()
		{
			_shiftPressed = !_shiftPressed;
			SendKeyEvent((Key)51, _shiftPressed);
		}

		public void SendKeyEvent(Key key, bool isPressed)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (Keyboard.current != null)
			{
				UpdateKeyState(key, isPressed);
				KeyboardState val = default(KeyboardState);
				if (_wPressed)
				{
					((KeyboardState)(ref val)).Set((Key)37, true);
				}
				if (_aPressed)
				{
					((KeyboardState)(ref val)).Set((Key)15, true);
				}
				if (_sPressed)
				{
					((KeyboardState)(ref val)).Set((Key)33, true);
				}
				if (_dPressed)
				{
					((KeyboardState)(ref val)).Set((Key)18, true);
				}
				if (_shiftPressed)
				{
					((KeyboardState)(ref val)).Set((Key)51, true);
				}
				if (_ctrlToggled)
				{
					((KeyboardState)(ref val)).Set((Key)55, true);
				}
				if (_tabToggled)
				{
					((KeyboardState)(ref val)).Set((Key)3, true);
				}
				((KeyboardState)(ref val)).Set(key, isPressed);
				InputSystem.QueueStateEvent<KeyboardState>((InputDevice)(object)Keyboard.current, val, -1.0);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)string.Format("Key {0} {1}", key, isPressed ? "pressed" : "released"));
				}
			}
		}

		private void UpdateKeyState(Key key, bool isPressed)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			if ((int)key <= 18)
			{
				if ((int)key != 3)
				{
					if ((int)key != 15)
					{
						if ((int)key == 18)
						{
							_dPressed = isPressed;
						}
					}
					else
					{
						_aPressed = isPressed;
					}
				}
				else
				{
					_tabToggled = isPressed;
				}
			}
			else if ((int)key <= 37)
			{
				if ((int)key != 33)
				{
					if ((int)key == 37)
					{
						_wPressed = isPressed;
					}
				}
				else
				{
					_sPressed = isPressed;
				}
			}
			else if ((int)key != 51)
			{
				if ((int)key == 55)
				{
					_ctrlToggled = isPressed;
				}
			}
			else
			{
				_shiftPressed = isPressed;
			}
		}

		public void ReleaseAllKeys()
		{
			try
			{
				if (Keyboard.current != null)
				{
					if (_wPressed)
					{
						SendKeyEvent((Key)37, isPressed: false);
					}
					if (_aPressed)
					{
						SendKeyEvent((Key)15, isPressed: false);
					}
					if (_sPressed)
					{
						SendKeyEvent((Key)33, isPressed: false);
					}
					if (_dPressed)
					{
						SendKeyEvent((Key)18, isPressed: false);
					}
					if (_shiftPressed)
					{
						SendKeyEvent((Key)51, isPressed: false);
					}
					if (_ctrlToggled)
					{
						SendKeyEvent((Key)55, isPressed: false);
					}
					if (_tabToggled)
					{
						SendKeyEvent((Key)3, isPressed: false);
					}
					SendKeyEvent((Key)1, isPressed: false);
					SendKeyEvent((Key)19, isPressed: false);
					SendKeyEvent((Key)31, isPressed: false);
					SendKeyEvent((Key)41, isPressed: false);
					SendKeyEvent((Key)42, isPressed: false);
					SendKeyEvent((Key)43, isPressed: false);
					SendKeyEvent((Key)60, isPressed: false);
					SendKeyEvent((Key)3, isPressed: false);
				}
			}
			catch (ArgumentNullException ex)
			{
				if (_configManager.DebugOutput)
				{
					_logger.LogError((object)("Error releasing keys: " + ex.Message));
				}
			}
		}
	}
	public class MouseSimulator
	{
		[Flags]
		private enum MouseEventFlags
		{
			LeftDown = 2,
			LeftUp = 4,
			RightDown = 8,
			RightUp = 0x10,
			Wheel = 0x800,
			Move = 1
		}

		private readonly ManualLogSource _logger;

		private readonly ConfigManager _configManager;

		private float _scrollAccumulator;

		[DllImport("user32.dll")]
		private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

		public MouseSimulator(ManualLogSource logger, ConfigManager configManager)
		{
			_logger = logger;
			_configManager = configManager;
		}

		public void MoveMouse(short x, short y)
		{
			float num = (float)x / 32768f;
			float num2 = (float)y / 32768f;
			if (Math.Abs(num) > _configManager.DeadZoneRadius || Math.Abs(num2) > _configManager.DeadZoneRadius)
			{
				int num3 = (int)(num * _configManager.MouseSensitivity);
				int num4 = (int)((0f - num2) * _configManager.MouseSensitivity);
				mouse_event(1, num3, num4, 0, 0);
				if (_configManager.DebugOutput)
				{
					_logger.LogInfo((object)$"Mouse move: {num3}, {num4}");
				}
			}
		}

		public void LeftMouseDown()
		{
			mouse_event(2, 0, 0, 0, 0);
		}

		public void LeftMouseUp()
		{
			mouse_event(4, 0, 0, 0, 0);
		}

		public void RightMouseDown()
		{
			mouse_event(8, 0, 0, 0, 0);
		}

		public void RightMouseUp()
		{
			mouse_event(16, 0, 0, 0, 0);
		}

		public void ProcessTriggers(byte leftTrigger, byte rightTrigger)
		{
			if (rightTrigger > 128)
			{
				mouse_event(2, 0, 0, 0, 0);
			}
			else
			{
				mouse_event(4, 0, 0, 0, 0);
			}
			if (leftTrigger > 128)
			{
				mouse_event(8, 0, 0, 0, 0);
			}
			else
			{
				mouse_event(16, 0, 0, 0, 0);
			}
		}

		public void Scroll(float amount)
		{
			_scrollAccumulator += amount;
			if (Math.Abs(_scrollAccumulator) >= 0.0084f)
			{
				float num = (float)Math.Sign(_scrollAccumulator) * 0.0084f;
				int dwData = (int)(num * 120f);
				mouse_event(2048, 0, 0, dwData, 0);
				_scrollAccumulator -= num;
			}
		}

		public void ReleaseAllButtons()
		{
			mouse_event(4, 0, 0, 0, 0);
			mouse_event(16, 0, 0, 0, 0);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ControllerSupport";

		public const string PLUGIN_NAME = "ControllerSupport";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

BepInEx/plugins/SharpDX.XInput.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using SharpDX.Mathematics.Interop;
using SharpDX.Win32;

[assembly: AssemblyTitle("SharpDX.XInput")]
[assembly: AssemblyProduct("SharpDX.XInput")]
[assembly: AssemblyInformationalVersion("4.2.0+8e5df9f17b1d328c595a9df5851dbb2537b55621")]
[assembly: AssemblyFileVersion("4.2.0")]
[assembly: AssemblyDescription("Assembly providing DirectX - XInput managed API.")]
[assembly: AssemblyCopyright("Copyright (c) 2010-2016 Alexandre Mutel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("Alexandre Mutel")]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: ComVisible(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.2.0.0")]
[module: UnverifiableCode]
namespace SharpDX.XInput;

[CompilerGenerated]
internal class AssemblyDoc
{
}
public class Controller
{
	private readonly UserIndex userIndex;

	private static readonly IXInput xinput;

	public UserIndex UserIndex => userIndex;

	public bool IsConnected
	{
		get
		{
			State stateRef;
			return xinput.XInputGetState((int)userIndex, out stateRef) == 0;
		}
	}

	public Controller(UserIndex userIndex = UserIndex.Any)
	{
		if (xinput == null)
		{
			throw new NotSupportedException("XInput 1.4 or 1.3 or 9.1.0 is not installed");
		}
		this.userIndex = userIndex;
	}

	public BatteryInformation GetBatteryInformation(BatteryDeviceType batteryDeviceType)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		BatteryInformation batteryInformationRef;
		Result val = ErrorCodeHelper.ToResult(xinput.XInputGetBatteryInformation((int)userIndex, batteryDeviceType, out batteryInformationRef));
		((Result)(ref val)).CheckError();
		return batteryInformationRef;
	}

	public Capabilities GetCapabilities(DeviceQueryType deviceQueryType)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		Capabilities capabilitiesRef;
		Result val = ErrorCodeHelper.ToResult(xinput.XInputGetCapabilities((int)userIndex, deviceQueryType, out capabilitiesRef));
		((Result)(ref val)).CheckError();
		return capabilitiesRef;
	}

	public bool GetCapabilities(DeviceQueryType deviceQueryType, out Capabilities capabilities)
	{
		return xinput.XInputGetCapabilities((int)userIndex, deviceQueryType, out capabilities) == 0;
	}

	public Result GetKeystroke(DeviceQueryType deviceQueryType, out Keystroke keystroke)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		return ErrorCodeHelper.ToResult(xinput.XInputGetKeystroke((int)userIndex, (int)deviceQueryType, out keystroke));
	}

	public State GetState()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		State stateRef;
		Result val = ErrorCodeHelper.ToResult(xinput.XInputGetState((int)userIndex, out stateRef));
		((Result)(ref val)).CheckError();
		return stateRef;
	}

	public bool GetState(out State state)
	{
		return xinput.XInputGetState((int)userIndex, out state) == 0;
	}

	public static void SetReporting(bool enableReporting)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		if (xinput != null)
		{
			xinput.XInputEnable(RawBool.op_Implicit(enableReporting));
		}
	}

	public Result SetVibration(Vibration vibration)
	{
		//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_001e: Unknown result type (might be due to invalid IL or missing references)
		Result result = ErrorCodeHelper.ToResult(xinput.XInputSetState((int)userIndex, vibration));
		((Result)(ref result)).CheckError();
		return result;
	}

	static Controller()
	{
		if (LoadLibrary("xinput1_4.dll") != IntPtr.Zero)
		{
			xinput = new XInput14();
		}
		else if (LoadLibrary("xinput1_3.dll") != IntPtr.Zero)
		{
			xinput = new XInput13();
		}
		else if (LoadLibrary("xinput9_1_0.dll") != IntPtr.Zero)
		{
			xinput = new XInput910();
		}
	}

	[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
	private static extern IntPtr LoadLibrary(string lpFileName);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Gamepad
{
	public const byte TriggerThreshold = 30;

	public const short LeftThumbDeadZone = 7849;

	public const short RightThumbDeadZone = 8689;

	public GamepadButtonFlags Buttons;

	public byte LeftTrigger;

	public byte RightTrigger;

	public short LeftThumbX;

	public short LeftThumbY;

	public short RightThumbX;

	public short RightThumbY;

	public override string ToString()
	{
		return $"Buttons: {Buttons}, LeftTrigger: {LeftTrigger}, RightTrigger: {RightTrigger}, LeftThumbX: {LeftThumbX}, LeftThumbY: {LeftThumbY}, RightThumbX: {RightThumbX}, RightThumbY: {RightThumbY}";
	}
}
[Flags]
public enum GamepadButtonFlags : ushort
{
	None = 0,
	DPadUp = 1,
	DPadDown = 2,
	DPadLeft = 4,
	DPadRight = 8,
	Start = 0x10,
	Back = 0x20,
	LeftThumb = 0x40,
	RightThumb = 0x80,
	LeftShoulder = 0x100,
	RightShoulder = 0x200,
	A = 0x1000,
	B = 0x2000,
	X = 0x4000,
	Y = 0x8000
}
internal interface IXInput
{
	int XInputSetState(int dwUserIndex, Vibration vibrationRef);

	int XInputGetState(int dwUserIndex, out State stateRef);

	int XInputGetAudioDeviceIds(int dwUserIndex, IntPtr renderDeviceIdRef, IntPtr renderCountRef, IntPtr captureDeviceIdRef, IntPtr captureCountRef);

	void XInputEnable(RawBool enable);

	int XInputGetBatteryInformation(int dwUserIndex, BatteryDeviceType devType, out BatteryInformation batteryInformationRef);

	int XInputGetKeystroke(int dwUserIndex, int dwReserved, out Keystroke keystrokeRef);

	int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef);
}
[CompilerGenerated]
internal class NamespaceDoc
{
}
public sealed class ResultCode
{
	public static readonly Result NotConnected = ErrorCodeHelper.ToResult((ErrorCode)1167);
}
internal class XInput13 : IXInput
{
	private static class Native
	{
		[DllImport("xinput1_3.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern int XInputGetKeystroke(int dwUserIndex, int dwReserved, out Keystroke keystrokeRef);

		[DllImport("xinput1_3.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern int XInputGetBatteryInformation(int dwUserIndex, BatteryDeviceType devType, out BatteryInformation batteryInformationRef);

		public unsafe static int XInputSetState(int dwUserIndex, Vibration vibrationRef)
		{
			return XInputSetState_(dwUserIndex, &vibrationRef);
		}

		[DllImport("xinput1_3.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputSetState")]
		private unsafe static extern int XInputSetState_(int arg0, void* arg1);

		[DllImport("xinput1_3.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern int XInputGetState(int dwUserIndex, out State stateRef);

		[DllImport("xinput1_3.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern void XInputEnable(RawBool arg0);

		[DllImport("xinput1_3.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef);
	}

	public int XInputSetState(int dwUserIndex, Vibration vibrationRef)
	{
		return Native.XInputSetState(dwUserIndex, vibrationRef);
	}

	public int XInputGetState(int dwUserIndex, out State stateRef)
	{
		return Native.XInputGetState(dwUserIndex, out stateRef);
	}

	public int XInputGetAudioDeviceIds(int dwUserIndex, IntPtr renderDeviceIdRef, IntPtr renderCountRef, IntPtr captureDeviceIdRef, IntPtr captureCountRef)
	{
		throw new NotSupportedException("Method not supported on XInput1.3");
	}

	public void XInputEnable(RawBool enable)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		Native.XInputEnable(enable);
	}

	public int XInputGetBatteryInformation(int dwUserIndex, BatteryDeviceType devType, out BatteryInformation batteryInformationRef)
	{
		return Native.XInputGetBatteryInformation(dwUserIndex, devType, out batteryInformationRef);
	}

	public int XInputGetKeystroke(int dwUserIndex, int dwReserved, out Keystroke keystrokeRef)
	{
		return Native.XInputGetKeystroke(dwUserIndex, dwReserved, out keystrokeRef);
	}

	public int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef)
	{
		return Native.XInputGetCapabilities(dwUserIndex, dwFlags, out capabilitiesRef);
	}
}
internal class XInput14 : IXInput
{
	public int XInputSetState(int dwUserIndex, Vibration vibrationRef)
	{
		return XInput.XInputSetState(dwUserIndex, ref vibrationRef);
	}

	public int XInputGetState(int dwUserIndex, out State stateRef)
	{
		return XInput.XInputGetState(dwUserIndex, out stateRef);
	}

	public int XInputGetAudioDeviceIds(int dwUserIndex, IntPtr renderDeviceIdRef, IntPtr renderCountRef, IntPtr captureDeviceIdRef, IntPtr captureCountRef)
	{
		return XInput.XInputGetAudioDeviceIds(dwUserIndex, renderDeviceIdRef, renderCountRef, captureDeviceIdRef, captureCountRef);
	}

	public void XInputEnable(RawBool enable)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		XInput.XInputEnable(enable);
	}

	public int XInputGetBatteryInformation(int dwUserIndex, BatteryDeviceType devType, out BatteryInformation batteryInformationRef)
	{
		return XInput.XInputGetBatteryInformation(dwUserIndex, devType, out batteryInformationRef);
	}

	public int XInputGetKeystroke(int dwUserIndex, int dwReserved, out Keystroke keystrokeRef)
	{
		return XInput.XInputGetKeystroke(dwUserIndex, dwReserved, out keystrokeRef);
	}

	public int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef)
	{
		return XInput.XInputGetCapabilities(dwUserIndex, dwFlags, out capabilitiesRef);
	}
}
internal class XInput910 : IXInput
{
	private static class Native
	{
		public unsafe static int XInputSetState(int dwUserIndex, Vibration vibrationRef)
		{
			return XInputSetState_(dwUserIndex, &vibrationRef);
		}

		[DllImport("xinput9_1_0.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputSetState")]
		private unsafe static extern int XInputSetState_(int arg0, void* arg1);

		[DllImport("xinput9_1_0.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern int XInputGetState(int dwUserIndex, out State stateRef);

		[DllImport("xinput9_1_0.dll", CallingConvention = CallingConvention.StdCall)]
		public static extern int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef);
	}

	public int XInputSetState(int dwUserIndex, Vibration vibrationRef)
	{
		return Native.XInputSetState(dwUserIndex, vibrationRef);
	}

	public int XInputGetState(int dwUserIndex, out State stateRef)
	{
		return Native.XInputGetState(dwUserIndex, out stateRef);
	}

	public int XInputGetAudioDeviceIds(int dwUserIndex, IntPtr renderDeviceIdRef, IntPtr renderCountRef, IntPtr captureDeviceIdRef, IntPtr captureCountRef)
	{
		throw new NotSupportedException("Method not supported on XInput9.1.0");
	}

	public void XInputEnable(RawBool enable)
	{
		throw new NotSupportedException("Method not supported on XInput9.1.0");
	}

	public int XInputGetBatteryInformation(int dwUserIndex, BatteryDeviceType devType, out BatteryInformation batteryInformationRef)
	{
		throw new NotSupportedException("Method not supported on XInput9.1.0");
	}

	public int XInputGetKeystroke(int dwUserIndex, int dwReserved, out Keystroke keystrokeRef)
	{
		throw new NotSupportedException("Method not supported on XInput9.1.0");
	}

	public int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef)
	{
		return Native.XInputGetCapabilities(dwUserIndex, dwFlags, out capabilitiesRef);
	}
}
public enum BatteryDeviceType
{
	Gamepad,
	Headset
}
public enum BatteryLevel : byte
{
	Empty,
	Low,
	Medium,
	Full
}
public enum BatteryType : byte
{
	Disconnected = 0,
	Wired = 1,
	Alkaline = 2,
	Nimh = 3,
	Unknown = byte.MaxValue
}
[Flags]
public enum CapabilityFlags : short
{
	VoiceSupported = 4,
	FfbSupported = 1,
	Wireless = 2,
	PmdSupported = 8,
	NoNavigation = 0x10,
	None = 0
}
public enum DeviceQueryType
{
	Gamepad = 1,
	Any = 0
}
public enum DeviceSubType : byte
{
	Gamepad = 1,
	Unknown = 0,
	Wheel = 2,
	ArcadeStick = 3,
	FlightStick = 4,
	DancePad = 5,
	Guitar = 6,
	GuitarAlternate = 7,
	DrumKit = 8,
	GuitarBass = 11,
	ArcadePad = 19
}
public enum DeviceType : byte
{
	Gamepad = 1
}
[Flags]
public enum GamepadKeyCode : short
{
	A = 0x5800,
	B = 0x5801,
	X = 0x5802,
	Y = 0x5803,
	RightShoulder = 0x5804,
	LeftShoulder = 0x5805,
	LeftTrigger = 0x5806,
	RightTrigger = 0x5807,
	DPadUp = 0x5810,
	DPadDown = 0x5811,
	DPadLeft = 0x5812,
	DPadRight = 0x5813,
	Start = 0x5814,
	Back = 0x5815,
	LeftThumbPress = 0x5816,
	RightThumbPress = 0x5817,
	LeftThumbUp = 0x5820,
	LeftThumbDown = 0x5821,
	LeftThumbRight = 0x5822,
	LeftThumbLeft = 0x5823,
	RightThumbUpLeft = 0x5824,
	LeftThumbUpright = 0x5825,
	LeftThumbDownright = 0x5826,
	RightThumbDownLeft = 0x5827,
	RightThumbUp = 0x5830,
	RightThumbDown = 0x5831,
	RightThumbRight = 0x5832,
	RightThumbLeft = 0x5833,
	RightThumbUpleft = 0x5834,
	RightThumbUpRight = 0x5835,
	RightThumbDownRight = 0x5836,
	RightThumbDownleft = 0x5837,
	None = 0
}
[Flags]
public enum KeyStrokeFlags : short
{
	KeyDown = 1,
	KeyUp = 2,
	Repeat = 4,
	None = 0
}
public enum UserIndex : byte
{
	Any = byte.MaxValue,
	One = 0,
	Two = 1,
	Three = 2,
	Four = 3
}
internal static class XInput
{
	public unsafe static int XInputGetState(int dwUserIndex, out State stateRef)
	{
		stateRef = default(State);
		int result;
		fixed (State* ptr = &stateRef)
		{
			void* param = ptr;
			result = XInputGetState_(dwUserIndex, param);
		}
		return result;
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputGetState")]
	private unsafe static extern int XInputGetState_(int param0, void* param1);

	public unsafe static int XInputSetState(int dwUserIndex, ref Vibration vibrationRef)
	{
		Vibration.__Native @ref = default(Vibration.__Native);
		vibrationRef.__MarshalTo(ref @ref);
		int result = XInputSetState_(dwUserIndex, &@ref);
		vibrationRef.__MarshalFree(ref @ref);
		return result;
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputSetState")]
	private unsafe static extern int XInputSetState_(int param0, void* param1);

	public unsafe static int XInputGetCapabilities(int dwUserIndex, DeviceQueryType dwFlags, out Capabilities capabilitiesRef)
	{
		Capabilities.__Native @ref = default(Capabilities.__Native);
		capabilitiesRef = default(Capabilities);
		int result = XInputGetCapabilities_(dwUserIndex, (int)dwFlags, &@ref);
		capabilitiesRef.__MarshalFrom(ref @ref);
		return result;
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputGetCapabilities")]
	private unsafe static extern int XInputGetCapabilities_(int param0, int param1, void* param2);

	public static void XInputEnable(RawBool enable)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		XInputEnable_(enable);
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputEnable")]
	private static extern void XInputEnable_(RawBool param0);

	public unsafe static int XInputGetAudioDeviceIds(int dwUserIndex, IntPtr renderDeviceIdRef, IntPtr renderCountRef, IntPtr captureDeviceIdRef, IntPtr captureCountRef)
	{
		return XInputGetAudioDeviceIds_(dwUserIndex, (void*)renderDeviceIdRef, (void*)renderCountRef, (void*)captureDeviceIdRef, (void*)captureCountRef);
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputGetAudioDeviceIds")]
	private unsafe static extern int XInputGetAudioDeviceIds_(int param0, void* param1, void* param2, void* param3, void* param4);

	public unsafe static int XInputGetBatteryInformation(int dwUserIndex, BatteryDeviceType devType, out BatteryInformation batteryInformationRef)
	{
		batteryInformationRef = default(BatteryInformation);
		int result;
		fixed (BatteryInformation* ptr = &batteryInformationRef)
		{
			void* param = ptr;
			result = XInputGetBatteryInformation_(dwUserIndex, (int)devType, param);
		}
		return result;
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputGetBatteryInformation")]
	private unsafe static extern int XInputGetBatteryInformation_(int param0, int param1, void* param2);

	public unsafe static int XInputGetKeystroke(int dwUserIndex, int dwReserved, out Keystroke keystrokeRef)
	{
		keystrokeRef = default(Keystroke);
		int result;
		fixed (Keystroke* ptr = &keystrokeRef)
		{
			void* param = ptr;
			result = XInputGetKeystroke_(dwUserIndex, dwReserved, param);
		}
		return result;
	}

	[DllImport("xinput1_4.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "XInputGetKeystroke")]
	private unsafe static extern int XInputGetKeystroke_(int param0, int param1, void* param2);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct BatteryInformation
{
	public BatteryType BatteryType;

	public BatteryLevel BatteryLevel;
}
public struct Capabilities
{
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
	internal struct __Native
	{
		public DeviceType Type;

		public DeviceSubType SubType;

		public CapabilityFlags Flags;

		public Gamepad Gamepad;

		public Vibration.__Native Vibration;
	}

	public DeviceType Type;

	public DeviceSubType SubType;

	public CapabilityFlags Flags;

	public Gamepad Gamepad;

	public Vibration Vibration;

	internal void __MarshalFree(ref __Native @ref)
	{
		Vibration.__MarshalFree(ref @ref.Vibration);
	}

	internal void __MarshalFrom(ref __Native @ref)
	{
		Type = @ref.Type;
		SubType = @ref.SubType;
		Flags = @ref.Flags;
		Gamepad = @ref.Gamepad;
		Vibration.__MarshalFrom(ref @ref.Vibration);
	}

	internal void __MarshalTo(ref __Native @ref)
	{
		@ref.Type = Type;
		@ref.SubType = SubType;
		@ref.Flags = Flags;
		@ref.Gamepad = Gamepad;
		Vibration.__MarshalTo(ref @ref.Vibration);
	}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Keystroke
{
	public GamepadKeyCode VirtualKey;

	public char Unicode;

	public KeyStrokeFlags Flags;

	public UserIndex UserIndex;

	public byte HidCode;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct State
{
	public int PacketNumber;

	public Gamepad Gamepad;
}
public struct Vibration
{
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
	internal struct __Native
	{
		public short LeftMotorSpeed;

		public short RightMotorSpeed;
	}

	public ushort LeftMotorSpeed;

	public ushort RightMotorSpeed;

	internal void __MarshalFree(ref __Native @ref)
	{
	}

	internal void __MarshalFrom(ref __Native @ref)
	{
		LeftMotorSpeed = (ushort)@ref.LeftMotorSpeed;
		RightMotorSpeed = (ushort)@ref.RightMotorSpeed;
	}

	internal void __MarshalTo(ref __Native @ref)
	{
		@ref.LeftMotorSpeed = (short)LeftMotorSpeed;
		@ref.RightMotorSpeed = (short)RightMotorSpeed;
	}
}