Ciao!
Ecco un'altra routine in puro BASIC. Stavolta, ho realizzato uno "scrolling prospettico" (una sorta di effetto 3D). Ecco il codice (usare il programma per MSDOS bastext - lo trovate anche nel sito di iAN CooG, versione ottimizzata - per convertire da txt a prg):
start tok64 land3d.prg
0 POKE 53265,PEEK(53265)AND239
1 POKE 53280,0:POKE 53281,0
5 d1=1:l1=8:d2=2:l2=16:d3=3:l3=24:s2=8:s3=24
6 f=30:g=28:p=255
7 GOSUB 1200
10 PRINT"{cyan}{@*40}";
12 PRINT"{a*40}";
14 PRINT"{b*40}";:GOSUB1000
15 FORt=12288TO12288+(32*8):POKEt,255:NEXT:FORt=14336TO14336+(32*8)
16 POKEt,255:NEXT:FORt=12288+(32*8)TO12288+(32*8)+7:POKEt,0:NEXT
17 FORt=14336+(32*8)TO14336+(32*8)+7:POKEt,0:NEXT:POKE 53265,PEEK(53265)OR16
20 i=12288:j=14337
22 q=53272
24 z=j+s3:w=j+s2
26 y=i+s3:h=i+s2:c=l1:l=l2:n=l3
30 POKEi,0:POKEq,28:POKEj,0
31 POKEq,f:POKEi+e,p:e=e+1
32 POKEi+e,0:POKEq,f:POKEh+u,p:u=u+2
33 POKEh+u,0:POKEy+a,p:a=a+3:IFe=8THENe=0:a=0:u=0
35 POKEy+a,0:POKEq,g:POKEj+v,p:v=v+1
36 POKEj+v,0:POKEw+b,p:b=b+2
37 POKEw+b,0:POKEz+d,p:d=d+3:IFv=8THENv=0:d=0:b=0
38 POKEz+d,0:GOTO31
999 END
1000 PRINT"{c*40}";
1002 PRINT"{d*40}";
1004 PRINT"{e*40}";
1006 RETURN
1200 REM * stars *
1202 PRINT"{clear}"
1204 PRINT"{white}.{space*7}.{space*13}.{space*8}.{space*5}.{down}"
1206 PRINT"{space*3}.{space*11}.{space*10}.{space*7}. . {down}"
1208 PRINT" .{space*6}.{space*9}.{space*4}.{space*8}.{space*2}.{down}"
1210 PRINT"{space*3}.{space*8}.{space*7}.{space*6}.{space*5}.{space*2}{down}"
1212 PRINT" .{space*6}.{space*6}.{space*8}.{space*3}. .{space*4}.{down}"
1214 PRINT"{space*2}.{space*5}.{space*3}.{space*7}.{space*6}.{space*5}.{space*2}{down}"
1220 FORt=12288+(46*8)TO12288+(46*8)+6:POKEt,0:NEXT:POKE12663,96
1230 FORt=14336+(46*8)TO14336+(46*8)+6:POKEt,0:NEXT:POKE14711,64
1250 RETURN
stop tok64
(bastext 1.03)
L'idea base sta nel traslare delle linee orizzontali dal basso verso l'alto. La distanza fra ciascuna linea è differente. Ad esempio, la distanza fra la linea 1 e la linea 2 è di 8 punti. La distanza fra la linea 2 e la linea 3 è di 16 punti. La distanza fra la linea 3 e l'estremità inferiore del paesaggio (riferendomi alla posizione iniziale) è di 24 punti. Non a caso vengono stampate in tutto sei file di caratteri programmabili.
Abbiamo quindi tre zone: una che si estende per 8 punti = 1 carattere, una per 16 punti = 2 caratteri e una per 24 punti = 3 caratteri (così si deduce che 1+2+3=6... non sono da prendere alla NASA?).
Ciascuna linea viene traslata nella propria zona dall'alto verso il basso, per poi riposizionarsi in alto e ripetere il movimento. Tutte e tre le linee percorrono le rispettive zone nello stesso tempo, quindi la velocità di traslazione della seconda linea è doppia della prima e la velocità della terza linea è tripla della prima. Infatti, la linea 1 viene spostata di 1 punto alla volta, la linea 2 di 2 punti alla volta e la linea 3 di 3.
L'idea di fondo è ridefinire al volo i caratteri, in modo da poter modificare molti punti nello schermo in una velocità apparente quasi da linguaggio macchina (basta far faticare il VIC-II!). Come noterete il movimento è pressoché perfettamente stabile (niente sfarfallii): ciò è stato ottenuto con un double-buffering (ho usato due set di caratteri programmabili che vengono alternati in continuazione). In questo modo non si ha il lampeggio nell'aggiornamento dell'immagine. Grazie a questo double-buffering, ho anche potuto far brillare le stelle, alternando rapidamente due definizioni del carattere "stella".
Questa routine dimostra la potenza del circuito VIC-II: lavorare in BASIC significa avere una potenza computazionale centinaia e centinaia di volte inferiore a quella di cui si dispone in linguaggio macchina e se non si è in presenza di un buon coprocessore grafico... o linguaggio macchina o niente, per routine del genere.
Il codice costituisce la versione "unrolled" di una mia routine di prototipo comprendente delle subroutine (uso di GOSUB); inoltre alcune variabili sono state rinominate in modo da avere nel ciclo principale i nomi più corti possibili, con un teorico aumento della velocità di esecuzione (di qui il perché di assegnazioni tipo L = L2).