Bandeau article textes en couleur

DBZ Buu’s Fury : Les textes en couleur


Introduction

En préambule, je précise que l’étude présentée n’a pas été créée de toute pièce et fait partie des mes travaux préparatoires à la traduction de DBZ Buu’s Fury en français dont voici l’article de présentation.

Dans le jeu de nombreux textes sont en couleur, et je vais vous expliquer comment utiliser la palette et le mécanisme de colorisation pour bien replacer les couleurs ou les modifier. Le mécanisme de colorisation est le même pour textes d’interface en clairs dans la rom et ceux des dialogues compressés. Je vais cependant détailler celui des dialogues qui possède certaines subtilités.


La palette de couleur

L’ensemble des textes utilisent la même palette de 256 couleurs indexées. Pour reconnaitre et choisir plus facilement les couleurs, j’ai vais extraire la palette et la transformer en tableau de couleurs.

Export du fichier pal de la palette

Palette de couleurs mGBA

Dans mGBA :
> Je lance le jeu et je clique sur Outils > Voir la palette…, puis j’attends l’apparition la palette encadrée ci-contre.
> Je clique sur Exporter l’OBJ pour enregistrer le fichier .pal

Conversion du fichier pal en fichier csv

Ensuite, mon programme Dart affiche et produit un fichier csv : chaque ligne est une couleur représentée par sa position hexadécimale dans la palette, son code RVB et son code HTML.

import 'dart:convert';
import "dart:io";

void main() {
    print("> Lecture du fichier .pal");
    File fichierPal = File("lib/obj_mgba.pal");
    List<code><</code>int> pal =  List.from(fichierPal.readAsBytesSync());

    int positionDebutCouleurs = 24;
    int j = 0;
    List<code><</code>String> listeCouleurs = [];
    print("\n> Liste des couleurs : ");
    for ( int i = positionDebutCouleurs; i < pal.length ; i+=4 ) {
      String couleur =
          "${IntToHex(j)},"
          "${pal[i]},${pal[i+1]},${pal[i+2]},"
          "#${IntToHex(pal[i])}${IntToHex(pal[i+1])}${IntToHex(pal[i+2])}";
      listeCouleurs.add(couleur);
      print(couleur);
      j += 1;
    }

    print("\n> Ecriture du fichier .csv");
    File fichierCsv = File ("lib/obj_mgba.csv");
    fichierCsv.writeAsStringSync(
        listeCouleurs.join("\n"),
        mode:FileMode.write,
        encoding:Utf8Codec());
}

String IntToHex (int val) => val.toRadixString(16).padLeft(2, '0').toUpperCase();
obj_mgba.csv
00,0,0,0,#000000
01,0,0,0,#000000
02,255,255,255,#FFFFFF
03,255,0,0,#FF0000
04,255,132,0,#FF8400
05,255,255,0,#FFFF00
06,0,255,0,#00FF00
07,0,255,255,#00FFFF
...

Conversion du fichier csv en un tableau de couleurs

Enfin, une fois le fichier csv ouvert dans Excel, je créer une macro appliquée à la feuille qui se déclenche  à l’évènement SelectionChange :

J’obtiens le tableau final avec le rendu des couleurs !

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim tHex As String
    If (Left(ActiveCell.Text, 1) = "#" And Len(ActiveCell.Text) = 7) Then
        tHex = Mid(ActiveCell.Text, 6, 2) 
             & Mid(ActiveCell.Text, 4, 2) 
             & Mid(ActiveCell.Text, 2, 2)
         ActiveCell.Offset(0, 1).Interior.Color = WorksheetFunction.Hex2Dec(tHex)
    End If
End Sub

Décodage du texte

Pour la suite, je vais prendre pour exemple le bloc de dialogue suivant :

You have to take a plane. It’s called « The Higher Plane » and it’s docked next to King Yemma’s Castle at the end of Snake Way.

Décodage personnalisé

59 00 6F 00 75 00 20 00 68 00 61 00 76 00 65 00 20 00 74 00 6F 00 20 00 74 00 61 00 6B 00 65 00 20 00 61 00 20 00 70 00 6C 00 61 00 6E 00 65 00 2E 00 20 00 49 00 74 00 27 00 73 00 20 00 63 00 61 00 6C 00 6C 00 65 00 64 00 20 00 22 00 08 00 07 00 54 00 68 00 65 00 20 00 48 00 69 00 67 00 68 00 65 00 72 00 20 00 50 00 6C 00 61 00 6E 00 65 00 08 00 02 00 22 00 20 00 61 00 6E 00 64 00 20 00 69 00 74 00 27 00 73 00 20 00 64 00 6F 00 63 00 6B 00 65 00 64 00 20 00 6E 00 65 00 78 00 74 00 20 00 74 00 6F 00 20 00 08 00 07 00 4B 00 69 00 6E 00 67 00 20 00 59 00 65 00 6D 00 6D 00 61 00 27 00 73 00 20 00 43 00 61 00 73 00 74 00 6C 00 65 00 08 00 02 00 20 00 61 00 74 00 20 00 74 00 68 00 65 00 20 00 65 00 6E 00 64 00 20 00 6F 00 66 00 20 00 53 00 6E 00 61 00 6B 00 65 00 20 00 57 00 61 00 79 00 2E 00

