[AvPlayer] Report a loaded source as active before playback starts
sceAvPlayerIsActive answered true only after sceAvPlayerStart. Titles poll it after adding a source and before starting playback; Superliminal waits for it to turn true before it calls Start, so New Game never left the loading screen. Report a player as active from the moment its source is loaded until it is stopped or reaches its end, and track Stop explicitly so a stopped player stays inactive.
This commit is contained in:
parent
4d65ff6d51
commit
830eeaff53
|
|
@ -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} " +
|
||||
|
|
|
|||
|
|
@ -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<TValue>(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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue