Заинтриговало меня, насколько быстро можно рендерить уровни в играх.
Потратил месяц (поэтому ничего сюда не постил) и написал рендерер уровней из спрайтов. Уровни могут содержать до 256 спрайтов и иметь максимальный размер 255x255 спрайт. Организация спрайтов -
2x на 2y на depth, где
x - байты
y - пикселы
depth - количество плоскостей.
Пришлось отдельно написать грабилку и конвертилку спрайтов, потому что формат спрайта довольно-таки заморочный, зато полностью исключает использование add/sub при выводе в плоскости. Для вывода на экран используются только inc,dec и push. Рендеринг возможен во viewport любого размера (от размера спрайта до всего окна)
О скорости рендеринга судите сами. В примере рендерится в 3 плоскости т.е. 8 цветов на экране. Скорость можно ещё увеличить, прописав custom interrupt handler. Я не заморачивался с этим вообще, важен алгоритм. Поэтому просто взял и использовал PPCLIB (поэтому .com файл немного раздуло из-за ненужного фонта).
Уровень находится в файле level001.map
Из readme:
Run under MicroDOS
KEYS:
Arrows : level scrolling
Plus key : render level at full screen
Minus key: render level in viewport
ESC (AP2): exit to MicroDOS
А перерисовываются ли те спрайты (тайлы), которые при скроллинге не меняются? Или можно за счёт этого ещё ускорить?
Да, перерисовывается всё, весь viewport (в пределе-экран). Скроллинга, как такового нет, он достигается перерисовкой. В принципе, можно помудрить и ускорить, если после "скроллинга" в новом месте такой-же спрайт, как был до этого.
На всяк случай, вот код отрисовки одного спрайта. Ассемблер нужен m80 (я макросы люблю).
StkMvUp Macro
pop d
mov m,e
inr l
mov m,d
EndM
StkMvDn Macro
pop d
mov m,e
dcr l
mov m,d
EndM
SpMvUp Macro _height
Rept (_height SHR 1) - 1
StkMvUp
inr l
EndM
StkMvUp
EndM
SpMvDn Macro _height
Rept (_height SHR 1) - 1
StkMvDn
dcr l
EndM
StkMvDn
EndM
NextPlane Macro
mov a,h
add b
mov h,a
EndM
CSEG
PUBLIC PutSp16
; Non-reentrable
; Needs disabled interrupts
; <HL> - sprite address
; <DE> - screen address
; <C> - number of planes 1-4
PutSp16:shld ldSpr+1
lxi h,0
dad sp
shld sp16ex+1
xchg ; <HL> - screen address, <DE> - return address
mvi b,20h
ldSpr: lxi sp,0
sp16lp: SpMvUp 16
inr h
SpMvDn 16
dcr c
jz sp16ex
NextPlane
SpMvUp 16
dcr h
SpMvDn 16
NextPlane
dcr c
jnz sp16lp
sp16ex: lxi sp,0
ret
End
Так мы скоро дойдем до портирования After the War
After The War 2
Авторы оригинала, скорее всего, очень не зря ограничились игровым пространством в пол-экрана. Ну и монохромная графика в игровом пространстве нам тоже очень на руку.
При желании, да наличии времени-вполне реализуемо. Причём можно даже в 4х цветах сделать. При этом рендерер заметно быстрее работает, чем c 8-ю цветами, даже полноэкранный вывод почти не напрягает.
Тут видятся 2 проблемы:
1. Как сделать плавные оверлеи (ну все эти летающие гады поверх карты уровня).
Думаю, можно соорудить frame buffer из 2х пар плоскостей, и переключать эти пары (прошивкой палитр) поочереди, отрисовывая overlays в затемнённую в данный момент пару. Визуально перемещение оверлеев при этом должно вроде выглядеть очень плавно.
2. Как добиться музыки с AY без затыков. Ведь по крайней мере, во время вывода спрайта по методу выше прерывания должны быть запрещены, и могут появиться небольшие audio glitches. Я в плавном воспроизведении музыки не копенгаген, может кто поделится идеями/соображениями?
Попробую, пожалуй написать поддержку фраме буфера.
Последний раз редактировалось PPC; 03.06.2011 в 05:34.
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Так а этих гадов можно как раз в отдельную экранную плоскость отрисовывать, у которой, путем программирования палитры, всегда приоритет над фоновыми 4мя цветами карты.
Собственно, все движущиеся спрайты можно в этой плоскости и держать. А если тактов хватит - то и две плоскости под спрайты отвести, тогда не только фон, но и герои будут 4х цветными.
Только вот в оригинале, судя по видео, горизонтальный скроллинг не умещался в одно прерывание в одном цвете, и это с Z80 на борту. На Векторе мы можем сэкономить на AND/XOR с маской для оверлеев, но даст ли это достаточный запас скорости? Учитывая более тормознутый i8080, без LDIR'ов, да еще и с неоптимальной Векторовской схемой тактирования?
Если во время обратного хода луча отрисовывать, то все должно быть плавно ИМХО. В "Полете" же такая схема применяется, и самолетик очень даже плавно летает.
Единственное что - скорее всего придется скролл фоновой карты делать за одно прерывание, потом пересчет координат героя, гадов и снарядов, и их отрисовка - уже в следующее прерывание. Могу ошибаться, но мне кажется, горизонтальный скролл по 2м плоскостям "съест" почти все такты, доступные в интервале ОХЛ.
"Это всё правильно, даа ... бумага написана справедливо" (с) Кавказская Пленница.
Но есть некоторые моменты...опять-же я только моё маленькое ИМХО, take it with a grain of salt.
В "Полёте" самолётик маленький, его размер не меняется, и это всего-лишь 1 спрайт. Такого не жаль выводить хоть во время каждого ОХЛ, он не изменит сильно время выполнения обработчика прерываний, и не повлияет сильно на плавность кода вне прерывания.
Отрисовывать всех гадов во время ОХЛ за раз накладно, да и нет смысла: всё равно 50-ти кадров в секунду от engine мы не добъёмся.
Считать, сколько тактов можно максимум использовать для вывода спрайтов в ОХЛ ИМХО нет смысла, всё равно кому-нибудь понадобиться вывести "ну ещё один спрайтик, Кешенька"
Затачивать универсальный (до разумных пределов) engine под 5 спрайтов и ни-ни, а то-расстрел не вижу смысла. Потом, своё положение/вид они меняют реже чем раз в 20ms. Значит-нужно делать pipeline, т.е. очередь отрисовки, и за каждое прерывание вынимать из очереди, скажем, не больше 2х гадов. Учитывая, что размеры гадоы разные, и очередь часто будет пустая, а иногда забита, engine будет то тормозить, то ускоряться. Кстати это конкретно видно на той спековской игрушке. Скорость-то есть, а вот плавности-нет. Это всё миллисекунды, но на скроллинге, который вне прерывания визуально скажется.
Безусловно, спрайты отдельно от уровня и проще (нет xor-ов) и быстрее. Но frame buffer, c другой стороны, позволяет полностью спрятать весь процесс отрисовки (и уровеня и гадов). Кста, pipeline там тоже возможно сделать (если не было команды на скроллинг уровня).
В общем, если время позволит, будем посмотреть, потому как надо экспериментировать и так и эдак.
Just my 5c.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)