Thursday, February 28, 2008

portamento ...

Retour pas mal d'année en arrière ? Alors que j'essaie d'ajouter les portamento (variation continue de la fréquence d'une des notes) à la bibliothèque ntxm, je me heurte aux même(s) difficulté(s) que lorsque je développais mon player S3M pour mes jeux DOS/Assembleur...

  • Pas évident de structurer les données des channels pour que les effets s'expriment proprement. Là, par exemple, je ne saurais probablement pas gérer la valeur 00 pour les portamento (qui permet de réutiliser la dernière valeur non-nulle).
  • Pas évident non plus de savoir quel est l'effet exact ... d'un effet. autre exemple: mon "portamento up" a une mémoire trop "longue" : au fur et à mesure que le morceau est rejoué, le portamento emmène la note de plus en plus haut au lieu de rejouer toujours do--ré--mi.
edit: au moins, j'ai réussi à avoir des "portamento" qui marchent à la bonne vitesse:
  1. le 'pas' défini par le format XM est "1/256ème d'octave par tick"
  2. la fonction BendNote(note,finetune) de ntxmlib considère qu'il y a 128 niveaux de "finetune" entre deux notes successives (p.ex. C et C#)
  3. le player exécute l'effet "portamento" uniquement sur un "tick". Le nombre de tick par ligne est défini par l'effet "set speed" du morceau. La durée de chaque tick (en millisecondes) est calculée à partir du tempo (en bpm). En clair, si je double le nombre de tick par ligne, le morceau semble défiler plus lentement, mais la même commande "portamento" me conduira deux fois plus loin dans les notes.
oh, just to let you know : portamento up is fixed. I need to reorganize a couple of things in the player to better capture (and manipulate) the "state of a playing sample" (since Sample is simply a static structure that represent "a sample in the module's sound repository"): atm. the new note won't clear the current "drift" of the previous slide (and thus it'll keep on sliding higher and higher).
// our finetune is 12 times finer than the XM 'octave interval'
effstate.actual_finetune[channel]+=param*12;
Instrument *inst = song->instruments[state.channel_instrument[channel]];
inst->bendNote(state.channel_note[channel]+(effstate.actual_finetune[channel]>>7),
state.channel_note[channel],
effstate.actual_finetune[channel]&0x7f,
channel);
break;

Wednesday, February 27, 2008

Beam it, play it, fix it, repeat

I had an argument with the CVS repository last night, but i finally managed to make it accept a new branch with the sources for runme featuring the NTXM player. I hope 0xtob won't be against the re-diffusion of his sources (well, he shouldn't since they're LGPL) ... I am now able to upload any .xm to the DS (up to 512KB) and play it with NTXM. I can also upgrade the software to a new build by just pressing SELECT (and test new effects). All it required was a small rewrite of the XMTransport class so that it works with an (abstract) DataReader rather than plain FILE* ... It even makes it more elegant ^_^

Après moult adverses commandes contre Sieur CVS, m'est avis que la nouvelle branche du projest ustilisant le ménestriciel NTXM estoit fièrement campée. Eh oui. Je vais laisser libmikmod derrière moi et poursuivre avec le code (lgpl) de 0xtob. Je peux donc uploader un .XM (jusqu'à 512KB) sur ma DS puis l'écouter avec NTXM. un p'tit SELECT et c'est le player que je mets à jour (histoire de tester le support de nouveaux effets). ça ne m'aura demander qu'une légère réécriture de XMTransport.

edit: okay, i've got "set tempo/speed" effect added. I also added (untested) offset effect and wrote a small tool that inspect .xm to report what effects they're using... I'm not that happy with the way the player keeps state, anyway. Both "Instrument" and "Sample" classes are used as an "samples database", but nothing capture the current state of a playing note, which makes e.g. offset effect tedious to implement ... I fear similar boring edits to be required when we'll have to support retrig and the like.

Tuesday, February 26, 2008

ntxm->play();

