Dans cet article, on va expliquer comment « bien » rajouter les images et les éléments pour pouvoir avoir un visuel spécifique et réaliste pour une manette. On expliquera aussi les parties QML à changer pour que cela puisse être intégrer dans la partie front end de Pegasus.
Dans cette article, on va voir avec le cas d’un manette de SNES (dans ce cas, on va prendre le visuelle de la Nintendo Switch Online SNES qui permet de couvrir le plus de cas de manettes SNES du marché parce qu’elle a un bouton L1/R1, mais aussi L2/R2). Bien sur, dans ce cas, on n’aura pas de stick analogique ni de L3/R3.
Choisir un image de « base » de qualité
Dans le cas de la SNES, j’ai pris cette du site de Nintendo switch online qui me semble vraiment belle, détaillé et sans ombre. On devra travailler avec des .png, les .svg n’apportent pas grand chose quand on utilise une source photo et non véctorielle.
Préparer l’image de base à afficher
Dans mon cas, j’ouvre le fichier avec GIMP https://www.gimp.org/ puis avec l’outil de sélection contigu
je sélectionne le fond blanc :
Pour selectionné encore mieux vous pouvez aussi utiliser « l’outil de sélection par couleur » :
et en jouant sur le seuil
Puis j’ajoute un « canal alpha » au calque (en faisant bouton droit sur celui-ci):
Ainsi quand je supprime la zone sélectionnée, il me reste que la partie de la manette avec un fond transparent :
Ensuite je réduite le calque pour suivre les contours de la manette en allant dans « image/rogner selon le contenu » :
Maintenant le fichier de « base » est prêt, on va pouvoir l’exporter dans « fichier/exporter sous » et en sélectionnant le format .png (et pour les autres paramètres, on peut garder par défaut ceux de GIMP):
En terme de nommage, c’est bien de suivre la règle:
base_XXXXXX.png
où XXXXX est le nom ou acronyme de la manette (s’assurer que c’est bien unique et pas déjà utilisé bien sur 😉
Dans notre cas, c’est « base_snes.png«
Attention, dans certains, il faudra corrigé des imperfections dans le détourages en virant des pixels voir un ligne entière manuellement si besoin ou corriger un rognage mal placé, C’est pas magique même si 99% du boulot sera acceptable, on pourra peaufiner si besoin ! 😉
On peut aussi pour un rendu encore meilleur dans pixL, supprimer les boutons de façade et remplacer la zone par du noir (à ne pas faire pour les boutons de tranches et autres gachettes qui n’utilisent pas le même type d’animation au final)
Et donc utiliser une image ainsi:
Préparer les images de boutons/pads/sticks/gâchettes
Pour les boutons, le challenge va être de bien les détourer avec l’outil de sélection de couleur ou contigu et en jouant sur les seuils, le but va être de les isolés dans un .png dédié.
On aura 2 solutions de sélections pour le rendu final:
- on peut sélectionner en évitant de prendre les contour noir ou unie qui ne font pas parti du bouton.
- on peut sélectionner le contour noir si on pense pouvoir le réutiliser directement pour les animations.
On pourra aussi utiliser « l’outil de sélection elliptique »
Pour les boutons :
Puis on ira le « copier puis le coller dans un nouvelle image »…
Qui nous donnera un nouvelle image avec un fond transparent:
Donc il faudra tester pour choisir le bon bouton finalement. Je conseil de tester un premier bouton dans le QML avant de continuer pour les autres boutons.
La convention de nommage sera la suivante :
{bouton}_XXXXXX.png
où:
{bouton} sera « a », »b », »x », »y », »l1″ etc…
et XXXXX est le nom ou acronyme de la manette (s’assurer que c’est bien unique et pas déjà utilisé bien sur 😉
Dans notre cas, on a fait le bouton x, donc le nom sera « x_snes.png«
Rajouter des bords noir (si besoin… et que pour les boutons)
Pas applicable pour les gachettes/stick/dpad parce que l’on veut pas de bord noir dans ces cas
Le but est d’expliqué ici comment rajouter directement dans the gimp un tour noir plus prononcé pour accentuer l’appui sur la touche lors de l’animation
Attention, ce n’est pas forcément le mieux, il faut tester pour s’en assurer, cela peut faire moche finalement.
De plus, je me suis rendu compte que si la sélection du bouton est bien faite (en fesant attention de bien prendre la limite du bouton et le corps de la manette (souvent en étant sur la partie noir/grisatre entre les deux), ce n’est plus nécessaire.
On va d’abord resélectionné le bouton lui même avec l’outil de sélection elliptique
Puis on va aller dans le menu « Sélection/Bordure »
On va juste prendre un bord de « 1 » pixel et en style de bordure « Adouci » et valider
Maintenant on va pouvoir remplir la zone autour du bouton avec du noir avec l’outil de remplissage (assuré vous que la couleur noire est bien sélectionné)
Pour avoir un beau cercle noir autour du bouton :
On pourra donc exporter de nouveau en png pour sauvegarder et écraser le fichier précédent si besoin :
Où mettre les nouvelles images préparées ?
Lien de l’ensemble des manettes faites par Aldébaran: https://drive.proton.me/urls/0ED4SCQFQ0#Xk3iNVodSq3K
on va rajouter les fichier de base (exemple: « base_snes.png ») & des touches (exemple: « x_snes.png ») dans le répertoire: src/frontend/assets/gamepad/{XXXXX} acronyme du pad et il faudra les rajouter aussi dans le projet pour être pris en compte dans le .qrc correspondant.
Remarque: pour bien prendre en compte les nouvelles ressources, il faudra « cleaner » et bien rebuilder le projet entièrement.
Paramètres à gérer
Créer des nouvelles images et des QMLs ne sont pas suffisant.
Il faudra le lié à un groupe de controlleur dans le ListModel « myDeviceIcons » qui se trouve dans src/frontend/main.qml et en rajoutant la partie en rouge:
//list model to manage icons of devices
ListModel {
id: myDeviceIcons
//CONTROLLERS PART
...
ListElement { icon: "\uf25e"; keywords: "snes,super nintendo"; type:"controller"; iconfont: "awesome"; layout: "snes"}
...
}
Attention: les contrôleurs sans « layout » déclaré utiliseront le layout « default »
Gestion des icones au passage (si besoin/manquante)
Pour information, la valeur icon et iconfont sont là pour customiser l’icone qui s’affiche quand vous connectez la manette ou quand on l’affiche dans la liste des contrôleurs.
le « \u » est pour préciser que l’on charge une valeur hexadécimal qui est la référence du caractère dans la police correspondante, ex: « awesome » qui est déclaré comme « Font » disponible dans Pegasus-Frontend.
Si vous ne savez pas comment récupérer une valeur spécifique (en fait, il faut être capable d’ouvrir une des fontes disponibles dans les assets de Pegasus et voir quelle icone utiliser et son code correspondant, voir même en rajoutant si besoin mais c’est surement le sujet d’un autre article 😉
Si on veut rajouter des nouvelles icones dans une fonte, il faudra :
- Ouvrir la font en question « fontawesome_webfont.ttf » aller en position F0D1 ou plus vu que l’on a déjà mis d’autres icones de manette.
- Double-cliquer sur une case vide pour aller en mode Edition de la font
- Importer des .svg pas trop lourd ou via un copier/coller venant de l’outil « lnkscape » https://inkscape.org/
- Fermer la fenêtre d’édition
- Vérifier que l’on voit bien la nouvelle icone
- Générer la fonte (ne pas simplement l’enregistrer sinon le format sera corrompu)
Attention, par défaut le nom proposé du fichier à générer est « FontAwesome.ttf », et donc il faudra bien renommer en « fontawesome_webfront.ttf » qui est le nom dans le repo (me demandez pas pourquoi, c’est historique, il faudrait le changer un jour peut-être 😉
Gestion du fichier qml à utiliser
Ensuite, Il faudra aussi mettre à jour le ListModel qui se trouve dans src/frontend/menu/settings/GamepadEditor.qml et dans un premier temps en rajoutant dans un ListElement le nom (exemple pour la SNES) et on utilisera toujours le même « Container » generique pour un nouveau layout (gamepad/preview/ContainerCustom.qml):
ListModel{
id: myControllerLayout
ListElement{name:"nes" ; qml:"gamepad/preview/ContainerCustom.qml"
...
}
ListElement{name:"snes" ; qml:"gamepad/preview/ContainerCustom.qml"
}
}
Remarque: en annexe on explique comment rajouter un nouveau Container (en mode expert 😉 mais cela sera rarement voir jamais utile.
Il va falloir maintenant gérer les coordonnées et donc le placement des boutons/dpad/sticks sur la « base ».
Attention : on devra gérer un ratio parce que l’affichage du « layout » du contrôleur devra être adapté dans certains cas. comme ci-après par exemple :
Il va falloir déjà préciser les informations de la « base » :
ratio: 80/100 //at 80% of the size to enter in the existing container available
padVaseSoureceSizeWidth: 906
padBaseSourceSizeHeight: 398
Remarque: Le « ratio » est important parce que certaines fois, l’image devra être zoomé ou rétrécie pour optimiser au mieux l’affichage.
Il va falloir aussi rentrer les coordonnées à partir de l’image de base, voici dans le cas du « select »…
Pour cela nous allons utiliser Gimp aussi pour connaitre les informations à remplir :
- Pour la taille de l’image on va aller dans « Image/Taille du Canevas »
padSelectWidth : 69;
padSelectHeight : 59;
Pour le positionnement du bouton, on va préciser les coordonnées de l’image dans l’image de base généralement en X/Y et en 2 infos: left X & top Y. voici pour l’info « top Y », on va se mettre en haut de l’image et lire la valeur en Y en bas à gauche (la seconde valeur) :
padSelectTopY: 205;
padSelectLeftX: 334;
Avec ceci, la taille de l’image en pixel + et les informations en X/Y, cela suffit à bien positionner le bouton dans l’image de base.
Attention, il faudra être rigoureux, RighX – LeftX = Width & BottomY – TopY = Height, c’est pour cela que l’on rentre les largeurs/hauteurs en plus des coordonnées pour être au plus juste. Un pixel peut faire la différence.
Donc en conclusion pour un pad comme celui de la SNES, voici les paramètre nécessaire que l’on va devoir mettre dans le ListElement correspondant pour la partie coordonnées:
//parameters for 'base'
ratio: 0.8;
padBaseSourceSizeWidth : 906 ;
padBaseSourceSizeHeight : 398;
//parameters for select
padSelectWidth : 69;
padSelectHeight : 59;
padSelectTopY: 205;
padSelectLeftX: 334;
//parameters for start
padStartWidth : 69;
padStartHeight : 59;
padStartTopY: 205;
padStartLeftX: 432;
//parameters for A/B/X/Y
padAWidth : 71;
padAHeight : 70;
padATopY: 170;
padALeftX: 763;
padBWidth : 71;
padBHeight : 71;
padBTopY: 237;
padBLeftX: 677;
padXWidth : 71;
padXHeight : 71;
padXTopY: 103;
padXLeftX: 677;
padYWidth : 73;
padYHeight : 72;
padYTopY: 170;
padYLeftX: 590;
//parameter for Dpad
dpadAreaTopY: 126;
dpadAreaBottomY: 285;
dpadAreaLeftX: 112;
dpadAreaRightX: 270;
//parameter for L1
padL1Width : 198;
padL1Height : 37;
padL1TopY: 0;
padL1LeftX: 97;
//parameter for R1
padR1Width : 198;
padR1Height : 36;
padR1TopY: 1;
padR1LeftX: 612;
//parameter for L2
padL2Width : 48;
padL2Height : 5;
padL2TopY: 4;
padL2LeftX: 350;
//parameter for R2
padR2Width : 54;
padR2Height : 6;
padR2TopY: 4;
padR2LeftX: 509;
De plus, on aura aussi le mapping des touches disponibles qui est décrit dans le ListElement pour nous permettre de savoir les touches disponibles et ne plus demander de configurer des touches non disponibles (pratique non ? ;-):
//layout availability features list
property var hasSelect : true
property var hasStart : true
property var hasDedicatedGuide : false
property var hasDpad : true
property var hasA : true
property var hasB : true
property var hasX : true
property var hasY : true
property var hasL1 : true
property var hasR1 : true
property var hasL2 : true
property var hasR2 : true
property var hasLeftStick : false
property var hasRightStick : false
property var hasScreenshotButton : false
Au final le nouveau ListElement complet ressemblera à cela :
ListElement { name: "snes"; qml: "gamepad/preview/ContainerCustom.qml";
hasDedicatedGuide: false;
hasSelect: true;
hasStart: true;
hasA: true;
hasB: true;
hasX: true;
hasY: true;
hasNintendoPad : true;
hasL1 : true; hasR1 : true;
hasL2 : true; hasR2 : true;
hasLeftStick : false; hasRightStick : false;
hasL3 : false; hasR3 : false;
hasScreenshotButton : false;
ratio: 0.8; padBaseSourceSizeWidth : 906 ; padBaseSourceSizeHeight : 398;
//parameters for select
padSelectWidth : 69;
padSelectHeight : 59;
padSelectTopY: 205;
padSelectLeftX: 334;
//parameters for start
padStartWidth : 69;
padStartHeight : 59;
padStartTopY: 205;
padStartLeftX: 432;
//parameters for A/B/X/Y
padAWidth : 71;
padAHeight : 70;
padATopY: 170;
padALeftX: 763;
padBWidth : 71;
padBHeight : 71;
padBTopY: 237;
padBLeftX: 677;
padXWidth : 71;
padXHeight : 71;
padXTopY: 103;
padXLeftX: 677;
padYWidth : 73;
padYHeight : 72;
padYTopY: 170;
padYLeftX: 590;
//parameter for Dpad
dpadAreaTopY: 126;
dpadAreaBottomY: 285;
dpadAreaLeftX: 112;
dpadAreaRightX: 270;
//parameter for L1
padL1Width : 198;
padL1Height : 37;
padL1TopY: 0;
padL1LeftX: 97;
//parameter for R1
padR1Width : 198;
padR1Height : 36;
padR1TopY: 1;
padR1LeftX: 612;
//parameter for L2
padL2Width : 48;
padL2Height : 5;
padL2TopY: 4;
padL2LeftX: 350;
//parameter for R2
padR2Width : 54;
padR2Height : 6;
padR2TopY: 4;
padR2LeftX: 509;
} //As SNES pad (but with L2/R2 to be compatible with switch online ones)
Cela semble beaucoup de paramètre mais ne peut pas vraiment faire autrement… donc si on a bien mesuré/reporté les dimensions, on pourra afficher cela au final :
ou même cela…
et la version avec sticks 😉
Prenons justement le cas de la manette de xbox 360 pour décrire certains paramètres importants à connaitre plus en détails :
hasDedicatedGuide: true;
hasSelect: true;
hasStart: true;
hasDedicatedGuide va nous permettre de préciser si on a le « select » qui fera office de hotkey/guide ou pas. Si à « true » cela veut dire que l’on a une touche dédié à la hotkey qui pourra être utilisé.
hasA: true;
hasB: true;
hasX: true;
hasY: true;
hasNintendoPad : false;
hasNintendoPad va nous permettre d’inverser x/y et a/b en fonction du mapping et l’aide contextuelle de la manette s’adaptera mais que dans le menu « gamepad Editor » pour le moment. Ceci pour éviter des incompréhensions d’usage des boutons A/B dans les menus par exemple
hasL1 : true; hasR1 : true;
hasL2 : true; hasR2 : true;
hasLeftStick : true; hasRightStick : true;
hasL3 : true; hasR3 : true;
hasLeftStick/hasRightStick va permettre de préciser que l’on utilise ou pas des sticks (juste L3/R3 utiliseront la même image que les sticks justement ex: lstick_xbox360 et rstick_xbox360)
//parameter for Dpad
dpadAreaTopY: 163;
dpadAreaBottomY: 289;
dpadAreaLeftX: 64;
dpadAreaRightX: 205;
Attention, pour le dpad, on utilise le coin supérieur gauche et le coin inférieur droit quand c’est une croix directionnelle (et pas la largeur/hauteur comme pour les boutons)
//parameter for Dpad with dedicated buttons and separated
dpadUpWidth : 69;
dpadUpHeight : 89;
dpadUpTopY: 189;
dpadUpLeftX: 213;
dpadDownWidth : 67;
dpadDownHeight : 89;
dpadDownTopY: 309;
dpadDownLeftX: 215;
dpadLeftWidth : 89;
dpadLeftHeight : 70;
dpadLeftTopY: 259;
dpadLeftLeftX: 145;
dpadRightWidth : 88;
dpadRightHeight : 70;
dpadRightTopY: 259;
dpadRightLeftX: 264;
Attention: Mais pour un Dpad comme celui du contrôleur de la PS4 avec des boutons indépendants, on aura plus de paramètres à saisir et cela sera géré comme des boutons. (voir ci-dessus, 4 paramètres par direction, up/down/left/right), les images des boutons seront du type: dpup_XXXX.png, dpdown_XXXX.png, dpright_XXXX.png et dpleft_XXXX.png
hasScreenshotButton : false;
hasScreenshotButton est pour voir par la suite si on pourra utiliser des boutons disctincts pour prendre des screenshots. Ce n’est pas encore supporté.
//to adapt contrast/brightness
contrast : 0.5
brightness: 0.5
contrast et brightness aident à distinguer quand on presse sur un bouton (à l’exception de A/B/X/Y qui reste à des valeurs moyennes (0.5)) mais pour les autres on peut les adapter en fonction de la couleur et du contrast du « layout » concerné. Les valeurs sont des « float » et doivent être plus grand que 0.0 et au maximum à 1.0
Par exemple, pour une manette plutôt noire comme celle de la PS4: c’est mieux d’augmenter « brightness » au dessus de 0.5 et baisser « contrast » en dessous de 0.5, mais cela reste à tester à chaque fois que l’on rajoute un layout.
Voilà, il reste les annexes si cela peut aider et voir comment on va pouvoir évoluer par la suite 😉
Enjoy !!!
ANNEXES
Liste des types de contrôleurs supportés à ce jour (dernière mise à jour: 06-03-2023)
(Attention, à ce jour Pegasus détecte par le nom et pas par le GUID. C’est pour que cela marche avec le plus de manette possible)
Pour rappel, le layout générique « default » est Container.qml
Type de manette | Layout utilisé | Mots clé recherché dans le nom de la manette | Apparence |
---|---|---|---|
nes | ContainerCustom.qml | nes,nintendo entertainment system | |
snes | ContainerCustom.qml | snes,super nintendo | |
xbox360 | ContainerCustom.qml | x360,xbox360,xbox 360,x-box 360 | |
xboxone | ContainerCustom.qml | xboxone,xbox one,x-box one | |
ps4 | ContainerCustom.qml | ps4,playstation 4,dualshock 4,wireless controller | |
ps5 | ContainerCustom.qml | ps5,playstation 5,dualsense,wireless controller | |
n64 | ContainerCustom.qml | n64,nintendo 64,nintendo64,huijia | |
switchpro | ContainerCustom.qml | pro controller |
Exemple d’éléments graphiques d’une manette
Les noms de fichiers ne sont pas forcément les bons, on est au début où on doit décomposer les éléments et préparer la base.
Pour tester/introduire un nouveau type de « Container » dans le QML
On aura besoin rarement de faire cela mais cela peut être utile de savoir comment faire un nouveau qml « container » même si avec l’introduction du « ContainerCustom.qml » et la gestion de ces paramètres, on en a plus vraiment besoin de le faire.
Donc, si on en a vraiment besoin (j’insiste ;-), on va juste modifier le qml et ajouter des fichiers dans le projet de Pegasus pour tester. (il faudra être capable de compiler)
- on va se créer un qml spécifique pour la « snes » dans ce cas, ContainerSNES.qml dans le répertoire: src/frontend/menu/settings/gamepad/preview à partir d’un ContainerXXXXX.qml précédent.
- on va se créer aussi un qml spécifique pour les boutons « snes », PadButtonSNES.qml dans le répertoire: src/frontend/menu/settings/gamepad/preview à partir d’un PadButtonXXXXX.qml précédent.
- Dans ContainerSNES.qml, on va changer la source de l’image « padBase » par « qrc:/frontend/assets/gamepad/base_snes.png«
- Pour l’instant dans PadButtonSNES.qml, on va changer la source de l’image « pieceImage » par « qrc:/frontend/assets/gamepad/ » + sortName + « _snes.png » en ligne 32.
- Pour tester le nouveau ContainerXXXXXXX.qml, on va juste l’intégrer dans la liste des « Layout » connu comme décrit dans le paragraphe ci-après.
Remarque: pour bien prendre en compte les nouvelles ressources, il faudra « cleaner » et bien rebuilder le projet entièrement.
Gérer un nouveau « layout »
En fait, on peut gérer des « layout » de style de manettes si besoin, par exemple, à ce jour on a le « layout » SNES qui sait géré des manettes avec 4 boutons + L1/R1 + L2/R2 (comme sur la switchj 😉 et un DPAD, mais sans sticks et seulement avec start/select et pas de touche dédié pour la hotkey.
Donc si on veut gérer un nouveau, il faudra mettre à jour le ListModel qui se trouve dans GamepadEditor.qml dans un premier temps en rajoutant un ListElement un nom et le chemin du fichier comme ci-après (exemple pour la SNES):
ListModel{
id: myControllerLayout
ListElement{name:"snes" ; qml:"gamepad/preview/ContainerSNES.qml"}
}
Puis il faudra le lié à un groupe de controlleur dans le ListModel qui se trouve dans main.qml et en rajoutant la partie en rouge:
//list model to manage icons of devices
ListModel {
id: myDeviceIcons
//CONTROLLERS PART
...
ListElement { icon: "\uf25e"; keywords: "snes,super nintendo"; type:"controller"; iconfont: "awesome"; layout: "snes"}
...
}
Remarque: si on ne défini pas de layout à ce niveau, on ira chercher un layout existant«
Fixer le « device layout » du design par le GUID du contrôleur (mise à jour du 06/03/2023)
Suite à la constatation que dans certains cas, des manettes possèdent le même nom même si elles sont de générations différentes: c’est le cas par exemple de la manette de PS4 et PS5 qui ont toutes les 2 le même nom générique « wireless controller », il a fallut mettre en place la gestion d’un « device layout » qui fait référence au design voulu au niveau de l’es_input.cfg maintenant.
Bien sur, le « device layout » est un paramètre optionnel pour garder la possibilité de chercher par nom qui a aussi ses avantages, et donc sans celui-ci dans l’es_inpujt.cfg, on cherchera dans la liste que l’on a déjà fourni avec une recherche par nom pour sélectionner le design associé.
le nouvelle attribut devra être ainsi:
deviceLayout="ps4"
ou
deviceLayout="ps5"
deviceLayout="xxx"
Il faudra faire référence dans ce « layout » au design existant et déjà défini pour bien forcer l’utilisation d’un design ou d’un autre.
Exemple pour une manette de ps4 :
<!-- Ps4 Wired -->
<inputConfig deviceLayout="ps4" deviceName="Sony Computer Entertainment Wireless Controller" deviceGUID="030000004c050000c405000011810000" deviceNbButtons="13" type="joystick" deviceNbAxes="6" deviceNbHats="1">
<input name="b" id="0" code="304" type="button" value="1"/>
<input name="a" id="1" code="305" type="button" value="1"/>
<input name="select" id="8" code="314" type="button" value="1"/>
<input name="down" id="0" code="16" type="hat" value="4"/>
<input name="left" id="0" code="16" type="hat" value="8"/>
<input name="right" id="0" code="16" type="hat" value="2"/>
<input name="up" id="0" code="16" type="hat" value="1"/>
<input name="hotkey" id="10" code="316" type="button" value="1"/>
<input name="l1" id="4" code="310" type="button" value="1"/>
<input name="l3" id="11" code="317" type="button" value="1"/>
<input name="l2" id="6" code="312" type="button" value="1"/>
<input name="joystick1left" id="0" code="0" type="axis" value="-1"/>
<input name="joystick1up" id="1" code="1" type="axis" value="-1"/>
<input name="r1" id="5" code="311" type="button" value="1"/>
<input name="r3" id="12" code="318" type="button" value="1"/>
<input name="r2" id="7" code="313" type="button" value="1"/>
<input name="joystick2left" id="3" code="3" type="axis" value="-1"/>
<input name="joystick2up" id="4" code="4" type="axis" value="-1"/>
<input name="start" id="9" code="315" type="button" value="1"/>
<input name="y" id="3" code="308" type="button" value="1"/>
<input name="x" id="2" code="307" type="button" value="1"/>
</inputConfig>
<!-- PS4 BT -->
<inputConfig deviceLayout="ps4" deviceName="Wireless Controller" deviceGUID="050000004c050000c405000000810000" deviceNbButtons="13" type="joystick" deviceNbAxes="6" deviceNbHats="1">
<input name="b" id="0" code="304" type="button" value="1"/>
<input name="a" id="1" code="305" type="button" value="1"/>
<input name="select" id="8" code="314" type="button" value="1"/>
<input name="down" id="0" code="16" type="hat" value="4"/>
<input name="left" id="0" code="16" type="hat" value="8"/>
<input name="right" id="0" code="16" type="hat" value="2"/>
<input name="up" id="0" code="16" type="hat" value="1"/>
<input name="hotkey" id="10" code="316" type="button" value="1"/>
<input name="l1" id="4" code="310" type="button" value="1"/>
<input name="l3" id="11" code="317" type="button" value="1"/>
<input name="l2" id="6" code="312" type="button" value="1"/>
<input name="joystick1left" id="0" code="0" type="axis" value="-1"/>
<input name="joystick1up" id="1" code="1" type="axis" value="-1"/>
<input name="r1" id="5" code="311" type="button" value="1"/>
<input name="r3" id="12" code="318" type="button" value="1"/>
<input name="r2" id="7" code="313" type="button" value="1"/>
<input name="joystick2left" id="3" code="3" type="axis" value="-1"/>
<input name="joystick2up" id="4" code="4" type="axis" value="-1"/>
<input name="start" id="9" code="315" type="button" value="1"/>
<input name="y" id="3" code="308" type="button" value="1"/>
<input name="x" id="2" code="307" type="button" value="1"/>
</inputConfig>
Exemple pour une manette de ps5 :
<!-- PS5 Official USB -->
<inputConfig deviceLayout="ps5" deviceName="Sony Interactive Entertainment Wireless Controller" deviceGUID="030000004c050000e60c000011810000" deviceNbButtons="13" type="joystick" deviceNbAxes="6" deviceNbHats="1">
<input name="b" id="0" code="304" type="button" value="1"/>
<input name="a" id="1" code="305" type="button" value="1"/>
<input name="select" id="8" code="314" type="button" value="1"/>
<input name="down" id="0" code="16" type="hat" value="4"/>
<input name="left" id="0" code="16" type="hat" value="8"/>
<input name="right" id="0" code="16" type="hat" value="2"/>
<input name="up" id="0" code="16" type="hat" value="1"/>
<input name="hotkey" id="10" code="316" type="button" value="1"/>
<input name="l1" id="4" code="310" type="button" value="1"/>
<input name="l3" id="11" code="317" type="button" value="1"/>
<input name="l2" id="2" code="2" type="axis" value="-1"/>
<input name="joystick1left" id="0" code="0" type="axis" value="-1"/>
<input name="joystick1up" id="1" code="1" type="axis" value="-1"/>
<input name="r1" id="5" code="311" type="button" value="1"/>
<input name="r3" id="12" code="318" type="button" value="1"/>
<input name="r2" id="5" code="5" type="axis" value="-1"/>
<input name="joystick2left" id="3" code="3" type="axis" value="-1"/>
<input name="joystick2up" id="4" code="4" type="axis" value="-1"/>
<input name="start" id="9" code="315" type="button" value="1"/>
<input name="y" id="3" code="308" type="button" value="1"/>
<input name="x" id="2" code="307" type="button" value="1"/>
</inputConfig>
<!-- PS5 Official Weifang Goertek Electronics Co.Ltd wireless -->
<inputConfig deviceLayout="ps5" deviceName="Wireless Controller" deviceGUID="050000004c050000e60c000000810000" deviceNbButtons="13" type="joystick" deviceNbAxes="6" deviceNbHats="1">
<input name="b" id="0" code="304" type="button" value="1"/>
<input name="a" id="1" code="305" type="button" value="1"/>
<input name="select" id="8" code="314" type="button" value="1"/>
<input name="down" id="0" code="16" type="hat" value="4"/>
<input name="left" id="0" code="16" type="hat" value="8"/>
<input name="right" id="0" code="16" type="hat" value="2"/>
<input name="up" id="0" code="16" type="hat" value="1"/>
<input name="hotkey" id="10" code="316" type="button" value="1"/>
<input name="l1" id="4" code="310" type="button" value="1"/>
<input name="l3" id="11" code="317" type="button" value="1"/>
<input name="l2" id="2" code="2" type="axis" value="-1"/>
<input name="joystick1left" id="0" code="0" type="axis" value="-1"/>
<input name="joystick1up" id="1" code="1" type="axis" value="-1"/>
<input name="r1" id="5" code="311" type="button" value="1"/>
<input name="r3" id="12" code="318" type="button" value="1"/>
<input name="r2" id="5" code="5" type="axis" value="-1"/>
<input name="joystick2left" id="3" code="3" type="axis" value="-1"/>
<input name="joystick2up" id="4" code="4" type="axis" value="-1"/>
<input name="start" id="9" code="315" type="button" value="1"/>
<input name="y" id="3" code="308" type="button" value="1"/>
<input name="x" id="2" code="307" type="button" value="1"/>
</inputConfig>
Pour simuler un visuel d’une manette donnée
Pendant la mise au point d’un nouveau visuel, si vous voulez intégrer sans avoir le contrôleur en question, vous pouvez donc « bricoler » le deviceLayout d’un de vos contrôleurs.
Il faudra aller modifier sur votre version de pixL, le fichier « input.cfg » qui est ici dans votre share:
Attention: Sur un PC de dev où on va vouloir tester à partir de QT Creator, vu que l’on va chercher dans le « user » de pixL habituellement pour cette partie de code, il faudra se mettre aussi un répertoire « .pegasus-frontend » dans votre « /home/{user} » avec une copie de l’input.cfg et c’est celui ci qu’il faudra modifier.
Et modifier le deviceLayout d’une de vos manettes (il faudra le faire avant de la connecter bien sur ;-), comme ici, où on utilise le layout « ps4 » sur une manette de xbox series :
Et voilà ce que l’on arrive à simuler :
Alternative à font forge (depuis le 7/10/2024)
Vu que FontForge est vraiment un outil vieillissant j’ai finalement trouvé une alternative opensource pour windows, linux et macos pour au moins consulter (j’ai pas encore essayé d’éditer) : https://birdfont.org/purchase.php
C’est gratuit
Après installation il faudra sélectionner la licence « non commercial » et ouvrir le fichier « font » en question puis si on veut voir les icones actuelles il faudra sélectionner « All Glyphs » :
On pourra double cliquer sur une icone pour voir plus précisément: