Blogue

Voici Asounding

En portant le jeu Tumiki Fighters au iPhone, j’ai eu bien des déboires avec l’audio. Faire jouer la musique de fond et les effets sonores correctement ensemble, fonctionner correctement quand la musique du iPod joue en arrière plan, et s’occuper des autres interruptions pouvant survenir n’est pas une chose aussi simple qu’il peut paraître au départ. J’ai fini par créer mon propre moteur audio pour ce jeu, et aujourd’hui je le rend disponible pour simplifier la vie à d’autre dévelopeurs qui en aurait besoin. Voici le moteur audio Asounding pour iPhone OS.

Ma première tentative de faire les choses simplement était d’utiliser la classe AVAudioPlayer pour la musique d’accompagnement et l’API SystemSounds pour les effets sonores. C’était simple, et ça marchait, jusqu’à un certain point. Dès que quelque sons était joués simultanément, le volume de la musique grimpait et des distortions apparaissaient jusqu’à ce que les effets sonore cessent. Cette solution ne fonctionnait tout simplement pas.

Ma deuxième tentative était d’utiliser le code du SoundEngine d’un exemple d’application fourni par Apple avec le SDK. Je ne vous dirai pas où le trouver puisqu’il plante régulièrement (pas de doute pourquoi Apple a retiré cet exemple), mais c’était tout de même mieux comme solution temporaire que SystemSounds simplement parce que ça marchait correctement (la majeure partie du temps) et j’ai donc pu m’attarder à d’autre choses que l’audio. Une fois le jeu rendu jouable, et après avoir récupéré une pelleté de crash logs, j’ai décidé que de déboguer une « race condition » dans SoundEngine n’était pas quelque chose que je voulais essayer, et je me suis donc penché sur d’autre solutions.

À ce moment, j’avais déjà décidé de créer mon propre système pour controller toute la partie audio du jeu. Je suis parti du code d’exemple oalTouch, que j’ai ensuite adapté pour accommoder mes besoins. Avec Asounding, vous pouvez :

  • Jouer plusieurs sons simultanément
  • Changer la musique d’accompagnement au milieu du jeu avec peu ou pas de bloquate
  • Arrêter la musique d’accompagnement en fondu

J’ai aussi ajouté quelque comportement automatiques :

  • Désactivation de la musique de son lorsque le iPod joue sa musique
  • Désactivation de tout l’audio quand l’application est interrompue, pour la durée de l’interruption

En plus, il est possible de désactiver la musique du iPod, et vous pouvez manuellement désactiver la musique d’accompagnement, les effets sonores, ou tout l’audio du programme (utile pour gérer les préférences de l’utilisateur).

Une attention particulière a été porté sur ce qui ce passe quand l’utilisateur double-clique le bouton Accueil et démarre la musique du iPod sans quitter l’application.

Asounding est maintenant disponible en code source ouvert (GPL) et via une license commerciale pour distribution dans une application à code fermé. Si vous êtes un développeur de jeu iPhone, vous devriez peut-être en faire l’essai et deviner combien de temps d’implémentation et de déboguage Asounding peut vous sauer.

Vous trouvez Asounding à l’œuvre dans le jeu Tumiki Fighters (lien vers le App Store).


Portage d'un jeu au iPhone

Bientôt, un portage de Tumiki Fighters, un jeu de Kenta Cho originalement pour Windows, apparaîtra sur le App Store. C’est un « shoot’em-up » à défilement horizontal où vous détruisez les vaisseaux ennemis fait de petit blocs colorés avec votre propre engin fait de ces même blocs. Pourquoi est-ce que j’en parle ? J’ai fait le portage. (Mise à jour : maintenant sur le App Store.)

