Tuesday, April 14, 2009

(Might be) Back again ?

La prison, "retaillée" pour DS
Ok, mettons que je n'essaie pas de faire un programme qui convertisse un jeu Game Maker en un jeu DS tout fait, mais plutôt que je reprenne les graphismes du premier Badman pour m'amuser un peu à faire une "version anniversaire" sur DS, reprennant les meilleurs niveaux, etc.

Première observation, les graphismes étaient tellement simplistes qu'ils passent pratiquement tous à travers une conversion "20x20 -> 16x16" brutale dans The Gimp. Certains (la porte en bois et les caisses) auront besoin d'un petit relifting dans SEDS, d'autres (la grille de la prison) auront tout intérêt à être réimportés de leur version 20x20 et "recollés" sur le fond.

A few more "mapshots" of RSD game-maker games i did in '95. Here comes Badman, an overweight parody of Batman, in a super-zero style. The tools i've crafted so far don't allow straight conversion of any RSD game, but let's try and see how much work a specific port (for instance an "15th anniversary release" of Badman) would require. Let's go. Just convert 2000x2000 map into 1600x1600 map and see what happens...

Le manoir, "retaillé" également à l'exception de Badman
Deuxio, Badman ne fait pas 16x16 mais seules ses "oreilles" et sa cape dépassent du cadre. Au niveau du gameplay, ça ne devrait donc pas choquer de le voir se faufiler dans des passages un peu trop étroits. Les ennemis seront conservés en 20x20 aussi (et prout pour la surconsommation de VRAM), sinon ça ne donne pas


la version d'origine, sur PC
Tertio, si la version PC était limitée, il y a moyen de s'amuser en variant un peu le comportement des ennemis, cette fois-ci. Faire hanter les cuirasses de chevalier par les fantômes du manoir, par exemple. Ou passer l'horrible grille de la prison en parallaxe, etc.

