contenu des pages Psp-Gun :: Creer vos Hombrews Mon titre contenu des pages
Psp-Gun Index du Forum
Psp-Gun
Le site armée pour une psp
 
Psp-Gun Index du ForumFAQRechercherMembresGroupesProfilS’enregistrerConnexion

Creer vos Hombrews

 
Poster un nouveau sujet   Répondre au sujet    Psp-Gun Index du Forum -> Tutoriels -> Creer Vos homebrews
Sujet précédent :: Sujet suivant  
Auteur Message
Prodig-Y
Big Big Boss

Hors ligne

Inscrit le: 05 Fév 2011
Messages: 50
Point(s): 3 021
Moyenne de points: 60,42

MessagePosté le: Mer 16 Fév - 10:13 (2011)    Sujet du message: Creer vos Hombrews Répondre en citant

Petite Introduction
Lua est un langage de script conçu à l'université de Rio de Janero par Luiz Henrique de Figueiredo, Roberto Ierusalimschy et Waldemar Celes en 1993. Il demeure encore aujourd'hui l'un des langages les plus performants, à la fois en terme de rapidité d'exécution que d'espace. En effet, Lua est très léger (un interpréteur minimal tient sur moins de 100Ko en mémoire) et il est de plus très portable, ce qui le rend très appréciable et apprécié.
Son utilisation peut-être multiple : en tant que langage de programmation à proprement parler, en tant que langage de script pour compléter un autre langage de plus bas niveau tel que le C, pour configurer facilement une application, un menu ou encore une intelligence artificielle. Si vous doutez encore des capacités de ce langage, sachez que de grandes compagnies internationales l'emploient régulièrement, notamment Adobe pour Photoshop Lightroom (un assistant pour photographes professionnels), et il n'est pas rare de le retrouver dans des jeux vidéos tels World of Warcraft ou Far Cry.
Nous verrons donc ici comment installer Lua sur une plateforme PC ainsi que son utilisation primaire via un interpréteur. 
 
 
 

 
 
I. InstallationA) Plateforme Windows
Pour installer Lua sur une plateforme Windows, il vous suffit de vous rendre sur le site du projet « Lua for Windows » et de télécharger la dernière version disponible. Notez que celle-ci installera également l'IDE Scite qui est un éditeur de texte particulièrement bien adapté pour ce langage ainsi que les headers de développement pour l'embarquer dans une application C. 
 
 
 
B) Plateforme UNIX
Deux choix s'offrent à vous pour installer Lua sur une plateforme de type UNIX :
- soit vous êtes sur une distribution UNIX « grand public » : vous disposerez certainement d'un paquet pré-compilé
- soit ce n'est pas le cas et vous devrez alors compiler les sources de Lua pour l'installer. 
 
Dans le cadre de l'installation de paquets pré-compilés, reportez-vous à votre gestionnaire de paquets ou bien entrez les commandes suivantes dans un terminal : 
 
1. Distributions Red Hat, Fedora Et Mandriva
 
 
 
 
Code:
su yum install lua5.1


2. Distributions Debian Et Ubuntu
 
 
 
 
Code:
su apt-get install lua5.1



Si le dépôt de votre distribution ne comporte pas de paquet et que vous ne pouvez vous en procurer sur internet, vous devrez alors télécharger les sources et les compiler.

 
 
 
 
Code:
wget http://www.lua.org/ftp/lua-5.1.tar.gz tar -xvzf lua-5.1.tar.gz cd lua-5.1 su make && make install make clean && make distclean cd .. rm -R lua-5.1/



 
 




II. Premier contact 
 
Nous allons maintenant nous assurer que tout est en place. Lancez un terminal sous UNIX et entrez la commande « lua » ou lancez l'exécutable Lua sous Windows qui doit être visible sur votre Bureau si vous l'avez correctement installé. 
 
Tapez le code suivant et appuyez sur la touche Entrée : 
 
 
 
Code:
print('hello world')




Si « hello world » s'affiche à l'écran après votre première instruction, c'est que tout fonctionne correctement. Nous pouvons donc attaquer les choses sérieuses ! 
 
I. La Notion De Variable
Une variable est un bout de mémoire auquel on fait correspondre une valeur. Pour pouvoir l'utiliser facilement, on lui donne un identifiant, autrement dit un nom. Vous l'avez sans doute compris, une variable est une sorte de conteneur, un tiroir qui va nous servir à stocker des nombres, des caractères, des chaînes de caractères, bref toute une kyrielle d'objets utiles en programmation !
Pour remplir une variable, il faut passer par l'étape de la déclaration de la variable (on lui attribue un nom) et on lui fait correspondre une valeur grâce a l'opérateur d'assignation " = ".


Exemple :



 
 
Code:
Mavariable =  5



Dans ce petit bout de code, Mavariable est le nom de notre variable et 5 le nombre que nous souhaitons y stocker. Mavariablepourrait très bien s'appeler Jean ou Marc, mais on préfère généralement nommer une variable en fonction de ce qu'elle contient : on appellera de préférence Nombre_De_Pommes la variable contenant un nombre de pommes, bien qu'on aurait aussi pu l'appelerVariable_avec_un_nom_de_la_mort_qui_tue. Avouez que ce n'est pas très représentatif du contenu de la variable ! 



Le Lua impose tout de même quelques contraintes pour les noms de variables :
  • Le nom ne doit pas comporter d'espaces ; les caractères spéciaux (comme [, \ ou "), accentués (é, à, ù ...), les opérateurs mathématiques (+, -, = ...) sont également à bannir.
  • Une variable ne doit pas posséder le même nom qu'une autre variable déclarée dans le même bloc d'instructions, sous peine de la remplacer. Les variables sont sensibles à la casse : cela signifie que Variablevariable et variAble sont trois variables différentes !

[*]Le nom ne doit pas commencer par un chiffre.
[*]Une variable ne doit pas être nommée telle un des mots-clés du langage, dont voici la liste:
 
 
Code:
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for',  'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',  'return', 'then', 'true', 'until', 'while'





Je vous disais tout à l'heure qu'on pouvait utiliser une variable pour stocker de nombreuses choses, voici quelques exemples :


 
 
Code:
Mon_Nombre = 932 -- Un nombre Ma_Lettre = 'c' -- Une lettre (ou "caractère"), encadrée par des apostrophes ' Ma_Chaine_De_Caracteres = "Bonjour à toi, ami codeur !" -- Une chaîne de caractères (c'est donc une suite de caractères), encadrée par des guillemets "





J'en profite pour introduire l'utilisation des commentaires. Le début d'un commentaire est indiqué au LuaPlayer par deux symboles "moins" (ou deux tirets).


Exemple :


 
 
Code:
--Mon commentaire





Les commentaires sont des indications laissées par le programmeur pour l'aider à se retrouver dans son code ; par exemple, pour indiquer le rôle de telle ou telle variable, ou une réflexion qui lui a prit un certain temps, ou tout ce qui lui passe par la tête ! Les commentaires sont tout simplement ignorés par le LuaPlayer, alors n'hésitez pas, c'est encore plus pratique que ça en a l'air !


Retenez ceci :


 
 
Code:
Ce code va être lu par le LuaPlayer -- Ce code sera ignoré 









II. Les Conditions
Une condition est une structure qui va effecteur ou non un code en fonction de la véracité de l'expression qu'on lui soumet, rien que ça. 

Les deux mots-clés principaux utilisés dans une condition sont "if" et "then". Pour les anglophobes, il s'agit des équivalents anglais de "si" et "alors". Ces mots-clés encadrent l'expression à vérifier. Cette expression consiste généralement à comparer une variable à un nombre, ou une variable à une autre variable du même type.


Exemple :


 
 
Code:
--On doit tout d'abord définir les variables à comparer NombreA = 6 NombreB = 35   if NombreA > 10 then -- Le code à exécuter dans ce cas end -- Toute structure conditionnelle se termine par un end   if NombreB == NombreA then -- Le code à exécuter dans ce cas end  



Le end clos donc la condition.
Bien entendu, les conditions présentées dans ce code sont purement théoriques, dans le sens ou il paraît stupide de vérifier un résultat que l'on connait déjà, mais vous comprendrez bien vite leur utilité.
Voici une petite liste des opérateurs logiques que vous pouvez utiliser dans vos conditions.







Opérateurs logiques

Signification

==

Égal à

~=

Différent de

<

Inférieur à

>

Supérieur à

<=

Inférieur ou égal à

>=

Supérieur ou égal à




Vous pouvez également vérifier plusieurs expressions en même temps grâce aux deux mot-clés suivants :
  • and : ("et") qui n'exécutera la condition que si les deux expressions sont vraies
  • or : ("ou") qui n'exécutera la condition que si au moins une des deux expressions est vraie



Exemple :


 
 
Code:
--On doit tout  d'abord définir les variables à comparer NombreA = 6 NombreB = 35   if  NombreA > 10 and NombreB == NombreA then -- Le code à exécuter dans ce cas end  



Il existe deux autres mots-clés à connaître pour une condition : les mots-clés "sinon" et "sinon si" ; en Lua, comme dans beaucoup d'autres langages, cela donne else et elseif.
esleif s'utilise dans le cas où on à plusieurs conditions successives à vérifier et qu'une seule d'entre elle peut être bonne. Si le LuaPlayer rencontre une condition esleif alors qu'il a déjà exécuté une des conditions de la structure, il l'ignorera. Il est nécessaire de commencer une structure conditionnelle par un if, autrement l'utilisation d'un 'sinon si' est illogique. On ne place le end qu'à la fin de la structure conditionnelle, après autant de conditions que l'on souhaite. Un else ne vérifiant aucune expression, il ne requiert pas de then.


Exemple :



 
 
Code:
-- On doit tout d'abord définir les variables à comparer NombreA = 11 NombreB = 35   -- Début de la structure conditionnelle, elle commence nécessairement par if if NombreA > 10 then  -- Si NombreA est supérieur à 10, alors : -- Le code à exécuter dans ce cas elseif NombreA == 10 then -- Sinon, si NombreA vaut 10, alors -- Le code à exécuter dans ce cas elseif NombreA ~= NombreB and NombreA < 0  then -- Sinon, si NombreA ne vaut pas NombreB et NombreA est négatif, alors --Le code à exécuter dans ce cas else -- Dans tous les autres cas : -- Le code à exécuter end



Voilà, vous savez tout ce qu'il faut savoir sur les conditions, abordons les boucles désormais !






III. Les Boucles
Les boucles sont un des outils les plus utilisés dans les programmes. Il est important de comprendre que le LuaPlayer lit votre code du début à la fin et s'il n'a plus rien à lire, s'il n'a plus aucune commande à exécuter, il s'arrêtera. Un programme étant souvent voué à durer dans le temps, on va vouloir faire en sorte que certaines parties de notre code soient lues plusieurs fois par le LuaPlayer : c'est le but de boucles.


Une boucle est un morceau de code qui serait répété tant qu'une condition est vraie. Comment ça marche ? C'est très simple. Tout d'abord, on distingue trois types de boucles :
  1. La boucle while (...) do ... end
  2. La boucle repeat ... until (...)
  3. La boucle for (..., ..., ...) do ... end



1. La Boucle While (...) Do ... End


C'est la boucle la plus courante, sa syntaxe est la suivante :


 
 
Code:
while (condition à vérifier) do instruction end





La véracité de l'expression en condtion est vérifiée au début de chaque tour de boucle et le code sera exécuté tant qu'elle sera vraie.



Exemple :



 
 
Code:
Vie_du_Heros = 10 while (Vie_du_Heros > 0) do -- Tant qu'il reste de la vie au héros, on exécute notre code : -- Code du jeu end





Vous noterez le fait que nous utilisons des parenthèses : elles servent à isoler les différents éléments afin de clarifier le code. Dans certains cours, vous verrez des boucles ayant pour condition true ("vrai" en anglais). Il s'agit d'un mot-clé qui  est toujours vrai, c'est donc une boucle qui ne s'arrête jamais.
Vous pouvez à tout moment stopper l'exécution d'une boucle en insérant la commande break ; l'exécution reprendra après le endfinal de la boucle actuelle.



Exemple :



 
 
Code:
m = 1 while true do   -- [...] autres codes [...]   m = m + 1   if m == 20 then     break   end end





On revoit ici l'opérateur d'assignation '=' et on introduit l'opérateur d'addition '+'. On aura 20 tours de boucles avant que la boucle ne se casse.


2. La Boucle Repeat ... Until (...)


La boucle repeat ... until (...) est très similaire à la boucle while (...) do ... end, sauf que l'expression sera évaluée à la fin de chaque tour de boucle (au lieu d'être vérifie au début), elle s'exécutera donc au moins une fois. Sa syntaxe est la suivante :


 
 
Code:
repeat   instruction until (condition)





Exemple :



 
 
Code:
m = 1 repeat   m = m + 1 until (m == 20)





On aura donc 20 tours de boucles avant de sortir de la boucle. Dans le code suivant, nous allons mettre en évidence la différence qu'il existe entre la boucle repeat ... until (...) et la boucle while (...) do ... end :


 
 
Code:
m = 1   while m <= 0 do     m = m+1 end





Le code à l'intérieur de la boucle ne sera pas exécuté car m n'est pas négatif. Après ce bout de code, m vaudra donc toujours 1.


 
 
Code:
m = 1   repeat   m = m+1 until (m > 0) -- Jusqu'à ce que m soit supérieur à 0





Désormais, la boucle sera exécutée même si m n'est pas négatif ; après ce code, m vaudra 2.



3. La Boucle For (..., ..., ...) Do ... End


La boucle for (..., ..., ...) do ... end est une boucle un peu à part ; elle est ce qu'on appelle une boucle d'incrémentation, c'est-à-dire qu'elle permet de faire varier une variable très facilement. On va créer dedans une variable, la valeur qu'elle doit atteindre et le pas (qui peut être négatif). Nous verrons que cette boucle est très pratique pour parcourir des tableaux de données (que nous verrons plus tard). Voici sa syntaxe :


 
 
Code:
for (variable = valeur de début, valeur de fin , pas) do   instruction end



Vous remarquerez que le pas est facultatif, par défaut il est à +1, ne l'indiquez que si vous en voulez un autre. On appelle généralement la variable que l'on incrémente i (pour itérateur).


Exemple:


 
 
Code:
nombreX = 30 compteur = 0   for (i = 1, 100) do   nombreX = nombreX + i   if (nombreX > 200 and compteur == 0) then     compteur = i   end end





