AquaDX/AquaMai/Utils/PractiseMode.cs

227 lines
5.9 KiB
C#
Raw Normal View History

2024-09-28 17:35:59 +08:00
using System;
2024-10-16 18:11:17 +08:00
using System.Collections;
2024-09-28 17:35:59 +08:00
using System.Collections.Generic;
using System.Diagnostics;
using AquaMai.Fix;
2024-09-28 16:30:19 +08:00
using AquaMai.Helpers;
using HarmonyLib;
2024-09-28 17:35:59 +08:00
using Manager;
2024-09-28 16:30:19 +08:00
using Monitor;
2024-10-16 18:41:07 +08:00
using Monitor.Game;
2024-09-28 16:30:19 +08:00
using Process;
using UnityEngine;
namespace AquaMai.Utils;
public class PractiseMode
{
2024-09-28 23:06:06 +08:00
public static double repeatStart = -1;
public static double repeatEnd = -1;
public static float speed = 1;
2024-09-28 19:42:42 +08:00
private static CriAtomExPlayer player;
2024-09-28 17:35:59 +08:00
private static MovieMaterialMai2 movie;
2024-10-16 18:41:07 +08:00
private static GameCtrl gameCtrl;
2024-09-28 16:30:19 +08:00
2024-09-28 23:06:06 +08:00
public static void SetRepeatEnd(double time)
2024-09-28 16:30:19 +08:00
{
if (repeatStart == -1)
{
MessageHelper.ShowMessage("Please set repeat start time first");
return;
}
if (time < repeatStart)
{
MessageHelper.ShowMessage("Repeat end time cannot be less than repeat start time");
return;
}
repeatEnd = time;
}
2024-09-28 23:06:06 +08:00
public static void ClearRepeat()
2024-09-28 16:30:19 +08:00
{
repeatStart = -1;
repeatEnd = -1;
}
2024-09-28 23:06:06 +08:00
public static void SetSpeed()
2024-09-28 17:35:59 +08:00
{
2024-09-28 19:42:42 +08:00
player.SetPitch((float)(1200 * Math.Log(speed, 2)));
// player.SetDspTimeStretchRatio(1 / speed);
player.UpdateAll();
2024-09-28 17:35:59 +08:00
movie.player.SetSpeed(speed);
2024-10-16 18:41:07 +08:00
gameCtrl?.ResetOptionSpeed();
2024-09-28 17:35:59 +08:00
}
2024-10-16 18:11:17 +08:00
private static IEnumerator SetSpeedCoroutineInner()
{
yield return null;
SetSpeed();
}
public static void SetSpeedCoroutine()
{
SharedInstances.GameMainObject.StartCoroutine(SetSpeedCoroutineInner());
}
2024-09-28 23:06:06 +08:00
public static void SpeedUp()
2024-09-28 17:35:59 +08:00
{
speed += .05f;
if (speed > 2)
{
speed = 2;
}
SetSpeed();
}
2024-09-28 23:06:06 +08:00
public static void SpeedDown()
2024-09-28 17:35:59 +08:00
{
speed -= .05f;
2024-10-16 18:11:17 +08:00
if (speed < 0.05)
2024-09-28 17:35:59 +08:00
{
2024-10-16 18:11:17 +08:00
speed = 0.05f;
2024-09-28 17:35:59 +08:00
}
SetSpeed();
}
2024-09-28 23:06:06 +08:00
public static void SpeedReset()
2024-09-28 17:35:59 +08:00
{
speed = 1;
SetSpeed();
}
public static void Seek(int addMsec)
{
// Debug feature 里面那个 timer 不能感知变速
// 为了和魔改版本统一polyfill 里面不修这个
// 这里重新实现一个能感知变速的 Seek
var msec = CurrentPlayMsec + addMsec;
if (msec < 0)
{
msec = 0;
}
DebugFeature.CurrentPlayMsec = msec;
}
public static double CurrentPlayMsec
{
get => NotesManager.GetCurrentMsec() - 91;
set => DebugFeature.CurrentPlayMsec = value;
}
2024-09-28 23:06:06 +08:00
public static PractiseModeUI ui;
2024-09-28 16:30:19 +08:00
2024-09-28 17:35:59 +08:00
[HarmonyPatch(typeof(GameProcess), "OnStart")]
[HarmonyPostfix]
public static void GameProcessPostStart()
{
repeatStart = -1;
repeatEnd = -1;
speed = 1;
2024-09-28 23:06:06 +08:00
ui = null;
2024-10-16 18:41:07 +08:00
}
[HarmonyPatch(typeof(GameCtrl), "Initialize")]
[HarmonyPostfix]
public static void GameCtrlPostInitialize(GameCtrl __instance)
{
gameCtrl = __instance;
2024-09-28 17:35:59 +08:00
}
2024-10-01 15:50:00 +08:00
# if DEBUG
2024-09-28 23:06:06 +08:00
[HarmonyPrefix]
[HarmonyPatch(typeof(GenericProcess), "OnUpdate")]
public static void OnGenericProcessUpdate(GenericMonitor[] ____monitors)
{
if (Input.GetKeyDown(KeyCode.F11))
2024-09-28 23:06:06 +08:00
{
____monitors[0].gameObject.AddComponent<PractiseModeUI>();
}
}
2024-10-01 15:50:00 +08:00
# endif
2024-09-28 23:06:06 +08:00
2024-09-28 16:30:19 +08:00
[HarmonyPatch(typeof(GameProcess), "OnUpdate")]
[HarmonyPostfix]
public static void GameProcessPostUpdate(GameProcess __instance, GameMonitor[] ____monitors)
{
2024-09-28 23:06:06 +08:00
if (InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonTest) && ui is null)
2024-09-28 16:30:19 +08:00
{
2024-09-28 23:06:06 +08:00
ui = ____monitors[0].gameObject.AddComponent<PractiseModeUI>();
2024-09-28 16:30:19 +08:00
}
if (repeatStart >= 0 && repeatEnd >= 0)
{
if (CurrentPlayMsec >= repeatEnd)
2024-09-28 16:30:19 +08:00
{
CurrentPlayMsec = repeatStart;
2024-09-28 16:30:19 +08:00
}
}
}
2024-09-28 17:35:59 +08:00
2024-10-16 18:41:07 +08:00
private static float startGap = -1f;
[HarmonyPatch(typeof(NotesManager), "StartPlay")]
2024-09-28 17:35:59 +08:00
[HarmonyPostfix]
2024-10-16 18:41:07 +08:00
public static void NotesManagerPostUpdateTimer(float msecStartGap)
{
startGap = msecStartGap;
}
[HarmonyPatch(typeof(NotesManager), "UpdateTimer")]
[HarmonyPrefix]
public static bool NotesManagerPostUpdateTimer(bool ____isPlaying, Stopwatch ____stopwatch, ref float ____curMSec, ref float ____curMSecPre, float ____msecStartGap)
2024-09-28 17:35:59 +08:00
{
2024-10-16 18:41:07 +08:00
if (startGap != -1f)
2024-09-28 17:35:59 +08:00
{
2024-10-16 18:41:07 +08:00
____curMSec = startGap;
____curMSecPre = startGap;
____stopwatch?.Reset();
startGap = -1f;
}
else
{
____curMSecPre = ____curMSec;
if (____isPlaying && ____stopwatch != null && !DebugFeature.Pause)
{
var num = (double)____stopwatch.ElapsedTicks / Stopwatch.Frequency * 1000.0 * speed;
____curMSec += (float)num;
____stopwatch.Reset();
____stopwatch.Start();
}
2024-09-28 17:35:59 +08:00
}
2024-10-16 18:41:07 +08:00
return false;
2024-09-28 17:35:59 +08:00
}
2024-09-28 19:42:42 +08:00
[HarmonyPatch(typeof(SoundCtrl), "Initialize")]
[HarmonyPostfix]
public static void SoundCtrlPostInitialize(SoundCtrl.InitParam param, Dictionary<int, object> ____players)
2024-09-28 17:35:59 +08:00
{
2024-09-28 19:42:42 +08:00
var wrapper = ____players[2];
player = (CriAtomExPlayer)wrapper.GetType().GetField("Player").GetValue(wrapper);
// var pool = new CriAtomExStandardVoicePool(1, 8, 96000, true, 2);
// pool.AttachDspTimeStretch();
// player.SetVoicePoolIdentifier(pool.identifier);
// debug
// var wrapper1 = ____players[7];
// var player1 = (CriAtomExPlayer)wrapper1.GetType().GetField("Player").GetValue(wrapper1);
// var pool = new CriAtomExStandardVoicePool(1, 8, 96000, true, 2);
// pool.AttachDspTimeStretch();
// player1.SetVoicePoolIdentifier(pool.identifier);
// player1.SetDspTimeStretchRatio(2);
2024-09-28 17:35:59 +08:00
}
[HarmonyPatch(typeof(MovieController), "Awake")]
[HarmonyPostfix]
public static void MovieControllerPostAwake(MovieMaterialMai2 ____moviePlayers)
{
movie = ____moviePlayers;
}
2024-09-28 16:30:19 +08:00
}