using System.IO; using ADOFAIRenderer.Core; using ADOFAIRenderer.Util; using HarmonyLib; namespace ADOFAIRenderer.Patch.Game { [HarmonyPatch(typeof(scnGame))] // ReSharper disable once InconsistentNaming public static class scnGamePatch { [HarmonyPrefix] [HarmonyPatch("UpdateVideo")] public static bool Prefix(scnGame __instance) { // Only replace when rendering is active if (!RenderManager.IsActive) { // Remove FFmpeg player if it was attached previously var oldPlayer = __instance.videoBG.gameObject.GetComponent(); if (oldPlayer != null) { UnityEngine.Object.Destroy(oldPlayer); } // Re-enable native player component __instance.videoBG.enabled = true; return true; // Execute original } string text = __instance.levelData.miscSettings.GetString("bgVideo"); if (string.IsNullOrEmpty(text)) { __instance.videoBG.gameObject.SetActive(false); return false; // Skip original } __instance.videoBG.gameObject.SetActive(true); // We can only play external video files via FFmpegNativeDecoder. // Internal/Bundle level background videos are built-in VideoClips, so we fallback to native Unity VideoPlayer. if (ADOBase.isInternalLevel || ADOBase.isBundleLevel) { __instance.videoBG.enabled = true; return true; // Execute original } // Custom level video path string videoPath = Path.Combine(Path.GetDirectoryName(ADOBase.levelPath), text); if (!File.Exists(videoPath)) { return true; // Let the original print error } // Disable native VideoPlayer component (to prevent it from attempting real-time playback and sync errors) __instance.videoBG.enabled = false; // Add or retrieve our custom FFmpeg video background player var player = __instance.videoBG.gameObject.GetComponent(); if (player == null) { player = __instance.videoBG.gameObject.AddComponent(); } bool isLooping = __instance.levelData.miscSettings.GetBool("loopVideo"); // In custom levels, ADOFAI's videoBG targetTexture is pre-allocated by the game to render background filters. // We initialize the player with the target RenderTexture. player.Init(videoPath, __instance.videoBG.targetTexture, isLooping); return false; // Skip original UpdateVideo } } }