755190674c
Спрайты персонажей хранятся column-major (ради бесплатного H-флипа), а вертикальное зеркало у такой раскладки — разворот байтов ВНУТРИ колонки, чего accel не умеет. Поэтому pop_vflip.c готовит зеркальные КОПИИ страниц атласов: копия побайтово повторяет раскладку .atl (заголовок, каталог, смещения лент), развёрнуты только пиксели — значит вызывающему достаточно подменить номер страницы, которую он мапит в W0. * Кэш ленивый (страница зеркалится при первом обращении в перевёрнутом виде) и живёт до смены уровня — зелье переключает состояние туда-обратно, перезеркаливать по 16 КБ на каждый переворот незачем. EMM хватает: 34 страницы из ~215 свободных. * pop_cdraw/pop_kdraw: страница + позиция (top = 191 - obj_y для персонажа, 192 - top - h для клинка). «Пропустить skip строк сверху» у зеркальной ленты = «срезать снизу» у оригинала, поэтому клипы считаются как обычно. * Модуль резидентный: он маппит W3 (приёмник копии) — банку так нельзя. * pop_vflip_reset на смене уровня: копии сделаны из старых страниц. Проверено в MAME: чит U переворачивает всё разом, Кид и факелы вверх ногами, полоса HP на месте, бег без следов на фоне (heal бьёт в те же координаты). ОСТАЁТСЯ (L9-CLIPCHAR): clip_char в перевороте должен резать снизу, а не сверху — пока при pop_upside не режем вовсе. Тени/брызг это не касается.
38 lines
2.5 KiB
C
38 lines
2.5 KiB
C
/*
|
|
* pop_vflip.h — зеркальные по вертикали копии страниц атласов персонажей
|
|
* (зелье инверсии, уровень 9). Реализация и «почему постранично» —
|
|
* в pop_vflip.c.
|
|
*
|
|
* Кому нужно. Фон и все row-major спрайты переворачиваются даром (порядок
|
|
* строк = знак страйда, gfx_blit_*_vflip), а персонажи хранятся колонками —
|
|
* им нужен заранее развёрнутый набор пикселей. Отсюда правило вызывающего:
|
|
*
|
|
* страница = pop_upside ? pop_vflip_page(a->page) : a->page;
|
|
*
|
|
* и больше НИЧЕГО не меняется: смещения лент, размеры кадров, флип по
|
|
* горизонтали (знак страйда) остаются как были.
|
|
*
|
|
* Почему кэш не сбрасывается на каждом перевороте: зелье инверсии в
|
|
* оригинале переключает состояние туда-обратно (второе зелье, смерть Кида —
|
|
* seg000:1224), и держать 34 страницы EMM дешевле, чем перезеркаливать по
|
|
* 16 КБ при каждом переключении. Бюджет EMM это позволяет: свободно ~215
|
|
* страниц из 256 (memory sprinter_emm_budget). Освобождаем на смене
|
|
* уровня — вместе с самими атласами.
|
|
*/
|
|
#ifndef POP_VFLIP_H
|
|
#define POP_VFLIP_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/* Номер страницы с ВЕРТИКАЛЬНО ЗЕРКАЛЬНОЙ копией атласа src. Первый вызов
|
|
* для страницы делает копию (~16 КБ побайтно — ощутимо, но однократно),
|
|
* дальше отдаёт из кэша. 0 — не хватило EMM-страниц (вызывающий должен
|
|
* нарисовать обычным атласом: лучше неперевёрнутый кадр, чем пустота). */
|
|
uint8_t pop_vflip_page(uint8_t src);
|
|
|
|
/* Освободить все копии (смена уровня). Атласы к этому моменту тоже
|
|
* перезагружаются, и старые копии стали бы мусором. */
|
|
void pop_vflip_reset(void);
|
|
|
|
#endif /* POP_VFLIP_H */
|