libbgi: спрайтовый движок v2 + accel-блит/heal leaf'ы + noclip-путь
Спрайтовая графика поверх accel block-copy (docs/sprite-api-design.md): - Ядро блиттинга: leaf'ы _bgi_blit_rows_raw (dst фикс, только src-страйд) / _bgi_copy_rows_raw (getimage) / _bgi_heal_rows_raw (src==dst). DI один на спрайт (санкция: малый спрайт под одним DI аудио не рвёт); src[0]-фикс снят (точная MAME подавляет CPU-байт триггера записи — на железе перепроверить; для heal был избыточен и снят безусловно). - Общие bracket-free ядра _gfx_blit_full/_gfx_heal_full (полная ширина: клип по экрану + split >256 для putimage) + лин _gfx_blit_sprite/ _gfx_heal_sprite (кадр ≤64, без split, 8-бит w/h) + noclip-варианты (клип-кода нет → полный codegen-win). Имя *_full (не *_clip) — «clip» двусмысленно (sprite-ядра тоже клипуют; различитель — ширина/split). - Движок retained-модели <sprite.h>: sprite_init/update/flip + inline move/frame/show/hide/touch; drawn[2] per-page внутри структуры; кадр — двухпроходно heal ВСЕ -> блит ВСЕ под одной W3-скобкой/банком на проход. - Флаг gfx_sprite_clip(on/off): приложение, само следящее за границами, отключает клип (~+19% на анимации; диспетч пока через if — funcptr далее). - putsprite/movesprite/gfx_blit/putimage(COPY)/getimage переведены на ядро. Тесты: examples/balls (движок, дабл-буфер, boundary-тест клипа), tests/sprites (RAM PASS, клип 4 края, атлас), tests/blitw (trig-leak), tests/spriteclip (hardware-probe: железо НЕ режет за краем -> клип нужен), tests/blitperf, tests/gfxbanks. size-baseline обновлён (53 программы). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+51
-1
@@ -46,9 +46,59 @@ void gfx_set_visible_page(uint8_t page); /* 0 or 1 */
|
||||
inline uint8_t gfx_get_visible_page(void) { return _gfx_visible_page; }
|
||||
void gfx_set_draw_page(uint8_t page); /* 0 or 1 */
|
||||
inline uint8_t gfx_get_draw_page(void) { return _gfx_draw_page; }
|
||||
inline void gfx_set_bank(uint8_t bank) { _gfx_bank = bank; } /* 0x50..0x5F */
|
||||
|
||||
/* Видеобанк W3 (0x50..0x5F): биты 2/3 номера страницы — аппаратные
|
||||
* подрежимы ЗАПИСИ (Иван Мак §4.3; docs/sprite-api-design.md §1),
|
||||
* действуют на ВСЕ примитивы рисования до следующего gfx_set_bank.
|
||||
* Биты 0/1 всегда 0 (резерв конфигураций). */
|
||||
#define GFX_BANK_NORMAL 0x50 /* запись в видео-ОЗУ + ОЗУ-копию */
|
||||
#define GFX_BANK_NOSHADOW 0x54 /* только видео-ОЗУ (врем. вывод) */
|
||||
#define GFX_BANK_TRANSPARENT 0x58 /* байт 0xFF не записывается */
|
||||
#define GFX_BANK_SPRITE 0x5C /* NOSHADOW + TRANSPARENT */
|
||||
|
||||
/* Прозрачный цвет аппаратной прозрачности (256-режим: пиксель;
|
||||
* 16-режим: ПАРА пикселей цвета 15). Цвет 255 нельзя нарисовать
|
||||
* через банк с битом 3 — он и есть прозрачный. */
|
||||
#define GFX_TRANSPARENT 0xFF
|
||||
|
||||
inline void gfx_set_bank(uint8_t bank) { _gfx_bank = bank; } /* GFX_BANK_* */
|
||||
inline uint8_t gfx_get_bank(void) { return _gfx_bank; }
|
||||
|
||||
/* Клип спрайтов по экрану (putsprite/movesprite/спрайтовый движок).
|
||||
* on=1 (дефолт) — клипить (спрайты могут уходить за края); on=0 —
|
||||
* ОТКЛЮЧИТЬ (приложение ГАРАНТИРУЕТ, что спрайты целиком на экране —
|
||||
* иначе запись за край портит соседнюю память, см. tests/spriteclip).
|
||||
* Выигрыш ~+19% на анимации: движок зовёт noclip-ядра без клип-кода
|
||||
* (не просто скип проверки — вся клип-математика физически отсутствует,
|
||||
* SDCC тесней раскладывает регистры). Флаг читается раз на спрайт.
|
||||
* НЕ влияет на putimage/gfx_blit (у них клип всегда). */
|
||||
extern uint8_t _gfx_sprite_clip;
|
||||
inline void gfx_sprite_clip(uint8_t on) { _gfx_sprite_clip = on; }
|
||||
inline uint8_t gfx_get_sprite_clip(void) { return _gfx_sprite_clip; }
|
||||
|
||||
/* ---- Блиттинг (ядро спрайтов; Фаза B sprite-api-design) ----------- *
|
||||
* Формат картинки — getimage: uint16 w, uint16 h, пиксели построчно
|
||||
* (1 байт/пиксель в 256-режиме). Буфер обязан лежать ВНЕ W3
|
||||
* (< 0xC000) — на время операции W3 замаплен на видеобанк.
|
||||
* Блит через accel block-copy (до 256 байт/burst), клиппинг по экрану
|
||||
* есть всегда; рисует ТЕКУЩИМ банком (gfx_set_bank). */
|
||||
|
||||
/* Блит целой картинки левым-верхним углом в (x,y). */
|
||||
void gfx_blit(int x, int y, const void *img);
|
||||
|
||||
/* Блит под-прямоугольника (sx,sy,w,h) картинки (атлас кадров:
|
||||
* кадр N ленты — sx = N*FRAME_W). Под-прямоугольник обязан лежать
|
||||
* внутри img; по экрану — клиппится. */
|
||||
void gfx_blit_part(int x, int y, const void *img,
|
||||
int sx, int sy, int w, int h);
|
||||
|
||||
/* Восстановить прямоугольник экрана из ОЗУ-копии (стирание спрайта/
|
||||
* оверлея, нарисованного банком с битом 2: 0x54/0x5C). Всегда
|
||||
* работает банком GFX_BANK_NORMAL независимо от gfx_set_bank;
|
||||
* клиппится по экрану. Буфер сохранения не нужен: ОЗУ-копия и есть
|
||||
* бэкап фона (чтение из #50..#5F всегда возвращает её). */
|
||||
void gfx_heal(int x, int y, int w, int h);
|
||||
|
||||
/* Block until the next frame (50 Hz). Типичный double-buffer:
|
||||
* gfx_set_draw_page(hidden); draw_frame(); gfx_wait_vsync();
|
||||
* gfx_set_visible_page(hidden); // tear-free flip */
|
||||
|
||||
Reference in New Issue
Block a user