Comprendre la conception du système vidéo de la Super Nintendo
(fabiensanglard.net)- La vidéo de la SNES a été conçue au début des années 1990 dans les limites des TV CRT et du signal NTSC, avec un écran de 256x224, une fréquence d’image de 60,098 Hz et des intervalles de blanking adaptés
- Le CRT ne fonctionne pas avec une grille de pixels, mais avec un canon à électrons, des signaux RGB et la synchronisation HSYNC/VSYNC pour tracer les lignes ; le progressif et l’entrelacé se distinguent aussi par la position des signaux de synchro
- La SNES ne pouvant pas disposer d’un oscillateur vidéo dédié, elle divise son horloge maître de 21,47727 MHz pour produire un dot clock de 5,3693175 MHz, et atteint 60,098 Hz avec une combinaison de 262 lignes et 341 dots, différente du standard NTSC à 59,94 Hz
- Le mode de base se compose, sur 262 lignes, de 224 lignes affichées et 38 lignes de VBLANK, et sur 341 dots, de 256 dots affichés et 85 dots de HBLANK, afin de laisser au PPU le temps de remplir son buffer de ligne pour les sprites
- La SNES PAL proposait, pour s’adapter à un environnement à 50 Hz et 312,5 lignes, un oscillateur différent et un mode overscan à 240 lignes, mais comme la plupart des jeux visaient 224 lignes, les bandes noires et une exécution 17 % plus lente étaient fréquentes
Là où la TV CRT imposait des limites à la conception
- La cible principale de la sortie vidéo de la SNES était la TV CRT standard, et à l’époque, les téléviseurs recevaient soit la diffusion analogique NTSC par antenne, soit une source vidéo externe via une entrée AUX
- L’entrée auxiliaire d’une TV classique se composait généralement d’une prise vidéo composite jaune et de prises audio stéréo blanche et rouge
- On peut voir un CRT comme un dispositif de tracé de lignes de classe 15 kHz, capable de dessiner environ 15 000 lignes par seconde
Le CRT fonctionne avec des lignes de balayage et des signaux, pas avec des pixels
- À l’intérieur d’un CRT se trouvent trois canons à électrons, et les électrons sont déviés vers le haut, le bas, la gauche et la droite par des aimants verticaux et horizontaux
- Les électrons eux-mêmes n’ont pas de couleur ; un masque fait en sorte que les électrons de chaque canon atteignent la bonne bande de phosphore coloré
- Un CRT n’a pas de pixels, et les fentes ne sont pas non plus des pixels
- Sur une TV haute résolution, les fentes sont plus petites, ce qui permet de reproduire plus fidèlement le même signal de couleur à l’horizontale
- Un CRT reçoit cinq signaux via quatre fils
- Les signaux Red, Green et Blue sont chacun reliés directement à un canon à électrons
- En l’absence de signal sur les trois lignes RGB, aucun électron n’est émis et l’image affichée est noire
- Le fil blanc transporte la Composite Sync (CSYNC), qui combine HSYNC et VSYNC
- Le CRT ne génère pas lui-même le VSYNC ; il reçoit les signaux de synchronisation envoyés par le système externe pour positionner les canons à électrons
Différence entre progressif et entrelacé
- Le CRT trace une ligne de gauche à droite et, lorsqu’il reçoit HSYNC, revient sur la gauche de l’écran à X=0
- Lorsqu’il reçoit VSYNC, il revient en haut de l’écran à Y=0
- Pendant que le canon se déplace vers la droite, il suit aussi une trajectoire inclinée vers le bas, de sorte que la ligne suivant un HSYNC est tracée sous la précédente
- Si le VSYNC se produit au même moment que le dernier HSYNC, on obtient un balayage progressif, où le champ est dessiné au même endroit
- Si le VSYNC se produit entre deux HSYNC, on obtient un balayage entrelacé, où les lignes du champ suivant s’insèrent entre celles du champ précédent
- L’entrelacé double la résolution verticale, mais réduit de moitié le taux de rafraîchissement de chaque ligne
- Le NTSC envoie environ 30 Hz de deux champs, donc les CRT prévoyaient l’espacement nécessaire à l’entrelacement, et en progressif on voit apparaître des intervalles noirs entre les scanlines
Spécification NTSC et limites d’une conception simplifiée
- La conception de la SNES devait rester proche des valeurs qu’une TV NTSC pouvait traiter
- Ratio d’image : 4:3
- Nombre de lignes par champ : 262,5
- Nombre de dots par ligne : 341,25
- Fréquence de champ : 59,94 Hz
- Le NTSC noir et blanc était à l’origine à 60 Hz, mais le NTSC couleur a abaissé cette fréquence de 0,1 % pour conserver la rétrocompatibilité et éviter des artéfacts lors de l’ajout de la couleur
- Une conception simplifiée pourrait choisir 262 lignes en progressif, 350 dots et 59,94 Hz, ce qui demanderait un dot clock de 5 496 498 Hz
- Mais cette conception ne correspondait pas à la SNES réelle
- À cause des contraintes de coût, il n’était pas possible d’ajouter un oscillateur dédié au système vidéo, et les sous-systèmes devaient diviser l’oscillateur maître
- Sur un CRT, le canon à électrons peut continuer à émettre pendant le retour à l’écran, ce qui impose de gérer l’overscan et le blanking
Blanking et choix de la résolution verticale
- Si le canon à électrons continue à tirer pendant la remise à zéro de sa position horizontale ou verticale, des artéfacts visibles apparaissent
- Les TV appliquent un overscan en affichant une image légèrement plus grande que l’écran, avec un niveau variable selon les modèles
- Après VSYNC et HSYNC, la position du canon tremble brièvement, donc il faut interrompre l’émission le temps d’obtenir une ligne stable
- L’intervalle d’arrêt d’émission après VSYNC est le VBLANK
- L’intervalle d’arrêt d’émission après HSYNC est le HBLANK
- Les systèmes concurrents de l’époque utilisaient eux aussi le blanking
- Capcom CPS-1 : 262 lignes, VBLANK de 38 lignes, 224 lignes affichées, 59,6294 fps
- Sega Genesis : 262 lignes, VBLANK de 38 lignes, 224 lignes affichées, 59,9227 fps
- Neo-Geo AES : 264 lignes, VBLANK de 40 lignes, 224 lignes affichées, 59,18 fps
- La SNES divise ses 262 lignes en 224 lignes affichées + 38 lignes de blanking
- 224 est divisible par 16, ce qui s’accorde bien avec un pipeline graphique basé sur des tuiles 16x16
Résolution horizontale et 60,098 Hz
- La SNES divise son horloge maître de 21,47727 MHz par 4 pour utiliser un dot clock de 5,3693175 MHz
- La fréquence d’image, le nombre de lignes, le nombre de dots par ligne et le dot clock sont liés entre eux
- En visant 59,94 Hz avec 262 lignes, on obtient environ 342 dots par ligne, mais à cause des artéfacts de porteuse sur la sortie composite, les ingénieurs de Nintendo ont dû utiliser 341 dots
- Avec cette combinaison, la fréquence d’image de la SNES devient 5,3693175 MHz / (341 * 262) = 60,098 Hz
- 60,098 Hz diffère des 59,94 Hz du NTSC, mais reste dans la plage de tolérance des CRT
Pourquoi l’écran de base est en 256x224
- Il n’est pas possible d’utiliser les 341 dots complets d’une ligne comme zone visible ; il faut un HBLANK pour masquer les tremblements, les artéfacts et l’overscan des TV
- Pour 224 lignes, une largeur d’affichage proche du 4:3 est de 224 * 4/3 = 298 dots
- Comme le pipeline tilemap utilise des tuiles 16x16, les valeurs possibles sont 304, 288, 272, 256, 240, etc.
- 304 dots est proche d’une valeur avec très peu de distorsion de l’image
- Le PPU devait aussi remplir son buffer de ligne pour les sprites pendant le HBLANK
- Avec un affichage de 304 dots, le HBLANK ne ferait que 37 dots, soit environ 7 µs
- Il est probable qu’il fallait davantage de temps pour charger les données d’au plus 128 sprites
- Le choix final a été 256 dots affichés + 85 dots de HBLANK
- Le PPU dispose ainsi d’environ 16 µs pendant le HBLANK
- Le ratio de la zone affichée n’est pas 4:3 mais 8:7, ce qui entraîne une légère distorsion une fois affiché sur un CRT
Le compromis des modes haute résolution
- La configuration vidéo de base de la SNES est une résolution overscan de 341x262, une résolution affichée de 256x224 et une fréquence d’image de 60,098 Hz
- 99 % des jeux utilisent cette configuration, mais la SNES dispose aussi de modes haute résolution qui doublent la résolution verticale ou horizontale
- Une résolution verticale de 448 lignes s’obtient en envoyant le VSYNC un demi-ligne après le dernier HSYNC, afin de produire une image entrelacée
- Dans ce cas, chaque ligne est rafraîchie à 30,049 Hz = 60,098/2
- Cela provoque du scintillement et n’est pas très agréable à regarder, mais augmente la résolution verticale
- Doubler la résolution horizontale est plus difficile faute de dot clock suffisant
- La SNES décale légèrement le second champ à l’horizontale pour que les points tombent entre ceux du champ précédent
- Le résultat est une fréquence d’image divisée par deux et un fort bavement des couleurs
- fullsnes.txt récapitule plusieurs exemples d’usage de la haute résolution dans différents titres
- Logo Nintendo de Donkey Kong Country 1 : 512x224, BgMode5
- Écran de réglages de Seiken Densetsu 2 : 512x224, BgMode5
- RPM Racing : intro et jeu en 512x448, BgMode5+Interlace
- Dans le cas de Ranma 1/2, l’image est en réalité en 256x224, mais l’entrelacé est activé par hasard, ce qui produit un scintillement inutile
PAL, SECAM et les problèmes de la SNES européenne
- Les TV européennes utilisaient PAL plutôt que NTSC, et la France utilisait aussi le SECAM
- L’environnement PAL attend précisément 50 Hz et 312,5 lignes par champ
- La SNES PAL embarque un oscillateur de 17,7344750 MHz au lieu des 21,4772700 MHz du NTSC
- La puce S-CLK applique un traitement 6/5, puis une division par 4 pour produire un dot clock de 5,32034250 MHz
- Si l’on n’utilise que des graphismes en 224 lignes, de larges bandes noires apparaissent en haut et en bas de la zone affichée
- Pour les réduire, il existait un mode overscan qui portait l’affichage à 240 lignes
- Ces 16 lignes supplémentaires correspondent à la hauteur d’une tuile
- En pratique, la plupart des titres étaient conçus pour 224 lignes et n’utilisaient presque jamais ce mode
- Au total, seuls 12 titres l’utilisent
- Super Mario World s’adapte en PAL en augmentant le champ de vision vertical
- Comme le NTSC et le PAL utilisent tous deux un ratio 4:3, l’image PAL est légèrement plus compressée verticalement que l’image NTSC
- Beaucoup de codes de jeu ne tenaient pas compte du fait que le VSYNC se produisait à 50,00697891 Hz au lieu de 60,098 Hz, si bien que les jeux s’exécutaient au final 17 % plus lentement que prévu
Signal de sortie et connecteur AV
- Les signaux RGB et de synchronisation vus plus haut sont des signaux purs pouvant piloter directement un CRT, mais la plupart des téléviseurs réels ne pouvaient pas recevoir directement ces signaux
- Beaucoup de TV n’avaient qu’une entrée composite jaune à l’arrière, et certains modèles plus haut de gamme proposaient une entrée S-Video
- La SNES convertit ses signaux destinés au CRT à la fois en composite et en S-Video
- Le connecteur AV ne jette pas ces signaux et propose plusieurs modes de sortie
- Red, Green, Blue
- C-Sync
- S-Video basé sur Luminance et Chrominance
- Composite Video
- +5V DC
- Ground
- Left Audio, Right Audio
- Les TV européennes, en particulier françaises, étaient souvent équipées d’un connecteur SCART, ce qui permettait de fabriquer des câbles envoyant le signal de manière plus directe au CRT
- Résultat : les utilisateurs européens pouvaient profiter de jeux 17 % plus lents et avec bandes noires, mais avec une fidélité d’image élevée
1 commentaires
Commentaires Hacker News
Il est probable que 224 ne soit pas un nombre choisi au hasard. Il est divisible par 16 (224/16=14), ce qui s’aligne bien avec les tilemaps du pipeline de rendu graphique
Quand j’étais enfant, je bricolais en essayant d’apprendre la programmation de jeux, et je n’ai compris ça que bien plus tard ; à ce moment-là, tout a pris sens. Les modes 320x200 étaient courants sur CGA/EGA/VGA, tandis que la NES et la SNES étaient en 256x224, ce qui tenait en pratique presque des contraintes des téléviseurs
En revanche, Pac-Man en arcade était en 288x224, donc les clones de Pac-Man sur PC n’avaient jamais l’air “correct”, et même la version NES de Pac-Man faite par Namco ne rentrait pas. Les tuiles de la carte devenaient plus petites et les personnages énormes, ou alors cela devenait un monde à défilement comme sur Game Boy/Tengen, ou bien on avait des compromis comme une déformation ou une carte non conforme à l’original ; du coup, quand on essayait de jouer à un jeu “d’arcade” à la maison, cela paraissait étrange et frustrant
Une fois que j’ai appris comment la machine était structurée et comment les sprites fonctionnaient, j’ai eu une vraie révélation en arrivant à la conclusion qu’il n’y avait finalement pas d’autre choix. Et cela devient encore plus compliqué si l’on ajoute le fait que, sur PC à cette résolution, les pixels n’étaient pas carrés
Depuis, chaque fois que je vois un portage ou un clone de Pac-Man, je regarde immédiatement la taille du monde, la taille des tuiles et la taille des sprites
Cela dit, cet overscan variait selon les téléviseurs, et les TV modernes ou les émulateurs affichent en général l’ensemble des 240 lignes
La résolution verticale de la SNES pouvait être configurée sur 224 ou 240 lignes, comme l’indique l’article. La plupart des jeux utilisaient 224 lignes, car cela allongeait le temps de blanking vertical et laissait plus de temps pour transférer les graphismes vers le PPU
L’article de Rodrigo Copetti sur l’architecture de la SNES vaut aussi le détour : https://www.copetti.org/writings/consoles/super-nintendo/
59.94Hz est certes un nombre étrange, mais à ma connaissance il n’existe pas de réseau électrique à 30Hz. L’Amérique du Nord, où le NTSC a été conçu, ainsi que quelques autres régions, utilisent un réseau à 60Hz
https://en.wikipedia.org/wiki/Mains_electricity_by_country
La fréquence la plus élevée générée dans un téléviseur noir et blanc était la fréquence de balayage horizontal, qui était un multiple de la fréquence d’image. Avec l’ajout du signal couleur NTSC utilisant une sous-porteuse de 3.579545MHz, la fréquence la plus élevée à l’intérieur du téléviseur est devenue bien plus élevée ; pour garder un matériel simple, les fréquences plus basses continuaient d’être calées comme des sous-multiples de cette fréquence maximale, c’est-à-dire de la sous-porteuse couleur. Résultat : la cadence est devenue de 59.94 champs par seconde
Le passage sur le fait que, dans les régions PAL, les jeux non adaptés au VSYNC à 50.00697891Hz tournaient 17 % plus lentement que la référence 60.098Hz me parle énormément
Ce n’est pas propre à la Super Nintendo, mais ça me rappelle la première fois où j’ai vu ou joué à Sonic the Hedgehog sur Mega Drive (Genesis). Comparé à la version Master System, ça paraissait plus mou et plus lent, donc ça ne m’avait pas particulièrement impressionné. Ce n’est qu’avec l’essor de YouTube que j’ai compris à quel point la différence de vitesse entre NTSC et PAL était énorme. Pas seulement pour la vitesse du jeu, la musique sonnait aussi atrocement en PAL
À l’époque 16 bits, je savais déjà ce qu’étaient le PAL et la nécessité des « boîtes noires », mais je ne pensais pas que l’écart était à ce point. Les magazines sur consoles de l’époque disaient en général que la différence était faible dans la plupart des jeux, même si, exception notable, la version SNES de DooM avait une image plus grande en NTSC
Quand j’étais enfant, j’étais assez bon à Punch-Out sur NES pour battre Mr. Dream ou Mike Tyson au 1er round, mais en y repensant, je jouais à la version PAL. Si j’avais participé à une compétition aux États-Unis, je me serais fait pulvériser dès le premier round et j’aurais sûrement été persuadé qu’on m’avait tendu un piège
Par exemple, avec un framerate plus bas, Samus et les projectiles parcourent plus de pixels par frame, donc il devient plus facile de traverser des objets, ce qui rend ce gate glitch possible uniquement en PAL : https://www.youtube.com/watch?v=RvyIwtO_qgM
Les constantes physiques de Samus et le timing de ses animations ont été ajustés au nouveau framerate, mais pas les ennemis, cinématiques et autres éléments de l’environnement. Résultat, en PAL, Samus se déplace à la même vitesse qu’en NTSC, mais le reste du monde bouge plus lentement. Cela permet de ramasser les Bombs et de quitter la salle juste avant que la porte ne se verrouille, ce qui permet de sauter le mini-boss : https://www.youtube.com/watch?v=R3t8TIIj7IM
Sur la version NTSC, faire le même skip demande une préparation complexe et des dizaines d’inputs frame-perfect d’affilée, et une seule personne y est arrivée à ce jour : https://www.youtube.com/watch?v=jcKUMk5g8Wk
Il existe aussi une comparaison des tool-assisted speedruns les plus courts entre NTSC (à gauche) et PAL (à droite) : https://www.youtube.com/watch?v=KD_-thqcB5s Les deux runs utilisent pratiquement le même parcours jusqu’à la toute fin, et la version NTSC est plus rapide dans presque toutes les salles, mais la préparation de l’exécution de code arbitraire est complètement différente, si bien que la version PAL termine au final en premier. Le run NTSC doit effectuer une très lente séquence de pause/reprise pour traverser une porte sans l’activer, sortir des limites et provoquer une corruption mémoire. La version PAL, elle, peut atteindre l’exécution de code arbitraire entièrement à l’écran en exploitant une race condition du système d’animation du jeu. Il s’agit d’une course entre le timer de recul des piques et l’animation d’atterrissage de Samus ; comme seul le timing de Samus a été ajusté pour le PAL et pas celui des piques, cela crée en PAL un timing exploitable uniquement dans ce contexte
Avec l’arrivée de la Dreamcast, c’est la première fois qu’il y a eu des jeux permettant de basculer entre 50Hz et 60Hz, à condition que le téléviseur le supporte. Et dans les jeux qui ne prenaient pas correctement en compte cette différence, on pouvait aussi repasser en 50Hz pour les rendre plus faciles ; dans mon souvenir, Crazy Taxi était nettement plus facile en 50Hz
Ça paraît étrange qu’on ait pu vendre tel quel des jeux aussi différents, mais je comprends parfaitement pourquoi ce choix a été fait. Enfant, je tenais pour acquis que Mario était Mario partout, et Sonic aussi
Je me demande si ces différences ont pris fin à l’époque des consoles 3D. À partir de là, le rendu et la logique du jeu n’étaient en général plus totalement couplés
Il semble y avoir une coquille dans l’article d’origine. Le format d’image est indiqué comme 8:6, mais c’est équivalent à 4:3, et d’après le calcul c’est bien 8:7
Il semble manquer le passage expliquant que le 8:7 en résolution de sortie de 256x224 s’étire jusqu’à environ du 4:3, plus précisément une image en 64:49
La fréquence de points du SNES est d’environ 5.37MHz, plus lente que la fréquence de pixels carrés d’environ 6.13MHz définie par la norme ATSC. Elle est exactement plus lente d’un facteur 8/7, donc les pixels sont étirés horizontalement de 8/7, et une résolution 8:7 est donc étirée de (8/7)(8/7)=64/49, ce qui la rapproche de 64:48=4:3
Le calcul disant qu’« il faut 298 points visibles, puisque 224(4/3)=298, pour obtenir un format proche du 4:3 » doit, en tenant compte du facteur ci-dessus, utiliser un coefficient de (4/3)/(8/7)=7/6. On obtient alors 224*(7/6)=261.33... points visibles nécessaires, ce qui est bien plus proche des 256 réellement retenus
Moi, j’utilisais la sortie RF avec un boîtier de commutation pour basculer entre la SNES et l’antenne TV
Plus tard, devenu ingénieur vidéo, j’ai pu en rire, mais heureusement que l’enfant que j’étais ne se rendait pas compte à quel point cette image était atroce
Le ratio d’affichage 8:7 de l’illustration se retrouve aussi dans d’autres portages sur plateformes de SFC/SNES, comme ROCKMANX3 / Mega Man X3
Les versions PSX/Saturn/PC ont conservé l’illustration d’origine sans l’étirer, mais ont ajouté des marges verticales adaptées aux stages pour faire correspondre le 8:7 au 4:3. Quand on est habitué à la version originale, c’est assez gênant en jouant, et les captures d’écran de la version Saturn montrent bien que tout paraît légèrement trop étroit : https://segaretro.org/Mega_Man_X3
Je me demande combien de temps Fabien met pour écrire des articles comme celui-ci. Il y a énormément de détails et c’est très bien structuré
Je me demande quelle part des résolutions du SNES est fixée par le matériel de la console, et quelle part relève de ce que la cartouche peut piloter
Par exemple, avec une cartouche dotée de son propre coprocesseur, qui n’aurait donc pas besoin de charger des sprites, et disposant aussi de son propre clock onboard, serait-il théoriquement possible d’afficher plus de 256 pixels horizontaux par ligne ?
Un coprocesseur peut rendre ses propres frames et les placer à l’emplacement mémoire où les tuiles de la ligne suivante seront lues. Il me semble que c’est à peu près ce que faisait le SuperFX
Mais au final, c’est bien le PPU qui dessine réellement les pixels et gère le nombre de couleurs, etc., donc au bout du compte on reste limité par les contraintes du PPU