{"id":2396,"date":"2019-12-14T22:26:27","date_gmt":"2019-12-14T19:26:27","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=2396"},"modified":"2024-12-16T22:32:32","modified_gmt":"2024-12-16T19:32:32","slug":"%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b0-%d0%b8%d0%b3%d1%80%d1%8b-%d0%b4%d0%bb%d1%8f-zx-spectrum-%d0%bd%d0%b0-c","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/fr\/2019\/12\/14\/%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b0-%d0%b8%d0%b3%d1%80%d1%8b-%d0%b4%d0%bb%d1%8f-zx-spectrum-%d0%bd%d0%b0-c\/","title":{"rendered":"D\u00e9veloppement de jeux pour ZX Spectrum en C"},"content":{"rendered":"<p>Cet article absurde est d\u00e9di\u00e9 au d\u00e9veloppement d&#8217;un jeu pour l&#8217;ancien ordinateur ZX Spectrum en C. Jetons un coup d&#8217;\u0153il au beau mec\u00a0:<\/p>\n<p><a href=\"https:\/\/www.flickr.com\/photos\/quenerapu\/2622099393\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2398\" src=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/12\/2622099393_8199976c15_w.jpg\" alt=\"\" width=\"400\" height=\"294\" srcset=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/12\/2622099393_8199976c15_w.jpg 400w, https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/12\/2622099393_8199976c15_w-300x221.jpg 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p> Sa production a commenc\u00e9 en 1982 et a \u00e9t\u00e9 produite jusqu&#8217;en 1992. Caract\u00e9ristiques techniques de la machine\u00a0: processeur Z80 8 bits, 16-128 Ko de m\u00e9moire et autres extensions, comme la <b>puce sonore AY-3-8910.<\/b><\/p>\n<p>Dans le cadre du concours <a href=\"http:\/\/rgb.yandex\/\" target=\"_blank\" rel=\"noopener noreferrer\">Yandex Retro Games Battle 2019<\/a> pour cette machine, j&#8217;ai \u00e9crit un jeu appel\u00e9 Interceptor 2020. Comme je n\u2019ai pas eu le temps d\u2019apprendre le langage assembleur pour le Z80, j\u2019ai d\u00e9cid\u00e9 de le d\u00e9velopper en C. En tant que cha\u00eene d&#8217;outils, j&#8217;ai choisi un ensemble pr\u00eat \u00e0 l&#8217;emploi &#8211; z88dk, qui contient des compilateurs C et de nombreuses biblioth\u00e8ques auxiliaires pour acc\u00e9l\u00e9rer la mise en \u0153uvre des applications pour Spectrum. Il prend \u00e9galement en charge de nombreuses autres machines Z80, telles que les calculatrices MSX et Texas Instruments.<\/p>\n<p>Ensuite, je d\u00e9crirai mon survol superficiel de l&#8217;architecture informatique, la cha\u00eene d&#8217;outils z88dk, et montrerai comment j&#8217;ai r\u00e9ussi \u00e0 mettre en \u0153uvre l&#8217;approche POO et \u00e0 utiliser des mod\u00e8les de conception.<\/p>\n<h3>Fonctionnalit\u00e9s d&#8217;installation<\/h3>\n<p>L&#8217;installation de z88dk doit \u00eatre effectu\u00e9e conform\u00e9ment au manuel du r\u00e9f\u00e9rentiel, cependant, pour les utilisateurs d&#8217;Ubuntu, je voudrais noter une fonctionnalit\u00e9 &#8211; Si vous avez d\u00e9j\u00e0 install\u00e9 des compilateurs pour Z80 \u00e0 partir de packages deb, vous devez les supprimer, puisque z88dk y acc\u00e9dera \u00e0 partir du dossier bin par d\u00e9faut en raison de l&#8217;incompatibilit\u00e9 des versions du compilateur de la cha\u00eene d&#8217;outils, vous ne pourrez probablement rien compiler.< \/p><\/p>\n<h3>Bonjour tout le monde<\/h3>\n<p>\u00c9crire Hello World est tr\u00e8s simple\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>#include \n\nvoid main()\n{\n    printf(\"Hello World\");\n}\n<\/code><\/pre>\n<\/div>\n<p>Il est encore plus simple de compiler un fichier tap\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>zcc +zx -lndos -create-app -o helloworld helloworld.c\n<\/code><\/pre>\n<\/div>\n<p>Pour l&#8217;ex\u00e9cuter, utilisez n&#8217;importe quel \u00e9mulateur ZX Spectrum prenant en charge les fichiers Tap, par exemple en ligne\u00a0:<br \/><a href=\"http:\/\/jsspeccy.zxdemo.org\/\">http:\/\/jsspeccy.zxdemo.org\/<\/a><\/p>\n<h3>Dessinez sur l&#8217;image en plein \u00e9cran<\/h3>\n<p><i>tl;dr Les images sont dessin\u00e9es en tuiles, des tuiles de taille 8&#215;8 pixels, les tuiles elles-m\u00eames sont int\u00e9gr\u00e9es dans la police Spectrum, puis l&#8217;image est imprim\u00e9e sous forme de ligne \u00e0 partir des index. <\/i><\/p>\n<p>La biblioth\u00e8que de sortie de sprites et de tuiles sp1 g\u00e9n\u00e8re des tuiles en utilisant UDG. L&#8217;image est traduite en un ensemble d&#8217;UDG individuels (tuiles), puis assembl\u00e9s sur l&#8217;\u00e9cran \u00e0 l&#8217;aide d&#8217;indices. Il ne faut pas oublier que UDG est utilis\u00e9 pour afficher du texte, et si votre image contient un tr\u00e8s grand ensemble de tuiles (par exemple, plus de 128 tuiles), alors vous devrez d\u00e9passer les limites de l&#8217;ensemble et effacer le spectre par d\u00e9faut. fonte. Pour contourner cette limitation, j&#8217;ai utilis\u00e9 une base de 128 &#8211; 255 en simplifiant les images tout en laissant la police d&#8217;origine en place. \u00c0 propos de la simplification des images ci-dessous.<\/p>\n<p>Pour dessiner des images en plein \u00e9cran, vous devez vous armer de trois utilitaires\u00a0:<br \/>Gimp<br \/>img2spec<br \/>png2c-z88dk<\/p>\n<p>Il existe un moyen pour les vrais hommes ZX, les vrais guerriers r\u00e9tro, celui-ci consiste \u00e0 ouvrir un \u00e9diteur graphique \u00e0 l&#8217;aide de la palette Spectrum, connaissant les caract\u00e9ristiques de la sortie de l&#8217;image, \u00e0 la pr\u00e9parer manuellement et \u00e0 la t\u00e9l\u00e9charger en utilisant png2c-z88dk ou png2scr.< \/p><\/p>\n<p>Le moyen le plus simple &#8211; prenez une image 32 bits, changez le nombre de couleurs sur 3-4 dans Gimp, modifiez-la l\u00e9g\u00e8rement, puis importez-la dans img2spec afin de ne pas travailler manuellement avec les restrictions de couleur, exportez png et convertissez-la en tableau C en utilisant png2c- z88dk.<\/p >\n<p>N&#8217;oubliez pas que pour une exportation r\u00e9ussie, chaque vignette ne peut pas contenir plus de deux couleurs.<\/p>\n<p>En cons\u00e9quence, vous recevrez un fichier h contenant le nombre de tuiles uniques, s&#8217;il y en a plus de ~128, alors simplifiez l&#8217;image dans Gimp (augmentez la r\u00e9p\u00e9tabilit\u00e9) et effectuez la proc\u00e9dure d&#8217;exportation sur une nouvelle. .<\/p>\n<p>Apr\u00e8s l&#8217;exportation, vous chargez litt\u00e9ralement la \u00ab police \u00bb des vignettes et imprimez le \u00ab texte \u00bb des index des vignettes sur l&#8217;\u00e9cran. Vous trouverez ci-dessous un exemple de la \u00ab\u00a0classe\u00a0\u00bb de rendu\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>\/\/ \u0433\u0440\u0443\u0437\u0438\u043c \u0448\u0440\u0438\u0444\u0442 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c\n    unsigned char *pt = fullscreenImage->tiles;\n\n    for (i = 0; i < fullscreenImage->tilesLength; i++, pt += 8) {\n            sp1_TileEntry(fullscreenImage->tilesBase + i, pt);\n    }\n\n    \/\/ \u0441\u0442\u0430\u0432\u0438\u043c \u043a\u0443\u0440\u0441\u043e\u0440 \u0432 0,0\n    sp1_SetPrintPos(&ps0, 0, 0);\n\n    \/\/ \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443\n    sp1_PrintString(&ps0, fullscreenImage->ptiles);\n<\/code><\/pre>\n<\/div>\n<h3>Dessiner des sprites sur l&#8217;\u00e9cran<\/h3>\n<p>Ensuite, je d\u00e9crirai une m\u00e9thode pour dessiner des sprites de 16 \u00e0 16 pixels sur l&#8217;\u00e9cran. Je n&#8217;ai pas abord\u00e9 l&#8217;animation et le changement de couleurs, parce que&#8230; C\u2019est trivial qu\u2019\u00e0 ce stade d\u00e9j\u00e0, comme je suppose, j\u2019ai manqu\u00e9 de m\u00e9moire. Par cons\u00e9quent, le jeu ne contient que des sprites monochromes transparents.<\/p>\n<p>Nous dessinons une image png monochrome 16&#215;16 dans Gimp, puis en utilisant png2sp1sprite nous la traduisons en un fichier d&#8217;assemblage asm, en code C nous d\u00e9clarons des tableaux \u00e0 partir du fichier d&#8217;assemblage et ajoutons le fichier au stade de l&#8217;assemblage.< \/p><\/p>\n<p>Apr\u00e8s l&#8217;\u00e9tape de d\u00e9claration de la ressource sprite, celle-ci doit \u00eatre ajout\u00e9e \u00e0 l&#8217;\u00e9cran \u00e0 la position souhait\u00e9e, ci-dessous un exemple de code pour la \u00ab classe \u00bb de l&#8217;objet du jeu\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>    struct sp1_ss *bubble_sprite = sp1_CreateSpr(SP1_DRAW_MASK2LB, SP1_TYPE_2BYTE, 3, 0, 0);\n    sp1_AddColSpr(bubble_sprite, SP1_DRAW_MASK2,    SP1_TYPE_2BYTE, col2-col1, 0);\n    sp1_AddColSpr(bubble_sprite, SP1_DRAW_MASK2RB,  SP1_TYPE_2BYTE, 0, 0);\n    sp1_IterateSprChar(bubble_sprite, initialiseColour);\n<\/code><\/pre>\n<\/div>\n<p>\u00c0 partir des noms des fonctions, vous pouvez comprendre approximativement la signification de \u00ab &#8211; allouez de la m\u00e9moire pour le sprite, ajoutez deux colonnes 8&#215;8, ajoutez une couleur pour le sprite.<\/p>\n<p>La position du sprite est indiqu\u00e9e dans chaque image\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>sp1_MoveSprPix(gameObject->gameObjectSprite, Renderer_fullScreenRect, gameObject->sprite_col, gameObject->x, gameObject->y);\n<\/code><\/pre>\n<\/div>\n<h3>\u00c9mulation de la POO<\/h3>\n<p>Il n&#8217;y a pas de syntaxe pour la POO en C, que devez-vous faire si vous le souhaitez toujours\u00a0? Vous devez connecter votre esprit et \u00eatre \u00e9clair\u00e9 par l&#8217;id\u00e9e qu&#8217;il n&#8217;existe pas d&#8217;\u00e9quipement POO\u00a0; tout revient finalement \u00e0 l&#8217;une des architectures de machines, dans lesquelles il n&#8217;y a tout simplement aucun concept d&#8217;objet et d&#8217;autres abstractions qui lui sont associ\u00e9es.< \/p><\/p>\n<p>Ce fait m&#8217;a emp\u00each\u00e9 pendant tr\u00e8s longtemps de comprendre pourquoi la POO est n\u00e9cessaire, pourquoi il est n\u00e9cessaire de l&#8217;utiliser si en fin de compte tout se r\u00e9sume au code machine.<\/p>\n<p>Cependant, apr\u00e8s avoir travaill\u00e9 dans le d\u00e9veloppement de produits, j&#8217;ai d\u00e9couvert les plaisirs de ce paradigme de programmation, principalement, bien s\u00fbr, la flexibilit\u00e9 du d\u00e9veloppement, les m\u00e9canismes de protection du code, avec la bonne approche, la r\u00e9duction de l&#8217;entropie, la simplification du travail d&#8217;\u00e9quipe. Tous les avantages ci-dessus d\u00e9coulent de trois piliers : polymorphisme, encapsulation, h\u00e9ritage.<\/p>\n<p>Il convient \u00e9galement de noter la simplification de la r\u00e9solution des probl\u00e8mes li\u00e9s \u00e0 l&#8217;architecture des applications, car 80 % des probl\u00e8mes architecturaux ont \u00e9t\u00e9 r\u00e9solus par des informaticiens au si\u00e8cle dernier et d\u00e9crits dans la litt\u00e9rature sur les mod\u00e8les de conception. Ensuite, je d\u00e9crirai les fa\u00e7ons d&#8217;ajouter une syntaxe de type POO au C.<\/p>\n<p>Il est plus pratique de prendre des structures C comme base pour stocker les donn\u00e9es d&#8217;une instance de classe. Bien s\u00fbr, vous pouvez utiliser un tampon d&#8217;octets, cr\u00e9er votre propre structure pour les classes, les m\u00e9thodes, mais pourquoi r\u00e9inventer la roue ? Apr\u00e8s tout, nous r\u00e9inventons d\u00e9j\u00e0 la syntaxe.<\/p>\n<h4>Donn\u00e9es de classe<\/h4>\n<p>Exemple de champs de donn\u00e9es \u00ab classe \u00bb GameObject\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>struct GameObjectStruct {\n    struct sp1_ss *gameObjectSprite;\n    unsigned char *sprite_col;\n    unsigned char x;\n    unsigned char y;\n    unsigned char referenceCount;\n    unsigned char beforeHideX;\n    unsigned char beforeHideY;\n};\ntypedef struct GameObjectStruct GameObject;\n<\/code><\/pre>\n<\/div>\n<p>Enregistrez notre classe sous \u00ab GameObject.h \u00bb, faites #include \u00ab GameObject.h \u00bb au bon endroit et utilisez-la.<\/p>\n<h4>M\u00e9thodes de classe<\/h4>\n<p>Compte tenu de l&#8217;exp\u00e9rience des d\u00e9veloppeurs du langage Objective-C, la signature d&#8217;une m\u00e9thode de classe sera constitu\u00e9e de fonctions dans une port\u00e9e globale, le premier argument sera toujours la structure des donn\u00e9es, suivi des arguments de la m\u00e9thode. Vous trouverez ci-dessous un exemple de \u00ab m\u00e9thode \u00bb de la \u00ab classe \u00bb GameObject\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>void GameObject_hide(GameObject *gameObject) {\n    gameObject->beforeHideX = gameObject->x;\n    gameObject->beforeHideY = gameObject->y;\n    gameObject->y = 200;\n}\n<\/code><\/pre>\n<\/div>\n<p>L&#8217;appel de m\u00e9thode ressemble \u00e0 ceci\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>GameObject_hide(gameObject);\n<\/code><\/pre>\n<\/div>\n<p>Les constructeurs et les destructeurs sont impl\u00e9ment\u00e9s de la m\u00eame mani\u00e8re. Il est possible d&#8217;impl\u00e9menter un constructeur en tant qu&#8217;allocateur et initialiseur de champ, mais je pr\u00e9f\u00e8re contr\u00f4ler l&#8217;allocation et l&#8217;initialisation des objets s\u00e9par\u00e9ment.<\/p>\n<h4>Travailler avec la m\u00e9moire<\/h4>\n<p>Gestion manuelle de la m\u00e9moire du formulaire \u00e0 l&#8217;aide de malloc et free envelopp\u00e9 dans des macros new et delete pour correspondre \u00e0 C++\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>#define new(X) (X*)malloc(sizeof(X))\n#define delete(X) free(X)\n<\/code><\/pre>\n<\/div>\n<p>Pour les objets utilis\u00e9s par plusieurs classes \u00e0 la fois, une gestion semi-manuelle de la m\u00e9moire est impl\u00e9ment\u00e9e sur la base d&#8217;un comptage de r\u00e9f\u00e9rences, \u00e0 l&#8217;image et \u00e0 la ressemblance de l&#8217;ancien m\u00e9canisme Objective-C Runtime ARC\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>void GameObject_retain(GameObject *gameObject) {\n    gameObject->referenceCount++;\n}\n\nvoid GameObject_release(GameObject *gameObject) {\n    gameObject->referenceCount--;\n\n    if (gameObject->referenceCount < 1) { sp1_MoveSprAbs(gameObject->gameObjectSprite, &Renderer_fullScreenRect, NULL, 0, 34, 0, 0);\n        sp1_DeleteSpr(gameObject->gameObjectSprite);\n        delete(gameObject);\n    }\n}\n<\/code><\/pre>\n<\/div>\n<p>Ainsi, chaque classe doit d\u00e9clarer l&#8217;utilisation d&#8217;un objet partag\u00e9 en utilisant retention, lib\u00e9rant ainsi la propri\u00e9t\u00e9 via release. La version moderne d&#8217;ARC utilise des appels automatiques de r\u00e9tention\/lib\u00e9ration.<\/p>\n<h3>Le son\u00a0!<\/h3>\n<p>Le Spectrum dispose d&#8217;un tweeter capable de reproduire de la musique 1 bit\u00a0; les compositeurs de l&#8217;\u00e9poque \u00e9taient capables de reproduire jusqu&#8217;\u00e0 4 canaux sonores simultan\u00e9ment.<\/p>\n<p>Le Spectrum 128k contient une puce sonore distincte AY-3-8910, qui peut lire de la musique de suivi.<\/p>\n<p>Une biblioth\u00e8que est propos\u00e9e pour utiliser le tweeter dans le z88dk<\/p>\n<h3>Ce qui reste \u00e0 apprendre<\/h3>\n<p>Je souhaitais me familiariser avec Spectrum, impl\u00e9menter le jeu \u00e0 l&#8217;aide du z88dk et apprendre beaucoup de choses int\u00e9ressantes. J&#8217;ai encore beaucoup \u00e0 apprendre, par exemple l&#8217;assembleur Z80, car il me permet d&#8217;utiliser toute la puissance du Spectrum, de travailler avec des banques de m\u00e9moire et de travailler avec la puce sonore AY-3-8910. J&#8217;esp\u00e8re participer au concours l&#8217;ann\u00e9e prochaine\u00a0!<\/p>\n<h3>Liens<\/h3>\n<p><a href=\"https:\/\/rgb.yandex\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/rgb.yandex<\/a><br \/><a href=\"https:\/\/vk.com\/sinc_lair\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/vk.com\/sinc_lair<\/a><br \/>\n<a href=\"https:\/\/www.z88dk.org\/forum\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.z88dk.org\/forum\/<\/a><\/p>\n<h3>Code source<\/h3>\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/zx-projects\/tree\/master\/interceptor2020\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/gitlab.com\/demensdeum\/ zx-projects\/tree\/master\/interceptor2020<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cet article absurde est d\u00e9di\u00e9 au d\u00e9veloppement d&#8217;un jeu pour l&#8217;ancien ordinateur ZX Spectrum en C. Jetons un coup d&#8217;\u0153il au beau mec\u00a0: Sa production a commenc\u00e9 en 1982 et a \u00e9t\u00e9 produite jusqu&#8217;en 1992. Caract\u00e9ristiques techniques de la machine\u00a0: processeur Z80 8 bits, 16-128 Ko de m\u00e9moire et autres extensions, comme la puce sonore<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/fr\/2019\/12\/14\/%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b0-%d0%b8%d0%b3%d1%80%d1%8b-%d0%b4%d0%bb%d1%8f-zx-spectrum-%d0%bd%d0%b0-c\/\">Continue reading <span class=\"screen-reader-text\">&#8220;D\u00e9veloppement de jeux pour ZX Spectrum en C&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[49,81,61],"tags":[134,133],"class_list":["post-2396","post","type-post","status-publish","format-standard","hentry","category-blog","category-demos","category-techie","tag-spectrum","tag-z88dk","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"fr","enabled_languages":["en","ru","zh","de","fr","ja","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/2396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/comments?post=2396"}],"version-history":[{"count":32,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/2396\/revisions"}],"predecessor-version":[{"id":3930,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/2396\/revisions\/3930"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/media?parent=2396"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/categories?post=2396"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/tags?post=2396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}