Je ne peux pas résister au plaisir de vous montrer les écrans que j’ai pu récupérer à partir du fichier TALISMAN_DEMO.WAV de Simon G. A ma connaissance il n’existe pas de fichier .TAP ou .DSK pour cette démo et je l’ai choisie pour illustrer la simplicité de la procédure de récupération des nombreux écrans Hires qu’elle contient. Cet article montre des recopies d’écran, mais vous trouverez tous ces écrans au format .tap dans le zip joint à cet article.
Prévu à l’origine pour être un cadeau de Noël, ce programme a connu un peu de retard à force de le peaufiner. Mais bon, il est maintenant disponible et vous le trouverez dans le zip accompagnant cet article, ainsi que sur mon site, à l’adresse http://andre.cheramy.net/telechargement/Programmes/choix.htm
C’est une sorte de bataille navale, mais dans le jeu
classique (en vigueur dans les cours de récréation et qui se joue sur une
grille papier), deux protagonistes
s’échangent des missiles pour couler les bateaux de l’adversaire et (cf. “touché”,
“en vue” et “dans l’eau”). Dans les équivalents numériques
le jeu est souvent réduit à un seul joueur contre l’ordinateur.
Dans Radar Oric, il n’y a aucun risque de recevoir des missiles sur vos bateaux, car vous n’avez pas de bateaux. C’est votre QG qui est attaqué par une flotte ennemie et pour vous défendre, vous disposez d’un tout nouveau radar couplé à un ordinateur dernier cri, l’ Oric. Votre tâche est de localiser exactement la position de tous les bateaux ennemis, puis de déclencher un feu apocalyptique qui les anéantira vite fait bien fait avant qu’ils aient eu de temps de dire ouf ! Oui, je sais les bateaux ne peuvent pas dire ouf, mais bon…
Le jeu proprement dit
Votre rade est représentée par une grille de 10×10 cases où les 10 bateaux de la flotte ennemie se sont faufilés, profitant d’un épais brouillard. Heureusement, il y a quelques trous dans ce brouillard, dans lesquels vous pouvez apercevoir des bouts de navires ou… de l’eau ! Mais c’est tout (voir la figure ci-dessous).
Pas facile de savoir où sont les bateaux ennemis !
Heureusement encore, votre super Radar Oric est capable de scanner cette grille
et de vous indiquer combien d’éléments de bateaux se trouvent dans chaque ligne
et dans chaque colonne (voir les chiffres rouges à gauche et sous la grille).
Heureusement encore, votre super Radar Oric est
capable de scanner cette grille, ligne par ligne et colonne par colonne, et de
vous indiquer combien d’éléments de bateaux s’y trouvent (voir les chiffres
rouges à gauche et sous la grille).
Un peu de réflexion vous permettra de déduire la
localisation exacte des 10 bateaux ennemis. Dernier petit service offert par
votre Radar Oric : il vous indiquera si vous vous êtes planté dans votre
raisonnement ou si les bateaux sont bien là où vous pensez.
Si c’est correct, il ne vous restera plus qu’à les anéantir
et l’ennemi n’aura même pas le temps de comprendre ce qui lui arrive. Le
résultat est garanti en un rien de temps !
Hélas, l’ennemi a la peau dure et il ne va pas tarder à vous
envoyer une nouvelle flotte. Sacrebleu, il va encore falloir se creuser les
méninges !
Mais tout est bien qui finit bien, il arrivera
inexorablement un moment où l’ennemi sera à court de bateaux et où aurez
définitivement gagné.
Chaque flotte ennemie est composée des 10 bateaux suivants
Un porte-avions (4 cases)
Deux croiseurs (3 cases)
Trois destroyers (2 cases)
Quatre Sous-marins (1 case)
Cet effectif vous est rappelé au-dessus de la grille et vous sera utile pour vous aider à trouver où peuvent se tenir les bateaux.
Les commandes disponibles
Les quatre flèches pour déplacer le curseur dans
la grille.
Les chiffres de 1 à 8 pour marquer la case au
curseur selon ce que vous pensez qu’elle contient.
La touche “R” pour recommencer la
grille au début, si vous êtes trop embrouillé.
La touche “S” pour sauvegarder la
partie en cours afin de la reprendre plus tard.
Correspondance entre les touches 1 à 8 et le marquage des cases
Case indéterminée
De l’eau
Corps de bateau
Sous-marins
Extrémité gauche d’un bateau
Extrémité droite d’un bateau
Extrémité basse d’un bateau
Extrémité haute d’un bateau
A tout moment, vous pourrez consulter le pense-bête, situé à
droite de la grille (chiffres bleus suivis d’une icône).
Enfin, le n° de la flotte qui vous attaque est visible juste au-dessus de ces chiffres (par exemple le
4 sur la figure ci-dessus indique que vous vous défendez contre la 4e
flotte ennemie).
Toutes les grilles du jeu ont bien sûr une solution et une seule.
En
mode HIRES, pour afficher quelque chose qui bouge rapidement (cas des jeux
d’arcade), il faut obligatoirement passer au langage machine.
La
commande Basic CHAR est trop lente pour faire évoluer des sprites basés sur des
caractères redéfinis. Or les astuces développées pour stocker, afficher et
déplacer des objets en mode HIRES restent mystérieuses tant qu’on ne procède
pas à un “reverse engineering”.
Et c’est un gros boulot !
Oui, mais il n’est pas sûr que l’on soit obligé d’en arriver là. Notre propos n’est pas de comprendre comment marche le programme, mais seulement de récupérer le dessin des sprites et les data nécessaires à leur affichage.
Lors
de la sortie de Xenon-1, je me souviens avoir été fasciné par la beauté et la
rapidité des sprites, lesquels sont animés qui plus est ! Je ne peux pas
faire autrement que de choisir cet exemple pour illustrer mon propos sur la
récupération des sprites.
Un écran HIRES est composé de 200 lignes de 40 octets. Ces 8000 octets sont, soit des attributs, soit des octets compris entre #40 et #7F. Dans ce dernier cas, chaque octet représente un “tiret” composé de 6 pixels. Récupérer les data d’un sprite, c’est récupérer les octets correspondant à tous les tirets qui le composent et si le sprite est multicolore, la valeur et la position des attributs utilisés. En outre, si le sprite est animé, il faut récupérer toutes les images du sprite.
Je vous propose deux méthodes :
Faire simultanément un dump de la mémoire et une
recopie d’écran (enfin, aussi simultanément que possible). Avec un éditeur
hexadécimal, comparer les octets de la zone écran HIRES avec les objets
présents sur la recopie d’écran. Récupérer tout simplement ces octets, qui
constituent les data de définition des sprites.
Faire une recopie d’écran. Agrandir le fichier
.bmp ou .png jusqu’au niveau du pixel avec un bon logiciel de traitement
d’image. Isoler le sprite intéressant et le numériser manuellement. La bonne
vieille méthode quoi ! Faisable mais ch…, heu… fastidieux ! Si vous
avez beaucoup de sprites à traiter vous pouvez aussi utiliser une feuille de
calculs pour simplifier la numérisation.
La première méthode en pratique
Les paresseux sont des gens qui cherchent à s’éviter du
travail. C’est en cherchant à échapper à la phase de numérisation des tirets
que j’ai eu l’idée de la méthode 1, dérivée de celle que j’ai utilisée
précédemment pour les écrans TEXT.
Autant vous avouer tout de suite, que ma paresse n’a
pas été récompensée ! Certes cette méthode marche, mais au final, c’est
très compliqué. Vous pouvez donc passer directement à la seconde méthode, sauf
si vous avez la fantaisie et le temps d’être curieux !
Procédure dans Euphoric :
Lancez Xenon1.tap avec Euphoric en configuration Atmos (vous trouverez la version Simon G. de ce tap dans le zip qui accompagne cet article, ainsi que sur le site oric.org).
Allez à l’écran qui vous intéresse, le premier par exemple.
Pressez aussi rapidement que possible les touches F9 (dump de la mémoire) puis F12 (recopie de l’écran).
Pressez F11 (débogueur) pour figer le jeu et gardez la fenêtre en réserve en vue d’un autre essai (il s’agit de sprites animés et il y a plusieurs images à récupérer pour chacun).
Renommez le fichier DUMP qui a été généré par exemple en DumpX1-01.bin
Ouvrez DumpX1-01.bin et réglez l’affichage pour
avoir 40 octets en largeur.
Allez à l’adresse #A000 (début de l’écran
HIRES). Chaque ligne de l’éditeur correspond à une ligne HIRES.
Dans la partie gauche de l’éditeur se trouvent
les octets présents dans l’écran. Chacun représente, soit un attribut, soit un
tiret de 6 pixels, selon que son bit 6 est à zéro (attribut) ou à un (tiret).
Dans ce dernier cas, les 6 bits les plus faibles représentent les pixels. Par
exemple les octets #40 (les plus nombreux et de loin) soit 01000000 en binaire,
correspondent à un espace ou plutôt à un tiret dont les 6 pixels sont de la
couleur du fond, donc invisibles (par défaut en HIRES, le fond est noir et
l’encre blanche).
Dans la partie droite de l’éditeur, sont
affichés les caractères Ascii correspondants. Le foisonnement de @ qui
correspond aux nombreux octets #40 saute aux yeux. On peut voir aussi soit des
points (les attributs), soit des caractères. Ces caractères n’ont rien à voir
avec des caractères dans l’écran. C’est seulement que l’éditeur hexadécimal
considère chaque octet comme un code Ascii et affiche le caractère
correspondant.
Contrairement à ce qui se passait avec l’écran texte,
il n’est pas possible de visualiser tout l’écran HIRES d’un seul coup. En
effet, alors que l’écran TEXT compte 28 lignes, l’écran HIRES en compte 200. Il
faut donc faire défiler l’affichage de l’éditeur verticalement pour comparer
les octets et caractères associés avec ce qu’on voit sur la recopie d’écran.
Comparaison des octets dans la Ram et de l’écran
La figure ci-dessus, montre une telle tranche d’écran, et permet de comparer les octets (à gauche), le caractère Ascii correspondant (à droite) et la portion d’écran HIRES correspondante en dessous. Les caractères correspondant aux tirets des sprites sautent aux yeux au milieu de la forêt des caractères @. Il “suffit” de noter (ou faire un collé/copié) des octets proprement dits (partie gauche de l’éditeur) pour avoir les data définissant chaque sprite. Enfin, c’était sans compter que les sprites se déplacent de façon très fluide (sur la figure ci-dessous, l’oiseau glisse, de un pixel à la fois, de gauche à droite dans l’écran). L’affichage d’un sprite coïncide rarement avec les octets (sinon les déplacements seraient saccadés de 6 pixels en 6 pixels).
Le sprite glisse de gauche à droite dans l’écran Hires, de un pixel à la fois
Dans le cas de cet écran Xenon1, les sprites font 18 pixels
de large sur 18 pixels de haut. En théorie, il faut donc 3 tirets de 6 pixels
pour afficher un sprite dans le sens de la largeur. En pratique, le programme
en langage machine se charge de faire glisser le sprite dans une fenêtre de 4
tirets de large.
Par exemple, la première ligne du sprite situé en haut à gauche de l’écran (ligne qui inclut le haut des deux cornes) peut être définie par les pixels suivant (0=pixel éteint, 1=pixel visible) : 000000100001000000. Ce qui devrait correspondre aux 3 octets suivants (après avoir forcé le bit 6 à 1, drapeau indiquant qu’il ne s’agit pas d’un attribut) : #40, #61 et #40. Or on observe sur la figure que 4 octets sont impliqués : #40, #42, #44 et #40, ce qui, en ne conservant que les bits b0 à b5, correspond aux pixels suivants : 000000000010000100000000. On voit que l’affichage du sprite de 18 pixels de large a été effectué sur 24 pixels. Pour récupérer les valeurs significatives des 3 octets il faudrait redécouper les 24 pixels en 3 zone de 6 pixel et laisser tomber (dans ce cas précis) les 4 pixels de tête et les 2 pixels de queue. En pratique c’est bien trop compliqué, à moins d’être un expert des tableurs genre Excel ou Calc !
La seconde méthode en pratique
La figure ci-dessous montre l’un des sprites de Xenon1, très agrandi. J’ai laissé volontairement une bande supplémentaire de 4 pixels de large à gauche et une autre de 2 pixels à droite pour que vous puissiez restituer et visualiser ce que nous avions précédemment avec la méthode 1.
Résumons ce que l’on voit : On a un sprite de 18×18 pixels
(3 tirets de 6 pixels de large sur 18 lignes HIRES de haut) affiché dans une
zone de 24×18 pixels (4 tirets de 6 pixels de large sur 18 lignes HIRES).
Les lignes verticales blanches délimitent les octets
directement impliqués dans le dessin du sprite proprement dit. Chacune des 18
lignes HIRES doit donc être découpée en 3 tirets de 6 pixels de façon à
récupérer le dessin réel du sprite. La nouvelle séparation en 3 zones de 6
pixels de large est visualisée par les lignes pointillées.
Numérisation du dessin pour obtenir les octets définissant le sprite
Au total, il nous faut donc numériser 18 fois 3 tirets pour récupérer tous les data du sprite. La figure ci-dessus montre un exemple de numérisation. Il s’agit de la tête du sprite.
Le premier tiret par exemple (haut des cornes sur la tête)
correspond à 100001
en binaire soit #21, valeur à laquelle il faudra ajouter #40 pour mettre le bit
6 à un (drapeau pour reconnaître les tirets), soit #61 dans cet exemple. Et
ainsi de suite pour l’ensemble des 54 tirets du sprite.
Ceci représente un travail forcément important, mais moins
qu’il n’y parait, car il y a beaucoup de redondances (tirets identiques).
A vous de voir si vous voulez vous aider soit d’un tableur (vous mettrez des croix dans les cases et il calcule les valeurs finales à utiliser), soit d’un simple tableau des 64 combinaisons possibles donnant directement les valeurs à utiliser.
Exemple d’écran-titre d’un logiciel protégé par C-SAFE
Constatation
Les cassettes et les disquettes 3″ vieillissent mal, de
même que leurs lecteurs respectifs. Le transfert des logiciels Oric sur des
supports modernes est donc crucial. C’est grâce à ces transferts et à divers
émulateurs que nous pouvons profiter, encore aujourd’hui, des programmes
achetés dans les années 80. Simon G., Dominique P., Fabrice F. et bien d’autres
ont réussi à transférer au format .tap la plupart des logiciels du commerce, notamment
ceux qui comptent parmi les mieux protégés.
La complexité des moyens de protection mis en œuvre
est parfois surprenante au vu de leur valeur économique somme toute limitée.
Un florilège de protections
Les passionnés de casse-têtes pourront découvrir ou relire
les nombreux articles passionnants parus dans le CEO-mag à ce sujet. Pas loin
d’une centaine d’articles ont été publiés qui décortiquent les divers procédés
de protection rencontrés. Parmi les plus spectaculaires, citons C-SAFE, utilisé
pour Titan, Logor et Talisman de chez Infogrames et pour Vortex de chez Loriciels
(voir articles “C-SAFE et .TAP” par Simon G. et Dominique P., CEO-mag
n°261, pages 14 et 15, ainsi que “Cassettes, un florilège de formats
exotiques (2) ” par Dominique P., CEO-mag 262, pages 18 et 19.
Mais il existe tout une panoplie d’autres systèmes de
protection et de formats exotiques…
Bilan des transferts au format .tap ou .dsk
Un très grand nombre de logiciels sont maintenant
disponibles dans ces formats. Pour lever les protections, il a parfois été
nécessaire de modifier un minimum d’octets, mais toujours avec le souci de coller au plus près
à l’original.
Les procédures utilisées pour contourner certaines
protections sont si complexes, qu’il est souvent beaucoup plus simple de lire
les cassettes audio, d’enregistrer la “musique” au format classique .wav.
Le fichier obtenu peut alors être placé sur une bande magnétique ou un CD et
réinjecté dans un Oric réel ou être rechargé dans un émulateur. Mais bien sûr
ce fichier .wav inclut toujours la protection. Le logiciel est utilisable, mais
on ne peut pas “regarder dedans”.
Au moins 25 fichiers au format .wav sont aujourd’hui disponibles
sur oric.org et concernent évidemment les logiciels les plus réticents.
Ecrans versus recopie d’écrans
Certes, les émulateurs permettent d’effectuer des recopies d’écrans, mais les fichiers obtenus sont aux formats .BMP, .GIF, etc. Il serait intéressant de récupérer les écrans TEXT ou HIRES aux formats Oric .SCR et .HRS sur un support .tap ou .dsk. Dans le même genre d’idée, ce serait chouette de récupérer les caractères redéfinis, les musiques, etc. Or, comme écrit plus haut, on ne peut pas “regarder dedans”. Mais est-ce bien sûr?
Exploration de la Ram
Non seulement c’est tout à fait possible, mais en plus c’est très simple. En effet, les émulateurs permettent d’effectuer un dump de la mémoire. Ainsi avec Euphoric, un simple appui sur la touche F9 sauve un fichier DUMP de 64 Ko correspondant à l’intégralité de la mémoire de l’Oric émulé. Il ne reste plus qu’à explorer ce fichier DUMP à l’aide d’un éditeur hexadécimal et d’en extraire les parties intéressantes par exemple les écrans.
Les divers types d’écrans
Trois types d’écrans peuvent être récupérés :
Ecrans basse résolution (TEXT, LORES0 et LORES1)
situés de #BB80 à #BFDF en Ram (soit #0460 octets ou 1120 en décimal ce qui
correspond bien à 28 lignes de 40 caractères).
Ecrans haute résolution seuls (sans les 3 lignes
de texte) situés de #A000 à #BF3F (soit #1F40 octets ou 8000 en décimal pour 200
lignes de 40 tirets de 6 pixels).
Ecrans haute résolution avec les 3 lignes de
texte en dessous, situés de #A000 à #BFDF (soit #1FE0 octets ou 8160 en
décimal. On remarquera une petite curiosité : la Ram comporte 4 lignes de
texte sous l’écran Hires (d’où les 160 octets supplémentaires) mais la première
des quatre n’est pas affichée et les 40 octets correspondants restent donc
inutilisés!
Puisqu’on connait les adresses de début et de fin de
ces écrans, rien ne sera plus facile que de les récupérer, puisqu’ils ont la
même adresse en Ram et dans le fichier DUMP, et de les copier derrière un
en-tête cassette. Les en-têtes cassettes ont été décrits dans le CEO-mag n°153
page 17. Mais il est plus simple (et plus sûr) de sauver un écran bidon et d’en
récupérer l’en-tête, plutôt que de construire celui-ci octet par octet.
Fabriquez les en-têtes appropriés
Pour ces 3 types de d’écran, il vous faudra faire 3 modèles
d’en-tête avec le petit programme SAUVENT.COM suivant (voir le fichier .zip
joint à cet article) :
100 HIRES
110 CSAVE”MODLHRS1″,A#A000,E#BF3F
120 CSAVE”MODLHRS2″,A#A000,E#BFDF
130 TEXT
140 CSAVE”MODLTEXT”,A#BB80,E#BFDF
150 PING
Pour avoir les 3 en-têtes, récupérez les octets du début du fichier .tap, allant du #16 initial au #00 (inclus) situé juste après le nom du fichier. Dans les conditions décrites, les 3 en-têtes auront au final une longueur de 23 octets (ou 22 si le début du fichier ne comporte que 3 fois l’octet #16 au lieu de 4, selon la version d’émulateur utilisé). A l’issue de ce petit travail, vous disposerez donc de 3 modèles d’en-tête que vous garderez précieusement [figures MODLHRS1, MODLHRS2 et MODLTEXT.GIF]. Les fichiers .tap correpondant à ces 3 en-têtes sont dans le zip joint à cet article.
Récupérez les DUMPs
La procédure de récupération des écrans est maintenant
simple :
Lancez Euphoric en mode Atmos, pressez F1, validez
“Hardware tape” et indiquez le nom du fichier .wav à traiter, (par
ex. LOGOR.WAV qui n’existe pas en version .tap).
Pressez F1 pour revenir à l’Atmos.
Tapez CLOAD”” et chargez le fichier
.wav. Tiens cela n’a pas changé : C’est toujours très long ! Sauf que
2 appuis sur la touche F4 et ça charge 4 fois plus vite ! Retour à la
vitesse normale par un appui sur la touche F5.
Le programme se lance. Guettez le moment où
s’affiche l’écran que vous désirez sauver et pressez la touche F9 (dump
mémoire) puis sur F11 (débogueur). En mode débogueur l’exécution se fige, ce
qui vous laisse le temps de renommer le fichier DUMP obtenu (par ex DUMP01
etc.), sinon il sera écrasé au prochain appui sur la touche F9. Nouvel appui
sur la touche F11 pour sortir du débogueur. Guettez le prochain écran
intéressant (s’il y en a), F9 puis F11, etc.
Notez qu’il est possible de recharger un des
états ainsi sauvé pour reprendre l’exécution du programme là où elle en était,
en relançant Euphoric avec “Euphoric -a –r” (attention le nom du
fichier utilisé par Euphoric sera DUMP tout court).
Petite difficulté dans mon système : Euphoric sauvegarde
le fichier DUMP dans le répertoire “Tapes”, mais si on relance avec
“Euphoric -a –r”, Euphoric cherche DUMP dans le répertoire “Euphoric”.
Mais c’est sans doute un problème de configuration.
Et enfin, récupérez les écrans
Vous vous trouvez maintenant en possession d’un ou plusieurs
fichiers DUMPxx. Il faut en extraire la zone écran qui vous intéresse et lui
coller un en-tête ad hoc par devant. Prenons par exemple le format Hires long
(avec les 3 lignes de texte en dessous) situé en Ram de #A000 à #BFDF.
Dans votre éditeur hexadécimal :
Ouvrez le modèle d’en-tête correspondant, soit MODLHRS2.
CTRL+A puis CTRL+C pour copier les 23 octets du fichier.
Ouvrez un nouveau document. CTRL+V pour y coller
l’en-tête. Editez les 8 caractères “MODLHRS2” pour renommer votre
fichier .tap
Ouvrez le fichier DUMPxx à traiter. Sélectionnez
les #1FE0 octets correspondant à l’écran Hires. Par exemple Goto #A000 puis Select bloc #1FE0, puis CTRL+C.
Allez dans le nouveau document, à la fin de
l’en-tête, CTRL+V, pour y coller l’écran.
Sauvegardez votre écran au format .tap par
exemple sous le nom ECRANxx.tap. C’est fait.