Tutorial:interference
Interference или Moire circles - очень популярный демоэффект, который заключается в наложении области памяти, назовём спрайтом, на аналогичный спрайт с помощью операции XOR. Спрайт представляет собой концентрические окружности. Эффект распространен в демо PowerUp, DemoDyin', Dizzy4k, Inner Universe (1994,Extacy-3), Scum 1k Одним из вариантов демоэффекта является операция над блоком памяти, где окружность представляет собой значение радиуса, результат наложения на подобную область памяти интерпретируется как произвольный цвет.
Нижеприведенный пример является иллюстрацией, в частности спрайт двидется не плавно, по точкам, а по байтам, на 8 точек. Оптимизация отсутствует.
часть первая: подготовка окружностей, комментарии излишни, процедуры подробно рассматривались
ORG #8000
tabbod = #6000
PIX_TAB EQU #6000
begin
call mkbod
;--zero crap---------------
ld hl,tabbod+192
lp0
ld(hl),0
inc l
jr nz,lp0
;-------------------------
ld a,3
ld bc,#6080
lp1 push bc,af
call circle
pop af,bc
add a,7
cp 7*17+3
jr nz,lp1
ld hl,#6080
ld b,8
lp2
push bc
push hl
call fill
pop hl
ld a,l
add a, 14
ld l,a
pop bc
djnz lp2
ld hl,#6010
call fill
ld hl,#60F0
call fill
;
;---------------------------------------
nbde INC D:LD A,D:AND 7:RET NZ
LD A,E:ADD A,#20:LD E,A:RET C
LD A,D:SUB 8:LD D,A:RET
; ===========================================================================
fill:
ld bc, 64h ; 'd'
call sub_800B
ret
; =============== S U B R O U T I N E =======================================
sub_800B: ; CODE XREF: RAM:8007�p
ld a, h
cp 0C0h ; 'А'
ret nc
dec bc
push bc
call sub_80F9
ex de, hl
call sub_814B
jr c, loc_801C
pop bc
ret
; ---------------------------------------------------------------------------
loc_801C: ; CODE XREF: sub_800B+D�j
ld ix, 0FFFFh
add ix, sp
push hl
push bc
inc sp
xor a
push af
dec sp
ld c, (ix+1)
ld b, (ix+2)
inc bc
ld l, c
ld h, b
add hl, bc
add hl, bc
ld c, l
ld b, h
ld h, a
ld l, a
sbc hl, bc
add hl, sp
ld (hl), a
ld sp, hl
ld a, 80h ; 'Ђ'
push af
inc sp
ld e, l
ld d, h
inc de
dec bc
ldir
push ix
pop bc
ld hl, 0FFFAh
add hl, bc
ex de, hl
ld l, c
ld h, b
loc_8050: ; CODE XREF: sub_800B+AB�j sub_800B+C0�j
ld a, (hl)
cp 80h ; 'Ђ'
jr c, loc_8059
push ix
pop hl
ld a, (hl)
loc_8059: ; CODE XREF: sub_800B+48�j
cp 40h ; '@'
jr c, loc_80B8
ld b, a
dec hl
ld c, (hl)
dec hl
ld a, (hl)
dec hl
inc (ix+1)
jr nz, loc_806B
inc (ix+2)
loc_806B: ; CODE XREF: sub_800B+5B�j
push hl
ld l, c
ld h, b
ld b, a
push hl
call sub_8120
jr c, loc_807D
push bc
call sub_814B
call c, sub_80D3
pop bc
loc_807D: ; CODE XREF: sub_800B+68�j
pop hl
push hl
call sub_8135
jr c, loc_808C
push bc
call sub_814B
call c, sub_80D3
pop bc
loc_808C: ; CODE XREF: sub_800B+77�j
pop hl
bit 7, b
jr z, loc_80A3
push hl
ld a, l
dec l
and 1Fh
jr z, loc_80A2
push bc
ld b, 1
call sub_814B
call c, sub_80D3
pop bc
loc_80A2: ; CODE XREF: sub_800B+8B�j
pop hl
loc_80A3: ; CODE XREF: sub_800B+84�j
bit 0, b
jr z, loc_80B5
inc l
ld a, l
and 1Fh
jr z, loc_80B5
ld b, 80h ; 'Ђ'
call sub_814B
call c, sub_80D3
loc_80B5: ; CODE XREF: sub_800B+9A�j sub_800B+A0�j
pop hl
jr loc_8050
; ---------------------------------------------------------------------------
loc_80B8: ; CODE XREF: sub_800B+50�j
dec hl
dec hl
dec hl
ld a, (de)
cp 80h ; 'Ђ'
jr c, loc_80C3
push ix
pop de
loc_80C3: ; CODE XREF: sub_800B+B3�j
xor a
ld (de), a
dec de
dec de
dec de
ld a, (hl)
cp 40h ; '@'
jr nc, loc_8050
ld sp, ix
inc sp
inc sp
inc sp
ret
; End of function sub_800B
; =============== S U B R O U T I N E =======================================
sub_80D3: ; CODE XREF: sub_800B+6E�p sub_800B+7D�p ...
push hl
ld l, (ix+1)
ld h, (ix+2)
ld a, h
or l
jr nz, loc_80E0
pop hl
ret
; ---------------------------------------------------------------------------
loc_80E0: ; CODE XREF: sub_80D3+9�j
dec hl
ld (ix+1), l
ld (ix+2), h
pop hl
ld a, (de)
cp 80h ; 'Ђ'
jr c, loc_80F0
push ix
pop de
loc_80F0: ; CODE XREF: sub_80D3+18�j
ex de, hl
ld (hl), d
dec hl
ld (hl), e
dec hl
ld (hl), b
dec hl
ex de, hl
ret
; End of function sub_80D3
; =============== S U B R O U T I N E =======================================
sub_80F9: ; CODE XREF: sub_800B+6�p
and 7
or 40h ; '@'
ld d, a
ld a, h
rra
rra
rra
and 18h
or d
ld d, a
ld a, l
and 7
ld b, a
ld a, 80h ; 'Ђ'
jr z, loc_8111
loc_810E: ; CODE XREF: sub_80F9+16�j
rra
djnz loc_810E
loc_8111: ; CODE XREF: sub_80F9+13�j
ld b, a
srl l
srl l
srl l
ld a, h
rla
rla
and 0E0h ; 'а'
or l
ld e, a
ret
; End of function sub_80F9
; =============== S U B R O U T I N E =======================================
sub_8120: ; CODE XREF: sub_800B+65�p
ld a, h
dec h
and 7
ret nz
ld a, 8
add a, h
ld h, a
ld a, l
sub 20h ; ' '
ld l, a
ret nc
ld a, h
sub 8
ld h, a
cp 40h ; '@'
ret
; End of function sub_8120
; =============== S U B R O U T I N E =======================================
sub_8135: ; CODE XREF: sub_800B+74�p
inc h
ld a, h
and 7
ret nz
ld a, h
sub 8
ld h, a
ld a, l
add a, 20h ; ' '
ld l, a
ret nc
ld a, h
add a, 8
ld h, a
cp 58h ; 'X'
ccf
ret
; End of function sub_8135
; =============== S U B R O U T I N E =======================================
sub_814B: ; CODE XREF: sub_800B+A�p sub_800B+6B�p ...
ld a, b
xor (hl)
and b
ret z
ld b, a
loc_8150: ; CODE XREF: sub_814B+10�j
rra
ld c, a
ld a, b
add a, a
or c
or b
ld c, a
xor (hl)
and c
cp b
ld b, a
jp nz, loc_8150
or (hl)
ld (hl), a
scf
ret
; End of function sub_814B
;-----------end fill procedure--------------
circle ld d,a
or a
jp z,bod
inc a
ld h,b
ld l,c
ld (xy14+1),hl
ld (xy15+1),hl
ld (xy16+1),hl
ld (xy17+1),hl
ld xl,a
dec a
ld e,a
ld a,d
add a,b
ld b,a
push de
call bod
pop de
ld a,b
sub d
sub d
ld b,a
push de
call bod
pop de
ld a,b
add a,d
ld b,a
ld a,c
add a,e
ld c,a
push de
call bod
pop de
ld a,c
sub e
sub e
ld c,a
call bod
ld d,#00
ld h,d
ld l,d
ld e,xl
ld ix,#ff
e130 inc d
ld c,d
ld b,#00
add hl,bc
ld a,h
add a,a
jr nz,e130
push hl
add hl,hl
add hl,hl
xor a
ld b,a
ld c,e
sbc hl,bc
pop hl
jr c,e130
ld b,#00
ld c,e
sbc hl,bc
dec e
push hl
call eelin
pop hl
ld xl,d
xor a
xor xh
jr z,e130
ret
eelin inc xl
ld a,xl
cp e
jr z,eeln1
ld a,e
cp d
jr nc,eeln1
ld xh,d
ret
eeln1 push de
push ix
xy14 ld bc,#5555
ld a,b
add a,e
ld b,a
push de
call ccnn1
pop de
xy15 ld bc,#5555
ld a,b
sub e
ld b,a
call ccnn1
pop ix
pop de
ld a,d
cp e
jr nz,eeln2
cp xl
ret z
eeln2 push de
push ix
xy16 ld bc,#5555
ld a,c
add a,e
ld c,a
push de
call ccnn2
pop de
xy17 ld bc,#5555
ld a,c
sub e
ld c,a
call ccnn2
pop ix
pop de
ret
ccnn1 push bc
push de
ld a,c
sub d
ex af,af
ld a,c
sub xl
ld d,a
ex af,af
ld c,a
call rovno
pop de
pop bc
ld a,c
add a,d
ld d,a
ld a,c
add a,xl
ld c,a
jp rovno
ccnn2 push bc
push de
ld a,b
sub d
ex af,af
ld a,b
sub xl
ld d,a
ex af,af
ld b,a
call zvislo
pop de
pop bc
ld a,b
add a,d
ld d,a
ld a,b
add a,xl
ld b,a
jp zvislo
;----------------------
bod ld h, high tabbod;>
ld l,b
ld d,(hl)
inc h
ld a,(hl)
inc h
ld l,c
or (hl)
ld e,a
inc h
ld a,(de)
bodset xor (hl)
ld (de),a
ret
;--------------------------
hitbod = high tabbod ;>
rovno ld a,d
cp c
jr nc,rov01
ld d,c
ld c,a
rov01 ld h,hitbod+2
ld l,c
ld a,(hl)
dec h
ld l,b
or (hl)
dec h
ld h,(hl)
ld l,a
ld a,c
and #f8
ld e,a
ld a,d
and #f8
cp e
jr nz,r2byte
ld a,c
and #07
ld b,a
ld a,#ff
jr z,rov02
rov03 srl a
djnz rov03
rov02 ld c,a
rov99 ld a,d
and #07
ld b,a
ld a,#80
jr z,rov04
rov05 scf
rra
djnz rov05
rov04 and c
ooset1 xor (hl)
ld (hl),a
ret
r2byte sub e
rrca
rrca
rrca
ld e,a
ld a,c
and #07
ld b,a
ld a,#ff
jr z,ooset2
rov06 srl a
djnz rov06
ooset2 xor (hl)
ld (hl),a
ld b,c
ld c,#ff
rov40 inc l
dec e
jr z,rov99
ld a,c
ooset3 xor (hl)
ld (hl),a
jr rov40
zvislo ld a,d
cp b
jr nc,zv2
ld d,b
ld b,a
zv2 ld a,d
sub b
ret c
inc a
ld d,a
ld h,hitbod+3
ld l,c
ld e,(hl)
dec h
ld a,(hl)
dec h
ld l,b
or (hl)
dec h
ld h,(hl)
ld l,a
ld a,b
zvis cpl
and #07
inc a
ld b,a
zv1 ld a,e
ooset4 xor (hl)
ld (hl),a
inc h
dec d
ret z
djnz zv1
ld b,#08
ld a,#20
add a,l
ld l,a
jr c,zv1
ld a,#f8
add a,h
ld h,a
jr zv1
;--------------------form
mkbod ld ix,tabbod
ld hl,#4000
mkbb1 ld (ix+#00),h
inc xh
ld (ix+#00),l
dec xh
call dole
inc xl
jr nz,mkbb1
inc xh
inc xh
mkbb2 ld a,xl
rrca
rrca
rrca
and #1f
ld (ix+#00),a
ld a,xl
cpl
add a,a
add a,a
add a,a
or #c7
ld (mkbb3+1),a
xor a
mkbb3 set 1,a
inc xh
ld (ix+#00),a
dec xh
inc xl
jr nz,mkbb2
ret
dole inc h
ld a,h
and #07
ret nz
ld a,#20
add a,l
ld l,a
ret c
ld a,#f8
add a,h
ld h,a
ret
часть вторая: Процедура демоэффекта
ld hl,#4000;рисунок запоминается в область памяти
ld de,#c000
ld bc,6144
ldir
ld hl,#4000;экран очищается
ld de,#4001
ld (hl),l
ld bc,6143
ldir
loop
ei
halt
ld hl, #c408;первая область памяти
var1: ld de,#c004;вторая область памяти, которая будет использована в качестве XOR
ld ix,#4004;экранная область, где будет производится вывод
ld b,192; 192 линии для вывода "спрайта"
ilp0
push hl
push de
push ix
ilp1
dup 24; для упрощения используется 24 операции
ld a,(de)
inc de
xor(hl);сама операция, наложение байта
inc hl
ld (ix),a;результат помещается на экран
inc ix
edup
pop de;для упрощения DE=IX, или адрес экрана
call nbde;переход вниз по линии
push de
pop ix; IX=DE, или теперь IX переместился на одну линию на экране
pop de;подобная операция используется, так как в памяти происходит перемещение по копии экрана
call nbde;
pop hl
ex de,hl;еще один трюк с использованием DE для вычисления адреса, хранимого в HL(первая область памяти)
call nbde
ex de,hl
dec b
jp nz,ilp0; цикл по линиям - 192
;--------------------вычисление движения блока памяти, снова: не по точкам, а через 8.
ld a,(var1+1)
var2: add a,1
jr z,changedir;если указатель достиг 0,то нужно изменить значение в операции add a,1 на -1
cp 8; почему 8? экран 32 байта в длину, операция XOR проводится 24 байта.
jr z,changedir;если 8, то изменение 1 на -1
jr skip
changedir
push af;значение запоминается
ld a,(var2+1)
neg; 1 на -1 и наоборот
ld (var2+1),a
pop af; полученное значение
skip
ld (var1+1),a
jp loop; действие продолжается.