Автор: Дмитрий Крапивин (g0blinish)

(Кадр м/ф «Падал прошлогодний снег», «Союзмультфильм», 1983 г.)
А вернее не прошлогодний, а олдскульный. Да и речь пойдет не о быстрых алгоритмах а об истории создания демо. По окончании зимы неплохо бы вспомнить об старом и красивом эффекте. Думаю, что многие вспомнят об увиденном эффекте в Blastersound BBStro by iguana.

Похожий эффект я решил сделать для проведения NY gift compo,объявленный ААА в 2012 году. Для bbstro приложены исходные тексты, где написано следующее:
The original idea for this intro comes from one of the
very first ASM routines that JCAB and I coded, long ago, on
the ZX Spectrum. We liked the way it looked, and as it
seems that this year we will not have snow in Madrid, we
brought the concept back. :-) Of course, we have improved it
(more pixel resolution and a random windy thing).
very first ASM routines that JCAB and I coded, long ago, on
the ZX Spectrum. We liked the way it looked, and as it
seems that this year we will not have snow in Madrid, we
brought the concept back. :-) Of course, we have improved it
(more pixel resolution and a random windy thing).
Я провел несколько часов, рассматривая, как работает эффект, потому что не разобрался в исходных текстах из-за незнания VGA.
Первая идея была следующая: нужно посчитать количество точек под пикселем (снежинкой):
*
421
Позиции точек пронумерованы для удобства, таким образом получается 8 значений, в зависимости от которых реализуется поведение снежинки:
0 (бинарное 0b000) — снег падает вниз
1 (0b001) – то же самое
4 (0b100) – то же самое
5 (0b101) – то же самое
2 (0b010) – производится случайный выбор: куда скатится снежинка, влево или вправо.
3 (0b011) – снежинка падает влево
6 (0b110) – снежинка падает вправо
7 (0b111) – стоп движения
Я написал простой код и после просмотра работы добавил еще одну вариацию — скорость падения.
Исходный код я прокомментирую по частям:
Код:
device zxspectrum128 ORG #4000 incbin "tree2-3.scr" ORG #6000 begin
6800-68FF: младший байт экранного адреса
6900-69FF: старший байт экранного адреса
6A00-6AFF: значение X/8
6B00-6BFF: битовые значения 128,64,32,16,8,4,2,1 для X.
Код:
;-----------tables for fast plot-------------------- FORMER LD DE,#4000,BC,#8000,L,E FLP1 LD H,PLOTTBL/256 LD (HL),D:INC H:LD (HL),E:INC H LD (HL),C:INC H:LD (HL),B RRC B LD A,C:ADC A,0:LD C,A FBR1 INC D:LD A,D:AND 7 JR NZ,FNXT:LD A,E:ADD A,32 LD E,A:JR C,FNXT LD A,D:SUB 8:LD D,A FNXT INC L:JR NZ,FLP1 LD HL,PLOTTBL+#C0,BC,#3F LD DE,HL:INC E LD (HL),0:LDIR
6C00-6CFF – X координата точки
6D00-6DFF – Y координата точки
6E00-6EFF – скорость падения точки
Код:
;-------------------------- PLOTTBL EQU #6800 yacc equ #6c00 sn equ #6d00;x,y=#6E000 ld hl,yacc ylp1:ld (hl),3:inc l:jr nz,ylp1;!3 ld b,170/2 ylp2:ld (hl),2:inc l:djnz ylp2 ld hl, sn prep_snowflake: call random ld (hl),a:inc h call random:and #0F ld (hl),a:dec h inc l:jr nz,prep_snowflake ;Начало работы ;----------------------main loop repeat1: ld hl, sn ei:halt
proceed_snow:
Код:
ld e,(hl):inc h:ld d,(hl):dec h ; ;стереть точки ; push de:exx:pop de LD H,HIGH PLOTTBL,L,D,B,(HL):INC H LD A,(HL),L,E ;B.A-адрес вертикальной линии INC H OR (HL) ;C+X/8 – адрес экрана по координатам. INC H:LD C,A
Код:
ld A,(BC),e,a
Код:
ld a,(HL) cpl and e LD (BC),A exx ld b,yacc/256,c,l,a,(bc),c,a ; ;движение "скорость" ;
Код:
push de,bc ld b,0 yloop: inc d push hl,bc LD H,HIGH PLOTTBL,L,D,B,(HL):INC H LD A,(HL),L,E:INC H:OR (HL) INC H:LD C,A ld A,(BC) and (hl) pop bc,hl jr z,foundbyte inc b foundbyte dec c:jr nz,yloop ld a,b pop bc,de or a:jr nz,step_one ld a,c:add a,d:ld d,a jr start_check
Код:
step_one: inc d start_check: push de inc e ld c,#00 call getpixel jr z,nextpix1 inc c;set 0,c nextpix1: dec e call getpixel jr z,nextpix2 set 1,c nextpix2: dec e call getpixel jr z,nextpix3 set 2,c nextpix3: pop de
Код:
push hl ld h,0,l,c add hl,hl ld bc,casetab add hl,bc ld c,(hl):inc hl ld b,(hl) pop hl push bc ret casetab: dw L1,L1,case3,case3,L1,L1,case6,case7 ;case0:;000 ; jp L1 ;case1:;001 ; jp L1 case2:;010 call random and 2:dec a:add a,e:ld e,a;+1 or -1 jp L1 case3:;011 dec e jp L1 ;case4:;100 ; jp L1 ;case5:;101 ; jp L1 case6:;110 inc e jp L1 case7:;111--------------stop dec d call putpixel ld d,0;;10h;0 call random ld e,a ; jp L1
Код:
L1: call putpixel ld (hl),e:inc h:ld (hl),d:dec h
Код:
inc l bit 7,l:jp z,proceed_snow
Код:
jp repeat1;to the loop ;---------------------------------------------
Код:
putpixel push hl LD H,HIGH PLOTTBL,L,D,B,(HL):INC H LD A,(HL),L,E:INC H:OR (HL) INC H:LD C,A ld A,(BC) OR (HL):LD (BC),A pop hl ret getpixel push de exx pop de LD H,HIGH PLOTTBL,L,D,B,(HL):INC H LD A,(HL),L,E:INC H:OR (HL) INC H:LD C,A ld A,(BC) and (HL) exx ret random LD A,(R1),C,A LD A,(R2):ADD A,C:LD C,A LD (R1),A,A,(R3) SUB C:LD C,A,(R2),A RRCA:LD (R3),A LD A,C RET R1 DB #15 R2 DB #70 R3 DB #FD end display /d,end-begin savesna "SnowF.sna",begin
Сообщение форума