Son Son II (maps + analyse technique)

Discussions techniques et Pixel Art en 9 bits.

Modérateurs : SirG, Redfield1, shubibiman, Laucops

Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

Code : Tout sélectionner

===============================================================================
= Son Son II (Stage Maps)                                                     =
= 16/04/10                                                                    =
= par  Tanuki                                                                 =
= pour Necstasy                                                               =
===============================================================================

- Sommaire -
------------

1) Introduction
2) Les macro-blocs
3) Tables de définition des macro-blocs
4) Organisation d'une map
5) Derniers détails

1) Introduction
---------------

Nous avons déjà vu que malgré que la BAT n'utilise que des tiles 8x8, nombreux
d'entre eux sont regroupés par 4 dans la VRAM pour former des blocs 16x16.
Nous allons voir maintenant leur utilisation.

2) Les macro-blocs
------------------

Un macro-bloc regroupe 4 blocs et associe à chacun une palette et un attribut.

    +---+---+
    | A | B |   disposition des 4 blocs
    +---+---+
    | C | D |   (1 macro-bloc = 32x32 pixels)
    +---+---+

Un macro-bloc est défini par 8 octets d'information (2 par bloc):

    +--------+             +-------------+
  0 | bloc A | ->    n + 0 | idx de bloc |
    +--------+             +-------------+
  2 | bloc B |              7    4 3    0
    +--------+             +------+------+
  4 | bloc C |       n + 1 | pal  |attrib|
    +--------+             +------+------+
  6 | bloc D |
    +--------+

L'index de bloc:

C'est le numéro de bloc dans la 'BG tile area' soustrait de la valeur $36.
En fin de compte, seules les valeurs $00 à $69 sont valides car ce sont les
106 derniers blocs disponibles.

L'index de palette:

Les 4 bits sont placés dans les poids forts pour faciliter leurs transferts
dans la BAT.

L'attribut:

L'interaction avec un bloc se joue au moyen de 5 attributs:

    +---+-------------+
    | n | attribut    |
    +---+-------------+
    | 0 | neutre      |
    | 1 | solide      |
    | 2 | agrippement |
    | 3 | *           |
    | 4 | dommage     |
    +---+-------------+

(*) il faut que je fasse quelques recherches mais il semblerait que celà
     évite au joueur de se manger un angle droit lorsqu'il cherche à monter à
     des endroits.

3) Tables de définition des macro-blocs
---------------------------------------

Le macro-bloc est la plus petite unité de construction d'une map.

Chaque stage peut définir jusqu'à 256 macro-blocs ($00~$FF).

Une table de définition a une taille fixe de 256 x 8 = 2KB.

Voici les 7 tables disponibles dans la ROM:

    +-------+------+-------------+
    | stage | bank | range       |
    +-------+------+-------------+
    |   1   | $06  | $0000~$07FF |
    |   2   | $06  | $0800~$0FFF |
    |   3   | $06  | $1000~$17FF |
    |   4   | $06  | $1800~$1FFF |
    |   5   | $07  | $0000~$07FF |
    |   6   | $07  | $0800~$0FFF |
    |   7   | $07  | $1000~$17FF |
    +-------+------+-------------+

4) Organisation d'une map
-------------------------

Comme chaque stage utilise au maximum 256 macro-blocs, un index est de 8 bits.

D'abord les index sont regroupés en 8x8 pour obtenir des secteurs
(zones virtuelles de 256x256 pixels).

Ensuite ces secteurs sont regroupés en 8x8 pour obtenir la map finale
(zone virtuelle de 2048x2048 pixels).

           une map                      un secteur
        (8x8 secteurs)                  (8x8 index)
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |00|01|02|..|05|06|07| ->     |00|01|02|..|05|06|07|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |08|09|..|  |..|0E|0F|        |08|09|..|  |..|0E|0F|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |10|..|  |  |  |  |17|        |10|..|  |  |  |  |17|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |..|  |  |  |  |  |..|        |..|  |  |  |  |  |..|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |28|..|  |  |  |..|2F|        |28|..|  |  |  |..|2F|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |30|31|..|  |..|36|37|        |30|31|..|  |..|36|37|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+
    |38|39|3A|..|3D|3E|3F|        |38|39|3A|..|3D|3E|3F|
    +--+--+--+--+--+--+--+        +--+--+--+--+--+--+--+