category:modplayerj'ai des petits soucis avec la bibliothèque mikmod qui aurait du servir de soundplayer dans mes jeux. De plus en plus de soucis, en fait ... Du coup, j'ai l'intention de passer à libntxm, le modplayer qui est au coeur de l'excellent NitroTracker de 0xtob, et qui nous fait pleinement profiter des capacités audio de la console (mixage hardware sur 16 canaux).

Le seul hic, c'est que pour l'instant, je n'arrive pas encore à lui faire cracher du son dans runme :( Une fois que ce sera règlé, il me restera à assurer le support des S3M (minimum) et des IT (là, ça va être plus chaud) pour pouvoir profiter des petites musiques du frérot.

Howdy! I got libntxm working in runme this lunch time. I was getting less and less satisfied with libmikmod's quality (corrupted playout buffer) and wanted to switch to hardware mixing instead. This is still a very basic test atm (e.g. just playing a pre-configured XM song when you enter the "beam out" window), but you can expect "play XM received by WiFi" feature within the week ...

Once i get that done, i bet i'll try to write a S3M reader (drawing inspiration from mikmod's source, of course) and add support for S3M effects to the libntxm. That should bring me most of my bros' music library (before he switched to Impulse Tracker -- which will be a higher challenge to deal with) for my games, with minimal CPU load and best possible output quality.

edit: okay. ça marche. J'avais fait l'andouille suprême: contrairement à la bibliothèque libmikmod, libntxm n'utilise *pas* le FIFO interne de la DS pour transmettre ses commandes. On a tout simplement un tableau circulaire dans lequel les commandes successives (e.g. playSong, stopSong, etc.) sont inscrite et que chaque "moitié" du modplayer manipule. Le tout est placé dans une zone de mémoire spéciale (qui sert également pour s'échanger les coordonnées du stylet, et tout ça).

