Атлас Тени: остановились на 16 цветах (гибридный подбор), блок 0xA0..0xAF

This commit is contained in:
2026-08-20 10:39:40 +03:00
parent acb483897d
commit b6660d7694
+24 -7
View File
@@ -95,9 +95,24 @@ XOR идёт по тому, что УЖЕ на экране, то есть ре
кадр. При 16 цветах разница уже есть: гибрид вдвое срезает «сильно» (257
→ 129), но заметных всё равно две с лишним тысячи.
Решение: **32 цвета, стратегия A** — она проще всех и оставляет ВСЕ частые
цвета пиксельно точными. Если когда-нибудь понадобится ужаться до 16,
брать гибрид C, а не «самые частые».
### Решение: **16 цветов, стратегия C (гибрид 10 + 6)**
Числа выше — про пиксели, а решает глаз. Отрендерил одни и те же кадры в
трёх видах (точный цвет / 32 / 16) и сравнил в увеличении ×3: **отличий
не видно**. Объяснение в самих числах: перцептивно значимых пикселей при
16 цветах 2 275 на 253 кадра, это ~9 пикселей на кадр при ~1 000 видимых,
и они РАССЫПАНЫ по контуру, а не собраны в пятно.
Поэтому берём 16, а не 32: экономим блок палитры (пригодится под будущие
наборы — принцесса, визирь, мышь), а разница неразличима.
**Но стратегия обязана быть гибридной.** При 16 цветах «взять самые
частые» вдвое хуже по грубым промахам (257 пикселей против 129), и это
единственное место, где выбор стратегии виден. Гибрид: 10 самых частых
берём ТОЧНО, оставшиеся 6 слотов отдаём под взвешенные кластеры хвоста.
Если в реальной игре кайма всё же будет резать глаз — переход на 32 цвета
это одна константа в упаковщике и один блок палитры, данные не меняются.
## 4. Палитра: что занято и куда класть
@@ -115,8 +130,9 @@ XOR идёт по тому, что УЖЕ на экране, то есть ре
16. Оговорки: 0xFF в наших атласах это маркер прозрачности, а запись 0
правит `flash_bg`, так что блоки 0x00 и 0xF0 лучше не трогать.
**Берём 0xA0..0xBF** (32 слота) — сразу за стражем, персонажи остаются
сгруппированы.
**Берём 0xA0..0xAF** (16 слотов) — сразу за стражем, персонажи остаются
сгруппированы, а блок 0xB0 остаётся свободным (под 32 цвета Тени, если
понадобится, или под будущие наборы).
Важно: в наших атласах прозрачность кодируется байтом 0xFF, а исходный
индекс 0 в них означает «прозрачно». У Тени **чёрный — настоящий цвет**
@@ -137,12 +153,13 @@ XOR идёт по тому, что УЖЕ на экране, то есть ре
## 6. План работ
**Ш1. Упаковщик** `toolchain/pop_pack_shadow.py`: прогнать оба набора
через алгоритм §1, собрать 32-цветную палитру, выдать
через алгоритм §1, собрать 16-цветную палитру гибридом (10 точных + 6
кластеров хвоста), выдать
`poc/res/shadow/shadow0..N.atl` + `shadow.pal` + `pop_shadow_atlas.h`.
Критерий: предпросмотр PNG совпадает с видом Тени в SDLPoP.
**Ш2. Загрузка**: `pop_shadow_load()` рядом с `pop_kid_load`, палитра в
0xA0..0xBF, и обе страницы дабл-буфера (как `bg_load_tile_pal`).
0xA0..0xAF, и обе страницы дабл-буфера (как `bg_load_tile_pal`).
Грузить ЛЕНИВО — только когда на уровне есть Тень (4, 5, 6, 12), иначе
28 страниц EMM висят зря.