libbgi: W0-атласы спрайтов — загрузчик, движок, упаковщик (все проверки PASS)
Реализация §3.1/§9в: атлас = один .atl-файл = одна EMM-страница, подключаемая в W0 на время блита. - atlas_load: read() файла целиком в страницу через W3 + патч ISR-стаба (0x38: JP _gfx_w0_isr; 0x66: RETN); atlas_free/atlas_image/ atlas_sprite_init; gfx_w0_map/unmap для ручных вызовов. - _gfx_w0_isr (стаб из tests/w0page): свап на ядро DSS → честный 0x38 → restore спрайт-страницы; покрывает IM1 и IM2-чейн. - sprite_t.page (0 = обычная память); sprite_update в блит-проходе мапит страницу по смене (один OUT на атлас), эпилог возвращает DSS (+52 Б на движок — цена фичи). - toolchain/mkatlas.py: PNG (indexed) / raw → .atl; заголовок 0x100, каталог 0x68 (19 лент), файл-офсет == офсет страницы == W0-адрес. - Сплит _gfx_sprite_fns → _gfx_blit_fn.c + _gfx_heal_fn.c (1 указатель = 1 модуль): putsprite-only программа не тянет heal-ядро (spriteclip ловил +292 Б; теперь −68 Б от эталона). tests/atlas (MAME dev, PASS): загрузка (count/страница), каталог и данные по W0-адресам (заголовок ленты через gfx_w0_map), 3 спрайта из двух лент через движок — пиксели проверены read_vram побайтно (0x10/0x12/0x21, прозрачный угол = фон). docs: §9г — предложение авто-анимации (кадровая ±step без умножений, tween-Брезенхэм порциями, тикер через funcptr) — ОБСУЖДАЕТСЯ. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,9 @@ typedef struct {
|
||||
int sx, sy; /* смещение кадра внутри img (атлас; 0 = целая) */
|
||||
uint8_t w, h; /* размер кадра (кэш заголовка), 1..255 */
|
||||
uint8_t flags; /* SPR_* | внутренние dirty */
|
||||
uint8_t page; /* 0 = img в обычной памяти; иначе физ. страница *
|
||||
* W0-атласа (img — адрес 0x0100-0x3FFF, движок *
|
||||
* сам мапит страницу в W0 на время блита) */
|
||||
/* --- внутреннее (владеет движок) --- */
|
||||
struct {
|
||||
int x, y; /* где нарисован на странице p */
|
||||
@@ -104,4 +107,44 @@ inline void sprite_hide(sprite_t *s) {
|
||||
* активный спрайт прошёл над статиком — приложение помечает статик). */
|
||||
inline void sprite_touch(sprite_t *s) { s->flags |= _SPR_DIRTY; }
|
||||
|
||||
/* ==== Атласы в EMM-страницах (W0) ====================================
|
||||
* Файл .atl (docs/sprite-api-design.md §3.1, вариант II): 0x100-байтовый
|
||||
* заголовок (магия 'SPA1', count; каталог с 0x68) + getimage-ленты;
|
||||
* файл-офсет == офсет в странице == адрес в W0. Загрузчик читает файл
|
||||
* ЦЕЛИКОМ в EMM-страницу через W3 и патчит ISR-стаб (0x38/0x66) —
|
||||
* страница безопасна в W0 при включённых прерываниях (§9в).
|
||||
*
|
||||
* ВАЖНО: указатели лент — адреса 0x0100-0x3FFF, разыменовывать их можно
|
||||
* ТОЛЬКО при подключенной странице (sprite_update мапит сам; для ручного
|
||||
* putsprite/gfx_blit_part — обернуть в gfx_w0_map/gfx_w0_unmap).
|
||||
* Пока страница в W0 — НИКАКИХ ESTEX/BIOS-вызовов. */
|
||||
|
||||
typedef struct {
|
||||
uint8_t page; /* физ. страница (маппить в W0/W3) */
|
||||
uint8_t blk; /* EMM-блок — для atlas_free */
|
||||
uint8_t count; /* число лент в атласе */
|
||||
} atlas_t;
|
||||
|
||||
/* Загрузить .atl в свежую EMM-страницу (read в W3 + патч стаба).
|
||||
* 0 — OK; -1 + errno (файл/память/формат). */
|
||||
int atlas_load(atlas_t *a, const char *path);
|
||||
|
||||
/* Освободить EMM-страницу атласа (все sprite_t с его лентами должны
|
||||
* быть скрыты/переинициализированы ДО вызова). */
|
||||
void atlas_free(atlas_t *a);
|
||||
|
||||
/* Указатель-лента idx (W0-адрес, см. ВАЖНО выше) — для gfx_blit_part
|
||||
* и ручных вызовов; кадр (i,j) ленты: sx = i*fw, sy = j*fh. */
|
||||
const void *atlas_image(const atlas_t *a, uint8_t idx);
|
||||
|
||||
/* Инициализировать спрайт лентой idx атласа: img/w/h (размер КАДРА из
|
||||
* каталога) /page; невидим, кадр (0,0). Аналог sprite_init для W0. */
|
||||
void atlas_sprite_init(sprite_t *s, const atlas_t *a, uint8_t idx);
|
||||
|
||||
/* Ручное подключение страницы атласа в W0 (для putsprite/gfx_blit_part
|
||||
* вне движка). map ставит и _gfx_w0_cur (ISR-стаб восстановит страницу
|
||||
* после прерывания), unmap возвращает страницу ядра DSS. */
|
||||
void gfx_w0_map(uint8_t page);
|
||||
void gfx_w0_unmap(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user