Files
Sprinter-SDCC/applications/PoP/roomtest/_pop_bg.h
T
snark13 14190f0210 MEM-BANK2 шаг 3: холодная половина слоя фона в банк 7 (90.4% -> 35.8%)
pop_bg.c разрезан по ЧАСТОТЕ вызова, а не по размеру:

  pop_bg.c   (банк 2)  горячее  fore-проход, оверлеи, кладка, клип
  pop_room.c (банк 7)  холодное draw_tile, точечные перерисовки, mob,
                                загрузка атласов

Стык — три тонкие __banked-обёртки (wall_pattern, wall_pattern_reset,
draw_gate_back): тела остаются непомеченными, поэтому горячий fore-проход,
зовущий wall_pattern до девяти раз за кадр, платит ноль, а трамплин
достаётся только холодному пути — ~40 вызовов на вход в комнату, 26 000
тактов = 0.06 кадра РАЗОВО.  Общее состояние (pop_loose_modif, pop_ceil_modif,
obj_row/obj_col) писучее, лежит в _DATA/W2 и видно обеим половинам.

Заодно удалена мёртвая potion_bubble (169 Б).

Грабля: n_banks объявляет само приложение (roomtest.c), а не sprinter-cc.
Восьмой банк без правки константы линкуется молча, _bank_pages[7] остаётся
0xFF, и программа встаёт намертво до первого кадра.  Диагноз снят дампом
_bank_pages из MAME.

Замер (ALLOCS=3000): BANK2 11 942 -> 5 872, BANK7 6 035; _CODE и куча не
тронуты (22 556 / 4 301).

Проверено: tests-host зелёные; построчная сверка pop_bg.c+pop_room.c против
дорефакторного pop_bg.c — ни одной строки логики не пропало; 8 комнат в MAME
до/после совпали попиксельно по активному экрану (различия только в фазе
анимации факелов и кадре Кида); живой прогон с переходами комнат, боем и
воротами сверен контрольным запуском HEAD-бинаря.

DRAW-COST поднят в приоритете: замер пользователя (ур.1 комната 3, страж
убит, Кид стоит) — синяя 80%, зелёная 20%, циан 110%, итого ~210 %
кадрового периода В ПОКОЕ.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 16:28:02 +03:00

50 lines
3.5 KiB
C

/*
* _pop_bg.h — ВНУТРЕННИЙ контракт между двумя половинами слоя фона.
* Публичный API слоя — pop_bg.h; общие листья (резидент) — pop_tile.h.
*
* Слой фона разрезан на два банка:
* pop_bg.c (банк 2) — ГОРЯЧАЯ половина: fore-проход поверх персонажей,
* оверлеи, клип. Работает каждый кадр.
* pop_room.c (банк 7) — ХОЛОДНАЯ: полная отрисовка комнаты (draw_tile),
* точечные перерисовки тайлов, падающие плиты,
* загрузка атласов. Раз на комнату/событие.
*
* Резать пришлось потому, что банк 2 упирался в 16 КБ страницы (90.4 % до
* разгрузки), а чомперам и остальным ловушкам уровня 3 место нужно. Граница
* проведена по частоте вызова: холодная половина платит трамплин (~654 такта)
* за каждый вызов сюда, и на входе в комнату таких вызовов ~40 — 26 000
* тактов, шестая часть кадрового бюджета РАЗОВО. Для горячего пути цена
* нулевая: он зовёт свои функции прямо, а общие листья — из резидента.
*
* Что осталось в банке 2 и вынесено сюда обёртками: кладка стены
* (wall_pattern — её зовёт и fore-проход каждый кадр) и решётка ворот
* соседней комнаты (draw_gate_back — её зовёт шовная окклюзия). Обратных
* зависимостей (горячая половина → холодная) нет вовсе.
*/
#ifndef _POP_BG_H
#define _POP_BG_H
#include <stdint.h>
/* Состояние дрожащих плит — живёт в pop_map, читают обе половины. */
extern uint8_t pop_loose_modif[30];
extern uint8_t pop_ceil_modif[10]; /* плита-потолок: loose ряда 2 комнаты сверху */
/* Видимая высота полосы кладки у потолка (room-space y 0..7): её печёт
* холодная половина, а поверх персонажа кладёт горячая. */
#define CEIL_BAND_H 8
/* Тайл ОБЪЕКТА активного персонажа (set_objtile_at_char, seg006:1833) — в
* момент обработки этого тайла спрайт попадает в midtable. Задаёт горячая
* половина (pop_fore_over_char), читают other_overlay_tile (там же) и
* порядок «плита vs Kid» в mob_tick_one (холодная). Писучие данные банка
* лежат в _DATA/W2 и видны из любого банка — см. sdcc_banked_call_rules. */
extern int8_t pop_bg_obj_col, pop_bg_obj_row;
/* ---- Точки входа ГОРЯЧЕЙ половины для холодной (через трамплин) ------- */
void pop_wall_pattern_b(int row, int col, int which_part) __banked;
void pop_wall_pattern_reset_b(void) __banked;
void pop_gate_back_b(uint8_t modl, int xh, int dby, int dmy) __banked;
#endif