Thursday, December 31, 2020

Early DS homebrew moments.

When I started considering doing homebrew on the Nintendo DS, the hardware used by hackers was pretty unconvenient to bring in a sofa. For years, I've kept those pictures around found on website such as http://natrium42.xyz/ or https://www.darkfader.net/ds/, two websites where people pushing the limits of homebrewing were exchanging information and achievements.

But I must admit, I was merely considering doing GBA homebrew on NDS, by then. I wanted to keep things simple. And to some extent, I still want, which is one of the reason why, in 2020, I still haven't started doing homebrew on any other system, unlike most former NDS homebrewers.

There's a much better coverage of the era in Modern Vintage Gamer's video (2019) (reached from Retro Reversing)

The hack on the first picture shows how to extend GBA device with mass storage through a IDE cable and a (portable, enclosed) hard disk. The first devices allowing to run DS homebrew software (not only GBA homebrew) was only half less chunky. To be able to do so, the PassMe device had to relay requests for signed headers to a genuine NDS cart plugged at the rear of the console while it was itself inserted in the slot 1 of the console. That sort of thing works fine on a 16-bit home console, like a game genie / Sonick & Knuckles like monster, but for a handheld, I'd have been constantly fearing to lose a part or break it.

The remaining alternative wasn't very appealing either, as it required you to flash the firmware of the console with one that would have a menu for browsing homebrews on GBA flash cart (iirc) and bypass copyprotection checks.

That involved bridging two testpoints (solder pads) together with a metallic device and keeping them in contact while you're flashing the ROM with new contents (don't remember how). Would you slip during the process, and you might end up with a bricked device that has incomplete firmware. 

Well, it turned out that I eventually started doing NDS homebrews running in emulators before I started doing GBA homebrews and that by the time I decided to purchase something doing GBA homebrew, 'passcard' were small enough to fit a slot 1.

Oh, and by the way, I just discovered someone made a top 5 best homebrew apps last month. When you see that they are youtube 4 DS, Yahoo messenger for DS, an MP3 player and a text editor disguised as WintenDoS, it shouldn't be a surprise why homebrew consumers turned to smartphones as soon as smartphones became cheap enough.

Happy new year, too.



Thursday, December 24, 2020

Sonic Mania

Il faut le reconnaître: Sonic Mania est une réussite. Ces nouvelles couleurs sont tout simplement fantastiques. Le mélange entre ancien et nouveau est particulièrement réussi. Je trouve le design franchement bien pensé, avec un premier niveau par zone qui est un hommage au niveaux originaux alors que la 2eme zone se lache pour étendre la formule. On retrouve ainsi un lac souterrain et des totems géants en deuxième volet de la "Green Hill Zone" (et si je ne me trompe pas, on peut déjà en avoir un aperçu dans certains itinéraires de la première zone).

Le changement est encore plus marquant dans la Chemical Zone, qui offre un revisitage de mécanique de jeu qui n'est pas sans rappeler la main-du-maître revisitée dans Link Between Worlds.Je m'explique.

