Custom Protocol

[PSP] [Vita] Le ONELua de nouveau mis à jour

Découvrons ensemble les nouveautés de cette nouvelle version du ONELua !

Note : cet article est très long et il s'adresse aux développeurs à devenir ou bien ceux maîtrisant déjà le langage Lua souhaitant découvrir ce que la PSP a dans le ventre. La quantité de travail fourni dans cet article est considérable et j'espère que vous l'apprécierez car j'y ai consacré beaucoup de mon temps libre. Je tiens à remercier notamment gdljjrod ainsi que Davis Nuñez pour leur patience et leur aide à la rédaction de cet article.

Nous vous l'avions annoncé, gdljjrod et Rober Galarga ont mis à jour leur interpréteur Lua pour PSP dénommé ONELua. Après deux versions réussies, les deux développeurs reviennent aujourd'hui avec une nouvelle version contenant encore une flopée de nouveautés que nous allons découvrir et décortiquer ensemble pour vous permettre de comprendre leur utilisation via des explications, des exemples et des captures d'écran : bref un article signé Custom Protocol.

vignette-ONELua-v3
Le ONELua Version 3

Optimisations

Commençons tout d'abord par les nouveautés au niveau des optimisations. Le ONELua en version 3 supporte maintenant les PS Vita utilisant le VHBL, pratique pour lancer des homebrews si on possède le jeu (et sa démo) Toukiden: Kiwami (dispo uniquement sr le Store JP) possédant un exploit en 3.51, ou encore l'exploit World of Pool. Ainsi le Lua Player devient pleinement compatible pour tourner sur toutes les PSP mais également sur les PS Vita. Les développeurs ont également ajouté une nouvelle bibliothèque nommée BitOp qui ajoute des opérations binaires sur les nombres. Vous pouvez regarder les fonctions disponibles avec des exemples à cette adresse.

N'oubliez pas de consulter notre tutoriel pour garder votre PS Vita en firmware 3.36 et empêcher la mise à jour automatique
Le ONELua version 3 pleinement compatible avec la PS Vita

Cette bibliothèque n'a pas été implémentée au ONELua par hasard, en effet, vous trouverez dans l'archive contenant l'interpréteur un exemple vous démontrant comment utiliser une nouvelle fonction permettant de créer des maps avec un simple fichier texte. Il y a seulement deux fonctions mais aux fonctionnalités intéressantes.

map.new(IMAGE tileset, TABLE mapData, NUMBER TileX, NUMBER TileY)
--IMAGE tileset : Image généré via GBA Graphics contenant les textures pour la map
--TABLE mapdata : Map créé via GBA Graphics contenant les informations de la map
--NUMBER TileX : Taille largeur en pixel des textures à découper
--NUMBER TileY : Taille longueur en pixel des textures à découper
--Retourne la map (à stocker dans une variable)

map.blit(MAP map, NUMBER x, NUMBER y)
--MAP map : Map à afficher généré via la fonction map.new
--NUMBER x : Placement sur l'écran en x
--NUMBER y : Placement sur l'écran en y
--Ne retourne rien

On peut soit dans l'exemple fourni créer une map en vue de face mais également en vue de côté. Comme cité dans les fonctions, il vous faudra obligatoirement utiliser le logiciel GBA Graphics 1.09 disponible certes en anglais mais aussi en français !

Voici quelques exemples postés par plusieurs développeurs des possibilités de ces fonctions.

En exemple, pour utiliser cette fonction, vous pouvez vous référer au contenu de l'archive du ONELua où le code a été commenté par @applelo1 (moi même) en français.

Fonctions images

Passons ensuite aux fonctions images, où nous avons le droit à une ribambelle de nouveautés. Nous avons enfin la possibilité de charger les images dans la VRAM (mémoire vidéo) via la fonction image.loadv() pour un affichage plus rapide de celles-ci (pour des sprites par exemple) mais plus limité en mémoire que la RAM (mémoire vive). Il est aussi possible de "déplacer" une image de la VRAM à la RAM et inversement en utilisant la fonction image.move().

Désormais, via la fonction image.loadfromdata(), les images converties en données binaires peuvent être chargées, utile pour charger les images disponibles sur internet permettant un gain de rapidité. Un petit exemple s'impose pour vous montrer :

