Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: Elder0010 - 08 Luglio 2011, 00:41:06
-
Ciao ragazzi, vi mostro un po' di codice del mio demo (in progress per secoli di questo passo :lol:).
Si tratta di uno scroller su tutto lo schermo, con una parte di schermo accesa e una spenta, di grandezza variabile. Per realizzarlo ho usato un pattern a "cubetti" (char mode), l'ho copiato su tutto lo schermo, che scrolla continuamente.
Poi, ho diviso lo schermo in aree (dall'alto in basso):
- area sempre accesa
- area "oscillante" accesa/spenta
- area centrale, con scritta
- area "oscillante" accesa / spenta
- area sempre accesa
L'effetto "a rimbalzo" è dato settando gli irq centrali leggendo da due sintables, con due diversi puntatori che oscillano tra un min e un max variabile.
La parte "spenta" è realizzata utilizzando $d011 con il valore #$7b (illegal mode). Sicuramente avrò peccato di scarsa ottimizzazione, al solito, ma vi mostro il risultato! In allegato, il prg compilato, i sorgenti e il resto :)
grazie a raffox per i cubetti!
*=$0900
sei
lda #$0
jsr $1000
lda #$35
sta $01
;Inizializzo scroller
lda #$0
sta scrollcount
lda $DD00
and #%11111100
ora #%00000011
sta $DD00
lda #$7f
ldx #$01
sta $dc0d ; Turn off CIA 1 interrupts
sta $dd0d ; Turn off CIA 2 interrupts
stx $d01a ; Turn on raster interrupts
lda #$1b
ldx #$08
ldy #$1c
sta $d011
stx $d016
sty $d018
lda #<scrollcubes
ldx #>scrollcubes
ldy #$01
sta $fffe
stx $ffff
sty $d012
lda $dc0d ; ACK CIA 1 interrupts
lda $dd0d ; ACK CIA 2 interrupts
asl $d019 ; ACK VIC interrupts
;Setto colori sfondo e del testo (cubetti)
lda #$0
sta $d020
lda #$0
sta $d021
lda #$6
sta $d022
lda #$0e
sta $d023
lda #$0f
sta $d024
lda #$d0
sta $d016
ldx #$0
clrsccubes
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
dex
bne clrsccubes
ldx #$0
cc
lda cubes,x
sta $0400,x
inx
cpx #$2
bne cc
ldx #$2
lda cubes,x
sta $0428
ldx #$3
lda cubes,x
sta $0429
ldx #$4
lda cubes,x
sta $0450
ldx #$5
lda cubes,x
sta $0451
ldx #$6
lda cubes,x
sta $0478
ldx #$7
lda cubes,x
sta $0479
;Colori
lda #$09
ldx #$0
clo
sta $d800 +$00,x
sta $d800 +$100,x
sta $d800 +$200,x
sta $d800 +$300,x
inx
bne clo
;Copio un pattern
ldx #$0
qlp
lda $0400,x
sta $0400+$2,x
lda $0428,x
sta $0428+$2,x
lda $0450,x
sta $0450+$2,x
lda $0478,x
sta $0478+$2,x
inx
cpx #$26
bne qlp
;Ripeto su tutto lo schermo
jsr clean_mid
jsr cubecloner_top
cli
loop:
jmp loop ; infinite loop
;SCHERMO OFF
scrollcubes:
pha
txa
pha
tya
pha
asl $d019
lda #$1b
sta $d011
lda #<cubes_sup_off
ldx #>cubes_sup_off
sta $fffe
stx $ffff
ldx sup_sin_count
ldy sin_sup,x
;ldy #$88
;ldy #$56
sty $d012
pla
tay
pla
tax
pla
rti ; return from interrupt
;SCHERMO OFF
cubes_sup_off
asl $d019 ; ACK interrupt (to re-enable it)
pha
txa
pha
tya
pha
lda #$0
sta $d020
nop
nop
nop
nop
nop
nop
nop
nop
lda #$7b
sta $d011
lda #<rasteropen
ldx #>rasteropen
ldy #$89
sta $fffe
stx $ffff
sty $d012
pla
tay
pla
tax
pla
rti
;Apertura 1
rasteropen:
asl $d019
pha
txa
pha
tya
pha
lda $d011
and #%11101111
sta $d011
lda #$c0
sta $d016
lda #$16
sta $d018
inc scrollcount
jsr show_endless
ldy #$14
del1
dey
cpy #$0
bne del1
lda #$5
; sta $d021
ldy #$13
del2
dey
cpy #$0
bne del2
lda #$0
; sta $d021
lda #$1b
sta $d011
lda #<rasterclose
ldx #>rasterclose
ldy #$a1
sta $fffe
stx $ffff
sty $d012
pla
tay
pla
tax
pla
rti
;QUI INIZIANO LE OSCILLAZIONI ALL'INGIU'!
;SCHERMO OFF
rasterclose
asl $d019
pha
txa
pha
tya
pha
nop
nop
lda $d016
and #%11110000
ora scrollcount
ora #%00010000
sta $d016
lda #$1c ; screen at $0400, chars at $2000
sta $d018
lda #$7b
sta $d011
lda #<cubes_low_off
ldx #>cubes_low_off
sta $fffe ; store in interrupt vector
stx $ffff
ldx low_sin_count
ldy sin_inf,x
;ldy #$c0
;ldy #$da
sty $d012
;inc s
pla
tay
pla
tax
pla
rti
;SCHERMO OFF
cubes_low_off
pha
txa
pha
tya
pha
asl $d019
lda #$0
sta $d020
nop
nop
nop
nop
nop
nop
nop
nop
lda #$9b
sta $d011
jsr $1003
lda #<holdcubes
ldx #>holdcubes
ldy #$01
sta $fffe
stx $ffff
sty $d012
pla
tay
pla
tax
pla
rti
;Scrolling cubi e parte bassa dello schermo
holdcubes
pha
txa
pha
tya
pha
asl $d019 ; ACK interrupt
lda #$1c
sta $d018
lda scrollcount
cmp #$7
bne no_reset
lda #$0
sta scrollcount
;Copio un pattern
ldx #$27
qloop
dex
lda $0400-1,x
sta $0400,x
lda $0400+$28-1,x
sta $0400+$28,x
lda $0400+$28*2-1,x
sta $0400+$28*2,x
lda $0400+$28*3-1,x
sta $0400+$28*3,x
lda $0400+$28*4-1,x
sta $0400+$28*4,x
cpx #$0
bne qloop
lda $0402
sta $0400
lda $0400+$28*1+$2
sta $0400+$28*1
lda $0400+$28*2+$2
sta $0400+$28*2
lda $0400+$28*3+$2
sta $0400+$28*3
lda $0400+$28*4+$2
sta $0400+$28*4
no_reset
lda #$1b
sta $d011
lda #<scrollcubes
ldx #>scrollcubes
ldy #$00
sta $fffe
stx $ffff
sty $d012
lda $d016
and #%11110000
ora scrollcount
sta $d016
;inc $d020
jsr cubecloner_top
;Bouncing degli irq
lda sup_sin_count
cmp sup_sin_max
bpl max_not_reach
lda sup_sin_max
sec
sbc #$7
sta sup_sin_max
dec sup_sin_count
dec sup_sin_count
dec sup_sin_count
dec sup_sin_count
inc low_sin_count
inc low_sin_count
inc low_sin_count
inc low_sin_count
jmp straight_exit
max_not_reach
inc sup_sin_count
dec low_sin_count
straight_exit
pla
tay
pla
tax
pla
rti ; return from interrupt
cubecloner_top
ldx #$0
frl
lda $0400,x
sta $0400+$28*4,x
sta $0400+$28*8,x
sta $0400+$28*16,x
sta $0400+$28*20,x
sta $0400+$28*24,x
sta $0400+$28*28,x
lda $0428,x
sta $0428+$28*4,x
sta $0428+$28*8,x
sta $0428+$28*16,x
sta $0428+$28*20,x
sta $0428+$28*24,x
sta $0428+$28*28,x
lda $0450,x
sta $0450+$28*4,x
sta $0450+$28*8,x
sta $0450+$28*12,x
sta $0450+$28*16,x
sta $0450+$28*20,x
lda $0478,x
sta $0478+$28*4,x
sta $0478+$28*12,x
sta $0478+$28*16,x
sta $0478+$28*20,x
sta $0478+$28*24,x
sta $0478+$28*28,x
inx
cpx #$27
bne frl
rts
clean_mid
lda #$20
ldx #$0
cl_0
sta $0428+$28*8,x
sta $0428+$28*12,x
sta $0450+$28*8,x
sta $0478+$28*8,x
sta $0400+$28*12,x
inx
cpx #$28
bne cl_0
rts
show_endless
ldy #$0
eelop lda endless,y
;SEC
;adc #$40
sta $05ef,y
lda #$f
sta $d9ef,y
iny
cpy #$9
bne eelop
rts
cubes
.byte $00,$01,$02,$03,$04,$05,$06,$07
endless
.SCRU ".endless."
scrollcount
.byte $0
sup_sin_count
.byte $40
sup_sin_max
.byte $30
low_sin_count
.byte $20
sup_irq_count
.byte $0
*=$1000
incprg "music.dat"
*=$3000
incbin "cubetticc.chr"
sin_sup
incbin "SINSOR.P00"
sin_inf
incbin "SINSSK.P00"
-
'giorno coder.
L'effetto é carino ed il programma, a mio umilissimo parere, é fatto bene.
Due sole note tecniche:
- i due passaggi charmode-illegal ed illegal-charmode non sono perfettamente regolari in corrispondenza delle badline. Avendole animate velocemente non si nota molto per la verità e comunque é un problema che sto affrontando anch'io nel programmino che divide lo schermo (quello che hai visto in IRC).
Ho l'impressione che l'unica soluzione sia chiamare l'IRQ qualche linea prima, mettersi in sincrono col raster, "assorbire" l'eventuale badline ed infine al momento giusto switchare $d011. Più facile a dirsi che a farsi.
- un'ottimizzazione molto mirata al caso specifico: dal momento che il pattern che disegni é regolare (si ripete ogni 2 caratteril), invece di far scrollare l'intero schermo potresti preparare due schermate. Una con lo schermo normale e l'altra con lo schermo scrollato di un carattere a sinistra. Ogni 8 pixel scrollati poi ti basterà passare da uno schermo all'altro alternativamente.
A ME MI piace comunque!
Thumb up
-
Molto interessante!
-
Bene, grazie delle osservazioni!!
Per quanto riguarda l'ottimizzazione delle schermate, mi farebbe guadagnare altro rastertime! E' una buona cosa, considerato che le zone in alto e in basso non si spengono mai perchè ho bisogno di un sacco di tempo per fare la copia di tutto lo schermo ad ogni frame...
Invece purtroppo ero a conoscenza del flicker.. ho tarato piu' possibile i ritardi e i colori per mascherare la faccenda :D :D il problema è che qui gli irq saltano continuamente per via di quelle due sintables con il lookup variabile e non vedo una via semplice per capire se sono in una badline o meno. Forse pensandoci a mente fresca mi verrà un'idea!
-
grazie a raffox per i cubetti!
Speriamo che il menestrello non legga... sennò chi lo sente!
Io ufficialmente faccio solo Pushover :fagiano:
-
grazie a raffox per i cubetti!
Speriamo che il menestrello non legga... sennò chi lo sente!
Io ufficialmente faccio solo Pushover :fagiano:
Il menestrello legge, ma è anche moooolto democratico...
E a parte ciò complimenti a Elder per il risultato ottenuto!
-
Il menestrello legge, ma è anche moooolto democratico...
E a parte ciò complimenti a Elder per il risultato ottenuto!
Ecco perché il menestrello ha tutta la mia infinita e incondizionata stima ;)