J'ai installé quelques anciens programmes sur un ordinateur Windows du début des années 90 et essayé de les exécuter sur un ordinateur relativement moderne. Chose intéressante, ils ont fonctionné à une vitesse fulgurante - non, pas avec la vitesse rapide de 60 images par seconde, mais plutôt avec le genre de personnage oh-mon-dieu-le-personnage-marche-à-la-vitesse du son vite. J'appuyais sur une flèche et le sprite du personnage glissait beaucoup plus rapidement que d'habitude sur l'écran. La progression temporelle dans le jeu se passait beaucoup plus rapidement que prévu. Il existe même des programmes conçus pour ralentir votre processeur afin que ces jeux soient réellement jouables.
J'ai entendu dire que cela est lié au jeu en fonction des cycles du processeur, ou quelque chose comme ça. Mes questions sont:
- Pourquoi les jeux plus anciens font-ils cela et comment s'en sont-ils sortis?
- Comment les jeux plus récents ne le font-ils pas et ne fonctionnent-ils pas indépendamment de la fréquence du processeur?
FOR F IN 0 TO 1000; NEXT F;
Réponses:
Je crois qu'ils ont supposé que l'horloge du système fonctionnerait à un taux spécifique et que leurs minuteries internes seraient liées à cette fréquence. La plupart de ces jeux fonctionnaient probablement sous DOS et étaient en mode réel (avec un accès matériel complet et direct) et supposaient que vous utilisiez un système iirc 4.77 MHz pour les PC et quel que soit le processeur standard utilisé par ce modèle pour d'autres systèmes comme Amiga.
Ils ont également utilisé des raccourcis astucieux basés sur ces hypothèses, notamment une économie de ressources en évitant l'écriture de boucles de synchronisation internes dans le programme. Ils ont également utilisé autant de puissance de processeur que possible - ce qui était une idée décente à l'époque des puces lentes, souvent refroidies passivement!
Le bon vieux bouton Turbo (qui ralentissait votre système) était initialement un moyen de contourner la vitesse du processeur . Les applications modernes sont en mode protégé et le système d'exploitation a tendance à gérer les ressources - elles ne permettraient pas à une application DOS (qui s'exécute sous NTVDM sur un système 32 bits de toute façon) d'utiliser tous les processeurs dans de nombreux cas. En bref, les systèmes d’exploitation sont devenus plus intelligents, tout comme les API.
Fortement inspiré de ce guide sur Oldskool PC où la logique et la mémoire me manquaient - c’est une excellente lecture, qui approfondit probablement le «pourquoi».
Des choses comme CPUkiller utilisent autant de ressources que possible pour "ralentir" votre système, ce qui est inefficace. Vous feriez mieux d'utiliser DOSBox pour gérer la vitesse d'horloge de votre application.
la source
game loop
. Il existe essentiellement 2 méthodes. 1) Courez aussi vite que possible et ajustez les vitesses de déplacement, etc. en fonction de la rapidité du jeu. 2) Si vous êtes trop rapide, attendez (sleep()
) jusqu'à ce que nous soyons prêts pour la prochaine "tick".En complément de la réponse de Journeyman Geek (parce que mon édition a été rejetée) pour les personnes intéressées par le point de vue du codage / développeur:
Du point de vue des programmeurs, pour ceux qui sont intéressés, les temps de DOS étaient des moments où chaque tick du processeur était important, les programmeurs gardaient donc le code le plus rapidement possible.
Un scénario typique dans lequel n'importe quel programme s'exécutera à la vitesse maximale de la CPU est simple (pseudo C):
cela fonctionnera pour toujours, transformons cet extrait de code en un pseudo-jeu-DOS:
À moins que les
DrawGameOnScreen
fonctions n'utilisent la double mise en tampon / synchronisation V (ce qui était assez cher à l'époque des jeux DOS), le jeu tournera à la vitesse maximale du processeur. Sur un mobile i7 moderne, cette vitesse serait environ 1 000 000 à 5 000 000 fois par seconde (en fonction de la configuration de l'ordinateur portable et de l'utilisation actuelle du processeur).Cela signifierait que si je pouvais faire jouer n'importe quel jeu DOS sur mon processeur moderne dans mes fenêtres 64 bits, je pourrais avoir plus de mille (1 000!) FPS, ce qui est trop rapide pour qu'un humain puisse jouer si le traitement physique "suppose" qu'il s'exécute. entre 50-60 fps.
Ce que les développeurs du jour actuel (peuvent) font est:
*** En fonction de la configuration de la carte graphique / du pilote / du système d'exploitation, cela peut être possible.
Pour le point 1, je ne montrerai aucun exemple car ce n’est pas vraiment une "programmation". C'est juste en utilisant les fonctionnalités graphiques.
En ce qui concerne les points 2 et 3, je montrerai les extraits de code et les explications correspondants:
2:
Ici, vous pouvez voir que les entrées utilisateur et la physique tiennent compte de la différence de temps, mais vous pouvez toujours obtenir plus de 1000 FPS à l'écran car la boucle est aussi rapide que possible. Parce que le moteur physique sait combien de temps a passé, il ne doit pas dépendre "d'aucune hypothèse" ou "d'un certain nombre d'images par seconde", de sorte que le jeu fonctionnera à la même vitesse sur n'importe quel processeur.
3:
Ce que les développeurs peuvent faire pour limiter le nombre d’images par exemple à 30 images par seconde n’est en réalité rien de plus difficile, jetez-y un coup d’œil:
Ce qui se passe ici, c’est que le programme compte le nombre de millisecondes écoulées. Si une certaine quantité est atteinte (33 ms), il redessine l’écran de jeu en appliquant effectivement une cadence proche de ~ 30.
En outre, en fonction du développeur, il / elle peut choisir de limiter le traitement TOUT à 30 ips avec le code ci-dessus légèrement modifié:
Il existe quelques autres méthodes, et certaines que je déteste vraiment.
Par exemple, en utilisant
sleep(<amount of milliseconds>)
.Je sais que cette méthode permet de limiter le nombre d'images par seconde, mais que se passe-t-il lorsque le traitement de votre jeu prend 3 millisecondes ou plus? Et puis vous exécutez le sommeil ...
Cela se traduira par une fréquence d'images inférieure à celle qui
sleep()
devrait être la seule cause.Prenons par exemple un temps de sommeil de 16 ms. cela ferait fonctionner le programme à 60 hz. maintenant, le traitement des données, la saisie, le dessin et tout le reste prend 5 millisecondes. nous sommes à 21 millisecondes pour une boucle, ce qui donne un peu moins de 50 hz, alors que vous pourriez facilement être à 60 hz, mais à cause du sommeil, c’est impossible.
Une solution serait de créer un sommeil adaptatif en mesurant le temps de traitement et en déduisant le temps de traitement du sommeil souhaité, ce qui résoudrait notre "bogue":
la source
L'une des principales causes est l'utilisation d'une boucle à retard calibrée au démarrage du programme. Ils comptent le nombre de fois qu'une boucle est exécutée dans un laps de temps connu et la divisent pour générer des retards plus courts. Ceci peut ensuite être utilisé pour implémenter une fonction sleep () afin de stimuler l'exécution du jeu. Les problèmes surviennent lorsque ce compteur atteint son maximum, car les processeurs sont tellement plus rapides sur la boucle que le petit retard finit par être beaucoup trop petit. De plus, les processeurs modernes changent de vitesse en fonction de la charge, parfois même par cœur, ce qui réduit encore plus le délai.
Pour de très vieux jeux sur PC, ils ont juste couru aussi vite qu'ils le pouvaient, sans se soucier d'essayer de rythme le jeu. C'était plus le cas à l'époque d'IBM PC XT, mais il existait un bouton turbo qui ralentissait le système afin qu'il corresponde à un processeur de 4,77 MHz pour cette raison.
Les jeux modernes et les bibliothèques telles que DirectX ont accès à des temporisateurs à précession élevée, vous n'avez donc pas besoin d'utiliser des boucles de retard basées sur du code calibré.
la source
Tous les premiers PC fonctionnaient à la même vitesse au début, il n'était donc pas nécessaire de prendre en compte la différence de vitesse.
En outre, de nombreux jeux au début avaient une charge de processeur assez fixe, il était donc peu probable que certaines images s'exécutent plus rapidement que d'autres.
De nos jours, avec vos enfants et vos tireurs FPS sophistiqués, vous pouvez regarder le sol une seconde, et dans le grand canyon la suivante, la variation de charge se produit plus souvent. :)
(Et, peu de consoles de matériel sont assez rapides pour faire fonctionner des jeux à 60 ips en permanence. Cela est principalement dû au fait que les développeurs de consoles optent pour 30 Hz et rendent les pixels deux fois plus brillants ...)
la source