Une map a une taille fixe de (8 x 8)(8 x 8) = 4KB.

Voici les 7 maps de ce format disponibles dans la ROM:

    +-------+------+-------------+
    | stage | bank | range       |
    +-------+------+-------------+
    |   1   | $0C  | $0000~$0FFF |
    |   2   | $0C  | $1000~$1FFF |
    |   3   | $0D  | $0000~$0FFF |
    |   4   | $0D  | $1000~$1FFF |
    |   5   | $0E  | $0000~$0FFF |
    |   6   | $0E  | $1000~$1FFF |
    |   7   | $0F  | $0000~$0FFF |
    +-------+------+-------------+

5) Derniers détails
-------------------

- la map est chargée dans la moitié supérieure de la RAM ($3000~$3FFF).

===============================================================================
= EOF                                                                         =
===============================================================================
Dernière modification par Tanuki le ven. 16 avr. 2010 17:03, modifié 1 fois.
Avatar de l’utilisateur
touko
NECromancer
Messages : 2297
Inscription : lun. 31 mars 2008 14:32

Re: Son Son II (tech)

Message par touko »

wahou, sacret boulot, la vache :shock:
Avatar de l’utilisateur
shubibiman
Administrateur
Messages : 16393
Inscription : jeu. 23 sept. 2004 14:26
Localisation : Meet me at Shubibi's

Re: Son Son II (tech)

Message par shubibiman »

Je comprends pas tout mais ça m'a l'air énorme comme boulot. C'est d'autant plus intéressant qu'il s'agit d'un des meilleurs (si ce n'est le meilleur) jeu de plateforme de la machine.
"You are truly the PCE game clearing master"

*****Membre du FLPCE Canal Historique*****
Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

Ce n'est pas vraiment énorme pour le moment (Touko parle sûrement des fichiers pcx des maps du post précédent, dont j'avoue être assez fier :mrgreen: ), par contre ici, ce n'est que l'aspect le plus simple des maps (je serai vraiment content lorsque j'aurai découvert comment marche le scrolling multi-directionnel).

Note:
Dans les docs, je n'explique pas forcément les choses très clairement, et met aussi des schémas pour éviter de décrire les choses avec des tonnes de lignes (mais je suis là aussi pour répondre à toutes vos questions). :)
Avatar de l’utilisateur
touko
NECromancer
Messages : 2297
Inscription : lun. 31 mars 2008 14:32

Re: Son Son II (tech)

Message par touko »

Pour les fichiers graphiques,ce sont ceux presents dans la rom ,ou tu les à ripper toi même ??
Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

J'ai fait un petit programme qui charge et interprète les données graphiques de la ROM.
Ensuite il exporte le résultat dans un fichier PCX (mon format préféré :D ).

La map 8bpp (de 4MB) sur ton écran est juste l'interprétation d'une simple map de 4KB de la ROM.

Code : Tout sélectionner

                                          [map]
                                            |
                                            |
                                       macro-bloc(n)  - - - - - - - 32x32 pixels
                                            |
                +----------------------+----+----+--------+
                |                      |         |        |
                |                      |         |        |
              bloc(A)                bloc(B)   bloc(C)  bloc(D) - - 16x16 pixels
                |                      |         |        |
    +-------+---+---+-------+        ####      ####     ####
    |       |       |       |
  tile(A) tile(B) tile(C) tile(D) - - - - - - - - - - - - - - - - -  8x8  pixels
:arrow: la map contient des index 8-bit.
:arrow: chaque index désigne un macro-bloc.
:arrow: chaque macro-bloc désigne 4 blocs.
:arrow: chaque bloc représente 4 tiles en VRAM.
Avatar de l’utilisateur
touko
NECromancer
Messages : 2297
Inscription : lun. 31 mars 2008 14:32

Re: Son Son II (tech)

Message par touko »

Ok, merci pour l'info :wink: .

Tes tiles pourraient servir pour faire des niveaux de jeux :mrgreen:
Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

Code : Tout sélectionner

===============================================================================
= Son Son II (Stage Pals)                                                     =
= 10/05/10                                                                    =
= par  Tanuki                                                                 =
= pout Necstasy                                                               =
===============================================================================

- Sommaire -
------------

1) Introduction
2) Chargement groupé des palettes
3) Chargement des couleurs dans la RAM
3) Séquence de chargement
4) Les palettes des stages
5) Derniers détails

