Samouraï Pizza Cats: le retour de la vengeance
Modérateur : Terminus Traduction
Samouraï Pizza Cats: le retour de la vengeance
Bon ça y est, c'est reparti!
Après presque 5 ans d'activité comateuse, j'ai décidé de reprendre le projet avec pour objectif de le terminer. Youpi yeah c'est parti!
Du coup, j'ai décidé de créer un post pour plusieurs raisons:
Allé on y croit!
Après presque 5 ans d'activité comateuse, j'ai décidé de reprendre le projet avec pour objectif de le terminer. Youpi yeah c'est parti!
Du coup, j'ai décidé de créer un post pour plusieurs raisons:
- montrer la progression au fil du temps
- conserver les infos liées au hack
- échanger avec des gens intéressés (si y en a, au pire osef)
- me motiver (le plus dur
)
Allé on y croit!
- Happexamendios
- Adepte !
- Messages : 6750
- Inscription : 22 févr. 2002, 12:01
- Localisation : Royaume d'Imajica
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
/me invoque Sexy Cheerleaders pour buff motivation
Je pionce donc je suis
Re: Samouraï Pizza Cats: le retour de la vengeance
Je suivrais ce post avec attention, surtout si tu parle technique avec les explication qui vont avec 
Bonne chance en tout cas !!!

Bonne chance en tout cas !!!
Traduction de BS Zelda - Ancient Stone Tablets (Projet en cour)

Re: Samouraï Pizza Cats: le retour de la vengeance
Je ne sais pas si je serai aussi clair que Baha ou Lyan, mais je vais quand même essayer.
Re: Samouraï Pizza Cats: le retour de la vengeance
Moi je dirais que tu es plutôt limpide...
... dans tes explications
... dans tes explications

Re: Samouraï Pizza Cats: le retour de la vengeance
Je confirme en tout cas, Baha tes info sont tres clair, tu donne generalement jusque ce qu'il faut pour que l'on puisse ce débrouiller seule par la suite, meme s'il faut relire plusieurs fois tes messages ^^
Traduction de BS Zelda - Ancient Stone Tablets (Projet en cour)

Re: Samouraï Pizza Cats: le retour de la vengeance
Aujourd'hui, je vais détailler le hack de l'écran titre du jeu. Cet article sera constitué de plusieurs parties, je ne dis pas combien car je n'en ai aucune idée. Mais l'objectif affiché est d'être suffisamment précis et clair pour permettre à toute personne disposant d'un petit bagage en romhack de comprendre ce qui se passe. Je m'attends à ce que vous ayez déjà joué avec le debugger de l'excellent FCEUXD-SP, et que des notions comme nametable ou encore PPU sonnent des vos esgourdes. De toute façon, nous reviendrons sur ces notions au fil des articles et des demandes s'il y en a...
Donc l'idée du topic, c'est de voir comment on peut passer de cette image à celle là.

Décodage
Pour ce faire (hommage vibrant à Albie's Hobbies), je me suis basé sur les techniques de hack NES présentées par Graou dans sa doc très utile.
Rapidement, on peut déterminer que le code chargé de l'initialisation de la nametable pour l'écran titre se trouve dans la bank #03 et commence à l'adresse $880D. Au moment de l'appel, l'Accumulateur contient l'indice du pointeur des données à charger dans la nametable. Le code commenté peut-être visualisé ci-dessous.
Localisation des données
Tout d'abord, on apprend donc que les données à écrire dans la nametable sont pointées par un pointeur qui est sauvegardé en RAM à l'adresse $0000. Ce pointeur est lui-même situé dans une table de pointeurs conservée à l'adresse $89E3 (dans la même bank que le code ci-dessus). Si on ouvre un éditeur hexadecimal, il est possible de visualiser cette table de pointeurs (je n'expliquerai pas ici comment on transpose une adresse CPU en offset, cela fera l'objet d'un autre article si besoin).

Pour rappel, un pointeur est une adresse codée sur 2 octets. Dans la table présentée ci-dessus, on compte 17 pointeurs. Celui qui nous intéresse ici est le premier de la table. En effet, l'instruction à l'adresse $880F est exécutée avec la valeur #$00 dans le registre X. Ce sont donc les deux premiers octets de la table de pointeurs qui seront lus. Ces octets sont #$05 et #$8A, or comme vous le savez peut-être, les adresses CPU sont généralement écrites en Little-Endian sur NES. Cela veut dire que c'est l'octet de poids faible qui est écrit en premier. Par conséquent, pour reconstituer l'adresse des données de la nametable, il suffit d'inverser les deux octets lus, ce qui donne $8A05. On peut noter cette fois encore que les données de la nametable sont donc situées dans la même bank que le code ci-dessus. Toujours depuis notre éditeur hexadécimal, on peut visualiser la "zone" de ces données. Mais il va falloir analyser encore un peu plus ces dernières pour bien les délimiter.