Dans ce code, on fait varier i de 1 à 100 ; à chaque tour de boucle, on le rajoute à nombreX qui vaudra donc 30 + 1 + 2 + 3 + 5 etc...
La variable compteur contiendra le numéro du tour où nombreX a dépassé 200 (on vérifie que c'est bien la première fois en vérifiant que compteur est égal à 0, sinon il serait écrasé à chaque tour à partir du moment où nombreX dépasse 200)
Notez qu'on pourrait écrire le programme précédent avec une boucle while de la manière suivante :


 
 
Code:
nombreX = 30 compteur = 0   i = 1 while (i ~= 100) do   nombreX = nombreX + i   if (nombreX > 200 and compteur == 0) then     compteur = i   end   i = i+1 end





Ce que vous avez appris aujourd'hui va vous servir constamment lorsque vous programmerez, soyez sûr d'avoir bien tout compris, et n'hésitez pas à y revenir. Il faut bien comprendre que vous avez acquis des outils, si vous voulez désormais qu'un code se répète plusieurs fois, utilisez une boucle ; si vous avez besoin de stocker quelque chose, utilisez une variable ; si vous ne voulez exécuter un code que dans certains cas, utilisez une condition. Cette notion d'outil est très importante en programmation, elle va vous permettre de structurer vos programmes.

I. Afficher Du Texte À L'écran

Dans ce cours, nous allons commencer à afficher du texte sur l'écran. La fonction qui permet d'afficher des données sur une texture est : 



 
 
Code:
texture:print( position en abscisses, position en ordonnées, données à écrire sur la texture, couleur à utiliser)





Nous introduisons ici pour la première fois une fonction, une méthode pour être plus précis. Une fonction en programmation est une sorte de petite usine, on lui donne des matières premières et elle nous renvoie un produit fini. La méthode s'applique ici sur la surface texture qui est la surface sur laquelle on va écrire. Les informations que l'on trouve entre parenthèses sont appelées desarguments, ce sont les matières premières - les directives - que l'on donne à la fonction pour qu'elle nous renvoie le résultat que l'on souhaite. Cette fonction prends 4 arguments.


La fonction texture:print() s'utilise généralement sur la surface 'screen', qui est une surface définie par le Lua Player et qui correspond à l'écran de la PSP, la surface sur laquelle nous écrivons généralement.


Nous allons maintenant détailler les arguments de cette fonction :
  • Les deux premiers arguments sont la position à laquelle nous souhaitons écrire, en x et en y (la valeur donnée doit être en pixels). Vous devez savoir que la PSP possède un écran de 480 pixels de longueur et 272 pixels de hauteur (480*272 pour être plus rapide 
    ). Regardez cette image si vous ne comprenez toujours pas : 



 
 
  • 'position en abscisses'  est donc la la position en x de départ de l'écriture, 'position en ordonnées' étant la position en y.
  • Le troisième argument est la donnée à écrire a l'écran ; cela peut être du texte (encadré par des guillemets " "), une valeur, ou une variable contenant des données : ce seront alors les données qui seront affichées.
  • Le quatrième argument est la couleur d'écriture. Pour définir une couleur, vous devez utiliser la fonction Color.new(R,G,B) ( attention à la majuscule de "Color"). Cette fonction renvoie un code couleur en fonction du code RGB donné en paramètres. Qu'est-ce que le code RGB ? C'est simple, ce sont les quantités de rouge, vert et bleu ( Red, Green et Blue en anglais) comprises entre 0 et 255 ; par exemple, (255,0,0) est la couleur pour du rouge pur, (255,0,50) sera du rouge avec un peu de bleu. Pour trouver les codes RGB de vos couleurs, c'est facile :
Ouvrez Paint puis cliquez sur "Couleurs", ensuite sur "Modifier les couleurs", vous obtiendrez une fenêtre comme celle-ci :




 
 
Cliquez sur "Définir les couleurs personnalisées" ; voici la fenêtre que vous obtiendrez :



 
 
Sur cette fenêtre, j'ai sélectionné la couleur rouge comme dans mon exemple et vous pouvez constater en bas à droite qu'apparaît le code de ma couleur rouge.



Voilà, maintenant que tout est clair, on va afficher un texte à l'écran.


 
 
Code:
screen:print(150,100,"Mon premier programme en lua par benja32", Color.new (255,0,0))





On affiche donc à une position x de 150, une position y de 100, la phrase : Mon premier programme en lua par benja32 en rouge.


Maintenant, nous devons ajouter la fonction screen.flip(). Cette fonction permet d'intervertir l'état des deux tampons. 
 C'est un peu compliqué alors je vais essayer d'expliquer simplement : toutes les opérations d'affichage se font sur un écran virtuel et cette fonction (je parle de la fonction screen.flip()) permet de remplacer l'écran qui est actuellement affiché par l'écran virtuel. Conséquence directe : si vous n'appelez pas cette fonction, vous ne verrez rien à l'ecran ! On parvient donc à faire apparaître le texte à l'écran mais cela ne dure qu'une fraction de secondes. Pour afficher le texte en continue, nous allons utiliser ce que vous avons appris précédemment : une boucle !


Dans ce cas précis, nous alons utiliser une boucle while et, comme nous voulons afficher notre texte en continu, nous allons mettretrue en condition. Nous allons aussi ajouter la fonction screen.waitVblankStart() juste avant le screen.flip() : cette fonction permet de vérifier que l'écran est bien prêt a être affiché. Dans le cas contraire, le programme attendra que cela soit le cas. On évite ainsi les effets de clignotement de l'écran ; n'oubliez donc pas cette fonction ! Et n'oubliez pas non plus le end qui fermera la boucle.


Assez parlé, place au code !


 
 
Code:
while true do     screen:print(150,100,"Mon premier programme en lua par benja32", Color.new (255,0,0))     screen.waitVblankStart()     screen.flip() end



Voici une image de ce que vous obtenez : 





 
 



II. Exemples D'application

Ce n'était pas dur, si ? 
 Maintenant, nous allons voir qu'en combinant ce que vous avez appris précédemment et ce que nous venons juste d'apprendre, on peut déjà faire beaucoup de choses !


Utilisation de la boucle for et affichage d'un texte en conséquence :


Pour le coup, je vous donne directement le code et je l'expliquerai après ; essayez de le comprendre par vous-même avant de lire les explications. 





 
 
Code:
y = 1 while true do     for y = 1, 272 do         screen:clear()         screen:print(230,y,y,Color.new(255,255,255))         screen.waitVblankStart()         screen.flip()     end     for y = 272, 1, -1 do         screen:clear()         screen:print(230,y,y,Color.new(255,255,255))         screen.waitVblankStart()         screen.flip()     end end  





Ce code va afficher un nombre contenu dans une variable  y, à une position y, en faisant varier y entre 1 et 272 (la taille de l'écran en ordonnées) ; la boucle while permet de recommencer constamment le code. La première boucle for augmente progressivementy, le nombre augmente, donc le nombre affiché descend. Il correspond à sa position en ordonnées. La seconde boucle fait l'inverse : le nombre y part de 272 et diminue jusqu'à atteindre la valeur 1. 



Il y a aussi une fonction dont je vous ne vous avais pas encore parlé : screen:clear() efface l'écran avec la couleur passée en paramètre. Si aucun paramètre n'est donné, elle efface en noir. Vous pourrez vous passer de cette fonction lorsque vous saurez afficher une image de fond (dans le prochain cours) mais, en attendant, essayez pour voir ce que ça donne sans 



On peut même pousser le vice un peu plus loin en utilisant y pour faire varier la couleur, mais dans ce cas-là on va limiter nos boucles for pour qu'elles ne fassent pas dépasser y de 255 (la quantité maximum d'un composant d'une couleur).


Voici ce que cela va donner:



 
 


 
 
Code:
y = 1 while true do     for y = 1, 255 do         screen:clear()         screen:print(230,y,y,Color.new(y,255,255))         screen.waitVblankStart()         screen.flip()     end     for y = 255, 1, -1 do         screen:clear()         screen:print(230,y,y,Color.new(255,y,255))         screen.waitVblankStart()         screen.flip()     end end  



Ici y sert aussi à faire varier la couleur du texte car on l'utilise comme paramètre pour le composant rouge dans la première boucle et dans le composant vert pour le second. Si vous ne comprenez pas tous ces exemples, relisez bien les cours précédents, et n'hésitez pas à aller demander des explications sur le forum, il est normal que vous soyez un peu perdu au début, mais vous avez tous les outils pour comprendre ce code.
Imaginons maintenant que nous voulons ajouter du texte devant la variable, on va utiliser l'opérateur de concaténation .. (deux points) qui sert à rassembler plusieurs données en une chaîne de caractères. Dans notre cas on va faire :


 
 
Code:
screen:print(230,y,"La valeur de y est de : " .. y,Color.new(y,255,255))





On aurait aussi pu ajouter du texte après : 



 
 
Code:
screen:print(230,y,La position de y est de : " ..  y .. "pixels",Color.new(y,255,255))



Voilà pour la concaténation.





III. Autres Opérations Sur L'écran
Vous en voulez encore ? D'accord, alors accrochez-vous bien ! 



Tant qu'à faire, nous allons apprendre une nouvelle fonction : screen:drawLine( X de départ, Y de départ, X d'arrivée, Y d'arrivée, couleur). Cette fonction va tracer une ligne de la couleur choisie entre un point de départ et un point d'arrivée, tous deux définis par leurs coordonnées respectives.


On va faire un petit programme avec deux lignes qui parcourent l'écran, une de haut en bas et une seconde de gauche à droite :


 
 
Code:
y = 1 for y = 1, 480 do   screen:clear(Color.new(91,42,109))   screen:drawLine(0, y, 480, y, Color.new(44,5,59))   screen:drawLine(y, 0, y, 272, Color.new(44,5,59))   screen.waitVblankStart()   screen.flip() end



Rien de nouveau ici, on trace juste les lignes ; on a également choisi une couleur pour le fond grâce aux arguments descreen:clear(). Testez ce code sur votre PSP.



 
 
 
 
L'écran de la PSP n'étant pas carré, la ligne horizontale sort de l'écran bien avant la ligne verticale. 
 Nous allons resoudre ce problème en un instant grâce a un peu de mathématiques :


 
 
Code:
y = 1 for y = 1, 480 do   screen:clear(Color.new(91,42,109))   screen:drawLine(0,y*(screen:height()/screen:width()),480,y*(screen:height()/screen:width()),Color.new(44,5,59))   screen:drawLine(y,0,y,272,Color.new(44,5,59))   screen.waitVblankStart()   screen.flip() end  





texture:height() et texture:width() permette de récupérer respectivement la longueur et la largeur d'une texture, ici screen (donc 480 et 272). On multiplie ainsi y par la fraction 272/480, puisque c'est le rapport entre la longueur et la largeur (règles de proportionnalité).
Bon, ça marche, mais si comme moi vous avez une dent contre les maths, et bien on va essayer de faire autrement ! Je disais tout a l'heure : l'écran de la PSP n'est pas carré.
Qu'à cela ne tienne ! On va créer un autre écran, carré celui-ci (on ne laisse pas les maths nous pourrir la vie ! 
).
Allez, c'est parti pour une nouvelle fonction ! Je vous présente Image.createEmpty(largeur, hauteur) qui sert à créer une surface. Par défaut, celle-ci est transparente. Dans notre cas, nous allons créer une surface carrée de 272 pixels de côté que nous allons enregistrer dans une variable nommée NewScreen.




 
 
Code:
y = 1 NewScreen = Image.createEmpty(272,272) for y = 1, 272 do     NewScreen:clear(Color.new(91,42,109))     NewScreen:drawLine(0,y,480,y,Color.new(44,5,59))     NewScreen:drawLine(y,0,y,272,Color.new(44,5,59))     screen:blit(104, 0, NewScreen)     screen.waitVblankStart()     screen.flip() end  





Comme vous le voyez, on effectue les opérations d'affichage/nettoyage sur NewScreen et on l'affiche lui-même sur screen grâce a la fonction Texture1:blit(Position X, Position Y, Texture2), qui permet de coller Texture2 sur Texture1 (ici NewScreen sur screen) à la position voulue. L'important est que nous ayons réussi à créer un écran virtuel carré. Vous remarquerez les positions x et y des fonctions d'affichage (ici drawLine() mais ça vaut pour les autres) mesurent à partir du coin supérieur gauche de la structure sur laquelle ils sont appliqués, et non le coin de l'écran. Voici un aperçu du résultat :



 
 
La technique fonctionne, néanmoins il vaut peut être mieux utiliser un peu de maths, vu la surface perdue 





IV. Exercices
Ne croyez pas que je vais vous laissez partir comme ça ! Pas question ! Je vous propose deux exercices faciles qui vont vous permettre de vérifier que vous avez tout compris :


Premier exercice :




 
 
Code:
nombreX = 30 compteur = 0   i = 1 while (i ~= 100) do   nombreX = nombreX + i   if (nombreX > 200 and compteur == 0) then     compteur = i   end   i = i+1 end





Ajoutez à la fin du code une boucle où vous afficherez : "La dernière valeur de nombreX était : " suivie de la valeur contenue dansnombreX, et "nombreX a dépassé 200 au " la valeur de compteur "ème tour".


Deuxième exercice :




 
 
Code:
y = 1 for y = 1, 480 do   screen:clear(Color.new(91, 42, 109))   screen:drawLine(0, y*(screen:height()/screen:width()), 480, y*(screen:height()/screen:width()),Color.new(44, 5, 59))   screen:drawLine(y, 0, y, 272, Color.new(44, 5, 59))   screen.waitVblankStart()   screen.flip() end





Vous devez modifier ce code pour y ajouter le retour des lignes dans l'autre sens, et un autre petit détail qui permettra au programme de tourner en boucle (alterner le déplacement dans un sens, puis dans l'autre, et ce sans arrêt). Au travail ! 

Tout d'abord, vos images doivent être au format .png ou .jpg et ne doivent pas dépasser 512×512 (pour un background, 480×272 est plus adapté (taille de l'écran)).
Avant toute chose nous allons enregistrer une couleur: Vous vous souvenez de la fonction Color.new(R,G,B)? Elle renvoie un code couleur. Eh bien on peut tres bien enregistrer ce code dans une variable, ici elle va contenir du bleu, alors nous allons l'appelerbleu.


 
 
Code:
bleu = Color.new(0,0,255)



Voila, cette couleur n'a rien a voir avec l'image, elle va nous servir plus tard pour l'affichage du texte, cela permet de gagner du temps d'exécution en appelant cette fonction une seule fois.
Cela dit, préoccupons nous de notre image: Avant toute chose il faut la charger en mémoire, pour cela on utilise la fonction:


 
 
Code:
ImageDeFond = Image.load("background.png")




Et voila l'image background.png est chargée dans une variable, qu'on a appelée ImageDeFond. Je suppose que vous vous demandez où placer l'image, vous devez la mettre à côté de votre script.lua. Si vous voulez faire un dossier “images” pour mettre toutes les images de votre homebrew, vous devrez charger l'image comme ça:
Code:
[right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=3][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]background = Image.load("images/background.png")

[/code]



Maintenant que notre image est en memoire, on va pouvoir l'afficher a l'ecran, grace a la fonction 

Code:
[code][right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=4][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]screen:blit(posX,posY,texture)

[/code]

[code]

[/code]
[/code]

Les coordonnées définissent la position du coin supérieur gauche de l'image, par rapport au point superieur gauche de l'ecran, c'est le même principe que pour le texte. texture est l'image a afficher, dans notre cas ca sera ImageDeFond.

Resumé du code :
Code:
[code][code][right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=5][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]bleu = Color.new(0,0,255) ImageDeFond = Image.load("background.png") screen:blit(0,0,ImageDeFond)--On place notre image dans le coin superieur gauche.

[/code]


[/code]

[/code]

Voici l'image que nous allons utiliser (veillez bien a ce qu'elle ai le même nom que celui indiqué dans le code.)



Maintenant, on va afficher du texte à l'écran donc sur l'image, je vais vous donner un petit truc qui est super important si vous voulez voir votre texte à l'ecran ! Prenons 2 exemples:
Code:
[right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=6][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]screen:print(100, 00," La psp est une console portable géniale", rouge) screen:blit(0,0,ImageDeFond)

[/code]



et
Code:
[right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=7][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]screen:blit(0,0,ImageDeFond) screen:print(100, 00," La psp est une console portable géniale", rouge)

[/code]



Je crois que vous avez compris que l'exemple numéro deux est le bon car si vous suivez l'exemple numéro 1, le texte sera affiché avant l'image donc l'image “recouvrira” le texte et il ne sera pas visible à l'écran. Continuons notre code, nous allons afficher comme texte ceci:
Code:
[right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=8][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]text = "XtreamLua est un site proposant" screen:print(100,100, text, bleu) screen:print(100, 120, "les meilleurs cours de programmation en lua",bleu)

[/code]



Voilà, je crois que vous avez compris le système, voici le code source complet et un screenshot du résultat final.


