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

  1.  
  2. ; Lezione7r2.s    UNO SPRITE MOSSO CON IL MOUSE CHE ARRIVA FINO AL BORDO DESTRO
  3.  
  4.  
  5.  
  6.     SECTION    CiriCop,CODE
  7.  
  8. Inizio:
  9.     move.l    4.w,a6        ; Execbase
  10.     jsr    -$78(a6)    ; Disable
  11.     lea    GfxName(PC),a1    ; Nome lib
  12.     jsr    -$198(a6)    ; OpenLibrary
  13.     move.l    d0,GfxBase
  14.     move.l    d0,a6
  15.     move.l    $26(a6),OldCop    ; salviamo la vecchia COP
  16.  
  17. ;    Puntiamo la PIC "vuota"
  18.  
  19.     MOVE.L    #BITPLANE,d0    ; dove puntare
  20.     LEA    BPLPOINTERS,A1    ; puntatori COP
  21.     move.w    d0,6(a1)
  22.     swap    d0
  23.     move.w    d0,2(a1)
  24.  
  25. ;    Puntiamo lo sprite
  26.  
  27.     MOVE.L    #MIOSPRITE,d0        ; indirizzo dello sprite in d0
  28.     LEA    SpritePointers,a1    ; Puntatori in copperlist
  29.     move.w    d0,6(a1)
  30.     swap    d0
  31.     move.w    d0,2(a1)
  32.  
  33.     move.l    #COPPERLIST,$dff080    ; nostra COP
  34.     move.w    d0,$dff088        ; START COP
  35.     move.w    #0,$dff1fc        ; NO AGA!
  36.     move.w    #$c00,$dff106        ; NO AGA!
  37.  
  38.     move.b    $dff00a,mouse_y
  39.     move.b    $dff00b,mouse_x
  40.  
  41. mouse:
  42.     cmpi.b    #$ff,$dff006    ; Linea 255?
  43.     bne.s    mouse
  44.  
  45.     bsr.s    LeggiMouse    ; questa legge il mouse
  46.     move.w    sprite_y(pc),d0 ; prepara i parametri per la routine
  47.     move.w    sprite_x(pc),d1 ; universale
  48.     lea    miosprite,a1    ; indirizzo sprite
  49.     moveq    #13,d2        ; altezza sprite
  50.     bsr.w    UniMuoviSprite    ; chiama la routine universale
  51.  
  52. Aspetta:
  53.     cmpi.b    #$ff,$dff006    ; linea 255?
  54.     beq.s    Aspetta
  55.  
  56.     btst    #6,$bfe001    ; mouse premuto?
  57.     bne.s    mouse
  58.  
  59.     move.l    OldCop(PC),$dff080    ; Puntiamo la cop di sistema
  60.     move.w    d0,$dff088        ; facciamo partire la vecchia cop
  61.  
  62.     move.l    4.w,a6
  63.     jsr    -$7e(a6)    ; Enable
  64.     move.l    gfxbase(PC),a1
  65.     jsr    -$19e(a6)    ; Closelibrary
  66.     rts
  67.  
  68. ;    Dati
  69.  
  70. GfxName:
  71.     dc.b    "graphics.library",0,0
  72.  
  73. GfxBase:
  74.     dc.l    0
  75.  
  76. OldCop:
  77.     dc.l    0
  78.  
  79. ; Questa routine legge il mouse e aggiorna i valori contenuti nelle
  80. ; variabili sprite_x e sprite_y
  81.  
  82. LeggiMouse:
  83.     move.b    $dff00a,d1    ; JOY0DAT posizione verticale mouse
  84.     move.b    d1,d0        ; copia in d0
  85.     sub.b    mouse_y(PC),d0    ; sottrai vecchia posizione mouse
  86.     beq.s    no_vert        ; se la differenza = 0, il mouse e` fermo
  87.     ext.w    d0        ; trasforma il byte in word
  88.                 ; (vedi alla fine del listato)
  89.     add.w    d0,sprite_y    ; modifica posizione sprite
  90. no_vert:
  91.       move.b    d1,mouse_y    ; salva posizione mouse per la prossima volta
  92.  
  93.     move.b    $dff00b,d1    ; posizione orizzontale mouse
  94.     move.b    d1,d0        ; copia in d0
  95.     sub.b    mouse_x(PC),d0    ; sottrai vecchia posizione
  96.     beq.s    no_oriz        ; se la differenza = 0, il mouse e` fermo
  97.     ext.w    d0        ; trasforma il byte in word
  98.                 ; (vedi alla fine del listato)
  99.     add.w    d0,sprite_x    ; modifica pos. sprite
  100. no_oriz
  101.       move.b    d1,mouse_x    ; salva posizione mouse per la prossima volta
  102.     RTS
  103.  
  104. SPRITE_Y:    dc.w    0    ; qui viene memorizzata la Y dello sprite
  105. SPRITE_X:    dc.w    0    ; qui viene memorizzata la X dello sprite
  106. MOUSE_Y:    dc.b    0    ; qui viene memorizzata la Y del mouse
  107. MOUSE_X:    dc.b    0    ; qui viene memorizzata la X del mouse
  108.  
  109.  
  110.  
  111.  
  112. ; Routine universale di posizionamento degli sprite.
  113.  
  114. ;
  115. ;    Parametri in entrata di UniMuoviSprite:
  116. ;
  117. ;    a1 = Indirizzo dello sprite
  118. ;    d0 = posizione verticale Y dello sprite sullo schermo (0-255)
  119. ;    d1 = posizione orizzontale X dello sprite sullo schermo (0-320)
  120. ;    d2 = altezza dello sprite
  121. ;
  122.  
  123. UniMuoviSprite:
  124. ; posizionamento verticale
  125.     ADD.W    #$2c,d0        ; aggiungi l'offset dell'inizio dello schermo
  126.  
  127. ; a1 contiene l'indirizzo dello sprite
  128.     MOVE.b    d0,(a1)        ; copia il byte in VSTART
  129.     btst.l    #8,d0
  130.     beq.s    NonVSTARTSET
  131.     bset.b    #2,3(a1)    ; Setta il bit 8 di VSTART (numero > $FF)
  132.     bra.s    ToVSTOP
  133. NonVSTARTSET:
  134.     bclr.b    #2,3(a1)    ; Azzera il bit 8 di VSTART (numero < $FF)
  135. ToVSTOP:
  136.     ADD.w    D2,D0        ; Aggiungi l'altezza dello sprite per
  137.                 ; determinare la posizione finale (VSTOP)
  138.     move.b    d0,2(a1)    ; Muovi il valore giusto in VSTOP
  139.     btst.l    #8,d0
  140.     beq.s    NonVSTOPSET
  141.     bset.b    #1,3(a1)    ; Setta il bit 8 di VSTOP (numero > $FF)
  142.     bra.w    VstopFIN
  143. NonVSTOPSET:
  144.     bclr.b    #1,3(a1)    ; Azzera il bit 8 di VSTOP (numero < $FF)
  145. VstopFIN:
  146.  
  147. ; posizionamento orizzontale
  148.     add.w    #128,D1        ; 128 - per centrare lo sprite.
  149.     btst    #0,D1        ; bit basso della coordinata X azzerato?
  150.     beq.s    BitBassoZERO
  151.     bset    #0,3(a1)    ; Settiamo il bit basso di HSTART
  152.     bra.s    PlaceCoords
  153.  
  154. BitBassoZERO:
  155.     bclr    #0,3(a1)    ; Azzeriamo il bit basso di HSTART
  156. PlaceCoords:
  157.     lsr.w    #1,D1        ; SHIFTIAMO, ossia spostiamo di 1 bit a destra
  158.                 ; il valore di HSTART, per "trasformarlo" nel
  159.                 ; valore fa porre nel byte HSTART, senza cioe'
  160.                 ; il bit basso.
  161.     move.b    D1,1(a1)    ; Poniamo il valore XX nel byte HSTART
  162.     rts
  163.  
  164.  
  165.     SECTION    GRAPHIC,DATA_C
  166.  
  167. COPPERLIST:
  168. SpritePointers:
  169.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  170.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  171.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  172.     dc.w    $13e,0
  173.  
  174.     dc.w    $8E,$2c81    ; DiwStrt
  175.     dc.w    $90,$2cc1    ; DiwStop
  176.     dc.w    $92,$38        ; DdfStart
  177.     dc.w    $94,$d0        ; DdfStop
  178.     dc.w    $102,0        ; BplCon1
  179.     dc.w    $104,0        ; BplCon2
  180.     dc.w    $108,0        ; Bpl1Mod
  181.     dc.w    $10a,0        ; Bpl2Mod
  182.  
  183.             ; 5432109876543210
  184.     dc.w    $100,%0001001000000000    ; bit 12 acceso!! 1 bitplane lowres
  185.  
  186. BPLPOINTERS:
  187.     dc.w $e0,0,$e2,0    ;primo     bitplane
  188.  
  189.     dc.w    $180,$000    ; color0    ; sfondo nero
  190.     dc.w    $182,$123    ; color1    ; colore 1 del bitplane, che
  191.                         ; in questo caso e' vuoto,
  192.                         ; per cui non compare.
  193.  
  194.     dc.w    $1A2,$F00    ; color17, ossia COLOR1 dello sprite0 - ROSSO
  195.     dc.w    $1A4,$0F0    ; color18, ossia COLOR2 dello sprite0 - VERDE
  196.     dc.w    $1A6,$FF0    ; color19, ossia COLOR3 dello sprite0 - GIALLO
  197.  
  198.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  199.  
  200.  
  201. ; ************ Ecco lo sprite: OVVIAMENTE deve essere in CHIP RAM! ************
  202.  
  203. MIOSPRITE:        ; lunghezza 13 linee
  204. VSTART:
  205.     dc.b $50    ; Posizione verticale di inizio sprite (da $2c a $f2)
  206. HSTART:
  207.     dc.b $90    ; Posizione orizzontale di inizio sprite (da $40 a $d8)
  208. VSTOP:
  209.     dc.b $5d    ; $50+13=$5d    ; posizione verticale di fine sprite
  210. VHBITS:
  211.     dc.b $00    ; bit
  212.  
  213.  dc.w    %0000000000000000,%0000110000110000 ; Formato binario per modifiche
  214.  dc.w    %0000000000000000,%0000011001100000
  215.  dc.w    %0000000000000000,%0000001001000000
  216.  dc.w    %0000000110000000,%0011000110001100 ;BINARIO 00=COLORE 0 (TRASPARENTE)
  217.  dc.w    %0000011111100000,%0110011111100110 ;BINARIO 10=COLORE 1 (ROSSO)
  218.  dc.w    %0000011111100000,%1100100110010011 ;BINARIO 01=COLORE 2 (VERDE)
  219.  dc.w    %0000110110110000,%1111100110011111 ;BINARIO 11=COLORE 3 (GIALLO)
  220.  dc.w    %0000011111100000,%0000011111100000
  221.  dc.w    %0000011111100000,%0001111001111000
  222.  dc.w    %0000001111000000,%0011101111011100
  223.  dc.w    %0000000110000000,%0011000110001100
  224.  dc.w    %0000000000000000,%1111000000001111
  225.  dc.w    %0000000000000000,%1111000000001111
  226.  dc.w    0,0    ; 2 word azzerate definiscono la fine dello sprite.
  227.  
  228.  
  229.     SECTION    PLANEVUOTO,BSS_C    ; Il bitplane azzerato che usiamo,
  230.                     ; perche' per vedere gli sprite
  231.                     ; e' necessario che ci siano bitplanes
  232.                     ; abilitati
  233. BITPLANE:
  234.     ds.b    40*256        ; bitplane azzerato lowres
  235.  
  236.     end
  237.  
  238. In questo esempio muoviamo uno sprite con il mouse in modo da raggiungere
  239. il bordo destro e da non avere problemi con un eventuale overscan verticale.
  240.  
  241. Se vogliamo raggiungere il bordo destro dobbiamo usare una word per la
  242. posizione orizzontale dello sprite. Il mouse pero` ci fornisce delle
  243. coordinate in forma di byte. Allora usiamo il seguente metodo:
  244. memorizziamo separatamente le coordinate dello sprite e le coordinate fornite
  245. dal mouse. Ogni volta che eseguiamo LeggiMouse, leggiamo delle nuove
  246. coordinate e le confrontiamo con le vecchie. Calcoliamo la differenza tra le
  247. vecchie e le nuove coordiante del mouse, e aggiungiamo questa differenza alle
  248. coordinate dello sprite. In questo modo non ha importanza il fatto che quando
  249. la posizione del mouse supera 255 ritorna a 0, perche` cio` che conta e` solo
  250. la differenza tra la nuova e la vecchia coordinata. Vi ricordo infatti che se
  251. un byte assume un valore da 128 a 255, quando lo usiamo in un'addizione o in 
  252. una sottrazione viene considerato un numero negativo in complemento a due.
  253. Per cui se la vecchia coordinata vale 255, e la nuova vale 1, facendo la
  254. differenza 255(=$ff) viene considerato -1. Quindi 1-(-1)=2.
  255. Questo numero 2 viene aggiunto alla coordinata x dello sprite e siccome e`
  256. positivo provoca comunque uno spostamento verso destra.
  257. Se invece la differenza fosse stata negativa, aggiungendola alla coordinata x
  258. dello sprite avrebbe provocato uno spostamento verso sinistra.
  259. C'e` comunque un particolare a cui bisogna prestare molta attenzione. Quando
  260. facciamo la differenza tra le coordinate del mouse stiamo lavorando con due
  261. byte. Per cui la differenza sara` ancora un byte. Questo byte poi lo sommiamo
  262. alla coordinata dello sprite che e` una word. Cio` provoca un problema.
  263. Prima di fare la somma e` necessario trasformare il byte in una word.
  264. La trasformazione viene fatta dal'istruzione EXT che trasforma un byte
  265. contenuto in un registro in una word. Vediamo come opera tale istruzione.
  266. Ci sono 2 casi:
  267. Il byte contiene un numero positivo, per es. 5. La EXT trasforma cosi`:
  268.  
  269.     Contenuto prima della EXT    Contenuto dopo la EXT
  270.     $XX05                $0005
  271. (XX indica un qualsiasi numero)
  272.  
  273. Infatti 5 in formato word si scrive proprio $0005
  274.  
  275. Il byte contiene un numero negativo, per es. -5. La EXT trasforma cosi`:
  276. Ricordando che -5 in formato byte si scrive $FB
  277.  
  278.     Contenuto prima della EXT    Contenuto dopo la EXT
  279.     $XXFB                $FFFB
  280. (XX indica un qualsiasi numero)
  281.  
  282. Infatti -5 in formato word si scrive proprio $FFFB.
  283.  
  284. In pratica la EXT prende il bit 7 di un registro (il bit che indica il segno)
  285. e lo copia nei bit da 8 a 15.
  286. Anche se non e` usata in questo esempio sappiate che per trasformare una word
  287. in una long-word si usa sempre l'istruzione EXT, solo in formato .L:
  288.  
  289.     EXT.L   d0    ; trasforma una word in long-word
  290.  
  291. La trasformazione avviene nella stessa maniera.
  292.  
  293. Per quanto riguarda le posizioni verticali il discorso e` lo stesso, e
  294. infatti la rouine e` identica.
  295.  
  296. Per posizionare lo sprite sullo schermo usiamo di nuovo la routine universale,
  297. che abbiamo gia` bella pronta. Vi renderete conto che anche le routine che
  298. gestiscono la letture del mouse e del joystick si possono usare in ogni
  299. programma che sia gestito il joystick e il mouse. Infatti i programmatori di
  300. giochi e demo riutilizzano gran parte delle routines.
  301.  
  302.