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.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FMOD;
using FMODUnity;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Localization;
using UnityEngine.UI;
using UnityEngine.Video;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DrivingRangeTheater")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DrivingRangeTheater")]
[assembly: AssemblyTitle("DrivingRangeTheater")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 DrivingRangeTheater
{
public class DrivingRangeBackCameraButton : MonoBehaviour, IInteractable
{
public Entity AsEntity { get; private set; }
public bool IsInteractionEnabled => DrivingRangeStaticCameraManager.IsCycleNextButtonEnabled;
public LocalizedString InteractString => UI.SPECTATOR_Prompt_Previous_Ref;
public void LocalPlayerInteract()
{
if (NetworkClient.active)
{
TheaterCycleMsg theaterCycleMsg = default(TheaterCycleMsg);
theaterCycleMsg.direction = -1;
NetworkClient.Send<TheaterCycleMsg>(theaterCycleMsg, 0);
}
}
private void Awake()
{
AsEntity = ((Component)this).GetComponent<Entity>();
}
}
internal static class BackButtonInstaller
{
private const float OffsetMeters = 0.2508f;
private static bool _installed;
public static void ResetForNewScene()
{
_installed = false;
}
public static void TryInstall(DrivingRangeStaticCameraManager mgr)
{
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
if (_installed)
{
return;
}
DrivingRangeNextCameraButton val = Traverse.Create((object)mgr).Field<DrivingRangeNextCameraButton>("nextCameraButton").Value;
if ((Object)(object)val == (Object)null)
{
val = Object.FindObjectOfType<DrivingRangeNextCameraButton>();
}
if ((Object)(object)val == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)"Back button: no DrivingRangeNextCameraButton found yet — will retry.");
}
return;
}
if ((Object)(object)((Component)val).transform.parent != (Object)null && (Object)(object)((Component)val).transform.parent.Find("SBG-BackCameraButton") != (Object)null)
{
_installed = true;
return;
}
GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
((Object)val2).name = "SBG-BackCameraButton";
Vector3 val3 = Vector3.right * 0.2508f;
Vector3 val4 = ((Component)val).transform.TransformVector(val3);
val2.transform.localPosition = ((Component)val).transform.localPosition + val3;
val2.transform.localRotation = ((Component)val).transform.localRotation;
val2.transform.localScale = ((Component)val).transform.localScale;
DrivingRangeNextCameraButton component = val2.GetComponent<DrivingRangeNextCameraButton>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
val2.AddComponent<DrivingRangeBackCameraButton>();
Entity component2 = ((Component)val).GetComponent<Entity>();
Entity component3 = val2.GetComponent<Entity>();
if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null && (Object)(object)component2.TargetReticlePosition != (Object)null && (Object)(object)component3.TargetReticlePosition != (Object)null)
{
((Component)component3.TargetReticlePosition).transform.position = ((Component)component2.TargetReticlePosition).transform.position + val4;
}
_installed = true;
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"Back button installed at {val2.transform.position}.");
}
}
}
public struct TheaterCycleMsg : NetworkMessage
{
public int direction;
}
[BepInPlugin("cray.drivingrangetheater", "DrivingRangeTheater", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(DrivingRangeStaticCameraManager), "OnStartServer")]
internal static class Patch_Manager_OnStartServer
{
private static void Postfix()
{
NetworkServer.ReplaceHandler<TheaterCycleMsg>((Action<NetworkConnectionToClient, TheaterCycleMsg>)OnClientCycle, true);
Log.LogInfo((object)"Registered TheaterCycleMsg server handler.");
}
}
[HarmonyPatch(typeof(DrivingRangeStaticCameraManager), "ApplyCurrentCameraIndex")]
internal static class Patch_Manager_ApplyCurrentCameraIndex
{
private static bool Prefix(DrivingRangeStaticCameraManager __instance)
{
Renderer value = Traverse.Create((object)__instance).Field<Renderer>("screenRenderer").Value;
if ((Object)(object)value == (Object)null)
{
return true;
}
if ((Object)(object)TheaterController.Current == (Object)null)
{
((Component)value).gameObject.AddComponent<TheaterController>().Initialize(value, __instance);
}
if (VideoLibrary.Videos.Count == 0)
{
TheaterController.Current.ShowNoVideos();
return false;
}
TheaterController.Current.ApplyIndex(__instance.NetworkcurrentCameraIndex);
BackButtonInstaller.TryInstall(__instance);
return false;
}
}
public const string ModGuid = "cray.drivingrangetheater";
public const string ModName = "DrivingRangeTheater";
public const string ModVersion = "0.1.0";
internal static ManualLogSource Log;
internal static ConfigEntry<float> VolumeConfig;
internal static ConfigEntry<float> OverscanCompensationConfig;
internal static ConfigEntry<int> ScreenResolutionConfig;
private static float _lastServerCycleTime;
private void Awake()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Expected O, but got Unknown
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
VolumeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Theater", "Volume", 0.5f, new ConfigDescription("Client-local master volume for the driving-range theater (0.0 - 1.0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
ScreenResolutionConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Theater", "ScreenResolution", 1024, new ConfigDescription("Client-local theater screen RT resolution. Accepted values: 1024, 1536, 2048.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[3] { 1024, 1536, 2048 }), Array.Empty<object>()));
OverscanCompensationConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Theater", "OverscanCompensation", 0f, new ConfigDescription("Shrinks the displayed video inside the theater screen RT to compensate for screen overscan/cropping (0.0 - 0.25).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.25f), Array.Empty<object>()));
VolumeConfig.SettingChanged += delegate
{
TheaterController.Current?.SetVolume(VolumeConfig.Value);
};
ScreenResolutionConfig.SettingChanged += delegate
{
TheaterController.Current?.ApplyConfiguredScreenResolution();
};
OverscanCompensationConfig.SettingChanged += delegate
{
TheaterController.Current?.RefreshDisplayComposition();
};
PauseMenu.Paused += VolumeSliderUi.HandlePauseShown;
PauseMenu.Unpaused += VolumeSliderUi.HandlePauseHidden;
VideoLibrary.ScanAll(Paths.PluginPath, Log);
new Harmony("cray.drivingrangetheater").PatchAll();
NetworkClient.OnConnectedEvent = (Action)Delegate.Combine(NetworkClient.OnConnectedEvent, new Action(RegisterClientHandlers));
Log.LogInfo((object)string.Format("{0} v{1} loaded ({2} video(s)).", "DrivingRangeTheater", "0.1.0", VideoLibrary.Videos.Count));
}
internal static int GetConfiguredScreenResolution()
{
int num = ((ScreenResolutionConfig != null) ? ScreenResolutionConfig.Value : 1024);
if (num != 1536 && num != 2048)
{
return 1024;
}
return num;
}
private static void RegisterClientHandlers()
{
}
internal static void OnClientCycle(NetworkConnectionToClient conn, TheaterCycleMsg msg)
{
if (Time.realtimeSinceStartup - _lastServerCycleTime < 0.2f)
{
return;
}
_lastServerCycleTime = Time.realtimeSinceStartup;
DrivingRangeStaticCameraManager instance = SingletonNetworkBehaviour<DrivingRangeStaticCameraManager>.Instance;
if (!((Object)(object)instance == (Object)null))
{
int num = Mathf.Max(VideoLibrary.Videos.Count, 1);
int num2 = ((msg.direction >= 0) ? 1 : (-1));
int num3 = instance.NetworkcurrentCameraIndex;
if (num3 < 0)
{
num3 = 0;
}
int networkcurrentCameraIndex = ((num3 + num2) % num + num) % num;
instance.NetworkcurrentCameraIndex = networkcurrentCameraIndex;
}
}
}
internal class TheaterController : MonoBehaviour
{
private struct ScreenTextureBinding
{
public string Name;
public Texture Texture;
public Vector2 Scale;
public Vector2 Offset;
}
private sealed class Slot
{
public string Label;
public VideoPlayer Player;
public RenderTexture RenderTexture;
public int VideoIndex = -1;
public bool Prepared;
}
public static TheaterController Current;
private Slot[] _slots;
private int _activeSlot;
private Renderer _screenRenderer;
private Material _screenMaterial;
private ScreenTextureBinding[] _screenBindings = Array.Empty<ScreenTextureBinding>();
private RenderTexture _screenRenderTexture;
private TextMeshPro _statusText;
private DrivingRangeStaticCameraManager _vanillaManager;
private Sound[] _sounds;
private Channel _activeChannel;
private bool _activeChannelValid;
private float _driftCheckTimer;
private const float DriftCheckInterval = 2f;
private const int DriftToleranceMs = 250;
private Vector3 _lastAudioWorldPos;
private const float AudioMinDistance = 6f;
private const float AudioMaxDistance = 45f;
private int _activeAudioIndex = -1;
private string[] _screenTextureSlots = Array.Empty<string>();
public void Initialize(Renderer screenRenderer, DrivingRangeStaticCameraManager vanillaMgr)
{
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Invalid comparison between Unknown and I4
//IL_028c: Unknown result type (might be due to invalid IL or missing references)
//IL_0291: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: 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_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
//IL_0311: Unknown result type (might be due to invalid IL or missing references)
Current = this;
_screenRenderer = screenRenderer;
_screenMaterial = screenRenderer.material;
_vanillaManager = vanillaMgr;
try
{
if (Traverse.Create((object)vanillaMgr).Field("cameras").GetValue() is DrivingRangeStaticCamera[] array && array.Length != 0)
{
object value = Traverse.Create((object)array[0]).Field("thisCamera").GetValue();
Camera val = (Camera)((value is Camera) ? value : null);
if ((Object)(object)val != (Object)null && (Object)(object)val.targetTexture != (Object)null)
{
_screenRenderTexture = val.targetTexture;
ApplyConfiguredScreenResolution();
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"Theater RT sized from vanilla camera: {((Texture)_screenRenderTexture).width}x{((Texture)_screenRenderTexture).height} ({((Object)_screenRenderTexture).name})");
}
}
}
}
catch (Exception ex)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("RT size probe failed: " + ex.Message));
}
}
_slots = new Slot[3];
for (int i = 0; i < _slots.Length; i++)
{
_slots[i] = CreateSlot("SBG-TheaterSlot-" + i, 1920, 1080);
}
Shader shader = _screenMaterial.shader;
int propertyCount = shader.GetPropertyCount();
List<string> list = new List<string>();
for (int j = 0; j < propertyCount; j++)
{
if ((int)shader.GetPropertyType(j) == 4)
{
string propertyName = shader.GetPropertyName(j);
string text = propertyName.ToLowerInvariant();
if (text.Contains("maintex") || text.Contains("basemap") || text.Contains("emission"))
{
list.Add(propertyName);
}
}
}
if (list.Count == 0)
{
if (_screenMaterial.HasProperty("_MainTex"))
{
list.Add("_MainTex");
}
if (_screenMaterial.HasProperty("_BaseMap"))
{
list.Add("_BaseMap");
}
if (_screenMaterial.HasProperty("_EmissionMap"))
{
list.Add("_EmissionMap");
}
}
_screenTextureSlots = list.ToArray();
_screenBindings = new ScreenTextureBinding[_screenTextureSlots.Length];
for (int k = 0; k < _screenTextureSlots.Length; k++)
{
string text2 = _screenTextureSlots[k];
_screenBindings[k] = new ScreenTextureBinding
{
Name = text2,
Texture = _screenMaterial.GetTexture(text2),
Scale = _screenMaterial.GetTextureScale(text2),
Offset = _screenMaterial.GetTextureOffset(text2)
};
_screenMaterial.SetTextureScale(text2, Vector2.one);
_screenMaterial.SetTextureOffset(text2, Vector2.zero);
}
if (_screenMaterial.HasProperty("_EmissionColor"))
{
_screenMaterial.SetColor("_EmissionColor", Color.white * 1.2f);
}
_screenMaterial.EnableKeyword("_EMISSION");
CreateStatusText();
_sounds = (Sound[])(object)new Sound[VideoLibrary.Entries.Count];
}
private Slot CreateSlot(string label, int rtW, int rtH)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: 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)
//IL_003a: 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_0049: Expected O, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Expected O, but got Unknown
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Expected O, but got Unknown
RenderTexture val = new RenderTexture(rtW, rtH, 0, (RenderTextureFormat)0)
{
name = label + "-RT",
wrapMode = (TextureWrapMode)1,
filterMode = (FilterMode)1,
useMipMap = false
};
val.Create();
GameObject val2 = new GameObject(label);
val2.transform.SetParent(((Component)this).transform, false);
VideoPlayer val3 = val2.AddComponent<VideoPlayer>();
val3.playOnAwake = false;
val3.waitForFirstFrame = true;
val3.isLooping = true;
val3.renderMode = (VideoRenderMode)2;
val3.targetTexture = val;
val3.source = (VideoSource)1;
val3.audioOutputMode = (VideoAudioOutputMode)0;
val3.aspectRatio = (VideoAspectRatio)5;
Slot slot = new Slot
{
Label = label,
Player = val3,
RenderTexture = val
};
val3.errorReceived += (ErrorEventHandler)delegate(VideoPlayer v, string msg)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("[" + label + "] " + msg));
}
};
val3.prepareCompleted += (EventHandler)delegate
{
HandleSlotPrepared(slot);
};
val3.started += (EventHandler)delegate
{
HandleSlotStarted(slot);
};
return slot;
}
public void ApplyIndex(int index)
{
if (VideoLibrary.Entries.Count != 0)
{
index = Wrap(index, VideoLibrary.Entries.Count);
StopActiveChannel();
int num = FindSlotFor(index);
if (num < 0)
{
num = _activeSlot;
BindSlotToVideo(_slots[num], index);
}
_activeSlot = num;
AssignRenderTargets(_activeSlot);
Slot slot = _slots[_activeSlot];
if (slot.Player.url != BuildUrl(index))
{
BindSlotToVideo(slot, index);
}
ShowStatus("Loading...");
slot.Player.Prepare();
slot.Player.Play();
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"Theater playing [{index}] {Path.GetFileName(VideoLibrary.Entries[index].VideoPath)} (slot {_activeSlot})");
}
PreloadNeighbors(index);
}
}
private void HandleSlotPrepared(Slot slot)
{
slot.Prepared = true;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[{slot.Label}] prepared: {Path.GetFileName(slot.Player.url)} ({slot.Player.width}x{slot.Player.height}x{slot.Player.frameRate:F1}fps)");
}
if (_slots != null && _slots[_activeSlot] == slot)
{
AssignRenderTargets(_activeSlot);
CompositeToScreen(slot.RenderTexture);
}
}
private void HandleSlotStarted(Slot slot)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[" + slot.Label + "] started: " + Path.GetFileName(slot.Player.url)));
}
if (_slots != null && _slots[_activeSlot] == slot)
{
AssignRenderTargets(_activeSlot);
CompositeToScreen(slot.RenderTexture);
HideStatus();
if (slot.VideoIndex >= 0 && slot.VideoIndex != _activeAudioIndex)
{
StartAudioFor(slot.VideoIndex);
}
}
}
private void PreloadNeighbors(int centerIndex)
{
int count = VideoLibrary.Entries.Count;
if (count <= 1)
{
return;
}
int num = Wrap(centerIndex + 1, count);
int num2 = Wrap(centerIndex - 1, count);
for (int i = 0; i < _slots.Length; i++)
{
if (i != _activeSlot)
{
int num3 = ((num != centerIndex && FindSlotFor(num) < 0) ? num : ((num2 != centerIndex && FindSlotFor(num2) < 0) ? num2 : (-1)));
if (num3 < 0)
{
break;
}
BindSlotToVideo(_slots[i], num3);
_slots[i].Player.Prepare();
}
}
}
private void BindSlotToVideo(Slot slot, int videoIndex)
{
if (slot.VideoIndex != videoIndex)
{
slot.Player.Stop();
slot.Player.url = VideoLibrary.Entries[videoIndex].VideoPath;
slot.VideoIndex = videoIndex;
slot.Prepared = false;
}
}
private int FindSlotFor(int videoIndex)
{
for (int i = 0; i < _slots.Length; i++)
{
if (_slots[i].VideoIndex == videoIndex)
{
return i;
}
}
return -1;
}
private void BindScreenTo(RenderTexture rt)
{
for (int i = 0; i < _screenTextureSlots.Length; i++)
{
_screenMaterial.SetTexture(_screenTextureSlots[i], (Texture)(object)rt);
}
_screenMaterial.mainTexture = (Texture)(object)rt;
}
private static void UpgradeVanillaRenderTextureInPlace(DrivingRangeStaticCameraManager vanillaMgr, RenderTexture sharedTarget, int desiredSize)
{
if ((Object)(object)sharedTarget == (Object)null || desiredSize <= 0 || (((Texture)sharedTarget).width == desiredSize && ((Texture)sharedTarget).height == desiredSize))
{
return;
}
try
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"Upgrading shared theater RT in place: '{((Object)sharedTarget).name}' {((Texture)sharedTarget).width}x{((Texture)sharedTarget).height} -> {desiredSize}x{desiredSize}");
}
sharedTarget.Release();
((Texture)sharedTarget).width = desiredSize;
((Texture)sharedTarget).height = desiredSize;
sharedTarget.Create();
if (!(Traverse.Create((object)vanillaMgr).Field("cameras").GetValue() is DrivingRangeStaticCamera[] array))
{
return;
}
foreach (DrivingRangeStaticCamera val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
Traverse val2 = Traverse.Create((object)val);
object value = val2.Field("thisCamera").GetValue();
Camera val3 = (Camera)((value is Camera) ? value : null);
if (!((Object)(object)val3 == (Object)null))
{
val3.targetTexture = sharedTarget;
val3.RemoveAllCommandBuffers();
object value2 = val2.Field("staticRenderTexture").GetValue();
RenderTexture val4 = (RenderTexture)((value2 is RenderTexture) ? value2 : null);
if ((Object)(object)val4 != (Object)null)
{
val4.Release();
Object.Destroy((Object)(object)val4);
}
object value3 = val2.Field("staticDepthTexture").GetValue();
RenderTexture val5 = (RenderTexture)((value3 is RenderTexture) ? value3 : null);
if ((Object)(object)val5 != (Object)null)
{
val5.Release();
Object.Destroy((Object)(object)val5);
}
val2.Field("staticRenderTexture").SetValue((object)null);
val2.Field("staticDepthTexture").SetValue((object)null);
val2.Field("hasTextures").SetValue((object)false);
val.RenderStaticTexture();
}
}
}
catch (Exception ex)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("In-place theater RT upgrade failed: " + ex.Message));
}
}
}
public void ApplyConfiguredScreenResolution()
{
if (!((Object)(object)_screenRenderTexture == (Object)null) && !((Object)(object)_vanillaManager == (Object)null))
{
UpgradeVanillaRenderTextureInPlace(_vanillaManager, _screenRenderTexture, Plugin.GetConfiguredScreenResolution());
RefreshDisplayComposition();
}
}
private void AssignRenderTargets(int activeSlot)
{
for (int i = 0; i < _slots.Length; i++)
{
if ((Object)(object)_slots[i].Player.targetTexture != (Object)(object)_slots[i].RenderTexture)
{
_slots[i].Player.targetTexture = _slots[i].RenderTexture;
}
}
if ((Object)(object)_screenRenderTexture == (Object)null)
{
BindScreenTo(_slots[activeSlot].RenderTexture);
}
else
{
BindScreenTo(_screenRenderTexture);
}
}
private void CompositeToScreen(RenderTexture source)
{
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_screenRenderTexture == (Object)null) && !((Object)(object)source == (Object)null))
{
float num = ((Plugin.OverscanCompensationConfig != null) ? Mathf.Clamp01(Plugin.OverscanCompensationConfig.Value) : 0.12f);
float num2 = ((Texture)_screenRenderTexture).width;
float num3 = ((Texture)_screenRenderTexture).height;
float num4 = num2 * (1f - num * 2f);
float num5 = num3 * (1f - num * 2f);
float num6 = ((((Texture)source).height > 0) ? ((float)((Texture)source).width / (float)((Texture)source).height) : 1.7777778f);
float num7 = ((num5 > 0f) ? (num4 / num5) : num6);
float num8 = num4;
float num9 = num5;
if (num7 > num6)
{
num8 = num9 * num6;
}
else
{
num9 = num8 / num6;
}
float num10 = (num2 - num8) * 0.5f;
float num11 = (num3 - num9) * 0.5f;
RenderTexture active = RenderTexture.active;
RenderTexture.active = _screenRenderTexture;
GL.PushMatrix();
GL.LoadPixelMatrix(0f, num2, num3, 0f);
GL.Clear(true, true, Color.black);
Graphics.DrawTexture(new Rect(num10, num11, num8, num9), (Texture)(object)source);
GL.PopMatrix();
RenderTexture.active = active;
}
}
private string BuildUrl(int index)
{
return VideoLibrary.Entries[index].VideoPath;
}
private void StartAudioFor(int index)
{
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
VideoEntry videoEntry = VideoLibrary.Entries[index];
if (string.IsNullOrEmpty(videoEntry.AudioPath))
{
return;
}
if (_sounds[index].handle == IntPtr.Zero)
{
System coreSystem = RuntimeManager.CoreSystem;
RESULT val = ((System)(ref coreSystem)).createSound(videoEntry.AudioPath, (MODE)2097298, ref _sounds[index]);
if ((int)val != 0)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"FMOD createSound failed for {videoEntry.AudioPath}: {val}");
}
return;
}
}
System coreSystem2 = RuntimeManager.CoreSystem;
RESULT val2 = ((System)(ref coreSystem2)).playSound(_sounds[index], default(ChannelGroup), false, ref _activeChannel);
if ((int)val2 != 0)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)$"FMOD playSound failed: {val2}");
}
}
else
{
((Channel)(ref _activeChannel)).setMode((MODE)2097168);
((Channel)(ref _activeChannel)).set3DMinMaxDistance(6f, 45f);
((Channel)(ref _activeChannel)).setVolume(Plugin.VolumeConfig.Value);
_activeChannelValid = true;
_activeAudioIndex = index;
_driftCheckTimer = 2f;
UpdateAudioSpatialization(force: true);
}
}
private void StopActiveChannel()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (_activeChannelValid)
{
((Channel)(ref _activeChannel)).stop();
_activeChannelValid = false;
_activeAudioIndex = -1;
}
}
public void SetVolume(float v)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
v = Mathf.Clamp01(v);
if (_activeChannelValid)
{
((Channel)(ref _activeChannel)).setVolume(v);
}
}
public void RefreshDisplayComposition()
{
if (_slots != null && _activeSlot >= 0 && _activeSlot < _slots.Length)
{
VideoPlayer player = _slots[_activeSlot].Player;
if ((Object)(object)_screenRenderTexture != (Object)null && (Object)(object)player != (Object)null && (player.isPlaying || player.isPrepared))
{
CompositeToScreen(_slots[_activeSlot].RenderTexture);
}
}
}
public void ShowNoVideos()
{
StopActiveChannel();
ShowStatus("No video files added");
}
private void CreateStatusText()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
//IL_007c: 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)
if (!((Object)(object)_statusText != (Object)null) && !((Object)(object)_screenRenderer == (Object)null))
{
GameObject val = new GameObject("SBG-TheaterStatus");
val.transform.SetParent(((Component)this).transform, false);
_statusText = val.AddComponent<TextMeshPro>();
((TMP_Text)_statusText).text = string.Empty;
((TMP_Text)_statusText).fontSize = 8f;
((TMP_Text)_statusText).alignment = (TextAlignmentOptions)514;
((Graphic)_statusText).color = Color.white;
((TMP_Text)_statusText).textWrappingMode = (TextWrappingModes)1;
((TMP_Text)_statusText).outlineWidth = 0.2f;
((TMP_Text)_statusText).rectTransform.sizeDelta = new Vector2(12f, 4f);
((Component)_statusText).gameObject.SetActive(false);
UpdateStatusTransform();
}
}
private void UpdateStatusTransform()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: 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_0099: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_statusText == (Object)null) && !((Object)(object)_screenRenderer == (Object)null))
{
Transform transform = _statusText.transform;
Bounds bounds = _screenRenderer.bounds;
transform.position = ((Bounds)(ref bounds)).center + ((Component)_screenRenderer).transform.forward * 0.03f;
transform.rotation = ((Component)_screenRenderer).transform.rotation * Quaternion.Euler(0f, 180f, 0f);
transform.localScale = Vector3.one * 0.45f;
}
}
private void ShowStatus(string text)
{
if ((Object)(object)_statusText == (Object)null)
{
CreateStatusText();
}
if (!((Object)(object)_statusText == (Object)null))
{
UpdateStatusTransform();
((TMP_Text)_statusText).text = text;
((Component)_statusText).gameObject.SetActive(true);
}
}
private void HideStatus()
{
if ((Object)(object)_statusText != (Object)null)
{
((Component)_statusText).gameObject.SetActive(false);
}
}
private Vector3 GetAudioWorldPosition()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_screenRenderer != (Object)null)
{
Bounds bounds = _screenRenderer.bounds;
return ((Bounds)(ref bounds)).center;
}
return ((Component)this).transform.position;
}
private void UpdateAudioSpatialization(bool force = false)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: 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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: 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_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
if (!_activeChannelValid)
{
return;
}
Vector3 audioWorldPosition = GetAudioWorldPosition();
if (!force)
{
Vector3 val = audioWorldPosition - _lastAudioWorldPos;
if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
{
return;
}
}
VECTOR val2 = RuntimeUtils.ToFMODVector(audioWorldPosition);
VECTOR val3 = RuntimeUtils.ToFMODVector(Vector3.zero);
((Channel)(ref _activeChannel)).set3DAttributes(ref val2, ref val3);
_lastAudioWorldPos = audioWorldPosition;
}
private void Update()
{
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
VideoPlayer val = ((_slots != null && _activeSlot >= 0 && _activeSlot < _slots.Length) ? _slots[_activeSlot].Player : null);
if ((Object)(object)_screenRenderTexture != (Object)null && (Object)(object)val != (Object)null && (val.isPlaying || val.isPrepared))
{
CompositeToScreen(_slots[_activeSlot].RenderTexture);
}
if ((Object)(object)_statusText != (Object)null && ((Component)_statusText).gameObject.activeSelf)
{
UpdateStatusTransform();
}
if (!_activeChannelValid)
{
return;
}
UpdateAudioSpatialization();
_driftCheckTimer -= Time.unscaledDeltaTime;
if (_driftCheckTimer > 0f)
{
return;
}
_driftCheckTimer = 2f;
if ((Object)(object)val == (Object)null || !val.isPlaying)
{
return;
}
uint num = default(uint);
((Channel)(ref _activeChannel)).getPosition(ref num, (TIMEUNIT)1);
double num2 = val.time * 1000.0;
double num3 = num2 - (double)num;
if (Math.Abs(num3) > 250.0)
{
((Channel)(ref _activeChannel)).setPosition((uint)num2, (TIMEUNIT)1);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogDebug((object)$"Theater drift correction: {num3:F1}ms → setPosition({num2:F0})");
}
}
}
private void OnDestroy()
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: 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)
if ((Object)(object)Current == (Object)(object)this)
{
Current = null;
}
StopActiveChannel();
if ((Object)(object)_screenMaterial != (Object)null)
{
for (int i = 0; i < _screenBindings.Length; i++)
{
_screenMaterial.SetTexture(_screenBindings[i].Name, _screenBindings[i].Texture);
_screenMaterial.SetTextureScale(_screenBindings[i].Name, _screenBindings[i].Scale);
_screenMaterial.SetTextureOffset(_screenBindings[i].Name, _screenBindings[i].Offset);
}
}
if (_slots != null)
{
for (int j = 0; j < _slots.Length; j++)
{
VideoPlayer player = _slots[j].Player;
if (player != null)
{
player.Stop();
}
if ((Object)(object)_slots[j].RenderTexture != (Object)null)
{
_slots[j].RenderTexture.Release();
Object.Destroy((Object)(object)_slots[j].RenderTexture);
}
}
}
if (_sounds == null)
{
return;
}
for (int k = 0; k < _sounds.Length; k++)
{
if (_sounds[k].handle != IntPtr.Zero)
{
((Sound)(ref _sounds[k])).release();
}
}
}
private static int Wrap(int v, int n)
{
return (v % n + n) % n;
}
}
internal sealed class VideoEntry
{
public string VideoPath;
public string AudioPath;
public string Name => Path.GetFileName(VideoPath);
}
internal static class VideoLibrary
{
private static readonly string[] VideoExtensions = new string[6] { ".mp4", ".webm", ".mov", ".ogv", ".mkv", ".m4v" };
private static readonly string[] AudioExtensions = new string[6] { ".ogg", ".wav", ".mp3", ".m4a", ".aac", ".flac" };
private static readonly string[] DedicatedSubfolders = new string[3] { "Videos", "Video", "video" };
public static List<VideoEntry> Entries { get; private set; } = new List<VideoEntry>();
public static List<string> Videos => Entries.ConvertAll((VideoEntry e) => e.VideoPath);
public static void ScanAll(string pluginsRoot, ManualLogSource log)
{
Entries.Clear();
if (!Directory.Exists(pluginsRoot))
{
log.LogWarning((object)("Plugins root '" + pluginsRoot + "' does not exist."));
return;
}
HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
string[] directories = Directory.GetDirectories(pluginsRoot);
foreach (string text in directories)
{
string[] dedicatedSubfolders = DedicatedSubfolders;
foreach (string path in dedicatedSubfolders)
{
string path2 = Path.Combine(text, path);
if (!Directory.Exists(path2))
{
continue;
}
string[] files = Directory.GetFiles(path2);
foreach (string text2 in files)
{
if (IsVideoFile(text2))
{
AddEntry(text2, requireSidecar: false, seen, log);
}
}
}
dedicatedSubfolders = Directory.GetFiles(text);
foreach (string text3 in dedicatedSubfolders)
{
if (IsVideoFile(text3))
{
AddEntry(text3, requireSidecar: true, seen, log);
}
}
}
Entries = Entries.OrderBy<VideoEntry, string>((VideoEntry e) => Path.GetFileName(e.VideoPath), StringComparer.OrdinalIgnoreCase).ToList();
if (Entries.Count == 0)
{
log.LogInfo((object)"No video files found (looked in plugin Videos/, Video/, and plugin roots with sidecar audio).");
return;
}
int num = Entries.Count((VideoEntry e) => e.AudioPath != null);
log.LogInfo((object)$"Theater loaded {Entries.Count} video(s) ({num} with sidecar audio):");
foreach (VideoEntry entry in Entries)
{
string text4 = ((entry.AudioPath != null) ? (" + " + Path.GetFileName(entry.AudioPath)) : " (silent — no sidecar)");
log.LogInfo((object)(" - " + entry.Name + text4));
}
}
private static void AddEntry(string file, bool requireSidecar, HashSet<string> seen, ManualLogSource log)
{
if (seen.Add(Path.GetFullPath(file)))
{
string text = FindSidecarAudio(file);
if (!requireSidecar || text != null)
{
Entries.Add(new VideoEntry
{
VideoPath = file,
AudioPath = text
});
}
}
}
private static bool IsVideoFile(string path)
{
return Array.IndexOf(VideoExtensions, Path.GetExtension(path).ToLowerInvariant()) >= 0;
}
private static string FindSidecarAudio(string videoPath)
{
string directoryName = Path.GetDirectoryName(videoPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(videoPath);
string[] audioExtensions = AudioExtensions;
foreach (string text in audioExtensions)
{
string text2 = Path.Combine(directoryName, fileNameWithoutExtension + text);
if (File.Exists(text2))
{
return text2;
}
}
return null;
}
}
internal class VolumeSliderUi : MonoBehaviour
{
private static readonly int[] ScreenResolutionOptions = new int[3] { 1024, 1536, 2048 };
public static VolumeSliderUi Instance;
private Slider _resolutionSlider;
private TextMeshProUGUI _resolutionValueLabel;
private Slider _volumeSlider;
private Slider _overscanSlider;
public static void EnsureExists(PauseMenu pauseMenu)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Instance != (Object)null) && !((Object)(object)pauseMenu == (Object)null) && !((Object)(object)pauseMenu.menuContainer == (Object)null))
{
GameObject val = new GameObject("SBG-TheaterVolumeSlider", new Type[1] { typeof(RectTransform) });
val.transform.SetParent(pauseMenu.menuContainer.transform, false);
Instance = val.AddComponent<VolumeSliderUi>();
}
}
public static void HandlePauseShown()
{
EnsureExists(SingletonBehaviour<PauseMenu>.Instance);
if (!((Object)(object)Instance == (Object)null))
{
Instance.SyncFromConfig();
Instance.SetVisible((Object)(object)TheaterController.Current != (Object)null);
}
}
public static void HandlePauseHidden()
{
Instance?.SetVisible(visible: false);
}
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: 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_0020: 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_0035: 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_004a: 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_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Expected O, but got Unknown
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = (RectTransform)((Component)this).transform;
val.anchorMin = new Vector2(0.5f, 0f);
val.anchorMax = new Vector2(0.5f, 0f);
val.pivot = new Vector2(0.5f, 0f);
val.anchoredPosition = new Vector2(0f, 64f);
val.sizeDelta = new Vector2(420f, 144f);
GameObject val2 = new GameObject("Panel", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val2.transform.SetParent(((Component)this).transform, false);
RectTransform component = val2.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
((Graphic)val2.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.65f);
(Slider, TextMeshProUGUI) tuple = CreateDiscreteSliderRow(val2.transform, "Screen res", 48f, ScreenResolutionOptions, Plugin.GetConfiguredScreenResolution(), delegate(int v)
{
Plugin.ScreenResolutionConfig.Value = v;
TheaterController.Current?.ApplyConfiguredScreenResolution();
});
_resolutionSlider = tuple.Item1;
_resolutionValueLabel = tuple.Item2;
_volumeSlider = CreateSliderRow(val2.transform, "Theater volume", 0f, 0f, 1f, Plugin.VolumeConfig.Value, delegate(float v)
{
Plugin.VolumeConfig.Value = v;
TheaterController.Current?.SetVolume(v);
});
_overscanSlider = CreateSliderRow(val2.transform, "Screen fit", -48f, 0f, 0.25f, Plugin.OverscanCompensationConfig.Value, delegate(float v)
{
Plugin.OverscanCompensationConfig.Value = v;
TheaterController.Current?.RefreshDisplayComposition();
});
SetVisible(visible: false);
}
private static Slider CreateSliderRow(Transform parent, string labelTextValue, float y, float min, float max, float value, UnityAction<float> onChanged)
{
//IL_002b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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_0089: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Expected O, but got Unknown
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_0228: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_0250: Expected O, but got Unknown
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_0288: Unknown result type (might be due to invalid IL or missing references)
//IL_029d: Unknown result type (might be due to invalid IL or missing references)
//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
//IL_02f7: 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_0322: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_034b: Expected O, but got Unknown
//IL_0370: Unknown result type (might be due to invalid IL or missing references)
//IL_0385: Unknown result type (might be due to invalid IL or missing references)
//IL_039a: Unknown result type (might be due to invalid IL or missing references)
//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0409: Unknown result type (might be due to invalid IL or missing references)
//IL_041c: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(labelTextValue + " Label", new Type[2]
{
typeof(RectTransform),
typeof(TextMeshProUGUI)
});
val.transform.SetParent(parent, false);
RectTransform component = val.GetComponent<RectTransform>();
component.anchorMin = new Vector2(0f, 0.5f);
component.anchorMax = new Vector2(0f, 0.5f);
component.pivot = new Vector2(0f, 0.5f);
component.anchoredPosition = new Vector2(14f, y);
component.sizeDelta = new Vector2(120f, 24f);
TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
((TMP_Text)component2).text = labelTextValue;
((TMP_Text)component2).fontSize = 16f;
((TMP_Text)component2).alignment = (TextAlignmentOptions)4097;
((Graphic)component2).color = Color.white;
GameObject val2 = new GameObject(labelTextValue + " Slider", new Type[2]
{
typeof(RectTransform),
typeof(Slider)
});
val2.transform.SetParent(parent, false);
RectTransform component3 = val2.GetComponent<RectTransform>();
component3.anchorMin = new Vector2(0f, 0.5f);
component3.anchorMax = new Vector2(1f, 0.5f);
component3.pivot = new Vector2(0f, 0.5f);
component3.anchoredPosition = new Vector2(140f, y);
component3.sizeDelta = new Vector2(-160f, 16f);
Slider component4 = val2.GetComponent<Slider>();
component4.minValue = min;
component4.maxValue = max;
component4.value = value;
GameObject val3 = new GameObject("Bg", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val3.transform.SetParent(val2.transform, false);
RectTransform component5 = val3.GetComponent<RectTransform>();
component5.anchorMin = new Vector2(0f, 0.25f);
component5.anchorMax = new Vector2(1f, 0.75f);
component5.sizeDelta = Vector2.zero;
((Graphic)val3.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.2f);
GameObject val4 = new GameObject("Fill Area", new Type[1] { typeof(RectTransform) });
val4.transform.SetParent(val2.transform, false);
RectTransform component6 = val4.GetComponent<RectTransform>();
component6.anchorMin = new Vector2(0f, 0.25f);
component6.anchorMax = new Vector2(1f, 0.75f);
component6.sizeDelta = new Vector2(-20f, 0f);
component6.anchoredPosition = new Vector2(-5f, 0f);
GameObject val5 = new GameObject("Fill", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val5.transform.SetParent(val4.transform, false);
RectTransform component7 = val5.GetComponent<RectTransform>();
component7.sizeDelta = Vector2.zero;
((Graphic)val5.GetComponent<Image>()).color = new Color(0.4f, 0.85f, 1f, 1f);
GameObject val6 = new GameObject("Handle Slide Area", new Type[1] { typeof(RectTransform) });
val6.transform.SetParent(val2.transform, false);
RectTransform component8 = val6.GetComponent<RectTransform>();
component8.anchorMin = new Vector2(0f, 0f);
component8.anchorMax = new Vector2(1f, 1f);
component8.sizeDelta = new Vector2(-20f, 0f);
component8.anchoredPosition = new Vector2(-5f, 0f);
GameObject val7 = new GameObject("Handle", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val7.transform.SetParent(val6.transform, false);
RectTransform component9 = val7.GetComponent<RectTransform>();
component9.sizeDelta = new Vector2(20f, 20f);
Image component10 = val7.GetComponent<Image>();
((Graphic)component10).color = Color.white;
((Selectable)component4).targetGraphic = (Graphic)(object)component10;
component4.fillRect = component7;
component4.handleRect = component9;
component4.direction = (Direction)0;
((UnityEvent<float>)(object)component4.onValueChanged).AddListener(onChanged);
return component4;
}
private static (Slider Slider, TextMeshProUGUI ValueLabel) CreateDiscreteSliderRow(Transform parent, string labelTextValue, float y, int[] options, int selectedValue, Action<int> onChanged)
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
Slider slider = CreateSliderRow(parent, labelTextValue, y, 0f, options.Length - 1, 0f, delegate
{
});
slider.wholeNumbers = true;
GameObject val = new GameObject(labelTextValue + " Value", new Type[2]
{
typeof(RectTransform),
typeof(TextMeshProUGUI)
});
val.transform.SetParent(parent, false);
RectTransform component = val.GetComponent<RectTransform>();
component.anchorMin = new Vector2(1f, 0.5f);
component.anchorMax = new Vector2(1f, 0.5f);
component.pivot = new Vector2(1f, 0.5f);
component.anchoredPosition = new Vector2(-12f, y);
component.sizeDelta = new Vector2(60f, 24f);
TextMeshProUGUI valueText = val.GetComponent<TextMeshProUGUI>();
((TMP_Text)valueText).fontSize = 16f;
((TMP_Text)valueText).alignment = (TextAlignmentOptions)4100;
((Graphic)valueText).color = Color.white;
int num = 0;
for (int i = 0; i < options.Length; i++)
{
if (options[i] == selectedValue)
{
num = i;
break;
}
}
slider.SetValueWithoutNotify((float)num);
((TMP_Text)valueText).text = options[num].ToString();
((UnityEventBase)slider.onValueChanged).RemoveAllListeners();
((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v)
{
int num2 = Mathf.Clamp(Mathf.RoundToInt(v), 0, options.Length - 1);
slider.SetValueWithoutNotify((float)num2);
((TMP_Text)valueText).text = options[num2].ToString();
onChanged(options[num2]);
});
return (slider, valueText);
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
private void SyncFromConfig()
{
if ((Object)(object)_resolutionSlider != (Object)null)
{
int configuredScreenResolution = Plugin.GetConfiguredScreenResolution();
int num = 0;
for (int i = 0; i < ScreenResolutionOptions.Length; i++)
{
if (ScreenResolutionOptions[i] == configuredScreenResolution)
{
num = i;
break;
}
}
_resolutionSlider.SetValueWithoutNotify((float)num);
if ((Object)(object)_resolutionValueLabel != (Object)null)
{
((TMP_Text)_resolutionValueLabel).text = ScreenResolutionOptions[num].ToString();
}
}
Slider volumeSlider = _volumeSlider;
if (volumeSlider != null)
{
volumeSlider.SetValueWithoutNotify(Plugin.VolumeConfig.Value);
}
Slider overscanSlider = _overscanSlider;
if (overscanSlider != null)
{
overscanSlider.SetValueWithoutNotify(Plugin.OverscanCompensationConfig.Value);
}
}
public void SetVisible(bool visible)
{
((Component)this).gameObject.SetActive(visible);
}
}
}