Code source complet :
Code:
[right][url=http://www.xtreamlua.com/plugins/content/highlight/vista_plana.php?source=9][img]http://www.xtreamlua.com/plugins/content/highlight/vista_plana.png[/img][/url] [/right][code]-- couleur bleu = Color.new(0,0,255)--On charge une couleur -- image background = Image.load("background.png")--on charge une image --text text = "XtreamLua est un site proposant"--On met un de nos textes dans une variable, ce n'est pas necessaire, mais on est la pour s'entrainer!   --boucle conditionnelle while true do screen:blit(0,0,background)--On affiche tout d'abord notre image de fond screen:print(100,100, text, bleu)--On ecris notres premier texte, contenu dans une variable screen:print(100, 120, "les meilleurs cours de programmation en lua",bleu)--on ecris notre second texte, directement screen.waitVblankStart() -- on verifie que notre ecran est pret screen.flip()-- on met a jour notre ecran end

[/code]




Introduction:
Depuis le l'apparition de la programmation, on utilise des fonctions, et en Lua on peut aussi le faire, c'est ce que nous allons montrer tout à l'heure. Sachez qu'une fonction sert principalement à nous faciliter le développement en effectuant des tâches répétitives et permettent d'avoir un code plus lisible. Mais, comment fait-on une fonction, et comment ça marche?
Pour vous éclairer un peu, une fonction est un peu comme une usine, on lui donne ce dont on a besoin, les matières premières, pour avoir un résultat fini et propre à la fin de plusieurs étapes de peaufinage.
Dans ce cours, nous allons d'abord voir les bases d'une fonction, puis nous approfondiront nos compétences sur les fonctions et finiront par un exercice d'application avec corrigé pour voir si vous avez bien compris le fonctionnement de tout ce tralala. 

Vous êtes prêts, c'est parti!

Sachez que pour une meilleure lisibilité, la structure de chaque nouveauté se fera sur ce modèle: 
-Mini-introduction
-Exemple
-Explications.

I - Apprenez les bases d'une fonction
1) Reconnaître une fonction
Toutes les fonctions en lua sont reconnaissables grâce au petit mot-clé : function. 

Exemple :

Syntaxe: [ Télécharger ] [ Masquer ]
function myFunc(args)
        --instructions
end




Explications :
myFunc: le nom de la fonction, c'est notre usine
args: le(s) argument(s) passés à la fonction, ce sont les matières premières
instructions : le code que vous souhaitez mettre dans la fonction, c'est ce qui va servir à peaufiner nos matières premières.

2) D'autres façons de faire une fonction
La méthode vue au-dessus n'est pas la seul méthode pour faire une fonction, car en lua, une fonction est avant tout une variable, on peut donc faire, pour l'exemple précédent:


Syntaxe: [ Télécharger ] [ Masquer ]
myFunc = function(args)
        --instructions
end




L'appel de cette fonction fera la même chose que notre première fonction.


Dans nos deux premiers exemples, nous avons nommé notre fonction: myFunc, sachez que vous n'êtes même pas obligés de donner un nom à votre fonction lua, vous pouvez la créer pendant un calcul par exemple:


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ]
3 * (function(nombre) 
return nombre * 2
end
) (5)




Ce code équivaut à:
3 * (5 * 2)

3) A quoi sert une fonction
Le plus souvent, les fonctions sont utilisées pour faire des tâches répétitives dans un programme, par exemple : dans un programme, on veut afficher plusieurs fois un texte centré sur l’écran avec une position en ordonnées non fixe, on pourrait faire :


Syntaxe: [ Télécharger ] [ Masquer ]
screen:print(240 – string.len("Mon texte 1") * 4, 100, "Mon texte 1")
screen:print(240 - string.len("Mon deuxieme texte") * 4, 130, "Mon deuxieme texte")
screen:print(240 - string.len("Le texte 3") * 4, 160,"Le texte 3")




Mais on peut aussi se créer une fonction pour nous simplifier la vie, c'est pas cool ça?

Voici ce que cela pourrait donner:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function ecritCentre(y, texte) 
        return screen:print(240 - string.len(texte) * 4, y, texte)
end

ecritCentre(100,"Mon texte 1")
ecritCentre(130,"Mon deuxieme texte")
ecritCentre(160,"Le texte 3")





C'est moins fastidieux, non? 


Explications:
ecritCentre: le nom de la fonction
y: la position en ordonnée de notre texte
texte: le texte à centrer
string.len(texte): renvoi la longueur du texte
240 - string.len(texte) * 4: sachant qu'une lettre fait environ 8 pixels de long, et que l'écran de la PSP en fait 480, pour centrer, on prend la moitié de la longueur de l'écran de la PSP et on lui enlève la moitié de la longueur du texte.
return: un mot clé en Lua, nous verrons comment ça marche dans la seconde partie de ce cours.

4) Supprimer une fonction
Il peut arriver que dans votre programme, vous n'ayez plus besoin de votre fonction, donc autant la supprimer pour éviter des erreurs, pour supprimer une fonction, rien de plus simple, il suffit de la mettre à nil:


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function addition(a,b)
        return a + b
end

addition(5,2)

addition = nil

addition(5,2)





Explications
Le premier appel à la fonction addition retournera 7, mais la deuxième retournera une erreur, car la fonction a été supprimée juste avant avec addition = nil. 


Ceci conclut la première partie de ce cours, maintenant, vous connaissez les bases de toute fonction, mais vous en voulez encore plus? Alors suivez bien la seconde partie de ce cours, et vous serez incollables sur le fonctionnement des fonctions en Lua.


II - Approfondissez vos connaissances
1) Le mot clé return
Dans le code précédent, nous avons utilisé 'return', ce mot-clé permet à la fonction de retourner quelque chose. C'est très utile dans divers cas, par exemple pour retourner une ligne précise dans un fichier:


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function retLine(chemin, line)
local file = io.open(chemin,"r")
        for = 1, line do
                ret = file:read()
        end
file:close()
return ret
end

retLine("fichier.txt", 5)





Explications:
A chaque fois que la boucle est incrémentée(on ajoute 1), ret vaut la ligne numéro i, donc a la fin, i vaudra line, et la boucle se terminera, on pourra retourner la ligne désirée.
Ici, on veut récupérer la 5e ligne du fichier nommé "fichier.txt".
ret est la variable à retourner, donc ici, c'est notre ligne.

2) Loi sur les variables
Comme expliqué dans le première partie du cours, une fonction lua est avant tout une variable, on peut donc très bien faire une fonction de "base" et une autre ayant la même vocation sans pour autant réécrire tout la fonction une deuxième fois, car vous le savez, le programmeur est un flemmard 
:


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function addition(a, b, c)
        return a + b + c --retourne la somme de trois nombres
end

somme = addition

somme(2,5,9)





Explications:
On se base sur le fait que pour une variable, si on fait maVariable1 = maVariable2, alors maVariable1 vaudra la même chose que maVariable2, ici maVariable1, c'est la fonction somme, et maVariable2, c'est la fonction addition.
A ce moment, somme(2,5,9) retournera donc 2 + 5 + 9, c'est à dire 16!

3) Le retour multiple
Jusqu'ici, on n'a appris à retourner qu'une seule variable, mais sachez qu'on peut aussi retourner plusieurs choses avec une seule fonction en séparant les variables à retourner d'une simplevirgule, prenons un exemple simple: les opérateurs + - / *


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function operateurs(a,b)
        return a+b,  a-b,  a/b,  a*b
end


add, sous, div, mult = operateurs(5,2)





Explications:
Grâce au retour multiple, add vaudra le premier retour de operateurs, sous le deuxième, div le troisième et mult le quatrième.
Ce qui nous donnera: add = 7, sous = 3, div = 2,5 et mult = 10.

Sachez que vous pouvez faire autant de retours multiples que vous le voulez avec une seule fonction.
Si vous retournez plus de choses que de variables que vous demandez, la première variable vaudra le premier retour, etc.. mais ls retours en trop seront ignorés. Si par contre vous demandez plus de variables que de retours possibles, les variables en trop vaudront 'nil'.

4) Les arguments illimités
En lua, vous pouvez passer autant d'arguments que vous le souhaitez, mais il se peut que vous ne sachiez pas le nombre total d'arguments passés, la lua a donc les arguments illimités.
Sachez que tous les arguments passés à une fonction sont stockés dans un tableau appelé: arg et que le nombre d'arguments passés à la fonction est stocké dans: arg.n:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function myFunc(...)
for i = 1, arg.n do
--quelque chose
end

return arg[1]
end

myFunc("texte", 2, "abc")
 





Explications:
Les '...' sont les marqueurs des arguments illimités en Lua.
La fonction retournera arg[1] = "texte"


Maintenant vous savez normalement le principal sur les fonctions Lua, nous allons tester vos connaissances à travers un exercice d'application.

III - Exercice d'application
Vous allez devoir créer une fonction(on se demande bien pourquoi? 
) qui convertira des dollars en euros, mais avec certaines conditions:
-La fonction comprend un nombre illimité d'arguments
-Depuis les arguments donnés en dollars, vous les convertirez en euros
-Vous ferez la somme de tous ces arguments
-Vous retournerez la somme ainsi que le nombre d'arguments initial
-Vous écrirez à l'écran comme suit: "La somme des 'nombre d'arguments' nombres entres en dollars fait: 'somme' euros"
-Enfin, vous supprimerez ensuite la fonction.

Info: 1 euro = 1,25 dollars
Vous prendrez pour l'exemple la somme de 15, 28, 78 et 1,2 dollars

Allez-y, Codez!


Vous n'y arrivez pas? Et bien regardez la correction et apprenez de vos erreurs:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
function somme(...) --Création de la fonction avec les arguments illimités
local maSomme = 0 --Création de la somme à retourner

  for i = 1, arg.n do --Pour tous les arguments
    maSomme = maSomme + (arg / 1.25) --On ajoute à la somme la conversion de l'argument en cours
  end

return maSomme, arg.n --On retourne la somme et le nombre d'arguments
end

sommeEuros, nombreSomme = somme(15,28,78,1.2) --On demande la somme en euros et le nombre d'arguments passés à la fonction.

screen:clear() --On nettoie l'écran
screen:print(10,100,"La somme des "..nombreSomme.." nombres entres en dollars fait: "..sommeEuros.." euros", Color.new(255,255,255)) --On écrit le texte demandé en blanc

while true do
screen.waitVblankStart()
screen.flip()
end

somme = nil --On supprime la fonction
 





Et bien voilà, ce n'était pas si compliqué!
Et voici un screenshot du rendu final:



Conclusion:
Et voici que ce termine ce cours sur les fonctions, j'espère que vous avez bien compris les bases d'une fonction, et si oui, avez réussi à approfondir vos connaissances. Vous devez maintenant savoir comment une fonction se construit: avec le mot clé 'function' et son utilité: les tâches répétitives par exemple. 
Reconnaissance Des Touches


Bonjour à tous.


Dans ce tutoriel, nous aborderons la gestion des touches de votre PSP, en LUA.


I) LA Fonction Qui Vous Permet D'interagir Avec Votre Programme.


Le but de ce tutoriel est de vous apprendre à interagir avec les touches sur votre PSP dans vos programmes. A quoi cela peut-il bien servir ? Plusieurs utilisations: 


  • Faire avancer un programme. Comme lors d'une installation d'un programme sur votre Ordinateur, le programme ne s'exécute que si vous appuyez sur les boutons "Suivant", "Quitter", "Annuler" et autres. 
  • Gérer des déplacements. Dans n'importe quel jeu, vous aurez besoin de déplacer votre personnage, un objet, de faire un choix dans un menu etc.. C'est grâce à la lecture des touches que tout cela s'effectue.
  • Tous les autres cas que vous pourrez imaginer.





La fonction qui permet tout cela se présente comme suit :

 

 
Code:
[i]Controls.read()[/i]




Ce qui pourrait être traduit approximativement par : "Lecture des contrôles".
En effet, cette fonction va lire l'état des touches, et vous le renvoyer. Elle ne prend aucun paramètre.

Par exemple, si l'on souhaite savoir si la touche X est pressée, on va utiliser :





 

 
Code:
[i]Controls.read():cross()[/i]





qui renverra true si c'est le cas, false sinon.

Et en pratique? Comment va-t-on utiliser ca ? Un petit programme d'exemple devrait vous éclairer, lisez bien les commentaires et essayez de comprendre.




 

 
Code:
[i][list=1][*] [/i]
[*][i] [/i]
[*][i] [/i]
[*][i] [/i]
[*][i] [/i]
[*][i]blanc = Color.new(255, 255, 255) --On enregistre la couleur blanche dans une variable blanc.[/i]
[*][i] [/i]
[*][i]--On commence notre boucle principale.[/i]
[*][i] [/i]
[*][i]while true do[/i]
[*][i] [/i]
[*][i]screen:clear()  --on nettoie l'écran.[/i]
[*][i] [/i]
[*][i]if Controls.read():cross() then  -- Si on appuie sur la touche croix,[/i]
[*][i] [/i]
[*][i]screen:print(5, 5, "Touche croix !", blanc) --On affiche "Touche croix !".[/i]
[*][i] [/i]
[*][i]end --Fin de la condition.[/i]
[*][i] [/i]
[*][i]screen.waitVblankStart() --on raffraichit l'écran[/i]
[*][i] [/i]
[*][i]screen.flip() --Idem[/i]
[*][i] [/i]
[*][i]end --Fin de la boucle principale.[/i]
[*][i] [/i]
[*][i] [/i]
[i][/list][/i]





Que fait ce programme ?  
Dès qu'on appuie sur la touche Croix, le programme affiche à (5; 5) la phrase "Touche croix !" en blanc. Tout simplement. 


Vous voulez peu-être la liste des touches de la PSP (à remplacer à la place de "cross" dans l'exemple ci-dessus).

Je les donnerais dans cet ordre : Touche, traduction, code pour la touche.







 

 
Code:
[i][list=1][*] [/i]
[*][i] [/i]
[*][i] [/i]
[*][i] [/i]
[*][i] [/i]
[*][i]croix = cross.  Controls.read():cross()[/i]
[*][i] [/i]
[*][i]rond = circle.  Controls.read():circle()[/i]
[*][i] [/i]
[*][i]triangle = triangle.  Controls.read():triangle()[/i]
[*][i] [/i]
[*][i]carre = square.  Controls.read():square()[/i]
[*][i] [/i]
[*][i]haut = up. Controls.read():up()[/i]
[*][i] [/i]
[*][i]gauche = left.  Controls.read():left()[/i]
[*][i] [/i]
[*][i]droite = right. Controls.read():right()[/i]
[*][i] [/i]
[*][i]bas = down. Controls.read():down()[/i]
[*][i] [/i]
[*][i]gachette L = l. Controls.read():l()[/i]
[*][i] [/i]
[*][i]gachette R = r. Controls.read():r()[/i]
[*][i] [/i]
[*][i]start = start.  Controls.read():start()[/i]
[*][i] [/i]
[*][i]select = select.  Controls.read():select()[/i]
[*][i] [/i]
[*][i] [/i]
[i][/list][/i]







II) Remarque Sur Cette Fonction
Vous savez donc, d'après le précédent chapitre, gérer les touches de votre PSP dans votre programme en LUA. C'est une "grande" connaissance que vous acquérissez. 

Mais voilà le problème, Controls.read() est une fonction plutôt lente à exécuter, c'est à dire que la psp va mettre un certain temps à aller vérifier l'état de ces touches. Lorsque je dis lente, je veux dire relativement lente évidement, l'opération ne prends que quelques microsecondes, mais il n'en est pas moins que dans les programmes comme le précédent, où on vérifie l'état d'une kyrielle de touches à la suite, le programme se trouve ralentit, et il arrive un moment où cela va nous gêner. 
 

Mais ne vous inquiétez pas, il existe un moyen très simple de palier à ce problème : on ne va lire l'état des touches qu'une fois par tour de boucle, le programme va assez vite pour que ce ne soit pas gênant (d'autant qu'il ira plus vite comme ça 
 ). 


Enfin c'est bien beau, mais comment fait-on pour ne lire l'état des touches une seule fois ? Eh bien c'est simple, on se contente d'enregistrer cet état dans une variable, en début de chaque boucle, puis de vérifier l'état des touches par rapport à cette variable. On nomme généralement cette variable "pad".
Rassurez vous, c'est plus simple que ça en a l'air.

On procède donc comme ceci, au début de notre boucle : 
 




 
 
Code:
pad = Controls.read()





Petit programme de démonstration avec "pad" :


 
 
