Files
Sprinter-SDCC/applications/PoP/roomtest/pop_vflip.c
T
snark13 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.
2026-08-12 23:17:22 +03:00

56 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* pop_vflip.c — таблица «страница атласа -> её ВЕРТИКАЛЬНО ЗЕРКАЛЬНАЯ пара»
* (зелье инверсии, уровень 9). См. pop_vflip.h.
*
* Сами зеркальные ленты делает упаковщик (`vflip_cols` в pop_pack_kid.py) и
* кладёт рядом с обычными: kid0_v.atl, sword_v.atl, g0_v.atl… Здесь остаётся
* только связать пары: зеркальный файл грузится обычным atlas_load, а его
* раскладка байт-в-байт совпадает с оригиналом — значит движку достаточно
* подменить НОМЕР СТРАНИЦЫ, которую он мапит в W0.
*
* Почему не считаем в рантайме (замеры MAME 2026-08-12, такты Z80):
* загрузка одной 16-КБ страницы с HDD — 970 003 такта (0.045 с);
* разворот той же страницы на месте — 12 645 582 такта (0.59 с).
* Даже идеальная конвертация (accel-копия + asm-реверс) даёт ~1.05 млн —
* то есть в лучшем случае сравнивается с чтением готового файла, а стоит
* asm-модуля. На все 34 страницы: 1.5 с загрузки против 20 с разворота.
*
* РЕЗИДЕНТ: pop_vflip_page зовёт отрисовка персонажей (банк 4) на каждый
* спрайт — трамплин тут ни к чему, а кода всего ничего.
*/
#include <stdint.h>
#include <sprite.h>
#include "pop_vflip.h"
/* Персонажных страниц: 28 (Кид) + 5 (страж) + 1 (меч) = 34; с запасом. */
#define VF_MAX 40
static uint8_t vf_src[VF_MAX]; /* страница оригинала */
static atlas_t vf_atl[VF_MAX]; /* зеркальный атлас (его page) */
static uint8_t vf_n;
int pop_vflip_add(const atlas_t *orig, const char *path)
{
if (!orig || vf_n >= VF_MAX) return -1;
if (atlas_load(&vf_atl[vf_n], path) != 0) return -1;
vf_src[vf_n] = orig->page;
vf_n++;
return 0;
}
uint8_t pop_vflip_page(uint8_t src)
{
uint8_t i;
for (i = 0; i < vf_n; i++)
if (vf_src[i] == src) return vf_atl[i].page;
return 0; /* пары нет — рисуем обычным атласом */
}
uint8_t pop_vflip_ready(void) { return vf_n != 0; }
void pop_vflip_reset(void)
{
uint8_t i;
for (i = 0; i < vf_n; i++) atlas_free(&vf_atl[i]);
vf_n = 0;
}