[Перевод] История ретро-консолей с точки зрения программиста, часть 2

image-loader.svg

Мы продолжаем обзор игровых консолей с точки зрения истории их развития. В прошлый раз мы остановились на 1990-ых годах — времени NEC TurboGrafx-16, Nintendo SNES и Sega Genesis. Сегодня продолжим с этого момента и поговорим о том, как на рынке игровых консолей появились Sony и Microsoft, о «шейдерной революции» и многом другом.

Пятое поколение (1993–2006): 32 бита

Пятое поколение консолей отличалось уже 32 битами взамен прежних 16. Этот переход открыл консолям доступ к экспоненциально большему количеству адресов памяти и возможность запускать игры на значительно более высокой тактовой частоте процессора.

Персональные компьютеры снова стали оказывать сильное давление на рынок домашних консолей: теперь ПК располагали быстрыми процессорами, да и аппаратное ускорение GPU тоже начинало претворяться в жизнь. Вслед за этим консоли были вынуждены сделать шаг вперед и выводить на экран не только быстрые пиксели, но и 3D-полигоны в реальном времени.

В пятом поколении только ворвавшаяся на рынок консолей Sony со своей оригинальной PlayStation тут же стала одним из главных игроков. Однако, если идти в хронологическом порядке, основными консолями этого поколения стали Sega Saturn, Sony PlayStation и Nintendo 64.

Основные консоли 32-битного поколения: Sega Saturn, Sony PlayStation и Nintendo 64Основные консоли 32-битного поколения: Sega Saturn, Sony PlayStation и Nintendo 64

В то время получили распространение и некоторые другие немаловажные технологии. Цена оптических дисков (CD-ROM) упала настолько, что производители игровых консолей тоже положили глаз именно на них. К тому времени диски уже использовались для дистрибьюции игр для ПК, но именно PlayStation популяризировала их использование для консольных игр.

Jet Moto демонстрирует реализацию 3D-полигонов на PlayStationJet Moto демонстрирует реализацию 3D-полигонов на PlayStation

При этом Nintendo 64 по-прежнему использовала игровые картриджи: преимущества картриджей перед CD-ROM во времени загрузки все еще казались компании более существенными, ровно как и возможность использования механизмов защиты авторских прав.

Кроме того, в пятом поколении наконец-то произошли подвижки в том, как программируют игры: с увеличением скорости работы процессора и ростом мощности компиляторов свое место в разработке игр занял язык C. 

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

И, конечно, стоит поговорить подробнее об используемых в этом поколении 32-битных процессорах, основанных на архитектуре RISC.

CISC против RISC

RISC и CISC — это два разных подхода к архитектуре процессоров. RISC расшифровывается как «компьютер с сокращенным набором команд» (Reduced Instruction Set Computer). Работа этой архитектуры основана на уменьшении количества циклов на инструкцию ценой увеличения количества инструкций в программе. CISC же расшифровывается как «компьютер со сложным набором команд» (Complex Instruction Set Computer). Она, в свою очередь, пытается минимизировать количество инструкций на программу, но ценой увеличения количества циклов на инструкцию.

image-loader.svg

И Motorola 68000, и Intel x86 основаны на архитектуре CISC. CISC выполняет множество низкоуровневых операций на одну инструкцию, что делает CISC-ассемблер компактнее и проще для понимания

Процессор NEC VR4300 на Nintendo 64 разработан на базе RISC. Инструкции RISC выполняются быстрее, обычно занимая всего один тактовый цикл. Однако, простые инструкции означают более длинные программы. Поэтому, возможно, писать RISC-ассемблер вручную более утомительно, но при этом он работает более эффективно и потребляет меньше энергии.

image-loader.svg

CISC-инструкции содержат много функций и требуют для выполнения множество тактов процессора. Инструкции RISC коротки и обтекаемы, но требуют меньше циклов процессора для выполнения.

В качестве примера рассмотрим следующий. Пусть у нас будет CISC-процессор, в котором есть встроенная инструкция для вычисления факториала числа, загруженного в регистр A. Для простоты назовем эту ассемблерную инструкцию FACT.

