Skip to content

Instantly share code, notes, and snippets.

@kolnogorov
Last active April 13, 2025 03:29
Show Gist options
  • Save kolnogorov/7374bae5fbb90f19cf6875d6e16309c1 to your computer and use it in GitHub Desktop.
Save kolnogorov/7374bae5fbb90f19cf6875d6e16309c1 to your computer and use it in GitHub Desktop.
tzunami

Tzunami 0.1.0

Что это

Tzunami - спрайтовый движок, представляющий собой скриптовый язык, основанный на макросах sjasmplus, предназначенный для работы на ZX Spectrum 128K и совместимых с ним клонах.

Tzunami позволяет выводить статические и анимированные спрайты по пиксельным координатам с атрибутами и без атрибутов, а также перемещать спрайты по экрану по прямым линиям (в том числе с субпиксельной точностью) и по заранее заданным траекториям (с пиксельной точностью).

Максимальный размер спрайта по горизонтали: 8 знакомест. По вертикали - 24 знакомест, но технически не ограничен.

Вывод спрайтов на экран осуществляется через OR. Проверка на выход за границы экрана пока не осуществляется.

Установка

Распакуйте архив в папку проекта и подключите файл tzunami/tzunami.asm:

	include "tzunami/tzunami.asm"

Идея и концепция

В основе tzunami лежит понятие “сцены”. Сцена - это зацикленная последовательность команд, которая выводится каждый фрейм (либо больше, если рендеринг сцены занимает несколько фреймов), начиная с указанного фрейма и заканчивая фреймом, с которого начинается следующая сцена.

Скрипт условно состоит из трёх частей.

Сценарий

Первая часть - собственно сценарий (скрипт), который начинается с метки script и состоит из команд tz.frame с указанием фрейма, в котором начинается сцена, и указателя (метки) на саму сцену (либо её модификатор, см. ниже).

Заканчивается сценарий командой tz.end.

Это основная часть скрипта и выглядит она примерно так:

script
	tz.frame 0, scene1
	tz.frame 128, scene2
	tz.frame 256, scene3	
	tz.frame 384, scene3.update		; это модификатор сцены,
						; изменяющий её параметры,
						; но не переключающий саму сцену
	tz.frame 512, scene4	
	tz.frame 768, scene5	
	tz.frame 1024, scene6	
...
		
tz.end

Описание сцен. Команды: эффекты, установщики и модификаторы

Каждая сцена состоит из команд: эффектов, установщиков и модификаторов.

Вторая часть - описание каждой сцены в виде последовательности эффектов, выводящих спрайты, установщиков, выставляющих параметры, распространяющиеся на все последующие эффекты, и модификаторов этой сцены.

Сцена заканчивается командой tz.repeat, которая является маркером её зацикленности.

Помимо эффектов, установщик и модификаторов, из команд так же можно условно выделить операции с экраном и его областями, а так же управление эффектами. Все они так же указываются в сценах.

Сцена

Простой пример:


scene1		
	tz.init 0, <circles, squares>

scene1.spr1 tz.set_color TZ.YELLOW_BRIGHT ; это установщик tz.idle 0, 96,64, 0 ; это эффект

scene1.spr2 tz.set_anim_speed 1 ; и это тоже установщик tz.anim 0, 128,96, 0, TZ.F ; и это тоже эффект tz.repeat

Модификатор

В этой части также описываются модификаторы сцены. Модификаторы вызываются один раз, изменяют параметры последней сцены, не прерывая её, после чего выполнение возвращается на сцену, которая указывается в параметре команде tz.return:


scene1.update							; а это модификатор
	tz.change scene1.spr1, <TZ.IDLE.X, 128, 100>	; меняет координаты на 128,100
	tz.change scene1.spr2, <TZ.ANIM.DIRECTION, TZ.B>	; меняет направление анимации на TZ.B
	tz.return scene1.spr					; и возвращает цикл на scene1.spr

Полный список параметров для модификаторов смотрите в разделе “Константы”.

Импорты

В третьей части импортируются все ассеты: спрайты, траектории, таблицы и т.п:

Импорт ассетов

