Le format de sauvegarde Gen 1 : Pokémon Rouge, Bleue & Jaune

Où se trouve quoi dans une sauvegarde Génération 1 de 32 Kio : adresses, sommes de contrôle, structure d'un Pokémon, boîtes du PC et encodage du texte. Vérifié sur les désassemblages pret et sur de vraies cartouches.

Une sauvegarde de Génération 1, c’est 32 Kio de SRAM sauvegardée par pile, et presque tout y est vide. Ce qui compte tient dans trois régions, protégées par trois sommes de contrôle, et une fois qu’on sait où elles sont le fichier cesse d’être opaque.

Tout ce qui suit est vérifié sur les désassemblages pret de Rouge, Bleue et Jaune — ram/sram.asm et ram/wram.asm — puis confronté à de vrais dumps de cartouches françaises et anglaises. Les tableaux sont générés à partir des constantes que l’analyseur de ce site utilise pour lire vos imports : ils ne peuvent donc pas se démoder en silence, puisque toute modification du code se répercute ici.

Le fichier

Une cartouche Gen 1 embarque 32 Kio de SRAM, répartis en quatre banques de $2000 octets. Une sauvegarde en est le décalque linéaire, dans l’ordre : une adresse dans le fichier est une adresse dans la SRAM, sans conversion.

Trois de ces banques servent à quelque chose :

Un fichier de 32 768 octets exactement est le cas normal. Les fichiers plus gros sont fréquents et généralement sains : certains lecteurs de cartouche lisent le maximum de SRAM adressable par le MBC au lieu de la taille annoncée dans l’en-tête, ce qui donne 128 Kio pour le MBC5 de Jaune, la vraie sauvegarde occupant les 32 premiers Kio. Tout ce qui dépasse $8000 peut être ignoré.

Où se trouve quoi

Les adresses sont des positions absolues dans le fichier. La colonne des symboles donne le nom de la région dans le désassemblage, utile si vous recoupez avec les sources pret.

Adresse Octets Symbole Champ
0x2598 11 wPlayerName Nom du joueur, terminé par un marqueur
0x25A3 19 wPokedexOwned Pokédex, Pokémon possédés : un bit par espèce
0x25B6 19 wPokedexSeen Pokédex, Pokémon vus : un bit par espèce
0x25C9 42 wNumBagItems Sac : nombre d’objets, puis paires (identifiant, quantité)
0x25F3 3 wPlayerMoney Argent, en décimal codé binaire
0x2602 1 wObtainedBadges Badges, un bit chacun dans l’ordre des arènes
0x2605 2 wPlayerID Identifiant de dresseur, 16 bits, fixé au lancement
0x260A 1 wCurMap Identifiant de la carte courante
0x260D 1 wYCoord Position Y du joueur, en pas de marche
0x260E 1 wXCoord Position X du joueur, en pas de marche
0x27E6 102 wNumBoxItems Objets déposés au PC : nombre, puis paires (identifiant, quantité)
0x284C 1 wCurrentBoxNum Boîte sélectionnée, sur les 7 bits de poids faible, à partir de 0
0x2852 32 wToggleableObjectFlags Drapeaux du décor : un bit par objet au sol ou sprite escamotable
0x299C 14 wObtainedHiddenItemsFlags Drapeaux des objets cachés, un bit par emplacement
0x29F3 320 wEventFlags Drapeaux d’événements : chaque dresseur battu, chaque action unique
0x2CED 5 wPlayTimeHours Temps de jeu : heures, drapeau de saturation, minutes, secondes, images
0x2F2C 404 wPartyCount Équipe : comptage, liste d’espèces, 6 structures, noms de dresseurs, surnoms
0x30C0 1122 wBoxCount La boîte du PC sélectionnée, copie de référence
0x3523 1 wMainDataCheckSum Somme de contrôle principale, sur 0x2598-0x3522

La somme de contrôle principale

La banque 1 est protégée par un octet unique en 0x3523. C’est le complément à un de la somme de tous les octets de 0x2598 à 0x3522 inclus, tronquée à huit bits :

somme = 0
pour adresse de 0x2598 à 0x3522 :
    somme = (somme + octet[adresse]) & 0xFF
controle = (~somme) & 0xFF

