Texte et polices

Annexe technique · Accueil · English

Le texte est décodé. Voir game-text.txt.

1. Couches d'encodage

G3.CON rec 0x29 → 5-bit codes → glyph bytes → font atlas → pixels
                  Txt_Decode5Bit             Vid_DrawGlyph

Le texte échappait aux recherches antérieures parce qu'il n'est ni en ASCII ni en données de glyphes alignées sur l'octet.

2. Octets de glyphes (vérifié)

byte = glyph index + 1.

Indice Caractères
0-25 a-z
26-51 A-Z
52-61 0-9
62-74 â ä à ç é ê ë è î ï ô ö ò (lus d'après les formes)
75, 76, 97, 98 vide
77-79 û ù ü (lus d'après les formes)
80-96 % " ' . , ; : ! ? / ( ) + - = ° ß (lus d'après les formes)

Octets spéciaux : 0x00 termine une chaîne, 0x65 passe à la ligne, 0x4C (indice 75) est l'espace entre les mots, que Txt_DrawIndexed teste en 0x15913. L'ordre des lettres et des chiffres, et tout le français décodé, confirment la table ; les accents et la ponctuation viennent de leurs formes.

3. Chaînes sur 5 bits : Txt_Decode5Bit EA 0x11402 (vérifié)

Entrée far 0x84:0xBC2. Arguments : pointeur far des bits, pointeur far des tailles, pointeur far de destination, indice.

  • Les tailles sont des longueurs u16 gros-boutiennes en octets. Début = somme des tailles avant l'indice.
  • Les codes font 5 bits, bit de poids fort d'abord (Txt_Read5Bits EA 0x114A2).
  • Le code n choisit page[n-1]. La page 0 est en DS:429. Le code 0x1E passe à la page 1 (DS:446) et 0x1F à la page 2 (DS:463), pour le code suivant seulement.
  • Le code 0 lirait l'octet précédant la table ; un texte correct ne l'utilise pas.
  • Au dernier octet (0x11478), un code de plus est lu s'il reste au moins 5 bits dans cet octet (mask >= 0x10) ; il n'est stocké que s'il est non nul.

La page 0 se décode en easrniutol.dc pmhvb\nfgé-'!,L, clairement adaptée au français.

4. Où sont les chaînes

Bits Tailles Chaînes Utilisées par
DS:1B06 DS:1BFD 20 crédits d'introduction Intro_OpShowCredit
G3.CON enr. 0x29 sous-enr. 0 enr. 0x28 sous-enr. 0 1 589 chaînes du jeu en 7 banques MAUPITI1, par les services 2 et 9

Les crédits comprennent LANKHOR présente et Copyright (c) 1990.

Banques de texte du jeu (vérifié)

MAUPITI1.EXE ajoute ces constantes aux deux pointeurs pour choisir une banque. Txt_DrawFromBank EA 0x1FD70 prend une classe de texte et la convertit par un tableau local (5,3,1,2,7,4,6), donc les numéros de classe dans le code diffèrent des numéros de banque. Chaque banque a ses propres numéros de chaînes, et les appels les comptent à partir de 1 : Game_AddEnergy affiche la classe 3, chaîne 37 + condition/20, soit l'entrée 36 de la banque 1, « Lessivé ». Txt_DrawLinesBank12 EA 0x1F230 choisit directement la banque 1 ou 2.

Banque Classe Chaînes Octets de la table de tailles Octets de texte Contenu, d'après un échantillon
1 3 235 0x1D6 0x6CE verbes, menus, messages courts
2 4 80 0xA0 0x240 noms d'objets
3 2 483 0x3C6 0x239E textes d'examen et d'objets
4 6 102 0xCC 0x270C longs documents : parties d'échecs, texte de la grotte et quelques chaînes qui semblent chiffrées
5 1 103 0xCE 0x104A événements de l'histoire
6 7 135 0x10E 0x6A0 questions et réponses
7 5 451 0x386 0x46C0 dialogues des personnages

Les tailles correspondent exactement aux enregistrements 0x28 (3 178 o) et 0x29 (45 410 o). Les banques sont alignées sur le mot : les chaînes de la banque 1 totalisent 1 741 o et celles de la banque 7 18 111 o, chacune avec un octet de remplissage. Aucune chaîne n'utilise le code invalide 0.

5. Polices

Deux descripteurs marqués aMpu, de 99 glyphes chacun. Vid_DrawGlyph utilise celui vers lequel pointe wFontDescSeg:wFontDescOfs.

Champ Signification DS:1522 (EA 0x1B942) DS:1F11 (EA 0x1C331)
+0x4E u8 lignes 8 7
+0x5C u16 atlas 110 110
+0x60 u16 pas des lignes 68 56
+0x62 u16 enregistrements {u16 bit offset, u16 ink width} 654 502
+0x66 u16 table d'avance 1050 898
+0x6A u16 table de décalage 1248 1096
encre totale / capacité d'une ligne (bits) 515 / 544 438 / 448
octets d'atlas permutés 544 392

advance == ink + 1 pour 95 glyphes sur 99 ; les exceptions sont les vides, avec des avances de 6, 6, 6, 4.

Installation : Font_LoadCharset installe la police de 8 lignes en 0x16F65 ; Font_SelectDescriptor EA 0x1734A installe celle de 7 lignes.

Lire l'atlas

Font_ByteswapBlock EA 0x1733C permute une fois chaque mot de 16 bits aligné de l'atlas. Après cela, chaque ligne est un simple flux de bits, poids fort d'abord. Pour lire un glyphe, Vid_DrawGlyph prend deux octets en gros-boutien en offset >> 3, décale à gauche de offset & 7 et échantillonne l'octet haut, soit au plus 8 pixels par glyphe. Certains glyphes de 8 lignes ont une largeur d'encre jusqu'à 11 ; le code les coupe à 8 pixels, et l'atlas le montre.

Permutez d'abord les mots. Lire le fichier en petit-boutien au même décalage n'est juste que pour les décalages pairs, et donne faux 47 des 99 glyphes de la police de 7 lignes.

6. Dessin

Vid_DrawGlyph EA 0x11590, pour chaque glyphe :

  1. Indice du glyphe = AL - 1.
  2. Ajoute nudge[index] à wCanvasX, et dessine à cette position avec wTextColorCur.
  3. Retire le décalage, puis ajoute advance[index] (0x1164D-0x11663).

Le texte est donc proportionnel. Vid_DrawString EA 0x11858 dessine jusqu'à 0x00 ou 0x65, copie wTextColor (DS:D4) dans wTextColorCur (DS:496) et ajoute un espacement supplémentaire fourni par l'appelant. Txt_DrawIndexed lit aussi la table d'avance pour mesurer le texte (0x158DF).

Appelants :

service 9 → Txt_DrawIndexed EA 0x157C3    (also Intro_OpShowCredit x3)
service 2 → Vid_DrawTextLines EA 0x15A38 → Vid_DrawString → Vid_DrawGlyph
                                           Txt_Decode5Bit at 0x15AC4
Vid_DrawStringEx EA 0x1188C → Vid_DrawGlyph

Txt_DrawIndexed appelle Txt_Decode5Bit en 0x15822 et 0x158A7. Son bloc de 28 mots contient la couleur en +0xC, y en +0x18, x en +0x1C, le tampon de chaîne en +0x28, les tailles en +0x2C, les bits en +0x30, et un numéro de chaîne à partir de 1 en +0. Vid_DrawTextLines avance de 10 par ligne (0x15C01, 0x15CCA).

Le retour à la ligne basé sur 0x4C et tout dessin par Txt_DrawIndexed au-delà de ses étapes de décodage et de mesure n'ont pas été suivis en entier.

7. Script d'introduction

Font_LoadCharset EA 0x16F04 est en réalité l'introduction (Intro_Run dans Binary Ninja). Il installe la police de 8 lignes, décode rec 0x27 sub 2 dans la page, le copie dans wPage2Seg, puis exécute le script en DS:1C25 :

Opcode Routine Action
0 0x17107 copie la page
4 0x17126 (IDA Font_LoadStrings) décode rec 0x27 sub n en x, y
8 0x1716B service 0x12
0xC 0x171A4 affiche une chaîne de crédit
0x10 0x172D7 étape temporisée (déduit)
0xFF contrôle de fin

L'enregistrement 0x27 contient donc des images et de la musique d'introduction, ainsi que d'autres ressources que MAUPITI1 charge au démarrage (Les deux programmes). Il ne contient ni polices ni chaînes.

Précédent : Vidéo · Suivant : Parole · Annexe technique · Accueil