Существует интересный способ изучения архитектуры компьютеров прошлого. Найти знакомую вам программу и попытаться выяснить, как она была портирована.


Хорошим выбором для этого мог бы стать DOOM. Мегахит 1994 года от id Software был портирован на всё, что только можно. Игра спроектирована вокруг ядра, чётко разделённого на слои. Обычно легко найти и прочитать реализацию шести подсистем ввода-вывода.


Другим выбором могла бы стать Another World 1991 года от Эрика Шайи, в Северной Америке более известная под именем Out Of This World. Я бы сказал, что на самом деле её интереснее изучать, чем DOOM, из-за полигональной графики, подходящей для диких оптимизаций. В некоторых случаях хитрые трюки позволяли игре работать на оборудовании, созданном за пять лет до выхода игры.




  1. Полигоны Another World.
  2. Полигоны Another World: Amiga 500

Эта серия статей представляет собой путешествие по оборудованию для видеоигр начала 90-х. От Amiga 500, Atari ST, IBM PC, Super Nintendo, до Sega Genesis. Для каждой машины я пытался узнать, как реализована Another World.


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


Another World 101


В Another World довольно мало кода. В первоначальной версии для Amiga, как сообщалось, было всего 6000 строк. Исполняемый файл для DOS под PC составляет всего 20 кБ. Удивительно для такой огромной игры, которая поставлялась на одной дискете 1.44 MiB. Всё потому, что большая часть бизнес-логики реализована с помощью байт-кода. Исполняемый файл Another World фактически является хостом виртуальной машины, читающим и выполняющим uint8_t опкоды.




Виртуальная машина в Another World определяет 256 переменных, 64 потока, 29 опкодов и три фреймбуфера (перевод от PatientZero). Вот и всё. Если вы создадите хост для виртуальной машины, способный справиться с этим, вы сможете запустить игру. Если вы можете сделать виртуальную машину достаточно быстрой, чтобы работать со скоростью 20 кадров в секунду, вы в действительности сможете сыграть в игру.


Графическая система виртуальной машины использует систему координат 320x200 с 16-цветовой палитрой. Ограничение на палитру может удивить, учитывая, что Amiga 500 поддерживает до 32 цветов. Это было сделано целенаправленно, что позволило совместить графику с другой крупной платформой того времени — Atari ST, которая поддерживает только 16 цветов.


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














Даже когда была возможность использовать определённую палитру для сцены, Эрик Шайи решил не делать этого. Во время столкновения с «Чудовищем» для оного используются всего три цвета: черный для тела, красный для глаз и бежевый для зубов. Воображение сделало остальное.






Подобная система для палитры полноценно раскрылась в начальной сцене. Весьма дешёвая смена палитры позволила легко изобразить удар молнии.










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



Здесь цвета хранятся в пределах [0x0,0x8].






Лучи от фар Ferrari полупрозрачны. Они нарисованы специальным цветом 0x10, которго не существует, поскольку доступно только 16 цветов. Специальное значение интерпретируется как «прочитать индекс кадрового буфера, добавить 0x8 и вернуть». Последняя часть трюка заключается в умном выборе следующих 8 цветов в палитре.


Прозрачность использовалась в игре не так часто,


но её можно увидеть ещё раз во время эксперимента,


когда молния вот-вот телепортирует Лестера в Другой Мир.






Три фреймбуфера


Из трёх фреймбуферов два используются для двойной буферизации, в то время как последний используется для сохранения фоновой (BKGD) композиции. Эта оптимизация позволяет избежать перерисовки всех полигонов статических фонов в пользу простой операции копирования.


В следующем видео посмотрите, как новая сцена рисуется сначала в BKGD буфере. Каждый новый кадр BKGD полностью копируется в двойной буфер. Там движущиеся элементы, такие как Лестер, отрисовываются. Обратите внимание, что после того, как автомобиль «припаркован», он также рисуется в BKGD буфере, чтобы минимизировать количество полигонов, которые будут отрисованы в последующих кадрах.



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


Опкоды виртуальной машины


В следующей таблице представлено 29 опкодов. Здесь можно найти опкоды по управлению потоками (THRD), управлению фреймбуферами (FB) и все операции управления регистрами. Большинство операций «просты» в реализации, за исключением «COPY FB», «FILL» и «DRAW_POLY*», которые сложны в плане производительности.




Оба DRAW_POLY_* опкода охватывают более одной ячеки. DRAW_POLY_BACKGROUND занимает половину пространства опкодов — от 0x80 до 0xFF. Весьма расточительно, но это уловка для экономии места. Использование всех операций, начинающихся с бита «1», позволяет 7 другим битам переноситься в пространство опкодов в качестве параметров отрисовки. Поскольку этот опкод используется для фона и синиматиков, экономия места очень важна.


SPRITE версия использует все опкоды, начинающиеся с битов «01», в то время как остальные оставшиеся 6 битов предназначены для кодирования [x, y] координат и зума для отрисовки «спрайтов» Лестера, друга и врагов.


Что дальше?


Как упоминалось ранее, 26 из 29 опкодов легко реализовать. Реальная проблема при портировании этой игры заключалась в манипулировании пикселями в пределах ограничений шины и пропускной способности процессора. В этой серии будет рассмотрено, как при порте происходила манипуляция фреймбуферами и как решались проблемы DRAW, FILL и COPY опкодов.

Комментарии (9)


  1. unbeliever
    05.01.2020 06:09
    +2

    Хороший перевод, спасибо!

    Чтобы понять, насколько продвинулась история про полигоны, достаточно посмотреть релиз 2019 года для этой же машины:

    <iframe width="560" height="315" src="https://www.youtube.com/embed/i1O4_58HVIg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

    Для настоящих ценителей — живой показ на пати: www.youtube.com/watch?v=zwoyfH7TgEQ&t=54m28s


  1. unbeliever
    05.01.2020 06:16

    До чего довел Хабр проклятый ПеЖе! ©

    Даже в моей молодости можно было YouTube в коменты вставлять…


    1. DreamingKitten
      05.01.2020 06:22
      +4


    1. perfect_genius
      07.01.2020 13:25

      В мобильной версии нет предпросмотра?


  1. v1000
    05.01.2020 20:09

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


    1. Keynessian
      05.01.2020 20:23

      Тут не только полигонов мало, тут ещё и звуковые возможности — крайне скромные, но из них выжато всё.


    1. khim
      05.01.2020 20:50
      +5

      Так фишка же не в том, что полигонов мало! Фишка в том, что тут каждый полигон — на своём месте.

      Точно также как и с пиксельартом: фишка его не в том, что пикселей мало — а в том, что положение каждого — просчитано.

      Попытки «по-быстрому» сотворить закос на пиксель-арт приводит к тому, что смотреть на это… не очень хочется. Думаю и с полигонами тоже самое будет, если тупо пытаться вместиться в их мизерное число…


  1. Jeyko
    06.01.2020 20:46
    +1

    Всплакнулъ… кстати, так до конца не осилил ее в свое время. Может стоит попробовать опять, через тридцать лет?.. Определено. И сейчас только заметил, что фары не настроены у машины. Вообще. Спасибо за статью! Огромные временные пласты сдвинулись, пошатнулись и разверзлись горы воспоминаний…


    1. perfect_genius
      07.01.2020 13:28

      Таки стоит пройти, она короткая. Эдакий Half-Life того времени, молчаливая непрерывная подача истории прямо на ходу.