docs: атласы — рекомендация по компоновке + предложение файл-формата .atl

Решение: in-memory формат остаётся (getimage + sx/sy, ленты/сетки).
Рекомендация: кадры одного спрайта — одного размера с полной сеткой;
для спрайтов разных размеров — контейнерный формат .atl (каталог +
независимые getimage-ленты, паддинг невозможен по построению).
Формат — предложение, реализация по потребности первого приложения.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 11:39:18 +03:00
parent ee1ca00c6f
commit 88a00bb4ec
+47
View File
@@ -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)