1) Introduction
---------------

Comme il a été déjà mentionné, le jeu Son Son II n'utilise que des graphismes
3-bpp, donc 8 couleurs par palette. De ce fait aucune couleur d'index $8~$F
n'est jamais initialisée ou utilisée par le jeu.

Je vais expliquer comment le jeu charge les palettes au tout début d'un stage.

2) Chargement groupé des palettes
---------------------------------

Le jeu charge les palettes du jeu en deux temps:
en premier celles de l'arrière-plan puis ensuite celles des sprites.

Les palettes (BG/SP) sont d'abord chargées à partir de la ROM, puis altérées
en fonction d'un indice de luminosité, et enfin rangées temporairement en RAM.

L'indice de luminosité (vous vous en doutez) va servir à produire les effets
de fondu.

Ensuite quand arrive le bon moment, les palettes sont envoyées vers le VCE.

Le même espace de RAM est utilisé à la fois pour les palettes BG et SP:
(rappel: 1 palette = 8 x 2 = 16 octets)

       +---------+--------------++---------+--------------+
       | address |  pal (BG/SP) || address |  pal (BG/SP) |
       +---------+--------------++---------+--------------+
       |  $2EA0  |      $0      ||  $2F20  |      $8      |
       |  $2EB0  |      $1      ||  $2F30  |      $9      |
       |  $2EC0  |      $2      ||  $2F40  |      $A      |
       |  $2ED0  |      $3      ||  $2F50  |      $B      |
       |  $2EE0  |      $4      ||  $2F60  |      $C      |
       |  $2EF0  |      $5      ||  $2F70  |      $D      |
       |  $2F00  |      $6      ||  $2F80  |      $E      |
       |  $2F10  |      $7      ||  $2F90  |      $F      |
       +---------+--------------++---------+--------------+

3) Chargement des couleurs dans la RAM
--------------------------------------

Le jeu utilise la fonction $1396 (banque $02) en utilisant les arguments
suivants:

       $2028: adresse de la palette dans la ROM (lsb) --+
       $2029: adresse de la palette dans la ROM (msb) --+ source

       $202A: adresse de la palette dans la RAM (lsb) --+
       $202B: adresse de la palette dans la RAM (msb) --+ destination

       $2037: nombre total de couleurs x 2

       reg X: indice de luminosité (0~7)

La fonction utilise une table pré-calculée au format suivant:
($15FA: 8x8 octets)

          0 1 2 3 4 5 6 7
         +---------------
       0 |0 0 0 0 0 0 0 0      1/8 (black)
       1 |0 0 0 0 1 1 1 1      2/8
       2 |0 0 0 1 1 1 2 2      3/8
       3 |0 0 1 1 2 2 3 3      4/8
       4 |0 0 1 1 2 3 3 4      5/8
       5 |0 0 1 2 3 3 4 5      6/8
       6 |0 0 1 2 3 4 5 6      7/8
       7 |0 1 2 3 4 5 6 7      8/8 (normal)

Pour chaque couleur:

le code extrait les 3 composantes RGB, utilise la table sur chacune d'elle,
puis regroupe et copie le résultat dans la RAM.

