Simple Xbox 360 Controller : une classe permettant l’utilisation des manettes Xbox 360 sous Windows avec Qt

Pour utiliser les manettes de xbox 360 sous Windows, Microsoft a mis au point la librairie Xinput. Si plusieurs développeurs ont déjà mis a disposition des classes C++ pour faciliter l’accès à Xinput, aucune n’a été écrite pour tirer partie du mécanisme des slot / signal de Qt. La classe SimpleXbox360Controller a pour objectif de pallier ce manque.

Le logiciel de test Simple Xbox 360 Controller Tester

Le logiciel de démo :  Simple Xbox 360 Controller Tester

Le programme d’exemple Xbox 360 Controller Tester permet de tester rapidement le fonctionnement d’une manette. L’exécutable est disponible ici : SimpleXbox360ControllerTester

L’ensemble du code de la classe, celui du programme d’exemple, et la documentation en anglais du code est disponible sur GitLab.

Pour mes amis francophones, vous trouverez ci-dessous une version française de la doc :

Important

 

Il faut impérativement ajouter la ligne suivante dans votre fichier .pro, sans quoi le compilateur ne trouvera pas le fichier XInput.lib :

win32:LIBS += $${PRO_FILE_PWD}/SimpleXbox360Controller/XInput.lib

 

Principe

 

La classe SimpleXbox360Controller permet de récupérer l’état d’une manette de xbox 360 connectée à l’ordinateur. (pour gérer 4 manettes, utiliser 4 instances de la classe). Cette classe a été écrite pour offrir un maximum de flexibilité, il y a par conséquente plusieurs façon de l’utiliser. La récupération des infos de la manette peut se faire soit de façon automatique (la classe dispose de son propre QTimer) soit manuellement, à chaque appel de la fonction update(). De même, la classe émet des signaux à chaque changement d’état de la manette, mais il est également possible de Statlire manuellement le dernier état reçu.

Mais commençons par le début :

 

Le constructeur

 

Celui ci prend jusqu’à 5 paramètres :

  1. Le numéro de la manette associée (de 0 à 3, correspond au manettes des joueurs 1 à 4).
  2. Le rayon du point mort du stick analogique gauche (de 0 à 32767). Il est conseillé d’omettre ce paramètre, la valeur par défaut étant alors utilisée.
  3. Le rayon du point mort du stick analogique droit (de 0 à 32767). Il est conseillé d’omettre ce paramètre, la valeur par défaut étant alors utilisée.
  4. Le seuil de détection des gâchettes (de 0 à 255). Il est conseillé d’omettre ce paramètre, la valeur par défaut étant alors utilisée.
  5. Le QObject parent. Permet à Qt d’améliorer la gestion mémoire. Pas vraiment nécessaire si l’on pense à mettre les delete.

 

La classe Input

 

Cette classe représente l’état de la manette. Elle appartient à la classe SimpleXbox360Controller ( pour en déclarer une nouvelle instance, il faut donc écrire SimpleXbox360Controller::InputState monInputState) Chaque stick analogique est représenté par 2 variables de type float dont la valeur varie de -1 (haut/gauche) à 1 (bas/droite), 0 correspondant à la position au repos.

Chaque gâchette est représentée par une variable float de valeur comprise entre 0 (gâchette au repos) à 1 (appuyée au maximum)

Ces valeurs sont obtenues après calcul des seuils et des des points morts, donc vous n’avez pas d’effectuer ces calculs.

Le type et l’état de la batterie sont représentés par des variables de type quint8 (entiers non signés sur 8 bits). Ces variables doivent être interprétées par comparaison avec les définitions BATTERY_TYPE_ et BATTERY_LEVEL_ du fichier XInput.h

L’état des boutons est représenté par une variable de type quint16. L’état de chaque bouton peut être évalué par appel de la méthode InputState::isButtonPressed() . Par exemple, pour vérifier si le bouton A est appuyé : myInputState.isButtonPressed(XINPUT_GAMEPAD_A) retourne true si A est appuyé, et false sinon.

 

Signaux

 

  • controllerNewState(SimpleXbox360Controller::InputState) : est émis si l’état de la manette a changé depuis l’appel précédent de la méthode update()
  • controllerNewBatteryState(quint8 newBatteryType, quint8 newBatteryLevel) : est émis si l’état de la batterie de la manette a changé depuis l’appel précédent de la méthode update(). Comment précédemment, les paramètres doivent être interprétées par comparaison avec les définitions BATTERY_TYPE_ et BATTERY_LEVEL_ du fichier XInput.h
  • void controllerConnected(unsigned int controllerNum) : est émis si la manette a été connectée depuis l’appel précédent de la fonction update()
  • void controllerDisconnected(unsigned int controllerNum) : est émis si la manette a été déconnectée l’appel précédent de la fonction update()

 

