using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Omniscye")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+343329221fb329c7e3fd5a225d612df8148bb674")] [assembly: AssemblyProduct("OmniDoomFX")] [assembly: AssemblyTitle("OmniDoomFX")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 REPO.CursedGfx { public static class Entry { [RuntimeInitializeOnLoadMethod(/*Could not decode attribute arguments.*/)] private static void Bootstrap() { CursedGraphicsMod.Init(); } } [HarmonyPatch] public static class CursedGraphicsMod { private static Harmony _harmony; private static bool _patched; public static void Init() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!_patched) { _patched = true; _harmony = new Harmony("repo.cursedgfx.doom.autowad"); _harmony.PatchAll(typeof(CursedGraphicsMod).Assembly); Debug.Log((object)"[OmniDoom] Harmony patches applied."); } } [HarmonyPostfix] [HarmonyPatch(typeof(RenderTextureMain), "Awake")] private static void RenderTextureMain_Awake_Postfix(RenderTextureMain __instance) { if (!((Object)(object)__instance == (Object)null) && (Object)(object)((Component)__instance).gameObject.GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } [HarmonyPostfix] [HarmonyPatch(typeof(RenderTextureMain), "SetRenderTexture")] private static void RenderTextureMain_SetRenderTexture_Postfix(RenderTextureMain __instance) { try { if ((Object)(object)__instance?.renderTexture != (Object)null) { ((Texture)__instance.renderTexture).filterMode = (FilterMode)0; } } catch { } } } [HarmonyPatch(typeof(Sound), "Play")] public static class Patch_DoomifyAudio { private static void Postfix(ref AudioSource __result) { if (!((Object)(object)__result == (Object)null)) { GameObject gameObject = ((Component)__result).gameObject; __result.spatialBlend = 1f; __result.reverbZoneMix = 0f; if ((Object)(object)gameObject.GetComponent() == (Object)null) { DoomifyFilter doomifyFilter = gameObject.AddComponent(); ((Behaviour)doomifyFilter).enabled = DoomAudioManager.GlobalSfxEnabled; } AudioLowPassFilter val = gameObject.GetComponent() ?? gameObject.AddComponent(); val.cutoffFrequency = 6000f; AudioHighPassFilter val2 = gameObject.GetComponent() ?? gameObject.AddComponent(); val2.cutoffFrequency = 40f; } } } public sealed class DoomAudioManager : MonoBehaviour { [CompilerGenerated] private sealed class d__16 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public DoomAudioManager <>4__this; private string 5__1; private string 5__2; private AudioType 5__3; private string 5__4; private string 5__5; private string 5__6; private UnityWebRequest 5__7; private AudioClip 5__8; private Exception 5__9; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; 5__4 = null; 5__5 = null; 5__6 = null; 5__7 = null; 5__8 = null; 5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; 5__1 = <>4__this.MusicDir; try { Directory.CreateDirectory(5__1); } catch { } 5__2 = Path.Combine(5__1, "DoomMusic.mp3"); if (!File.Exists(5__2)) { 5__5 = Path.Combine(5__1, "DoomMusic.ogg"); 5__6 = Path.Combine(5__1, "DoomMusic.wav"); if (File.Exists(5__5)) { 5__2 = 5__5; } else if (File.Exists(5__6)) { 5__2 = 5__6; } 5__5 = null; 5__6 = null; } if (!File.Exists(5__2)) { Debug.Log((object)("[OmniDoom] No music file found. Place 'DoomMusic.mp3' in: " + 5__1)); <>4__this._loader = null; result = false; break; } 5__3 = GuessAudioTypeFromExtension(5__2); 5__4 = new Uri(5__2).AbsoluteUri; 5__7 = UnityWebRequestMultimedia.GetAudioClip(5__4, 5__3); <>1__state = -3; <>2__current = 5__7.SendWebRequest(); <>1__state = 1; result = true; break; case 1: { <>1__state = -3; if (5__7.isNetworkError || 5__7.isHttpError) { Debug.LogWarning((object)("[OmniDoom] Failed to load " + 5__2 + ": " + 5__7.error)); <>4__this._loader = null; result = false; goto IL_027e; } try { 5__8 = DownloadHandlerAudioClip.GetContent(5__7); if ((Object)(object)5__8 != (Object)null) { <>4__this._clip = 5__8; } 5__8 = null; } catch (Exception ex) { 5__9 = ex; Debug.LogWarning((object)("[OmniDoom] Exception decoding " + 5__2 + ": " + 5__9.Message)); <>4__this._loader = null; result = false; goto IL_027e; } <>m__Finally1(); 5__7 = null; if (<>4__this._active && (Object)(object)<>4__this._clip != (Object)null) { <>4__this._music.clip = <>4__this._clip; <>4__this._music.Play(); } <>4__this._loader = null; result = false; break; } IL_027e: <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__7 != null) { ((IDisposable)5__7).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static bool GlobalSfxEnabled; private AudioSource _music; private AudioClip _clip; private bool _active; private Coroutine _loader; public static DoomAudioManager Instance { get; private set; } private string MusicDir { get { try { return Path.Combine(Paths.PluginPath, "Omniscye-DoomFX", "Music"); } catch { return Path.Combine(Application.dataPath, "..", "plugins", "Omniscye-DoomFX", "Music"); } } } public static DoomAudioManager Ensure() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if ((Object)(object)Instance != (Object)null) { return Instance; } GameObject val = new GameObject("REPO.DoomAudioManager"); Object.DontDestroyOnLoad((Object)(object)val); Instance = val.AddComponent(); return Instance; } private void Awake() { _music = ((Component)this).gameObject.AddComponent(); _music.loop = true; _music.playOnAwake = false; _music.spatialBlend = 0f; _music.reverbZoneMix = 0f; _music.volume = 0.6f; } public void SetActive(bool on) { _active = on; if (on) { if ((Object)(object)_clip == (Object)null && _loader == null) { _loader = ((MonoBehaviour)this).StartCoroutine(LoadClipCoroutine()); } else if ((Object)(object)_clip != (Object)null && !_music.isPlaying) { _music.clip = _clip; _music.Play(); } } else if (_music.isPlaying) { _music.Stop(); } } public void ToggleMusic() { if (!_active) { SetActive(on: true); return; } if ((Object)(object)_clip == (Object)null) { if (_loader == null) { _loader = ((MonoBehaviour)this).StartCoroutine(LoadClipCoroutine()); } return; } if (_music.isPlaying) { _music.Pause(); return; } if ((Object)(object)_music.clip != (Object)(object)_clip) { _music.clip = _clip; } if (_music.time > 0f && _music.time < _music.clip.length) { _music.UnPause(); } else { _music.Play(); } } public void Reload() { if (_loader != null) { ((MonoBehaviour)this).StopCoroutine(_loader); } _clip = null; if (_music.isPlaying) { _music.Stop(); } _loader = ((MonoBehaviour)this).StartCoroutine(LoadClipCoroutine()); } [IteratorStateMachine(typeof(d__16))] private IEnumerator LoadClipCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(0) { <>4__this = this }; } private static AudioType GuessAudioTypeFromExtension(string path) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) string text = Path.GetExtension(path).ToLowerInvariant(); if (1 == 0) { } AudioType result = (AudioType)(text switch { ".ogg" => 14, ".wav" => 20, ".mp3" => 13, _ => 0, }); if (1 == 0) { } return result; } } public class DoomifyFilter : MonoBehaviour { [Range(8000f, 16000f)] public float targetSampleRate = 11025f; [Range(0f, 24f)] public float preGainDb = 6f; [Range(0f, 1f)] public float drive = 0.15f; private int _systemRate; private float _holdStep; private float _holdCounter; private float _last; private void Awake() { _systemRate = AudioSettings.outputSampleRate; _holdStep = Mathf.Max(1f, (float)_systemRate / Mathf.Max(1000f, targetSampleRate)); _holdCounter = 0f; } private void OnEnable() { _systemRate = AudioSettings.outputSampleRate; _holdStep = Mathf.Max(1f, (float)_systemRate / Mathf.Max(1000f, targetSampleRate)); } private void OnAudioFilterRead(float[] data, int channels) { if (!DoomAudioManager.GlobalSfxEnabled || channels <= 0) { return; } float num = Mathf.Pow(10f, preGainDb / 20f); for (int i = 0; i < data.Length; i += channels) { float num2 = 0f; for (int j = 0; j < channels; j++) { num2 += data[i + j]; } num2 /= (float)channels; _holdCounter += 1f; if (_holdCounter >= _holdStep) { _holdCounter = 0f; float num3 = Mathf.Clamp(num2 * num, -1f, 1f); if (drive > 0f) { num3 = (float)Math.Tanh(num3 * (1f + drive * 10f)); } int num4 = Mathf.Clamp(Mathf.RoundToInt((num3 * 0.5f + 0.5f) * 255f), 0, 255); _last = ((float)num4 / 255f - 0.5f) * 2f; } for (int k = 0; k < channels; k++) { data[i + k] = _last; } } } } public sealed class CursedGraphicsController : MonoBehaviour { [CompilerGenerated] private sealed class d__45 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float extraDelaySeconds; public CursedGraphicsController <>4__this; private EnemyParent[] <>s__1; private int <>s__2; private EnemyParent 5__3; private ValuableObject[] <>s__4; private int <>s__5; private ValuableObject 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__45(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>s__1 = null; 5__3 = null; <>s__4 = null; 5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 2; return true; case 2: <>1__state = -1; if (extraDelaySeconds > 0f) { <>2__current = (object)new WaitForSecondsRealtime(extraDelaySeconds); <>1__state = 3; return true; } break; case 3: <>1__state = -1; break; } if (!<>4__this.ModEnabled) { return false; } <>s__1 = Object.FindObjectsByType((FindObjectsSortMode)0); for (<>s__2 = 0; <>s__2 < <>s__1.Length; <>s__2++) { 5__3 = <>s__1[<>s__2]; if (Object.op_Implicit((Object)(object)5__3) && ((Component)5__3).gameObject.activeInHierarchy) { FlatUtil.TryFlatify(((Component)5__3).gameObject); } 5__3 = null; } <>s__1 = null; <>s__4 = Object.FindObjectsByType((FindObjectsSortMode)0); for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++) { 5__6 = <>s__4[<>s__5]; if (Object.op_Implicit((Object)(object)5__6) && ((Component)5__6).gameObject.activeInHierarchy) { FlatUtil.TryFlatify(((Component)5__6).gameObject); } 5__6 = null; } <>s__4 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public bool ModEnabled = false; [Range(0.25f, 4f)] public float DoomLightScale = 1f; [Range(-1f, 1f)] public float DoomLightBias = 0f; public bool DoomLightByRow = true; public bool Scanlines = true; [Range(0f, 2f)] public int Sharpen = 1; [Range(64f, 960f)] public int TargetWidth = 320; [Range(64f, 960f)] public int TargetHeight = 200; private RenderTextureMain _rtm; private RenderTexture _rt; private RawImage _gameOverlay; private RawImage _cursedOverlay; private Texture _originalGameTexture; private bool _installedOverlay; private Texture2D _workTex; private Color32[] _buffer; private Color32[] _outBuffer; private RenderTexture _downscaleRT; private bool _doomAssetsLoaded; private string _wadUsed = ""; private Color32[] _doomPalette; private byte[,] _colormap; private int[] _rgbToIndexLUT; private void Awake() { CursedGraphicsMod.Init(); } private void Start() { _rtm = RenderTextureMain.instance; if ((Object)(object)_rtm == (Object)null) { ((Behaviour)this).enabled = false; return; } _gameOverlay = _rtm.overlayRawImage; _rt = _rtm.renderTexture; if ((Object)(object)_rt != (Object)null) { ((Texture)_rt).filterMode = (FilterMode)0; } RawImage gameOverlay = _gameOverlay; if ((Object)(object)((gameOverlay != null) ? gameOverlay.texture : null) != (Object)null) { _gameOverlay.texture.filterMode = (FilterMode)0; } AllocateWorking(TargetWidth, TargetHeight); if ((Object)(object)_gameOverlay != (Object)null) { _originalGameTexture = _gameOverlay.texture; } TryLoadDoomAssets(); DoomAudioManager.Ensure(); DoomAudioManager.GlobalSfxEnabled = false; DoomAudioManager.Ensure().SetActive(on: false); SyncAllDoomifyFilters(enabled: false); Debug.Log((object)(_doomAssetsLoaded ? ("[OmniDoom] DOOM palette ACTIVE (from \"" + _wadUsed + "\"). Starts OFF.") : "[OmniDoom] DOOM assets not found; effect will be inert.")); } private void TryLoadDoomAssets() { byte[] playpal = null; byte[] colormap = null; string dir = Path.Combine(Paths.PluginPath, "Omniscye-DoomFX"); if (TryLoadFromPreferredNames(dir, out playpal, out colormap, out _wadUsed) || TryScanWadsInDir(dir, out playpal, out colormap, out _wadUsed) || TryScanWadsInDir(Paths.PluginPath, out playpal, out colormap, out _wadUsed)) { ParseDoomLumps(playpal, colormap); return; } TextAsset val = Resources.Load("DOOM/PLAYPAL"); TextAsset val2 = Resources.Load("DOOM/COLORMAP"); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { _wadUsed = "Resources/DOOM/*"; ParseDoomLumps(val.bytes, val2.bytes); } else { _doomAssetsLoaded = false; } } private bool TryLoadFromPreferredNames(string dir, out byte[] playpal, out byte[] colormap, out string wadUsed) { playpal = (colormap = null); wadUsed = ""; if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return false; } string[] array = new string[6] { "freedm.wad", "freedoom.wad", "freedoom1.wad", "freedoom2.wad", "doom.wad", "doom2.wad" }; string[] array2 = array; foreach (string text in array2) { string text2 = Path.Combine(dir, text); if (File.Exists(text2) && TryLoadFromWad(text2, "PLAYPAL", "COLORMAP", out playpal, out colormap)) { wadUsed = Path.GetFileName(text2); return true; } string text3 = Path.Combine(dir, text.ToUpperInvariant()); if (File.Exists(text3) && TryLoadFromWad(text3, "PLAYPAL", "COLORMAP", out playpal, out colormap)) { wadUsed = Path.GetFileName(text3); return true; } } return false; } private bool TryScanWadsInDir(string dir, out byte[] playpal, out byte[] colormap, out string wadUsed) { playpal = (colormap = null); wadUsed = ""; if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return false; } string[] files = Directory.GetFiles(dir, "*.wad", SearchOption.TopDirectoryOnly); if (files.Length == 0) { files = Directory.GetFiles(dir, "*.WAD", SearchOption.TopDirectoryOnly); } string[] array = files; foreach (string text in array) { if (TryLoadFromWad(text, "PLAYPAL", "COLORMAP", out playpal, out colormap)) { wadUsed = Path.GetFileName(text); return true; } } return false; } private bool TryLoadFromWad(string wadPath, string lumpA, string lumpB, out byte[] a, out byte[] b) { a = (b = null); try { using FileStream fileStream = new FileStream(wadPath, FileMode.Open, FileAccess.Read); using BinaryReader binaryReader = new BinaryReader(fileStream); string text = new string(binaryReader.ReadChars(4)); int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); if (num <= 0 || num2 <= 0) { return false; } fileStream.Position = num2; long position = 0L; long position2 = 0L; int num3 = 0; int num4 = 0; for (int i = 0; i < num; i++) { int num5 = binaryReader.ReadInt32(); int num6 = binaryReader.ReadInt32(); string text2 = new string(binaryReader.ReadChars(8)).TrimEnd('\0'); if (text2.Equals(lumpA, StringComparison.OrdinalIgnoreCase)) { position = num5; num3 = num6; } if (text2.Equals(lumpB, StringComparison.OrdinalIgnoreCase)) { position2 = num5; num4 = num6; } } if (num3 > 0) { fileStream.Position = position; a = binaryReader.ReadBytes(num3); } if (num4 > 0) { fileStream.Position = position2; b = binaryReader.ReadBytes(num4); } return a != null && b != null; } catch (Exception ex) { Debug.LogWarning((object)("[OmniDoom] WAD read failed: " + ex.Message)); return false; } } private void ParseDoomLumps(byte[] pp, byte[] cm) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { if (pp == null || cm == null) { _doomAssetsLoaded = false; return; } if (pp.Length < 10752) { _doomAssetsLoaded = false; return; } _doomPalette = (Color32[])(object)new Color32[256]; int num = 0; for (int i = 0; i < 256; i++) { int num2 = num + i * 3; _doomPalette[i] = new Color32(pp[num2], pp[num2 + 1], pp[num2 + 2], byte.MaxValue); } int num3 = cm.Length / 256; int num4 = Mathf.Clamp(num3, 1, 34); _colormap = new byte[num4, 256]; for (int j = 0; j < num4; j++) { for (int k = 0; k < 256; k++) { _colormap[j, k] = cm[j * 256 + k]; } } BuildRGBToIndexLUT(); _doomAssetsLoaded = true; } catch (Exception ex) { Debug.LogWarning((object)("[OmniDoom] Failed to parse DOOM lumps: " + ex.Message)); _doomAssetsLoaded = false; } } private void BuildRGBToIndexLUT() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) _rgbToIndexLUT = new int[32768]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { for (int k = 0; k < 32; k++) { int num = (i << 3) | (i >> 2); int num2 = (j << 3) | (j >> 2); int num3 = (k << 3) | (k >> 2); int num4 = 0; int num5 = int.MaxValue; for (int l = 0; l < 256; l++) { Color32 val = _doomPalette[l]; int num6 = num - val.r; num6 *= num6; int num7 = num2 - val.g; num7 *= num6; int num8 = num3 - val.b; num8 *= num8; int num9 = num6 + num7 + num8; if (num9 < num5) { num5 = num9; num4 = l; } } _rgbToIndexLUT[(i << 10) | (j << 5) | k] = num4; } } } } private void AllocateWorking(int w, int h) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if ((Object)(object)_workTex != (Object)null) { Object.Destroy((Object)(object)_workTex); } _workTex = new Texture2D(w, h, (TextureFormat)4, false, false) { filterMode = (FilterMode)0 }; _buffer = (Color32[])(object)new Color32[w * h]; _outBuffer = (Color32[])(object)new Color32[w * h]; EnsureDownscaleRT(w, h); if ((Object)(object)_cursedOverlay != (Object)null) { _cursedOverlay.texture = (Texture)(object)_workTex; } } private void EnsureDownscaleRT(int w, int h) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if ((Object)(object)_downscaleRT != (Object)null && (((Texture)_downscaleRT).width != w || ((Texture)_downscaleRT).height != h)) { _downscaleRT.Release(); Object.Destroy((Object)(object)_downscaleRT); _downscaleRT = null; } if ((Object)(object)_downscaleRT == (Object)null) { _downscaleRT = new RenderTexture(w, h, 0, (RenderTextureFormat)0) { filterMode = (FilterMode)0, useMipMap = false, autoGenerateMips = false }; _downscaleRT.Create(); } } private void InstallOverlay() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (!_installedOverlay && !((Object)(object)_gameOverlay == (Object)null)) { GameObject val = new GameObject("OmniDoom Output", new Type[2] { typeof(RectTransform), typeof(RawImage) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent(((Component)_gameOverlay).transform.parent, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; _cursedOverlay = val.GetComponent(); ((Graphic)_cursedOverlay).raycastTarget = false; ((Graphic)_cursedOverlay).material = ((Graphic)_gameOverlay).material; _cursedOverlay.texture = (Texture)(object)_workTex; val.transform.SetSiblingIndex(((Component)_gameOverlay).transform.GetSiblingIndex()); ((Behaviour)_gameOverlay).enabled = false; _installedOverlay = true; } } private void RestoreOverlay() { if ((Object)(object)_gameOverlay != (Object)null) { ((Behaviour)_gameOverlay).enabled = true; if ((Object)(object)_originalGameTexture != (Object)null) { _gameOverlay.texture = _originalGameTexture; } } if ((Object)(object)_cursedOverlay != (Object)null) { Object.Destroy((Object)(object)((Component)_cursedOverlay).gameObject); } _cursedOverlay = null; _installedOverlay = false; } private void Update() { HandleHotkeys(); } private void LateUpdate() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (ModEnabled && _doomAssetsLoaded && !((Object)(object)_rtm?.renderTexture == (Object)null) && !((Object)(object)_workTex == (Object)null)) { if (!_installedOverlay && (Object)(object)_gameOverlay != (Object)null) { InstallOverlay(); } int targetWidth = TargetWidth; int targetHeight = TargetHeight; if (((Texture)_workTex).width != targetWidth || ((Texture)_workTex).height != targetHeight) { AllocateWorking(targetWidth, targetHeight); } _rt = _rtm.renderTexture; ((Texture)_rt).filterMode = (FilterMode)0; RenderTexture active = RenderTexture.active; try { Graphics.Blit((Texture)(object)_rt, _downscaleRT); RenderTexture.active = _downscaleRT; _workTex.ReadPixels(new Rect(0f, 0f, (float)targetWidth, (float)targetHeight), 0, 0, false); _workTex.Apply(false, false); } finally { RenderTexture.active = active; } Color32[] pixels = _workTex.GetPixels32(); EnsureBuffers(pixels.Length); ProcessDoomPalette(pixels, _outBuffer, targetWidth, targetHeight); _workTex.SetPixels32(_outBuffer); _workTex.Apply(false, false); if ((Object)(object)_cursedOverlay != (Object)null && (Object)(object)_cursedOverlay.texture != (Object)(object)_workTex) { _cursedOverlay.texture = (Texture)(object)_workTex; } } } private void EnsureBuffers(int n) { if (_buffer == null || _buffer.Length != n) { _buffer = (Color32[])(object)new Color32[n]; } if (_outBuffer == null || _outBuffer.Length != n) { _outBuffer = (Color32[])(object)new Color32[n]; } } private void ProcessDoomPalette(Color32[] src, Color32[] dst, int w, int h) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) int num = Math.Min(_colormap.GetLength(0), 32); float doomLightBias = DoomLightBias; float doomLightScale = DoomLightScale; for (int i = 0; i < h; i++) { float num2 = (float)i / (float)(h - 1); float num3 = (DoomLightByRow ? (1f - num2) : 1f); float num4 = Mathf.Clamp01(num3 * doomLightScale + doomLightBias); int num5 = Mathf.Clamp(Mathf.RoundToInt((1f - num4) * (float)(num - 1)), 0, num - 1); int num6 = i * w; for (int j = 0; j < w; j++) { Color32 val = src[num6 + j]; int num7 = (val.r >> 3 << 10) | (val.g >> 3 << 5) | (val.b >> 3); int num8 = _rgbToIndexLUT[num7]; int num9 = _colormap[num5, num8]; dst[num6 + j] = _doomPalette[num9]; } } if (Scanlines) { DarkenEveryOtherRow(dst, w, h, 0.75f); } if (Sharpen > 0) { ApplySharpen(dst, w, h, Sharpen); } } private static void DarkenEveryOtherRow(Color32[] px, int w, int h, float factor) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < h; i += 2) { int num = i * w; for (int j = 0; j < w; j++) { int num2 = num + j; Color32 val = px[num2]; val.r = (byte)((float)(int)val.r * factor); val.g = (byte)((float)(int)val.g * factor); val.b = (byte)((float)(int)val.b * factor); px[num2] = val; } } } private void ApplySharpen(Color32[] px, int w, int h, int strength) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) Color32[] buffer = _buffer; Array.Copy(px, buffer, px.Length); for (int i = 0; i < strength; i++) { for (int j = 1; j < h - 1; j++) { int num = j * w; for (int k = 1; k < w - 1; k++) { int num2 = num + k; Color32 val = buffer[num2]; int num3 = val.r * 5; int num4 = val.g * 5; int num5 = val.b * 5; Color32 val2 = buffer[num2 - 1]; Color32 val3 = buffer[num2 + 1]; Color32 val4 = buffer[num2 - w]; Color32 val5 = buffer[num2 + w]; num3 -= val2.r + val3.r + val4.r + val5.r; num4 -= val2.g + val3.g + val4.g + val5.g; num5 -= val2.b + val3.b + val4.b + val5.b; px[num2] = new Color32((byte)Mathf.Clamp(num3, 0, 255), (byte)Mathf.Clamp(num4, 0, 255), (byte)Mathf.Clamp(num5, 0, 255), byte.MaxValue); } } Array.Copy(px, buffer, px.Length); } } private void HandleHotkeys() { if (Input.GetKeyDown((KeyCode)289)) { ModEnabled = !ModEnabled; if (ModEnabled) { InstallOverlay(); DoomAudioManager.GlobalSfxEnabled = true; SyncAllDoomifyFilters(enabled: true); DoomAudioManager.Ensure().SetActive(on: true); ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).StartCoroutine(ApplyFlatToExistingDelayed(0.15f)); } else { DoomAudioManager.GlobalSfxEnabled = false; SyncAllDoomifyFilters(enabled: false); DoomAudioManager.Ensure().SetActive(on: false); RestoreOverlay(); RestoreAllFlatified(); } } if (ModEnabled) { if (Input.GetKeyDown((KeyCode)59)) { DoomLightScale = Mathf.Clamp(DoomLightScale * 0.9f, 0.25f, 4f); } if (Input.GetKeyDown((KeyCode)39)) { DoomLightScale = Mathf.Clamp(DoomLightScale * 1.1f, 0.25f, 4f); } if (Input.GetKeyDown((KeyCode)44)) { DoomLightBias = Mathf.Clamp(DoomLightBias - 0.05f, -1f, 1f); } if (Input.GetKeyDown((KeyCode)46)) { DoomLightBias = Mathf.Clamp(DoomLightBias + 0.05f, -1f, 1f); } if (Input.GetKeyDown((KeyCode)288)) { Scanlines = !Scanlines; } if (Input.GetKeyDown((KeyCode)91)) { Sharpen = Mathf.Clamp(Sharpen - 1, 0, 2); } if (Input.GetKeyDown((KeyCode)93)) { Sharpen = Mathf.Clamp(Sharpen + 1, 0, 2); } if (Input.GetKeyDown((KeyCode)280)) { TargetWidth = Mathf.Clamp(TargetWidth + 16, 64, 960); TargetHeight = Mathf.Clamp(TargetHeight + 10, 64, 960); AllocateWorking(TargetWidth, TargetHeight); } else if (Input.GetKeyDown((KeyCode)281)) { TargetWidth = Mathf.Clamp(TargetWidth - 16, 64, 960); TargetHeight = Mathf.Clamp(TargetHeight - 10, 64, 960); AllocateWorking(TargetWidth, TargetHeight); } if (Input.GetKeyDown((KeyCode)291)) { DoomAudioManager.Ensure().ToggleMusic(); } if (Input.GetKeyDown((KeyCode)293)) { DoomAudioManager.Ensure().Reload(); } if (Input.GetKeyDown((KeyCode)292)) { DoomAudioManager.GlobalSfxEnabled = !DoomAudioManager.GlobalSfxEnabled; SyncAllDoomifyFilters(DoomAudioManager.GlobalSfxEnabled); } } } private void OnGUI() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0141: 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_015f: Unknown result type (might be due to invalid IL or missing references) string text = (_doomAssetsLoaded ? ("OmniDoom (PLAYPAL from \"" + _wadUsed + "\")") : "OmniDoom"); string text2 = (ModEnabled ? ($"{text} — {TargetWidth}x{TargetHeight}\n" + "[F8 toggle | F7 scanlines | [ ] sharpen | PgUp/PgDn res]\n" + string.Format("LightScale:{0:0.00} (;/') LightBias:{1:+0.00;-0.00;0} (,/.) RowLight:{2}\n", DoomLightScale, DoomLightBias, DoomLightByRow ? "ON" : "OFF") + "Audio: F10 music on/off | F11 SFX Doomify (" + (DoomAudioManager.GlobalSfxEnabled ? "ON" : "OFF") + ") | F12 reload music") : (text + " — DISABLED (F8 to enable)")); GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 12 }; val.normal.textColor = Color.black; GUIStyle val2 = val; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(10f, 10f, (float)Screen.width, 80f); GUI.Label(new Rect(((Rect)(ref val3)).x + 1f, ((Rect)(ref val3)).y + 1f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), text2, val2); val2.normal.textColor = Color.green; GUI.Label(val3, text2, val2); } private void OnDisable() { RestoreAllFlatified(); DoomAudioManager.GlobalSfxEnabled = false; SyncAllDoomifyFilters(enabled: false); DoomAudioManager.Ensure().SetActive(on: false); } private void RestoreAllFlatified() { _FlatMarker[] array = Object.FindObjectsByType<_FlatMarker>((FindObjectsSortMode)0); foreach (_FlatMarker flatMarker in array) { FlatUtil.Restore(((Component)flatMarker).gameObject); } } [IteratorStateMachine(typeof(d__45))] private IEnumerator ApplyFlatToExistingDelayed(float extraDelaySeconds) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__45(0) { <>4__this = this, extraDelaySeconds = extraDelaySeconds }; } private void SyncAllDoomifyFilters(bool enabled) { DoomifyFilter[] array = Object.FindObjectsByType((FindObjectsSortMode)0); DoomifyFilter[] array2 = array; foreach (DoomifyFilter doomifyFilter in array2) { if (Object.op_Implicit((Object)(object)doomifyFilter)) { ((Behaviour)doomifyFilter).enabled = enabled; } } } } internal sealed class _FlatMarker : MonoBehaviour { public Dictionary original = new Dictionary(); } internal static class FlatUtil { public static void TryFlatify(GameObject root, float depth = 0.01f) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } _FlatMarker flatMarker = root.GetComponent<_FlatMarker>() ?? root.AddComponent<_FlatMarker>(); Renderer[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { Transform transform = ((Component)val).transform; if (!flatMarker.original.ContainsKey(transform)) { flatMarker.original[transform] = transform.localScale; } Vector3 localScale = transform.localScale; transform.localScale = new Vector3(localScale.x, localScale.y, Mathf.Max(depth, 0.0001f)); } } public static void Restore(GameObject root) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) _FlatMarker flatMarker = ((root != null) ? root.GetComponent<_FlatMarker>() : null); if ((Object)(object)flatMarker == (Object)null) { return; } foreach (KeyValuePair item in flatMarker.original) { if (Object.op_Implicit((Object)(object)item.Key)) { item.Key.localScale = item.Value; } } Object.Destroy((Object)(object)flatMarker); } } internal static class FlatDelay { [CompilerGenerated] private sealed class d__0 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject go; public float depth; public float extraSeconds; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 2; return true; case 2: <>1__state = -1; if (extraSeconds > 0f) { <>2__current = (object)new WaitForSecondsRealtime(extraSeconds); <>1__state = 3; return true; } break; case 3: <>1__state = -1; break; } if ((Object)(object)go != (Object)null) { FlatUtil.TryFlatify(go, depth); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [IteratorStateMachine(typeof(d__0))] public static IEnumerator WaitThenFlat(GameObject go, float depth, float extraSeconds = 0.1f) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(0) { go = go, depth = depth, extraSeconds = extraSeconds }; } } [HarmonyPatch(typeof(EnemyParent), "SpawnRPC")] internal static class Patch_FlatEnemies_OnSpawn { private const float EnemyFlatDepth = 0.01f; private const float EnemyExtraDelay = 0.15f; private static void Postfix(EnemyParent __instance) { if (!((Object)(object)__instance == (Object)null)) { CursedGraphicsController cursedGraphicsController = Object.FindFirstObjectByType(); if (!((Object)(object)cursedGraphicsController == (Object)null) && cursedGraphicsController.ModEnabled) { ((MonoBehaviour)__instance).StartCoroutine(FlatDelay.WaitThenFlat(((Component)__instance).gameObject, 0.01f, 0.15f)); } } } } [HarmonyPatch(typeof(ValuableObject), "Start")] internal static class Patch_FlatValuables_OnStart { private const float ValFlatDepth = 0.01f; private const float ValExtraDelay = 0.1f; private static void Postfix(ValuableObject __instance) { if (!((Object)(object)__instance == (Object)null)) { CursedGraphicsController cursedGraphicsController = Object.FindFirstObjectByType(); if (!((Object)(object)cursedGraphicsController == (Object)null) && cursedGraphicsController.ModEnabled) { ((MonoBehaviour)__instance).StartCoroutine(FlatDelay.WaitThenFlat(((Component)__instance).gameObject, 0.01f)); } } } } } namespace OmniDoomFX { [BepInPlugin("Omniscye.OmniDoomFX", "OmniDoomFX", "1.0")] public class OmniDoomFX : BaseUnityPlugin { internal static OmniDoomFX Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } }