Абзац
:: Поиск
:: ПоддерЖка ПрОекта
Webmoney:
  • Z610389805629
  • R427996570517
  • E023541002978
  • :: №32 (10.10.2009) ПрОсмотрОв: 2794

    Автор: Дмитрий Быстров / 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.

    © 2004-2013 Perspective group