Thursday, February 12, 2009

Script powaa!

Bon. Ouvrez un p'tit terminal (tcsh), on va s'amuser ...

display fairy.jpg
setenv FAIRY `eesh -ewait window_list | grep Magick | cut -f 1 -d :`
randomize `find /pingu/photos/ | grep -v thumb` |\
fe - "display -window $FAIRY '%' & sleep 8"
C'est ma manière à moi de me faire un petit diaporama de mes photos sur mon laptop, mode "discret: je travaille mais j'ai besoin de voir un peu mes proches".

J'vous explique ? Bon, tout d'abord, vous devez penser à tous ces programmes comme des "filtres" qui reçoivent des données par un côté (l'entrée standard) et qui en produisent de l'autre côté (la sortie standard). Un élément de base pour interconnecter les programmes est le tube ("unix pipe") représenté par la barre verticale. program1 | program2 attache les deux programmes de sorte que la sortie de program1 est utilisé comme entrée pour program2... Visualisez une usine avec des robots qui bricolent des pièces qui défilent sur un tapis roulant et vous n'êtes pas loin.

Comme certains programmes ne sont pas prévus pour recevoir leurs données sur l'entrée standard mais plutôt comme des arguments sur la ligne de commande, j'utilise aussi les guillemets arrière qui remplace dans une commande une expression par le résultat de son évaluation. Si add et mul étaient des programmes pour additioner et multiplier leurs arguments, on pourrait faire des expressions un peu plus compliquées à coup de add 5 `mul 2 3` qui serait transformé en add 5 6 avant d'appeler le programme add.

I love how scripting expands the possibilities of programming. Maybe I could have experienced something similar with Visual Basic, but that tool has never happened to be available on my Windows systems afaik. The code you see above is a script I use to periodically change one part of my screen's background as if it was a diaporama.

display FILE will just create the window and show one file. then the line with eesh will capture the identifier of that window into some variable and calling display again with -window $FAIRY will make it paint on the existing window instead of creating a new one.

That's already pretty neat, but I can push it further, like scanning through my pictures repository with find, filtering out the thumbnails with grep and randomize the output with a Perl script of mine that isn't even aware it is processing picture file names.

This is possible thanks to the unix pipe | and shell sub-expressions `sub expr` that gets a program called and its output injected as parameter for another program.

Bref, les programmes utilisés ici:
  • display, le programme d'affichage du projet ImageMagick hyper-standard. Par défaut il ouvre une nouvelle fenêtre pour la nouvelle photo, mais avec -window , il modifie l'image de fond d'une fenêtre existante. En l'occurence, cela me changera l'image affichée.
  • eesh, le kit du bricoleur pour enlightenment, utilisé ici pour récupérer la liste des fenêtres. Si vous n'utilisez pas enlightenment, le package wmctrl pourrait faire l'affaire ...
  • grep, le filtre passe partout, en standard dans toutes les distributions Unix, utilisé aussi bien pour retrouver la fenêtre dont le titre contient "Magick" dans la deuxième commande que pour retirer toutes les miniatures dans la deuxième commande
  • find, également un outil standard, liste tous les fichiers à partir d'un répertoire donné
  • cut : pour extraire un champ d'une ligne du type "fichier CSV".
  • setenv <var> <val>: pour donner un nom au résultat d'une exécution (en l'occurence, enregistrer le n° de la fenêtre d'affichage dans la variable $FAIRY)
  • randomize <args> : un p'tit script perl à moi qui renvoie ses arguments mélangés, ligne par ligne.
  • fe - "commande" : un autre petit programme à moi ("foreach") qui applique une commande à une liste d'arguments. Les puristes auraient utilisé xargs ou find -exec.
  • sleep <secondes> : pour marquer une pause entre 2 images, bien-sûr
Chouettos, non ? Allez, les amateurs de VBA. Vous mettez combien de temps pour faire ça ?

Monday, February 09, 2009

Scripting Sunday

Didn't quite got as far as i hoped in my "coding sunday", so it has rather be a "scripting - and - guru - meditation" sunday instead. Most has been done through state machine scripts or within Sprite/Level editor on the DS ... but some code will have to change. I cannot keep Bilou walking through walls or in the sky, can I ?

C'était un dimanche bien rempli donc, même si je n'ai pas vraiment coder autant que je l'avais prévu. Entre le bricolage de la machine d'état qui gère Bilou, les nouvelles animations et la construction d'un premier "niveau démo" avec les tiles que j'ai dessiné pendant l'année 2008. Pourtant, il faudra que j'y passe. Il y a quelque-chose de fondamentalement foireux dans le couplage "animation/déplacement" qui permet à Bilou de marcher à travers les murs ou dans le ciel ^^"

  • got the GameScript understand multi-set spritesheets (with one set for tiles and one for monsters all in the same file)
  • got Bilou walking animation done
  • bilou walks up/right, jumps and fall
  • sketched a little level for those new tiles i've been working on in 2008 ^_^
  • figured out that i'm still missing *many* tiles and a lot other tiles are unusable ^^"
  • fixed so weird memory things in libntxm, but i still have data corruption happening. Maybe a checksum of some internal arrays will help ... or replacing arrays with std::vectors somewhere ...
  • had fun with sprites on "mid" layer. Bilou can now hide within tree, so can woodworms :P
  • STill to do:
    • [done] testpoints should be checked at every frame, not just when the animation loops
    • [done] moving Bilou through the animation isn't the right way to go. Maybe "delay x" in the animation sequence to have the next frame triggered only when we move to the next pixel would be better.
    • [done] check my own code for things that might corrupt libntxm's internal state. (identified some memory leaks, but no buffer overflows or double-frees)
    • make sure we can see Bilou's feet on grass
    • [doc] let animated blocks work with "extra tilesheets"rather than copying sheets "as needed".
    • [done, leds] ignore extra sheets in the level editor (rather than just showing empty sheets)

    Saturday, February 07, 2009

    Xargon, Jill et Nikita

    Okay, pour ceux qui en nourrirait encore vaguement l'espoir, je n'ai pas l'intention de porter Jill ou Xargon sur DS. C'étaient de bons jeux dans leur temps, mais même le fait que les sources soient disponibles (pour Xargon en tout cas) ne me tente pas.

    Je m'explique. Un des éléments qui m'intéressait dans l'étude du code de Xargon, c'est que tout comme notre Commander Keen, Jill et Malvineous (eh oui: Xargon, c'est le vilain pas beau et Malvineous le héros tout en muscles) savent grimper aux lianes (chaines et autres). Un des aspects qui me coince un peu dans Bilou. Or donc, grace au flag f_notvine, ces héros grimpotent grace aux éléments suivants:

    • le test "y a-t'il une liane" n'est effectué que sur des frontières de tiles (comprenez, quand x est un multiple de 16)
    • une fois accroché à une liane, il n'y a plus de déplacement horizontal

    Maybe my last post made you believe I was about to port Xargon or Jill of the Jungle to the Nintendo DS. I'm not. They were solid games back in the days, but even with sources available, I'm not tempted. What's interesting me while studying Epic source code is that their heroes (much like Commander Keen) can CLIMB. Vines, chains, pole. Name it, you have it. That's one thing I don't know how to deal with in Bilou so far, but thanks to the F_NOTVINE flag. Things seem to work fine. The 'is there a vine' test is performed only at tile edges (x is a multiple of 16) and no horizontal motion is allowed on a vine. Fine.

    But there's one thing missing: where's the code that aligns character to a vine if they aren't yet ? having to pixel-perfectly aligning before climbing is usually not something you leave to your players. And I don't recall it being so hard to hop from vine to vine in Jill of the Jungle. Almost easier than hopping from block to block, actually.

    Apparemment tout ce qu'il faut sauf qu'il n'y avait apparemment rien dans le code qui permette de forcer le perso à s'ajuster à l'emplacement de la liane si jamais il n'était pas pile en-dessous ... louche, ça. Vous vous voyez jouer à un jeu où il faut être positionner au pixel près pour monter à l'échelle, vous ?

    Pourtant je me souviens que ce n'était pas si difficile de sauter de liane en liane dans Jill (j'ai peu joué à Xargon, en fait). Bien plus facile que de sauter de bloc en bloc, d'ailleurs.

    Bin voui. pas étonnant. Figurez-vous que Jill ne se déplace jamais que _de 8 pixels à la fois_ idem pour le scrolling. Oui, vous avez bien lu : 8 pixels. La taille d'un caractère à l'écran. Jill est soit sur le bloc gris, à moitié sur le bloc gris ou à côté du bloc gris. Point barre. Le jeu est un peu plus "souple" pour les déplacements verticaux (2 pixels) mais n'empèche. La version shareware avait beau se gausser de Commander Keen et de Super Mario, le slogan "The Brothers are History", c'est à Giana qu'il revient, certainement pas à Jill. Et toutes ses voix enregistrées et ses cuisses bien rondes n'y changeront rien!

    So here's the catch: Jill and Xargon only move by 8 pixels. Same for the scrolling. Yes, 8. A full-sized letter on CGA screen. Either Jill is perfectly centered on a 16x16 grey block, or she's exactly on the edge of that block. Or she's next to it. That's it. Vertical motion is a bit smoother (2 pixels granularity), but barely. There may be a similar 'minimum walking distance' in commander Keen (4 pixels), but motion happens pixel per pixels, much more smoothly. And while Jill's jerky motion could be excused by the run animation on the ground, nothing justifies it while jumping (and it hurts the gameplay a lot).

    Dans Commander Keen, cette "distance de déplacement minimale" est de 4 pixels (en tout cas, si je donne le plus court déplacement possible, c'est ce qu'il se passe), mais malgré tout Keen est déplacé pixel par pixel. Bien plus fluide. Et si ce genre de "déplacement brusque" peut se justifier pour l'animation de la course, en revanche, il est complètement ridicule (et pénible au niveau du gameplay) lors d'un saut. Tiens, à creuser par contre ... Et si j'utilisais le freinage du perso pour forcer ce genre de déplacement minimum ?

    Bref, le code était instructif, je vais me replonger dans la programmation de mon p'tit Bilou (qui a appris à marcher ce matin ;) et en attendant, si vous êtes en manque d'exploration de mondes curieux à grand renfort de transformations magiques (c'était un des points-forts de Jill, je l'admet), je vous recommande chaudement Nikita, la femme-loup du jeu Inner Worlds. (merci à CJ pour l'URL et sa compil' "nostalgy power" :)

    Voilà. Ma sauce bloubloute alors je vais vous laisser. A+.

    Thursday, February 05, 2009

    Xargon : may the source be with you ...

    Vous ne connaissez pas Xargon ? pensez à Jill of the Jungle avec un chromosome Y et vous ne serez pas loin... Vous ne connaissez pas Jill of the Jungle non plus ? Ah. Bin probablement que votre PC n'avait pas encore de carte SoundBlaster ou d'écran VGA en 1992. C'est vrai que ça coûtait un peu cher, à l'époque.

    Quoi qu'il en soit, si je vous en parle, ce n'est pas parce que les 3 épisodes de Xargon sont disponibles sur classicdosgames.com. Non, c'est parce que le code source de Allen Pilgrim est également disponible. C'est du code C, mode réel pour le DOS, mais suffisamment propre pour que tous les aspects "hardware" soient extrait de la logique du jeu -- et croyez moi, sur PC, c'est un exploit majeur.

    Ce n'est pas la bibliothèque d'abstraction du hardware qui m'intéresse, bien sûr. Même si c'était impressionnant à l'époque, le scrolling des jeux de plate-forme Epic ne pouvait concurrencer celui du moteur de John Carmack (commander Keen & autres), le player de fichiers CMF (adlib/midi) était bien connu, mais je n'ai jamais vu d'éditeur correspondant, et si l'on se laissait impressionner par un "yeeaaah" en ramassant un gros bonus, le mixage des effets sonores était en réalité peu convaincant (voire absent).

    I'm currently studying the game logic of Xargon from Allen Pilgrim's sources. I hope that giving a look on someone else job will help me to overcome that "analysis paralysis" in my own game engine. I know i tend to overcomplicate things ... The management of objects-to-world collision has already shown enlightening... more to come. And, by the way, if anyone of you is interested into porting Xargon to the DS (or whatever other system), you may want to give a look to information gathered on the game modding wiki at shikadi.net in addition to the source code. Personnally, it's not in my to-do list :P

    Non, ce qui m'intéresse c'est la logique du jeu. Et quelque-part, cette logique me crie le maître-mot de Mollusk: "ne vous posez pas de question: codez". C'est vrai quoi. Je me prends la tête avec mes test-points alors qu'en fait, ce n'est qu'une optimisation bancale que je traîne depuis l'age du BASIC, renforcée par l'étude d'un jeu NES. La gestion des collisions perso-monde dans Xargon est bien plus simplement basée sur les possibilités de l'ensemble des tiles recouverts et l'affectation de propriétés sur chacune de ces tiles.

    int cando (int n, int newx, int newy, int ourflags) {
     int x,y,temp;
     int flagor, result;
     int startx, endx, starty, splity, endy;
    
     startx=newx/16;
     starty=newy/16;
     endx=(newx+objs[n].xl+15)/16;
     endy=(newy+objs[n].yl+15)/16;
     splity=(objs[n].y+kindyl[objs[n].objkind]+15)/16;
    
     flagor=f_notstair;
     result=0xffff;
     for (y=starty; y<endy; y++) {
           if (y>=splity) flagor=0;
           for (x=startx; x<endx; x++) {
             temp=(info[board(x,y)].flags|flagor)&ourflags;
             result&=temp;
           };
     };return (result);
    };


    Comme disait Colomb en quittant le Portugal "Il suffisait d'y penser": le tout est de concevoir les propriétés des tiles de manières à ce qu'elles "s'additionnent" bien. Un personnage ne peut se déplacer vers un nouvel endroit que si tous les tiles possèdent les bonnes propriétés ("pas un bloc", ce que Allen appelle f_passthru. Celà demande parfois un peu de jonglage mental. f_water est évident, f_climbable aussi. f_not_stairs un peu moins...


    int trymove (int n, int newx, int newy) {
     int ourflags;
     ourflags=f_playerthru;
    
     if (newy>objs[n].y) ourflags|=f_notstair;
     if (cando (n,newx,newy,ourflags)==ourflags) {
        moveobj (n,newx,newy);
        return (1); // successfully made it to new location.
     } 
     else if (cando (n,objs[n].x,newy,ourflags)==ourflags) {
        moveobj (n,objs[n].x,newy);
        return (2); // could only move vertically
     }
     else if (cando (n,newx,objs[n].y,ourflags)==ourflags) {
        moveobj (n,newx,objs[n].y);
        return (4); // could only move horizontally
     };
     return (0);    // couldn't move at all.
    };


    J'aime bien aussi la manière dont il a réussi à capturer les comportements de déplacement simples Il faudra que je tente d'en faire autant. Bion. Je vous en dirai sans doute plus. Malgré tout, la routine de gestion du personnage principal fait quand-même 7 pages, et je n'ai pas encore tout lu.

    Wednesday, February 04, 2009

    [section pour ch1]

    Le premier moteur

    Avec la mise en ligne du code source de quelques vieux jeux MS-DOS, je vais enfin avoir ce qu'il me faut pour démarrer sérieusement mon premier moteur de jeu. S'il y avait déjà eu une petite démo diffusée à ce stade, elle n'était guère convaincante au niveau du comportement des personnage et fonctionnait fort sur le principe "tout ce qui n'est pas complètement transparent est solide" et son "niveau" devait être entièrement réalisé dans un programme de dessin puis converti.

    Thursday, January 22, 2009

    un autre mot sur la VRAM

    Ouaip. "un petit jeu tout simple où il suffirait de trouver toutes les pommes pour passer au niveau suivant" disais-je donc. Pendant les préparatifs de SeafoxDS, j'avais ajouté la possibilité de demander le chargement d'un fichier .pcx (une belle grosse image bitmap, quoi) comme image de fond. Sympa.

    Histoire de tester ça, je bidouille un peu hier soir, mais pas moyen de sortir le décor de Donkey : King of Swing (qui n'est là qu'à titre temporaire, hein) sur mon écran: je me retrouve à la place avec un tas de tiles bleu suivant un motif improbable et quelques pixels aléatoires ça et là.

    So, the next milestone should be a very simple "grab all the bonuses and head to the gate" kind of platformer, where i can gradually introduce tests. I just wanted to add a fancy background, since i added support for .PCX loading when "working on Seafox DS". I just couldn't make it work, while runMe can happily show .PCX files for at least two years ... I just forgot that SUB_BG0_CR register is not the only guy who matters here. Whether you have bitmap or tiled background is defined by the video mode, which in turn tells the graphic hardware how to interprete the content of SUB_BGx_CR.

    J'avais beau fixer les lignes "SUB_BG0_CR = BG_BMP8_256x256|BG_BMP_BASE(1)|BG_PRIORITY(3);", identiques dans le mode "télécharger un .pcx et l'afficher" de runMe et dans le moteur de jeu ... rien n'y fait.

    J'ai fini par me rendre compte ce matin que changer les attributs d'un fond particulier ne suffit pas à faire de lui un fond bitmap sur la DS. Il faut d'abord s'assurer que le mode vidéo supporte bien ce type de plan, mais aussi qu'il peut s'appliquer au plan choisi. En clair, les seules possibilités sont renseignées dans gbatek:

    BG Mode
    Engine A BG Mode (DISPCNT LSBs) (0-6, 7=Reserved)

    Mode BG0 BG1 BG2 BG3
    0 Text/3D Text Text Text
    1 Text/3D Text Text Affine
    2 Text/3D Text Affine Affine
    3 Text/3D Text Text Extended
    4 Text/3D Text Affine Extended
    5 Text/3D Text Extended Extended
    6 3D - Large -

    Le mode "bitmap 256 couleurs" est un des modes étendus (de même que les plans avec rotations et 1024 tiles, d'ailleurs), et donc disponible uniquement sur les plans 2 et 3 dans le mode 5. Vous suivez ? Ce que nintendo appelle le "mode texte", c'est en réalité le mode "tile" qui effectivement s'apparente au bon vieux mode texte des années 80 à ceci près que vous avez 1024 caractères (et non pas 256), 16 palettes de 256 couleurs et que chaque "caractère" peut combiner comme il veut n'importe lesquelles de ces couleurs (il y a aussi un mode 16x16 couleurs, pour les nostalgiques de la GBA, bien sûr :)

    Only those combinations detailed in gbatek are possible. E.g. 3D + two text + one of the "extended" (DS-only) modes. But then, only "BG0" can handle 3D and only BG3 can be an extended mode. What i need for PCX (256 colours bitmap) is extended, clearly, which make me stumble into trouble as the Game Engine i've got so far is hard-coded to use BG2 and BG3 for maps, so that i could zoom in the front layer. Somehow, it was a bad idea >_< . It's not much a dead-end, just a reminder that DS hardware comes with constraints and that a "you just have to ..." idea must always be checked against those constraints...

    Y'a un hic, évidemment: j'avais pour ainsi dire "hard-codé" mon moteur de jeu pour que la map utilise les plans 2 et 3 (histoire de bénéficier des effets de zoom, par exemple ... ça m'avait paru sympa). Mauvaise idée, comme dirait l'autre, hein :P

    Oh, rassurez-vous, ce n'est pas un problème insurmontable. En soi, le "bitmap" tiendrait sans difficulté en mode "texte". C'est juste que ça me rappelle ma lecture de ce matin dans le bus, selon laquelle les druides théorisent que "l'univers, pour sa bonne marche, dépend de l'équilibre de quatre forces : le charme, la conviction, le doute, et l'envie d'emmerder le monde".

    Tuesday, January 20, 2009

    analysis paralysis ?

    Près de 3 mois loin de chez moi, maintenant, et toujours pas de petit homebrew à vous mettre sous la dent. Okay, mon laptop est un char à boeufs comparé aux PC que j'ai à la maison. Okay, je n'ai pas de Wifi dans mon k0dek et le laptop n'est pas configuré pour faire base station pour la DS mais il y a autre chose.

    Je sais qu'il y aura pas mal de choses à mettre en place pour parvenir à réaliser Bilou sur DS ... je veux dire par là, "le jeu de plate-formes tel qu'il avait été prévu dans les années '90 et prototypé sur BASIC", mais revu et corrigé pour la DS, bien sûr.

    Par exemple:

    • [just started] la gestion des bordures. Même si je garde au départ un système tile-based, les plate-formes mobiles et autres sables mouvant devront être capable d'altérer le comportement des sprites
    • [ongoin] les pentes. Je veux que Bilou puisse se déplacer sur des plate-formes qui ne soient pas uniquement horizontales.
    • [done] l'animation modulaire. ou "à la rayman", qui me demande un éditeur d'animations spécifique en plus des ajustements dans le moteur de jeu
    • [done] les collisions perso-bloc qui soient plus maniable que juste le "petit bonus" que j'ai pour l'instant. Plate-formes qui disparaissent, échelles, etc.
    • [done] des réactions aux collisions perso-monstre. Avec une question pertinente "et comment fait-on perdre une vie, au fait"
    J'accumule les idées sympa sans vraiment avancer dans le développement. Je sautille d'un projet de shoot à une reprise de Seafox à un "bubble bobble - like" etc. Et bien sûr, comme j'aime le pixel art, j'ai tendance à explorer les aspects graphiques à tort et à travers avant de me lancer dans un jeu.

    Je vais devoir me fixer une "roadmap" jallonée de petits projets intermédiaires, et attaquer les difficultés techniques une à une, sinon je vais finir par recommencer à programmer sur Clicker :P

    Bonne résolution 2009 #1: on garde Bilou. Quelque soit le petit jeu envisagé
    Bonne résolution 2009 #2: un nouveau thème graphique si et seulement si un jeu est produit.
    Bonne résolution 2009 #3: s'il n'y a pas d'image de fond (ou si l'image est fixe, etc.) ce n'est pas un problème pour l'instant.
    Bonne résolution 2009 #4: faire la vaisselle ce soir

    edit: côté "base station", j'ai au moins pris la peine de recompiler le module de mon stick WiFi. M'en vais aller manger une soupe et tester ça @home, tiens.
    edit++: toujours pas de connexion Internet au k0dek, mais au moins, j'ai su modifier runme pour qu'il puisse démarrer un programme 'runme-compatible' après l'avoir téléchargé.


    3 monthes in Switzerland and still no updates. I'm not focused enough and therefore I'm missing the #1 golden rule of game development : *release*. Having no Internet access in my Swiss flat doesn't help, so I modified runme so that it can launch the last compatible .nds it received from a WiFi transfer. Using my laptop as an access point, it allows ad-hoc development.

    Allez, je vais essayer de me faire un petit "ramasse toutes les pommes pour passer au niveau suivant". Ce sera déjà un bon début. Après tout, c'est fort le principe de base de Qwak, Bubble Bobble et même Still Alive DS :P