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.