-- Factorial of 6 on CISC
LOAD A, 6
FACT A

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

-- Factorial of 6 on RISC
LOAD A, 6
MUL 5
MUL 4
MUL 3
MUL 2

Вероятно, вы наслышаны о процессорах ARM, на которых работают мобильные телефоны и планшеты. Они разработаны на базе RISC, и именно такие процессоры стали популярным решением для мобильных устройств и энергоэффективного оборудования. Чипы Apple M1 как раз основаны на ARM/RISC.

Написание ассемблера вручную было обычным делом в 1989 году, но сегодня всем очевидны преимущества более простой, эффективной и оптимизированной архитектуры RISC. Если учесть, что сегодня код на ассемблере преимущественно генерируется компиляторами, а не людьми, можно сказать, что архитектура RISC опередила свое время.

Прошивка

Еще одна важная вещь, которая произошла с приходом 32 бит — это появление некого программного пласта между разработчиком и устройством. На предыдущих консолях еще не существовало концепции операционной системы, стоящей между разработчиком и машиной, и мы имели прямой доступ к аппаратному обеспечению. В 32-битном поколении появилась идея прошивки, представляющей из себя легкую ОС для консоли.

Это нововведение стало необходимо по мере того, насколько сложными становились консоли. ОС выступала в роли посредника между кодом и железом, позволяя программисту использовать низкоуровневую функциональность. Такие компании, как Sony и Nintendo, также предоставляли своего рода SDK и библиотеки программирования, которые разработчики должны были использовать для создания игр для своих консолей.

3D-полигоны

Пятое поколение также ознаменовалось бурным ростом числа 3D-игр. Используя преимущества выделенных чипов для рендеринга полигонов, новые 32-битные консоли теперь могли работать с быстрыми полигонами и рендерить 3D-графику в реальном времени. Конечно, речь идет о низкополигональных 3D-сетках и текстурах низкого разрешения, но и это было огромным прогрессом.

Разработанная Nintendo Super Mario 64 стала первой 3D-игрой про Супер МариоРазработанная Nintendo Super Mario 64 стала первой 3D-игрой про Супер Марио

Графические процессоры

Возможность эмулировать консольные игры на ПК всегда имела большое значение для геймеров. Проделывать это с играми предыдущих поколений на домашнем компьютере технически было не так уж сложно, поскольку большинство процессоров ПК того времени могли отображать 2D-пиксели и вычислять 2D-эффекты с помощью ПО. Но консоли пятого поколения теперь поставлялись со сложным специализированным оборудованием для обработки полигонов, так что эмулировать такие игры только при помощи процессора для ПК стало уже куда сложнее.

Некоторые компьютерные эмуляторы для PlayStation и Nintendo 64 использовали преимущества аппаратного ускорения. И если вы хотели ощутить всю мощь 3D-игр поздних версий PlayStation или Nintendo 64, скорее всего, вам нужно было установить в компьютер GPU.

image-loader.svg

Одним из пионеров того времени в области ускорения графики была компания 3Dfx, пробившаяся на рынок ПК благодаря знаменитому графическому процессору Voodoo. Чтобы воспользоваться преимуществами этой GPU, программисты использовали библиотеку под названием Glide, разрабатываемую и распространяющуюся самой 3Dfx.

Именно поэтому с целью эмуляции рендеринга полигонов консольного уровня на компьютерном GPU часто прибегали к помощи Glide API. Если вы когда-либо устанавливали такие эмуляторы, как Bleem! или ePSXe для Windows, вам, вероятно, приходилось искать правильную версию DLL Glide API для вашей системы. Эти DLL содержат реализацию функций, открытых 3Dfx, которые эмулятор может использовать для доступа к графическому процессору.

Чтобы получить представление о том, как работают GPU, давайте рассмотрим очень простой пример.

Представим, что мы разрабатываем игру для консоли с процессором, работающим на частоте 7,6 МГц (7,6 миллиона инструкций в секунду), и разрешением экрана 320×224. В общей сложности это 71 680 пикселей для одного кадра нашей игры.

image-loader.svg

Теперь представьте, что на одном из уровней нам нужно преобразовать определенную сцену в серый цвет. Используя только инструкции процессора, нам, вероятно, понадобится цикл while-loop для охвата каждого пикселя экрана и изменения их одного за другим. А это 71 680 пикселей на кадр! И помните, что мы находимся внутри игрового цикла, поэтому все это должно происходить 60 раз в секунду.

Даже если предположить, что каждая операция с пикселями занимает всего один тактовый цикл, то, если 71 680 циклов умножить на 60, это дает нам в общей сложности 4,3 миллиона инструкций за одну секунду. А это более половины того, что может обработать наш процессор с частотой 7,6 МГц.

Теперь давайте рассмотрим ту же проблему, но попробуем решить ее с помощью графического процессора. В отличие от CPU, GPU содержит десятки и даже сотни маленьких ядер. Наличие этих ядер означает для нас одно: возможность параллельной обработки большого числа данных.

Помимо наличия нескольких ядер, стоит отметить еще одно преимущество: GPU любят работать с массивами. Поэтому вместо того, чтобы выполнять команду над одним единственным значением, GPU будут обрабатывать большие векторы данных за цикл. Если нам нужно обработать все 320×224 пикселей экрана, мы можем отправить на обработку большие массивы пикселей. GPU будет «разделять и властвовать» над ними и задействует как можно больше ядер для выполнения этой задачи.

GPU может обрабатывать большие массивы 3D-вершин и пиксельные операцииGPU может обрабатывать большие массивы 3D-вершин и пиксельные операции

Ключевое слово здесь — параллелизм. Так уж вышло, что большинство задач компьютерной графики можно оптимизировать с помощью этого подхода.

Не забывайте, что GPU решают очень специфические задачи, и не все вычисления можно оптимизировать с их помощью. Если проблема линейна (то есть, следующая инструкция зависит от результата предыдущей), CPU по-прежнему справится с ней лучше. Однако, в нашем исходном примере, поскольку каждый ряд пикселей не зависит от результата предыдущего ряда, GPU определенно улучшит скорость рендеринга.

И последнее, что хотелось бы упомянуть о GPU, — это то, что в свое время их производители предоставляли разработчикам собственные библиотеки для работы со своим железом. Если мы возьмем в качестве примера все тот же 3Dfx Voodoo — Glide API была библиотекой 3Dfx, которая умела взаимодействовать только с процессорами 3Dfx. Если же у вас был GPU от другого производителя, вам требовался совершенно другой API.

Таким образом, по мере развития компьютерной графики все чаще вставала проблема поиска некого стандарта для программирования графических процессоров. Именно поэтому теперь у нас есть такие вещи, как OpenGL и Vulkan. Это открытые библиотеки, которые не зависят от способа реализации GPU и работают со всеми графическими процессорами. Это делает программирование современной графики и работу с современными GPU куда менее громоздкими, чем программирование в эпоху 3Dfx/Voodoo.

OpenGL — один из популярных графических APIOpenGL — один из популярных графических API

Современные GPU также позволяют отправлять небольшие скрипты с инструкциями о том, что GPU необходимо выполнить для каждой вершины и каждого пикселя нашей 3D-сцены. Вероятно, вы знаете такие скрипты под названием шейдеры. Код внутри шейдеров говорит GPU, как преобразовать каждую вершину нашей 3D-модели (вершинные шейдеры) или отрисовать каждый пиксель на дисплее (пиксельные шейдеры). Именно поэтому современные графические процессоры заявляют о наличии программируемого пайплайна — что, по сути, означает, что разработчики могут использовать шейдеры для программирования того, как графический пайплайн будет обрабатывать вершины и пиксели при рендеринге. Все это было сделано для того, чтобы разгрузить центральный процессор.

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

Шестое поколение (1998–2013): Вровень с ПК

В этом поколении консоли начали догонять и постепенно сравнялись по производительности с персональными компьютерами того времени.

DVD в то время выступали в качестве основного носителя данных, а плазменные или LED телевизоры присутствовали почти в каждом доме, так что консоли шестого поколения попытались объединить в себе функции и других электронных приборов для гостиной.