При импорте ассетов сначала, после команды tz.page указывается страница, куда грузятся ассеты, затем в команде tz.load указывается уникальная метка для спрайтшита, путь к файлу, ширина, высота и количество фреймов в спрайтшите:


	tz.page  1
	tz.load  circles, "assets/sprites/circlex_24x24x16.spr", 3, 3, 16
	tz.load  squares, "assets/sprites/squares_32x32x32.spr", 4, 4, 32
	tz.log  "page 1 end"

Специального маркера конца для импорта ассетов не требуется.

Импорт траекторий и таблиц

Траектории, таблицы и прочие текстовые файлы грузятся командой tz.import:

path.spiral 	
	tz.import  "assets/paths/path_spiral.asm"
	tz.end
path.wave
	tz.import  "assets/paths/path_wave.asm"
	tz.end

Каждый импорт завершается импорт командой tz.end.

Команды, константы, переменные и дефайны

Все команды tzunami начинаются с префикса tz. - это сделано для того, чтобы избежать путаницы и конфликта неймспейсов, если вы планируете использовать tzunami в своём проекте.

Предопределённые константы начинаются с прописных букв TZ., и самой константы, написанной так же прописными буквами.

Переменные и дефайны находятся в файле variables.asm и рекомендуются к изменению только в том случае, если вы планируете кастомизировать движок tzunami, либо использовать его в своём проекте, и вы знаете, что делаете. По умолчанию, изменения они не требуют.

Список команд

Импорт и инициализация

tz.frame

Элемент сценария. Устанавливает последовательность проигрываемых сцен через номера привязанных к ним фреймов.

    tz.frame frame, scene
  • frame - номер фрейма, в который начнёт проигрываться следующая сцена
  • scene - метка сцены

tz.end

Маркер конца сценария, либо импорта.

    tz.end
  • Нет аргументов

tz.import

Импортирует внешние файлы ассемблера или текстовые файлы (пути, таблицы и т.д.).

	tz.import "/path/to/file"
  • "/path/to/file" — путь к файлу, который нужно импортировать.

Работает на основе директивы include.


tz.page

Устанавливает страницу памяти перед загрузкой ресурсов.

	tz.page memory_page
  • memory_page — номер страницы памяти, в которую будут загружены ресурсы

Страница указывается числом от 0 до 6. Вы можете использовать memory allocation по своей усмотрению, но по умолчанию, скрипт находится в странице 0, музыка в странице 6, следовательно под спрайты вы можете использовать страницы 1, 3 и 4. В странице 7 выше экранной области используются системные процедуры очистки экрана, поэтому грузить туда что-либо нежелательно, если вы не планируете кастомизировать движок.


tz.load

Загружает спрайтовый лист в память.

	tz.load label, "/path/to/file", width, height, total_frames
  • label — метка для спрайтшита
  • "/path/to/file" — путь к файлу
  • width — ширина одного кадра спрайта (в знакоместах, от 1 до 8)
  • height — высота одного кадра спрайта (в знакоместах, от 1 до 24)
  • total_frames — общее количество кадров в последовательности спрайтов

tz.init

Инициализирует спрайты в указанной странице памяти.

          tz.init memory_page <spritesheet1, spritesheet2, ...>
  • memory_page — номер страницы памяти, где будут инициализированы спрайты
  • <spritesheet1, spritesheet2, ...> — список меток спрайтовых листов для инициализации

Чтобы вывести спрайт из спрайтшита, нужно сначала его синхронизировать.

Инициализация спрайтов подразумевает перемещение спрайтов из верхней памяти в буфер в нижней памяти. По умолчанию, буфер для вывода спрайтов занимает 8кб (8192 байт). Следовательно, одновременно проинициализировать можно спрайты, которые занимают именно столько памяти. Инициализация 4кб спрайтов занимает 1 фрейм, следовательно инициализация всего буфера будет занимать 2 фрейма времени, учитывайте это при синхронизации. Выход за пределы буфера контролируется пользователем, системных проверок нет.