La Chemical Zone de Sonic 2 est remplie d'un liquide chimique pénible, avec en plus des gouttes d'un autre liquide chimique. L'un tue rapidement, l'autre lentement (enfin, l'inverse). C'est probablement le premier véritable obstacle du jeu, et on a beau faire, contrairement à de la lave qui nous blesse mais sur laquelle on peut courir pendant nos phases d'invincibilité, dans un produit chimique, Sonic coule.

Mais dans le 2eme niveau de Sonic Mania, on fait apparaître des switches qui permettent de faire réagir ces liquides chimiques pour produire une sorte de slime ultra-élastique et obtenir un trampoline géant. La difficulté transformée en fun par l'intermédiaire des actions du joueur, c'est déjà bien chouette. Quand en plus ça se traduit en trampoline (sans pics par-dessus) dans un jeu de plate-forme, c'est fun-compte-double.

Bien sûr, on saute dans un jeu de plate-forme. Mais régulièrement, on ne saute pas assez haut. Parfois il y a un bumper pour nous propulser plus haut, mais il y a alors le risque de mal retomber, ou de rater sa cible. Une salle-trampoline, c'est de la pure gourmandise: saut jusque tout en haut, on peut tout attraper, on ne prend aucun risque. 

(Bon, ça fait un moment que Sonic Mania est sur ma switch, bien sûr. Les notes qui disent "J.L.N a encore les réflexes un peu lent pour éviter les crabes qui lancent des boules en ouvrant les pinces" doivent dater du mois d'Avril).

Pour l'instant je cale sur le boss de la Flying Battery Zone, mais il y a un dernier élément sur lequel j'aimerais revenir: la boule-rouge-à-ressort de StudioPolis Zone. Une variation sur le thème du trampoline qui vaut la peine qu'on y regarde de plus près.

Ceux-ci ne propulse franchement pas haut, mais on a bien le temps de profiter de leur animation atypique. En plus, ils déclenchent "à la demande" une animation normalement plutôt rare de Sonic (celle utilisée pour le faire marcher dans les pistes-tourbillon de la GHZ).

Leur forme sphérique s'accompagne d'une mécanique où on est propulsé un peu dans n'importe qu'elle direction, les transformant en un mélange entre bumper et tapis-roulant, mais comme ils sont placés en groupes assez généreux et à l'écart des dangers, ils restent fun.


Wednesday, December 23, 2020

Bonjour Stravingo

Je vous ai déjà un peu parlé de Stravingo, un développeur de homebrew avec qui j'avais eu quelques contacts du côté de 2007. Il a lancé un nouveau site web ces derniers temps, l'occasion de le retrouver et de lui poser quelques questions.

Voilà, donc. Est-ce que tu peux nous raconter comment tu as découvert la programmation homebrew ? Et à quelle époque de ta vie as-tu fait tes premiers pas sur DS ?

En fait, je suis tombé dans la programmation depuis tout petit, vers l'âge de 10 ans au début des années 80, grâce à un ZX81 gagné par mes parents à un concours organisé par un supermarché. C'était les débuts de la micro-informatique, rare étaient les gens qui avaient un ordinateur chez eux. Mais cette petite machine à l'affichage monochrome dotée de 1Ko de RAM a complètement orienté ma destinée et m'a permis de découvrir ce que je souhaitai faire plus tard. J'ai commencé à programmer très tôt, car à l'époque il était difficile de se procurer des cassettes de jeux pour cette machine.
J'ai en revanche eu des livres et des magazines expliquant la programmation en basic et donnant des listings d'exemples. J'ai donc dû pour jouer recopier ces exemples, parfois les relire pour trouver des erreurs de recopie occasionnant des bugs, appris peu à peu à les modifier puis à créer à partir de zéro mes premiers programmes. J'ai ainsi appris tout seul à programmer, en tâtonnant avec les ressources de l'époque. Mes premiers véritables cours en informatique, je ne les ai eu qu'à la fac 10 ans plus tard !
Entre temps j'ai eu d'autres ordinateurs, un ZX Spectrum donné par un oncle féru d'informatique qui m'a permis d'afficher mes premiers pixels en couleur (quelle émotion, encore maintenant), puis un Atari STE qui a redonné un coup de fouet à ma passion pour l'informatique. C'était pour moi une révolution, sonore et visuelle ! J'ai beaucoup joué dessus, mais aussi beaucoup codé. Toujours en Basic grâce à l'excellentissime GFA Basic, mais c'est aussi là que j'ai découvert l'assembleur et le langage C.

Le même GFA BASIC qui avait été utilisé par Eric Chahi pour développer les outils de son "Another World", si ma mémoire est bonne. Mais légèrement plus jeune qu'Eric ou Michel Ancel (qui avait aussi commencé sur ZX81?) si je calcule bien. Avais-tu déjà essayer de programmer sur une autre console (avant la DS) ou sur un autre appareil embarqué avant ? Avais-tu fais de la programmation PC ?
 C'était l'époque où le monde vidéoludique se partageait en 4 : l'arcade, les consoles, les Atari/Amiga, et les PC. Les Mac étaient dans une dimension un peu parallèle. Personne parmi mes connaissances n'avait de console ou de PC, mais j'en suivais l'actualité avec émerveillement dans les pages du regretté magazine TILT. Je voyais bien que les Super NES, Megadrive et autres PC Engine tenaient la dragée haute à l'Atari (je n'entrerai pas dans la polémique Atari/Amiga), mais le monde de la console ne m'interessait pas à l'époque, car une machine sans clavier qui ne permettait que de jouer ne me disait rien.
C'était la programmation qui m'attirait avant tout. Mais pas forcément pour développer des jeux. Ce que j'aime dans la programmation, c'est la possibilité de créer. Toutes sortes de choses. C'est un outil qui permet de créer et c'est ça en fait que j'aime avant tout, et pas forcément que dans le domaine de l'informatique.
Marrant... de mon côté, il y avait beaucoup de PC, quelques consoles 16-bit et quelques Amigas parmi les potes rencontrés après mes 15 ans. Pour jouer sur Amiga, il fallait une autorisation parentale et prendre deux bus. Et personne n'avait pris d'Atari.
Puis ça a été l'hégémonie du PC et les machines 16/32 bits ont laissé leur place. Un âge d'or à mon sens a disparu et j'en garde la nostalgie. Celle où deux potes peuvent faire un jeu dans leur garage. C'est ce qui est revenu avec l'esprit du homebrew et qui me plait. J'ai eu de nombreux PC, mais je crois que je ne me suis toujours pas remis de pouvoir afficher 256 couleurs simultanément avec une carte VGA. Merci Sylvain de me permettre de faire cette thérapie 😉 J'ai continuer à coder, sur PC et sur Mac, et j'en ai même fait mon métier 🙂

Mais pour ce qui est des consoles, c'est un monde dans lequel je n'ai mis les pieds que très tardivement ! J'ai acheté ma première Nintendo DS en 2007, mais très rapidement j'ai cherché un moyen de la programmer et c'est là que j'ai découvert de monde du homebrew et de ses kits de développement amateurs. 
Ca m'a tout de suite plu, car la petite bestiole aux deux écrans a bien des charmes et des possibilités techniques que j'ai cherché à expérimenter au travers de la réalisation de jeux (Ka-Boom, Setsuzoku no Puzzle) et d'utilitaires (DS Weather Report, Treasures of Gaia, Miniville DS Manager, Secret Hordes) et de quantité de projets plus ou moins esquissés. J'ai aussi découvert une communauté très active de développement amateur sur Nintendo DS, en particulier française sur un site web hélas maintenant disparu, dev-fr.org. C'est cet esprit de communauté que j'aime beaucoup dans le monde du homebrew, avec son esprit d'entraide, d'apport d'outils, de vision critique.
Une disparition que je regrette aussi, évidemment. On retrouve certains anciens sur twitter, de temps en temps, mais ce n'est plus la même chose.

L'autre console que j'ai acheté, c'est cette année, une gameboy FAT première génération de 1989. Avant tout pour le côté icônique, la nostalgie d'une époque, la beauté de son design. Mais on ne se refait pas, le côté programmeur a vite pris le dessus. J'ai acheté une cartouche avec mémoire flash, je me suis interessé aux possibilités de développement, et je viens de sortir mon premier essai de programme, Kalimboy, permettant d'utiliser la Gameboy comme kalimba, le "piano à pouces" africain 🙂
Intéressant. Je me demande si ça fonctionne aussi avec une cartouche programmable avec carte micro-SD ...
Sinon, en matière d'appareil embarqué, j'ai réalisé des applis sur smartphone et iPad, sur Arduino, sur Raspberry Pi et aussi sur une pédale d'effets pour guitare programmable ! En fait, ce que j'aime, c'est la diversité, explorer de nouveaux champs d'expression via la programmation, expérimenter de nouvelles plateformes, pas forcément récentes. D'ailleurs la programmation sur Super NES et sur Megadrive me tente bien 😉
Je te comprends ^_^

Tuesday, December 22, 2020

hg up -r default ; hg merge -r tip

 Replier la branche sur défaut... sur le tronc. Un truc qui fait partie intégrante du processus de développement de mon équipe au boulot et que j'ai tendance à laisser complètement de côté dans mon développement homebrew. Au point que là, je suis dans la branche "newmap" depuis .. je ne sais plus. Novembre 2019 ? (  hg glog | grep '^[^:]*[/\\]' -A5 -B2 --color=always | less -R à la rescousse)

Avant ça, le code venait de "refactory-engine", une autre branche démarrée Janvier 2018. Qui elle-même était le prolongement de "latest-devkitpro" (commencée elle en Novembre 2017) qui prolonge "restructuring" (une initiative d'août 2016). Eh ouais.

Bref, je me suis lancé dans quelque-chose de complètement 2.0

Je me demandais ce matin si je ne replierais pas l'état actuel sur default avant de réouvrir une branche "spr+spr=spr" qui serait bien utile pour le projet "dreamland". Mais bon, les outils sont encore expérimentaux et j'ai tellement déplacé des trucs d'un fichier à l'autre que le diff fait plus de 100000 lignes.

Donc, bin non. On est pas en environnement professionnel. Et je n'ai aucun contributeur tiers ou client qui pourrait avoir besoin que je fasse un patch pour un SchoolRush Definitive Edition, donc "default" attendra encore un peu.

Friday, December 18, 2020

From iColorUsed to ScanTiles

 Bion. Vous vous souvenez peut-être qu'au moment d'attaquer l'ère post-desktop, je vous avais fait une photo de mon carnet de Bilouterie (entretemps aussi devenu mon agenda) dans lequel je mettais à plat un autre algorithme pour identifier les couleurs utiles et les couleurs inutiles dans mon Sprite Editor. Peut-être ... 

Oui, parce que par la suite, je n'en ai pas vraiment fait grand-chose: ça ne permettait d'atteindre aucun objectif. ça ne contribuait pas à cocher des cases dans la todo list. Mais si 2020 m'a appris quelque chose au niveau des bilouteries c'est que je dois arrêter de faire comme si elles étaient un entrainement à la gestion de projet.

Ne pas travailler sur certains aspects d'un projet parce que le management trouve que ce sont d'autres aspects qui doivent recevoir la priorité, c'est plus ou moins mon lot quotidien au bureau. J'ai besoin de casser avec ça et de faire (faire faire) c'qui me plaire (plaire plaire). Pas de prétendre que je suis dans le management en plus d'être un bon exécutant. Alors, la semaine dernière, j'ai remis ça en route.

Bon, il est vrai que j'ai aussi essayé une fois de plus d'utiliser la fonction 'tiens, qui utilise cette couleur' pendant que je gribouillais des essais de décor inspiré du graphisme de Nerkin, et qu'une fois encore, j'ai perdu tout le travail en cours parce que le programme s'est gelé.

Au final, j'ai maintenant des boutons plus clairs, mieux séparés les uns des autres pour éviter les maladresses, et un tout nouvel algorithme basé sur une sorte d'énumération générique du tileset. Il faudra d'ailleurs que je réécrive aussi la fonction "Zap!" pour en bénéficier.

Et tant qu'on y est, je pense qu'avec une petite modification supplémentaire, je pourrais aussi m'en servir pour préparer (enfin) une prévisualisation des pages de graphisme quand on choisit quel doit être la prochaine page à éditer. Une idée vieille comme l'éditeur de niveau, mais qui ne s'était jamais retrouvé "en tête" de la liste des priorités...

Mais là, c'est les vacances qui s'annoncent, alors au diable les priorités. Faisons du hobby-coding. C'est pas Monsieur-je-suis-un-dev qui va me contredire.



Friday, November 27, 2020

4U2

 C'est un groove dont je ne me lasse pas, même s'il a plus de 10 ans maintenant. Mon frangin a écrit "4U2" à une période où on avait la SNES et Donkey Kong à la maison, et pour ma part, ses roulements de percu m'invitent à sauter d'arbre en arbre aussi.

Et comme j'ai plus trop l'âge pour ce genre d'exercice, j'ai furieusement envie de filer le rôle à Bilou, ce thème viendrait alors compléter "little flower on the grass" pour illustrer musicalement la Green Zone.

Mon frère le présente comme un morceau 16 pistes (que j'avais ramené sur 6 pistes à l'époque de mon player SoundBlaster), mais vérifications faites, on pourrait le ramener à 13 pistes + 3 pistes libres pour les effets sonores. Il est un peu gros (611K), mais il y a un sample de synthé qui fait plus de 290K et qui ne demande qu'à être loopé (on en passe d'ailleurs jamais la moitié pendant le replay). Il y a aussi pas mal de sons de drums'n'bass qui se terminent par du quasi-silence et qui pourraient aussi être raccourcis/loopés/finalisés à coup d'enveloppe.

Il lui reste un dernier défaut: il est fort répétitif. On a 2 patterns qui tournent en boucle pendant pas loin de 2 minutes, avec un instrument de percu qui arrive au bout de 40'. Puis on coupe un peu la rythmique, puis on la remet. etc. ça manque d'une p'tite mélodie, et les syntés qui arrivent pour doubler le 'marimba' à 2 minutes ne relève pas vraiment le niveau. Les 2 mesures de piano "façon planer n'est pas jouer" sont très chouettes mais trop courtes elles aussi.

Bref, il faudrait trouver un thème sympa (1er monde) à jouer p.ex. à la flute de pan. Mais je n'ai encore rien à proposer pour l'instant.

Tuesday, November 17, 2020

Pixel study: Nerkin's pyramid

For once, I truly did some pixel study of that art piece I retweeted. It was an interior-and-exterior pyramid scene which I thought would let me improve my desert.spr much more than a random NSMBU screenshot of Honey Dunes...

Pour une fois, je me suis fait un vrai "pixel study", pas juste un p'tit retweet avec l'ambition noble (mais un peu hypocryte) de revenir dessus plus tard. C'est que je voudrais enrichir l'environnement de la pyramide, voyez-vous, et que les "Dunes de Miel" de NSMBU m'ont un peu laissé sur ma fin. Mais la scène de de Nerkin (ci-contre) a aussi bien une toile de fond qui évoque la grande structure (un truc que j'avais bien aimé dans Shantae et Eagle Island), un mur proche sombre et intéressant, et des pierres "de structures" aux contrastes bien pensés.

