f4b4852d51
roomtest: - QuickSave/QuickLoad (F6/F9): снапшот 'POPQ' v3 в POP.SAV/POP.BAK на HDD, транзакционная запись (POP.NEW -> rename, откат при ошибке), XOR-контрольная сумма payload'а; сериализация всех игровых переменных через W0-примитивы pop_qs_*; pop_qsave_process() на границе кадра вне Char-окон - pop_qsave_restore_room(): полная перезагрузка комнаты после загрузки (карта/края/швы, сброс bake-кэша, перерисовка обеих страниц, инвалидация кэшей спрайтов и HP) - сериализаторы в pop_map/pop_loose_mob/pop_trob/pop_guard_ai (+ восстановление инвариантов: mobs_live, trob_drawn, redraw) - immortal-чит 2 уровня: уровень 2 поглощает только малый урон Kid'а libc/libbgi: - bank_load_file()/bank_save_file() — резидентное файловое I/O в банк, без правила W3 (путь читается до переключения страницы) - gfx_w0_page_prepare(page) — подготовка W0-окна (IRQ/NMI-стабы) одной функцией; atlas_load.c и roomtest переведены на новые примитивы; ручные ISR-стабы удалены sprinter-cc / сборка: - --bank N=FILE.c: автогенерация n_banks (_n_banks_auto.c), ручные const n_banks удалены из тестов - roomtest/app.mk: ресурсы через stamp-файлы (.resource-stamps/) — один запуск упаковщика на группу вместо N под -B; HDD_PACK_ARGS
80 lines
4.2 KiB
C
80 lines
4.2 KiB
C
/*
|
||
* _pop_level.h — ВНУТРЕННИЙ контракт между двумя половинами уровня:
|
||
*
|
||
* pop_level.c — ГОРЯЧАЯ (резидент W1): чтение тайлов/связей/дверных
|
||
* таблиц, живое состояние стражей. Её зовут все банки
|
||
* и кадровый путь главного цикла, местами на каждый тайл.
|
||
* pop_level_cold.c — ХОЛОДНАЯ (банк 8): чтение файла уровня, разбор комнаты,
|
||
* рестарт, потабличные различия уровней. Всё это
|
||
* отрабатывает раз на уровень или раз на комнату, и
|
||
* держать ~1.9 КБ в дефицитном W1 незачем.
|
||
*
|
||
* Общее состояние (страница уровня, копии дверных таблиц, живые стражи)
|
||
* живёт в ГОРЯЧЕЙ половине и объявлено здесь: данные банковых модулей
|
||
* линкуются в общий _DATA (--bank-data мы не включаем), поэтому обе
|
||
* половины видят их как обычные глобалы — в банк уехал только КОД.
|
||
*
|
||
* Заголовок НЕ публичный: снаружи уровень виден только через pop_level.h.
|
||
*/
|
||
#ifndef _POP_LEVEL_H
|
||
#define _POP_LEVEL_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/* Раскладка страницы уровня (Table 6 POP-DAT); подробности — в pop_level.c. */
|
||
#define LVL_DATA_OFF 0x100u /* данные с 0x100; 0x00..0xFF — ISR-стаб */
|
||
#define LVL_PRISTINE_OFF 0x1000u /* эталон foretable для рестарта уровня */
|
||
|
||
#define BP_FG 0u
|
||
#define BP_BG 720u
|
||
#define BP_LINKLOC 1440u
|
||
#define BP_LINKMAP 1696u
|
||
#define BP_LINKS 1952u
|
||
#define BP_GTILE 2119u
|
||
#define BP_GDIR 2143u
|
||
#define BP_GX 2167u
|
||
#define BP_GSEQLO 2191u
|
||
#define BP_GSKILL 2215u
|
||
#define BP_GSEQHI 2239u
|
||
#define BP_GCOLOR 2263u
|
||
#define BP_START 2112u
|
||
#define ROOM_TILES 30u
|
||
#define MIN_SIZE (BP_START + 3u)
|
||
|
||
/* Живое состояние стражей: 6 байт на комнату (порт level.guards_*). */
|
||
#define GS_TILE 0
|
||
#define GS_DIR 1
|
||
#define GS_X 2
|
||
#define GS_SKILL 3
|
||
#define GS_SEQL 4
|
||
#define GS_SEQH 5
|
||
|
||
/* ---- общее состояние (определено в pop_level.c) ---------------------- */
|
||
extern uint8_t pop_lvl_blk; /* EMM-блок страницы уровня */
|
||
extern uint8_t pop_lvl_page; /* её номер (маппится в W0/W3) */
|
||
extern uint8_t pop_lvl_ok; /* уровень загружен */
|
||
extern uint8_t pop_dl1[256]; /* LINKLOC как в файле */
|
||
extern uint8_t pop_dl2[256]; /* LINKMAP, МУТАБЕЛЬНА (таймеры кнопок) */
|
||
extern uint8_t pop_gstate[24 * 6];
|
||
|
||
/* Указатели на тайлы комнаты r (1..24) в W0-пространстве — страницу мапит
|
||
* вызывающий. static-инлайн в обеих половинах: две команды сложения, звать
|
||
* их через границу банка было бы дороже самого вычисления. */
|
||
static const uint8_t *room_fg_ptr(uint8_t r)
|
||
{
|
||
return (const uint8_t *)(LVL_DATA_OFF + BP_FG) + (uint16_t)(r - 1) * ROOM_TILES;
|
||
}
|
||
static const uint8_t *room_bg_ptr(uint8_t r)
|
||
{
|
||
return (const uint8_t *)(LVL_DATA_OFF + BP_BG) + (uint16_t)(r - 1) * ROOM_TILES;
|
||
}
|
||
|
||
/* ПРАВИЛО ОКНА W3. Банковый модуль исполняется ИЗ W3 и сам менять окно
|
||
* не может. Файлы в EMM читает резидентный bank_load_file(), после его
|
||
* возврата холодный код продолжает подготовку страницы через W0. */
|
||
|
||
/* Живая копия стражей из данных уровня (загрузка/рестарт) — в холодной. */
|
||
void pop_gstate_init(void) __banked;
|
||
|
||
#endif /* _POP_LEVEL_H */
|