Ich habe ein paar alte Programme, die ich auf einem Windows-Computer aus den frühen 90er Jahren erstellt und versucht habe, sie auf einem relativ modernen Computer auszuführen. Interessanterweise liefen sie mit einer blitzschnellen Geschwindigkeit - nein, nicht die 60 Bilder pro Sekunde, sondern die Art von "Oh mein Gott, der Charakter geht mit der Geschwindigkeit des Klangs" schnell. Ich drückte eine Pfeiltaste und das Sprite des Charakters bewegte sich viel schneller als normal über den Bildschirm. Der Zeitverlauf im Spiel verlief viel schneller als es sollte. Es gibt sogar Programme, die Ihre CPU verlangsamen, damit diese Spiele tatsächlich spielbar sind.
Ich habe gehört, dass dies abhängig von den CPU-Zyklen mit dem Spiel zusammenhängt oder so ähnlich. Meine Fragen sind:
- Warum machen ältere Spiele das und wie sind sie damit durchgekommen?
- Wie machen neuere Spiele das nicht und laufen unabhängig von der CPU-Frequenz?
FOR F IN 0 TO 1000; NEXT F;
Antworten:
Ich glaube, sie gingen davon aus, dass die Systemuhr mit einer bestimmten Rate laufen würde, und banden ihre internen Timer an diese Taktrate an. Die meisten dieser Spiele liefen wahrscheinlich unter DOS und waren im Real-Modus (mit vollständigem, direktem Hardware-Zugriff) und gingen davon aus, dass Sie ein iirc 4,77 MHz-System für PCs und einen beliebigen Standardprozessor verwenden, den dieses Modell für andere Systeme wie den Amiga ausführte .
Sie nahmen auch clevere Verknüpfungen, die auf diesen Annahmen basierten, einschließlich der Einsparung eines winzigen Teils der Ressourcen, indem sie keine internen Timing-Schleifen innerhalb des Programms schrieben. Sie nahmen auch so viel Prozessorleistung auf, wie sie konnten - was zu Zeiten langsamer, oft passiv gekühlter Chips eine anständige Idee war!
Anfänglich war ein Weg, um die unterschiedliche Prozessorgeschwindigkeit zu umgehen, der gute alte Turbo-Knopf (der Ihr System verlangsamte). Moderne Anwendungen sind im geschützten Modus und das Betriebssystem dazu tendiert Ressourcen zu verwalten - sie würde nicht erlauben , eine DOS - Anwendung (die auf einem 32-Bit - System ohnehin in NTVDM ausgeführt wird ) , die alle den Prozessor in vielen Fällen aufbrauchen. Kurz gesagt, Betriebssysteme und APIs sind schlauer geworden.
Dieses Handbuch basiert stark auf Oldskool-PCs, bei denen Logik und Speicher versagten. Es ist eine großartige Lektüre und geht wahrscheinlich eingehender auf das "Warum" ein.
Sachen wie CPUkiller verbrauchen so viele Ressourcen wie möglich, um Ihr System zu "verlangsamen", was ineffizient ist. Sie sollten DOSBox verwenden , um die für Ihre Anwendung festgelegte Taktrate zu verwalten.
quelle
game loop
. Grundsätzlich gibt es 2 Methoden. 1) Laufen Sie so schnell wie möglich und skalieren Sie die Bewegungsgeschwindigkeiten usw. basierend darauf, wie schnell das Spiel läuft. 2) Wenn Sie zu schnell sind, warten Sie (sleep()
), bis wir für das nächste 'Häkchen' bereit sind.Als Ergänzung zu Journeyman Geeks Antwort (weil meine Bearbeitung abgelehnt wurde) für die Leute, die sich für den Codierungsteil / die Entwicklerperspektive interessieren:
Aus Sicht der Programmierer waren die DOS-Zeiten für diejenigen, die interessiert sind, Zeiten, in denen jeder CPU-Tick wichtig war, damit die Programmierer den Code so schnell wie möglich hielten.
Ein typisches Szenario, in dem ein Programm mit maximaler CPU-Geschwindigkeit ausgeführt wird, ist das folgende einfache Szenario (Pseudo-C):
das wird für immer laufen, jetzt wollen wir dieses Code-Snippet in ein Pseudo-DOS-Spiel verwandeln:
Sofern die
DrawGameOnScreen
Funktionen nicht Double Buffering / V-Sync verwenden (was in den Tagen, in denen DOS-Spiele erstellt wurden, ziemlich teuer war), wird das Spiel mit maximaler CPU-Geschwindigkeit ausgeführt. Auf einem modernen mobilen i7 würde dies mit einer Geschwindigkeit von 1.000.000 bis 5.000.000 Mal pro Sekunde (abhängig von der Laptop-Konfiguration und der aktuellen CPU-Auslastung) ausgeführt.Dies würde bedeuten, dass, wenn ich ein DOS-Spiel auf meiner modernen CPU in meinen 64-Bit-Fenstern zum Laufen bringen könnte, ich mehr als tausend (1000!) FPS bekommen könnte, was für jeden Menschen zu schnell ist, wenn die physikalische Verarbeitung davon ausgeht, dass es läuft zwischen 50-60 fps.
Was Entwickler heute tun können, ist:
*** Abhängig von der Konfiguration der Grafikkarte / des Treibers / des Betriebssystems ist dies möglicherweise möglich.
Für Punkt 1 gibt es kein Beispiel, das ich zeigen werde, weil es eigentlich keine "Programmierung" ist. Es werden nur die Grafikfunktionen verwendet.
Zu Punkt 2 und 3 zeige ich die entsprechenden Codefragmente und Erläuterungen:
2:
Hier können Sie sehen, dass die Benutzereingaben und die Physik den Zeitunterschied berücksichtigen. Sie können jedoch immer noch über 1000 FPS auf dem Bildschirm anzeigen, da die Schleife so schnell wie möglich ausgeführt wird. Da die Physik-Engine weiß, wie viel Zeit vergangen ist, muss sie nicht auf "keine Annahmen" oder "eine bestimmte Framerate" angewiesen sein, damit das Spiel auf jeder CPU mit der gleichen Geschwindigkeit funktioniert.
3:
Was Entwickler tun können, um die Framerate auf beispielsweise 30 FPS zu begrenzen, ist eigentlich nichts Schwierigeres.
Was hier passiert, ist, dass das Programm zählt, wie viele Millisekunden vergangen sind. Wenn eine bestimmte Zeitspanne (33 ms) erreicht ist, wird der Spielbildschirm neu gezeichnet und eine Bildrate von ungefähr 30 angewendet.
Abhängig vom Entwickler kann er die ALL-Verarbeitung auf 30 fps beschränken, wobei der obige Code geringfügig geändert wird:
Es gibt ein paar andere Methoden, und einige davon hasse ich wirklich.
Zum Beispiel mit
sleep(<amount of milliseconds>)
.Ich weiß, dass dies eine Methode ist, um die Framerate zu begrenzen, aber was passiert, wenn Ihre Spielverarbeitung 3 Millisekunden oder mehr dauert? Und dann führen Sie den Schlaf aus ...
Dies führt zu einer niedrigeren Bildrate als diejenige, die nur
sleep()
verursacht werden sollte.Nehmen wir zum Beispiel eine Ruhezeit von 16 ms. Dies würde das Programm auf 60 Hz laufen lassen. Jetzt dauert die Verarbeitung der Daten, der Eingaben, des Zeichnens und des gesamten Materials 5 Millisekunden. Wir sind jetzt bei 21 Millisekunden für eine Schleife, was etwas weniger als 50 Hz ergibt, während Sie leicht noch bei 60 Hz sein könnten, aber wegen des Schlafes ist es unmöglich.
Eine Lösung wäre, einen adaptiven Schlaf in Form der Messung der Verarbeitungszeit und Abzug der Verarbeitungszeit von dem gewünschten Schlaf zu machen, was zur Behebung unseres "Fehlers" führt:
quelle
Eine Hauptursache ist die Verwendung einer Verzögerungsschleife, die beim Programmstart kalibriert wird. Sie zählen, wie oft eine Schleife in einer bekannten Zeit ausgeführt wird, und teilen sie, um kleinere Verzögerungen zu erzeugen. Dies kann dann verwendet werden, um eine sleep () - Funktion zu implementieren, um die Ausführung des Spiels zu beschleunigen. Die Probleme treten auf, wenn dieser Zähler voll ist, weil die Prozessoren in der Schleife so viel schneller sind, dass die kleine Verzögerung viel zu klein wird. Außerdem ändern moderne Prozessoren die Geschwindigkeit abhängig von der Last, manchmal sogar pro Kern, wodurch die Verzögerung noch größer wird.
Für wirklich alte PC-Spiele liefen sie so schnell sie konnten, ohne zu versuchen, das Spiel zu beschleunigen. Dies war in den Tagen von IBM PC XT jedoch eher der Fall, als eine Turbotaste existierte, die das System aus diesem Grund verlangsamte, um mit einem 4,77 MHz-Prozessor übereinzustimmen.
Moderne Spiele und Bibliotheken wie DirectX haben Zugriff auf Zeitgeber mit hoher Präzision, sodass keine kalibrierten, auf Code basierenden Verzögerungsschleifen verwendet werden müssen.
quelle
Alle ersten PCs liefen zu Beginn mit der gleichen Geschwindigkeit, sodass Geschwindigkeitsunterschiede nicht berücksichtigt werden mussten.
Außerdem hatten viele Spiele zu Beginn eine ziemlich feste CPU-Auslastung, so dass es unwahrscheinlich war, dass einige Frames schneller als andere liefen.
Heutzutage können Sie mit Ihren Kindern und Ihren FPS-Schützen in einer Sekunde auf den Boden schauen und in der nächsten auf den Grand Canyon. Lastschwankungen treten häufiger auf. :)
(Und nur wenige Hardware-Konsolen sind schnell genug, um Spiele konstant mit 60 fps auszuführen. Dies liegt hauptsächlich daran, dass Konsolenentwickler 30 Hz wählen und die Pixel doppelt so glänzend machen ...)
quelle