Fix menu cursor auto-move

This commit is contained in:
gamer147
2026-08-16 11:07:09 -04:00
parent d4d9def8f4
commit eef1225b56
11 changed files with 75 additions and 10 deletions

View File

@@ -47,6 +47,25 @@ public class InputBindingTests
Assert.NotEqual(0, vm.InputBindings.JoystickButtonActionMask(3) & (1 << 4));
}
[Fact]
public void SetCursorVirtualUpdatesVmCoordinatesAndRequestsAHostWarp()
{
var script = ScriptAssembler.Assemble(Table, "CURSOR_WARP", new List<(int, Operand[])>
{
(0x10a, new[] { I(321), I(234) }),
(0x109, new[] { G(0x710), G(0x711) }),
(0x2, Array.Empty<Operand>()),
}, Array.Empty<string>());
var host = new RecordingHost();
var vm = new VirtualMachine(script, Table, host);
vm.Run();
Assert.Equal((321, 234), Assert.Single(host.CursorWarps));
Assert.Equal(321, vm.Globals.GetValueOrDefault(0x710));
Assert.Equal(234, vm.Globals.GetValueOrDefault(0x711));
}
[Fact]
[Trait("Category", "Workspace")]
public void System4BootstrapReplaysAllSixteenInputConfigurationCalls()

View File

@@ -76,6 +76,7 @@ internal class RecordingHost : IHost
public readonly List<FullwidthTextEditRequest> FullwidthTextEdits = new();
public System.Func<FullwidthTextEditRequest, FullwidthTextEditResult>? OnFullwidthTextEdit;
public readonly List<long> CursorResources = new();
public readonly List<(int X, int Y)> CursorWarps = new();
public readonly List<bool> AdvPagePresentationSuspended = new();
public readonly List<(AdvLiveTextRun Run, int GlyphDelayMilliseconds)> LiveTextRuns = new();
public readonly Dictionary<int, RgbaImage> SurfacePixels = new();
@@ -176,6 +177,7 @@ internal class RecordingHost : IHost
public virtual long InputClockMilliseconds => Environment.TickCount64;
public void SetCursorResource(long resourceId) => CursorResources.Add(resourceId);
public void ClearCursorResource() => CursorClearCount++;
public void WarpCursor(int virtualX, int virtualY) => CursorWarps.Add((virtualX, virtualY));
public virtual void Sleep(long duration) => SleptDurations.Add(duration);
public virtual void WaitForTimedCallbackDeadline(long duration)
{

View File

@@ -32,6 +32,7 @@ public interface IInputHost
void SetCursorResource(long resourceId) { }
void ClearCursorResource() { }
void WarpCursor(int virtualX, int virtualY) { }
// Native 0x1c7/0x1cc query two distinct ADV skip channels. Headless and non-interactive
// hosts default to normal playback; the Godot host supplies the live interactive values.

View File

@@ -159,8 +159,14 @@ public sealed partial class VirtualMachine
return pc + 1;
}
case "u0041E540":
case "set-cursor-virtual": // 0x10a; retain the virtual position even without OS warping
UpdatePointer((int)Read(a[0]), (int)Read(a[1])); return pc + 1;
case "set-cursor-virtual": // 0x10a: update AGE state immediately, then request the native warp
{
int x = (int)Read(a[0]);
int y = (int)Read(a[1]);
UpdatePointer(x, y);
_host.WarpCursor(x, y);
return pc + 1;
}
case "u0041E5A0":
case "map-mouse-button": // 0x10b: physical button -> slot, polled action is slot+4
InputBindings.MapMouseButton(unchecked((int)Read(a[0])), unchecked((int)Read(a[1])));