Le jeu refuse une sauvegarde dont la somme ne tombe pas juste, et vous devriez en faire autant. C’est aussi pourquoi on ne modifie pas une sauvegarde en changeant un octet dans un éditeur hexadécimal : toute retouche dans cette plage oblige à recalculer cet octet.

Regardez bien ce que la plage couvre. Elle commence au nom du joueur et s’arrête juste avant la somme elle-même : elle inclut donc l’équipe et la boîte du PC sélectionnée — mais pas les onze autres, qui vivent dans leurs propres banques avec leurs propres sommes.

Les boîtes du PC

Les douze boîtes se répartissent sur deux banques : les boîtes 1 à 6 commencent en 0x4000, les boîtes 7 à 12 en 0x6000. Chaque boîte occupe 0x462 octets, disposés comme la région de l’équipe mais avec de la place pour vingt Pokémon au lieu de six.

Chaque banque porte sa propre somme de contrôle, calculée comme la principale, sur les six boîtes de la banque et rangée dans l’octet qui les suit immédiatement — soit 0x4000 + 6 × 0x462 pour la première. Sur une sauvegarde où le joueur n’a jamais ouvert le PC, ces banques ne sont pas initialisées et leurs sommes ne tombent pas juste : il faut y lire « pas de boîtes ici » et non « fichier corrompu ».

Un piège mérite d’être signalé. La boîte sélectionnée existe en double : une fois dans sa banque, une fois en 0x30C0 dans la banque 1. C’est la seconde qui fait foi. Le jeu ne réécrit la copie de banque qu’au changement de boîte, si bien que sur une sauvegarde prise en cours de partie les deux peuvent diverger, et c’est la copie de banque qui est périmée. Lisez la boîte active — son numéro tient dans les sept bits de poids faible de 0x284C, plus un — depuis 0x30C0, et les onze autres depuis leurs banques.

Comment un Pokémon est rangé

Les régions de boîte et celle de l’équipe partagent une disposition : un octet de comptage, une liste d’index d’espèces close par un terminateur 0xFF, les structures, les noms des dresseurs d’origine, puis les surnoms. Chaque champ de nom fait onze octets, rempli ou non.

La structure fait 33 octets en boîte et 44 dans l’équipe. Les 33 premiers sont identiques ; les onze octets supplémentaires de l’équipe contiennent les PV actuels, le statut, le niveau et les cinq statistiques calculées — que le jeu recalcule de toute façon. Les octets 5 et 6 sont les deux octets de type de l’espèce, copiés depuis ses statistiques de base — les valeurs qui indexent la table des types de première génération.

Décalage Octets Champ
+0x00 1 Espèce, sous forme d’index interne
+0x03 1 Niveau, copie partagée — sert à restaurer un Pokémon en boîte
+0x08 4 Identifiants des attaques, un octet chacun
+0x0E 3 Expérience, sur 24 bits
+0x11 10 Expérience de stats : PV, Attaque, Défense, Vitesse, Spécial, 16 bits chacune
+0x1B 2 DV, quatre quartets : Attaque, Défense, Vitesse, Spécial
+0x21 1 Niveau, équipe seulement — celui qui fait autorité

Deux détails piègent régulièrement.

L’octet d’espèce n’est pas le numéro du Pokédex. La Gen 1 range un index interne, héritage d’un ordre de développement sans rapport avec le Pokédex national. Mew vaut 0x15, Bulbizarre 0x99. Il faut une table de correspondance dans les deux sens ; le désassemblage la fournit dans constants/pokemon_constants.asm.

Il y a deux octets de niveau. L’un en +0x03, dans les 33 octets partagés, l’autre en +0x21, propre à l’équipe. C’est +0x21 qui fait autorité pour un Pokémon de l’équipe, et +0x03 qui sert à restaurer un Pokémon sorti d’une boîte. Écrivez les deux.

DV et expérience de statistiques

Les DV — les ancêtres Gen 1 des IV — sont rangés en quatre quartets sur deux octets à partir de +0x1B : Attaque et Défense dans le premier, Vitesse et Spécial dans le second, poids fort puis poids faible. Chacun va de 0 à 15.

Le DV de PV n’est stocké nulle part. Il se déduit du bit de poids faible des quatre autres :

dv_pv = ((atq & 1) << 3) | ((def & 1) << 2) | ((vit & 1) << 1) | (spe & 1)

D’où le fait qu’un Pokémon dont les quatre DV valent 15 a aussi un DV de PV parfait, et qu’on ne peut pas régler les PV indépendamment du reste.

