Correct ADV Hide Window restore behavior

This commit is contained in:
gamer147
2026-07-18 22:23:06 -04:00
parent d8ead3da6e
commit 56f8adfa2d
13 changed files with 177 additions and 35 deletions

View File

@@ -18,6 +18,10 @@ public interface IHost
void SetAdvTextCursor(int layoutSlot, int x, int y) { }
void DrawStringToSurface(int surfaceSlot, int x, int y, string text) { }
void ConfigureAdvWaitIndicator(AdvWaitIndicatorConfig config) { }
// Op 0x199 temporarily yields the active ADV page into its registered hide-window coroutine.
// The retained scene continues to render, but the text layout and its wait marker are suspended
// until op 0x7c restores the saved page PC.
void SetAdvPagePresentationSuspended(bool suspended) { }
void WaitForInput();
void WaitForInput(int layoutSlot) => WaitForInput();
// Interactive hosts service script callbacks on the VM thread while the enclosing ADV page remains

View File

@@ -330,8 +330,18 @@ public sealed class VirtualMachine
LookupStore(a[0], BaseAddr(a[1]) + Read(a[2])); return pc + 1;
case "lookup-array-2d":
LookupStore(a[0], BaseAddr(a[1]) + Read(a[2]) * Read(a[3]) + Read(a[4])); return pc + 1;
case "bit-set": Write(a[0], Read(a[0]) | Read(a[1])); return pc + 1;
case "bit-reset": Write(a[0], Read(a[0]) & ~Read(a[1])); return pc + 1;
case "bit-set":
{
long bit = Read(a[1]);
if ((ulong)bit >= 32) { HaltReason ??= $"bit-index-out-of-range:{bit}"; return HALT; }
Write(a[0], Read(a[0]) | (1L << (int)bit)); return pc + 1;
}
case "bit-reset":
{
long bit = Read(a[1]);
if ((ulong)bit >= 32) { HaltReason ??= $"bit-index-out-of-range:{bit}"; return HALT; }
Write(a[0], Read(a[0]) & ~(1L << (int)bit)); return pc + 1;
}
case "check-bit": Write(a[0], (Read(a[1]) >> (int)(Read(a[2]) & 31)) & 1); return pc + 1;
case "copy-to-global": Write(a[0], Read(a[1])); return pc + 1;
case "jmp": return _cur.Script.IndexByOffset.GetValueOrDefault((int)a[0].Value, pc + 1);
@@ -357,6 +367,7 @@ public sealed class VirtualMachine
{
_cur.CoroutineResumePc = pc + 1;
_cur.CoroutineYieldActive = true;
_host.SetAdvPagePresentationSuspended(true);
targetOffset = _cur.CoroutineYieldHandlerA;
}
else targetOffset = _cur.CoroutineYieldHandlerB;
@@ -371,6 +382,7 @@ public sealed class VirtualMachine
{
_cur.CoroutineResumePc = null;
_cur.CoroutineYieldActive = false;
_host.SetAdvPagePresentationSuspended(false);
return resumePc;
}
return pc + 1; // cold bounded scene-entry path