Nel Lino Banfi demo ho usato una routine per visualizzare la bitmap con un effetto dissolvenza, copiando i byte non in sequenza ma con un pattern pseudo casuale.
Orbene, visto che ci sono sempre 1000 modi per spellare un gatto, ho fatto un prg di esempio con alcuni altri effetti, sia usando calcoli a runtime che usando tabelle precalcolate, oltre al gia' visto pseudo random generator.
Il "trucco" consiste nel generare sempre 256 valori univoci da 0 a 255.
Questo valore poi verra' usato come indice per la copia da sorgente a destinazione, il tutto ripetuto ogni $100 bytes: prima da $6000, poi da $6100... fino a $7f00, a quel punto si genera un altro indice e si ricomincia.
Lo stesso procedimento si appilca anche alla copia degli attributi colore e schermo.
Un altro esempio di dissolvenza e' presente in quest'altro thread
http://ready64.org/smf/index.php?topic=1596.0dove pero' vengono usati sprites multiplexati per coprire la bmp, qua invece copio da una bmp "vera" a una "finta", da $6000 a $2000. Ovviamente e' applicabile solo se abbiamo una pagina bitmap libera.
; esempio di effetti dissolvenza bitmap selezionabili
; iAN CooG/HokutoForce
BMPFILLER = $00; $00 per un effetto verso il nero, $55/$ff per background
SCRFILLER = $66
COLFILLER = $06
SCREENADR = $0400
COLORSADR = $d800
*=$0801
word eop
word 7102
byte $9e,"2061",0
eop word 0
lda #<info
ldy #>info
jsr $ab1e
jsr w8k
ldy #0
fillscreen
lda #SCRFILLER
sta SCREENADR,y
sta SCREENADR+$100,y
sta SCREENADR+$200,y
sta SCREENADR+$300,y
lda #COLFILLER
sta COLORSADR,y
sta COLORSADR+$100,y
sta COLORSADR+$200,y
sta COLORSADR+$300,y
iny
bne fillscreen
jsr picdisp
loop
jsr cripplebmp
jsr w8k
jsr dissolvebmp
jsr w8k
jmp loop
info petc "press keys 0-9 for effects",0
;-----------------------------------------------------------------------------
subroutine
w8k
again jsr $ffe4
beq again
cmp #"Q"
beq exit
cmp #$30
bcc again
cmp #$3a
bcs again
;ottieniamo un valore 0-9 e usiamolo come indice
;per cambiare la routine di generazione
and #$0f
tay
lda fnptrlo,y
sta rand1+1
sta rand2+1
lda fnptrhi,y
sta rand1+2
sta rand2+2
rts
exit pla; siamo in una subroutine, quindi l'indirizzo di ritorno va
pla; tolto dallo stack per evitare comportamenti indefinibili
jmp picnodisp
;-----------------------------------------------------------------------------
subroutine
w8retrace
lda $d012
bpl *-3
lda $d012
bmi *-3
rts
;-----------------------------------------------------------------------------
subroutine
; calcoli generici per determinare $d018 e $dd00
ns = >SCREENADR<<2
nc = [>fakebmp&$3f]>>2
v18 = [ns|nc]&$ff
bank= 3-[>fakebmp>>6]
lda #v18
sta $d018
picdisp
lda $dd00
and #$f8
ora #bank
sta $dd00
lda #v18
sta $d018
lda #$18
sta $d016
lda picd021
sta $d021
sta $d020
lda #$3b
sta $d011
rts
;-----------------------------------------------------------------------------
subroutine
picnodisp
lda $dd00
and #$f8
ora #$03
sta $dd00
lda #$16
sta $d018
lda #$c8
sta $d016
lda #$06
sta $d021
lda #$1b
sta $d011
lda #$0e
jmp $e536; cancella schermo e ritorno al basic
;-----------------------------------------------------------------------------
subroutine
seed = $fc
eorseed = $fb
pseudorand
lda eorseed; la prima volta il seme e' vuoto
bne seedok
lda $d012 ; seleziona un seme a caso
eor $a2
and #$0f
tay
lda rndtab,y
sta eorseed
seedok
lda seed
beq doEor
asl
beq noEor
bcc noEor
doEor eor eorseed
noEor sta seed
tay
rts
rndtab
; questi valori garantiscono la generazione di sequenze diverse di
; 256 valori pseudo-random ciclici e mai ripetuti
byte $1d,$2b,$2d,$4d,$5f,$63,$65,$69,$71,$87,$8d,$a9,$c3,$cf,$e7,$f5
;-----------------------------------------------------------------------------
; sequenza progressiva 1,2,3...255,0
subroutine
iny01
iny
rts
;-----------------------------------------------------------------------------
subroutine
dey01
dey
rts
;-----------------------------------------------------------------------------
; queste sequenze generano 256 valori univoci
subroutine
iny09
tya
clc
adc #$09
tay
rts
;-----------------------------------------------------------------------------
subroutine
iny07
tya
clc
adc #$07
tay
rts
;-----------------------------------------------------------------------------
subroutine
iny99
tya
clc
adc #$99
tay
rts
;-----------------------------------------------------------------------------
; Qua si sfrutta anche il carry, ad esempio:
; quando A=$f8, +8 si ottiene a=$00 + carry=1, adc #00 fa si' che diventi $01
; All'ultimo ciclo e' necessario aggiustare il tiro, rimettendo Y=0
subroutine
iny08
tya
clc
adc #$08
adc #00
tay
cpx #$00
bne exiti8
ldy #0
exiti8
rts
;-----------------------------------------------------------------------------
; identico ma sottraendo
subroutine
dey08
tya
sec
sbc #$08
sbc #00
tay
cpx #$00
bne exitd8
ldy #$ff
exitd8
rts
;-----------------------------------------------------------------------------
; valori a spirale da 0 a 255, li ho generati da un programma che ho
; scritto in C, l'1 e' al centro
subroutine
spiral
ldy spiraldata,x
rts
spiraldata
byte 211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226
byte 210,157,158,159,160,161,162,163,164,165,166,167,168,169,170,227
byte 209,156,111,112,113,114,115,116,117,118,119,120,121,122,171,228
byte 208,155,110,073,074,075,076,077,078,079,080,081,082,123,172,229
byte 207,154,109,072,043,044,045,046,047,048,049,050,083,124,173,230
byte 206,153,108,071,042,021,022,023,024,025,026,051,084,125,174,231
byte 205,152,107,070,041,020,007,008,009,010,027,052,085,126,175,232
byte 204,151,106,069,040,019,006,001,002,011,028,053,086,127,176,233
byte 203,150,105,068,039,018,005,004,003,012,029,054,087,128,177,234
byte 202,149,104,067,038,017,016,015,014,013,030,055,088,129,178,235
byte 201,148,103,066,037,036,035,034,033,032,031,056,089,130,179,236
byte 200,147,102,065,064,063,062,061,060,059,058,057,090,131,180,237
byte 199,146,101,100,099,098,097,096,095,094,093,092,091,132,181,238
byte 198,145,144,143,142,141,140,139,138,137,136,135,134,133,182,239
byte 197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,240
byte 000,255,254,253,252,251,250,249,248,247,246,245,244,243,242,241
;-----------------------------------------------------------------------------
; valori a spirale, da 0 a 63 e mischiati in una griglia 2x2
subroutine
spiral4
ldy spiral4data,x
rts
spiral4data
; 1 x
; x x
byte 43-1+[64*0],44-1+[64*0],45-1+[64*0],46-1+[64*0],47-1+[64*0],48-1+[64*0],49-1+[64*0],50-1+[64*0]
byte 42-1+[64*0],21-1+[64*0],22-1+[64*0],23-1+[64*0],24-1+[64*0],25-1+[64*0],26-1+[64*0],51-1+[64*0]
byte 41-1+[64*0],20-1+[64*0],07-1+[64*0],08-1+[64*0],09-1+[64*0],10-1+[64*0],27-1+[64*0],52-1+[64*0]
byte 40-1+[64*0],19-1+[64*0],06-1+[64*0],01-1+[64*0],02-1+[64*0],11-1+[64*0],28-1+[64*0],53-1+[64*0]
byte 39-1+[64*0],18-1+[64*0],05-1+[64*0],04-1+[64*0],03-1+[64*0],12-1+[64*0],29-1+[64*0],54-1+[64*0]
byte 38-1+[64*0],17-1+[64*0],16-1+[64*0],15-1+[64*0],14-1+[64*0],13-1+[64*0],30-1+[64*0],55-1+[64*0]
byte 37-1+[64*0],36-1+[64*0],35-1+[64*0],34-1+[64*0],33-1+[64*0],32-1+[64*0],31-1+[64*0],56-1+[64*0]
byte 64-1+[64*0],63-1+[64*0],62-1+[64*0],61-1+[64*0],60-1+[64*0],59-1+[64*0],58-1+[64*0],57-1+[64*0]
; x 2
; x x
byte 43-1+[64*1],44-1+[64*1],45-1+[64*1],46-1+[64*1],47-1+[64*1],48-1+[64*1],49-1+[64*1],50-1+[64*1]
byte 42-1+[64*1],21-1+[64*1],22-1+[64*1],23-1+[64*1],24-1+[64*1],25-1+[64*1],26-1+[64*1],51-1+[64*1]
byte 41-1+[64*1],20-1+[64*1],07-1+[64*1],08-1+[64*1],09-1+[64*1],10-1+[64*1],27-1+[64*1],52-1+[64*1]
byte 40-1+[64*1],19-1+[64*1],06-1+[64*1],01-1+[64*1],02-1+[64*1],11-1+[64*1],28-1+[64*1],53-1+[64*1]
byte 39-1+[64*1],18-1+[64*1],05-1+[64*1],04-1+[64*1],03-1+[64*1],12-1+[64*1],29-1+[64*1],54-1+[64*1]
byte 38-1+[64*1],17-1+[64*1],16-1+[64*1],15-1+[64*1],14-1+[64*1],13-1+[64*1],30-1+[64*1],55-1+[64*1]
byte 37-1+[64*1],36-1+[64*1],35-1+[64*1],34-1+[64*1],33-1+[64*1],32-1+[64*1],31-1+[64*1],56-1+[64*1]
byte 64-1+[64*1],63-1+[64*1],62-1+[64*1],61-1+[64*1],60-1+[64*1],59-1+[64*1],58-1+[64*1],57-1+[64*1]
; x x
; 3 x
byte 43-1+[64*2],44-1+[64*2],45-1+[64*2],46-1+[64*2],47-1+[64*2],48-1+[64*2],49-1+[64*2],50-1+[64*2]
byte 42-1+[64*2],21-1+[64*2],22-1+[64*2],23-1+[64*2],24-1+[64*2],25-1+[64*2],26-1+[64*2],51-1+[64*2]
byte 41-1+[64*2],20-1+[64*2],07-1+[64*2],08-1+[64*2],09-1+[64*2],10-1+[64*2],27-1+[64*2],52-1+[64*2]
byte 40-1+[64*2],19-1+[64*2],06-1+[64*2],01-1+[64*2],02-1+[64*2],11-1+[64*2],28-1+[64*2],53-1+[64*2]
byte 39-1+[64*2],18-1+[64*2],05-1+[64*2],04-1+[64*2],03-1+[64*2],12-1+[64*2],29-1+[64*2],54-1+[64*2]
byte 38-1+[64*2],17-1+[64*2],16-1+[64*2],15-1+[64*2],14-1+[64*2],13-1+[64*2],30-1+[64*2],55-1+[64*2]
byte 37-1+[64*2],36-1+[64*2],35-1+[64*2],34-1+[64*2],33-1+[64*2],32-1+[64*2],31-1+[64*2],56-1+[64*2]
byte 64-1+[64*2],63-1+[64*2],62-1+[64*2],61-1+[64*2],60-1+[64*2],59-1+[64*2],58-1+[64*2],57-1+[64*2]
; x x
; x 4
byte 43-1+[64*3],44-1+[64*3],45-1+[64*3],46-1+[64*3],47-1+[64*3],48-1+[64*3],49-1+[64*3],50-1+[64*3]
byte 42-1+[64*3],21-1+[64*3],22-1+[64*3],23-1+[64*3],24-1+[64*3],25-1+[64*3],26-1+[64*3],51-1+[64*3]
byte 41-1+[64*3],20-1+[64*3],07-1+[64*3],08-1+[64*3],09-1+[64*3],10-1+[64*3],27-1+[64*3],52-1+[64*3]
byte 40-1+[64*3],19-1+[64*3],06-1+[64*3],01-1+[64*3],02-1+[64*3],11-1+[64*3],28-1+[64*3],53-1+[64*3]
byte 39-1+[64*3],18-1+[64*3],05-1+[64*3],04-1+[64*3],03-1+[64*3],12-1+[64*3],29-1+[64*3],54-1+[64*3]
byte 38-1+[64*3],17-1+[64*3],16-1+[64*3],15-1+[64*3],14-1+[64*3],13-1+[64*3],30-1+[64*3],55-1+[64*3]
byte 37-1+[64*3],36-1+[64*3],35-1+[64*3],34-1+[64*3],33-1+[64*3],32-1+[64*3],31-1+[64*3],56-1+[64*3]
byte 64-1+[64*3],63-1+[64*3],62-1+[64*3],61-1+[64*3],60-1+[64*3],59-1+[64*3],58-1+[64*3],57-1+[64*3]
;-----------------------------------------------------------------------------
subroutine
dissolvebmp
ldx #0
ldy #0
rand1 jsr pseudorand; indirizzo sostituito con la routine scelta
jsr storescreen
inx
bne rand1
stx eorseed
rts
;-----------------------------------------------------------------------------
; pulizia schermata
; a seconda della pic vanno aggiustati i valori di riempimento in testa al src
subroutine
storescreen
lda #BMPFILLER
storebm sta fakebmp,y
inc storebm+2
lda storebm+2
cmp #>[fakebmp]+$20
bne storescreen
; ripristina puntatori per il prossimo giro
lda #>fakebmp
sta storebm+2
store04
lda #SCRFILLER
storesc sta SCREENADR,y
inc storesc+2
lda storesc+2
cmp #>[SCREENADR]+$04
bne store04
lda #>SCREENADR
sta storesc+2
stored8
lda #COLFILLER
storeco sta COLORSADR,y
inc storeco+2
lda storeco+2
cmp #>[COLORSADR]+$04
bne stored8
lda #>COLORSADR
sta storeco+2
jmp w8retrace
;-----------------------------------------------------------------------------
subroutine
cripplebmp
ldx #0
ldy #0
rand2 jsr pseudorand; indirizzo sostituito con la routine scelta
jsr putscreen
inx
bne rand2
stx eorseed
rts
;-----------------------------------------------------------------------------
; riempimento schermata
; copia dalla vera bmp a quella di lavoro, usando Y come indice
subroutine
putscreen
srcbm lda realbmp,y
putbm sta fakebmp,y
inc srcbm+2
inc putbm+2
lda putbm+2
cmp #>[fakebmp]+$20
bne putscreen
; ripristina puntatori per il prossimo giro
lda #>fakebmp
sta putbm+2
lda #>realbmp
sta srcbm+2
put04 lda screen,y
putsc sta SCREENADR,y
inc put04+2
inc putsc+2
lda putsc+2
cmp #>[SCREENADR]+$04
bne put04
lda #>SCREENADR
sta putsc+2
lda #>screen
sta put04+2
putd8
lda colors,y
putco sta COLORSADR,y
inc putd8+2
inc putco+2
lda putco+2
cmp #>[COLORSADR]+$04
bne putd8
lda #>COLORSADR
sta putco+2
lda #>colors
sta putd8+2
jmp w8retrace
;-----------------------------------------------------------------------------
subroutine
fnptrlo
byte <pseudorand
byte <iny01
byte <iny07
byte <iny09
byte <iny99
byte <dey01
byte <iny08
byte <dey08
byte <spiral
byte <spiral4
fnptrhi
byte >pseudorand
byte >iny01
byte >iny07
byte >iny09
byte >iny99
byte >dey01
byte >iny08
byte >dey08
byte >spiral
byte >spiral4
;-----------------------------------------------------------------------------
*=$6000
realbmp
incprg bmp\foo3x.kla
screen = realbmp +8000
colors = realbmp +8000+1000
picd021= realbmp +8000+1000+1000
; bmp di destinazione, preparata con filler
*=$2000
fakebmp
ds 8000,BMPFILLER