local fp = io.open("monimg.png","rb")--J'ouvre l'image comme si s'était un fichier
local databin = fp:read("*a")--Je lis le contenu du fichier
fp:close()--Je ferme la lecture du fichier

monimg = image.loadfromdata(databin,__PNG)--La fonction charge et transforme les données binaires en fichiers

while true do--J'ouvre ma boucle
image.blit(monimg,0,0) --J'affiche mon image
screen.flip()--Je rafraichie l'écran
end--Je ferme la boucle

Et c'est pas fini, puisqu'on peut également modifier ses images via trois nouvelles fonctions ! La première, image.blitadd(), permet d'afficher l'image en y ajoutant un effet de couleur alors que la deuxième, image.blitsub(), au contraire, permet de supprimer la couleur. La dernière quant à elle, image.blittint(), permet d'afficher une image et de la teindre également d'une couleur.

Voici le récapitulatif de toute les nouvelles fonctions concernant les images retranscrit ici.

image.loadv(STRING path)
image.loadv(STRING path, COLOR mask)
image.loadv(STRING path, NUMBER w, NUMBER h)
image.loadv(STRING path, NUMBER w, NUMBER h, COLOR mask)
--STRING path : Chemin de l'image
--COLOR mask : Masque de couleur à appliquer à l'image
--NUMBER w : Largeur pour couper les sprites
--NUMBER h : Hauteur pour couper les sprites
--Retourne une image, prête à être utiliser.

image.move(IMAGE img)
--IMAGE img : Variable de l'image
--Ne retourne rien

image.loadfromdata(STRING data, NUMBER type)
--STRING data : Donnée de l'image en fichier binaire
--NUMBER type : 
---------------__PNG (0) pour image en .png
---------------__JPG (1) pour image en .jpg
---------------__GIF (2) pour image en .gif


image.blitadd(IMAGE img,NUMBER x,NUMBER y,NUMBER coef)
--IMAGE img : Variable de l'image
--NUMBER x : Placement sur l'écran en x
--NUMBER Y : Placement sur l'écran en y	
--NUMBER coef : Niveau d'ajout de couleur (entre 0 et 255)
--Ne retourne rien

image.blitsub(IMAGE img,NUMBER x,NUMBER y,NUMBER coef)
--IMAGE img : Variable de l'image
--NUMBER x : Placement sur l'écran en x
--NUMBER Y : Placement sur l'écran en y	
--NUMBER coef : Niveau de suppression de couleur (entre 0 et 255)
--Ne retourne rien

image.blittint(IMAGE img,NUMBER x,NUMBER y,COLOR color)
--IMAGE img : Variable de l'image
--NUMBER x : Placement sur l'écran en x
--NUMBER Y : Placement sur l'écran en y	
--COLOR color : Couleur pour teindre l'image
--Ne retourne rien

Le ONELua se montre aussi très performant comme gestionnaire des EBOOT.PBP, 3 nouvelles fonctions font ainsi leur entrée avec cette troisième version par ce que l'on appelle leurs callbacks. La fonction game.pack() permet de créer un EBOOT si vous disposez d'un dossier contenant toutes les ressources nécessaires (PARAM.SFO, ICON0.PNG...). Ensuite, game.add() permet d'ajouter ou remplacer un fichier alors que la fonction game.remove() permet finalement de supprimer un fichier contenu dans l'EBOOT.PBP.

Fonctions TV

Vous devriez savoir, puisque nous vous l'avions déjà annoncé, que le ONELua intègre désormais des fonctions liées à la télévision, la première étant de pouvoir retransmettre l'écran de la PSP vers l'écran d'une télé si vous disposez d'un adaptateur. Il est possible notamment de régler via cette fonction la qualité de la retransmission. Attention, il vous faudra impérativement le dvemgr.prx contenu dans l'archive pour pouvoir faire fonctionner la fonction. La deuxième, os.cabletv(), permet de reconnaître si votre PSP est branchée à un écran externe ainsi que le type de câble utilisé.