До этого момента тремя основными соперниками на рынке домашних консолей были Sega, Nintendo и Sony. В шестом поколении один из претендентов выбыл, но вместо него появился новый.

Sega выпустила Dreamcast в ноябре 1998 года. Работающая на центральном процессоре Hitachi SH-4 и графическом процессоре NEC PowerVR2, Dreamcast считается первой консолью шестого поколения. Также она стала первой консолью, оснащенной модемом, позволяющим игрокам подключаться к сети Sega и играть онлайн.

image-loader.svg

Но ее во многом затмила Sony PlayStation 2 — так что Dreamcast стала последней консолью Sega перед тем, как фирма сосредоточилась на издании ПО.

image-loader.svg

Новой консолью от Nintendo была GameCube, выпущенная в сентябре 2001 года. Она стала преемницей Nintendo 64 и первой консолью Nintendo, в которой использовались оптические диски. В качестве носителя информации в ней использовался фирменный диск miniDVD, который позволял хранить до 1,5 ГБ данных.

В технической точки зрения GameCube была крайне интересной. Nintendo использовала центральные процессоры IBM, а также GPU и системную логику ArtX/ATI. IBM разработала для GameCube процессор на базе RISC PowerPC под названием Gekko, работающий на частоте 486 МГц и имеющий мощный блок вычислений с плавающей запятой (FPU). GPU, в свою очередь, носил название Flipper, работал на частоте 162 МГц и содержал не только графический блок, но и аудио DSP, и блоки ввода-вывода.

GameCube была принята неоднозначно. Ее хвалили за инновационные решения, но ругали за отсутствие многих базовых функций. К сожалению, консоль продавалась гораздо хуже, чем ожидала Nintendo, и в 2007 году она была снята с производства.

image-loader.svg

В свою очередь, PlayStation 2 была абсолютным монстром. Работала она на специально разработанном 128-битном процессоре R5900 Emotion Engine. Графический процессор (Graphics Synthesiser) также был разработан на заказ и мог воспроизводить до 75 миллионов полигонов в секунду. Помимо технических характеристик, решение Sony обеспечить обратную совместимость PS2 с играми для оригинальной PS стало гениальным маркетинговым ходом. Благодаря всему этому PS2 стала самой продаваемой игровой консолью в истории с 155 миллионами проданных копий.

Именно тогда Microsoft увидела в успехе PS2 угрозу для рынка игр на ПК — и выпустила свою первую консоль, Xbox.

Оригинальная Xbox имела свою ОС на базе Microsoft Windows с функциями DirectX. Консоль работала на процессоре Intel Pentium III, использовала жесткий диск для сохранения игровых состояний, а также имела встроенную функцию Ethernet — и стала первой консолью со своим онлайн-сервисом Xbox Live для поддержки многопользовательских игр.

image-loader.svg

Если же говорить о самом процессе разработки игр — теперь игры уже определенно становились продуктом масштабного сотрудничества многих специалистов. В игровых студиях работали художники, программисты, дизайнеры уровней, менеджеры и люди многих других специальностей — например, из маркетинга и R&D.

Совместная работа столь огромного числа разработчиков над одним общим проектом — одна из причин, по которой мы сегодня используем такие инструменты контроля исходных кодов, как Git или Mercurial. Кроме того, в условиях жестких рыночных сроков игровые студии даже позаимствовали некоторые традиционные приемы повышения производительности из мира разработки ПО, такие как XP или SCRUMM.

Также мы стали свидетелями принятия парадигм программирования, которые помогли командам разработчиков рассуждать о качестве, росте и методах улучшения своего кода. Такие методы, как объектно-ориентированное программирование (ООП) и функциональное программирование (ФП), теперь часто встречаются и в игровой разработке. C++ стал стандартным языком для игр — в основном из-за своей высокой производительности при компилировании, а также хорошей поддержки ООП.

С появлением технически более сложных устройств и свободных тактов процессора стало возможным использование игровых движков общего назначения, сродни на IDE. Такие движки, как Unity и Unreal Engine, стали обычными инструментами игровых разработчиков и являются таковыми по сей день. Благодаря ним стало возможным говорить об играх в таких абстрактных терминах, таких как игровые объекты, сущности, компоненты, а геймдизайнеры и, в частности, левел-дизайнеры получили возможность связывать их друг с другом, используя высокоуровневый язык сценариев (scripting language).