Есть ещё несколько важных моментов, на которые стоит обратить внимание:

  1. Вы не обязаны инициализировать спрайты каждый раз в начале сцены. Если команды tz.init в начале нет, в сцене будут использованы последние проинициализированные спрайты из предыдущей сцены.
  2. Командаtz.init исполняется только один раз, при первом выполнении сцены — во время последующих итераций она не выполняется, если только вы принудительно не установите на неё цикл через tz.loop_for или tz.return (см. ниже) - в этом случае произойдёт повторная инициализация.

Эффекты

tz.idle

Рисует статичный спрайт без анимации

    tz.idle spritesheet_index, pos.x, pos.y, start_frame
  • spritesheet_index — индекс инициализированного спрайтшита
  • pos.x — координата X (в пикселях)
  • pos.y — координата Y (в пикселях)
  • start_frame — начальный кадр спрайта

tz.anim

Рисует статичный анимированный спрайт.

    tz.anim spritesheet_index, pos.x, pos.y, start_frame, anim_direction
  • spritesheet_index — индекс инициализированного спрайтшита
  • pos.x — координата X (в пикселях)
  • pos.y — координата Y (в пикселях)
  • start_frame — начальный кадр анимации
  • anim_direction — направление анимации (TZ.FORWARD, TZ.BACKWARD, TZ.NONE, TZ.RANDOM)

tz.move

Рисует движущийся спрайт без анимации.


    tz.move spritesheet_index, pos.x, pos.y, start_frame, direction.x, direction.y

  • spritesheet_index — индекс инициализированного спрайтшита
  • pos.x — начальная координата X (в пикселях)
  • pos.y — начальная координата Y (в пикселях)
  • start_frame — начальный кадр спрайта
  • direction.x — направление движения по X (в формате 8.8 fixed-point)
  • direction.y — направление движения по Y (в формате 8.8 fixed-point)

tz.move_path

Рисует движущийся статичный спрайт по заданному пути.

    tz.move_path spritesheet_index, start_frame, path, path_offset
  • spritesheet_index — индекс спрайтового листа
  • start_frame — начальный кадр спрайта
  • path — метка импортированного файла пути
  • path_offset — смещение от начала пути

tz.anim_move

Рисует движущийся анимированный спрайт.

    tz.anim_move spritesheet_index, pos.x, pos.y, start_frame, anim_direction, direction.x, direction.y
  • spritesheet_index — индекс спрайтового листа
  • pos.x — начальная координата X (в пикселях)
  • pos.y — начальная координата Y (в пикселях)
  • start_frame — начальный кадр анимации
  • anim_direction — направление анимации
  • direction.x — направление движения по X (в формате 8.8 fixed-point)
  • direction.y — направление движения по Y (в формате 8.8 fixed-point)

tz.anim_move_path

Рисует движущийся анимированный спрайт по заданному пути.

    tz.anim_move_path spritesheet_index, start_frame, anim_direction, path, path_offset
  • spritesheet_index — индекс спрайтового листа
  • start_frame — начальный кадр анимации
  • anim_direction — направление анимации
  • path — путь движения
  • path_offset — смещение на пути

tz.trace

Рисование движущимся спрайтом по направлению движения

    tz.trace spritesheet_index, pos.x, pos.y, start_frame, direction.x, direction.y
  • spritesheet_index — индекс спрайтового листа
  • pos.x — начальная координата X (в пикселях)
  • pos.y — начальная координата Y (в пикселях)
  • start_frame — начальный кадр спрайта
  • direction.x — направление движения по X (в формате 8.8 fixed-point)
  • direction.y — направление движения по Y (в формате 8.8 fixed-point)

tz.trace_path

Рисованием движущимся спрайтом по заданному пути

    tz.trace_path spritesheet_index, start_frame, path, path_offset
  • spritesheet_index — индекс спрайтового листа
  • start_frame — начальный кадр спрайта
  • path — путь движения
  • path_offset — смещение на пути

Установщики

tz.set_color

Устанавливает цвет INK для последующих спрайтов.

	tz.set_color ink_color
  • ink_color — цвет INK, стандартные цвета ZX Spectrum. Можно задавать либо числом, либо константой (список констант см. в следующем разделе)

Параметр наследуется и используются во всех последующих рендерах.


tz.set_anim_speed

