mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-23 19:00:34 +02:00
101 lines
4.9 KiB
Markdown
101 lines
4.9 KiB
Markdown
# Players.obj matching notes
|
|
|
|
## `code_000ab820` powerup expiry
|
|
|
|
The authentic reconstruction iterates the two `player.powerup_durations`,
|
|
decrements active timers, and calls `code_000aa560` when a timer expires. A
|
|
compile-time-dead reference to `code_000ab820` retained both private bodies.
|
|
|
|
- January and candidate were both `0x70` padded bytes with five identical
|
|
relocations.
|
|
- The first normalized divergence was the inlined powerup-index test: January
|
|
emitted the long `test edi, edi`; the exact standalone `code_000aa560` source
|
|
requires `(short)powerup_type` and inlined as `test di, di`.
|
|
- Adding an explicit long outer guard allowed the inner short test to fold, but
|
|
VC7 expanded `code_000ab820` to `0x80` bytes.
|
|
- Calling `code_000aa4f0`/`code_000aa530` from the already-exact public powerup
|
|
handlers changed their machine code, so those call-form experiments were
|
|
reverted.
|
|
|
|
The `code_000ab820` foundation was not admitted because it added no exact
|
|
function credit. Its source and retention experiment may be revisited when
|
|
`players_update_after_game` is reconstructed.
|
|
|
|
## `players_update_before_game`
|
|
|
|
The dependency-complete action/update loop reconstructs to January's exact
|
|
`0x6E0` padded size with all 101 relocation identities and addresses aligned.
|
|
After restoring the proper `main_respawn(boolean)` declaration, only four
|
|
normalized instruction bytes differ:
|
|
|
|
- January keeps the player pointer in `ECX`, loads the unit index into `EDX`,
|
|
and later forms `&iterator` in `EAX`.
|
|
- VC7 instead coalesces the unit index into `ECX` and forms `&iterator` in
|
|
`EDX`.
|
|
- Passing `player->unit_index` directly increased the residual to ten bytes.
|
|
- Removing the compiler barrier produced the same worse schedule.
|
|
|
|
The proven four-byte baseline retains the local `player_unit_index` and
|
|
`_ReadWriteBarrier()`. The function remains dormant and uncredited until its
|
|
register-allocation tie is resolved.
|
|
|
|
## `players_update_after_game`
|
|
|
|
The authentic post-game loop and its expiry dependency reconstruct to
|
|
January's exact `0x330` padded size with all 52 relocations. The first CFG
|
|
divergence occurs when forming the scenario BSP-switch block pointer:
|
|
|
|
- January emits `lea ecx, [eax+0x39C]` and keeps the loop index in `EDI`.
|
|
- VC7 emits a base copy, offset load, and offset add, then keeps the loop index
|
|
in `EBX`; this creates a nonuniform register/branch-layout drift through the
|
|
loop.
|
|
- The historically grounded `byte * + offsetof(...)` expression compiled
|
|
identically to the named-field expression and did not improve the residual.
|
|
|
|
The semantic lift remains uncredited and is not retained in `players.c`.
|
|
|
|
## `code_000a9ff0`
|
|
|
|
The semantic PVS reconstruction has January's exact `0x170` padded size and
|
|
all 22 relocation identities. Only one instruction-scheduling window differs:
|
|
|
|
- January emits `lea ecx, [ebp-0x14]`, stores the activation-call result at
|
|
`[ebp-4]`, then loads `player_data`.
|
|
- VC7 stores the result, loads and pushes `player_data`, and only then forms
|
|
`&iterator`; the `player_data` relocation is therefore at `+0x32` instead of
|
|
January's `+0x35`.
|
|
- The normalized residual is 11 bytes at offsets `0x2E` through `0x39`; every
|
|
instruction after that window matches.
|
|
- An explicit iterator pointer, a result temporary plus compiler barrier, and
|
|
an aggregate exposing the iterator/result stack adjacency all compiled to
|
|
the same baseline schedule. Argument-expression and premature-pointer
|
|
variants either retained that schedule or worsened it.
|
|
|
|
The function remains dormant and uncredited as a scheduler/lifetime tie.
|
|
|
|
## `code_000aa9e0`
|
|
|
|
The independent-pointer reconstruction retains January's exact `0x510`
|
|
padded size and all 61 relocation identities. Its residual begins with a
|
|
stack-home and register-allocation difference and expands into a block-layout
|
|
tie:
|
|
|
|
- January homes `player`, `player_unit_index`, `biped`, and
|
|
`source_root_object` at `[ebp-8]`, `[ebp-0x14]`, `[ebp-0x10]`, and
|
|
`[ebp-0xC]`; VC7 uses a `0x78` frame, omits the source-root home, and maps the
|
|
other three to `[ebp-4]`, `[ebp-0xC]`, and `[ebp-0x14]`.
|
|
- January keeps the initial `biped_get` result in `ESI` before homing it and
|
|
later uses a stack-homed source-root pointer. VC7 instead homes the biped
|
|
immediately and keeps the source-root pointer in `ESI`.
|
|
- Splitting the two-pointer aggregate into independent locals restored the
|
|
exact `0x510` size after a failed CFG experiment, but did not resolve the
|
|
opening register allocation and is not retained in production source.
|
|
- Whole-variable and targeted volatile access produced the `0x7C` frame but
|
|
inflated the body to `0x520` and mapped the homes incorrectly.
|
|
- Hoisting/reordering scalar declarations was byte-identical to the best form.
|
|
- Late-label and single-fallback CFG rewrites shortened the body to `0x500`;
|
|
VC7 either placed the fallback block early or over-merged the source paths.
|
|
|
|
The aggregate baseline remains dormant and uncredited pending a compiler
|
|
register-allocation/block-layout solution.
|