I also re-crafted a scene close to the one I already have with my own pyramid tileset so I could do a comparison. much more color depth on the background layer for Nerkin. He also let bricks protrude more, and favoured 'damaged areas' vs. my own "specks and scratches" that make the background unnecessarily noisy.

Interresting, too is the sand dropped here and there in the background. And he works with 2 or 3 pixels per "line" while I've been working with .7 or .5 pixels, leading to 'dotted' patterns whenever I want something to be irregular.

Il faudra que je m'essaye à ces briques de fond que le temps à progressivement décalé, soit vers le côté soit vers le bas, ce qui donne quelque-chose de plus convaincant que mon décor tout-en-carton. Et pour ça il faudra que je m'autorise 2 à 3 pixels par "ligne" (contre le demi-pixel utilisé ici qui a tendance à rajouter du bruit avec ses pointilliés.

If we look at the values alone (i.e. convert to plain greyscale), there's more depth in Nenkin's artwork. using about 30% of the range for the background and 45% for the 'I'm the ground' brick (centered around half-bright grey, btw). 'ignore-me' bricks use only 20% of the range (the second 20%, in fact) 

Seeing the two side-by-side makes me wonder: should I really push a 'slightly elevated perspective' in my next game ? There seems to be plenty of room for improvement even by keeping perpendicular-to-level-map camera ...

Je dois reconnaître qu'à les mettre côte à côte, j'en viens à me demander si le passage à une perspective 5:6 plutôt que "de face" est vraiment si intéressant que ça. Nerkin n'en a pas eu besoin, en tout cas.

Bon, par contre, avant de pouvoir creuser plus loin, il va falloir que je me refasse un jeu de dsgametools récents, parce que le "guru meditation error" quand je demande à SEDS de me lister les tiles qui ont une couleur donnée après avoir réencodé les palettes de Nerkin ... ça me gonfle un peu.

Sunday, November 15, 2020

DS Day Off

 Il me restait quelques jours de congé à prendre. Et la Wallonie avait prolongé les congés de Toussaint de 7 jours ... du coup de mercredi à dimanche, j'ai pu prendre à peu près 2 heures par jour pour faire un peu de développement DS. L'objectif: pouvoir faire une démo des "blocs interactifs de taille variable". La stratégie: remplacer les fichiers de la "démo git père Noël" par les fichiers de Crazy Brix.

J'ai fini par y arriver, mais avec 3 jours de bidouille pour parvenir à utiliser des fichiers pré-existants, on ne peut pas dire que dsgametools soit prêt pour une game jam.

Mon éditeur de sprite ne m'a pas aidé à manipuler ce 'brix.spr', importé par WiFi, si bien que j'ai finalement ajouté un widget pour pouvoir ouvrir n'importe quel fichier (et pas juste les quatre "projets en cours").

Je devrai rajouter une p'tite couche de ce côté-là: une tentative pour sauvegarder les modifications, et vlan, c'est le répertoire tout entier qui s'est retrouvé renommé 'movibak'. Et aussi bien runMe que mon éditeur de niveau se sont retrouvés incapables de poursuivre le travail parce qu'ils n'avaient plus leur répertoire temporaire.

Le code de base du moteur de jeu m'a mis les bâtons dans les roues, lui aussi. Pour pouvoir changer la couleur des briques, j'ai utilisé les changements de palettes. Si, vous savez: ce mécanisme qui permettait à Super Mario Bros 1 de gratter quelques blocs mémoire en recolorant les nuages pour en faire des buissons. Ouais. Bin la DS sait faire ça aussi mais avec 16 variantes de couleurs pour 256 couleurs. Quelque part cet été, j'avais ajouté la possibilité de repeindre les morceaux du niveau (pas juste les éléments de décor, comme dans School Rush, mais aussi les éléments principaux). Mais j'avais oublié que le moteur de jeu, lui, n'était toujours pas prêt pour cette rajoute ^^". Et desmume n'est pas aussi sexy de ce point de vue-là que les émulateurs des devkits SNES ou NES: je ne me suis rendu compte de rien jusqu'à ce que je fasse un dump des registres graphiques dans DDD...

Voilà. Ajoutez un premier jour bien cahotique où le code importé du repository git ne voulait pas compiler, ou ne trouvait plus ses fichiers intégrés, ou "oubliait" de reprendre les couleurs des personnages parce que, dans sa branche, il n'y a même pas encore de support multi-palette pour les sprites (mais si, enfin. Ces p'tits blocs mobiles qui se déplacent librement sur l'écran, en plus des grilles qui servent pour les décors)... Vous comprendrez pourquoi ce genre de chose ne s'était pas mis en place depuis un bon moment.

Saturday, November 07, 2020

Newsaholic?

 

J'aurais bien voulu faire un peu de bilouteries pour me distraire ces derniers jours, mais je n'y parvenais pas. J'étais accroché aux chiffres. Evolution du covid en Belgique, en France, UK, US, ... nombre de votes restant à dépouiller en Arizona, en Georgie, avance des bleus sur les rouges dans le Wisconsin, le Michigan, la Pennsylvanie... Et le nombre effectif de bulletins terminé dans les états déclarés "gagnés".

ça a commencé par un suivi de plus en plus fréquent de la page 'info' de la RTBF en plus des deux journaux quotidiens, puis en plus du dashboard GISandDATA de John Hopkins, les compte-rendus de la page google histoire de voir s'il n'y avait pas des nouvelles qui n'auraient pas encore été reprises sur la story RTBF ...

Enfin, ça devrait aller mieux, maintenant. J'vais préparer des champignons.

Saturday, October 31, 2020

Cancelled refactoring

I had a checkbox in my notebook asking whether BlockArea really needs to be a full-fledged GameObject or could be something simpler. So I started to refactor things and see whether we couldn't have more features moved from GameObject into CommonGob instead.

Yeah, I know. You're lost. 

Let's start with GameObject. That one is how the engine sees Bilou, Bladors and all the other characters in the game.

Now the 'BlockArea'. This is a temporary object that captures information about where a GameObject interacts with a special block on the map. During that time, that part of the map must be able to trigger and get collisions.

The part that annoys me is how being a GameObject implies being an Animator. That implies being registered with the engine. There's no good reason for BlockArea to be an Animator: it won't exist for more than one frame. But because being a GameObject implies being an Animator, I have no choice.

Or do I ? I started trying to change the inheritance graph so that now CommonGob -- the thing I introduced to capture what was previously into SimpleGob (AppleAssault-like GOBs made of only one hardware sprite) but had to be shared with CompoundGob (SchoolRush-like GOBs made with AnimEDS). 

But that turned out to be a bad idea: many parts that used GameObject (including the script-parsing code) assumes that GameObjects are Animators that can be played, stopped, etc. 

So I'll have to roll back and return the things as they are. That would have been a nightmare in the CarzyBrix era, but hopefully, it's just one command in mercurial. 

c:> oubliette


Sunday, October 11, 2020

Direct Flags

Signing in for a 7-days trial of the Nintendo Online sure affected how I used my hobby time these last days. But nevertheless, I could do some homebrew coding, and it was for the level editor.

You may recall that I'd like to introduce 'direct flags tiles' in the engine. The idea is to enable any combination of some very basic properties like "can be swum through", "can be climbed on" or "can be fallen through" within the level by dedicating 64 tile types where the 'type identifier' part is used as a direct set of flags for those properties.

Une des idées avec la révision du monde de Bilou, c'est de pouvoir permettre à certains tiles de définir directement les propriétés physiques à appliquer. Dans Apple Assault et School Rush, chaque numéro de tile fait appel à un lookup dans une table de correspondance pour connaître les 'flags' à utiliser dans cando(): ça, c'est l'encodage indirect. (ça vous rappelle vos cours d'assembleur ? c'est normal). Un quart des types de tiles seront maintenant dédiés à ce fameux encodage direct, qui permet notamment d'exprimer n'importe quelle combinaison de 6 propriétés fondamentales comme "permet de tomber", "permet de nager", "peut être escaladé", etc.

Yet, that's only efficient if you don't have to come with 64 custom editor art for them. And that was only possible with a few changes to my MetaFlags widget and the surrounding code:

  • paint color for 'environment type' tiles 
  • on/off switches for those tiles in MetaFlags
  • auto-generate combined tiles for combined environment (e.g. CAN_SWIM + CAN_CLIMB)

"auto-generation" works by painting the the 'pure' tile with the highest bit, then painting over the lower-priority bits. So if you swap the order of  all-blue CAN_SWIM and some-green CAN_CLIMB, you won't see that you can do both anymore.

Jusque là, c'est bien beau sur papier, mais dans l'éditeur, comment représente-t-on que le bit 4 est utilisé pour l'eau et le bit 3 pour l'escalade ? Eh bien à travers le fichier .gam, bien-sûr. Celui qui contient déjà des commandes "block {}" pour tous les blocs spéciaux (bonus, clés, portes, etc.). Comme leur nombre a été réduit à 64, je peux utiliser une partie des numéros pour décrire 6 graphismes de base (un par propriété fondamentale). La chaine hexa sert toujours à définir l'image à afficher, le nombre qui est derrière la couleur à utiliser (le noir pouvant servir à 'effacer'). A partir de ces images de bases, l'éditeur générera les combinaisons possibles.

It's far from perfect, especially because I still have to override that for the tile that says "plain air here, sir". But I realised it was merely an optimization over the 'indirect' tiles, and premature optimization is the cause of so much bad things ...

*but* I can manage to get some clean output if I define 'flags' in the .gam file. Especially, knowing that meta-tiles are alpha-rendered, meaning that any black color turns transparent, whatever their palette indices. 

*edit* And the reason why so many levels I edited lately would have buggy 'empty' tiles rendering is that this "rush.gam" file I modified for the snapshots is only used in two levels so far.

Wednesday, October 07, 2020

Other perspectives

I should possibly call them 'projections', because a perspective is something where distances shorten coherently when things are further away, and typically will never have parallel segments to depict things that are parallel in the 3D world. 

And I don't have to make the height of the front face shorter than the width of the same cube. If I do, it will be a stylistic choice of mine. 

cyangmou: Really depends on the type of projection you use. You can use foreshortening, but you don't have to, as long as it is consistent between the objects you are using. I mean it's more about the consistency of the general ruleset which is applied. e.g.:
I'll have to keep that in mind before setting the pixel sizes into stone tiles.

 (There's more about isometric pixel art tutorials in Cyangmou's "Pixel Art Knowledge" collection, of course)


Thursday, October 01, 2020

Ori et le Langage Retrouvé

 J'ai finalement terminé Ori & the Will of the Wisps hier, soit 13 jours après son achat. Pourtant, je pense qu'il est dans l'absolu plus difficile que son prédécesseur, mais je suis nettement mieux rôdé à manipuler le p'tit bonhomme.

"Est-ce qu'il est dans la continuité" demande ma collègue 'Sparkling', fan de la série ? Eh ... difficile de répondre. On est dans un jeu qui débute son histoire après l'histoire du premier jeu, mais qui en rupture avec le jeu précédent puisqu'on commence en échouant sur une île inconnue.

D'une certaine façon, "The Will of the Wisps" est autant dans la continuité de "The Blind Forest" que "Link's Awakening" n'est dans la continuité de "A Link to the Past".

La grosse "nouveauté" dans le jeu, c'est cette société de personnages non-jouables qui tiennent la bavette ça et là, que ce soit pour nous renseigner sur le fonctionnement de l'île, nous envoyer dans des recoins pour des quê-quêtes à la Guilde Noob ... ou pour nous soutirer des crédits.

Eh oui, c'est l'autre "nouveauté": les orbes de lumière spirituelles sont sur cette île une monnaie d'échange pour payer le cartographe (qui arrive toujours sur les lieux avant nous, hmm), le guru des arts martiaux et le type louche qui deale des éclats d'esprit pour nous permettre d'être mieux défendu ou de faire un 3eme saut. 

Vous l'aurez compris, je ne suis pas convaincu. Et si j'ai systématiquement mis "nouveauté" entre guillemets, c'est parce qu'il ne s'agit ni plus ni moins que de réinjecter des mécaniques conventionnelles du jeu vidéo dans une oeuvre qui jusque là n'en avait pas besoin. 

Ori and the Blind Forest n'avait pas besoin d'armes, pas besoin de crédits. Le lien empathique entre Ori et le monde qui l'entoure suffisait à entrer en phase avec les souvenirs, permettant du coup de raconter l'histoire sans avoir besoin d'un vieux barbu qui nous explique que "ah... oui, mais tu ne connais pas toute l'histoire à propos de X". 

Ce lien permettait aussi de faire monter son personnage en puissance grâce aux orbes spirituelles. C'était à moitié direct (il fallait quand même retourner à un point de sauvegarde après avoir reçu assez de lumière). C'était suffisant. ça collait avec le personnage. Mais c'est fini.

ça ne ruine pas le jeu, évidemment, mais je ne peux m'empêcher de regretter ce manque d'ambition. Ca me rappelle un peu la difficulté à faire une suite à Another World après avoir fait un jeu-culte qui avait su casser les codes du genre en ne nécessitant ni score, ni barre de vie, ni 1-UPs.

Touche finale, les personnages proposent ici une sorte de chaîne de l'échange qui m'avait si bien plu dans Link's Awakening. Je vais avoir du mal à être objectif ici parce qu'un plantage à l'arrivée dans la clairière aux Mokis m'a empêché de recevoir le 2eme objet lors de mon premier essai, et que, craignant de provoquer à nouveau un plantage en reprenant la manette, j'ai évité comme la peste le Moki qui permet de commencer cette chaîne. Je n'avais donc jamais l'objet dont aurait eu envie les PNJs rencontrés au fil de l'aventure.

Pour l'amour du jeu, j'aurais bien fait la chaîne quand-même, avant de retourner affronter le boss final. Malheureusement, l'idée n'a pas été super-bien exécutée. Me voilà avec quelqu'un qui me file un sac. 

"Ah ouais, j'me souviens d'un Moki qui voulait un sac pour devenir aventurier". Seulement, lequel ? Eh oui, 80% des PNJs du jeu sont des mokis, à peu près aussi reconnaissables les uns des autres que ne le seraient des écureuils. Parfois ça n'est pas trop dur: "cherche quelqu'un qui a froid" ou "cherche quelqu'un qui a besoin de lumière" quand il y a un territoire des glaces et un territoire des ombres, c'est dans mes cordes. Mais quelqu'un qui a besoin d'un sac ? ou d'une longue vue ?

Certains sont amusants à retenir. le moki qui veut un chapeau est à côté du vendeur qui a un chapeau. Mais comment deviner qui va nous filer un chapeau ? Au moins, sur Koholint, l'alligator qui ne veut plus de ses bananes est entouré de bananes. Le type qui file du miel est à côté d'une ruche, etc. On peut essayer de remonter le fil depuis un personnage vers celui qui peut nous débloquer. Dans Ori, ça semble la plupart du temps impossible à deviner.

edit: Les mokis de la chaîne de l'échange ne sont pas les seuls PNJ avec lesquels on peut faire des mini-quêtes, mais à part quelques unes, je les ai trouvées très noires, et pas franchement satisfaisantes. Je m'explique: supposons qu'on vous demande de retouver doudou qui s'est perdu. Bon, c'est pas la quête la plus héroïque du monde, mais au moins vous aurez fait votre B.A. et un sprite sourira à l'écran. C'est un scénario plutôt rare dans Ori. une fois le lieu demandé découvert (mon ancienne maison dans les bois perdus), il y a de forte chance que la-dite maison soit complètement pétrifiée et que le doudou ne soit plus qu'une masse informe de graviers. "nouvelle quête: allez annoncer la triste nouvelle à Machin". Pas franchement chouette, hein ? On en regrette presque d'avoir accepté la quête.


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 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

Friday, July 31, 2020

I hate it!

Let me be 100% clear. It really gets on my nerves to the point I feel like I should crush my mouse into the desk to fill better. Why on Arrakis did they had to make their operating system in such a way that every item you could think of needs a dedicated tool to be investigated. What was wrong with "everything is a file", uh ?

Everything is IUnknown. Wonderful.

- - - Round 1 - - FIGHT! - - -

I wouldn't even object if you had a clear way to scan that.

Want to find the log where DbgPrint wrote stuff ? Better download debugview.exe and don't mess with its settings or you won't see anything
Need to check some NDIS log instead ? that will be tracelog.exe for you. But make sure to check you got anything with tracert.exe before you try to use PDB files to make sense of what you got.
Want to figure out what devices are out there ? You'll need c:\program files (x86)\Windows Kits\...\devcon.exe (that's another download for you)

