bone_sse_ref: fix M2 black screen — 5 bugs found via asm comparison

Assembly-level comparison of compiled REF against original 0x714260 revealed:

1. Billboard cross product sign error (types 0x10/0x20): computed +cross
   instead of -cross for components 0/1, corrupting billboard bone matrices
2. colorAnimLoop wrong count field: read model_hdr+0x6C instead of +0x64
3. colorAnimLoop wrong gate offset: checked anim_data+0x04 instead of +0x0C
4. Timestamp delta guard inverted: REF guarded on cur_ts!=0 and always
   wrote to this+0x4C; original guards on this+0x4C!=0 first and never
   seeds the field (something else initializes it)
5. Section 5 emitter_ctx cached instead of re-read after matMul call

Also: build REF with x87-only target (subtract SSE/SSE2 features) to
match original's FLD/FMUL/FSTP codegen, and use callVec3SqMag for all
magnitude computations instead of inline SSE math.

Remaining known issues (not yet fixed):
- texAnimLoop alpha track missing crossfade blend
- colorAnimLoop missing crossfade blend
- Missing word animation section (model_hdr+0x6C/0x70)
- Bisect infrastructure and diagnostic code still present (test scaffolding)
This commit is contained in:
MarcelineVQ
2026-03-15 15:04:05 -07:00
parent 89e49cedf2
commit 36ce1a05ce
3 changed files with 144 additions and 46 deletions
+10 -1
View File
@@ -71,11 +71,20 @@ pub fn build(b: *std.Build) void {
.optimize = .ReleaseFast,
}),
});
// REF uses x87-only target to match original game code structure.
// The global target has SSE/SSE2 which generates movss/mulss;
// the original at 0x714260 uses pure x87 (FLD/FMUL/FSTP).
const ref_target = b.resolveTargetQuery(.{
.cpu_arch = .x86,
.os_tag = .windows,
.abi = .msvc,
.cpu_features_sub = std.Target.x86.featureSet(&.{ .sse, .sse2 }),
});
const bone_sse_ref_obj = b.addObject(.{
.name = "bone_sse_ref",
.root_module = b.createModule(.{
.root_source_file = b.path("src/transform44/bone_sse_reference.zig"),
.target = target,
.target = ref_target,
.optimize = .ReleaseFast,
}),
});