Что такое «взлом боковой прокрутки» из старых игр? - PullRequest
15 голосов
/ 13 ноября 2011

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

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

Приведенный выше подход работает только тогда, когда фонне изменяется (и, следовательно, большинство пикселей на экране остаются неподвижными).

Игры с вертикальной прокруткой , как и в старшей школе в стрелялках, с фоном немного сложнееизменение каждого кадра из-за прокрутки.Однако можно воспользоваться тем, как пиксели подаются на дисплей (построчно).Я полагаю, что можно использовать больший буфер и сдвигать указатель данных на несколько строк «вниз» каждого кадра, чтобы он перерисовывался, начиная с другой позиции, создавая впечатление плавной прокрутки.По-прежнему нужно перерисовывать только спрайты (и немного фона на краю экрана), что является серьезной оптимизацией.

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

IIRC, который он использовалво многих старых играх, в основном в стиле бэт-бэмов 80-х, а также в демосценах

Можете ли вы описать эту технику и назвать ее автора?

Ответы [ 4 ]

11 голосов
/ 13 ноября 2011

Я написал игры для старого доброго C64, делающие именно это. И есть две основные вещи, о которых нужно знать:

  1. В этих играх НЕ использовалась растровая графика, вместо этого использовались «переназначенные» шрифты символов, что означает, что фрагменты размером 8x8 пикселей фактически были разбиты на один байт.

  2. Следующее, что следует отметить, это то, что была аппаратная поддержка для смещения всего экрана на семь пикселей. Обратите внимание, что это никоим образом не повлияло ни на какую графику - оно просто сделало все, что отправлено на телевизор, немного смещено.

Итак, 2) сделало возможным действительно плавную прокрутку на расстоянии 7 пикселей. Затем вы перемещали каждый символ - для полноэкранного экрана было ровно 1000 байтов, с которыми компьютер мог справиться, в то же время вы перемещали регистр прокрутки назад на 7 пикселей. 8 - 7 = 1 означает, что это выглядело так, как будто вы прокрутили еще один пиксель ... и затем продолжили в том же духе. Итак, 1) и 2) вместе создали иллюзию истинной плавной прокрутки!

После этого в игру вступило третье: растровые прерывания. Это означает, что ЦП получает прерывание, когда телевизор / монитор собирались начать рисование линии сканирования в указанном месте. Эта техника позволила создать разделенный экран, так что вам не нужно было прокручивать экран весь в отличие от моего первого описания.

И чтобы быть еще более в деталях: даже если вы не хотели разделять экран, растровое прерывание было очень важно в любом случае: потому что оно было так же важно, как и сегодня (но сегодня фреймворк скрывает это от вас ) обновить экран в нужное время. Изменение «регистра прокрутки», когда телевизор / монитор обновлялся в любом месте видимой области, может вызвать эффект, называемый «разрыв» - когда вы четко заметите, что две части экрана синхронизированы по одному пикселю друг с другом.

Что еще сказать? Хорошо, техника с переназначенными наборами символов позволила сделать некоторые анимации очень легко. Например, конвейеры, зубчатые колеса и прочее можно анимировать, постоянно изменяя внешний вид «персонажей», представляющих их на экране. Таким образом, конвейер, охватывающий всю ширину экрана, может выглядеть так, как будто он вращается повсюду, просто изменив один байт на карте символов.

8 голосов
/ 13 ноября 2011

Я сделал нечто похожее еще в 90-х, используя два разных подхода.

Первый связан с «оконным режимом», который поддерживается стандартом VESA SVGA. Некоторые карты реализовали это правильно. По сути, если бы у вас был кадровый буфер / видеопамять больше, чем отображаемая область, вы могли бы нарисовать большое растровое изображение и дать системные координаты для окна в той области, которую вы хотите отобразить. Изменяя эти координаты, вы можете прокручивать без необходимости заново заполнять буфер кадра.

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

Я нашел этот старый код ассемблера 286 (на работающей 17-летней дискете!), Который копировал экран размером 64000 байт (320x200) со страницы вне экрана в видеобуфер:

  Procedure flip; assembler;
    { This copies the entire screen at "source" to destination }
    asm
      push    ds
      mov     ax, [Dest]
      mov     es, ax
      mov     ax, [Source]
      mov     ds, ax
      xor     si, si
      xor     di, di
      mov     cx, 32000
      rep     movsw
      pop     ds
    end;

rep movsw перемещенные слова CX (где слово в данном случае составляет два байта). Это было очень эффективно, так как это в основном единственная инструкция, которая указывает процессору перемещать все как можно быстрее.

Однако, если бы у вас был больший буфер (скажем, 1024 * 200 для боковой скроллера), вы могли бы так же легко использовать вложенный цикл и копировать одну строку пикселей на цикл. Например, в буфере шириной 1024 пикселя можно скопировать байты:

start          count            
0+left         320
1024+left      320 
...
255*1024+left  320

, где left - это координата x в большом фоновом изображении, с которого вы хотите начать (с левой стороны экрана).

Конечно, в 16-битном режиме требовалось некоторое волшебство и манипулирование указателями сегментов (ES, DS), чтобы получить буфер размером более 64 КБ (в действительности это несколько смежных буферов по 64 КБ), но это работало довольно хорошо.

Вероятно, были и более эффективные решения этой проблемы (и определенно более подходящие для использования сегодня), но это помогло мне.

2 голосов
/ 24 февраля 2012

В аркадных играх часто используются настраиваемые видеочипы или дискретная логика, позволяющая осуществлять прокрутку без необходимости (большой) работы процессора.Подход был бы похож на то, что Данбистром описывал на С-64.

В основном графическое оборудование позаботилось о точной прокрутке символов (или тайлов), а затем процессор обработал замену всех тайлов после того, как регистры прокрутки достигли своего предела.В настоящее время я смотрю на плату Irem m-52, которая имеет дело с несколькими фонами прокрутки в оборудовании.Схемы можно найти в Интернете.

1 голос
/ 22 апреля 2014

Для прокрутки вправо на Commodore Amiga мы использовали Copper , чтобы сместить экран вправо до 16 пикселей.Когда экран сместился, мы добавили 2 байта к начальному адресу экранного буфера, в то время как с правой стороны мы использовали Blitter для копирования графики из основной памяти в экранный буфер.Мы установили бы экранный буфер немного больше, чем экранный вид, чтобы мы могли копировать графику без видимого эффекта мерцания при копировании в правой части области просмотра.

...