QuickSave F6/F9 в roomtest; bank_load_file/bank_save_file/gfx_w0_page_prepare; sprinter-cc: авто n_banks
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
This commit is contained in:
@@ -18,16 +18,8 @@
|
||||
#include "_pop_level.h"
|
||||
#include "pop_geom.h" /* pop_x_bump / FIRST_ONSCREEN_COLUMN — pos_guards */
|
||||
|
||||
/* ISR-стаб W0-страницы (тот же приём, что atlas_load): при прерывании с
|
||||
* замапленной в W0 страницей CPU прыгает на 0x0038 → там обязан быть JP на
|
||||
* _gfx_w0_isr (восстановит окно). Символ внутренний для libbgi, но
|
||||
* стабильный — линкер тянет его из bgi256.lib (графика уже подключена). */
|
||||
extern void _gfx_w0_isr(void);
|
||||
|
||||
/* ЧТЕНИЕ ФАЙЛА уровня живёт в РЕЗИДЕНТЕ (pop_level.c, pop_level_read_file):
|
||||
* оно маппит страницу в W3 на время read(), а этот модуль сам лежит в W3 —
|
||||
* переключив окно, он вырезал бы из-под себя собственный код (проверено:
|
||||
* первый же вызов улетал в halt по мусору). Правило записано в _pop_level.h. */
|
||||
/* Низкоуровневое чтение через W3 выполняет резидентный bank_load_file();
|
||||
* остальная одноразовая подготовка уровня безопасно остаётся в банке 8. */
|
||||
|
||||
void pop_level_free(void) __banked
|
||||
{
|
||||
@@ -58,6 +50,31 @@ int8_t pop_level_guard_type(uint8_t n) __banked { return n < 16 ? tbl_guard_typ
|
||||
uint8_t pop_level_tileset(uint8_t n) __banked { return n < 16 ? tbl_level_type[n] : 0; }
|
||||
uint8_t pop_level_type(void) __banked { return tbl_level_type[pop_current_level & 15]; }
|
||||
|
||||
static int level_read_file(const char *path)
|
||||
{
|
||||
uint8_t blk, page;
|
||||
uint16_t i;
|
||||
int n;
|
||||
blk=mem_alloc_pages(1);
|
||||
if (!blk) return -1;
|
||||
page=mem_get_page(blk,0);
|
||||
n=bank_load_file(page,LVL_DATA_OFF,path,16384-LVL_DATA_OFF);
|
||||
if (n < (int)MIN_SIZE) { mem_free_block(blk); return -1; }
|
||||
gfx_w0_page_prepare(page);
|
||||
gfx_w0_map(page);
|
||||
for (i=0; i<256; i++) {
|
||||
pop_dl1[i]=((const uint8_t *)LVL_DATA_OFF)[BP_LINKLOC+i];
|
||||
pop_dl2[i]=((const uint8_t *)LVL_DATA_OFF)[BP_LINKMAP+i];
|
||||
}
|
||||
for (i=0; i<24u*ROOM_TILES; i++)
|
||||
((uint8_t *)LVL_PRISTINE_OFF)[i]=
|
||||
((const uint8_t *)(LVL_DATA_OFF+BP_FG))[i];
|
||||
gfx_w0_unmap();
|
||||
pop_lvl_blk=blk; pop_lvl_page=page; pop_lvl_ok=1;
|
||||
pop_gstate_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pop_level_load_num(uint8_t n) __banked
|
||||
{
|
||||
/* Имена патчим на месте, а не через sprintf: printf-семейство тянет в
|
||||
@@ -71,10 +88,10 @@ int pop_level_load_num(uint8_t n) __banked
|
||||
pri[13] = alt[9] = (char)('0' + n % 10);
|
||||
|
||||
/* Старую страницу отпускаем ТОЛЬКО после успешной загрузки новой:
|
||||
* pop_level_read_file сам аллоцирует страницу, и если файла нет — остаёмся
|
||||
* level_read_file сам аллоцирует страницу, и если файла нет — остаёмся
|
||||
* на текущем уровне вместо падения в пустой уровень. */
|
||||
pop_lvl_ok = 0; /* чтобы level_load_path не мешался */
|
||||
if (pop_level_read_file(pri) != 0 && pop_level_read_file(alt) != 0) {
|
||||
if (level_read_file(pri) != 0 && level_read_file(alt) != 0) {
|
||||
pop_lvl_blk = saved_blk; pop_lvl_page = saved_page; pop_lvl_ok = saved_ok;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user