J’ai été contacté en mai par un certain Jeremy qui voulais amener Tumiki Fighters sur le iPhone et le vendre sur le App Store. J’ai dû paraître la bonne personne pour ça vu que j’ai déjà beaucoup travaillé en D (le jeu est écrit dans le language de programmation D) et avec Mac OS X. Il y avait aussi des choses avec lesquelles j’étais moins familier mais dont j’étais très intéressé à apprendre (ou du moins à expérimenter), tel que :

  • Le développement de jeux
  • Le développement pour iPhone OS
  • OpenGL

Pour moi, c’était un projet très intéressant parce que je n’ai jamais travaillé sur un jeu avant (du moins pas depuis ces petits jeux que j’ai fait pour un 486 il y a longtemps), et je n’ai jamais touché à OpenGL.

Le premier problème était de réussir à compiler le jeu pour le iPhone : il n’y a pas de compilateur et runtime D pour ARM en ce moment, et bien que j’aurai pu travailler pour mener ça à terme, j’ai décidé que j’avais déjà assez d’inconnus dans le projet et qu’il serait plus sage de simplement porter le jeu en C++, ce qui c’est avéré pas trop difficile (la plus grande difficulté étant de traquer les liens de possessions des objets pour palier à l’absence du garbage collector du D).

Ensuite, après avoir converti le jeu du D au C++, il restait à le porter sur la plateforme du iPhone. Tumiki Fighters dépend de SDL pour accéder à l’écran et aux contrôles (clavier, manette), SDL_mixer pour l’audio, et OpenGL pour les graphiques. Le iPhone n’a qu’une version réduite de OpenGL appelé OpenGL ES. OpenGL ES ne fonctionne qu’avec des coordonnées triangulaires (j’ai du convertir des tats de dessins basés sur des « quads » en triangles) et ne supporte pas les formes précompilées (« display lists »). J’ai donc du réimplémenter les graphiques à l’intérieur de ces contraintes.

Se débarrasser de SDL n’était pas si difficile : j’ai basé le contexte OpenGL sur l’exemple EAGLView d’Apple, et puisque j’avais à refaire les contrôles de toute façon (pour utiliser l’accéléromètre et des boutons à l’écran) c’était plus facile de remplacer SDL complètement.

