Fix ADV config opacity and text lifetime
This commit is contained in:
@@ -16,6 +16,8 @@ public static class AdvTextLayoutBootstrap
|
||||
int? resetOpcode = table.ByLabel("reset-adv-text-layout");
|
||||
int? resetCursorOpcode = table.ByLabel("set-adv-text-reset-cursor");
|
||||
int? boundsOpcode = table.ByLabel("set-adv-text-bounds");
|
||||
int? waitIndicatorHandleOpcode = table.ByLabel("set-adv-wait-indicator-handle");
|
||||
int? textObjectRangeOpcode = table.ByLabel("set-adv-text-object-range");
|
||||
int? addOpcode = table.ByLabel("add");
|
||||
if (defineOpcode == null || resetOpcode == null) return 0;
|
||||
|
||||
@@ -60,6 +62,7 @@ public static class AdvTextLayoutBootstrap
|
||||
bool inLayoutBlock = false;
|
||||
int cursorConfigurations = 0;
|
||||
int boundConfigurations = 0;
|
||||
int objectRangeConfigurations = 0;
|
||||
foreach (var instruction in systemScript.Instructions)
|
||||
{
|
||||
if (!inLayoutBlock)
|
||||
@@ -89,20 +92,38 @@ public static class AdvTextLayoutBootstrap
|
||||
history.SetBounds(values[0], values[1], values[2]);
|
||||
boundConfigurations++;
|
||||
}
|
||||
else if (waitIndicatorHandleOpcode != null
|
||||
&& instruction.Opcode == waitIndicatorHandleOpcode.Value)
|
||||
{
|
||||
var values = ResolveConfiguration(
|
||||
instruction, localInts, systemScript.Name, expectedCount: 2);
|
||||
history.SetWaitIndicatorObjectHandle(values[0], values[1]);
|
||||
}
|
||||
else if (textObjectRangeOpcode != null
|
||||
&& instruction.Opcode == textObjectRangeOpcode.Value)
|
||||
{
|
||||
var values = ResolveConfiguration(instruction, localInts, systemScript.Name);
|
||||
history.SetTextObjectRange(values[0], values[1], values[2]);
|
||||
objectRangeConfigurations++;
|
||||
}
|
||||
|
||||
if (cursorConfigurations >= definitions && boundConfigurations >= definitions) break;
|
||||
if (cursorConfigurations >= definitions && boundConfigurations >= definitions
|
||||
&& (textObjectRangeOpcode == null || objectRangeConfigurations >= definitions))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return definitions;
|
||||
}
|
||||
|
||||
private static int[] ResolveConfiguration(
|
||||
Instruction instruction, IReadOnlyDictionary<int, long> localInts, string scriptName)
|
||||
Instruction instruction, IReadOnlyDictionary<int, long> localInts, string scriptName,
|
||||
int expectedCount = 3)
|
||||
{
|
||||
if (instruction.Args.Count != 3)
|
||||
if (instruction.Args.Count != expectedCount)
|
||||
throw new InvalidDataException(
|
||||
$"{scriptName}@0x{instruction.Offset:x}: ADV layout configuration must use three operands");
|
||||
var values = new int[3];
|
||||
$"{scriptName}@0x{instruction.Offset:x}: ADV layout configuration must use " +
|
||||
$"{expectedCount} operands");
|
||||
var values = new int[expectedCount];
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
if (!TryResolveConstant(instruction.Args[i], localInts, out long value))
|
||||
|
||||
@@ -82,6 +82,7 @@ public sealed class VirtualMachine
|
||||
private volatile bool _advSkipServiceEnabled;
|
||||
private bool _advReadSkipState;
|
||||
private AdvTextStyle _advTextStyle = AdvTextStyle.Default;
|
||||
private int _messageWindowAlphaSetting;
|
||||
private int _messageGlyphDelayMilliseconds;
|
||||
private readonly Dictionary<string, int> _valueSwitchTargets = new(StringComparer.Ordinal);
|
||||
// Native EngineCtx owns 11 lazily allocated integer FIFOs at +0x55130. ATSEEK/MVSEEK use
|
||||
@@ -156,6 +157,7 @@ public sealed class VirtualMachine
|
||||
_sink = sink ?? NullTraceSink.Instance; TextHistory = textHistory ?? new AdvTextHistory();
|
||||
_sharedProfile = sharedProfile ?? new SharedProfile();
|
||||
_nativeDatStore = nativeDatStore;
|
||||
_messageWindowAlphaSetting = host.MessageWindowAlphaSetting;
|
||||
_messageGlyphDelayMilliseconds = System.Math.Max(0, host.MessageGlyphDelayMilliseconds);
|
||||
_accumulatedPlaySeconds = _sharedProfile.AccumulatedPlaySeconds;
|
||||
_sessionStartTimestamp = System.Diagnostics.Stopwatch.GetTimestamp();
|
||||
@@ -2242,9 +2244,14 @@ public sealed class VirtualMachine
|
||||
case "u0041B540":
|
||||
TextHistory.SetLayoutOrigin((int)Read(a[0]), (int)Read(a[1]), (int)Read(a[2]));
|
||||
return pc + 1;
|
||||
case "get-message-window-alpha": // 0x131: host profile/config seam; default host currently supplies 0
|
||||
case "get-message-window-alpha": // 0x131: process-owned message:MesWinAlpha setting
|
||||
case "u00415F70":
|
||||
Write(a[0], _host.MessageWindowAlphaSetting); return pc + 1;
|
||||
Write(a[0], _messageWindowAlphaSetting); return pc + 1;
|
||||
case "set-message-window-alpha": // 0x141: paired message:MesWinAlpha configuration setter
|
||||
case "u0041FAA0":
|
||||
_messageWindowAlphaSetting = (int)Read(a[0]);
|
||||
_host.SetMessageWindowAlphaSetting(_messageWindowAlphaSetting);
|
||||
return pc + 1;
|
||||
case "get-message-glyph-delay": // 0x7f
|
||||
case "u00414C60":
|
||||
Write(a[0], _messageGlyphDelayMilliseconds); return pc + 1;
|
||||
@@ -2543,14 +2550,24 @@ public sealed class VirtualMachine
|
||||
case "u00420620": // upstream ABI label
|
||||
case "gfx-set-scale-current": // 0x1fd (handle)(sx%)(sy%)(sz%) -> current scale matrix
|
||||
Gfx.SetCurrentScale(Read(a[0]), (Read(a[1]), Read(a[2]), Read(a[3]))); return pc + 1;
|
||||
case "set-gfx-field64": // 0x212 (idx)(val)
|
||||
Gfx.SetObjectField64(Read(a[0]), Read(a[1])); return pc + 1;
|
||||
case "set-gfx-xy": // 0x213 (idx)(x)(y)
|
||||
case "set-adv-wait-indicator-handle": // 0x212 (layout)(retained handle)
|
||||
{
|
||||
Gfx.SetObjectFields68And6c(Read(a[0]), Read(a[1]), Read(a[2])); return pc + 1;
|
||||
TextHistory.SetWaitIndicatorObjectHandle((int)Read(a[0]), Read(a[1]));
|
||||
return pc + 1;
|
||||
}
|
||||
case "set-adv-text-object-range": // 0x213 (layout)(first handle)(count)
|
||||
{
|
||||
TextHistory.SetTextObjectRange((int)Read(a[0]), Read(a[1]), Read(a[2]));
|
||||
return pc + 1;
|
||||
}
|
||||
case "gfx-elem-erase": // 0x1f7 (handle)(count) — erase retained-object range
|
||||
Gfx.EraseRange(Read(a[0]), Read(a[1])); return pc + 1;
|
||||
{
|
||||
long first = Read(a[0]), count = Read(a[1]);
|
||||
Gfx.EraseRange(first, count);
|
||||
foreach (int layoutSlot in TextHistory.LayoutsCoveredByTextObjectErase(first, count))
|
||||
_host.ClearRenderedAdvTextLayout(layoutSlot);
|
||||
return pc + 1;
|
||||
}
|
||||
case "gfx-elem-release": // 0x1fa (surface slot)
|
||||
_host.ReleaseSurface((int)Read(a[0])); Gfx.ClearSurface((int)Read(a[0])); return pc + 1;
|
||||
case "clone-gfx-object": // 0x21d (source handle)(destination handle)
|
||||
|
||||
Reference in New Issue
Block a user