Déchiffrage des données
Pour déchiffrer et délimiter cette zone de données, il faut revenir au code désassemblé présenté plus haut. Ce qu'il dit, c'est que le CPU va lire des blocs de données. Chaque type de bloc caractérise une méthode de lecture ou d'écriture de données. On distingue 3 types de blocs:
Le premier octet de ce type de bloc doit avoir une valeur différente de #$00 et de #$FE. Il est composé de trois parties:
Le premier octet de ce type de bloc doit avoir la valeur #$FE. Il est lui aussi composé de trois parties:
Le premier et unique octet de ce type de bloc doit avoir la valeur #$00.
Dans notre éditeur hexadécimal, on peut alors déterminer les différents blocs.

Conclusion
Ceci met fin à la première partie de cet article. Nous avons vu comment localiser le code de chargement de la nametable associée à l'écran titre, ainsi que comment localiser puis déchiffrer (en partie c'est vrai) les données relatives à cette nametable. Dans la prochaine partie, nous verrons ce que fait la PPU de ces données, je pense que je reviendrai sur les notions de nametable, d'attribute table et de palette.
Merci d'avoir pris le temps de lire cet article. J'espère jusqu'ici avoir été clair. N'hésitez pas à laisser vos commentaires ou questions!
EDIT -- Correction de quelques erreurs au niveau du code désassemblé.
Donc l'idée du topic, c'est de voir comment on peut passer de cette image à celle là.


