Guide de la traduction v2

De T.R.A.F - Wiki
Aller à : navigation, rechercher

Edito

Le Guide de la Traduction fut créé en 1997 alors que Wild Ham, fondateur de la T.R.A.F. (Traduction de ROMs Anglais/Français), désirait enseigner sa passion au plus grand nombre et ainsi faire naître des vocations. Il y parvint, et de fort belle manière.

Ce Guide était destiné à faire comprendre la manière dont on traduisait des jeux vidéo sortis sur consoles (nostalgie oblige, il s'agissait des 8 bits puis des 16 bits). Avec le temps, jusqu'au début des années 2000, le Guide s'enrichit de divers documents écrits par des passionnés et des gens désireux de partager leur savoir en apportant leur pierre à l'édifice. Le résultat fut plutôt brillant, quoiqu'un peu fouillis, et profitable au plus grand nombre.

Qu'en est-il 10 ans plus tard ? Le Guide est toujours un incontournable mais ses articles n'ont jamais été retouchés alors qu'ils furent écrits à l'époque des balbutiements, les outils qu'il propose sont quasiment tous faits pour DOS, ce qui génère aujourd'hui des problèmes de compatibilité et de compréhension, et certaines nouvelles techniques sont apparues. A l'heure où la scène vieillit et où elle peine à trouver du sang neuf et des gens motivés, il nous semblait donc important, à nous, nouveaux gardiens de la T.R.A.F., de réécrire un document en nous appuyant sur ce qui a déjà été fait afin de vous présenter un guide plus clair, plus complet et plus simple d'accès.

Mais entrons dans le vif du sujet, voulez-vous ?

Comment traduit-on ?

Eh oui, il s'agit là d'une excellente question ! La plupart d'entre vous peuvent s'imaginer (de manière tout à fait légitime) que les jeux vidéo contiennent des fichiers de textes qu'il suffit de traduire. Si seulement tout était aussi simple... En réalité, il n'en est rien. Pour traduire des "jeux vidéo consoles", il faut commencer par ROMhacker. Et même si des fichiers textes étaient présents sous une forme ou une autre à l'intérieur d'un jeu vidéo, il faudrait de toute façon... ROMhacker. Mais quel est le but de cette opération ?

ROMhacker, c'est, comme son nom l'indique, hacker une image de ROM. ROM ? Cela veut dire "Read Only Memory" ("Mémoire qui ne peut être que lue"). En gros, il peut s'agir d'un circuit électronique ou de données sur un CD : les données ne peuvent être que lues. L'image d'une ROM, c'est donc la transcription informatique de cette "Mémoire qui ne peut être que lue". En ayant accès à cette image, on va pouvoir la modifier. Par abus de langage, on assimile souvent "ROM" et "image de ROM".

D'ailleurs, puisqu'il est question d'informatique, je vous conseille vivement de vous familiariser avec les systèmes binaire et hexadécimal. Vous trouverez quelques informations à ce sujet en annexe.

Bref, une fois ce fichier numérique en main, cette "image de ROM", vous pourrez le modifier en essayant de trifouiller le code binaire. C'est ce que l'on appelle "ROMhacker". Par extension, on utilisera parfois le terme ISOhacker lorsqu'il s'agit de hacker des images de CD : des ISOs. Pour éviter des questions subsidiaires, "traduire une ROM" c'est : "hacker l'image de la ROM" et, plus particulièrement, "traduire les textes extraits de cette image de ROM"

Les outils dédiés au ROMHacking

Parmi le florilège d'outils créés depuis les balbutiements de la traduction jusqu'à aujourd'hui, il nous faut déblayer le terrain pour vous donner ces types d'outils nécessaires à la traduction de ROMs. Si des termes barbares vous intriguent, rendez-vous dans les annexes pour comprendre un peu mieux de quoi on veut parler.

Les catégories d'outils nécessaires

Rappelons-nous que nous sommes de pauvres débutants qui ne savons pas programmer, même si nous possédons de vagues connaissances dans le domaine de la programmation ou du fonctionnement d'un ordinateur. Voici donc les catégories d'outils qui nous semblent nécessaires pour ROMhacker.

  • Les éditeurs hexadécimaux ou éditeurs de textes

Comme nous l'avons dit plus haut, les fichiers sont au format binaire. En réalité, au lieu d'être en base 2 (0 ou 1), on visualisera les fichiers en base 16 (0 1 2 3 4 5 6 7 8 9 A B C D E et F). Pour ceux qui ne seraient pas familiers avec ces notions mathématiques, je vous conseille d'aller faire un tour dans les annexes à propos du système hexadécimal.

Les éditeurs de textes/hexadécimaux sont là pour visualiser le code hexadécimal du fichier source et, le cas échéant, le modifier. Ils peuvent être encore plus complets et vous permettre d'extraire des textes et de les réinsérer une fois modifiés. Nous aborderons ces thèmes un peu plus loin.

  • Les extracteurs/inséreurs de textes

Ils vous permettent d'extraire les textes et de les réinsérer. Vous imaginez bien, en effet, que si les textes se trouvent au sein de la ROM, il va falloir aller les chercher puis les retranscrire sur un fichier modifiable dans un format compréhensible : c'est à cela que servent ces outils. Leur niveau de sophistication peut également leur permettre d'extraire/d'insérer le texte tout en tenant compte des "pointeurs" (ce sont des octets permettant d'indiquer au programme où le texte se situe : ils "pointent"), de vérifier la taille du texte inséré et bien d'autres choses encore.

  • Les éditeurs graphiques

Ils permettent tout simplement d'éditer les graphismes d'une ROM suivant différents formats. Certains peuvent être dédiés à des consoles comme TIM Viewer pour la PlayStation (et son format TIM) ou N64 GFX, spécialement dédié à la Nintendo 64.

  • Les outils de recherche

Les plus utilisés sont les outils de recherche relative. Ils vous permettent alors de rechercher le texte dans une ROM (car il n'est bien évidemment pas toujours placé au même endroit). Pourquoi "relatif" ? Parce qu'une lettre n'a jamais la même valeur hexadécimale. Si, dans le système ASCII, le A vaut $41 en hexadécimal, il n'en est pas nécessairement de même dans la plupart des ROMs. L'outil de recherche relative va en plus vous indiquer la valeur du A afin que vous en déduisiez celle des autres lettres.

Il existe d'autres outils de recherche à utiliser, lorsque le texte est compressé par exemple, mais nous y reviendrons plus tard.

  • Les outils de patching

Ces outils permettent de créer ou d'appliquer des patchs de traduction. Un patch est un fichier qui, appliqué à un autre, permet d'en modifier le contenu. En effet, une fois votre travail terminé, plutôt que de redistribuer la ROM modifiée (voire l'ISO, beaucoup plus volumineuse), vous redistribuerez seulement le patch qui va permettre d'effectuer les changements nécessaires à la ROM afin de la traduire. Cela prend bien évidemment moins de place à télécharger et à stocker.

Ainsi, vous créez un patch à partir de votre ROM modifiée et l'heureux quidam qui voudra utiliser votre travail n'aura plus qu'à l'appliquer sur la ROM d'origine, sur laquelle vous avez travaillé. Il y a donc un outil "développeur" et un outil "utilisateur" de patching. Certains outils font les deux (ce qui est plus pratique).

  • Outils de création de tables

Comme dit précédemment, à chaque lettre est associé un nombre hexadécimal. Une fois que vous connaissez ces associations, il vous faut créer une table de caractères qui reflétera ces "équivalences" de manière à ce qu'elles puissent être lues par votre éditeur hexadécimal et que le texte puisse, Ô joie, vous apparaître dans toute sa magnificence à la place du code barbare peu accessible à l'intellect humain. Si vous pouvez en théorie la faire à la main, il existe des outils qui vous permettent de les créer plus rapidement et plus simplement.

  • Émulateurs munis d'un debugger"

Certains émulateurs sont équipés d'applications permettant de savoir ce qui se passe dans le jeu, notamment les accès mémoire. Ces outils sont appelés "debuggers" et se déclinent en différentes catégories. Les débutants n'utiliseront bien souvent que la visualisation de la mémoire graphique. Les programmeurs confirmés feront également usage des fonctions de traçage du code assembleur qui leur permet de savoir ce qu'il se passe à la milliseconde près (voire bien davantage avec les machines récentes) dans la programmation du jeu.

  • Les autres outils

En tant que débutants, vous n'aurez pas besoin, dans un premier temps, d'autres outils. Tous ceux qui viennent d'être cités sont largement suffisants pour traduire n'importe quel jeu qui n'est pas sous l'emprise d'une méchante compression qui brouille absolument toutes les pistes.

Les ROMhackeurs confirmés codent en général leurs propres outils pour extraire et réinsérer les textes du jeu. Ils sont doués en programmation et ont un niveau d'abstraction assez élevé qui leur permette de comprendre comment un jeu a été compressé, quel type de schéma a été utilisé, comment reproduire ce schéma, etc.

Nous ne sommes que d'humbles ROMhackeurs qui désirons débuter alors commençons par nous familiariser avec les principes de base avant de nous attaquer à d'autres choses plus ardues.

Munissez-vous de l'un ou l'autre de ces logiciels dans chacune des catégories que je viens de citer (je ne parle uniquement QUE des utilitaires GRATUITS développés par des amateurs désireux de partager leur travail avec le plus grand nombre). Utilisateurs de Linux ou de Mac, certains outils sont disponibles sur la T.R.A.F. mais se trouvent en nombre relativement réduits. Néanmoins, vous devriez trouver votre bonheur.

Les outils conseillés

Voici une liste restreinte d'outils par catégorie que nous conseillons volontiers aux débutants.

  • Éditeurs de texte : Translhextion, Hexecute, WindHex32
  • Extracteurs de texte : Hareng-Tool, Pointer Tables
  • Éditeurs graphique : Tile Layer Pro, Tile Molester, YY-CHR
  • Outils de recherche : SearchR 3, SearchR X
  • Outils de patching : IPS XP, Lunar IPS, UIPS, Ninja, xdelta
  • Outils de création de tables : Table Auto Generator, Table Manager
  • Émulateurs munis d'un debugger : FCEUXD SP (NES), SNES 9X Geiger (Super NES) Gens Tracer (Mega Drive), etc.

Les principes étudiés dans ce document sont valables pour n'importe quel outil qui se respecte. Cependant, il sera plus facile d'apprendre en vous familiarisant avec des outils que nous utilisons fréquemment.

Note importante avant de commencer

Nous partirons du principe que la ROM que vous allez hacker N'EST PAS COMPRESSÉE, c'est-à-dire que les données sont entièrement visibles : une compression permet en effet de réduire la taille des données, ce qui modifie plus ou moins en profondeur la forme de départ de ces dernières (c'est comme si vous chiffonniez une feuille de papier sur laquelle était écrits des textes : la boule, de taille réduite, ne laisse quasiment plus rien transparaître des textes qui étaient au départ écrits sur la feuille). Il fut une époque où compresser des données était très important car, d'une part, les supports étaient de faible taille et, d'autre part, ils coûtaient chers : gain de place = gain d'argent. On a moins ce problème avec les supports d'aujourd'hui.

Bref, fort heureusement pour nous, pour une assez grande partie des jeux que l'on peut trouver, nous ne serons pas confrontés au problème de compression des données (cela concerne très souvent les jeux de rôle qui renferment un script conséquent). Nous développerons les techniques à utiliser lorsque la ROM est compressée suivant des schémas connus un peu plus loin (voir les annexes).

Trouver des textes et fabriquer une table

Avant toute chose, afin d'illustrer mon propos, j'utiliserai l'image de la ROM de Kid Icarus sur NES car il est très riche d'enseignement et son hack présente quelques particularités très faciles à comprendre. J'utiliserai également l'image de la ROM Gargoyle's Quest II (versions japonaise et américaine) sur NES pour d'autres démonstrations un peu plus complexes.

La première chose à faire lorsque l'on hacke une ROM, c'est, d'une part, décoder les lettres afin de rendre le texte lisible et, d'autre part, trouver où se situe ledit texte. Chaque lettre a une valeur hexadécimale, que ce soit en japonais, en chinois ou en français. Ces lettres peuvent être codées sur un octet (de 00 à FF) ou sur deux octets (de 00 00 à FF FF), voire plus (mais c'est beaucoup plus rare car 2 octets suffisent à construire un alphabet de 65 536 valeurs).

Pour davantage d'informations subsidiaires sur cette section, veuillez consulter l'annexe dédiée.

La recherche relative

Première étape très simple dans votre recherche de texte : jouez avec votre jeu afin de trouver des choses à traduire. Ne cherchez pas les "PRESS START BUTTON", "GAME OVER" et autres textes qui ne se trouvent pas dans le jeu lui-même. En effet, il arrive souvent que le codage de ces caractères soit différent de celui des textes principaux (ceci dit, dans ce cas, il faudra bien, à un moment ou à un autre, créer une table pour ces quelques caractères). Concentrez-vous donc, dans un premier temps, sur le script principal du jeu.

Dans Kid Icarus, vous pourrez, par exemple, trouver le texte "HEART" dans les menus. Si vous êtes assez patients, vous trouverez des textes de dialogues un peu plus loin avec des termes comme "BUY", "EVERYTHING" ou "THANK". Vous trouverez également des textes si vous voulez entrer un code, au début du jeu : "SACRED" ou "WORDS".

Kidicarus.1.png

Notez ces mots quelque part puis utilisez votre outil de recherche relative. J'ai pris SearchR X. Entrez le mot à chercher dans la ligne prévue à cet effet (c'est-à-dire "Find"). Plusieurs lignes vont apparaître avec le mot trouvé et la valeur du "A", du "a" et du "1". Cherchez les lignes où ce mot est cohérent avec le reste du texte traduit aux alentours. Ne cherchez pas des mots simples comme OF, THE, IN, etc. car il est très simple, en recherche "relative", de trouver un faible nombre d'octets qui puissent se suivre avec les mêmes écarts de comptage que lesdites lettres.

Pour Kid Icarus, si j'entre le mot "EVERYTHING" dans un logiciel de recherche relative comme SearchR X, on trouve ce mot en $0197D1 et le logiciel nous dit que la lettre A vaut $16. A noter que SearchR X possède une fonction de visualisation hexadécimale (SearchR 3 l'intègre également) ce qui permet de savoir rapidement ce qu'il se passe autour du mot.

Searchrx.2.png

Searchrx.1.png

Avant de poursuivre, notez les adresses hexadécimales où trouver les textes que vous avez cherchés. Cela vous sera utile pour plus tard afin de trouver des blocs de texte où se situent vos mots. Ici, notez l'adresse hexadécimale $0197D1.

Construire la table de caractères

La plupart des tables sont organisées de la même manière que l'alphabet et la numérotation classiques, à savoir : A B C D E, etc. et 0 1 2 3 etc. Ainsi, une fois que vous possédez la valeur hexadécimale du A, il sera plus facile de déterminer la valeur du B, puis du C, etc. Il arrive que, parfois, cela ne soit pas le cas. Une méthode consiste à aller trouver la font dans la ROM à l'aide d'un éditeur graphique ou d'un debugger et de voir comment les lettres et chiffres sont agencés. Nous en parlerons un peu plus bas.

Pour construire votre table, vous avez deux solutions. La première consiste à créer la table "à la main". On suppose que SearchR X m'a donné A=16 comme dans notre exemple, et que l'alphabet ne possède aucune particularité dans l'agencement de ses lettres - on suppose que la table est complète, c'est-à-dire que toutes les 26 lettres de l'alphabet sont présentes et dans l'ordre.

  16=A
  17=B
  18=C
  19=D
  1A=E
  1B=F
  1C=G
  1D=H
  1E=I
  1F=J
  20=K
  21=L
  ...
  2D=X
  2E=Y
  2F=Z

Procédez de même pour les lettres minuscules puis pour les chiffres puisque SearchR X vous donne les valeurs du a et du 0 (pourvu que votre recherche contînt des minuscules et/ou des chiffres). Puisque cela n'est pas le cas dans Kid Icarus (les textes du jeu ne sont écrits qu'en majuscules et les minuscules utilisées pour l'écriture du mot de passe ne sont pas utilisables en l'état), nous vous proposons des solutions dans les paragraphes suivants.

La deuxième solution pour créer une table consiste à utiliser des outils de création de table. S'il n'y a aucun problème d'agencement des lettres et des chiffres, je vous conseille vivement Table Auto Generator : il suffit de mettre les valeurs du A, du a et du 0 pour obtenir immédiatement la table. Il s'occupe même des alphabets japonais (les kana). Si les lettres ne sont pas agencées "normalement", Table Manager devrait faire l'affaire (bien que Table Auto Generator puisse également s'en occuper). Il est très intuitif à utiliser. Ne vous inquiétez pas s'il vous manque des valeurs : les tables créées automatiquement peuvent être modifiées "à la main". Les outils de création de tables permettent avant tout de dégrossir le travail initial.

Tag.1.png

Au final, sauvegardez votre table en lui mettant l'extension .tbl (par exemple kidicarus.tbl).

Compléter sa table avec un éditeur graphique

Avec un outil d'édition graphique, il est possible de trouver les agencements des lettres. Prenez la ROM de Kid Icarus et cherchez la police de caractères avec vos petits yeux en utilisant Tile Molester (ou n'importe quel autre outil d'édition graphique gérant le mode 2 BPP spécifique de la NES). Vous l'avez trouvée ? Elle se trouve aux environs de $001010, au tout début ! Vous voyez le A ? Vous voyez les autres lettres ? Eh bien elles sont agencées comme dans la table. De la même manière, si vous comptez en hexadécimal, vous allez trouvez les valeurs des autres caractères.

Tilemolester.1.png
  00=0
  01=1
  02=2
  ...
  0A=?
  0B==
  0C=,
  0D=.
  0E=!
  0F=-
  10='
  ...

Cette technique fonctionne dans 95% des cas... car il arrive que les programmeurs s'amusent à quelques facéties !

Une autre technique consiste à utiliser un debugger VRAM associé à un émulateur (FCEUXD SP pour NES, Gens/Fusion pour Mega Drive, etc.) ou à dumper la VRAM (si, une fois de plus, les émulateurs sont équipés d'outils pour cela) puis à la visualiser avec un éditeur graphique. Ensuite, la méthode est identique à ce que nous venons de montrer. Cette méthode permet d'ailleurs de créer une table complète sans passer par la recherche relative (voir plus bas).

Compléter sa table à l'aide d'un éditeur hexadécimal

Afin de trouver des caractères spéciaux, il existe une autre méthode. Soit vous utilisez la méthode de l'édition graphique et ça fonctionne (c'est-à-dire que la police de caractères apparaît clairement et que nous sommes dans les 95% de cas où nous ne rencontrons aucun obstacle - cf. le paragraphe précédent), soit on utilise la méthode de la devinette. Cette méthode est de toute façon indispensable pour trouver d'autres valeurs non accessibles via un éditeur graphique.

Pour cela, lancez votre éditeur hexadécimal favori (je prends Translhextion). Ouvrez la ROM puis cherchez une option "Open Table" ou quelque chose de similaire. Cela permettra à votre éditeur d'affilier à chaque octet existant dans la table une lettre qui apparaîtra alors "traduite" dans l'éditeur hexadécimal (colonne de droite dans notre cas) : le script vous apparaîtra clairement. Par défaut, l'éditeur utilise en général une table de norme internationale appelée ASCII dans laquelle A=41 et a=61. De nombreux jeux utilisent cette table par défaut. On trouve donc le texte sans même avoir besoin d'un outil de recherche relative (c'est surtout le cas des jeux "récents" à partir des 32 bits où la taille du support permettait de s'affranchir, pour les programmeurs, des problèmes de place).

Normalement, avec votre table, le texte devrait, disais-je, apparaître en clair dans votre éditeur. Il vous suffit de chercher. Pour vous faciliter la tâche, rendez-vous tout d'abord aux endroits que vous avez notés lors de votre recherche relative. Vous vous rappelez de l'adresse ? Oui ? Bravo, vous êtes consciencieux ! Rendons-nous donc en $0197D1, soit en cherchant une fonction "Go to (offset)" dans les menus ou en faisant défiler la barre de navigation jusqu'à cette adresse (les valeurs des lignes sont indiquées à gauche dans Translhextion).

Oooh ! Mais on voit qu'il y a du texte par ici ! On voit nos textes qui apparaissent. C'est joli, n'est-ce pas ? La méthode de la devinette consiste en quoi ? Eh bien vous repérez un texte dans le jeu qui possède un caractère spécial et vous regardez où il se trouve dans votre éditeur hexadécimal : vous trouvez ainsi sa valeur.

Translhextion.1.png

Prenons par exemple "YOU WEAKLING!". Dans la ROM, il se trouve à l'adresse $019782. Si vous n'avez pas utilisé la méthode graphique, vous devez voir, sous Translhextion, le texte suivant : "YOU#WEAKLING#" (lorsqu'un éditeur ne reconnaît pas un octet, il l'affiche sous une forme générique ; dans Translhextion, la forme générique est un #). Que vaut ce # ? Il suffit de se positionner dessus et de regarder sa valeur hexadécimale. On trouve ainsi que # = ! = $0E et $12 correspond à l'espace. On reproduit cette recherche "à la devinette" pour tous les caractères utilisés dans le jeu.

Créer une table incomplète

Je vois venir certains d'entre vous : "Eh, pas si vite ! Dans mon éditeur graphique, j'ai vu des lettres en 0x003010 ! Elles sont mal agencées : c'est ce dont tu voulais parler quand tu évoquais les tables incomplètes ?" En effet. Ici, les lettres sont reparties de manière chaotique. Ces lettres sont utilisées pour l'écran titre "ANGEL LAND STORY". Comment faire pour fabriquer une table ?

Tilemolester.2.png

Si on applique la technique consistant à compléter sa table avec un éditeur graphique, on sait quel espace sépare chaque lettre. Donc, on connaît leur positionnement relatif. Ainsi, si on arrive à connaître la valeur d'une seule lettre, on connaît nécessairement les autres (dans 95% des cas, je le rappelle). On sait qu'on ne peut utiliser que des alphabets dans les outils de recherche relative. Le but consiste donc à imposer qu'une des lettres présentes représente le "A" du nouvel alphabet. Il faut pouvoir reconstituer un mot ou une partie d'un mot grâce à cet alphabet virtuel.

Pour notre cas, remplaçons E par le A et "recopions mentalement" le reste de l'alphabet. Nous avons alors les changements suivants :

  E -> A
  N -> H
  A -> I
  Y -> Q
  G -> W
  R -> X
  O -> Y

Quels mots ou morceaux de mot peut-on former qui se trouve dans ANGEL LAND STORY ? Eh bien nous avons : ANGE (4 lettres, pas mal), ORY (3 lettres, ça peut aider) et AN (2 lettres, inutile). Cherchons donc ANGE. Avec notre nouvel alphabet, il faut donc chercher IHWA dans notre logiciel de recherche relative (SearchR X, je le rappelle, dans notre cas).

Searchrx.3.png

Miracle ! Il n'en trouve qu'un seul ! Il se trouve à l'adresse $0063C3 et le A vaut 9F. On revient donc en sens inverse et on sait que le A est là où se trouve le E. Ainsi, le E vaut 9F. En comptant les tiles de "manière hexadécimale", on retrouve la valeur de toutes les autres lettres et chiffres :

  00=0
  01=1
  02=2
  03=3
  04=4
  05=5
  06=6
  07=7
  08=8
  09=9
  0A=©
  0B=.
  A7=A
  65=B
  BF=D
  9F=E
  B5=G
  64=H
  7B=L
  D3=M
  A6=N
  B7=O
  31=P
  B6=R
  C0=S
  c3=T
  5D=U
  AF=Y
  D2=Z

On a même 0C0D=TM et 20212223242526=NINTENDO (car ce mot est formé des tiles dont les valeurs hexadécimales sont, dans l'ordre $20, $21, $22, $23, $24, $25 et $26). Mais cela ne nous intéresse pas trop ici. Ces valeurs sont là pour vérifier que vous avez compris comment fonctionne l'agencement des octets et la création de tables à la main. Notez donc bien que ce jeu possède deux tables de caractère !

Créer une table avec un debugger

Une technique, qui était assez rare il y a une dizaine d'années (et pour cause), consiste à utiliser le debugger de certains émulateurs, en particulier la fonction de visualisation de la VRAM (mémoire vidéo). Si on réfléchit 30 secondes, cette méthode est logique : ce qui se trouve dans la VRAM est, par définition, ce qui est directement utilisé au moment de l'affichage. Lorsqu'on visualise la VRAM, la position des caractères en abscisse et en ordonnées correspond exactement à sa valeur hexadécimale : s'il est placé en x=8 et y=B (les abscisses et ordonnées étant numérotées de 0 à F), alors sa valeur sera de $8B.

Fceuxdsp.1.png

Fceuxdsp.2.png

Et hop ! on s'affranchit d'un coup de la recherche relative. Il faut savoir qu'il y a une dizaine d'années, les debuggers étaient très rares. C'est la raison pour laquelle Nesticle (émulateur NES sous DOS particulièrement en avance sur son temps) a eu autant de succès.

Si compléter sa table de caractères à l'aide d'un éditeur graphique (qui charge la ROM, comme vu ci-dessus) est assez efficace, c'est parce qu'au moment du chargement des caractères en mémoire, les développeurs ne se sont pas embêtés (dans quel but le ferait-il, d'ailleurs ?) à charger les tiles dans le désordre : on prend le gros paquet qui va de telle adresse à telle adresse (bank de 32 ko pour un jeu NES) et puis point barre !

Petite histoire d'octets bizarres

Une fois tout ceci accompli, ce n'est pas tout car, même lorsque vous avez trouvé les caractères de la table, il reste plein d'octets inconnus # qui se dressent au milieu du texte... ou plutôt à la fin. Voyons... réfléchissons... Un programme qui "lit" une phrase. Comment sait-il qu'on arrive à la fin d'une phrase ? Ou même à la fin d'une ligne ? Regardons cela d'un peu plus prêt.

Reprenons notre script de Kid Icarus et regardons cette phrase (on suppose que votre table de caractères est complète) :

  ##KCAN YOU ENDURE###THIS HARSH TRAINING?## 

Dans le jeu, cette phrase apparaît de la manière suivante :

Kidicarus.2.png

Réécrivons la phrase issue de l'éditeur de texte avec les octets à la place des # :

  <FE><C8><20>CAN YOU ENDURE<FE><08><21>THIS HARSH TRAINING?<FF>

Ces octets sont certainement des "indicateurs" pour le programme qui va lire le texte. Essayons de les modifier. Par exemple, je vais changer mon C8 en C9 (ne cassons pas tout) et je relance le jeu. Que vois-je ? Le texte a été décalé d'un octet vers la droite !

Translhextion.3.png

Kidicarus.3.png

Bon, allez, je modifie le 20 en 21. Là, le texte a carrément sauté des lignes. Il se passe la même chose si je modifie les 08 et 21 de la seconde ligne de texte.

Translhextion.4.png

Kidicarus.4.png

J'en conclus qu'en début de ligne, il y a des "octets de position". Ces octets servent à placer le texte dans l'espace. En tâtonnant, on comprend vite comment ils fonctionnent : dans notre cas, on ne modifiera que le premier octet des groupements de deux octets de position. En clair, on ne touchera pas aux 20 et 21 car ils incrémentent très loin : on ne veut que replacer le texte sur la ligne une fois celui-ci traduit, non ? Bref, amusez-vous à les modifier pour voir quelles conséquences cela a.

Bon, il nous reste encore ces <FE> et <FF> tout de même. On remarque que le <FE> doit très certainement indiquer le début d'une nouvelle ligne. Si on remplace celui du milieu par une lettre, on constate en effet à l'écran que le texte s'affiche sur une seule ligne et a remplacé les <08><21> par des caractères issus des tiles qui se trouvent aux endroits hexadécimaux indiqués. Bref, <FE> = nouvelle ligne.

Translhextion.5.png

Kidicarus.5.png

Et notre <FF> ? D'après ce que je vois à l'écran, il semble clairement indiquer la fin globale de la section de texte. En effet, si je remplace le <FF> par un autre caractère, une autre phrase va apparaître à l'écran : il s'agit de celle qui se trouve juste derrière dans l'éditeur hexadécimal (d'ailleurs, cette phrase se trouve à la même position que le début de notre phrase exemple puisqu'elle possède aussi les octets de position <C8><20>). Bref, <FF> = fin de section.

Translhextion.6.png

Kidicarus.6.png

Enfin, si on regarde la toute première phrase, on constate un <FD>. En jouant, il apparaît qu'après cette phrase, vous deviez appuyer sur un bouton pour poursuivre le dialogue. De la même manière que les autres octets, si vous supprimez celui-ci, la suite de ce qui se trouve dans l'éditeur hexadécimal apparaît. Bref, <FD> = Pause.

On retrouve quasiment tout le temps des octets de retour à la ligne et/ou de fin de section. Les octets de pause sont également fréquents. Les octets de position ne sont pas obligatoires (là, on a la chance d'en voir). Mais on aurait tout aussi bien pu trouver des "octets de comptage" qui donne la longueur du texte avant qu'une fin de section n'intervienne : par exemple, si on imagine un "<06>Ça va ?", le <06> indiquerait que la phrase fait 6 caractères de long. Dans ce cas, pas besoin de balise de fin de section ! On en retrouve d'ailleurs dans les menus de Kid Icarus mais leur écriture n'est pas aussi évidente.

En général, dans les tables, on écrit les fins de ligne et de section de la manière suivante quand ils existent (cela dépend de l'extracteur ; par exemple, Pointer Tables n'utilise pas ce format) :

  *FE
  /FF

On peut aussi traiter nos octets de cette manière (plus moderne) :

  FD=[PAUSE]\n
  FE=\n
  FF=[FIN]\n\n

Trouver la table de caractères de jeux récents

Pour les jeux récents, la recherche des tables de caractères n'est pratiquement plus de mise (et, ce, depuis l'apparition du support CD datant de l'époque des 32 bits). Les jeux peuvent maintenant charger n'importe quelle table de caractères en mémoire. De plus, les moyens de développement des jeux vidéo ont considérablement évolué. Du coup, on retrouve tout un tas de standards d'affichage qui nous évitent la recherche relative et, pour les jeux japonais, la technique que nous allons développer ci-dessous. Ainsi, on se retrouvera fréquemment en présence de standards Unicode (ASCII 8 bits pour les Européens/Américains, GOST pour les Russes, ISO 8859 pour l'ensemble du monde occidental, ISO 2022 pour les Asiatiques, SHIFT JIS pour les Japonais, GB2312 ou BIG5 pour les Chinois, UTF-8 pour tout ce que l'on veut, etc. qui ont en commun le "tronçon" ASCII 7 bits).

Bref, pour les jeux récents (voire à partir des 32 bits), votre table de caractères devrait pouvoir se faire "toute seule" : les standards se trouvent très facilement sur internet, de nos jours !

Trouver la table et les textes d'un jeu japonais

Revenons plutôt à l'époque des 8 et 16 bits et prenons la ROM japonaise NES Reddo Ariimaa II (Gargoyle's Quest II - The Demon Darkness en dehors du Japon ; Red Arremar dans le GoodNES). La construction d'une table, on l'a vu, peut se faire en un instant grâce à la visualisation de la mémoire vidéo VRAM, endroit où sont stockées les tiles qui vont être affichées.

Fceuxdsp.3.png

Aujourd'hui, la plupart des émulateurs 8 et 16 bits sont équipés de tels outils (ce qui n'était pas le cas il y a une dizaine d'années, d'où, je le rappelle, le succès de Nesticle et Genecyst qui, eux, permettaient de faire tout ça). Bref, c'est bien joli mais cela ne nous dit pas où se trouve le script !

Nous avons ici deux techniques.

  • Utilisation directe de l'éditeur hexadécimal : méthode moderne

La première technique fonctionne pour tout type de jeu.

Une fois que vous avez votre table de caractères (méthode VRAM, la plus rapide), allez repérer une phrase dans le jeu qui n'utilise pas d'accent " ou ° (cf. dernier point). Mettons que ce soit おはよう (o ha yo u). Même si vous ne parlez pas japonais (mais qu'est-ce que vous faites là, alors ?), vos petits yeux sauront distinguer les "dessins" et les associer à votre table. Je rappelle que la table est la même que celle définie pour Reddo Ariimaa II. Ainsi, おはよう a pour code hexadécimal "$05 $1A $26 $03". Il ne vous reste plus qu'à chercher cette chaîne hexadécimale à l'aide de votre éditeur favori. Si vous avez chargé la table, vous devriez voir apparaître du texte à côté du おはよう. Si ce n'est pas le cas, il est possible qu'il ne s'agisse pas de texte mais d'une combinaison fortuite d'octets qui réussit à faire apparaître un tel mot. Cherchez la chaîne hexadécimale suivante : vous finirez bien par tomber sur le texte recherché.

  • Utilisation d'une méthode graphique : la vieille école

La seconde technique ne fonctionne que pour des jeux dont le nombre de caractères est limité. Ici, nous ne parlerons donc que des jeux japonais. Les jeux chinois utilisent un trop grand nombre de caractères (ils n'ont pas de système "d'alphabet" comme les Japonais) pour que la technique développée ici puisse fonctionner facilement. Et puis je doute que vous soyez amenés à traduire des jeux 8/16 bits développés par des Chinois (bien qu'il en existe quelques uns bien sympathiques sur Mega Drive). Autre précision : la technique fonctionne extrêmement bien pour les jeux 8 bits qui n'utilisent que des hiragana/katakana.

Bref, reprenons Reddo Ariimaa II. Vous vous rappelez que le jeu affiche ce qui se trouve en mémoire VRAM (qu'il a chargée à partir des données brutes de la ROM). Alors modifions sa mémoire en trifouillant la ROM et, à l'aide d'un logiciel d'édition graphique comme Tile Layer Pro ou Tile Molester, remplaçons tous les hiragana (alphabet destiné à écrire les mots japonais alors que les katakana sont destinés davantage aux mots étrangers) avec notre alphabet latin minuscules/majuscules, soit 52 lettres en tout ; un tout petit peu plus que le nombre d'hiragana disponibles. Sauvegardez vos changements et lancez le jeu.

Tilemolester.3.png

Tilemolester.4.png

Ce qui devait se produire se produit alors : tous les hiragana sont remplacés par une suite de lettres latines qui ne veulent strictement rien dire. Prenez une chaîne assez longue (5 ou 6 lettres latines successives). Par exemple, dès le premier menu ("START" ou "PASSWORD"), j'ai un magnifique "YMCL". Ceci dit, il vaut mieux un mot plus long. On a de la chance : dès les premières phrases du jeu, un extraordinaire "BQVteDY" nous attend. Mais il n'est pas tout en majuscule (ce qui peut poser problème à certains outils de recherche relative). Ceci dit, dans la même phrase, nous avons un "BQVQ" tout en majuscule (4 lettres, c'est tout de même pas si mal).

Gargoylesiijap.1.png

Prenez alors votre logiciel de recherche relative (SearchR3 est super rapide mais semble considérer à chaque fois que les majuscules et minuscules sont séparées de $20, alors que SearchR X sait faire la distinction entre les deux : à utiliser lorsque vous cherchez des mots en minuscules et majuscules comme notre exemple) puis recherchez la chaîne "BQVteDY" ou "BQVQ". Le logiciel va vous donner une adresse à laquelle se trouve ledit texte (si vous avez bien suivi ce tutoriel, ceci ne devrait être qu'un rappel).

Searchrx.4.png

Ouvrez votre éditeur hexadécimal, chargez la ROM et sa table (japonaise) puis allez à ladite adresse (voire aux adresses, s'il y en a plusieurs) et vous devriez trouver votre script. Si ce n'est pas le cas, allez à l'adresse suivante.

Windhex32.1.png

N.B. : comme nous le verrons plus tard, le script de Gargoyle's Quest II est compressé selon une technique qui permet de voir tout ou partie des mots. Les recherches de mots "tels quels" ne fonctionneront donc pas tout le temps mais l'illustration qui en est faite ici est suffisante pour comprendre le principe de cette technique.

  • Le "plus" de la seconde technique

Si vous ne comprenez pas pourquoi le logiciel de recherche relative est bien utile dans cette seconde technique, je vous conseille vivement de relire le passage qui vous en parle. Vous comprendrez mieux le pourquoi de cette technique. En particulier, vous comprendrez pourquoi elle était tellement puissante à l'époque où on n'avait pas de debugger pour construire une table.

En effet, une fois que vous avez effectué votre recherche relative, vous connaissez la valeur d'une lettre puis, quasiment systématiquement, la valeur de toutes les lettres qui suivent. Cette technique permet donc de créer la table de caractères ET de trouver le script. Dans notre cas, on aurait trouvé A = 01 ; sachant que la lettre "A" remplace le あ japonais, on sait donc que あ = 01. La table devient donc :

  01=あ
  02=い
  03=う
  04=え
  05=お
  06=か
  07=き
  08=く
  09=け
  0A=こ
  0B=さ
  0C=し
  0D=す
  0E=せ
  0F=そ
  10=た
  11=ち
  12=つ
  13=て
  14=と
  etc.


  • Les caractères accentués japonais

En général, les jeux japonais 8 bits affichent les accents indépendamment des caractères ; ça se voit très bien dans Final Fantasy II sur NES, par exemple, et encore mieux lorsque vous utilisez la seconde technique : les lettres latines s'affichent avec les accents japonais qui restent à leur place.

Ce système peut être clairement réutilisé pour la traduction Fr de jeux japonais afin d'avoir des accents clairement séparés du reste de la lettre (comme cela a été le cas dans le cadre de la traduction d'Ys II - Ancient Ys Vanished - The Final Chapter sur NES) . Ainsi, lorsque la recherche porte sur ありがとう (a ri ga to u), il vaut mieux chercher ありかとう (a ri ka to u) lorsqu'on utilise la première technique. Du coup, si on ne connaît pas le système de "codage" de ces accents, il vaut mieux chercher une suite de caractères qui n'en possède pas.

Introduction aux pointeurs

Une ultime question, et pas des moindres... Comment le jeu "sait" que les textes doivent se lire "à cet endroit dans la ROM" ? Eh bien tout simplement en "pointant" les textes, c'est-à-dire en indiquant au jeu, via une suite d'octets, qu'il doit regarder à certains endroits de la ROM. Bref, prenez cela comme des indicateurs qui disent "le texte est là !". On appelle cela les "pointeurs". Et comme la plupart des machines que nous ROMhackons ont un système bien précis pour calculer les pointeurs, nous leur dédions une petite section dans les annexes (à lire maintenant !).

Utilisation des pointeurs par l'exemple

Dans notre cas (Kid Icarus), nous allons chercher des octets qui se retrouvent dans une "table". On retrouve ce schéma de pointeurs dans de nombreux cas et c'est en général le premier que l'on recherche parce que c'est le plus simple à détecter. A quoi cela ressemble-t-il ? Si vous avez lu l'annexe sur les pointeurs NES en particulier, vous savez à peu prêt ce que vous chercher : des couples d'octet qui "ressemblent" aux 4 derniers octets de l'adresse où se trouve le texte. Reprenons notre phrase exemple ci-dessus qui se trouve à l'adresse 0x019756. Les octets qui nous intéressent sont donc 97 56. Notons que le 97 est l'octet "haut" (high) et 56 est l'octet "bas" (low). Étant donné que la NES est "Little Endian", nous cherchons donc un "inversion(9756-offset)". L'offset, ici, est de 10 (c'est à vous de le découvrir, en général) : inversion(9756-10) = inversion(9746) = 4697. A l'adresse 0x019710, on trouve :

  XX XX 1E 97 46 97 6F 97 80 97 A4 97 CD 97 E5 97
  08 98 20 98 49 98 75 98 92 98 B9 98 XX XX XX XX

Il y a en effet un 46 97 qui nous intéresse. Établissons une liste de deux octets en colonne :

  1E 97
  46 97
  6F 97
  80 97
  A4 97
  CD 97
  E5 97
  08 98
  20 98
  49 98
  75 98
  92 98
  B9 98

On voit cette suite de 97 et 98 étant donné que le texte se trouve en 0x0197YY et 0x0198ZZ ! C'est en général de cette manière que l'on repère des tables de pointeurs : il y a répétition du deuxième octet qui s'incrémente doucement. Attention ! On n'a pas toujours ce type de schéma (voir l'annexe sur les pointeurs) ! Ce guide essaie d'être le plus exhaustif possible mais il ne remplacera jamais votre cerveau !

Les tables de pointeurs, ce n'est pas obligatoire

Petite précision tout de même : il arrive que des textes ne soient pas "pointés" phrase par phrase ou section par section. Gardez à l'esprit que le programmeur du jeu a toute latitude pour le réaliser. Il pourrait très bien, au niveau de la programmation, ne mettre qu'un seul pointeur vers un bloc de textes représentant l'intégralité du script puis faire une série d'impression de texte à l'écran (par exemple "PRINT" en BASIC ou "printf" en C). Il pourrait même se passer de pointeur en imprimant directement le texte à l'écran sans passer par un bloc de texte. On dit alors que le script est "hardcodé" (il s'agit d'une technique en général utilisée pour de petits mots). Sans aucune connaissance en programmation et en assembleur, il est extrêmement difficile de déplacer ce genre de script au sein de la ROM.

Bref, j'attire votre attention sur le fait qu'il y a 50 000 façons d'indiquer à un programme où trouver des textes, surtout dans les ISOs qui sont constitués de multiples fichiers. Ceci dit, il existe des formes que l'on retrouve plus souvent que d'autres.

Quelques exemples de types de pointeurs

Un petit résumé des différentes techniques les plus courantes peut être le bienvenu, non ?

  • Little Endian

Comme on vient de le voir, il s'agit d'une inversion d'octets : Adresse(texte) = inversion(Pointeur) + offset. Notre exemple portait sur des pointeurs 16 bits (2 octets) mais on peut avoir des choses plus exotiques en 24 voire 32 bits (pas sur NES, rassurez-vous) ! Ce schéma est très utilisé sur les machines Nintendo (NES et Super NES). Un aperçu de ce que l'on peut faire avec ces types de pointeurs se trouve en annexe (attention : ce document est destiné aux personnes qui ont déjà compris les bases et le vocabulaire).

A titre d'exemple, la date au format français JJ/MM/AAAA (jour/mois/année) peut être considérée de type 'Little Endian'. Pourquoi ? Imaginez que vous vouliez trier des fichiers par date de modification, du plus récent au plus ancien. Comment feriez-vous ? Vous commenceriez par regarder l'année (de la plus récente à la plus ancienne), puis le mois et enfin le jour. Du coup, si vous aviez été un programme, vous auriez regardé la date comme ceci : AAAA/MM/JJ. Qu'auriez-vous donc fait par rapport à la donnée de départ ? Vous auriez tout simplement inversé les parties de la date !

  • Big Endian

Là, il n'y a pas d'inversion d'octet. On a une formule de type Adresse(texte) = Pointeur + offset. Beaucoup plus simple à repérer dans une ROM, n'est-ce pas ? Surtout quand l'offset vaut 00 ou 10 00 00. Ce schéma est très utilisé sur Mega Drive.

Pour faire un parallèle avec ce qui a été dit au paragraphe précédent, le format horaire HH:MM:SS (heures/ minutes/secondes) peut être considéré comme étant du "Big Endian" puisque le sens de lecture accordé par ce format nous permettrait de le manipuler tel quel pour, par exemple, ranger les évènements d'une journée par ordre chronologique (on commencerait par lire les heures, puis les minutes et enfin les secondes ; on ne commencerait bien évidemment pas par lire les secondes).

  • Relatif

Quasiment impossible à détecter à l'œil nu, il s'agit pourtant d'un pointeur "logique" : Adresse(texte) = Adresse(début du pointeur) + Pointeur. En gros, à un endroit de la ROM, on demande au programme d'aller voir ce qu'il se passe un peu plus loin. On le repère en général à l'aide d'un debugger couplé à un émulateur. On retrouve ce genre de schéma sur des jeux Mega Drive comme Mega Turrican.

  • Découpé

Une sorte de pointeur exotique que j'ai découvert dans Gargoyle's Quest II sur NES. Grosso modo, tous les octets "bas" étaient mis d'un côté et tous les octets "hauts" étaient mis d'un autre côté (dans des pointeurs 24 et 32 bits, on verrait les octets "moyens" dans un autre coin). Si on reprend l'exemple de Kid Icarus, la table aurait ressemblé à : 1E 46 6F 80 A4 03 2C... 97 97 97 97 97 98 98 etc. On constate qu'il est assez "simple" de les retrouver à cause de la suite d'octets "hauts". Une fois que l'on a regroupé chaque octet "bas" avec chaque octet "haut" qui lui correspond, le pointeur ainsi trouvé fonctionne de la même manière que les schémas little ou big endian.

  • Indicateur de taille

On pourrait voir une liste de "taille de texte". Très difficile à trouver à l'œil nu, cela pourrait ressembler à : 06 14 2B 1C 29 3A etc. ce qui signifie, en gros, qu'à partir de la première phrase du bloc de texte, les phrases feront 6, 20, 43, 28, 41 et 58 caractères.

  • Imbriqués

Il arrive que l'on puisse trouver une table de pointeurs qui redirigent... vers d'autres tables de pointeurs (eux-mêmes redirigeant vers des morceaux de scripts). Cela permet, entre autres, de procéder par blocs de textes et de disposer de pointeurs 16 bits (limités) pour des jeux contenant beaucoup de textes. On retrouve ce principe dans Mega Man Zero 4 sur Game Boy Advance ou Breath of Fire III sur PlayStation (et PlayStation Portable), par exemple. On notera que chaque table de pointeurs (y compris la table principale) se traite ensuite selon les mêmes techniques que celles citées précédemment : il ne s'agit donc pas d'un "format" à proprement parler.

Bref, vous avez compris le principe ? Alors parcourez la ROM avec vos yeux et repérer où se trouvent les textes qui utilisent vos tables. Notez dans un coin les adresses de ces textes, les pointeurs éventuellement. Prenez des notes sur les octets que vous trouvez bizarres, modifier-les pour voir les impacts, etc. Recherchez les graphismes susceptibles d'être modifiés avec un éditeur de tiles. Faites fonctionner vos méninges !

Introduction aux compressions

Une compression est un moyen de réduire la taille des données afin de pouvoir intégrer l'intégralité de ces dernières dans un espace donné. A l'époque des 8 et 16 bits (voire 32 bits comme la NEO.GEO), l'espace disponible sur les cartouches de jeux était faible et coûtait cher (rappelez-vous Street Fighter II à 690 FF, soit plus de 100 euros, au début des années 1990). Depuis l'apparition des formats de disques numériques (CD, DVD, UMD, HD-DVD, Blu-Ray, etc.) et la rapide augmentation de capacité des disques durs (de 3 Go en 1997 à plus de 500 Go en 2007), les prix associés à l'espace ont considérablement diminué. De fait, il est devenu beaucoup moins contraignant de créer des jeux dont toutes les données ne sont pas compressées.

Parmi les compressions existant dans le domaine des jeux vidéo, certaines sont accessibles au débutant (encore faut-il savoir les détecter). Procédons d'abord à un petit résumé de ce que l'on peut rencontrer :

Dual Tile Encoding (DTE)

Comme son nom l'indique, le but de cette compression est de coder deux octets en un seul. Notre alphabet comptant grosso modo 75 caractères ponctuation comprise, cela nous laisse potentiellement 180 combinaisons possibles. Ce type de compression est souvent introduit, lorsqu'il n'existe pas, dans les traductions à partir du japonais. On la retrouve d'ailleurs dans le RPG Doraemon - Giga Zombie no Gyakushuu sur NES.

Prenons un exemple simple :

  j'aime bien me baigner dans la mer

Prenons la table suivante :

  10=a
  11=b
  12=c
  13=d
  14=e
  15=f
  16=g
  17=h
  18=i
  19=j
  1A=k
  1B=l
  1C=m
  1D=n
  1E=o
  1F=p
  20=q
  21=r
  22=s
  23=t
  24=u
  25=v
  26=w
  27=x
  28=y
  29=z
  30='
  31= 
  40=ai
  41=me
  42=er
  43= b

Sans DTE, la phrase s'écrit alors :

  19 30 10 18 1C 14 31 11 18 14 1D 31 1C 14 31 11
  10 18 16 1D 14 21 31 13 10 1D 22 31 1B 10 31 1C
  14 21

Avec DTE, la phrase s'écrit :

  19 30 40 41 43 18 14 1D 31 41 43 40 16 1D 42 31
  13 10 1D 22 31 1B 10 31 41 21

Vous voyez que l'on vient de gagner 8 caractères sur les 34 présents initialement soit près d'un quart du texte. Bien entendu, le plus difficile est de trouver cette DTE. De plus, tous les mots ne sont pas représenter entièrement, ce qui gêne la recherche relative. Par exemple, dans notre éditeur hexadécimal, si on ne possède que la partie entière de l'alphabet (et pas la DTE), la phrase va apparaître comme ceci :

  j'###ien ###gn# dans la #r

Du coup, ce n'est pas parce qu'on ne trouve pas un mot en recherche relative que le texte n'est pas "visible". Après plusieurs tentatives (notamment avec de petits mots - ici, il s'agit de "dans"), on pourra construire une table digne de ce nom. La DTE se construira en lisant le texte avec l'éditeur hexadécimal (une fois la table principale construite) et en jouant au jeu afin de retrouver les valeurs manquantes.

Une DTE peut être purement graphique. On l'applique essentiellement sur des lettres ou symboles de faible largeur : il ti ri ll J' L' par exemple, se casent dans une seule tile au lieu de deux. C'est ce que j'ai utilisé pour Gargoyle's Quest II (sinon, je ne m'en sortais pas !).

Multiple Tile Encoding (MTE)

Il s'agit d'un cas plus global que la DTE et parfois plus simple. Comme son nom l'indique, plusieurs octets peuvent être codés sur un ou plusieurs autres octets (le but étant que le nombre d'octets codés soit supérieur aux octets de codage). On retrouve ce système de compression dans Gargoyle's Quest II sur NES (que ce soit dans sa version US ou japonaise) ou Lufia sur Super NES.

Tout comme pour la DTE, il existe des MTE graphiques que l'on peut réaliser soi-même si l'on dispose de place (ce qui est efficace si le mot codé est assez souvent utilisé). J'ai également fait usage de cette technique dans Gargoyle's Quest II.

Ce mode de compression (ainsi que le cas plus particulier de la DTE) est expliqué un peu plus en détails en annexe.

LZSS / LZ77

Un système de compression qui s'appuie sur des octets antérieurs pour coder les octets suivants. Cette compression est "détectable" lors d'une recherche relative puisque certains mots apparaissent en entier (surtout ceux servant de point de départ à la compression). Les débutants ne pourront rien faire : il faut savoir programmer afin de pouvoir correctement comprendre la compression, extraire puis insérer le script traduit. Ce type de compression se retrouve dans Langrisser II ou Phantasy Star IV sur Mega Drive.

La différence entre le LZSS et le LZ77 est, en gros, le fait que le LZSS s'appuie sur des octets alors que le LZ77 s'appuie plutôt sur des bits. On peut aussi trouver la compression de type LZW (celle utilisée par exemple pour le format Zip) dont les bases fondamentales sont équivalentes, mais qui s'appuie sur la génération d'un "dictionnaire de mots" de manière dynamique et qui utilise ce dictionnaire pour compresser les données : une sorte de MTE dynamique.

Huffman

Une compression strictement indétectable sans debugger. Elle se base sur la fréquence d'utilisation des lettres via l'utilisation d'un arbre dont le nombre de bits est réduit (chaque lettre n'est pas nécessairement codée sur 8 bits). S'il n'est pas difficile de la comprendre pour le profane avec un peu d'effort, la détecter, l'extraire et la réinsérer est une autre paire de manches. On la retrouve dans Shining Force II sur Mega Drive (et dans les Shining Force en général).

Si vous désirez en savoir davantage sur le mode de fonctionnement de cette compression, vous pouvez aller voir en annexe.

Limitation des bits

Les lettres sont en général codées sur 8 bits = 1 octets. Imaginons à présent que nous ayons un codage des lettres sur moins de bits. Sachant que l'éditeur hexadécimal regroupe tout par 8 bits afin d'afficher des octets, le texte deviendra complètement invisible (un peu comme pour du Huffman).

Prenons une phrase toute simple : "je traduis". En utilisant la partie principale de la table des DTE, on obtient :

  19 14 31 23 21 10 13 24 18 22

Classique (vous commencez à avoir l'habitude).

Imaginons une table codée sur 5 bits :

  a=00000
  b=00001
  c=00010
  d=00011
  e=00100
  f=00101
  g=00110
  h=00111
  i=01000
  j=01001
  k=01010
  l=01011
  m=01100
  n=01101
  o=01110
  p=01111
  q=10000
  r=10001
  s=10010
  t=10011
  u=10100
  v=10101
  w=10110
  x=10111
  y=11000
  z=11001
   =11010

La phrase s'écrit alors :

  01001 00100 11010 10011 10001 00000 00011 10100 01000 10010

Regroupons tout par 8 bits :

  0100100 10011010 10011100 01000000 00111010 00100010 01000000

On a rajouté des 0 pour compléter la lecture, un peu comme pour du Huffman.

En hexadécimal (ce que vous verrez avec votre éditeur), la phrase devient :

  24 9A 9C 40 3A 22 40

Vous voyez un rapport entre ces 7 octets et les 10 de départ ? Non ! Édifiant, n'est-ce pas ? Une fois encore, seul un programmeur peut s'en sortir. On retrouve cette compression appliquée à The Battle of Olympus sur NES dans lequel il y a, de plus, une suite de bits permettant de passer des majuscules aux minuscules et vice-versa. Un codage sur 5 bits, c'est 32 caractères possibles. Si l'on compte la ponctuation, ces bits de changement et les octets de fin de phrase, il ne reste absolument aucune place pour les lettres accentuées.

Un détail amusant est le système de Bionic Commando sur NES : les caractères sont codés sur 12 bits. On n'en comprend pas vraiment l'utilité (à moins que les Japonais aient utilisés ce mode de fonctionnement pour avoir plus de caractères disponibles sans que les Américains ne retouchent à la programmation du jeu lors de la traduction) mais il s'agit là d'un codage indétectable de manière classique !

Run Length Encoding (RLE)

Une compression "intuitive" puisque, sur le principe, elle compte les octets identiques qui se suivent. Du coup, on l'utilise rarement pour des textes mais plus souvent pour des images dont le nombre de couleurs maximum affichables est limité (à 16 millions, ce n'est même pas la peine d'y penser !) : les formats TGA et PCX peuvent faire usage de la compression RLE. Par exemple :

  aaaaaaaabbccdeeeeeeeaaaddddddddd

En reprenant notre table initiale (cf. la DTE), le texte s'écrirait :

  10 10 10 10 10 10 10 10 11 11 12 12 13 14 14 14
  14 14 14 14 10 10 10 10 13 13 13 13 13 13 13 13

En utilisant un système RLE, on pourrait très bien retrouver ce texte sous la forme :

  08 10 02 11 02 12 01 13 07 14 04 10 08 13

14 octets contre 32 initialement, ce n'est pas trop mal : en gros, on lit qu'il y a 8 "a", 2 "b", 2 "c", etc. Rien de bien compliqué, en somme. On retrouve cette compression dans l'écran titre de Double Dragon III sur NES. Bien sûr, notre exemple est extrêmement simple. En réalité, on peut l'utiliser sous forme de variantes plus complexes, ce qui est le cas pour le jeu que je viens de citer.

Vous trouverez d'ailleurs un peu plus d'informations sur les applications de cette compression en annexe.

Extraire un texte

Il n'y a rien de bien compliqué à extraire un texte tant les outils dédiés sont intuitifs (lire la notice, tout de même). Une fois que vous connaissez les endroits où se trouvent, d'une part, votre table de pointeurs et, d'autre part, le script associé, le travail est terminé puisque les outils n'ont besoin que de ces paramètres (ainsi que de la table d'extraction fabriquée un peu plus haut). En effet, à l'insertion, ces outils (que je vous ai préconisés plus haut) se chargent de recalculer les pointeurs de manière automatique. Notez que vous pouvez également extraire des textes sans pointeurs (comme cela arrive parfois, surtout si les textes sont "hardcodés").

Il fut un temps où les extracteurs ne faisaient pas attention aux tables de pointeurs. Il fallait en général les extraire dans un autre fichier qui devait être édité.

Traduire le script

Une fois tout votre script extrait, il ne vous reste qu'à le traduire. Je ne vais pas vous faire de cours de langue (ce n'est pas le but). La traduction vous appartient (et, si vous désirez en savoir davantage sur les principes professionnels de la traduction, je vous invite à lire cet article). En revanche, voici la principale difficulté à laquelle vous devrez faire face : la place.

Ceci est le cauchemar de tout traducteur (par extension, il devient celui du ROMhackeur). Vous imaginez bien que, si vous extrayez un texte de 6 caractères, il va être difficile d'en insérer 7 sans mettre le boxon dans la ROM. Une solution consiste à trouver de la place dans la ROM (partout où il y a des blocs de 00 ou de FF, par exemple - à vous d'expérimenter pour voir si vous ne touchez pas à une partie du programme initial, ce qui ferait planter le jeu de manière monumentale) afin de déplacer le bloc de texte plus grand que l'original. Ceci ne peut se réaliser que si vous avez des pointeurs (eh oui !). Et encore : faites attention aux pointeurs 16 bits qui sont limités puisqu'ils ne sont constitués que de 2 octets (de 00 00 à FF FF, ce qui ne représente que 65 ko : une ROM NES peut faire 256 ko) ; vous ne pourrez donc pas vraiment aller où vous voulez dans la ROM (surtout pas dans une partie dédiée aux graphismes, malheureusement.. sauf en reprogrammant les allocations mémoires).

Pour s'affranchir des problèmes de place, beaucoup de gens essaient de respecter la taille du script initial. Ceci est très efficace mais limite la liberté de mouvement, surtout que les phrases françaises sont en général plus longues de 5% à 10% que les phrases anglaises, elles-mêmes plus longues de 10% à 15% que les phrases japonaises.

Il existe même pire que cela : pour s'affranchir des problèmes des pointeurs ET de place, certains vont jusqu'à traduire le jeu directement dans leur éditeur hexadécimal. S'ils sont très forts en interprétation de texte ("comment faire comprendre la même chose d'une manière différente"), cela peut tout à fait être à leur portée. Dans le cas contraire, ils vont passer du temps à trouver la phrase exacte, souvent au mot-à-mot alors qu'avec un peu de recherche, trouver des pointeurs et extraire le texte simplifie énormément le travail. Ceci dit, si le jeu reste compréhensible pour les anglophobes (et autres japanophobes) alors pourquoi pas. Cela laisse juste un goût d'inachevé, en général.

Une autre difficulté réside dans le respect de la taille des lignes : comptez soi-même le nombre de caractères devient vite très rébarbatif. Des outils comme le Hareng-Tool permettent de faire oublier ce problème. Rien de bien dramatique, n'est-ce pas ?

Insérer le script

A présent, vous avez la traduction dont vous aviez plus ou moins envie. On va supposer que vous avez respecté ce tutoriel et ses mises en garde ainsi que ses "bons" conseils.

La table d'insertion

Comme pour l'extraction, il va vous falloir une table... une table d'insertion. Il s'agit quasiment de la même table que celle utilisée lors de l'extraction. Pourquoi "quasiment" ? Parce que vous n'êtes pas sans savoir que la langue française contient 14 caractères spéciaux : à â é è ê ë î ï ô œ ù û ü ç (à, hâte, été, lèvre, être, aiguë, île, haïr, hôte, œuf, où, sûr, capharnaüm, ça). Il faut donc, dans la mesure du possible, pouvoir insérer ces lettres spéciales dans la police de caractères utilisée pour afficher à l'écran les textes que vous venez de traduire.

Pour cela, il existe quatre cas de figure.

  • La police de caractères possède de la place (normalement, vous avez déjà regardé les entrailles de votre ROM avec un éditeur graphique) : c'est tout de même l'un des meilleurs cas de figure ! Il vous suffit tout simplement de dessiner les lettres manquantes. Leur valeur hexadécimale devrait vous être simple à trouver si vous avez correctement lu la partie sur la création de tables.
  • La police de caractères possède déjà ces lettres : c'est en général le cas pour les jeux récents qui utilisent des tables standardisées. Cherchez sur internet les valeurs hexadécimales de ces standards et vous devriez vous en sortir (pour un codage de la police en 8 bits, c'est rare mais, en 16 bits, c'est beaucoup plus fréquent).
  • La police de caractère n'a aucune place :
    • soit certains caractères ne sont jamais utilisés dans votre script (comme des / < > * ou ce genre de symboles) et, dans ce cas, vous pourrez les remplacer par vos lettres spéciales ;
    • soit vous n'avez que quelques caractères de libres et il va vous falloir faire un choix entre une accentuation partielle (genre à é è ù ç) et pas d'accentuation du tout ;
    • soit vous n'avez aucune place et, en tant que débutant, vous ne pourrez absolument rien faire. Cela passe nécessairement par de l'assembleur et encore : on ne fait pas nécessairement tout ce que l'on veut avec.
  • La police de caractère n'a que des majuscules : en général, on laisse le texte en majuscule, ce qui nous permet d'éviter le problème. Dans Kid Icarus, le texte était initialement en majuscule mais la police possédait également des minuscules. Je m'en suis donc servi, bien entendu ! Il a juste fallu rectifier la couleur de cette police (c'est celle qui est utilisée pour les mots de passe).

Dans le cas où vous auriez traduit votre texte avec des lettres spéciales mais qu'il s'avère finalement que vous n'ayez pas la place d'insérer ces lettres, il existe une technique très simple pour construire sa table d'insertion (plutôt que de se taper des remplacements rébarbatifs à la main). Prenons la table suivante :

  1A=a
  1B=b
  1C=c
  1D=d
  1E=e
  1F=f
  20=g
  21=h
  22=i
  23=j
  24=k
  25=l
  26=m
  27=n
  28=o
  29=p
  ...

Il vous suffit juste d'ajouter vos lettres accentuées qui auront alors les mêmes valeurs que celles leur correspondant sans accent :

  1A=à
  1A=â
  1C=ç
  1E=é
  1E=è
  1E=ê
  1E=ë
  22=î
  22=ï
  28=ô
  281E=œ
  ...

Simple, non ?

L'insertion proprement dite

Une fois votre table d'insertion créée, il vous suffit d'insérer avec votre logiciel favori (Hareng-Tool, Pointer Tables ; certains nostalgiques aiment utiliser UHR) : celui-ci devrait tout faire automatiquement (insertion, calcul des pointeurs), comme je le disais un peu plus haut.

Je rappelle tout de même qu'il existe une difficulté : trouver de la place (cf. paragraphe précédent). Si le script traduit dépasse sa taille initiale, vous devrez opérer quelques manipulations avec les inséreurs de texte. La technique la plus courante consiste à insérer une partie du script puis de déplacer ce qui reste un peu plus loin ; c'est ce qui a été fait pour Kid Icarus. Notez donc bien les pointeurs que vous souhaitez déplacer et découper votre script en deux ou plusieurs morceaux (suivant la place disponible dans la ROM).

Une autre technique consiste à déplacer toute la traduction dans un autre bloc (on peut le faire en général à l'aide de pointeurs 24 ou 32 bits en agrandissant la ROM ; les pointeurs 16 bits sont trop limités pour que l'on puisse effectuer ce genre d'opération sans passer par une bonne dose d'assembleur). Dans ce cas, la manipulation des inséreurs de texte est plus aisée car il ne suffit de changer que la partie "adresse d'insertion" : les pointeurs, je le rappelle, sont calculés automatiquement.

Notez tout de même, comme il a été dit plus haut, que les premiers outils d'extraction étaient incapables d'extraire les pointeurs en même temps. Du coup, il existait deux solutions pour correctement réinsérer le script avec ses pointeurs : ou bien, lors de la réinsertion, il fallait tout recalculer à la main (acceptable pour de petits jeux mais inconcevable pour des RPGs - c'était également une grosse source d'erreurs qui pouvaient potentiellement faire planter le jeu), ou bien il existait des outils dédiés pour recalculer la table de pointeurs qu'il fallait ensuite réinsérer.

Traduire des graphismes

Dans la plupart des jeux, une partie des textes se trouvent sous forme graphique (par exemple, un écran titre ou des options vues dans le jeu comme un "life up"). Il est assez simple de "traduire" ces graphismes, pour peu qu'ils ne soient pas compressés et dans un format connu par nos chers éditeurs graphiques.

En général, les trois que je vous ai proposés plus haut (ma préférence allant vers Tile Molester) s'en sortent très bien. Après, pour Mega Drive ou PlayStation par exemple, il existe d'autres outils spécialement dédiés à des formats particulièrement tordus ou inconnus de nos éditeurs favoris (vous les trouverez bien sûr sur le site de la T.R.A.F).

Ce qu'il y a de particulièrement intéressant avec Tile Molester (successeur de Tile Layer Pro - longtemps considéré comme le meilleur), c'est que l'on peut, à l'instar de son grand frère, extraire les graphismes sous un format modifiable à l'aide de n'importe quel logiciel de retouche d'images (dont Paint) : BMP, PNG, etc. La modification des graphismes vous appartient sachant que, là aussi, vous serez peut-être confrontés à des problèmes de place ou de réutilisation de tiles dans un autre coin de l'image (le cas le plus sadique : un exemple sur Attack of the Killer Tomatoes. Cela ne se voit pas trop car la tile réutilisée donne une impression de saignement, ce qui lui permet de se fondre à peu près dans l'image... ouf).

Sachez également qu'un écran titre fonctionne un peu comme un script : le programme va rechercher les tiles qu'il vaut afficher à l'écran de la même manière qu'il va rechercher les lettres à afficher. C'est ce qu'on appelle la "Tile Map". Si vous parvenez à la retrouver (astuce de la recherche relative dont je parlais plus haut pour les tables incomplètes, par exemple), vous pourrez certainement agrandir un tout petit peu votre espace.

Créer son patch

Pourquoi créer un patch ? Tout simplement parce que cela prend, d'une part, moins de place et que, d'autre part, vous ne conservez que le fruit de votre travail (les lois sur la propriété intellectuelle étant ce qu'elles sont, ne prenons pas trop de risques).

  • Pour tout ce qui est 8 et 16 bits, nous utiliserons le format IPS.
  • Pour tout ce qui est 32 bits et au-delà, c'est un peu à la charge du programmeur. On voit souvent utilisé le format PPF avec des outils comme PPF-o-Matic. Je conseillerais davantage le format proposé par xdelta, ce dernier fonctionnant un peu comme l'IPS mais possédant une capacité beaucoup plus grande.
  • D a créé un format plus versatile permettant de supporter d'autres formats : Ninja.

Créer un patch n'a rien de compliqué. RTFM comme on dit ! Prenons comme exemple le format IPS. Si vous êtes sous Windows et que la ligne de commande ne vous enchante guère, utilisez IPS XP ou Lunar IPS : vous n'aurez qu'à suivre les instructions (qui ne se résument qu'à : choisir votre ROM modifiée, choisir votre ROM originale). Pour UIPS, il s'agit d'une ligne de commande très simple :

  uips c patch.ips ROM_originale.bin ROM_modifiée.bin

Je signale au passage qu'il existe un outil java (donc multi-plateforme - et muni d'une interface) permettant de créer et d'appliquer des patchs : SPI. De cette manière, ceux qui criaient au scandale il y a deux minutes parce que je ne prenais exemple que sur des outils développés pour Windows devraient être satisfaits.

Appliquer un patch se fait avec les mêmes outils (certains étant spécialement dédiés à cela, ce qui les limite fortement dans leur utilisation).