Want to know what drivers are out there ? that will be driverquery, sir. But maybe you want a cup of sc query first ? Or some pnputil.exe /enum-drivers to check the drivers cache ?
Want to know what that 1077 error code means ? Please use net helpmsg 1077.

Let's not even talk about where to find 'all the running applications' or their windows.

No wonder why they needed a powershell to make things start to work.

Oh, /dev, /sys, /proc. How much I miss you... msinfo32 is such a poor substitute ...

- - - Round 2 - - FIGHT! - - - 

I wish I could simply use my knowledge of gdb on Windows binaries, but I haven't found any way to do so. Granted, Visual Studio debugger does a decent job, but given the size (and the license requirement) of VS, I can hardly install that on every test system on which stepping through code might be required.

Easy (in gdb environment): you'd use gdbserver on the 'test system' and connect from your full-fledged gdb-compatible debugger on the machine that has the source and stuff. Again, I have no clue whether this is possible in the Windows econosystem.

So what's left is WinDbg, which requires a much smaller package to be installed. I'm going through GFFault.net tutorial to try figuring out how to learn that tool.

- - - Round 3 - - FIGHT! - - - 

There's a strace-like tool in https://github.com/DynamoRIO/drmemory ... we'll see whether that makes me a better windebugger during 2021 ... forget it: drstrace.exe just crashes when starting to trace most programs, including something as simple as Notepad.exe >_<
If not, I guess I could at least teach myself https://docs.microsoft.com/en-us/sysinternals/downloads/procmon

Just in case you wonder how to enable core dumps on a system without ulimit, check out Windows Error Reporting. It's not like you hadn't launched the Registry Editor earlier this week, right ?

- - - Epilogue - - -
Before you install rogue sotfware on your machine, you might want to know that Windows has md5sum "equivalent" within the swiss-knife certutil tool: certutil /hashfile your_file_name md5.