Игра твит или как создать игру, которая уместится в один твит

игра твиттер

В далеком 1998 году люди соревновались, кто напишет самую короткую игру для DOS. Со временем это хобби назвали «код-гольфингом». Я решил вернуться к такому кусочку кода (nibbles.asm) и превратить его в загрузочный образ дискеты, который бы умещался в твит, то есть в 140 символов.Вот как выглядит результат.

В некоторых системах (например, Linux) ключ -D пишется в нижнем регистре ( base64 -d).

Это адаптированный перевод двух публикаций Алока Менхраджани: Bootloader + retro game in a tweet и Bootable CD + retro game in a tweet. Публикуется с разрешения автора. Перевел и адаптировал на русский язык Андрeй Письмeнный.

Образ загрузочной дискеты со «Змейкой»

Технически мой код — это не бутлоадер. Настоящий бутлоадер переводит машину с x86 в защищенный режим, загружает информацию с диска (BIOS загружает только первые 512 байт) и так далее. Я пропустил все это и вместо этого задаю некоторые регистры и прыгаю прямо в игру.

hugi.de

Один из популярных сайтов, где проходили эти соревнования, назывался Hugi, и игра Nibbles, которую Altair и ODDS entertainment уместили в 48 байт, была одним из моих любимых творений. Данная игра также широко известна как Tron и «Змейка».

РЕКОМЕНДУЕМ:
Лучшие игры для программистов

К моему большому сожалению, старый код оказалось не так-то просто заставить работать. Нужен DOS, и если работать с эмулятором, то приходится догадываться, какое железо могло тогда быть у разрабов и на какой частоте все это работало.

По-сему я решил взять код Altair и сделать из него загрузочную дискету. По ходу сделал несколько изменений, чтобы можно было нормально поиграть.

floppy.asm

Итак, давайте разберем код.

Для запуска кода его нужно сначала скомпилировать:

После чего запустить в QEMU, если у вас по каким-то причинам нет возможности записать на настоящую дискету:

Код начинается с прагмы, которая сообщает процессору, что нужно перейти в шестнадцатиразрядный режим (в нем машина x86 изначально находится при загрузке с флоппи).

Еще одна прагма сообщает ассемблеру, где находится код, который необходимо загрузить.

Задаем начальную позицию для нашей змейки.

Загружаем адрес VRAM в регистр ES.

Теперь задаем позицию червя в центре экрана и переключаем видеорежим. Режим 13h — это VGA (1 байт на пиксель, тогда как настоящий цвет хранится в палитре), общий размер 320 на 200. При рестарте сразу же очищаем экран.

Рисуем границы. Предполагаем, что палитра по умолчанию нас устроит. Также предполагаем, что если мы начнем снизу и закрасим 2176 пикселей, то получатся границы снизу и сверху.

Обратите внимание на переход в середине инструкции rep stosb.

В основном цикле мы читаем ввод с клавиатуры на порте 0x60. Сюда же попадает ввод мыши, но нам необходимо обрабатывать только «вверх» (0x48), «влево» (0x4b), «вправо» (0x4d) и «вниз» (0x50).

В конце регистр BX будет содержать сдвиг позиции (+1, -1, +320, -320) в зависимости от нажатой/отпущенной клавиши на клавиатуре. Я почти уверен, что тут можно срезать пару байтов, учитывая, что мы выше уже проверяли края.

Изначально тут использовалась команда, которая задавала палитру (10h/0bh), чтобы подождать вертикальной перерисовки. Теперь компьютеры слишком быстры, так что мы вместо этого используем 15h 86h. Это заодно сэкономит нам пару байтов.

Обратите внимание: вам понадобится твикнуть cx+dx, чтобы запускать этот код в виртуальной машине, а не на реальном железе. Практика показывает, что виртуалки ждут в три-четыре раза дольше, чем реальное железо.

Рисуем змейку и проверяем достижение коллизий (четное равенство означает коллизию).

Возвращаемся в основной цикл.

Мы столкнулись со стеной или с хвостом. Начинаем заново.

Забиваем остаток сектора нулями. Значение 0xaa55 — это подпись в конце загрузчика.

Код в твите создает загрузочный файл boot.img. Можно загрузить его в QEMU или VirtualBox и играть в игру стрелочками. Или можно записать все это на дискету и загрузиться с нее по-настоящему.

Игра твит

Образ загрузочного компакт-диска

С тех пор как я сделал загрузочный флоппи, в «Твиттере» расширили лимит длины вдвое, так что я решил сделать своими руками образ загрузочного компакт-диска. На нем будет работать улучшенная версия нашей «Змейки».

Этот код создает образ загрузочного компакт-диска cd.iso. Как и образ дискеты, его можно отправлять в QEMU или VirtualBox, загружаться и играть.

Чтобы вручную сделать образ CD, сначала нужно разобраться со стандартом ISO 9660. К сожалению, доступ к стандартам ISO недешев, но, по счастью, этот существует в варианте ECMA 119, где и можно бесплатно позаимствовать все спецификации.

У ISO 9660 много всяких дополнений, например UDF, El Torito, RockRidge, Joliet и так далее. В случае с загрузочными образами нас интересует только El Torito. Однако его спецификация, на мой взгляд, одна из самых плохо написанных. В ней есть ошибки (смотри, например, последнюю строчку на рисунке 7), легко забыть, что все значения — шестнадцатеричные (нет префиксов 0x), картинки стоят в неочевидном порядке и так далее. Одно хорошо — документ короткий.

Чтобы создать загрузочный диск, нам понадобится сначала сделать 17 пустых секторов, за которыми будет идти набор дескрипторов тома (Volume Descriptor Set). Сектор составляет 2048 байт.

Обратите внимание: по спецификации ISO 9660 дескрипторы тома должны начинаться с сектора 16. А вот по El Torito загрузочная запись должна проживать в секторе 17. Технически это значит, что нужно поместить в шестнадцатом секторе пустой дескриптор тома в качестве заглушки, но все вроде бы работает и без этого.

Итак, пишем дескриптор тома.

Следующий сектор — это терминатор набора дескрипторов тома (Volume Descriptor Set Terminator).

За дескрипторами томов следует загрузочный каталог (Boot Catalog). El Torito поддерживает разные режимы эмуляции. Компакт-диск может эмулировать загрузочный флоппи, загрузочный жесткий диск и так далее. Я выбрал вариант без эмуляции — в этом случае подразумевается, что BIOS загрузит определенное число секторов и передаст управление нашему бутлоадеру.

Контрольная сумма вычисляется таким образом, чтобы все шестнадцатибитные значения в записи давали в сумме ноль (mod 65536).

Вот первая запись в загрузочном каталоге (Validation Entry).

Вторая запись (Default Entry):

Дальше идут нули до конца сектора.

Дальше идет бутлоадер игры, ниже — он целиком. Никаких отличий от флоппи-версии здесь нет.

Дальше мне оставалось только написать скрипт для компиляции загрузчика, сборки образа и создания текста твита. Закончив со всем этим, я прожег результат на болванку и потестировал на реальном железе.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий