Rahmensprite
Mit Rahmensprites (engl. border sprites) wird eine spezielle Methode der Grafikprogrammierung bezeichnet, bei der Sprites an den Bildschirmrändern sichtbar gemacht werden, wo sie normalerweise vom einfarbigen Bildschirmrahmen überdeckt werden.
Um den Rahmen "öffnen" zu können, muss der VIC "ausgetrickst" werden. Hierbei ist zwischen zwei verschiedenen Tricks zu unterscheiden: Dem für den horizontalen Rahmen (links und rechts) und dem für den vertikalen Rahmen (oben und unten). Die vier Ecken gehören hierbei zum horizontalen Rahmen.
Nicht nur für die Demoszene war die Entdeckung dieses Programmiertricks von enormer Bedeutung, sondern auch im Bereich der kommerziellen Software-Entwicklung konnten auf diese Weise plötzlich wesentlich mehr Informationen auf dem Bildschirm untergebracht werden. In Anwendungen wie Malprogrammen (Giga Paint, Amica Paint) konnten im Rahmenbereich beispielsweise Koordinaten oder Zeichenmodi angezeigt werden, so dass der Bereich des Bildmotivs immer komplett sichtbar bleiben konnte.
Auch in Spielen wurden diverse Punkte- oder Energieanzeigen in den Rahmen gelegt (Paperboy, Wizball). In seltenen Fällen wurde sogar das Spielfeld vergrößert (No Mercy, Creatures II).
Erstmalig wurden Rahmensprites 1985 im Demo Flash XI verwendet.
Trick 1: Vertikale Rahmen abschalten[Bearbeiten | Quelltext bearbeiten]
Bei diesem Trick macht man sich zu Nutze, dass man beim VIC einstellen kann, ob vom Bildschirm 24 oder 25 Zeilen angezeigt werden sollen. Das legt man mit Bit 3 des 1. Steuerregisters des VIC ($D011) fest. Der Trick besteht nun darin, im richtigen Moment von 25 auf 24 Zeilen umzuschalten. Der VIC bekommt dann den Wechsel in den Rahmen nicht mit.
Genauer muss man das Bit abschalten, wenn sich der Rasterstrahl in den Zeilen 248 bis 250 befindet. Kurz darauf, nämlich ab Zeile 252 kann man das Bit dann wieder anschalten.
Trick 2: Horizontale Rahmen abschalten[Bearbeiten | Quelltext bearbeiten]
Dieser Trick ist weitaus schwieriger, da hierfür ganz exaktes Timing benötigt wird. Die Idee ist aber im Wesentlichen dieselbe: Diesmal wird dafür das Bit 3 des 2. Steuerregisters des VIC ($D016) benötigt, welches zwischen 38 und 40 Spalten umschaltet.
Dieses Bit muss beim Erreichen des rechten Rands abgeschaltet und kurz darauf wieder angeschaltet werden. Auch diesmal bekommt der VIC dann den Wechsel nicht mit und zeigt deshalb den Rahmen nicht an. Für das Umschalten hat man aber nur genau einen Taktzyklus Zeit. Das Programm muss also sehr exakt arbeiten, was bedeutet, dass dem Prozessor für die normalen Arbeiten nur noch wenig Zeit übrig bleibt.
Kleine Beispielprogramme[Bearbeiten | Quelltext bearbeiten]
Assembler (Oben und unten)[Bearbeiten | Quelltext bearbeiten]
Das nachfolgende Assembler-Programm bewegt ein Sprite von oben nach unten über den gesamten Bildschirm. Um den Code kurz zu halten, wird das Sprite nur rudimentär initialisiert: Es ist einfach nur ein rechteckiger Block. Auch das Abfragen der Rasterzeile erfolgt der Einfachheit halber nicht über einen Interrupt, sondern als Busy-Wait-Schleife.
*=$c000 lda #$00 ; Streifen im Rahmenbereich verhindern sta $3FFF lda #$01 ; Sprite 0 einschalten sta $D015 lda #$0D ; Sprite-Daten bei $0340 sta $07F8 lda #172 ; X-Koordinate von Sprite 0 auf Mitte des Bildschirms sta $D000 ldx #$3E ; Aussehen des Sprites: Rechteckiger Block lda #$FF loop sta $0340,x dex bpl loop sei ; Interrupt aus, damit der nicht stört loop1 lda $D012 ; Auf Zeile 248 warten cmp #248 bne loop1 lda $D011 ; Bit 3 in $D011 löschen and #%11110111 sta $D011 loop2 lda $D012 ; Auf Zeile 252 warten cmp #252 bne loop2 lda $D011 ; Bit 3 in $D011 setzen ora #%00001000 sta $D011 inc $D001 ; Y-Koordinate von Sprite 0 erhöhen jmp loop1
Assembler (Links und rechts)[Bearbeiten | Quelltext bearbeiten]
Die Rahmen links und rechts zu öffnen ist weitaus schwieriger, da unter anderem auch jedes angezeigte Sprite das Timing ändert. Um das Beispielprogramm nicht ausufern zu lassen, hier eines, das einfach abwechselnd zwischen 40-Zeichen-Modus und 38-Zeichen-Modus hin- und herspringt, um ab und an das richtige Timing zu erwischen. Man kann deutlich sehen, dass das eine Sprite links aus dem Rahmen herausragt und das andere rechts.
*=$c000 lda #$50 ; Sprite 4 und 6 einschalten sta $D015 lda #$0D ; Sprite-Daten bei $0340 sta $07FC sta $07FE lda #$08 ; X-Koordinate Sprite 4: $08 (linker Rand) sta $D008 lda #140 ; Y-Koordinate Sprite 4 sta $D009 lda #$50 ; X-Koordinate Sprite 6: $150 (rechter Rand) sta $D00C lda #$40 sta $D010 lda #130 ; Y-Koordinate Sprite 6 sta $D00D ldx #$3E ; Aussehen des Sprites: Rechteckiger Block lda #$FF loop sta $0340,x dex bpl loop sei ; Störenden Interrupt abschalten lda $D016 tax and #%11110111 ; Bit 3 ausblenden loop1 sta $D016 ; Abwechselnd Bit 3 an und aus stx $D016 ; in der Hoffnung, gelegentlich das bne loop1 ; richtige Timing zu erwischen...
BASIC (Oben und unten)[Bearbeiten | Quelltext bearbeiten]
Mit der Technik, die Simon Stelling (S.E.S.) für Sprite-Multiplexer erfunden hat, ist es auch in BASIC möglich, Rahmensprites im oberen und unteren Rahmen zu nutzen. Das nachfolgende Programm zeigt, wie das möglich ist:
10 PRINT"{black}{clr}":POKE53280,0:POKE53281,10 20 FORI=0TO62:POKE832+I,255:NEXT 30 FORI=0TO16:READX:POKE53248+I,X:NEXT 40 FORI=0TO7:POKE2040+I,13:NEXT 50 POKE648,208:POKE56334,0:POKE16383,255 60 W=53266:V=128:A=64:POKE53269,255 70 PRINT"{home}{17x right}"; 80 FORI=1024TO2023:POKEI,255:WAITW,V:WAITW,A 90 ::PRINT"{rvs on}{right}{left}{right}{left}{right}{left}S{left}[{left}";:NEXT 100 POKE56324,37:POKE56325,64:POKE56333,129:POKE56334,PEEK(56334)AND128OR17 110 POKE648,4:POKE53269,0:PRINT"{clr}"; 120 DATA52,31,112,44,172,31,232,44,36,31,72,240,172,255,16,240,144
Die wesentliche Idee des Programms besteht darin, den Ausgabebereich des Print-Befehls mit POKE648,208
auf die Adresse $D000 umzubiegen. Dadurch können die zeitkritischen POKEs durch die wesentlich schnellere Ausgabe des PRINT-Befehls ersetzt werden (Zeile 90). Für das Timing wird der WAIT-Befehl benutzt: Zuerst wird auf Rasterzeile 128 gewartet, dann auf Rasterzeile 192. Da danach noch bis Rasterzeile 248 gewartet werden muss, dies aber mit dem WAIT-Befehl nicht mehr möglich ist, wird die Zeit durch Cursorbewegungen gefüllt. Das Finetuning erfolgt durch die beiden Doppelpunkte am Anfang von Zeile 90.
Man beachte: Beim Timing ist noch Spielraum in den Rasterzeilen vor 128 übrig, der für andere Befehle genutzt werden kann. Dies zeigt hier exemplarisch der Befehl POKEI,255
in Zeile 80, mit dem der Bildschirm nach und nach gefüllt wird. Man könnte den Spielraum auch nutzen, um die Sprites zu bewegen.
Hinweise[Bearbeiten | Quelltext bearbeiten]
- Wenn die Rahmen ausgeschaltet sind, wird als Hintergrund das letzte Byte ($3FFF) des VIC-Adressbereichs angezeigt. Im Extended-Color-Mode wird das Byte $39FF angezeigt.
- Da es mehr als 255 Rasterzeilen gibt, wird ein Sprite mit einer niedrigen Y-Koordinate (<32) sowohl oben am Bildschirm, als auch unten angezeigt. Mit einem Sprite-Multiplexer kann diese doppelte Anzeige verhindert werden.
C64-Software mit Rahmensprites (Auszug)[Bearbeiten | Quelltext bearbeiten]
Bei vielen Spielen und einigen Anwendungen wird der obere und untere Rahmen geöffnet, um dort zusätzliche Informationen wie Punkteanzeigen und ähnliches unterzubringen. Weiterhin wird auch die Spielegrafik in den Bildschirmrahmen erweitert.
Punkte- und Energieanzeigen:
- Another World
- Armalyte
- Cobra
- Delta
- Dungeon
- Paperboy
- Phobia
- Pinball Dreams C64 Preview
- Puzzle Bobble
- Turbo Outrun
- Nemesis the Warlock
- Wizball
Spielfelderweiterung:
Anwendungen:
Sonstiges[Bearbeiten | Quelltext bearbeiten]
In den Zeittafeln der C64-Demos, C64-Anwendungen und C64-Spiele wird versucht, die Programme, bei denen Effekte wie diese zum ersten Mal verwendet wurden, in chronologischer Form zusammenzutragen.