Friday, December 28, 2007
Phantom Hourglass
Persos en 3D et contrôle au stylet, je dois dire que je n'étais qu'à moitié convaincu que ça allait me plaire (je n'ai jamais été un grand fan des jeux 3D et le côté "low polygons" de "Ocarina of Time" et "Majora's Mask" était très décevant à mon sens).
La première bonne nouvelle, c'est que dans les phases de jeu, la 3D passe plutôt bien (grâce à la vue d'en haut qui conserve le gameplay d'un zelda classique, notamment). Du point de vue des personnages, par contre, je trouve qu'on a perdu de la "magie" par rapport à "Minish Cap" sur GBA. Ils ont un peu tous l'air de porter des masques en toile de jute peinturées à la place du visage, rebondissent en parlant d'une manière assez peu naturelle. Bref, on est loin des minish mimi-tout-plein en pixel art du volet précédent. snif.
Le stylet, par contre, est redoutable, même si j'ai tendance à vouloir utiliser la croix pour déplacer link à certains moments (dans les combats, notamment, c'est difficile d'esquiver un grand nombre d'ennemis). On quitte le mode 'contrôle absolu' des jeux précédents pour quelque-chose qui ressemble d'avantage à un "command&conquer". Si certains mouvements (roulade, épée tournoyante) sont plus difficiles à exécuter que dans les bons-vieux-zelda-en-pixels (je l'ai dit), le boomerang dont on peut tracer la trajectoire compense largement. C'est d'ailleurs une de mes techniques de combat préférée: assomer la plus grande partie des grogneurs à coup de boomerang pour aller me concentrer sur un monstre pendant que les autres comptent les ptits zoizos.
Reste le très controversé "temple du roi des mers", ou "temple du sablier fantôme" ou "temple maudit". Appelez-le comme vous voudrez. Avec ces gardiens-spectres indestructibles, il introduit une dimension "infiltration" assez nouvelle dans le genre. Je le trouve stressant. Très stressant. Mais avec une bonne mémoire et des notes correctes prises sur la carte, on ne s'en sort finalement pas si mal. Oui, on doit le revisiter plusieurs fois, mais à chaque visite, on dispose de nouveaux "outils" (bombes, pelle) qui permettent au joueur attentif de prendre de fameux raccourcis et de grapiller des secondes supplémentaires dans les jarres dorées. Ajoutez à celà des minutes gratuites retrouvées au fond des mers, et je suis arrivé au "blason du soleil" avec 8'42" restantes (contre moins de 2 minutes de temps restant la dernière fois que j'ai du le faire.
Bon, évidemment, ce serait trop beau si ça avait été un rien utile. Bin non. Je me suis précipité jusque là pour rien. La "clé solaire", c'est pour un autre temple, ailleurs ...
Les dongeons sont chouettes (enfin, corsés, quoi, mais on s'en sort sans la soluce à l'exception de deux ou trois énigmes dont les indices sont donnés de manière foireuse). Les boss bien dosés (quoi qu'aucun d'eux ne m'aient encore tué :P) ... Je suis déjà au navire fantôme en seulement 3 jours ... C'est grave, docteur ?
edit: ma fée vient ingénument de tirer la cartouche du jeu que j'avais laissé en veille avant d'essayer de ramener la quatrième soeur au début du bateau fantôme pour faire ses exercices d'entrainement cérébral. Comme vous pouvez le voir, elle ne recule vraiment devant aucun sacrifice pour rallonger la durée de vie de son cadeau ^^"
edit+: c'est bien, le stylet, mais dans les combats contre les boss, ça a un inconvénient majeur: ça glisse des doigts. Croyez-le si vous le voulez, mais je me suis retrouvé crétin comme un lapin pendant le combat contre le crabe invisible qu'il faut viser entre les yeux à avoir mon stylet qui me "zippe" entre les doigts! Ledit crabe en profite naturellement pour me choper et le jeu dit "frotte l'écran pour te libérer". Ah ouaiche.
Je m'en suis sorti quand-même, mais de justesse. 'Suis pas sûr d'être 100% prêt pour Twilight Princess sur la Wii, moi ^^"
edit++: oh, j'aurais peut-être dû préciser que mon Zelda préféré (toutes catégories) était "Link's Awakening" sur le tout vieux GameBoy. Vous comprendrez sans doute mieux ma difficulté à accrocher à OT et MM, du coup :P
edit+++: vous êtes coincés mais vous n'avez pas envie de consulter la soluce du jeu ? repassez faire un bonjour à la voyante de l'île du feu. C'est gratuit et elle aura peut-être même un petit cadeau pour vous ;)
Friday, December 21, 2007
spr2html ^_^
Et comme j'ai un peu la flemme d'écrire des pixels sur une image .png, je me suis plutôt tourner sur une jolie petite table HTML. Avouez que le résultat est plutôt réussi, non ? bon, évidemment pour l'instant on ne voit encore que les "tiles" un par un, tels qu'ils sont dans la mémoire vidéo, mais encore un peu de chipotage, et je pourrai les voir par "bloc" de 16x16 ...
De quoi simplifier les procédures de conversion de données que je vais devoir faire... Parce que là, sans un éditeur de map, je n'irai pas beaucoup plus loin. Animer les pommes qui n'utilisent pas des tiles consécutives. bof.
So far, the tiles you edited with SEDS could only be opened with SEDS (or shown on your DS screen through the 'runme' companion program). That was true until yesterday. Here comes the "spr2html" converter tool that can turn those "opaque" .spr files into a bunch of HTML tables that show palettes and tilesets contained in the spriteset. So far, it is mostly a debugging tool for the other manipulation scripts (merging sprite sheets, converting colors, etc) that prooved to be more efficient than beaming files to the DS and back, but it should be quite trivial to upgrade into a full-featured "exporter" that would produce .png pictures straight out of my .spr files...
edit: et je me rends compte de la raison des palettes "toutes mélangées" que j'ai obtenues dans mes "livres de sprites" qui rassemblent plusieurs planches séparées: je comptais les couleurs 1,10,11,...,19,2,20,21, ... 29,3 ... à chaque étape, alors forcément, quand on répête ça, on finit par un jeu de couleurs tellement mélangé qu'on est prêt pour une petite belote :P
oh, for those who wonders, i've used the "bgcolor" attribute of "td" tags and and solely filled my table cells with
Wednesday, December 19, 2007
Plagiat ?
Du coup, les illustrations sont encore un peu plus "worm-inspirées". Mais j'ai un affreux doute. Mon ver jaune pixelisé est il assez "original", ou donne-t-il l'impression d'un repompage honteux du jeu de Team 17 ? C'est un peu le défaut des blogs, à mon avis. Je lis régulièrement les messages de bodman et j'imagine qu'il lit mon blog aussi, mais je n'ai aucun moyen de l'inviter à une petite discussion sur ce qu'il pense réellement de mon ver, au-delà de ce qu'il a déjà dit. Personne ne laisse d'adresse mail nulle-part vu qu'on a tous peur de recevoir (encore plus) de spam ... Bin moi, mon e-mail c'est pype_1999.geo@yahoo.com. Et je ne vois pas comment je pourrais avoir encore plus de spam là que je n'en reçois déjà. Donc, si bodman ou un autre veut prendre contact pour une petite discussion sur ICQ (#98176626) ou msn (je vous enverrai mon adresse par retour de hibou), you're welcome ;)
edit: après une (chouette) petite discussion sur ICQ, j'ai fini par apprendre que bodman avait visiblement fort idéalisé les petits vers de la première version de Worms, qui sont beaucoup plus proche des lemmings, et avec des yeux biens plus proéminents. Non, à la réflection, je pense avoir réussi un bon croisement entre le Worms Armageddon et le "Poison Slug" de Commander Keen. Un double clin d'oeil, donc.
oh, et la démo du Worms original de 1995 est un peu lente dans dosbox, mais tout à fait jouable ^_^
Monday, December 17, 2007
Des pentes et des testpoints ...
Bref. L'idée globale des testpoints, c'est s'assurer que le testpoint situé sous le personnage soit toujours à la frontière entre le "ciel" et le "sol". Ultra-simple sur des horizontales, un peu plus subtil sur une pente (mais grosso-modo il suffit d'ajuster le déplacement vertical en fonction du déplacement horizontal). Le hic, c'est de passer d'une surface horizontale à une pente. LE hic, c'est que la pente commence devant notre personnage alors que le point-test que l'on doit garder sur cette pente est sous le personnage (ici, yelloworm). En clair, notre worm va soit s'arrêter avant la pente (s'il la considère comme un mur), soit rentrer dans le premier tile puis s'arrêter au premier bloc de "mur" complet.
Dans M.C. Kids (et selon les dires de l'auteur, dans SMB3 également), ils résolvent le problème en introduisant un nouveau type de tiles: le "bas de colline", qui est placé dans le sol, dans le prolongement de la pente à amorcer. Ca marche, bien sûr, mais personnellement, je trouve ça un peu "bricolage". Un autre point qu'ils mettent en avant, c'est l'importance de garder un nombre de "test de map" fixe et le plus réduit possible -- de préférence un tile par testpoint.
Mais nous avons de toutes façon un testpoint devant notre personnage: celui qui sert à déterminer si oui ou non on arrive dans un mur. Et il est important de s'assurer qu'il soit suffisamment bas pour qu'il stoppe Bilou (et le yelloworm) même si le mur est très bas.
Du coup, on peut en profiter pour détecter le début d'une pente quand on arrive un tile avant. Il nous reste alors à ajuster la vitesse verticale de manière à ce que, un tile plus loin, on soit monté d'un pixel. On sera alors effectivement "sur" la pente. Bingo.
Il faudra évidemment s'arranger pour que l'angle entre les deux testpoints soit suffisant par rapport à l'angle de la pente la plus forte dans le jeu, mais ça, ça ne devrait pas nous poser de problème particulier.
Voilà. C'était ma cogitation du dimanche un peu en retard ... j'espère que c'était suivable ^_^
Tile Racer
Comme dans S4DD, vous pourrez construire vos propres circuits de dingues (mêlant tonneaux, loopings, rampes, tremplins, etc) à l'aide d'un éditeur basé sur le modêle des "tiles" (mosaïques, en gros) avant d'y faire une petite course contre la montre.
Patience: l'adversaire IA est en cours :P
Saturday, December 15, 2007
demi-tour, marche!
Il faudra aussi que j'automatise le demi-tour (pour l'instant, le ver s'arrête au bord, et je lui fais faire demi-tour "à la main" en programmant la deuxième animation.
edit: yes! le petit ver est maintenant entièrement autonome et toujours avec un code 100% générique. Une petite machine d'état avec des animations de "pause" entre les allées et venues, et ça y est. Et je peux en mettre autant que je veux! il suffit de rajouter une ligne dans test.cmd ;) Etapes suivantes:animer les pommesdésactiver/réactiver les OAM quand ils sortent de l'écranpasser *réellement* à deux plans pour l'affichage du décor- scrolling parallaxe
- (post-posé: animation composite pour Bilou).
Friday, December 14, 2007
iWorld has non-virtual desctructor
Oh, il y a eu d'autres chipotages, bien sûr. Les sprites et quelques autres éléments sont enregistrés directement auprès du GuiEngine, pour les animations notamment, et il est assez malvenu de supprimer l'un deux sans l'avoir "désenregistré" sous peine de voir le moteur du jeu essayer d'animer les morts (sic).
Oui, je sais, c'est assez macabre. Mais que voulez-vous: la Faucheuse (traduisez: le Garbage Collector) n'est pas de mise en C++ et quand un objet meurt, il est pour ainsi dire obliger de s'enterrer lui-même.
faire et défaire ...
autre bonne nouvelle: les animations marchent! enfin, quand je dis "marchent", je devrais plutôt dire "rampent", puisque pour l'instant, seul le "petit ver jaune" de la forêt a été animé.
Je suis pas mal fier de mon coup, je dois dire. J'ai gardé un code tout à fait générique, qui est paramétrisé par un petit script de commandes. Petite astuce, les déplacements du ver sont intégrés dans la séquence d'animation elle-même, ce qui permet d'avoir un contrôle plus fin du déplacement (pour vraiment donner l'impression que le ver rampe, et pas qu'il glisse sur le sol pendant qu'il se tortille, comme on le voit si souvent dans les jeux amateurs).
En revanche, si je commence à être assez rôdé sur les std::vector<GameObject*>::iterator, je suis encore un peu perplexe sur les destructeurs virtuels. L'environnement d'exécution du "petit script" en question doit être "renettoyé" chaque fois que l'on veut relancer le script, et pour l'instant, ça se traduit encore trop souvent par un écran rouge de la mort. J'aime bien la méditation, mais toutes les 5 minutes, ça devient lassant. (quicklink: l'assembleur ARM par TONC: http://www.coranac.com/tonc/text/asm.htm)
D'un autre côté, j'ai un peu relooké mon script qui traduit une image (comme celle ci-dessus) en un tas de tiles et les données pour la map, de sorte qu'on puisse lui indiquer quelle couleur doit être considérée comme "transparente", et il s'arrange tout seul pour que les tiles entièrement de cette couleur soient considérés par la toute nouvelle routine de "testpoints" comme étant "EMPTY", tout le reste étant de type "BLOCK"...
edit-PS: la première version du level editor (sans sauvegarde) n'arrivera qu'en avril de l'année à venir. Là, on est donc toujours dans une "composition" de niveaux à coup de Gimp suivi d'une conversion avec détection des tiles redondants par un script fait-maison.
Tuesday, December 11, 2007
Et les sprites ?
Rien de bien méchant à arranger, mais ça demande quand-même un peu de (ré)organisation du code, ce qui me prend systématiquement une plombe. Enfin, dans l'immédiat, ça ne marche pas trop mal, excepté un petit "glitch" désagréable (le fond est déplacé trop tôt par rapport aux sprites, ce qui leur donne de s'enfoncer dans le sol quand on scrolle vers le haut, par exemple).
Ce midi, j'attaque les animations !
Tuesday, December 04, 2007
Yes! Ca scrolle!
C'a été un drôle de combat, reprennant les bonnes vieilles habitudes du cours Algo I (invariants, etc) pour parvenir à faire scroller le niveau de Sonic sur ma DS. Faire un scrolling vertical, c'est simple. Le scrolling horizontal m'a déjà donné plus de fil à retordre, mais pour s'assurer qu'ils n'essaient pas de s'assassiner dans les coins, j'aime autant vous dire que ça ne va pas sans mal.
J'ai laissé tomber les transfers DMA pour la plus grande partie du code. L'idée maîtresse ici était une "fenêtre de validité" qui indique quelle portion de la map est effectivement présente dans la mémoire vidéo, et à partir de quelle position. L'ennui, c'est que pendant tout un temps, le scrolling "vertical" modifiait des zones que le scrolling horizontal tenait pour acquises. Bref, on se retrouvait avec de gros blocs de terre au milieu du ciel, de l'eau dans le sol, des hybrides guèpes-singes, etc.
mais ça y est. Ca marche. Pour les curieux, le code est sur le CVS. Et au passage, j'en ai profité pour commencer un petit interpréteur de scripts pour ce genre de tests (histoire de pouvoir réutiliser un fichier .spr transféré préalablement). L'ennui, avec ce genre de méthode, c'est qu'il vous faudrait 5 minutes pour mettre en place le test à partir de runme.nds ... D'où la vidéo ;)
Pas de musique sur la vidéo, donc si vous voulez vous mettre dans l'ambiance, jetez une oreille à "Oil Ocean (WT-40 mix)" qui m'a accompagné lors de tous ces tests ^_^
edit 2024: Le CVS, c'est fini, et le travail sur le scrolling arrive d'un bloc dans le repository mercurial. Entre les deux, il y a eu un SVN où on voit le travail évoluer jusqu'à l'étape ça marche (4 décembre).
Friday, November 30, 2007
dev-fr.org ... le paradis du homebrew
Bon, j'ai bien aimé "Bloops", adoré "Tetris Attack DS" et "Setsuzoku no Puzzle" ... Mia est passé sur PSP. J'ai bien ri avec Kaboom et versé une larme de nostalgie sur XRickDS et GianaSister DS ... Quoi d'autre. Quid quand les blogs restent quois ? Tournons nous vers les forums !
Après quelques semaines peu convaincantes sur playeradvance (trop noob) et gbadev (trop prise de tête), j'ai essayé dev-fr, et jusqu'ici, je suis séduit ^_^. C'est tout à fait le genre "gazette" que je cherchais. Si vous avez déjà acheté un magazine un peu "touche à tout" sur l'informatique (je pense par exemple au PC team, création graphique, musicale, jeux, OS alternatifs et programmation), vous aurez peut-être remarqué que j'ai tendance à animer ce blog un peu comme quelques rubriques dans ce style de journal.
Okay, i liked Bloops, loved Tetris Attack DS and Setsuzoku no Puzzle. I quite liked Mia's homebrew too, but he's now dev'ing on the PSP. Kaboom made me laugh and both XrickDS and GianaDS have wet my eyes with tears of nostalgia. Then what ? What when blogs are silent ? Let's check out the forums.
My experience on player advance (too n00b) and gbadev (people are just too complicated) didn't convince me until i found dev-fr.org. That's exactly the kind of homebrew gazette i was looking for (i once hoped Drunken Coders news would offer this, but it turn out they merely advertise new movies available on the moonbook project >_<).
Here's a small sample on what you can found there (okay, it's a french-speaking forum. Noone's perfect). An interesting event on that board is the Saturday's demo. A homebrew guru details with videos and code a common special effect or programming technique. It can be about particle systems or the use of horizontal blank interrupts to achieve wobbling and parallax scrolling. Very pleasant.
Petit tour d'horizon, donc, de ce que j'ai vu d'intéressant. Je laisserai à mon frère le soin de faire les tests et les scores ^_^
FAT Mod Player, par cid2mizard. Comme le nom l'indique, ça sert à écouter .mod ... Tous les mods que vous auriez mis sur votre carte flash.
Autre évènement sympaLa démo du samedi soir: scrolling list. Un principe assez original: illustrer des techniques de programmation (généralement sur la DS) avec le code à la clé. Des articles généralement très bien ficelés, et dignes de ce que l'on trouvait dans les magazine (même si les démos, elles, ne sont pas nécessairement très impressionnantes comparées à ce que l'on voyait sur la Scène Amiga il y a 10 ans d'ici. Le mot d'ordre, c'est BabySteps ...
Plop invaders ... un petit jeu bien sympa qui rappelle le principe de Chuzzle (mais pas tout à fait) avec un scénario digne des invasions blorks de Kid Paddle.
C'est mignon, ça fait cogiter les neurones et c'est bien ficelé, même si les graphismes dans les phases de jeu sont parfois un peu légers à mon goût (et les plops sont probablement un chouya trop petits).
Then come the Plops. Kind of blobs from unexpected nuclear experiment that you have to erradicate by exhausting their air. A chuzzle-like (though the gameplay differ) with a Kid Paddle-like scenario. Cute, mind-twisting and well tied together, despite some effort could be done to improve in-game gfx.
Par Mollusk , Pitt et Zeblackos. Une collection de mini-jeux un peu curieux, réalisés dans un langage dont personne ne voudrait, mais pour un résultat qui vous dévorera des heures de transport en commun.
Another blog-worthy stuff is Mental Games by Mollusk & friends. The kind of minigames pack that many suggest on the DS, but with a retro-look that gave me the urge to try it (compared to Puzzle Maniak which still leaves me cold). Ideal if you want 5-minutes fun in the bus. Check out my blogmarks if you want to keep up to date of my other findings.
Le tout, évidemment, uploadé sur ma DS Phat avec mon propre petit "runme", que j'ai boosté à 1Mbps, et ses scripts perl ... Parce que je le veux bien.
edit: je suis loin d'avoir fait le tour, bien sûr, et comme je ne suis pas mon frère, je ne vais pas essayer d'animer une rubrique "le jeu homebrew de la semaine". Mais si je repère un jeu qui a l'air de valoir le coup sur ces forums, je l'ajoute dans mes blogmarks.
Saturday, November 24, 2007
BG_WRAP_ON ?
class UnderProgress : public Animator {
unsigned offset;
public:
UnderProgress():Animator(1,"-cx-") {offset=0;}
virtual Animator::donecode play() {
if(!running) return Animator::DISMISS;
offset++;
BG2_X0=offset;
SUB_BG0_X0=-(offset>>1);
return Animator::QUEUE;
}
};
Difficile de trouver des informations précises sur le scrolling de la DS, en fait. Si bien que les infos trouvées sur GBAtek et autres wiki laissaient à penser que seul le mode 5 (avec des plans carrés capables de rotations et zooms) pouvait fonctionner avec le "scrolling infini". C'est effectivement le rôle de BG_WRAP_ON pour les plans dits "extended rotation", mais je vous assure pour l'avoir fait fonctionner pas plus tard qu'il y a 2 minutes que le mode 0 et ses plans "texte classique" supporte parfaitement le scrolling infini, et sur tous les background.
En fait, c'est le comportement par défaut de la console et notre bit "BG_WRAP_ON" n'est là que pour désactiver cette fonctionnalité (qui pourrait être gênante si on essayait de se servir des plans déformés pour faire de la 3D (cf. le "mode 7" de la SNES).
Je souffle un coup, donc: je pourrai sans soucis choisir la taille 512x256 qui m'est si chère pour l'instant (les mode 5 n'offrant que 128x128, 256x256, 512x512 et 1024x1024).
(PS: j'en profite pour signaler à ceux que l'anglais rebiffent que le premier des posts "tutoriel" sur le scrolling est (enfin) complètement traduit).
Thursday, November 22, 2007
Scrollons encore
Mais si la vitesse devient trop élevée, on risque de se retrouver à passer d'un 'bloc' à l'autre mais en gardant toujours plus d'un bloc de VRAM à l'écran, ce qui nous empèche de mettre l'image à jour sans prendre le risque d'un affichage inconsistant. Mais c'est là que Cyril est intervenu: rien n'empèche d'arrêter le scrolling plus tôt que prévu juste pour ce 1/60eme de seconde... On a alors de nouveau les mains libres pour copier le bloc suivant en VRAM, et au coup suivant, on scrollera un peu plus.
Problem: at speeds higher than 1px/frame, we might never have one of the squares fully off-screen because we switch from "still showing some pixels from the logical square on our left" to "already showing some pixels from the logical square on our right.
Proposal: snap the camera to the squares grid when a transition is detected. That snapping will affect the scrolling speed, but only for 16.6ms so it shouldn't be noticeable.
Result: that looks smooth, indeed. I cannot notice when the snapping happens.
Mais pour remettre tout un bloc à jour (2K), il serait franchement préférable de passer par le DMA.
Mais bonne nouvelle, on peut s'en sortir avec un encodage un peu plus subtil. Imaginez: on a besoin d'encoder si chaque tile est solide, traversable, incliné, etc. mais aussi s'il s'agit d'un bonus, de pics, de lave, etc. Trop pour 4 bits ... sauf si on encode que 12 types de tiles et que l'on se sert des numéros 12 à 15 pour des blocs plus "spéciaux", par exemple ceux dont seul le personnage du joueur doit s'occuper.
Idea: Let's have 12 "direct" properties for slopes, ground, air, etc. and have only other properties for 16x16 pixels blocks. That means we can combine the palette bits of 4 tiles to know what block (out of 256 possible special blocks) we use.
Alors, quel est le truc ? Eh bien voilà. Notre niveau n'est pas construit à partir de tiles 8x8 mais à partir de blocs 16x16. On peut donc supposer que la lave prendra bien 16x16, et ce n'est pas juste 2 bits (de 12 à 15) que l'on a pour faire la différence entre les picots, la lave ou les bonus, mais bien 4x2 bits (2 dans chaque tile faisant partir du bloc 16x16). Soit 256 types de blocs spéciaux possibles. De quoi voir venir...
Monday, November 19, 2007
Ideas for smooth scrolling on the DS...
Je rafinerai et traduirai plus tard ...
The hardware (from Liranura's 2D tutorial)
Map bases always have 32×32 entries. To create bigger BGs (Like 64×64) you need to use several map bases. As for tile bases - If you want to make use of the full tileset (1024 tiles), you will have to use several tile bases - 4 Tile bases for 256col full tileset, and 2 Tile bases for full tileset of 16col mode. Since the Map bases and the Tile bases are located on the same region in VRAM, they can overlap. Since a map base is 2Kbytes and a Tile base is 16Kbytes, each Tile base contains 8 Map bases.Une surface affichable sur la DS est constituée de 32x32 tiles (l'écran en fait 32x24) et occupe 2KB dans la mémoire vidéo. Pour construire des plans de décor plus larges (p.ex 64x64 tiles), il nous faudra plusieurs 'morceaux' de 32x32 mis côte à côte pour former une surface plus grande. On retrouve le même phénomène avec les tiles (pour utiliser l'entièreté d'un jeu de tiles (1024 tiles), il nous faut 4 sections de 16K en mode 256 couleurs). Notez que c'est au programmeur de choisir s'il va stocker 16K de tiles ou 8 maps dans une région donnée de la mémoire vidéo.
La console nous permet de positionner l'écran librement dans la surface définie (pour chaque plan séparément, hein, ) et -- contrairement aux carte VGA -- par défaut la surface 'boucle' sur elle-même (si la zone affichée déborde par la droite, c'est la gauche de la surface qui sera réutilisée).
We can have hybrid technique ...
At some point we have to alter parts of the map to keep scrolling smoothly. Nothing forces us, however, to have a unified technique that accomodates both horizontal and vertical moves. The fact that the screen isn't a square, that memory stores lines continuously and columns discontinuously and similar consideration -- not omitting the fact that our game may have a side-scrolling or vertical-scrolling action (shmups ;) -- may suggest that we have two distinct mechanisms for updating the map after a vertical and a horizontal movement of the "camera".
Le système de scrolling va forcément mélanger software et hardware. Le côté hardware, c'est le choix de la portion visible de la surface en VRAM (on l'appelle "onscreen surface" -- litéralement 'à l'écran' en anglais). Le côté software consistera à modifier des portions de cette surface (de préférence qui sont actuellement invisible pour le joueur) afin de donner l'illusion d'un décalage continu alors qu'en réalité, nous somme piégés dans un carré de 512x512 pixels.
Avant de ce lancer dans le code, il serait bon de se rappeler que rien ne nous oblige à avoir une technique unique pour les scrolling horizontaux et verticaux. Les uns pourrait parfaitement s'opérer à grands coups de DMA sur des tranches entières alors que les autres se feraient "bloc par bloc" gérés entièrement depuis le CPU.
- we can't have smooth scrolling in a 64x64 area if we reprogram 32x32 entries (dma copy) at once (<-- cyril contests this, see next post).
- we could do the "John Carmack" trick, using hardware scroll in the 64x64 area and then "jump" to a second 64x64 area when we're about to move out, but that would kind of be silly on hardware that allows to "wrap around" the area with our viewport (which the PC hardware couldn't do properly).
- doing "double-buffer" of the map will involve a burst of up to 8K memory transfer (through DMA), potentially leading to gameplay lags
- we have better things to do with the other maps (e.g. additional planes)
- DMA copy for the map might be interesting to save CPU (well, it is actually frozen during the move), but it requires that the offscreen map is a verbatim copy of what's used on screen. manual copy of the map parts instead allow us to use more bits for tiles meta-data and wipe them as the tiles are moved on screen. That would give us 64 types of block, more than we need to encode "slipperiness", identify bonus, etc.
Nothing forces us to use 64x64 ... since the height of the screen is smaller than 32 tiles, we can very well work with e.g. 64x32 instead. This is not only nice because it halves the amount of work without loss of functionnality (maybe a bit less effective "caching" of vertical scrolling), but also because it means we now can do the "carmack jump" thing effectively: Suppose we are working with maps 0 and 1 initially (side-by-side 32x32 areas of the level map) and that the viewport is getting close to the edge of the currently displayed area ... rush! we dump another 32x32 chunk of the level map (and now we can just ask for a DmaCopy of the whole data if it is properly stored offscreen) into map #2. When it then appears that we are about to scroll out of the current 32x32 area, we then cheat the video hardware, reprogramming the map base to be map#1 (instead of map #0) and the X scrolling register to show us in the new area (most likely x=x-256 or x=x+256 depending on the movement).
Autre petite constatation: rien ne nous oblige à utiliser du 512x512 pixels! en fait, ce serait même l'inverse (en cas de scrolling horizontal, ce mode nous oblige à faire plus de mises à jour et ne nous offre pas grand-chose en contrepartie). Au passage, ça nous permettrait de faire un "scrolling à la John Carmack" plus efficacement (enfin, au moins une fois de temps en temps...).
Mais entretemps, je suis nettement plus sceptique sur l'interêt de la technique Carmack (rendue célèbre par la série des Commander Keen) sur le hardware de la DS.
I'm not sure we could keep it smooth forever with that technique, unfortunately: there would be no way for us to tell the hardware that map #N-1 and map #0 should be shown as a continuous 64x32 area...
see also captain Apathy's tutorial
voir aussi le tutoriel de Edorul (GBA)
Sonic the Hedgehog 2 (Emerald Hill) from soniccenter.org
Friday, November 16, 2007
Un autre arbre pour Bilou
L'idée, c'est de faire vite et de mettre les éléments en place: ils seront retravaillés plus tard dans mon sprite editor, mais ce dernier n'est pas encore très pratique quand on veut rapidement entasser quelques gros ronds pour faire une forme de feuillage (à noter pour plus tard, en blanc sur bleu, ça aurait pu faire de beaux nuages) ou les formes étirées du tronc d'arbre.
J'en dirai plus plus tard, mais je crois que c'est un bon début...
Thursday, November 15, 2007
2D sur la DS : quelques chiffres ...
Pour un jeu de plateforme comme Bilou et Badman, le plus raisonable serait de partir sur 256K pour les décors, 128 à 256K pour les sprites (tout ça sur l'écran principal) et de garder les 128K restant pour gérer l'écran secondaire (map, inventaire ... peu importe). 256K de décors ... avec mes blocs qui font 16x16 pixel, ça veut dire que j'ai droit à un bon millier de blocs différents conservés simultanément en mémoire. Soit près de 5 écran de DS. C'est déjà honnête ...
Bien sûr, rien n'empèche de changer le contenu de la VRAM au fil du jeu. C'est notamment ce que j'ai l'intention de faire pour les blocs animés (pensez à la pièce d'or de SuperMario ou au bloc-question). On leur attribue quelques tiles sur lesquels on ira recopier systématiquement l'étape d'animation suivante au bon moment (depuis nos 4Mo de mémoire de travail, donc). Ainsi on gagne du temps et de la place. On pourrait aussi essayer d'éliminer certains blocs non-affichés pour les remplacer par d'autre en fonction de la progression du joueur dans le niveau, par exemple si l'on voulait faire un traveling continu sur les écrans d'Another World... mais il y a peu de chances que je me serve de quelque-chose de ce genre.
Dans un niveau ou le scrolling est libre dans toutes les directions, on choisira de préférence une map 512x512, de manière à pouvoir toujours modifier les "bords" de la map pour avancer dans le niveau sans que le joueur ne remarque quoi que ce soit. Il y a aussi des map 512x256 et 256x256 que l'on utilisera dans des jeux ou le scrolling suit un seul axe (les shoot'm'up, par exemple, ou des niveaux spéciaux dans un jeu de plate-forme).
Evidemment, on pourrait se dire que c'est du gâchis de prendre une carte de 512x512 alors que 256+16 aurait suffi à un scrolling fluide (réfléchissez un peu: pourquoi le GBA a-t-il un écran de 240 pixels de large, selon vous?). Mais ce serait compter sans le fait que la "carte" des tiles peut aussi nous servir directement pour savoir si notre personnage (et tous ses adversaires) ont affaire à un mur ou à un trou. Chaque "tile" est encodé sur 16 bit dans la carte (cf cet autre post précédent) et on peut choisir parmis 1024 "tiles" différents, les autres bits permettant de "retourner" les blocs horizontalement et verticalement.
single tile encoding, from LiraNuna's tutorial
Restent 4 bits inutilisés qui pourraient se révéler bien pratiques pour encoder directement le type de bloc: creux, plein, "montée" à 45°, "descente" à 45°, "montée" à 22.5% ...
Dans Rayman Designer, il y a 24 types de blocs différents, y compris le bloc semi-solide (on peut passer à travers en sautant, mais pas en tombant), les blocs glissants (de nouveau 7 inclinaisons différentes), des blocs qui blessent, qui tuent, qui noient, qui font rebondir, escaladable, etc.
<obsolete why= "si les bits "palette" sont actuellement effectivement utilisés, c'est en les combinant par blocs de 4 tiles que l'on étendra le nombre de propriétés disponibles.">
Bien sûr, avec 4 bits de libre, c'est un peu juste pour proposer les 24 types de Rayman, et pourtant, dans Bilou, il nous faudra bien tout ça. Mais dans notre cas, il y a peu de chance que l'on se serve du "retournement" de tiles. Le plus souvent, ça fouterait en l'air tous nos efforts d'éclairage sur les blocs. Résultat, on pourrait s'arranger, par exemple, pour stocker certains blocs "à l'envers" et pour pouvoir se servir du bit "miroir horizontal" pour faire la différence entre les montées et les descentes ... L'alternative, ce serait d'avoir une des combinaisons pour indiquer que le bloc est "spécial", et de se servir à ce moment de son numéro pour choisir le comportement approprié, sachant que ce sera un peu plus compliqué à traiter... L'idéal, ce serait de garder ça pour les interactions que seul le personnage fera (grimper, se blesser, etc.) et d'avoir les effets sensibles égalements pour les monstres directement encodés sur la map...
</obsolete>
Enfin. 'faudra tester tout ça. J'espère que ça ne vous a pas paru trop imbuvable: j'avais besoin de mettre les idées au clair avant de me lancer dans le code de gestion des niveaux ...
Wednesday, November 14, 2007
LBM & Linux
Sous ubuntu, pourtant, le package
Reste que imagemagick persiste dans l'idée que mes fichiers Deluxe Paint devraient s'appeler ".ilbm" et pas ".lbm". Comme c'est pénible et que je suis geek, j'édite le fichier /usr/lib/ImageMagick-6.2.4/config/delegates.xml et là ou on voyait une ligne "decode 'ilbm', je passe à
<delegate decode="lbm" command='"ilbmtoppm" "%i" > "%o"' />
<delegate decode="ilbm" command='"ilbmtoppm" "%i" > "%o"' />
Bref, voilà comment mon frère a maintenant mes petits sprites de Kid Paddle pour les envoyer sur le forum de Midam ^_^
(packages à installer: libimlib2, imagemagick et netpbm/libnetpbm10)
Monday, November 12, 2007
Java pas m'énerver ...
J'y vais donc de mon petit test débile:
import java.lang.*;
import java.util.*;
import javax.xml.xpath.*;
import org.xml.sax.InputSource;
public class XpathTest {
public static void main(String[] args) {
try {
System.err.println("creating xpath...");
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = args[0];
InputSource src =
new InputSource(new java.io.FileInputStream(new java.io.File(args[1])));
System.err.println("search for "+args[0]);
String content = xpath.evaluate(expression, src);
System.out.println("here: "+content);
xpath.reset();
src = new InputSource(new java.io.FileInputStream(new java.io.File(args[1])));
Object node = xpath.evaluate(expression, src, XPathConstants.NODESET);
System.out.println("here: ("+node+")");
} catch (javax.xml.xpath.XPathExpressionException ex) {
System.err.println("oops: "+ex);
} catch (java.io.FileNotFoundException ex) {
System.err.println("no file : "+ex);
} catch (java.io.IOException ex) {
System.err.println("doh: "+ex);
}
}
}
Tout ça à l'aide de la première référence que je trouve: la doc de sun bien claire, sauf sur un point "c'est quoi cette 'nodelist' que je suis supposé recevoir mais qui m'est transmise sous la simple forme d'un 'Object' ?". Au bout de quelques minutes de tests, je me rends compte que la seule chose qui marche, c'est le chemin "/" qui reprend tout le texte du document. le reste ("/feed/entry[1]/title" ou "//author", ce genre de choses chouettes et utiles), ne donne aucun résultat. Pas une exception ou un message d'erreur. non. rien, tout simplement. que le chemin corresponde à un noeud existant dans le document ou pas, d'ailleurs.
grmbl.
Puis à force d'essayer, je finis par constater que le fameux objet que je récupère est de la classe com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList.
Et là, je dis: ça pue. pourquoi m'ont-ils renvoyé un objet interne non-documenté et (de plus) qu'est-ce que c'est que ce "sun...apache..." ou bien c'est dans le standard, ou bien ça n'y est pas, non ?
allons bon ...
Xerces does not provide an XPath implementation (it implements only support for the limited expressions allowed by XML Schema constraints). Xalan provides an XPath 1.0 implementation and from the com.sun.org.apache... package name it seems there is the Sun (derived from Xalan) implementation that is included with the JVM.ref
Tout de suite, ça m'étonne moins. Reprenons calmement avec la doc d'apache, donc.
- on installe le package "xalan", un traducteur XSLT qui est sensé fournir XPath pour de vrai
- on redéfini sa variable d'environnement CLASSPATH pour pointer sur /usr/share/java/xalan2.jar
- on google sur "org.apache.xpath example" et pas "xpath java example"
Bref, le code le plus simple auquel j'arrive ressemble à ceci:
mais pour ça, il me faut écrire une horrible fonction capable de passer d'un nom de fichier à un Document, parce que visiblement, les gens qui ont écrit XPathAPI n'ont pas pensé à rendre ce cas-là simple :(import org.apache.xpath.*; // for XPathAPI, obviously!
import org.apache.xpath.objects.*; // for items, nodelists, etc. (XObject)
import org.w3c.dom.*; // for Document and friends
import java.lang.*; // for String and the like.
/** see also:
http://xml.apache.org/xalan-j/apidocs/javax/xml/parsers/DocumentBuilder.html
*/
class xpath2 {
public static void main(String args[]) {
Document doc=FileToDoc(args[0]);
String xpath = args[1];
System.out.println("\nQuerying DOM using xpath string:" + xpath);
try {
XObject o = XPathAPI.eval(doc, xpath);
System.out.println(o.getTypeString()+"> "+o);
} catch (Exception e) {
System.err.println("doh:" +e);
}
}
}
Notez que si vous avez déjà un InputStream prêt sur le contenu (p.ex. une connexion réseau), inutile de passer par un fichier:static Document FileToDoc(String fname) {
/* well, Document is an interface and cannot be built simply */
/* -- grmbl -- */
try {
javax.xml.parsers.DocumentBuilderFactory docBuilderFactory =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder docBuilder =
docBuilderFactory.newDocumentBuilder();
// Parse the XML file and build the Document object in RAM
return docBuilder.parse(new java.io.File(fname));
} catch (Exception e) {
System.err.println("parse error: "+e);
return null;
}
}
docBuilder.parse(InputStream)
existe également. Il y a même docBuilder.parse(URL)
pour ceux qui ne sont pas occupés à faire un exercice sur l'écriture d'un client HTTP :P(soupir)
Et pour être sûr, ils ont *aussi* rendu la réécriture de documents XML vers un fichier tordue:
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
Pour la postérité, la javadoc de l'API XPath sur le projet Apache.
Jouons avec netcat ...
Alors, bin souvenez-vous du post sur netcat, cet outil unix capable d'ouvrir et de manipuler des sockets en ligne de commande (je simplifie, mais bion). Avec quelques connaissances de HTTP 1.1 on va pouvoir s'amuser un peu. Tout d'abord, il nous faut l'URI d'un flux RSS, en l'occurence, le mien: http://sylvainhb.blogspot.com/feeds/posts/default
Nous avons déjà l'outil wget qui nous permet de récupérer une ressource sans passer par un navigateur, mais netcat va nous permettre de bidouiller un peu notre requête HTTP et de récupérer "en live" la réponse du serveur.
Voyons donc. La manière la plus simple pour récupérer la page avec notre flux RSS en HTTP correspond à
GET http://sylvainhb.blogspot.com/feeds/posts/default HTTP/1.1
Host: sylvainhb.blogspot.com
Auquel le serveur répondra quelque-chose comme
HTTP/1.1 200 OK...
Content-Type: application/atom+xml; charset=UTF-8
Last-Modified: Mon, 12 Nov 2007 11:00:00 GMT
Cache-Control: max-age=0 private
ETag: "8ec946e4-7f26-4280-8dad-30c1e7f20e51"
Transfer-Encoding: chunked
Date: Mon, 12 Nov 2007 11:15:53 GMT
Server: GFE/1.3
Connection: Close
c04
<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'>
<id>tag:blogger.com,1999:blog-34057821</id>
<updated>2007-11-12T12:07:24.724+01:00</updated>
<title type='text'>Bilou HomeBrew's Blog</title>
La réponse est divisée en deux parties: des en-têtes, qui nous indiquent ce que l'on va recevoir, de quand celà date et comment gérer la suite du transfer et le contenu qui nous intéresse (le flux RSS proprement dit). Ceux qui ont fait un peu de programmation WEB auront tout de suite reconnu le "look HTML" de notre contenu. Il s'agit en fait d'un document XML, qui adopte les conventions d'HTML pour présenter n'importe quel type d'information (ici, un "flux" (
Grâce à la balise
Vous avez remarqué la ligne "Last-Modified" dans les en-tête de la réponse ? Il s'agit de la dernière date de mise à jour (enfin, ce qu'en pense le serveur). Et nous pouvons demander au serveur de ne nous retransmettre le document que s'il a changé depuis cette date avec une petite variante de notre requête:
GET http://sylvainhb.blogspot.com/feeds/posts/default HTTP/1.1
Host: sylvainhb.blogspot.com
If-Modified-Since: Mon, 12 Nov 2007 11:00:00 GMT
Le serveur ne répondra maintenant par un "200 OK" que si la page a changé. Dans le cas contraire, on aura droit à un petit "304", sans contenu. Nettement plus léger, non ^_^ et plus simple que d'extraire à nouveau la balise <updated> pour comparer avec la précédente. Et tout ça avec une seule ligne de commande (à mon avis, bien plus sympa pour les tests que de lancer un "telnet" et d'essayer de taper toute sa requète avant que le serveur WEB n'estime que vous êtes trop lent):
echo "GET http://sylvainhb.blogspot.com/feeds/posts/default HTTP/1.1\nHost: sylvainhb.blogspot.com\nIf-Modified-Since: Mon, 12 Nov 2007 09:51:53 GMT\nConnection: close\n\n" | nc sylvainhb.blogspot.com 80
Petit raffinement: sous Unix, on dispose aussi d'un outil "watch" qui appelle la même commande, encore et encore. On pourra donc se faire un "surveilleur de blog ultra-geek" avec
watch 'echo "GET http://sylvainhb.blogspot.com/feeds/posts/default HTTP/1.1\nHost: sylvainhb.blogspot.com\nIf-Modified-Since: Mon, 12 Nov 2007 09:51:53 GMT\nConnection: close\n\n" | nc sylvainhb.blogspot.com 80'
Bon, okay, la date de référence pour laquelle on teste les mises à jour est toujours la même ici, ce qui rend l'exercice assez inutile. C'est que le début, d'accord, d'accord ?
(edit: amusant: non seulement cette méthode m'indique quand il y a un nouveau post, mais aussi si un post a été remanié ou s'il y a un commentaire en attente de modération ;)
Thursday, November 08, 2007
Encore Titus
the Blues Brothers, c'est le jeu où Titus Interactive prépare les ingrédients de ses futurs jeux. Des munitions (caisses à lancer sur les ennemis), pas encore tant de passages secrets, mais une série de "salles secrètes", comme les cavernes de Prehistorik (premier du nom) qu'il faudra explorer pour rassembler les objets nécessaires au concert de Jack et Elwood, mais qui peuvent aussi bien contenir des "bêtes" bonus ou un loubard.
The whole is spiced up with some exploration, as you will need to find a special item in each level to get the "good ending" of the game. By then, I found that mix much more interesting than the usual straightforward, infinite amno, gun-oriented platformer.
Autre détail qui a son importance, si vous êtes touchés alors que vous transportez une caisse, vous la perdez, ce qui veut dire que plus loin dans le jeu, vous serez désarmé face à un autre danger. Bref, le moindre faux-pas est lourd en conséquence. Autre exemple, les designers se sont amusés à s'assurer qu'à deux ou trois endroits, vous risquiez de retomber plus en arrière dans le jeu (de préférence là où vous n'aviez pas la possibilité d'éliminer tous les ennemis).
- niveau 1 : le magasin (guitare dans une des échoppes). On affronte des loubards, des mémés en caddie, des policiers, des serveuses furieuses et des jardiniers toqués. Une fois dans les nuage, c'est le piaf pond-vite qui nous mêne la vie dure
- niveau 2: en construction (lunettes et chapeau que je ne parviens pas à atteindre. Peut-être faut-il un parapluie ...) Sale gosses armés de pulvérisateur d'acide et gros bras maniaques de la clé à molettes, mais gare aux mares d'acides et aux broyeurs.
Autre petit élément sympathique, des objets tels que les parapluies ou les balons du premier niveau, offrent un gameplay plus varié.
Bref, du bon jeu de plateau comme on aimerait en voir à nouveau. Dommage que l'opus "II" (juke box adventure) n'ait pas été une réussite... Bien sûr, les graphismes sont nettement plus beaux, mais ils ont complètement perdu le fil de l'histoire. Tout d'abord, le principe même du jeu n'a plus rien avoir. On le catégorise sur abandonia de "no-brain fun", et en effet, plus la moindre recherche. La progression dans le niveau est devenue ultra-linéaire. Finies les caisses, ici on lance des disques, et il faudra souvent en balancer plusieurs pour venir à bout d'un monstre apparemment inoffensif.
Là aussi, le bât blesse: alors que Blues 1 nous avait fait affronter des personnages parfois déjantés, mais toujours réalistes, on se retrouve ici face à des pièges à loup vivants et géants, et .. euh une sorte de tondeuse à gazon croisée avec une pelleteuse mécanique qui à visiblement des instincts de pit-bull.
Bref, les deux premiers niveaux sont beaux, mais franchement insipide une fois leur côté démo/tutoriel passé, et dès le niveau 2, les monstres sont tout simplement pénibles (mouvements trop rapides, impossibilité de les dégommer quand ils sont "au repos", bref, pas impassables, mais pénibles)
Et pour le coup de grâce, je vous laisse contempler, hébétés, nos fameux blueseurs transformés en sur-hommes après avoir mangé une part de gâteau, ce qui semblerait leur permettre de faire des sauts plus longs, et peut-être renforcerait la puissance de leur lancer de disque.
Ridicule et pas convaincant pour un sous. Bref, autant Titus Interactive nous a fait de bons jeux dans ses jeunes années, autant il semblerait qu'ils aient été contaminés par la transformation du monde du jeu vidéo en un "marché" et progressivement perdu toute notion du gameplay et de la conception des bons niveaux. Je n'oserais même pas dire qu'ils ont transformé BB en un clône de Megaman: la seule ressemblance viendrait du fait que l'on tire sur des ennemis dans un sidescroller.
Bref, concentrez-vous sur le premier volet à moins d'être un graphiste en manque d'inspiration.
Monday, November 05, 2007
Pas bien (2)
je ne dois pas blogger au lieu de préparer ma défense de thèse.
je ne dois pas blogger au lieu de préparer ma défense de thèse.
je ne dois pas blogger au lieu de préparer ma défense de thèse.
je ne dois pas blogger au lieu de préparer ma défense de thèse.
je ne dois pas blogger au lieu de préparer ma défense de thèse.
je ne dois pas blogger au lieu de préparer ma défense de thèse.
je ne dois pas blogger au lieu de préparer ma défense de thèse.
Wednesday, October 24, 2007
SEDS 32x32 needs you
Je m'attaque donc au support de blocs plus grand (32x32 pour commencer, mais de manière à pouvoir supporter les résolutions classiques des sprites GBA/DS, à savoir 32x16/16x32 ou 16x8/8x16 également).
Ca fait pas mal de chose à réviser dans le code (d'autant que je ne peux pas garder le même type d'affichage de grille à un autre niveau de zoom: on ne verrait plus rien), mais j'ai déjà pu faire quelques essais de tracé dans la grille 32x32 ce midi.
L'ennui, c'est que le touchscreen de la DS ne permet pas un tracé suffisament précis à cette résolution. En clair, ça ira pour donner les "grandes lignes" d'un dessin, mais pas pour une édition au pixel près :(
SEDS has been now officially advertised on some NDS forums, and i got plenty of feedback from beta-testers. Among other things, for many guys, 16x16 canvas is just too small, so i'm now trying to have 32x32 edition to work. That makes many things in the code to be adjusted, including reviving the alternate grid display -- and those are getting in place.
The one thing that is more annoying is that 'pixels' are then only 4x4 wide if i want the full 32x32 sprite displayed -- and imho, 4x4 areas are too small to be accurately enough plotted directly with the stylus. It sounds thus that i'll keep this experiment for "rough sketches", but that we will still have to work with a higher zoom level of a sprite sub-region.
A re-réfléchir, donc...
Dans le même ordre d'idées, la palette n'est pas toujours évidente à utiliser. Dans ma manière d'utiliser l'éditeur, ce n'est pas bien grave parce que je travaille essentiellement avec les flèches (couleur suivante/couleur précédente) ou la pipette, mais je dois reconnaître que cobain a mis le doigt sur un point noir. Et déplacer la palette plus loin du bord n'a pas arrangé grand-chose: cliquer dans une case 4x4 sans en sortir, ce n'est pas une mince affaire sur le touchscreen de la DS.
Le mieux, ce serait sans doute de "doubler" la palette d'une zone agrandie des 16 couleurs autour de la dernière couleur choisie ...
Similarly, the palette isn't that easy to use accurately for people who haven't fine-calibrated their stylus input. I don't care too much myself since i'm not that much using the palette directly -- i make wide use of "next/previous color" with the Dpad and the "color picking" on the grid... The best alternative i can think of would be to offer both the full palette with 4x4 per color, and a "quick pick" area where you have access to the 16 colors around the one you just clicked, but with e.g. 8x8 region per color.
pre-release 0.1 beta-test for download here
Monday, October 22, 2007
tiles extraction ...
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 ...
Tuesday, October 16, 2007
SEDS Multipage
Wow, needless to say, it's really a good thing to have software update to speed up application development. Just a couple of edit-compile-update loops were enough to brew the first version of SEDS that can manage multi-page .spr files (which had been tested in runme a couple of weeks ago). That means i can at last break the "48 sprites per file" limit and reorganize my own tiles theme-wise, e.g. grouping all the forest-related tiles with one page for dirt blocks, one for the tree trunk & roots, anoter one for in-progress tree tops, one for the apples, and so on.
C'est aussi un premier pas vers la possibilité de mélanger des blocs 16x16, 8x8 (pour les pieds et les mains de bilou, entre autre) et 32x32 (l'encrier).
Bon, ceci dit, pour l'instant, les réorganisations sont pénibles au possible, mais c'est juste parce qu'il me manque une interface pratique pour ce genre de tâche :P
Et il a fallu faire tout celà sans que les aventuriers qui avaient téléchargé la release d'hier ne se retrouve temporairement avec un programme inutilisable suite à un update malencontreux... ce qui n'a pas été sans mal :P
This is also the first step towards the ability of mixing 16x16, 8x8, 32x32 (and other sizes coming) resolutions in a single editor/spriteset, which will be crucial to go on working with Bilou's world. Well, right atm. "reorganization" is as tedious as moving files using MS word, but that's still better than no reorganization at all :P
Allez, ça mérite bien une "0.2"