Code:
[list=1][*] 
[*] 
[*]blanc = Color.new(255,255,255)
[*] 
[*]while true do
[*] 
[*]screen:clear()
[*] 
[*]pad = Controls.read() -- On attribue a pad la valeur actuelle de Controls.read().
[*] 
[*]if pad:cross() then --Si on appuie sur la touche croix alors....
[*] 
[*]screen:print(5, 5, "Touche Croix !", blanc)
[*] 
[*]end
[*] 
[*]screen.waitVblankStart()
[*] 
[*]screen.flip()
[*] 
[*]end
[*] 
[*] 
[*] 
[*] 
[*] 
[*] 
[*] 
[*] 
[/list]





Voilà, vous savez maintenant correctement utiliser la lecture de contrôle des touches de la PSP ! 


III) Petit Programme Exemple
 
 
 
 
Code:
[list=1][*] 
[*] 
[*]blanc = Color.new(255,255,255)
[*] 
[*]while true do
[*] 
[*]screen:clear()
[*] 
[*]pad = Controls.read()
[*] 
[*]if pad:cross() then
[*] 
[*]screen:print(5, 5, "la touche Croix est enfoncee", blanc)
[*] 
[*]elseif pad:circle() then
[*] 
[*]screen:print(5, 10, "la touche Rond est enfoncee", blanc)
[*] 
[*]elseif pad:square() then
[*] 
[*]screen:print(5, 20, "la touche Carre est enfoncee", blanc)
[*] 
[*]elseif pad:triangle() then
[*] 
[*]screen:print(5, 30, "la touche Triangle est enfoncee", blanc)
[*] 
[*]elseif pad:r() then
[*] 
[*]screen:print(5, 40, "la touche R est enfoncee", blanc)
[*] 
[*]elseif pad:l() then
[*] 
[*]screen:print(5, 50, "la touche L est enfoncee", blanc)
[*] 
[*]elseif pad:down() then
[*] 
[*]screen:print(5, 60, "la touche Bas est enfoncee", blanc)
[*] 
[*]elseif pad:right() then
[*] 
[*]screen:print(5, 70, "la touche Droite est enfoncee", blanc)
[*] 
[*]elseif pad:left() then
[*] 
[*]screen:print(5, 80, "la touche Gauche est enfoncee", blanc)
[*] 
[*]elseif pad:up() then
[*] 
[*]screen:print(5, 90, "la touche Haut est enfoncee", blanc)
[*] 
[*]elseif pad:start() then
[*] 
[*]screen:print(5, 100, "la touche Start est enfoncee", blanc)
[*] 
[*]elseif pad:select() then
[*] 
[*]screen:print(5, 110, "la touche Select est enfoncee", blanc)
[*] 
[*]else
[*] 
[*]screen:print(5, 120, "Aucune touche n'est pressee !", blanc)
[*] 
[*]end
[*] 
[*]screen.waitVblankStart()
[*] 
[*]screen.flip()
[*] 
[*]end
[*] 
[*] 
[/list]



Que fait ce programme ? 
Je vais vous l'expliquer. 
D'abord, on initialise la couleur blanche grâce à Color.new(). Puis on débute une boucle car on veut que notre programme se répète.
On efface l'écran. Jusque là rien de nouveau. 
Après ça, on remplit la variable "pad" avec l'état actuel des touches.



Puis, on ferme la boucle "while".

Ensuite, on créé nos conditions qui, en fonction des touches pressées, affichent un texte. Et si on appuies sur aucune d'elles, un texte est affiché. Vous verrez, il est très facile à comprendre et en même temps très basique !

Voici le résultat : 



Petit plus, imaginez que vous ne voulez afficher une message que lorsque aucune touche n'est pressée, vous devez obligatoirement mettre toutes les condition se trouvant avant ? Non, car la fonction Controls.read() renvoie également une variable qui vaut 0 si une touche est pressée, et plus de 0 si au moins une touche l'est. Vous la trouverez dans Controls.read():buttons() (ou pad:buttons() si vous passez par une variable) il vous suffira donc de mettre cette condition :




 
 
Code:
[list=1][*] 
[*] 
[*]if not pad:buttons() then
[*] 
[*]screen:print(5, 120, "Aucune touche n'est pressee !", blanc)
[*] 
[*]end
[*] 
[*] 
[/list]







IV) TP : Bouge Une Image !
Le TP qui suit aura pour but de faire bouger une image. Un TP assez simple quand on a assimilé ce tutoriel. 

Caractéristiques de ce TP :
 
 
  • Faire bouger une image de haut en bas et de gauche à droite, avec les touches fléchées de la PSP.
  • Afficher les coordonnées de l'image.
Vous aurez besoin pour faire ce TP de : 

  • screen:print()
  • Image.load()
  • Color.new()
  • screen:blit()
  • Controls.read()
  • une image assez petite. (15*15px suffira)

Ressources : Image 15*15 : 

Voici ce que j'attends de vous : 



Solution : 
Je vous donne la solution en téléchargeant cette archive (script.lua + image.png) :



http://www.mediafire.com/?td9ty3md0udect3





Si vous n'avez pas réussis à réaliser ce TP, c'est que vous n'êtes pas encore au point.
I. Quel Genre D'utilisation ?

 
 
Plusieurs possibilités :
 
 
  • Faire des animations.
  • Faire des sortes de Quizz, où il faut agir avant un temps impartit.
  • Tout autre chose qui vous passe par l'esprit.
Vous verrez, un timer c'est vraiment simple à comprendre, une vingtaine de lignes suffisent pour faire ceci.






II. Les Fonctions/Mots-Clés À Connaître

 
 

 
 
Il y en a six principales. Elle sont très instinctives et très faciles d'utilisation. 

 
 
Code:
nom_du_timer = Timer.new() -- Permet de, comme son nom l'indique, creer son "timer" avec pour nom : nom_du_timer. nom_du_timer:start() -- Permet de mettre en marche le timer "nom_du_timer". nom_du_timer:time() -- Renvoie le temps, en MILLISECONDES, du timer "nom_du_timer". nom_du_minuteur:reset(nombre) --Remet le timer à partir d'un temps choisit. nom_du_minuteur:stop() -- Permet de stopper le minuteur "nom_du_minuteur"




 
 

 
 


 
 
III. Creer Un Programme Qui Affiche Le Temps Du Timer

 
 
On va créer un mini programme qui va permettre de vous familiariser avec les timer. Ce programme va nous afficher le temps écoulé du timer en blanc, par exemple, et, une fois arrivé à 5000ms(5s) il recommence. 
 
 
Tout d'abord, nous allons charger notre couleur pour afficher le texte.
 
 

 
 
Code:
local rouge = Color.new(255, 0, 0)



 
 

 
 
Puis, nous allons créer notre timer;
 
 

 
 
Code:
local timer = Timer.new()



 
 

 
 
Nota : J'ai attribué au timer le nom "timer" pour plus de compréhensibilité, mais vous auriez pu mettre "chien", "raviolis", "gencive" etc...
 
 
Puis, nous allons activer notre timer;
 
 

 
 
Code:
timer:start()



 
 

 
 
Attaquons-nous maintenant à la boucle principale : 
 

 
 
Code:
while true do       screen:clear()  


 
 

 
 
Puis, viens le moment de la condition qui dis que : "Si le temps est supérieur à 5000, alors on 'reset' le timer à 0." 
 

 
 
Code:
if timer:time() > 500 then       timer:reset(0)      timer:start() end



 
 

 
 
nota : timer:time() renvoie le temps du timer, vous pouvez, si vous le souhaitez, le mettre dans une variable(dans la boucle !). Mais c'est déconseillé car vous aurez une imprécision. Donc, il est préférable de le mettre tel quel dans le code. 
 

 
 

Donc là, on a dit que si le temps dépassait les 5 secondes, on remet le temps à 0 et on re-start le timer. 
 
On va ensuite afficher notre temps :  

 
 
Code:
 screen:print(50, 50, timer:time()/1000.."s", rouge)


 
 

 
 
(1 ms = 1.10^-3 s. donc on divise par 1000 le résultat en ms, pour l'avoir en s.) 
 

 
 
On ferme notre boucle principale; 
 

 
 
Code:
     screen.waitVblankStart()      screen.flip() end



 
 

 
 
Voilà, si vous avez suivis ce tutoriel, vous devez avoir ceci :
 
 
 
 

 
 
LUA=FINI 
 
Passons au C 
 
La bibliothèque SDL 
 
Salut !

Je vais vous montrer comment utiliser la SDL sur PSP.

/!\ Je vous conseille tout d'abord d'apprendre à utiliser la SDL sur PC /!\

Dans ce tuto, je vais essayer de vous apprendre à afficher une image (un arrière plan) sur votre écran.

L'arrière plan :



On commence par les includes :

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include
#include

#include
#include





Ce sont les seules lib que l'on va utiliser pour l'instant.

Ensuite les informations sur la PSP :

Syntaxe: [ Télécharger ] [ Masquer ]
PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);




On initialise une variable globale, qui sera utilisée plus tard, afin de pouvoir quitter le programme en appuyant sur le bouton HOME. N'oubliez pas de faire les fonctions callbacks.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}





Le main :

Syntaxe: [ Télécharger ] [ Masquer ]
int main(int argc, char **argv)
{
 




On appelle les fonctions SetupCallbacks et pspDebugScreenInit, pour pouvoir quitter à tout moment et initialiser l'écran.

Syntaxe: [ Télécharger ] [ Masquer ]
        pspDebugScreenInit();
        SetupCallbacks();




Voilà, pour l'instant ce n'est pas compliqué, il ne s'agit que de code "de base", (si je peux appeler cela comme ça) pour un homebrew.

Maintenant nous allons initialiser la SDL :

Syntaxe: [ Télécharger ] [ Masquer ]
        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();




La fonction SDL_Init va initialiser SDL_INIT_VIDEO. Si, par exemple, vous voulez initialiser la vidéo et le son, il faudra faire :

Syntaxe: [ Télécharger ] [ Masquer ]
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
                sceKernelExitGame();




D'autres flag sont possibles, mais pour l'instant, nous n'utiliserons que la vidéo.
J'initialise la SDL dans un "if", car si la fonction renvoie un int plus petit que 0, cela voudrait dire que l'initialisation de la SDL a échoué.

Ensuite nous allons créer notre écran.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Surface *screen = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE |SDL_DOUBLEBUF);




SDL_SetVideoMode prend 4 paramètres :
- La largeur de l'ecran (480 pixels)
- La hauteur de l'ecran (272 pixels)
- Le nombre de bits par pixel (8, 16, 32)
- Les flags

La surface screen est la surface où nous allons afficher toutes nos images, par dessus.

/!\ Pour les flags utilisés dans SDL_init et SDL_SetVideoMode, je vous conseille d'aller voir les tutos SDL sur le SdZ /!\ 

Nous allons maintenant charger notre arrière plan, qui a la même largeur et hauteur que l'ecran de la PSP. Celui-ci est au format PNG.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Surface *background = IMG_Load("background.png");




On charge l'image dans une surface nommée background. 
IMG_Load est utilisé pour charger les images. Comme vous pouvez le voir, il prend en paramètre le chemin vers l'image à charger.

C'est au tour de la boucle principale maintenant. Vous vous souvenez de la variable globale (j'espère que oui ;D) ? Nous l'utiliserons ici :

Syntaxe: [ Télécharger ] [ Masquer ]
        while (!done)
        {
 



À présent, nous allons effacer la surface screen. On va remplir cette surface de noir.

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0,0));




SDL_FillRect, comme son nom l'indique, va remplir la surface screen avec une couleur. Cette couleur est renvoyée par la fonction SDL_MapRGB, qui elle, nécessite 4 paramètres.
Le format de l'écran, c'est-à-dire les bits par pixel. Pour récupérer ce format, il faut juste écrire screen->format.
La couleur RGB. Ici tout est a 0, donc la couleur sera noire.

Passons à la fonction suivante. 
Nous allons blitter l'arriere plan à l'écran.
Blitter ? Kézako ?
En quelque sorte, nous allons "copier" et "coller" la surface qui contient l'arrière plan sur la surface screen.

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_BlitSurface(background, NULL, screen, NULL);




SDL_BlitSurface prend 4 paramètres :
- La surface à blitter
- SDL_Rect*, utilisé pour n'afficher qu'une certaine partie d'une surface. Si l'on écrit NULL à la place d'un SDL_Rect*, on affichera toute la surface.
- La surface sur laquelle on va blitter les autres surfaces
- SDL_Rect*, utilisé pour afficher la surface à blitter à une certaine position [X,Y]. Si l'on écrit NULL à la place d'un SDL_Rect, la position est [0,0].

Avec le code présent, on ne verra pas grand chose. On doit appeler SDL_Flip.

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_Flip(screen);




SDL_Flip prend un parametre :
- La surface sur laquelle les autres surfaces ont été blittées.

Avec cette fonction, on va pouvoir voir notre arrière plan.

Il ne nous reste plus qu'à fermer la boucle, effacer les surfaces de la mémoire, quitter la SDL et quitter le programme 


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        }
        
        SDL_FreeSurface(screen);
        SDL_FreeSurface(background);

        SDL_Quit();

        sceKernelExitGame();

        return 0;
}





SDL_FreeSurface libère la surface de la mémoire.


Voilà, c'est fini, j'espère ne pas avoir dit de bêtises et également de vous avoir appris quelque chose 


Ah. J'allais oublier. Voilà le makefile 
.



