diff --git a/context/wintesla-port.md b/context/wintesla-port.md index b3cd593..eb28f73 100644 --- a/context/wintesla-port.md +++ b/context/wintesla-port.md @@ -55,13 +55,47 @@ on top of it. Full detail: `docs/PROGRESS_LOG.md §5b, §8`. the mech + all subsystems binds to a real indicator, and the alarms are already `SetLevel`'d by the sims, so generator/condenser/reservoir/ammo state sounds fire on transition. **Still inert** (read 0, silent, non-crashing — no modeled backing member in the size-locked layouts, a polish follow-up): - `ReportLeak` (Logical), `ConfigureActivePress` (Integer), `Torso.MotionState` (Enum), - `Torso.SpeedOfTorsoHorizontal` + `ControlsMapper.TargetRangeExponent` (Scalar). The **bring-up guards** + `ReportLeak` (Logical), `Torso.MotionState` (Enum), `Torso.SpeedOfTorsoHorizontal` (Scalar). + NOW REAL (fidelity Phase 1, commit fc7f311): `ConfigureActivePress` published at the **MechSubsystem + BASE** (binary attr id 2, descriptor @0x50de5c → member @+0x110 — the field previously misnamed + `vitalSubsystemIndex`; idle −1, driven 0/−1 by `MechWeapon::ConfigureMappablesMessageHandler`), + `AmmoBin.FireCountdownStarted` → `cookOffArmed`@0x18C, `L4MechControlsMapper.TargetRangeExponent` → + `targetRangeExponent`@0x1a4. The **bring-up guards** [T3, self-clearing] stay: a NULL subsystem attr → inert pad (was a fatal `Fail`); an `AudioStateWatcher` on an unconstructed indicator (chain@+0x18 null/0xCDCDCDCD) → skip. Both pass automatically once a subsystem is built. Diagnostics: `BT_AUDIO_LOG` (chain + skips/redirects), `BT_ATTRBIND_LOG` (every - attr bind), `BT_AUDIO_TEST` (proof-of-life buffer0). NOTE: `AUDIO1/2.RES` were SF2 v1.0 (16-byte shdr; - sample rate assumed 22050 Hz — may need tuning if pitch is off). + attr bind), `BT_AUDIO_TEST` (proof-of-life buffer0). +- **Audio FIDELITY pass (2026-07-16, commits fc7f311 + 691e885; the full audit ledger is + `docs/AUDIO_FIDELITY.md`, 37 findings).** Settled facts [T1 unless noted]: + - **Patch numbering = SF2 `wPreset`.** Any tooling must key presets on `wPreset`, never on phdr + record order. `AUDIO1/2.RES` are SF2 **v1.0** (16-byte shdr, NO name/rate/pitch field); pitch + metadata rides generators: 55 = SBK samplePitch (`root*100+cents`, on every zone), 58 = + overridingRootKey, 51/52 = coarse/fineTune. **EMU8000 v1 base rate = 44100 Hz** → a zone's true + data rate is baked into its WAV: `rate = round(44100·2^(((6000−rootCents)+tune)/1200))` + (`tools/sf2extract.py`); the engine's note-60 pitch model (`BTNotePitchFactor`) then reproduces + original playback at every note. SBK `initialAttenuation`(48) is **INVERTED** (127 = full + volume; 0.375 dB/step [T3 exact curve], baked into the PCM). + - **Full-zone table**: 603 zones / 241 presets in `audiopresets.cpp`; the authored MIDI note + SELECTS zones by keyRange in `SetupPatch/PlayNote` (key-splits: Loaded/Jam family low-36 + clunk vs high-84 blip; Warnings01 8-way klaxon split), layers attach together, + `MAX_PRESET_SAMPLES=25` (AllExplosion). Authored loop REGIONS apply via `AL_SOFT_loop_points`; + authored `releaseVolEnv` (1.1–3.9 s on ~20 looping presets) fades on Stop + (`PRESET_serviceReleaseFades`, serviced from `AudioHead::Execute`). + - **Distance/volume/doppler**: OpenAL distance model is `AL_NONE` — the AUTHORED + `GetDistanceVolumeScale()` curve multiplies in `CalculateSourceVolumeScale` (Dynamic3D + + Static3D); per-source `AL_GAIN = volume_scale²` (GM CC7 squared law); `alDopplerFactor(0)` — + the authored `GetDopplerCents()` (AUDIO.INI model, consumer decomp part_008.c:7466) adds into + the Dynamic3D pitch chain. + - **Audio clock**: `FUN_0044e19c` is `ApplicationManager::GetFrameRate` — the original audio + "frames" were SYSTEM CLOCK TICKS; `MakeAudioRenderer` calibrates at + `SystemClock::GetTicksPerSecond()` (fallback 1000), never the old garbage + `divisionParameters+0x10` read. + - **Published `localVelocity` smoothing is authentic** [T1]: `Mech::Execute` (FUN_004ab430) runs + the localVelocity components through `AverageOf` running-average filters + (part_012.c:15169-15179); the port's ~0.25 s exponential filter in `mech4.cpp` reconstructs it. + - Remaining (per `docs/AUDIO_FIDELITY.md` §5): EFX (authored low-pass fc/Q, reverb), F5 footstep + contact level, F19 remove the mech2.cpp step broadcast, F6/F7 ReportLeak + missile-lock attrs, + Torso attrs, F23 AnimationState numbering audit. - **L4 HAL on Windows + the VS build system: DONE.** [T1] - **Red Planet game logic: COMPLETE & buildable** — `VTV/VTVMPPR/WEAPSYS/...`. RP is at/near playable. [T1] - **Multiplayer: the DOS `NETNUB` driver is already replaced by a ~3.5k-line WinSock2 TCP diff --git a/game/reconstructed/mech4.cpp b/game/reconstructed/mech4.cpp index 227158a..c84b190 100644 --- a/game/reconstructed/mech4.cpp +++ b/game/reconstructed/mech4.cpp @@ -3647,6 +3647,10 @@ void // Start/Stop-flapped the engine ambience on every footfall (heard as a // static tick per step). ~0.25s exponential filter kills the stride // ripple while tracking real speed changes within a couple of strides. + // AUTHENTIC [T1]: the binary's Mech::Execute (FUN_004ab430) runs the + // localVelocity components through AverageOf running-average filters + // (part_012.c:15169-15179) -- the original smoothed the published + // velocity the same way; this filter reconstructs that stage. { Scalar alpha = dt / (dt + 0.25f); fwdSpeedFiltered += alpha * (fwdSpeed - fwdSpeedFiltered);