Showing posts with label animeds. Show all posts
Showing posts with label animeds. Show all posts

Tuesday, March 24, 2026

A few fixes

It should have been a calendar, and somehow I'm using it that way on the "recto" side. But it's a week-by-week calendar, which means it's also a near-A3 rigid laptop with good quality paper that I can use nearly anywhere to write notes about nearly anything. 

But I wouldn't be studying Turing processors this week-end, nor how the 1st Pokemon game stored its maps. Instead I was trying to tackle two old bugs in my editors that affect loading new files in AnimEditorDS and leaving "monsters edition mode" in LEDS. It's not very impressive, but it's releaseversary day, so here it is anyway.

And, well, it seems like it's been nearly one year since I made a release of the Dreamland demo itself. Now that the "WIP" level in the greenzone -- the one I intend to keep and that has been historically the first Bilou level ever -- has an exit door, I can make some release for that as well. Enjoy

  • water slides
  • revised appleman mechanics, including the funny rolling throw
  • connected doors
  • smashing big punches

I'm sure there are plenty of bugs and glitches here and there. This is not a polished demo, more a presumably playable snapshot of the ongoing work.

 

 

 


 

Wednesday, April 23, 2025

appleman 2.0.1

A little bit of work on the Appleman last week-end (at last, you could add and I wouldn't blame you). I've got the "shocked" animation revised, added "carried" animations and gathered infos about where these are in green.spr.

I'll still need to see why there is no "bounce" when it is shocked (reason: it's just using stopper and the animation is supposed to do the job) and patch the greent.cmd level script on the SD card of DarkneSs, because it still show the appleman with big purple punches instead of feet. (appleman.cmd must be correct, since level 2 doesn't seem to have any similar issue).

Voilà donc enfin le moment que je prends pour compléter les animations et le comportement de l'Appleman pour le projet Dreamland. J'ai corrigé l'animation "étonné", j'ai ajouté les animations "transporté", tout ça attend dans un petit fichier green.spr le prochain passage du WiFi. Je note au passage que le fichier "greent.cmd" qui décrit le premier niveau des "3 salles" a besoin d'un petit rectificatif pour ne plus me montrer un appleman aux poings mauves ^^".

La prochaine étape sera d'ajouter les animations des "pieds perdus". J'ai aussi retiré la commande de boucle pour l'animation "assommé", mais j'arrive trop tard: c'était bon pour compléter le comportement "Apple Assault" où les applemen se réveillent seuls, mais c'est inutile pour le comportement construit à partir du fichier "blador.cmd". Car oui, le nouvel appleman est plus ou moins la fusion des deux.

So let's add tonight "undead feet" animations, check a "do not loop stunned animation" that must be over 1 year old in my notebook. I've got another notebook where I've written down blador's behaviour ... let's merge that into appleman's script and we'll cleanup the resulting code mess once the home mess is tidied up.

edit: adding the wandering feet turned out extremely annoying. They're one-sprite objects, unlike most of the things I animate with AnimEDS, and it seems the software still handle that in a very different manner: touching an sprite in the side panel adds a frame with that item, rather than changing the current frame. It also breaks relationship between timeline, frame editor and buttons in general. I'll have to get that fixed: it really breaks the user experience...

edit': pick up works, stun works, wandering feet work. Apple/water interaction is a catastrophy, throwing only work from times to times, and there's something odd when you stomp on a stunned apple (blador acted as a platform there, appleman won't). That feels like it should roll instead ... A good thing animation 2.0 freed some frames ;)
 

Tuesday, February 20, 2024

Tools update


It'd be fun to try your editors! I'd probably do any serious development on a computer, but it's still cool to have an opportunity to try something I would've loved to have as a kid.

(Nova Storm, 7 February 2024)

I told you about Nova's work on NES and SNES already. Earlier this year, she shown interest into NDS homebrew and linkers, so I proposed her to try the dsgametools, and she replied with the heartwarming sentence above. My last tools release dates back from 2021, and while there are not that many things that have changed since, some annoying bugs were fixed nonetheless. So I went for a new package with some README, example files and PERL tools in addition to the .nds files proper. 

Salut les neveux. Si vous voulez tenter de faire des jeux sur Nintendo DS avec mes outils, vous êtes arrivés sur la bonne page. Téléchargez le .zip en utilisant l'image-lien ci-dessus et copiez les fichiers *dlta.nds à la racine de la carte-mémoire de votre DS. Tant que vous y êtes, vous pouvez aussi créer un répertoire nommé "moving" à la racine de la carte mémoire et déposer les fichiers présents dans Demo/efsroot/ du zip. On fait bien attention à ne rien effacer, on éjecte en toute sécurité, on remet tout en place dans la DS et voilà.

Level Editor: 

  • fixing bugs with meta buttons;
  • add support for special tiles used in conveyer belts and flowing water
  • cosmetics: buttons with shadow and show when they are pushed

AnimEditor: 

  • fixing 'apply to all previous frames' and 'apply to all future frames' buttons.
  • only store thumbnails when the animation is used. 

runME:

SEDSdlta est votre éditeur de graphismes. Il permet de définir des palettes de couleurs et des pages de blocs 16x16 ou 32x32 qui seront sauvées dans des fichiers .spr. Ces fichiers peuvent ensuite être ouverts dans l'éditeur d'animations MEDSdlta ou dans l'éditeur de niveau LEDSdlta. Les niveaux créés par LEDSdlta seront sauvés dans des fichiers .map

Deux points communs dans tous ces éditeurs: maintenir L enfoncé pendant qu'on touche un bouton/une grille/une image à l'écran permet de faire une opération différente. Et appuyer sur L+R donne un peu d'aide.

These tools seem like they're very compact and full of features, maybe to the point of feeling a little bit cramped or unintuitive, though it's tricky to do something about that with this sort of screen resolution. I do appreciate the manual that you can access whenever to find out how to do stuff, and I'd rather have all the features than have a simplified tool. I liked the "scan" button in the sprite editor; that's not something I've really seen in pixel art programs.

I can certainly agree with that. It isn't rare that I have to dig my own blog -- or worse, the source code -- of AnimEDS when I want to do something a bit less frequent like copy a frame to a given position, create a new skeletton or adjust hit boxes. I'll have to complete the "L+R to get hint on how to use things" but it's good news that someone noticed it and appreciated it. Maybe it could be completed by a "please explain that control" mode where you can touch something on screen and learn about it rather than use it ...

I feel like it would help a lot to have buttons that bring up menus (especially on the animation editor, which needs more explanation than sprite editors do), where you'd have more room to make it clear what each option does or avoid needing button combos so you can fit more options on-screen, but that has to be weighed against how much it would slow down a user who knows what they're doing. You *could* have quick shortcuts with small icons alongside a button that brings up a menu that's less compact, though.

I have started something along these lines for 'monsters edition' in LEDS... That will be motivating to push it further

As you may have guessed, that lovely avatar for Nova comes straight from her website ;)

Saturday, September 30, 2023

Un p'tit coup de marteau ...

Mes dernières sessions avec AnimEDS s'étaient toutes soldées par des "guru meditation". Peu de travail perdu, heureusement, le problème se produisant généralement soit juste au début, soit juste après une sauvegarde. L'impact sur ma motivation à continuer à animer mes p'tits persos en prenait quand-même chaque fois un coup: j'aurais pu effectivement perdre un travail précieux.

Alors j'ai noté de faire du debugging de tout ça. Il y a un bail. D'abord refaire une version précise de l'animateur (rH2021) et garder le .nds et son .elf à côté des fichiers re-générés à tout bout de champ quand je bricole du homebrew, histoire que quand le problème se présente console en main, je puisse effectivement utiliser la valeur du registre PC pour retrouver un numéro de ligne dans le code. C'est le cas depuis Juin.

I can't help wondering whether this is worth translating. It's another epic (?) showdown between me and my code to see who's got the StrongARM. But well, it has been bugging me since January, crashing the animation editor almost every time I used it. I'm just lucky I never lost anything important but motivation to work on some cute things over the evening. The "guru meditation" screens I got during the first half of the year were almost useless: the AnimEDS build on my 'lime' DS was so old I did not have the matching .ELF file for my debugger anymore. Believe it or not, the RealLife (tm) has turned so intense that I even had to write down an agenda check list with "rebuild ; keep .elf apart ; upload .nds to lime" to actually get it done.

Pas de chance: c'est un de ces bugs où l'adresse ne dit pas grand-chose parce qu'on est a suivi des pointeurs de fonctions qui ne voulaient rien dire. Mais! Bonne nouvelle, avec les nouvelles animations pour l'Appleman, le bug est plus facile à reproduire: il suffit d'essayer de copier une frame d'animation juste après avoir chargé la première animation du fichier dans l'éditeur.

Alors j'ai ressorti mon émulateur et mon débuggeur et là, bonne nouvelle, ça foire aussi dans l'émulateur. Différemment, mais ça foire, donc c'est débuggable. Et là, j'ai galéré pendant des heures ... Des structures qui ne veulent rien dire, des vptr complètement à l'ouest ... Il faut dire que pour encoder la ligne du temps utilisée par l'éditeur, j'ai pris une std::list de std::pair de classe dérivées. Bref, on se perd sous les couches de templates, de membres dépendant de l'implémentation et d'optimisation du compilateur qui prend un malin plaisir à rendre inaccessible les variables dont on aurait besoin.

With that done, I wasn't much more lucky. It's one of those bugs where you try doing a virtual function call on something that isn't truly an object and thus end up in the middle of nowhere, especially where memory contents doesn't match any valid opcode. Hopefully, while trying to get the crash to write down registers values, I realised that the bug was actually easy to reproduce (just open one animation and try to copy the frame before selecting any frame) and a bit later, that it also happened with the same file in my emulator. At least I could save the evening where I navigate DS memory to reconstruct objects on paper this time.

J'allais jeter le gant puis un soir j'ai noté dans mon calepin "fait du débugging indirect en surveillant les constructeurs". Bah oui: la variable aura beau avoir été optimisée, il faut bien qu'il soit construit à un moment où à un autre, le TIFrame qui explique pourquoi j'ai du n'importe quoi dans les registres au moment de copier cette première frame.

Sauf que ... non. Les "TIFrames" sont construites vides, puis au fur et à mesure que l'AnimationParser traite la liste de commandes destinées à GEDS -- le moteur de jeu -- il complète les coordonnées, les numéros d'images, etc. J'étais sur le point de laisser tomber (traduire: réécrire tout avec ma propre classe 'liste' plus propice au debugging) quand je réalise que je peux "figer" l'afficher d'une ou de TIFrame dont je capture l'adresse à la construction, et suivre leur évolution jusqu'au bug (l'animation en question ne contient en réalité qu'une frame et une commande de contrôle). Et là, surprise, tout va très bien (Mme la Marquise :)

 It did not save navigating memory altogether though. The way gdb handles std::list and std::pair combined to the amount of variables that were actually "optimized away" when they would be critical to have around still turned that debugging session into some guru meditation. I first thought that it was because of some incoherent animation instructions into the animation itself, but inspecting how the animationParser processed them shown everything should be fine. Yet, if I tried to see what frame was triggering the bug, all I'd get was garbage non-sense. I was about to replace all that std::* by some pype::* when I realised that I could just break on constructors of the contained TimeItems to see what the list contained.

That did not work either, unfortunately, because when TimeItems are added to the list, they are "blank" items that will be modified by the yet-to-come UPDATE animation commands. What did help, was creating some static watches at addresses discovered in a constructor-breakpoints so that I could look at the state of my list just before the offending call. That and realising that the list was just fine, thanks, but that I was using an iterator that might not have been updated since the previous list had been trashed and replaced by the new one :P

Une seule explication restante: c'est l'itérateur qui devient invalide au bout d'un moment. Je sors mon cahier A4 histoire de me faire une map UML de tous les bouts de code impliqués et c'est bien ça: quand on choisit une animation à éditer, la liste est vidée, mais l'itérateur reste inchangé, ce qui est invalide.

Ah oui. Vous vous demandez "pourquoi le marteau" ... et vous n'avez pas Thor. C'est à cause de cette blague d'ingénieur où un consultant rentre une facture de $100000 pour une intervention et ça rouspète chez le client parce que "vous avez juste donné un coup de marteau!". Et le consultant de reconnaître qu'il a fait une erreur et de préparer la facture suivante

  • 1 hammer hit: $10
  • knowing where to hit $99990

(bon, c'était vraiment une grosse machine très chère qu'il fallait dépanner). Bin c'est un peu la sensation que ça me fait sur ce bug-ci. Sauf que je ne vais pas recevoir des cents et des mille et que je ne devrai pas les débourser non plus :P

 

Saturday, June 24, 2023

area %d = anim %x

Bon, franchement, je me demande depuis quand ce problème attend que je m'y attelle... que ce soit mon blog, twitter ou mon calepin, impossible de trouver une date correspondant à "oui, la plate-forme se reclappe, mais quand je me mets plus sur sa gauche, je passe à travers.

J'imagine que ça fait partie des choses qui m'ont motivé, fin du mois dernier, à faire en sorte qu'Inspector Widget marche à nouveau dans la démo "3 rooms". Et la visualisation des zones de collision m'avait porté à croire que j'avais mal défini les zones de collision dans l'éditeur, sur NDS.

At some point, I noticed that InspectorWidget wasn't working anymore in Dreams.nds ... not quit ideal when you're trying to add bits of gameplay to your years-long-under-development demo. Especially not when you barely manage to get more than 1 hour of gamedev at once. And after I managed to get it back, I suddenly remembered that seeing Bilou falling through the flipping platform was nothing new and that it was linked to the platform having bad hitbox.

Parce que oui, ayant la flemme de définir les zones à la main, cette 'crocforme' est (avec la branche-qui-rebondit), un des premiers objets du jeu à importer une zone de collision passive directement avec area 0 = anim ${FLAGS}, plutôt que d'en fixer explicitement les coordonnées comme j'ai fait avec Apple Assault et School Rush.

Sauf que sur DS, les hitbox sont parfaites. Rien à redire. Je re-transfère le fichier (le lendemain), des fois que j'aurais oublié que j'avais déjà corrigé le soucis. Je recompile (le surlendemain), je teste. Pas d'amélioration. On est samedi, je sors l'artillerie lourde: une nouvelle instruction `break` pour le langage de script histoire de pouvoir mettre un breakpoint dans ddd et commencer à inspecter le comportement du parseur de script pile là où ça coince: dans la boucle qui lit les commandes 'Define' de l'animation où on fixe les coordonnées de la zone solide et des hitboxes pour l'animation.

At first, I thought I had just messed the hitbox within AnimEditor for DS. But a few checks and WiFi transfers later, it turned out that no: the data (as far as the editor was concerned) was ok, but the game still would use the bad hitbox. Checking that on the parser would be darker than night -- or so I thought. This is how the parser now supports an additional "break" instruction that is a noop where you can set a gdb breakpoint while parsing things. These are not meant to be committed, of course, but it definitely helped.

A few 'next instruction' later, it turns out that my engine is using tool-absolute coordinates for the hitbox instead of object-relative coordinates. That is, when you edit an animation in AnimEDS, you don't only store how to use it in-game, but also what you need to edit it again in the editor, and that includes where to put each component on-screen in the editor. The character's center and the edition widget center may match, but they don't have to.

Le code qui gère ça n'est pas tout neuf: il a permis d'améliorer les hitboxes pour attraper les objets dans SchoolRush il y a près de 10 ans. Mais j'ai commis l'erreur de copier-coller le code plutôt que de faire une fonction "importArea" qui serait utilisée des deux côtés: pour les zones actives et les zones passives.
ça n'aura donc pas été trop compliqué de faire en sorte que les deux utilisent le même bloc de code (le bon) et d'avoir une plate-forme qui fait *enfin* ce qu'on attend d'elle :-P

J'espère que je passerai un peu plus vite de la découverte du problème à la recherche de sa solution, la fois prochaine ^^"

If I want to fix that, I need to track not only hitbox#n ORIGIN coordinates, but also those of the 'solid' box -- the one used to decide whether the object cando() something. then when one 'ORIGIN' instruction shows up for the area we're interested in, we create relative coordinates. Hopefunny enough, it turns out I already have code that does precisely that, because I have both active and passive hitboxes and I failed to avoid repeating myself when writing the original parsing code ... and later failed to fix both copies when I realised things were not going as they should have.

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)

Tuesday, April 19, 2022

des sprites 32x16 ?

Le support des sprites rectangulaires, c'est pas encore une grande réussite dans GEDS. En chipotant un peu, on parvient à avoir une planche de sprites verticaux ou horizontaux dans SEDS. Ils sont quand-même édités sur une grille carrée, mais soit.

Les choses sont déjà un peu plus louches dans AnimEDS, où de curieux résidus viennent se placer par-dessous un sprite 32x16. ça gâche un peu l'effet, mais disons qu'on s'en serait accommodé le temps de d'un ennemi ou deux.

There is somehow way to introduce non-square sprites in my SpriteEditor (with those 'new W(ide)' and 'new H(igh)' buttons), and the NDS hardware definitely has support for them, but let's face it: none of the game engine or Animation Editor was half ready for a 32x16 scorpeye 'shell'

Mais le moteur de jeu a l'air de perdre complètement les pédales, lui.


Une petite réactivation de l'afficheur-de-sprites finit par me pointer le problème: je suis déjà au bout des 1024 sprites possibles dans ce nouvel environnement... enfin, pas exactement. Je n'ai pas encore saturé les 128K de mémoire disponibles pour les sprites, mais seulement les identifiants disponibles.

J'ai déjà joué avec ça pour l'éditeur de sprites, mais le moteur de jeu, visiblement, n'était pas prêt non-plus pour ça ... ça va faire un gros commit ...

