15 Stimmen

Was ist der "Side-Scrolling-Hack" aus alten Spielen?

Ich habe gehört, dass alte Arcade-Side-Scrolling-Spiele einen bestimmten Programmiertrick verwendet haben, um performantes Side-Scrolling zu ermöglichen.

Meines Wissens nach waren die Maschinen vor Jahren nicht leistungsstark genug, um den gesamten Bildschirm in jedem Frame neu zu zeichnen, wie es heutzutage gemacht wird. Es gibt Techniken wie Dirty Rectangles, die es ermöglichen, den Bereich auf dem Bildschirm zu minimieren, der neu gezeichnet werden muss, wenn der Hintergrund stationär ist und nur die Sprites sich bewegen.

Der oben genannte Ansatz funktioniert nur, wenn sich der Hintergrund nicht ändert (und somit die meisten Bildschirmpixel stationär bleiben).

Vertikale Scrollingspiele, wie alte Shoot'em Ups, haben es etwas schwieriger, da sich der Hintergrund aufgrund des Scrollens in jedem Frame ändert. Man könnte jedoch von der Art und Weise profitieren, wie die Pixel an den Bildschirm übertragen werden (zeilenweise). Ich stelle mir vor, dass man einen größeren Pufferspeicher verwenden und den Datenzeiger in jedem Frame einige Zeilen "nach unten" verschieben könnte, so dass er von einer anderen Position aus neu gezeichnet wird und damit den Eindruck eines flüssigen Scrolls erweckt. Trotzdem müssten nur die Sprites (und ein kleiner Teil des Hintergrunds am Bildschirmrand) neu gezeichnet werden, was eine ernsthafte Optimierung darstellt.

Allerdings ist das für Side-Scrolling-Spiele nicht so einfach und offensichtlich. Dennoch bin ich mir bewusst, dass irgendjemand, irgendwann in der Vergangenheit, eine Optimierungsidee hatte, die es den alten Maschinen ermöglichte, den Hintergrund horizontal zu scrollen, ohne ihn in jedem Frame neu zu zeichnen.

Soweit ich mich erinnere, wurde dies in vielen alten Spielen verwendet, hauptsächlich in den Beat'em-Ups der 80er Jahre sowie in Demoszene-Produktionen.

Können Sie diese Technik beschreiben und den Autor benennen?

1 Stimmen

Zwei ausgezeichnete nicht überlappende Antworten! Ich wünschte, ich könnte beide akzeptieren :-)

11voto

Dan Byström Punkte 8850

Ich habe Spiele für den guten alten C64 geschrieben, die genau das getan haben. Und es gibt im Grunde zwei Dinge, auf die man achten sollte:

  1. Diese Spiele verwendeten KEINE Bitmap-Grafiken, sondern verwendeten stattdessen "umgestaltete" Zeichensätze, was bedeutet, dass Segmente von 8x8 Pixel tatsächlich als nur ein Byte bewegt wurden.

  2. Das nächste, was zu beachten ist, ist, dass es Hardwareunterstützung gab, um den gesamten Bildschirm um sieben Pixel zu verschieben. Beachten Sie, dass dies die Grafiken in keiner Weise beeinflusste - es hat einfach alles, was an den Fernseher gesendet wurde, ein wenig verschoben.

Also 2) machte es möglich, wirklich schön 7 Pixel wegzuscrollen. Dann haben Sie jede Zeichen umherbewegt - was für einen ganzen Bildschirm genau 1000 Bytes waren, mit denen der Computer zurechtkam, während Sie gleichzeitig das Scrollregister um 7 Pixel zurückbewegten. 8 - 7 = 1 bedeutet, dass es aussah, als ob Sie noch ein weiteres einzelnes Pixel gescrollt hätten… und dann ging es einfach so weiter. Also 1) und 2) kombiniert erzeugten die Illusion des echten sanften Scrollens!

Danach kam ein dritter Punkt ins Spiel: Rasterunterbrechungen. Das bedeutet, dass die CPU eine Unterbrechung erhält, wenn der Fernseher / Monitor dabei war, eine Scanlinie an einer bestimmten Stelle zu zeichnen. Diese Technik machte es möglich, einen Bildschirm zu erstellen, ohne dass Sie den gesamten Bildschirm scrollen mussten, im Gegensatz zu meiner ersten Beschreibung.

Und um noch genauer zu sein: selbst wenn Sie keinen geteilten Bildschirm wollten, war die Rasterunterbrechung trotzdem sehr wichtig: denn es war genauso wichtig damals wie heute (aber heute verbirgt das Framework dies vor Ihnen), den Bildschirm zum richtigen Zeitpunkt zu aktualisieren. Das Ändern des "Scrollregisters", während der Fernseher / Monitor irgendwo im sichtbaren Bereich aktualisiert wurde, würde einen Effekt namens "zerreißen" verursachen - wo Sie deutlich bemerken, dass die beiden Teile des Bildschirms nicht pixelgenau synchron sind.

