Gamedev
Andrey Apanasik
908

Полигоны Another World: Atari ST

Это третья статья из серии про портирование игры Another World. В ней пойдёт речь про хитрости при работе с Atari ST. Рекомендуется сначала прочитать предыдущие статьи.

В закладки
Аудио

Зарождение Atari ST было, мягко говоря, неспокойным. Всё начинается как в сказке, а заканчивается войной и предательствами при участии Amiga Corp, Commodore, Atari и Atari Computer.

Серия статей

История ATARI ST

В 1983 году Hi-Toro был стартапом из Санта-Клары, разрабатывающим игровую консоль под названием «Lorraine». Обладая мощным 68000 с потрясающими графическими возможностями, он был технологическим чудом, намного превосходящим всех своих конкурентов. У Hi-Toro, однако, заканчивались деньги. Atari, тогда гигант видеоигр, вложил 500 000 долларов для продолжения разработки в обмен на право добавить клавиатуру и продавать консоль как компьютер.

Вдали от Калифорнии, в Пенсильвании, борьба за власть в Commodore привела к уходу основателя Джека Трамиэля. Он сразу же основал компанию Tramel Technology, в процессе переманивая инженеров Commodore. Излишне говорить, что разделение было далеко не дружеским.

К середине 1984 года настала очередь Атари переживать финансовые потрясения. Когда Джек Трамиэль выразил заинтересованность в покупке компьютерного подразделения Atari, в Commodore увидели возможность выступить против своего бывшего генерального директора. Они купили Hi-Toro (которая к тому времени была переименована в Amiga Corporation), и только вернули Atari их «кредит»[1].

Трамиэль завершил сделку по приобретению Atari Computers и немедленно подал в суд на Amiga Corporation. Этот вопрос не будет решён до марта 1987 года[2]. Между тем Atari оказалась без новых технологий, которые бы помогли снова стать прибыльной[3].

Некоторое время Джек Трамиэль рассматривал возможность покупки Genesis у Sega, которая искала партнёра с опытом работы в Северной Америке. В конечном итоге идея была отклонена. Что произошло дальше, рассказывает DadHacker[4][5]. Джек оставил только 900 из 10 000 сотрудников Atari. Оставшиеся же участвовали в марше смерти с целью разработать и выпустить новую машину в течение года.

Удивительно, но у них получилось. Atari ST была выпущен в июне 1985 года, выйдя на рынок на месяц раньше, чем Amiga 1000.

Устройство было хорошо принято пользователями. К ноябрю 1985 года Джек Трамиэль объявил, что Atari реализовала 50 000 единиц. Цена удивляла. 520ST продавался за 999 долларов, а Amiga 1000 за 1285.

Выбирая из двух машин с одинаковым процессором и одинаковым объёмом оперативной памяти, дополнительные 300 долларов не стоили того. Многие потребители выбрали ST.

Помимо основного ценового преимущества, у машины есть несколько примечательных преимуществ перед конкурентами. Монохромный режим с высоким разрешением 640x480 был идеален для программистов. Встроенный интерфейс MIDI был оценен музыкантами. Небольшая деталь, которая могла иметь значение, операционная система (TOS) и ядро были на самом деле в ПЗУ. Не было необходимости в загрузке с дискеты!

Atari ST быстро собрала культ последователей, особенно в Европе. Создатели демо-сцены одержимо пытались разработать методы оверсканирования[6][7][8][9] для удаления границ чёрного экрана. В конечном итоге эти попытки увенчались успехом[10].

В течение своей жизни, с 1985 по 1993 год, Atari Computers продала 2 миллиона устройств[11]. Многим, кто пережил эту эру, она запомнилась как печально известная война Amiga против Atari ST.

Atari STE

С точки зрения компьютерной графики, анимации и видеоигр войны, как таковой, не было. Это даже сложно назвать битвой. Благодаря своим сопроцессорам Agnus и Denise, Amiga значительно превзошла Atari ST. Например, работа с памятью фреймбуфера Atari ST была мучительной при попытке перемещения спрайта по экрану.

Чтобы смягчить свои недостатки, Atari Computers обновила линию Atari ST в 1989 году, выпустив 520 STE и 1040 STE. Среди улучшений: Genlock, 12-битные цвета, PCM-аудио и, что самое важное, BLiTTER[12]. Эти новшества сделали Atari ST технологией, позволившей конкурировать с Amiga.

Архитектура

Возможности блиттера были неоценимы для разработчиков игр. К сожалению, он появился слишком поздно. У Atari ST была огромная база, мешавшая разработчикам тратить время на то, чтобы сделать их игру лучше для небольшого числа пользователей. Не говоря уже о том, что никто не осмелился выпустить игру эксклюзивно на STE. Another World не исключение, как утверждает разработчик Jaguar версии (который видел исходный код Atari ST).

Another World был полностью запрограммирован для запуска на 68000. Возможности STE не использовались вообще.

Sébastien Briais

