dm2-graphics: Ent1::find ignores cls5 language — 545 duplicate tuples on dos-en, last-wins returns arbitrary variant #189
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Ent1::findresolves records through a(cls1, cls2, cls3, cls4) → indexHashMap with last-wins semantics, and its docstring claims duplicate tuples are "not observed in DOS/Mac fixtures" (crates/dm2-graphics/src/ent1.rs~191).They are observed, at scale: dos-en has 545 duplicate 4-tuples (dos-de/dos-fr similar), Amiga EU has 550. Breakdown on dos-en: 540 are dtText language variants (distinguished by
cls5), 4 are images — the charsheet records(0x07, 0x00, 0x01, {0x00, 0x06, 0x07, 0x08})exist in three language variants each (cls5 carries the language tag, e.g. 0x18/0x38/0x48), pointing at different payloads — plus 1 duplicated inline record (same value, harmless).The engine resolves this by filtering at table-build time: a record is admitted into the runtime lookup table only when
cls5 & 0xf0is 0 or equals the configured language tag ([SKPROJECT] v5/bgdat.cpp:335-342,DM2_dballoc_3e74_2162, used as the admission predicate byDM2_BUILD_GDAT_ENTRY_DATAatbgdat.cpp:675), then binary-searches (cls2, cls4) within (cls1, cls3) buckets (v5/skgdtqdb.cpp:70-103). So the 4-tuple is unique per language view, never globally.Consequences in the crate:
Archive::find/Archive::decode_imageon a duplicated tuple silently return whichever record parsed last — e.g.decode_image(0x07, 0x00, cls4)on dos-en returns one arbitrary language's charsheet image.GraphicFileEntry::cls5docstring calls the field "vestigial in the engine runtime" for images — wrong: it decides which records exist in the engine's lookup table at all.iter_texts,iter_image_with_palette) are unaffected (they yield every record), and the champion path is safe (its records are cls5 = 0 and unique).Fix direction
Either add a language-aware lookup (
find_in_language(cls1..cls4, lang)mirroring the engine'scls5 & 0xf0 ∈ {0, lang}rule, withfinddocumented as "language-agnostic, ambiguous on 545 dos-en tuples"), or makeby_tuplestore all matches and letfindtake/require a language filter. Correct the two docstrings either way.Probe:
scratch/probe_gfx.py(gitignored).Fixed by #208 (merged into
main).