Sunday, October 31, 2021

Loading more, in LEDS

Bon, les soucis avec le moteur de jeu semblaient réglés, donc j'ai voulu vérifier que l'éditeur, dans sa version 1919 (une petite révision en-dessous du code sur mon laptop) présente sur Lime savait bien modifier des choses sans perdre d'information.

Je me rends compte que tenter de re-charger un deuxième niveau dans l'éditeur conduit au mieux à un iScriptException, au pire à un crash à une adresse venant du void*. Entre les deux, un "bon vieux" crash comme sur cette photo, qui pointe du doigt la boucle interne à Block::getnext()

Le 'pire crash' contenait quand-même quelques adresses vers du code dans la pile et suggère de regarder du côté de l'appel à Block::append() dans Level::ScanSubFile().

L'affichage des miniatures dans l'écran d'accueil, c'était pas terrible non plus. Plusieurs fichiers avaient juste des têtes de Bilou partout. Une résurgence d'un problème que je croyais cru réglé ? (ça se produit essentiellement avec greent.cmd et ses SimpleGobs, on dirait)

On dirait bien que ce n'est pas trop difficile de reproduire le problème avec 'cmdck' pour peu qu'on lui ajoute un moyen pour charger un 2eme fichier de commandes. Un peu plus de mettre le doigt sur le problème, puisqu'au moment du SEGV, on est envoyé à une adresse invalide.

Un cran plus tôt, on voit une liste de blocs dont le dernier a une table de méthode virtuelle totalement farfelue. Et ça, pour le premier bloc à traiter dans 'ink.gam'. Mais il y a eu un autre fichier .gam passé en revue avant, et le bloc farfelu est de type 'END'.

Je refais un 3eme tour de programme, je surveille tous les ajouts de blocs spéciaux. Et en réalité, le bloc "end" s'auto-ajoute dans la liste. Du coup, faire un 'delete' dessus parce qu'il n'est pas du type 'spécial', ça casse forcément tout.

edit: un petit 'ledsdbug.nds' qui reprenait les modifications utilisées en Avril pour corriger les miniatures, je remarque du coup que les miniatures sur NDS essaient toutes d'utiliser le sprite #0 ... louche ... la modif 'Anykey()' ramenée aussi et je constate que la ligne 'spr.more' n'a pas été correctement traitée. La faute à une valeur incorrecte pour la correction des numéros de pages d'animations (ouais. C'est technique hein ? j'aurais peut-être juste dû parler de 'pageshift', comme dans le code ^^). Rien de ce genre sur mon PC et pour cause: le code de LEDS a inversé le pageshift lors de la dernière sauvegarde ...

Par contre, du coup, l'outil de test cmdck -s greent.cmd > /tmp/green2.cmd me montre que toute la première moitié du script n'est pas ré-écrite après le traîtement. 'va falloir que je ressorte encore ddd. Euh non. ça c'était juste une interférence entre fprintf(stdout) et fopen("/dev/stdout"). 'faudra que je sois plus prudent avec ça.

re-edit: une fois ce pageshift corrigé, ça ne marche guère beaucoup mieux. Les miniatures ne sont toujours pas chargées parce qu'il y a des valeurs complètement incohérentes à la place des numéros d'animations dans le fichier. En fait, le fichier tout entier est sans-dessus-dessous dès qu'on atteint la section des animations et des miniatures.

Et ce n'est pas la première fois que j'ai des ennuis avec ces sections. Je ne peux pas exclure que c'est parce que j'ai utilisé une ancienne version de SEDS ou MEDS sur Lime. Mais je ne peux pas non plus exclure qu'il reste quelque-chose à corriger dans les éditeurs. (les éditeurs en version finale sont clean. Mieux: AnimEDS est capable de corriger un fichier foireux rien qu'en l'ouvrant et le re-sauvant).

