ponizej przyklad pseudoplasmy z uzyciem podwojnego buforowania
gfx_mem equ $8000 ; mlodszy bajt musi miec wartosc 00!
gfx_mem2 equ $a000 ; mlodszy bajt musi miec wartosc 00!
pos_x equ $80
pos_y equ $81
color equ $82
sinval equ $83
licznik equ $84
;
org $4000
;
; Start
;
Start
ldx #<antic
ldy #>antic
stx 560
sty 561
lda #%01000000
sta 623
lda #%00100010
sta 559
;
; Init
;
Init
lda #>GFX_MEM
sta SCRBUF_PTR+1 ; ustawiamy bufor na GFX_MEM
;
; glowna petla efektu
;
Loop
lda 20
cmp 20
beq *-2 ; czekamy ramke
lda scrbuf_ptr
sta gfx_ptr
lda scrbuf_ptr+1
sta gfx_ptr+1 ; ustawiamy bufor na ktorym chcemy rysowac
lda scrbuf_ptr+1 ; podmieniamy bufor ekranu,
eor #>GFX_MEM ^ >GFX_MEM2 ; tak zeby bufor na ktorym
sta scrbuf_ptr+1 ; chcemy rysowac nie byl wyswietlany
;
; tu zaczynamy rysowac nasz efekt
;
inc licznik
ldx licznik
ldy 20
clc
lda sintab,x
adc sintab,y
sta sinval ; takie cos, co spowoduje, ze plasma bedzie sie ruszac
ldy #0 ; Y bedzie zawierac pozycje Y
Loop_Y
ldx #0 ; X bedzie zawierac pozycje X (podzielona przez 2)
Loop_X
sty pos_y ; zapisujemy aktualna pozycje Y
; liczymy kolor dla parzystego pixela
tya
clc
adc 20 ; dodajemy wartosc licznika aby uzyskac jakis ruch
tay
clc
lda sintab,x
adc sintab,y ; liczymy kolor uzywajac wsporzednych X i Y
adc sinval
; lsr @ ; sin(x)+sin(y)+sinval da w wyniku wartosc z
; lsr @ ; zakresu 0-255, musimy wiec podzielic przez 16
; lsr @ ; aby miec wartosc z zakresu 0-15
; lsr @
; asl @
; asl @
; asl @
; asl @ ; a teraz przesuwamy o 4 bity w lewo
and #$f0 ; robi dokladnie to samo co ten ciag lsr i asl u gory ;)
sta color ; zapisujemy chwilowo kolor
; nastepny pixel (pixel nieparzysty)
inx
clc
lda sintab,x
adc sintab,y ; liczymy kolor uzywajac wsporzednych X i Y
adc sinval
lsr @ ; sin(x)+sin(y)+sinval da w wyniku wartosc z
lsr @ ; zakresu 0-255, musimy wiec podzielic przez 16
lsr @ ; aby miec wartosc z zakresu 0-15
lsr @
ora color ; "dodajemy" pixel parzysty do nieparzystego
sta color ; zapamietujemy kolor
txa
lsr @
tay ; dzielimy X przez 2 aby wskazywal na odpowiednie miejsce na ekranie
lda color
gfx_ptr equ *+1
sta $ffff,y
ldy pos_y
inx ; nastepny pixel
cpx #64 ; 64 pixeli w poziomie
bcc Loop_X
; nastepna linia
clc
lda gfx_ptr
adc #40
sta gfx_ptr ; dodajemy do wskaznika ekranu 40 aby przejsc do nowej lini
bcc Skip
inc gfx_ptr+1
Skip
iny ; nastepna linia
cpy #90 ; 90 linie w pionie
bcc Loop_Y
jmp Loop
;
antic
dta b($70,$70,$70)
dta b($00)
scrbuf_ptr equ *+1
dta b($4f),a($9000)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($f,$f,$f,$f,$f,$f,$f,$f,$f,$f)
dta b($41),a(antic)
; tablica sinusa - zawiera wartosci od 0 do 63
sintab
costab equ sintab+64
dta sin(32, 31, 64, 0, 256+64)
;
run Start
kod jest bardzo wolny, ale chcialem zeby byl dosc przejrzysty i latwy do zrozumienia
plasmy nie powinny migac nawet jesli nie uzywamy podwojnego buforowania - usun: eor #>GFX_MEM ^ >GFX_MEM2 z powyzszego przykladu zeby wylaczyc podwojne buforwania - widac co prawda jak sie ekran rysuje ale nie jest to miganie...
nie uzyskasz plynnej plasmy (50fps czy nawet 25fps) w tak wysokiej rozdzielczosci (80x192) - bez uzycia trickow z LMS (powtarzanie lini przez display liste) jest to technicznie niemozliwe - sam zapis wartosci koloru na ekran w 80x192 wymaga az 7680 sta! (40*192) - a to w najlepszym przypadku 30720cykli - czyli prawie cala ramka
jesli chodzi o optymalizacje to powinienes dazyc aby LoopX wygladal mniej wiecej tak:
Loop
lda t1
clc
adc #2
sta t1
sta _sin1+1
...
lda t2
clc
adc #3
sta t2
sta _sin2+1
LoopY
...
_sin2 lda sintab,x
adc sintab,y
sta _sin0+1
....
ldx #39
LoopX
_sin0 lda #0
_sin1 adc sintab,x
tay
lda colortable,y
_scr sta screen,x
dex
bpl LoopX
i zamaist bawic sie w pixele parzyste i nieparzyste zrobic sobie rozdzielczosc pozioma 40pixeli zamiast 80 (czyli kolor 15 ma wartosc $FF, kolor 3 wartosc $33 itp) - to bardzo przyspiesza obliczenia
ogolnie najlepiej do plasm uzywac trybu textowego ze specialnym zestawem znakow - szybki i prosty w uzyciu, a plasmy w tym trybie niedosc ze chodza szybciej (mozliwe zrobienie plasmy w 1 ramce bez uzycia trickow LMS) to w dodatku wygladaja lepiej...