Décodage
Pour ce faire (hommage vibrant à Albie's Hobbies), je me suis basé sur les techniques de hack NES présentées par Graou dans sa doc très utile.
Rapidement, on peut déterminer que le code chargé de l'initialisation de la nametable pour l'écran titre se trouve dans la bank #03 et commence à l'adresse $880D. Au moment de l'appel, l'Accumulateur contient l'indice du pointeur des données à charger dans la nametable. Le code commenté peut-être visualisé ci-dessous.
Code : Tout sélectionner
$880D 0A ASL ; double la valeur de l'indice du pointeur (car les pointeurs sont codés sur 2 octets)
$880E AA TAX ; placer cette valeur dans X
$880F BD E3 89 LDA $89E3,X ; lecture du pointeur à partir de l'adresse $89E3 indexée par X
$8812 85 00 STA $00 ; sauvegarde du pointeur en RAM à l'adresse $0000
$8814 BD E4 89 LDA $89E4,X ;
$8817 85 01 STA $01 ;
$8819 2C 02 20 BIT $2002 ; ?? si quelqu'un peut m'expliquer l'intérêt de cette instruction ??
$881C A0 00 LDY #$00 ; initialisation de l'index de lecture des données
$881E B1 00 LDA ($00,Y) ; lecture d'un octet à partir de l'adresse pointée sauvegardée en RAM à l'adresse $00
+-------- $8820 F0 52 BEQ $52 ; si l'octet lu == #$00 alors on saute à l'instruction pointée par la flèche
| $8822 C9 FE CMP #$FE ;
| +----- $8824 D0 25 BNE $25 ; sinon si l'octet lu != #$FE alors on saute à l'instruction pointée par la flèche
| | $8826 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| | $8829 B1 00 LDA ($00,Y) ; lecture d'un octet qui correspond au nombre de fois qu'on va écrire le même octet dans la PPU
| | $882B AA TAX ; sauvegarde de cet octet dans le registre X
| | $882C 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| | $882F B1 00 LDA ($00,Y) ; lecture du premier octet d'une adresse PPU
| | $8831 8D 06 20 STA $2006 ; début d'initialisation du pointeur d'écriture dans la PPU
| | $8834 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| | $8837 B1 00 LDA ($00,Y) ; lecture du second octet d'une adresse PPU
| | $8839 8D 06 20 STA $2006 ; fin d'initialisation du pointeur d'écriture dans la PPU
| | $883C C8 INY ; incrémentation de l'index de lecture des données
| | ;(ATTENTION: on remarque ici qu'on ne passe pas par la subroutine $886F)
| | $883D B1 00 LDA ($00,Y) ; lecture d'un octet à partir de l'adresse pointée sauvegardée en RAM à l'adresse $00
| | +-> $883F 8D 07 20 STA $2007 ; écriture de cet octet dans la PPU à l'adresse pointée
| | | $8842 CA DEX ; décrémentation du compteur du nombre d'écriture placé dans le registre X
| | +-- $8843 D0 FA BNE $FA ; tant que X contient une valeur > 0 alors on saute à l'instruction pointée par la flèche
| | $8845 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| | $8848 4C 1E 88 JMP $881E ; on saute à l'instruction $881E
| +----> $884B 85 03 STA $03 ; l'octet lu est sauvegardé en RAM à l'adresse $0003, il indique le nombre d'octets à lire
| $884D 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| $8850 B1 00 LDA ($00,Y) ; lecture du premier octet d'une adresse PPU
| $8852 8D 06 20 STA $2006 ; début d'initialisation du pointeur d'écriture dans la PPU
| $8855 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| $8858 B1 00 LDA ($00,Y) ; lecture du second octet d'une adresse PPU
| $885A 8D 06 20 STA $2006 ; fin d'initialisation du pointeur d'écriture dans la PPU
| +-> $885D 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| | $8860 B1 00 LDA ($00,Y) ; lecture d'un octet à partir de l'adresse pointée sauvegardée en RAM à l'adresse $00
| | $8862 8D 07 20 STA $2007 ; écriture de cet octet lu dans la PPU à l'adresse pointée
| | $8865 C6 03 DEC $03 ; décrémentation du nombre d'octets restant à lire conservé à l'adresse $0003
| +-- $8867 D0 F4 BNE $F4 ; si ce nombre > 0, alors on boucle en sautant à l'adresse pointée par la flèche
| $8869 20 6F 88 JSR $886F ; incrémentation de l'index de lecture des données
| $886C 4C 1E 88 JMP $881E ; on saute à l'instruction $881E
;-----------|---------------------------------------------------------------------------
; | subroutine: incrémentation de l'index Y et incrémentation du pointeur de données à $0000 si besoin
;-----------|---------------------------------------------------------------------------
| $886F C8 INY ;
| +-- $8870 D0 02 BNE $02 ;
| | $8872 E6 01 INC $01 ;
+-----+-> $8874 60 RTS ;
Tout d'abord, on apprend donc que les données à écrire dans la nametable sont pointées par un pointeur qui est sauvegardé en RAM à l'adresse $0000. Ce pointeur est lui-même situé dans une table de pointeurs conservée à l'adresse $89E3 (dans la même bank que le code ci-dessus). Si on ouvre un éditeur hexadecimal, il est possible de visualiser cette table de pointeurs (je n'expliquerai pas ici comment on transpose une adresse CPU en offset, cela fera l'objet d'un autre article si besoin).

Pour rappel, un pointeur est une adresse codée sur 2 octets. Dans la table présentée ci-dessus, on compte 17 pointeurs. Celui qui nous intéresse ici est le premier de la table. En effet, l'instruction à l'adresse $880F est exécutée avec la valeur #$00 dans le registre X. Ce sont donc les deux premiers octets de la table de pointeurs qui seront lus. Ces octets sont #$05 et #$8A, or comme vous le savez peut-être, les adresses CPU sont généralement écrites en Little-Endian sur NES. Cela veut dire que c'est l'octet de poids faible qui est écrit en premier. Par conséquent, pour reconstituer l'adresse des données de la nametable, il suffit d'inverser les deux octets lus, ce qui donne $8A05. On peut noter cette fois encore que les données de la nametable sont donc situées dans la même bank que le code ci-dessus. Toujours depuis notre éditeur hexadécimal, on peut visualiser la "zone" de ces données. Mais il va falloir analyser encore un peu plus ces dernières pour bien les délimiter.

Déchiffrage des données
Pour déchiffrer et délimiter cette zone de données, il faut revenir au code désassemblé présenté plus haut. Ce qu'il dit, c'est que le CPU va lire des blocs de données. Chaque type de bloc caractérise une méthode de lecture ou d'écriture de données. On distingue 3 types de blocs:
- * les blocs de X octets à lire et à écrire dans la PPU;
* les blocs de 1 octet à lire et à écrire X fois dans la PPU;
* les blocs indiquant la fin des données de la nametable.
Le premier octet de ce type de bloc doit avoir une valeur différente de #$00 et de #$FE. Il est composé de trois parties:
- * sur 1 octet: le nombre de données à lire et à écrire dans la PPU;
* sur 2 octets: une adresse pour initialiser le pointeur d'écriture des données dans la PPU;
* sur X octets: les données à écrire dans la PPU.
Le premier octet de ce type de bloc doit avoir la valeur #$FE. Il est lui aussi composé de trois parties:
- * sur 1 octet: le nombre de fois que l'octet à lire va être écrit dans la PPU;
* sur 2 octets: une adresse pour initialiser le pointeur d'écriture des données dans la PPU;
* sur 1 octet: la donnée à écrire dans la PPU.
Le premier et unique octet de ce type de bloc doit avoir la valeur #$00.
Dans notre éditeur hexadécimal, on peut alors déterminer les différents blocs.

Conclusion
Ceci met fin à la première partie de cet article. Nous avons vu comment localiser le code de chargement de la nametable associée à l'écran titre, ainsi que comment localiser puis déchiffrer (en partie c'est vrai) les données relatives à cette nametable. Dans la prochaine partie, nous verrons ce que fait la PPU de ces données, je pense que je reviendrai sur les notions de nametable, d'attribute table et de palette.
Merci d'avoir pris le temps de lire cet article. J'espère jusqu'ici avoir été clair. N'hésitez pas à laisser vos commentaires ou questions!

