lundi, octobre 22, 2007

tiles extraction ...

Un autre petit outil en Perl (basé sur la bibliothèque de manipulation d'images Imlib) qui décortique une image et identifie les tiles uniques (8x8) et le nombre de couleurs utilisées...
Il ne fallait pas grand chose pour en faire un convertisseur .gif->.spr un peu plus automatisé. Je m'y suis attelé ^_^. L'outil en question s'appelle "imlib2spr.pl" et est disponible dans le CVS du projet 'runme'.

I've been working on a new small (PERL) tool for SEDS/runme. "imlib2spr.pl" is using the "imlib" package to open your .gif, .png ... pictures and identify uniques tiles and colors so that it can then convert them into .spr files.
It also builds a map of how to reuse those tiles to get the initial image back.

Mais pourquoi chercher à transformer une image .gif en un tas de tuiles, me demanderez-vous. Okay, certaines images contiennent des zones un peu répétitives et pourront donc prendre moins de place en VRAM... et c'est tout ?

Ooh non! Notre DS est effectivement capable d'afficher directement des images 'bitmap' (c'est ce que je fais quand vous envoyez à runme un fichier .pcx), mais avec une taille maximale de 256x256 ou de 512x512, selon la configuration d'écran choisie. Impeccable tant que vous voulez une image fixe, mais imaginons que je veux faire scroller horizontalement une image de 320 pixels de large, je fais quoi ?

Je passe à 512x512 ? le bitmap fera alors 256K, presque la totalité de la mémoire vidéo!
Je tronque à 256x256 et je redessine une colonne chaque fois que je me décale d'un pixel ? Bonjour le code!

Maybe you wonder why i'm trying so hard to split a picture into small tiles while i've shown with runme that it was fully possible to display a .pcx (and thus .gif and .bmp aswell) image straight on the screen. Well, the reason is scrolling. You very well can show a 256x256 image on the DS screen (which is 256x192) and side-scroll it again and again (using the 'scrolling wrap' hardware option). That will take you 64K worth of VRAM. Now if you want instead to side-scroll a 320x200 image, you'll get into trouble unless you're agree to devote 512K of VRAM just for your background image.

On the other side, once you have 'tiled' your background, you can easily repeat it as many times as you want: it's merely a matter of a few KB, and you can easily rewrite offscreen parts of the map as the scrolling goes so that you keep showing the right stuff at the right time, with a 64:1 reduction of the stress on VRAM.
Since we are running on gaming hardware, i think we should make the best possible use of it, shouldn't we?

Well, demo and code for that will follow once the 7.11.7 day is over.

Sous GBA, pas tout ces soucis: l'écran faisait 240 pixels de large et le mode bitmap 256x256 aussi, donc on avait tout loisir de redessiner des blocs dans la partie complètement masquée de l'écran, puis de scroller un peu, puis de redessiner, etc.

Eh bien, si l'on prend la peine de convertir notre bitmap en "tiles", on peut continuer ce petit jeu: une fois les tiles en mémoire, une "carte" peut très bien contenir deux fois l'image initiale sans nécessiter d'avantage de mémoire vidéo (allez, quand-même 1 ou 2K de plus, mais c'est quand même mieux que de passer de 64 à 256K, non?)

Bref, c'est Cyril qui sera content. Lui qui me proposait y'a pas 48 heures d'ajouter un mode "construisons notre map" dans SEDS ... On en est plus très loin ;)



à la base, c'était ça:

#!/usr/bin/perl
use Image::Imlib2;

$image = Image::Imlib2->load($ARGV[0]);
print STDERR "$ARGV[0]: ".$image->width."x".$image->height."\n";
while ($ty<$image->height) {
$tx=0;
while ($tx<$image->width) {
foreach $y (0..7) {
foreach $x(0..7) {
($r,$g,$b,$a) = $image->query_pixel($tx+$x,$ty+$y);
$r=pack("C1",$r);
$g=pack("C1",$g);
$b=pack("C1",$b);
$colors{"$r$g$b"}=$ncolors++ if !exists $colors{"$r$g$b"};
$tile.=$colors{"$r$g$b"};
}
}
$tiles{$tile}.="($tx,$ty)";
$tx+=8;
$tile="";
$ntiles++;
}
$ty+=8;
print STDERR ".";
}

print scalar(keys(%tiles)) . "unique tiles (/$ntiles) detected\n";
print scalar(keys(%colors)) . "unique colors detected\n";

exit 0;

note: il nous faudra installer le package libimage-imlib2-perl pour faire fonctionner le tout.


rem: pendant ce temps-là, Globoeil nous faisait une release de son "virtual game maker DS" ...
à découvrir sur globoeil.fr/vgdms ...

Aucun commentaire: