Commit Graph

2 Commits

Author SHA1 Message Date
6840d9df88 Audio overrides: lossless UTF-8 name round-trip (no high-bit collision)
The per-game override store keyed and persisted image names through narrow(), which
masked each character with & 0x7F, and widen() used the full byte -- not a true
inverse. So a non-ASCII exe name was corrupted on reload, and two names differing
only in their high bits collapsed onto the same key (e.g. U+00E9 'é' masked to
'i', so "café.exe" collided with "cafi.exe").

Use real WideCharToMultiByte/MultiByteToWideChar(CP_UTF8) so the round-trip is
lossless for any Unicode name. ASCII names are byte-identical under UTF-8, so
existing override files stay compatible.

audio_overrides_test gains a high-bit-collision case (café vs cafi, built from a
code point to keep the source ASCII) plus a non-ASCII persist/reload check -- both
of which the old 7-bit mask failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 01:52:01 +02:00
32028cb286 Audio: per-game persisted format overrides + auto-learn
Persist audio overrides keyed by game image name (coop_audio_overrides.ini
next to the exe) so a known-bad game is auto-corrected on its next launch:
on attach to a guessed stream the host applies any saved override, and a
manual Override now saves too. A format the hook catches exactly at
IAudioClient::Initialize is auto-saved as that game's override (ground truth);
if it overwrites a differing stored value, a warning is logged. Host-originated
log lines now reach the Log window via IpcServer::host_log (color-coded).

Validated live (harness): a pre-seeded override for coop_tone is auto-applied
over the guess (state -> manual override, 48000/2/16). audio_overrides_test
covers persist/reload/case-insensitive lookup/differing-overwrite. Trim README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:59:11 +02:00