Wednesday, September 13, 2006

fighting with rotoscale hardware

sometimes, you realise you should have put more times reading the specs. That happens with my IXP2400 processor, but also with the NDS.
After the fight-against-blending story, i tried to put the grid of my sprite editor on a "rot/scale" background so that you could opt for 16x16, 32x32 or whatever edition size you prefer (though beside 24x24, i don't see what else we could have). That came just after a slight modification that was intended to fully useable 'upper' screen.

But the result was a rather black stuff. It took me hours of tests with the flash card (the emulator didn't help finding out what was going wrong, as in the blending case) to finally figure out that, while you have 8-bit per tile only on rotoscale layers, you still must write 16 bits at a time, or your access pattern is lost.

Il y a des jours où on se dit qu'on devrait lire les manuels plus en détail. C'est ce qui arrive régulièrement avec mon Network Processor IXP2400, mais aussi avec la nintendo. Après l'épisode "je me bats contre des fantômes transparents", j'ai essayé de mettre la grille du "Sprite Editor" sur un calque zoomable (rot/scale), histoire que l'on puisse aussi bien éditer des blocs 16x16 ou 32x32 ... Et ça juste après avoir modifié le code pour permettre l'utilisation de l'écran supérieur ...

Résultat? Du noir. C'est tout.

J'ai passé des heures à monter/démonter ma carte SD (comme dans le cas de la transparence, l'émulateur n'est pas vraiment utile ici non-plus) pour finalement me rendre compte d'une erreur débile. Même si les calques avec zoom n'utilisent que 8 bits par "tuile", on est quand même obligé d'écrire dans la mémoire vidéo par mots de 16 bits d'un coup... sans ça, les données se perdent :P

Monday, September 11, 2006

Cute Pixels ...

Cute pixels from Indigo Art...
I really like how he did amiga-like tiles for a "green level". Just using 32 colours for the whole stuff. Very efficient. The "ground", for instance, is mainly using colors #966d42 and #b68e50 with a "back" colour that has a more "purple" taste: #774953 ... That nicely allows you to do shadows of trees (hidden branches,etc) using #623551 and #392232. Another thing i like much is how the grass is given a "curvy" look by using only two-pixel bar of #c8d551 (yellow green) over #7fbc43 green. The effect is even reinforced using a nice blue-green (#197c3e) for grass shadows (as well as back leaves that can even pick #335955 and #304942). and #f5f08d gives the shiny pixels where grass catches the light a bit more (and there aren't many of them, as you can see...
De biens jolis pixels venant de "Indigo Art" ... j'aime vraiment le style Amigaesque de ces blocs pour une "green zone". Et tout ça sur moins de 32 couleurs! chapeau. Le sol, par exemple, avec deux teintes et un fond tirant sur le pourpre, ce qui donne bien mieux que les teintes habituelles pour les ombres des arbres, etc.
J'aime bien aussi le look "courbe" de son herbe, avec une barre de 2 pixels plus clairs au milieu, renforcé par un vert plus jaune pour les reflets et un vert-bleu pour les ombres...

Maybe you wonder why you've had that many #rrggbb color codes in the previous paragraph? that's just because it's lunchtime and i need to take notes of all those values until i have a "palette editor" for my DS-based "pixel factory" ... Another trick i like quite much is how the ground itself is given is given a rounded shape (thanks to layer transparency, of course), and how Dan Fessler has been using a pretty wide "suspended grass" to break the monotony... I tried something alike to add some snow to castle walls in some blocks of mine a couple o' days ago, but i was clearly using too small patterns, making them "unguessable" for the player.

Ah, vous vous demandez pourquoi tous ces #rrggbb dans la version anglaise? c'est les codes de couleur. On est sur le temps de midi et je prends note de tout ça en attendant d'avoir un éditeur de palettes pour ma DS. Autre chose qui donne bien dans les blocs de Dan Fessler, c'est le look arrondi du sol lui-même (grâce aux pixels transparents) et la manière dont les touffes d'herbes suspendues sont utilisées pour casser la monotonie. J'avais essayé de faire pareil dans le "chateau enneigé" que je dessinais il y a quelques jours, mais apparament, j'utilisait un motif trop petit, et on ne voyait pas de la neige, mais juste des erreurs de dessin.

Note, too, that the whole "ground" pattern is pretty large (40 pixels, actually) ... that makes me thing i was unhappy with the fact the nintendo DS has 8x8 tile size and that most of my previous pixart on the PC was using 20x20 blocs ... since it takes a rather long time to make "good" tiles for ground, etc (i mean, tiles that can be repeated smoothly in both dimensions), thinking all that previous work was "lost" made me rather frowning... but as i was looking at that grass more closely, it just appeared that we had light-pattern repeating, sometimes at the edge, sometimes in the middle of the block ... which suggested the actual block pattern wasn't Nx16 but something more built out of 8x8 tiles directly. And after i counted the tiles, my mind suddenly reminded me i should practice maths in base-10 more often :P 8x5 == 40 == 20x2.

Et si on y regarde de plus près, le bloc de terre et relartivement large (40 pixels). Ce qui me rappelle mes précédents spritesets sur PC (avec le GameMaker) qui utilisait des blocs de 20x20, alors que la DS fonctionne avec des "tuiles" de 8x8 ... Tout ce travail perdu? ce serait trop bête... Alors que si on en colle 2 l'un à côté de l'autre, ça donne 40 pixels, soit 5 tuiles (oui, je sais, je devrais réapprendre à compter en base 10).

There are still two things worth of bloggin about those blocks. First, the grass has a shadow, which suggests it's bushy and falls over the ground. Second, the "ground pattern" itself, despite looking random, is given some inherent coherency by the "tall rectangles" shape...

The general aspect of the map has something else pretty nice. It gives you a depth feeling. I think with a bit of tweaking, we could easily have a Bilou game where you can just "fall off" from one platform to the one below (which isn't actually "below" you, but rather more "below and a bit closer to the player" ... That'd be just more natural than a mario-like level design).

Deux autres choses à blogger à propos de ces blocs. D'abord l'ombre de l'herbe, qui suggère un aspect un peu "buissonneux" et qui retombe par-devant le sol. Ensuite le motif du sol lui-même, qui malgré son apparence aléatoire, possède une sorte de "cohérence" grâce aux formes généralement rectangulaires et verticales ...
La construction de la carte elle-même est assez chouette. Elle donne un effet de profondeur grâce au sol qui devient plus uniforme, ce qui -- avec un rien d'ajustement -- pourrait mener à un jeu Bilou où il est possible de se 'laisser tomber' d'une plate-forme vers celle qui est en-dessous (en fait, pas vraiment en-dessous, mais plutôt "en dessous et un chouya plus proche du joueur. Ce qui est plus logique que les designs "à la Mario" avec des blocs qui flottent dans les airs).

Oh, and before you click on another page, just have a look at those so-amiga-stylish golden coins ... #ffffff:#faf078:#efbb1c:#d07c28:#ab4625 made it pretty well, no. They remind me of "fury of the furries" game ^_^

Et juste avant que vous ne partiez vers une autre page, jettez un oeil à ces pièces d'or si typiquement amiga-esques ... Elles me rappellent 'Fury of the Furries' ^_^

original artwork found on http://www.spriteart.com/indigo/ ...

Saturday, September 09, 2006

Alpha blending.

Okay, i'm trying to make sense of the alpha-blending bits of the nintendo DS. I'd like a blended grid for my editor ;)

So, let's see the specs first:

4000050h 2 R/W BLDCNT Color Special Effects Selection (BLEND_CR)
4000052h 2 W BLDALPHA Alpha Blending Coefficients (BLEND_AB)
4000054h 2 W BLDY Brightness (Fade-In/Out) Coefficient (BLEND_Y)
Bion. Voyons voir comment marche l'alpha-blending -- c'est à dire la transparence sur les fonds -- sur la console DS (j'aimerais bien pouvoir "estomper" la grille de mon sprite editor, si vous voulez tout savoir). Trois registres jouent un rôle dans les "effets spéciaux" (fade-in/fade-out et blending) : BLEND_CR, BLEND_AB et BLEND_Y. Je suis reparti de la démo Complex2D du devkitpro pour étudier comment ça marche.

You have 3 registers responsible of "special effects", including fade-in, fade-out and alpha blending. The latter one is the one we want (mixing two layers to have one of them appearing "translucent" and seeing the second one through. Clearly, we want it for fogs, clouds, mirrors, ghosts and plenty other reasons ;)

So, let's take the Complex2D demo from devkitpro and spice it up a little bit.

//set up the sub display
videoSetModeSub(MODE_0_2D |
DISPLAY_SPR_1D_LAYOUT |
DISPLAY_SPR_ACTIVE |
DISPLAY_BG0_ACTIVE |
DISPLAY_BG1_ACTIVE );

//set up two backgrounds to scroll around
SUB_BG0_CR = BG_COLOR_256 | (1 << SCREEN_SHIFT) | BG_PRIORITY(0);
SUB_BG1_CR = BG_COLOR_256 | (2 << SCREEN_SHIFT) | BG_PRIORITY(1);
BG_PALETTE_SUB[0] = RGB15(10,10,10);
BG_PALETTE_SUB[1] = RGB15(0,16,0);
BG_PALETTE_SUB[2] = RGB15(0,0,31);
vramSetMainBanks(VRAM_A_MAIN_BG, VRAM_B_MAIN_SPRITE, VRAM_C_SUB_BG, VRAM_D_SUB_SPRITE);

There is two background layers, one being green-checker (BG0) and the other one being blue-checker (BG1). Each checker's "dark" squares are actually see-through pixels (purely transparent), which you achieve with color 0. Moreover, you have the 'backdrop' layer (here a dark-grey colour) that is seen when all pixels of all layers use color 0 (you typically never see the backdrop in a game, for instance).

Dans cette démo, on construit deux damiers, l'un vert (BG0) et l'autre bleu (BG1). Les cases "noires" de ces damiers sont en fait des pixels complètement transparents (couleur #0) et la couleur de fond (le "backdrop" -- que l'on préfère ne jamais voir dans un jeu vidéo) est gris-foncé.

//load the maps with alternating tiles (0,1 for bg0 and 0,2 for bg1)
for(iy = 0; iy < 32; iy++)
for(ix = 0; ix <32; ix++) {
map0[iy * 32 + ix] = ((ix ^ iy) & 2)>>1;
map1[iy * 32 + ix] = ((ix ^ iy) & 2);
}

//fill 2 tiles with different colors
for(i = 0; i < 64 / 2; i++) {
BG_GFX_SUB[i+32] = 0x0101;
BG_GFX_SUB[i+32+32] = 0x0202;
}


So far, we'll use SUB_BLEND_AB=0x1010, which is full intensity for both layers. If one is blue, the other red and that blending occurs, we should see purple somewhere. The initial priority is set to green-over-blue and we slowly scroll the green checker over the blue one. No blending is activated so far.

  • with SUB_BLEND_CR=BLEND_ALPHA|BLEND_SRC_BG0|BLEND_SRC_BG1; we do not change much things, as both layers are used as "blending source" but no layer is definde "transparent".

  • SUB_BLEND_CR=BLEND_ALPHA|BLEND_SRC_BG0|BLEND_DST_BG1; is more interesting. The green checker is still over the blue one, but it no longer "hides" blue pixels. Instead, it mixes with them to produce
    light-blue.

  • SUB_BLEND_CR=BLEND_ALPHA|BLEND_DST_BG0|BLEND_SRC_BG1; and SUB_BLEND_CR=BLEND_ALPHA| BLEND_DST_BG0|BLEND_DST_BG1|BLEND_SRC_BACKDROP appear such as the initial (no destination) blending.


Now, if we swap the priorities (e.g. blue checker-BG1 over green checker-BG0), the first setting (SRC_BG0|SRC_BG1) still show both layers opaque, but now that's (DST_BG0|SRC_BG1) that shows
alpha-blending while (SRC_BG0|DST_BG1) only shows opaque pixels.

In other words:
  • the source layer(s) must be over destination layer(s) to have some blending displayed. that means the priority of source layers should be numerically lower than the priority of destination layers.

  • the source layer is what is going to be translucent, the destination(s) is what is going to be seen through (and yes, i find this rather confusing).

En clair, le layer 'source' doit être par-dessus le layer "destination" pour que l'effet soit visible. Cela signifie que la priorité du layer "source" doit être numériquement inférieure à celle du layer "destination". Et oui, la libnds appelle "source" le layer qui sera transparent et "destination" le layer que l'on voit à travers l'effet. C'est perturbant, mais c'est comme ça.
J'ai parlé de transparence 50/50, mais une valeur 0x1010 pour BLEND_AB correspond plutôt à une composition additionnelle: R = 1*Ra + 1*Rb, V = 1*Va + 1*Vb ... ce qui peut être perturbant aussi. Supposons qu'on veuille faire un nuage ou un fantôme (qui sera donc notre source), on prendra une valeur de 1 pour le multiplicateur des layers-destination (histoire que le fantôme n'assombrisse jamais le décor) mais le fantôme étant du blanc pur, on ne l'affichera qu'à 50%, ce qui donnera BLEND_AB = 0x0810.

Note that calling 0x1010 a 50/50 blending is a bit exagerated. what it means is that you end up with a pixel whose values are R = 1*Ra + 1*Rb, G = 1*Ga +1*Gb and B = 1*Ba + 1*Bb. That may be a bit confusing too.
For clouds/ghosts, you want the cloud-carrying layer to be the source. The other layers should keeps they alpha-blending value to 1 (so that the cloud doesn't "darken" them), but the cloud itself (bright white) should e.g. only affect by 0.5, so that your grey tower appearslightgrey where the cloud is. That leads to e.g. BLEND_AB=0x0810.

The full demo code is available here.
Btw, See also liranuna's witch demo for alpha-blending of sprites over backgrounds.

Friday, September 08, 2006

SpriteEditor DS

Les choses prennent forme. Je peux éditer un sprite avec un outil 'crayon' ou 'block', et grâce au code de la "libfat" de chism & dragonminded, je peux charger et sauver mes sprites sur la carte SD.
J'ai rajouté hier une fonction "copier le sprite" en utilisant un truc venant de SCUMMVM (le moteur de jeux pointer-cliquer de Lucas Arts).

Un pression sur l'écran correspond à un clic simple, alors qu'une pression pendant que le bouton "L" est enfoncé correspond à un "clic droit". Pour la grille, celà correspond à prélever la couleur comme couleur en cours, et sur la table de sprites, à enregistrer la zone de travail.

Things starts getting in place ... i can edit the sprite (of course) using both 'pencil' and 'block' mode, and thanks to the "libfat" code from chishm and dragonminded, i can read sprite tables from the SD flash card and write them back. Yesterday, i've also been adding the "copy sprite" feature, using a trick found in SCUMMVM for DS (the maniac-mansion editor).

When you just click the screen, that's a regular click (GUI_CLICKED event in my engine), and if you click while pressing the "L" key, that's a GUI_ALT_CLICKED. So we now have a touchscreen with "left" and "right" click :P Right-clicking the grid is used to "pick" a color and right-clicking the sprite table is used to "save" the sprite edited.

Oh, and another goodie: just click "beyond" the current table to "extend" it with the newly saved sprite ...

Now the next step will be showing animations and supporting multi-layer sprites (with layer merging).


PS: avant ce post, il y avait mon skyblog. Les messages relatifs à la programmation DS ont été rassemblés dans ce post-anniversaire

Friday, August 25, 2006

Writing code that works ...

Deuxième petit programme pour la DS ... Hier matin, un peu avant le temps de midi, j'entends passer la musique que mon frère avait écrit pour un jeu jamais réalisé: XMASMAN vs Packs ... un concept de tetris ou le père noël doit empiler des cadeaux qui dégringolent...

A second small utility : picture grabber. It's pre-compiled with a .pcx file that is shown on the bottom screen and allows you to grab parts of the image into tiles for sprites (that moves on the upper screen) and that you can later save on the SD card).
The intent was to speed up porting of my former "pixel art" and do small games ... which never took of. But it was the starting point of "runme", the all-in-one DS-WiFi-PC converter stuff.

J'avais fait des super petits sprites (vous savez ce que c'est, hein, maintenant) avec un chouette programme (Delux Paint II, je l'avais déjà sur mon 8086, celui-là!), et je les ai toujours... alors je me dit "voilà le petit jeu que je pourrais facilement avoir réalisé pour noël!". Il marcherait nickel avec 2 écrans, pas trop még-à-l'eau ni rien. Mais bon, ce serait ridicule de devoir redessiner tout avec le SpriteEditor DS qui n'est pas encore au dixième des possibilités de DP2.

Donc je rebidouille un petit "sprite grabber", un outil qui affiche une image complète et qui permet d'en récupérer des morceaux. Première esquisse sur le temps de midi. Ca tourne dans l'émulateur. cool.
Je reviens le soir @home et ma fée est toujours à Maastricht pour la-journée-ou-les-magasins de-bricolages-sont-ouverts-jusque-21h ... Et je rattaque. A 20h30, j'ai intégré le code de Chishm et DragonMinded, et je fais le premier essai "temps réel" d'écriture de fichiers sur ma petite carte SD.

Et ça marche, les gars! Sortez les cotillons, c'est la journée du code qui fonctionne (après une semaine de combat avec les codes à redondance cycliques de ma carte-réseau-qui-tue qui s'est enfin mise à fonctionner le matin)!

Donc voilà, y'aura encore un peu de boulot pour qu'on puisse choisir n'importe qu'elle image et sauver dans plusieurs fichiers, mais le départ est là ^_^

Wednesday, August 23, 2006

Premier Bilou sur la DS

CA y est, les gars. Le matériel de GameLand-Shop.fr est arrivé ... supercard, superpass et lecteur de cartes SD en USB, tout y est! Et bonne nouvelle, mon sprite editor marche presqu' impeccablement (évidemment, avec un design aussi minimaliste, je vois mal ce qui aurait pu foirer :P)

Hahaa! My homebrew dev'er hardware has arrived. Supercard, Superpass and SD card readers. I gave my Sprite Editor a real try and it works! Here it comes : the electronic millimetric sheet for drawing things ^_^. Only one sprite and no saving at this time :P
"Ah, si tu mets Bilou dessus, je veux bien regarder", me disait mon e-papou l'autre jour. Bin voilà, en arrivant chez eux, j'ai redessiné un p'tit bilou sur cette grille-là et je lui ai montré ... "Tu retournes aux sources, là", répond e-papou en voyant le même genre de grille que celui que j'ai utilisé il y a près de 10 ans pour tous mes petits jeux... Bin oui, c'était l'idée ... sauf que je ne suis plus obligé de démolir des claviers en faisant "flèche, espace, flèche, espace, flèche, espace" pour remplir un carré :)

"C'est encore plus un retour au source" que je lui dit, "c'est un peu comme si j'avais une feuille de papier millimétrée intelligente qui pourrait retenir tout ce qu'on dessine dessus ... enfin, sauf que j'ai pas encore programmé les sauvegardes, donc si je l'éteint, j'ai perdu mon Bilou".

Sunday, August 06, 2006

DS SPrite Editor 0.0

Ma fée est en camp pour 2 semaines ... Elle passe par surprise de temps à autres pour récupérer un chargeur ou des papiers oubliés, mais la maison est terriblement vide. Tellement vide que je me suis mis à la ranger, tiens ... pour passer le temps.

" Et maintenant, que vais-je faire ?
De tout ce temps,
Que sera ma vie ?"


Que je lui chantais pendant qu'elle préparait ses sacs. Elle a répondu que j'allais aller travailler, tiens. Pas de bol, c'est le week-end, d'où les rangements. Mais je ne suis pas maso non plus. J'en profite pour bricoler ce petit éditeur de sprites pour la nintendo DS ... Evidemment, pour l'instant c'est pas brilliantissime, mais ça reste (à mon avis) une bonne manière de prendre le hardware en main ... un exemple ? tous les pavés de couleurs pour la grille sont des caractères reprogrammés (256 en tout). On ne sait pas faire ça sur un PC, généralement, mais ici, c'est simple comme bonjour, et ça veut dire qu'il suffit d'écrire la nouvelle couleur au bon endroit pour que toute la case se remplisse ;) Un peu comme si on faisait un logimage avec un crayon qui remplit toute la case d'un coup (à quoi les adeptes du logimage vont me répondre que c'est gâcher le plaisir de crayonner les cases, évidemment :P )

Et je dois dire que l'affichage sur plusieurs calques, c'est vraiment le panar. C'est mon premier sprite editor avec un décor qui n'est pas "uni" ^_^ ... Là, j'avais commencé à y dessiner un bilou, mais je suis partit trop haut et je n'ai pas encore les commandes pour déplacer, inverser, etc.