diff --git a/applications/PoP/roomtest/TASKS_OPEN.md b/applications/PoP/roomtest/TASKS_OPEN.md index b08eef1..a67c073 100644 --- a/applications/PoP/roomtest/TASKS_OPEN.md +++ b/applications/PoP/roomtest/TASKS_OPEN.md @@ -47,6 +47,55 @@ чомпера комнаты 4, а стражи там сильнее прежних (комната 5 — skill **7**, это максимум из встречавшихся; 12/22/24 — skill 2/3/3). + +### L9-INVERT. Зелье ПЕРЕВОРОТА (уровень 9, комнаты 7 и 10) + +Единственное новое на уровнях 9-11: зелья типа 4 на `(1,7)` комнаты 7 и +`(0,4)` комнаты 10 (сверено по `res2009.bin`). Уровни 10 и 11 не приносят ни +тайлов, ни спецсобытий — только дворцовый тайлсет (есть) и стражи skill 3-4. + +Механика оригинала (seg000:15E9 `toggle_upside`, seg006:1886): +`upside_down = ~upside_down`, снимается смертью Кида (seg000:1224, при +`alive >= 0`) и стартом уровня (seg003:38/188); второе зелье переворачивает +обратно. Управление НЕ инвертируется. Переворот у оригинала — чисто вывод: +`flip_screen(offscreen)` перед копированием прямоугольников на экран и обратно +после (seg000:939/946); полоса HP рисуется прямо на экран (y = 194) и НЕ +переворачивается. + +**Приём оригинала нам не подходит:** мы рисуем инкрементально прямо в +видеостраницу (heal + спрайты), готового offscreen-кадра нет, и «перевернуть +буфер на вывод» означало бы полный кадровый блит 61 440 Б. Значит +переворачиваем НА ОТРИСОВКЕ: `y' = POP_YOFF + POP_PLAYFIELD_H - (y - POP_YOFF) - h` +плюс вертикальное зеркало самого спрайта. + +Зеркало по вертикали стоит по-разному в зависимости от раскладки спрайта: + +- **row-major** (весь слой фона: тайлы, кладка, факелы, зелья, обломки, + двери) — бесплатно: внешний цикл идёт по строкам источника снизу вверх, сама + строка копируется вперёд. В libbgi такого варианта СЕЙЧАС НЕТ (флип есть + только у `gfx_blit_cols*`, и он горизонтальный) — нужна пара + `gfx_blit*_vflip`; +- **column-major** (Кид, стражи, мышь, меч — 34 атласа, 228 563 Б) — реверс + ВНУТРИ колонки, а accel копирует блок только вперёд. Нужны перевёрнутые + копии в отдельных EMM-страницах (реверс через стек `pop`/`push`, ~10 тактов + на байт). + +**Когда делать копии — решать при реализации,** варианты в порядке +предпочтения: + +1. **ленивый постраничный кэш**: страница атласа (8 кадров, 3-10 КБ) + переворачивается при первом обращении в перевёрнутом режиме — ~0.2-0.4 + растрового кадра на страницу, размазано по времени; реально нужны 5-10 + страниц из 34, и если зелье не выпито, не тратится ничего; +2. на входе в уровень, где в данных есть зелье типа 4 (скан `bg` уровня) — + вся пачка разом, ~5-6 млн тактов ≈ 0.3 с, пауза прячется в загрузку; +3. офлайн в `pop_pack_kid.py`/`pop_pack_guard.py` — рантайм ноль, но +228 КБ + на диске и +34 страницы всегда, а на дискете это заметная загрузка. + +Не забыть при реализации: зеркалить надо и heal-прямоугольники, и футпринт +fore-слоя, и клип (`clip_char`), и брызги; полоса HP и лейбл комнаты остаются +как есть (они вне поля 192). + ### MEM-COLD2. Второй шаг разгрузки резидента