Fix skip completion for visual transitions
This commit is contained in:
@@ -131,9 +131,13 @@ public interface IHost
|
||||
void PresentFrame(GfxState gfx) { }
|
||||
// Legacy SYS4 screen-transition family (ops 0x21, 0x22, and 0x25): scripts render complete
|
||||
// frames into numbered surfaces, then block while the engine alpha-composites an endpoint.
|
||||
// Native bypasses the timed service when ADV fast-forward is already active at opcode dispatch.
|
||||
void FadeSurfaceWithBlack(
|
||||
GfxState gfx, int surface, long intervalArgument, SurfaceBlackFadeDirection direction) { }
|
||||
void CrossfadeSurfaces(GfxState gfx, int sourceSurface, int targetSurface, long intervalArgument) { }
|
||||
GfxState gfx, int surface, long intervalArgument, SurfaceBlackFadeDirection direction,
|
||||
bool forceEndpoint = false) { }
|
||||
void CrossfadeSurfaces(
|
||||
GfxState gfx, int sourceSurface, int targetSurface, long intervalArgument,
|
||||
bool forceEndpoint = false) { }
|
||||
void CreateTexture(int slot, int width, int height);
|
||||
/// <summary>Return a stable RGBA snapshot of one numbered surface, or null when unavailable.</summary>
|
||||
RgbaImage? CaptureSurfacePixels(int slot) => null;
|
||||
|
||||
@@ -934,7 +934,49 @@ public sealed class GfxState
|
||||
(o.RotationEnabled && o.RotationPeriodMs > 0)));
|
||||
}
|
||||
|
||||
/// <summary>Click completion affects only type-0 foreground transitions, never ambient object channels.</summary>
|
||||
/// <summary>Force the finite retained presentation serviced by native run-state bit 0x400 to its
|
||||
/// endpoint. This is the EffectSkipOnClick path: type-0 surface commands and ordinary finite object
|
||||
/// channels complete together, while movie masks, ambient cycles, and op-0x242-detached channels remain
|
||||
/// active. Op 0x24e bit 0 disables click skipping; bit 1 suppresses the shared force-complete request.</summary>
|
||||
public int CompleteClickSkippableTimedPresentation(long nowMs)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if ((AnimationServiceFlags & 3) != 0) return 0;
|
||||
|
||||
int completed = 0;
|
||||
foreach (var t in _surfaceTransitions.Values)
|
||||
{
|
||||
if (t.Forced || TransitionProgress(t, nowMs) >= 1.0) continue;
|
||||
t.Forced = true;
|
||||
completed++;
|
||||
}
|
||||
|
||||
completed += CountOneShotChannels(_rangeTransform);
|
||||
foreach (var o in _objects.Values)
|
||||
{
|
||||
if ((o.OneShotAnimationControlFlags & 1) != 0) continue;
|
||||
completed += CountOneShotChannels(o);
|
||||
}
|
||||
ForceCompleteOneShotChannels();
|
||||
|
||||
if (AnimClockDurationTicks != 0) completed++;
|
||||
AnimClockDurationTicks = 0;
|
||||
AnimClockGeneration++;
|
||||
|
||||
if (completed > 0) MarkRetainedMutation();
|
||||
return completed;
|
||||
}
|
||||
}
|
||||
|
||||
private static int CountOneShotChannels(GfxObject o)
|
||||
=> (o.OneShotColorEnabled ? 1 : 0)
|
||||
+ (o.ScaleEnabled ? 1 : 0)
|
||||
+ (o.RotationChannelEnabled ? 1 : 0)
|
||||
+ (o.TranslationEnabled ? 1 : 0);
|
||||
|
||||
/// <summary>Force only queued type-0 foreground transitions. PresentFrame uses this to publish a
|
||||
/// command endpoint immediately; interactive run-state-0x400 skipping uses the broader method above.</summary>
|
||||
public int CompleteForegroundTransitions(long nowMs)
|
||||
{
|
||||
lock (_lock)
|
||||
|
||||
@@ -2862,16 +2862,20 @@ public sealed class VirtualMachine
|
||||
case "fade-surface-in-from-black": // 0x21: blocking black -> captured full-frame surface
|
||||
case "u00418860":
|
||||
_host.FadeSurfaceWithBlack(
|
||||
Gfx, (int)Read(a[0]), Read(a[1]), SurfaceBlackFadeDirection.FromBlack);
|
||||
Gfx, (int)Read(a[0]), Read(a[1]), SurfaceBlackFadeDirection.FromBlack,
|
||||
_messageSkipServiceActive || _host.IsMessageSkipActive);
|
||||
return pc + 1;
|
||||
case "fade-surface-out-to-black": // 0x22: blocking captured full-frame surface -> black
|
||||
case "u00418920":
|
||||
_host.FadeSurfaceWithBlack(
|
||||
Gfx, (int)Read(a[0]), Read(a[1]), SurfaceBlackFadeDirection.ToBlack);
|
||||
Gfx, (int)Read(a[0]), Read(a[1]), SurfaceBlackFadeDirection.ToBlack,
|
||||
_messageSkipServiceActive || _host.IsMessageSkipActive);
|
||||
return pc + 1;
|
||||
case "crossfade-surfaces": // 0x25: legacy full-frame surface alpha transition
|
||||
case "u00418B40":
|
||||
_host.CrossfadeSurfaces(Gfx, (int)Read(a[0]), (int)Read(a[1]), Read(a[2]));
|
||||
_host.CrossfadeSurfaces(
|
||||
Gfx, (int)Read(a[0]), (int)Read(a[1]), Read(a[2]),
|
||||
_messageSkipServiceActive || _host.IsMessageSkipActive);
|
||||
return pc + 1;
|
||||
case "mark-frame-yield": // 0x21c: normal foreground-transition scheduler/resume boundary
|
||||
_host.WaitForForegroundTransition(Gfx); return pc + 1;
|
||||
|
||||
Reference in New Issue
Block a user