/* * pop_bg.h — отрисовка СТАТИЧЕСКОГО фона комнаты PoP композицией слоёв * (порт seg008.c draw_tile/wall_pattern, Шаг 3). Рисует прямо в текущую * страницу (banked GFX_BANK_TRANSPARENT — в видео-ОЗУ + теневую копию, * 0xFF прозрачен), ОДИН раз при входе в комнату. * * Данные: getimage-спрайты в атласах pop_env0..4/pop_wall/pop_fore * (toolchain/pop_pack_bg.py), палитра pop_bg.pal. Прямая адресация * id: env[id>>5] idx id&31, wall idx=id, fore idx=id — ноль remap-таблиц. */ #ifndef POP_BG_H #define POP_BG_H #include /* ---- Вертикальный layout (PoP-экран 320×200 в нашем 320×256) --------- * * Игровой экран 200px центрируем по высоте: сдвиг всего рисунка вниз на * POP_YOFF = (256-200)/2 = 28px (чёрные борта сверху/снизу). Внутри 200px * верхние POP_PLAYFIELD_H = 192 — поле тайлов/спрайтов (комната = 3 ряда), * нижние 8 — статус-полоса (жизни/сообщения): тайлы/спрайты туда НЕ лезут. * Сдвиг применяется на границе примитивов (blit/heal) — логика рисования * остаётся в «room-space» y=0..191. */ #define POP_YOFF 28 #define POP_PLAYFIELD_H 192 /* Экранный y нижней границы поля (ниже — статус-полоса + борт → клип). */ #define POP_CLIP_BOTTOM (POP_YOFF + POP_PLAYFIELD_H) /* Загрузить 7 атласов фона. Звать ДО initgraph (как poc.c — atlas_load * трогает W3; проверенный порядок). Палитру pop_bg.pal грузит ПРИЛОЖЕНИЕ * после initgraph (gfx_pal_fload). 0 — OK, -1 — ошибка. */ int pop_bg_load(void); /* Освободить EMM-страницы атласов. */ void pop_bg_free(void); /* Нарисовать комнату: fg[30]/bg[30] — foretable-коды/backtable-модификаторы * (по строкам, row*10+col). lcol_fg/lcol_bg — 3 тайла правого столбца * ЛЕВОЙ соседней комнаты (для границы, напр. решётки ворот), или 0 — * тогда левая кромка = стена. room_num — номер комнаты (зерно стен). */ void pop_room_draw(uint8_t room_num, const uint8_t *fg, const uint8_t *bg, const uint8_t *lcol_fg, const uint8_t *lcol_bg); /* Задать ряд 0 комнаты СНИЗУ (fg-коды, 10 шт.) — для draw_tile_topright, * когда тайл нижнего ряда стал empty (после падения loose): «стена вниз» * рисуется по коду room_B(0, col-1). 0 — нет комнаты снизу. */ void pop_room_set_below(const uint8_t *below_row0_fg); /* Перерисовать передний слой (fore) тайлов футпринта Kid ПОВЕРХ него — * звать ПОСЛЕ kid_draw. obj_x — ЛОГИЧЕСКАЯ X кадра (до ×8/7), obj_y — низ * спрайта, w/h — размер кадра, dir — направление Kid (<0 влево). Метрики * берутся из pop_kid (kid_fp_*). См. redraw_at_char/set_char_collision. */ void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, int8_t dir, uint8_t frame, uint8_t action); /* Loose floors — динамическая отрисовка (состояние pop_loose_modif в * pop_map). Звать на ТЕКУЩЕЙ (back) странице из pop_loose_tick. * shake_draw — дрожащий кадр (heal+SPRITE); bake_empty — запечь пустоту * после падения (NORMAL, в ОЗУ-копию). */ void pop_loose_shake_draw(int row, int col); void pop_loose_bake_empty(int row, int col); /* Падающий кусок loose (mob, seg007 move_loose): спавн при падении тайла * (row,col) и покадровое продвижение+отрисовка на back-странице. tick * зовётся каждый кадр (внутри pop_loose_tick); клип низа делает clip. */ void pop_loose_mob_spawn(int row, int col); void pop_loose_mob_tick(void); /* Детектор выхода спрайта за поле: если спрайт [x,w] с ЭКРАННЫМ верхом * sy_top и высотой h заходит ниже поля (статус-полоса/борт) или выше * верхнего борта — взводит внутренний флаг «борта грязные» на 2 кадра. * Звать СРАЗУ после блита падающего объекта (Kid/кусок). */ void pop_clip_sprite(int x, int w, int sy_top, int h); /* Почистить борта (верхний + статус-полоса/нижний) — но ТОЛЬКО в кадрах, * где кто-то реально вышел за поле (гейт по флагу от pop_clip_sprite): * даром в покое, O(1) при падении (не зависит от числа спрайтов). Звать * КАЖДЫЙ кадр ПОСЛЕ kid_draw+fore на back-странице. */ void pop_room_clip_borders(void); #endif