Code:
TARGET = SDL_TUTO
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= -lSDLmain -lSDL_image -lSDL -lGL -lpng -ljpeg -lz -lm\
      -lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS=$(STDLIBS)$(YOURLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto SDL By Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak 



Amusez-vous ! ;D
 
 
Salut,

Aujourd'hui je vais vous montrer comment afficher une image a un point X et Y.

Tout d'abord reprennez le code du précédent tuto: Afficher une image.

L'image que nous allons afficher est la suivante:


Comme vous pouvez le voir, cette image a un fond rouge (R255, G0, B0). Ce ne sera pas très beau d'afficher cette image sur un arriere plan...
Ne vous inquiétez pas! La SDL a une fonction qui va faire disparaitre cette couleur rouge.

Bon tout d'abord nous allons charger notre image. :

Syntaxe: [ Télécharger ] [ Masquer ]
        //On charge notre image apres le background
        SDL_Surface *hero = IMG_Load("image.png");




Rien de nouveau dans ce petit bout de code.

Maintenant nous allons initialisé une nouvelle variable SDL_Rect:

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Rect position;




Comme son nom l'indique, cette nouvelle variable va nous permettre de placer notre hero a une certaine position X et Y.

Pour cette exemple nous allons afficher notre hero au centre de l'ecran. Pour faire cela nous aurons besoin de la taille de l'écran et la taille de l'image.

On fait comment pour trouver la taille de l'image ??
Tout simplement avec la surface qui contient le hero. 

Syntaxe: [ Télécharger ] [ Masquer ]
        hero->w // largeur de l'image (width)
        hero->h // hauteur de l'image (height)




Nous donnons la position x et y avec ce petit bout de code:

Syntaxe: [ Télécharger ] [ Masquer ]
        position.x = (480 - hero->w)/2;
        position.y = (272 - hero->w)/2;




Maintenant nous allons blitter la surface hero.
Avant de la blitter nous allons utiliser une fonction qui va enlever la couleur rouge de l'image.

Le petit bout de code:

Syntaxe: [ Télécharger ] [ Masquer ]
                //On est dans la boucle principale, apres avoir blitté la surface background
                SDL_SetColorKey(hero, SDL_SRCCOLORKEY, SDL_MapRGB(hero->format,255, 0, 0));
                SDL_BlitSurface(hero, NULL, screen, &position);
                SDL_SetColorKey(hero, NULL, NULL);




SDL_SetColorKey prend 3 parametres:
- La surface avec la couleur a "enlever".
- Un flag (Voir site du zero ou autre pour d'autres flag). Nous n'utiliserons que le flag SDL_SRCCOLORKEY.
- La couleur a "enlever".

Apres on blit la surface hero. Regarder bien ou se trouve la variable SDL_Rect position.
C'est la qu'il faut la placer pour pouvoir positionner la surface.
La fonction suivante sert à désactiver la couler a mettre en transparent. Si nous ne le ferions pas, les surfaces suivantes ou certaines parties sont rouges seront transparent!

On termine par libérer la mémoire avec un petit:

Syntaxe: [ Télécharger ] [ Masquer ]
        //apres la boucle
        SDL_FreeSurface(hero);




Un petit screen du resultat avec et sans SDL_SetColorKey:



Pour finir le tuto, voila le makefile:


Code:
TARGET = SDL_TUTO2
OBJS = main.o Animation.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= -lSDLmain -lSDL_image -lSDL -lGL -lpng -ljpeg -lz -lm\
      -lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS=$(STDLIBS)$(YOURLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto 2 SDL By Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak 



Merci d'avoir lu ce tuto 
, j'espère vous avoir appris quelque chose.

 
 
Salut 
,


Aujourd'hui, on va bouger une image !

Tout d'abord reprennez le code du tuto précédent: Afficher une image à un point X et Y

Pour bouger l'image on va utiliser pspctrl.h, donc la première chose a faire est de l'inclure dans le programme.

Syntaxe: [ Télécharger ] [ Masquer ]
//apres pspdebug
#include




Avec pspctrl.h inclut, on pourra utiliser nos touches pour bouger notre hero.

D'abord nous devons initialisé une variable SceCtrlData. Cette nouvelle variable nous aidera a savoir si nous avons appuyé sur une touche et laquelle.

Syntaxe: [ Télécharger ] [ Masquer ]
        //apres l'initialisation de SDL_Rect position
        SceCtrlData pad;




Dans notre boucle maintenant nous devrons appeller une fonction de pspctrl.h. Cette fonction va "regarder" si un touche a été appuié.

Syntaxe: [ Télécharger ] [ Masquer ]
                //apres le while
                sceCtrlReadBufferPositive(&pad, 1);




Puis la gestion des touches !

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                if (pad.Buttons & PSP_CTRL_UP)
                        position.y--;
                else if (pad.Buttons & PSP_CTRL_DOWN)
                        position.y++;
                else if (pad.Buttons & PSP_CTRL_LEFT)
                        position.x--;
                else if (pad.Buttons & PSP_CTRL_RIGHT)
                        position.x++;





On vérifie si la touche "haut" est appuyé avec le premier if. 
PSP_CTRL_UP est un flag pour la touche "haut". Pour d'autres flags ouvrez pspctrl.h 
.

Pour faire bouger votre hero vous pouvez augmenter l'incrémentation/décrémentation des positions dans les if.
Petit ex.:

Syntaxe: [ Télécharger ] [ Masquer ]
                if (pad.Buttons & PSP_CTRL_UP)
                        position.y -= 3;




Ici l'on montera de 3 pixels plus vite que précédemment.

Pour éviter que notre hero n'aille trop loin. On va éviter que ça position dépasse les bords de l'ecran.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                if (position.x < 0)
                        position.x = 0;
                else if (position.x > (480 - hero->w))
                        position.x = 480 - hero->w;

                if (position.y < 0)
                        position.y = 0;
                else if (position.y > (272 - hero->h))
                        position.y = 272 - hero->h;





Et voila c'est fait ! Il ne vous reste plus qu'a tester ;D

Je vous mets cette fois si le programme au complet suivi du makefil 
.



Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
/*
 *  Tuto SDL by pyroesp for DevsGen & XtreamLua
 *
 *            17/04/2010
 */

#include
#include
#include

#include
#include

PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}

int main(int argc, char **argv)
{
        pspDebugScreenInit();
        SetupCallbacks();

        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();

        SDL_Surface *screen = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE |SDL_DOUBLEBUF);
        SDL_Surface *background = IMG_Load("background.png");
        SDL_Surface *hero = IMG_Load("image.png");

        SDL_Rect position;

        position.x = (480 - hero->w)/2;
        position.y = (272 - hero->h)/2;

        SceCtrlData pad;

        while (!done)
        {
                sceCtrlReadBufferPositive(&pad, 1);

                if (pad.Buttons & PSP_CTRL_UP)
                        position.y--;
                else if (pad.Buttons & PSP_CTRL_DOWN)
                        position.y++;
                else if (pad.Buttons & PSP_CTRL_LEFT)
                        position.x--;
                else if (pad.Buttons & PSP_CTRL_RIGHT)
                        position.x++;

                if (position.x < 0)
                        position.x = 0;
                else if (position.x > (480 - hero->w))
                        position.x = 480 - hero->w;

                if (position.y < 0)
                        position.y = 0;
                else if (position.y > (272 - hero->h))
                        position.y = 272 - hero->h;

                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0,0));

                SDL_BlitSurface(background, NULL, screen, NULL);

                SDL_SetColorKey(hero, SDL_SRCCOLORKEY, SDL_MapRGB(hero->format, 255, 0, 0));
                SDL_BlitSurface(hero, NULL, screen, &position);
                SDL_SetColorKey(hero, NULL, NULL);

                SDL_Flip(screen);
        }

        SDL_FreeSurface(screen);
        SDL_FreeSurface(hero);
        SDL_FreeSurface(background);

        SDL_Quit();

        sceKernelExitGame();

        return 0;
}
 






Code:
TARGET = SDL_TUTO
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= -lSDLmain -lSDL_image -lSDL -lGL -lpng -ljpeg -lz -lm\
-lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS=$(STDLIBS)$(YOURLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto 3 SDL By Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak 



Amusez vous 
.

 
 
Salut,

Aujourd'hui nous allons utiliser SDL_ttf !
On peut faire quoi avec SDL_ttf ?
On va pouvoir charger des polices pour apres ecrire avec de jolies lettres  
 .


La première chose à faire c'est de téléchargé la police (google is your friend).
La police que j'ai choisit est la suivante:
http://www.dafont.com/fr/the-king-queen-font.font

Téléchargez la police et mettez la a coté de votre eboot (pour plus tard).

Le resultat de ce tuto en image:


Le programme:

Tout d'abord les includes.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include
#include

#include
#include





On inclut SDL_ttf.h qui va nous permettre d'utilisez des polices 


Puis le code "de base" et l'info sur la PSP. Voir premier tuto SDL: Afficher une image

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}


int main (int argc, char **argv)
{





Rien de nouveau la dedans 
.


On doit initialiser l'écran et appeler la fonction SetupCallbacks pour pouvoir quitter avec le bouton HOME.

Syntaxe: [ Télécharger ] [ Masquer ]
        pspDebugScreenInit();
        SetupCallbacks();




On initialise la SDL, comme dans le premier tuto.

Syntaxe: [ Télécharger ] [ Masquer ]
        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();




Il faut maintenant initialiser SDL_ttf et pour cela on fait a peu pres comme SDL_Init, mais pour SDL_ttf 
.


Syntaxe: [ Télécharger ] [ Masquer ]
    if (TTF_Init() < 0)
        sceKernelExitGame();




SDL_ttf maintenant initialisé, on va déclaré une variable TTF_Font* et une autre SDL_Color.
On va charger la police dans la variable TTF_Font* et la variable SDL_Color va être utilisé pour la couleur du texte.

Syntaxe: [ Télécharger ] [ Masquer ]
    TTF_Font *police = NULL;
    SDL_Color couleur_text = {0xFF, 0xFF, 0xFF}; //blanc




SDL_Color couleur text = {R, G, B}.
Comme vous pouvez le voir, la couleur du texte va être en blanc. 
Note: Vous n'êtes pas obligé d'écrire en chiffre hexadécimaux. 0xFF = 255

La variable TTF_Font* déclaré, l'on va charger la police.

Syntaxe: [ Télécharger ] [ Masquer ]
    police = TTF_OpenFont("the_King__26_Queen_font.ttf", 30);




TTF_OpenFont renvoi un TTF_Font*.
Cette fonction prend 2 paramètres:
- Le chemin vers la police.
- La taille du texte.

Nous déclarons deux surface. Une pour l'écran et une autre pour le texte.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Surface *screen = SDL_SetVideoMode(480, 272, 32, SDL_HWSURFACE |SDL_DOUBLEBUF);
        SDL_Surface *text = TTF_RenderText_Blended(police, "Hello World",couleur_text);




La première surface, vous devriez la connaitre. Si vous ne vous en souvenez plus, retournez voir le premier tuto SDL.
La deuxième surface contient le texte à afficher à l'écran.

TTF_RenderText_Blended est la fonction qui va faire la surface avec le texte.
Cette fonction a 3 paramètres:
- La police
- Le texte a afficher a l'écran
- La couleur du texte

D'autres fonction pour créer la surface texte sont possibles. 
Je vous laisse regarder ça sur le site du zéro 
.


On va positionner le texte au centre de l'écran. 
On va donc déclaré une variable SDL_Rect et lui donner une position X et Y, comme dans le précédent tuto.


Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Rect position;

        position.x = (480 - text->w)/2;
        position.y = (272 - text->h)/2;




Voila ça c'est fait !
On passe a la boucle principale.
Normalement vous devriez déjà savoir le code qui suit. 
Il faut "effacer" l'ecran, blitter chaque surface et afficher la surface sur laquelle nous avons blitté les autres surfaces.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        while (!done)
        {
                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0,0));

                SDL_BlitSurface(text, NULL, screen, &position);
                SDL_Flip(screen);
        }





Rien de nouveau ici 


On continue !
Maintenant que la boucle est fini il faudra libérer la mémoire de ces surfaces et polices, ainsi que désinitialisé la SDL_ttf et SDL.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_FreeSurface(screen);
        SDL_FreeSurface(text);

        TTF_CloseFont(police);

        TTF_Quit();
        SDL_Quit();





TTF_CloseFont sert a "fermer" la police et puis on désinitialise la SDL_ttf avec TTF_Quit.

Voila on termine par quitter le programme avec:

Syntaxe: [ Télécharger ] [ Masquer ]
        sceKernelExitGame();

        return 0;
}




C'est fini !
Compiler, tester, et contempler votre travail 
 !


Ah non vous pouvez pas encore compiler, voila le Makefile:

Code:
TARGET = testsdl
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= 
LIBS= -lSDL_ttf -lSDLmain -lSDL -lGL -lfreetype -lpng -ljpeg -lz -lm \
      -lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto SDL by Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak


Pour info, j'ai enlevé -lSDL_image vu qu'il n'est pas utilisé dans cet exemple et j'ai ajouté -lSDL_ttf et -lfreetype.
 
 
Salut tout le monde,

Je vais vous montrer comment faire un beau menu avec la SDL, SDL_ttf et SDL_gfx 


Je vous montrer d'ores et déjà le  programme en action avec quelques screen:








Allez, on attaque le code !

Comme tout programme écrit en C (ou C++), la première chose a faire est d'inclure quelques lib.
Voici celles que nous allons utiliser aujourd'hui.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include
#include
#include

#include
#include
#include //sdl_gfx





Un nouveau include: SDL_gfxPrimitives.h.
Cette lib nous permettra de dessiner, entre autres, des rectangle.

Le code "de base" et l'info sur la PSP (voir tuto précédent).

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}
 





J'ai rajouté 2 defines, une pour la hauteur de l'écran et une autre pour la largeur. 
Vous pourrez modifier la taille de l'écran en changeant simplement ces 2 defines.

Suivit du main avec l'initialisation de l'écran et des setupcallbacks qui nous permettrons de quitter le programme à tout moment avec le bouton HOME.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
int main(int argc, char **argv)
{
        pspDebugScreenInit();
        SetupCallbacks();
 





Ensuite nous initialisons la SDL et la SDL_ttf.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();

        if (TTF_Init() < 0)
                sceKernelExitGame();





Pour ce menu je vais utiliser 2 police différentes, une pour le titre et une autre pour les options.
Donc on déclare 2 variables TTF_Font* et on charge les polices 
.


Syntaxe: [ Télécharger ] [ Masquer ]
        TTF_Font *titlefont, *optionfont;
        titlefont = TTF_OpenFont("the_King__26_Queen_font.ttf", 25);
        optionfont = TTF_OpenFont("Arial.ttf", 20);




Vous pourrez télécharger la police utilisé pour le titre ici: http://www.dafont.com/the-king-queen-font.font
La deuxième police est la police Arial.ttf que vous pourrez retrouver dans C:\WINDOWS\Font\ si vous êtes sous windows.

Maintenant, 2 variables SDL_Color pour le titre et les options.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Color blanc = {0xFF, 0xFF, 0xFF};
        SDL_Color noir = {0, 0, 0};




Ensuite nous allons créer notre écran.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Surface *screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 
                                                32, SDL_HWSURFACE |SDL_DOUBLEBUF);




Vous pouvez voir dans la fonction que j'ai utilisé les defines plutot que de mettre '480' et/ou '272' pour la largeur et hauteur de l'écran.

On continue avec un tableau 2D et 2 variables int.

Syntaxe: [ Télécharger ] [ Masquer ]
        char *menu[4] = {{"Menu Title"},{"Option n°1"},{"Option n°2"},{"Option n°3"}};
        int i = 0, option = 1;
 




Le tableau menu contient le texte à afficher dans notre menu.
La variable 'i' sera utilisé pour des for... Et puis la variable option sera elle utilisé pour "dire" sur quelles options nous nous trouvons.
Nous verrons ça plus en détails plus tard 
.


Ensuite nous allons déclarer 4 surfaces qui vont contenir les surfaces avec les textes a afficher a l'écran.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_Surface* s_menu[4];

        s_menu[0] = TTF_RenderText_Blended(titlefont, menu[0], blanc);
        for (i = 1; i < 4; i++)
            s_menu = TTF_RenderText_Blended(optionfont, menu, noir);





Nous faisons ici les surfaces contenant le texte du menu.

Pour l'instant nous n'avons rien vue de nouveau, vous devriez tout comprendre.
Si vous ne comprenez pas, relisez les tutos précédent ou aller voir les tutos SDL sur le Site du Zéro 


On déclare 2 variables SDL_Rect pour les positions des options et pour la position du titre. Puis deux variable SceCtrlData pour la gestion des touches.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_Rect title;
        title.x = (SCREEN_WIDTH - s_menu[0]->w)/2;
        title.y = 5;

        SDL_Rect pos_option;

        SceCtrlData pad, oldpad;





On positionne le titre du menu en haut de l'écran et au centre.
La position des options sera calculé plus tard, dans la boucle 


Pourquoi 2 variables SceCtrlData ??
On utilisera les deux variables pour bouger d'une option par appuie de touche (haut ou bas).

Allez on attaque la boucle 
.


Syntaxe: [ Télécharger ] [ Masquer ]
        while (!done)
        {
 




On regarde si une touche a été appuyé avec sceCtrlReadBufferPositive et on efface l'écran.

Syntaxe: [ Télécharger ] [ Masquer ]
                sceCtrlReadBufferPositive(&pad, 1);

                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 100, 100,200));
 




Remarque: La surface screen n'est plus rempli de noir, mais de bleu. C'est le bleu en arrière plan des screen.
J'utilise cette surface comme arrière plan.

Rien de nouveau ici non plus ;D.

Maintenant nous allons blitter le titre du menu et grâce à SDL_gfx on pourra souligner notre titre:

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_BlitSurface(s_menu[0], NULL, screen, &title);
                hlineRGBA(screen, title.x, title.x + s_menu[0]->w, title.y +s_menu[0]->h - 30,
                                255, 255, 255, 255);
 




Une nouvelle fonction ! hlineRGBA => Dessiner un ligne horizontale aux couleurs RGBA.
On va utiliser cette fonction pour souligner le titre.

Cette derniere prends 8 paramètres:
- La surface ou afficher la ligne
- Position x1
- Position x2
- Position y
- Couleur R (8 bit)
- Couleur G
- Couleur B
- Couleur A

x1 est la position X du titre.
x2 est cette même position + la largeur de la surface.
y est la position y du titre + la hauteur du titre. J'ai enlever quelques pixels (30) parce que la ligne se retrouve trop bas sans les 30 pixels en moins. 
Je suppose que c'est un petit problème de police. A vous de voir ou voulez le placer 
.


