Sunday, March 26, 2023

3 rooms on 3DS

Novembre 2021, un rétro-fan nommé Fei m'invite à rejoindre un chat francophone qui accueille déjà un certain nombre de mes contacts twitter versés dans le rétro-coding. J'y ai fait quelques apparitions, mais je dois bien admettre que j'ai du mal avec la formule 'discord' qui a tendance à semer la confusion dans mon esprit.

Du coup, quand j'ai une nouvelle petite démo avec les 3-salles, bin je leur poste le lien, pour avoir un peu des retours. Sauf qu'à l'époque, la plupart des dev' qui ont un matériel compatible avec les homebrews NDS ont en réalité une DSi ou une 3DS... et là, bardaf: écran bleu.

J'en arrive assez rapidement à la conclusion que le fautif est le support des vieux linkers utilisant le port GBA (qui est absent des DSi et 3DS). Les tentatives de lectures sur la plage d'adresse prévue pour le "gba slot" provoquant des exceptions hardware. Mais même une fois ce code-là commenté, toujours pas moyen de faire tourner la démo. En fait, le code n'a pas trouvé les fichiers de données "intégrés" au .nds avec l'Embedded File System de Noda. Fei utilise le "Twilight Menu++" ... je creuse un peu mais fin de semaine, je n'ai toujours rien. Perso, ma 3DS n'a encore jamais vu de homebrew de sa vie (malgré l'acquisition d'un OOT3D) et j'ai oublié comment je faisais tourner des homebrews sur ma DSi avant que ses triggers ne me lachent. Le tourbillon du printemps 2022 va emporter tout ça au pays d'Oz dans l'oubli.

My bad. Really. It would not have taken me one whole year figuring out why my homebrew wasn't running on DSi and 3DS if I had not been messing with the ndstool settings in an attempt to avoid 'twl' headers. I started studying how any exploit on DSi seems to ultimately rely on something called 'generictwlpayload' to launch devkitpro/bootloader. But chances are that if it does not find some specific signature in the binary, it will fail to inject hooks to e.g. SD card reading.

Anyway, this is *so* satisfying to finally see someone else (Fei, this time) being able to run my demos again. I hope I will find a way to make it compatible with desmume as well and quickly manage to backport that 'fix' to some SchoolRush build... just in case.

Mais là, ce week-end, pour voir comment je peux m'y prendre pour faire des tapis roulants, je me rends compte que mon mercurial sur sourceforge n'est pas à jour. de plusieurs mois ^^". En regardant de plus près je retrouve une micro-branche qui reprend mes tentatives pour corriger le problème. La différence, c'est qu'entre temps, j'ai été démarché pour une version "cartouche" de SchoolRush. Et que j'ai commencé à essayer de comprendre comment faire tourner des homebrews DSi sans linker, encouragé par un post sur hackaday qui promet un mécanisme ne nécessitant ni jeu particulier ni modification permanente. Juste un p'tit serveur web et le navigateur intégré au firmware. (j'ai encore un peu de codestudy à faire dessus, mais on y reviendra).

Tout ça pour dire que j'avais une idée bien plus précise de "twl = indispensable pour démarrer quelque-chose sur DSi" qu'il y a 4 ans quand j'ai fait la mise à jour de mon devkit. A l'époque, j'avais d'abord remarqué un gonflement de tous mes programmes, puis une incompatibilité avec desmume. Le coeur du problème, c'était un changement de fonctionnement de l'outil ndstool mais en voulant "forcer" le support de desmume, j'avais aussi sabordé le support des consoles DSi et 3DS. Une petite marche arrière et Fei est maintenant en mesure de faire tourner la démo "three rooms" sur sa 3DS ^_^.

Voyons donc si je peux aider desmume à comprendre ces "nouveaux headers" si chers au TWLoader, sans lesquels il n'essaie même pas de faire le patch DLDI des softs qu'il charge... encore que ... en 2016, je pointais que desmume n'avait plus besoin de --gbaslot-rom pour faire tourner SchoolRush ... à creuser.


Monday, March 20, 2023

qmake (CMake and 'friends' pour une autre fois)

j'ai mis un tag 'tutoriel', mais considérez ceci comme juste un moyen pour moi de ne pas oublier les griffes que le chat m'a fait pendant que j'essayais d'apprendre à me servir d'un nouvel outil

Bon, des Makefiles, ça va faire plus de 20 ans que j'en mange. C'est plus ou moins la base des règles de compilation. Vous indiquez un nom de fichier à obtenir, puis les fichiers dont il dépend, puis les commandes à exécuter pour passer de l'un à l'autre.


Monfichier.o: Monfichier.c FichierImportant.h
	compiler Monfichier.c -o Monfichier.o
     
Et bien sûr, vous avez le droit de rendre ça plus générique:

%.o: %.c FichierImportant.h
	compiler $< -o $@

Bon, assez rapidement, ça devient plus complexe que ça, hein. Par exemple, il y a peu de chance que tout votre projet dépende de FichierImportant.h et seulement de ça. On risque plus d'avoir quelque-chose comme jeu.c qui dépend de jeu.h et sprite.h alors que sprite.c ne dépend que de sprite.h et menu.c dépend à la fois de menu.h sauvegardes.h et sprite.h, par exemple.

Si on a de la chance, le compilateur offre alors une option pour générer des fichiers de dépendances qui capturent ça (disons, jeu.dep, menu.dep et sprite.dep) et on s'en sort avec


%.o: %.c
	compiler $< -o $@ $(ET_GENERER_LES_DEPENDANCES)

-include *.dep

