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

GFX640 — 2D-графика 640×256×16

GFX640.DLL — библиотека ускоренной 2D-графики для Sprinter в режиме DSS #82 (640×256 точек, 16 цветов). Интерфейс сознательно повторяет GFX320: те же номера функций 0–35, те же регистры, дескрипторы, флаги, палитра и fade. Если программа умеет работать с GFX320, перенести её на GFX640 несложно — меняются в основном правила координат. Координаты задаются в пикселях, цвета — 0..15.

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

В режиме #82 пиксели упакованы по два в байт: старший полубайт — левый пиксель, младший — правый. Отсюда главные отличия:

  • Заливки, рамки и горизонтальные линии требуют чётных X и ширины. Копирование, перемещение и восстановление областей — чётных X источника, X приёмника и ширины; скролл — чётных X, ширины и сдвига. Нарушение возвращает ошибку GFX_ERR_ARGUMENT, а не рисует «почти правильно».
  • put_pixel, get_pixel, вертикальные и наклонные линии работают с любым X — библиотека сама делает чтение-изменение-запись нужного полубайта.
  • Цвет больше 15 — ошибка аргумента.
  • Тайл здесь 32×16 пикселей (те же 256 байт, что и 16×16 при 256 цветах); экран — сетка 20×16 тайлов.

У hline и vline длина и флаги упакованы в один регистр DE: десять бит длины плюс четыре бита флагов:

DE = (длина & #03FF) | (флаги << 10)

В C-биндинге эту упаковку делает обёртка; в ассемблере помогают константы GFX_LENGTH_MASK и GFX_LENGTH_FLAGS_SHIFT из gfx640.inc.

Аппаратный ключ GFX_KEY_FF действует на байты: байт #FF пропускает сразу пару пикселей цвета 15. Для точной попиксельной прозрачности добавлены отдельные тайловые функции 36–41 (*_TRANSPARENT): в них полубайт #F в байте #F? или #?F сохраняет соответствующий пиксель фона, а полный #FF по-прежнему обрабатывается аппаратно. Без ключа те же функции рисуют по обычному ускоренному пути, и цвет 15 непрозрачен.

#include "gfx640.h"
gfx_u8 draw(gfx_u8 handle) {
gfx_u8 status;
gfx640_bind(handle);
status = gfx640_clear(0, GFX_TARGET_FRONT);
if (status) return status;
/* панель: чётные x и ширина — обязательны */
status = gfx640_hline(16, 80, 288, 15, GFX_TARGET_FRONT);
if (status) return status;
/* одиночные пиксели можно ставить в любую позицию, даже 639 */
return gfx640_put_pixel(639, 255, 7, GFX_TARGET_FRONT);
}

Обёртка сама упаковывает длину и флаги hline в слово DE и возвращает статус библиотеки: 0 — успех, #10..#17 — коды GFX_ERR_*.

Как и в GFX320: приложение выделяет 16-КБ страницы (64 тайла на страницу), передаёт таблицу физических номеров в gfx_set_page_table и адресует тайлы парой «страница + слот». Упаковщик принимает индексированные PNG/BMP, у которых все индексы пикселей лежат в 0..15:

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

С флагом --keyed каждый пиксель цвета 15 становится прозрачным — в том числе одна половинка упакованной пары, что как раз и обслуживают функции *_TRANSPARENT.

  • Видеорежим #82 включает приложение; библиотека его не переключает.
  • Тайловые операции временно подключают источник в окно WIN0 под запретом прерываний — код и стек приложения не должны находиться в WIN0.
  • Библиотека нереентерабельна, вызывать её из обработчика прерываний нельзя: ISR только взводит флаг кадра, а gfx_swap_buffers и gfx_fade_step вызываются из главного цикла.
  • После каждой операции библиотека восстанавливает подключённые страницы и состояние прерываний.
Файл Назначение
GFX640.DLL сама библиотека
gfx640.inc константы ABI и смещения дескрипторов для sjasmplus
bindings/sdcc/gfx640.h, gfx640.lib биндинг для C (SDCC)
bindings/tpascal/GFX640.INC константы и хелперы для Turbo Pascal
tools/tilepack.py упаковщик тайлов из PNG/BMP
GFX640.EXE визуальный тест; приложениям не нужен