"Банковское переключение" спрайтов на старых приложениях NES
В настоящее время я пишу на C#, что можно было бы назвать моей собственной интерпретацией аппаратного обеспечения NES для разрабатываемой игры старой школы. Я запустил FCE и наблюдал, как NES отображал и отображал графику.
Короче говоря, NES может содержать два графических изображения, каждое из которых имеет размеры 128x128. Они называются таблицами PPU. Один был для плиток BG, а другой - для спрайтов. Данные должны были находиться в этой памяти, чтобы их можно было выводить на экран. Теперь, если в игре было больше графических данных, чем в этих двух банках, она могла бы записывать части этой новой информации в эти банки - переписывать то, что там было - в конце каждого кадра, и использовать ее со следующего кадра.
Итак, как программисты "переключали банк" в старых играх? Я имею в виду, в рамках дизайна уровней, как они узнали, какой графический набор загружать? Я заметил, что банки Mega Man 2 переключаются, когда экран программно прокручивается от одной части сцены к другой. Но как они хранили эту информацию на уровне - какие спрайты копировать в таблицы PPU и куда их записывать?
Другим примером будет удар по паузе в MM2. Плитки BG перезаписываются во время паузы, а затем восстанавливаются, когда игрок делает паузу. Как они запомнили, какие плитки они заменили и как их восстановить?
Если бы мне было лень, я мог бы просто создать один огромный статический растровый рисунок и просто получить значения таким образом. Но я заставляю себя ограничить эти значения, чтобы создать более аутентичный опыт. Я прочитал удивительное руководство по созданию MC Kids и пытаюсь понять, как программировать эту игру. Мне просто непонятно, как эти программисты достигли того, что они сделали с тем, что имели.
РЕДАКТИРОВАТЬ: Единственное решение, которое я могу придумать, состоит в том, чтобы держать отдельные таблицы, в которых указано, какие плитки должны быть в PPU и в какое время, но я думаю, что это будет огромный ресурс памяти, с которым NES не сможет справиться.
1 ответ
Так что после ночи обдумывания и перечитывания документов я думаю, что нашел идеальное решение. Матрица!
Учитывая следующие данные:
3, -1, -1, -1, -1
-1, 0, 1, 2, -1
-1, -1, -1, 3, -1
-1, -1, 5, 4, -1
-1, -1, -1, -1, -1
Я могу использовать эту информацию для доступа к информации в справочных таблицах, чтобы определить, какая информация мне нужна. Первая запись (0,0) определяет всю карту, где другие значения определяют, что необходимо на этом конкретном экране.
MAP ARRAY PALETTE MUSIC TILESET STARTINGSCR
0 0 0 1 4
1 4 3 2 2
2 etc.
3
Поэтому при загрузке карты я смотрю на пункт (0,0). Он скажет, что мне нужно загрузить X плиток в PPU, использовать Y цветовую палитру, Z плиток и A music. Также будет сказано, что экран 0 является стартовым экраном и уровень начинается там - расположите персонажа соответственно.
SCREEN PALETTE TILESET MUSIC TILEDATA SCROLLL SCROLLR SCROLLU SCROLLD
0 0 1 2 4 true true true true
1 etc
2 2 1 2 3 false false false true
Теперь допустим, что мне нужно переходить между экранами. Я могу посмотреть на текущий экран против целевого экрана. Если новый экран нуждается в информации, отсутствующей в PPU, я могу инициировать переход, который будет загружать данные во время него. Я также могу видеть, могу ли я прокрутить в этом направлении; Например, если целевой экран равен -1, я не могу прокрутить это направление. Я также могу хранить флаг где-нибудь, чтобы определить, что при прокрутке на этот экран я не могу прокрутить назад. Например, я могу перейти прямо на экран № 2, но не могу прокрутить влево на экран 1.