4.9 KiB
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
0x70padded bytes with five identical relocations. - The first normalized divergence was the inlined powerup-index test: January
emitted the long
test edi, edi; the exact standalonecode_000aa560source requires(short)powerup_typeand inlined astest di, di. - Adding an explicit long outer guard allowed the inner short test to fold, but
VC7 expanded
code_000ab820to0x80bytes. - Calling
code_000aa4f0/code_000aa530from 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 intoEDX, and later forms&iteratorinEAX. - VC7 instead coalesces the unit index into
ECXand forms&iteratorinEDX. - Passing
player->unit_indexdirectly 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 inEDI. - 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 loadsplayer_data. - VC7 stores the result, loads and pushes
player_data, and only then forms&iterator; theplayer_datarelocation is therefore at+0x32instead of January's+0x35. - The normalized residual is 11 bytes at offsets
0x2Ethrough0x39; 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, andsource_root_objectat[ebp-8],[ebp-0x14],[ebp-0x10], and[ebp-0xC]; VC7 uses a0x78frame, omits the source-root home, and maps the other three to[ebp-4],[ebp-0xC], and[ebp-0x14]. - January keeps the initial
biped_getresult inESIbefore homing it and later uses a stack-homed source-root pointer. VC7 instead homes the biped immediately and keeps the source-root pointer inESI. - Splitting the two-pointer aggregate into independent locals restored the
exact
0x510size 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
0x7Cframe but inflated the body to0x520and 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.