os.modetv(NUMBER quality)	
--Active la retransmission
--NUMBER quality : La qualité de retransmission
--------------------__8888 (32 bits RGBA)
--------------------__4444 (16 bits R4G4B4A4)
--------------------__5551 (16 bits R5G5B5A1)
--------------------__5650 (16 bits R5G5B5, pas de chaîne alpha)
--Ne retourne rien

os.modetv()
--Désactive la retransmission
--Ne retourne rien

os.cabletv()	
--Reconnait le cable utilisé
--Retourne un nombre
--0 si aucun cable n'est connecté
--1 si c'est un cable S-Video/AV (composite)
--2 si c'est un cable D Terminal Cable/Component Cable

Fonction windows

En plus de cela, une nouvelle fonction vient de faire son apparition, et nommée os.messagebox(). Elle permet d'afficher une boîte de dialogue (ressemblant beaucoup à celle de Windows) avec des possibilités de personnalisation. On peut par exemple entrer le titre et le message de son choix, ainsi que choisir entre 1 à 4 boutons associés à des actions simples (Oui, Non, Quitter, Annuler, Ok) mais malheureusement qui ne sont pas paramétrables et en anglais. Voici l'exemple fourni par les auteurs avec les commentaires traduits en français :

option = {"OK","CANCEL","YES","NO",""}--Table des réponses

--La variable ou est reçu les réponses de la fonction os.messagebox()
local response = 5

local title = "Test Of Box" -- Titre
local msg = "Hello From Box...\nOK = 1\nCANCEL = 2\nYES = 3\nNO = 4\nEXIT = 5" -- Message

while true do
    buttons.read() -- Lecture des touches pressés

    if buttons.triangle then -- Pressez /\
	-- Montre deux boutons X:OK, O:CANCEL par défaut
		response = os.messagebox(title,msg)

    elseif buttons.circle then --Pressez O
	-- Montre le bouton 0:EXIT
        response = os.messagebox(title,msg,__CIRCLE,__EXIT)

    elseif buttons.cross then--Pressez X
	-- Montre deux boutons avec L: No, R: Yes
		response = os.messagebox(title,msg,__L,__NO,__R,__YES)

    elseif buttons.square then -- Pressez []
	-- Montre trois boutons avec L: No, R: Yes X: YES, O: NO, /\: Exit
		response = os.messagebox(title,msg,__CROSS,__YES,__CIRCLE,__CANCEL,__TRIANGLE,__EXIT)
    end

    screen.print(10,5,"Example Message Box")
	
	screen.print(10,17,"Presez triangle pour un simple Message Box (X:OK, O:CANCEL)",0.6)
	screen.print(10,32,"Pressez rond pour un Message Box (O:EXIT)",0.6)
	screen.print(10,47,"Pressez croix pour un Message Box (L:NO, R:YES)",0.6)
	screen.print(10,62,"Pressez carré pour un Message Box (X:YES, O:CANCEL, triangle:EXIT)",0.6)

    -- Nous affichons la valeur pour telle action :)
	screen.print(10,200,"Résultat: "..response.." Selection: "..option[response])

    screen.flip() -- Rafraîchissement de l'écran
end
	
ONELua_messagebox
La boîte de dialogue sympathique mais qui reste limitée...

De plus, impossible de personnaliser l'apparence des boutons et de la boîte de dialogue. Espérons une mise à jour pour pouvoir personnaliser d'avantage cette petite fonction bien sympathique.

os.messagebox(STRING title,STRING mje)
--STRING title : Le titre de la boîte de dialogue
--STRING mje : Le message à mettre dans la boîte de dialogue
--Retourne 1 si la réponse est OK (quand vous pressez X) ou bien 2 quand vous choisissez CANCEL (quand vous pressez O)

os.messagebox(STRING title,STRING mje,NUMBER button1,NUMBER assigned1)
--STRING title : Le titre de la boîte de dialogue
--STRING mje : Le message à mettre dans la boîte de dialogue
--NUMBER button1 : Le bouton à inscrire (par exemple __CIRCLE, __UP, __L)
--NUMBER assigned1 : L'action à assigner __OK, __CANCEL, __YES, __NO, __EXIT
--Retourne 1 si l'action est __OK, 2 si __CANCEL, 3 si __YES, 4 si __NO et 5 si __EXIT

os.messagebox(STRING title,STRING mje,NUMBER button1,NUMBER assigned1,NUMBER button2,NUMBER assigned2)
--STRING title : Le titre de la boîte de dialogue
--STRING mje : Le message à mettre dans la boîte de dialogue
--NUMBER button1 : Le bouton à inscrire (par exemple __CIRCLE, __UP, __L)
--NUMBER assigned1 : L'action à assigner __OK, __CANCEL, __YES, __NO, __EXIT
--NUMBER button2 : Le bouton à inscrire (par exemple __CIRCLE, __UP, __L)
--NUMBER assigned2 : L'action à assigner __OK, __CANCEL, __YES, __NO, __EXIT
--Retourne 1 si l'action est __OK, 2 si __CANCEL, 3 si __YES, 4 si __NO et 5 si __EXIT

os.messagebox(STRING title,STRING mje,NUMBER button1,NUMBER assigned1,NUMBER button2,NUMBER assigned2,NUMBER button3,NUMBER assigned3)
--STRING title : Le titre de la boîte de dialogue
--STRING mje : Le message à mettre dans la boîte de dialogue
--NUMBER button1 : Le bouton à inscrire (par exemple __CIRCLE, __UP, __L)
--NUMBER assigned1 : L'action à assigner __OK, __CANCEL, __YES, __NO, __EXIT
--NUMBER button2 : Le bouton à inscrire (par exemple __CIRCLE, __UP, __L)
--NUMBER assigned2 : L'action à assigner __OK, __CANCEL, __YES, __NO, __EXIT
--NUMBER button3 : Le bouton à inscrire (par exemple __CIRCLE, __UP, __L)
--NUMBER assigned3 : L'action à assigner __OK, __CANCEL, __YES, __NO, __EXIT
--Retourne 1 si l'action est __OK, 2 si __CANCEL, 3 si __YES, 4 si __NO et 5 si __EXIT

Fonctions écran

Continuons sur une nouvelle fonction qui ravira toute personne qui ne souhaiterait pas utiliser le grand écran de la PSP : la fonction screen.clip(). Vous l'aurez deviné, elle permet de n'afficher qu'une partie de l'écran déterminable avec la fonction.

screen.clip(NUMBER x,NUMBER y, NUMBER w, NUMBER h)
--Active la délimitation d'affichage à l'écran
--NUMBER x : Position sur l'axe x 
--NUMBER y : Position sur l'axe y
--NUMBER w : Largeur
--NUMBER h : Hauteur
--Ne retourne rien

screen.clip()
--Désactive la délimitation d'affichage à l'écran
--Ne retourne rien
ONELua_screen.clip()
Le logo Custom Protocol un peu coupé :p

 

Fonctions texte

Le développeur a également ajouté une fonctionnalité déjà présente dans plusieurs Lua Players : la fonctionnalité permettant de faire défiler un texte. Disponible maintenant avec la fonction screen.print(), il est ainsi possible de réaliser "un scroll" du texte de gauche à droite, de droite à gauche, de droite à gauche puis de gauche à droite et...

-- ## Example Scroll Print ##

-- Nous assignors des variables pour les valeurs X permettrons le daplacement du texte
scrollx1 = 10 -- axe pour déplacement vers la gauche (droite vers gauche)
scrollx2 = 450 -- axe pour déplacement vers la droite (gauche vers droite)
scrollx3 = 240 -- axe pout déplacement de la droite vers la gauche (droite vers la gauche sans disparition)
scrollx4 = 240 -- gauche droite puis droite gauche (centré)


--Charge la palette de couleur
color.loadpalette()