Reste le son : après plusieurs tentatives à tout faire marcher correctement, j’ai fini par créer mon propre moteur audio basé sur OpenAL (pour les effets sonores) et AVAudioPlayer (pour la musique). Faire marcher l’audio correctement sur le iPhone s’est avéré la partie la plus pénible de la création du jeu pour iPhone : il faut faire attention à la musique de fond du iPod (que l’utilisateur peut démarrer à n’importe quel moment en double-cliquant sur le bouton Accueil, et AVAudioPlayer a la mauvaise manie de bloquer le thread appelant pour une demi seconde lorsqu’on charge une nouvelle musique. C’est pour régler ces problèmes et quelques autres que j’ai créé ma propre interface audio, et je vais vais bientôt le rendre disponible aux autres développeurs (en espérant aider quelqu’un).

Je suis pas mal satisfait du résultat final — mon client, Jeremy, est vraiment ravi de voir le jeu enfin arriver ! J’espère que vous l’aimerez aussi ; Tumiki Fighters sera bientôt maintenant disponible sur le App Store au cas où vous voudriez en faire l’essai.


Application mystère

Surprise ! Pour la majorité d’entre vous qui ne savez pas, j’ai beaucoup travaillé dernièrement pour porter un jeu sur la plateforme du iPhone. Ça a été une expérience intéressante : se démêler avec les certificats cryptographiques d’Apple, jouer avec l’accéléromètre, convertir du code OpenGL à OpenGL ES, sans compter la difficulté de gérer correctement le son et la musique sur la plateforme universelle de la musique qu’est le iPod. (J’en aurai plus à dire sur l’audio dans un autre article.) Maintenant, pendant que mon client et moi attendons patiemment que l’application soit approuvée par Apple, quelqu’un veut jeter un coup d’œil à l’icône et deviner quel jeu c’est ?

mystery-app


Notation hongroise, l'originale

Si vous programmez sur Windows depuis quelque temps, vous connaissez certainement la notation hongroise. C’est une convention où l’on écrit quelques caractères devant chaque nom de variable pour indiquer le type de variable. Par exemple, le nom d’une variable de type int est préfixé de i, un pointeur de p, et un pointeur vers un int de pi. Aujourd’hui, cette pratique n’est pas très bien vue, même chez Microsoft, parce qu’elle est pratiquement inutile et comporte un grand risque d’erreur. J’ai été agréablement surpris cependant quand j’ai appris que cette interprétation n’est qu’un mauvais pli de l’usage original de la notation hongroise telle qu’elle a été inventée à ses débuts.

Voici un extrait de Making Wrong Code Look Wrong (Joel on Software), traduction libre :

Le hongrois d’application était très précieux, spécialement dans le temps du C où le compilateur n’avait pas un système de type très utile.

Mais un jour, quelque chose de mauvais est arrivé.

Le coté obscur s’est emparé de la notation hongroise.

Personne ne sait trop pourquoi ni comment, mais il semblerait que les rédacteurs de documentation dans l’équipe de Windows ont inventé par inadvertance ce que l’on appelera le hongrois système.

Quelqu’un, quelque part, a lu le document de Simonyi, là où il utilise le mot « type, » et a pensé qu’il parlait d’un type, comme une classe, comme dans un système de type, comme la vérification de type faite par le compilateur. Ce n’est pas ça. Il explique très clairement exactement ce qu’il entend par le mot « type, » mais ça n’a pas été suffisant. Le mal était fait.

Le hongrois d’application utilisait des préfixes très utiles, significatifs tel que « ix » pour signifier l’index dans un tableau, « c » pour indiquer un compte, « d » pour la différence entre deux nombres (par exemple « dx » signifiait « largeur ») et ainsi de suite.

Le hongrois système avait des préfixes bien moins utiles, tel que « l » pour le type long et ul pour le type unsigned long et dw pour « double word », qui est, surprise !, un unsigned long. En hongrois système, la seule chose que le préfixe indiquait était le type stockage de la variable.

Donc, en simple, le hongrois d’application est utile pour différencier les données que le compilateur vous laisse mélanger parce qu’elles sont du même type, mais que vous ne devriez pas mélanger. C’est un peu la même analogie que de garder vos unités avec vous en écrivant des formules pour rendre les erreurs plus évidentes.

Mais ça ne s’applique pas qu’au maths…

PHP Markdown utilise une approche similaire

Bien que je ne sois pas certain qu’un suffixe peut se qualifier de notation hongroise, dans PHP Markdown plusieurs chaînes de caractères en ont un : le suffixe _re sur une variable dénote qu’elle contient une expression régulière. Ceci aide à s’assurer qu’aucun caractère n’est passé au parseur d’expression régulière sans être d’abord proprement échappé.

Le résultat final est que c’est très facile de trouver des erreurs. Par exemple, si je vois ceci dans PHP Mardkown, je sais qu’il y a un problème avec la variable $token lorsqu’elle se fait intégrer à une expression régulière sans être d’abord convertie (remarquez l’absence de suffixe _re) :

preg_match('/^(.*?[^`])' . $token . '(?!`)(.*)$/sm', $str, $matches);

Dans ce cas, la solution est d’appeler preg_quote sur $token afin de la rendre sécuritaire pour le parseur d’expression régulière.

C’est intéressant de noter qu’avec les langages qui permettent de définir vos propres types et de surcharger les opérateurs — tel que le C++, lel C# ou le D — vous pourriez définir vos propre types et faire en sorte que le compilateur vous indique vos erreurs. L’effort requis pour la définition de nouveaux types (ainsi que toutes leurs interactions) n’en vaudra cependant peut-être pas la peine comparé à l’utilisation d’une simple notation.



  • © 2003–2024 Michel Fortin.