re-re-edit: avec un fichier .spr valide, il me restait deux soucis à résoudre dans LEDS:

  • éviter les crash si on pointe dans le vide pendant l'édition des monstres (MonsterPropertiesWindow n'était pas prêt pour ça). Un 'simple' pointeur NULL, mais qui attire mon attention sur le fait que le hardware de la DS autorise qu'on lise à l'adresse 0 (en fait, tout une page de 32K).
  • avoir un affichage correct des miniatures produites par AnimEDS, et pas cet espèce de potée aux pixels que l'on voit pour Bilou. un simple '+2' qui manquait dans la version qui tournait sur DS.

Mais c'est compris et réglé pour attaquer le dernier week-end de congé. 'faudra que je note de comprendre pourquoi mon curseur de monstre a re-disparu, par contre.

Saturday, October 23, 2021

Le tout premier ?

 

Je viens de retomber sur une pièce d'anthologie. Une reproduction colorisée de ce qui pourrait bien être le tout premier synopsis de Bilou's Adventure! On y voit d'ailleurs dans le bas un 'bubule' dessiné par mon frère.

Premier élément remarquable, la 'school zone' est loin dans le jeu alors qu'elle passera assez rapidement comme deuxième zone. La zone aquatique est visible dès le départ, mais nécessitera des palmes (juste avant la School Zone) pour qu'on puisse y entrer ... Comme dans Commander Keen.

My brother had a fascination for maps back in '93, so I should not have been surprised if one of the first documents he brought me after we decided to rename the 'buble' character 'Bilou' was a world map of the games' big adventure. 

And on the back of that world map, there was a set of sketches for the games' introduction sequence ("magic" stones get scattered during a space shuttle crash), the main menu screen, and so on. Unlike in previous documents, the character is already identified as 'Bilou', and we are 'PPP Studio'.

Cerise sur le gateau, au dos de cette feuille, les croquis de mon frère pour l'intro, les menus, etc. Qui nous confirme que même si on dans du tout vieux, le nom "Bilou" avait déjà été arrêté.

There are a few interesting similarities between that map and the ones from the original Commander Keen trilogy. Notably the abundance of world map teleporters and an early-visible area that requires a swimming upgrade to be visited.

Compared to other maps of the game, the school zone appears quite late in this proposal, and the final boss is "catvador", the evil ruler of the Black (sic. we meant dark) Empire recycled from Calimero.
 

Tuesday, October 19, 2021

Dangerous au magasin.

Premier écran. premier niveau. Un long corridor s'ouvre devant vous. Rien ne bouge. Rien ne brille. Un coup de stick a droite, vous faites quelques pas. Soudain, un bruit derrière vous: un énorme rocher rond vient de tomber sur le sol, et avance vers vous, implacable. Le temps de vous remettre de votre surprise, et vous êtes déjà en-dessous.


Bienvenue dans Rick Dangerous.

On reprend. On avance sans hésiter, On se jette dans le trou au bout du couloir : il n'y a pas grand-chose d'autre à faire. Ah-ça fait demi tour? stick à gauche... trop tard.Vous êtes de nouveau mort. 
On recommence. Avancer tomber, tac-demi-tour, avancer tomber, et là, il faudra des réflexes de jedi pour sortir du creux où se ballade votre premier ennemi (ou probablement quelques vies en plus). Bref, vous avez de la chance si vous atteignez le 2eme écran avant d'être game over.

Moi, je n'avais pas eu cette chance. J'ai posé le stick et je me suis remis au bout de la file pendant que celui derrière moi s'essayait à son tour au jeu. C'est la règle, à la maxithèque. Oh, je pourrais bien essayer d'aller attendre pour Sonic, le jeu qui vient de sortir sur la nouvelle console, mais tous les grands y sont, ou presque. J'en ai pour 45 minutes d'attente minimum. Côté Nintendo, bof. Cette semaine, c'est de nouveau les tortues ninja. Le look est sympa, mais impossible de comprendre ce qu'il faut faire dans le jeu. Je n'arrive même pas à comprendre pourquoi je meurs.

