Fix AE001H translation target query
This commit is contained in:
@@ -843,7 +843,7 @@ annotated in Ghidra, saved.
|
||||
| `0x239` | `gfx_op_0x239_set_srcrect_cell` → `gfx_worker_set_srcrect_cell` | one-shot **spritesheet-cell** channel: delay/duration `obj+0x48/+0x5c`, total frames/columns `obj+0x238/+0x23c`, target frame `obj+0x234` |
|
||||
| `0x231` | `gfx_op_0x231_anim_srcrect` → `gfx_worker_anim_srcrect` | looping **spritesheet-cell** channel: milliseconds per frame `obj+0x230`, total frames `obj+0x238`, columns `obj+0x23c`; row-major and wraps, not ping-pong |
|
||||
| `0x232` | `gfx_op_0x232_anim_color` → `gfx_worker_anim_color` | **animate color** (pulsing GLOW): bit2 active, period `obj+0x220`, target `obj+0x240` → interpolator COLOR channel (ping-pong). Distinct from static `0x202`/`0x203` (`obj+0x60/0x64`) |
|
||||
| `0x228` | `gfx_op_0x228_query_position` (`FUN_0047cdd0`) | **query** current computed (x,y,z) → operand slots 3/4/5 (script logic, not render) |
|
||||
| `0x228` | `gfx_op_0x228_query_position` → `gfx_object_query_translation_target` (`0x47cdd0`) | **query** the decomposed target-translation matrix (x,y,z), `obj+0x1ac/+0x1b0/+0x1b4`, → operand slots 3/4/5; success is 0 and missing is 1 |
|
||||
| `0x23f` | `gfx_op_0x23f_query_object` (`FUN_0042a520`) | **query** an object status/value → operand slot 1 |
|
||||
|
||||
**Follow-up resolution (2026-07-10):** `0x21f` is the one-shot axis-angle channel and is implemented with
|
||||
@@ -886,6 +886,19 @@ set by `draw-texture`; `0x231` does not divide that rectangle by its operands. I
|
||||
`(100, 8, 4)` for AE001H: eight 200x200 cells in an 800x400, 4x2 sheet. Treating 8 and 4 as grid width
|
||||
and height shrank the crop to 25x50 and made the intended cave spirit effectively disappear.
|
||||
|
||||
**AE001H travel-path correction (2026-07-11):** the three post-movie movement legs exposed a separate
|
||||
port bug from the source-rectangle correction. Native `0x228` copies the full retained-object record and
|
||||
decomposes the target matrix beginning at `obj+0x17c`; the returned translation comes from
|
||||
`obj+0x1ac/+0x1b0/+0x1b4`. It does **not** return the draw/base position at `obj+0x24` (`V24`). SC0000 uses
|
||||
that query before each `0x220` to derive the next translation target. AE001H's draw base is `(360,20)` and
|
||||
its initial translation target is `(0,0)`, so the first native leg targets `(40,-20)`. The current C#
|
||||
`0x228` implementation instead returns `(360,20)`, producing `(400,0)`; the compositor then adds that
|
||||
translation to the unchanged draw base, placing the object near `(760,20)` before its cyclic rotation.
|
||||
That explained the observed immediate off-screen movement and why later legs never visibly returned. The
|
||||
port now queries `TranslationTarget` independently of `V24`, returns the native status convention, and
|
||||
leaves output operands untouched when the object is absent. A bytecode-level regression reproduces the
|
||||
three SC0000 targets `(40,-20)`, `(50,-80)`, and `(130,-100)` while retaining base `V24=(360,20)`.
|
||||
|
||||
**Resolved 2026-07-11:** `0x236` is the movie-to-retained-surface path described below. The unclassified
|
||||
`0x242/0x23d/0x20a/0x20e` tail (2-arg flags / inline) remains GAP and outside this slice.
|
||||
|
||||
|
||||
@@ -269,8 +269,9 @@ Native handler gfx_op_0x20c_present_frame -> gfx_render_frame @0x4820b0. This is
|
||||
- **evidence:** Ghidra handler 0x417550 -> gfx_command_queue_clear 0x47cb10, which destroys queued nodes and restores the sentinel links/count.
|
||||
|
||||
### 0x228 `u00421940` (u00421940, argc 5)
|
||||
- **summary:** 0x228 query-position (succ)(handle)(outX)(outY)(outZ): read the object's current computed position into vars (worker FUN_0047cdd0). C# VM: writes V24 + success flag. See docs/engine-re.md §SC0000 anim cluster.
|
||||
- **grounding:** source=kelebek, confidence=low
|
||||
- **summary:** 0x228 query translation target (succ)(handle)(outX)(outY)(outZ): clone the retained object, decompose its target translation matrix at obj+0x17c, and return matrix translation obj+0x1ac/+0x1b0/+0x1b4. Returns succ=0 when found; when absent, writes succ=1 and leaves outputs untouched. The C# VM queries TranslationTarget independently of V24. See docs/engine-re.md §SC0000 anim cluster.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **evidence:** Ghidra /v2 handler gfx_op_0x228_query_position@0x42a3a0 calls gfx_object_query_translation_target@0x47cdd0. The worker copies the complete 0xb5-dword object record, passes copied obj+0x17c to matrix4_decompose_affine@0x48d7c8, and returns its translation outputs; the decomposition reads matrix elements +0x30/+0x34/+0x38, corresponding to obj+0x1ac/+0x1b0/+0x1b4. SC0000 AE001H queries this before each 0x220 leg. C# regression covers targets (40,-20), (50,-80), (130,-100), plus the missing-object output-preservation path.
|
||||
|
||||
### 0x229 `u004219E0` (u004219E0, argc 5)
|
||||
- **summary:** 0x229 set-position2 (handle)(op2)(x)(y)(z): set object position/geometry directly (FUN_00472bb0/be0). C# VM: sets V24. See docs/engine-re.md §SC0000 anim cluster.
|
||||
|
||||
@@ -1405,3 +1405,17 @@ now cycles the eight AE001H cells row-major and wraps. Focused tests cover the e
|
||||
Validation: engine **146/146**, opcode sources regenerated, Godot zero-warning build and threaded selftest,
|
||||
real-scene compositor trace across all eight cells, Ghidra `/v2` annotations saved, and user confirmation
|
||||
on the normal client path. The automated-shot wrong-CG state remains the pre-existing separate gotcha.
|
||||
|
||||
### A2b -- SC0000 post-movie AE001H travel-path correction ✅ DONE (2026-07-11)
|
||||
|
||||
The remaining off-screen motion is a separate `0x228` query-model bug, not part of the spritesheet crop.
|
||||
Native `0x228` decomposes and returns the retained object's target translation (`obj+0x1ac..+0x1b4`), while
|
||||
the C# VM currently returns its static draw/base position `V24`. For AE001H this changes the first `0x220`
|
||||
target from `(40,-20)` to `(400,0)`; because the compositor also retains the `(360,20)` draw base, the
|
||||
sprite was displaced to approximately x=760 before cyclic rotation. `GfxState.TryQueryTranslationTarget`
|
||||
now exposes the retained target independently of `V24`; VM dispatch matches the native 0/1 status convention
|
||||
and preserves output operands on a miss. Bytecode-level tests cover the exact three targets `(40,-20)`,
|
||||
`(50,-80)`, `(130,-100)` plus missing-object behavior. Validation: engine **149/149**, zero-warning Godot
|
||||
build, and threaded `SELFTEST OK`. Current static SC0000 coverage is **94/129 distinct ops handled
|
||||
(72.9%)**: 82 implemented + 12 safe no-ops, leaving 35 GAP ops / 88 GAP instructions. By instruction
|
||||
frequency, 16,169/16,257 are handled (**99.5%**); this gauge does not replace manual end-to-end fidelity.
|
||||
|
||||
Reference in New Issue
Block a user