mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-17 19:00:25 +02:00
R3 batch 2: owner rulings 1, 4, 7 - five objects complete
Owner rulings 2026-09-24: - Q1 YES (04, not 04b): _actor_aim_grenade in its natural /Od body (no goto), keeping the BUG comment on January's vehicle-path read of the unassigned aim_vector. Header-inline helpers replace the TU redirects and the NODUP cross_product2d hand copy; the new COMDATs are identical to January's. Unlocks collision_features, real_math and path_smoothing (config 03A) and retires the stale collision_features rejection (04). The decals rejection, path_structure_bsp and path_obstacle_avoidance are untouched. - Q4 YES (A2): _first_person_weapon_update without the two NULL guards, VALID_INDEX at all five /Od-attested sites, and the three magnitude redirects removed. The weapon-switch invariant is documented in source. - Q7 YES: _uncompress_int32_to_real_vector3d stages the conversion through a real temp with a declaration-time initialiser (debug exact; verbatim in Oct-2001 2276P and the Sept-2001 cache.exe). Full gate: 383 -> 388 / 468 Halo objects, +3 functions (+2,211 meaningful code), 0 regressions, parks 82 -> 80, admission 0 contradicted / 0 revoked, fake-match leads 26, pytest 1,161 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6c44a15135
commit
3ee32a5cb5
6 files changed
+61
-94
No files matched your search
+5
-5
@@ -468,7 +468,7 @@
|
||||
{ "name": "source/rasterizer/rasterizer_swizzle.c", "index": 93, "status": "Matching" },
|
||||
{ "name": "source/rasterizer/rasterizer_memory_pool.c", "index": 94, "status": "Matching" },
|
||||
{ "name": "source/rasterizer/rasterizer_lights.c", "index": 95, "status": "NonMatching" },
|
||||
{ "name": "source/rasterizer/rasterizer_geometry.c", "index": 96, "status": "NonMatching" },
|
||||
{ "name": "source/rasterizer/rasterizer_geometry.c", "index": 96, "status": "Matching" },
|
||||
{ "name": "source/rasterizer/rasterizer_frame_statistics.c", "index": 97, "status": "Matching" },
|
||||
{ "name": "source/rasterizer/rasterizer_debug.c", "index": 98, "status": "Matching" },
|
||||
{ "name": "source/rasterizer/rasterizer_cinematics.c", "index": 99, "status": "Matching" },
|
||||
@@ -511,7 +511,7 @@
|
||||
{ "name": "source/physics/collision_usage.c", "index": 136, "status": "Matching" },
|
||||
{ "name": "source/physics/collision_models.c", "index": 137, "status": "Matching" },
|
||||
{ "name": "source/physics/collision_model_definitions.c", "index": 138, "status": "Matching" },
|
||||
{ "name": "source/physics/collision_features.c", "index": 139, "status": "NonMatching" },
|
||||
{ "name": "source/physics/collision_features.c", "index": 139, "status": "Matching" },
|
||||
{ "name": "source/physics/collision_debug.c", "index": 140, "status": "Matching" },
|
||||
{ "name": "source/physics/collision_bsp_definitions.c", "index": 141, "status": "Matching" },
|
||||
{ "name": "source/physics/collision_bsp.c", "index": 142, "status": "NonMatching" },
|
||||
@@ -594,7 +594,7 @@
|
||||
{ "name": "source/memory/zlib/adler32.c", "index": 219, "status": "Matching" },
|
||||
{ "name": "source/math/vector_tree.c", "index": 220, "status": "Matching" },
|
||||
{ "name": "source/math/trig_math.c", "index": 221, "status": "Matching" },
|
||||
{ "name": "source/math/real_math.c", "index": 222, "status": "NonMatching" },
|
||||
{ "name": "source/math/real_math.c", "index": 222, "status": "Matching" },
|
||||
{ "name": "source/math/random_math.c", "index": 223, "status": "Matching" },
|
||||
{ "name": "source/math/probability.c", "index": 224, "status": "Matching" },
|
||||
{ "name": "source/math/periodic_functions.c", "index": 225, "status": "NonMatching" },
|
||||
@@ -634,7 +634,7 @@
|
||||
{ "name": "source/interface/inventory_displays.c", "index": 259, "status": "Matching" },
|
||||
{ "name": "source/interface/interface_panels.c", "index": 260, "status": "Matching" },
|
||||
{ "name": "source/interface/interface.c", "index": 261, "status": "NonMatching" },
|
||||
{ "name": "source/interface/first_person_weapons.c", "index": 262, "status": "NonMatching" },
|
||||
{ "name": "source/interface/first_person_weapons.c", "index": 262, "status": "Matching" },
|
||||
{ "name": "source/interface/event_manager.c", "index": 263, "status": "Matching" },
|
||||
{ "name": "source/interface/attract_mode.c", "index": 264, "status": "Matching" },
|
||||
{ "name": "source/interface/weapon_hud_interface_definition.c", "index": 265, "status": "Matching" },
|
||||
@@ -799,7 +799,7 @@
|
||||
{ "name": "source/bitmaps/libtiff/tif_aux.c", "index": 424, "status": "Matching" },
|
||||
{ "name": "source/ai/props.c", "index": 425, "status": "Matching" },
|
||||
{ "name": "source/ai/path_structure_bsp.c", "index": 426, "status": "NonMatching" },
|
||||
{ "name": "source/ai/path_smoothing.c", "index": 427, "status": "NonMatching" },
|
||||
{ "name": "source/ai/path_smoothing.c", "index": 427, "status": "Matching" },
|
||||
{ "name": "source/ai/path_obstacles.c", "index": 428, "status": "NonMatching" },
|
||||
{ "name": "source/ai/path_obstacle_avoidance.c", "index": 429, "status": "NonMatching" },
|
||||
{ "name": "source/ai/path.c", "index": 430, "status": "Matching" },
|
||||
|
||||
@@ -40,14 +40,6 @@
|
||||
"reason": "The exact typed decal_projection_create body naturally inlines cross_product2d as January requires, but VC7 also emits an unreferenced select-any helper body absent from the January Decals split. January's selected Actor Combat copy is no-duplicates. The exact target function receives valid credit; the surplus helper receives none and blocks whole-object Matching.",
|
||||
"evidence": "docs/object_matching_logs/decals_obj_color_projection_packet_20260912.md#inline-helper-ownership-boundary",
|
||||
"reopen": "Remove only when authentic source topology or an ordinary compatible canonical link preserves decal_projection_create while preventing or safely coalescing the extra helper. Do not force inline, manually expand the helper for code shaping, alter COMDAT metadata, or count the candidate-only bytes."
|
||||
},
|
||||
{
|
||||
"unit": "source/physics/collision_features",
|
||||
"class": "candidate-only-comdat-owner",
|
||||
"symbol": "_projection_from_vector3d",
|
||||
"reason": "All 20 target-owned functions compare strict exact, but the rebuilt translation unit also emits an 80-byte _projection_from_vector3d COMDAT absent from its January split. That surplus body reverses the x/y dominant-axis choice and differs from January's selected decals owner; exact external callers do not establish correct helper code or ownership.",
|
||||
"evidence": "docs/object_matching_logs/shared_inline_helper_admission_audit_20260904.md#collision-features-projection-owner",
|
||||
"reopen": "Correct the shared helper from January evidence, preserve inherited target-function matches across all header consumers, and establish authentic compatible ownership through ordinary source topology and link verification. Do not invent a helper owner, force emission, or credit the decals-owned 80 bytes from a candidate-only copy."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -474,25 +474,6 @@
|
||||
"objdiff_percent": 99.87755
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/rasterizer/rasterizer_geometry",
|
||||
"function": "_uncompress_int32_to_real_vector3d",
|
||||
"class": "instruction-scheduling",
|
||||
"evidence": "Equal 144-byte padded size, 9/9 relocations with identical destinations, and 49/49 instructions. The sole divergence is one dependency-free transposition: January emits `fadd __real@3f800000` before `shl eax, 0x16`, the candidate emits them in the opposite order, which also shifts that one relocation's address by three bytes. The bit fields, scales, masks, destructive shift sequence and the local real_vector3d copied out through *result are all confirmed. Measured inert: folding the second shift into the k expression, long-hand assignment, hoisting the shift ahead of j, and a division form of the k scale.",
|
||||
"measurements": {
|
||||
"target": {
|
||||
"size": 144,
|
||||
"relocation_count": 9,
|
||||
"normalized_sha256": "aa4a69683e5f1148413f6029acfc993341346b93b86809dcb5450896dcc3944d"
|
||||
},
|
||||
"base": {
|
||||
"size": 144,
|
||||
"relocation_count": 9,
|
||||
"normalized_sha256": "8199ac81b23a4607ed8191dbe2f95cb11da85761ecf353514714f8261562b55f"
|
||||
},
|
||||
"objdiff_percent": 95.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/ai/actions",
|
||||
"function": "_actor_action_handle_vehicle_entry",
|
||||
@@ -1253,17 +1234,6 @@
|
||||
"objdiff_percent": 62.452587
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/interface/first_person_weapons",
|
||||
"function": "_first_person_weapon_update",
|
||||
"class": "unclassified",
|
||||
"evidence": "Complete HCEA-corroborated first-person weapon state machine with the four-player January loop. Wave 2 of claude/fifty-objects-20260925 applied three /Od-attested corrections. First, a key-frame result no longer advances the state: January @0x13c jumps past next_state on _animation_key_frame, and /Od 0x61fb2e has an empty then-arm. Second, both animation updates call the TU wrapper animation_update_render_only (/Od 0x61fb22/0x61fc59); no other January object references the wrapper, so it was inlined here. Third, turning is a real_vector2d aggregate (/Od RTC descriptor turning, 8 bytes). With the null guards removed and magnitude3d inlined, the function is strictly exact (scratch/w/first_person_weapons/final_exact.c). January omits both null tests after count ? TAG_BLOCK_GET_ELEMENT(...) : NULL, and the later /Od build omits them too. That is an authentic unguarded dereference and is owner-gated. The retained defined-behaviour body keeps both guards and keeps magnitude3d out of line, so no helper COMDAT is emitted while the caller is non-exact. Zero credit. Reopen on an owner ruling admitting the unguarded dereference. See scratch/w/first_person_weapons/LEDGER.md.",
|
||||
"measurements": {
|
||||
"target": { "size": 1536, "relocation_count": 59, "normalized_sha256": "912d95683f14ff39699c4a1056af92441a20ceeec0584007512ce26b5d70478d" },
|
||||
"base": { "size": 1520, "relocation_count": 60, "normalized_sha256": "ba39884c90f2ef0afbac711db26225e2b41d4fc0719a2afbe0a600883e2bf8ff" },
|
||||
"objdiff_percent": 95.21506
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/math/geometry",
|
||||
"function": "_convex_polygon2d_clip_to_plane",
|
||||
|
||||
+27
-34
@@ -126,8 +126,6 @@ symbols in this file:
|
||||
|
||||
/* ---------- headers */
|
||||
|
||||
#define cross_product2d cross_product2d_inline
|
||||
#define normalize2d normalize2d_inline
|
||||
#define normalize3d normalize3d_inline
|
||||
#define point_from_line3d actor_combat_point_from_line3d_inline
|
||||
#define vector_from_points3d actor_combat_vector_from_points3d_inline
|
||||
@@ -166,8 +164,6 @@ symbols in this file:
|
||||
#undef vector_from_points3d
|
||||
#undef point_from_line3d
|
||||
#undef normalize3d
|
||||
#undef normalize2d
|
||||
#undef cross_product2d
|
||||
|
||||
#include "math/real_math_declarations.h"
|
||||
|
||||
@@ -520,13 +516,6 @@ static struct projectile_definition *actor_get_grenade_definition(
|
||||
return projectile_definition;
|
||||
}
|
||||
|
||||
real cross_product2d(
|
||||
real_vector2d const *a,
|
||||
real_vector2d const *b)
|
||||
{
|
||||
return a->i*b->j - a->j*b->i;
|
||||
}
|
||||
|
||||
static void actor_combat_find_nearby_target(
|
||||
real_point3d *target_point,
|
||||
real miss_distance)
|
||||
@@ -1556,8 +1545,8 @@ long actor_aim_grenade(
|
||||
real_vector3d *vector)
|
||||
{
|
||||
struct actor_datum *actor = actor_get(actor_index);
|
||||
real_vector3d aim_vector;
|
||||
long target_unit_index = NONE;
|
||||
real_vector3d aim_vector;
|
||||
|
||||
if (actor->control.grenade_current_prop_index != NONE)
|
||||
{
|
||||
@@ -1572,12 +1561,12 @@ long actor_aim_grenade(
|
||||
if (prop->state < _prop_state_unacknowledged ||
|
||||
prop->state > _prop_state_becoming_acknowledged)
|
||||
{
|
||||
real_point3d desired_grenade_target = prop->body_position;
|
||||
real_point3d new_desired_target = prop->body_position;
|
||||
|
||||
desired_grenade_target.z += 0.2f;
|
||||
new_desired_target.z += 0.2f;
|
||||
actor_combat_retarget_grenade(
|
||||
actor_index,
|
||||
&desired_grenade_target);
|
||||
&new_desired_target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1585,33 +1574,30 @@ long actor_aim_grenade(
|
||||
|
||||
if (actor->input.vehicle_index == NONE)
|
||||
{
|
||||
real_vector2d aim_vector2d;
|
||||
real_vector2d horizontal_aim_vector;
|
||||
|
||||
aim_vector = actor->control.grenade_current_aim_vector;
|
||||
aim_vector2d.i = aim_vector.i;
|
||||
aim_vector2d.j = aim_vector.j;
|
||||
horizontal_aim_vector = *(real_vector2d const *)&aim_vector;
|
||||
|
||||
if (normalize2d(&aim_vector2d) > 0.0f &&
|
||||
aim_vector2d.i*actor->input.facing_vector.i +
|
||||
aim_vector2d.j*actor->input.facing_vector.j <
|
||||
GRENADE_AIMING_ANGLE_COSINE)
|
||||
if (normalize2d(&horizontal_aim_vector) > 0.0f &&
|
||||
dot_product2d(
|
||||
(real_vector2d const *)&actor->input.facing_vector,
|
||||
&horizontal_aim_vector) < GRENADE_AIMING_ANGLE_COSINE)
|
||||
{
|
||||
boolean counterclockwise =
|
||||
aim_vector2d.j*actor->input.facing_vector.i -
|
||||
aim_vector2d.i*actor->input.facing_vector.j > 0.0f;
|
||||
real_vector3d new_aim_vector = actor->input.facing_vector;
|
||||
real magnitude;
|
||||
boolean counterclockwise = cross_product2d(
|
||||
(real_vector2d const *)&actor->input.facing_vector,
|
||||
&horizontal_aim_vector) > 0.0f;
|
||||
|
||||
rotate_vector_about_axis(
|
||||
&new_aim_vector,
|
||||
global_up3d,
|
||||
(counterclockwise ? 1 : -1)*GRENADE_AIMING_ANGLE_SINE,
|
||||
GRENADE_AIMING_ANGLE_COSINE);
|
||||
|
||||
magnitude = square_root(
|
||||
aim_vector.i*aim_vector.i + aim_vector.j*aim_vector.j);
|
||||
new_aim_vector.i *= magnitude;
|
||||
new_aim_vector.j *= magnitude;
|
||||
scale_vector2d(
|
||||
(real_vector2d const *)&new_aim_vector,
|
||||
magnitude2d((real_vector2d const *)&aim_vector),
|
||||
(real_vector2d *)&new_aim_vector);
|
||||
new_aim_vector.k = aim_vector.k;
|
||||
|
||||
match_assert_valid_real_normal3d(
|
||||
@@ -1623,9 +1609,16 @@ long actor_aim_grenade(
|
||||
}
|
||||
}
|
||||
|
||||
vector->i = aim_vector.i*actor->control.grenade_current_aim_speed;
|
||||
vector->j = aim_vector.j*actor->control.grenade_current_aim_speed;
|
||||
vector->k = aim_vector.k*actor->control.grenade_current_aim_speed;
|
||||
/* BUG (preserved for exact matching): aim_vector is assigned only on foot.
|
||||
* With actor->input.vehicle_index != NONE, January branches from its vehicle
|
||||
* test straight to this scale and reads the unassigned local; the 2011 HCEX
|
||||
* and later /Od builds keep the same path. A corrected build should start
|
||||
* from actor->control.grenade_current_aim_vector.
|
||||
*/
|
||||
scale_vector3d(
|
||||
&aim_vector,
|
||||
actor->control.grenade_current_aim_speed,
|
||||
vector);
|
||||
|
||||
return target_unit_index;
|
||||
}
|
||||
|
||||
@@ -97,9 +97,6 @@ symbols in this file:
|
||||
/* ---------- headers */
|
||||
|
||||
#define REAL_MATH_EXTERNAL_SIGNED_ANGULAR_DIFFERENCE
|
||||
#define REAL_MATH_EXTERNAL_SQUARE_ROOT
|
||||
#define REAL_MATH_EXTERNAL_MAGNITUDE_SQUARED3D
|
||||
#define REAL_MATH_EXTERNAL_MAGNITUDE3D
|
||||
#define REAL_MATH_EXTERNAL_REAL_LOCAL_RANDOM
|
||||
#define REAL_MATH_EXTERNAL_REAL_LOCAL_RANDOM_RANGE
|
||||
#include "interface/first_person_weapons.h"
|
||||
@@ -1120,8 +1117,9 @@ static void first_person_weapon_build_node_matrices(
|
||||
model_get_node_orientations(model, first_person_weapon->node_orientations);
|
||||
}
|
||||
|
||||
firing_animation_index= (first_person_weapon_animations->animations.count>
|
||||
_first_person_weapon_animation_ammunition) ?
|
||||
firing_animation_index= VALID_INDEX(
|
||||
_first_person_weapon_animation_ammunition,
|
||||
first_person_weapon_animations->animations.count) ?
|
||||
animation_graph_animation_index_get(
|
||||
&first_person_weapon_animations->animations)
|
||||
[_first_person_weapon_animation_ammunition].animation_index :
|
||||
@@ -1201,8 +1199,9 @@ static void first_person_weapon_build_node_matrices(
|
||||
first_person_weapon->node_orientations);
|
||||
}
|
||||
|
||||
overlay_animation_index= (first_person_weapon_animations->animations.count>
|
||||
_first_person_weapon_animation_overlays) ?
|
||||
overlay_animation_index= VALID_INDEX(
|
||||
_first_person_weapon_animation_overlays,
|
||||
first_person_weapon_animations->animations.count) ?
|
||||
animation_graph_animation_index_get(
|
||||
&first_person_weapon_animations->animations)
|
||||
[_first_person_weapon_animation_overlays].animation_index :
|
||||
@@ -1479,8 +1478,9 @@ static void first_person_weapon_switch_weapons(
|
||||
struct game_globals_first_person_interface *first_person_interface;
|
||||
|
||||
first_person_weapon->overlay_animation_index= NONE;
|
||||
if (first_person_weapon_animations->animations.count>
|
||||
_first_person_weapon_animation_overlays)
|
||||
if (VALID_INDEX(
|
||||
_first_person_weapon_animation_overlays,
|
||||
first_person_weapon_animations->animations.count))
|
||||
{
|
||||
short overlay_animation_index= animation_graph_animation_index_get(
|
||||
&first_person_weapon_animations->animations)
|
||||
@@ -1758,9 +1758,16 @@ static void first_person_weapon_update(
|
||||
struct animation_graph_first_person_weapon_animations);
|
||||
|
||||
first_person_weapon->moving_animation.frame_index= 0;
|
||||
/* no NULL test (January, and the later first-party build at /Od 0x61fcea): a non-NONE
|
||||
* weapon_index is only committed by first_person_weapon_switch_weapons inside
|
||||
* `if (animation_graph->first_person_weapon_animations.count)` for this same graph. The
|
||||
* new-map reset leaves weapon_index 0 but unit_index NONE, and first_person_weapon_new_unit
|
||||
* runs switch_weapons (which stores NONE first) as soon as it sets unit_index, so the NULL
|
||||
* arm above cannot reach this read. */
|
||||
first_person_weapon->moving_animation.index=
|
||||
first_person_weapon_animations &&
|
||||
first_person_weapon_animations->animations.count>_first_person_weapon_animation_moving ?
|
||||
VALID_INDEX(
|
||||
_first_person_weapon_animation_moving,
|
||||
first_person_weapon_animations->animations.count) ?
|
||||
animation_graph_animation_index_get(
|
||||
&first_person_weapon_animations->animations)
|
||||
[_first_person_weapon_animation_moving].animation_index :
|
||||
@@ -1780,10 +1787,12 @@ static void first_person_weapon_update(
|
||||
struct animation_graph_first_person_weapon_animations);
|
||||
|
||||
first_person_weapon->overcharged_jitter_animation.frame_index= 0.0f;
|
||||
/* no NULL test: the same switch_weapons invariant as the moving animation above
|
||||
* (January and /Od 0x61fd96). */
|
||||
first_person_weapon->overcharged_jitter_animation.index=
|
||||
first_person_weapon_animations &&
|
||||
first_person_weapon_animations->animations.count>
|
||||
_first_person_weapon_animation_overcharged_jitter ?
|
||||
VALID_INDEX(
|
||||
_first_person_weapon_animation_overcharged_jitter,
|
||||
first_person_weapon_animations->animations.count) ?
|
||||
animation_graph_animation_index_get(
|
||||
&first_person_weapon_animations->animations)
|
||||
[_first_person_weapon_animation_overcharged_jitter].animation_index :
|
||||
|
||||
@@ -538,12 +538,15 @@ real_vector3d uncompress_int32_to_real_vector3d(
|
||||
unsigned long compressed)
|
||||
{
|
||||
real_vector3d v;
|
||||
real value = (real)(long)(compressed<<21);
|
||||
|
||||
v.i = ((real)(long)(compressed<<21) * (1.0f/1048576.0f) + 1.0f) * (1.0f/2047.0f);
|
||||
v.i = (value * (1.0f/1048576.0f) + 1.0f) * (1.0f/2047.0f);
|
||||
compressed >>= 11;
|
||||
v.j = ((real)(long)(compressed<<21) * (1.0f/1048576.0f) + 1.0f) * (1.0f/2047.0f);
|
||||
value = (real)(long)(compressed<<21);
|
||||
v.j = (value * (1.0f/1048576.0f) + 1.0f) * (1.0f/2047.0f);
|
||||
compressed >>= 11;
|
||||
v.k = ((real)(long)(compressed<<22) * (1.0f/2097152.0f) + 1.0f) * (1.0f/1023.0f);
|
||||
value = (real)(long)(compressed<<22);
|
||||
v.k = (value * (1.0f/2097152.0f) + 1.0f) * (1.0f/1023.0f);
|
||||
|
||||
return v;
|
||||
}
|
||||
Reference in new issue
Block a user