From 88a00bb4ec8d30a9b3609e72503aa46773cf7eff Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Mon, 13 Jul 2026 11:39:18 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=B0=D1=82=D0=BB=D0=B0=D1=81=D1=8B=20?= =?UTF-8?q?=E2=80=94=20=D1=80=D0=B5=D0=BA=D0=BE=D0=BC=D0=B5=D0=BD=D0=B4?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BF=D0=BE=D0=BD=D0=BE=D0=B2=D0=BA=D0=B5=20+=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84?= =?UTF-8?q?=D0=B0=D0=B9=D0=BB-=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=20.atl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Решение: in-memory формат остаётся (getimage + sx/sy, ленты/сетки). Рекомендация: кадры одного спрайта — одного размера с полной сеткой; для спрайтов разных размеров — контейнерный формат .atl (каталог + независимые getimage-ленты, паддинг невозможен по построению). Формат — предложение, реализация по потребности первого приложения. Co-Authored-By: Claude Fable 5 --- docs/sprite-api-design.md | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/sprite-api-design.md b/docs/sprite-api-design.md index 1ed0d30..cebded4 100644 --- a/docs/sprite-api-design.md +++ b/docs/sprite-api-design.md @@ -153,6 +153,53 @@ void movesprite(int oldx, int oldy, int x, int y, const void *img); (банк выставить `GFX_BANK_SPRITE` вокруг — или см. §9 про `putsprite_part`). +### 3.1 Атласы: рекомендация по компоновке и файл-формат (предложение) + +Решение 2026-07-13: in-memory адресация кадра остаётся как есть — +атлас = обычная getimage-картинка, кадр выбирается sx/sy (единичные +изображения, ленты по горизонтали и по вертикали, сетки nx×ny). + +В одном атласе могут храниться изображения разных размеров и разного +количества вариаций. РЕКОМЕНДАЦИЯ: для одного спрайта держать кадры +одинакового размера и полностью заполнять его сетку (nx*ny == число +вариаций) — иначе в прямоугольнике атласа возникают пустые сегменты, +теряющие место и на диске, и в памяти при загрузке. Смешивать +спрайты РАЗНЫХ размеров в одном прямоугольнике не надо вообще: для +этого предлагается файл-формат БЕЗ пустых мест — контейнер независимых +лент, где паддинг невозможен по построению. + +Файл-атлас (.atl, предложение — НЕ реализовано): + +``` +Шапка (8 байт): 'S','P','A','1' | count u8 | резерв ×3 +Каталог (count × 8 байт): + offset u16 смещение ленты от начала файла + fw, fh u8,u8 размер кадра + nx, ny u8,u8 сетка кадров (вариаций = nx*ny) + резерв u16 (id/флаги) +Данные: count лент подряд, каждая — обычный getimage-блоб + (u16 w = fw*nx, u16 h = fh*ny, пиксели построчно) +``` + +ВАЖНО: offset указывает на ПЕРВЫЙ БАЙТ getimage-шапки ленты (не на +пиксели) — 4 байта `u16 w, u16 h` хранятся В ФАЙЛЕ в начале каждого +блоба. Поэтому каждая лента — самостоятельная getimage-картинка со +своим stride: после загрузки файла целиком в память указатель +`base + dir[i].offset` напрямую годится в putsprite/sprite_init/ +gfx_blit_part — рантайм не меняется вовсе, кадр (i,j) = sx=i*fw, +sy=j*fh. (w/h ленты при этом задублированы: выводимы из fw*nx/fh*ny +каталога И лежат в шапке блоба — осознанные 4 байта на спрайт за +прямую совместимость указателя. Каталог же несёт то, чего в шапке +нет: размер КАДРА и сетку — без них лента 128×16 неотличима от +одного кадра 128×16.) Пустых байтов нет по +построению: ленты разных размеров просто конкатенируются. Пример +(два спрайта 16×16 на 8 и 12 вариаций + один 24×24 на 4): шапка 8 + +каталог 24 + (4+2048) + (4+3072) + (4+2304) = 7468 байт, паддинг 0. +Ограничение u16-offset: файл ≤ 64 КБ (для больших — версия 'SPA2' с +u24/u32, пока не нужна). Загрузчик — тонкий хелпер (fread целиком + +арифметика каталога) + Python-упаковщик (PNG → .atl) в toolchain; +делать по потребности первого реального приложения. + ## 4. Внутренности ### 4.1 Leaf-примитив (per-driver, asm)