Honor ADV skip for BGM fades

This commit is contained in:
gamer147
2026-08-17 13:54:20 -04:00
parent 4d9b786ffb
commit 9ed954fa1b
7 changed files with 77 additions and 13 deletions

View File

@@ -99,4 +99,34 @@ public class SfxOpsTests
Assert.Equal(0, Assert.Single(host.SfxReleases));
Assert.Equal((25, 3000L), Assert.Single(host.BgmFades));
}
[Fact]
public void ActiveAdvSkipForcesBgmFadeEndpointButOrdinaryDispatchKeepsAuthoredDelay()
{
var table = OpcodeTableJson.Load(Paths.OpcodesJson);
var script = ScriptAssembler.Assemble(table, "BGM-FADE-SKIP",
new List<(int, Operand[])>
{
(0xc2, new[] { new Operand(0, 0), new Operand(0, 3000) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var persistentSkipScript = ScriptAssembler.Assemble(table, "BGM-FADE-PERSISTENT-SKIP",
new List<(int, Operand[])>
{
(0x88, new[] { new Operand(0, 1) }),
(0xc2, new[] { new Operand(0, 0), new Operand(0, 3000) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var ordinaryHost = new RecordingHost();
var physicalSkipHost = new RecordingHost { MessageSkip = true };
var persistentSkipHost = new RecordingHost();
new VirtualMachine(script, table, ordinaryHost).Run();
new VirtualMachine(script, table, physicalSkipHost).Run();
new VirtualMachine(persistentSkipScript, table, persistentSkipHost).Run();
Assert.Equal((0, 3000L), Assert.Single(ordinaryHost.BgmFades));
Assert.Equal((0, 0L), Assert.Single(physicalSkipHost.BgmFades));
Assert.Equal((0, 0L), Assert.Single(persistentSkipHost.BgmFades));
}
}

View File

@@ -90,7 +90,12 @@ public sealed partial class VirtualMachine
case "u0041D2B0": // 0xc2 / semantics: fade-bgm
{
int targetPercent = (int)Read(a[0]);
_host.FadeBgm(targetPercent, Read(a[1]));
long durationMs = Read(a[1]);
// Native op 0xc2 enters its timed run-state only during ordinary playback. An
// already-active ADV fast-forward applies the fade endpoint immediately; a normal
// advance click does not set that skip state and therefore retains the authored delay.
bool forceEndpoint = _messageSkipServiceActive || _host.IsMessageSkipActive;
_host.FadeBgm(targetPercent, forceEndpoint ? 0 : durationMs);
if (targetPercent == 0)
{
_currentBgmTrackId = 0;