You see: it really doesn't make sense. We get parts of Bilou heads instead of getting our expected shell, and the shape isn't even rectangular. Part of it is because the engine cannot change the shape of a 'limb' for a compound character while playing (changing states doesn't let you break that rule). If you're rectangular on your frame one, you're rectangular all your life long. Another part of it is because I'm hitting the tile number limit. I thought SchoolRush was already using 128K of VRAM for sprites, but it seems I was wrong and everything used to fit the default 64K. Only the background tiles had been increased. Anyway, the Makefiles didn't like it, but it is now expanded to 128K. Anything else ? Yep. size = 16 + mode = wide gives you 32x8 sprites. Not 32x16. That explains the lone stripe I had in the final attempts.

Un autre soucis visible sur l'animation: les tailles de gobs pour une page donnée ne peuvent pas être changées en passant d'une animation à l'autre. Et j'avais gardé la première version 32x32 pour l'animation "immobile". Du coup, les autres animations tentaient aussi d'utiliser du 32x32 même quand les images à charger étaient en 32x16.

Ah, et j'ai probablement sous-estimé l'existence des sprites 32x8, ce qui fait qu'encore après tous ces patches, il me manque la moitié de ma carapace ...

Sunday, February 06, 2022

tuning de branche ...

Ben ça aura été une semaine de gros débugging pour ... pas grand-chose au final. Enfin, la bonne nouvelle c'est que la branche rebondissante a bien évolué. On avait quelque-chose de peu logique le mois dernier, là, j'ai repris le contrôle.

Le premier truc, c'était de re-définir le timing des interactions entre la branche et Bilou: quand on tombe dessus, la branche s'abaisse d'abord, puis nous envoie vers le haut. Evidemment, c'est seulement pendant la phase "remontante" de l'animation de la branche qu'on a envie qu'elle puisse propulser Bilou.

Il y a déjà (et depuis longtemps) ce qu'il faut pour ça dans AnimEDS, mais j'avoue qu'au moment de créer l'animation, j'avais un peu oublié comment ça marchait. En fait, au moment où on active le mode 'box', la ligne du temps en bas l'écran permet d'indiquer dans quelles frames la boîte est active.

A week spent in debugging because I had forgotten how my tools define over what part of the animation a collision box is active. I had also forgotten that the same keyword 'area' describes the sensitive-and-passive role of a collision for 'sprites' and the offensive-and-active role for special blocks.

Well, at least, it's almost clean now. I should be able to build a new demo version next week-end. But first, I will have to make a check list of the things that are still a bit weird in the current state.

Mais quand j'ai voulu faire les essais avec cette nouvelle animation, plus rien ne marchait. Enfin, la branche détectait l'arrivée de Bilou, provoquait un rebond et activait son animation, mais impossible de se faire projeter en l'air.

Tout ça parce que j'ai mélangé deux mots-clés dans la définition des blocs interactifs (dont la gomme-qui-rebondit qui a servi de modèle à la branche): dans les définitions de machines d'état, area introduit une zone sensible (et passive) pour les collisions alors que test introduit une zone offensive (et active). Pour les blocs spéciaux, il y a un seul mot-clé -- area -- mais il définit une zone offensive. Je l'avais oublié. Du coup, j'ai passé les soirées en mode 'guru meditation' ... pour rien.

Je ferais bien une nouvelle démo pour fêter ça, mais il y a deux ou trois trucs louches aux entournures ... je vais repasser par la case "faire une todo list", donc.

I did some playtesting with J.L.N and *deline ... They mostly wouldn't fall off the branch (I made sure that one wouldn't happen too often), but it wasn't obvious to them how to make big jumps. The thing is you don't need to press JUMP when stomping the branch, but *when it throws you back*. Maybe I should trigger a 'super-throw-back' if player hit JUMP when stomping ? so you don't have to bother too much about bumper timings in level 1 ?

