Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DoomFX v1.0.0
OmniDoomFX.dll
Decompiled 9 months agousing 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<CursedGraphicsController>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<CursedGraphicsController>(); } } [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<DoomifyFilter>() == (Object)null) { DoomifyFilter doomifyFilter = gameObject.AddComponent<DoomifyFilter>(); ((Behaviour)doomifyFilter).enabled = DoomAudioManager.GlobalSfxEnabled; } AudioLowPassFilter val = gameObject.GetComponent<AudioLowPassFilter>() ?? gameObject.AddComponent<AudioLowPassFilter>(); val.cutoffFrequency = 6000f; AudioHighPassFilter val2 = gameObject.GetComponent<AudioHighPassFilter>() ?? gameObject.AddComponent<AudioHighPassFilter>(); val2.cutoffFrequency = 40f; } } } public sealed class DoomAudioManager : MonoBehaviour { [CompilerGenerated] private sealed class <LoadClipCoroutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public DoomAudioManager <>4__this; private string <baseDir>5__1; private string <chosen>5__2; private AudioType <type>5__3; private string <uri>5__4; private string <ogg>5__5; private string <wav>5__6; private UnityWebRequest <req>5__7; private AudioClip <clip>5__8; private Exception <e>5__9; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadClipCoroutine>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(); } } <baseDir>5__1 = null; <chosen>5__2 = null; <uri>5__4 = null; <ogg>5__5 = null; <wav>5__6 = null; <req>5__7 = null; <clip>5__8 = null; <e>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; <baseDir>5__1 = <>4__this.MusicDir; try { Directory.CreateDirectory(<baseDir>5__1); } catch { } <chosen>5__2 = Path.Combine(<baseDir>5__1, "DoomMusic.mp3"); if (!File.Exists(<chosen>5__2)) { <ogg>5__5 = Path.Combine(<baseDir>5__1, "DoomMusic.ogg"); <wav>5__6 = Path.Combine(<baseDir>5__1, "DoomMusic.wav"); if (File.Exists(<ogg>5__5)) { <chosen>5__2 = <ogg>5__5; } else if (File.Exists(<wav>5__6)) { <chosen>5__2 = <wav>5__6; } <ogg>5__5 = null; <wav>5__6 = null; } if (!File.Exists(<chosen>5__2)) { Debug.Log((object)("[OmniDoom] No music file found. Place 'DoomMusic.mp3' in: " + <baseDir>5__1)); <>4__this._loader = null; result = false; break; } <type>5__3 = GuessAudioTypeFromExtension(<chosen>5__2); <uri>5__4 = new Uri(<chosen>5__2).AbsoluteUri; <req>5__7 = UnityWebRequestMultimedia.GetAudioClip(<uri>5__4, <type>5__3); <>1__state = -3; <>2__current = <req>5__7.SendWebRequest(); <>1__state = 1; result = true; break; case 1: { <>1__state = -3; if (<req>5__7.isNetworkError || <req>5__7.isHttpError) { Debug.LogWarning((object)("[OmniDoom] Failed to load " + <chosen>5__2 + ": " + <req>5__7.error)); <>4__this._loader = null; result = false; goto IL_027e; } try { <clip>5__8 = DownloadHandlerAudioClip.GetContent(<req>5__7); if ((Object)(object)<clip>5__8 != (Object)null) { <>4__this._clip = <clip>5__8; } <clip>5__8 = null; } catch (Exception ex) { <e>5__9 = ex; Debug.LogWarning((object)("[OmniDoom] Exception decoding " + <chosen>5__2 + ": " + <e>5__9.Message)); <>4__this._loader = null; result = false; goto IL_027e; } <>m__Finally1(); <req>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 (<req>5__7 != null) { ((IDisposable)<req>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<DoomAudioManager>(); return Instance; } private void Awake() { _music = ((Component)this).gameObject.AddComponent<AudioSource>(); _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(<LoadClipCoroutine>d__16))] private IEnumerator LoadClipCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadClipCoroutine>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 <ApplyFlatToExistingDelayed>d__45 : IEnumerator<object>, 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 <e>5__3; private ValuableObject[] <>s__4; private int <>s__5; private ValuableObject <v>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyFlatToExistingDelayed>d__45(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>s__1 = null; <e>5__3 = null; <>s__4 = null; <v>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<EnemyParent>((FindObjectsSortMode)0); for (<>s__2 = 0; <>s__2 < <>s__1.Length; <>s__2++) { <e>5__3 = <>s__1[<>s__2]; if (Object.op_Implicit((Object)(object)<e>5__3) && ((Component)<e>5__3).gameObject.activeInHierarchy) { FlatUtil.TryFlatify(((Component)<e>5__3).gameObject); } <e>5__3 = null; } <>s__1 = null; <>s__4 = Object.FindObjectsByType<ValuableObject>((FindObjectsSortMode)0); for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++) { <v>5__6 = <>s__4[<>s__5]; if (Object.op_Implicit((Object)(object)<v>5__6) && ((Component)<v>5__6).gameObject.activeInHierarchy) { FlatUtil.TryFlatify(((Component)<v>5__6).gameObject); } <v>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<TextAsset>("DOOM/PLAYPAL"); TextAsset val2 = Resources.Load<TextAsset>("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<RectTransform>(); ((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<RawImage>(); ((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(<ApplyFlatToExistingDelayed>d__45))] private IEnumerator ApplyFlatToExistingDelayed(float extraDelaySeconds) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ApplyFlatToExistingDelayed>d__45(0) { <>4__this = this, extraDelaySeconds = extraDelaySeconds }; } private void SyncAllDoomifyFilters(bool enabled) { DoomifyFilter[] array = Object.FindObjectsByType<DoomifyFilter>((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<Transform, Vector3> original = new Dictionary<Transform, Vector3>(); } 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<Renderer>(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<Transform, Vector3> 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 <WaitThenFlat>d__0 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject go; public float depth; public float extraSeconds; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitThenFlat>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(<WaitThenFlat>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 <WaitThenFlat>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<CursedGraphicsController>(); 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<CursedGraphicsController>(); 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() { } } }