Tutorial:interference

Материал из SpeccyWiki
Версия от 04:16, 8 августа 2012; Goblinish (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

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; действие продолжается.