Saturday, December 25, 2021

xmas21.zip

I finally posted something more on my sourceforge project: the set of editors (plus runme) as I've got them by this Christmas, invoking oven-hot slopes support.

I wish I could provide you with a meaningful 'change log' for this 'release' of my tools, but let's be

honest: there are over 20000 lines changed between then and now (assuming that you're only interested in what changed since last AnimEDS release in 2020). It won't be exhaustive, but I'll try to give you an idea of what's in anyway.

Sprite Editor

  • allows you to work on any file you've got on your memory card (including automatic backups put in /DATA/SEDS/*)
  • better 'colors zapping' implementation.
  • 'where is that color used?' now cleanly implemented in the PaletteWindow
  • (improved host tools sprdo and sprck are missing from this pack)

Animation Editor

  • allows you to work on any file you've got on your memory card. 

Level Editor

  • uses new map layout with dedicated PHYS layer (accidentally named 'SYHP' in the file >_>)
  • show the 8 color palettes when selecting a block in DRAW mode (A). Color paint mode now available on both foreground and background layers (trigger with L+A on the desired layer)
  • supports new any-sized special blocks with 'lookup arrows', features revised 'meta buttons' widget to select tile properties.
  • reads new 'slopes %d = "%x"' hint in .cmd or .gam files and populates the slope tiles graphics accordingly. Different maps can use different slopes or share them by importing the same .gam file.
  • supports spritesets and tilesets overlay commands

runMe (gameplay preview & WiFi transport)

  • Allows live-skipping of buggy script lines
  • allows auto-repair of the /moving/ directory
  • features new level map engine
  • supports script-driven song swapping with zik.file = "%s"
  • Improved modplayer playback speed stability
  • supports spriteset overlays (spr.more "%s" ...) and tileset overlays (bg0.more "%s" ...)

All these .nds files will work from anywhere in your flash card, but if you install them with their original *dlta.nds filenames at the root, you'll be allowed to hope from one tool to another with the embedded buttons (quit, LEDS, SEDS, MEDS) in the application welcome windows.

Saturday, April 03, 2021

Where are my thumbs ?

I'm trying to add support for spr.more in LevelEditor (so that we keep seeing monsters positioning while editing DreamLand maps ;) but it doesn't work well. After some debugging, I realize that the values for the 'animation number' stored in the first word of the 'TINY' section make no sense. Animation #17000 ? with 48 animations per sheet ?

A simple test with ./sprdo confirms that even if I just load-and-save a file that has meaningful thumbs numbers, we end up with bogus numbers in the saved file.

Still wondering what thumbs I'm talking about ? They are still 32x32 images produced while saving animations in AnimEDS that are then used in LEDS for monsters edition.

Watching the memory backing my vector through execution, I finally found a suspicious set of `free()` statements at the end of the 'extra/unknown data blocks to set of MEDS animations' function.

The history of that function is that it abstracted something from `spr.load` script statement so that `spr.more`can exist. When it is done with them, the GameScript used to dispose of remaining really-unknown data blocks. Such as thumbnails. They won't be needed while we play the game and they eat up significant amount of memory.

Then, there was the code of SpriteEditor, the FileModel, to be precise. It had been updated so that it could invoke the same sort of 'FromExtras' function, but since we're not interested in MEDS animations while editing sprites, template magic makes this whole function unused. And then is the new tool, that tries and use code meant to be for GameScript but in a load-modify-write setup. That one ends up with freed pointers in its array and then try to save back those opaque data in the file. This is where my 17000 comes from.

The perplexing thing is that AnimEditor itself doesn't seem to read back the TINY thumbnails, but still when I load a file from OtherFileWindow, I get no thumbs on my top screen. Not until I edit something and move to another page, that is.

It took me time to check everything, and it finally revealed that, yes, makeThumb() are properly invoked even for OtherFileWindow, as soon as we call MetaWindow::data_reloaded() to signal things were updated. But the setup ThumbsWindow::restore() installed to show and use the TileTable showing the thumbnails got screwed up by OtherFileWindow's default layers settings. forcing a call to THW::restore() within data_reloaded finally fixed the issue. So that means bilou.spr on lime DS is likely fine and I can download it to resume development of LevelEditor's support for spr.do ^_^ (erhm. Next time. It's quarter-to-midnight and I've got meetings tomorrow ^^")

edit: unfortunately, after retrieving bilou.spr and school.spr that had been edited by AnimEditor on the NDS, they still contain rubbish TINY sections... I'll have to work on a medsdo tool to study that...

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.

Saturday, May 19, 2018

Un p'tit bug?

Dans l'éditeur d'animation, dernière mouture ? Je m'explique, je voulais prendre quelques captures d'écran pour expliquer comment se faire un petit personnage à partir de "composants" simple, puisque la "branche tutoriel" sur github est maintenant capable de gérer aussi bien les personnages simples que composés.

Malheureusement, un des widgets (normalement sur la gauche) n'affiche plus rien. Particulièrement ennuyeux puis qu'il s'agit en fait de la "palette de composants" qui permet de sélectionner un pied, la tête, le corps, etc.

J'ai du louper quelque-chose lors du refactoring.



Doing some bug-hunting on AnimEditor so I could do a 'setup your compound character' tutorial for the github tutorials series. Some flat facts:
- the thumbnails are on the "sub" screen, the timeline and sprite pages preview are on the main screen.
- the 'limb table' is actually rendered, but only on BG3, which appears to be hidden.
- clicking limbs properly switch sprite pages
- clicking the sprite page does weird things with the cursor on the top (sub) screen.
Oddly enough, if the layer with limbs table is hidden, how comes we see the sprite page ?


Somehow, it looks like the widget I'm using to show what is selected when clicking on the sprite page was hard-wired to the sub-screen, instead of letting the window creating it telling which resource to use. That's easy to fix.

It also looks like AnimEditor didn't get its dedicated LayersConfig, and still use the default layers setup combined with some custom register programming. That doesn't help. And we still see the SpritePage because, unlike the limbs table, this one is truly made of sprites.

Finally, it looks like the 'limbs table' is initially empty. It only fills when I drop new sprites there. It should be pre-loaded with the animation's skeletton when I load an animation.

So, some more flat fact:
- in the old approach, fill_anim_thumbs_16() is the code that copies pixels from the spriteset into a spritesheet used by the limbsTable. Exactly one 'block' of data per limb.
- only other calling site fill_anim_thumbs_16() is AnimWindow::restore().

Q: do we still call fill_anim_thumbs_16() on FileWindow::event() ?
A: yes.

Q: what is the target spritesheet then ?
A: one pointing to main-screen background tiles.

Q: did loading an anim changed the limbs table in medsgama.nds ? 
A: no. Only "opening" the animation on the AnimWindow did. And it still does. With a spritesheet using some main-screen BG memory.

Saturday, January 27, 2018

AnimationModel

Donc, j'ai fini Fez (enfin, j'ai 64 cubes) mais ça, je vous en parlerai plus tard. J'ai aussi fini de réorganiser le code de mon éditeur d'animation de sorte que les manipulations effectuées sur la liste d'images puisse être extraites du code de l'interface graphique correspondante. Je ne vais pas qualifier ça de Model/View/Controller, mais c'est un pas dans la bonne direction, à mon avis.

At last, am done with one big chunk of nefactoring on the DS Animation Editor. Frames list can now be manipulared from any piece of code. It no longer requires emulation of the whole widgets/windows engine. 

It is probably not scleanly separated as MVC code, but it is definitely one step in the right direction. Now I can get rid of the ugly coupling between thumbs display and thumbs-bitmap filling when saving the file. I can get rid of global objects. I can introduce my new Resources class.

Tout ça parce qu'il était impossible dans l'état actuel de débarasser AnimEDS de ses objets globaux vu le couplage tordu et foireux entre la fenêtre qui fait le rendu des miniatures et le système de sauvegarde. Pensez un peu: pour sauver les miniatures (utilisées par l'éditeur de niveau), on allait devoir faire croire à cette "fenêtre" que l'utilisateur passe d'une page à l'autre pour la forcer à re-générer des prévisualisations en mémoire vidéo que l'on capture pour les placer dans le fichier.

Prévisualisations qui - au passage -- demandaient qu'on fasse croire à la fenêtre d'édition des animations qu'il y a une nouvelle animation à éditer pour qu'elle la décode, construise la liste de frames correspondante et qu'on puisse demander un rendu de la première frame à chaque coup.

C'est presque un miracle qu'on ait pu continuer à éditer des animations après une sauvegarde, à ce tarif-là.

Tout ça parce que si AnimEDS garde ses objets globaux, il est impossible de réorganiser la gestion des resources dans le Game/GuiEngine.


Thursday, January 11, 2018

Engine Refactory

The Big Refactory has started (I could pretend it is a new-year resolution). And it even went pretty far, like abstracting away the animated objects list so that only the code for animated objects need to know details of the animation scheduler.

I was about to try changing the VRAM allocation system so that only classes deriving from using Resources could request items, and I got stuck in the animation editor.

Unlike SEDs and -to some extent- LEDs, AniMEDs still use a lot of global variables. Things like the sprite set or the animation being editted are used almost directly in many places, instead of being captured as "structural singletons". And at some places, it also means that we were calling Ressource Manager directly at top-level code, and that contradicts what a common base class can do.

There is one other peculiar thing about the animation editor: the set of pixels used in the game isn't uploaded to the video memory. Instead, we keep it in main memory, and only some bits of it go tothe VRAM through a Sprite sheet that map some sprite memory.  These sprite sheets are linked to a specific widget, such as the timeline or the frame preview. I must not try to make them part of a "model": they truly belong to the implementation of the widgets.

And yeah, although I have a digital sketchpad and an e-boox, I still enjoy some good paper and fine (erasable) pens for such things.

Thursday, January 29, 2015

Time to fix things.

After graphically resolving dependencies between my huge list of todo items, I attacked with usability issues in RunMe. I trashed a couple of evening on long-lasting bugs (although pathetically trivial >_<) in InspectorWidget and adjusted further the areas reporting so that I can follow which one is active when. That way -- and with another fix on AnimEDS -- I can check that flashing hitboxes needed to improve GRAB animations work fine.

There is also a curious asymmetry in the "GRAB" states. Just having left-facing GRAB react "on dpad" prevents the animation to run to completion. Indeed, the button will appear to be released (triggering a "dpad" event) a few frames after it was pressed (as a result of the mechanic allowing for precise jumps). Better seems to be Good's archenemy.

I've got an on-going experiment that allow beaming only "tiles" or "animations" or "sprites" (...) of a .spr file, in an attempt to work around limited reliability of WiFi transfers for increasingly large files from the DS... It's not very convincing so far.

Oh, and compared to June, Inspector widget has improved. I can expand/shrink behaviour controllers, set breakpoints on their events, and touching left/right "monster area" change the "suspect" in the GOBs list (only selecting those that are active, iirc).

Friday, January 23, 2015

Les vieux tout doux

Eh bien, il y en a, des choses marquées "à faire" depuis les années. Plus de 20 pages si je veux les imprimer sur papier. Ce sont principalement des améliorations pour les éditeurs, comme la possibilité de définir les zones de collision et les points-tests dans un éditeur graphique, aujourd'hui (enfin) très actuel.

La plus ancienne des fonctions manquantes du Level Editor -- les propriétés des blocs -- serait plutôt revu en "appliquer la combinaison graphisme/propriété à l'ensemble du niveau", et il faudrait aussi que je permette aux descriptions de blocs d'être partagées entre plusieurs scripts de niveaux.

Enfin, il y aura la liste des projets devenus hors-propos ou qui ne sont plus à l'ordre du jour pour mon projet actuel, rebaptisés "wish", comme l'éditeur 3D de bangbash ou l'intégration de RunME dans la PAlib :P

Mais la palme du PlusVieuxToutDouxDuMonde, c'est sans doute la possibilité de partager des tiles d'un bloc à l'autre (les blocs faisant 2x2 tiles), qui apparaît dès les premières réflexions sur l'animation des blocs en 2005 et marqué "need" en 2008 (traduisez: fonctionnalité jugée indispensable pour l'avancement du projet, qui permettrait de redescendre à 66% du nombre de tiles actuels). La possibilité de poser des quarts de blocs dans LEDS aidant, évidemment... Dans l'immédiat, j'aimerais plutôt pouvoir enregistrer des morceaux de niveau pour capturer des objets complets (qui apparaissait 6 mois plus tard, puis revient à la charge).


Voilà. J'ai fait un peu le ménage dans ce qui datait d'avant 2013 ... je ne suis pas sûr que ça m'ait vraiment fait progresser pour améliorer le niveau des expériences en cours, par contre. A suivre. Comme toujours :P
codes couleur: [done], [todo nécessaire pour school rush], [todo dans l'absolu], [wish]


That's what gets out of the 20+ pages of 'todo'-tagged posts already available on this blog. When you condense them on a sheet of paper, with focus on releasing the 'School Rush' game. There's one big point missing, though.

Write a documentation page for AnimEDS

Tuesday, October 28, 2014

Couper les cheveux en quatre ?

J'hésitais à introduire le contrôle des boîtes de collisions dans mon éditeur d'animations. J'hésitais encore plus à ce qu'on puisse activer ou désactiver certaines de ces boîtes au fil de l'animation. Tout ça me semblait plutôt relever de la machine d'états et des gardiens de transitions. Et puis Shantae m'a fait changer d'avis.

So far, I have been able to keep hitboxes on a per-state basis. Anything more subtle was resolved either by spawning new GOBs (like the punch attack in Apple Assault) or splitting the animation (inkjet). I was growing the conviction that it wouldn't be enough for new grab-in-the-air mechanic, Shantae's move pushed the definitive argument: *any* punch or kick-like move has build-up and recover phases, and the hitbox shouldn't be active by then. Splitting the animation in such cases ? That would quickly turn into a nightmare!

At this point, not adding edition of hit boxes in the animation editor would strongly reduce my chance to have form-fit-function ...


Lors de l'animation d'un coup, on peut distinguer trois phase: la préparation, l'action et le retour. Idéalement, seule l'action correspond à une hitbox offensive. Selon la longueur de la préparation et du retour, enfreindre cette règle (qui dérive du "form fits function"), c'est produire des effets incohérents et du coup rendre beaucoup plus complexe l'apprentissage du système par le joueur. Je n'ai pas eu le problème dans Apple Assault parce que les coups de poing étaient en réalité des sprites indépendants. J'ai contourné le problème avec inkjet en tronçonnant l'animation en deux parties et en faisant en sorte que Bilou ne puisse réagir qu'au moment précis de la transition entre les deux tronçons. Mais soyons clairs: faire la même chose avec tous les mouvements "power-up" prévus serait un véritable cauchemar.

Sunday, November 10, 2013

L'avis de Joke

Longue session de beta-testing hier avec Joke de la BilouCorp -- une corporation sans lien direct avec mon personnage fétiche mais néanmoins fort sympathique et versé dans la conception de jeu vidéo -- si bien que ce matin, je passais le démarrage du niveau en mode "image par image" pour comprendre d'où venait ces "à-coups" quasi systématique quand on descend de la latte pour aller se mesurer à notre premier crayon.

  • il sautille un peu sur la descente de la règle au début
  •  … la caméra ça va je trouve
  •  ça manque d'effet sonore pour les sauts et rebonds 
  • le premier saut qu'on doit faire d'un crayon à l'autre avant le pot d'encre, je remarque qu'on peut pas y arriver si on ne se tourne pas d'abord dans la bonne direction
  • La gomme du crayon c'est volontaire la possibilité de passer derrière ? le fait qu'on soit propulsé en sautant quand on est dessus n'a pas l'air de nous aider à passer. il faut prendre de l'élan je pense, ça complique les choses
 Il y a deux ans, j'aurais plus ou moins considéré ça comme du temps perdu: ce sautillement ne gène en rien le gameplay... mais ça fait tache et en plus, c'est la première chose que le joueur va voir du jeu. Donc, je creuse à grands coups de ddd avec la méthode désormais bien rôdée de "je m'arrête avec Inspector Widget dans la situation qui m'intéresse avant de mettre mes breakpoints".
Après une bonne heure d'inspection méticuleuse, j'arrive à la conclusion que le code du moteur de jeu, des contrôleurs etc. est 100% clean: c'est dans l'animation que ça coince. Pour une raison encore inconnue, une des étapes d'animation force le déplacement à être horizontal plutôt que de s'adapter à la pente en cours ... bizarre, bizarre.

Je ressors donc mon "extracteur d'animation en vrac (à perforation en vrille): il y a en effet quelque-chose de louche avec les animations de marche de Bilou. Les étapes d'animations qui se comportent bizarrement ont un bit "déplacement vertical autorisé" qui reste à zéro. Chose intéressante: le pendat (qui était incapable de suivre les pentes) a systématiquement ce bit à zéro. Dumblador, lui a son bit "déplacement vertical autorisé" mis pour chaque étape.

J'aurais été bien incapable de dire en aveugle à ma fée quelle manipulation elle aurait du faire pour changer ce règlage dans AnimEDS, ce qui signifie que c'est un des contrôles-candidats pour un menu déroulant ou quelque-chose de ce genre.
En fait, c'est le petit "!" devant "y" qui doit être retiré pour "déverouiller" l'animation verticalement.

Mais alors ? Si ce sont des règlages au niveau de l'animation (et pas d'une étape isolée), pourquoi cet étrange étape verouillée dans la marche de Bilou qui ne l'est pas pour le reste ? Sans doute parce qu'il s'agit de la liste de commandes générée pour permettre de boucler la boucle, et que son code n'a probablement pas eu droit à sa mise à jour (ouuuuh ^^").

J'édite l'animation en hexadécimal dans Midnight Commander ... Je recompile à cloche pied ... Bilou retient son souffle: c'est l'heure du test fatidique ... attente insupportable de 15 seconde pendant que la caméra re-traverse le niveau à contre sens pour venir se centrer sur Bilou au départ.

Ah oui! Bien mieux! La descente est fluide, la remontée aussi... Il me reste à aller corriger AnimEDS, donc.


Sunday, September 15, 2013

Ready? School!

one whole line of airborn (trans)anims!
Aah ! Ça fait du bien! J'ai réussi à mener à bien les modifications synchronisées de l'éditeur de niveau et d'animations pour permettre jusqu'à 6 fois plus d'animations. Du coup, ma DS "green lime" est prête à reprendre le flambeau et me permet d'enfin bricoler ce "niveau anniversaire", qui a d'ailleurs bien avancé ^_^ Le fait que toute la famille ait été à moitié K.O.-microbes pendant le week-end n'y est pas tout à fait étranger ^^"


I'm kinda proud of this week-end's progress. LEDS, AnimEDS and runME have been syncrhonously updated to allow more animations (up to 6 sheets) and thus more flexibility in behaviours. That will give me plenty of headroom for "thrown by an inkjet", stunned by a blador and all other interactions that should make the School Zone interesting to play. As a result, I have doubled the content of the "anniversary school zone" level which I hope to be ready by the end of the month.

Btw, be ready to hate the bopping eraser. It will not exactly "chase" Bilou, but it's gonna turn back or adjust the height of its jumps depending on your position 0:-°