Обратите внимание, что на всех Atari ST есть контроллер DMA, но он может переносить только с дискеты/жёсткого диска в оперативную память, что не сильно помогало при разработке игр. Программистам оставалось не так много. А именно процессор Motorola 68000 с тактовой частотой 8 МГц и оперативной памятью 512 КиБ.

Видео система

Чип GLUE, отвечающий за генерацию видеосигнала, использует 3 бита на канал (9 бит на пиксель), что даёт 512 цветов.

На заметку: именно манипулируя Shifter, GLUE и MMU, демомейкер сумел убрать печально известные чёрные границы экрана Atari. Техники «overscan» и «fullscreen» переключают частоту обновления между 50 Гц и 60 Гц, а также переходят от hiRes к LowRes до завершения сканирования линии, чтобы заставить GLUE задерживать сигналы VSYNC/HSYNC[13]!

Another World на Atari ST

Another World под Atari ST был полностью написан Эриком Шайи параллельно с версией для Amiga. Процессор 68000, аналогичный Amiga, облегчил порт, так как большую часть VM ASM можно было переиспользовать. Были отличия в графической части, где доступны три режима. Высокое разрешение (640x400 2 цвета), которое отлично подходит для программирования, среднее разрешение (640x200 4 цвета), которое не очень интересно в этом контексте, и низкое разрешение (320x200 16 цветов[14]), которое идеально подходило для Another World.

Все разрешения используют 32 КБ на каждый фреймбуфер. Здесь нет битпланов, как на Amiga, которые были упомянуты в прошлой статье. В высоком разрешении каждый бит соответствует пикселю. В низком разрешении индекс пикселя разбит на 4 бита, распределённых по 64 битам.

Небольшой ад

Для игры, использующей спрайты, подобная низкоуровневая компоновка была проблемой. Попробуйте представить себе задачу по использованию маски/записи с разрешением в один бит, когда разрешение шины составляет один байт (8 бит). Теперь представьте, как спрайт пересекает границу байтов, и задача превращается в кошмар[15]. Нагрузка на CPU была такой большой, что игры не использовали маску/запись и вместо этого предпочитали использовать предварительно повёрнутые спрайты (один набор для каждого выравнивания битов), что, к чести Atari ST, не было слишком большой проблемой, учитывая щедрое количество оперативной памяти на борту.

Интересно, что в Another World ад чередующихся графических слоёв превращается в рай, когда речь заходит об отрисовке длинных линий одного цвета. Посмотрим почему.

FILL и COPY

Имея только процессор для выполнения FILL и COPY, эта задача выполняется самым простым способом. Здесь нет хитрого трюка, но неплоская компоновка фреймбуфера позволяет 68000 «путешествовать». С кадровым буфером на 32 КБ операции move.l длиной 8000 (32 бита) выполняют работу в обоих случаях. Задисамблированный вывод части COPY операции на 68000-й выглядит следующим образом.

... move.w #49,d0 ;50*160*4 = 32000 octets .copy_loop: rept 160 move.l (a1)+,(a0)+ endr dbra d0,.copy_loop ...

Поскольку тайминг 68000 очень хорошо задокументирован[16][17], мы можем точно рассчитать, сколько времени необходимо на выполнение операции COPY. Поскольку для move.l требуется 20 циклов, общее числу требуемых циклов составляет 20 * 160 * 50 = 160 000 циклов. При скорости 8 000 000 циклов/с COPY занимает 20 мс.

Та же идея для FILL, за исключением того, что вместо операнда «Address register indirect with post-incrementing» первый операнд команды move.l представляет собой «Data direct», который занимает «только» 12 циклов. Это даёт в общей сложности 12 мс для FILL.

... move.w #49,d0 ;50*160*4 = 32000 octets .fill_loop: rept 160 ; d1 = color repeated 8 times since d1=32 bits and color index=4 bits) move.l d1,(a0)+ endr dbra d0,.fill_loop ...

На заметку: вы можете легко отличить версию для Atari ST от Amiga версии, если посмотрите на второй игровой экран.

Милый скарабей, встречающийся в версии на Amiga, исчез на Atari ST. На самом деле, он отсутствует во всех других портах[18], что делает его эксклюзивом Amiga по какой-то неясной причине.

Решение проблемы с отрисовкой

Без режимов «line drawing» и «area filling» порт под Atari ST использует простой алгоритм Брезенхэма[22] для отслеживания рёбер многоугольника. С двумя рёбрами и горизонтальными линиями создаются начальные и конечные координаты пространства экрана. Затем 68000 заполняет пространство между ними[19]. В целом принцип работы похож на блиттер Amiga, за исключением того, что здесь всё сделано программно.

Подход на первый взгляд очень медленный, но «крейсерская скорость» также может быть достигнута здесь, используя преимущества woven layout. Если вы посмотрите внимательно, большинство кадров Another World состоят из длинных горизонтальных линий одного цвета. Это позволяет 68000 писать строки в блоке из 16 пикселей с помощью инструкции move.l, которую мы рассмотрели ранее.

Экран, где Лестер встречает своего «спасителя», является хорошим примером.