La gestion des touches. Celle ci comporte "3 partie" dans le if.
D'abord les limites de la variable option, puis la touche a appuyé pour et un la variable oldpad qui "bloquera" les touches après une pression.
Donc pour parcourir le menu, vous ne pouvez pas rester appuyer sur la touche haut ou bas, il faut appuyer plusieurs fois 
.


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        if ((option > 1) && (pad.Buttons & PSP_CTRL_UP) && !(oldpad.Buttons& PSP_CTRL_UP))
            option--;
        else if ((option < 3) && (pad.Buttons & PSP_CTRL_DOWN) &&!(oldpad.Buttons & PSP_CTRL_DOWN))
            option++;
        else if (pad.Buttons & PSP_CTRL_CROSS)
        {
            switch (option)
            {
                case 1:
                case 2:
                case 3:
                    done = 1;
            }
        }





Comme nous avons 3 options, on limite les options à 3.

J'ai rajouté que si l'on appuie sur la touche X, on sélectionne l'option choisi.
Dans ce tuto mes 3 options font quitter le programme. A vous de voir ce que chaque option doit faire dans votre programme 
.

Si option vaut 1 cela veut dire que nous avons sélectionné la première option, logique me direz vous 
.


Bon on continue !

Maintenant la partie intéressante du programme. En voyant les screen, vous remarquerez le "rectangle" blanc-noir au tour de l'option choisi.
Le code qui suit, va blitter chaque surface texte et en même temps dessiner le rectangle autour de l'option choisi.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        for (i = 1; i < 4; i++)
        {
                pos_option.x = (SCREEN_WIDTH - s_menu->w)/2;
                pos_option.y = SCREEN_HEIGHT/2 + 40 * (i - 1);
        
                if (option == i)
                {
                        boxRGBA(screen, pos_option.x - 6, pos_option.y - 2,pos_option.x + s_menu[option]->w + 6,
                                pos_option.y + s_menu[option]->h + 2, 255,255, 255, 100);
                        rectangleRGBA(screen, pos_option.x - 6, pos_option.y- 2, pos_option.x + s_menu[option]->w + 6,
                                pos_option.y + s_menu[option]->h + 2, 0, 0,0, 255);
                }

                SDL_BlitSurface(s_menu, NULL, screen, &pos_option);
        }





Tout d'abord il faut calculer la position des options.
Comme vous pouvez le voir, la position X du texte s_menu[ i] est placé au centre de l'écran. La position Y, elle, augmente de 40 pixels pour chaque option suivante.
Donc si i vaut 2, nous calculons la position de la surface contenant la deuxième option. 
Et celle ci est 40 pixels en dessous de la moitié de l'écran (SCREEN_HEIGHT/2 + 40 * ( 2 - 1 ))!

Pour dessiner le rectangle autour de l'option choisi, il faut savoir sur quelle option nous nous trouvons! C'est pour cela que nous vérifions si la variable i est égale a la variable option.
Si tel est le cas, nous dessinons un rectangle, sinon on ne fait rien 
.


Nous voyons ici 2 nouvelles fonction (venant de SDL_gfx).
boxRGBA crée un rectangle rempli, et rectangleRGBA un rectangle vide.
Avec boxRGBA nous allons faire le rectangle blanc-transparent et avec rectangleRGBA le contour en noir 


boxRGBA prend 9 paramètres:
- La surface sur laquelle dessiner le rectangle
- La position x1 du rectangle
- La position y1 du rectangle
- La position x2 du rectangle
- La position y2 du rectangle
- Couleur R (8 bit)
- Couleur G
- Couleur B
- Couleur A

rectangleRGBA prend lui aussi 9 paramètres:
- La surface sur laquelle dessiner le rectangle
- La position x1 du rectangle
- La position y1 du rectangle
- La position x2 du rectangle
- La position y2 du rectangle
- Couleur R (8 bit)
- Couleur G
- Couleur B
- Couleur A

Pour que le rectangle soit transparent, j'ai ecrit la valeur 100 pour le couleur alpha.
Note: Le rectangle est visible a 100% quand alpha vaut 255 et 0% quand alpha vaut 0.

Les positions du rectangle:

J'utilise SDL_Rect pour connaitre la position de la surface a afficher.

Pour x1: On prend le point x de la position de l'option et on soustrait quelques pixels, ainsi le rectangle ne sera pas au même niveau que le texte.
Pour y1: On prend le point y de la position de l'option, comme pour x1, et on soustrait la aussi quelques pixels pour les mêmes raison 
.

Pour x2: Ici nous prenons le point x de la position de l'option et nous y additionnons la largeur de la surface s_menu[ i] + quelques pixels pour éviter que le rectangle ne soit au même niveau que le texte.
Pour y2: Comme pour x2, nous prenons le point y de la position de l'option et nous y additionnons la hauteur de la surface s_menu[ i] + quelques pixels.

Cela créera votre rectangle autour de votre option 


Ensuite il ne nous reste plus qu'a blitté la surface s_menu[ i].

Il ne nous reste plus qu'a utiliser la fonction SDL_Flip pour tout afficher sur l'ecran.

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_Flip(screen);

                oldpad = pad;
        }




Il faut aussi dire que a variable oldpad vaut la variable pad, sinon vous ne pourrez pas changer d'option en appuyant une fois sur une touche.
Voyez par vous-même ce qu'il arrive si vous ne faites pas ça 
.


N'oubliez pas de refermer votre boucle principal 
.


Nous terminerons le code par libérer la mémoire des surfaces et polices. Puis nous désinitialiserons la SDL_ttf et la SDL.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_FreeSurface(screen);

        for (i = 0; i < 4; i++)
        SDL_FreeSurface(s_menu);

        TTF_CloseFont(titlefont);
        TTF_CloseFont(optionfont);

        TTF_Quit();
        SDL_Quit();

        sceKernelExitGame();

        return 0;
}





Voila c'est fini. Vous savez maintenant faire un beau menu avec la SDL ;D.

Je met a disposition le code au complet et je fini ce tuto par vous donner le makefile:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
/*
 *  Tuto SDL by pyroesp for DevsGen & XtreamLua
 *
 *            18/04/2010
 */

#include
#include
#include

#include
#include
#include //sdl_gfx

PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}

int main(int argc, char **argv)
{
        pspDebugScreenInit();
        SetupCallbacks();

        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();

    if (TTF_Init() < 0)
        sceKernelExitGame();

    TTF_Font *titlefont, *optionfont;
    titlefont = TTF_OpenFont("the_King__26_Queen_font.ttf", 25);
    optionfont = TTF_OpenFont("Arial.ttf", 20);

    SDL_Color blanc = {0xFF, 0xFF, 0xFF};
    SDL_Color noir = {0, 0, 0};

        SDL_Surface *screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,32, SDL_HWSURFACE | SDL_DOUBLEBUF);

        char *menu[4] = {{"Menu Title"},{"Option n°1"},{"Option n°2"},{"Option n°3"}};
    int i = 0, option = 1;

        SDL_Surface* s_menu[4];

    s_menu[0] = TTF_RenderText_Blended(titlefont, menu[0], blanc);
    for (i = 1; i < 4; i++)
        s_menu = TTF_RenderText_Blended(optionfont, menu, noir);

        SDL_Rect title;
        title.x = (SCREEN_WIDTH - s_menu[0]->w)/2;
        title.y = 5;

    SDL_Rect pos_option;

    SceCtrlData pad, oldpad;

        while (!done)
        {
            sceCtrlReadBufferPositive(&pad, 1);

                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 100,100, 200));

                SDL_BlitSurface(s_menu[0], NULL, screen, &title);
        hlineRGBA(screen, title.x, title.x + s_menu[0]->w, title.y +s_menu[0]->h - 30, 255, 255, 255, 255);

        if ((option > 1) && (pad.Buttons & PSP_CTRL_UP) && !(oldpad.Buttons& PSP_CTRL_UP))
            option--;
        else if ((option < 3) && (pad.Buttons & PSP_CTRL_DOWN) &&!(oldpad.Buttons & PSP_CTRL_DOWN))
            option++;
        else if (pad.Buttons & PSP_CTRL_CROSS)
        {
            switch (option)
            {
                case 1:
                case 2:
                case 3:
                    done = 1;
            }
        }

        for (i = 1; i < 4; i++)
        {
            pos_option.x = (SCREEN_WIDTH - s_menu->w)/2;
            pos_option.y = SCREEN_HEIGHT/2 + 40 * (i - 1);

            if (option == i)
            {
                boxRGBA(screen, pos_option.x - 6, pos_option.y - 2,pos_option.x + s_menu[option]->w + 6,
                    pos_option.y + s_menu[option]->h + 2, 255, 255, 255,100);
                rectangleRGBA(screen, pos_option.x - 6, pos_option.y - 2,pos_option.x + s_menu[option]->w + 6,
                    pos_option.y + s_menu[option]->h + 2, 0, 0, 0, 255);
            }

            SDL_BlitSurface(s_menu, NULL, screen, &pos_option);
        }

                SDL_Flip(screen);

                oldpad = pad;
        }

        SDL_FreeSurface(screen);

        for (i = 0; i < 4; i++)
        SDL_FreeSurface(s_menu);

    TTF_CloseFont(titlefont);
    TTF_CloseFont(optionfont);

    TTF_Quit();
        SDL_Quit();

        sceKernelExitGame();

        return 0;
}
 





Et le Makefile:

Code:
TARGET = testsdl
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS = -lSDLmain -lSDL -lGL -lpng -ljpeg -lz -lm \
      -lstdc++ -lpspgu -lpspctrl -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS= -lSDL_ttf -lSDL_gfx -lfreetype $(STDLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto SDL by Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak


Petite remarque: 
J'ai modifié le makefile. Comme vous pouvez le voir dans STDLIBS il y a les libs "standard" pour un programme utilisant simplement la SDL.h.
Vous devez juste rajouter les libs tel que SDL_ttf (+ freetype), SDL_gfx ... dans la ligne "LIBS = ..." et il faut que $(STDLIBS) soit présent a la fin de cette ligne.

Pour ajouter SDL_gfxPrimitives.h dans le makfile, il faut ajouter -lSDL_gfx.

Voici la planche de sprites que nous allons découper:



Bon ouvrez paint et découper chaque image, une à une, puis... Stoooooop ! 
Je plaisante 
, laissons la SDL découper chaque image pour vous !!


Comme toujours quelques images qui vous montrerons ce que vous aller faire:











Le sprite découpé ce trouve au centre de l'écran.
La planche de sprite se trouve en haut a gauche. Un petit rectangle désigne le sprite coupé pour vous montrer comme ça marche 
.

Pour ça il ne faut que 2 fonctions, rien de bien méchant. On verra ça plus tard 


Comme d'habitude, les includes 


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include
#include
#include

#include
#include
#include





Puis nous avons le code de base avec l'info sur la PSP et les defines de l'ecran.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}





Ce n'est pas fini !!
On continue avec le main, l'initialisation de l'écran, les setupcallbacks et l'initialisation de la SDL.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
int main(int argc, char **argv)
{
        pspDebugScreenInit();
        SetupCallbacks();

        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();





On créé notre écran et on charge la planche de sprites.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Surface *screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32,
                                                        SDL_HWSURFACE |SDL_DOUBLEBUF);
        SDL_Surface *sprite = IMG_Load("sprite.png");




Maintenant on déclare deux SDL_Rect, l'un pour afficher le sprite au centre de l'écran et l'autre pour découper la planche de sprites.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_Rect position_sprite, image_decouper;

        image_decouper.x = 0;
        image_decouper.y = 0;
        image_decouper.w = 32; //largeur d'un hero
        image_decouper.h = 32; //hauteur d'un hero

        position_sprite.x = (SCREEN_WIDTH - image_decouper.w)/2;
        position_sprite.y = (SCREEN_HEIGHT - image_decouper.h)/2;





On initialise la position de image_découper a [0,0], ce qui veut dire le point en haut a gauche la planche de sprites !
Puis nous initialisons la largeur et la hauteur d'un sprite. Dans cette planche de sprites chaque sprite est une image de 32p x 32p.

Maintenant imaginez un rectangle, sur la planche de sprites, allant de la position x = 0, y = 0, jusqu'à la position x = 32, y = 32.
Que voyez-vous ??
Le premier sprite !!

On termine par initialiser la position du sprite au centre de l'écran. Cette fois si il ne faut pas mettre sprite->w ou sprite->h, car ce sont la largeur et hauteur de la planche de sprites et non d'un sprite !!!

On déclare deux SceCtrlData pour la gestion des touches et on entre dans la boucle principale.
Une fois rentrer dans la boucle on appelle la fonction sceCtrlReadBufferPositive pour "lire" les touches.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SceCtrlData pad, oldpad;

        while (!done)
        {
                sceCtrlReadBufferPositive(&pad, 1);





On rempli l'écran, avec un petit SDL_FillRect, d'une couleur bleutée. 

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 100, 100,255));




La gestion des touches ! C'est elle qui va nous permettre de "naviguer" entre les différent sprites.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
            if ((image_decouper.y > 0) && (pad.Buttons & PSP_CTRL_UP) && 
                                !(oldpad.Buttons & PSP_CTRL_UP))
                        image_decouper.y -= image_decouper.h;
                else if ((image_decouper.y < 3 * image_decouper.h) &&(pad.Buttons & PSP_CTRL_DOWN) && 
                                !(oldpad.Buttons & PSP_CTRL_DOWN))
                        image_decouper.y += image_decouper.h;
            else if ((image_decouper.x > 0) && (pad.Buttons & PSP_CTRL_LEFT)&& 
                                !(oldpad.Buttons & PSP_CTRL_LEFT))
                   image_decouper.x -= image_decouper.w;
            else if ((image_decouper.x < 2 * image_decouper.w) &&(pad.Buttons & PSP_CTRL_RIGHT) && 
                                !(oldpad.Buttons & PSP_CTRL_RIGHT))
                          image_decouper.x += image_decouper.w;





A chaque fois qu'une touche (haut, bas, droite, gauche) est appuyé la position x ou y incrémente ou décrémente.
Voila une image qui vous montrera les différents sprites pour leur position x et y :



Limites a ne pas dépasser : ex. (image_decouper.y < 3 * image_decouper.h) 
Vous vous demander peut-être pourquoi j'ai ecrit 3 * image_decouper.h. Tout simplement parce qu'il y a 4 images en hauteur.

Ok, il y a 4 images, mais ça n'explique toujours pas pourquoi tu as ecrit 3 !! ??
Et c'est pourquoi je vous montre cette seconde images 




Comme vous pouvez le voir, la premiere image est l'image "0" ! C'est pourquoi au lieu d'ecrire 4 * image_decouper.h, j'écris 3 


(Note: Comme un tableau, on commence par 0 et non par 1 
 )


Maintenant nous allons blitté notre sprite.

Syntaxe: [ Télécharger ] [ Masquer ]
            SDL_BlitSurface(sprite, &image_decouper, screen, &position_sprite);




C'est là qu'il faut mettre la variable image_decouper pour ne blitter qu'une partie de la surface sprite !

Vous n'êtes pas obligé de mettre les deux lignes de code suivant, mais cela vous permettra de suivre l'image à découper de la planche de sprites.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
            SDL_BlitSurface(sprite, NULL, screen, NULL);

            rectangleRGBA(screen, image_decouper.x, image_decouper.y, 
                                image_decouper.x + image_decouper.w,
                              image_decouper.y + image_decouper.h, 
                                255, 0, 0, 255);





On affiche la planche de sprites a l'écran, puis on dessine un rectangle autour de l'image découpé.

On affiche le tout a l'ecran et on dit que oldpad vaut pad. Si vous ne savez plus pourquoi, allez voir le tuto précédent.

Syntaxe: [ Télécharger ] [ Masquer ]
                SDL_Flip(screen);

                oldpad = pad;
        }




