From 5e81dabff04678ea6cf3eff840d1fc46c6ee110c Mon Sep 17 00:00:00 2001 From: Jonas Volman Date: Wed, 23 Sep 2026 10:38:14 -0700 Subject: [PATCH] Close five Halo objects with verified shared-helper ownership --- config/config.json | 12 +- config/parked.json | 133 --------- config/symbols.json | 2 +- .../fourth_five_objects_admission_20260923.md | 31 ++ libs/libcmt/ioinit.c | 97 +++++++ source/ai/action_charge.c | 127 -------- source/ai/action_obey.c | 14 - source/ai/actor_type_infection.c | 22 +- source/cache/cache_files_decompress_windows.c | 15 +- source/effects/decals.c | 12 - source/math/geometry.c | 11 - source/units/biped_limp_noodle.c | 271 ++++++++---------- 12 files changed, 274 insertions(+), 473 deletions(-) create mode 100644 docs/object_matching_logs/fourth_five_objects_admission_20260923.md create mode 100644 libs/libcmt/ioinit.c diff --git a/config/config.json b/config/config.json index 89d49297..d0d5d867 100644 --- a/config/config.json +++ b/config/config.json @@ -405,7 +405,7 @@ { "name": "source/cache/predicted_resources.c", "index": 30, "status": "Matching" }, { "name": "source/cache/physical_memory_map.c", "index": 31, "status": "Matching" }, { "name": "source/cache/cache_files_windows.c", "index": 32, "status": "NonMatching" }, - { "name": "source/cache/cache_files_decompress_windows.c", "index": 33, "status": "NonMatching" }, + { "name": "source/cache/cache_files_decompress_windows.c", "index": 33, "status": "Matching" }, { "name": "source/cache/cache_files.c", "index": 34, "status": "Matching" }, { "name": "source/units/vehicles.c", "index": 35, "status": "NonMatching" }, { "name": "source/units/vehicle_definitions.c", "index": 36, "status": "Matching" }, @@ -415,7 +415,7 @@ { "name": "source/units/unit_definitions.c", "index": 40, "status": "Matching" }, { "name": "source/units/dialogue_definitions.c", "index": 41, "status": "Matching" }, { "name": "source/units/bipeds.c", "index": 42, "status": "NonMatching" }, - { "name": "source/units/biped_limp_noodle.c", "index": 43, "status": "NonMatching" }, + { "name": "source/units/biped_limp_noodle.c", "index": 43, "status": "Matching" }, { "name": "source/units/biped_definitions.c", "index": 44, "status": "Matching" }, { "name": "source/text/unicode.c", "index": 45, "status": "Matching" }, { "name": "source/text/text_group.c", "index": 46, "status": "Matching" }, @@ -428,7 +428,7 @@ { "name": "source/tag_files/files_windows.c", "index": 53, "status": "NonMatching" }, { "name": "source/tag_files/files.c", "index": 54, "status": "Matching" }, { "name": "source/structures/structures.c", "index": 55, "status": "NonMatching" }, - { "name": "source/structures/structure_visibility.c", "index": 56, "status": "NonMatching" }, + { "name": "source/structures/structure_visibility.c", "index": 56, "status": "Matching" }, { "name": "source/structures/structure_runtime_decals.c", "index": 57, "status": "Matching" }, { "name": "source/structures/structure_render.c", "index": 58, "status": "Matching" }, { "name": "source/structures/structure_lens_flares.c", "index": 59, "status": "NonMatching" }, @@ -816,10 +816,10 @@ { "name": "source/ai/actor_type_mounted_weapon.c", "index": 441, "status": "Matching" }, { "name": "source/ai/actor_type_marine.c", "index": 442, "status": "Matching" }, { "name": "source/ai/actor_type_jackal.c", "index": 443, "status": "Matching" }, - { "name": "source/ai/actor_type_infection.c", "index": 444, "status": "NonMatching" }, + { "name": "source/ai/actor_type_infection.c", "index": 444, "status": "Matching" }, { "name": "source/ai/actor_type_hunter.c", "index": 445, "status": "Matching" }, { "name": "source/ai/actor_type_grunt.c", "index": 446, "status": "Matching" }, - { "name": "source/ai/actor_type_flood.c", "index": 447, "status": "NonMatching" }, + { "name": "source/ai/actor_type_flood.c", "index": 447, "status": "Matching" }, { "name": "source/ai/actor_type_engineer.c", "index": 448, "status": "Matching" }, { "name": "source/ai/actor_type_elite.c", "index": 449, "status": "Matching" }, { "name": "source/ai/actor_type_crew.c", "index": 450, "status": "Matching" }, @@ -1018,7 +1018,7 @@ { "name": "libs/libcmt/ismbspc.c", "index": 777, "status": "Matching" }, { "name": "libs/libcmt/wopen.c", "index": 778, "status": "MISSING" }, { "name": "libs/libcmt/lseeki64.c", "index": 779, "status": "MISSING" }, - { "name": "libs/libcmt/ioinit.c", "index": 780, "status": "MISSING" }, + { "name": "libs/libcmt/ioinit.c", "index": 780, "status": "NonMatching" }, { "name": "libs/libcmt/write.c", "index": 781, "status": "MISSING" }, { "name": "libs/libcmt/txtmode.c", "index": 782, "status": "Matching" }, { "name": "libs/libcmt/setmode.c", "index": 783, "status": "MISSING" }, diff --git a/config/parked.json b/config/parked.json index ecaec271..55060566 100644 --- a/config/parked.json +++ b/config/parked.json @@ -778,44 +778,6 @@ "objdiff_percent": 98.51674 } }, - { - "unit": "source/units/biped_limp_noodle", - "function": "_biped_limp_noodle_valid_joint_rotation", - "class": "unclassified", - "evidence": "Fuzzy-parked after reconstructing the complete typed joint-constraint path from January disassembly, relocation/assert topology, and the independent HCEA implementation. The retained ordinary C resolves the biped and animation graph through subsystem accessors, validates the authored collision radius, implements hinge and conical constraints, tests January's three-argument collision sphere interface, updates the moved-node bit vector, and follows the parent when required. Target is 1248 padded bytes and the candidate 1216, with the same ordered 34-entry relocation target/type sequence although some relocation addresses drift; objdiff reports 81.18033 percent. The first measured divergence is the stack frame at +0x03 (January 0xE4, candidate 0xCC), followed by broad local/register allocation differences. The authenticated node-block flag names and ten-plane Xbox collision topology are retained. No register hint, volatile access, barrier, pragma, assembly, raw offset, representation punning, fake dependency, forced inline, or nonsensical branch is present. Reopen only for authoritative January source/local records, a natural same-compiler donor explaining the frame and lifetimes, or a source-authentic semantic correction.", - "measurements": { - "target": { - "size": 1248, - "relocation_count": 34, - "normalized_sha256": "699263a33b8b8131dfa843828894caa194dff415596b92545c5e5f96cd666a14" - }, - "base": { - "size": 1216, - "relocation_count": 34, - "normalized_sha256": "8306eb3e4e81348ff9a5a2f823d70735cfdd1984ebd813dfea954dca5434949b" - }, - "objdiff_percent": 81.18033 - } - }, - { - "unit": "source/units/biped_limp_noodle", - "function": "_biped_limp_noodle_move_relax_and_constrain_positions", - "class": "unclassified", - "evidence": "Fuzzy-parked after reconstructing the complete limp-body relaxation solver from January disassembly and the independent HCEA control flow, corrected for January's ten-plane scratch array and Xbox collision interfaces. The retained ordinary C installs the collision user, gathers sphere features, performs four breadth-first relaxation passes, applies gravity and point movement, resolves embedded endpoints, restores authored bone lengths, and unwinds the collision-user stack. Target is 1968 padded bytes and the candidate 1888, with the same ordered 66-entry relocation target/type sequence although some relocation addresses drift; objdiff reports 87.124596 percent. The prologue and setup are instruction-identical through +0xE0; the first measured divergence is January homing the integer conversion temporary at [ebp-0x20] while the candidate selects [ebp-0x1C], after which local-slot and instruction schedules differ. Correcting the third collision_test_sphere argument naturally improved the candidate by 16 bytes. No volatile/register forcing, barrier, pragma, gameplay assembly, raw offset, representation punning, fake dependency, forced inline, or invented branch is retained. Reopen only for authoritative January source/local records, a natural same-compiler lifetime donor, or a source-authentic semantic correction.", - "measurements": { - "target": { - "size": 1968, - "relocation_count": 66, - "normalized_sha256": "5964980a1f042d1c452e559fcba37592d608e1798ae0b7b5cef8deb9e40961d8" - }, - "base": { - "size": 1888, - "relocation_count": 66, - "normalized_sha256": "34b872cd2ae1a72136400424c983c399b7a2f8fbc7a3f342d9ed968e90dd19b3" - }, - "objdiff_percent": 87.124596 - } - }, { "unit": "source/networking/network_connection", "function": "_network_connection_connect", @@ -968,101 +930,6 @@ "objdiff_percent": 99.89011 } }, - { - "unit": "source/cache/cache_files_decompress_windows", - "function": "_cache_copy_FileIOCompletionRoutine@12", - "class": "unclassified", - "evidence": "Fuzzy-parked after reconstructing the complete typed asynchronous-I/O completion path from January's assertions, inclusive read/write range checks, timer bookkeeping, progress event, and failure flags, with behavior independently corroborated by HCEA. The evidence-backed dirty Opus continuation adds function-scope pointers for the two bit vectors and restores January's inclusive range forms, improving the candidate to 480 padded bytes, all 24 relocations, and 93.868965 percent objdiff similarity against January's 496 bytes. The remaining gap is a stack-slot/scheduling decision for completed_flags and the timer temporary plus the same RMW-fold peephole isolated in cache_copy_set_flag. Direct member-bit macros, pointer locals, half-open and inclusive ranges, and natural flag-expression orders were measured; the retained form is the closest honest source. No register/volatile forcing, barrier, pragma, assembly, fake dependency, raw offset, forced inline, undefined behavior, or nonsensical branch is retained.", - "measurements": { - "target": { - "size": 496, - "relocation_count": 24, - "normalized_sha256": "319636f87325bb6800f85ad4a3fc25cca604a0df2e78a859c8cada14ce81390f" - }, - "base": { - "size": 480, - "relocation_count": 24, - "normalized_sha256": "a693a54573c6b18882bc51a8fa0c7bc3aad14645a497b1baf2e18873aaf2a876" - }, - "objdiff_percent": 93.868965 - } - }, - { - "unit": "source/cache/cache_files_decompress_windows", - "function": "_cache_copy_issue_read", - "class": "register-allocation", - "evidence": "Fuzzy-parked with the complete typed asynchronous read issuer reconstructed from January's assertion, OVERLAPPED setup, retry/error handling, failure flag, and timer accounting. Target and candidate both occupy 320 padded bytes with all 21 relocations and objdiff reports 99.462364 percent similarity. The first 0x10e bytes are identical; only the trailing inlined, independently exact decompressor_timer_stop chooses an EDX/ECX/EAX register rotation rather than the candidate's ECX/EDX/EAX rotation. Three natural elapsed-time expression shapes did not move the tie. No register keyword, volatile access, barrier, pragma, assembly, fake dependency, raw offset, forced inline, undefined behavior, or nonsensical logic is retained.", - "measurements": { - "target": { - "size": 320, - "relocation_count": 21, - "normalized_sha256": "82ab59307459d188e9fc66d440cdfcef412bd1ad7a0e30b55d69903874259fd2" - }, - "base": { - "size": 320, - "relocation_count": 21, - "normalized_sha256": "da1834c4b9e0f3f8276c749ac1ddef6be1a51d0a16a1c60d039d999cca2b750a" - }, - "objdiff_percent": 99.462364 - } - }, - { - "unit": "source/cache/cache_files_decompress_windows", - "function": "_cache_copy_issue_write", - "class": "register-allocation", - "evidence": "Fuzzy-parked with the complete typed asynchronous write issuer reconstructed from January's assertion, OVERLAPPED setup, retry/error handling, failure flag, and timer accounting. Target and candidate both occupy 320 padded bytes with all 21 relocations and objdiff reports 99.46809 percent similarity. The first 0x10e bytes are identical; only the trailing inlined, independently exact decompressor_timer_stop chooses an EDX/ECX/EAX register rotation rather than the candidate's ECX/EDX/EAX rotation. Three natural elapsed-time expression shapes did not move the tie. No register keyword, volatile access, barrier, pragma, assembly, fake dependency, raw offset, forced inline, undefined behavior, or nonsensical logic is retained.", - "measurements": { - "target": { - "size": 320, - "relocation_count": 21, - "normalized_sha256": "b539e11396fe030b46aeb1f7a6f3f231d923dabb23f31449bd10c8fc24624e31" - }, - "base": { - "size": 320, - "relocation_count": 21, - "normalized_sha256": "fbee508d8baa41f0c178580aeeed25cdabcd94b77f7ebd1aa3476c33d3323a58" - }, - "objdiff_percent": 99.46809 - } - }, - { - "unit": "source/cache/cache_files_decompress_windows", - "function": "_cache_copy_set_flag", - "class": "private-register-convention", - "evidence": "Fuzzy-parked with the natural private typed flag setter used throughout the reconstructed cache-copy worker. January occupies 48 padded bytes with one relocation; the retained candidate occupies 32 bytes with one relocation and objdiff reports 40 percent. A public byte-parameter form reproduces January's stack frame and first 0x12 bytes, proving the parameter width, but would invent external linkage for a helper with no public owner and still leaves January's load/or/store versus VC7's RMW-or peephole unmatched. Static __cdecl and six natural SET_FLAG, temporary, operand-order, and getter forms all preserve the private register ABI or the RMW fold. The honest static helper and cseries bit-vector macro are retained; no false public prototype, register/volatile forcing, barrier, pragma, assembly, fake dependency, raw offset, forced inline, undefined behavior, or nonsensical logic is used.", - "measurements": { - "target": { - "size": 48, - "relocation_count": 1, - "normalized_sha256": "7550a1e6b978f5c5a14f4ab8f9eb968b8ecc030a91bf37867e6bc6e130a84632" - }, - "base": { - "size": 32, - "relocation_count": 1, - "normalized_sha256": "7d6d7761738324b18a21d67b0b64de805d65b6351e0b113c930fb1dc87eb72bd" - }, - "objdiff_percent": 40.0 - } - }, - { - "unit": "source/cache/cache_files_decompress_windows", - "function": "_simple_cache_copy_thread@4", - "class": "register-allocation", - "evidence": "Fuzzy-parked with the complete typed cache-copy worker state machine reconstructed from January's instruction/relocation topology, assertion strings, exact callee tree, and the independently corroborating HCEA implementation. Target and candidate both occupy 992 padded bytes with all 73 relocations and objdiff reports 99.14717 percent similarity. Both have 279 instructions with identical mnemonics, operand roles, calls, and branches; the residual is 42 bytes in five shallow register-name/load-order clusters, including inlined cache_copy_set_flag's known RMW/register tie. The relevant helper bodies and natural local/expression orders were measured without finding a source-authentic lever. No register keyword, volatile access, barrier, pragma, assembly, fake dependency, raw offset, forced inline, undefined behavior, or nonsensical branch is retained.", - "measurements": { - "target": { - "size": 992, - "relocation_count": 73, - "normalized_sha256": "6bb679d927ee902bcbe66d6a7a825123bb56cfea48d5c3759ce9de8717fea14f" - }, - "base": { - "size": 992, - "relocation_count": 73, - "normalized_sha256": "9272438fae80290e2f4e23d0f9d5ee8e04187d90894b4d74701599c2b3bd26f9" - }, - "objdiff_percent": 99.14717 - } - }, { "unit": "source/effects/effects", "function": "_effect_allowed_by_environment", diff --git a/config/symbols.json b/config/symbols.json index 81e9134b..508c4a17 100644 --- a/config/symbols.json +++ b/config/symbols.json @@ -22299,7 +22299,7 @@ { "file_offset": 2845228, "flags": 0, "name": "_rdata_002b6a2c" }, { "file_offset": 2845312, "flags": 0, "name": "___xri_a" }, { "file_offset": 2845316, "flags": 0, "name": "___pmtinit" }, -{ "file_offset": 2845320, "flags": 0, "name": "_data_002b6a88" }, +{ "file_offset": 2845320, "flags": 0, "name": "_io_initialize_handles" }, { "file_offset": 2845324, "flags": 0, "name": "___xri_z" }, { "file_offset": 2845328, "flags": 0, "name": "___xc_a" }, { "file_offset": 2845332, "flags": 0, "name": "_data_002b6a94" }, diff --git a/docs/object_matching_logs/fourth_five_objects_admission_20260923.md b/docs/object_matching_logs/fourth_five_objects_admission_20260923.md new file mode 100644 index 00000000..f63a3b98 --- /dev/null +++ b/docs/object_matching_logs/fourth_five_objects_admission_20260923.md @@ -0,0 +1,31 @@ +# Five Halo object admissions and one CRT draft (2026-09-23) + +## Credited result + +Five Halo-owned units moved from `NonMatching` to `Matching` only after guarded function comparisons, target-owned data/owner checks, and ordinary selected-provider link checks: + +| Unit | January functions | How this batch closed it | +| --- | ---: | --- | +| `source/cache/cache_files_decompress_windows` | 46/46 | Five newly exact functions; first-party debug types support volatile `flags` and `read_progress`, and the flag parameter is narrow. | +| `source/units/biped_limp_noodle` | 6/6 | Two newly exact constraint/relaxation functions using existing typed math helpers and `realcmp`. | +| `source/ai/actor_type_infection` | 5/5 | Newly exact `_infection_swarm_control`; direct component arithmetic was replaced by existing vector/point helpers. | +| `source/ai/actor_type_flood` | 2/2 | Existing exact code and data admitted after the shared-helper provider link was repaired. No new code bytes claimed. | +| `source/structures/structure_visibility` | 21/21 | Existing exact code and data admitted after the shared-helper provider link was repaired. No new code bytes claimed. | + +The current strict COFF snapshot versus `scratch/claude_structural_merged_20260923.json` gains nine functions / **9,109 padded bytes** with **zero regressions**. Eight of those functions are Halo-owned: **8,925 meaningful code bytes** (cache 2,117; biped 3,199; infection 3,609). Halo credited code is now **1,547,308 / 1,770,166** (87.41%). The ninth is CRT `__ioinit` (101 meaningful bytes); it does **not** close its object. Flood and visibility were already strict-exact in isolation, so their admission is an ownership/link result, not newly matched code. + +## Source and ownership proof + +The cache `volatile` qualifiers have independent HCEX/HCEA type-record support, not a register-forcing guess. They preserve January's field layout. Biped's apparently repeated distance-epsilon test and two queue-tail blocks are attested by January's distinct branches at 0x59a, 0x5d7, 0x6d4, and 0x713; the second enqueue has real effects. Infection retains typed vector access and removes redundant casts. All changed Halo source passed the fake-match scanner with no new leads. + +`action_charge.c`, `action_obey.c`, `geometry.c`, and `decals.c` now obtain their relevant shared math helpers from the genuine `real_math.h` inlines instead of hand-written external duplicates. The previously exact functions in those provider objects remain exact. The selected helper definitions are byte-identical and use coalescible SELECT_ANY COMDATs. Bounded ordinary VC7 base/base links pass both tested input orders for limp/infection with ActionCharge, Geometry, and ActionObey, and all six orders tested for flood and visibility with their selected providers. These partial links check duplicate ownership; `/force:unresolved` is used only because they deliberately omit unrelated objects, so they are not proof of a complete executable link. + +Named target-owned noncode sections, sizes, flags, bytes, relocations, and symbol storage/offsets match for all five: cache 5,945/5,945 data bytes; limp 6/6 sections including the 44,808-byte BSS; infection 12/12; flood 7/7; visibility 25/25. The raw objdiff function percentages for flood and infection remain below 100 despite strict `coff_compare.section_infos_equal` gates and exact target-owned sections; the `Matching` label is based on the stricter COFF/owner checks, not those fuzzy percentages alone. Candidate-only coalescible helpers receive no target-byte credit. + +## Held CRT result + +`libs/libcmt/ioinit.c` is now present as `NonMatching`: `__ioinit` is strict exact (101 meaningful bytes), and `__ioterm` has byte-identical 35-byte instructions but one unresolved *relocation spelling* difference. January names `___piob+0`, while our natural 64-entry table loop names `___pioinfo+256`; the final image address is the same. A trial spelling with `__piob` changed code size to 50 bytes and encoded linker adjacency, so it was rejected. The 40-byte `.data` and 4-byte `.CRT$RII20` sections match. The descriptive initializer name `io_initialize_handles` replaces an address placeholder in the symbol map, but the object remains uncredited as a whole until its relocation identity is reconciled without source fakery. + +## Verification + +Full `ninja` passes. Strict snapshot: 8,245 functions, 7,574 exact; +9 exact, 0 lost. Parks: 103 active, 0 stale, 0 invalid; the five cache and two biped entries were retired only after exact gates. Tool tests: 1,154 passed, 5 skipped, 26 subtests. `git diff --check` passes. Admission audit has the same 26 pre-existing data-incomplete status contradictions as the incoming baseline; none of the five units is newly contradicted. No whole-object or data credit is claimed for `ioinit`. diff --git a/libs/libcmt/ioinit.c b/libs/libcmt/ioinit.c new file mode 100644 index 00000000..0d12e273 --- /dev/null +++ b/libs/libcmt/ioinit.c @@ -0,0 +1,97 @@ +/* +IOINIT.C + +Initialize and release the CRT's low-level I/O handle table. +*/ + +#include +#include + +struct runtime_critical_section +{ + void *debug_information; + long lock_count; + long recursion_count; + void *owning_thread; + void *lock_semaphore; + unsigned long spin_count; +}; + +struct io_info +{ + long os_file_handle; + char flags; + unsigned char pipe_character; + unsigned short alignment; + int lock_initialized; + struct runtime_critical_section lock; + void *raw_event; +}; + +enum +{ + _ioinfo_array_count= 64, + _ioinfo_entries_per_array= 32, + _file_open= 0x01, + _file_device= 0x40, + _file_text= 0x80, + _standard_file_flags= _file_open | _file_device | _file_text, + _newline= 10 +}; + +extern struct io_info *__pioinfo[_ioinfo_array_count]; +extern int _nhandle; + +struct io_info __badioinfo= { -1, _file_text, _newline }; + +int __cdecl _ioinit( + void) +{ + struct io_info *info; + int index; + + info= (struct io_info *)malloc(_ioinfo_entries_per_array*sizeof(*info)); + if (!info) + return -1; + __pioinfo[0]= info; + _nhandle= _ioinfo_entries_per_array; + + for (; info<__pioinfo[0]+_ioinfo_entries_per_array; info++) + { + info->flags= 0; + info->os_file_handle= -1; + info->lock_initialized= 0; + info->pipe_character= _newline; + } + + index= 0; + while (index<3) + { + struct io_info *standard_info= __pioinfo[0]+index; + index++; + standard_info->flags= _standard_file_flags; + } + + return 0; +} + +void __cdecl _ioterm( + void) +{ + int index; + for (index=0; index<_ioinfo_array_count; index++) + { + if (__pioinfo[index]) + { + free(__pioinfo[index]); + __pioinfo[index]= NULL; + } + } + return; +} + +typedef int (__cdecl *io_initializer_proc)( + void); +#pragma data_seg(".CRT$RII20") +io_initializer_proc io_initialize_handles= _ioinit; +#pragma data_seg() diff --git a/source/ai/action_charge.c b/source/ai/action_charge.c index 33ba75c5..2f6b6ddd 100644 --- a/source/ai/action_charge.c +++ b/source/ai/action_charge.c @@ -83,16 +83,6 @@ symbols in this file: #include "cseries.h" #include "cseries/errors.h" -#define scale_vector2d scale_vector2d_inline -#define magnitude2d magnitude2d_inline -#define normalize2d normalize2d_inline -#define dot_product2d dot_product2d_inline -#define point_from_line3d point_from_line3d_inline -#define scale_vector3d scale_vector3d_inline -#define magnitude3d magnitude3d_inline -#define normalize3d normalize3d_inline -#define dot_product3d dot_product3d_inline -#define subtract_vectors3d subtract_vectors3d_inline #define real_random real_random_inline #include "actions.h" @@ -111,16 +101,6 @@ symbols in this file: #include "physics/collision_usage.h" #include "units/units.h" #include "ai_debug.h" -#undef scale_vector2d -#undef magnitude2d -#undef normalize2d -#undef dot_product2d -#undef point_from_line3d -#undef scale_vector3d -#undef magnitude3d -#undef normalize3d -#undef dot_product3d -#undef subtract_vectors3d #undef real_random /* ---------- constants */ @@ -350,113 +330,6 @@ boolean action_charge_is_leaping( return result; } -real_vector2d *scale_vector2d( - real_vector2d const *a, - real c, - real_vector2d *result) -{ - result->i = c*a->i; - result->j = c*a->j; - - return result; -} - -real magnitude2d( - real_vector2d const *v) -{ - return square_root(magnitude_squared2d(v)); -} - -real normalize2d( - real_vector2d *v) -{ - real magnitude = magnitude2d(v); - - if (!(_real_epsilon>fabs(magnitude-0.f))) - { - scale_vector2d(v, 1.f / magnitude, v); - } - else - { - magnitude = 0.f; - } - - return magnitude; -} - -real dot_product2d( - real_vector2d const *a, - real_vector2d const *b) -{ - return a->i*b->i + a->j*b->j; -} - -real_point3d *point_from_line3d( - real_point3d const *p, - real_vector3d const *v, - real t, - real_point3d *result) -{ - result->x = v->i*t + p->x; - result->y = v->j*t + p->y; - result->z = v->k*t + p->z; - - return result; -} - -real_vector3d *scale_vector3d( - real_vector3d const *a, - real c, - real_vector3d *result) -{ - result->i = c*a->i; - result->j = c*a->j; - result->k = c*a->k; - - return result; -} - -real magnitude3d( - real_vector3d const *v) -{ - return square_root(v->i*v->i + v->j*v->j + v->k*v->k); -} - -real normalize3d( - real_vector3d *v) -{ - real magnitude = magnitude3d(v); - - if (!(_real_epsilon>fabs(magnitude-0.f))) - { - scale_vector3d(v, 1.f / magnitude, v); - } - else - { - magnitude = 0.f; - } - - return magnitude; -} - -real dot_product3d( - real_vector3d const *a, - real_vector3d const *b) -{ - return a->i*b->i + a->j*b->j + a->k*b->k; -} - -real_vector3d *subtract_vectors3d( - real_vector3d const *a, - real_vector3d const *b, - real_vector3d *result) -{ - result->i = a->i-b->i; - result->j = a->j-b->j; - result->k = a->k-b->k; - - return result; -} real real_random( void) diff --git a/source/ai/action_obey.c b/source/ai/action_obey.c index 5883bcd2..a0a90380 100644 --- a/source/ai/action_obey.c +++ b/source/ai/action_obey.c @@ -247,7 +247,6 @@ symbols in this file: /* ---------- headers */ #define random_range random_range_inline -#define vector_from_points2d vector_from_points2d_inline #include "cseries.h" #include "actions.h" @@ -274,7 +273,6 @@ symbols in this file: #include "units/biped_definitions.h" #include "memory/data.h" #include "units/units.h" -#undef vector_from_points2d #undef random_range /* ---------- constants */ @@ -1310,18 +1308,6 @@ short random_range( upper_bound); } -real_vector2d *vector_from_points2d( - real_point2d const *a, - real_point2d const *b, - real_vector2d *result) -{ - result->i = b->x-a->x; - result->j = b->y-a->y; - - return result; -} - - /* ---------- private code */ static int vehicle_possibility_qsort( diff --git a/source/ai/actor_type_infection.c b/source/ai/actor_type_infection.c index 6ac63afa..6ae881a0 100644 --- a/source/ai/actor_type_infection.c +++ b/source/ai/actor_type_infection.c @@ -654,9 +654,7 @@ void infection_swarm_control( &direction); if (movement_type == _swarm_movement_away_from_prop) { - direction.i = -direction.i; - direction.j = -direction.j; - direction.k = -direction.k; + negate_vector3d(&direction, &direction); } has_direction = TRUE; } @@ -679,9 +677,7 @@ void infection_swarm_control( cross_product3d(&up, &swarm_component->obey.directmovement.vector, &direction); if (swarm_component->obey.directmovement.facing == _ai_atom_move_facing_right) { - direction.i = -direction.i; - direction.j = -direction.j; - direction.k = -direction.k; + negate_vector3d(&direction, &direction); } break; @@ -689,9 +685,7 @@ void infection_swarm_control( direction = swarm_component->obey.directmovement.vector; if (swarm_component->obey.directmovement.facing == _ai_atom_move_facing_backwards) { - direction.i = -direction.i; - direction.j = -direction.j; - direction.k = -direction.k; + negate_vector3d(&direction, &direction); } break; } @@ -754,9 +748,7 @@ void infection_swarm_control( real separation = 0.f; short neighbor_index; - probe.x = swarm_component->position.x - direction.i * 0.2f; - probe.y = swarm_component->position.y - direction.j * 0.2f; - probe.z = swarm_component->position.z - direction.k * 0.2f; + point_from_line3d(&swarm_component->position, &direction, -0.2f, &probe); cross_product3d(&up, &direction, &right); for (neighbor_index = 0; @@ -879,10 +871,10 @@ void infection_swarm_control( control.weapon_index = NONE; control.grenade_index = NONE; control.zoom_level = NONE; - control.control_flags = (word)control_flags; + control.control_flags = control_flags; control.primary_trigger = 0.f; - control.animation_state = (char)animation_state; - control.aiming_speed = (char)aiming_speed; + control.animation_state = animation_state; + control.aiming_speed = aiming_speed; if (has_direction) { set_real_vector3d(&control.throttle, 1.f, 0.f, 0.f); diff --git a/source/cache/cache_files_decompress_windows.c b/source/cache/cache_files_decompress_windows.c index f6fa3a87..a333ae99 100644 --- a/source/cache/cache_files_decompress_windows.c +++ b/source/cache/cache_files_decompress_windows.c @@ -317,7 +317,7 @@ struct simple_decompressor_definition { char src_name[260]; struct cache_file_header header; - unsigned long flags; + volatile unsigned long flags; z_stream zlib_stream; byte *zlib_buffer; long zlib_buffer_size; @@ -345,7 +345,7 @@ struct simple_decompressor_definition long read_bytes_left; long async_write_bytes_left; long write_bytes_left; - real read_progress; + volatile real read_progress; long current_write_offset; long current_read_offset; struct cache_copy_read_request *current_request; @@ -430,7 +430,7 @@ static boolean cache_copy_stop_requested( static void cache_copy_yield( void); static void cache_copy_set_flag( - long flag); + short flag); static long cache_copy_read_buffer_size( void); static long cache_copy_write_buffer_size( @@ -931,7 +931,7 @@ static void cache_copy_wait_for_async_io( } static void cache_copy_set_flag( - long flag) + short flag) { SET_FLAG(global_self->flags, flag, TRUE); @@ -1090,10 +1090,9 @@ static void CALLBACK cache_copy_FileIOCompletionRoutine( unsigned long bytes_transferred, OVERLAPPED *overlapped) { - struct simple_decompressor_definition *self = global_self; - long overlapped_index = overlapped - self->overlapped; - long *in_use_flags = self->overlapped_in_use_flags; - long *completed_flags = self->overlapped_completed_flags; + long *in_use_flags = global_self->overlapped_in_use_flags; + long *completed_flags = global_self->overlapped_completed_flags; + long overlapped_index = overlapped - global_self->overlapped; if (!error_code) { diff --git a/source/effects/decals.c b/source/effects/decals.c index ec97f4dd..488891d9 100644 --- a/source/effects/decals.c +++ b/source/effects/decals.c @@ -219,7 +219,6 @@ symbols in this file: #define plane2d_from_points plane2d_from_points_inline #define plane3d_from_point_and_normal plane3d_from_point_and_normal_inline #define plane3d_negate plane3d_negate_inline -#define plane3d_distance_to_point plane3d_distance_to_point_inline #define REAL_MATH_EXTERNAL_PROJECT_POINT3D #include "effects/decals.h" #include "cseries/cseries.h" @@ -232,7 +231,6 @@ symbols in this file: #undef plane2d_from_points #undef plane3d_from_point_and_normal #undef plane3d_negate -#undef plane3d_distance_to_point #undef REAL_MATH_EXTERNAL_PROJECT_POINT3D #include "cseries/errors.h" @@ -930,16 +928,6 @@ real_plane3d *plane3d_negate( return plane; } -real plane3d_distance_to_point( - real_plane3d const *plane, - real_point3d const *point) -{ - return point->x * plane->n.i - + point->y * plane->n.j - + point->z * plane->n.k - - plane->d; -} - pixel32 real_a_rgb_color_to_pixel32( real alpha, real_rgb_color const *color) diff --git a/source/math/geometry.c b/source/math/geometry.c index c0abc0a1..0d03f69f 100644 --- a/source/math/geometry.c +++ b/source/math/geometry.c @@ -186,9 +186,7 @@ symbols in this file: #include "cseries.h" #define plane2d_distance_to_point plane2d_distance_to_point_inline -#define vector_intersect_plane3d vector_intersect_plane3d_inline #include "real_math.h" -#undef vector_intersect_plane3d #undef plane2d_distance_to_point #include "geometry.h" @@ -561,15 +559,6 @@ real vector_intersect_plane2d( -(plane->n.i*vector->i + plane->n.j*vector->j); } -real vector_intersect_plane3d( - real_point3d const *point, - real_vector3d const *vector, - real_plane3d const *plane) -{ - return (point->x*plane->n.i + point->y*plane->n.j + point->z*plane->n.k - plane->d) / - -(vector->i*plane->n.i + vector->j*plane->n.j + vector->k*plane->n.k); -} - static void calculate_vertex( struct geosphere *sphere, short new_vertex, diff --git a/source/units/biped_limp_noodle.c b/source/units/biped_limp_noodle.c index 52ce4dad..e6ef182e 100644 --- a/source/units/biped_limp_noodle.c +++ b/source/units/biped_limp_noodle.c @@ -121,18 +121,17 @@ static boolean biped_limp_noodle_valid_joint_rotation( struct biped_definition *definition = biped_definition_get(biped->definition_index); struct animation_graph *animation_graph = animation_graph_definition_get( definition->object.animation_graph.index); - struct tag_block *nodes = &animation_graph->nodes; struct animation_graph_node *node = TAG_BLOCK_GET_ELEMENT( - nodes, + &animation_graph->nodes, node_index, struct animation_graph_node); struct animation_graph_node *parent_node = TAG_BLOCK_GET_ELEMENT( - nodes, + &animation_graph->nodes, node->parent_node_index, struct animation_graph_node); real collision_radius = animation_graph->limp_body_node_collision_radius; - if (fabs(collision_radius) < _real_epsilon || + if (realcmp(collision_radius, 0.f) || collision_radius < 0.f || collision_radius > 0.07f) { @@ -142,18 +141,17 @@ static boolean biped_limp_noodle_valid_joint_rotation( if (node->parent_node_index && !TEST_FLAG(parent_node->flags, _joint_type_no_movement)) { - real_matrix4x3 *parent_matrix = &node_matrices[node->parent_node_index]; real_vector3d current_direction; real_vector3d desired_direction; real_vector3d rotation_axis; real rotation_cosine; vector_from_points3d( - &parent_matrix->position, + &node_matrices[node->parent_node_index].position, &node_matrices[node_index].position, ¤t_direction); vector_from_points3d( - &parent_matrix->position, + &node_matrices[node->parent_node_index].position, new_world_position, &desired_direction); normalize3d(¤t_direction); @@ -162,16 +160,15 @@ static boolean biped_limp_noodle_valid_joint_rotation( normalize3d(&rotation_axis); rotation_cosine = dot_product3d(¤t_direction, &desired_direction); - if (fabs(rotation_cosine - 1.f) >= _real_epsilon) + if (!realcmp(rotation_cosine, 1.f)) { real rotation_angle = arccosine(rotation_cosine); real_matrix4x3 parent_inverse; real_matrix4x3 grandparent_inverse; real_vector3d local_rotation_axis; real_vector3d parent_axis; - real_vector3d *constraint_axis = &parent_node->base_vector; - matrix4x3_inverse(parent_matrix, &parent_inverse); + matrix4x3_inverse(&node_matrices[node->parent_node_index], &parent_inverse); matrix4x3_inverse( &node_matrices[parent_node->parent_node_index], &grandparent_inverse); @@ -179,7 +176,7 @@ static boolean biped_limp_noodle_valid_joint_rotation( &parent_inverse, &rotation_axis, &local_rotation_axis); - parent_axis = parent_matrix->forward; + parent_axis = node_matrices[node->parent_node_index].forward; matrix4x3_transform_vector( &grandparent_inverse, &parent_axis, @@ -187,33 +184,31 @@ static boolean biped_limp_noodle_valid_joint_rotation( if (TEST_FLAG(parent_node->flags, _joint_type_hinge)) { + real_vector3d plane_normal = node_matrices[node->parent_node_index].up; real_plane3d plane; - real_vector3d plane_normal = parent_matrix->up; + real projection_distance; real_point3d rotate_to_position; real_vector3d rotate_to_direction; real_vector3d local_rotate_to_direction; - real constraint_cosine; - real projection_distance; plane3d_from_point_and_normal( &plane, - &parent_matrix->position, + &node_matrices[node->parent_node_index].position, &plane_normal); projection_distance = plane3d_distance_to_point(&plane, new_world_position) * -1.f; - rotate_to_position.x = - plane.n.i * projection_distance + new_world_position->x; - rotate_to_position.y = - plane.n.j * projection_distance + new_world_position->y; - rotate_to_position.z = - plane.n.k * projection_distance + new_world_position->z; + point_from_line3d( + new_world_position, + &plane_normal, + projection_distance, + &rotate_to_position); match_assert( "c:\\halo\\SOURCE\\units\\biped_limp_noodle.c", 231, realcmp(plane3d_distance_to_point(&plane, &rotate_to_position), 0.f)); vector_from_points3d( - &parent_matrix->position, + &node_matrices[node->parent_node_index].position, &rotate_to_position, &rotate_to_direction); normalize3d(&rotate_to_direction); @@ -221,64 +216,53 @@ static boolean biped_limp_noodle_valid_joint_rotation( &parent_inverse, &rotate_to_direction, &local_rotate_to_direction); - constraint_cosine = dot_product3d( - constraint_axis, - &local_rotate_to_direction); - if (fabs(constraint_cosine - 1.f) < _real_epsilon) - goto follow_parent; - - BIT_VECTOR_SET_FLAG(moved_node_flags, node_index, TRUE); - if (current_world_position->z >= rotate_to_position.z && - !collision_test_sphere( - &rotate_to_position, - collision_radius, - biped_index)) + if (!realcmp(dot_product3d(&parent_node->base_vector, &local_rotate_to_direction), 1.f)) { - *current_world_position = rotate_to_position; + BIT_VECTOR_SET_FLAG(moved_node_flags, node_index, TRUE); + if (current_world_position->z >= rotate_to_position.z && + !collision_test_sphere( + &rotate_to_position, + collision_radius, + biped_index)) + { + *current_world_position = rotate_to_position; + } + moved = TRUE; } } else { real constraint_cosine; - real constraint_angle; rotate_vector_about_axis( &parent_axis, &local_rotation_axis, sine(rotation_angle), rotation_cosine); - constraint_cosine = dot_product3d(constraint_axis, &parent_axis); - if (fabs(constraint_cosine - 1.f) < _real_epsilon) - goto follow_parent; - - constraint_angle = arccosine(constraint_cosine); - if (fabs(constraint_angle) >= parent_node->range || - current_world_position->z <= new_world_position->z) + constraint_cosine = dot_product3d(&parent_node->base_vector, &parent_axis); + if (!realcmp(constraint_cosine, 1.f) && + fabs(arccosine(constraint_cosine)) < parent_node->range && + current_world_position->z > new_world_position->z) { - goto follow_parent; + BIT_VECTOR_SET_FLAG(moved_node_flags, node_index, TRUE); + moved = TRUE; + *current_world_position = *new_world_position; } - - BIT_VECTOR_SET_FLAG(moved_node_flags, node_index, TRUE); - *current_world_position = *new_world_position; } - - moved = TRUE; } } -follow_parent: - if ((!TEST_FLAG(parent_node->flags, _joint_type_no_movement) && moved) || - !BIT_VECTOR_TEST_FLAG(moved_node_flags, node->parent_node_index) || - current_world_position->z <= new_world_position->z) + if ((TEST_FLAG(parent_node->flags, _joint_type_no_movement) || !moved) && + BIT_VECTOR_TEST_FLAG(moved_node_flags, node->parent_node_index) && + current_world_position->z > new_world_position->z) { - return moved; + BIT_VECTOR_SET_FLAG(moved_node_flags, node_index, TRUE); + *current_world_position = *new_world_position; + moved = TRUE; } - BIT_VECTOR_SET_FLAG(moved_node_flags, node_index, TRUE); - *current_world_position = *new_world_position; - - return TRUE; + return moved; } static void biped_limp_noodle_move_relax_and_constrain_positions( @@ -294,6 +278,8 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( byte current_iteration; real relaxation_fraction; unsigned long moved_node_flags[BIT_VECTOR_SIZE_IN_LONGS(MAXIMUM_NODES_PER_ANIMATION)]; + short node_queue[MAXIMUM_NODES_PER_ANIMATION]; + real_vector3d velocity; struct collision_plane collision_planes[10]; long iteration; @@ -304,7 +290,7 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( global_current_collision_users[global_current_collision_user_depth++] = _collision_user_limp_body_physics; - if (fabs(collision_radius) < _real_epsilon || + if (realcmp(collision_radius, 0.f) || collision_radius < 0.f || collision_radius > 0.07f) { @@ -319,7 +305,7 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( relaxation_fraction = (real)(current_iteration + 1) / (real)total_iterations; - if (fabs(relaxation_fraction) < _real_epsilon) + if (realcmp(relaxation_fraction, 0.f)) return; if (current_iteration >= total_iterations) goto collision_user_end; @@ -337,7 +323,6 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( for (iteration = 0; iteration < 4; iteration++) { - short node_queue[MAXIMUM_NODES_PER_ANIMATION]; short queue_head = 0; short queue_tail = 1; @@ -352,10 +337,8 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( if (node_index) { - real_point3d *position = &node_matrices[node_index].position; - real_point3d *parent_position = - &node_matrices[node->parent_node_index].position; - real_vector3d velocity; + real_point3d *position; + real_point3d *parent_position; real_vector3d segment; set_real_vector3d( @@ -363,6 +346,8 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( 0.f, 0.f, relaxation_fraction * -0.032086615f); + position = &node_matrices[node_index].position; + parent_position = &node_matrices[node->parent_node_index].position; vector_from_points3d(parent_position, position, &segment); if (!iteration && @@ -382,8 +367,8 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( &moved_velocity, 3, collision_planes); - if (fabs(moved_velocity.i) < _real_epsilon && - fabs(moved_velocity.j) < _real_epsilon) + if (realcmp(moved_velocity.i, 0.f) && + realcmp(moved_velocity.j, 0.f)) { biped_limp_noodle_valid_joint_rotation( biped_index, @@ -400,9 +385,7 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( struct collision_result collision; vector_from_points3d(parent_position, position, &segment); - ray_origin.x = segment.i * -0.015f + parent_position->x; - ray_origin.y = segment.j * -0.015f + parent_position->y; - ray_origin.z = segment.k * -0.015f + parent_position->z; + point_from_line3d(parent_position, &segment, -0.015f, &ray_origin); scale_vector3d(&segment, 1.03f, &segment); if (collision_test_vector( @@ -416,6 +399,7 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( boolean embedded[2]; real push_distance[2]; long endpoint_index; + long embedded_count; embedded[0] = collision_test_sphere( position, @@ -425,23 +409,18 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( parent_position, 0.03f, biped_index); + embedded_count = embedded[0] + embedded[1]; - if (embedded[0] || embedded[1]) + if (embedded_count) { - if (embedded[0] + embedded[1] == 2) + if (embedded_count == 2) { for (endpoint_index = 0; endpoint_index < 2; endpoint_index++) { - real_point3d *endpoint = - endpoint_index ? parent_position : position; - - push_distance[endpoint_index] = - -plane3d_distance_to_point( - &collision.plane, - endpoint) / - dot_product3d( - &collision.plane.n, - &collision.plane.n); + push_distance[endpoint_index] = vector_intersect_plane3d( + endpoint_index == 0 ? position : parent_position, + &collision.plane.n, + &collision.plane); if (push_distance[endpoint_index] != 0.f) { push_distance[endpoint_index] += @@ -455,16 +434,10 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( { if (embedded[endpoint_index]) { - real_point3d *endpoint = - endpoint_index ? parent_position : position; - - push_distance[endpoint_index] = - -plane3d_distance_to_point( - &collision.plane, - endpoint) / - dot_product3d( - &collision.plane.n, - &collision.plane.n); + push_distance[endpoint_index] = vector_intersect_plane3d( + endpoint_index == 0 ? position : parent_position, + &collision.plane.n, + &collision.plane); if (push_distance[endpoint_index] != 0.f) { push_distance[endpoint_index] += @@ -480,16 +453,13 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( for (endpoint_index = 0; endpoint_index < 2; endpoint_index++) { - if (!(_real_epsilon > fabs(push_distance[endpoint_index]))) + if (!realcmp(push_distance[endpoint_index], 0.f)) { - real_point3d *endpoint = - endpoint_index ? parent_position : position; - real push = - push_distance[endpoint_index] * relaxation_fraction; - - endpoint->x = collision.plane.n.i * push + endpoint->x; - endpoint->y = collision.plane.n.j * push + endpoint->y; - endpoint->z = collision.plane.n.k * push + endpoint->z; + point_from_line3d( + endpoint_index == 0 ? position : parent_position, + &collision.plane.n, + relaxation_fraction * push_distance[endpoint_index], + endpoint_index == 0 ? position : parent_position); } } } @@ -507,60 +477,69 @@ static void biped_limp_noodle_move_relax_and_constrain_positions( real rest_distance = model_node->node_distance_from_parent; real distance = distance3d(position, parent_position); - if (rest_distance > 0.f && - rest_distance <= 10.f && + if (!(rest_distance <= 0.f || rest_distance > 10.f) && distance >= 0.f && distance < 20.f && - fabs(distance) >= _real_epsilon && - fabs(rest_distance) >= _real_epsilon && - rest_distance != distance && - fabs(distance) >= _real_epsilon) + !realcmp(distance, 0.f)) { - real correction = (rest_distance - distance) / distance; - - if (node->parent_node_index) + if (!realcmp(rest_distance, 0.f) && + rest_distance != distance && + !realcmp(distance, 0.f)) { - real half_correction = correction * 0.5f; + real correction = (rest_distance - distance) / distance; - scale_vector3d(&segment, -half_correction, &velocity); - collision_move_point( - parent_position, - &velocity, - &biped_limp_noodle_globals.features, - parent_position, - &velocity, - 3, - collision_planes); - scale_vector3d(&segment, half_correction, &velocity); - collision_move_point( - position, - &velocity, - &biped_limp_noodle_globals.features, - position, - &velocity, - 3, - collision_planes); - } - else - { - scale_vector3d(&segment, correction, &velocity); - if (collision_test_sphere( - position, - collision_radius, - biped_index)) + if (node->parent_node_index) { - goto next_node; + real half_correction = correction * 0.5f; + + scale_vector3d(&segment, -half_correction, &velocity); + collision_move_point( + parent_position, + &velocity, + &biped_limp_noodle_globals.features, + parent_position, + &velocity, + 3, + collision_planes); + scale_vector3d(&segment, half_correction, &velocity); + collision_move_point( + position, + &velocity, + &biped_limp_noodle_globals.features, + position, + &velocity, + 3, + collision_planes); + } + else + { + scale_vector3d(&segment, correction, &velocity); + if (collision_test_sphere( + position, + collision_radius, + biped_index)) + { + goto next_node; + } + collision_move_point( + position, + &velocity, + &biped_limp_noodle_globals.features, + position, + &velocity, + 3, + collision_planes); } - collision_move_point( - position, - &velocity, - &biped_limp_noodle_globals.features, - position, - &velocity, - 3, - collision_planes); } } + else + { + if (node->next_sibling_node_index != NONE) + node_queue[queue_tail++] = node->next_sibling_node_index; + if (node->first_child_node_index != NONE) + node_queue[queue_tail++] = node->first_child_node_index; + continue; + } } }