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:
@@ -20,6 +20,8 @@
|
||||
#include "pop_guard.h" /* CHARID_* — клинок есть и у стража */
|
||||
#include "pop_bg.h" /* POP_YOFF — вертикальное центрирование */
|
||||
#include "_pop_draw.h" /* pop_onscreen_cols */
|
||||
#include "pop_map.h" /* pop_upside — зелье инверсии */
|
||||
#include "pop_vflip.h" /* зеркальные страницы атласов */
|
||||
#include "kid_data.h"
|
||||
|
||||
/* chtab_0 «меч в руке» (add_sword_to_objtable, seg006:1798): клинок —
|
||||
@@ -66,7 +68,14 @@ uint8_t pop_sword_draw(const pop_char_t *ch, const kframe *fr,
|
||||
if (id == 0xFF) return 0;
|
||||
|
||||
simg = (const uint8_t *)atlas_image(&swordp, id);
|
||||
gfx_w0_map(swordp.page);
|
||||
{ /* ПЕРЕВОРОТ: зеркальная копия страницы меча (см. pop_vflip.h) */
|
||||
uint8_t vpg = swordp.page;
|
||||
if (pop_upside) {
|
||||
uint8_t f = pop_vflip_page(vpg);
|
||||
if (f) vpg = f;
|
||||
}
|
||||
gfx_w0_map(vpg);
|
||||
}
|
||||
w = (uint16_t)(simg[0] | ((uint16_t)simg[1] << 8));
|
||||
h = (uint16_t)(simg[2] | ((uint16_t)simg[3] << 8));
|
||||
if (!w || !h) return 0;
|
||||
@@ -74,6 +83,9 @@ uint8_t pop_sword_draw(const pop_char_t *ch, const kframe *fr,
|
||||
flip = (uint8_t)(ch->direction >= 0);
|
||||
bx = obj_x + ((ch->direction < 0) ? -(int)SWORD_DX[sf] : (int)SWORD_DX[sf]);
|
||||
top = obj_y + (int)SWORD_DY[sf] - (int)h + 1;
|
||||
/* Та же формула, что у самого персонажа (pop_cdraw.c): верх кадра
|
||||
* [top, top+h) уезжает в 192 - top - h. */
|
||||
if (pop_upside) top = POP_PLAYFIELD_H - top - (int)h;
|
||||
if (flip) bx -= (int)w;
|
||||
/* Поле комнаты — 192 строки (reset_obj_clip, seg006:0507): клинок
|
||||
* обрезается по нему так же, как сам персонаж. Без этого у падающего
|
||||
|
||||
Reference in New Issue
Block a user