Monday, September 21, 2020

Ori et le Lien d'âme

 J'avais du mal à y croire, mais si: Ori 2 est bel et bien sorti sur Switch, et ça à peine 6 mois après sa sortie officielle sur XBox (contre 2 ans pour l'épisode "blind forest"). Chose assez peu courante, j'ai bondi dessus dès qu'il a été disponible. Il est superbe, il est prenant, mais il y a aussi des différences assez profondes et parmi elles, la gestion des échecs du joueur.

Il faut dire que le premier opus avait opté pour une approche assez innovante. Pas de points de sauvegarde imposés: c'est au joueur de créer à certains endroits des "liens d'âme" d'où il pourra réapparaître en cas d'échec. Tous les objets récupérés, toutes les portes déverrouillées seront perdues en cas d'échec.

Sauver quand on veut, ça me rappelle ma manière de jouer à Commander Keen dans les années '90 (et sur émulateur, en fait ^^"). Mais ici, il y a une subtilité: pour pouvoir créer un point de sauvegarde, il faut dépenser un point de mana. Et pour retrouver du mana, il faut généralement briser des cristaux pas si fréquents que ça. D'une certaine manière, les cristaux faisaient office de point de sauvegarde... mais d'une certaine manière seulement.

Parmi les 'compétences' que l'on peut débloquer à l'aide de points d'expérience, on trouvera par exemple la possibilité de réutiliser à volonté un point de sauvegarde déjà créé. On peut ainsi faire une sauvegarde, aller éliminer un monstre, retourner sauvegarder, éliminer le monstre suivant, etc. (ou pareil avec des clés à récupérer). On pourra aussi débloquer la possibilité de reprendre de la vie au moment où on crèe un nouveau point de sauvegarde (mais là, il va falloir commencer à dégotter un fameux nombre de points d'expérience, hein).

Bref, tout ça était frais, unique, assez bien en phase avec le concept de 'je suis un esprit de la nature brille et qui saute dans tous les sens'. Eh bien c'est fini. Ori and the Will of the Wisps, avec son côté 'ninja-vania' sauvegarde automatiquement quand on franchit certaines 'portes' (invisibles). On ne risque plus de perdre tout d'un coup 15 minutes de progression juste parce qu'on hésitait à dépenser un des précieux points de mana (3 au départ). Par contre, on a plus non plus ce côté 'stratégique' consistant à choisir où faire ses sauvegardes.

Il reste cependant un lien entre mana et santé par le biais d'une sorte de 'sort de soin', plus convenu, mais aussi bienvenu dans les combats contre les boss qui ont l'air plus développés que dans le premier opus.

En fait, c'est tout le gameplay des combats qui a été renforcé, avec une palette de mouvements d'attaque dignes de Kirby en mode 'épéiste' et un arsenal d'armes secondaires qui n'ont pas à rougir de Link between Worlds.


Tuesday, September 15, 2020

makechar(BG_GFX, digit[i])

Bon, j'avais des affichages curieux dans LEDS. "où sont passé les pentes et les blocs jump-through" disait mon calepin. Eh bien ils étaient toujours bien là. Simplement pour les voir, il faut qu'il y ait quelque-chose au bon endroit dans la mémoire vidéo de la DS. Et jusque là, le code d'initialisation n'avait pas suivi l'évolution de la branche "newmap". Le niveau était donc bien converti mais les codes 0x81 pour "est une pente, type 1" n'avaient droit à aucun dessin.

Mais je n'ai pas sucé ça de mon pouce. Pour y voir clair, j'ai bricolé une p'tite table de caractères hexa en 3x7 pixels qui sont ensuite combinés pour faire 256 tiles dont le dessin indique le numéro.

I started getting weird effects in LEDS on the 'newmap/newmeta' branch. Special blocks and plain blocks seemed to work fine, but everything in-between (shadows, slopes, jump-through) was missing. Or so it seemed. They were actually still present, but invisible because the pixels to render them was still on the 'old codes' rather than on the new ones. I got it confirmed once I introduced a small loop that primes all the tiles used by the meta-layer with two-digit hex codes stating explicitly who's who.
 Unlike the legacy 0-3 codes, these are not meant to be shown to the level designer. As soon as we load the level, effective tiles will be filled, for instance using the 'symbol' statements.