Устанавливает скорость анимации для последующих спрайтов.

    tz.set_anim_speed speed
  • speed — скорость анимации во фреймах, задаёт количество фреймов, через которые будет происходит смена фазы анимации (чем меньше значение — тем быстрее)

Параметр наследуется и используются во всех последующих рендерах.


Операции с экраном и его областями

tz.cls

Очистка теневого экрана (пиксели)

    tz.cls
  • Нет аргументов

tz.clear

Очищает пиксели в прямоугольной область экрана.

    tz.clear pos.x, pos.y, width, height
  • pos.x — координата X (в пикселях)
  • pos.y — координата Y (в пикселях)
  • width — ширина области (в ячейках)
  • height — высота области (в ячейках)

tz.set_bg

Устанавливает цвета PAPER и INK для фона.

    tz.set_bg paper_color, ink_color
  • paper_color — цвет PAPER
  • ink_color — цвет INK

Стандартные цвета ZX Spectrum. Можно задавать либо числом, либо константой.

BORDER устанавливается в цвет PAPER.


tz.attr

    tz.attr x, y, width, height, color
  • x — координата X в пикселях
  • y — координата Y в пикселях
  • width — ширина области в знакоместах
  • height — высота области в знакоместах
  • color — устанавливаемый цвет

Устанавливает атрибуты в заданном прямоугольнике.

Обратите внимание, что координаты задаются в пикселях, ширина и высота в знакоместах, а цвет задаётся для атрибутного прямоугольника, покрывающего заданную область.


Управление эффектами

tz.loop_for

Устанавливает новый эффект для зацикливания.

    tz.loop_for frames, effect_label
  • frames - количество фреймов, в течение которого будет проигрываться зацикленный эффект
  • effect_label — метка эффекта.

tz.change

Изменяет параметры эффекта.

    tz.change effect_label, <PARAM, value, PARAM, value, ...>
  • effect_label — метка эффекта
  • <PARAM, value, ...> — список параметров и их значений (см. константы параметров эффекта)

tz.repeat

Маркер конца сцены, зацикливает её, начиная проигрывать с начала.

    tz.repeat
  • Нет аргументов

tz.return

Возврат из модификатора в сцену на определённый эффект.

    tz.return effect_label
  • effect_label - метка эффекта, куда цикл вернётся после изменения параметра

Системные и прочие команды

tz.log

Вывод информации в консоль во время компиляции скрипта с указанием текущего адреса, по которому находится tz.log

    tz.log "Some debug information about current address"
  • Текст

tz.text

Вывод текста в консоль.

    tz.text "Any text"
  • Текст

Константы

Эти константы можно использовать вместо числовых значений для удобства задания некоторых параметров: цветов, направления анимаций и адресации к изменяемым параметрам в команде tz.change. В скобках указаны их алиасы — они равнозначны.

Цвета

TZ.TRANSPARENT (TZ.NOCOLOR) - Прозрачный цвет (если указан, спрайт рисуется без цвета, с текущим цветом в атрибутной области экрана)
TZ.BLACK - Чёрный
TZ.BLUE - Синий
TZ.RED - Красный
TZ.MAGENTA - Фиолетовый
TZ.GREEN - Зелёный
TZ.CYAN - Голубой
TZ.YELLOW - Жёлтый
TZ.WHITE - Белый
TZ.BLUE_BRIGHT (TZ.BRIGHT_BLUE) - Синий с яркостью
TZ.RED_BRIGHT (TZ.BRIGHT_RED) - Красный с яркостью
TZ.MAGENTA_BRIGHT (TZ.BRIGHT_MAGENTA) - Фиолетовый с яркостью
TZ.GREEN_BRIGHT (TZ.BRIGHT_GREEN) - Зелёный с яркостью
TZ.CYAN_BRIGHT (TZ.BRIGHT_CYAN) - Голубой с яркостью
TZ.YELLOW_BRIGHT (TZ.BRIGHT_YELLOW) - Жёлтый с яркостью
TZ.WHITE_BRIGHT (TZ.BRIGHT_WHITE) - Белый с яркостью

Направления анимации

