01 апреля 2021

        О ротаторах 
Alone Coder 

  Наверно,  каждый   помнит  вращающегося 
Соника в демо Illusion (1996). Он строится 
пикселями  2x2, совершенно  честным  кодом 
типа такого: 

       ld a,(hl)
       [inc/dec h/l]
       add a,a
       add a,a
       add a,(hl)
       [inc/dec h/l]
       add a,a
       add a,a
       add a,(hl)
       [inc/dec h/l]
       add a,a
       add a,a
       add a,(hl)
       [inc/dec h/l]
       ld (de),a
       inc e 
;~83t/byte (260K/экран + 40K копирование) 

  Инкременты/декременты   патчатся.   Это 
ограничивает возможности зума,но небольшой 
зум  там  есть. Похожая  техника  вращения 
используется  в Eye Ache, но уже в мульти─ 
колоре 4x4. 
  А что можно сделать в пиксельном разре─ 
шении? 
  Можно  переписать эту процедуру на пик─ 
сели, но тогда будет 6 fps, да и адресного 
пространства не хватит на картинку во весь 
экран. 
  Можно натягивать текстуру через расста─ 
новку точек, EOR-fill и сдвиг строк, как в 
кубике  из  Mission Highly Improbable,  но 
это тоже работает не быстро. 
  Можно  негенерировать  повёрнутые байты 
от каждого пикселя, как в The Link, но для 
этого даже с небольшой картинкой понадоби─ 
тся больше,чем 128K ОЗУ ( The Link требует 
NeoGS ). 
  Можно,наконец,сделать ротатор с пропус─ 
ком знакомест. Сначала рендер пропусков по 
отдельной  карте, оттуда  же  берём цвет и 
номера тайлов. Заранее   повёрнутые  тайлы 
можно просто сдвигать, чтобы не вертеть их 
каждый  раз. Отдельный  тип тайла - прямой 
цветопереход, его можно рендерить... 
  Но такой эффект ещё никто не писал. По─ 
этому расскажу про более простые эффекты - 
rotating chessfield и ротатор цветной кар─ 
тинки из клеточек такого же размера, как в 
rotating chessfield. 

         1. Rotating chessfield

   Этот  эффект  появился  где-то в дебрях
C-64, а на  Speccy  был  реализован в деме 
The Board (2011). Идея  его в том, что для 
каждого  конкретного  угла  поворота  есть
всего  8*8 рисунков знакоместа (при разре─
шении U, V в  8 субтекселей), плюс столько
же инверсных копий.
   Соответственно,задача делится на подго─
товку знакомест,ротатор и вывод знакомест.
   После  некоторого   перебора  вариантов
оказалось,что со знакоместами 8x4 работать
проще  (вывод чанков  по методу Monster'а,
т. е. цепочкой ret ; U  и V кодируются как
младший и старший  байты  адреса процедуры
вывода чанка).Был ещё вариант 8x2, который
можно  было  выводить прямо в ротаторе, но
что-то мне в нём не понравилось.
   Был сделан простой ротатор 37 t/chunk:

;B,C=#X0, где X=dU,dU+1 
;D,E=#X0, где Y=dV,dV+1 
;A=U0, A'=V0 
;SP=endline 
MAPPERLINE 
      dup 16
       push hl
       add a,b ;или c (патч)
       ld l,a
       ex af,af'
       add a,d ;или e (патч)
       or chout/256 ;там выводилки чанков
       ld h,a
       push hl 
__=$ ;последний проход кончается здесь 
       add a,d ;или e (патч)
       or chout/256 ;там выводилки чанков
       ld h,a
       ex af,af'
       add a,b ;или c (патч)
       ld l,a
      edup
       org __
       jp MAPPERLQ

   Патч  add a,b/c и add a,d/e  для такого
ротатора:

;H0=U0 
;D0=dU 
;B=#80 ;"add a,b" 
;C=0 
PATCHLINEU 
_=MAPPERLINE 
      dup 16
       add hl,de
       ld a,b
       adc a,c ;0
       ld (_+1),a 
__=$ ;последний проход кончается здесь 
       add hl,de
       ld a,b
       adc a,c ;0
       ld (_+14),a 
_=_+16 
      edup
       org __
       ret

   Вывод чанков 8x4:

       ld h,a
       ld (hl),N
       inc h
       ld (hl),N
       inc h
       ld (hl),N
       inc h
       ld (hl),N
       inc l
       ret

   Чанки,конечно,можно сгенерировать зара─
нее, но в The Board они считались на лету.
Сначала генерировались все нужные скосы по
U и V  для  текущего угла, а потом они на─
кладывались по XOR  во всех 16 комбинациях
(точность U,V - 8 субтекселей):

XORUV 
;all upics XOR current vpic 
       ld bc,upics 
_=2 
     dup 8 ;8 чанков, 8 инверсных копий
      dup 4 ;4 строки в чанке
       ld a,(bc) ;можно ускорить стеком
       xor (hl)
       ld e,_
       ld (de),a
       cpl
       ld e,_+#80 ;там инверсная копия
       ld (de),a                   ;чанка
       inc c
       inc l 