Здесь мы видим, выделенные красным, части линий, которые не могут быть отображены в 16-пиксельных блоках из-за расположения и выравнивания фреймбуфера. Эти «медленные» пиксели составляют только 23% фреймбуфера на краю полигонов. 77% фрейм буфера рендерится с «быстрой» 16-пиксельной записью блоков.

Решение проблемы с палитрой

Последняя проблема, которую нужно решить, связана с тем, что Atari ST имеет небольшую глубину цвета. В то время как Amiga допускает 12 бит на цвет, AtariST может дать только 9.

Решение состояло в том, чтобы поставить игру с палитрами Amiga и позволить 68000 позаботиться о преобразовании из 12-битного в 9-битный с простым 1-битным сдвигом (LRS) для каждого канала во время загрузки.

Итоговая картинка выглядит немного темнее по сравнению с Amiga, но разница едва заметна[20].

В заключение

Несмотря на очевидные недостатки, Atari ST удалось запустить точную версию Another World. Несмотря ни на что, игра не должна отклоняться от версии под Amiga. Меньшее цветовое пространство было едва заметно, и движок работал лишь немного медленнее[21], чем на Amiga (которая работала почти со скоростью 24 кадра в секунду).

Ссылки

Материал опубликован пользователем.
Нажмите кнопку «Написать», чтобы поделиться мнением или рассказать о своём проекте.

Написать
{ "author_name": "Andrey Apanasik", "author_type": "self", "tags": ["\u0440\u0435\u0432\u0435\u0440\u0441\u0438\u043d\u0436\u0438\u043d\u0438\u0440\u0438\u043d","\u043f\u0430\u043b\u0438\u0442\u0440\u0430","outofthisworld","atarist","atari","anotherworld","49"], "comments": 9, "likes": 41, "favorites": 78, "is_advertisement": false, "subsite_label": "gamedev", "id": 95847, "is_wide": false, "is_ugc": true, "date": "Thu, 23 Jan 2020 08:01:27 +0300", "is_special": false }
0
{ "id": 95847, "author_id": 1922, "diff_limit": 1000, "urls": {"diff":"\/comments\/95847\/get","add":"\/comments\/95847\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/95847"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }
9 комментариев
Популярные
По порядку
Написать комментарий...
2

Отличная статья, спасиб

Ответить
1

На первый взгляд выглядит нормально, но если почитать внимательнее, то очевидно, что аффтар перевода нихуя не понимает, что переводит:

 Здесь нет хитрого трюка, но неплоская компоновка фреймбуфера позволяет 68000 «путешествовать». С кадровым буфером на 32 КБ операции move.l длиной 8000 (32 бита) выполняют работу в обоих случаях.

 Та же идея для FILL, за исключением того, что вместо операнда «Address register indirect with post-incrementing» первый операнд команды move.l представляет собой «Data direct», который занимает «только» 12 циклов. Это даёт в общей сложности 12 мс для FILL.

Полная ахинея.

Ответить
0

Буду рад помощи от специалистов по Atari. Спасибо.

Ответить
0

Я не буду за тебя переводить, сам старайся.

 операции move.l длиной 8000 (32 бита) 

Это не длина операции, а максимальная дальность перехода в пределах 32-битного адресного пространства.

 выполняют работу в обоих случаях

В каких? Ответ в заголовке оригинала - операции fill и copy.

 операнд команды move.l представляет собой «Data direct», который занимает «только» 12 циклов

Не операнд, а команда, и не "занимает", а "требует". Fill выполняется за 12 циклов.

Ответить
1

 В то время как Amiga допускает 12 бит на цвет, AtariST может дать только 9.

Не на цвет, а на пиксель, недопереводчик. 12 бит на цвет даже современные мониторы не дают. Даже ниже у тебя про это написано:

 преобразовании из 12-битного в 9-битный с простым 1-битным сдвигом (LRS) для каждого канала во время загрузки

Ответить
0

Не на цвет, а на пиксель

На цвет каждого пикселя, 3 на каждый канал.
недопереводчик

Что ж.

Ответить
0

У тебя пиксель из трёх цветов формируется. По 4 бита на каждый цветовой канал у одного компьютера и по 3 бита у другого.

Ответить
0

Ну да, я выше так и написал. 3 бита на каждый канал -> 9 бит в сумме.

Ответить
0

Нифую не понятно, но очень интересно(звиняйте, забыл взять мем)

Ответить

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "Article Branding", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "cfovz", "p2": "glug" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Баннер в ленте на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 16, "label": "Кнопка в шапке мобайл", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "chvjx", "p2": "ftwx" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } }, { "id": 20, "label": "Кнопка в сайдбаре", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "chfbl", "p2": "gnwc" } } } ]
{ "jsPath": "/static/build/dtf.ru/specials/DeliveryCheats/js/all.min.js?v=05.02.2020", "cssPath": "/static/build/dtf.ru/specials/DeliveryCheats/styles/all.min.css?v=05.02.2020", "fontsPath": "https://fonts.googleapis.com/css?family=Roboto+Mono:400,700,700i&subset=cyrillic" }