diff --git a/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs b/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs index fdf686d..4e201bd 100644 --- a/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs +++ b/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs @@ -437,6 +437,7 @@ public static class AvPlayerExports public uint AvSyncMode { get; set; } = AvSyncModeDefault; public bool IsGen5 { get; init; } public bool Started { get; set; } + public bool Stopped { get; set; } public bool Paused { get; set; } public bool Looping { get; set; } public bool EndOfStream { get; set; } @@ -724,6 +725,7 @@ public static class AvPlayerExports player = foundPlayer; player.Started = true; + player.Stopped = false; player.Paused = false; player.EndOfStream = false; Trace($"start handle=0x{player.Handle:X16}"); @@ -767,6 +769,7 @@ public static class AvPlayerExports player.ResetPlayback(); player.Started = false; + player.Stopped = true; } NotifyEvent(ctx, player, 1); // StateStop @@ -1001,7 +1004,9 @@ public static class AvPlayerExports lock (StateGate) { var found = Players.TryGetValue(ctx[CpuRegister.Rdi], out var player); - var active = found && player!.Started && !player.EndOfStream; + // Active from the moment a source is ready until it stops, fails or reaches its end, + // whether or not playback has started (titles poll it before calling sceAvPlayerStart). + var active = found && player!.SourcePath is not null && !player.Stopped && !player.EndOfStream; TraceOnce( "is_active", $"is_active found={found} started={(found && player!.Started)} " + @@ -1388,6 +1393,7 @@ public static class AvPlayerExports player.DurationMilliseconds = duration; player.HasAudio = hasAudio; player.Started = player.AutoStart; + player.Stopped = false; autoStart = player.AutoStart; Trace( $"source guest='{guestPath}' host='{hostPath}' {width}x{height} " + diff --git a/tests/SharpEmu.Libs.Tests/AvPlayer/AvPlayerPlaybackTests.cs b/tests/SharpEmu.Libs.Tests/AvPlayer/AvPlayerPlaybackTests.cs index 971bd94..33a0797 100644 --- a/tests/SharpEmu.Libs.Tests/AvPlayer/AvPlayerPlaybackTests.cs +++ b/tests/SharpEmu.Libs.Tests/AvPlayer/AvPlayerPlaybackTests.cs @@ -96,6 +96,17 @@ public sealed class AvPlayerPlaybackTests Assert.Equal(1, playback.IsActive()); } + [Fact] + public void ALoadedSourceIsActiveBeforePlaybackStarts() + { + using var playback = new DecodedPlayback(0, 3, 2, 0); + playback.SetState("Started", false); + Assert.Equal(1, playback.IsActive()); + + playback.SetState("Stopped", true); + Assert.Equal(0, playback.IsActive()); + } + private sealed class DecodedPlayback : IDisposable { private const ulong Handle = 0xA0_0000_2300; @@ -215,7 +226,7 @@ public sealed class AvPlayerPlaybackTests public TValue GetState(string propertyName) => (TValue)_player.GetType().GetProperty(propertyName)!.GetValue(_player)!; - private void SetState(string propertyName, object value) => + public void SetState(string propertyName, object value) => _player.GetType().GetProperty(propertyName)!.SetValue(_player, value); private void SetArguments()