Le programme est maintenant fini, on libère la ram et on quitte le tout 


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_FreeSurface(screen);
        SDL_FreeSurface(sprite);

        SDL_Quit();

        sceKernelExitGame();

        return 0;
}





Et voila, vous savez maintenant comment découper une planche de sprite (ou tout autre image 
).


Je terminerai donc ce tuto par le code complet et le Makefile 
 :


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
/*
 *  Tuto SDL by pyroesp for DevsGen & XtreamLua
 *
 *            19/04/2010
 */

#include
#include
#include

#include
#include
#include

PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}

int main(int argc, char **argv)
{
        pspDebugScreenInit();
        SetupCallbacks();

        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();

        SDL_Surface *screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    SDL_Surface *sprite = IMG_Load("sprite.png");

    SDL_Rect position_sprite, image_decouper;

    image_decouper.x = 0;
    image_decouper.y = 0;
    image_decouper.w = 32;
    image_decouper.h = 32;

    position_sprite.x = (SCREEN_WIDTH - image_decouper.w)/2;
    position_sprite.y = (SCREEN_HEIGHT - image_decouper.h)/2;

    SceCtrlData pad, oldpad;

        while (!done)
        {
            sceCtrlReadBufferPositive(&pad, 1);

                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 100,100, 255));

        if ((image_decouper.y > 0) && (pad.Buttons & PSP_CTRL_UP) &&!(oldpad.Buttons & PSP_CTRL_UP))
            image_decouper.y -= image_decouper.h;
        else if ((image_decouper.y < 3 * image_decouper.h) && (pad.Buttons &PSP_CTRL_DOWN) && !(oldpad.Buttons & PSP_CTRL_DOWN))
            image_decouper.y += image_decouper.h;
        else if ((image_decouper.x > 0) && (pad.Buttons & PSP_CTRL_LEFT) &&!(oldpad.Buttons & PSP_CTRL_LEFT))
            image_decouper.x -= image_decouper.w;
        else if ((image_decouper.x < 2 * image_decouper.w) && (pad.Buttons &PSP_CTRL_RIGHT) && !(oldpad.Buttons & PSP_CTRL_RIGHT))
            image_decouper.x += image_decouper.w;

        SDL_BlitSurface(sprite, &image_decouper, screen, &position_sprite);
        SDL_BlitSurface(sprite, NULL, screen, NULL);

        rectangleRGBA(screen, image_decouper.x, image_decouper.y,image_decouper.x + image_decouper.w,
                            image_decouper.y + image_decouper.h, 255, 0, 0,255);

                SDL_Flip(screen);

                oldpad = pad;
        }

        SDL_FreeSurface(screen);
        SDL_FreeSurface(sprite);

        SDL_Quit();

        sceKernelExitGame();

        return 0;
}
 






Code:
TARGET = SDL_TUTO
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= -lSDLmain -lSDL -lGL -lpng -ljpeg -lz -lm\
      -lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS= -lSDL_image -lSDL_gfx $(STDLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto SDL By Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak


Salut tout le monde ;D

Comme le titre le dit, nous allons jouer une musique au format .WAV avec SDL_mixer.

/!\ Les mp3 ne marchent pas, j'ai déjà essayé 
, par contre les ogg je ne sais pas /!\


Pas de screen cette fois si, mais un doc a télécharger: ICI

On commence par les includes:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include
#include
#include

#include
#include





Le code de base (ou j'ai rajouter le début du main, pspDebugScreenInit et setupcallbacks):

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}


int main()
{
    pspDebugScreenInit();
    SetupCallbacks();





On initialise la SDL et cette fois si, pour que SDL_mixer marche, il faut initialiser l'audio.

Syntaxe: [ Télécharger ] [ Masquer ]
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
                sceKernelExitGame();




On crée notre écran.

Syntaxe: [ Télécharger ] [ Masquer ]
        SDL_Surface *screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32,
                                                        SDL_HWSURFACE |SDL_DOUBLEBUF);
 




Ce qui suit est nouveau alors soyez attentif 


Une nouvelle fonction:

Syntaxe: [ Télécharger ] [ Masquer ]
        Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096);
 




Mix_OpenAudio prend 4 paramètres:
- Fréquence du son que l'on va utiliser. MIX_DEFAULT_FREQUENCY équivaut à écrire 22050.
- Le format du son utilisé. MIX_DEFAULT_FORMAT pour le format par défaut.
- Le nombre de "channels" a utiliser. 1 pour mono, 2 pour stéréo.
- taille d'échantillon. D'après la doc, si on joue une musique la taille d'échantillon devrait être 4096 ou plus.

On déclare une variable Mix_Musique* et on charge le son.

Syntaxe: [ Télécharger ] [ Masquer ]
    Mix_Music* Musique = {NULL};
    Musique = Mix_LoadMUS("wave.wav");
 




On pourrait dire que Mix_Music est comme une SDL_Surface mais pour SDL_mixer. En tout cas c'est comme ça que je le vois 
.

Mix_LoadMUS Charge la musique dans la variable Mix_Music*. Ici nous chargeons une musique appelé wave.wav.

Puis on déclare 2 variables SceCtrlData, nous entrons dans la boucle principale.
On appelle la fonction sceCtrlReadBufferPositive pour "lire" les touches, et on termine par "effacer"/remplir l'écran d'une couleur bleutée.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SceCtrlData pad, oldpad;

        while (!done)
        {       
                sceCtrlReadBufferPositive(&pad, 1);

                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 40,100, 255));





Maintenant la gestion des touches 
.

Je vous donne le code complet et je vous explique juste après les différentes fonction utilisé 
.


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                if (!Mix_PlayingMusic() && (pad.Buttons & PSP_CTRL_CROSS) &&
                                                !(oldpad.Buttons &PSP_CTRL_CROSS))
                        Mix_PlayMusic(Musique, 1);
                else if ((pad.Buttons & PSP_CTRL_TRIANGLE) &&!(oldpad.Buttons & PSP_CTRL_TRIANGLE))
                {
                        if(Mix_PausedMusic() == 1)
                            Mix_ResumeMusic();
                        else
                                Mix_PauseMusic();
                }
                else if ((pad.Buttons & PSP_CTRL_SQUARE) && !(oldpad.Buttons& PSP_CTRL_SQUARE))
                        Mix_HaltMusic();
                else if ((pad.Buttons & PSP_CTRL_START) && !(oldpad.Buttons& PSP_CTRL_START))
                {
                        Mix_HaltMusic();
                        done = 1;
                }





Tout d'abord: Quelle touche fait quoi ??
- Touch X : PLAY
- Touche [] : STOP
- Touche /\ : PAUSE/RESUME
- Touche START : Quit

La fonction Mix_PlayingMusic vérifie si une musique est en cours de lecture et renvoi 0 si ce n'est pas le cas.
Ce qui veut dire que nous pouvons appuyer sur X seulement si aucune musique n'est joué 


Mix_PlayMusic prend 2 paramètres:
- La variable Mix_Music*
- Le nombre de fois que l'on va jouer une musique. 1 = 1 fois, 2 = 2 fois, ..., -1 = infini.

La fonction Mix_PausedMusic vérifie si une musique a été mit en pause ou non. Si oui alors elle renvoi 1.
Mix_PauseMusic va mettre la musique en pause.
Mix_ResumeMusic va continuer a jouer la musique a partir de la ou on la mit en pause.

Mix_HaltMusic est utilisé pour arrêter une musique.

On écrit à l'écran quelle touche fait quoi, on dit que oldpad vaut pad, on affiche le tout a l'écran avec un SDL_Flip et on referme la boucle principale.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                pspDebugScreenSetXY(2,2);
                pspDebugScreenPrintf("X = Play, /\\ = Pause/Resume, [] = stop, START = quit");

                oldpad = pad;

                SDL_Flip(screen);
        }





Pour finir on va libérer la mémoire des surfaces et musiques chargé, on ferme l'audio, on quitte la SDL et on quitte le programme 


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        Mix_FreeMusic(Musique);
        Mix_CloseAudio();

        SDL_FreeSurface(screen);
        SDL_Quit();

        sceKernelExitGame();

        return 0;
}
 





Voila c'est fait. Trouvez vous un musique .wav et vous pourrez la jouer sur votre PSP.
Moi j'utilise audacity pour exporter mes sons au format .wav, il est gratuit et simple d'utilisation 
.


Je termine le tuto par le Makefile :

Code:
TARGET = SDL_TUTO
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= -lSDLmain -lSDL -lGL -lpng -ljpeg -lz -lm \
      -lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS= -lSDL_mixer -lvorbisfile -lvorbis -logg $(STDLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto SDL By Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak
Salut tout le monde,

Aujourd'hui on va voir comment utiliser SDL_GetTicks et SDL_Delay, des fonctions pour gérer le temps 


Quoi de mieux qu'un chronomètre pour ça ?

La SDL démarre automatiquement un timer au démarrage du programme. L'on peut récupérer le temps écoulé depuis le début du programme avec la fonction SDL_GetTicks

Commençons notre programme. Pour le chronomètre on va utiliser la SDL et la SDL_ttf. 
Nous allons aussi avoir besoin de stdio.h pour sprintf, donc :

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include
#include
#include

#include

#include
#include





Le code de base. J'y ai ajouté deux structure.
La première est pour le chronomètre et le deuxième sera utilisé pour la "précision" du chronomètre.
On verra comment les utiliser un peu plus tard.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
PSP_MODULE_INFO("Tuto_by_pyroesp", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

typedef struct
{
    int start, running;
    int activated;
}Chrono;

typedef struct
{
    int time, oldtime;
}myTime;

int done = 0;

int exit_callback(int arg1, int arg2, void *common) {
        done = 1;
        return 0;
}

int CallbackThread(SceSize args, void *argp) {
        int cbid = sceKernelCreateCallback("Exit Callback", exit_callback,NULL);
        sceKernelRegisterExitCallback(cbid);
        sceKernelSleepThreadCB();
        return 0;
}

int SetupCallbacks(void) {
        int thid = sceKernelCreateThread("CallbackThread", CallbackThread,0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
        if (thid >= 0) sceKernelStartThread(thid, 0, 0);
        return thid;
}
 





Le main, initialisation de l'écran, le setupcallback, l'initialisation de la SDL et de la SDL_ttf.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
int main(int argc, char **argv)
{
        pspDebugScreenInit();
        SetupCallbacks();

        if(SDL_Init(SDL_INIT_VIDEO) < 0)
                sceKernelExitGame();

        if (TTF_Init() < 0)
                sceKernelExitGame();
 





Ensuite nous déclarons quelques variables pour l'heure, les minutes, secondes, millisecondes et un buffer ou y "écrire" le temps écoulé.

Syntaxe: [ Télécharger ] [ Masquer ]
        int h = 0, m = 0, s = 0, ms = 0;
        char bf[30] = {NULL};




Nous déclarerons une variable SDL_Color et une autre TTF_Font* pour y charger la police a utiliser.
On crée également l& surface pour l'écran.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_Color couleur_text = {0, 0, 0};
        TTF_Font *police = TTF_OpenFont("Arial.ttf", 70);

        SDL_Surface *screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,32, 
                                                SDL_HWSURFACE |SDL_DOUBLEBUF);





Comme vous pourrez le voir, la couleur du texte est noir et la police que l'on utilisera est la police arial.ttf.

Maintenant nous "écrivons" les variables h, m, s et ms dans le buffer et puis nous créons une surface avec ce qu'il y dans ce buffer.

Syntaxe: [ Télécharger ] [ Masquer ]
        sprintf(bf, "%d:%d:%d:%d", h, m, s, ms);
        SDL_Surface *chronometre = TTF_RenderText_Blended(police, bf,couleur_text);




Maintenant on va déclaré une variable SDL_Rect, SceCtrlData, Chrono et myTime.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_Rect pos;
        pos.x = (SCREEN_WIDTH - chronometre->w) / 2;
        pos.y = 15;

        SceCtrlData pad, oldpad;
    
        Chrono chrono_t;
        chrono_t.start = 0;
        chrono_t.running = 0;
        chrono_t.activated = 0;

        myTime mytime_t;
        mytime_t.time = 0;
        mytime_t.oldtime = 0;





La variable SDL_Rect sera utilisé pour centrer le chronomètre a 15 pixels du bord de l'écran en haut.
Les variables SceCtrlData seront utilisé pour la gestion des touches, comme dans les tutos précédent.

La variable Chrono est initialisé a 0.
Celle ci sera utilisé pour savoir si le chronomètre est activé ou non et pour récupérer le temps écoulé.

La variable myTime est utilisé pour "rafraichir" la surface chronomètre tout le X ms. On verra comment un peu plus tard 


On entre dans la boucle, on "lit" les touches et on "efface" l'écran.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        while (!done)
        {
                sceCtrlReadBufferPositive(&pad, 1);

                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 50,100, 255));





La gestion des touches :

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                if ((pad.Buttons & PSP_CTRL_CROSS) && !(oldpad.Buttons &PSP_CTRL_CROSS))
                {
                        chrono_t.activated++;
                        
                        if (chrono_t.activated == 1)
                                chrono_t.start = SDL_GetTicks();
                        else if (chrono_t.activated == 2)
                                chrono_t.activated = 0;
                }
                else if ((pad.Buttons & PSP_CTRL_START) && !(oldpad.Buttons& PSP_CTRL_START))
                        done = 1;





Nous n'utiliseront que 2 touches ; X et START.

Si nous appuyons sur X, la variable chrono_t.activated va incrémenter. Ce qui fait que le chronomètre va s'activer.
La variable chrono_t.start récupère le temps écoulé depuis le début du programme. Nous l'utiliserons comme un point de repère.
Puis, si chrono_t.activated vaut 2 nous la réinitialisons a 0 et le chronomètre est arrêté.

La touche START permet de quitter le programme, c'est tout 
.


Maintenant le "coeur" du programme :

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                mytime_t.time = SDL_GetTicks();

                if(mytime_t.time - mytime_t.oldtime > 10)
                {
                        if (chrono_t.activated == 1)
                        {
                                chrono_t.running = SDL_GetTicks() -chrono_t.start;
                                bf[0] = '\0';
                                ms = (chrono_t.running % 1000) / 10;//récupérer les ms
                                s = (chrono_t.running / 1000) % 60;//récupérer les s
                                m = ((chrono_t.running / 1000) / 60) % 60 ;//récupérer les m
                                h = (((chrono_t.running / 1000) / 60) / 60)% 60; //récupérer les h

                                SDL_FreeSurface(chronometre);
                                chronometre = NULL;
                                sprintf(bf, "%d:%d:%d:%d", h, m, s, ms);
                                chronometre = TTF_RenderText_Blended(police,bf, couleur_text);

                                pos.x = (SCREEN_WIDTH - chronometre->w) / 2;
                        }

                        mytime_t.oldtime = mytime_t.time;
                }
                else
                        SDL_Delay(mytime_t.time - mytime_t.oldtime);





mytime_t.time récupère le temps écoulé depuis le début du programme.
Nous vérifions si le temps écoulé est plus grand que 10ms. 
Si tel est le cas, nous vérifions si le chronomètre est activé, puis mytime_t.oldtime vaut mytime_t.time.
Si ce n'est pas le cas alors cela veut dire qu'il n'y a pas encore 10ms d'écoulé, donc nous faisons une petite pause grâce a la fonction SDL_Delay.
Cette dernier ne prend qu'un paramètres et c'est le temps en ms. Ici nous mettons le programme en pause pendant le temps qu'il reste avant que 10ms ne soit écoulé.

Si le chronomètre est activé nous allons récupéré le temps écoulé dans la variable chrono_t.running et y soustraire chrono_t.start, le point de repère de tout a l'heure.
On réinitialise le buffer, pour ensuite y écrire l'heure, les minutes, etc.

Maintenant quelques calculs pour connaitre les ms, s, m, h, passé.
On libère la mémoire de la surface chronomètre, puis on l'initialise à NULL.
On écrit dans le buffer les différentes variables pour le temps, précédemment calculé, grâce à sprintf.
Il ne nous reste plus qu'a refaire la surface chronomètre avec ce qu'il y a dans le buffer et a recentrer le chronomètre.

On écrit a l'écran si le chronomètre est en route ou non. On blitte la surface et on affiche le tout a l'écran. Sans oublier de refermer la boucle principale.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
                pspDebugScreenSetXY(10, 30);
                pspDebugScreenPrintf("Chronometre is%sactivated",chrono_t.activated ? " " : " not ");

                SDL_BlitSurface(chronometre, NULL, screen, &pos);
                SDL_Flip(screen);

                oldpad = pad;
        }





Ah, et ne pas oublier de dire que oldpad vaut pad, sinon le chronomètre va bugger 
.


Et voila on termine le programme avec :

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
        SDL_FreeSurface(screen);
        SDL_FreeSurface(chronometre);
        SDL_Quit();

        sceKernelExitGame();

        return 0;
}





