bone_sse: replace IsParticleBufferEmpty with pure Zig — 1 game call remains (atexit)

This commit is contained in:
MarcelineVQ
2026-03-16 10:45:06 -07:00
parent 1987dc5622
commit 08d1992eaf
2 changed files with 46 additions and 5 deletions
+15 -5
View File
@@ -466,6 +466,20 @@ inline fn crossVec3(ax: f32, ay: f32, az: f32, bx: f32, by: f32, bz: f32) [3]f32
// Output: indices[0] = lower index, [1] = upper index, [2] = interpolation t (float bits)
// =============================================================================
/// IsParticleBufferEmpty (0x7B5F60) — recursive tree check.
/// Returns true if any node in the tree has active particles (this->0x64 != 0).
fn isParticleBufferNotEmpty(ptr: u32) bool {
if (ru32(ptr + 0x64) != 0) return true;
const count = ru32(ptr + 0x7C);
if (count == 0) return false;
const children = ptr + 0x80;
var i: u32 = 0;
while (i < count) : (i += 1) {
if (isParticleBufferNotEmpty(ru32(children + i * 4))) return true;
}
return false;
}
/// findInterpIdx: temporal-coherence keyframe search.
/// Reimplementation of game function at 0x713D50 (334 bytes).
/// Assembly-verified against t44_helpers_asm.txt.
@@ -2252,11 +2266,7 @@ fn additionalParticleLoops(this: u32, model_hdr: u32) void {
if (emitter_active != 0) {
buf_active = 1;
} else {
// Call IsParticleBufferEmpty (0x7B5F60)
// Assembly: MOV ECX,[EBP-0x10]; CALL 0x7B5F60
// __thiscall(ECX=ptr), plain RET, returns 0 or 1 in EAX
const isEmptyFn: *const fn (u32) callconv(.{ .x86_fastcall = .{} }) u32 = @ptrFromInt(0x7B5F60);
if (isEmptyFn(local_14) != 0) {
if (isParticleBufferNotEmpty(local_14)) {
buf_active = 1;
}
}
@@ -775,3 +775,34 @@ OpenJDK 64-Bit Server VM (build 21.0.10+7, mixed mode)
0x00454A0C FSTP ST0
0x00454A0E RET << RET
=== IsParticleBufferEmpty (0x007B5F60, 59 bytes) ===
0x007B5F60 8B 41 64 MOV EAX,dword ptr [ECX + 0x64]
0x007B5F63 85 C0 TEST EAX,EAX
0x007B5F65 53 PUSH EBX
0x007B5F66 56 PUSH ESI
0x007B5F67 57 PUSH EDI
0x007B5F68 74 09 JZ 0x007b5f73
0x007B5F6A 5F POP EDI
0x007B5F6B 5E POP ESI
0x007B5F6C B8 01 00 00 00 MOV EAX,0x1
0x007B5F71 5B POP EBX
0x007B5F72 C3 RET << RET
0x007B5F73 8B 79 7C MOV EDI,dword ptr [ECX + 0x7c]
0x007B5F76 33 F6 XOR ESI,ESI
0x007B5F78 85 FF TEST EDI,EDI
0x007B5F7A 76 19 JBE 0x007b5f95
0x007B5F7C 8D 99 80 00 00 00 LEA EBX,[ECX + 0x80]
0x007B5F82 8B 0B MOV ECX,dword ptr [EBX]
0x007B5F84 E8 D7 FF FF FF CALL 0x007b5f60 << CALL
0x007B5F89 85 C0 TEST EAX,EAX
0x007B5F8B 75 DD JNZ 0x007b5f6a
0x007B5F8D 46 INC ESI
0x007B5F8E 83 C3 04 ADD EBX,0x4
0x007B5F91 3B F7 CMP ESI,EDI
0x007B5F93 72 ED JC 0x007b5f82
0x007B5F95 5F POP EDI
0x007B5F96 5E POP ESI
0x007B5F97 33 C0 XOR EAX,EAX
0x007B5F99 5B POP EBX
0x007B5F9A C3 RET << RET