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

  1.  
  2. ; Listing7r2.s    EIN MIT DER MAUS BEWEGTER SPRITE, DER BIS ZUM RECHTEN RAND
  3. ;        KOMMT
  4.  
  5.     SECTION CipundCop,CODE
  6.  
  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    #$ff,$dff006    ; Zeile $ff?
  40.     bne.s    mouse
  41.  
  42.     bsr.s    LiesMouse    ; Da wird die Maus ausgelesen
  43.     move.w    sprite_y(pc),d0 ; bereite die Parameter für die
  44.     move.w    sprite_x(pc),d1 ; Universalroutine vor
  45.     lea    MEINSPRITE,a1    ; Spriteadresse
  46.     moveq    #13,d2        ; Höhe des Sprite
  47.     bsr.w    UniMoveSprite    ; Aufruf der Universalroutine
  48.  
  49. Warte:
  50.     cmpi.b    #$ff,$dff006    ; Zeile $ff?
  51.     beq.s    Warte
  52.  
  53.     btst    #6,$bfe001    ; Mouse gedrückt?
  54.     bne.s    mouse
  55.  
  56.  
  57.     move.l    OldCop(PC),$dff080    ; Pointen auf die SystemCOP
  58.     move.w    d0,$dff088        ; Starten die alte SystemCOP
  59.  
  60.     move.l    4.w,a6
  61.     jsr    -$7e(a6)    ; Enable
  62.     move.l    gfxbase(PC),a1
  63.     jsr    -$19e(a6)    ; Closelibrary
  64.     rts
  65.  
  66. ;    Daten
  67. GfxName:
  68.     dc.b    "graphics.library",0,0
  69.  
  70. GfxBase:
  71.     dc.l    0
  72.  
  73. OldCop:
  74.     dc.l    0
  75.  
  76. ; Diese Routine liset die Maus aus und erneuert die Werte in den
  77. ; Variabeln Sprite_x und Sprite_y
  78.  
  79. LiesMouse:
  80.     move.b    $dff00a,d1    ; JOY0DAT Vertikale Position der Maus
  81.     move.b    d1,d0        ; kopiert in d0
  82.     sub.b    mouse_y(PC),d0    ; zähle alte Mausposition weg
  83.     beq.s    no_vert        ; wenn die Differenz = 0 ist, dann wurde
  84.                 ; die Maus nicht bewegt
  85.     ext.w    d0        ; verwandle das Byte in Word
  86.                 ; (siehe Ende des Listings)
  87.     add.w    d0,sprite_y    ; modifizieren Spriteposition
  88. no_vert:
  89.     move.b    d1,mouse_y    ; speichere Mausposition für´s nächste Mal
  90.  
  91.     move.b    $dff00b,d1    ; horizontale Mausposition
  92.     move.b    d1,d0        ; kopiert in d0
  93.     sub.b    mouse_x(PC),d0    ; zähle alte Mausposition weg
  94.     beq.s    no_oriz        ; wenn die Differenz = 0 ist, dann wurde
  95.                 ; die Maus nicht bewegt
  96.     ext.w    d0        ; verwandle das Byte in Word
  97.                 ; (siehe Ende des Listings)
  98.     add.w    d0,sprite_x    ; modifiziere Spriteposition
  99. no_oriz
  100.     move.b    d1,mouse_x    ; speichere Mausposition für´s nächste Mal
  101.     RTS
  102.  
  103. SPRITE_Y:    dc.w    0 ; hier wird die Y - Position des Sprite gespeichert
  104. SPRITE_X:    dc.w    0 ; hier wird die X - Position des Sprite gespeichert
  105. MOUSE_Y:    dc.b    0 ; hier wird die Y - Position der Maus gesperichert
  106. MOUSE_X:    dc.b    0 ; hier wird die X - Position der Maus gespeiuchert
  107.  
  108.  
  109. ; Universelle Routine zum Positionieren der Sprites
  110.  
  111. ;    Eingangsparameter von UniMoveSprite:
  112. ;
  113. ;    a1 = Adresse des Sprite
  114. ;    d0 = Vertikale Position des Sprite auf dem Screen (0-255)
  115. ;    d1 = Horizontale Position des Sprite auf dem Screen (0-320)
  116. ;    d2 = Höhe des Sprite
  117. ;
  118. UniMoveSprite:
  119. ; Vertikale Positionierung
  120.  
  121.     ADD.W    #$2c,d0        ; zähle den Offset vom Anfang des Screens dazu
  122.  
  123. ; a1 enthält die Adresse des Sprite
  124.  
  125.     MOVE.b    d0,(a1)        ; kopiert das Byte in VSTART
  126.     btst.l    #8,d0
  127.     beq.s    NichtVSTARTSET
  128.     bset.b    #2,3(a1)    ; Setzt das Bit 8 von VSTART (Zahl > $FF)
  129.     bra.s    ToVSTOP
  130. NichtVSTARTSET:
  131.     bclr.b    #2,3(a1)    ; Löscht das Bit 8 von VSTART (Zahl < $FF)
  132. ToVSTOP:
  133.     ADD.w    D2,D0        ; Zähle die Höhe des Sprite dazu, um
  134.                 ; die Endposition zu errechnen (VSTOP)
  135.     move.b    d0,2(a1)    ; Setze den richtigen Wert in VSTOP
  136.     btst.l    #8,d0
  137.     beq.s    NichtVSTOPSET
  138.     bset.b    #1,3(a1)    ; Setzt Bit 8 von VSTOP (Zahl > $FF)
  139.     bra.w    VVSTOPENDE
  140. NichtVSTOPSET:
  141.     bclr.b    #1,3(a1)    ; Löscht Bit 8 von VSTOP (Zahl < $FF)
  142. VVSTOPENDE:
  143.  
  144. ; horizontale Positionierung
  145.  
  146.     add.w    #128,D1        ; 128 - um den Sprite zu zentrieren
  147.     btst    #0,D1        ; niederwert. Bit der X-Koordinate auf 0?
  148.     beq.s    NiederBitNull
  149.     bset    #0,3(a1)    ; Setzen das niederw. Bit von HSTART
  150.     bra.s    PlaceCoords
  151.  
  152. NiederBitNull:
  153.     bclr    #0,3(a1)    ; Löschen das niederw. Bit von HSTART
  154. PlaceCoords:
  155.     lsr.w    #1,D1        ; SHIFTEN, verschieben den Wert von HSTART um
  156.                 ; 1 Bit nach Rechts, um es in den Wert zu
  157.                 ; "verwandeln", der dann in HSTART kommt, also
  158.                 ; ohne dem niederwertigen Bit.
  159.     move.b    D1,1(a1)    ; geben den Wert XX ins Byte HSTART
  160.     rts
  161.  
  162.  
  163.     SECTION GRAPHIC,DATA_C
  164.  
  165. COPPERLIST:
  166. SpritePointers:
  167.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  168.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  169.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  170.     dc.w    $13e,0
  171.  
  172.     dc.w    $8E,$2c81    ; DiwStrt
  173.     dc.w    $90,$2cc1    ; DiwStop
  174.     dc.w    $92,$38        ; DdfStart
  175.     dc.w    $94,$d0        ; DdfStop
  176.     dc.w    $102,0        ; BplCon1
  177.     dc.w    $104,0        ; BplCon2
  178.     dc.w    $108,0        ; Bpl1Mod
  179.     dc.w    $10a,0        ; Bpl2Mod
  180.  
  181.             ; 5432109876543210
  182.     dc.w    $100,%0001001000000000    ; Bit 12 an!! 1 Bitplane Lowres
  183.  
  184. BPLPOINTERS:
  185.     dc.w $e0,0,$e2,0    ;erstes    Bitplane
  186.  
  187.     dc.w    $180,$000    ; Color0    ; Hintergrund Schwarz
  188.     dc.w    $182,$123    ; Color1    ; Farbe 1 des Bitplane, die
  189.                         ; in diesem Fall leer ist,
  190.                         ; und deswegen nicht erscheint
  191.  
  192.     dc.w    $1A2,$F00    ; Color17, oder COLOR1 des Sprite0 - ROT
  193.     dc.w    $1A4,$0F0    ; Color18, oder COLOR2 des Sprite0 - GRÜN
  194.     dc.w    $1A6,$FF0    ; Color19, oder COLOR3 des Sprite0 - GELB
  195.  
  196.     dc.w    $FFFF,$FFFE    ; Ende der Copperlist
  197.  
  198.  
  199. ; ************ Hier ist der Sprite: NATÜRLICH muß er in CHIP RAM sein! ********
  200.  
  201. MEINSPRITE:      ; Länge 13 Zeilen
  202. VSTART:
  203.     dc.b $50  ; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
  204. HSTART:
  205.     dc.b $90  ; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
  206. VSTOP:
  207.     dc.b $5d  ; $50+13=$5d    ; Vertikale Endposition des Sprite
  208. VHBITS:
  209.     dc.b $00
  210.  dc.w    %0000000000000000,%0000110000110000 ; Binäres Format für ev. Änderungen
  211.  dc.w    %0000000000000000,%0000011001100000
  212.  dc.w    %0000000000000000,%0000001001000000
  213.  dc.w    %0000000110000000,%0011000110001100 ;BINÄR 00=COLOR 0 (DURCHSICHTIG)
  214.  dc.w    %0000011111100000,%0110011111100110 ;BINÄR 10=COLOR 1 (ROT)
  215.  dc.w    %0000011111100000,%1100100110010011 ;BINÄR 01=COLOR 2 (GRÜN)
  216.  dc.w    %0000110110110000,%1111100110011111 ;BINÄR 11=COLOR 3 (GELB)
  217.  dc.w    %0000011111100000,%0000011111100000
  218.  dc.w    %0000011111100000,%0001111001111000
  219.  dc.w    %0000001111000000,%0011101111011100
  220.  dc.w    %0000000110000000,%0011000110001100
  221.  dc.w    %0000000000000000,%1111000000001111
  222.  dc.w    %0000000000000000,%1111000000001111
  223.  dc.w    0,0    ; 2 word auf NULL definieren das Ende des Sprite.
  224.  
  225.  
  226.     SECTION LEERESPLANE,BSS_C ; Ein auf 0 gesetztes Bitplane, wir
  227.                   ; müssen es verwenden, denn ohne Bitplane
  228.                   ; ist es nicht möglich, die Sprites
  229.                   ; zu aktivieren
  230. BITPLANE:
  231.     ds.b    40*256        ; Bitplane auf 0 Lowres
  232.  
  233.     end
  234.  
  235. In  diesem  Beispiel bewegen wir einen Sprite mit der Maus so, daß wir den
  236. rechten  Rand  erreichen.  Es  gibt  auch  keine  weiteren  Probleme  mit
  237. vertikalem Overscan.
  238.  
  239. Wenn wir den rechten Rand erreichen  wollen,  dann  müssen  wir  ein  Word
  240. verwenden,  um  die horizontale Position des Sprites festhalten zu können.
  241. Die Maus gibt uns aber Koordinaten  im  Byte-Format.  Wir  verwenden  also
  242. folgende  Methode:  Wir  speichern die Koordinaten, die der Sprite hat und
  243. die, die uns die Maus liefert, separat ab. Jedesmal,  wenn  wir  LiesMouse
  244. ausführen,  lesen  wir  die  neuen Koordinaten und vergleichen sie mit den
  245. alten.  Wir  berechnen  die  Differenz  aus  den  alten  und  den  neuen
  246. Mauskoordinaten  und  zählen  sie  zur  Spriteposition dazu. Damit gibt es
  247. keine Probleme, wenn die Mausposition 255 überschreitet und  somit  auf  0
  248. zurückkommt,  denn  das,  was  zählt,  ist  immer  nur  die Differenz. Ich
  249. erinnere euch auch daran, daß wenn ein Byte einen Wert  zwischen  128  und
  250. 255 einnimmt, und es als Addition oder Subtraktion verwendet wird, wird es
  251. als negative Zahl  im  Zweierkomplement  angesehen.  Wenn  also  die  alte
  252. Position 255 war (=$ff), dann wird das als -1 angesehen. Also 1-(-1)=2
  253. Diese Zahl 2 wird zur X-Koordinate  des  Sprite  dazugezählt,  und  da  es
  254. positiv  ist,  wird  es  immer eine Bewegung nach rechts ergeben. Wenn die
  255. Differenz hingegen negativ gewesen wäre, dann würde das dazuzählen  dieser
  256. eine Bewegung nach Links nach sich ziehen.
  257. Es gibt aber eine Kleinigkeit, auf die Acht gegeben werden muß.  Wenn  wir
  258. die  Differenz  zwischen  den Mauskoordinaten machen, dann rechnen wir mit
  259. Bytes. Die Differenz wird also immer ein Byte sein. Dieses Byte  summieren
  260. wir  aber  zur  Koordinate  des  Sprite,  und  das  ist ein Word. Das gibt
  261. Probleme.  Bevor  wir  die  Summe  machen,  müssen  wir  es  in  ein  Word
  262. verwandeln.  Diese Aufgabe übernimmt die Anweisung EXT, sie verwandelt ein
  263. Byte, das in einem Register steht, in ein Word. Es gibt  nun  zwei  Fälle:
  264. Das Byte enthält eine positive Zahl, z.B. 5. EXT wird nun so vorgehen:
  265.  
  266. Inhalt vor dem EXT          Inhalt nach dem EXT
  267.     $XX05                       $0005
  268. (XX deutet auf irgend eine Zahl hin)
  269.  
  270.  
  271. 5 schribt man im Word-Format genau $0005.
  272.  
  273. Anderer Fall: der Inhalt war -5. Nun wird EXT so arbeiten:
  274. Ich erinnere daran, daß -5 in Hexadezimal $FB ist.
  275.  
  276. Inhalt vor dem EXT          Inhalt nach dem EXT
  277.     $XXFB                       $FFFB
  278. (XX deutet auf irgend eine Zahl hin)
  279.  
  280. -5 wird in der Tat im Wordformat als $FFFB geschrieben.
  281.  
  282. Praktisch gesehen nimmt das EXT das Bit 7 des Registers (das Bit, das  das
  283. Vorzeichen  angibt), und kopiert es in die Bit 8 bis 15. Auch wenn es hier
  284. nicht verwendet wird, solltet ihr wissen, daß um ein Word in ein  Longword
  285. zu verwandeln, immer ein EXT verwendet wird, nur im .L-Format:
  286.  
  287.     EXT.L   d0      ;verwandelt ein Word in ein Longword
  288.  
  289. Die Umwandlung erfolgt genau gleich wie oben.
  290.  
  291. Was die vertikalen Positionen angeht, so  ist  es  nur  das  Gleiche.  Die
  292. Routine ist auch die Selbe.
  293.  
  294. Um den Sprite zu bewegen, verwenden wir wie immer unsere Universalroutine.
  295. Ihr werdet bemerken, daß die Routinen, die  die  Maus  oder  den  Joystick
  296. verwalten,  in  jedem  eurer  Programme  verwendet werden können, die eine
  297. solche Verwaltung  brauchen.  Die  Programmierer  von  Spielen  und  Demos
  298. verwenden die meisten Routinen immer wieder.
  299.  
  300.