Implement ADV system menu input routing
This commit is contained in:
@@ -121,6 +121,8 @@ public sealed class GfxState
|
||||
|
||||
private readonly Dictionary<long, long> _fieldTable = new(); // ctx+0x46d14 (0x216); no family writer -> default 0
|
||||
public long CurrentObject { get; private set; }
|
||||
/// <summary>EngineCtx+0x14e08, selected by op 0x80 and used by op 0x1d9 when its slot is zero.</summary>
|
||||
public int DefaultObjectSlot { get; private set; }
|
||||
/// <summary>The D3D render target selected by op 0x20d. -1 denotes the main backbuffer.</summary>
|
||||
public int CurrentRenderTargetSlot { get; private set; } = -1;
|
||||
|
||||
@@ -148,6 +150,11 @@ public sealed class GfxState
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDefaultObjectSlot(int slot)
|
||||
{
|
||||
lock (_lock) DefaultObjectSlot = slot;
|
||||
}
|
||||
|
||||
/// <summary>Op 0x21d: clone the native 0x2d4-byte retained-object record from source to destination.</summary>
|
||||
public bool CloneObject(long sourceHandle, long destinationHandle)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ internal sealed class HotspotRegistry
|
||||
{
|
||||
public int Left, Top, Right, Bottom;
|
||||
public int EnterTarget, LeaveTarget, ActivateTarget;
|
||||
public int? InputBit;
|
||||
public int? LogicalAction;
|
||||
|
||||
public bool Contains(int x, int y)
|
||||
=> x >= Left && x <= Right && y >= Top && y <= Bottom;
|
||||
@@ -36,12 +36,12 @@ internal sealed class HotspotRegistry
|
||||
});
|
||||
}
|
||||
|
||||
public void BindKey(int x, int y, int width, int height, int inputBit)
|
||||
public void BindKey(int x, int y, int width, int height, int logicalAction)
|
||||
{
|
||||
int right = x + width, bottom = y + height;
|
||||
var entry = _entries.FirstOrDefault(e => e.Left == x && e.Top == y
|
||||
&& e.Right == right && e.Bottom == bottom);
|
||||
if (entry != null) entry.InputBit = inputBit;
|
||||
if (entry != null) entry.LogicalAction = logicalAction;
|
||||
}
|
||||
|
||||
public bool Arm(int pointerX, int pointerY)
|
||||
@@ -69,7 +69,25 @@ internal sealed class HotspotRegistry
|
||||
int hit = FindHit(x, y);
|
||||
if (hit < 0) return false;
|
||||
|
||||
int target = _entries[hit].ActivateTarget;
|
||||
return ConsumeActivation(_entries[hit].ActivateTarget);
|
||||
}
|
||||
|
||||
/// <summary>Activate the first armed record whose op-0x97 logical action is present in the
|
||||
/// current input mask. Native scans records in registration order before pointer activation.</summary>
|
||||
public bool ActivateBoundActions(int actionMask)
|
||||
{
|
||||
if (!Armed || actionMask == 0) return false;
|
||||
for (int i = 0; i < _entries.Count; i++)
|
||||
{
|
||||
int? action = _entries[i].LogicalAction;
|
||||
if (action is >= 0 and < 32 && (actionMask & (1 << action.Value)) != 0)
|
||||
return ConsumeActivation(_entries[i].ActivateTarget);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ConsumeActivation(int target)
|
||||
{
|
||||
// Native consumes the active input registration before dispatch. Its ADV scheduler revisits the
|
||||
// shared registration routine afterward; retain the definitions so the blocking host can model
|
||||
// that revisit without advancing the enclosing dialogue page.
|
||||
|
||||
@@ -135,6 +135,17 @@ public sealed class VirtualMachine
|
||||
return consumed;
|
||||
}
|
||||
|
||||
/// <summary>Queue the first armed hotspot callback bound by op 0x97 to any action in
|
||||
/// <paramref name="actionMask"/>. True means the logical input was consumed.</summary>
|
||||
public bool TryActivateInputActions(int actionMask)
|
||||
{
|
||||
bool consumed;
|
||||
lock (_interactiveLock)
|
||||
consumed = _interactiveFrame?.Hotspots.ActivateBoundActions(actionMask) == true;
|
||||
if (consumed) _host.WakeInputCallbackService();
|
||||
return consumed;
|
||||
}
|
||||
|
||||
/// <summary>Update one native mouse-button bit (left=0x1, right=0x2 in Himegari).</summary>
|
||||
public void UpdateMouseButtonState(int bit, bool pressed) => UpdateMaskBit(ref _mouseButtonState, bit, pressed);
|
||||
|
||||
@@ -962,7 +973,7 @@ public sealed class VirtualMachine
|
||||
return pc + 1;
|
||||
}
|
||||
case "u0041C150":
|
||||
case "bind-hotspot-key": // 0x97: keyboard/pad routing is a later host-input slice
|
||||
case "bind-hotspot-key": // 0x97: bind a configured logical action to this record
|
||||
lock (_interactiveLock)
|
||||
_cur.Hotspots.BindKey((int)Read(a[0]), (int)Read(a[1]), (int)Read(a[2]),
|
||||
(int)Read(a[3]), (int)Read(a[4]));
|
||||
@@ -1398,6 +1409,9 @@ public sealed class VirtualMachine
|
||||
Gfx.GetOrCreate(Read(a[0])).V18 = (Read(a[1]), Read(a[2]), Read(a[3])); return pc + 1;
|
||||
case "set-gfx-geom3-b": // 0x219 (handle)(a)(b)(c) -> V24
|
||||
Gfx.GetOrCreate(Read(a[0])).V24 = (Read(a[1]), Read(a[2]), Read(a[3])); return pc + 1;
|
||||
case "u0041AF00": // 0x80: default object slot substituted by native op 0x1d9
|
||||
case "set-default-gfx-object-slot":
|
||||
Gfx.SetDefaultObjectSlot((int)Read(a[0])); return pc + 1;
|
||||
|
||||
// ---- SC0000 anim/transform/spritesheet cluster (docs/engine-re.md §"SC0000 anim ... cluster") ----
|
||||
case "u00421DD0": // 0x22f set-position: (handle)(op2)(x)(y)(z) -> base position (direct set)
|
||||
|
||||
Reference in New Issue
Block a user