Replace Director assembly transcription with credible C

This commit is contained in:
Jonas Volman committed 2026-08-30 22:39:31 -07:00
1 parent 981e89a355
commit decf689cb5
7 files changed
+506 -193

No files matched your search

+6 -6
View File
@@ -137,8 +137,8 @@
{
"unit": "source/camera/director",
"function": "_director_initialize_for_new_map",
"class": "asm-implemented",
"evidence": "Parked under asm-implemented: our source implements this function with MSVC inline assembly, so it is byte-identical to January by construction rather than by reconstruction. This violates the campaign's standing 'no asm' rule, and the two rules interact badly - an assembly transcription always compares exact, so section_infos_equal cannot distinguish it from a genuine C recovery; only reading the source can. Parked rather than deleted so the exact tally stops counting it as a C reconstruction while the bytes remain reproducible. Same treatment as the pre-existing vendored-assembly park for matrix4x3_multiply. To unpark, replace the __asm with C that gates exact. Audit and full inventory: research/asm_credited_functions_audit.md. Worst case in the set: the loop body, the bounds assert, all three switch arms and the pointer walk are hand-written asm, including '_emit 07ch / _emit 006h' to plant a raw jl opcode and a comment stating the original TU 'keeps the zero constant in bx'. That is a transcription of January's listing, not a reconstruction of its source. Note objdiff reports 90.48% fuzzy here even though the strict comparator says exact.",
"class": "tu-context-optimization",
"evidence": "The 2026-08-30 source-credibility audit removed all eight hand-transcribed assembly blocks, including the raw '_emit 07ch / _emit 006h' branch bytes, register staging, direct structure offsets, helper-call setup, and pointer walk. The retained ordinary C is the coherent source-level routine corroborated independently by the January CFG/data offsets, HCEA, and the stianeklund/pastudan trees: choose game versus editor mode, clear initialize_camera, reset each player's camera-change/bored state, then call director_choose_camera(local_player_index, TRUE, FALSE) and director_initialize_variables(local_player_index). The typed static director_get accessor was recovered separately and now gates 64 padded bytes and five relocations exact while inlining naturally into the inherited exact callers. The camera-selection wrapper call is deliberately not manually inlined. January's 208-byte new-map function shows VC7 also inlined the 80-byte director_choose_camera wrapper and propagated the private conventions of its still-missing callees, so the honest form emits 128 padded bytes and ten relocations instead of reproducing that unavailable optimization context. No asm, raw emission, volatile/register forcing, undefined behavior, optimizer directive, synthetic branch, or byte patch remains. Reopen only with ordinary-C definitions for the remaining named director helper cluster so VC7 can recover the original private conventions and inlining naturally.",
"measurements": {
"target": {
"size": 208,
@@ -146,11 +146,11 @@
"normalized_sha256": "70b72e43999f76618be8ead0ece3d3a9facba546b477b5245a1f0d2f88e9c6c6"
},
"base": {
"size": 208,
"relocation_count": 19,
"normalized_sha256": "70b72e43999f76618be8ead0ece3d3a9facba546b477b5245a1f0d2f88e9c6c6"
"size": 128,
"relocation_count": 10,
"normalized_sha256": "5b1d60ea43cdd981bff2360af7d12b07702fc9dc2e763aa4b5648ff28ae5d459"
},
"objdiff_percent": 90.47619
"objdiff_percent": 55.460316
}
},
{
-5
View File
@@ -124,11 +124,6 @@
"function": "_code_0007cb70",
"reason": "hardened COFF comparison proves exact bytes and semantic relocations; objdiff reports a local-label/relocation encoding false negative"
},
{
"unit": "source/camera/director",
"function": "_director_initialize_for_new_map",
"reason": "hardened COFF comparison proves exact bytes and semantic relocations; objdiff reports a local-label/relocation encoding false negative"
},
{
"unit": "source/bungie_net/network/transport_address",
"function": "_transport_error_to_string",
+19 -13
View File
@@ -1447,7 +1447,7 @@
{ "file_offset": 475424, "flags": 32, "name": "_code_00074120" },
{ "file_offset": 475600, "flags": 32, "name": "_dead_camera_new" },
{ "file_offset": 475888, "flags": 32, "name": "_dead_camera_update" },
{ "file_offset": 477136, "flags": 32, "name": "_code_000747d0" },
{ "file_offset": 477136, "flags": 32, "name": "_director_get", "static": true },
{ "file_offset": 477200, "flags": 32, "name": "_director_initialize" },
{ "file_offset": 477232, "flags": 32, "name": "_director_dispose" },
{ "file_offset": 477248, "flags": 32, "name": "_director_inhibit_facing" },
@@ -1458,20 +1458,20 @@
{ "file_offset": 477648, "flags": 32, "name": "_director_save_camera" },
{ "file_offset": 477824, "flags": 32, "name": "_director_get_perspective" },
{ "file_offset": 477984, "flags": 32, "name": "_director_desired_perspective" },
{ "file_offset": 478224, "flags": 32, "name": "_code_00074c10" },
{ "file_offset": 478320, "flags": 32, "name": "_code_00074c70" },
{ "file_offset": 478432, "flags": 32, "name": "_code_00074ce0" },
{ "file_offset": 478224, "flags": 32, "name": "_director_set_camera" },
{ "file_offset": 478320, "flags": 32, "name": "_director_initialize_variables" },
{ "file_offset": 478432, "flags": 32, "name": "_director_process_variables" },
{ "file_offset": 478976, "flags": 32, "name": "_director_dispose_from_old_map" },
{ "file_offset": 479088, "flags": 32, "name": "_director_load_camera" },
{ "file_offset": 479424, "flags": 32, "name": "_code_000750c0" },
{ "file_offset": 479424, "flags": 32, "name": "_director_rotate_cameras" },
{ "file_offset": 479728, "flags": 32, "name": "_director_camera_deterministic" },
{ "file_offset": 479824, "flags": 32, "name": "_code_00075250" },
{ "file_offset": 479824, "flags": 32, "name": "_director_choose_game_perspective" },
{ "file_offset": 480032, "flags": 32, "name": "_director_script_camera" },
{ "file_offset": 480336, "flags": 32, "name": "_code_00075450" },
{ "file_offset": 480784, "flags": 32, "name": "_code_00075610" },
{ "file_offset": 480960, "flags": 32, "name": "_code_000756c0" },
{ "file_offset": 481152, "flags": 32, "name": "_code_00075780" },
{ "file_offset": 482112, "flags": 32, "name": "_code_00075b40" },
{ "file_offset": 480336, "flags": 32, "name": "_director_choose_camera_game" },
{ "file_offset": 480784, "flags": 32, "name": "_director_choose_camera_editor" },
{ "file_offset": 480960, "flags": 32, "name": "_director_choose_camera_script_camera_record" },
{ "file_offset": 481152, "flags": 32, "name": "_director_update_controls" },
{ "file_offset": 482112, "flags": 32, "name": "_director_choose_camera" },
{ "file_offset": 482192, "flags": 32, "name": "_director_initialize_for_new_map" },
{ "file_offset": 482400, "flags": 32, "name": "_director_update" },
{ "file_offset": 482896, "flags": 32, "name": "_director_initialize_for_saved_game" },
@@ -14062,7 +14062,12 @@
{ "file_offset": 2452156, "flags": 0, "name": "??_C@_0CJ@GLCFCHKA@c?3?2halo?2SOURCE?2camera?2camera_scr@" },
{ "file_offset": 2452200, "flags": 0, "name": "_rdata_00256ae8" },
{ "file_offset": 2452212, "flags": 0, "name": "??_C@_0CE@LCNMEPOD@c?3?2halo?2SOURCE?2camera?2dead_camer@" },
{ "file_offset": 2452248, "flags": 0, "name": "_rdata_00256b18" },
{ "file_offset": 2452248, "flags": 0, "name": "_director_game_camera_modes" },
{ "file_offset": 2452256, "flags": 0, "name": "_director_script_camera_record_camera_modes" },
{ "file_offset": 2452264, "flags": 0, "name": "__real@3cf5c28f" },
{ "file_offset": 2452268, "flags": 0, "name": "_friction" },
{ "file_offset": 2452272, "flags": 0, "name": "__real@41c80000" },
{ "file_offset": 2452276, "flags": 0, "name": "__real@3fa66666" },
{ "file_offset": 2452280, "flags": 0, "name": "??_C@_0N@PCFDPHGK@first?5person?$AA@" },
{ "file_offset": 2452296, "flags": 0, "name": "??_C@_06GIFLLBB@editor?$AA@" },
{ "file_offset": 2452304, "flags": 0, "name": "??_C@_06CPNKLHAC@flying?$AA@" },
@@ -21942,7 +21947,8 @@
{ "file_offset": 3001036, "flags": 0, "name": "_bits_per_channel_a4r4g4b4" },
{ "file_offset": 3001044, "flags": 0, "name": "_data_002dcad4" },
{ "file_offset": 3001184, "flags": 0, "name": "_data_002dcb60" },
{ "file_offset": 3001248, "flags": 0, "name": "_data_002dcba0" },
{ "file_offset": 3001248, "flags": 0, "name": "_director_camera_mode_names" },
{ "file_offset": 3001272, "flags": 0, "name": "_variables" },
{ "file_offset": 3001384, "flags": 0, "name": "_data_002dcc28" },
{ "file_offset": 3001392, "flags": 0, "name": "_editor_custom_render" },
{ "file_offset": 3001436, "flags": 0, "name": "_following_camera_zoom_levels" },
@@ -0,0 +1,237 @@
# `director.obj` Jonas ordinary-C credibility recovery
## Result
This 2026-08-30 audit starts from canonical commit
`69324deca14d7c3d96da1c4894dda79f5bf9be4c`. It revokes one false exact claim:
`_director_initialize_for_new_map` was byte-identical only because its body
contained eight hand-transcribed MSVC assembly blocks. The blocks reproduced
January's register allocation, direct offsets, private call setup and loop,
including `_emit 07ch` / `_emit 006h` raw branch bytes. That is object-code
transcription, not source reconstruction.
The function is now ordinary, typed C with no assembly or code-generation
coercion. It is intentionally reported as an honest fuzzy residual and remains
parked under `tu-context-optimization`; it receives no exact or semantic-exact
credit. Its obsolete entry in `config/semantic_matches.json` is removed so the
strict progress gate cannot continue crediting the former transcription.
The same source-level audit recovers the previously absent 64-byte private
accessor as `static struct director *director_get(short)`. VC7 assigns its
private SI convention naturally and emits all five target relocations exactly:
normalized SHA-256
`ca74e12a19a2f27ec8a62ac17e08e1042b3ad679ac9e3980249f257b1aa16035`.
No register convention is declared or forced.
The authenticated `director_camera_mode_names` and `variables` initializers
also reproduce the complete 136-byte `.data` section, including all five
string relocations, with normalized SHA-256
`2f47b267059a50f6bee1a0a581bf1c613cf52fc664109b56756d5e288a03c88f`.
The two camera-mode arrays reproduce the first 16 bytes of the target
`.rdata` section, including their natural alignment. The named 5.0f `friction`
value also reproduces its target bytes, but appears at candidate offset 0x10
rather than target offset 0x14 because the preceding 0.03f literal pool belongs
to a still-missing Director function. The other missing literals are 25.0f and
1.3f, so the honest candidate section is 20 bytes versus the target's 32. No
synthetic globals or padding were added to imitate those pools.
| Candidate | Source status | Padded bytes | Relocations | Normalized SHA-256 | Objdiff fuzzy |
| --- | --- | ---: | ---: | --- | ---: |
| E00 | Rejected assembly transcription | 208 | 19 | `70b72e43999f76618be8ead0ece3d3a9facba546b477b5245a1f0d2f88e9c6c6` | strict exact by construction |
| E01 | Accepted ordinary C | 128 | 10 | `5b1d60ea43cdd981bff2360af7d12b07702fc9dc2e763aa4b5648ff28ae5d459` | 55.460316% |
The 13 inherited sibling exact functions remain strict byte-and-relocation
exact, and `_director_get` is newly exact. The invalid assembly-backed exact
owner is therefore replaced in the strict count by one genuine ordinary-C
owner. The object remains nonmatching.
## Accepted source shape
The accepted routine performs only source-level work justified by the program:
1. Set the primary Director mode to `_director_mode_editor` when
`game_in_editor()` is true, otherwise `_director_mode_game`.
2. Clear the authenticated `initialize_camera` flag.
3. For every local player, resolve the typed state through `director_get`, then
clear `camera_change_pause`, `bored_time`, and `bored`.
4. Call `director_choose_camera(local_player_index, TRUE, FALSE)` and
`director_initialize_variables(local_player_index)`.
The wrapper call is deliberate. January's 208-byte function contains the
mode-switch work of the separate 80-byte `_director_choose_camera` wrapper
inlined into the loop. The current translation unit declares that wrapper but
does not yet define its private camera-selection callees, so VC7 cannot
recover the original whole-TU inline and register schedule. Manually expanding
the switch, forcing registers, or spelling private ABI calls in assembly would
only recreate object code. The honest residual is parked until ordinary-C
helper definitions make that optimization context available naturally.
The January inline schedule remains otherwise untouched. In particular, this
change does not introduce or emit a `point_from_line3d` COMDAT.
## Authenticated names and types
`source/camera/director.h` now uses the real C-series `real`, `boolean`, `short`,
and `long` types already required by the ABI. The former overlapping
`director_player_globals[4]` model is replaced by the authenticated layout:
- one 0x3E8-byte `struct director_globals` containing `dtime`, `game_mode`,
`initialize_camera`, and four 0xF8-byte `struct director` player states;
- the candidate common `_director_globals` symbol is now exactly 1,000 bytes,
ending at January's separately named `director_camera_switch_fast` byte;
- `camera_mode_index`, `camera_proc`, `camera_data`, `seat_state`, `command`,
and `debug_variables` now occupy their proven fields instead of anonymous
padding.
The header also adds the DB-authenticated enum constants:
- `_director_mode_game`
- `_director_mode_netgame`
- `_director_mode_editor`
- `_director_mode_scripted`
- `_director_mode_script_camera_record`
Target offsets plus the HCEA type database authenticate the renamed fields:
`game_mode`, `initialize_camera`, `camera_change_pause`, `bored_time`, `bored`,
`debug_controls`, and `debug_input_scale`.
The same Director ordering, extents, calls, and HCEA evidence map ten private
address placeholders to authenticated names. January proves the remaining
0x40-byte owner is the bounds-checking typed state accessor; because its
original name was not present in the available database or donor trees, it is
named `_director_get` under the repository's established `<subsystem>_get`
convention, as explicitly permitted for unresolved private names:
| January address | Semantic symbol |
| --- | --- |
| `000747D0` | `_director_get` |
| `00074C10` | `_director_set_camera` |
| `00074C70` | `_director_initialize_variables` |
| `00074CE0` | `_director_process_variables` |
| `000750C0` | `_director_rotate_cameras` |
| `00075250` | `_director_choose_game_perspective` |
| `00075450` | `_director_choose_camera_game` |
| `00075610` | `_director_choose_camera_editor` |
| `000756C0` | `_director_choose_camera_script_camera_record` |
| `00075780` | `_director_update_controls` |
| `00075B40` | `_director_choose_camera` |
`director_get` is defined `static` in `source/camera/director.c`; its prototype
does not leak into the public header. Only the two still-external helpers called
by the recovered routine are declared in that C file's own prototype section.
No prototype was moved into an unrelated implementation file and no missing
definition was fabricated.
The Director-owned address-only data labels are also split at their proven
boundaries and named: `director_game_camera_modes`,
`director_script_camera_record_camera_modes`, `friction`,
`director_camera_mode_names`, and `variables`. The intervening unnamed floating
constants retain normal `__real@...` compiler names. HCEA database types and
the January bytes establish the 5-pointer name table and four 0x1C-byte
`director_variable_definition` records.
## Provenance
Evidence was ranked rather than copied indiscriminately:
- January target COFF, disassembly, and relocations are authoritative for
layout, control flow, call order, object extent, and exactness.
- `research-cache/halocea-cseries-20260820/src/blam/camera/director_initialize_for_new_map.c`
independently corroborates the typed reset-and-two-calls routine.
- `research-cache/halocea-cseries-20260820/src/headers/director_game_mode.h`
supplies the database-authenticated enum names and values. The same tree's
individual Director helper files corroborate the semantic helper mapping and
field names.
- `research-cache/stian-halo-complete-history-20260828/src/halo/camera/director.c`
and
`research-cache/pastudan-halo-full-history-20260828/src/halo/camera/director.c`
independently recover the same mode selection, per-player three-field reset,
mode dispatch, and per-player initializer.
- `research-cache/punpckhdq-halo-full-history-20260828/source/camera/director.c`
contains only address placeholders for this cluster and provides no stronger
source to integrate.
The repository `CLAUDE.md`, the accessible donor-tree `CLAUDE.md` files,
`docs/matching_methodology.md`, `docs/fake_match_review.md`,
`docs/object_matching_logs/README.md`, and
`research/asm_credited_functions_audit.md` were read and reconciled before the
edit. Scoped Marathon-source searches found no analogous camera Director
implementation, so no Marathon behavior was inferred. Community discussion
that helper/math functions may sometimes contain original inline assembly does
not establish provenance for Director control-flow assembly and was not treated
as permission to retain it.
## Rejected shapes and do-not-repeat guidance
Do not reintroduce any of the following to improve the score:
- `_emit`, raw instruction bytes, inline or naked `__asm`;
- manually staged EAX/EBX/ESI/EDI values or comments that prescribe registers;
- direct Director byte offsets or a hand-maintained pointer stride;
- a manually expanded mode switch whose only purpose is to imitate the inlined
wrapper;
- `volatile`, `register`, optimizer pragmas/barriers, forced-inline attributes,
undefined behavior, fabricated branches, synthetic anchors, or byte patches;
- numeric enum cases where authenticated constants exist;
- address-derived private function or BSS names.
Any future retry must begin with ordinary-C definitions for the authenticated
helper cluster, then let VC7 choose inlining and its private conventions. A
higher fuzzy score alone is not evidence of better source.
## Validation record
The target profile is XDK 3911, compiled through the repository's production
graph with `/O2 /Oy- /DDEBUG /Dxbox`. The audit uses the hardened function
comparator, which requires code bytes and relocation identity rather than an
objdiff percentage.
Recorded gates:
- candidate build and direct function comparison for
`_director_initialize_for_new_map`;
- exact-set comparison against the preserved E00 object: all 13 inherited
sibling exact functions retained and `_director_get` newly exact;
- scoped fake-match scan of `source/camera/director.c` and
`source/camera/director.h`: zero findings;
- parked-function validation: 13 active, zero stale, zero invalid;
- `git diff --check`: pass.
Final production validation:
- `halobetacache_build` and `libcmt_build`: pass; no work remained after the
final Director replay.
- Semantic report: 470 units scanned; 4,987 functions evaluated; 4,877
semantic exact; 130 hidden exact / 78,743 hidden code bytes; 4,887 accepted
exact; zero ordinary rejected and zero unit errors.
- Strict campaign board: 384/833 files, 4,848/11,060 functions, and
618,804/2,198,102 meaningful code bytes.
- Halo board: 282/468 files, 4,681/7,574 functions, and
605,890/1,770,166 meaningful code bytes.
- Object-admission audit: zero candidates. Its sole contradiction/revocation
is the inherited `source/ai/action_converse` completion label, unrelated to
this wave.
- Tooling suite: 221 tests passed.
- Candidate COFF symbol audit: no `point_from_line3d` symbol or COMDAT.
Reproducibility identities:
- Final `director.c` Git blob:
`4f7db666d586273dc38ac03d55793b4c011eeda9`.
- Final `director.h` Git blob:
`fe455a79ad7ef4e4151eeeeab1f45b9457c78da7`.
- Final source SHA-256:
`52b4b773c43f27209241fc2df8da73d6ad4f042cd82e621e4386fe03f3124a67`.
- Final header SHA-256:
`9d3f64a45d6ac6ace89c215a229d58e49937b34b738ce380f537dd0e84262588`.
- January split object SHA-256:
`0238797739ab317ba363419ab943d929bdab4173a39a8a6a92b64dc763cb70ba`.
- Candidate raw object SHA-256:
`86d76476bf86426dbc3263135f80e00654e22446006f74fb25f258bb487a497d`.
- `build/report.json` SHA-256:
`a64bcee6234f6ac5209f9067db4e7cfc702661b639d10501fc0d341f781513f4`.
- `build/semantic_report.json` SHA-256:
`07229eada628261dfd37cfdaccb497bb855146e8fb3b46eb8e2a53ae5fe07707`.
Raw COFF hashes include producer metadata; the normalized per-function hashes
in the result table are the stable comparison identities.
+62 -22
View File
@@ -3,11 +3,12 @@
Found incidentally 2026-08-16 while reading `source/camera/director.c` for an
unrelated reconstruction. The initial audit parked the affected functions so
assembly transcriptions were not credited as C reconstructions. Subsequent
source-credibility work recovered `object_shadows.code_0012b870` and
`action_converse_perform` in ordinary C. On 2026-08-30 the four Active
Camouflage transcriptions were deleted after stock-XDK owner evidence exposed
their address-placeholder premise as false. Four assembly implementations now
remain parked: Director, `stristr`, and two Particles functions.
source-credibility work recovered `object_shadows.code_0012b870`,
`action_converse_perform`, and `director_initialize_for_new_map` in ordinary C.
On 2026-08-30 the four Active Camouflage transcriptions were also deleted after
stock-XDK owner evidence exposed their address-placeholder premise as false.
Three assembly implementations now remain parked: `stristr` and two Particles
functions.
## The standing rule
@@ -16,19 +17,17 @@ no byte-forcing, readable code only* — and, separately, *never credit anything
that is not byte-identical*. At discovery, the first rule was violated in nine
functions across five units, and the two rules interacted badly: an assembly
transcription will always be byte-identical, so the strict comparator cannot
distinguish a genuine C recovery from a transcribed listing. Four such
distinguish a genuine C recovery from a transcribed listing. Three such
implementations remain, explicitly parked and excluded from credit. The gate
is not a defence here; only reading the source is.
## Historical inventory at discovery
Nine functions contain inline or naked `__asm` and compare
Seven functions contain whole-body or naked `__asm` and compare
`EXACT` by `section_infos_equal`:
| unit | function | asm blocks | kind |
|---|---|---|---|
| `ai/action_converse` | `action_converse_perform` | 3 | inline, inside C |
| `camera/director` | `director_initialize_for_new_map` | 8 | inline, inside C |
| `cseries/cseries` | `stristr` | 1 | whole body |
| `effects/particles` | `code_0008fcd0` | 1 | whole body |
| `effects/particles` | `code_0008ff30` | 1 | whole body |
@@ -47,21 +46,20 @@ then gate each enclosing function.
## Why this matters more than the count suggests
`director_initialize_for_new_map` is the clearest case. It is not a C function
with an asm hint — the loop body, the assert, the switch arms and the pointer
walk are all hand-written asm, including `_emit 07ch / _emit 006h` to plant a
raw `jl` opcode, and comments that say the original TU "keeps the zero constant
in bx". That is a transcription of January's listing, not a reconstruction of
January's source. It will never stop matching, and it teaches the project
nothing about what the original C looked like.
`director_initialize_for_new_map` was the clearest case when this inventory was
opened. It was not a C function with an asm hint — the loop body, assert,
switch arms and pointer walk were all hand-written asm, including `_emit 07ch /
_emit 006h` to plant a raw `jl` opcode, and comments claimed the original TU
"keeps the zero constant in bx". That transcription was removed on 2026-08-30;
see the ordinary-C recovery below.
The former `__declspec(naked)` cases were unambiguous by construction: a naked
function has no C body at all.
The inline cases (`action_converse_perform`, `director_initialize_for_new_map`)
were the subtler risk, because the function reads as C at a glance and the asm
is buried mid-body. Action Converse is now ordinary fuzzy C;
`director_initialize_for_new_map` remains parked assembly.
were the subtler risk, because each function read as C at a glance while the
assembly was buried mid-body. Both are now ordinary fuzzy C. The remaining
inventory is visibly whole-body assembly.
## Initial resolution (owner chose: park them)
@@ -85,6 +83,45 @@ Two regression tests cover both directions
(`test_asm_implemented_entry_stays_active_when_exact`,
`test_asm_implemented_entry_is_invalid_when_not_exact`).
## Ordinary-C recovery: Director new-map initialization
On 2026-08-30, all eight assembly blocks were removed from
`source/camera/director.c::director_initialize_for_new_map`, including the raw
branch-byte emission, manually staged registers, direct structure offsets,
private-call setup, and pointer walk. The retained source is a coherent typed C
routine: select the authenticated game/editor mode, clear `initialize_camera`,
reset each local player's `camera_change_pause`, `bored_time`, and `bored`
state, then call `director_choose_camera(local_player_index, TRUE, FALSE)` and
`director_initialize_variables(local_player_index)`.
This shape is independently corroborated by the January control flow and data
offsets, HCEA's Director reconstruction, and the stianeklund and pastudan
histories. The authenticated `director_game_mode` constants, full Director
layout, and field names replace numeric switch labels, unknown-member names,
and the prior overlapping pseudo-array layout. Ten adjacent address
placeholders were mapped to authenticated semantic Director helper names. The
remaining 64-byte accessor, whose original name was unavailable, is named
`director_get` by the repository's getter convention and implemented as a typed
static helper.
The former transcription was 208 padded bytes with 19 relocations and matched
January by construction. The ordinary-C candidate is 128 padded bytes with ten
relocations and an objdiff fuzzy score of 55.460316%. All 13 inherited sibling
exact functions remain strict exact. In addition, `director_get` now gates its
64 padded bytes and five relocations exact and inlines naturally into its
callers. Thus the invalid assembly-backed exact owner was replaced in the count
by a genuine ordinary-C exact helper. January also inlined the 80-byte
`director_choose_camera` wrapper and propagated the private conventions of its
callees, whose definitions are still missing from this translation unit. The
source deliberately retains that natural wrapper call instead of manually
reproducing its inline schedule.
Accordingly, the function remains parked, but its class is now
`tu-context-optimization`. Reopen it only when ordinary-C definitions for the
named private helper cluster can restore the original VC7 translation-unit
context naturally. Full measurements and provenance are recorded in
`docs/object_matching_logs/director_obj_jonas_ordinary_c_credibility_recovery_20260830.md`.
## Ordinary-C recovery: object shadows
On 2026-08-29, `source/objects/object_shadows.c` replaced the naked assembly
@@ -106,7 +143,9 @@ preserves that function's original branch topology. The complete object now
gates 3/3 exact with no assembly, intrinsic, pragma, barrier, or attribute, so
the obsolete `asm-implemented` park was deleted.
Unparking one means replacing its `__asm` with C that gates exact.
Unparking an `asm-implemented` entry means replacing its `__asm` with C that
gates exact. Replacing the asm with honest nonexact C is still a credibility
recovery, but the function must remain parked under the correct residual class.
## Recovery attempt, 2026-08-16 (stristr + the four naked thunks)
@@ -222,8 +261,9 @@ options are:
they stop counting toward the exact tally, exactly as `matrix4x3_multiply`
does. This is the option that matches existing precedent.
2. **Re-reconstruct in C** — treat each as unwritten and find the real source
shape. `stristr` and the small naked helpers look tractable; the
`director_initialize_for_new_map` loop is a real piece of work.
shape. `stristr` and the small naked helpers look tractable. The Director
recovery above demonstrates that honest fuzzy C is preferable to retaining
a transcribed exact body even when missing TU context prevents admission.
3. **Leave and document** — accept them as knowingly-transcribed, but record it
so the headline "N functions byte-exact" is not read as "N functions
reconstructed in C".
+106 -124
View File
@@ -3,7 +3,7 @@ DIRECTOR.C
symbols in this file:
000747D0 0040:
_code_000747d0 (0000)
_director_get (0000)
00074810 0020:
_director_initialize (0000)
00074830 0010:
@@ -25,41 +25,51 @@ symbols in this file:
00074B20 00f0:
_director_desired_perspective (0000)
00074C10 0060:
_code_00074c10 (0000)
_director_set_camera (0000)
00074C70 0070:
_code_00074c70 (0000)
_director_initialize_variables (0000)
00074CE0 0220:
_code_00074ce0 (0000)
_director_process_variables (0000)
00074F00 0070:
_director_dispose_from_old_map (0000)
00074F70 0150:
_director_load_camera (0000)
000750C0 0130:
_code_000750c0 (0000)
_director_rotate_cameras (0000)
000751F0 0060:
_director_camera_deterministic (0000)
00075250 00d0:
_code_00075250 (0000)
_director_choose_game_perspective (0000)
00075320 0130:
_director_script_camera (0000)
00075450 01c0:
_code_00075450 (0000)
_director_choose_camera_game (0000)
00075610 00b0:
_code_00075610 (0000)
_director_choose_camera_editor (0000)
000756C0 00c0:
_code_000756c0 (0000)
_director_choose_camera_script_camera_record (0000)
00075780 03c0:
_code_00075780 (0000)
_director_update_controls (0000)
00075B40 0050:
_code_00075b40 (0000)
_director_choose_camera (0000)
00075B90 00d0:
_director_initialize_for_new_map (0000)
00075C60 01f0:
_director_update (0000)
00075E50 0020:
_director_initialize_for_saved_game (0000)
00256B18 0020:
_rdata_00256b18 (0000)
00256B18 0008:
_director_game_camera_modes (0000)
00256B20 0008:
_director_script_camera_record_camera_modes (0000)
00256B28 0004:
__real@3cf5c28f (0000)
00256B2C 0004:
_friction (0000)
00256B30 0004:
__real@41c80000 (0000)
00256B34 0004:
__real@3fa66666 (0000)
00256B38 000d:
??_C@_0N@PCFDPHGK@first?5person?$AA@ (0000)
00256B48 0007:
@@ -96,8 +106,10 @@ symbols in this file:
__real@37a4b5be (0000)
00256C60 0004:
__real@b824b5be (0000)
002DCBA0 0088:
_data_002dcba0 (0000)
002DCBA0 0018:
_director_camera_mode_names (0000)
002DCBB8 0070:
_variables (0000)
0031D048 03ea:
_director_globals (0000)
_director_camera_switch_fast (03e8)
@@ -133,21 +145,61 @@ void scripted_camera_update(
void *camera,
void *command,
void *result);
void code_00074c70(
void);
void code_00075450(
void);
void code_00075610(
void);
void code_000756c0(
void);
void director_initialize_variables(
short local_player_index);
void director_choose_camera(
short local_player_index,
boolean initialize,
boolean key);
/* ---------- globals */
struct director_player_globals director_globals[MAXIMUM_NUMBER_OF_LOCAL_PLAYERS];
short const director_game_camera_modes[3] =
{
_camera_first_person,
_camera_flying,
_camera_following
};
short const director_script_camera_record_camera_modes[4] =
{
_camera_first_person,
_camera_flying,
_camera_following,
_camera_orbiting
};
real const friction = 5.f;
char const *director_camera_mode_names[NUMBER_OF_DIRECTOR_CAMERA_MODES] =
{
"following",
"orbiting",
"flying",
"editor",
"first person"
};
struct director_variable_definition variables[NUMBER_OF_DIRECTOR_VARIABLES] =
{
{ 5, 4, NONE, { 0, 0 }, 0.15f, 0.f, -REAL_MAX, REAL_MAX, TRUE, { 0, 0, 0 } },
{ 6, 7, NONE, { 0, 0 }, 0.075f, 0.f, -REAL_MAX, REAL_MAX, FALSE, { 0, 0, 0 } },
{ 1, 0, NONE, { 0, 0 }, 0.075f, 0.f, -REAL_MAX, REAL_MAX, TRUE, { 0, 0, 0 } },
{ 3, 2, NONE, { 0, 0 }, 0.075f, 0.f, -REAL_MAX, REAL_MAX, TRUE, { 0, 0, 0 } }
};
struct director_globals director_globals;
boolean director_camera_switch_fast;
/* ---------- public code */
static struct director *director_get(
short local_player_index)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
return &director_globals.local_players[local_player_index];
}
void director_initialize(
void)
{
@@ -169,10 +221,11 @@ void director_dispose_from_old_map(
for (local_player_index = 0; local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS; local_player_index++)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
director_globals[local_player_index].camera.update = NULL;
director_globals[local_player_index].camera.unknown_c4 = 1.f;
director_globals[local_player_index].camera.unknown_c0 = FALSE;
struct director *director = director_get(local_player_index);
director->camera_proc = NULL;
director->debug_input_scale = 1.f;
director->debug_controls = FALSE;
}
director_camera_scripted->camera_scripted = FALSE;
@@ -182,51 +235,46 @@ void director_dispose_from_old_map(
void director_inhibit_facing(
short local_player_index)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
director_globals[local_player_index].camera.inhibit_facing = TRUE;
director_get(local_player_index)->inhibited_facing = TRUE;
return;
}
void director_inhibit_input(
short local_player_index)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
director_globals[local_player_index].camera.inhibit_input = TRUE;
director_get(local_player_index)->inhibited_input = TRUE;
return;
}
boolean director_inhibited_facing(
short local_player_index)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
return director_globals[local_player_index].camera.inhibit_facing;
return director_get(local_player_index)->inhibited_facing;
}
boolean director_inhibited_input(
short local_player_index)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
return director_globals[local_player_index].camera.inhibit_input;
return director_get(local_player_index)->inhibited_input;
}
director_perspective director_get_perspective(
short local_player_index)
{
struct director_camera_state *camera;
struct director *camera;
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
camera = &director_globals[local_player_index].camera;
camera = director_get(local_player_index);
if (camera->update == first_person_camera_update)
if (camera->camera_proc == first_person_camera_update)
{
if (camera->transition == 0.f)
if (camera->camera_change_pause == 0.f)
camera->perspective = 0;
}
else if (camera->update == following_camera_update)
else if (camera->camera_proc == following_camera_update)
{
camera->perspective = 1;
}
else if (camera->update == scripted_camera_update)
else if (camera->camera_proc == scripted_camera_update)
{
camera->perspective = 2;
}
@@ -293,10 +341,10 @@ void director_set_mode(
short mode)
{
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 384, mode>=0 && mode<NUMBER_OF_DIRECTOR_GAME_MODES);
if (director_globals[0].mode != mode)
if (director_globals.game_mode != mode)
{
director_globals[0].mode = mode;
director_globals[0].mode_changed = TRUE;
director_globals.game_mode = mode;
director_globals.initialize_camera = TRUE;
}
return;
@@ -328,87 +376,21 @@ void director_initialize_for_new_map(
{
short local_player_index;
/* These private helpers use translation-unit register conventions. */
__asm
director_globals.game_mode = game_in_editor() ? _director_mode_editor : _director_mode_game;
director_globals.initialize_camera = FALSE;
for (local_player_index = 0;
local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS;
local_player_index++)
{
call game_in_editor
neg al
mov edi, offset director_globals+54h
sbb eax, eax
and eax, 2
xor ebx, ebx
mov word ptr [director_globals+4], ax
mov byte ptr [director_globals+6], bl
struct director *camera = director_get(local_player_index);
camera->camera_change_pause = 0.f;
camera->bored_time = 0;
camera->bored = FALSE;
director_choose_camera(local_player_index, TRUE, FALSE);
director_initialize_variables(local_player_index);
}
local_player_index = 0;
do
{
/* The original TU keeps the zero constant in bx for this assertion. */
__asm
{
cmp si, bx
_emit 07ch
_emit 006h
}
if (local_player_index >= MAXIMUM_NUMBER_OF_LOCAL_PLAYERS)
{
display_assert("local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS", "c:\\halo\\SOURCE\\camera\\director.c", 179, TRUE);
system_exit(NONE);
}
__asm
{
mov byte ptr [edi+4], bl
mov dword ptr [edi], ebx
mov dword ptr [edi-48h], ebx
}
switch (director_globals[0].mode)
{
case 0:
case 1:
__asm
{
push ebx
push 1
mov eax, esi
call code_00075450
add esp, 8
}
break;
case 2:
__asm
{
push ebx
push 1
call code_00075610
add esp, 8
}
break;
case 4:
__asm
{
push ebx
mov al, 1
call code_000756c0
add esp, 4
}
break;
}
__asm
{
mov eax, esi
call code_00074c70
}
local_player_index++;
__asm add edi, 0f8h
}
while (local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
return;
}
+76 -23
View File
@@ -16,11 +16,35 @@ header included in hcex build.
/* ---------- constants */
enum
enum director_game_mode
{
_director_mode_game = 0,
_director_mode_netgame,
_director_mode_editor,
_director_mode_scripted,
_director_mode_script_camera_record,
NUMBER_OF_DIRECTOR_GAME_MODES = 5
};
enum director_camera_mode
{
_camera_following = 0,
_camera_orbiting,
_camera_flying,
_camera_editor,
_camera_first_person,
NUMBER_OF_DIRECTOR_CAMERA_MODES
};
enum director_variable
{
_variable_height = 0,
_variable_roll,
_variable_forward,
_variable_right,
NUMBER_OF_DIRECTOR_VARIABLES
};
/* ---------- macros */
/* ---------- structures */
@@ -38,32 +62,55 @@ struct director_scripting_globals
byte pad[3];
};
struct director_camera_state
struct director_variable_instance
{
byte pad0[4];
real transition;
director_camera_update_proc update;
byte padC[0x40];
long unknown_4c;
boolean unknown_50;
boolean inhibit_facing;
boolean inhibit_input;
byte pad53[3];
director_perspective perspective;
byte pad58[0x68];
boolean unknown_c0;
byte padC1[3];
real unknown_c4;
byte padC8[0x28];
real value;
real velocity;
real delta;
};
struct director_player_globals
struct director_variable_definition
{
byte pad0[4];
short mode;
boolean mode_changed;
short negative_bit;
short positive_bit;
short reset_bit;
byte pad6[2];
real scale;
real initial_value;
real minimum;
real maximum;
boolean has_hyper_scale;
byte pad19[3];
};
struct director
{
short camera_mode_index;
byte pad2[2];
real camera_change_pause;
director_camera_update_proc camera_proc;
byte camera_data[0x40];
long bored_time;
boolean bored;
boolean inhibited_facing;
boolean inhibited_input;
byte pad53;
short seat_state;
director_perspective perspective;
byte command[0x68];
boolean debug_controls;
byte padC1[3];
real debug_input_scale;
struct director_variable_instance debug_variables[NUMBER_OF_DIRECTOR_VARIABLES];
};
struct director_globals
{
real dtime;
short game_mode;
boolean initialize_camera;
byte pad7;
struct director_camera_state camera;
struct director local_players[MAXIMUM_NUMBER_OF_LOCAL_PLAYERS];
};
/* ---------- prototypes/DIRECTOR.C */
@@ -105,7 +152,13 @@ void director_initialize_for_saved_game(
/* ---------- globals */
extern struct director_scripting_globals *director_camera_scripted;
extern struct director_player_globals director_globals[MAXIMUM_NUMBER_OF_LOCAL_PLAYERS];
extern struct director_globals director_globals;
extern boolean director_camera_switch_fast;
extern short const director_game_camera_modes[3];
extern short const director_script_camera_record_camera_modes[4];
extern real const friction;
extern char const *director_camera_mode_names[NUMBER_OF_DIRECTOR_CAMERA_MODES];
extern struct director_variable_definition variables[NUMBER_OF_DIRECTOR_VARIABLES];
/* ---------- public code */