Contrairement aux anciens codes, il n'est pas prévu ici de les conserver à l'écran: pendant le chargement du niveau, tous les codes utilisés seront remplacés par les symboles définis dans "rules.gam". Seuls restent affichés à coup de codes hexa les types de tiles "inconnus" -- ici les 00 qui servaient à "pousser" les personnages par-devant tous les plans de tiles et la pointe de crayon inversée.

Par contre, du coup, les "méta-boutons" deviennent beaucoup plus vides ^^"

Et comme maintenant je suis en mode multi-palettes pour tous les rendus de graphisme du jeu dans l'éditeur de niveau, j'ai les coudées franches pour redéfinir la palette principale, toujours utilisée par les plans "16x15 couleurs". C'est fondamental vu l'affichage du meta-layer en alpha-blending: utilisez une couleur non-définie (donc noire) et le truc est invisible. Prenez du blanc, et l'alpha blending sature.

Ok, c'est à peu près aussi passionnant que l'avancée des négotiations fédérales belges. Mais si je ne me remets pas ce genre de chose au frais en tête, je n'ai aucune chance d'avancer sur du homebrew. Et si je le fais, il est 23:37 quand j'ai fini ^^". 

C'est pas terrible pour la lisibilité des méta-boutons, par contre. Je vais leur donner une palette rien qu'à eux avec des couleurs bien EGA pour qu'on ne les loupe pas, du coup.  Puis j'irai jeter un oeil à la page du projet "Méta-Boutons" aussi, pour voir ce que j'avais envisagé pour passer les valeurs "inutilisées", parce que là, ça serait assez désagréable à utiliser (1 à 2 tiles utiles par "page" de boutons ... bof)

Friday, September 04, 2020

Les alliés des étoiles

J'avoue qu'on a pas tenté les vacances en mode corona. Par contre, j'aurai passé pas mal de temps cet été sur Kirby Star Allies dont la démo avait déjà bien accroché les enfants, et qui s'en sont donnés à coeur joie une fois la saison des camps & stages passée. (un peu trop, peut-être : J.L.N semblait

incapable de nous parler d'autre chose que des techniques de meta-knight avec l'épée des vents)

Bref, sans parvenir  aller détrôner le légendaire Labyrinthe des miroirs, cet opus est tout de même une belle réussite. Bon, ne cherchez pas du challenge pour les oldschool gamers, hein: pour ça, on s'orientera vers une autre boule rose plus indépendante: Whipseey (dont il faudra que je vous reparle vu que j'ai aussi acheté le jeu). Sous le couvert de "magie de l'amitié", le principe de base de ce Kirby est de pouvoir se constituer une équipe de quatre personnages pour traverser les niveaux, les joueurs humains pouvant "recruter" n'importe quel adversaire qui possède un pouvoir.

Les laboratoires HAL n'en sont pas à leur coup d'essai là-dessus: Kirby Amazing Mirror permettait déjà de faire intervenir 4 protagonistes sur un seul écran (utile surtout pendant les boss) et Kirby Squeak Squads -- une fois le mode fantôme débloqué -- permettait de son côté de prendre le contrôle de n'importe quel personnage du jeu. Oui, vraiment en prendre le contrôle, pas juste lui voler son pouvoir façon mégaman. Je dois bien reconnaître que depuis que mon frère m'avais parlé du mode "debug" de Sonic, j'avais rêvé de pouvoir faire ce genre de chose (allez, Jill of the Jungle nous en avait donné un avant-goût). Là, c'est chose faite.

On remarque au passage que pas mal de pouvoirs "classiques" des Kirbys précédents sont passés à la trappe -- notamment Kirby-roue, presqu'un incontournable depuis le premier épisode sur NES -- et je soupçonne fort que ce soit lié au besoin de garder les 4 joueurs à l'écran. Du coup, tout ce qui va trop vite reste au placard.