while true do--On ouvre la boucle
	draw.line(240,0,240,272,color.red) --Nous traçons une ligne vertical rouge au milieu de l'écran
	--[[La variable précédente assigné à l'axe x est passé comme un argument et ergot le résultat de la fonction et s'ajoute à cela l'argument "w" pour régler l'affichage de la zone de texte.]]


	--__SLEFT est comme un alignement vers la gauche affiché à partir de l'axe x vers la droite avec un espace d'affichage de 90.
	scrollx1 = screen.print(scrollx1,10,"test scroll gauche",0.7,color.white,color.black,__SLEFT,90)

	--__SRIGHT est comme un alignement vers la droite affiché à partir de l'axe x vers la gauche avec un espace d'affichage de 100.
	scrollx2 = screen.print(scrollx2,25,"test scroll right",0.7,color.white,color.black,__SRIGHT,100)

	-- __STHROUGH est comme un alignement vers la gauche qui est affiché à partir de l'axe x vers la droite avec un espace d'affichage de 100. 
	scrollx3 = screen.print(scrollx3,50,"test scroll throuh",0.7,color.white,color.black,__STHROUGH,100)

	--[[__SSEESAW est un alignement au centre affiché sur l'axe x - moitié de l'espace pour l'afficher,
du droite centrer à gauche centré avec un espace d'affichage de 100
	Note: Si ce mode n'a pas d'effet, c'est pour les raison précedemment cité, alors il effete normalement un texte aligné à gauche.]]

	scrollx4 = screen.print(scrollx4,70,"test scroll seesaw",0.7,color.white,color.black,__SSEESAW,100)

	screen.flip() --Rafraichissement de l'écran
end--Fin de la boucle
	
ONELuav3_scroll
La fonction screen.print() fait maintenant défiler le texte.

Concernant toujours la fonction gérant l'affichage de texte, il est maintenant possible de pouvoir justifier le texte en plus d'aligner à droite, à gauche ou bien au centre.

Fonction contrôle

L'une des dernières principales nouveautés dont nous allons vous parler concerne les contrôles : qui n'a jamais trouvé cela fatigant dans un homebrew de devoir appuyer plusieurs fois sur "Haut" ou "Bas" pour naviguer dans un long menu ? Ce n'est clairement pas pratique, mais gdljjrod et Rober Galarga ont trouvé une solution : la fonction buttons.interval(). Elle permet tout simplement de simuler le fait de rappuyer sur une touche, tout cela étant paramétrable que ce soit le temps d'activation ou le temps entre chaque répétition. Cette fonction ne fonctionne évidemment pas si vous avez choisi que l'action effectuée doit être "maintenir appuyer le bouton".

buttons.interval(NUMBER delay,NUMBER interval)
--Active la fonction
--NUMBER delay : Le délai en cycle avant l'activation (valeur conseillé 40)
--NUMBER interval : L'interval de répétition en cycle (valeur conseillé 10)
--Ne retourne rien

buttons.interval()
--Désactive la fonction
--Ne retourne rien

Autres fonctions

Dans les ajouts mineurs, on retrouve plusieurs petites nouveautés. Tout d'abord, la fonction amg.screenshot() a été ajoutée et permet, comme vous l'aurez sans doute deviné, de prendre une capture d'écran lorsque vous utilisez la librairie AMG spécialisée dans la 3D. Ensuite, les fonctions timers.new et timer.reset retournent la valeur initiale, et la fonction os.cfw() reconnait si l'utilisateur utilise le VHBL. Enfin, la fonction ini.read() peut maintenant lire jusqu'à 1024 caractères. Le développeur a amélioré par ailleurs les performances et corrigé des bugs notamment celui concernant la fonction screen.textheight().

Comme vous pouvez le constater, le ONELua version 3 est l'aboutissement d'un long travail de ces développeurs qui incluent des nouveautés de plus en plus ambitieuses. En espérant qu'ils ne s'arrêtent pas de si tôt !

Bouton télécharger
ONELua v3 pour PSP/PS Vita

Pour finir ce long article en beauté, on va conclure comme dans notre dernier article sur une superbe vidéo montrant les capacités de ce Lua Player. Mise en ligne par gljjrod, il s'agit d'une capture vidéo de la démo réalisée par Mills (développeur connu notamment pour son jeu Space Ball) baptisée Fruit Explosion, que nous vous conseillons de télécharger que vous soyez développeur ou pas pour admirer les capacités de notre bonne vielle PSP.

Bouton télécharger
Fruit Explosion pour PSP/PS Vita

0 commentaire

Suivez-nous

Venez, on n'est pas méchants, on est même très sympas ! 🙂

Nouveaux sujets

Pas de nouveaux messages

Catégories

Archives

Bannière Hypsoma

Suivez-nous

Venez, on n'est pas méchants, on est même très sympas ! 🙂

Catégories

Archives