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

  1.  
  2. ; Lezione7p.s    UNO SPRITE MOSSO CON IL JOYSTICK
  3.  
  4.  
  5.     SECTION    CiriCop,CODE
  6.  
  7. Inizio:
  8.     move.l    4.w,a6        ; Execbase
  9.     jsr    -$78(a6)    ; Disable
  10.     lea    GfxName(PC),a1    ; Nome lib
  11.     jsr    -$198(a6)    ; OpenLibrary
  12.     move.l    d0,GfxBase
  13.     move.l    d0,a6
  14.     move.l    $26(a6),OldCop    ; salviamo la vecchia COP
  15.  
  16. ;    Puntiamo la PIC "vuota"
  17.  
  18.     MOVE.L    #BITPLANE,d0    ; dove puntare
  19.     LEA    BPLPOINTERS,A1    ; puntatori COP
  20.     move.w    d0,6(a1)
  21.     swap    d0
  22.     move.w    d0,2(a1)
  23.  
  24. ;    Puntiamo lo sprite
  25.  
  26.     MOVE.L    #MIOSPRITE,d0        ; indirizzo dello sprite in d0
  27.     LEA    SpritePointers,a1    ; Puntatori in copperlist
  28.     move.w    d0,6(a1)
  29.     swap    d0
  30.     move.w    d0,2(a1)
  31.  
  32.     move.l    #COPPERLIST,$dff080    ; nostra COP
  33.     move.w    d0,$dff088        ; START COP
  34.     move.w    #0,$dff1fc        ; NO AGA!
  35.     move.w    #$c00,$dff106        ; NO AGA!
  36.  
  37. mouse:
  38.     cmpi.b    #$ff,$dff006    ; Linea 255?
  39.     bne.s    mouse
  40.  
  41.     btst    #7,$bfe001    ; Tasto FIRE premuto?
  42.     bne.s    NonFuoco    ; se no, salta l'istruzione seguente
  43.     move.w    #$f00,$dff180    ; se si, il metti un bel ROSSO nel COLOR0
  44. NonFuoco:
  45.  
  46.     bsr.s    LeggiJoyst    ; questa legge il joystick
  47.     move.w    sprite_y(pc),d0 ; prepara i parametri per la routine
  48.     move.w    sprite_x(pc),d1 ; universale
  49.     lea    miosprite,a1    ; indirizzo sprite
  50.     moveq    #13,d2        ; altezza sprite
  51.     bsr.w    UniMuoviSprite    ; chiama la routine universale
  52.  
  53. Aspetta:
  54.     cmpi.b    #$ff,$dff006    ; linea 255?
  55.     beq.s    Aspetta
  56.  
  57.     btst    #6,$bfe001    ; mouse premuto?
  58.     bne.s    mouse
  59.  
  60.     move.l    OldCop(PC),$dff080    ; Puntiamo la cop di sistema
  61.     move.w    d0,$dff088        ; facciamo partire la vecchia cop
  62.  
  63.     move.l    4.w,a6
  64.     jsr    -$7e(a6)    ; Enable
  65.     move.l    gfxbase(PC),a1
  66.     jsr    -$19e(a6)    ; Closelibrary
  67.     rts
  68.  
  69. ;    Dati
  70.  
  71. GfxName:
  72.     dc.b    "graphics.library",0,0
  73.  
  74. GfxBase:
  75.     dc.l    0
  76.  
  77. OldCop:
  78.     dc.l    0
  79.  
  80. ; Questa routine legge il joystick e aggiorna i valori contenuti nelle
  81. ; variabili sprite_x e sprite_y
  82.  
  83. LeggiJoyst:
  84.     MOVE.w    $dff00c,D3    ; JOY1DAT
  85.     BTST.l    #1,D3        ; il bit 1 ci dice se si va a destra
  86.     BEQ.S    NODESTRA    ; se vale zero non si va a destra
  87.     ADDQ.w    #1,SPRITE_X    ; se vale 1 sposta a di un pixel lo sprite
  88.     BRA.S    CHECK_Y        ; vai al controllo della Y
  89. NODESTRA:
  90.     BTST.l    #9,D3        ; il bit 9 ci dice se si va a sinistra
  91.     BEQ.S    CHECK_Y        ; se vale zero non si va a sinistra
  92.     SUBQ.W    #1,SPRITE_X    ; se vale 1 sposta lo sprite
  93. CHECK_Y:
  94.     MOVE.w    D3,D2        ; copia il valore del registro
  95.     LSR.w    #1,D2        ; fa scorrere i bit di un posto verso destra 
  96.     EOR.w    D2,D3        ; esegue l'or esclusivo. Ora possiamo testare
  97.     BTST.l    #8,D3        ; testiamo se va in alto
  98.     BEQ.S    NOALTO        ; se no controlla se va in basso
  99.     SUBQ.W    #1,SPRITE_Y    ; se si sposta lo sprite
  100.     BRA.S    ENDJOYST
  101. NOALTO:
  102.     BTST.l    #0,D3        ; testiamo se va in basso
  103.     BEQ.S    ENDJOYST    ; se no finisci
  104.     ADDQ.W    #1,SPRITE_Y    ; se si sposta lo sprite
  105. ENDJOYST:
  106.     RTS
  107.  
  108. SPRITE_Y:    dc.w    0    ; qui viene memorizzata la Y dello sprite
  109. SPRITE_X:    dc.w    0    ; qui viene memorizzata la X dello sprite
  110.  
  111.  
  112.  
  113. ; Routine universale di posizionamento degli sprite.
  114.  
  115. ;
  116. ;    Parametri in entrata di UniMuoviSprite:
  117. ;
  118. ;    a1 = Indirizzo dello sprite
  119. ;    d0 = posizione verticale Y dello sprite sullo schermo (0-255)
  120. ;    d1 = posizione orizzontale X dello sprite sullo schermo (0-320)
  121. ;    d2 = altezza dello sprite
  122. ;
  123.  
  124. UniMuoviSprite:
  125. ; posizionamento verticale
  126.     ADD.W    #$2c,d0        ; aggiungi l'offset dell'inizio dello schermo
  127.  
  128. ; a1 contiene l'indirizzo dello sprite
  129.     MOVE.b    d0,(a1)        ; copia il byte in VSTART
  130.     btst.l    #8,d0
  131.     beq.s    NonVSTARTSET
  132.     bset.b    #2,3(a1)    ; Setta il bit 8 di VSTART (numero > $FF)
  133.     bra.s    ToVSTOP
  134. NonVSTARTSET:
  135.     bclr.b    #2,3(a1)    ; Azzera il bit 8 di VSTART (numero < $FF)
  136. ToVSTOP:
  137.     ADD.w    D2,D0        ; Aggiungi l'altezza dello sprite per
  138.                 ; determinare la posizione finale (VSTOP)
  139.     move.b    d0,2(a1)    ; Muovi il valore giusto in VSTOP
  140.     btst.l    #8,d0
  141.     beq.s    NonVSTOPSET
  142.     bset.b    #1,3(a1)    ; Setta il bit 8 di VSTOP (numero > $FF)
  143.     bra.w    VstopFIN
  144. NonVSTOPSET:
  145.     bclr.b    #1,3(a1)    ; Azzera il bit 8 di VSTOP (numero < $FF)
  146. VstopFIN:
  147.  
  148. ; posizionamento orizzontale
  149.     add.w    #128,D1        ; 128 - per centrare lo sprite.
  150.     btst    #0,D1        ; bit basso della coordinata X azzerato?
  151.     beq.s    BitBassoZERO
  152.     bset    #0,3(a1)    ; Settiamo il bit basso di HSTART
  153.     bra.s    PlaceCoords
  154.  
  155. BitBassoZERO:
  156.     bclr    #0,3(a1)    ; Azzeriamo il bit basso di HSTART
  157. PlaceCoords:
  158.     lsr.w    #1,D1        ; SHIFTIAMO, ossia spostiamo di 1 bit a destra
  159.                 ; il valore di HSTART, per "trasformarlo" nel
  160.                 ; valore fa porre nel byte HSTART, senza cioe'
  161.                 ; il bit basso.
  162.     move.b    D1,1(a1)    ; Poniamo il valore XX nel byte HSTART
  163.     rts
  164.  
  165.  
  166.  
  167.     SECTION    GRAPHIC,DATA_C
  168.  
  169. COPPERLIST:
  170. SpritePointers:
  171.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  172.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  173.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  174.     dc.w    $13e,0
  175.  
  176.     dc.w    $8E,$2c81    ; DiwStrt
  177.     dc.w    $90,$2cc1    ; DiwStop
  178.     dc.w    $92,$38        ; DdfStart
  179.     dc.w    $94,$d0        ; DdfStop
  180.     dc.w    $102,0        ; BplCon1
  181.     dc.w    $104,0        ; BplCon2
  182.     dc.w    $108,0        ; Bpl1Mod
  183.     dc.w    $10a,0        ; Bpl2Mod
  184.  
  185.             ; 5432109876543210
  186.     dc.w    $100,%0001001000000000    ; bit 12 acceso!! 1 bitplane lowres
  187.  
  188. BPLPOINTERS:
  189.     dc.w $e0,0,$e2,0    ;primo     bitplane
  190.  
  191.     dc.w    $180,$000    ; color0    ; sfondo nero
  192.     dc.w    $182,$123    ; color1    ; colore 1 del bitplane, che
  193.                         ; in questo caso e' vuoto,
  194.                         ; per cui non compare.
  195.  
  196.     dc.w    $1A2,$F00    ; color17, ossia COLOR1 dello sprite0 - ROSSO
  197.     dc.w    $1A4,$0F0    ; color18, ossia COLOR2 dello sprite0 - VERDE
  198.     dc.w    $1A6,$FF0    ; color19, ossia COLOR3 dello sprite0 - GIALLO
  199.  
  200.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  201.  
  202.  
  203. ; ************ Ecco lo sprite: OVVIAMENTE deve essere in CHIP RAM! ************
  204.  
  205. MIOSPRITE:        ; lunghezza 13 linee
  206. VSTART:
  207.     dc.b $50    ; Posizione verticale di inizio sprite (da $2c a $f2)
  208. HSTART:
  209.     dc.b $90    ; Posizione orizzontale di inizio sprite (da $40 a $d8)
  210. VSTOP:
  211.     dc.b $5d    ; $50+13=$5d    ; posizione verticale di fine sprite
  212. VHBITS:
  213.     dc.b $00    ; bit
  214.  
  215.  dc.w    %0000000000000000,%0000110000110000 ; Formato binario per modifiche
  216.  dc.w    %0000000000000000,%0000011001100000
  217.  dc.w    %0000000000000000,%0000001001000000
  218.  dc.w    %0000000110000000,%0011000110001100 ;BINARIO 00=COLORE 0 (TRASPARENTE)
  219.  dc.w    %0000011111100000,%0110011111100110 ;BINARIO 10=COLORE 1 (ROSSO)
  220.  dc.w    %0000011111100000,%1100100110010011 ;BINARIO 01=COLORE 2 (VERDE)
  221.  dc.w    %0000110110110000,%1111100110011111 ;BINARIO 11=COLORE 3 (GIALLO)
  222.  dc.w    %0000011111100000,%0000011111100000
  223.  dc.w    %0000011111100000,%0001111001111000
  224.  dc.w    %0000001111000000,%0011101111011100
  225.  dc.w    %0000000110000000,%0011000110001100
  226.  dc.w    %0000000000000000,%1111000000001111
  227.  dc.w    %0000000000000000,%1111000000001111
  228.  dc.w    0,0    ; 2 word azzerate definiscono la fine dello sprite.
  229.  
  230.  
  231.     SECTION    PLANEVUOTO,BSS_C    ; Il bitplane azzerato che usiamo,
  232.                     ; perche' per vedere gli sprite
  233.                     ; e' necessario che ci siano bitplanes
  234.                     ; abilitati
  235. BITPLANE:
  236.     ds.b    40*256        ; bitplane azzerato lowres
  237.  
  238.     end
  239.  
  240. In questo esempio muoviamo uno sprite con il joystick.
  241. La cosa piu' facile e' rilevare se il bottone FIRE e' premuto, infatti basta
  242. un BTST #7,$bfe001, analogamente al tasto sinistro del mouse che e' il bit 6.
  243. Per posizionare lo sprite sullo schermo usiamo la nostra routine universale,
  244. che abbiamo gia` bella pronta risparmiandoci un po' di lavoro.
  245. La routine Leggijoyst invece si occupa di rilevare lo stato del joystick e di
  246. conseguenza aggiorna le coordinate dello sprite che sono memorizzate
  247. in 2 locazioni di memoria: SPRITE_X e SPRITE_Y. Per leggere il joystick
  248. e` necessario utilizzare l'istruzione EOR che, come abbiamo visto nella lezione
  249. esegue un'operazione di OR ESCLUSIVO tra i bit di 2 registri.
  250. Infatti la lettura del joystick avviene tramite il registro JOY1DAT. Per sapere
  251. se la leva del joystick e` stata premuta a destra o a sinistra, basta sapere
  252. lo stato dei bit 1 e 9. per le altre direzioni e` un po' piu` complicato.
  253. Infatti, per sapere se la leva del joystick e` spinta verso l'alto bisogna
  254. calcolare l'OR ESCLUSIVO tra il bit 8 e il bit 9 del registro JOY1DAT.
  255. Poiche` questi 2 bit si trovano sullo stesso registro, prima copiamo il
  256. registro in 2 registri dati del 68000, per esempio D2 e D3. Poi SHIFTIAMO
  257. (cioe` facciamo scorrere) verso destra i bit di uno dei 2 registri dati.
  258. In questo modo il bit 9 del registro dati viene spostato nella posizione 8.
  259. Poiche` il registro che abbiamo SHIFTATO conteneva una copia di JOY1DAT,
  260. dopo lo SHIFT il bit 8 del registro dati sara` uguale al bit 9 di JOY1DAT.
  261. Nel registro non SHIFTATO, invece il bit 8 e` uguale al bit 8 di JOY1DAT.
  262. Facendo ora l'EOR tra i due registri, nella posizione 8 ci sara` quindi l'EOR
  263. tra il bit 8 del registro JOY1DAT e il bit 9 del registro JOY1DAT. Proprio
  264. quello che ci serviva per sapere se dobbiamo muovere lo sprite verso l'alto.
  265. Per quanto riguarda il basso si deve calcolare l'OR ESCLUSIVO tra i bit 0 e 1
  266. nello stesso modo che per l'alto.
  267.  
  268. Potete provare a variare la velocita` dello sprite. Nella routine LeggiJoyst
  269. quando viene rilevato che la leva e` stata spostata in una certa direzione 
  270. viene corrrispondentemente spostato di 1 pixel lo sprite con una ADDQ #1,xxx
  271. (o con una SUBQ #1,xxx) . Se invece di 1 mettete valori maggiori lo sprite
  272. si muovera` piu` velocemente.
  273.