Implement held ADV fast-forward input

This commit is contained in:
gamer147
2026-07-21 10:45:46 -04:00
parent f840e356cf
commit c6b4985984
9 changed files with 167 additions and 17 deletions

View File

@@ -68,6 +68,59 @@ public class InputBindingTests
Assert.Equal(7, bindings.MouseAction(1));
}
[Theory]
[InlineData(0x08)] // retained native Backspace default
[InlineData(0x11)] // SYSTEM4 LeftCtrl binding
[InlineData(0x43)] // SYSTEM4 C binding
public void LogicalActionSixDrivesHeldAdvFastForward(int virtualKey)
{
var script = ScriptAssembler.Assemble(Table, "ADV_FAST_FORWARD", new List<(int, Operand[])>
{
(0x19c, Array.Empty<Operand>()),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var host = new RecordingHost();
var vm = new VirtualMachine(script, Table, host);
InputBindingBootstrap.Apply(
Sys4ScriptProvider.Load(Table).RequireByName("SYSTEM4.BIN"), vm.InputBindings);
vm.UpdateKeyboardVirtualKeyState(virtualKey, true);
Assert.False(host.PhysicalMessageSkip); // ADV lifecycle is not active yet.
vm.Run();
Assert.True(host.PhysicalMessageSkip);
Assert.True(host.MessageSkip);
vm.UpdateKeyboardVirtualKeyState(virtualKey, false);
Assert.False(host.PhysicalMessageSkip);
Assert.False(host.MessageSkip);
}
[Fact]
public void ReleasingPhysicalFastForwardDoesNotClearPersistentSkip()
{
var script = ScriptAssembler.Assemble(Table, "ADV_PERSISTENT_AND_HELD_SKIP", new List<(int, Operand[])>
{
(0x19c, Array.Empty<Operand>()),
(0x88, new[] { I(1) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var host = new RecordingHost();
var vm = new VirtualMachine(script, Table, host);
InputBindingBootstrap.Apply(
Sys4ScriptProvider.Load(Table).RequireByName("SYSTEM4.BIN"), vm.InputBindings);
vm.Run();
vm.UpdateKeyboardVirtualKeyState(0x11, true);
vm.UpdateKeyboardVirtualKeyState(0x11, false);
Assert.True(vm.MessageSkipEnabled);
Assert.False(host.PhysicalMessageSkip);
Assert.True(host.MessageSkip);
}
[Fact]
public void EmptyPollDispatchesTheCallbackAtActionCount()
{

View File

@@ -13,6 +13,8 @@ internal class RecordingHost : IHost
public int TransitionWaits;
public int InputCallbackFrames;
public bool MessageSkip;
public bool ScriptMessageSkip;
public bool PhysicalMessageSkip;
public bool AdvReadSkip;
public readonly List<(int Offset, string Text)> Lines = new();
public readonly List<(int Slot, int X, int Y)> TextCursors = new();
@@ -41,6 +43,7 @@ internal class RecordingHost : IHost
public readonly List<(int First, int Count)> ReleasedSurfaceRanges = new();
public readonly List<(int Source, int Target, long Interval)> SurfaceCrossfades = new();
public readonly List<bool> MessageSkipChanges = new();
public readonly List<bool> PhysicalMessageSkipChanges = new();
public readonly List<long> CursorResources = new();
public readonly List<bool> AdvPagePresentationSuspended = new();
public int CursorClearCount;
@@ -94,8 +97,15 @@ internal class RecordingHost : IHost
public bool IsMessageSkipActive => MessageSkip;
public void SetMessageSkipActive(bool active)
{
MessageSkip = active;
MessageSkipChanges.Add(active);
ScriptMessageSkip = active;
MessageSkip = ScriptMessageSkip || PhysicalMessageSkip;
MessageSkipChanges.Add(MessageSkip);
}
public void SetPhysicalMessageSkipActive(bool active)
{
PhysicalMessageSkip = active;
MessageSkip = ScriptMessageSkip || PhysicalMessageSkip;
PhysicalMessageSkipChanges.Add(active);
}
public bool IsAdvReadSkipActive => AdvReadSkip;
public void PresentFrame(GfxState gfx)