64'er, Ausgabe 9/September 1989
Sprites sind die wichtigsten Elemente eines Spiels. Ohne sie wäre der Bildschirm »leblos«. Lernen Sie, mit Sprites Bewegung ins Computerbild zu bringen.
Wer schon mit Sprites gearbeitet hat, denkt vielleicht, die Programmierung sei ganz einfach, weil der VIC alle Funktionen zur Verfügung stellt. Dem ist nicht ganz so, denn es wird reger Gebrauch von Rasterzeilen-IRQs gemacht. Wer Teil 2 und 3 dieses Kurses studiert hat, kann hier sein Wissen voll anwenden. Grundlegende Kenntnisse der Spriteprogrammierung werden vorausgesetzt. Sie sollen also zumindest in Basic einmal ausprobiert haben, Sprites zu definieren und auf dem Bildschirm darzustellen. Verfügen Sie nicht über diese Kenntnisse, empfiehlt sich das 64'er-Sonderheft Nr. 20. Dort wird genau auf die Programmierung von Sprites eingegangen.
Sehen wir uns zunächst die einfache Bewegung eines Sprites näher an. Sie ist die Grundlage jedes Spiels und zum Beispiel dafür verantwortlich, daß ein Raumschiff über den Bildschirm gleitet. Sprites bewegt man, indem man die Register der X-/Y-Koordinate (Gültigkeitsbereiche siehe Bild 1) kontinuierlich hoch- oder herunterzählt. (inkrementiert bzw. dekrementiert). Es stellt sich allerdings ein Problem: Bewegt man Sprites in Maschinensprache vom Hauptprogramm aus, so sind unbedingt Warteschleifen erforderlich. Der Computer wäre dann aber vorwiegend damit beschäftigt, nichts zu tun, und für das Spiel hätte er keine Zeit mehr. Aus diesem Grunde programmiert man Spritebewegungen im IRQ. Probieren wir es zunächst im System-IRQ aus. Tippen Sie hierfür Listing 1 ein und starten Sie es mit SYS 49152.
Es bewegt sich nun ein Sprite von links nach rechts, dessen Geschwindigkeit Sie durch POKE 56325,Wert beeinflussen können. Sie verändern mit diesem POKE-Befehl die Häufigkeit der IRQs, die durch den CIA 1 ausgelöst werden.
Das Programm selber ist ohne weitere Erklärungen verständlich, da alle Befehle in diesem Kursteil bzw. in Teil 2 behandelt wurden.
Wie Sie sehen, erzielt man mit dieser Methode keine besonders guten Ergebnisse. Zum einen ist die Bewegung nicht fließend, zum anderen wird das Sprite »zerrissen«, wenn Sie den IRQ schnell einstellen (kleine Wert in die Speicherzelle 56325 schreiben).
Dies kommt durch das schlechte Timing zustande. Es kann passieren, daß der Rasterstrahl zweimal über das Sprite läuft, obwohl nur einmal die Position geändert wurde. Es kann aber auch geschehen, daß der Rasterstrahl nur einmal über das Sprite läuft, obwohl schon mehrmals die Position geändert wurde. Dadurch kommt die unruhige Bewegung zustande. Ferner ist es möglich, daß die Koordinaten gerade in dem Moment verändert werden, wenn der Rasterstrahl dabei ist, das Sprite darzustellen. Die erste Hälfte wird mit der alten, die zweite mit der neuen Position dargestellt. Man erhält den Eindruck eines »zerrissenen« Sprites (Bild 2).
Bild 2. Ein Sprite wird bewegt, während der Rasterstrahl es darstellt. Es wird dadurch scheinbar »zerrissen«. |
Rasterstrahlen-IRQs lösen dieses Problem.
Löst man immer bei Rasterzeile 0 einen IRQ aus, in dessen IRQ-Routine die Sprite-Koordinaten verändert werden, ist zum einen sichergestellt, daß pro Bildschirmaufbau genau einmal die Position verändert wird, und zum anderen, daß das Sprite erst nach der erneuten Positionierung vom Rasterstrahl dargestellt wird. Natürlich muß der System-IRQ inaktiviert und vom Raster-IRQ abgewickelt werden (vlg. Teil 2).
In Listing 2 wird von der hier beschriebenen Methode Gebrauch gemacht. Wie Sie sehen, ist die Bewegung nun fließend und flimmerfrei.
Man ist jetzt auch in der Lage, mehrere Sprites gleichzeitig zu bewegen, was in Basic aufgrund der geringen Laufgeschwindigkeit nicht möglich ist.
Auch kann man durch Überlagern von mehreren Single-Color-Sprites ein Multicolor-Sprite mit hoher Auflösung simulieren und dieses dann bewegen. Positioniert man mehrere Sprites nebeneinander, erhält man ein »Compound-Sprite« (ein aus mehreren Sprites zusammengesetzes Objekt).
Schießlich ist es nun auch möglich, ein oder mehrere Sprites mit dem Joystick zu »koppeln«. Man liest in der IRQ-Routine das Joystickregister aus und legt dann die Richtung fest, in die sich das Sprite bewegen soll. Dies wurde im Programm »SPRITE-CONNECT« (Listing 3) getan. Tippen Sie es mit dem MSE ein. Starten Sie es mit SYS 49152, so wird Sprite 0, das vorher bereits aktiviert sein muß, mit dem Joystick in Port 2 »verbunden«. Durch eingebaute Legalitätskontrollen wird sichergestellt, daß das Sprite nicht über die Grenzen des darstellbaren Bildschirmes hinausläuft. Durch POKE 49393,Wert können Sie die Geschwindigkeit variieren, genauer gesagt, die Schrittweite, mit der sich das Sprite über den Bildschirm bewegt.
WICHTIG: Sie können das Programm auch downloaden |
Eine Animation entspricht von der Programmstruktur her einer Spritebewegung. Nur wird hier nicht die Position des Sprites, sondern der Wert des Spritepointers, also sein Inhalt, verändert. Hierdurch bekommt das Sprite ständig ein anderes Aussehen. Stehen zum Beispiel im Block 128 bis 130 die Spritedaten einer Animationssequenz und zählt man den Spritepointer ständig zwischen den Werten 128 und 130 herauf und herunter, so entsteht der Eindruck einer fließenden Formveränderung. Auch hier erhält man eine fließende und flimmerfreie Bewegung nur dann, wenn die IRQ-Routine vom Rasterzeilen-IRQ gesteuert wird.
Tippen Sie Listing 4 ein und starten es mit SYS 49152. Das Programm belegt acht Spriteblocks mit Bitmustern. Anschließend wird regelmäßig zwischen diesen Spriteblocks umgeschaltet.
Wie Sie sehen, hat sich Listing 4 gegenüber Listing 2 nicht wesentlich verändert. Lediglich die Routine, die die Spritedaten generiert, wurde modifiziert. Ferner wird anstelle der Spriteposition der Spritepointer inkrementiert bzw. dekrementiert. Verändern Sie den Wert in Zeile 790, so läßt sich die Animationsgeschwindigkeit variieren. Setzen Sie zum Beispiel eine 2 ein, so wird nur bei jedem zweiten IRQ der Spritepointer verändert.
Mit den Kenntnissen über Spritebewegung und -animation sollte es Ihnen nun möglich sein, Ihre ersten Spieleversionen in Basic von Maschinensprache aus zu unterstützen. Selbstverständlich lassen sich Animation und Bewegung auch gleichzeitig abwickeln. Versuchen Sie doch einmal durch Ergänzung des Listings 4 mit der IRQ-Routine aus Listing 2 ein animiertes und bewegtes Sprite zu zaubern.
Der VIC bietet die Möglichkeit, bei Kollisionen zwischen zwei Sprites oder zwischen Sprite und Hintergrund einen IRQ auszulösen. Sehen Sie sich Listing 5 an. Dieses Programm gibt einen VIC-IRQ für Sprite/Hintergrund-Kollisionen frei. Starten Sie das Programm mit SYS 49152, erscheint ein Sprite in der Mitte des Bildschirms. Schreiben Sie nun per Tastatur ein Zeichen unter das Sprite, so verändert sich das linke obere Zeichen des Bildschirms so lange, bis das Zeichen wieder gelöscht wurde. Zu beachten ist hierbei, daß nicht nur das IRQ-Requestregister (sowohl bei der Initialisierung als auch in der IRQ-Routine) durch Auslesen und Rückschreiben gelöscht werden muß, sodern auch das Sprite-Hintergrund-Kollisionsregister VIC+31. Dies geschieht durch einfaches Auslesen. Eine Programmierung von Sprite-Sprite-Kollisionen erfolgt analog, mit der einzigen Ausnahme, daß Sie in das IRQ-Maskenregister den Wert 132 (128+4) schreiben und statt der Sprite-Hintergrund-Kollisionsregister das Sprite-Sprite-Kollisionsregister VIC+30 auslesen müssen.
Leider läßt sich diese Kollisionserkennung nicht für anspruchsvolle Spiele nutzen, aus folgendem Grund:
Wie Sie sehen, wird so lange ein IRQ ausgelöst, bis die Kollision aufgehoben wurde, entweder duch Abschalten des Sprites oder durch Löschen des beziehungsweise der Zeichen, mit denen das Sprite kollidiert. Das ist in den meisten Spielen unerwünscht, da nur einmal pro Kollision eine Reaktion ausgelöst werden soll. Eine naheliegende Lösung wäre:
Man speichert immer den alten Wert des Kolllisionsregisters zwischen, und wenn ein Kollisions-IRQ auftritt, wird der aktuelle Wert des Kollisionsregister mit dem zwischengespeicherten Wert verglichen. Sind die beide Werte verschieden, so hat sich irgendetwas getan, und es wird eine Reaktion ausgeführt. Beim Initialisieren wird der Zwischenspeicher mit einer 0 belegt. Was passiert nun, wenn ein Sprite mit einem Zeichen kollidiert und einen Kollisions-IRQ ausgelöst hat? Jetzt wird nur einmal eine Reaktion ausgeführt, weil alle folgenden IRQs durch den Vergleich abgefangen werden, da sich der Inhalt des Kollisionsregister nach der Kollision nicht verändert hat. Nun ist das Sprite über das Zeichen hinweg gelaufen. Im Zwischenspeicher steht jetzt der Wert, den das Kollisionsregister zum Zeitpunkt der Kollision enthielt. Kollidiert das Sprite erneut, wird das Kollisionsregister mit dessen altem Wert verglichen und da beide identisch sind, wird nun keine Reaktion mehr ausgelöst!
Wenn der VIC auch beim Verschwinden einer Kollision einen spezifischen IRQ auslösen würde, könnte man den Zwischenspeicher per IRQ wieder auf Null setzen, und alles wäre in bester Ordnung. Leider kann der VIC dies nicht, und man muß sich daher per Programm durch Vergleichen der Sprite- und Zeichenkoordinaten um die Reinitialisierung des Zwischenspeichers kümmern. Damit geht aber der Vorteil der IRQ-Ausnutzung leider gänzlich verloren.
Da es meistens erwünscht ist, daß die kollidierten Sprites auch nach der Kollision noch eingeschaltet bleiben, ist der oben beschriebene Weg der Kollisionserkennung nicht zufriedenstellend.
Es bietet sich jedoch eine ähnliche Methode an, die allerdings keinen Gebrauch von Kollisions-IRQ macht: Da bei Spielen fast immer irgendeine IRQ-Quelle eingeschaltet ist, kann man in die zugehörige IRQ-Routine eine permanente Abfrage der Kollisionsregister einhängen. Man läßt nur dann eine Reaktion zu, wenn ein Bit in diesem Register zusätzlich gesetzt wurde. Wenn das Register erst eine 0 enthielt, dannach eine 1, da Sprite 0 kollidiert ist, wird eine Reaktion ausgelöst. Verändert sich das Register wieder, es wird zum Beispiel aus der 1 wieder eine 0, so erfolgt keine Reaktion.
Nun haben wir umfassende Kenntnisse zum Thema Spritebewegung, -animation und -kollision. Im nächsten Teil lesen Sie, wie Sie sich eigene Zeichensätze erstellen und diese in eigenen Spielen verwenden können.
(H. Rosenfeld/mf)
Listing 1 zeigt eine Spritebewegung ohne Berücksichtigung des Rasterstrahls (download Quellcode in Hypra-Ass Format) |
||
10 -.BA 49152 ;START = 49152 20 -.GL VIC = $D000 ;VIC BASISADRESSE 30 -.GL IRQVEC = $0314 ;IRQ-VEKTOR 40 -.GL IRQALT = $EA31 ;ALTE IRQ-ROUTINE 200 -INIT JSR MAKESPR ;SPRITE GENERIEREN 210 - SEI ;IRQ SPERREN 220 - LDA #<(IRQNEU);IRQ-VEKTOR AUF IRQNEU STELLEN 230 - LDX #>(IRQNEU) 240 - STA IRQVEC 250 - STX IRQVEC+1 260 - CLI ;IRQ ZULASSEN 270 - RTS ;UND ZURUECK... 280 -; 290 -MAKESPR LDX #62 ;SPRITE-DATEN NACH BLOCK 32 300 - LDA #255 ;(2048-2110) 310 -MAKELOOP STA 2048,X 320 - DEX 330 - BPL MAKELOOP 340 - LDA #32 ;BLOCK 32 FESTLEGEN 350 - STA 2040 360 - LDA #0 ;SINGLECOLOR-MODUS 370 - STA VIC+28 380 - LDA #1 ;SPRITE 0 = WEISS 390 - STA VIC+39 400 - LDA #0 410 - STA VIC+29 ;KEINE X-VERGROESSERUNG 420 - STA VIC+23 ;KEINE Y-VERGROESSERUNG 430 - STA VIC ;X-KOORDINATE = 0 440 - STA VIC+16 450 - LDA #140 ;Y-KOORDINATE = 140 460 - STA VIC+1 470 - LDA #1 ;SPRITE 0 EINSCHALTEN 480 - STA VIC+21 490 - RTS ;UND ZURUECK... 500 -; 510 -IRQNEU INC VIC ;LO-BYTE DER X-KOORDINATE 520 - BEQ INCHI ;ERHOEHEN- IST ES 0, DANN INCHHI 530 - LDA VIC ;LO-BYTE GROESSER ALS 120 ? 540 - CMP #120 550 - BCC IRQRET ;NEIN, DANN IRQ BEENDEN 560 - LDA VIC+16 ;JA, DANN HI-BYTE = 1 ? 570 - AND #1 580 - BEQ IRQRET ;NEIN, DANN IRQ BEENDEN 590 - LDA #0 ;JA, DANN X-KOORDINATE = 0 600 - STA VIC 610 - STA VIC+16 620 -IRQRET JMP IRQALT ;ZUR ALTEN IRQ-ROUTINE 630 -INCHI INC VIC+16 ;HI-BYTE ERHOEHEN 640 - JMP IRQRET ;IRQ BEENDEN READY. | ||
Listing 2 erzeugt eine flimmerfreie Spritebewegung durch Berücksichtigung des Rasterstrahls (download Quellcode in Hypra-Ass Format) |
||
10 -.BA 49152 ;START = 49152 20 -.GL VIC = $D000 ;VIC BASISADRESSE 30 -.GL IRQVEC = $0314 ;IRQ-VEKTOR 40 -.GL IRQALT = $EA31 ;ALTE IRQ-ROUTINE 50 -.GL RASTER = VIC+18 ;RASTERZEILEN-REGISTER 60 -.GL IRQMASK= VIC+26 ;IRQ-MASKENREGISTER 70 -.GL IRQFLAG= VIC+25 ;IRQ-REQUESTREGISTER 80 -.GL HIBIT = VIC+17 ;HI-BIT VOM RASTERREGISTER 90 -.GL CIATIME= $DC0E ;CIA-TIMER-STEUERREGISTER 200 -INIT JSR MAKESPR ;SPRITE GENERIEREN 210 - SEI ;IRQ SPERREN 220 - LDA #0 ;RASTER-IRQ BEI ZEILE 0 230 - STA RASTER 240 - LDA HIBIT 250 - AND #127 260 - STA HIBIT 270 - LDA #129 ;RASTER-IRQ MASKIEREN 280 - STA IRQMASK 290 - LDA CIATIME ;CIA-TIMER AUSSCHALTEN 300 - AND #254 310 - STA CIATIME 320 - LDA #<(IRQNEU);IRQ-VEKTOR AUF IRQNEU STELLEN 330 - LDX #>(IRQNEU) 340 - STA IRQVEC 350 - STX IRQVEC+1 360 - LDA IRQFLAG ;IRQ-REQUESTREGISTER 370 - STA IRQFLAG ;LOESCHEN 380 - CLI ;IRQ ZULASSEN 390 - RTS ;UND ZURUECK... 400 -; 410 -MAKESPR LDX #62 ;SPRITE-DATEN NACH BLOCK 32 420 - LDA #255 ;(2048-2110) 430 -MAKELOOP STA 2048,X 440 - DEX 450 - BPL MAKELOOP 460 - LDA #32 ;BLOCK 32 FESTLEGEN 470 - STA 2040 480 - LDA #0 ;SINGLECOLOR-MODUS 490 - STA VIC+28 500 - LDA #1 ;SPRITE 0 = WEISS 510 - STA VIC+39 520 - LDA #0 530 - STA VIC+29 ;KEINE X-VERGROESSERUNG 540 - STA VIC+23 ;KEINE Y-VERGROESSERUNG 550 - STA VIC ;X-KOORDINATE = 0 560 - STA VIC+16 570 - LDA #140 ;Y-KOORDINATE = 140 580 - STA VIC+1 590 - LDA #1 ;SPRITE 0 EINSCHALTEN 600 - STA VIC+21 610 - RTS ;UND ZURUECK... 620 -; 630 -IRQNEU LDA IRQFLAG ;IRQ-RASTERREGISTER 640 - STA IRQFLAG ;LOESCHEN 650 - INC VIC ;LO-BYTE DER X-KOORDINATE 660 - BEQ INCHI ;ERHOEHEN- IST ES 0, DANN INCHHI 670 - LDA VIC ;LO-BYTE GROESSER ALS 120 ? 680 - CMP #120 690 - BCC IRQRET ;NEIN, DANN IRQ BEENDEN 700 - LDA VIC+16 ;JA, DANN HI-BYTE = 1 ? 710 - AND #1 720 - BEQ IRQRET ;NEIN, DANN IRQ BEENDEN 730 - LDA #0 ;JA, DANN X-KOORDINATE = 0 740 - STA VIC 750 - STA VIC+16 760 -IRQRET JMP IRQALT ;ZUR ALTEN IRQ-ROUTINE 770 -INCHI INC VIC+16 ;HI-BYTE ERHOEHEN 780 - JMP IRQRET ;IRQ BEENDEN READY. | ||
Listing 3 koppelt Sprite 0 mit dem Joystick an Port 2 (Sie können dieses File auch downloaden) |
||
Name : sprite-connect c000 c0f2 ---------------------------------- c000 : 78 a9 00 8d 12 d0 ad 11 7f c008 : d0 29 7f 8d 11 d0 a9 81 40 c010 : 8d 1a d0 ad 0e dc 29 fe ff c018 : 8d 0e dc a9 2d a2 c0 8d 1f c020 : 14 03 8e 15 03 ad 19 d0 a0 c028 : 8d 19 d0 58 60 ad 19 d0 fa c030 : 8d 19 d0 ad 00 dc 29 0f dd c038 : aa bd cf c0 8d ef c0 bd a4 c040 : df c0 8d f0 c0 ad ef c0 bb c048 : 30 4d d0 27 ad 00 d0 c9 ea c050 : 19 b0 07 ad 10 d0 29 01 67 c058 : f0 3d ad 10 d0 29 01 aa 04 c060 : 38 ad 00 d0 ed f1 c0 8d 15 c068 : 00 d0 8a e9 00 20 be c0 2e c070 : 4c 97 c0 ad 00 d0 c9 41 9e c078 : 90 07 ad 10 d0 29 01 d0 f5 c080 : 16 ad 10 d0 29 01 aa 18 00 c088 : ad 00 d0 6d f1 c0 8d 00 72 c090 : d0 8a 69 00 20 be c0 ad 56 c098 : f0 c0 30 1f d0 10 ad 01 1f c0a0 : d0 c9 32 90 16 ed f1 c0 0e c0a8 : 8d 01 d0 4c bb c0 ad 01 ee c0b0 : d0 c9 e6 b0 06 6d f1 c0 4a c0b8 : 8d 01 d0 4c 31 ea 48 ad 6a c0c0 : 10 d0 29 fe 8d 10 d0 68 d0 c0c8 : 0d 10 d0 8d 10 d0 60 80 cd c0d0 : 80 80 80 80 01 01 01 80 de c0d8 : 00 00 00 80 80 80 80 80 f8 c0e0 : 80 80 80 80 01 00 80 80 e4 c0e8 : 01 00 80 80 01 00 80 00 2c c0f0 : 00 04 00 00 ff ff 00 00 f2 | ||
Listing 4 zeigt eine Sprite-Animation, die durch Umschalten des Spritepointers erzeugt wird. Probieren Sie, es mit Listing 2 zu kombinieren! (download Quellcode in Hypra-Ass Format) |
||
10 -.BA 49152 ;START = 49152 20 -.GL VIC = $D000 ;VIC BASISADRESSE 30 -.GL IRQVEC = $0314 ;IRQ-VEKTOR 40 -.GL IRQALT = $EA31 ;ALTE IRQ-ROUTINE 50 -.GL RASTER = VIC+18 ;RASTERZEILEN-REGISTER 60 -.GL IRQMASK= VIC+26 ;IRQ-MASKENREGISTER 70 -.GL IRQFLAG= VIC+25 ;IRQ-REQUESTREGISTER 80 -.GL HIBIT = VIC+17 ;HI-BIT VOM RASTERREGISTER 90 -.GL CIATIME= $DC0E ;CIA-TIMER-STEUERREGISTER 100 -.GL JOYSTICK=56320 ;JOYSTICK PORT 2 200 -INIT SEI ;IRQ SPERREN 210 - JSR MAKESPR ;SPRITES GENERIEREN 220 - LDA #0 ;RASTER-IRQ BEI ZEILE 0 230 - STA RASTER 240 - LDA HIBIT 250 - AND #127 260 - STA HIBIT 270 - LDA #129 ;RASTER-IRQ MASKIEREN 280 - STA IRQMASK 290 - LDA CIATIME ;CIA-TIMER AUSSCHALTEN 300 - AND #254 310 - STA CIATIME 320 - LDA #<(IRQNEU);IRQ-VEKTOR AUF IRQNEU STELLEN 330 - LDX #>(IRQNEU) 340 - STA IRQVEC 350 - STX IRQVEC+1 360 - LDA IRQFLAG ;IRQ-REQUESTREGISTER 370 - STA IRQFLAG ;LOESCHEN 380 - CLI ;IRQ ZULASSEN 390 - RTS ;UND ZURUECK... 400 -; 410 -MAKESPR LDA #<(2048) ;POINTER AUF 2048 420 - LDX #>(2048) 430 - STA LOOP+1 440 - STX LOOP+2 450 - LDX #62 ;62 INS X-REGISTER 460 - LDY #8 ;8 EINZEL-SPRITES 470 - LDA #254 ;SPRITE 1 BITMUSTER %11111110 480 -LOOP STA 65535,X ;SPRITE X MIT BITMUSTER 490 - DEX ;BELEGEN 500 - BPL LOOP 510 - PHA ;AKKU MERKEN 520 - CLC ;POINTER UM 64 AUFADDIEREN 530 - LDA LOOP+1 540 - ADC #64 550 - STA LOOP+1 560 - LDA LOOP+2 570 - ADC #0 580 - STA LOOP+2 590 - LDX #62 ;ERNEUT 62 INS X-REGISTER 600 - PLA ;AKKU ZURUECKHOLEN 610 - SEC ;CARRY SETZEN 620 - ROL ;UND 'HINEINROTIEREN' 630 - DEY ;Y-DEKREMENTIEREN 640 - BNE LOOP ;UNGLEICH NULL, DANN WEITER 650 - LDA #32 ;SONST SPRITE-POINTER 660 - STA 2040 ;BELEGEN 670 - LDA #1 ;SPRITE 0 = WEISS 680 - STA VIC+39 690 - LDA #100 ;SPRITE 0 KOORDINATEN 100:100 700 - STA VIC 710 - STA VIC+1 720 - LDA #1 ;SPRITE 0 EINSCHALTEN 730 - STA VIC+21 740 - RTS ;UND ZURUECK... 750 -IRQNEU LDA IRQFLAG ;IRQ-STEUERREGISTER LOESCHEN 760 - STA IRQFLAG 770 - DEC WART ;WARTE-SCHLEIFE ERNIEDRIGEN 780 - BNE IRQRET ;UNGLEICH 0, DANN IRQ BEENDEN 790 - LDA #5 ;SONST WARTESCHLEIFE NEU 800 - STA WART ;BELEGEN 810 - LDA DIRECT ;WENN ZAEHLRICHTING = 0, 820 - BEQ UP ;DANN NACH 'UP' 830 -DOWN DEC 2040 ;SONST SPRITE-POINTER 840 - LDA 2040 ;HERUNTERZAEHLEN UND MIT 850 - CMP #31 ;31 VERGLEICHEN 860 - BNE IRQRET ;UNGLEICH, DANN ENDE 870 - LDA #0 ;SONST ZAEHLRICHTUNG = UP 880 - STA DIRECT 890 -UP INC 2040 ;SPRITE-POINTER ERHOEHEN 900 - LDA 2040 ;MIT 40 VERGLEICHEN 910 - CMP #40 920 - BNE IRQRET ;UNGLEICH, DANN ENDE 930 - LDA #1 ;ZAEHLRICHTING = DOWN 940 - STA DIRECT 950 - JMP DOWN ;NACH 'DOWN' 960 -IRQRET JMP IRQALT ;IRQ-ROUTINE BEENDEN 970 -WART .BY 1 980 -DIRECT .BY 0 READY. | ||
Listing 5 demonstriert einen VIC-Interrupt für Sprite/Hintergrund-Kollisionen (download Quellcode in Hypra-Ass Format) |
||
10 -.BA 49152 ;START = 49152 20 -.GL VIC = $D000 ;VIC BASISADRESSE 30 -.GL IRQVEC = $0314 ;IRQ-VEKTOR 40 -.GL IRQALT = $EA31 ;ALTE IRQ-ROUTINE 50 -.GL IRQEND = $FEBC ;IRQ BEENDEN 60 -.GL RASTER = VIC+18 ;RASTERZEILEN-REGISTER 70 -.GL IRQMASK= VIC+26 ;IRQ-MASKENREGISTER 80 -.GL IRQFLAG= VIC+25 ;IRQ-REQUESTREGISTER 90 -.GL HIBIT = VIC+17 ;HI-BIT VOM RASTERREGISTER 100 -.GL SPRKOL = VIC+30 ;SPRITE-SPRITE-KOLL. 110 -.GL SCRKOL = VIC+31 ;SPRITE-HINTERGRUND-KOLL. 999 -; 1000 -INIT JSR MAKESPR ;SPRITE-GENERIEREN 1010 - SEI ;IRQ SPERREN 1020 - LDA #130 ;SPRITE-HINTERGRUND-KOLL. 1030 - STA IRQMASK ;MASKIEREN 1040 - LDA #<(IRQNEU);IRQ-VEKTOR 1050 - LDX #>(IRQNEU);VERBIEGEN 1060 - STA IRQVEC 1070 - STX IRQVEC+1 1080 - LDA SCRKOL ;KOLL.-REGISTER LOESCHEN 1090 - LDA IRQFLAG ;IRQ-REQUESTREGISTER 1100 - STA IRQFLAG ;LOESCHEN 1110 - CLI ;IRQ ZULASSEN 1120 - RTS ;UND ZURUECK... 1130 -; 1140 -MAKESPR LDX #62 ;BLOCK 32 MIT 255 BELEGEN 1150 - LDA #255 1160 -LOOP STA 2048,X 1170 - DEX 1180 - BPL LOOP 1190 - LDA #32 ;BLOCK 32 FUER SPRITE 0 1200 - STA 2040 ;FESTLEGEN 1210 - LDA #1 ;SPRITE 0 = WEISS 1220 - STA VIC+39 1230 - LDA #160 ;X-KOORDINATE = 160 1240 - STA VIC 1250 - LDA #130 ;Y-KOORDINATE = 130 1260 - STA VIC+1 1270 - LDA #0 ;HILFSBIT LOESCHEN 1280 - STA VIC+16 1290 - LDA #1 ;SPRITE 0 EINSCHALTEN 1300 - STA VIC+21 1310 - RTS ;UND ZURUECK... 1320 -; 1330 -IRQNEU LDA IRQFLAG ;IRQ-REQUESTREGISTER 1340 - STA IRQFLAG ;LOESCHEN 1350 - BMI VICIRQ ;BIT 7 GESETZT, DANN VICIRQ 1360 - JMP IRQALT ;SONST ALTE IRQ-ROUTINE 1370 -VICIRQ LDA SCRKOL ;KOLL-REGISTER LOESCHEN 1380 - INC 1024 ;1024 INKREMENTIEREN 1390 - JMP IRQEND ;IRQ BEENDEN READY. | ||