Add MPQ archive file cache: skip redundant chain walks on repeat file opens

Hook File_FindInArchive (0x6549a0) with a direct-mapped filename-verified
cache. First open does the full MPQ chain walk (~60K cycles), subsequent
opens hit the cache (~300 cycles). 80% hit rate in gameplay testing.

Cache design: 16384 entries, FNV-1a hash for slot index, raw filename
comparison (128 bytes) for collision safety. Stores outer_archive,
inner_archive, and block_entry per file. Negative cache for not-found files.
Refcount at +0x38 incremented on all output archives to match original
File_FindInArchive behavior (verified via Ghidra: FindAndIncrementResourceReference
at 0x650780, DecrementResourceReference at 0x6507e0).

Also: default build changed to ReleaseFast (works around Zig fastcall inreg
bug in Debug mode), logging gate changed to != ReleaseSmall, file cache
integrated as transform44 sub-module with A/B comparison timing in readout.
This commit is contained in:
MarcelineVQ
2026-03-13 23:05:38 -07:00
parent bb8a6ef8a6
commit 55735d7b9e
6 changed files with 295 additions and 47 deletions
+3 -2
View File
@@ -1,4 +1,5 @@
//! Debug logging - compiles out entirely in non-Debug builds.
//! Logging - available in Debug, ReleaseSafe, and ReleaseFast builds.
//! Compiles out entirely in ReleaseSmall.
//!
//! Per-module Logger with optional file output and per-call destination routing.
//! Log files are created lazily on first write -- modules that never log to
@@ -28,7 +29,7 @@
const std = @import("std");
const builtin = @import("builtin");
const debug = builtin.mode == .Debug;
const debug = builtin.mode != .ReleaseSmall;
const WINAPI = std.builtin.CallingConvention.winapi;