Slots

 

  • update() : permet de rafraichir les infos de la manette, et provoque alors l’émission des signaux adéquats. Si l’on ne souhaite pas utiliser les signaux, il est possible de récupérer les dernières infos reçus avec la méthode getCurrentState()
  • startAutoPolling(unsigned int interval) : démarre un QTimer qui sera chargé d’appeler la fonction update() toute les interval milliseconds.
  • stopAutoPolling() : arrête le QTimer.
  • void setVibration(float leftVibration, float rightVibration) : règle la valeur des vibrations pour les moteurs gauche et droits. Les valeurs doivent être comprises entre 0 et 1. Les deux moteurs produisent des vibrations différentes, donc n’hésitez pas à essayer l’un ou l’autre, voire mixer les deux pour obtenir le ressenti recherché.

 

Réglage manuel des points morts

 

Ces fonctions sont là au cas où vous en auriez besoin dans un cas particulier. En temps normal elle ne sont pas nécessaires. Elles peuvent s’avérer utile, par exemple, pour celui qui souhaite joué avec une manette dont les ressorts des sticks analogiques sont particulièrement usés, et pour laquelle les valeurs par défaut des points morts ne conviennent pas. Pour les gâchettes, normalement le problème de vieillissement des ressorts ne se pose pas, donc il est possible de réduire la valeur (la valeur par défaut est de 30) pour profiter d’une plus grande course des gâchettes :

  • setLeftStickDeadZone(unsigned int newDeadZone) : règle le rayon du point mort du stick analogique gauche (de 0 à 32767). Il est conseillé d’omettre ce paramètre, la valeur par défaut étant alors utilisée.
  • setRightStickDeadZone(unsigned int newDeadZone) : règle le rayon du point mort du stick analogique droit (de 0 à 32767). Il est conseillé d’omettre ce paramètre, la valeur par défaut étant alors utilisée.
  • setTriggerThreshold(unsigned int newThreshold) : règle le seuil de déclenchement des gâchettes ( de 0 à 255).

 

Autre méthodes

 

  • bool isStateChanged(void) : retourne true si l’état de la manette a changé depuis l’appel précédent de la fonction update().
  • bool isConnected(void) : retourne true si la manette est connectée.

 

Conclusion

 

Ayant utilisé cette classe sur 2 projets depuis sont écriture, dont logiciel de démo Simple Xbox 360 Controller Tester, qui fonctionne parfaitement, elle me semble adaptée, et les quelques bugs résiduels ont été découverts et corrigés, donc vous devriez pouvoir l’utiliser sans problème !

N’hésitez pas à me faire par de vos commentaires, idées, améliorations, où même projets utilisant cette classe. Je précise que l’ensemble est sous license GPL.

Enjoy 🙂

5 Commentaires

Passer au formulaire de commentaire

  1. jai pas reussi mon capteur rf xbox 360 pour window pout tu m envoyer tes plant la limiere allume pas svp meerci

  2. chu bon EN ELECTRONIC MAIS LA BESOIN AIDE

    1. Bonjour Dave,
      ceci n’est pas un Skyblog, tu es prié de porter un minimum d’attention à ton orthographe, de poster dans les commentaires de l’article approprié, et de décrire ton problème avec plus de précision. Sans ses efforts de ta part, je n’en ferai pas non plus pour t’aider.

  3. Salut !

    Je sais que ça remonte à loin mais je cherche à programmer un soft en utilisant un receveur sans fil xbox et apparemment ton code source n’est plus disponible.
    Est-ce que c’est possible de le récupérer ? Est-il toujours maintenu ?

    Merci d’avance !

  4. Salut Thomas,

    Désolé, j’ai récemment migré tous mes projets de Gitorious vers GitLab, et visiblement je me suis trompé en mettant à jour l’URL. C’est corrigé.

    Le projet n’a pas été modifié depuis longtemps, mais est toujours pleinement fonctionnel, et si besoin je peux y apporter des corrections.

    Tiens moi au courant 😉

Répondre à Pila Annuler la réponse

Votre adresse de messagerie ne sera pas publiée.