01 апреля 2021

  О туннелях и небоскребах 
Alone Coder 

  Прямоугольный  туннель  появился  ещё в 
волосатом  году  в  сеговской  игре Galaxy 
Force II. На  Спектруме мы его впервые на─  
блюдали в демо Yes (1997). 
  Разумеется, для  отрисовки  такого тун─ 
неля  не нужно рисовать прямоугольники. Он 
строится по строчкам. Обычно в одной стро─ 
чке  добавляется проекция не более чем од─ 
ного прямоугольника. Но если и больше - не 
страшно. Главное - во  всём кадре видно не 
более N разных строчек, где N - общее чис─ 
ло прямоугольников в туннеле (включая вне─ 
шний, который во весь экран). 
  Эффект  с  небоскрёбами при виде сверху 
тоже  рисуется ограниченным числом строчек 
(в данном случае 2*N,где N - число слоёв). 
  Туда же зуминг шахматных сеток, бегущих 
строчек и т.п. 
  Итак.

             1. Nedotunnel

   В  деме Yes туннель был чёрно-белым, но
ничто  не мешает его раскрасить. Например,
в  мультиколоре 8x2 (всего лишь стек пере─
ставлять  между  строчками). Но  мне такой
туннель  понадобился  в Nedodemo 2, а дема
эта под ATM-Turbo 2+ (рекомендуется ZX Evo
baseconf ),так что я строил этот туннель в 
аппаратном  мультиколоре  объёмом аж 32000
байт.
   Задача разбивается на следующие шаги:
 - нагенерировать  координаты N прямоуго─ 
льников; 
 - нагенерировать  N строчек с последова─ 
тельным добавлением прямоугольников; 
 - составить массив,где для каждой строки 
экрана указано,какую графику использовать; 
 - вывести экран по этому массиву (в слу─ 
чае  мультиколора - тривиально, а в случае 
жирного АТМного экрана надо подумать). 

   Поскольку строчки содержат много одина─
ковых байтов подряд, можно генерировать не
графику  строчек, а  код для их вывода. Но
все 32000 байт мы выводить не будем, выво─
дить будем только атрибуты, как и для про─
граммного мультиколора.
   Также отметим, что в аппаратном мульти─
колоре  ATM-Turbo  есть  два  чередующихся
слоя экрана.
   Можно  оба  слоя вывести в рамках одной
процедуры:

      dup 20
       [ld de/d/e,...]
       push de
      edup
       ld sp,ix
      dup 20
       [ld de/d/e,...]
       push de
      edup
       jp (iy)

   Чтобы  сгенерировать  такую оптимизиро─
ванную процедуру (а всего их, напомню, N),
удобно  иметь сначала графику строки в ли─
нейном виде.
   Вызывалка  может  выглядеть  так (можно
совместить с вычислением массива строк,так
что массив будет и не нужен):

       <логика>
       ld sp,scr+#2000
       ld ix,scr
       ld iy,$+ /ld ly,$+
       jp (hl)

и так для каждой строки.
   Логика  просто  следит, пересекли ли мы
верхнюю  (или  нижнюю)  границу очередного
прямоугольника,если да,то пересекли ли для
следующего и т. д., с каждым  разом  меняя
номер рисуемой графики строчки.
   Расчёт координат тоже ничего особенного
не представляет - опишу его в двух словах,
подробности можете посмотреть в исходниках
Nedodemo 2. 
   У каждого прямоугольника есть виртуаль─
ные X,Y,Z  и виртуальные размеры (в данном
случае у всех одинаковые).
   По  идее размеры слоёв убывают как 1/N.
Но при плавном зуме N будет дробным.
   Так что лучше иметь массив всех видимых
размеров прямоугольников и шагать по этому
массиву большими шагами.
   Прямоугольники  не только приближаются,
но и колеблются по X и Y (например, по си─
нусам). Сдвиги  прямоугольников по X и Y в
проекции  экрана  должны быть сообразны их
масштабу.
   Вот и весь эффект.

            2. Skyscrappers

   Эффект с небоскрёбами с высоты птичьего
полёта  я писал для The Board II (эта дема
написана  раньше предыдущей). Там тоже ап─
паратный мультиколор ATM-Turbo и тоже было
два варианта:
 А) заранее готовим все строки и юзаем их
 Б) строку апдейтим по ходу отрисовки.
   Прикинул и решил сгенерировать все воз─
