Friday, June 29, 2018

Grand nettoyage de printemps ?

Bon, j'ai presque fini avec la révision des "évènements" provenant des contrôleurs de comportement (juste encore un peu de cleanup). Les histoires de signe sont réglées, Bilou fait à nouveau ses pirouettes comme il faut... et oui, j'ai encore fait du débugging avec des p'tits dessins.

Le dernier sur la liste des "grands nettoyages de printemps" devrait être l'élimination de GobExpression::xcontext, et je devrais avoir quelques notes là-dedans sur mon boox.

Après ça, il sera temps de tourner la page (parce que ça devient limite trop long, comme "printemps") vers de nouvelles aventures. J'ai bien progressé dans les recherches sur l'évolution du langage de scripting. Suis-je prêt pour attaquer le "behaviour editor on DS" ?

Tuesday, June 26, 2018

Guru Meditation again

Bon, je me suis retrouvé après avoir fait quelques essais du nouveau système de gestion des évènements de mon moteur de jeu avec un bel écran bleu. Sur DS uniquement, évidemment. Après quelques tentatives infructueuses de régler ça en une demie-heure, j'ai fini par profiter du fait que ma fée était en réunion pour me faire une soirée "guru méditation" à l'ancienne.

Papier quadrillé, désassemblage des fonctions impliquées (au moins, la position dans le programme était correcte), déduction de quel registre contient quelle variable (pour pouvoir exploiter le contenu de l'écran bleu) et structure physique des différents objets impliqués à grand coup de ddd en comparant le contenu "brut" de la mémoire et des affichages haut-niveau.

Vu que le crash se produit à cause d'un accès à la mémoire via quelque-chose qui n'a rien à voir avec un pointeur, j'étais prêt à rajouter des "nombres magiques" ça et là pour pouvoir reconnaître une transition, un état, une expression, etc. Mais en réalité, je n'ai besoin de rien de tout cela. Tous mes objets critiques ont au moins une méthode virtuelle, ce qui signifie que je peux utiliser la référence vers la vtable pour déterminer directement si une zone de mémoire donnée contient toujours un objet d'un type donné ou si elle a été écrasée.

A partir de là, c'est de la navigation dans la mémoire de la DS en suivant les pointeurs retrouvés sur l'écran bleu pour reconstruire l'état des objets impliqués dans le crash. Et au terme de tout ce sudoku-géant je finis par trouver deux indices troublant:
- l'adresse d'une des transitions à tester en cas d'évènement est un anagramme de l'adresse qui a causé le crash
- l'adresse de la liste de transitions correspondante n'est pas multiple de 4 alors que toutes les adresses ont une taille de 4 (bytes, mon cher Wattson).

L'émulateur voyant cet accès étrange aura "redresser" l'adresse, ignorant les bits les plus faibles. Parce que, oui, la machine sait que je veux prendre 32 bits quand-même. Le CPU de la DS, lui ... eh bien, il m'a sorti une variante mélangée des 32-bits se trouvant à l'adresse utilisée par l'émulateur. Les 8 bits "les plus à droite" de la valeur en mémoire se sont retrouvés à gauche pendant que tous les autres étaient décalés vers la droite.

Friday, June 22, 2018

deep blue InfiniMap

CommonMap revision changed the lookAt/scrollTo interface of background layers to take unsigned positions. After all, it shouldn't be possible to set the center of the screen into negative coordinates when the top-most corner is (0,0).

But I will need to keep internal computation of signed integers anyway. else I get blue meditation screens...

The core of the problem is that processors have two main way to understand numbers: one where the top bit of the number has no special meaning (we call them 'unsigned' numbers and they're all positive), and one where it tells whether the number is positive or negative (with some tweaks, and we call them 'signed' numbers). And among the operations the CPU can perform on number one behaves very differently on signed and unsigned numbers: division. Divide an unsigned number by two, and you'll always have to insert a zero in the top bit. Divide a signed number by two and the top bit remains sticky.

If you mess with the numbers signedness (issue unsigned operations when you should have used signed operations) and you may easily turn a small, negative number into a big, positive number during a division. That's what I did with my update ... this is what I have to fix now... hmm... tomorrow. It's time I give my eyes and brain some rest.

once upon a skunny

Ok, il y a les jeux qui vous motivent à les imiter, puis il y a les jeux qui vous motivent à faire mieux qu'eux pour prouver que c'est faisable. D'aussi loin que ça remonte, Skunny in the Wild West appartient à cette deuxième catégorie. Alors qu'on rêvait de pouvoir faire nos preuves sur Super Nintendo dans Bubsy, mon frangin ramène une diskette du supermarché avec la version shareware de Skunny. Une sorte de Mr Nutz pour PC ?

côté graphismes, Skunny nous démontre par l'absurde l'importance de la cohérence du style au sein d'un jeu. Un grand nombre des principes que je me suis juré de suivre du point de vue du pixel art vienne d'une négation de ce qui se passait dans ce jeu
- Tu ne numérisera pas des photos pour mettre dans ton jeu
- tu n'utilisera pas des lignes noires pour le contour de tes personnages.
- tu n'abusera pas des dégradés ni des tramages automatiques.

Rien que sur la séquence d'intro, Skunny fait tout l'inverse

Alors oui, ce dégradé pour le ciel est superbe. Et le canyon rend pas trop mal du tout pour du 256 couleurs. L'ennui, c'est que ça ne correspond absolument pas aux personnages ni au terrain du jeu. Exactement comme si vous preniez les playmobils des gamins et que vous les mettiez devant la peinture à l'huile de mamy pour tourner un mini-film avec des arbres en pâte à modeler.

Les personnages aux lignes noires (qui tuent le contraste et les applatissent) donnent un effet grotesque et décalé, style "bip-bip et le coyote". Le jeu devrait donc être humoristique et pris au second degré. Mais le décor, lui, est réaliste et avec perspective et profondeur, ce qui induit une forme de dramatisme. Au final, le mélange a un goût d'artifice. Comme un tour de magie dont on verrait le truc.

Autre exemple, le sol suggère que le les plate-formes se rétrécissent sur les bords gauche et droite. Un peu comme si on était sur un de ces plateaux circulaires. Mais la partie "verticale" de ce même sol reste elle parfaitement plate, sans aucun effet de luminosité ou de torsion de la texture pour soutenir ce que suggère la partie horizontale.

Alors oui, quand Morris dessine son "Canyon Apache", il utilise de l'encre de chine noire pour les traits. Mais l'épaisseur de trait par rapport à la surface du personnage n'a rien avoir avec du pixel art en 320x200. Et il n'a pas non plus besoin de faire de l'anti-aliasing. D'ailleurs, si on zoome sur une des cases de la BD, on se rend compte que les traits ne sont plus noirs, une fois la numérisation accomplie. Ils se sont mélangés avec la couleur de ce qu'ils entourent. Pour donner du brun le plus souvent. Et la résolution des sprites de skunny est 3 à 4 fois plus faible.

Je tente donc d'appliquer ça rapidement au screenshot de skunny. Et j'en profite pour essayer de corriger le dernier problème: l'équilibre entre le contraste de l'avant plan et de l'arrière plan. Les structures sur lesquelles ont doit se déplacer sont extrêmement délavées dans le jeu original, alors que le décor lui est dans des tonalités chaudes.

Or notre oeil à l'habitude que la distance "bleuisse" les choses et atténue les contraste. Il faudrait donc faire l'inverse: pousser le contraste et la saturation de l'avant-plan (et le ramener vers le rouge) tout en atténuant le contraste de l'arrière plan, diminuant également sa saturation en couleur (aller plus vers du pastel, quoi) et le décaler légèrement vers les bleus. Je n'ai pas touché au ciel lui-même: il est suffisamment en-dehors de la zone de jeu.

Et bien sûr, on s'abstient de faire pareil avec les masques gauche et droite. Ils avaient le gros défaut d'utiliser à peu près les même couleurs que le sol dans l'image originale, ce qui augmente encore la confusion.

Bon, ça ne sauverait pas le jeu dont le gameplay est infogramesque au possible (n'espérez pas ramasser plus d'une demi-douzaine de mouton lors de votre première partie), mais au moins on y verrait plus clair.

Bon, en dépit de tout ça, je dois reconnaître un sacré talent de programmation sur le moteur de jeu. Du scrolling parallaxe en 256 couleurs et fluide avec des sprites de cette taille-là, en 1994, j'aurais aimé en voir plus souvent. Et si la musique est répétitive, elle est présente et entraînante comme il se doit. Je ne peux pas m'empêcher de me demander ce que ça aurait donné si j'avais disposé de cette technologie pour réaliser Badman et Bilou... parce que le jeu est Belge! eh oui!

Saturday, June 16, 2018

iris mouse to the rescue

It is pretty handy to have the boox to draw sketches, but I don't find them as nice as the one I draw on paper. . Plus, when I'm using the boox to read the code, I can't update notes too. If I ever try, I'll have to face a near-minute swapping time every time.

So as I found the 'IRIScan Mouse' near my boarding gate, I just bought it. It's pretty funny. It's a hand-moved scanner (like the very first one I had) but fit into a mouse, and it can do both ... on Windows at least.

So it won't really make the USB printer/scanner obsolete at home, but it will certainly be helpful at the office. it has pretty nice rendering of my tiny handscript, avoids doing JPEG-by-default (afaik) and makes export of captured files pretty easy.

Or well, it should have been useful. Unfortunately, plugging the dongle into my Windows7 workstation didn't let me use the scanner feature. The mouse remains unreachable through the WiFi.

On my Linux laptop, all I see is a USB device with vendor ID 274f (Systech Electronics, according to dmesg) and product ID c001 (Zcan Wireless). no text identification of the device. The "mouse" feature does work, though. but I don't get an additional WiFi interface. So what is in the dongle exactly ? Some forum post suggests it is using the uvcvideo driver. It indeeds gets loaded. It doesn't seem like the USB device offers multiple

The dongle could be featuring just one NRF LU1P16 chip (there's one additional 1101GE marking), possibly made by NORDIC, although I couldn't find such a chip in their catalog.

But the original manufacturer's manual is clear:
Scan function requires Wi-Fi connection between computer and Zcan Wireless directly. Please add a Wi-Fi adapter (802.11 n is recommended) if Wi-Fi function is not available in your computer
my workstation at the office doesn't have any WiFi, and the dongle won't provide it. It also explains why scanning would fail on the office's laptop I've used so far when I had wifi enabled. When I'm actually connected to a network with my WiFi, the scanner can no longer reconfigure the WiFi interface to communicate with the mouse. Looks like I'll have to do some more shopping ...

Sunday, June 10, 2018

simplifying events engine

I want to get rid of some static pointers in the management of events. The idea turned cleaner as I was flying over Denmark. But the result isn't convincing yet.
- you can't jump out of inkjets anymore (event from dpad controller is ignored - apparently because TrackAttached produced an event too -- although it has no corresponding transitions)
- you might get pushed away from spongebops when you try to grab them -- weird things still occur here with my best solution for inkjets.
- if Bilou starts swimming up, he'll keep swimming up forever -- that's fixed with swapped-priorities
- the little stars shining around you when you pick a health bonus keep shining forever. -- seems fixed with swapped-priorities too.

The thing is, when I want to combine the "thoughts" of two controllers, only one events list can survive. And of course, things don't get fixed if I swap the order in which they are produced (unless I swap them properly, that is). Weird things remains with that swapped-priorities, though. Like why don't we play the 'roll-in-the-air' animation anymore when Bilou's direction is changed while jumping ? I'll have to re-activate InspectorWidget and use the combined powers of InspectorWidgets and DDD to find out.

By the way, did you know that we could have methods, operators overloading and constructors for unions ?

Friday, June 08, 2018

GameObject::useEvent() should go away.

https://sourceforge.net/p/dsgametools/hg/ci/refactory-engine/tree/libgeds/include/GameObject.h#l175
That shouldn't happen. The way controllers fire an event is not satisfying. A static pointer set by class X so that it is used by class Y with no restriction on who does what and that merely works because we know X calling ::useEvent() and Y checking *::doevents happens to take place with the right timing ? No.

I mean, look at the documentation: "assumes no re-entrance until gobRunController". That has turned false the minute I introduced 'attach-to-other-game-object' feature where you might have to run the object you're attached to before you can run yourself.

I'd like to convert {NONE, FAIL, EVENT}  enum into something else that allow "EVENT" to carry the list of transitions to check by itself.

Sunday, June 03, 2018

bubsy

I think I was 20 years younger the last time I need a SNES gamepad to press start on Bubsy title screen. After a month of training, I was able to reach world 4 and found a few 2"continues". I couldn't beat the level 3 last week-end, but at least I got the confirmation that Bubsy "claws encounters" is a fun game.

It might be the only fun thing made with that character (I do not expect much of Black Forrest's "woolies strike back"), it may have arguable pixel art, the tunes are catchy, the atmosphere is playful, the character is fun, and there is enough variety in the level design to keep us entertained.


It is clearly difficult and sometimes even frustrating without becoming utterly unfair or boring. As far as I've played it, it is challenging.


It is far from being a masterpiece in terms of game mechanics, though. The air control is sometimes a bit awkward, Packing precision, - and the "GLIDE" mechanics isn't always sufficient to save the day, But what really seem broken is what happen when you jump off a slope. First, you don't move purely upwards (if standing), but slightly backwards on a climbing slope. You'll have to compensate that with more air control. I've never seen that happening to any mammal in the real world, presumably because we feel the slope and compensate when jumping. But I can accept it: it makes sense from a pure physics perspective, and it echoes a similar mechanics in Sonic. What is broken is that if you then release the directions pad, you will find yourself pushed backwards again!