Unity помогает разработчикам создавать игры для различных платформ (Xbox, PlayStation, ПК и т.д.)Unity помогает разработчикам создавать игры для различных платформ (Xbox, PlayStation, ПК и т.д.)

Что же до разработки игр для PlayStation и Xbox, здесь разработчики в значительной степени оставались привязанными к игровым движкам или SDK, предоставляемыми Sony и Microsoft. Это не только библиотеки и инструменты, но и целые экосистемы для разработки и дистрибьюции игр. 

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

Седьмое поколение (2005–2017): HD-революция

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

Картина уже стала походить на то, что мы имеем сейчас: Sony и Microsoft выпустили каждая по мощной машине, размывающей границы между возможностями консолей и ПК.

Xbox 360 и PS3 обладали чрезвычайно мощными аппаратными характеристикамиXbox 360 и PS3 обладали чрезвычайно мощными аппаратными характеристиками

PS3 была оснащена Blu Ray и микропроцессором Cell — все это делало ее дороже, чем Xbox, и тем самым давало Microsoft огромное преимущество, вынуждая Sony продвигать эксклюзивные игры, такие как Uncharted и The Last of Us от Naughty Dog. И, несмотря на хороший прием, PS3 в итоге так и не стала продаваться так же хорошо, и как ее предшественники.

Студия Naughty Dog быстро стала эталоном высококачественной графики для PlayStationСтудия Naughty Dog быстро стала эталоном высококачественной графики для PlayStation

Nintendo отказалась от участия этой гонке на рынке топовых игр и попыталась сделать нечто другое, используя свой опыт, полученный при создании GameCube.

image-loader.svg

Новым продуктом компании стала консоль, построенная на инновационном интерфейсе управления движением. Nintendo Wii не хватало HD-графики и мощности PS3 и Xbox 360, но ее управление было интуитивно понятным и привлекало ранее не изученную неигровую аудиторию.

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

Восьмое поколение (2012 — по сей день): Казуал против хардкора

В восьмом поколении продолжилась интеграция с другими носителями информации и расширение сервисов, которые предоставляют консоли. Все эти аппаратные усовершенствования способствовали повышению частоты кадров и появлению разрешения 4K. Microsoft попыталась перепозиционировать Xbox как универсальное устройство для домашних развлечений, в то время как Sony больше ориентировалась на хардкорных геймеров.

Sony выпустила PlayStation 4, а Microsoft — Xbox One. Вычислительная мощность обеих машин поддерживает до 60 кадров в секунду при разрешении 1080p. Nintendo же продолжила дистанцироваться от своих конкурентов, пытаясь улучшить то, чему они научились на Wii, выпустив новую консоль под названием Wii U.

Xbox One от Microsoft и PS4 от SonyXbox One от Microsoft и PS4 от Sony

Кроме того, в марте 2017 года Nintendo выпустила Nintendo Switch. Это первая гибридная консоль, позволяющая пользователям использовать ее как портативную либо домашнюю приставку. 

С технической точки зрения Switch представляет собой несколько интересных концепций. Она оснащена процессором ARM Cortex и использует SoC, разработанную в партнерстве с NVIDIA, которая разработала для них также и GPU на базе Maxwell. В Switch используется специальная комбинация CPU-GPU, которая может работать на разных тактовых частотах в зависимости от того, как используется консоль.

Switch позволяет казуальным геймерам играть дома и в дорогеSwitch позволяет казуальным геймерам играть дома и в дороге

Большинство игр для Nintendo Switch достаточно просты в освоении, что делает ее отличным вариантом для казуальных геймеров. Казуальные игры впервые взорвались на рынок с появлением мобильных платформ, а гибридный характер Switch позволил Nintendo освоить и этот сегмент рынка.

Что касается разработки игр для Switch, в настоящее время Unity является единственным вариантом, указанным Nintendo, но также можно использовать и пользовательский SDK с интерфейсом Nintendo Dev Interface.

Заключение

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

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

© Habrahabr.ru