можные  строки, и  их оптимизировать в ld: 
push. Все  возможные  строки  для случая 4 
слоёв (в деме их столько,а не больше,пото─
му  что иначе не получался красивый цвето─
переход):

                пусто
                 0
                 01
                 012
                 0123
                  123
                   23
                    3

итого 8 строк.
   Можно  представить  себе  промежуточный
формат строки как байт на точку,каждый бит
- наличие  определённого  слоя небоскрёба.
Чтобы  сгенерировать  эти  битпланы, нужно
запустить зумер для каждого из 4 битпланов
и каждый байт либо не трогать, либо пропи─
сать  нужный бит в каждый из битпланов. Из
такого  байта с битпланами можно вычислить
видимый цвет по таблице, а заодно пересчи─
тать в два пикселя в байте и в два череду─
ющихся слоя.
   Удалось реализовать это без промежуточ─
ного  буфера, сразу в два пикселя в байте.
Слои накладывает сама палитра, а зумер од─
ного  битплана состоит из цикла пропуска и
цикла рисования залитой части.
   Цикл пропуска (b=ширина пропуска):

ZOOMSKIP 
_=0 
      dup wid/2 
_=_+42 
       djnz $+26 ;обходим запись и jp 
;кончился пропуск 
       ld h,c
       ld d,ly
       dup 4
       ld a,(hl)
       or d
       ld (hl),a ;правый пиксель
       inc h
       edup
       org $-1
       inc l
       ld b,hx ;ширина залитой части-1
       jp ZOOMWRITE+_ ;идём на рисование 
;+26 - это сюда 
       inc l
       djnz $+7 
;кончился пропуск 
        ld b,lx ;ширина залитой части
        jp ZOOMWRITE+_
      edup

  Цикл рисования (b=ширина залитой части):

ZOOMWRITE 
_=0 
      dup wid/2 
_=_+34 
       djnz $+26 ;обходим запись и jp
       ld h,c
       ld d,hy
       dup 4
       ld a,(hl)
       or d
       ld (hl),a ;левый пиксель
       inc h
       edup
       org $-1
       inc l
       ld b,hx ;ширина пропуска-1
       jp ZOOMSKIP+_ 
;+26 - это сюда 
       ld h,c
       dup 4
       ld (hl),e ;левый+правый пиксель
       inc h
       edup
       org $-1
       inc l
       djnz $+7
        ld b,lx ;ширина пропуска
        jp ZOOMSKIP+_
      edup

   В  любом случае, надо будет пересчитать
сгенерированные  строки  (кроме  пустой) в 
ld:push. 
   Вот таким кодом (для упрощения считаем,
что d и e одновременно не меняются):

       pop af ;два пикселя от зумера
               ;(второй слой пропускаем)
       cp b
       jr z,$+10
        exd
        ld (hl),#16 ;"ld d,"
        exd
        inc e
        ld (de),a
        inc e
        ld b,a
       pop af ;два пикселя от зумера
               ;(второй слой пропускаем)
       cp c
       jr z,$+10
        exd
        ld (hl),#1e ;"ld e,"
        exd
        inc e
        ld (de),a
        inc e
        ld c,a
       ld a,#d5 ;"push de"
       ld (de),a
       inc e

   Вызывалка ld:push'ей (она сама вычисля─
ет, какие  слои  активны в данной строке -
код  похож на 4-канальный плейер на бипере
:))

       exx
       dec h
       jr nz,$+5
        xor 8
        ld h,l
       dec d
       jr nz,$+5
        xor 4
        ld d,e
       djnz $+5
        xor 2
        ld b,c
       exx
       djnz $+5
        xor 1
        ld b,c
       ld h,a ;%1111EDCB
       ld h,(hl)
       ld sp,первыйслой
       ld ix,второйслой
       ld iy/ly,следующаявызывалка
       jp (hl)
       ...
       ld:push *20
       ld sp,ix
       ld:push *20
       jp (iy) ;на следующую вызывалку

   В The Board II строки  повторяются (всё
равно  атрибутные "пиксели" широкие, а так
получатся  квадратные), так  что на каждой
второй строке расчёта нет, а стоит опять:

       ld sp,первыйслой
       ld ix,второйслой
       ld iy/ly,следующаявызывалка
       jp (hl)

   В таком  духе  можно писать и вызывалки
для  зума, скролла или ещё чего-нибудь, но
обычно я так не делаю. Главное,что работа─
ет! :)



Other articles:


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Similar articles:
Hard - the problem of temporary protection discs from the record.
Story - Christmas stories and poems.
Smile - Poems from BROM'a.

В этот день...   21 November