Even if you have never played Rick Dangerous, I could hardly believe you reach this part of the Internet and still ignore it may be one of the earliest implementation of the 'Die and Retry' concept. What may sound strange is how people could have *enjoy* diying because of such impossible to predict traps and yet retry. So let me tell you how we were playing that game back in the day.

Rick Dangerous was not like other C64 games. It was a wonder. A console game for mini-computers. No loading times. No key to press or obscure options to toggle with function keys. If you happened to have the cartridge, you'd just stick it in your computer and plug a joystick in port 1. You'd be ready to play. Of course, none of us had ever owned the cartridge, and because it wasn't a disk, none of us either had a pirate copy of the game. The only place where we could play it was in the supermarkt.

Non, j'aime autant rester ici et regarder par-dessus les épaules pour voir comment les autres s'y prennent après la grosse pierre. Ah ? on peut tirer. Il faut gérer son timing par rapport aux ennemis qui font des va-et-viens. On descend, on descend... Ça va, la 2eme partie à l'air moins méchante, en fait. Mais le niveau a l'air super-long.  Ah ? on peut mettre des bombes, aussi? Et voilà qu'on appelle notre joueur, plus qu'un et c'est de nouveau à moi. Reprendre le stick dans une partie en cours, c'est toujours chaud. La règle implicite c'est que soit on se fait game over rapidement pour pouvoir repartir de l'écran titre avec tout le stock de vie, soit on essaie de profiter de la situation du joueur précédent, mais au risque en cas de game over rapide-mais-pas-tant de s'entendre dire que 'eh mais non, c'est à moi, maintenant'. Ici, il était sur la salle mortelle du bloc fou, et visiblement il ne connait pas encore le truc. 
 
A moi donc, de nouveau. On élimine le premier ennemi. On descend s'occuper du deuxiEh !? il sait nous toucher depuis le bas de l'escalier ? Bon, heureusement il y a un check-point juste avant ce 2eme ennemi. Je l'élimine, je descends l'échelle je ... Mais!? il bouge, lui, maintenant ? Je reprends. Tirer.. Descendre. Tirer. Tirer. Descendre par l'échelle de droite. (ah ouais, avec le lance-flèche je comprends pourquoi), sauter dans le QUOI!? des pics qui sortent du sol au moment où j'atterris ? "ah ouais. 'faut serrer à gauche, là." fait-on dans mon dos. (un sympa, celui-là. Je me réjouis de voir jusqu'où il va).

Back then, the area of the store where you could purchase electronic devices like TVs, HiFis and recently mini-computers, they decided that interactive devices like game consoles and computers would be openly usable by potential customers. Of course, quite quickly, grown-ups thought they had no need to type more PRINT statements on yet another qwerty keyboard, but kids would start to line up for a chance to hold a NES or master system game pad. You'd have one game available per machine, no access to the reset button and so on and couldn't ask for the cartridge to be swapped unless you were grown up.

So you could play until you'd be game over. Then you'd have to hand over the stick to the next in line. But that means while you're waiting for your turn to approach, you can get a clue of what will wait you in areas you haven't explored yet. You won't always learn *everything* about the game, of course, because you might end up taking a slightly different path than those experienced players you've "followed", but it gives die and retry a very different taste, imho.

Mais ça ne suffira pas. Ce n'est pas encore aujourd'hui que je verrai la fameuse chauve-souris qui bloquait mon frère. Je cale sur une sale avec des plate-formes en bois et des ennemis partout. Leur mouvements me déconcerte. Quoi que je fasse, ils finissent par me prendre en tenaille. En plus, quand j'arrive là, je n'ai pratiquement plus de munitions donc je perds presque d'office une vie pour pouvoir refaire le plein.
 
Vous l'aurez compris, regarder jouer les autres était une partie intégrante de l'expérience du jeu à l'époque, mais regarder un bon joueur, c'était aussi risquer de passer à côté de toute une série de pièges qu'il a subtilement évités. Il faudra non seulement apprendre la bonne route, mais aussi la taille des hit-box invisibles et les temps de réactions. Tout ça avec un jeu qui aurait mérité d'être sur une manette NES ou Megadrive pour que les actions soient directes, mais qui doit se contenter d'un stick Atari à 1 bouton avec des combinaisons douteuses comme "haut = saute", "feu + haut = tirer", "avant + feu = coup de baton", "bas + avant = ramper", "feu + bas = bombe". 

Bah, je suis out pour cette fois-ci. Et manque de pot, le "sympa" derrière moi connaissait la manip pour mettre le jeu de voiture également présent sur la cartouche. c'est foutu pour aujourd'hui. Je vais aller voir s'il n'y a pas une nouvelle M.A.S.K. sortie d'une boîte, puis j'irai me lire quelques Scrameustaches.

Retour en 2021. Rick Dangerous est resté un de mes titres-référence. Même si je n'essaierais pas d'en cloner l'esprit, j'apprécie toujours de le reprendre en main. La qualité audio-visuelle du titre était bluffante pour les possesseurs de Commodore plus habitué à un Zorro ou un Boulder Dash, mais je ne suis pas sûr que ça aurait suffi si on avait eu le jeu à la maison (donc 1/2h/j pendant les vacances scolaires uniquement) plutôt que de pouvoir y jouer "en société" au supermarché. Merci, la maxithèque ;)
 