Donc pour faire simple (à partir de la table):

  - X est l'index de ligne (la luminosité)
  - R, G, ou B est l'index de colonne (la composante altérée)

        +---+---+---+                     +---+---+---+
  (ROM) | G | R | B |                     | G | R | B | (RAM)
        +---+---+---+                     +---+---+---+
          |   |   |                         |   |   |
          |   |   +-----> TABLE[X][B] >-------------+
          |   +---------> TABLE[X][R] >---------+
          +-------------> TABLE[X][G] >-----+

3) Séquence de chargement
-------------------------

Une fois les palettes en RAM, le jeu utilise une des deux fonctions suivantes:
(banque $02)

  - $13FC: transfère les 16 palettes (BG) vers le VCE.

  - $14EB: transfère les 16 palettes (SP) vers le VCE.

Au final la séquence de chargement complète est la suivante:
(pour X allant de 0 à 7)

  - chargement des 16 palettes (BG) en RAM
  - attente (2 frames)
  - transfert des palettes vers le VCE

  - chargement des 16 palettes (SP) en RAM
  - attente (1 frame)
  - transfert des palettes vers le VCE

4) Les palettes des stages
--------------------------

Voici les palettes utilisées lors du chargement des stages:
(banque $01)

       +-------+------------+---------------+
       | stage |    pals    | start address |
       +-------+------------+---------------+
       |   x   | BG $0 ~ $4 |    $0000      |
       |   1   | BG $5 ~ $F |    $00DE      |
       |   2   | BG $5 ~ $F |    $018E      |
       |   3   | BG $5 ~ $F |    $023E      |
       |   4   | BG $5 ~ $F |    $02EE      |
       |   5   | BG $5 ~ $F |    $039E      |
       |   6   | BG $5 ~ $F |    $044E      |
       |   7   | BG $5 ~ $F |    $04FE      |
       +-------+------------+---------------+
       |   x   | SP $0 ~ $7 |    $0050      |
       |   1   | SP $8 ~ $F |    $05BC      |
       |   2   | SP $8 ~ $F |    $063C      |
       |   3   | SP $8 ~ $F |    $06BC      |
       |   4   | SP $8 ~ $F |    $073C      |
       |   5   | SP $8 ~ $F |    $07BC      |
       |   6   | SP $8 ~ $F |    $083C      |
       |   7   | SP $8 ~ $F |    $08BC      |
       +-------+------------+---------------+

  x: mêmes palettes pour chaque stage

5) Derniers détails
-------------------

  - la palette SP $0 est celle du personnage principal.
    (celle du cochon également, et d'autres choses)

  - tous les index $0 de chaque palette (SP) ont une couleur.
    (à part la première, je ne sais pas à quoi elles servent)

===============================================================================
= EOF                                                                         =
===============================================================================
Dernière modification par Tanuki le ven. 14 mai 2010 05:52, modifié 1 fois.
Avatar de l’utilisateur
cosmos99
Backup RAM Full!
Messages : 11904
Inscription : jeu. 02 déc. 2004 21:02

Re: Son Son II (tech)

Message par cosmos99 »

Salut Tanuki !

dis, tu pourrais pas me faire un ptit trainer pour ce jeu des fois ? Merci d'avance ! :)
Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

Je ne suis pas encore arrivé dans cette section du jeu (barre d'état/vie/continue...).

En ce moment je suis sur les sprites, de plus il me faut souvent beaucoup de temps pour comprendre certain morceaux de code: celui qui construit la map en VRAM, par exemple, mis bout à bout, faisait presque 200 lignes. :shock:

Mais quand j'y serai, il suffira sûrement d'un simple patch avec 2 ou 3 octets de changés pour avoir une barre de vie figée ou des continues illimités.

Je t'enverai un MP quand j'y serai (mais dans quelle année ?). :lol:
Dernière modification par Tanuki le lun. 10 mai 2010 15:40, modifié 1 fois.
Avatar de l’utilisateur
cosmos99
Backup RAM Full!
Messages : 11904
Inscription : jeu. 02 déc. 2004 21:02

Re: Son Son II (tech)

Message par cosmos99 »

Merci ! :)
Avatar de l’utilisateur
Redfield1
Administrateur
Messages : 6218
Inscription : mar. 21 sept. 2004 05:08
Localisation : Aero-City

Re: Son Son II (tech)

Message par Redfield1 »

Beau boulot Tanuki.

Bon courage pour la suite.

... Red ...
Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

Code : Tout sélectionner

===============================================================================
= Son Son II (Pad Proc)                                                       =
= 13/02/10                                                                    =
= par  Tanuki                                                                 =
= pour Necstasy                                                               =
===============================================================================

- Sommaire -
------------

1) Introduction
2) Utilisation des variables
3) La phase de lecture
4) Interprétation des données
5) Mapping des données
6) Les grandes lignes du code
7) Derniers détails