L’expérience de statistiques — ce que les générations suivantes ont remplacé par les EV — tient en cinq valeurs de 16 bits, poids fort en tête, à partir de +0x11, dans l’ordre PV, Attaque, Défense, Vitesse, Spécial. Chacune monte à 65 535 et apporte floor(ceil(sqrt(ev)) / 4) à la statistique calculée.

Le texte

La Gen 1 n’utilise pas l’ASCII, mais un encodage maison décrit dans constants/charmap.asm :

Le reste, c’est la ponctuation et les glyphes propres au jeu : 0xE1 et 0xE2 forment les deux moitiés de la ligature Pk/Mn, 0xEF et 0xF5 sont les symboles mâle et femelle, et deux codes distincts s’affichent tous deux comme un point.

Un champ de nom fait onze octets terminateur compris, soit dix caractères utiles. Les octets qui suivent le terminateur contiennent ce qui s’y trouvait avant : ne les supposez pas remis à zéro.

Les cartouches non anglaises utilisent la même disposition. Une sauvegarde française, allemande ou espagnole range ses régions exactement aux mêmes adresses ; seul le texte diffère, ces ROM attribuant les caractères accentués à des codes que la table anglaise n’utilise pas. Les espèces étant numériques, un outil anglophone lit une sauvegarde française sans la moindre conversion. Seuls les noms ressortent abîmés, et seulement s’ils portent un accent.

Jaune ne fait pas exception : la comparaison de sram.asm entre les désassemblages Rouge/Bleue et Jaune ne donne aucune différence. Un analyseur écrit pour Rouge lit une sauvegarde Jaune sans la moindre modification.

Ce que la sauvegarde ne contient pas

Aucun champ n’indique quel jeu l’a écrite. Rien, dans une sauvegarde Gen 1, ne dit Rouge, Bleue ou Jaune. La chose surprend, et mieux vaut l’annoncer franchement : on peut y perdre beaucoup de temps.

On suggère en général de déduire la version du starter, mais le starter n’est pas rangé en tant que tel — seuls les Pokémon le sont, et quand une sauvegarde devient intéressante, le starter d’origine a pu être échangé, avoir évolué ou être rangé derrière onze autres Pokémon. Se fonder sur les drapeaux du Pokédex ne vaut pas mieux : une sauvegarde assez précoce pour être distinctive est une sauvegarde presque vide.

Pour distinguer deux sauvegardes, servez-vous du nom du dresseur associé à son identifiant sur 16 bits, en 0x2605. Cet identifiant est fixé au lancement de la partie et ne bouge plus jamais, ce qui fait du couple une identité fiable pour une cartouche, valable pour toutes les sauvegardes qu’elle produira. C’est ce que ce site utilise pour reconnaître à quelle cartouche appartient un import.

En vrac

L’argent occupe trois octets en décimal codé binaire en 0x25F3 : 0x00 0x99 0x99 vaut donc 9 999 ₽, et le jeu plafonne son affichage à 999 999 ₽.

Les badges tiennent dans un champ de bits en 0x2602, un bit par badge, dans l’ordre des arènes : Roche, Cascade, Foudre, Prisme, Âme, Marais, Volcan, Terre. Compter les bits à 1 donne le nombre de badges affiché sur la carte de dresseur.

Le Pokédex occupe deux champs de bits de dix-neuf octets — les Pokémon possédés en 0x25A3, ceux vus en 0x25B6. Le bit n de l’octet m désigne le numéro m × 8 + n + 1, poids faible en premier. Dix-neuf octets offrent 152 bits pour 151 espèces : le bit de poids fort du dernier octet ne sert pas. Un Pokémon peut être vu sans être possédé, l’inverse n’a pas de sens, et le jeu imprime volontiers un diplôme dès que tous les bits « possédé » sont mis, quelle que soit la manière dont ils y sont arrivés — c’est précisément ce qui rend possibles les 151 sur une seule cartouche, alors qu’aucune version ne permet de tous les attraper.

Le temps de jeu occupe cinq octets en 0x2CED : les heures, un drapeau signalant le compteur saturé, puis les minutes, les secondes et les images.

Votre position tient dans l’identifiant de carte en 0x260A et les coordonnées en 0x260D et 0x260E, comptées en pas de seize pixels depuis le coin supérieur gauche de la carte courante, et non en pixels.