Il y aurait pas mal à redire par contre sur la lisibilité de l'action. Quatre personnages qui font la baston sur le grand écran contre un boss commun, on finit par ne plus retrouver le sien que grâce au petit "J1" qui pointe dessus. HAL a eu le bon goût de donner une couleur unique aux personnages secondaires (oui, je peine à dire 'les amis') et c'est très bien la plupart du temps, mais dans le feu de l'action, c'est insuffisant. Et les combinaisons du genre "épée de feu, lasso de glace, lance électrique", etc. rajoutent une couche qui n'aide pas. Ajoutez à tout ça un ou deux personnages légendaires (comprenez, un boss d'un jeu précédent aux attaques surpuissantes et tape-à-l'oeil), et vous comprendrez que le combat contre un boss dans ce jeu n'a plus grand chose de tactique: c'est surtout une sorte de gros défouloir familial.

Saturday, August 29, 2020

Reality check

 J'ai atteint un stade dans le développement de mon nouveau LEDS ou je peux envisager de faire un essai sur du vrai hardware. (En fait, il y a plusieurs choses que j'aurais dû essayer depuis longtemps, mais il semble y avoir une sorte de flemme à ressortir la DS et démarrer server.pl, ces derniers temps). ça fait une jolie photo, mais j'ai facilement passé la soirée à faire l'inventaire des choses qui ne vont pas :P

One bit at a time, a new build of LEDS has appeared, that combine enough patches from the 'newmap' branch so that I can consider giving it a spin on real hardware. Well, or so will I pretend. The crude reality is that the "Check List for RealThing" is only a few page past "April 2020" in my notebook.

I got no significant crash, but many of the features are incomplete. The evening was gone when I finally had the list compiled. Next evening, I'll update the e-book doxy-code and will start investigating why I have "bugWindow" inserted between MapeditWindow and MonsterWindow ...

La conversion des niveaux, par exemple, est incomplète. Ni les tiles "jump-through" ni les pentes n'ont été récupérées. Sur un vieux niveau où il n'y a pas de déclaration des blocs spéciaux, ils sont tout simplement invisibles (voire peut-être ignorés).

Les copier/collers de blocs spéciaux sont un peu bizarres aussi, en particulier pour les tiles "voir ci-contre". Je sais pourtant en créer de nouveaux en utilisant directement les Meta-Boutons.

Enfin, il se passe quelque-chose d'étrange avec la gestion des "fenêtres", comme si il y avait un mode "buggué" entre le mode "dessin" et le mode "édition de monstres".

Je sens qu'il va y avoir un nouveau .epub avec le code le plus récent à télécharger sur boox ...

Monday, August 17, 2020

En couleurs

 Un dernier p'tit bout d'code pour finir les vacances ... J'ajoute à LEDS la possibilité de peindre aussi bien le décor d'avant plan que le décor d'arrière plan.

En dehors des détails d'organisation (on passe tout par le "Meta Tile" qui indique les informations à remplir quand on touche le niveau quelque-part), je me suis retrouvé à plusieurs reprise "coincé" de par le fait que seul un plan de tiles était prévu pour fonctionner en mode 16 palettes jusqu'ici.

There has been more wall-painting than tile-painting these holidays, but walls are now white enough and I can pick up my notebook and start applying those changes.

On a 'software architecture' point of view, selecting the colors will be the responsibility of upper-screen's "TilesetWindow" (that's where I have room for it). Which color is selected isn't explicitly delivered to MapWidget (that paints tiles on the bottom screen). Instead, it is directly encoded into the palette bits of the recently refactored MetaTile structure that captures what blocks we want to write while drawing.

Then I realised how much the code base was unprepared for my plan. Only one layer on the bottom screen effectively had 16 palettes to use: the 'front' layer of tiles replicated the palette #0 on all slots (so that it could pretend to ignore physics info in palette bits). Things were hardly better on the upper screen, where the GUI engine itself had no idea of how to enable multi-palettes.