1) Introduction
---------------

Ici nous allons nous intérésser à la fonction qui lit la manette.

Les explications qui vont suivre ne s'appliquent pas uniquement à Son Son II,
mais également à d'autres jeux PC-Engine.

En effet comme ils utilisent le même code générique gérant le multi-tap, il n'y
a que les localités du code et des variables qui changent d'un jeu à l'autre.

2) Utilisation des variables
----------------------------

La première chose à rappeler, c'est que les données de la manette arrivent avec
des 0 lorsqu'il y a quelque chose de pressé, et des 1 dans la cas contraire.

Donc une fois que les données ont été lues à partir du port, la première chose
à faire est de complémenter les bits pour ramener le tout à une logique plus
proche de la notre:

  data <- NOT(data)          ; rappel: A XOR $FF = NOT(A)

A partir de là nous obtenons:

  1 = pressé
  0 = non pressé

Le code à besoin de trois variables 8-bit pour gérer un pad:

  - une pour stocker les anciennes données               (old_dat)
  - une pour stocker les données actuelles               (cur_dat)
  - une pour stocker uniquement les nouvelles pressions  (new_dat)

Il faut préciser que puisque la RAM est entièrement mise à zéro lors de
l'initialisation du jeu, ces trois variables sont nulles lors de leur première
utilisation.

3) La phase de lecture
----------------------

Les anciennes données sont d'abord sauvegardées:

  old_dat <- cur_dat

Ensuite vient la lecture du port et l'inversion des données:

  cur_dat <- IO_PORT
  cur_dat <- NOT(cur_dat)

Puis enfin la déduction des nouvelles pressions:

  new_dat <- (old_dat XOR cur_dat) AND cur_dat

4) Interprétation des données
-----------------------------

note: le détail sur l'attribution des bits se trouve dans la section 6.

On commence à zéro (la manette est neutre):

  old_dat = %00000000
  cur_dat = %00000000        ; rien de pressé
  new_dat = %00000000

Maintenant je presse le bouton I:

  old_dat = %00000000
  cur_dat = %00000001        ; le bouton I est pressé
  new_dat = %00000001        ; le bouton I vient d'être pressé

Maintenant je presse en même temps le bouton II:

  old_dat = %00000001
  cur_dat = %00000011        ; les boutons I et II sont pressés
  new_dat = %00000010        ; le bouton II vient d'être pressé

Et je relâche tout:

  old_dat = %00000011
  cur_dat = %00000000        ; rien de pressé
  new_dat = %00000000

5) Mapping des données
----------------------

Puisque le multi-tap peut gérer jusqu'à cinq pads, nous avons donc:

  3 x 5 = 15 octets

auquel nous ajoutons une variable supplémentaire:

  15 + 1 = 16 octets

Voici le mapping pour Son Son II:

                   +------------+
             $2016 |   pad #1   |
             $2017 |   pad #2   |
             $2018 |   pad #3   | current
             $2019 |   pad #4   |
             $201A |   pad #5   |
                   +------------+
             $201B |   pad #1   |
             $201C |   pad #2   |
             $201D |   pad #3   | old
             $201E |   pad #4   |
             $201F |   pad #5   |
                   +------------+
             $2020 |   pad #1   |
             $2021 |   pad #2   |
             $2022 |   pad #3   | new
             $2023 |   pad #4   |
             $2024 |   pad #5   |
                   +------------+
             $2025 |  pad_flags |
                   +------------+

