{"id":1419,"date":"2019-12-12T17:37:49","date_gmt":"2019-12-12T16:37:49","guid":{"rendered":"https:\/\/ceo.oric.org\/?p=1419"},"modified":"2019-12-12T17:37:49","modified_gmt":"2019-12-12T16:37:49","slug":"recuperez-les-sprites-des-logiciels-en-mode-hires","status":"publish","type":"post","link":"https:\/\/oric.bqtt.net\/index.php\/2019\/12\/12\/recuperez-les-sprites-des-logiciels-en-mode-hires\/","title":{"rendered":"R\u00e9cup\u00e9rez les sprites des logiciels en mode HIRES"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em> par Andr\u00e9 C. <\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En\nmode HIRES, pour afficher quelque chose qui bouge rapidement (cas des jeux\nd&#8217;arcade), il faut obligatoirement passer au langage machine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La\ncommande Basic CHAR est trop lente pour faire \u00e9voluer des sprites bas\u00e9s sur des\ncaract\u00e8res red\u00e9finis. Or les astuces d\u00e9velopp\u00e9es pour stocker, afficher et\nd\u00e9placer des objets en mode HIRES restent myst\u00e9rieuses tant qu&#8217;on ne proc\u00e8de\npas \u00e0 un &#8220;reverse engineering&#8221;.\nEt c&#8217;est un gros boulot&nbsp;! <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Oui, mais il n&#8217;est pas s\u00fbr que l&#8217;on soit oblig\u00e9 d&#8217;en arriver l\u00e0. Notre propos n&#8217;est pas de comprendre comment marche le programme, <em>mais seulement de r\u00e9cup\u00e9rer le dessin des sprites et les data n\u00e9cessaires \u00e0 leur affichage<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lors\nde la sortie de Xenon-1, je me souviens avoir \u00e9t\u00e9 fascin\u00e9 par la beaut\u00e9 et la\nrapidit\u00e9 des sprites, lesquels sont anim\u00e9s qui plus est&nbsp;! Je ne peux pas\nfaire autrement que de choisir cet exemple pour illustrer mon propos sur la\nr\u00e9cup\u00e9ration des sprites.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un \u00e9cran HIRES est compos\u00e9 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\u00e9sente un &#8220;tiret&#8221; compos\u00e9 de 6 pixels. R\u00e9cup\u00e9rer les data d&#8217;un sprite, c&#8217;est r\u00e9cup\u00e9rer les octets correspondant \u00e0 tous les tirets qui le composent et si le sprite est multicolore, la valeur et la position des attributs utilis\u00e9s. En outre, si le sprite est anim\u00e9, <em>il faut r\u00e9cup\u00e9rer toutes les images du sprite<\/em>. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Je vous propose deux m\u00e9thodes&nbsp;:<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\"><li>Faire simultan\u00e9ment un dump de la m\u00e9moire et une\nrecopie d&#8217;\u00e9cran (enfin, aussi simultan\u00e9ment que possible). Avec un \u00e9diteur\nhexad\u00e9cimal, comparer les octets de la zone \u00e9cran HIRES avec les objets\npr\u00e9sents sur la recopie d&#8217;\u00e9cran. R\u00e9cup\u00e9rer tout simplement ces octets, qui\nconstituent les data de d\u00e9finition des sprites.<\/li><li>Faire une recopie d&#8217;\u00e9cran. Agrandir le fichier\n.bmp ou .png jusqu&#8217;au niveau du pixel avec un bon logiciel de traitement\nd&#8217;image. Isoler le sprite int\u00e9ressant et le num\u00e9riser manuellement. La bonne\nvieille m\u00e9thode quoi&nbsp;! Faisable mais ch\u2026, heu\u2026 fastidieux&nbsp;! Si vous\navez beaucoup de sprites \u00e0 traiter vous pouvez aussi utiliser une feuille de\ncalculs pour simplifier la num\u00e9risation.<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>La premi\u00e8re m\u00e9thode en pratique<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Les paresseux sont des gens qui cherchent \u00e0 s&#8217;\u00e9viter du\ntravail. C&#8217;est en cherchant \u00e0 \u00e9chapper \u00e0 la phase de num\u00e9risation des tirets\nque j&#8217;ai eu l&#8217;id\u00e9e de la m\u00e9thode 1, d\u00e9riv\u00e9e de celle que j&#8217;ai utilis\u00e9e\npr\u00e9c\u00e9demment pour les \u00e9crans TEXT.\n\nAutant vous avouer tout de suite, que ma paresse n&#8217;a\npas \u00e9t\u00e9 r\u00e9compens\u00e9e&nbsp;! Certes cette m\u00e9thode marche, mais au final, c&#8217;est\ntr\u00e8s compliqu\u00e9. Vous pouvez donc passer directement \u00e0 la seconde m\u00e9thode, sauf\nsi vous avez la fantaisie et le temps d&#8217;\u00eatre curieux&nbsp;!\n\n\n\n<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Proc\u00e9dure dans Euphoric :<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\"><li>Lancez Xenon1.tap avec Euphoric en configuration Atmos (vous trouverez la version Simon&nbsp;G. de ce tap dans le zip qui accompagne cet article, ainsi que sur le site oric.org).<\/li><li>Allez \u00e0 l&#8217;\u00e9cran qui vous int\u00e9resse, le premier par exemple.<\/li><li>Pressez aussi rapidement que possible les touches F9 (dump de la m\u00e9moire) puis F12 (recopie de l&#8217;\u00e9cran).<\/li><li>Pressez F11 (d\u00e9bogueur) pour figer le jeu et gardez la fen\u00eatre en r\u00e9serve en vue d&#8217;un autre essai (il s&#8217;agit de sprites anim\u00e9s et il y a plusieurs images \u00e0 r\u00e9cup\u00e9rer pour chacun).<\/li><li>Renommez le fichier DUMP qui a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 par exemple en DumpX1-01.bin<\/li><li>Renommez le fichier Screenxx.bmp en Xenon1-01.bmp <\/li><\/ol>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/oric.bqtt.net\/wp-content\/uploads\/2019\/12\/RecupSprites.zip\">RecupSprites<\/a><a href=\"https:\/\/oric.bqtt.net\/wp-content\/uploads\/2019\/12\/RecupSprites.zip\" class=\"wp-block-file__button\" download>T\u00e9l\u00e9charger<\/a><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Proc\u00e9dure avec votre \u00e9diteur hexad\u00e9cimal :<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\"><li>Ouvrez DumpX1-01.bin et r\u00e9glez l&#8217;affichage pour\navoir 40 octets en largeur.<\/li><li>Allez \u00e0 l&#8217;adresse #A000 (d\u00e9but de l&#8217;\u00e9cran\nHIRES). Chaque ligne de l&#8217;\u00e9diteur correspond \u00e0 une ligne HIRES.<\/li><li>Dans la partie gauche de l&#8217;\u00e9diteur se trouvent\nles octets pr\u00e9sents dans l&#8217;\u00e9cran. Chacun repr\u00e9sente, soit un attribut, soit un\ntiret de 6 pixels, selon que son bit 6 est \u00e0 z\u00e9ro (attribut) ou \u00e0 un (tiret).\nDans ce dernier cas, les 6 bits les plus faibles repr\u00e9sentent les pixels. Par\nexemple les octets #40 (les plus nombreux et de loin) soit 01000000 en binaire,\ncorrespondent \u00e0 un espace ou plut\u00f4t \u00e0 un tiret dont les 6 pixels sont de la\ncouleur du fond, donc invisibles (par d\u00e9faut en HIRES, le fond est noir et\nl&#8217;encre blanche).<\/li><li>Dans la partie droite de l&#8217;\u00e9diteur, sont\naffich\u00e9s les caract\u00e8res Ascii correspondants. Le foisonnement de @ qui\ncorrespond aux nombreux octets #40 saute aux yeux. On peut voir aussi soit des\npoints (les attributs), soit des caract\u00e8res. Ces caract\u00e8res n&#8217;ont rien \u00e0 voir\navec des caract\u00e8res dans l&#8217;\u00e9cran. C&#8217;est seulement que l&#8217;\u00e9diteur hexad\u00e9cimal\nconsid\u00e8re chaque octet comme un code Ascii et affiche le caract\u00e8re\ncorrespondant.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\n\n\n\n\n\n\n\nContrairement \u00e0 ce qui se passait avec l&#8217;\u00e9cran texte,\nil n&#8217;est pas possible de visualiser tout l&#8217;\u00e9cran HIRES d&#8217;un seul coup. En\neffet, alors que l&#8217;\u00e9cran TEXT compte 28 lignes, l&#8217;\u00e9cran HIRES en compte 200. Il\nfaut donc faire d\u00e9filer l&#8217;affichage de l&#8217;\u00e9diteur verticalement pour comparer\nles octets et caract\u00e8res associ\u00e9s avec ce qu&#8217;on voit sur la recopie d&#8217;\u00e9cran.\n\n\n\n<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/oric.bqtt.net\/wp-content\/uploads\/2019\/12\/DumpX1-01F12-1024x570.gif\" alt=\"\" class=\"wp-image-1421\"\/><figcaption>Comparaison des octets dans la Ram et de l&#8217;\u00e9cran<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">La figure ci-dessus, montre une telle tranche d&#8217;\u00e9cran, et permet de comparer les octets (\u00e0 gauche), le caract\u00e8re Ascii correspondant (\u00e0 droite) et la portion d&#8217;\u00e9cran HIRES correspondante en dessous. Les caract\u00e8res correspondant aux tirets des sprites sautent aux yeux au milieu de la for\u00eat des caract\u00e8res @. Il &#8220;suffit&#8221; de noter (ou faire un coll\u00e9\/copi\u00e9) des octets proprement dits (partie gauche de l&#8217;\u00e9diteur) pour avoir les data d\u00e9finissant chaque sprite. Enfin, c&#8217;\u00e9tait sans compter que les sprites se d\u00e9placent de fa\u00e7on tr\u00e8s fluide (sur la figure ci-dessous, l&#8217;oiseau glisse, de un pixel \u00e0 la fois, de gauche \u00e0 droite dans l&#8217;\u00e9cran). L&#8217;affichage d&#8217;un sprite co\u00efncide rarement avec les octets (sinon les d\u00e9placements seraient saccad\u00e9s de 6 pixels en 6 pixels). <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/oric.bqtt.net\/wp-content\/uploads\/2019\/12\/Xenon1Animation-1024x110.png\" alt=\"\" class=\"wp-image-1422\"\/><figcaption>Le sprite glisse de gauche \u00e0 droite dans l&#8217;\u00e9cran Hires, de un pixel \u00e0 la fois<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Dans le cas de cet \u00e9cran Xenon1, les sprites font 18 pixels\nde large sur 18 pixels de haut. En th\u00e9orie, il faut donc 3 tirets de 6 pixels\npour afficher un sprite dans le sens de la largeur. En pratique, le programme\nen langage machine se charge de faire glisser le sprite dans une fen\u00eatre de 4\ntirets de large.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Par exemple, la premi\u00e8re ligne du sprite situ\u00e9 en haut \u00e0 gauche de l&#8217;\u00e9cran (ligne qui inclut le haut des deux cornes) peut \u00eatre d\u00e9finie par les pixels suivant (0=pixel \u00e9teint, 1=pixel visible)&nbsp;: <strong>000000<\/strong><em>100001<\/em><strong>000000<\/strong>. Ce qui devrait correspondre aux 3 octets suivants (apr\u00e8s avoir forc\u00e9 le bit 6 \u00e0 1, drapeau indiquant qu&#8217;il ne s&#8217;agit pas d&#8217;un attribut)&nbsp;: #40, #61 et #40. Or on observe sur la figure que 4 octets sont impliqu\u00e9s&nbsp;: #40, #42, #44 et #40, ce qui, en ne conservant que les bits b0 \u00e0 b5, correspond aux pixels suivants&nbsp;: 0000<strong>000000<\/strong><em>100001<\/em><strong>000000<\/strong>00. On voit que l&#8217;affichage du sprite de 18 pixels de large a \u00e9t\u00e9 effectu\u00e9 sur 24 pixels. Pour r\u00e9cup\u00e9rer les valeurs significatives des 3 octets il faudrait red\u00e9couper les 24 pixels en 3 zone de 6 pixel et laisser tomber (dans ce cas pr\u00e9cis) les 4 pixels de t\u00eate et les 2 pixels de queue. En pratique c&#8217;est bien trop compliqu\u00e9, \u00e0 moins d&#8217;\u00eatre un expert des tableurs genre Excel ou Calc&nbsp;! <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>La seconde m\u00e9thode en pratique<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"> La figure ci-dessous montre l&#8217;un des sprites de Xenon1, tr\u00e8s agrandi. J&#8217;ai laiss\u00e9 volontairement une bande suppl\u00e9mentaire de 4 pixels de large \u00e0 gauche et une autre de 2 pixels \u00e0 droite pour que vous puissiez restituer et visualiser ce que nous avions pr\u00e9c\u00e9demment avec la m\u00e9thode&nbsp;1. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/oric.bqtt.net\/wp-content\/uploads\/2019\/12\/Xenon1-01SpriteHG-1024x777.png\" alt=\"\" class=\"wp-image-1423\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">R\u00e9sumons ce que l&#8217;on voit : On a un sprite de 18&#215;18 pixels\n(3 tirets de 6 pixels de large sur 18 lignes HIRES de haut) affich\u00e9 dans une\nzone de 24&#215;18 pixels (4 tirets de 6 pixels de large sur 18 lignes HIRES).\n\nLes lignes verticales blanches d\u00e9limitent les octets\ndirectement impliqu\u00e9s dans le dessin du sprite proprement dit. Chacune des 18\nlignes HIRES doit donc \u00eatre d\u00e9coup\u00e9e en 3 tirets de 6 pixels de fa\u00e7on \u00e0\nr\u00e9cup\u00e9rer le dessin r\u00e9el du sprite. La nouvelle s\u00e9paration en 3 zones de 6\npixels de large est visualis\u00e9e par les lignes pointill\u00e9es.\n\n\n\n<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/oric.bqtt.net\/wp-content\/uploads\/2019\/12\/Num%C3%A9risationT%C3%AAte-1024x1003.png\" alt=\"\" class=\"wp-image-1424\"\/><figcaption>Num\u00e9risation du dessin pour obtenir les octets d\u00e9finissant le sprite<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Au total, il nous faut donc num\u00e9riser 18 fois 3 tirets pour r\u00e9cup\u00e9rer tous les data du sprite. La figure ci-dessus montre un exemple de num\u00e9risation. Il s&#8217;agit de la t\u00eate du sprite.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Le premier tiret par exemple (haut des cornes sur la t\u00eate)\ncorrespond \u00e0 100001\nen binaire soit #21, valeur \u00e0 laquelle il faudra ajouter #40 pour mettre le bit\n6 \u00e0 un (drapeau pour reconna\u00eetre les tirets), soit #61 dans cet exemple. Et\nainsi de suite pour l&#8217;ensemble des 54 tirets du sprite. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ceci repr\u00e9sente un travail forc\u00e9ment important, mais moins\nqu&#8217;il n&#8217;y parait, car il y a beaucoup de redondances (tirets identiques). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A vous de voir si vous voulez vous aider soit d&#8217;un tableur (vous mettrez des croix dans les cases et il calcule les valeurs finales \u00e0 utiliser), soit d&#8217;un simple tableau des 64 combinaisons possibles donnant directement les valeurs \u00e0 utiliser.<\/p>\n\n\n\n<p class=\"has-text-align-right wp-block-paragraph\">Bon courage&nbsp;! <\/p>\n","protected":false},"excerpt":{"rendered":"<p>par Andr\u00e9 C. En mode HIRES, pour afficher quelque chose qui bouge rapidement (cas des jeux d&#8217;arcade), il faut obligatoirement passer au langage machine. La commande Basic CHAR est trop lente pour faire \u00e9voluer des sprites bas\u00e9s sur des caract\u00e8res red\u00e9finis. Or les astuces d\u00e9velopp\u00e9es pour stocker, afficher et d\u00e9placer des objets en mode HIRES [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1423,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[347,22,359],"tags":[899],"class_list":["post-1419","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-atmos","category-ceomag","category-emulateur","tag-truc-software"],"_links":{"self":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/posts\/1419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/comments?post=1419"}],"version-history":[{"count":0,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/posts\/1419\/revisions"}],"wp:attachment":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/media?parent=1419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/categories?post=1419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/tags?post=1419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}