Il aura fallu faire sauter certaines limites (style une copie de 16 fois la première palette dans la mémoire de l'avant-plan) et ajouter le support multi-palettes sur l'écran secondaire, chose que GuiEngine ne supportait pas encore jusqu'ici. Et comme vous pouvez voir, j'ai du chipoter pour ne pas perdre le "fond à carreaux" qui permet de savoir dans quel mode d'édition (dessin, copie ou recolorisation) on se trouve.

Il y aura aussi un peu de refactoring à faire du côté du widget "cursor": je ne suis pas convaincu par la manière dont on doit re-manipuler ses coordonnées et forcer des setxy() pour implémenter des actions spéciales en cas de débordement d'une zone donnée. 

 Y'a des trucs pas encore très nets avec le mode "édition de monstres", par contre...

Well, there we are now. I still have to give it a spin on real hardware, and fix the switch to grey checker when editing monsters, (done) but we should be close to a usable editor for the newmap branch.

Look at them colored replicas of the selected tile, on the right of your tileset. Ain't them sweet ?

Tuesday, August 11, 2020

AnimEDS, cru 2020

Okay, these will be the first tools release with my new devkit setup. They seem to work fine on my iPlayer + lime DS setup.

I won't try to go with a 'how to use XXX' here, as this will be the mission of the AnimEDS manual page I'm editing this week. but you may want to know what to do after you

Download AnimEDS-2020.zip

right ? 

I want to use them on my NDS

Fine. Look at all the files in the archive, find back your micro-SD adapter and copy the files at the root of your SD card. The files themselves need to go there, not the AnimEDS-2020 folder. Don't change any file name.

Then put back everything in place, ensure your DS linker supports DLDI and launch medsdlta.nds. You can load the demo spritesheet by pressing START then L then A.

I want to use them in an emulator

Fine as well. I suggest you download the latest desmume (or at least 0.9.11). 

  • In the Config menu, check "ROM Loading > Load entirely to RAM"
  • In the Config menu, click "SLOT 1" to make the dialog box appear
  • opt for R4 as the type of device
  • point the 'director' to the location where you unpacked all the files. spriteA.spr should be in that directory.
  • launch medsdlta.nds 

Then, again, press START, then L then A to get the santa-demo file loaded.

Why should spriteA.spr be at the root of my SD card ?

This is where the Sprite Editor and the Animation Editor will look for your projects. That allows reliable load/save commands even when you're commuting, rather than having to cross finger while you tap the screen with the stylus.

Why shouldn't I change the names of the .nds files ?

They have path to each other hard-coded, so that you can switch from one to another easily (real hardware only, so far). This is also why you should drop them at the root of your media card.

Hope that will help ManafilledMangoes try out the soft.

Thursday, August 06, 2020

Petits essais desmume

J'ai pris conscience il y a quelques jours que je n'avais toujours pas écrit de document présentant le fonctionnement de AnimEDS, pourtant lauréat du concours NeoFlash.

Du coup, comme j'ai un PC windows qui traine à la maison en ces temps confinés, j'ai
- re-téléchargé un desmume-0.9.11
- configuré le chargement des ROM en mode "load into RAM" (pour la compatibilité DLDI)
- ajusté le SLOT 1 pour émuler une R4 vers le répertoire "efsroot" de mon dernier tuto en date (auquel j'ai quand-même rajouté un sous-répertoire "moving", pour la forme).

ça suffit pour LEDS. Maintenant, voyons AnimEDS ...
 
Some days ago, I realised I still had no document describing how one would use my Animation Editor for Nintendo DS: AnimEDS, despite it is the only homebrew I had ever submitted to a coding compo. 
Since I have a windows PC at home during "lock down", I re-downloaded desmume-0.9.11 and went through the required "load into RAM" and setup SLOT 1 folder through the 'Config' menu . (yep, I'll be emulating an R4 on slot 1, this time). Contents of the folder will be that latest tutorial I uploaded on gbatemp. That worked for LEDS (packed with the tutorial), but not with AnimEDS.
 
PS: oui, j'ai bien lu: les gens derrière le projet Desmume recommandent plutôt de prendre un "nightly build" plutôt que les "stable build", mais ces derniers sont les seuls à ne pas faire grincer les dents de Winwin avec un auteur du logiciel non défini. On ne va pas tenter le diable, non plus.

Par contre, le dernier build que j'ai d'AnimEDS ne parvient pas à charger les fichiers .spr de la même manière. J'aurais dû m'en douter >_<.

Puis les vacances sont arrivées. J'ai pris un moment pour comprendre ce qui se passait, et pourquoi il fallait une combinaison "desmume/devkit" pour que ça coince. 
 
I should have guessed. I knew there's a compatibility issue between desmume 0.9+ and devkitpro's resources since I downloaded them back in 2018. So far, I just rebuilt stuff with my 'older' devkit (still running GCC 4.x >_<), but the laptop where I did that seems to be definitely damaged. Well. It's locked-down holiday time and the painting is drying on the walls, so I kicked up my debugger and started investigating what happened.
  • things work fine on a real Nintendo DS
  • things work fine with an old emulator
  • things work fine with an old devkit compiling nearly the same sources.
  • when things go wrong, we see that fatInitDefault fails. Yet it found the 'fat' device but it cannot mount it.
Et j'ai fini par me rendre compte que toutes les fonctions liées au DLDI pointaient vers la même fonction qui return false.

Je creuse encore et je me rends compte que les fichiers .nds qui marchent sont renseigné comme ayant un autre type de header que les .nds qui échouent. Et que le code de desmume a un test du type "taille du header < 16K" pour décider si il a affaire ou non à un homebrew.

When I realised that all the IO functions in the DLDI interface were pointing to the same code (actually just returning false), I started to be very suspicious about desmume's DLDI patching feature, and I re-downloaded its sources. While it was building, I noticed that the old-built-working .NDS and the new-built-failing .NDS were not reported similarly by the 'file' linux tool. And here's the catch:
  • desmume has some code checking whether it is running a homebrew before patching DLDI
  • that code only work for so-called 'old' (512-bytes) headers.
  • 'new' devkitpro tools use 'new' (16K) headers by default.
Visiblement, les "nouveaux" homebrews ne sont plus reconnus comme tels, et donc même plus candidats au patch DLDI. Heureusement, l'outil ndstool est toujours capable de faire des "vieux headers" (-h 0x200) en plus des "nouveaux headers" (par défaut, -h 0x4000).

Il faudra que je vérifie que ça marche aussi avec l'émulateur "tout frais" sous Windows, bien sûr, et que je me souvienne que je suis aller bricoler dans /opt/devkitpro/devkitARM/ds_rules ... un patch qui n'était pas indispensable puisque j'ai repris une règle équivalente dans mon common.mk.
Enfin, avec un peu de chance, je pourrai enfin faire mon tuto "comment utiliser AnimEDS" ;)

In devkitpro packages, there is a tool that convert .elf compiled files and into a single .nds ROM image: ndstool. Hopefully, it is still able to produce both types of headers, you just have to request it with -h argument. And luckily, I already had replaced the default makefile rule that uses ndstool in my own common.mk helper, so I don't need to mess with the contents of /opt/devkitpro to get working NDS files again... and be able to load contents in AnimEDS. Tuto-writing can at lasts start (as soon as the temperature drops under 30°C, that is)
 
Sounds like it was all over ? Well, there's a bit more of it. While I was debugging desmume, I trigger another issue that makes desmume-0.9.11 crash on my Ubuntu laptop when it encounter a symbolic link. A bit of bug hunt located a pretty trivial error in vfat.cpp. I'm proud to say that this is my first accepted pull request on a homebrew-related project ^_^ 
 
So
  • I need to use the desmume-cli version I recompiled (0.9.12)
  • desmume-cli --slot1 R4 --preload-rom --slot1-fat-dir FAKEROOT_DIR TOOL.NDS
  • with 0.9.11 (still what's shipped on Ubuntu 22.04 :P) I frequently use desmume-cli --load-type=1 --gbaslot-rom=DS/Dreams/Dreams.nds DS/Dreams/Dreams.nds --nojoy=1 to run standalone games.