Ich habe mein eigenes Handspielgerät entwickelt, das auf einem AVR-Mikrocontroller und einem kleinen OLED-Display basiert.
Ich habe mit einem monochromen Display mit 128 x 64 Pixeln begonnen und kann bequem mit über 60 Bildern pro Sekunde darauf zeichnen.
Ich habe es kürzlich überarbeitet, um eine RGB-OLED mit 128 x 128 Pixeln zu verwenden, ohne wirklich zu viel darüber nachzudenken, nur um festzustellen, dass ich nur etwa 4 FPS erreichen konnte. Nach einigem Überlegen und sorgfältigem Refactoring kann ich das auf ~ 12fps bringen, wenn es mir nicht so wichtig ist, etwas anderes zu tun!
Meine Frage ist - wie hat ein Gerät wie der GBA (Game Boy Advance) eine Bildrate von fast 60 fps erreicht? Ich dachte über einen separaten Grafikprozessor nach, erkannte aber, dass ich immer noch einen Engpass haben würde, wenn ich die Anzeigedaten dorthin übertrage.
Ich habe mich auch gefragt, ob ich die ursprüngliche 8-Bit-Parallelschnittstelle verwenden soll, die die meisten dieser Bildschirme haben, was mir eine 8-fache Geschwindigkeit einbringt, mit der Ausnahme, dass moderne MCUs keine Hardware-Parallelschnittstellen haben, wie sie es für serielle und bitbasierte Schnittstellen tun. Schlagen wird wahrscheinlich einen großen Teil des Geschwindigkeitsgewinns verschlingen.
Welche anderen Möglichkeiten gibt es?
Ich verwende derzeit einen ATmega1284P, der über USART-SPI an einen SSD1306-OLED-Controller angeschlossen ist. Das ist die monochrome Version.
Der Farbbildschirm war eine SSD1351, die ursprünglich nicht mit Hardware-SPI verbunden war. Ich war nicht überzeugt, dass es genug bringen würde Unterschied , es ist insgesamt einfach zu langsam
Ich weiß, dass ich schnellere MCUs bekommen kann, aber ich möchte wissen, welche anderen Optionen ich untersuchen könnte - der GBA-Prozessor ist viel langsamer als mein 1284!
quelle
Antworten:
Andere Antworten decken Ihre Frage auf abstrakter Ebene (Hardware) ziemlich gut ab, aber ich war der Meinung, dass es sich lohnen könnte, eine detailliertere Erklärung zu geben, wenn ich über konkrete Erfahrungen mit der GBA verfüge.
Der GBA verfügte über zahlreiche Zeichenmodi und -einstellungen, mit denen gesteuert werden konnte, wie der Grafikprozessor den Video-RAM interpretierte. Eines war jedoch unausweichlich: die Bildrate. Der Grafikprozessor zeichnete in einer fast (mehr dazu weiter unten) konstanten Schleife auf den Bildschirm. (Dies ist wahrscheinlich das relevanteste Bit für Ihre Frage.)
Es würde eine Linie nach der anderen ziehen und eine sehr kurze Pause zwischen den beiden einlegen. Nach dem Zeichnen der letzten Linie für den Rahmen würde eine Pause erforderlich sein, die in etwa der Zeit entspricht, die zum Zeichnen von 30 Linien benötigt wird. Dann wieder von vorne anfangen. Das Timing jeder Zeile und das Timing jedes Rahmens waren alle vorbestimmt und in Stein gemeißelt. In vielerlei Hinsicht war der Grafikprozessor wirklich der Meister dieses Systems, und Sie mussten Ihre Spiele um sein Verhalten herum schreiben, da er weiterhin das tat, was er tat, unabhängig davon, ob Sie bereit waren oder nicht.
Ungefähr 75-80% der Zeit wurde aktiv auf den Bildschirm gedrückt. Welche Frameraten könnten Sie erreichen, wenn Sie dasselbe tun?
In 80% der Zeit musste die CPU auch Benutzereingaben verarbeiten, den Spielstatus berechnen und Sprites / Kacheln in Bereiche des VRAM laden, die sich derzeit außerhalb des Bildschirms befanden (oder zumindest nicht in der aktuell gezeichneten Linie enthalten waren).
Die 20% zwischen den Frames waren alles, was die CPU für die Optimierung der Videoeinstellungen oder des RAM-Speichers benötigte, um den gesamten nächsten Frame zu beeinflussen.
Am Ende jeder Zeile würde der Grafikprozessor einen Zeilensynchronisations-Interrupt an die CPU senden. Dieser Interrupt kann verwendet werden, um Einstellungen für einige Sprites oder einige Hintergrundebenen zu optimieren (auf diese Weise können Sie einen Effekt wie bei einem konischen Scheinwerfer erzielen, indem Sie die Größe und Position einer der rechteckigen Masken zwischen den einzelnen Linien ändern In Bezug auf die Hardware sind alle diese Bereiche rechteckig.). Sie müssen vorsichtig sein, um diese Updates klein zu halten und fertig zu stellen, bevor der Grafikprozessor mit dem Zeichnen der nächsten Zeile beginnt. Andernfalls können hässliche Ergebnisse erzielt werden. Jeder Zeitaufwand für die Verarbeitung dieser Interrupts verkürzt auch die Verarbeitungszeit der CPU um 80%.
Bei Spielen, die das meiste aus diesem System herausholen, haben weder die CPU noch der Grafikprozessor jemals eine Pause eingelegt. jeder jagte den anderen um die Schleife und aktualisierte, was der andere gerade nicht ansah.
quelle
Das Hauptmerkmal aller Spielekonsolen, die sie von früheren PCs und praktisch allen Heimcomputern unterschieden (1), waren Hardware-Sprites .
Der verknüpfte GBA-Programmierleitfaden zeigt, wie sie aus Sicht des Hauptprozessors funktionieren. Bitmaps, die Spieler, Hintergrund, Gegner usw. darstellen, werden in einen Speicherbereich geladen. Ein anderer Speicherbereich gibt die Position der Sprites an. Anstatt den gesamten Video-RAM für jeden Frame neu schreiben zu müssen, was viele Anweisungen erfordert, muss der Prozessor nur die Position der Sprites aktualisieren.
Der Videoprozessor kann dann pixelweise arbeiten, um zu bestimmen, welches Sprite an diesem Punkt gezeichnet werden soll.
Dies erfordert jedoch einen Dual-Port-RAM, der von beiden gemeinsam genutzt wird, und ich denke, dass sich der Videoprozessor im GBA auf demselben Chip befindet wie der Haupt-ARM- und der sekundäre Z80-Prozessor.
(1) Bemerkenswerte Ausnahme: Amiga
quelle
"Meine Frage ist - wie hat ein Gerät wie der GBA eine Bildrate von fast 60 fps erreicht?"
Um nur die Frage zu beantworten, haben sie es mit einem Grafikprozessor gemacht. Ich bin mir ziemlich sicher, dass der Game Boy Sprite-Grafiken verwendet hat. Auf der obersten Ebene bedeutet dies, dass der Grafikprozessor Dinge wie ein Bild eines Hintergrunds und ein Bild von Mario und ein Bild von Prinzessin Peach usw. lädt. Dann gibt der Hauptprozessor Befehle aus, wie "Hintergrundversatz dadurch anzeigen" Englisch: www.mjfriendship.de/en/index.php?op...37&Itemid=32 Viel in x und y überlagern Sie Mario - Bild 3 an dieser x, y - Position ", usw. Der Hauptprozessor befasst sich also absolut nicht mit dem Zeichnen jedes Pixels, und der Grafikprozessor befasst sich absolut nicht mit dem Berechnen des Zustands von Spiel. Jedes ist für das optimiert, was es tun muss, und das Ergebnis ist ein ziemlich gutes Videospiel ohne viel Rechenleistung.
quelle
Der GBA hatte einen ziemlich langsamen Prozessor. Der ARM7 ist sehr schön; Sie liefen es nur langsam und gaben es so gut wie keine Ressourcen.
Es gibt einen Grund, warum viele Nintendo-Spiele zu diesem Zeitpunkt und früher Side-Scroller waren. HARDWARE. Es ist alles in Hardware erledigt. Sie hatten mehrere Kachelebenen plus ein oder mehrere Sprites, und die Hardware hat alles getan, um Pixel aus diesen Tabellen zu extrahieren und die Anzeige zu steuern.
Sie bauten die Kacheln vorne auf und hatten dann ein kleines Gedächtnis, das eine Kachelkarte war. Soll die untere linke Kachel Kachel 7 sein? Sie setzen eine 7 in diesen Speicherort. Soll die nächste Kachel die Kachel 19 sein? Im Kachelsatz setzen Sie dort eine 19 und so weiter für jede Ebene, die Sie aktiviert haben. Für das Sprite legen Sie einfach die x / y-Adresse fest. Sie können auch skalieren und drehen, indem Sie einige Register setzen. Den Rest erledigt die Hardware.
Wenn ich mich recht erinnere, war Modus 7 ein Pixelmodus, aber das war wie bei einer herkömmlichen Grafikkarte, bei der Sie Bytes in die Farbe eines Pixels einfügen und die Hardware die Aktualisierung des Videos übernimmt. Ich denke, du könntest Ping-Pong spielen oder wenn du einen neuen Rahmen hättest, könntest du sie umdrehen, aber ich erinnere mich nicht richtig. Auch hier war der Prozessor für diesen Tag und dieses Alter ziemlich übertaktet und verfügte nicht über zu viele schnelle Ressourcen. Während einige Spiele Mode 7 waren, waren viele Side-Scroller auf Kachelbasis ...
Wenn Sie eine Lösung mit hoher Bildrate wünschen, müssen Sie diese Lösung entwerfen. Sie können nicht einfach ein altes Display nehmen und über SPI oder I²C oder ähnliches damit sprechen. Stellen Sie mindestens einen Framebuffer davor, idealerweise zwei, und steuern Sie Zeilen und Spalten, wenn möglich, über diese Anzeige.
Ich vermute, dass einige der Displays, die Sie kaufen, über einen Controller verfügen, mit dem Sie tatsächlich sprechen. Wenn Sie eine Leistung vom Typ GBA / Konsole wünschen, erstellen / implementieren Sie den Controller. Oder Sie kaufen / bauen mit einer GPU / einem Videochip / einem Logik-Blob und verwenden HDMI oder eine andere gemeinsame Schnittstelle für einen Lagermonitor.
Nur weil ein Fahrrad Reifen und eine Kette und Zahnräder hat, kann es nicht so schnell fahren wie ein Motorrad. Sie müssen das System so gestalten, dass es Ihre Leistungsanforderungen von Ende zu Ende erfüllt. Sie können das Fahrradrad auf das Motorrad setzen, aber es funktioniert nicht wie gewünscht. Alle Komponenten müssen Teil des Gesamtdesigns sein.
Asteroiden arbeiteten auch so; es wurde nur ein 6502 benötigt. Die Vektorgrafiken wurden mit separater Logik erstellt; Der 6502 hat eine winzige Datenfolge an den Vektorgrafik-Controller gesendet, der ein ROM und diese Daten für das xy-Zeichnen des Strahls und des zs verwendet hat. Ein / Aus ... Einige Stand-ups hatten separate Prozessoren, um Audio und Video getrennt zu verarbeiten der Prozessor, der das Spiel berechnet. Natürlich wird das Video heute von einigen Hundert, wenn nicht Tausenden von Prozessoren verarbeitet, die vom Hauptprozessor getrennt sind ...
quelle
Hardware.
Es verfügt über einen Grafikspeicher, der möglicherweise den gleichen Bus wie der Programm- / Datenspeicher verwendet oder nicht. Wichtig ist jedoch, dass er über einen Grafikprozessor verfügt, der den Speicher 60 Mal pro Sekunde liest und die Daten mithilfe von an auf das LCD sendet optimierte Schnittstelle, die dafür effizient ausgelegt ist.
Dasselbe können Sie mit jedem modernen Mikrocontroller tun, der mit einem "LCD-Interface" -Peripheriegerät ausgestattet ist, z. B. dem LPC4330, obwohl dies viel zu viel sein kann. Natürlich benötigen Sie ein kompatibles LCD-Panel.
Mit modernen schnellen Mikrocontrollern (z. B. ARM, nicht AVR) und einem so kleinen Bildschirm werden Sie wahrscheinlich keine Sprites oder Blitter benötigen, um Grafikoperationen zu beschleunigen. Mit einem 8-Bit-AVR kann es langsam sein.
Aber egal wie hoch die CPU-Leistung ist, ein bisschen hämmert die Schnittstelle zum Display.
Ich glaube, der Atari 2600 verwendete CPU-Bit-Banging, um das Bild an den Fernseher zu senden. Das ist ein bisschen veraltet.
quelle