EDIT -- Correction de quelques erreurs au niveau du code désassemblé.
- BahaBulle
- Bub'n'Bob Pawa!
- Messages : 6498
- Inscription : 06 août 2002, 09:34
- Localisation : Sur une bulle
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
D'après une doc de Crispysix :
On peut voir si la PPU est en période de VBlank en controlant le bit #7 du registre $2002(il est alors à 1), tout comme on peut mettre celui ci à zero. Celui ci est remis à 0 à la fin du VBlank.
Le bit #6 du registre $2002 est appelé Hit Flag, et sert a controler à l'affichage d'un sprite quand est-ce que l'on va ecrire la première ligne du sprite (il sera alors mis à 1). Si la coordonnée en ordonnée (Y) du sprite est 12, ce flag sera mis à 1 lors de l'écriture de la ligne 12. Il est automatiquement remis à 0 lors du VBlank.
On utilise souvent le contrôle du VBlank comme un timer, à défaut d'y avoir une quelquonque horloge sur la NES.
On peut voir si la PPU est en période de VBlank en controlant le bit #7 du registre $2002(il est alors à 1), tout comme on peut mettre celui ci à zero. Celui ci est remis à 0 à la fin du VBlank.
Le bit #6 du registre $2002 est appelé Hit Flag, et sert a controler à l'affichage d'un sprite quand est-ce que l'on va ecrire la première ligne du sprite (il sera alors mis à 1). Si la coordonnée en ordonnée (Y) du sprite est 12, ce flag sera mis à 1 lors de l'écriture de la ligne 12. Il est automatiquement remis à 0 lors du VBlank.
On utilise souvent le contrôle du VBlank comme un timer, à défaut d'y avoir une quelquonque horloge sur la NES.
Code : Tout sélectionner
Registre $2002: Registre de Status de la PPU (Lecture seulement)
masque: vhsw---- (-> 4 bits de poids faibles non utilisés)
v = Période de VBlank
Ce bit est mis à 1 durant une période de VBlank.
Il est mis à 0 dès qu'on fait une lecture de ce registre pour
éviter de reéxecuter une routine dans un même VBlank.
Remarque: très utile pour s'en servir comme timer.
h = Occurence Sprite #0
Ce bit est mis à 1 dès que le VBlank à atteint la position
du sprite #0 (du moins le premier pixel non transparent).
Il est mis à 0 après chaque VBlank.
Voir l'excellente FAQ de Chris Covell pour en savoir d'avantage.
s = Compteur de sprites par ligne
0 = 8 ou moins de 8 sprites par ligne
1 = plus de 8 sprites par ligne
w = Flag d'ecriture en VRAM
Ce bit mis à 1 indique que la PPU ignore les ecritures faites en VRAM.
Remarque: Utilisez ce registre SYSTEMATIQUEMENT pour ecrire des données en VRAM.
| Il n'est pas conseillé d'ecrire des données hors d'un VBlank durant l'execution.
- FlashPV
- Dieu Suprême du flood
- Messages : 1754
- Inscription : 15 sept. 2002, 23:44
- Localisation : Un coin perdu dans la colline
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
Ouais Ridicule lâche pas le morceau, moi aussi je suis encore (un peu) là. Ah oui bonne année à tous!
- Lyan
- Dieu Suprême du flood
- Messages : 1441
- Inscription : 19 nov. 2007, 04:56
- Localisation : Raxacoricofallapatorius
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
Chat-pristi !!
Chat y est ! (presque ??)
Je te tire mon chat-peau
Chat y est ! (presque ??)
Je te tire mon chat-peau