Y�o�u� �h�a�v�e� �t�o� �t�a�k�e� �a� �p�l�a�n�e�.� �I�t�’�s� �c�a�l�l�e�d� � »���T�h�e� �H�i�g�h�e�r� �P�l�a�n�e��[1]� »� �a�n�d� �i�t�’�s� �d�o�c�k�e�d� �n�e�x�t� �t�o� ���K�i�n�g� �Y�e�m�m�a�’�s� �C�a�s�t�l�e��[1]� �a�t� �t�h�e� �e�n�d� �o�f� �S�n�a�k�e� �W�a�y�.�

You have to take a plane. It’s called « \x08\x07The Higher Plane\x08\x02 » and it’s docked next to \x08\x07King Yemma’s Castle\x08\x02 at the end of Snake Way.

Dans la rom, le texte en hexadécimal est manifestement encodé en UCS2-2LE.

Cela a deux conséquences :
– Chaque caractère est codé sur 2 octets dans une plage théorique de 0000 à FFFF, ce qui équivaut à 65336 caractères possibles.
– Chaque groupe de 2 octets est ordonné en petit-boutiste (little-endian LE), l’octet de poids faible est en deuxième position.
Exemple : la lettre Y est codée en 59 00

Le jeu n’utilise que la plage 00 à FF donc le deuxième octet est toujours à 00, ce qui donne cette impression de séparateur entre chaque caractère.

Pour traduire le texte facilement, il faut le décoder dans une représentation « humaine ».
Les éditeurs hexadécimaux ou textuels n’y parviennent que partiellement, avec des points d’interrogations ou des caractères bizarres.

C’est ainsi que j’ai créé mon propre décodage qui supprime le 2ème octet de chaque caractère et échappe les caractères de contrôle en affichant l’octet brut préfixé de ‘\x’.


Mécanisme de colorisation

Définition d’une couleur

Par défaut, le texte d’un bloc de dialogue est en blanc (n°03 dans la palette).

Pour le coloriser il faut écrire deux octets à la suite :

1er octet : \x08 <- marqueur de colorisation
2ème octet : numéro hexadécimal de la couleur dans la palette

Donc \x08\x07 signifie : afficher le texte qui suit avec la couleur n°07 (cyan)

Dbz Buu's Fury, Discussion Goku et Kaio multicolor

Un joli arc-en-ciel :

You have to take a plane. It’s called « \x08\x03T\x08\x04h\x08\x05e\x08\x06 H\x08\x07i\x08\x08g\x08\x09h\x08\x0Ae\x08\x02r Plane » and it’s docked next to King Yemma’s Castle at the end of Snake Way.

Portée de la colorisation

La couleur s’applique jusqu’à la définition d’une autre couleur ou sinon jusqu’à la fin du bloc de dialogue.
Dans l’exemple du jeu, le cyan et le blanc s’alternent, d’où les enchaînements de \x08\x07 et \x08\x02.

La couleur n’est pas réinitialisée après un saut de fenêtre, qu’il est important de différencier d’une fin de bloc.

Le saut de fenêtre change de fenêtre sans effet de transition, et c’est toujours le même personnage qui parle.
Ce saut peut-être :
– Automatique : Quand la fenêtre est remplie et qu’il reste encore du texte à afficher du bloc de dialogue.
– Manuel : Quand le saut de fenêtre est écrit avec \x0B. Cela permet d’aérer la lecture en affichant moins de texte dans une fenêtre.

La fin d’un bloc de dialogue ferme la fenêtre avec un effet de transition.
Cela se produit quand un personnage a finis de parler pour qu’un autre personnage prenne la parole, que le joueur reprenne le contrôle, ou qu’une cinématique se lance.
Cependant, il arrive aussi que le même personnage enchaine avec un autre bloc de dialogue, ce qui ménage une pause dans la lecture ou un effet de suspens.

Dbz Buu's Fury, Discussion Goku et Kaio avec couleur cyan qui reste

Dans cet exemple, la couleur cyan s’applique jusqu’à la fin du bloc de dialogue.

You have to take a plane. It’s called « \x08\x07The Higher Plane » and it’s docked next to King Yemma’s Castle at the end of Snake Way.


Un commentaire

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *