Phantasy Star III: Generations of Doom/FrenchNotes: Difference between revisions

From Data Crystal
Jump to navigation Jump to search
 
(15 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{subpage}}
{{notes|game=Phantasy Star III}}
{{notes|game=Phantasy Star III}}


Line 18: Line 20:
=== Patterns Non-compressés ===
=== Patterns Non-compressés ===


Quelques graphismes sont non-compressés, par exemple l'écran-titre et la police. Voir la [[Phantasy_Star_III:ROM_map|ROM map]].
Quelques graphismes sont non-compressés, par exemple l'écran-titre et la police. Voir la [[Phantasy Star III:ROM map|ROM map]].


=== Patterns Compressés ===
=== Patterns Compressés ===


La plupart des graphismes (tiles, persos) sont compressés à l'aide de l'algorithme Nemesis (voir [http://segaretro.org/Nemesis_compression ici] pour plus de renseignements).
La plupart des graphismes (tiles, persos) sont compressés à l'aide d'une modification de l'algorithme Nemesis : voir [http://segaretro.org/Nemesis_compression ici] pour plus de renseignements, mais attention, ici l'algorithme a été légèrement modifié.
 
Je dois encore analyser comment, mais j'ai écrit un décompresseur, encore obscur :
 
 


Voir la ROM map.
Voir la ROM map.
Line 31: Line 37:


== Objets ==
== Objets ==
Les Objets (terminologie assez pourrie) sont des entités assez générales, qui ont comme principal point commun d'avoir leur propre routine de rafraîchissement exécutée lors de chaque vblank.
Par exemple,
* un NPC
* une sortie (sauf temples de Laya, palais englouti, zones de transformation de Wren)
* un "cycleur de couleurs"
* les piliers et portails dans les villages, les ponts sur les cartes, ...
Mais aussi :
* un chargeur de NPCs (qui va donc créer d'autres objets)
* un chargeur de sorties (même remarque)
* un détecteur de sortie vers tout temple de Laya (un seul objet pour tous les temples, alors que les sorties "classiques" ont un objet par sortie)
Dans un certain sens, les PCs sont des objets "enrichis" (avec un peu plus de paramètres)
=== Organisation en mémoire ===
Les Objets sont situés en RAM 0xFFC300, en blocs de 0x40 octets :
* 0x00 (b) : flags


== Cartes ==
== Cartes ==
Une carte est formée de deux layers qui utilisent chacun le bit priority, ce qui fait qu'il peut être plus simple de considérer qu'il y a 4 layers (en général, au moins l'une est vide).
Chaque couche est formée de tiles, elles-mêmes de 4x4 patterns (d'où une taille de 32x32 pixels), et d'informations sur leurs propriétés (obstacles ou non par exemple).
Les patterns sont chargés en VRAM lors de la lecture de la table des chargements.
Les tiles sont lues dans une table spécifiques, ainsi que la composition des layers.
=== Codage des Tiles ===
L'adresse de début du buffer source des données compressées est déterminée au moment de la lecture de la table des chargements.
==== Décompression ====
Le buffer des données décompressées est formé de séquences de 0x22 octets, numérotées à partir de 0.
Il est construit de la façon suivante :
* la première séquence est formée par 0x0000, puis 0x20 fois 0x0100
* ensuite, on lit un octet X depuis la source :
** si c'est 0xFF, la décompression est terminée
** si c'est 0x00, l'octet suivant désigne le numéro de séquence, et les 0x22 octets suivants sont les valeurs de celle-ci
** sinon X est le numéro de la séquence, les 5 octets suivants sont un masque. Seuls les bits 0 à 0x22 sont pertinents :
*** si le bit du masque est à 1, le prochain octet de la séquence courante est le même que celui correspondant dans la dernière séquence décodée
*** si le bit du masque est à 0, le prochain octet de la séquence courante est le prochain octet lu dans source
==== Signification ====
Le premier mot est attribute_id. Il réfère à une entrée dans la table des collisions.
Les 16 mots suivants sont les pattern_ids des 16 patterns formant la tile, donnés en colonnes.
Par exemple, la première séquence des données décompressées est toujours 0x0000 suivi de 0x20 fois 0x0100, ce qui signifie que
=== Codage des collisions ===
Elle est formée de ?? entrées de 16 octets, chaque octet décrivant un attribut d'un des 16 blocs 8x8 formant une tile, données en colonne.
Valeurs de ces entrées :
* 00 : pas de collision
* ?? : à creuser
=== Codage des layers ===
Les layers sont chargées par les commandes 0x14.
==== Décompression ====
Le système de compression est similaire à celui utilisé pour les tiles.
Cette fois, les données décompressées sont des séquences de 0x10 octets, construites de la façon suivante :
* On lit un octet X depuis la source
** si X = 0xFF, c'est terminé
** si X = 0xC0,
*** le mot suivant est le numéro de la séquence en cours
*** les 0x10 octets suivants codent le contenu de la séquence en cours (en clair)
** sinon
*** X et l'octet suivent forment un mot qui est le numéro de la séquence en cours,
*** le mot suivant est le masque et pour chaque bit du masque
**** si le bit est à 0, le prochain octet de la source est le prochain octet de la séquence
**** si le bit est à 1, le prochain octet de le séquence en cours es égal à l'octet correspondant dans la dernière séquence décodée
==== Signification ====
Le buffer décompressé donne les tiles formant la layer, en ligne.


== Scènes ==
== Scènes ==
Line 39: Line 129:


La plupart des scènes sont un assemblage cartes / NPCs / musique / autres infos, mais certaines scènes ne sont pas des cartes.
La plupart des scènes sont un assemblage cartes / NPCs / musique / autres infos, mais certaines scènes ne sont pas des cartes.
=== Table des initialisations ===
Table en 0x1B87A, démarrant par des offsets (w) vers chaque entrée.
Une entrée est une liste terminée par un FFFF. Chaque entrée de la liste est de la forme :
* 00 (w) : compteur n,
* 02 - (w) : (n + 1) offsets qu'il faut rajouter à l'adresse de début de l'offset pour avoir data_addr
En data_addr on trouve les 8 premiers octets d'un Objet (voir section Objets) :
* 00 (b) : flags
* 01 (b) : param_1
* 02 (w) : param_2
* 04 (l) : ptr_to_action_routine
Lorsque l'objet est traité la première fois, l'action_routine est exécutée.
Certaines de ces action_routines sont générales, d'autres spécifiques à une carte ou une scène.
Voici quelques action_routines :
* 0x1BB6 (load_NPCs) : crée les objets représentant les NPCs de village
* 0x245C (load_exits) : Lit la table des sorties de cette scène
* 0x27E4 (load_pillars) : crée les objets représentant les piliers de châteaux dans les villages
* 0x2A66 (load_gates) : crée les objets représentant les portails de châteaux dans les villages
* 0x11F7E (load_mieu) : objet représentant Mieu dans la carte du dôme de Landen au début du jeu
* 0x13D2A (load_miun) : crée l'objet "Miun" dans Aridia
* 0x176F4 (load_color_cycling) : crée un objet faisant cycler les couleurs dans une palette
* 0x172D0 (load_boat) : crée l'objet représentant le bateau dans le dome de Landen
* 0x177B0 (load_bridge_in_landen) : objet représentant un pont dans le dome de Landen
* de 0x19122 à 0x1915E (load_airports) : crée un objet qui teste si la party passe sur un aéroport dans le cas où Wren possède les Aeroparts. Une seule entrée pour tous les aéroports de la carte. Une routine par monde. Voir plus loin (un autre jour) pour plus de détails.
* 0x191FE : Même chose, pour les subparts
* 0x19C6A : Teste si le groupe entre dans un temple de Laya
* 0x1A7E8 : objey testant les ports (lorsque Wren est dans le groupe et dispose des aquaparts)


=== Table de paramètres ===
=== Table de paramètres ===
Line 72: Line 194:
* type = 0x20 : copie n octets de source + quest_id*32 vers 0xFFDD40 + destination (palettes)
* type = 0x20 : copie n octets de source + quest_id*32 vers 0xFFDD40 + destination (palettes)


La table est dumpée [ici Phantasy_Star_III:DumpTableLoadings].
La table est dumpée [[Phantasy Star III:DumpTableLoadings|ici]].


=== Table des ajustements ===
=== Table des ajustements ===
Line 83: Line 205:
* 01 (b) : event_id (voir ROM map)
* 01 (b) : event_id (voir ROM map)
* 02 (w) : scene_id
* 02 (w) : scene_id
Si numéro de quête = quest_id et si l'event de evenet_id est True, alors le numéro de carte actuel est remplacé par scene_id.
Si numéro de quête = quest_id et si l'event de event_id est True, alors le numéro de carte actuel est remplacé par scene_id.
 
=== Table des Sorties ===
 
Une table contient la liste des emplacements de la scène où l'on doit passer à une autre scène. Elle démarre en 0x34E4A, par des offsets vers chaque entrée (seules les scènes dont l'id va de 0 à 0x380 sont concernées).
 
Chaque entrée est une liste (taille variable) de format :
* 00 (w) : nombre d'éléments - 1 (0xFFFF si vide) puis, pour chaque élément :
** 00 (w) : x, coordonnée x de la sortie dans la scène courante
** 02 (w) : y, coordonnée y de la sortie dans la scène courante
** 04 (w) : scene_id, id de la scène de sortie
** 06 (w) : x_new, coordonnée x dans la nouvelle carte
** 08 (w) : y_new, coordonnée y dans la nouvelle carte
** 0A (b) : w, largeur de la sortie
** 0B (b) : h, hauteur de la sortie
** 0C (b) : c ?
** 0D (b) : d ?
** 0E (b) : e ?
** 0F (b) : f ?
 
Un dump de cette table est disponible [[Phantasy Star III:DumpTableExits|ici]].


== Batailles ==
== Batailles ==


== Stats ==
== Stats ==

Latest revision as of 21:17, 28 January 2024

This is a sub-page of Phantasy Star III: Generations of Doom.

Chip tiny.png The following article is a Notes Page for Phantasy Star III: Generations of Doom.

Ces notes ne concernent que les versions US et européennes (les adresses sont différentes pour la version japonaise).

Elles sont encore incomplètes. Certains renseignements proviennent de la page de Hugues Johnson (sections hacking-rom, hacking et aridia wiki).

J'utilise la terminologie du document genvdp de Charles McDonald pour ce qui concerne la gestion des graphismes.

Pour le jeu lui-même :

  • Les Objets sont en général représentés par des sprites. Ce sont les PC, les NPC, et certains autres objets (par exemple les portails de châteaux, dans les villes, qui peuvent être ouverts ou fermés).
  • Les Cartes sont "vides", formées de deux Layers et d'informations de collisions.
  • Une Scène est la donnée d'une carte, de palettes, d'Objets.

Graphismes

Palettes

Patterns Non-compressés

Quelques graphismes sont non-compressés, par exemple l'écran-titre et la police. Voir la ROM map.

Patterns Compressés

La plupart des graphismes (tiles, persos) sont compressés à l'aide d'une modification de l'algorithme Nemesis : voir ici pour plus de renseignements, mais attention, ici l'algorithme a été légèrement modifié.

Je dois encore analyser comment, mais j'ai écrit un décompresseur, encore obscur :


Voir la ROM map.

Police

Textes

Objets

Les Objets (terminologie assez pourrie) sont des entités assez générales, qui ont comme principal point commun d'avoir leur propre routine de rafraîchissement exécutée lors de chaque vblank.

Par exemple,

  • un NPC
  • une sortie (sauf temples de Laya, palais englouti, zones de transformation de Wren)
  • un "cycleur de couleurs"
  • les piliers et portails dans les villages, les ponts sur les cartes, ...

Mais aussi :

  • un chargeur de NPCs (qui va donc créer d'autres objets)
  • un chargeur de sorties (même remarque)
  • un détecteur de sortie vers tout temple de Laya (un seul objet pour tous les temples, alors que les sorties "classiques" ont un objet par sortie)

Dans un certain sens, les PCs sont des objets "enrichis" (avec un peu plus de paramètres)

Organisation en mémoire

Les Objets sont situés en RAM 0xFFC300, en blocs de 0x40 octets :

  • 0x00 (b) : flags

Cartes

Une carte est formée de deux layers qui utilisent chacun le bit priority, ce qui fait qu'il peut être plus simple de considérer qu'il y a 4 layers (en général, au moins l'une est vide).

Chaque couche est formée de tiles, elles-mêmes de 4x4 patterns (d'où une taille de 32x32 pixels), et d'informations sur leurs propriétés (obstacles ou non par exemple).

Les patterns sont chargés en VRAM lors de la lecture de la table des chargements.

Les tiles sont lues dans une table spécifiques, ainsi que la composition des layers.

Codage des Tiles

L'adresse de début du buffer source des données compressées est déterminée au moment de la lecture de la table des chargements.

Décompression

Le buffer des données décompressées est formé de séquences de 0x22 octets, numérotées à partir de 0.

Il est construit de la façon suivante :

  • la première séquence est formée par 0x0000, puis 0x20 fois 0x0100
  • ensuite, on lit un octet X depuis la source :
    • si c'est 0xFF, la décompression est terminée
    • si c'est 0x00, l'octet suivant désigne le numéro de séquence, et les 0x22 octets suivants sont les valeurs de celle-ci
    • sinon X est le numéro de la séquence, les 5 octets suivants sont un masque. Seuls les bits 0 à 0x22 sont pertinents :
      • si le bit du masque est à 1, le prochain octet de la séquence courante est le même que celui correspondant dans la dernière séquence décodée
      • si le bit du masque est à 0, le prochain octet de la séquence courante est le prochain octet lu dans source

Signification

Le premier mot est attribute_id. Il réfère à une entrée dans la table des collisions.

Les 16 mots suivants sont les pattern_ids des 16 patterns formant la tile, donnés en colonnes.

Par exemple, la première séquence des données décompressées est toujours 0x0000 suivi de 0x20 fois 0x0100, ce qui signifie que

Codage des collisions

Elle est formée de ?? entrées de 16 octets, chaque octet décrivant un attribut d'un des 16 blocs 8x8 formant une tile, données en colonne.

Valeurs de ces entrées :

  • 00 : pas de collision
  • ?? : à creuser

Codage des layers

Les layers sont chargées par les commandes 0x14.

Décompression

Le système de compression est similaire à celui utilisé pour les tiles. Cette fois, les données décompressées sont des séquences de 0x10 octets, construites de la façon suivante :

  • On lit un octet X depuis la source
    • si X = 0xFF, c'est terminé
    • si X = 0xC0,
      • le mot suivant est le numéro de la séquence en cours
      • les 0x10 octets suivants codent le contenu de la séquence en cours (en clair)
    • sinon
      • X et l'octet suivent forment un mot qui est le numéro de la séquence en cours,
      • le mot suivant est le masque et pour chaque bit du masque
        • si le bit est à 0, le prochain octet de la source est le prochain octet de la séquence
        • si le bit est à 1, le prochain octet de le séquence en cours es égal à l'octet correspondant dans la dernière séquence décodée

Signification

Le buffer décompressé donne les tiles formant la layer, en ligne.

Scènes

Les scènes sont identifiée par un scene_id pair entre 0 et 0x3CA.

La plupart des scènes sont un assemblage cartes / NPCs / musique / autres infos, mais certaines scènes ne sont pas des cartes.

Table des initialisations

Table en 0x1B87A, démarrant par des offsets (w) vers chaque entrée. Une entrée est une liste terminée par un FFFF. Chaque entrée de la liste est de la forme :

  • 00 (w) : compteur n,
  • 02 - (w) : (n + 1) offsets qu'il faut rajouter à l'adresse de début de l'offset pour avoir data_addr

En data_addr on trouve les 8 premiers octets d'un Objet (voir section Objets) :

  • 00 (b) : flags
  • 01 (b) : param_1
  • 02 (w) : param_2
  • 04 (l) : ptr_to_action_routine

Lorsque l'objet est traité la première fois, l'action_routine est exécutée.

Certaines de ces action_routines sont générales, d'autres spécifiques à une carte ou une scène.

Voici quelques action_routines :

  • 0x1BB6 (load_NPCs) : crée les objets représentant les NPCs de village
  • 0x245C (load_exits) : Lit la table des sorties de cette scène
  • 0x27E4 (load_pillars) : crée les objets représentant les piliers de châteaux dans les villages
  • 0x2A66 (load_gates) : crée les objets représentant les portails de châteaux dans les villages
  • 0x11F7E (load_mieu) : objet représentant Mieu dans la carte du dôme de Landen au début du jeu
  • 0x13D2A (load_miun) : crée l'objet "Miun" dans Aridia
  • 0x176F4 (load_color_cycling) : crée un objet faisant cycler les couleurs dans une palette
  • 0x172D0 (load_boat) : crée l'objet représentant le bateau dans le dome de Landen
  • 0x177B0 (load_bridge_in_landen) : objet représentant un pont dans le dome de Landen
  • de 0x19122 à 0x1915E (load_airports) : crée un objet qui teste si la party passe sur un aéroport dans le cas où Wren possède les Aeroparts. Une seule entrée pour tous les aéroports de la carte. Une routine par monde. Voir plus loin (un autre jour) pour plus de détails.
  • 0x191FE : Même chose, pour les subparts
  • 0x19C6A : Teste si le groupe entre dans un temple de Laya
  • 0x1A7E8 : objey testant les ports (lorsque Wren est dans le groupe et dispose des aquaparts)

Table de paramètres

Une table de paramètres en 0x3C36A, démarrant par des offsets (w) vers chaque entrée. Une entrée est de la forme :

  • 00 (b) : largeur, en nbre de tiles
  • 01 (b) : hauteur, en nbre de tiles
  • 02 (w) : autant que je puisse en juger, ignoré (lu nulle part)
  • 04 (w) : de la forme xxbb. Si xx >= 0x80, alors la scène peut présenter des combats, et bb donne alors la battle_formations_id (voir section combats)
  • 06 (b) : id de la musique
  • 07 (b) : si 0xFF, le plan inférieur bouge moins vite (exemple : donjons futuristes)

Table de chargements

Une table de chargements en 0x21B70, démarrant par des offsets (w) vers chaque entrée. Une entrée est une liste, terminée par un 0x0000. Chaque entrée de la liste est sur 12 octets :

  • 00 (w) : paramètre n
  • 02 (w) : type (multiple de 4)
  • 04 (l) : adresse source
  • 08 (l) : adresse destination

Selon le type, l'action est différente :

  • type = 0x00 : copie n octets de source vers destination en RAM
  • type = 0x04 : copie n octets de source vers destination en VRAM
  • type = 0x08 : copie n octets de source vers 0xFFDD40 + destination (zone réservée aux palettes)
  • type = 0x0C : décompresse les patterns (Nemesis) depuis source vers destination en VRAM (n est ignoré)
  • type = 0x10 : charge les tiles (voir section maps pour la description du format) en RAM destination depuis source (n est ignoré).
  • type = 0x14 : charge une layer (voir section maps pour la description du format) en RAM destination depuis source (n est ignoré).
  • type = 0x18 : décompresse les patterns (Nemesis) depuis source vers destination en RAM (n est ignoré)
  • type = 0x1C : à étudier ; ça écrit des trucs en 0xFF8000 et ça a à voir avec les tiles
  • type = 0x20 : copie n octets de source + quest_id*32 vers 0xFFDD40 + destination (palettes)

La table est dumpée ici.

Table des ajustements

Une table spéciale modifie le scene_id selon les events du jeu débloquée. Elle débute en 0x3EF86, par des offsets (w) vers chaque entrée. Une entrée est une liste, terminée par 0xFF.

Chaque entrée est sur 4 octets :

  • 00 (b) : numéro de la quête (voir quest_id dans la ROM map)
  • 01 (b) : event_id (voir ROM map)
  • 02 (w) : scene_id

Si numéro de quête = quest_id et si l'event de event_id est True, alors le numéro de carte actuel est remplacé par scene_id.

Table des Sorties

Une table contient la liste des emplacements de la scène où l'on doit passer à une autre scène. Elle démarre en 0x34E4A, par des offsets vers chaque entrée (seules les scènes dont l'id va de 0 à 0x380 sont concernées).

Chaque entrée est une liste (taille variable) de format :

  • 00 (w) : nombre d'éléments - 1 (0xFFFF si vide) puis, pour chaque élément :
    • 00 (w) : x, coordonnée x de la sortie dans la scène courante
    • 02 (w) : y, coordonnée y de la sortie dans la scène courante
    • 04 (w) : scene_id, id de la scène de sortie
    • 06 (w) : x_new, coordonnée x dans la nouvelle carte
    • 08 (w) : y_new, coordonnée y dans la nouvelle carte
    • 0A (b) : w, largeur de la sortie
    • 0B (b) : h, hauteur de la sortie
    • 0C (b) : c ?
    • 0D (b) : d ?
    • 0E (b) : e ?
    • 0F (b) : f ?

Un dump de cette table est disponible ici.

Batailles

Stats