Implement History mouse wheel navigation
This commit is contained in:
@@ -11,6 +11,7 @@ Struct `EngineCtx`, size `0xa1000`. Applied to the Ghidra `/v2` image (dispatch-
|
||||
| `0x410` | `archive_name_table` | `void*` | archive-name table base (arc_id*0x100 indexes it) |
|
||||
| `0x414` | `sys4ini_records` | `void*` | SYS4INI 80-byte record base {name[64],arc_id,file_number,offset,size}; record = base + id*0x50 |
|
||||
| `0x13dc` | `message_skip_enabled` | `int` | persistent all-message Skip flag; op 0x88 writes it and adv_interpreter_tick injects input bit 0x40 while nonzero |
|
||||
| `0x1c34` | `mouse_wheel_delta` | `int` | signed WM_MOUSEWHEEL delta accumulated by age_main_window_proc; op 0x10d returns and clears it |
|
||||
| `0x3028` | `alt_pack_table` | `int` | call-script high-byte alternate pack table (unused by corpus) |
|
||||
| `0xb558` | `gfx_dirty_a` | `int` | gfx dirty flag (anim set raises) |
|
||||
| `0xb560` | `gfx_dirty_b` | `int` | gfx dirty flag |
|
||||
|
||||
@@ -1445,7 +1445,31 @@ script frame, blocks only at these scheduler service boundaries using the host c
|
||||
after each local callback returns. Focused tests cover exact relative deadlines and the late catch-up choice.
|
||||
|
||||
Smooth-scroll scheduling is now implemented without changing History backlog ownership or choosing a
|
||||
save/profile backend. HISTORY's remaining static gaps are five supporting opcodes across seven instructions.
|
||||
save/profile backend.
|
||||
|
||||
#### Mouse-wheel accumulation and History navigation (2026-07-19)
|
||||
|
||||
Opcode `0x10d` is the read half of AGE's generic Win32 mouse-wheel service. The newly recovered
|
||||
`age_main_window_proc@0x486320` handles `WM_MOUSEWHEEL` (`0x20a`), sign-extends the high word of `wParam`,
|
||||
and normally adds that value to `ctx+0x1c34`. In special run modes it instead maps the sign through the
|
||||
configurable `set:WheelKeyUp`/`set:WheelKeyDown` actions, so the accumulator is specifically the ordinary
|
||||
raw-wheel channel used by scripts such as HISTORY.
|
||||
|
||||
`op_0x10d_consume_mouse_wheel_delta@0x428cf0` writes the accumulated signed value to operand 1 and clears
|
||||
the field immediately. HISTORY polls it twice: once while establishing the callback loop to discard stale
|
||||
input, then once per timed mouse callback. The script only tests zero and sign, converting a positive or
|
||||
negative native delta into one call of its existing smooth-scroll path.
|
||||
|
||||
The port follows that ownership directly: Godot converts wheel-up/down events to signed 120-unit native
|
||||
deltas, the VM atomically accumulates them, and `0x10d` atomically reads and clears the total. This state is
|
||||
runtime input only; it is neither a script seed nor profile/save data. A real SC0000-to-HISTORY regression
|
||||
opens after eight retained messages and proves wheel-up selects older retained rows without releasing or
|
||||
re-entering the enclosing ADV wait.
|
||||
|
||||
HISTORY is now 74/78 distinct opcodes and 849/854 instructions handled or safe-noop. Its remaining static
|
||||
gaps are four supporting opcodes across five instructions: text-style setter `0x8b` occurs twice,
|
||||
`0x1ce`/`0x20a` form a sprite-animation service pair, and `0x1cb` reads the deliberately deferred
|
||||
Read-message Skip profile setting.
|
||||
|
||||
The original dependency order was **Hide Window first** to establish reusable callback/coroutine input, then
|
||||
Read-message Skip, then History after both the input layer and message-completion seam exist. Hide Window is
|
||||
|
||||
@@ -594,6 +594,11 @@ op 0x90 (u0041BEB0, argc 7): `0x90 x y w h tgt_a tgt_b tgt_c`. Kelebek left it "
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **evidence:** Ghidra /v2: op_0x10a_set_cursor_virtual@0x421590 maps virtual coordinates through the active VirtualFullScreen geometry and calls SetCursorPos. SC0000 alternates the cursor by one vertical pixel after state-changing ADV button clicks so the hover state re-enters cleanly.
|
||||
|
||||
### 0x10d `consume-mouse-wheel-delta` (u00415F10, argc 1)
|
||||
- **summary:** (out) - return the accumulated signed mouse-wheel delta and clear it.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **evidence:** Ghidra /v2: op_0x10d_consume_mouse_wheel_delta@0x428cf0 copies ctx+0x1c34 to operand 1 and immediately clears the field. AGE's window procedure at 0x486925 handles WM_MOUSEWHEEL by sign-extending the high word of wParam and accumulating it at ctx+0x1c34; HISTORY.BIN polls this value and branches on its sign to select one scroll direction.
|
||||
|
||||
### 0x12e `find-hit-rectangle` (find-hit-rectangle, argc 8)
|
||||
- **summary:** (index_inout)(reference_rect)(pointer_x)(pointer_y)(rect_array)(x_offsets)(y_offsets)(count) - scan after the incoming index for the next inclusive rectangle intersection, or return -1.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
@@ -878,10 +883,6 @@ op 0x90 (u0041BEB0, argc 7): `0x90 x y w h tgt_a tgt_b tgt_c`. Kelebek left it "
|
||||
- **summary:** —
|
||||
- **grounding:** source=kelebek, confidence=low
|
||||
|
||||
### 0x10d `u00415F10` (u00415F10, argc 1)
|
||||
- **summary:** —
|
||||
- **grounding:** source=kelebek, confidence=low
|
||||
|
||||
### 0x12c `lookup-array-2d` (lookup-array-2d, argc 5)
|
||||
- **summary:** —
|
||||
- **grounding:** source=kelebek, confidence=med
|
||||
|
||||
@@ -1874,3 +1874,28 @@ implementation slice from their actual responsibilities rather than treating the
|
||||
|
||||
Validation: all 203 engine tests pass, opcode and EngineCtx tests/lints are clean, vm0 RECOVER passes, the
|
||||
Godot build has zero warnings, and threaded `SELFTEST OK`.
|
||||
|
||||
### ADV History mouse-wheel navigation implemented (2026-07-19)
|
||||
|
||||
The five-gap investigation separated independent responsibilities instead of grouping them by proximity.
|
||||
Native `age_main_window_proc@0x486320` handles `WM_MOUSEWHEEL` by sign-extending its high-word delta and
|
||||
accumulating it at `EngineCtx+0x1c34`; op `0x10d` returns that signed total and clears it. HISTORY first
|
||||
uses the opcode to discard stale motion, then polls it from its timed mouse callback and feeds the sign into
|
||||
the already implemented smooth-scroll route.
|
||||
|
||||
Godot now translates wheel-up/down into signed 120-unit deltas, and the VM atomically accumulates and
|
||||
consumes them. This extends the existing generic raw-input callback seam and introduces no script-specific
|
||||
offsets, seeded state, or persistence choice. A focused regression proves accumulation/read-clear behavior;
|
||||
a real SC0000-to-HISTORY regression opens after eight messages and proves wheel-up changes the retained row
|
||||
selection without releasing the enclosing ADV wait.
|
||||
|
||||
The canonical opcode and EngineCtx sources are regenerated, and `/v2` now names/comments the recovered main
|
||||
window procedure and the specific `0x10d` handler. HISTORY is 74/78 distinct opcodes and 849/854 instructions
|
||||
handled or safe-noop. Remaining: `0x8b` twice, paired sprite-animation service ops `0x1ce`/`0x20a`, and the
|
||||
deferred Read-message Skip setting getter `0x1cb`.
|
||||
|
||||
**Next:** reverse the common text-style block around `0x8b`; it is the smallest remaining non-persistence
|
||||
gap. Keep `0x1cb` deferred, and treat `0x1ce`/`0x20a` together as their own sprite-animation slice.
|
||||
|
||||
Validation: all 205 engine tests pass, opcode and EngineCtx tests/lints are clean, vm0 RECOVER passes, the
|
||||
Godot build has zero warnings, and threaded `SELFTEST OK`.
|
||||
|
||||
Reference in New Issue
Block a user