Mais restons-en là pour l'instant. Dès que le projet grossit, qu'il commence à dépendre de bibliothèque externes (pour les formats d'images, la gestion du son, etc.), et surtout, dès qu'on commence à vouloir le compiler pour plusieurs plate-formes différentes (linux et windows?), ça devient vite un beau gros sac de noeuds ... en particulier parce que si make est omniprésent dans le monde Linux, il est toujours boudé par Microsoft qui y va de son propre msbuild.exe qui manipule des fichiers XML déguisés en .vcxproj ... D'où l'intérêt de programmes qui vont générer des Makefiles à partir de descriptions plus haut-niveau du projet à compiler.

C'est le cas de qmake, notamment, qu'on va exécuter dans un répertoire vide en lui indiquant l'emplacement de nos sources et qui va créer un Makefile dédié à la compilation de nos sources dans ce répertoire-là en utilisant le fichier *.pro distribué avec les sources.


  mkdir build
  cd build
  qmake ../src
  
  • il y définit tous les programmes utilisés (compilateur, linkeur, etc.) dans des variables pour make;
  • il donne une règle indiquant quand re-générer le Makefile (est-ce que le fichier .pro a changé?) qui réappellera qmake;
  • il ajoute les règles pour préparer une distribution du programme, nettoyer les fichiers intermédiaires, etc.
  • et surtout, parce que qmake est lié au projet d'interface graphique Qt, il prend en charge tout ce qui concerne la génération de code pour l'interface graphique à l'aide de moc.

A travers son fichier .pro, qmake prend en charge le fait que les différents compilateurs ont des préférences différentes pour les macro-définitions (à ajouter dans DEFINES) ou les répertoires à explorer quand il tombe sur un #include (à ajouter dans INCLUDEPATH). Idem avec les bibliothèques à passer au linkeur. On trouve évidemment aussi SOURCES pour les fichiers à compiler et HEADERS pour les déclaration de classes contenant des annotations pour le système de signal/slot propre à Qt (qui en aura besoin pour générer du code et compléter les vtables).

Une autre grande différence entre make et qmake est que ce dernier se veut multi-plate-formes et indépendant du shell. ça se traduit notamment par une manière franchement confortable pour les éléments conditionnels, comme


linux {
    LIBS += pthread
    !isEmpty(ENABLE_GL) {
       SOURCES += backend/opengl.cpp
    }
}
windows {
    LIBS += direct3D
}

Et autres astuces du genre. Attention par contre: si il était possible de faire des Makefile qui incluent d'autre makefiles (notamment pour combiner les résultats de plusieurs répertoires), la chose qui s'en rapproche le plus avec qmake c'est le TEMPLATE = subdirs, mais qui à l'instar de makefiles récursifs, ne partage pas les variables d'un fichier .pro à l'autre. Oui, je sais, en lisant ça, ça semble évident, mais ça l'était nettement moins en écrivant le makefile. La solution, c'est de faire venir la variable de l'extérieur soit avec qmake ENABLE_GL=y sur la ligne de commande, soit avec Qt Creator


 Une approche pas toujours très confortable, cela dit, en particulier à cause d'une gestion des dépendances entre variables et fichiers .o pas toujours très claire ... je comprends pourquoi mes collègues lui ont préféré include (../projet.pri) dans les .pro-feuilles et qui contient les DEFINES += ENABLE_GL=yes et autre MODEL_EXPORTER_PATH=/usr/bin/export_to_gl

Friday, February 03, 2023

Souldiers Pyramid

Je l'ai découvert à travers une vidéo "Game of the Year", mais dans la catégorie "jeux les plus décevants". Pourtant, Souldiers est carrément superbe. Et principalement réalisé en pixel art. Et enfin, cerise sur le gateau, il propose généreusement une zone du sable avec une pyramide cachée dedans! L'idéal pour aller à la pêche au pixels, en somme, d'autant que même la perspective du jeu est compatible avec ce que je veux faire dans Bilou's Dreamland.

I happily clicked on a "game of the year" video without realising it was mentioning the "most disappointing GOTY". But given how gorgeous the visuals were, I've been shocked that this was actually referred to as disappointing. Souliders is a piece of magic when it comes to pixel art. Plus it has a desert and a pyramid level, so while people are debating about its difficulty, I'll just increase the zoom level and see what I can learn from it.

Bon, malheureusement, un jeu récent sorti sur une machine haute-résolution (il sort des images 1920x1080 où on distingue clairement des sprites et tiles prévus pour du 640xqqch), je n'ai pas beaucoup de screenshots "propres" à me mettre sous la dent. C'est surtout des vidéos youtube qui vont me servir de base.
Premier élément à réfléchir pour Bilou: des toutes grosses pierres comme décor de fond, ça marche finalement mieux que des briques à la MegaMan & Bass ...

It wasn't that easy as I'd have liked, though: the game is running scaled up to 1920x1080 with only some effects/rotations using the increased resolution while sprites and maps are at 640xSomething. Add some touch of JPEG encoding of people's snapshots and you end up with 9 candidate colors per pixel, and little chance to see the same RGB value twice. So my pixelstudy session will be less precise than some earlier pixelstudies ...

On a un élément 'pente ensablée', juste le look qu'il faut pour du sol qui pousse Bilou dans une direction ou l'autre (ce qui n'a pas l'air d'être le cas dans ce jeu-ci). J'aime bien les motif en croissant de lune qu'on retrouve un peu partout dans le sable, que ce soient les paliers dans la pente ou les dunes au sol (petites ou grandes), ça passe nettement mieux que tout ce que j'ai essayé de dessiner jusque là.

Among the interesting items, I note a sandy slope, just the kind I need to implement 'conveyer belts' in Bilou's own pyramid. Note the moon-crescents patterns in the sands. We have such shapes almost everywhere, in background dunes, on the foreground sands etc. but I especially like how they make 'steps' here.

Another item I'm interested in is the sands-within-pyramid. Souldiers features both patches of sands that do not fully cover the ground and 'pools' of sands. Note how they used layers of sands to suggest depth and end up with a solid color rather than texturing the 'side' view of the sands area.

Et on a des zones ensablées dans la pyramide. Et du sable qui traine au sol sans couvrir l'entièreté du sol. Notez au passage la manière dont ces développeurs-ci ont utilisé une teinte nettement plus sombre pour faire "le sable au sol à l'avant plan" qui sert aussi de 'fond de sable' pour l'intérieur de la pyramide.
Allons-y, donc. Un des éléments qui m'intéresse dans tout ça, c'est la taille choisie par l'artiste (un crayon dédicacé à celui qui me trouve son nom/instagram/twitterID) pour les 'vagues' de sable au sol, selon qu'elles sont à l'avant plan, à l'arrière plan ou sur la trajectoire prévue pour le joueur. Verdict: on est avec un modeste 8 pixels de haut que ce soit sur le chemin ou à l'arrière plan, et seuls les dunettes à l'avant plan vont pouvoir se permettre de monter à 12 ou 16 pixels de haut. Les plus hautes sont principalement devant des structures en rocher, d'ailleurs.
 
Chose remarquable, par contre, un "dune au sol" (ici le modèle 64x16 de l'image ci-dessous) n'utilise au final que 4 teintes en plus du ton de base "sable sombre" utilisé pour le remplissage quand des espaces sans détails. Les pentes avant et arrière de la mini-dune sont linéaires (sauf au sommet) et utilisent le même angle par rapport à l'horizontale (contrairement à ce que mon croquis suggère ^^")

It took me some time before I could actually start and study those sand grounds, but a first item I could directly check on the raw picture: what sizes the artist has picked for those waves. I have noted that Souldier's main character is about 40-48 pixels high (roughly the size of pendats). The biggest dunes are 64x16, but that's only seen out of the character's path, as foreground element, but always put under the ground line so that it doesn't obscure the view. On the ground line, we only see 8-pixel high dunes.

I spot only 4 colours per dune, plus one extra 'darkest' tone that is also used as a filler. Of course dunes on another layer will use a lighter set of 4 colours. Another unexpected thing is that the slopes on each side of the wave is are almost linear (except at the top) and fairly symmetric (unlike what I drawn ^^").

There's so much more I could talk about. Those rock strucures, the bigger dunes in the background, the fallen statues... But there's not a chance I could use so much things in "Bilou's Dreamland" project ... so that will be for much, much later ;-)

Il y aurait largement de quoi étudier ces structures rocheuses, les dunes à l'arrière plan et les monstres, mais bon ... je n'aurai pas le luxe de tenter tout ça pour le jeu en cours: juste l'intérieur de la pyramide, ce sera déjà un bon début. Gardons donc ça sous le coude pour un prochain jeu ?

Niveau couleurs, j'ai fait quelques petits essais de superposition des morceaux de sable de souldiers dans la pyramide de Bilou ... c'est pas la grande joie. Les couleurs de prowler passeront probablement mieux. à vérifier.

Saturday, January 28, 2023

How it is bashing

Mon agenda étant en vadrouille le week-end dernier, je suis retombé sur mon cahier bleu, celui qui se concentre sur le game design de Bilou's Dreamland. De page en page, je reviens en arrière dans le temps ... je fais une pause sur la révision du niveau de Rémi, toujours en attente avec ses nombreux bangbash, puis tout naturellement, je tombe sur la page dédiée à Bangbash

Et il se trouve que quelque jours plus tard, ma fée m'a retrouvé du temps, alors j'ai attrapé ma DS et j'ai essayé de reproduire sur une grille de 32x32 les mouvements que j'avais capturé sur mon calepin.

I couldn't find my agenda, last week-end, but I did flip the pages of my blue design notebook ... I stopped on Remi's level thoughts and from there, to that page where I wrote down decisions about how to make BangBash come back. The next day, my fairy gave me some time and my Lime DS was sitting near, with a battery ready. So I opened the school zone file and tried to sketch some of the BangBash poses I had drawn in the notebook.

So here's what I've got so far. one idle animation, one jump split into prime/apex/landing sub-animations and one front smash that is Bangbash's signature move. That one could use one or two extra frames, and I'll have to draw the eyeslids directly over some of the frames to better slant with the move (and have one sprite free for the mouth ?), but I'm pretty satisfied of how it came so far.

Voilà ce que ça donne après le montage de quelques animations dans AnimEDS. Il y a encore un peu de détails à peaufiner, mais je crois qu'on peut dire que l'un dans l'autre, les animations marchent plutôt bien et qu'on peut effectivement s'en tirer sans avoir besoin de 3D. Peut-être même sans rotations. (bon, entre-autres parce que je laisse tomber l'attaque tournoyante du design originel)

Friday, January 20, 2023

jewel colors by Prowler

 Comme souvent, ces temps-ci, c'est par un tweet que tout a commencé: une image de l'artiste Prowler (croisé sur Nectarine et un peu sur pixelation pendant l'ère des forums) prévue pour un music disk sorti de Nectarine il y a 2 ans (pour amiga. Eh oui) dont les couleurs m'ont tapé dans l'oeil.

I 'know' Prowler for some time, now, since he was one of the most welcoming dude on Nectarine, but little did I know that he had drawn the cover of some 21th Century Music Disk for the commodore Amiga... Hopefully, Prowler was on twitter too, and he eventually posted the rework of his 'skylab', and the colors he used immediately struck me. Especially the greens.

Une palette désertique digne du Dune de Cryo avec une teinte secondaire en vert particulièrement attrayante ... alors que je ne suis toujours pas satisfait par les tons verts utilisés pour les trucs spéciaux de ma pyramide.

#77ff99 - #44bb77 - (#389e72?) - #229955 - #007744 - #006633 - #004422 ... 

Puis je me suis amusé du fait que certaines briques s'agençaient presqu'en bloc de tetris sur mon mockup. Comme je suis dans la semaine des plate-formes-sur-rail en forme de Snake et du boss Araknoïd, je me dis qu'on mettrait bien franchement des tetrominos en guise de blocs dans cette pyramide qui n'en est pas une... ça a l'air de plaire. On verra bien si on en met uniquement dans les zones secrètes, ou un peu partout.

You see, I'm not that satisfied with the colors I've been using so far for the green, interactive things in my "pyramid-that-is-a-computer" tileset. 

(je serais curieux de les comparer avec les couleurs des émeraudes d'Aladdin sur SNES, tiens)

You'll note on the new mock-up that some of the rectangular bricks have been merged together to make tetrominoes ... This was the week where I realised that platforms-on-rail in my pyramid could easily mimmic the good-ole-game 'nibbles' (snake) and that I could name the scorpio-boss 'Araknoïd' and design the arena such that Bilou has to break bricks/pots to hit the boss, tetris-shaped walls would definitely be fitting. Good news is that most of poll respondents did agree (sorry for the few RSS readers around here: blogger has long dismissed the poll widget. Feel free to make your voice heard in the comments)

edit: bon, les diamants d'Aladdin (SNES) n'ont pas vraiment le niveau en comparaison. Je serais presque tenté de dire que ceux de Commander Keen 4/5 étaient plus intéressants. La palette de couleur n'est pas particulièrement inspirée, sauf peut-être la teinte la plus sombre, le 003828. Le reste fait presqu'EGA non assumé.

Friday, January 13, 2023

Megaman & Bass, ground man : pixel art and perspective.

I had some "megaman animation" video in my watch list and it appeared to have a sands-and-ruins themed level. So I should have been googling for Megaman 8 Swordman on PSX, but for some reason, I ended up googling for Megaman & Bass (ground man) on SNES instead.

Note how both have visible ground (as opposed to the plain-flat-side view of most megaman games), too. So that will make another reference for perspective study, too.

I'll mostly focus the perspective part on the SNES game, where it is closer to the one I want, with 8 pixels of ground for 16 pixels-high blocks. Note how they introduced two 'slanted edge' for the ground, providing a depth effect (and visual hint for platform edge) that pleases the eye.

They have sandfalls too, which I still have to draw, but they mostly went for noise with cycling palette and dither pattern to fake translucency. That may have worked on good old CRTs, but there's nothing to study here, after all.

Les megaman sur Super NES ont des graphismes plutôt sympa, et je suis toujours à la recherche de pixelart de référence pour le sable de ma propre pyramide, donc creusons. D'autant que ce 'Megaman & Bass' sorti en fin de vie de la console a tous les éléments qui m'intéressent: chute de sable, sable au sol, un peu ou beaucoup, avec une perspective compatible avec ce que j'ai en tête ...

They do have sands-on-the-ground too, another element for which I need pixel references, and some more sands-pit-in-depth-of-the-ruins, as well.

The snake-dragon depicted on the walls and the geometrical patterns do not feel Egyptian at all, but there's nothing forcing those ruins to be Egyptian, after all. In the case of Megaman 8, they were even quite obviously South-American rather than North-African.

On est plus ou moins forcé d'essayer de faire un parallèle entre le stage de Ground Man dans MM&B et celui de Sword Man dans MM8 sur PSX. MM8 avait clairement joué la carte du temple Maya, MM&B est un peu plus pyramidesque, mais il reste quelques détails qui nous rappellent sa filliation. Comme ces espèces de dragons. (qui ornent la salle remplie de sable ;)

Bon, malheureusement, les chutes de sables sont surtout un pattern "bruité" animé par rotation de palette qui joue sur le flou-crt pour adoucir les angles... pas grand-chose à étudier pour Bilou de ce côté là, à part les pixels qui se rajoutent près de la tête de Megaman quand il est dans le sable.

Oh, and they have a nice 'particles shower' effect when character stands in a sands fall (likely they'd have something similar for waterfall). I remember I have commented on some cosmic boll video where such shower particles is a hint that you're experiencing some sort of "extra gravity" for being pushed by the falling fluids that I might want some similar mechanics in Bilou.

Tout comme la perspective a rajouté 1 tile de sol par-derrière la position de MegaMan (semi-transparent sur les bords de certaines plateformes), on a droit à un tile de sommet-de-sable par-dessus le "bloc-sol" sable ... derrière lequel Megaman s'enfonce avec un peu de glitches sur les bords... Dommage pour l'alignement des 'dunes' et leur aspect exclusivement triangulaire dans le "bloc-sable"

the ground-sand has some unexpected look, especially in the way further piles of sands stand out more than closer one. They are given one tile of part-translucent / background over the walked-on pattern.

They tried to make it behave as a sort of quick-sands by letting the character slowly dip into the sands, but the effect comes short as soon as you approach a wall, imho.


And I finally found some of those iconic carved blocks in Megaman & Bass, although they appear to be only around the level's Master Robot room ...

Bon, idéalement, j'aurais dû vous sortir les code couleurs utilisés, analyser les hauteurs de pixels et compagnie... mais au final, je ne suis pas fan de ce look, que je trouve un peu pâlichons et pas toujours convaincant. Comme en plus trouver des images propres avec les vraies couleurs et la vraie taille s'avère pénible pour ce niveau particulier et que j'ai trouvé bien mieux à analyser entre-temps ... on va en rester là ;-)

Wednesday, January 11, 2023

2023 - 1993 = 30

ça vient juste de me frapper ce matin en réunion. Cette année-ci, Bilou aura 30 ans en septembre! J'avais fait un homebrew-d'anniversaire pour ses 20 ans, avec juste un niveau. J'aurais aimé avoir un Dreamland au moins en pré-alpha quand j'ai envisagé de commencer à travailler sur Dreamland, mais c'était compté sans les ralentissements et distractions de ces dernières années.

Alors, bon, avant de vous sortir une jolie carte postale, je vais peut-être déjà me pousser un peu à implementer la solution crasse-mais-simple pour corriger cette plate-forme reclapante, non ?

Guess which blue ball turns 30 this year ! Hmm ? Hmm ? Yes. That one. I don't know whether I can still something like 'Dreamland' by the end of 2023, but I can surely try and find some more hobby time for it, right ?