Back to the 3 Rooms ... hopefully.

 

Most of what had been identified as faulty early this summer is now fixed. Even the mysterious way Bilou flickered while running has been understood (something cleared the VRAM slot of one of the head's sprites) and fixed (animation was using the wrong page). It's been quite time-consuming but at least it is done. It's time I start doing some [todo] pixel art to make proper 'doors' in each environment and [todo] craft the kind of rooms I actually need for my 3-rooms milestone.

But see, I've taken almost 1 hour editing that and commenting about it. So I've captured my description of the milestone in my notebook because it's much easier to take it and focus a bit on what I'm going to do next than it is with a blog. 

Anyway. Let's have all tools and runMe rebuilt. Let's have them installed on the cube so that I can use the latest build on the Real Thing before I start messing up with the maps and spritesets.

Many of the 'todo' items for last year had nothing more 'to do' on them.

In the milestone, each room had two doors, so it could communicate with both alternate world. [todo] the engine needs to be able to remember which world we come from and spawn Bilou at either left or right door based on that information. That requires at least an engine upgrade.

Friday, October 15, 2021

Coupez!

Imaginons qu'on ait envie de faire un peu de demoscene au milieu de Linux. Imaginons encore qu'on ait vraiment besoin qu'une partie du programme ne soit jamais interrompue par autre-chose. Difficile, hein ?

J'ai fait un truc un peu du genre, un jour, mais il faut avoir accès à la configuration du bootloader. De même qu'on peut forcer le kernel Linux à n'utiliser qu'une partie de la mémoire, on peut restreindre l'ensemble de coeurs accessibles au scheduler grâce à isolcpus=0,1,2 (ou tout autre combinaison qui vous convienne, laisser un coeur sur 4 au système, c'était un peu extrême :-P). Quel est l'intérêt ? eh bien, c'est que si ces coeurs ne sont plus utilisés par les processus génériques, un programme ayant les droits suffisant peut toujours faire appel à sched_setaffinity() pour se lier à un coeur en particulier, y compris un coeur qui avait été 'isolé' du reste du système.

Je me demande si ça donnerait quelque-chose d'intéressant sur le devterm. 'faudra que j'y exécute un lscpu ce soir, tiens... Pourquoi je vous ressort ça là maintenant? Hmm ... peut-être à cause du gars qui faisait la promotion de ce genre de technique poussée au point d'héberger un système temps-réel à côté de Windows entre la démo de miroirs déformables en temps réel, les caméras 3D temps-réel et du système de lentille liquide contrôlée électriquement sur la foire de Stuttgart ...