well, a few background tiles will need to be reworked, of course, though in some cases, like the jail's grid, i can just re-import the pixels because they actually don't have per-block granularity.
Clearly, i should better keep
sprites 20x20 anyway (if i dedicate per-OAM vram rather than per-frame vram, it should work for every game, and it really doesn't care for Badman 1 which features some 40 frames for all animated objects throughout the game ;)


Retenus pour l'occasion : gettham city, le manoir, la prison et le japon.

et point de vue code:
  • extraire les animations des blocs vers du script "GEDS"
  • itou pour la position des monstres sur la map (avec un offset et ajustement des coordonnées quand-même)
  • un mbl2spr qui ajuste les sprites 20x20 sur du 32x32 (ou éventuellement 24x24 si vous êtes sages.

Saturday, April 11, 2009

Bubule Warrior

Si vous cherchez à savoir "Qui est Bilou", je crois que ceci est le plus ancien document que je peux vous ressortir. Presqu'une pièce de musée. Gribouillée par mon frère entre deux heures de cours alors qu'il venait tout juste de rencontrer Pierrick, Piet nous fait un petit topo des mouvements de "Bubule Warrior" qui cherchera à retrouver sa belle Raph aux talons pointus et aux cils courbés.

Funny enough, many people on the internet mix up my own identity with Bilou's identity. In the case you wonder "who is Bilou, anyway", this is the eldest piece of museum i can show you. Sketched by my brother while he just met Pierrick, this is where you get a few hints on moves that "Bubble Warrior" would have and why he'll be running through a strange world to save his sweetheart from unknown hazard. It shared most of the previous level design in my earlier Calimero platforming game.

Et avec ça, un bestiaire rudimentaire où l'on voit déjà Bubble Bat (que je suis occupé à transformer en "Berry Bat" après avoir abandonné l'"Apple Bat") et une "space chenille" qui préfigure "Big Caterpillar", le premier boss de Bilou.

La "little bomb" est un clin d'oeil au "Bob Omb" de Mario 3 (et fait probablement un peu référence aux mines marchantes de Commander Keen ?). La "tortue turbo" nous annonce la "turtle zone" et le "tictac bull fire" faisait office de premier boss.

Comme dirait l'autre, ça ne nous rajeunit pas.

Another interesting part was a small list of foes that would be found on the road. Most of them didn't made it through the filter of years, such as one-eyed snail, the turbo turtle and those fire-thrower-bubbles. You'll note the "batbull" that has now turned into the berrybat, but still keep the idea of "a ball with wings". Note, too, the "space caterpillar" that has been the root for World1 boss: BigCaterpillar.
"Little Bomb" is likely a lost tribute to SMB3's Bob Omb, and never showed in any level.

By those ancient times (around 1994), i was just the "pixeler" guy in charge to turn my brother's impressive (;) graphics into pixels into the digital world, usually through millimeter-sheets and DATA lines of BASIC listings.

Piet prévoyait visiblement une sortie sous Amstrad, puisqu'il bombardait Pierrick à la programmation et me reléguait au rôle subalterne de "pixeliseur" (comprenez, retraceur de ses dessins géniaux sur des feuilles millimétrées pour ensuite les encoder sous forme de "DATA 0,0,0,1,3,3,1,0,0 ..." dans un programme BASIC :P

edit: want to read more ? the first ever world map has been scanned too !

Refactoring again...

Well, once again, i'm refactoring the code of my game engine, as suggested in this earlier post ... Though i already have to revise some of those proposals: iGobPubstate is not clean object-oriented approach and causes more trouble than solution for the rest of the stuffs.

Meanwhile, i've updated a former post about collision detection on slopes with a review of how a selection of popular side-scrolling platformers handle such slopes, both technically and gameplay-wise.

And while reading the Frequently Questionned Anwsers about C++, it reminds me that most of these late refactoring things doesn't come from the fact that i hesitate on how things should be done, but rather how work should be delegated to the different classes. I'm certainly not a C++ guru, and the whole SEDS/GEDS project is also an attempt to get more familiar with C++ (though i deliberately avoid templates and friends so far).


Well, at least i'm not throwing all my energy into Yet Another LinkedList/HashTable/AvlTree library :P

Friday, April 10, 2009

To the moon and back

My homebrew development kit has recently been upgraded to include a shiny DS lite, in order to enjoy the true colors of my pixels. That's for the neat side. I asked my brother to get me a R4 chip to fuel it, since i had quite a good experience with his (see former entries), and so he ordered me a R4-IIISDHC. Quite confusing device, i must say. On the web, everything looks like it is indeed an upgrade of the former R4, but documentation provided doesn't match the device's operation. It doesn't seem to be really using MoonShell at all (which my bross installed on the device, following former instruction), and it is said to be "a fake, scam, don't buy" on forums (as of june 2008)...

En plus de ma DS "phat" et sa Supercard, me voici équipé d'une DS Lite et sa R4-IIIsdhc, légèrement différente de la R4 "originale" de mon frère, et un rien intriguante (nombreux forums la dénonce comme "clone pirate" de la R4), mais en gros, je n'ai pas à m'en plaindre. Seul hic, ils ont fait l'impasse sur le "CD d'installation", pourtant annoncé sur le site du constructeur (www.r4iii.com, www.r4iiisdhc.com ou www.r4dsl.net selon celle que vous avez obtenue). Il faudra donc aller télécharger le "kernel" adapté et installer les fichiers à la racine de votre carte mémoire micro-SD, faute de quoi, vous aurez juste droit à un écran bigarré avec un petit logo "loading" animé en bas à droite de l'écran ...

I first thought that the authors of MoonShell didn't like that their product was embedded and defaced into a device's firmware, but i'm really starting to wonder whether that R4iii has anything to do with the earlier device :-/

Anyway, my software runs flawlessly on that beast. So far, i only regret it has no notion of directories and obviously recursively scan the media for some .nds, showing 4 of them per screen ... i feel like i'm gonna miss my supercard's menu, somehow.

At least, tweaking directories names and things alike could allow me to have files in a more "usable" order. On the other side, it made me realise that Moonshell is capable of something that i still have to implement in runme : soft reset to the firmware. And they do this quite simply via "reset.mse" (MoonShell Executable) pluging provided by the card vendor.

To quote "reset.txt" that comes along with the "R4iii upgrade" :

MoonShell execute plug-in

This plug-in is exclusive return to firmware function.

Reference URL that becomes base of reset function.
Most of reset.mse is a copy of LoveLite.

Lick + ds homebrew
http://licklick.wordpress.com/tag/lovelite/

For other homebrew developers.
'reset.mse' can be used from your self-made application.

Please make the C/D bank of VRAM accessible from ARM9.
example.
VRAM_C_CR = VRAM_ENABLE | _VRAM_CD_MAIN_BG_0x6000000;
VRAM_D_CR = VRAM_ENABLE | _VRAM_CD_MAIN_BG_0x6020000;

Please write the following values in 1024 bytes from 0x0603FC00. (16bit access is necessary.)
0x0603FC00 0x01
0x0603FC01 0x01
0x0603FC02 0x01
0x0603FC03 0x01
0x0603FC04 '?'
0x0603FC05 '?'
0x0603FC06 '?'
0x0603FC07 '?'
0x0603FC08 0x00
0x0603FC09 0x00
0x0603FC0A 0x00
0x0603FC0B 0x00
0x0603FC0C 0x00,0x00,0x00...
Please input the adaptor name (four characters) from 0x0603FC04 to 0x0603FC07.
Please fill zero from 0x0603FC0C to 0x0603FFFF.

Please start 'reset.mse'. (Please begin with usual NDS multi boot in a similar way.)


As a matter of fact, i did not even tried to implement this directly. I happen to have a slightly different memory setup in exec.cpp:LoadNDS_VRAM, which is the root of my devstation (and comes from GrizzlyAdams' work in DSChannels, remember?). All i want is a way from runme to the firmware without going through the power button. Moonshell does this ? fine. So just

if (keys & KEY_SELECT) {
  if ((keysHeld()&KEY_L)) {
printf("** trying to switch to moonshell **\n");
LoadNDS_VRAM("_DS_MSHL.NDS","/",0);
  }
  printf("checking for updates...");

does the trick ... at the expense of going through moonshell, i admit (which is a shortcut if you had just uploaded some MP3 to your system, i must add). This is somehow an ugly hack, true. I'm not proud of it in any way, but it's there and maybe at some point it will save the day. Who knows.

It could be equally sufficient if moonshell was able to run my tools, but for some reason, all i get is some "not support adapter type" error message when i try to. Only a few programs (without DLDI ?) seem to work with the version of moonshell that ended up on my system. Wait and see...

Monday, April 06, 2009

Quid de Qwak ?

Il y a quelques semaines, je craquais pour "Qwak", un petit jeu d'arcade/ plate-formes adorable et bien foutu. Sans être vraiment "bon" à ce genre de jeu, je n'ai jamais pu y résiter... Bubble Bobble et BombJack ont toujours eu ma préférence sur les Sega Rally, Street Fighter et autres R-Type sur les bornes d'arcade de ma jeunesse. Alors prout! Plutôt que de relancer une énième fois Arcane pour qu'elle me refile ses superbes graphismes pour en faire un jeu DS, j'ai décidé d'apporter mon soutien à un vieu de la vieille (pensez, la première version de Qwak tournait sur un micro 8 bits) en achetant cette étrangeté : une cartouche homebrew.

I got Qwak, a small, lovely arcade/platform game particularly well-crafted. It reminds me of the Lode-Runner / Bubble Bobble / Bombjack era, but with the level of polish of the Amiga era. I've always prefered them to Sega Rally, Street Fighter or R-Type. The original thing is that Qwak, a GBA game, is also a homebrew.

The goal of the game is to collect all the keys shown on single-screen levels. Some shields power-up allows for a single hit. Eggs to collect so that you can later throw them on monsters and fruits to collect to get more eggs at the end of the level.


Eh bien, après quelques heures de jeu, je suis définitivement séduit. Le principe est simple : ramassez toutes les clés du tableau pour ouvrir la sortie et poursuivre vers un tableau plus dur. Notre mignon canard peut ramasser des "fioles-bouclier" (dans les coins supérieurs de l'image) pour se protéger contre les monstres qui rôdent, lancer des oeufs sur les monstres en question pour s'en débarasser et ramasser des fruits qui seront transformés en oeufs supplémentaires à la fin du niveau. Le tout avec des graphismes et une bande son probablement repris tels quels de la version Amiga, Qwak GBA à tout ce qu'il faut.

The number one gameplay idea that I love in that game is the fact that bonus fruits are also walls for the monsters. So monsters start the level confined in small areas, but you set them free as you progress in collecting keys. Eating fruit is both good and bad.


My number one complain on the game is that hitpoints are hard to spot on the game. Rather than hearts or shields or armors, they are small grey bottles, with a small shield icon stamped on it. Given that, when you enter a new level, they may be the only chance you have to avoid instant death on contact with an enemy, I really wish they had more distinct shape so that I could spot them at glance, and maybe that they'd blink if I'm just a naked duck. The color of your armor, too, is quite hard to see on the GBA screen, and this carry the indication of your hitpoints.


J'avais été attiré par le gameplay un peu unique : les bonus font aussi office de murs pour les ennemis, qui sont donc au départ confinés dans une petite zone mais que vous libérez au fur et à mesure que vous progressez dans le niveau. Eh bien, je n'étais pas au bout de mes surprises. Ce jeu est un régal de petites recettes qui prolongent sa durée de vie d'une manière quasi impensable en cette époque du jeu jetable.

  • Si les mondes de Qwak sont toujours traversés dans le même ordre, en revanche, vous visitez les niveaux de chaque monde dans un ordre varié (si pas aléatoire).
  • Notre p'tit canard, une fois rôti, recommence le niveau, mais pas toujours du même endroit.
  • En plus des "bêtes bonus", 10 fleurs vous donnent une vie et un arc-en-ciel de diamants = gros points. Il y a aussi des fioles "power-up", malheureusement au look un peu trop difficile à prévoir pour que j'aie vraiment pu m'y retrouver.
  • Une fois le temps imparti écoulé, vous pouvez continuer le niveau, mais il se met à pleuvoir des boulets hérissés de pointes qui vous donneront du fil à retordre. Heureusement, le changement de musique avertit le joueur quelques secondes avant l'averse fatidique.
Mais ce qui fait de chaque partie de Qwak un moment unique, se sont ces évènement aléatoires qui sont annoncés lors de l'écran de bonus. La "pluie de bonus", est probablement ma préférée, quoi qu'il faille tout de même se méfier de certains "malus" qui s'y cache. Dans un autre genre "Attrape la clé volante" rappellera une séquence de Harry Potter et peut allonger de manière inquiétante le temps nécessaire pour finir le niveau. Quand à "Baddies get Revenge" et "Welcome the Happy Ghost", ils ne dureront heureusement pour moi que le temps d'une vie, parce que dans ces conditions, mon stock d'oeufs baisse dangereusement vite.

There is other very interesting design element in Qwak, that makes the game fresh more often than "lode runner" or "manic miner". Although the levels are pre-defined, there are several layers of randomness added:
  • the order in which levels are presented within a world;
  • the respawn location after the player got fried by a monster;
  • special rules may be added to the level with low probability, like a moving key, respawning baddies, an additional "ghost" monster or the bonus rain. Note that if you die during the level, the special rule terminates, be it good or bad.
Much like many other single-screen collect-them-all platformer, there is a time limit. But unlike e.g. Manic Miner, you don't arbitrarily die when the timer runs out. Instead, it starts raining spikeballs. If you have the required skills, you can still barely escape the level, and maybe even quickly collect a last key.


Voilà. Un jeu bien sympa, donc, que les plus chanceux pourront emporter avec eux sur GBA (Dépéchez-vous, il n'y a plus que quelques cartouches disponibles : c'était une édition limitée) et que les autres préfèreront peut-être en version multi-joueur sur PC avec des graphismes "HD-ready" (ce que personnellement je regrette, mais bon). Merci Jamie. Je t'envoie un Bilou par retour de hibou dès qu'il est prêt et je retourne bricoler des étagères dans ma cave.

PS: tout ceci a été bloggué dans les escaliers: j'ai des petits soucis avec ces adaptateurs "Ethernet sur courant porteur" qui amenaient ma connexion Internet jusque dans mon salon :P

Friday, March 27, 2009

vgmaps tool for RDS Game-Maker


bbl2map.pl

Et voilà. L'outil ultime : conversion des fichiers .MAP en allant rechercher les animations des monstres dans les .MON. Je suis encore loin d'avoir tout compris aux .mon (déplacement, etc.), mais au moins, j'ai de quoi me faire un joli musée de niveaux de nos jeux RSD Game-Maker. Pour ce qui est de faire une conversion .gam -> .nds, par contre, ce n'est toujours pas gagné. Si la plupart des maps se "compressent" assez bien sur des tiles de 8x8 (pour Badman II, en tous cas), la gestion des animations serait un vrai cauchemar dans un environnement pareil ...

Good news if you used to design games on RSD Game-Maker: i managed to build a fully-featured RSD .MAP reader that lookups .MON files (at least animations) to render a full map of your levels, with monsters depicted... Oh, it could still use the information from .GAM files to show you entry/exit points as well, i admit.

I guess anyone fluent in PERL could reuse the code to write a RSD->XXX converter given that you already know the map format for XXX. Unfortunately, that doesn't really bring me much closer to the "RSD->NDS" conversion/replay tool due to the silly 20x20 block size in .BBL files. Not much of a concern for handling the map (at least, in Badman II, most of the maps use quite few blocks and a plain conversion to 8x8 tiles does the trick), but animating such 20x20 blocks that are split over different tiles would likely turn into a nightmare. And trying to update a bitmap rendering of the level might be tedious (and boring) to implement, not mentioning the limited bandwidth to the screen's backbuffer , that would hit the framerate quite badly.
.

Thursday, March 26, 2009

BBL metadata.

Voilà. Une fois qu'on dispose de tout un jeu de .BBL avec les tileset correspondant, c'est bien plus simple de reconstituer le rôle des 20 bytes de contrôle ... C'est ce que fait de son mieux ce petit outil "bblmeta.pl" que je vous offre également.

Chaque ligne rappelle le numéro du bloc (en hexa) et sa position dans l'image générée par bbl2png (le premier, par exemple, r02 c12 correspond au premier canon, tourné vers la gauche sur la 3eme ligne de l'image). Suit ensuite les "flags" tels que lus dans le fichier .BBL puis l'interprétation de ces flags par le script bblmeta.pl

J'ai repris la technique des répertoires UNIX: un '-' chaque fois qu'il n'y a rien à signaler, une lettre sinon. Ainsi "B--a-K" serait un bloc solide (B) animé qui interagit avec une clé (probablement une porte). "--g-+-" est un bonus qui rapporte uniquement des points, etc. Pour être exhaustif, je dirais que le programme reconnait:

  1. Bloc, Floor, Wall ou ciel (-)
  2. Pickme : l'objet peut être ramassé pour l'inventaire
  3. g, l ou r : gravité normale, vers la gauche ou la droite. Les autres combinaisons ne sont pas reconnues.
  4. a : bloc animé,
  5. t: réagit au contact
  6. bonus/malus : H=hitpoints, x=kills, + : score
  7. L = 1UP, K=clé/porte.
En plus de ces "flags", certaines valeurs sont indiquées dans une liste entre parenthèse, comme la succession des blocs pour une animation, le nombre de hitpoints ou de clés, ou de points modifiés lors d'un contact , le numéro du monstre tiré (pour les blocs qui tirent des monstres), etc.

Here comes a second funny PERL script. It extracts meta-data from .BBL (Background BLocks), .CBL (Character BLocks) and .MBL (Monster BLocks) produced by RSD Game-Maker. If you used to write games with that editor, feel free to use that tool to retrieve all meaningful elements and port your old funware to some new platform. If you do so (or just plan to do so), please share the joy and post a comment.

This tool is a kind of "preliminary" reverse-engineering tool. It can tell you roughly what are the properties of individual blocks but detailed information may need to be looked up in the 40-digits hex string. Each line describes a block. Right to left you'll have the following information :

1c (r01 c13): 400100000000000000ffff1b64001c0400010000  --ga-x-  (a1b,100)(h-1)
^    coords   |--- complete hex dump of meta-data ---|  |flags|  |---details--|
+- block number
On the right side, "flags" tell you roughly what are the properties of your block. here you see an Animated block that has downwards Gravity and that hurts the player (x) on contact. Details tell you that it animates to block 1b after 100 ticks and that hitpoints are reduced by 1 on contact. On the left, you have block number (block #x pixels are located at bytes x*420..x*420+399 in xBL file) and the row/column coordinates on the picture generated by my former bbl2png.pl script.
Bref, ce n'est certainement pas aussi souple que l'éditeur du game-maker (et d'ailleurs, ce n'est pas un éditeur, juste un outil d'inspection), mais ça capturera la plus grande partie des cas que l'on retrouve dans un jeu de plates-forme comme les Badman.

Hope it Helps ^_^
PS: 1st byte is the index of the generated monster (0x40 = no monster generated), thus byte 2 is likely the delay between two such generations.