Um die Eingabe Latenz in Denise zu verbessern, stelle ich verschiedene Möglichkeiten vor um dies zu erreichen. Da Verbesserungen zu diesem Thema doch sehr subjektiv sind, hoffe ich auf ein paar eingefleischte C64 Zocker, denen das Thema wichtig ist und die entstehenden Umbauten testen/vergleichen und dann ihre Erfahrungen hier teilen.
das Problem
Emulatoren haben im Gegensatz zum Original Gerät eine subjektiv wahrnehmbare Latenz zwischen Eingabe und Verarbeitung. Die Gründe dafür sind hauptsächlich im OS (der lange Weg durchs OS), dem LCD und den USB Geräten zu suchen.
Die Ergebnisse schwanken mit den verwendeten Geräten. Extrem Spieler achten hier besonders auf USB Joypads mit hohen Abtast Raten.
Es gibt Spieler die aufgrund dieser Latenz in der Emulation nicht die gleichen Resultate erreichen, wie am Original Gerät.
Die meisten Emulatoren (Gast) tasten die am PC/Mac (Host) angeschlossenen Geräte zwischen den Bildern ab. Programme prüfen in der Regel im Rahmen Bereich oder Vertical blanking, also nach dem sichtbaren Teil des Bildes, die Eingabegeräte.
Abhängig davon, wann die emulierten Programme die Eingabe prüfen, kann zwischen Host und Gast Abtastung fast ein komplettes Bild verstrichen sein. Somit ist es nicht selten, das zur natürlichen Eingabe Latenz noch ein weiteres Bild die Erkennung der Eingabe verpasst wird.
welche Techniken gibt es
- aggressives Abtasten der Eingabe in jeder Bildzeile
Es gibt tatsächlich Emulatoren, die das tun. Aus meiner Sicht ist das eine ziemliche Performance Verschwendung. Die besten USB Geräte tasten mit einer Rate von 1000Hz ab, üblich sind jedoch um die 100Hz.
- Just in Time Polling (Hiermit beginne ich.)
Bei dieser Technik tastet der Host erst ab, wenn der Gast auch tatsächlich auf die Controller zugreifen will. Auf diese Weise ist das Abtasten zwischen Host und Gast sehr dicht beieinander. Sinnvoll ist bei weiterem Abtasten des Gastes,
den Host nicht nach zu kurz verstrichener Zeit erneut abtasten zu lassen. Das würde nur Performance verschwenden aber keine Änderungen bringen. Ein weiteres Abtasten des Hostes sollte erst in frühstens 5 ms wieder erfolgen.
Auf diese Weise lässt sich schon das ein oder andere Mal die Eingabe Latenz um ein Bild senken, nicht jedoch die außerhalb des Emulators generierte Eingabe Latenz.
- Vsync abschalten
Beim Vsync blockiert die Grafikkarte die Emulation eine gewisse Zeit bis ein neues Bild eingefügt werden kann. In dieser Zeit kann die Eingabe nicht geprüft werden. Natürlich will man auf flüssiges scrolling nicht verzichten.
Beam Racing beschreibt eine Möglichkeit flüssiges scrolling ohne Vsync zu erreichen. Das ist ein Kapitel für sich und sei deswegen hier nur am Rande bemerkt.
Eine Rest Latenz bleibt jedoch auch hier zurück.
- Vsync Verhalten selber programmieren
Hierbei hat man mehr Kontrolle innerhalb der Wartezeit. Es ist jedoch nicht ganz trivial die gleiche Genauigkeit wie das automatisierte Vsync der Grafikkarte zu erreichen. WinUAE verwendet ein selbst gebautes Low Latency Vsync.
Eine Rest Latenz bleibt jedoch auch hier zurück.
- Run Ahead
diese Technik verursacht eine Zeit Verschiebung in der Emulation und ist um es vorweg zu nehmen in der Lage sämtliche Eingabe Latenz zu eliminieren. Es ist sogar möglich eine niedrigere Latenz als das Original zu erreichen.
Das hat jedoch einen hohen Preis und der lautet Performance.
Wie funktioniert das?
Als erstes muss der Emulator in der Lage sein, Spielstände zu generieren. Nehmen wir an es sollen 2 Bilder Latenz eliminiert werden. Für die Emulation eines jeden Bildes ist dann folgendes zu tun:
- taste alle Eingabe Geräte ab
- emuliere ein Bild und verwerfe Video und Audio (nicht durch den Host ausgeben lassen)
- generiere ein Spielstand im Arbeitsspeicher
- emuliere ein weiteres Bild und verwerfe ebenso Video und Audio (nicht durch den Host ausgeben lassen)
- emuliere das letzte Bild aber mit Ausgabe von Video und Audio durch den Host
- lade den zuvor gesicherten Spielstand wieder
Es werden in einem emulierten Bild somit 3 Bilder emuliert. Das erklärt warum die Performance so stark beansprucht wird.
Der Emulator läuft 2 Bilder in der Vergangenheit, das heißt die aktuelle Eingabe wird in dem Zustand des Emulators vor 2 Bildern verarbeitet. Die ersten beiden Bilder werden versteckt emuliert und erst das 3. Bild kommt zur Anzeige.
Wir sehen nun das Resultat, als hätten wir die Eingabe 2 Bilder vor dem Aktuellen getätigt. Damit simulieren wir die schnelle Verarbeitung, welche das Original Gerät nur benötigt um die Eingabe zu registrieren.
Abschließend wird der Spielstand, welcher nach dem ersten Bild gezogen wurde, wieder geladen damit der Emulator in einem Bild tatsächlich auch nur ein Bild vorankommt, ansonsten wären ja 3 Bilder vergangen.
Intern ist der Emulator also im gleichen Zustand, wie normal auch. Audio und Video Verzerrungen sind komplett ausgeschlossen. Es wird nur das Audio und Video des letzten Bildes an den Host übertragen.
Ein Bild zu eliminieren ist eine sichere Angelegenheit um bei keinem Spiel tiefer als das Original zu kommen, also die natürliche Latenz zu eliminieren. Alles darüber hinaus muss ausprobiert werden. Geht man zu tief verwirrt man die Spiellogik.
Auch bemerkt man es durch Bild (verpasst erste Sprung Animation ) oder Ton (z.B. Sprunggeräusche der Spielfigur spielen nicht von vorne)
Aus dem Grund wird die Anzahl der eliminierten Bilder am Besten über Hotkeys zur Laufzeit gesteuert.