Перейти к содержимому

GFX320 — 2D-графика 320×256×256

GFX320.DLL — библиотека 2D-графики для Sprinter в режиме DSS #81 (320×256 точек, 256 цветов). Она даёт готовые графические функции программам на ассемблере, C и Pascal: приложение не программирует видеоконтроллер, страницы VRAM, палитру или блиттер — оно просто вызывает функции по номерам. Внутри библиотека использует аппаратный акселератор Sprinter, но это деталь реализации, а не часть интерфейса.

Общие правила загрузки DLL и передачи аргументов описаны в обзоре библиотек.

  • Заливки и линии — очистка экрана, прямоугольники (fill_rect, draw_rect), горизонтальные и вертикальные линии, произвольные линии по Брезенхэму.
  • Пикселиput_pixel / get_pixel.
  • Двойная буферизация — копирование прямоугольников и целых буферов, переключение видимого экрана (swap_buffers), перемещение и скролл областей, восстановление фона из зеркала в обычной памяти.
  • Палитра — загрузка всех 256 цветов RGB, диапазона или одного цвета.
  • Fade — плавное затемнение и проявление экрана на 33 уровнях яркости; библиотека делает один шаг за вызов, темп задаёт приложение (обычно раз в кадр).
  • Тайлы 16×16 — вывод одиночных тайлов, рядов, списков, целых карт и метатайлов из страниц памяти, подготовленных приложением.
  • Прозрачность — флаг GFX_KEY_FF: байты #FF аппаратно пропускаются при выводе, что даёт «дырявые» спрайты без попиксельных проверок.
include "gfx320.inc"
ld bc,#0050 ; DSS SETVMOD
ld a,#81 ; включаем режим 320x256x256 сами
rst #10
ld hl,libname ; "GFX320.DLL",0
ld a,3 ; загрузить DLL в окно WIN3
call LIBMAN.l_load
jp c,load_error
ld (handle),hl
; очистить видимый экран цветом 0
ld hl,(handle)
ld a,0 ; цвет
ld e,GFX_TARGET_FRONT
ld b,GFX_CLEAR ; номер функции из gfx320.inc
call LIBMAN.l_call
jp c,dispatch_error ; ошибка libman
or a
jp nz,gfx_error ; статус GFX320: 0 — успех

Разбор: приложение само включает режим #81 (библиотека видеорежим не трогает), загружает DLL через libman и вызывает функцию GFX_CLEAR. Аргументы идут в регистрах A, DE, IX, IY; E здесь выбирает цельGFX_TARGET_FRONT (видимый экран) или GFX_TARGET_BACK (скрытый буфер). Статус возвращается в A: ноль — успех, #10..#17 — коды ошибок GFX_ERR_* (неверный аргумент, выход за экран и т. п.).

В поставке есть биндинг для SDCC — заголовок gfx320.h и библиотека обёрток:

#include "gfx320.h"
/* handle — от загрузчика libman в приложении */
gfx_u8 draw(gfx_u8 handle) {
gfx320_rect_t panel = {
16, 16, 288, 48, /* x, y, ширина, высота */
4, /* цвет */
GFX_TARGET_FRONT, /* куда рисуем */
{0, 0, 0} /* служебные поля */
};
gfx_u8 status;
gfx320_bind(handle); /* привязать обёртки к DLL */
status = gfx320_clear(0, GFX_TARGET_FRONT);
if (status) return status;
status = gfx320_fill_rect(&panel); /* панель 288x48 цветом 4 */
if (status) return status;
return gfx320_hline(16, 80, 288, 15, GFX_TARGET_FRONT);
}

Обёртки повторяют регистровый ABI один в один: каждая функция возвращает тот же статус, что пришёл бы в регистре A. Крупные аргументы (прямоугольники, описания тайлов) оформлены структурами — в ассемблере им соответствуют packed-дескрипторы, смещения полей которых описаны в gfx320.inc.

В режиме #81 у Sprinter два экранных буфера; какой из них видим, определяет бит регистра RGMOD. Классический игровой цикл с GFX320:

  1. рисуем кадр в GFX_TARGET_BACK;
  2. вызываем gfx_swap_buffers — скрытый буфер становится видимым;
  3. повторяем.

Кроме VRAM, библиотека ведёт зеркало экрана в обычной памяти. Благодаря ему работают get_pixel, копирования и restore_rect — быстрое восстановление фона под спрайтом без перерисовки сцены. Флаг GFX_VRAM_ONLY позволяет рисовать мимо зеркала (быстрее), но такие пиксели зеркало «не видит» — их нельзя прочитать или использовать как источник копирования.

Тайл — картинка 16×16 пикселей (256 байт). Тайлы лежат в 16-килобайтных страницах памяти по 64 штуки; страницы выделяет приложение (DSS #3D), узнаёт их физические номера (BIOS #C5) и один раз передаёт таблицу в gfx_set_page_table. Дальше любой тайл адресуется парой «страница + слот».

Готовить страницы вручную не нужно — в поставке есть упаковщик, который режет индексированный PNG/BMP на тайлы:

Окно терминала
python3 gfx320/tools/tilepack.py assets.png build/tiles \
--keyed --transparent-index 0 \
--metatile-width 2 --metatile-height 2

На выходе — готовые 16-КБ файлы pageNN.bin, палитра и JSON-манифест с номерами слотов. Флаг --keyed превращает выбранный цвет в прозрачный байт #FF для вывода с GFX_KEY_FF.

  • На время тайловых операций страница-источник подключается в окно WIN0 под запретом прерываний, поэтому код, стек и сама DLL не должны находиться в WIN0.
  • Библиотека нереентерабельна: не вызывайте её функции из обработчика прерываний. Из ISR взводите флаг кадра, а gfx_swap_buffers и gfx_fade_step вызывайте в главном цикле.
  • Не выводите текст консолью DSS при активном режиме #81 — испортите картинку (подробнее в обзоре).
Файл Назначение
GFX320.DLL сама библиотека — единственный файл, нужный приложению
gfx320.inc константы и смещения дескрипторов для sjasmplus
bindings/sdcc/ заголовок и библиотека для C (SDCC)
bindings/tpascal/ include для Turbo Pascal
tools/tilepack.py упаковщик тайлов из PNG/BMP
GFX320.EXE визуальный тест; приложениям не нужен