TZ.FORWARD (TZ.F) - Вперёд (по возрастанию кадров)
TZ.BACKWARD (TZ.B) - Назад (по убыванию кадров)
TZ.RANDOM (TZ.R) - Случайные кадры (пока не реализовано)
TZ.IDLE (TZ.NO) - Статичный кадр анимации (может понадобиться, чтобы остановить анимацию, либо впоследствии заменить на активную; пока не реализовано)

Параметры модификаторов эффектов

Ниже перечислены эффекты и все доступные для них параметры для модификации.

tz.idle

TZ.IDLE.X - Координата X в пикселях
TZ.IDLE.Y - Координата Y в пикселях
TZ.IDLE.FRAME - Номер спрайта в спрайтшите

tz.anim

TZ.ANIM.X - Координата X в пикселях
TZ.ANIM.Y - Координата Y в пикселях
TZ.ANIM.FRAME - Номер спрайта в спрайтшите (он же - кадр анимации)
TZ.ANIM.SPEED - Скорость анимации во фреймах
TZ.ANIM.DIRECTION - Направление анимации

tz.move

TZ.MOVE.X - Координата X в пикселях
TZ.MOVE.Y - Координата Y в пикселях (целая часть)
TZ.MOVE.FRAME - Номер спрайта в спрайтшите
TZ.MOVE.DIR.X - Приращение движения по X (целая часть)
TZ.MOVE.DIR.X.FRAC - Приращение движения по X (дробная часть)
TZ.MOVE.DIR.Y - Приращение движения по Y (целая часть)
TZ.MOVE.DIR.X.FRAC - Приращение движения по Y (дробная часть)

tz.move_path

TZ.MOVE_PATH.FRAME - Номер спрайта в спрайтшите
TZ.MOVE_PATH.OFFSET - Смешение относительно начала траектории (пока не реализовано)

tz.anim_move

TZ.ANIM_MOVE.X - Координата X в пикселях
TZ.ANIM_MOVE.Y - Координата Y в пикселях
TZ.ANIM_MOVE.FRAME - Номер спрайта в спрайтшите (он же - кадр анимации)
TZ.ANIM_MOVE.SPEED - Скорость анимации во фреймах (начиная с 0)
TZ.ANIM_MOVE.DIRECTION - Направление анимации (TZ.F/TZ.B)
TZ.ANIM_MOVE.DIR.X - Приращение движения по X (целая часть)
TZ.ANIM_MOVE.DIR.X.FRAC - Приращение движения по X (дробная часть)
TZ.ANIM_MOVE.DIR.Y - Приращение движения по Y (целая часть)
TZ.ANIM_MOVE.DIR.X.FRAC - Приращение движения по Y (дробная часть)

tz.anim_move_path

TZ.ANIM_MOVE_PATH.FRAME - Номер спрайта в спрайтшите (он же - кадр анимации)
TZ.ANIM_MOVE_PATH.SPEED - Скорость анимации во фреймах
TZ.ANIM_MOVE_PATH.DIRECTION - Направление анимации
TZ.ANIM_MOVE_PATH.OFFSET - Смешение относительно начала траектории (пока не реализовано)

tz.trace

TZ.TRACE.X - Координата X в пикселях
TZ.TRACE.Y - Координата Y в пикселях (целая часть)
TZ.TRACE.FRAME - Номер спрайта в спрайтшите
TZ.TRACE.DIR.X - Приращение движения по X (целая часть)
TZ.TRACE.DIR.X.FRAC - Приращение движения по X (дробная часть)
TZ.TRACE.DIR.Y - Приращение движения по Y (целая часть)
TZ.TRACE.DIR.X.FRAC - Приращение движения по Y (дробная часть)

tz.trace_path

TZ.TRACE_PATH.FRAME - Номер спрайта в спрайтшите
TZ.TRACE_PATH.OFFSET - Смешение относительно начала траектории (пока не реализовано)

Соглашения и рекомендации по стилю кода

Рекомендуется не использовать в метках сцен, эффектов и модификаторов знак нижнего подчёркивания, в связи с особенностями обработки этого символа макросами sjasmplus. Вместо них можно использовать точку, либо camelCase. В имени файла знак подчёркивания можно использовать без ограничений.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment