home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / assembler-kurs / listings3 / listing7n.s < prev    next >
Text File  |  1977-12-31  |  8KB  |  275 lines

  1.  
  2. ; Listing7n.s - Beispiel der Applikation der Universalroutine:
  3. ;        ein Sprite, der abprallt
  4.  
  5.  
  6.      SECTION CipundCop,CODE
  7.  
  8. Anfang:
  9.     move.l    4.w,a6        ; Execbase
  10.     jsr    -$78(a6)    ; Disable
  11.     lea    GfxName(PC),a1    ; Libname
  12.     jsr    -$198(a6)    ; OpenLibrary
  13.     move.l    d0,GfxBase
  14.     move.l    d0,a6
  15.     move.l    $26(a6),OldCop    ; speichern die alte COP
  16.  
  17. ;    Pointen auf das "leere" PIC
  18.  
  19.     MOVE.L    #BITPLANE,d0    ; wohin pointen
  20.     LEA    BPLPOINTERS,A1    ; COP-Pointer
  21.     move.w    d0,6(a1)
  22.     swap    d0
  23.     move.w    d0,2(a1)
  24.  
  25. ;    Pointen auf den Sprite
  26.  
  27.     MOVE.L    #MEINSPRITE,d0        ; Adresse des Sprite in d0
  28.     LEA    SpritePointers,a1    ; Pointer in der Copperlist
  29.     move.w    d0,6(a1)
  30.     swap    d0
  31.     move.w    d0,2(a1)
  32.  
  33.     move.l    #COPPERLIST,$dff080    ; unsere COP
  34.     move.w    d0,$dff088        ; START COP
  35.     move.w    #0,$dff1fc        ; NO AGA!
  36.     move.w    #$c00,$dff106
  37.  
  38. mouse:
  39.     cmpi.b    #$aa,$dff006    ; Zeile $aa?
  40.     bne.s    mouse
  41.  
  42.  
  43.     btst    #2,$dff016
  44.     beq.s    Warte
  45.     bsr.w    BewegeSprite    ; Bewege Sprite
  46.  
  47. Warte:
  48.     cmpi.b    #$aa,$dff006    ; Zeile $aa?
  49.     beq.s    Warte
  50.  
  51.     btst    #6,$bfe001    ; Mouse gedrückt?
  52.     bne.s    mouse
  53.  
  54.  
  55.     move.l    OldCop(PC),$dff080    ; Pointen auf die SystemCOP
  56.     move.w    d0,$dff088        ; Starten die alte SystemCOP
  57.  
  58.     move.l    4.w,a6
  59.     jsr    -$7e(a6)    ; Enable
  60.     move.l    gfxbase(PC),a1
  61.     jsr    -$19e(a6)    ; Closelibrary
  62.     rts
  63.  
  64. ;    Daten
  65.  
  66. GfxName:
  67.     dc.b    "graphics.library",0,0
  68.  
  69. GfxBase:
  70.     dc.l    0
  71.  
  72. OldCop:
  73.     dc.l    0
  74.  
  75. ; Diese Routine ändert die Koordinaten des Sprite, indem sie eine kostante
  76. ; Geschwindigkeit sowohl vertikal als auch horizontal dazuzählt. Weiters,
  77. ; wenn der Sprite einen Rand berührt, wird die Richtung invertiert.
  78. ; Um diese Routine zu verstehen muß man die Anweisung "NEG" kennen:
  79. ; Sie verwandelt eine positive Zahl in eine negative und umgekehrt.
  80.  
  81. BewegeSprite:
  82.     move.w    sprite_y(PC),d0    ; lies die alte Position
  83.     add.w    speed_y(PC),d0    ; zähle Geschwindigkeit dazu
  84.     btst    #15,d0        ; Wenn Bit 15 gesetzt ist, dann ist die
  85.                 ; Zahl negativ. Ist sie das geworden?
  86.     beq.s    Nicht_angehen_oben ; wenn >0, dann ist alles gut
  87.     neg.w    speed_y        ; wenn <0, dann haben wir den oberen Rand
  88.                 ;  berührt also invertiere die Richtung
  89.     bra.s    BewegeSprite    ; errechne die neue Position
  90.  
  91. Nicht_angehen_oben:
  92.     cmp.w    #243,d0        ; wenn die Position 256-13=243 ist, dann
  93.                 ; berührt der Sprite den unteren Rand
  94.     blo.s    Nicht_angehen_unten
  95.     neg.w    speed_y        ; wenn der Sprite den unteren RAnd berührt,
  96.                 ; invertiere die Geschwindigkeit
  97.     bra.s    BewegeSprite    ; errechne die neue Position
  98.  
  99. Nicht_angehen_unten:
  100.     move    d0,sprite_y    ; erneuere die Position
  101. Pos_x:
  102.     move.w    sprite_x(PC),d1    ; lies die alte Position
  103.     add.w    speed_x(PC),d1    ; zähle Geschwindigkeit dazu
  104.     btst    #15,d0        ; Wenn das Bit 15 gesetzt ist, dann ist die
  105.                 ;  Zahl negativ. Ist sie das geworden?
  106.     beq.s    Nicht_angehen_links
  107.     neg.w    speed_x        ; wenn <0 dann berührt er den linken Rand:
  108.                 ; invertiere die Richtung
  109.     bra.s    Pos_x        ; errechne die neue hor. Position
  110.  
  111. Nicht_angehen_links:
  112.     cmp.w    #304,d1        ; wenn die Position 320-16=304 ist, dann
  113.                 ; berührt der Sprite den rechten Rand
  114.     blo.s    Nicht_angehen_rechts
  115.     neg.w    speed_x        ; wenn er rechts anstoßt, invert die Richtung
  116.     bra.s    Pos_x        ; errechne die neue hor. Position
  117.  
  118. Nicht_angehen_rechts:
  119.     move.w    d1,sprite_x    ; erneuere die Position
  120.  
  121.     lea    MEINSPRITE,a1    ; Adresse Sprite
  122.     moveq    #13,d2        ; Höhe Sprite
  123.     bsr.s    UniMoveSprite    ; Führt die UniversalRoutine aus, die
  124.                 ; den Sprite positioniert
  125.     rts
  126.  
  127. SPRITE_Y:
  128.         DC.W    10    ; Position Sprite
  129. SPRITE_X:
  130.         DC.W    0
  131. SPEED_Y:
  132.         dc.w    -4    ; Geschwindigkeit Sprite
  133. SPEED_X:
  134.         dc.w    3
  135.  
  136. ; Universelle Routine zum Positionieren der Sprites
  137.  
  138. ;    Eingangsparameter von UniMoveSprite:
  139. ;
  140. ;    a1 = Adresse des Sprite
  141. ;    d0 = Vertikale Position des Sprite auf dem Screen (0-255)
  142. ;    d1 = Horizontale Position des Sprite auf dem Screen (0-320)
  143. ;    d2 = Höhe des Sprite
  144. ;
  145. UniMoveSprite:
  146. ; Vertikale Positionierung
  147.  
  148.     ADD.W    #$2c,d0     ; zähle den Offset vom Anfang des Screens dazu
  149.  
  150. ; a1 enthält die Adresse des Sprite
  151.  
  152.     MOVE.b    d0,(a1)        ; kopiert das Byte in VSTART
  153.     btst.l    #8,d0
  154.     beq.s    NichtVSTARTSET
  155.     bset.b    #2,3(a1)    ; Setzt das Bit 8 von VSTART (Zahl > $FF)
  156.     bra.s    ToVSTOP
  157. NichtVSTARTSET:
  158.     bclr.b    #2,3(a1)    ; Löscht das Bit 8 von VSTART (Zahl < $FF)
  159. ToVSTOP:
  160.     ADD.w    D2,D0        ; Zähle die Höhe des Sprite dazu, um
  161.                 ; die Endposition zu errechnen (VSTOP)
  162.     move.b    d0,2(a1)    ; Setze den richtigen Wert in VSTOP
  163.     btst.l    #8,d0
  164.     beq.s    NichtVSTOPSET
  165.     bset.b    #1,3(a1)    ; Setzt Bit 8 von VSTOP (Zahl > $FF)
  166.     bra.w    VVSTOPENDE
  167. NichtVSTOPSET:
  168.     bclr.b    #1,3(a1)    ; Löscht Bit 8 von VSTOP (Zahl < $FF)
  169. VVSTOPENDE:
  170.  
  171. ; horizontale Positionierung
  172.  
  173.     add.w    #128,D1        ; 128 - um den Sprite zu zentrieren
  174.     btst    #0,D1        ; niederwert. Bit der X-Koordinate auf 0?
  175.     beq.s    NiederBitNull
  176.     bset    #0,3(a1)    ; Setzen das niederw. Bit von HSTART
  177.     bra.s    PlaceCoords
  178.  
  179. NiederBitNull:
  180.     bclr    #0,3(a1)    ; Löschen das niederw. Bit von HSTART
  181. PlaceCoords:
  182.     lsr.w    #1,D1        ; SHIFTEN, verschieben den Wert von HSTART um
  183.                 ; 1 Bit nach Rechts, um es in den Wert zu
  184.                 ; "verwandeln", der dann in HSTART kommt, also
  185.                 ; ohne dem niederwertigen Bit.
  186.     move.b    D1,1(a1)    ; geben den Wert XX ins Byte HSTART
  187.     rts
  188.  
  189.  
  190.  
  191.     SECTION GRAPHIC,DATA_C
  192.  
  193. COPPERLIST:
  194. SpritePointers:
  195.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  196.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  197.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  198.     dc.w    $13e,0
  199.  
  200.     dc.w    $8E,$2c81    ; DiwStrt
  201.     dc.w    $90,$2cc1    ; DiwStop
  202.     dc.w    $92,$38        ; DdfStart
  203.     dc.w    $94,$d0        ; DdfStop
  204.     dc.w    $102,0        ; BplCon1
  205.     dc.w    $104,0        ; BplCon2
  206.     dc.w    $108,0        ; Bpl1Mod
  207.     dc.w    $10a,0        ; Bpl2Mod
  208.  
  209.             ; 5432109876543210
  210.     dc.w    $100,%0001001000000000    ; Bit 12 an!! 1 Bitplane Lowres
  211.  
  212. BPLPOINTERS:
  213.     dc.w $e0,0,$e2,0    ;erstes    Bitplane
  214.  
  215.     dc.w    $180,$000    ; Color0    ; Hintergrund Schwarz
  216.     dc.w    $182,$123    ; Color1    ; Farbe 1 des Bitplane, die
  217.                         ; in diesem Fall leer ist,
  218.                         ; und deswegen nicht erscheint
  219.  
  220.     dc.w    $1A2,$F00    ; Color17, oder COLOR1 des Sprite0 - ROT
  221.     dc.w    $1A4,$0F0    ; Color18, oder COLOR2 des Sprite0 - GRÜN
  222.     dc.w    $1A6,$FF0    ; Color19, oder COLOR3 des Sprite0 - GELB
  223.  
  224.     dc.w    $FFFF,$FFFE    ; Ende der Copperlist
  225.  
  226.  
  227. ; ************ Hier ist der Sprite: NATÜRLICH muß er in CHIP RAM sein! ********
  228.  
  229. MEINSPRITE:      ; Länge 13 Zeilen
  230.     dc.b $50  ; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
  231.     dc.b $90  ; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
  232.     dc.b $5d  ; $50+13=$5d    ; Vertikale Endposition des Sprite
  233.     dc.b $00
  234.  dc.w    %0000000000000000,%0000110000110000 ; Binäres Format für ev. Änderungen
  235.  dc.w    %0000000000000000,%0000011001100000
  236.  dc.w    %0000000000000000,%0000001001000000
  237.  dc.w    %0000000110000000,%0011000110001100 ;BINÄR 00=COLOR 0 (DURCHSICHTIG)
  238.  dc.w    %0000011111100000,%0110011111100110 ;BINÄR 10=COLOR 1 (ROT)
  239.  dc.w    %0000011111100000,%1100100110010011 ;BINÄR 01=COLOR 2 (GRÜN)
  240.  dc.w    %0000110110110000,%1111100110011111 ;BINÄR 11=COLOR 3 (GELB)
  241.  dc.w    %0000011111100000,%0000011111100000
  242.  dc.w    %0000011111100000,%0001111001111000
  243.  dc.w    %0000001111000000,%0011101111011100
  244.  dc.w    %0000000110000000,%0011000110001100
  245.  dc.w    %0000000000000000,%1111000000001111
  246.  dc.w    %0000000000000000,%1111000000001111
  247.  dc.w    0,0    ; 2 word auf NULL definieren das Ende des Sprite.
  248.  
  249.  
  250.     SECTION LEERESPLANE,BSS_C ; Ein auf 0 gesetztes Bitplane, wir
  251.                   ; müssen es verwenden, denn ohne Bitplane
  252.                   ; ist es nicht möglich, die Sprites
  253.                   ; zu aktivieren
  254. BITPLANE:
  255.     ds.b    40*256        ; Bitplane auf 0 Lowres
  256.  
  257.     end
  258.  
  259. In diesem Beispiel zeigen wir eine  andere  Methode,  um  die  Sprites  zu
  260. bewegen,  ohne  Tabellen.  In  diesem  Listing  bewegt  sich  ein  Sprite
  261. geradlinig mit konstanter Geschwindigkeit, sowohl in vertikaler  als  auch
  262. in  horizontaler Richtung. Die Geschwindigkeit ist nichts anderes als eine
  263. Zahl, die sich in einer Speicherzelle befindet, die jedesmal zur  Position
  264. dazugezählt  wird,  die der Sprite vorher hatte, und errechnet so die neue
  265. Position. Wenn die Geschwindigkeit eine positive Zahl war, dann  wird  die
  266. Position  des  Sprites  jedesmal  erhöht, und somit nach rechts verschoben
  267. (oder nach Unten, im Falle der Y-Achse).
  268. Wenn der Sprite einen Rand berührt, ist es notwendig,  seine  Richtung  zu
  269. ändern. Um das zu tun reicht es aus, das Vorzeichen der Geschwindigkeit zu
  270. invertieren,  und  sie  so  von  Positiv  in  Negativ  umzuschalten  oder
  271. umgekehrt.  Darum  kümmert  sich  der  Befehl "NEG", der genau das tut: er
  272. ändert das Vorzeichen einer Zahl, die sich in einem  Register  oder  einer
  273. Speicherzelle befindet.
  274.  
  275.