5b6664ffce
Замеры в MAME (такты Z80, кадр = 430 000) решили вопрос однозначно: загрузка 28 атласов Кида с HDD — 27 160 092 такта (1.26 с), 970 003 на страницу; разворот ОДНОЙ страницы на месте — 12 645 582 такта (0.59 с), т.е. 771 такт/байт. Даже идеальный вариант (копия accel'ом ~0.25 кадра + asm-реверс ~2.2 кадра) дал бы ~1.05 млн на страницу — то есть в лучшем случае сравнялся бы с чтением готового файла. На 34 страницы: 1.5 с загрузки против 20 с разворота. * Упаковщики пишут второй набор: vflip_cols/vflip_page в pop_pack_kid.py -> kid0_v.atl…kid27_v.atl, sword_v.atl; pop_pack_guard.py -> g0_v.atl…g4_v.atl ТОЛЬКО для обычного стража (на уровне 9 tbl_guard_type = 0; тень рисуется атласами Кида, скелет/визирь с переворотом не встречаются). * pop_vflip.c схлопнулся до таблицы «страница -> зеркальная пара»; весь побайтовый разворот и аллокация EMM удалены. * pop_vflip_load_all (банк 8) грузит набор ОДНИМ вызовом и откуда угодно — задел под загрузку ресурсов во время интро. Зовётся при старте и при смене уровня, если это POP_UPSIDE_LEVEL; чит U на других уровнях поднимает набор лениво (страховка в главном цикле). * Стартовый уровень стал параметром сборки: make LEVEL=N (-DFIRST_LEVEL). Проверено в MAME на уровне 9: переворот мгновенный, pop_flip_screen = 897 263 такта (2.1 кадра) — это сама копия экрана, загрузки в кадре больше нет. tests-host 6/6.
87 lines
3.9 KiB
C
87 lines
3.9 KiB
C
/*
|
|
* pop_kboot.c — ЗАГРУЗКА ресурсов Кида: атласы chtab_2 (kid0..27.atl) и
|
|
* страница таблиц анимации (kid_data.bin). БАНК 8.
|
|
*
|
|
* Отрабатывает раз за игру (и на выходе — освобождение), поэтому места в
|
|
* резиденте W1 не занимает: контракт с интерпретатором — _pop_kid.h, там
|
|
* же дескриптор страницы данных.
|
|
*/
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sprinter.h>
|
|
#include <sprinter_mem.h>
|
|
#include <sprite.h>
|
|
#include "pop_kid.h"
|
|
#include "_pop_kid.h"
|
|
#include "kid_data.h"
|
|
#include "pop_vflip.h"
|
|
#include "pop_guard.h" /* pop_guard_vflip_load — зеркала соперника */
|
|
|
|
/* ISR-стаб W0-страницы (тот же приём, что atlas_load): при прерывании с
|
|
* замапленной в W0 страницей CPU прыгает на 0x0038 → там обязан быть JP на
|
|
* _gfx_w0_isr (восстановит окно). */
|
|
extern void _gfx_w0_isr(void);
|
|
|
|
#define KID_MAXPAGES 28
|
|
|
|
int pop_kid_load(uint8_t npages) __banked
|
|
{
|
|
static const char *const names[KID_MAXPAGES] = {
|
|
"KID\\kid0.atl","KID\\kid1.atl","KID\\kid2.atl","KID\\kid3.atl","KID\\kid4.atl","KID\\kid5.atl",
|
|
"KID\\kid6.atl","KID\\kid7.atl","KID\\kid8.atl","KID\\kid9.atl","KID\\kid10.atl","KID\\kid11.atl",
|
|
"KID\\kid12.atl","KID\\kid13.atl","KID\\kid14.atl","KID\\kid15.atl","KID\\kid16.atl","KID\\kid17.atl",
|
|
"KID\\kid18.atl","KID\\kid19.atl","KID\\kid20.atl","KID\\kid21.atl","KID\\kid22.atl","KID\\kid23.atl",
|
|
"KID\\kid24.atl","KID\\kid25.atl","KID\\kid26.atl","KID\\kid27.atl"
|
|
};
|
|
uint8_t i;
|
|
if (npages > KID_MAXPAGES) npages = KID_MAXPAGES;
|
|
for (i = 0; i < npages; i++)
|
|
if (atlas_load(&kidp[i], names[i]) != 0)
|
|
return -1;
|
|
kid_npages = npages;
|
|
return 0;
|
|
}
|
|
|
|
void pop_kid_free(void) __banked
|
|
{
|
|
uint8_t i;
|
|
for (i = 0; i < kid_npages; i++)
|
|
atlas_free(&kidp[i]);
|
|
kid_npages = 0;
|
|
}
|
|
|
|
/* ЗАГРУЗКА kid_data.bin (pop_kid_data_load) осталась в РЕЗИДЕНТЕ: она
|
|
* маппит страницу в W3 на время чтения, а этот модуль сам в W3 — см.
|
|
* то же правило в _pop_kid.h. */
|
|
|
|
void pop_kid_data_free(void) __banked
|
|
{
|
|
if (kdat_ok) { mem_free_block(kdat_blk); kdat_ok = 0; }
|
|
}
|
|
|
|
/* ---- Зеркальный набор (зелье инверсии, уровень 9) -------------------- *
|
|
* Грузится ОДНИМ вызовом и откуда угодно: со старта игры, из показа интро
|
|
* или при входе на уровень с зельем — см. pop_vflip.h. Внутри обычный
|
|
* atlas_load (он резидентный и сам мапит W3, банку это разрешено делать
|
|
* только через него). Идемпотентна. */
|
|
int pop_vflip_load_all(void) __banked
|
|
{
|
|
static const char *const kidv[KID_MAXPAGES] = {
|
|
"KID\\kid0_v.atl","KID\\kid1_v.atl","KID\\kid2_v.atl","KID\\kid3_v.atl",
|
|
"KID\\kid4_v.atl","KID\\kid5_v.atl","KID\\kid6_v.atl","KID\\kid7_v.atl",
|
|
"KID\\kid8_v.atl","KID\\kid9_v.atl","KID\\kid10_v.atl","KID\\kid11_v.atl",
|
|
"KID\\kid12_v.atl","KID\\kid13_v.atl","KID\\kid14_v.atl","KID\\kid15_v.atl",
|
|
"KID\\kid16_v.atl","KID\\kid17_v.atl","KID\\kid18_v.atl","KID\\kid19_v.atl",
|
|
"KID\\kid20_v.atl","KID\\kid21_v.atl","KID\\kid22_v.atl","KID\\kid23_v.atl",
|
|
"KID\\kid24_v.atl","KID\\kid25_v.atl","KID\\kid26_v.atl","KID\\kid27_v.atl"
|
|
};
|
|
uint8_t i;
|
|
int res = 0;
|
|
if (pop_vflip_ready()) return 0;
|
|
for (i = 0; i < kid_npages; i++)
|
|
if (pop_vflip_add(&kidp[i], kidv[i]) != 0) res = -1;
|
|
if (pop_sword_vflip_load() != 0) res = -1;
|
|
if (pop_guard_vflip_load() != 0) res = -1;
|
|
return res;
|
|
}
|