-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
79487d9
commit f72c253
Showing
8 changed files
with
409 additions
and
6 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
Osu.Patcher.Hook/Patches/Mods/AudioPreview/FixUpdatePlaybackRate.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
using HarmonyLib; | ||
using JetBrains.Annotations; | ||
using Osu.Stubs.Audio; | ||
using Osu.Utils.Extensions; | ||
using static System.Reflection.Emit.OpCodes; | ||
|
||
namespace Osu.Patcher.Hook.Patches.Mods.AudioPreview; | ||
|
||
/// <summary> | ||
/// <c>AudioTrackBass::updatePlaybackRate()</c> forcibly resets the tempo to | ||
/// normal if a pitch isn't applied. This forces the tempo to be set if pitch isn't applied, | ||
/// to be used with the <see cref="ModSelectAudioPreview" /> patch | ||
/// </summary> | ||
[OsuPatch] | ||
[HarmonyPatch] | ||
[UsedImplicitly] | ||
internal static class FixUpdatePlaybackRate | ||
{ | ||
// static FixUpdatePlaybackRate() | ||
// { | ||
// Task.Run(async () => | ||
// { | ||
// await Task.Delay(2000); | ||
// try | ||
// { | ||
// var mtd = AccessTools.Method(AudioTrackBass.Class.Reference.Name + ":" + | ||
// AudioTrackBass.UpdatePlaybackRate.Reference.Name); | ||
// foreach (var instruction in MethodReader.GetInstructions(mtd)) | ||
// { | ||
// Console.WriteLine($"{instruction.Opcode} {instruction.Operand}"); | ||
// } | ||
// } | ||
// catch (Exception e) | ||
// { | ||
// Console.WriteLine(e); | ||
// } | ||
// }); | ||
// } | ||
|
||
[UsedImplicitly] | ||
[HarmonyTargetMethod] | ||
private static MethodBase Target() => AudioTrackBass.UpdatePlaybackRate.Reference; | ||
|
||
// TODO: WHY THE FUCK ISN'T THIS TRANSPILER APPLYING CHANGES????? PRE/POST PATCHES WORK FINE BUT THIS DOESN'T???????? | ||
[UsedImplicitly] | ||
[HarmonyTranspiler] | ||
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) | ||
{ | ||
instructions = instructions.ManipulatorReplace( | ||
// Find inst that loads 0f as the parameter "value" to BASS_ChannelSetAttribute | ||
inst => inst.Is(Ldc_R4, 0f), | ||
inst => new CodeInstruction[] | ||
{ | ||
new(Ldarg_0) { labels = inst.labels }, // Load "this" | ||
new(Ldfld, AudioTrackBass.PlaybackRate.Reference), // Load the float64 "playbackRate" | ||
new(Ldc_R8, 100.0), // Load the float64 "100.0" | ||
new(Sub), // Subtract 100.0 from playbackRate | ||
new(Conv_R4), // Convert to float32 | ||
} | ||
); | ||
|
||
return instructions; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
Osu.Patcher.Hook/Patches/Mods/AudioPreview/ModSelectAudioPreview.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Reflection; | ||
using HarmonyLib; | ||
using JetBrains.Annotations; | ||
using Osu.Stubs.Audio; | ||
using Osu.Stubs.SongSelect; | ||
using static Osu.Stubs.Other.Mods; | ||
|
||
namespace Osu.Patcher.Hook.Patches.Mods.AudioPreview; | ||
|
||
[OsuPatch] | ||
[HarmonyPatch] | ||
[UsedImplicitly] | ||
internal class ModSelectAudioPreview | ||
{ | ||
[UsedImplicitly] | ||
[HarmonyTargetMethod] | ||
private static MethodBase Target() => ModButton.SetStatus.Reference; | ||
|
||
[UsedImplicitly] | ||
[HarmonyPostfix] | ||
[SuppressMessage("ReSharper", "InconsistentNaming")] | ||
private static void After( | ||
object __instance, // typeof(ModButton) | ||
[HarmonyArgument(1)] int mod, | ||
[HarmonyArgument(2)] bool playSound) | ||
{ | ||
// These calls happen for all mods on any mod update and don't actually do anything | ||
if (!playSound) return; | ||
|
||
// var availableModStates = ModButton.AvailableStates.Get(__instance); | ||
// | ||
// // Check that this is the DT+NC or HF button | ||
// if (availableModStates[0] is not (DoubleTime or HalfTime)) | ||
// return; | ||
|
||
ApplyChanges(mod); | ||
} | ||
|
||
internal static void ApplyChanges(int mods) | ||
{ | ||
ResetChanges(); | ||
|
||
switch (mods & (DoubleTime | Nightcore | HalfTime)) | ||
{ | ||
case DoubleTime: | ||
UpdateAudioRate(rate => rate * 1.5); | ||
break; | ||
case Nightcore: | ||
AudioEngine.Nightcore.Set(true); | ||
UpdateAudioRate(rate => rate * 1.5); | ||
break; | ||
case HalfTime: | ||
UpdateAudioRate(rate => rate * 0.75); | ||
break; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Resets the audio stream effects back to default. | ||
/// </summary> | ||
private static void ResetChanges() | ||
{ | ||
AudioEngine.Nightcore.Set(false); | ||
UpdateAudioRate(_ => 100); | ||
} | ||
|
||
private static void UpdateAudioRate(Func<double, double> onModify) | ||
{ | ||
var currentRate = AudioEngine.GetCurrentPlaybackRate.Invoke(); | ||
var newRate = onModify.Invoke(currentRate); | ||
|
||
AudioEngine.SetCurrentPlaybackRate.Invoke(parameters: [newRate]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using System.Linq; | ||
using System.Reflection; | ||
using JetBrains.Annotations; | ||
using Osu.Utils.IL; | ||
using Osu.Utils.Lazy; | ||
using static System.Reflection.Emit.OpCodes; | ||
|
||
namespace Osu.Stubs.Audio; | ||
|
||
/// <summary> | ||
/// Original: <c>osu.Audio.AudioEngine</c> | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[PublicAPI] | ||
public class AudioEngine | ||
{ | ||
/// <summary> | ||
/// Original: <c>get_CurrentPlaybackRate()</c> (property getter) | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyMethod<double> GetCurrentPlaybackRate = LazyMethod<double>.BySignature( | ||
"osu.Audio.AudioEngine::get_CurrentPlaybackRate()", | ||
[ | ||
Ldsfld, | ||
Dup, | ||
Brtrue_S, | ||
Pop, | ||
Ldc_R8, | ||
Ret, | ||
Callvirt, | ||
Ret, | ||
] | ||
); | ||
|
||
/// <summary> | ||
/// Original: <c>set_CurrentPlaybackRate()</c> (property setter) | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyMethod SetCurrentPlaybackRate = LazyMethod.ByPartialSignature( | ||
"osu.Audio.AudioEngine::set_CurrentPlaybackRate()", | ||
[ | ||
Ldsfld, // Reference to AudioEngine::Nightcore | ||
Ldc_I4_0, | ||
Ceq, | ||
Callvirt, | ||
Ldloc_0, | ||
Ldarg_0, | ||
Callvirt, | ||
Ret, | ||
] | ||
); | ||
|
||
/// <summary> | ||
/// Original: <c>Nightcore</c> | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyField<bool> Nightcore = new( | ||
"osu.Audio.AudioEngine::Nightcore", | ||
() => | ||
{ | ||
// Last Ldsfld in get_CurrentPlaybackRate() is a reference to AudioEngine::Nightcore | ||
var instruction = MethodReader | ||
.GetInstructions(SetCurrentPlaybackRate.Reference) | ||
.Reverse() | ||
.First(inst => inst.Opcode == Ldsfld); | ||
|
||
return (FieldInfo)instruction.Operand; | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System.Linq; | ||
using HarmonyLib; | ||
using JetBrains.Annotations; | ||
using Osu.Utils.Lazy; | ||
using static System.Reflection.Emit.OpCodes; | ||
|
||
namespace Osu.Stubs.Audio; | ||
|
||
[PublicAPI] | ||
public class AudioTrackBass | ||
{ | ||
/// <summary> | ||
/// Original: <c>osu.Audio.AudioTrackBass</c> | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyType Class = new( | ||
"osu.Audio.AudioTrackBass", | ||
() => UpdatePlaybackRate!.Reference.DeclaringType! | ||
); | ||
|
||
/// <summary> | ||
/// Original: <c>updatePlaybackRate()</c> | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyMethod UpdatePlaybackRate = LazyMethod.ByPartialSignature( | ||
"osu.Audio.AudioTrackBass::updatePlaybackRate()", | ||
[ | ||
Conv_R8, | ||
Ldarg_0, | ||
Ldfld, | ||
Mul, | ||
Ldc_R8, | ||
Div, | ||
Conv_R4, | ||
Call, | ||
Pop, | ||
] | ||
); | ||
|
||
/// <summary> | ||
/// Original: <c>playbackRate</c> | ||
/// b20240123: <c></c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyField<double> PlaybackRate = new( | ||
"osu.Audio.AudioTrackBass::playbackRate", | ||
() => Class.Reference | ||
.GetDeclaredFields() | ||
.Single(field => field.FieldType == typeof(double)) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using JetBrains.Annotations; | ||
using Osu.Utils.Lazy; | ||
|
||
namespace Osu.Stubs.Other; | ||
|
||
[PublicAPI] | ||
public class Mods | ||
{ | ||
public const int None = 0; | ||
public const int NoFail = 1 << 0; | ||
public const int Easy = 1 << 1; | ||
public const int Hidden = 1 << 3; | ||
public const int HardRock = 1 << 4; | ||
public const int SuddenDeath = 1 << 5; | ||
public const int DoubleTime = 1 << 6; | ||
public const int Relax = 1 << 7; | ||
public const int HalfTime = 1 << 8; | ||
public const int Nightcore = 1 << 9; | ||
public const int Flashlight = 1 << 10; | ||
public const int Autoplay = 1 << 11; | ||
public const int SpunOut = 1 << 12; | ||
public const int Relax2 = 1 << 13; | ||
public const int Perfect = 1 << 14; | ||
public const int Key4 = 1 << 15; | ||
public const int Key5 = 1 << 16; | ||
public const int Key6 = 1 << 17; | ||
public const int Key7 = 1 << 18; | ||
public const int Key8 = 1 << 19; | ||
public const int FadeIn = 1 << 20; | ||
public const int Random = 1 << 21; | ||
public const int Cinema = 1 << 22; | ||
public const int Target = 1 << 23; | ||
public const int Key9 = 1 << 24; | ||
public const int KeyCoop = 1 << 25; | ||
public const int Key1 = 1 << 26; | ||
public const int Key3 = 1 << 27; | ||
public const int Key2 = 1 << 28; | ||
|
||
/// <summary> | ||
/// Original: <c>osu_common.Mods</c> | ||
/// b20240123: <c>osu_common.Mods</c> | ||
/// </summary> | ||
[Stub] | ||
public static readonly LazyType Type = LazyType.ByName("osu_common.Mods"); | ||
} |
Oops, something went wrong.