Code - effects of rotators and mouth zoomers

About rotators 
Alone Coder 

Probably everyone remembers the rotating 
Sonic in demoIllusion (1996).It's under construction 
2x2 pixels, completely honest code 
like this: 

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/screen + 40K copy) 

 Increments/decrements are being patched.   This 
limits possibilitieszoom, but small 
zoom is there. Similar rotation technique 
used inEye Ache,but already in multi─ 
color 4x4. 
And what can be done in pixel size─ 
cheniya? 
 You can rewrite this procedure to peak─ 
sat down, but then there will be 6 fps, and the address one 
there is not enough space for the whole picture 
screen. 
You can stretch the texture through the spacer─ 
new points, EOR-fill and line shift, as in 
cube from  Mission Highly Improbable,but 
this also does not work quickly. 
You can ungenerate rotated bytes 
from each pixel, as inThe Link,but for 
this is needed even with a small picture─ 
more than 128K RAM (The Linkrequires 
NeoGS ). 
 You can finally make a rotator with a pass─ 
com acquaintance. First, render the passes by 
a separate card, from there we take the color and 
tile numbers. Pre-rotated tiles 
you can simply move them so as not to rotate them 
every time. A separate type of tile is straight 
color transition, it can be rendered... 
 But no one has written such an effect yet. By─ 
I'll tell you about simpler effects - 
rotating chessfield and color car rotator─ 
tiles made of cells the same size as in 
rotating chessfield. 1. Rotating chessfield

   This effect appeared somewhere in the wilds
C-64, and on  Speccy  was implemented in the demo 
The Board (2011).The idea is that for 
for each specific rotation angle there is
a total of 8 * 8 drawings of familiar places (at the size─
rendition of U, V in 8 subtexels), plus as many
or inverse copies.
   Accordingly, the task is divided into preparation
familiarity maker, rotator and familiarity output.
   After some searching of options
it turned out that it works with 8x4 acquaintances
simpler (outputting chunks using Monster's method
t. e. chain ret ; U and V are encoded as
low and high bytes of the procedure address
chunk output). There was also an 8x2 option, which
could be displayed directly in the rotator, but
There was something I didn't like about him.
   A simple 37 t/chunk rotator was made:

;B,C=#X0, where X=dU,dU+1 
;D,E=#X0, where Y=dV,dV+1 
;A=U0, A'=V0 
;SP=endline 
MAPPERLINE 
 dup 16
 push hl
 add a,b ;or c (patch)
 ld l,a
 ex af,af'
 add a,d ;or e (patch)
 or chout/256 ;there are chunk outputs
 ld h,a
push hl 
__=$ ;last pass ends here 
 add a,d ;or e (patch)
 or chout/256 ;there are chunk outputs
 ld h,a
 ex af,af'
 add a,b ;or c (patch)
 ld l,a
edup
org __
jp MAPPERLQ

   Patch add a,b/candadd 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

   Chunks, of course, can be generated in advance─
her, but inThe Boardthey were calculated on the fly.
First, all the necessary bevels were generated according to
U and V for the current angle, and then they are on─
placed using XOR in all 16 combinations
(U,V accuracy - 8 subtexels):

XORUV 
;all upics XOR current vpic 
ld bc,upics 
_=2 
 dup 8 ;8 chunks, 8 inverse copies
 dup 4 ;4 lines in a chunk
 ld a,(bc) ;can be accelerated with a stack
 xor (hl)
ld e,_
 ld (de),a
cpl
 ld e,_+#80 ;there is an inverse copy
 ld (de),a  ; chunk
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 ;construct a byte pattern
 ld a,b
 add a,lx ;U0=U0+dV ;or V0=V0-dU
edup

   The byte pattern is constructed by writing overflow─
doubts when adding and then "horizontal"
EOR-fill" (which is just a table):

;A=U*2 ;or V*2 
;C=dU*2 ;or dV*2 
;D=teorfrom0/256 
;HL=upic ;or vpic 
;CY=U[7] ;or 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. And how to rotate the image on this?

   Let's take the demo Mekanix withC-64:

A
B
B
G
D
E
F
Z
And
Y
K
L
M
N
Oh
P
R
C
T
U
F
X
C
H

   Cells 2x2.2 colors. The cells are filled
only every second line and every second─
swarm pixel.
   Texture 8(7?)x64.  With this size
textures repeats are guaranteed - you can for─
bother copy-pasting pieces of the screen, just
they don't.
   In each familiar place you can see a maximum of 4
texel, which is only 16 options. 4 shifts
in U, 4 in V in 16 variants - it turns out
256 8x8 chunks.

   This means that you must first generate 4 characters─
places of shifts in U, 4 in V, then 256 chan─
kov by or, xor, and.Instead of half ri─
Sunkov can do inversion of attributes.
   To use in these conditions obu─
exact rotator, you need to store a cell with
three neighbors, for a total of 4 bits. Which means it’s necessary
4 cards depending on direction signs─
tion, otherwise the contents of the cells will not be co─
answer. You can, of course, change the order
cells inside these four bits due to
changing the numbering order of chunks. Problem -
from which one to take attributes.
   On  C-64  the chunks are 8x8 hardware, and on
Speccy  their output (even through a line) zay─ 
metal 62976 clock cycles:

 ld h,a
 dup 4ld (hl),N
inc h
inc h
edup
org $-2
 inc l
 ret ;17 b 
;8 pieces in segment (U), 4(texture)*8(V)*256b 
:82*768=62976 

 However, when outputting chunks, you can fill
empty familiar places attribute (and do not generate
their schedule). Therefore the whole effect is better
do it in color right away, but at the same time you can do it in
1x1, not per pixel.
   Output of 8x8 chunks in color:

 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 

 Output of an empty chunk:

 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
- в этой деме  скосы уже неwere generated
on each frame, and ready-made ones were taken (ready─
32 turns were introduced). It turned out a bit rough
but the whole screen is in 2 frames at 3.5 MHz.
   Statistics in the picture "-=rotate" when
32x24:

empty cells (including neighbors) = 67% 
muz = 4000..6000 
out = 45000..55000 (output of chunks and empty 
 cells) 
math = 500 
xor = 27606 (generation of chunks from ready-made 
bevels) 
patchuv = 2500 (patch add a,N in the rotator) 
rotator = 47500 

total 133000 +- 6000 

 I think based on this technique you can create
and other effects, what do you think?

Share your thoughts about the article