Je n'ai plus besoin de vous expliquer ça 
.


Le makefile :

Code:
TARGET = SDL_TUTO
OBJS = main.o

INCDIR =
CFLAGS = -G4 -Wall -O3 -I/usr/local/pspdev/psp/include/SDL
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)


PSPSDK=$(shell psp-config --pspsdk-path)
PSPBIN = $(PSPSDK)/../bin

LIBDIR =
LDFLAGS =
STDLIBS= -lSDLmain -lSDL -lGL -lpng -ljpeg -lz -lm\
      -lstdc++ -lpspgu -lpspvfpu -lpsprtc -lpsphprm -lpspaudio
LIBS= -lSDL_ttf -lfreetype $(STDLIBS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto SDL By Pyroesp

PSPSDK=$(shell psp-config --pspsdk-path)
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
include $(PSPSDK)/lib/build.mak
On passe a 
 
La bibliothèque GameEngine : 
 
La LibGE, ou Game Engine Library, est une bibliothèque de développement sur PSP qui propose des fonctions d'affichage d'images et de textes, de lecture de sons et musiques, des fonctions permettant d'utiliser les touches, d'utiliser des timers, des threads ou encore afficher un clavier virtuel à l'écran.

Cette bibliothèque de programmation se veut la plus performante possible, elle est en effet capable d'afficher énormément d'images en même temps permettant de faire des jeux et des programmes complexes, elle utilise également une gestion poussée de la mémoire vive permettant de charger une grande quantité d'objets en même temps. La LibGE propose des fonctions aux noms clairs et précis. Ses prochaines versions proposeront également l'utilisation de scènes en 3 dimensions pour réaliser des jeux ou même des programmes ayant une interface en 3D.

La LibGE utilise une syntaxe particulière permettant de la reconnaitre facilement :
- Tous les types déclarés par la LibGE sont précédés de ge_, le type commence par une majuscule, exemples :
Show/Hidden c code

 

 
Code:
[b][b]ge_Image  //structure contenant une image ge_Font  //structure contenant une police d'écriture[/b][/b]



Toutes les structures de la LibGE seront des pointeurs, chaque appel de chargement ou d'utilisation d'une structure de type ge_Xxx renverra out utilisera un pointeur de type ge_Xxx*

- Toutes les fonctions proposées par la LibGE sont précédées de ge, exemples:
Show/Hidden c code

 

 
Code:
[b][b]geLoadImage geDrawImage[/b][/b]



 
 

Bonjour,

Dans ce tuto je vais vous apprendre à faire le programme de base pour la LibGE de dridri85.
Vraiment rien de compliqué 
.

Tout d'abord je précise que ce tuto est fait avec la dernière version en date de la LibGE, notamment la LibGE 0.5 BugFix.


Syntaxe: [ Télécharger ] [ Masquer ]
#include
#include
 



Les includes, à choisir selon vos besoins et ne pas oublier d'inclure la libge 
.


Syntaxe: [ Télécharger ] [ Masquer ]
PSP_MODULE_INFO("LibGE_HelloWorld", 0, 0, 0);
PSP_HEAP_SIZE_KB(512);
 



L'info de la PSP. Rien de super spécial là dedans, juste que le heap size reste toujours le même, dans tous vos programmes.


Syntaxe: [ Télécharger ] [ Masquer ]
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
 



Je définis presque toujours la taille de l'écran. Cela pourra nous être utile pour afficher par exemple une image au centre de l'écran, ect.


Syntaxe: [ Télécharger ] [ Masquer ]
int main(int argc, char *argv[])
{
 



Le main, rien de nouveau.


Syntaxe: [ Télécharger ] [ Masquer ]
    geInit();
 



On initialise la LibGE. Pour ceux qui ont déjà travaillé avec la SDL, cette fonction revient à faire SDL_Init(...).
Cette fonction doit être présente dans le programme avant tout autre fonction de la LibGE.


Syntaxe: [ Télécharger ] [ Masquer ]
    while (1) //boucle principale
    {
 



On ouvre la boucle principale.


Syntaxe: [ Télécharger ] [ Masquer ]
        geClearScreen();
        geSwapBuffers();
 



La première fonction (geClearScreen) éfface, comme son nom l'indique, l'écran.
La seconde fonction (geSwapBuffers) va intervertir les display buffers.
Pour ceux qui ont utilisé la SDL, cela revient à utiliser SDL_DOUBLEBUF.

Petite citation du Site Du Zéro (que je remercie 
):

Citer:
Le double buffering est une technique couramment utilisée dans les jeux. Elle permet d'éviter un scintillement de l'image.
Pourquoi l'image scintillerait-elle ? Parce que quand vous dessinez à l'écran, l'utilisateur "voit" quand vous dessinez et donc quand l'écran s'efface. Même si ça va très vite, notre cerveau perçoit un clignotement et c'est sacrément désagréable.

La technique du double buffering consiste à utiliser 2 "écrans" : l'un est réel (celui que l'utilisateur est en train de voir sur son moniteur), l'autre est virtuel (c'est une image que l'ordinateur est en train de construire en mémoire).

Ces 2 écrans alternent : l'écran A est affiché pendant que l'autre (l'écran B) en "arrière-plan" prépare l'image suivante.

Une fois que l'image en arrière-plan (l'écran B) a fini d'être dessinée, on intervertit les 2 écrans.

L'écran A part en arrière-plan préparer l'image suivante, tandis que l'image de l'écran B s'affiche directement et instantanément aux yeux de l'utilisateur.
Résultat : aucun scintillement 



C'est entre ces deux fonctions que vous afficherez vos images, textes, ...


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
    }

    sceKernelExitGame();
    return 0;
}
 




On ferme la boucle principale, on quitte le programme, on retourne 0 et on ferme le main.

Voila, rien de compliqué 
.

Je termine donc par le code complet et le makefile:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include

PSP_MODULE_INFO("LibGE_HelloWorld", 0, 0, 0);
PSP_HEAP_SIZE_KB(512);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int main(int argc, char *argv[])
{
    geInit();

    while (1)
    {
        geClearScreen();
        geSwapBuffers();
    }

    sceKernelExitGame();
    return 0;
}
 






Code:
TARGET = LibGE
OBJS = main.o

CFLAGS = -O2 -G0 -Wall -DPSPFW3xx
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBS = -lge -lfreetype -lpspmp3 -lm

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World with LibGE

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak



Sur ce, je vous dis à la prochaine pour un autre tuto 


Bye.

PS: Encore un peu et j'oubliais. Ce programme peut être compilé, le seul bémol c'est que vous avez un écran noir (tout le temps). Vous pourrez, néanmoins, quitter à l'aide de la touche HOME.

EDIT:

J'ai oublié de dire encore un truc:
Vous avez surement/peut-être remarqué qu'il n'y a pas de callbacks et que le programme ne plante pas en quittant avec HOME.
C'est grâce à la LibGE qui gère automatiquement les callbacks 
.

C'est pas génial ça 
 ?



 
 
Salut à tous.
J'ai décidé de faire un tuto sur la libGE de dridri85.
On va voir comment afficher du texte avec la LibGE.

Tout d'abord, téléchargez une police. Allez sur http://dafont.com et, une fois téléchargée, mettez la dans le dossier de votre projet. Moi j'utiliserais la police Arial.ttf

Ouvrez un nouveau projet et on va pouvoir commencer !

On inclut les headers nécessaires :


Code:
#include
#include
#include //Pour inclure la lib



On va ensuite donner les informations à la PSP :

Code:
GE_PSP_INFO("Tuto TTF", 0, 0, 1,512);


Après, on commence notre fonction principale (main) :

Code:
int main(int argc, char *argv[])
{



Si on veut utiliser les fonction debug (pspDebugScreenSetXY(), pspDebugScreenPrintf(), le clavier debug ...) on ajoute

Code:
pspDebugScreenInit();


On initialise ensuite la LibGE :

Code:
     geInit();


Ensuite, on va charger la font qu'on a téléchargée tout à l'heure :

Code:
     ge_Font *font = geLoadFont("Arial.ttf");


Puis on va définir la taille d'écriture :

Code:
     geFontSize(font, 16); //font étant le nom de la police chargée plus haut


On commence la boucle while, puis on efface l'écran :

Code:
     while(1)
     {
          geClearScreen();



Ensuite, on va afficher notre texte avec la fonction geFontPrintScreen(x, y, font, texte, couleur);

  • x est la position du texte en abscisse
  • y est la position du texte en ordonnée
  • font est la police utilisée
  • texte est le texte à afficher
  • couleur est le couleur du texte. Grâce à RGB(r,g,b)


Code:
          geFontPrintScreen(10, 10, font, "GeFont !", RGB(255, 255, 255));


On rafraichit l'écran, puis on ferme le while. 

Code:
          geSwapBuffer();
     }


On libère ensuite la police de la RAM :

Code:
    geFreeFont(font);


Puis on quitte la LibGE puis le programme et enfin, on ferme le main :

Code:
    geQuit();
    sceKernelExitGame();
    return 0;
}


On a fini ! 
 Voici le code complet :



Code:
#include
#include
#include

PSP_MODULE_INFO("Tuto LibGE", 0, 0, 1);
PSP_HEAP_SIZE_KB(512);

int main(int argc, char *argv[])
{
    //pspDebugScreenInit(); //Uniquement pour les fonctions debug
    geInit();

    ge_Font *font = geLoadFont("Arial.ttf");
    geFontSize(font, 16);

    while (1)
    {
        geClearScreen();
        geFontPrintScreen(10, 10, font, "GeFont !", RGB(255,255,255));
        geSwapBuffers();
    }

    geFreeFont(font);
    geQuit();
    sceKernelExitGame();
    return 0;
}


Voici le MakeFile, pensez bien a ajouter -lfreetype aux LIBS: 

Code:
TARGET = LibGE
OBJS = main.o

CFLAGS = -O2 -G0 -Wall -DPSPFW3xx
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBS = -lge -lfreetype -lm

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = LibGE

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


Voici le résultat :



Voici l'archive contenant le code source + l'eboot.pbp :
http://www.mediafire.com/?t77wdya5psexbp0

Voilà, vous savez maintenant écrire avec la LibGE. 
 
 
Le code n'est pas très compliqué, le voici : 

Code:
#include

PSP_MODULE_INFO("Tuto IntraFont", 0, 0, 1);

#define BLANC 0xFFFFFFFF //Couleur du texte

int main(int args, char** argc){
    //Initialise la LibGE
    geInit();

    //On charge la police IntraFont (format *.pgf)
    ge_Font* police = geLoadIntraFont("flash0:/font/ltn8.pgf");

    //Taille de la police de caractères
    geIntraFontSize(police, 12); //12 est la taille standard

    while(1){
        //Efface l'écran
        geClearScreen();

        //Affichage d'un texte avec l'IntraFont
        geIntraFontPrintScreen(50, 50, police, "Tuto IntraFont par Blecta pour XTreamLua", BLANC);

        //Mise à jour de l'écran
        geSwapBuffers();
    }
    //Libère la police de la ram de la PSP
    geFreeIntraFont(police); 
    return 0;
}


J'ai commenté quasiment toutes les lignes pour que vous compreniez bien 

Et voici le Makefile pour compiler le code pour la PSP :

Code:
TARGET = tuto_IntraFont
OBJS = main.o

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBS = -lge -lm -lpsprtc

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Tuto IntraFont

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


Pour finir, voici le résultat :


J'espère que ce tuto vous a plu. Si vous n'avez pas compris certains points n'hésitez pas à poser des questions 



Bonjour,

Ce tuto va vous apprendre à afficher une image, sur votre PSP, à l'aide de la LibGE.
L'image que nous allons afficher est la suivante:



Tout d'abord reprennons le "code de base", que vous retrouverez dans le lien si dessous:
[LibGE] Code de base pour LibGE

Prêt 
 ?

Ok, c'est parti.

Tout d'abord, une petite question:
Ou doit-on écrire le chargement de l'image ?
- La boucle principale ? Bien sur que non, voyons...
- Avant geInit() ? Encore raté

La bonne réponse est après geInit().
Pourquoi ?
Je vois mal comment l'on pourrait utiliser des fonctions de la LibGE alors que celle ci n'est même pas initialisé.

Le chargement de l'image:

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
    geInit(); //déjà écrit dans le code de base

    ge_Image *bg = NULL;
    bg = geLoadImage("background.png");
    geSwizzle(bg);
 





Nous déclarons un pointeur de structure de type ge_Image, nommé bg et on l'initialise a NULL.
Pour ceux d'entre vous qui ont déjà utilisé la SDL, l'on pourrait comparer ge_Image par SDL_Surface.

Une fonction importante !
ge_Image* geLoadImage(const char* file)
Cette fonction va charger votre image et renvoyer une ge_Image 
.


Une autre fonction, geSwizzle(ge_Image* image).
Pour être franc je ne sais pas trop à quoi elle sert.

Ensuite nous allons afficher l'image a l'écran.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ]
        geClearScreen(); //déjà écrit dans le code de base
        geDrawImage(0,0, bg);
        geSwapBuffers(); //déjà écrit dans le code de base
 





La fonction qui affiche l'image est geDrawImage(int x, int y, ge_Image* image).
Je ne pense pas devoir expliquer comment l'utiliser. Simple comme bonjour 
.


Sachez que la fonction geClearScreen n'est pas nécéssaire.
L'image "éfface" l'ecran pour nous, sauf qu'au lieu d'avoir un ecran noir, l'on a directement l'image 
.


Une dernière petite chose, "liberer" l'image de la ram.

Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
    geFreeImage(bg);

    //déjà écrit dans le code de base
    sceKernelExitGame();
    return 0;
}
 





geFreeImage(ge_Image* image).
Rien de compliqué ici non plus 
.


Sur ce, je termine ce tuto avec le programme en entier et le makefile.


Syntaxe: [ Télécharger ] [ Masquer ] [ Sélectionner ] [ Etendre ]
#include

PSP_MODULE_INFO("LibGE_HelloWorld", 0, 0, 0);
PSP_HEAP_SIZE_KB(512);

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

int main(int argc, char *argv[])
{
    geInit();

    ge_Image *bg = NULL;
    bg = geLoadImage("background.png");
    geSwizzle(bg);

    while (1)
    {
        geClearScreen();
        geDrawImage(0,0, bg);
        geSwapBuffers();
    }

    geFreeImage(bg);

    sceKernelExitGame();
    return 0;
}
 






Code:
TARGET = LibGE
OBJS = main.o

CFLAGS = -O2 -G0 -Wall -DPSPFW3xx
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBS = -lge -lfreetype -lpspmp3 -lm

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World with LibGE

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak



Vous pouvez maintenant creer vos propres homebrews
n'oubliez pas de les mettre sur le site et
  A XTREAMLUA pour ce tuto
 
 


 
 
  
  


Revenir en haut
Visiter le site web du posteur
Publicité






MessagePosté le: Mer 16 Fév - 10:13 (2011)    Sujet du message: Publicité

PublicitéSupprimer les publicités ?
Revenir en haut
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    Psp-Gun Index du Forum -> Tutoriels -> Creer Vos homebrews Toutes les heures sont au format GMT + 1 Heure
Page 1 sur 1

 
Sauter vers:  
Index | Panneau d’administration | Creer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation