![]() |
:: СОДЕРЖАНИЕ НОМЕРА
:: Газетные рубрики
:: АВТОРЫ
:: Поиск
:: Поддержка проекта
Webmoney:
|
:: №32 (10.10.2009) Просмотров: 4414
![]() Автор: Дмитрий Быстров / Alone Coder. Рубрика: В помощь разработчику. Номер: №32 (10.10.2009). Фреймовость в режиме 16 colorПродолжение статьи, опубликованной в ACNews #55.* * * Есть возможность писать на NGS (NeoGS) фреймовые игры в режиме «цвет на точку». Идея в том, что NGS генерирует последовательность команд для ZX, а ZX их исполняет через DMA. Один экран светится на экране, другой в это время строится. Для этого DMA должна поддерживать возможность исполнять команды из памяти NGS. Команды такого типа: LD HL,... LD (HL),... INC L или такого: LD A,... LD (...),A или же такого: LD HL,... LD (...),HL Можно использовать и команды CALL, например, для переключения страниц с экранами. Код можно выполнять только подряд, поскольку в FPGA NGS заведены не все адресные сигналы ZX (только A0-A7, A14, A15), поэтому она не знает, какой адрес хочет прочитать ZX. Она отдаёт байты подряд с автоинкрементом адреса. Причём считываемый байт подготавливается заранее, что минимизирует вайты процессору NGS. На прозрачных областях спрайтов код генерировать не надо. 30 спрайтов 16x16 при последнем варианте вполне умещаются во фрейм. При этом последовательность команд занимает чуть менее 16K. Если понадобится больше 16K, то можно разбивать код на страницы по слоям экрана (4 слоя) или поспрайтово, или (если выводим большую картинку разом) построчно/постолбцово. Чтобы генерировать такие команды для вывода/стирания спрайтов, NGS должен хранить копию текущего игрового экрана (точнее, обеих экранных областей). Есть несколько различных методов генерации такого кода: Метод 1 Работаем со спрайтами на NGS как обычно на ZX, а потом сравниваем текущий и предыдущий (точнее, предыдущее состояние текущей экранной области из двух) экраны и генерируем на их основе код. С точки зрения ZX этот метод наиболее эффективен (не требуется несколько раз перерисовывать байты спрайтов, которые стоят на месте или перекрывают друг друга). Но NGS не потянет. Сравнение требует 66 тактов на слово (на пустых словах), итого, более 800000 тактов на весь экран. На NGS у нас в лучшем случае 491520 тактов. Метод 2 Строим код непосредственно во время вывода и стирания спрайтов. Проблема в том, что в главном цикле вывода спрайтов использовано слишком много регистров - а это значит тормоз: 1. Адрес графики спрайта. 2. Адрес на экранном буфере NGS. 3. Адрес в буфере заднего плана. 4. Адрес на экране ZX. 5. Адрес генерируемого кода. Можно 2 и 4 сделать одинаковыми. Можно убрать 3, если фон перерисовывается в NGS целиком (258048 тактов – не рекомендую; впрочем, можно сделать быстрый аналог LDIR внутри FPGA). Можно убрать 1, если сгенерировать процедуры для каждого спрайта (точнее, каждой фазы). В этом случае можно вообще пропускать прозрачные участки спрайтов. Метод 3 Во время вывода спрайтов устанавливаем байты в байтмаске экрана, а потом по ней строим выводилку, как в первом методе. В этом случае будет от 27 (INC L: LD A,(HL): INC L: OR (HL): RET NZ) тактов на слово (на пустых словах), то есть 331776 тактов на весь экран. Это неприемлемо. Если же вместо байтмаски использовать битмаску, то можно сравнивать быстрее, но процедура вывода спрайтов усложнится. Так что метод заслуживает обсуждения. При этом методе не обязательно сохранять картинку под выводимыми спрайтами, так как её можно восстанавливать по байтмаске/битмаске и копии фона. Это позволит сэкономить регистры и получить более скоростной вывод спрайтов. Метод 4 Поскольку во время вывода спрайтов мы строим буфер для их восстановления, то на основе этого буфера можно строить нужный нам код (отдельной процедурой). При аккуратном программировании можно достичь этих самых 30 спрайтов на экране. Именно при аккуратном, т.к., например, в PANG 16C было 130 тактов на байт спрайта, включая обработку списков объектов (но не интеллект!). Разумеется, чем спрайты меньше, тем меньше времени они занимают вообще, но больше в расчёте на байт. Спрайты типа разлетающихся пикселей (если их сотни) надо обрабатывать отдельными оптимизированными процедурами. Аппаратный скролл в настоящий момент доступен только по вертикали: на АТМ Turbo 2+ по умолчанию, на Pentagon 1024 SL 2.2 при новой прошивке от DDp (http://zx.pk.ru/showthread.php?p=205230). Он делал и горизонтальный, но оба не умещаются в одну прошивку. Приехавшие при скроллинге линии надо перерисовывать теми же методами: NGS генерирует код, ZX его исполняет. Проблема в том, что игровую панельку придётся перерисовывать на каждом кадре. Игры, где движущегося фона не очень много (типа Super Mario) можно писать и без аппаратного скролла. Графику в памяти ZX хранить не требуется - она вся будет внутри NGS. |