Et pour la petite histoire, la bibliothèque réseau dswifi, elle, utilise encore un autre mécanisme (une zone de transfert dans la RAM principale, mais dont l'adresse est bidouillée pour court-circuiter le cache du processeur). Là, l'ARM7 apprend l'adresse de la structure (allouée côté ARM9) lors d'une phase de dialogue initial à travers le FIFO, et les mises à jour de la structure sont également annoncées "over FIFO". 0xtob, lui, reprenant le code du modplayer posté sur le forum GBAdev, vérifie gentillement si un nouveau message est arrivé tous les 60èmes de secondes (et donc dans le "Vblank" handler plutôt qu'en réponse à un évènement sur le FIFO :P)

Ca y est ? vous êtes perdus ?

2024 #choice reality check: I'm still using libntxm and don't intend to change. Significant work was needed to add effects support and I failed to push that back into the original repository. Oh, and I never added S3M or IT support. Instead, I just went on converting files into .XM with schismtracker :P

Monday, February 25, 2008

Zelda Sound Test

Tout a commencé par une archive que m'avait filé MinishLink : la bande son intégrale de Zelda : Phantom Hourglass. Du coup, je me suis lancé ce week-end dans une frénésie de downloads (principalement sur le très excellent sound-test.org), à grand renfort de plugin "flashgot" pour firefox d'ailleurs.

J'ai toujours trouvé les "autres" zeldas un peu faiblards côté musique par rapport à mon "Link's Awakening fétiche". Le décompte :

  • Zelda : Link to the Past : 30 thèmes, tous les donjons (ou presque) utilisent la même musique
  • Zelda : Link's Awakening : 80 pistes, dont 8 pour les donjons et 8 pour les instruments collectés à la fin de chaque donjon.
  • Zelda : Oracle of xxx : 40 pistes chacun. Il y a aussi une musique séparée pour chaque donjon.
  • Zelda : Occarina of Time : 80 pistes.
  • Zelda : The Minish Cap : 50 pistes
  • Zelda : Phantom Hourglass : près de 70 pistes, mais dont une dizaine servent d'introduction (des thèmes des premiers zeldas joués à 2 instruments)
Bon, la comparaison n'est pas très juste. Je devrais filtrer les pistes qui ne sont que des effets sonores (genre "il reste un trésor" ou "trouvé une petite clé" ...)

edit:
au niveau sonore, c'est la bande son de "Minish Cap" qui me plaît le plus ... Ce mélange "chip+midi" avec quelques samples et des ondes toutes simples pour les basses et le rythme donnent un style absolument unique et parfaitement adapté au jeu. Par contre, le son de la N64, bof bof. Il manque de pèche.
edit++: finalement, je retire les "oracle of xxx" de ma playlist ... Même s'il y a quelques thèmes sympas, je trouve qu'il y a sur-utilisation de square waves (et faire un chiptune tout en squarewave, bof.) ... Elles ne sont pas aussi agréables à écouter que celles de Link's Awakening (mais c'est peut-être dû aux émulateurs qui ont été utilisés pour rendre les .mp3 plus qu'au boulot des musiciens de la "zelda-team", of course).

Saturday, February 23, 2008

Link's Awakening sur DS

Je suis parti dans un trip nostalgique hier (minishlink pourra témoigner), si bien que ce matin, je suis parti à la pèche aux émulateurs Game Boy et GBC pour me refaire les excellents Zelda sorti sur ces petites consoles. A faire tourner sur ma DS, évidemment whistle

Le meilleur que j'aie trouvé jusqu'ici, c'est Lameboy. J'ai aussi essayé DSboy (qui ne supporte apparement pas le GBC) et goomba (pour GBA, que je n'ai pas réussi à démarrer avec ma SuperCard) ... Bref. Aucun d'eux n'a l'air de supporter le son du gameboy, et c'est là que je m'étonne.

Sans le son, un jeu gameboy, c'est franchement insipide ... Je suis d'autant plus surpris que je pensais que ce serait un jeu d'enfant pour une autre console nintendo. J'avais tenté un émulateur GB sur mon PDA (sharp zaurus) il y a quelques années, mais je n'avais pas été très étonné que le son en soit absent (petit CPU et hardware son a priori très différent, tout juste capable de faire du streaming audio).

Bref. Les choses auraient pu en rester là sans Cobain, qui m'a fait remarquer que l'adaptateur Supercard SD intègre un émulateur NES (pocket NES, je pense), un émulateur GB et GBC (Goomba DS, mais une version qui marche ^_^) et même un émulateur Master System (iirc). Et en effet, les fichiers .gb et .gbc sont listés par le menu de démarrage de la supercard!

I have to confess, I've been emulating lots of Nintendo titles while switching millenium. So many NES, SNES and even gameboy titles we had found on the freshly-available Internet made me realise how small the 'supermarkt demonstration kiosk' selection was compared to the international catalogue. And chatting with MinishLink made me wish I could play some gameboy titles again. Preferably on the Nintendo DS.

I tried a few of the suggested homebrew emulators (lameboy, DSboy, goomba), but even the best-working one lacked sound support. And a gameboy title is quite tasteless if you remove sound, imho. Then Cobain pointed out that my Supercard linker does feature a NES and a GB/GBC emulator. Even a Master System emulator!
Things unfortunately go a bit wild when trying to save, especially in Zelda titles.

Ca marche impec (mais j'imagine que les possesseur d'un linker slot 1 auront quand-même besoin d'un émulateur). J'avais cru comprendre que la DS n'avait pas les chips nécessaires pour faire tourner les jeux GBC ... je viens de pousser sur L+R pour tenter une sauvegarde ... Et je tombe sur le menu "Goomba Color alpha 6 on NDS" ... on dirait bien que les cocos de chez Supercard ont embarqué plus que je ne le pensais sur la cartouche ^_^

J'ai pu me refaire un petit "Zelda DX" (version GBC de "Link's Awakening", mon zelda préféré -- auquel il paraît qu'ils auraient rajouté un donjon caché ... me réjouis de le tester). Par contre, sauver est un peu plus complexe:
  1. pressons START+SELECT+A+B pendant le jeu pour écrire l'état de la quête dans la fausse mémoire de sauvegarde de l'émulateur
  2. pressons maintenant L+R pour invoquer le menu de l'émulateur, ce qui l'oblige à copier "fausse mémoire de sauvegarde" dans la "fausse mémoire de sauvegarde" embarquée sur la supercard.
  3. Enfin, appuyons sur "L+R+SELECT+A" pour invoquer la gestion des sauvegarde de la Supercard et sauver ça dans un fichier .sav sur la carte SD.
  4. Sur certains jeux, la dernière étape ne marche pas (je n'ai pas su la faire fonctionner dans Zelda : Oracle of Ages, par exemple). Il faut alors éteindre la console et la rallumer immédiatement après. On voit alors le fichier dans le menu "saver" et on a la possibilité de le copier vers la carte SD (il était en effet resté quelques secondes sur la supercard, même privée d'alim.

Thursday, February 21, 2008

extern "C" { ... }

Dans la série "le monde magique et surprenant du C++", le commandant stdio nous emmène au plus profond de la mer d'incompréhension pour observer le standard (poisson très farouche) dans son milieu naturel ...

on s'accroche bien.

extern "C" {
class X {
X() { iprintf("toto"); }
~X() { iprintf("tutu"); }
void stuut() {iprintf("stuut\a\n");}
};
}

on compile, eh oui. Ca marche. Surpris ? Je viens (dans un fichier C++) de déclarer une classe à l'intérieur d'un bloc que beaucoup considère comme "un truc compatible avec le bon vieux C". Bin détrompez-vous, 'extern "C"' sert uniquement à décider si l'on utilise ou pas le triturage de noms de fonction (en anglais, "name mangling") propre au C++.

Wednesday, February 20, 2008

Pendant ce temps là, sur la Wii

Après un petit "pong", c'est au tour de Tetris d'apparaître en homebrew sur la Wii. Quelqu'un a en effet trouvé une faille dans le jeu Zelda: Twilight Princess qui lui permet d'exécuter le code de son choix, tout ça rien qu'en bidouillant un fichier de sauvegarde stocké sur une carte mémoire SD. Le principe est assez classique: c'est celui du stack overflow qui hante les cauchemars des sysadmins UNIX depuis deux générations. Peu pratique et longuet, j'en conviens, mais personnellement, je trouve l'approche plus élégante que d'aller souder une puce sur le lecteur de disque.

Jouons à Tetris dans Twilight Princess ?

Vous avez une Wii et le jeu "Twilight Princess" ? faites un tour sur http://wiibrew.org/index.php pour en savoir plus et télécharger les petites démos, puis racontez-nous ce que vous en avez pensé dans les commentaires ^_^

Running homebrew on a cartridge-based console usually gets down to finding a PCB that will present custom (and dynamic) contents as if it was legit contents, thanks to custom chips. But what about consoles using optical disks ? Well, one thing you could still do is abuse some existing flaws in existing games so that you force it to run some (bootstrap) code that was made part of innocuous payload. Such tricks are used to bypass securities in many other systems, so it is nice to see it done for fun rather than for havoc or profit, for once.
This is what happens with the 'tetris in twilight princess' exploit. You tweak a savefile (which happen on SD card) so that your horse's name (iirc) triggers a crash, and while crashing, the game's code suddenly start executing your Tetris code. It isn't as convenient as a linker, but I'd definitely better try something like that than soldering wires or custom chips around the optical disk of a console of mine, tbh.

edit: depuis le temps, le "Homebrew Channel" s'est mis en place, qui ne nécessite plus l'emploi de Twilight Princess que pour son "installation". Je n'ai pas eu l'occasion de me familiariser avec son fonctionnement, donc je vous renvoie soit vers les pages proposées par Olivier B. soit vers le blog de mon frère.