PDA

Voir la version complète : [GBA][Tutorial] Afficher des scores avec Ximox


Bobby Sixkilla
19/09/2006, 01h03
Afficher des scores avec Ximox
Auteur : rmstudiogames

Bon alors voilà le tuto est double en fait. La premiere partie montre comment afficher du texte en utilisant Ximox. Vous allez voir que c'est extremement simple
La deuxieme montre comment transformer un nombre (par exemple un score a 1942 au bout de 3mn de jeu pour un acharne ) en chaine de caracteres. J'ai codé ça car comme vous allez le voir, le sprintf est dramatiquement lent (mais c'est normal car il fait beaucoup de choses dont nous n'avons absolument pas besoin). Et le temps, c'est de l'argent, euh des fps pardon.

D'ailleurs, regardez les résultats avec un timer qui chronomètre à la vitesse du système (grosso modo à la fréquence du microprocesseur), c'est flagrant, on a un rapport 26!!!

http://rmstudiogames.free.fr/images/misc/Sprintf.png

Bon alors le but du jeu surtout, c'est d'eviter les divisions et les modulos qui viennent tout de suite à l'esprit quand on veut coder ça. Ces deux opérations sont EXTREMEMENT lentes sur la GBA ! Il faut donc s'en passer coute que coute. Restent donc la multiplication et l'addition. Ca tombe bien, ça suffit amplement.

Alors maintenant, passons au code, c'est quand même ça le plus intéressant

#include "Graphics.h"
#include "Text.h"
#include "Timer.h"

#include "stdio.h"

using namespace graphics;
using namespace text;
using namespace timer;

void xsprintf(char *string, long number, long numDigits)
{
long comp;
short iter;

while(numDigits != 0)
{
*string = '0';
for(comp = 1, iter = 1; iter < numDigits; comp *= 10, iter++)
;
while(number >= comp)
{
(*string)++;
number -= comp;
}

numDigits--;
string++;
}

*(++string) = 0;
}

int main(void)
{
long test, time1, time2, scan;
char string[10], string1[10], string2[10];

// On choisit le mode 0 et on active le background 0
SetMode0();
// On reserve le background 0 pour le text manager.
AllocateBackground(background::nBack0);
// On choisit une des deux fontes disponibles en standard.
InstallDefaultFont(dfFont1);
// On cale le timer 0 sur la frequence du systeme.
SetProperties(tTimer0, fSystem);


test = 124650;

// On resette le timer et on le demarre.
SetCount(tTimer0, 0);
Start(tTimer0);
xsprintf(string, test, 6);
Stop(tTimer0);
// Quand c'est termine, on stoppe le timer et on recupere sa valeur.
time1 = GetCount(tTimer0);

// Meme chose ici.
SetCount(tTimer0, 0);
Start(tTimer0);
sprintf(string, "%d", test);
Stop(tTimer0);
time2 = GetCount(tTimer0);

sprintf(string1, "%d", time1);
sprintf(string2, "%d", time2);

// On utilise les commandes du text manager pour afficher tous les resultats.
PrintCenter(2, "TEST D'AFFICHAGE DE NOMBRE !");
Print(2, 3, string);

Print(1, 5, "XIMOX SPRINTF");
Print(2, 6, string1);

Print(1, 7, "C LIBRARY SPRINTF");
Print(2, 8, string2);

while(1);
}


Voilà, j'ai laissé le code du xsprintf non commenté, ce n'est pas très compliqué.

Foxy
19/09/2006, 02h48
On peut faire plus rapide en evitant la multiplication par 10 dans la premiere iteration .
Sinon, c'est vrai que ce genre de routine est utile pour les score, mais ca n'enleve pas l'avantage du sprintf qui lui permet de formater une chaine de carateres en une seule fois en utilisant plusieurs parametres (ex.: "score:%d - hiscore:%d - lives: %d") Donc il faut voir ce qui est le moins couteux au final ;)

omg
19/09/2006, 14h58
Bonjour Foxy! Ravi de te revoir!
Sinon merci pour ce tuto je vais bientôt en avoir besoin!

Mollusk
19/09/2006, 17h20
Foxy, quand j'avais codé mes fonctions texte, avec support %d, %f, %s, et le tout en précisant le nombre de chiffres apres la virgule, etc... Ben ca mettait moins de temps pour faire ca et afficher le texte que le sprintf pour juste convertir...

Donc je suis en faveur du code perso. La raison est simple : sprintf doit avoir tout un jeu de trucs à vérifier dont on n'a pas forcément besoin... Le code est dispo pour si on veut 'ripper' la fonction et la vider de tout contenu inutile ?

Foxy
19/09/2006, 20h51
L'idéal c'est en effet de recoder une fonction qui prend en compte les vargs() en parametres comme le sprintf et de faire une fonction plus ou moins hybride qui permet de tout gerer en une seule fois :)

Si j'ai le temps, j'essayerai de deterrer mes archives ou j'avais recoder une ofnction de ce type avec passage de parametres non predefinis.

[edit:] Pour un source de sprintf: http://www.ruby-doc.org/doxygen/1.8.2/sprintf_8c-source.html

Qui donne un bon exemple sur comment parser des arguments dans une fonction, et un autre source pour l'utilisation des fonction va_xxx():
http://www-ccs.ucsd.edu/c/stdarg.html

Qui permet de passer un nombre indéfini de parametres a une fonction.