http://www.youtube.com/user/Lyan53

- Avec les gens de cour, vos pareils don Salluste, je vous laisse et je reste avec mes chenapans. Je vis avec les loups, non avec les serpents.
- L'amour a dompté le loup ! Ôtez-lui l'amour, il redeviendra un loup.
- Avec les gens de cour, vos pareils don Salluste, je vous laisse et je reste avec mes chenapans. Je vis avec les loups, non avec les serpents.
- L'amour a dompté le loup ! Ôtez-lui l'amour, il redeviendra un loup.
Re: Samouraï Pizza Cats: le retour de la vengeance
Presque en effet, je viens de terminer un petit beta-test et je me suis rendu compte de quelques loupés dans la synchronisation des animations, et j'ai aussi zappé l'écran de game over.
Rien de bien méchant en somme
Rien de bien méchant en somme

- Happexamendios
- Adepte !
- Messages : 6750
- Inscription : 22 févr. 2002, 12:01
- Localisation : Royaume d'Imajica
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
Chat-alors!
Chat-peau bas!

Chat-peau bas!

- BahaBulle
- Bub'n'Bob Pawa!
- Messages : 6498
- Inscription : 06 août 2002, 09:34
- Localisation : Sur une bulle
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
Je trouve que ces screens ne montrent pas l'étendu de ton travail 

- Musashi
- Maître Suprême Floodeur
- Messages : 522
- Inscription : 19 mars 2005, 19:51
- Localisation : Wonderland
Re: Samouraï Pizza Cats: le retour de la vengeance
Pourquoi y'a un T majuscule dans le mot "Vite" de l'écran des passwords? 

Re: Samouraï Pizza Cats: le retour de la vengeance
Merci, ça a été vu et corrigé 

Re: Samouraï Pizza Cats: le retour de la vengeance
Le hack a l'air tres propre, ca fais pro.
Bien joué en tout cas !!!
Bien joué en tout cas !!!
Traduction de BS Zelda - Ancient Stone Tablets (Projet en cour)

Re: Samouraï Pizza Cats: le retour de la vengeance
Ouaip!
Ça y est ! Le patch est sorti, pfew que ça fait du bien !
A titre de comparaison, voici les screens qui comparent version jap / fr. Après j'arrête de vous embêter avec ça (d'ailleurs va falloir que je reset mon avatar...).







Ça y est ! Le patch est sorti, pfew que ça fait du bien !
A titre de comparaison, voici les screens qui comparent version jap / fr. Après j'arrête de vous embêter avec ça (d'ailleurs va falloir que je reset mon avatar...).














Re: Samouraï Pizza Cats: le retour de la vengeance
Il a l'air marrant comme jeu et la traduction a l'air bien adaptée, bravo Rid 

Re: Samouraï Pizza Cats: le retour de la vengeance
Miam! Miam!
Petite question:
Au niveau du script traduis par Spring, tu as réussi à tout caser ou tu as été obliger d'adapter le script?
Vu les captures, très beau travail Rid!

Petite question:
Au niveau du script traduis par Spring, tu as réussi à tout caser ou tu as été obliger d'adapter le script?
Vu les captures, très beau travail Rid!
- Happexamendios
- Adepte !
- Messages : 6750
- Inscription : 22 févr. 2002, 12:01
- Localisation : Royaume d'Imajica
- Contact :
Re: Samouraï Pizza Cats: le retour de la vengeance
joli boulot, chat-peau bas
Je pionce donc je suis
Re: Samouraï Pizza Cats: le retour de la vengeance
Un peu des deux en fait.4ph a écrit :Miam! Miam!![]()
Petite question:
Au niveau du script traduis par Spring, tu as réussi à tout caser ou tu as été obliger d'adapter le script?
Vu les captures, très beau travail Rid!
Certes le script de Spring était plus long que l'original, mais comme j'avais doublé la PRG-ROM cela ne posait pas de problème.
Après j'avais apporté quelques modifications au script rendu par Spring pour coller un peu plus à l'esprit de la série.