Was gibt es noch zu sagen? Nun, die Technik mit umgestalteten Zeichensätzen ermöglichte es, einige Animationen sehr einfach durchzuführen. Zum Beispiel konnten Förderbänder und Zahnräder und ähnliches durch ständige Änderung des Aussehens der "Zeichen", die sie auf dem Bildschirm darstellten, animiert werden. So konnte ein über die gesamte Bildschirmbreite verlaufendes Förderband überall wie ein sich drehendes Band aussehen, indem einfach ein einzelnes Byte in der Zeichenkarte geändert wurde.

0 Stimmen

Gut. Ich habe so etwas schon einmal auf einem PC ausprobiert, war aber gehemmt, da ich nur 256 verschiedene "Zeichen" in einem Satz platzieren konnte.

0 Stimmen

Es gab auch eine Flagge im Videochip des C64, um das Display horizontal um ein Zeichen zu verkleinern, sodass man das zusätzliche Zeichen, das gerade gescrollt wird, nicht bemerken würde.

0 Stimmen

@yi_H Ganz genau. Jetzt gehen Sie wirklich ins Detail! :-)

8voto

3Dave Punkte 27742

Ich habe Anfang der 90er Jahre etwas Ähnliches gemacht, mit zwei verschiedenen Ansätzen.

Der erste beinhaltete "Windowing", das vom VESA SVGA-Standard unterstützt wurde. Einige Karten haben es korrekt implementiert. Grundsätzlich konnte man, wenn man einen Framebuffer/Video-RAM hatte, der größer als der darstellbare Bereich war, einen großen Bitmap zeichnen und dem System Koordinaten für ein Fenster innerhalb dieses Bereichs geben, das angezeigt werden sollte. Durch Ändern dieser Koordinaten konnte man herumscrollen, ohne den Framebuffer erneut füllen zu müssen.

Die andere Methode beruhte auf der Manipulation der BLT-Methode, die verwendet wurde, um einen vollständigen Frame in den Framebuffer zu übertragen. Ein Page auf den Framebuffer zu blitten, die die gleiche Größe wie der Bildschirm hatte, war einfach und effizient.

Ich fand diesen alten 286 Assembler-Code (auf einer funktionierenden 17 Jahre alten Diskette!), der einen 64000 Byte (320x200) Screen von einer Off-Screen-Page in den Videobuffer kopierte:

  Procedure flip; assembler;
    { Dies kopiert den gesamten Screen bei "Quelle" nach Ziel }
    asm
      push    ds
      mov     ax, [Dest]
      mov     es, ax
      mov     ax, [Source]
      mov     ds, ax
      xor     si, si
      xor     di, di
      mov     cx, 32000
      rep     movsw
      pop     ds
    end;

Das rep movsw hat CX Wörter verschoben (wobei ein Wort in diesem Fall zwei Bytes ist). Das war sehr effizient, da es im Grunde genommen eine einzige Anweisung war, die dem Prozessor sagte, das Ganze so schnell wie möglich zu bewegen.

Wenn man jedoch einen größeren Buffer hatte (zum Beispiel 1024*200 für ein Side-Scroller), konnte man genauso gut eine verschachtelte Schleife verwenden und pro Schleifendurchlauf eine Zeile Pixel kopieren. In einem 1024 Pixel breiten Buffer könnte man zum Beispiel Bytes kopieren:

start          count            
0+left         320
1024+left      320 
...
255*1024+left  320

wo left die x-Koordinate innerhalb des großen Hintergrundbildes ist, bei der man beginnen möchte (linke Seite des Bildschirms).

Natürlich waren in 16-Bit-Modus etwas Magie und Manipulation der Segment-Zeiger (ES, DS) erforderlich, um einen Buffer größer als 64KB zu erhalten (in Wirklichkeit mehrere benachbarte 64K-Buffer), aber es funktionierte ziemlich gut.

Es gab wahrscheinlich bessere Lösungen für dieses Problem (und definitiv bessere Lösungen, die man heute verwenden könnte), aber es funktionierte für mich.

2voto

Cross_ Punkte 513

Arcade-Spiele enthielten häufig angepasste Videochips oder diskrete Logik, um Scrolling ohne dass die CPU (viel) arbeiten musste, zu ermöglichen. Der Ansatz wäre ähnlich wie das, was danbystrom auf dem C-64 beschrieben hat.

Im Grunde hat sich die Grafikhardware um das feine Scrollen von Zeichen (oder Kacheln) gekümmert, und die CPU hat dann alle Kacheln ausgetauscht, sobald die Scroll-Register ihr Limit erreicht haben. Ich beschäftige mich derzeit mit dem Irem m-52-Board, das mit mehreren Scroll-Hintergründen hardwareseitig umgeht. Schaltpläne sind online verfügbar.

1voto

Für das Rechts-Scrollen auf dem Commodore Amiga haben wir den Copper verwendet, um den Bildschirm um bis zu 16 Pixel nach rechts zu verschieben. Nachdem der Bildschirm verschoben worden war, haben wir 2 Bytes zur Startadresse des Bildschirmspeichers hinzugefügt, während auf der rechten Seite der Blitter verwendet wurde, um Grafiken vom Hauptspeicher in den Bildschirmspeicher zu kopieren. Wir haben den Bildschirmspeicher etwas größer als die Bildschirmansicht eingestellt, damit wir die Grafiken kopieren konnten, ohne dass Sie einen Flimmereffekt vom Kopieren auf der rechten Seite des Viewports sehen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X