Bien sûr Son Son II n'interprète que les données du pad #1.

6) Les grandes lignes du code
-----------------------------

La fonction se trouve à l'adresse $FEDE (banque $00) et est principalement
utilisée par la routine IRQ.

Le code commence par une manipulation pour ré-initialiser le compteur interne
du multi-tap (s'il n'est pas là, celà désactive/active simplement la sortie
du multiplexeur de la manette).

Ensuite pour chaque pad (#1 à #5):

  - il sauvegarde les anciennes données.

  - il lit l'état des directions à partir du port
    (qu'il masque et place dans les poids forts de la variable)

  - il lit l'état des boutons à partir du port
    (qu'il masque et ajoute aux poids faibles de la variable)

Ce qui nous donne la disposition suivante:

            7      6      5      4      3      2      1      0
         +------+------+------+------+------+------+------+------+
         | Left | Down |Right |  Up  | Run  |Select|  II  |  I   |
         +------+------+------+------+------+------+------+------+
            |                     |     |                     |
            +---------------------+     +---------------------+
                  directions                   boutons

Entre la sélection et la lecture des données, le code attend à peu prés
9 cycles (~= 1.257µs en mode 7.16MHz).

  - ensuite il complémente le tout.

  - et enfin déduit les nouvelles pressions.

Une manette directement plugée sur le port de la console sera lue cinq fois de
suite (comme étant les pads #1 à #5);

Une fois la lecture des cinq manettes effectuées, il parcourt la variable
'pad_flags' pour savoir lesquelles ont le droit de forcer le jeu à faire un
reset:

                   7    6    5    4    3    2    1    0
                 +----+----+----+----+----+----+----+----+
                 | -  | -  | -  |pad5|pad4|pad3|pad2|pad1|
                 +----+----+----+----+----+----+----+----+

Si le bit corespondant à une manette est à 1, alors le code teste les données
de cette dernière pour savoir si elles contiennent la séquence Run+Select.

Conditions requises:

  cur_dat = %00001100        ; seuls Run et Select sont pressés

  new_dat = %00000100        ; seul Select vient d'être pressé

Si c'est la cas, le code se branche à l'emplacement dans le jeu correspondant
à un soft-reset ($E013 pour Son Son II).

7) Derniers détails
-------------------

- La différence entre le hard et soft reset (pour Son Son II) est que pour
  l'un, toute la RAM est mise à zéro, alors que l'autre conserve la plage
  $2FF8~$2FFF (celle-ci contient principalement le hi-score de 7 chiffres).

- Voici pour exemple d'autres jeux utilisant exactement le même code:

   Coryoon
   Detana!!! TwinBee
   Gradius
   Gunhed
   Hana Taka Daka!
   Magical Chase (J)
   Marchen Maze
   Mizubaku Daibouken
   Parodius Da!
   PC Genjin
   PC Genjin 2
   PC Genjin 3
   ...

===============================================================================
= EOF                                                                         =
===============================================================================
Avatar de l’utilisateur
touko
NECromancer
Messages : 2297
Inscription : lun. 31 mars 2008 14:32

Re: Son Son II (tech)

Message par touko »

Très instructif,merci :wink:
Bon tu commences quand à nous faire un jeu sur pce ?? :mrgreen:
Avatar de l’utilisateur
Tanuki
Push Run Button!
Messages : 95
Inscription : mer. 14 oct. 2009 17:02

Re: Son Son II (tech)

Message par Tanuki »

1) Je dois d'abord terminer de décortiquer le jeu (ce qui va me prendre des lustres).

2) Je pense ensuite faire une grosse doc pdf qui fera la synthèse de tout (avec des beaux schèmas, des écrans, et tout et tout ...).

3) Enfin (si je suis encore vivant) je ferai PEUT-ETRE quelque chose de sympa en m'inspirant du code du jeu. 8)
Répondre