_=_+3 ;т.к. чанк - это ld (hl),N:inc h... 
      edup 
_=_+4 ;следующий чанк 
       org $-1
       dec l
       dec l
       dec l
     edup

   Генератор скосов был такой:

;U0=(256*upic/16)=upic*16=L*4 
;или V0=(256*vpic/16)=vpic*16=L*4 
       ld a,l
       add a,a
       add a,a
       xor hx ;0/#7f
      dup 4
       ld b,a
       add a,a ;CY=U[7] 
;A=U*2 ;или V*2 
;C=dU*2 ;или dV*2 
;D=teorfrom0/256 
;HL=upic ;или vpic 
       FILLU ;строим рисунок байта
       ld a,b
       add a,lx ;U0=U0+dV ;или V0=V0-dU
      edup

   Рисунок байта строится записью перепол─
нений при сложении и потом "горизонтальным
EOR-fill" (который - просто таблица):

;A=U*2 ;или V*2 
;C=dU*2 ;или dV*2 
;D=teorfrom0/256 
;HL=upic ;или vpic 
;CY=U[7] ;или V[7] 
      macro FILLU
       dup 8
       rl e
       add a,c
       edup
       org $-1
       ld a,(de) ;d=teorfrom0/256
       ld (hl),a
       inc l
      endm

   2. И как на этом вертеть картинку?

   Возьмём за образец дему Mekanix с C-64:

А
Б
В
Г
Д
Е
Ж
З
И
Й
К
Л
М
Н
О
П
Р
С
Т
У
Ф
Х
Ц
Ч

   Клетки 2x2,2 цвета. В клетках заполнена
только каждая вторая строчка и каждый вто─
рой пиксель.
   Текстура  8(7?)x64.  С  таким  размером
текстуры повторы гарантированы - можно за─
ниматься  копипастой кусков экрана, только
они это не делают.
   В каждом  знакоместе  видно  максимум 4
текселя,а это всего 16 вариантов. 4 сдвига
по U, 4 по V  в 16  вариантах - получается
256 чанков 8x8.

   Значит, надо сначала сгенерить 4 знако─
места сдвигов по U, 4 по V, потом 256 чан─
ков по  or, xor, and.  Вместо половины ри─
сунков можно делать инверсию атрибутов.
   Чтобы использовать в этих условиях обы─
чный ротатор,надо хранить в карте клетку с
тремя соседями,итого 4 бита. А значит,надо
4 карты  в зависимости от знаков направле─
ния,иначе содержимое клеточек не будет со─
ответствовать.Можно,конечно,менять порядок
клеточек  внутри  этих четырёх бит за счёт
смены порядка нумерации чанков. Проблема -
от какой из них брать атрибуты.
   На  C-64  чанки  8x8  аппаратные, а  на
Speccy  их вывод (даже через строчку) зай─ 
мёт 62976 тактов:

       ld h,a
      dup 4
       ld (hl),N
       inc h
       inc h
      edup
       org $-2
       inc l
       ret ;17 b 
;8 шт.в сегменте (U), 4(texture)*8(V)*256b 
:82*768=62976 

   Однако при выводе чанков можно заливать
пустые знакоместа атрибутом (и не генерить
их  графику). Поэтому  весь  эффект  лучше
сразу  делать  в цвете, а заодно можно и в
1x1, а не через пиксель.
   Вывод чанков 8x8 в цвете:

       ld (hl),b/c/e/#30 ;attr
       ld h,a
      dup 8
       ld (hl),N
       inc h
      edup
       org $-1
       ld h,d
       inc l
       ret 
;28(29) b, 137(140) t 

   Вывод пустого чанка:

       ld (hl),0/#3f ;attr
       inc l
       ret

   Ротатор текстуры:

;addr=%11UUUuu0 VVVVVVvv 
       ld h,a
       ld e,(hl)
       inc h
       ld d,(hl)
       push de
       add a,b/c ;du (патч)
       or #c0
       ld h,a
       exa
       add a,... ;dv (патч)
       ---
       ld l,a
       ld e,(hl)
       inc h
       ld d,(hl)
       push de
       add a,... ;dv (патч)
       ld l,a
       exa
       add a,b/c ;du (патч)
       or #c0 
;59 t/chunk 

   Этот вариант использован в New Wave 48K
- в этой деме  скосы уже не генерировались
на каждом кадре,а брались готовые (загото─
влено  32 поворота). Получилось грубовато,
но зато весь экран за 2 фрейма на 3,5 МГц.
   Статистика  на  картинке "-=rotate" при
32x24:

пустых клеток (с учётом соседей) = 67% 
muz = 4000..6000 
out = 45000..55000 (вывод чанков и пустых 
                                   клеток) 
math = 500 
xor = 27606 (генерация чанков из готовых 
                                   скосов) 
patchuv = 2500 (патч add a,N в ротаторе) 
ротатор = 47500 

итого 133000 +- 6000 

   Думаю,на основе этой техники можно сде─
лать и другие эффекты, как считаете?



Other articles:


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

Similar articles:
Coding - Error Handling TR-DOS when working through # 3D13.
News - A new network Minsk newspaper.

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