L9-INVERT II.4: персонажи рисуются перевёрнутыми (зеркальные страницы атласов)
Спрайты персонажей хранятся 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 не режем вовсе. Тени/брызг это не касается.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 */
|
||||
Reference in New Issue
Block a user