home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti3 / lezione7p.s < prev    next >
Text File  |  1995-09-29  |  11KB  |  350 lines

  1.  
  2. ; Lezione7p.s - esempio di applicazione della routine universale:
  3. ;           4 SPRITE A 4 COLORI AFFIANCATI PER FORMARE UNA FIGURA
  4. ;        LARGA 64 PIXEL.
  5. ;         USANDO DUE TABELLE DI VALORI (ossia di coordinate verticali
  6. ;        e orizzontali) PRESTABILITI.
  7.  
  8.     SECTION    CiriCop,CODE
  9.  
  10. Inizio:
  11.     move.l    4.w,a6        ; Execbase
  12.     jsr    -$78(a6)    ; Disable
  13.     lea    GfxName(PC),a1    ; Nome lib
  14.     jsr    -$198(a6)    ; OpenLibrary
  15.     move.l    d0,GfxBase
  16.     move.l    d0,a6
  17.     move.l    $26(a6),OldCop    ; salviamo la vecchia COP
  18.  
  19. ;    Puntiamo la PIC "vuota"
  20.  
  21.     MOVE.L    #BITPLANE,d0    ; dove puntare
  22.     LEA    BPLPOINTERS,A1    ; puntatori COP
  23.     move.w    d0,6(a1)
  24.     swap    d0
  25.     move.w    d0,2(a1)
  26.  
  27. ;    Puntiamo 4 sprite
  28.  
  29.  
  30.     MOVE.L    #MIOSPRITE,d0        ; indirizzo dello sprite in d0
  31.     LEA    SpritePointers,a1    ; Puntatori in copperlist
  32.     move.w    d0,6(a1)
  33.     swap    d0
  34.     move.w    d0,2(a1)
  35.     MOVE.L    #MIOSPRITE1,d0        ; indirizzo dello sprite in d0
  36.     addq.w    #8,a1            ; prossimi SPRITEPOINTERS
  37.     move.w    d0,6(a1)
  38.     swap    d0
  39.     move.w    d0,2(a1)
  40.     MOVE.L    #MIOSPRITE2,d0        ; indirizzo dello sprite in d0
  41.     addq.w    #8,a1            ; prossimi SPRITEPOINTERS
  42.     move.w    d0,6(a1)
  43.     swap    d0
  44.     move.w    d0,2(a1)
  45.     MOVE.L    #MIOSPRITE3,d0        ; indirizzo dello sprite in d0
  46.     addq.w    #8,a1            ; prossimi SPRITEPOINTERS
  47.     move.w    d0,6(a1)
  48.     swap    d0
  49.     move.w    d0,2(a1)
  50.  
  51.     move.l    #COPPERLIST,$dff080    ; nostra COP
  52.     move.w    d0,$dff088        ; START COP
  53.     move.w    #0,$dff1fc        ; NO AGA!
  54.     move.w    #$c00,$dff106        ; NO AGA!
  55.  
  56.  
  57. Mouse1:
  58.     cmpi.b    #$ff,$dff006    ; Linea 255?
  59.     bne.s    Mouse1
  60.  
  61.     bsr.w    MuoviGliSprite    ; muove tutti gli sprite
  62.     
  63. Aspetta:
  64.     cmpi.b    #$ff,$dff006    ; linea 255?
  65.     beq.s    Aspetta
  66.  
  67.     btst    #6,$bfe001    ; tasto sinistro del mouse premuto?
  68.     bne.s    mouse1
  69.  
  70.     move.l    OldCop(PC),$dff080    ; Puntiamo la cop di sistema
  71.     move.w    d0,$dff088        ; facciamo partire la vecchia cop
  72.  
  73.  
  74.     move.l    4.w,a6
  75.     jsr    -$7e(a6)    ; Enable
  76.     move.l    gfxbase(PC),a1
  77.     jsr    -$19e(a6)    ; Closelibrary
  78.     rts
  79.  
  80. ;    Dati
  81.  
  82. GfxName:
  83.     dc.b    "graphics.library",0,0
  84.  
  85. GfxBase:
  86.     dc.l    0
  87.  
  88. OldCop:
  89.     dc.l    0
  90.  
  91.  
  92. ; Questa routine legge dalla tabella le coordinate dello sprite 0, lo muove
  93. ; usando la routine Universale che abbiamo visto in lezione7m, e poi sposta
  94. ; anche gli altri sprite. Gli altri sprite avranno la stessa coordinata
  95. ; verticale del primo e saranno affiancati distando 16 pixel l'uno dall'altro.
  96. ; la posiz. orizzontale dello sprite 1 e` 16 pixel piu` a destra dello sprite 0
  97. ; la posiz. orizzontale dello sprite 2 e` 16 pixel piu` a destra dello sprite 1
  98. ; la posiz. orizzontale dello sprite 3 e` 16 pixel piu` a destra dello sprite 2
  99.  
  100. MuoviGliSprite:
  101.     ADDQ.L    #1,TABYPOINT     ; Fai puntare al byte successivo
  102.     MOVE.L    TABYPOINT(PC),A0 ; indirizzo contenuto in long TABXPOINT
  103.                  ; copiato in a0
  104.     CMP.L    #FINETABY-1,A0  ; Siamo all'ultimo byte della TAB?
  105.     BNE.S    NOBSTARTY    ; non ancora? allora continua
  106.     MOVE.L    #TABY-1,TABYPOINT ; Riparti a puntare dal primo byte
  107. NOBSTARTY:
  108.     moveq    #0,d4        ; Pulisci d4
  109.     MOVE.b    (A0),d4        ; copia il byte dalla tabella in d4
  110.                 ; in modo da farla trovare alla routine
  111.                 ; universale
  112.  
  113.     ADDQ.L    #1,TABXPOINT
  114.     MOVE.L    TABXPOINT(PC),A0 ; indirizzo contenuto in long TABXPOINT
  115.                  ; copiato in a0
  116.     CMP.L    #FINETABX-1,A0
  117.     BNE.S    NOBSTARTX
  118.     MOVE.L    #TABX-1,TABXPOINT
  119. NOBSTARTX:
  120.     moveq    #0,d3        ; azzeriamo d3
  121.     MOVE.b    (A0),d3    ; poniamo il valore della tabella in d3
  122.  
  123.     moveq    #15,d2        ; altezza dello sprite: e` la stessa per
  124.                                 ; tutti e 4, quindi la mettiamo in d2
  125.                 ; una volta per tutte!
  126.  
  127.     lea    MIOSPRITE,A1    ; indirizzo sprite 0
  128.     move.w    d4,d0        ; mettiamo le coordinate nei registri
  129.     move.w    d3,d1
  130.     bsr.w    UniMuoviSprite    ; esegue la routine universale che posiziona
  131.                 ; lo sprite
  132.  
  133.     lea    MIOSPRITE1,A1    ; indirizzo sprite 1
  134.     add.w    #16,d3        ; sprite 1 16 pixel piu` a destra di sprite 0
  135.     move.w    d4,d0        ; mettiamo le coordinate nei registri
  136.     move.w    d3,d1
  137.     bsr.w    UniMuoviSprite    ; esegue la routine universale che posiziona
  138.                 ; lo sprite
  139.  
  140.     lea    MIOSPRITE2,A1    ; indirizzo sprite 2
  141.     add.w    #16,d3        ; sprite 2 16 pixel piu` a destra di sprite 1
  142.     move.w    d4,d0        ; mettiamo le coordinate nei registri
  143.     move.w    d3,d1
  144.     bsr.w    UniMuoviSprite    ; esegue la routine universale che posiziona
  145.                 ; lo sprite
  146.  
  147.     lea    MIOSPRITE3,A1    ; indirizzo sprite 3
  148.     add.w    #16,d3        ; sprite 3 16 pixel piu` a destra di sprite 2
  149.     move.w    d4,d0        ; mettiamo le coordinate nei registri
  150.     move.w    d3,d1
  151.     bsr.w    UniMuoviSprite    ; esegue la routine universale che posiziona
  152.                 ; lo sprite
  153.     rts
  154.  
  155.  
  156. TABYPOINT:
  157.     dc.l    TABY-1        ; NOTA: i valori della tabella qua sono bytes,
  158.                 ; dunque lavoriamo con un ADDQ.L #1,TABYPOINT
  159.                 ; e non #2 come per quando sono word o con #4
  160.                 ; come quando sono longword.
  161. TABXPOINT:
  162.     dc.l    TABX-1        ; NOTA: i valori della tabella qua sono byte
  163.  
  164. ; Tabella con coordinate Y dello sprite precalcolate.
  165. ; Da notare che la posizione Y per far entrare lo sprite nella finestra video
  166. ; deve essere compresa tra $0 e $ff, infatti l'offset di $2c viene aggiunto
  167. ; dalla routine. Se non si usano schermi overscan, ossia non piu' lunghi di
  168. ; 255 linee, si puo' usare una tabella di valori dc.b (da $00 a $FF)
  169.  
  170. TABY:
  171.     incbin    "ycoordinatok.tab"    ; 200 valori .B
  172. FINETABY:
  173.  
  174.  
  175. ; Tabella con coordinate X dello sprite piu` a sinistra precalcolate.
  176. ; Questa tabella contiene valori reali, senza gli offset che sono aggiunti
  177. ; automaticamente dalla routine universale.
  178. ; Poiche` i 4 sprite insieme formano una figura larga 64 pixel, lo sprite
  179. ; piu` a sinistra puo` variare la sua posizione orizzontale tra 0 e 
  180. ; 319-64=255. Questo fatto ci consente di usare anche per questa tabella
  181. ; dei bytes anziche` delle word
  182. ; La tabella e` fatta sempre con
  183. ; IS
  184. ; beg>0
  185. ; end>360
  186. ; amount>300
  187. ; amp>255/2
  188. ; y_offset>255/2
  189. ; multiplier>1
  190.  
  191. TABX:
  192.     DC.B    $80,$83,$86,$88,$8B,$8E,$90,$93,$95,$98,$9B,$9D,$A0,$A2,$A5,$A8
  193.     DC.B    $AA,$AD,$AF,$B1,$B4,$B6,$B9,$BB,$BD,$C0,$C2,$C4,$C6,$C9,$CB,$CD
  194.     DC.B    $CF,$D1,$D3,$D5,$D7,$D9,$DB,$DC,$DE,$E0,$E2,$E3,$E5,$E7,$E8,$EA
  195.     DC.B    $EB,$EC,$EE,$EF,$F0,$F1,$F2,$F4,$F5,$F6,$F6,$F7,$F8,$F9,$FA,$FA
  196.     DC.B    $FB,$FB,$FC,$FC,$FD,$FD,$FD,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FD
  197.     DC.B    $FD,$FD,$FC,$FC,$FB,$FB,$FA,$FA,$F9,$F8,$F7,$F6,$F6,$F5,$F4,$F2
  198.     DC.B    $F1,$F0,$EF,$EE,$EC,$EB,$EA,$E8,$E7,$E5,$E3,$E2,$E0,$DE,$DC,$DB
  199.     DC.B    $D9,$D7,$D5,$D3,$D1,$CF,$CD,$CB,$C9,$C6,$C4,$C2,$C0,$BD,$BB,$B9
  200.     DC.B    $B6,$B4,$B1,$AF,$AD,$AA,$A8,$A5,$A2,$A0,$9D,$9B,$98,$95,$93,$90
  201.     DC.B    $8E,$8B,$88,$86,$83,$80,$7E,$7B,$78,$76,$73,$70,$6E,$6B,$69,$66
  202.     DC.B    $63,$61,$5E,$5C,$59,$56,$54,$51,$4F,$4D,$4A,$48,$45,$43,$41,$3E
  203.     DC.B    $3C,$3A,$38,$35,$33,$31,$2F,$2D,$2B,$29,$27,$25,$23,$22,$20,$1E
  204.     DC.B    $1C,$1B,$19,$17,$16,$14,$13,$12,$10,$0F,$0E,$0D,$0C,$0A,$09,$08
  205.     DC.B    $08,$07,$06,$05,$04,$04,$03,$03,$02,$02,$01,$01,$01,$00,$00,$00
  206.     DC.B    $00,$00,$00,$00,$00,$01,$01,$01,$02,$02,$03,$03,$04,$04,$05,$06
  207.     DC.B    $07,$08,$08,$09,$0A,$0C,$0D,$0E,$0F,$10,$12,$13,$14,$16,$17,$19
  208.     DC.B    $1B,$1C,$1E,$20,$22,$23,$25,$27,$29,$2B,$2D,$2F,$31,$33,$35,$38
  209.     DC.B    $3A,$3C,$3E,$41,$43,$45,$48,$4A,$4D,$4F,$51,$54,$56,$59,$5C,$5E
  210.     DC.B    $61,$63,$66,$69,$6B,$6E,$70,$73,$76,$78,$7B,$7E
  211. FINETABX:
  212.  
  213.  
  214.  
  215. ; Routine universale di posizionamento degli sprite.
  216.  
  217. ;
  218. ;    Parametri in entrata di UniMuoviSprite:
  219. ;
  220. ;    a1 = Indirizzo dello sprite
  221. ;    d0 = posizione verticale Y dello sprite sullo schermo (0-255)
  222. ;    d1 = posizione orizzontale X dello sprite sullo schermo (0-320)
  223. ;    d2 = altezza dello sprite
  224. ;
  225.  
  226. UniMuoviSprite:
  227. ; posizionamento verticale
  228.     ADD.W    #$2c,d0        ; aggiungi l'offset dell'inizio dello schermo
  229.  
  230. ; a1 contiene l'indirizzo dello sprite
  231.     MOVE.b    d0,(a1)        ; copia il byte in VSTART
  232.     btst.l    #8,d0
  233.     beq.s    NonVSTARTSET
  234.     bset.b    #2,3(a1)    ; Setta il bit 8 di VSTART (numero > $FF)
  235.     bra.s    ToVSTOP
  236. NonVSTARTSET:
  237.     bclr.b    #2,3(a1)    ; Azzera il bit 8 di VSTART (numero < $FF)
  238. ToVSTOP:
  239.     ADD.w    D2,D0        ; Aggiungi l'altezza dello sprite per
  240.                 ; determinare la posizione finale (VSTOP)
  241.     move.b    d0,2(a1)    ; Muovi il valore giusto in VSTOP
  242.     btst.l    #8,d0
  243.     beq.s    NonVSTOPSET
  244.     bset.b    #1,3(a1)    ; Setta il bit 8 di VSTOP (numero > $FF)
  245.     bra.w    VstopFIN
  246. NonVSTOPSET:
  247.     bclr.b    #1,3(a1)    ; Azzera il bit 8 di VSTOP (numero < $FF)
  248. VstopFIN:
  249.  
  250. ; posizionamento orizzontale
  251.     add.w    #128,D1        ; 128 - per centrare lo sprite.
  252.     btst    #0,D1        ; bit basso della coordinata X azzerato?
  253.     beq.s    BitBassoZERO
  254.     bset    #0,3(a1)    ; Settiamo il bit basso di HSTART
  255.     bra.s    PlaceCoords
  256.  
  257. BitBassoZERO:
  258.     bclr    #0,3(a1)    ; Azzeriamo il bit basso di HSTART
  259. PlaceCoords:
  260.     lsr.w    #1,D1        ; SHIFTIAMO, ossia spostiamo di 1 bit a destra
  261.                 ; il valore di HSTART, per "trasformarlo" nel
  262.                 ; valore fa porre nel byte HSTART, senza cioe'
  263.                 ; il bit basso.
  264.     move.b    D1,1(a1)    ; Poniamo il valore XX nel byte HSTART
  265.     rts
  266.  
  267.  
  268.     SECTION    GRAPHIC,DATA_C
  269.  
  270. COPPERLIST:
  271. SpritePointers:
  272.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  273.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  274.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  275.     dc.w    $13e,0
  276.  
  277.     dc.w    $8E,$2c81    ; DiwStrt
  278.     dc.w    $90,$2cc1    ; DiwStop
  279.     dc.w    $92,$38        ; DdfStart
  280.     dc.w    $94,$d0        ; DdfStop
  281.     dc.w    $102,0        ; BplCon1
  282.     dc.w    $104,0        ; BplCon2
  283.     dc.w    $108,0        ; Bpl1Mod
  284.     dc.w    $10a,0        ; Bpl2Mod
  285.  
  286.             ; 5432109876543210
  287.     dc.w    $100,%0001001000000000    ; bit 12 acceso!! 1 bitplane lowres
  288.  
  289. BPLPOINTERS:
  290.     dc.w $e0,0,$e2,0    ;primo     bitplane
  291.  
  292. ;    Palette della PIC
  293.  
  294.     dc.w    $180,$000    ; color0    ; sfondo nero
  295.     dc.w    $182,$123    ; color1    ; colore 1 del bitplane, che
  296.                         ; in questo caso e' vuoto,
  297.                         ; per cui non compare.
  298.  
  299. ;    Palette degli SPRITE
  300.  
  301.     dc.w    $1A2,$800    ; color17
  302.     dc.w    $1A4,$d00    ; color18
  303.     dc.w    $1A6,$cc0    ; color19
  304.  
  305.      ; i colori per gli sprite 2 e 3 sono gli stessi che per sprite 0 e 1
  306.     dc.w    $1AA,$800    ; color21
  307.     dc.w    $1AC,$d00    ; color22
  308.     dc.w    $1AE,$cc0    ; color23
  309.  
  310.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  311.  
  312.  
  313. ; ************ Ecco gli sprite: OVVIAMENTE in CHIP RAM! **********
  314.  
  315. MIOSPRITE:                ; lunghezza 15 linee
  316.     incbin    "Largesprite0.raw"
  317.  
  318. MIOSPRITE1:                ; lunghezza 15 linee
  319.     incbin    "Largesprite1.raw"
  320.  
  321. MIOSPRITE2:                ; lunghezza 15 linee
  322.     incbin    "Largesprite2.raw"
  323.  
  324. MIOSPRITE3:                ; lunghezza 15 linee
  325.     incbin    "Largesprite3.raw"
  326.  
  327.  
  328.     SECTION    PLANEVUOTO,BSS_C    ; Il bitplane azzerato che usiamo,
  329.                     ; perche' per vedere gli sprite
  330.                     ; e' necessario che ci siano bitplanes
  331.                     ; abilitati
  332. BITPLANE:
  333.     ds.b    40*256        ; bitplane azzerato lowres
  334.  
  335.     end
  336.  
  337. In questo listato utiliziamo 4 sprite a 4 colori per realizzare una figura
  338. larga 64 pixel. Gli sprite sono allineati orizzontalmente. Pertanto hanno
  339. tutti la stessa posizione verticale, mentre orizzontalmente distano 16 pixel
  340. l'uno dall'altro.
  341. Dalle tabelle leggiamo la posizione del primo sprite, mentre per gli altri
  342. usiamo la stessa coordinata verticale e aggiungiamo ogni volta 16 pixel a
  343. quella orizzontale.
  344. Notate la comodita` di avere una routine universale: per spostare gli sprite
  345. usiamo sempre la stessa routine, solo che ogni volta mettiamo un diverso
  346. indirizzo in a1 e diverse coordinate nei registri d0 e d1. In questo caso
  347. l'altezza e` sempre la stessa, per cui non modifichiamo d2. Se pero` avessimo
  348. bisogno di muovere sprite di diverse altezze, non ci sarebbe problema,
  349. basterebbe cambiare anche d2 e usare sempre la stessa routine universale.
  350.