Skip to content

Commit

Permalink
Patches to allow fade outs
Browse files Browse the repository at this point in the history
  • Loading branch information
Metious committed Nov 10, 2024
1 parent 8b074bd commit 80ae484
Showing 1 changed file with 48 additions and 7 deletions.
55 changes: 48 additions & 7 deletions Nautilus/Patchers/CustomSoundPatcher.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
using System;
using System.Collections.Generic;
using FMOD;
using FMOD.Studio;
using FMODUnity;
using HarmonyLib;
using Nautilus.Extensions;
using Nautilus.FMod.Interfaces;
using Nautilus.Handlers;
using Nautilus.Utility;
using UnityEngine;
using UnityEngine.Playables;
using STOP_MODE = FMOD.Studio.STOP_MODE;

namespace Nautilus.Patchers;

internal class CustomSoundPatcher
{
internal record struct AttachedChannel(Channel Channel, Transform Transform);
internal record struct FadeInfo(Sound Sound, float Seconds);

internal static readonly SelfCheckingDictionary<string, Sound> CustomSounds = new("CustomSounds");
internal static readonly SelfCheckingDictionary<string, Bus> CustomSoundBuses = new("CustomSoundBuses");
internal static readonly SelfCheckingDictionary<string, IFModSound> CustomFModSounds = new("CustoomFModSounds");
internal static readonly Dictionary<int, Channel> EmitterPlayedChannels = new();
internal static readonly Dictionary<IntPtr, FadeInfo> FadeOuts = new();
internal static List<AttachedChannel> AttachedChannels = new();

private static readonly Dictionary<string, Channel> PlayedChannels = new();
Expand Down Expand Up @@ -159,10 +164,14 @@ public static bool FMODEventPlayableBehavior_OnExit_Prefix(FMODEventPlayableBeha
return false;
}

if (__instance.stopType != FMODUnity.STOP_MODE.None)
if (__instance.stopType == FMODUnity.STOP_MODE.Immediate)
{
channel.stop();
}
else if (__instance.stopType == FMODUnity.STOP_MODE.AllowFadeout)
{
TryFadeOutBeforeStop(channel);
}

PlayableBehaviorChannels.Remove(__instance);
__instance.isPlayheadInside = false;
Expand Down Expand Up @@ -440,11 +449,18 @@ public static bool FMOD_CustomEmitter_Play_Prefix(FMOD_CustomEmitter __instance)

[HarmonyPatch(typeof(FMOD_CustomEmitter), nameof(FMOD_CustomEmitter.Stop))]
[HarmonyPrefix]
public static bool FMOD_CustomEmitter_Stop_Prefix(FMOD_CustomEmitter __instance)
public static bool FMOD_CustomEmitter_Stop_Prefix(FMOD_CustomEmitter __instance, STOP_MODE stopMode)
{
if (!EmitterPlayedChannels.TryGetValue(__instance.GetInstanceID(), out var channel)) return true;

channel.stop();
if (stopMode == STOP_MODE.IMMEDIATE)
{
channel.stop();
}
else
{
TryFadeOutBeforeStop(channel);
}
__instance._playing = false;
__instance.OnStop();

Expand Down Expand Up @@ -486,7 +502,8 @@ public static bool FMOD_CustomEmitter_ReleaseEvent_Prefix(FMOD_CustomEmitter __i
if (__instance.asset == null || !CustomSounds.ContainsKey(__instance.asset.path) && !CustomFModSounds.ContainsKey(__instance.asset.path)) return true;
if (!EmitterPlayedChannels.TryGetValue(__instance.GetInstanceID(), out var channel)) return false; // known sound but not played yet

channel.stop();
!TryFadeOutBeforeStop(channel);

EmitterPlayedChannels.Remove(__instance.GetInstanceID());

return false;
Expand Down Expand Up @@ -761,14 +778,22 @@ public static bool FMOD_CustomEmitter_Play_Prefix(FMOD_CustomEmitter __instance)

[HarmonyPatch(typeof(FMOD_CustomEmitter), nameof(FMOD_CustomEmitter.Stop))]
[HarmonyPrefix]
public static bool FMOD_CustomEmitter_Stop_Prefix(FMOD_CustomEmitter __instance)
public static bool FMOD_CustomEmitter_Stop_Prefix(FMOD_CustomEmitter __instance, STOP_MODE stopMode)
{
if (!EmitterPlayedChannels.TryGetValue(__instance.GetInstanceID(), out Channel channel))
{
return true;
}

channel.stop();
if (stopMode == STOP_MODE.ALLOWFADEOUT)
{
TryFadeOutBeforeStop(channel);
}
else
{
channel.stop();
}

__instance._playing = false;
__instance.OnStop();

Expand Down Expand Up @@ -827,7 +852,9 @@ public static bool FMOD_CustomEmitter_ReleaseEvent_Prefix(FMOD_CustomEmitter __i
return false; // known sound but not played yet
}

channel.stop();
TryFadeOutBeforeStop(channel);


EmitterPlayedChannels.Remove(__instance.GetInstanceID());

return false;
Expand Down Expand Up @@ -923,4 +950,18 @@ internal static void SetChannel3DAttributes(Channel channel, Vector3 position)
ATTRIBUTES_3D attributes = position.To3DAttributes();
channel.set3DAttributes(ref attributes.position, ref attributes.velocity);
}

private static bool TryFadeOutBeforeStop(Channel channel)
{
if (channel.getCurrentSound(out var sound) != RESULT.OK || !FadeOuts.TryGetValue(sound.handle, out var fadeOut))
{
channel.stop();
return false;
}

RuntimeManager.CoreSystem.getSoftwareFormat(out var samplesRate, out _, out _);
channel.AddFadeOut(fadeOut.Seconds, out var dspClock);
channel.setDelay(0, dspClock + (ulong)(samplesRate * fadeOut.Seconds));
return true;
}
}

0 comments on commit 80ae484

Please sign in to comment.