Différences clés
Les différences clés entre XInput et GameInput sont abordées dans les sections suivantes.C ou C++
L’API XInput est une collection de fonctions C plates. GameInput, en revanche, est en C++ et utilise des interfaces (tout comme les API graphiques et audio). En pratique, cela ne complique pas le code qui utilise l’API GameInput, n’a aucune incidence sur les performances et présente certains avantages qui deviennent évidents une fois que vous connaissez mieux le fonctionnement de GameInput. Il est important de comprendre que, même si ces interfaces peuvent ressembler à COM, elles n’en sont pas. Seule une compréhension de base du décompte de références est nécessaire pour utiliser ces interfaces. Pour plus d’informations, consultez la section Interfaces de la rubrique Notions fondamentales de GameInput.Obtention des entrées
Dans XInput, la plupart des jeux parcourent les index d’utilisateur jusqu’à en trouver un auquel un périphérique est connecté, puis l’état est lu à partir de ce périphérique. Les jeux mémorisent souvent l’index d’utilisateur pour ne pas avoir à refaire la boucle la fois suivante. Par exemple, le code suivant est typique d’un jeu qui invite l’utilisateur à « appuyer sur A » sur sa manette :Rétroaction par vibration
Dans XInput, les jeux appellent simplementXInputSetState pour envoyer des commandes de vibration à un périphérique. Dans GameInput, les jeux doivent obtenir l’instance IGameInputDevice du périphérique, puis appeler sa méthode SetRumbleState. L’utilisation est semblable entre ces deux méthodes. Il s’agit d’un exemple de cas où vous appellerez des fonctions sur l’interface du périphérique, plutôt que de l’utiliser uniquement comme identificateur de périphérique.
Focus de l’application
Sur console, GameInput fournit des entrées à une application uniquement lorsqu’elle a le focus. Sinon, l’état retourné contient des valeurs neutres ou « au repos », comme si l’utilisateur ne touchait pas du tout le périphérique. Cela élimine le besoin de code d’entrée supplémentaire pour gérer les changements de focus (par exemple, l’appel àXInputEnable).
Sur PC, les entrées sont envoyées à tous les processus par défaut. À l’avenir, ce comportement pourra être modifié à l’aide de la méthode SetFocusPolicy.
Le wrapper XInputOnGameInput
Le Microsoft Game Development Kit (GDK) est fourni avec un fichier d’en-tête appeléXInputOnGameInput.h qui contient une implémentation de l’API XInput par-dessus GameInput. Nous recommandons de porter directement vers GameInput, surtout si vous voulez prendre en charge le clavier et la souris ou d’autres périphériques d’entrée. Cependant, le wrapper XInputOnGameInput peut servir à amorcer un premier effort de portage sans nécessiter de modifications du code XInput existant.
Pour utiliser le wrapper XInputOnGameInput, remplacez simplement ce code :
Différences entre XInput et XInputOnGameInput
En général, le wrapper XInputOnGameInput remplace directement l’ancienne API XInput. Cependant, il existe quelques différences mineures :- Par souci de simplicité, seule la prise en charge des manettes a été codée dans le wrapper. Si vous devez prendre en charge d’autres périphériques, comme les volants de course ou les sticks d’arcade, utilisez GameInput directement ou ajoutez la prise en charge de ces périphériques dans le code de XInputOnGameInput.
-
Le wrapper ne retourne les entrées de manette que lorsque le jeu a le focus. Lorsque le jeu n’a pas le focus, tout état de manette retourné est défini sur des valeurs neutres ou « au repos », comme si l’utilisateur ne touchait pas la manette. C’est le cas indépendamment de tout appel à
XInputEnable(ou de son absence). -
La valeur de
XUSER_MAX_COUNTest passée de 4 à 8. Cela devrait généralement être transparent pour la plupart du code XInput existant. Cependant, assurez-vous d’examiner attentivement toute utilisation de la fonctionXInputGetKeystrokedans votre code pour vous assurer que rien n’est codé en dur en supposant une valeur maximale de 4 retournée dans le membreUserIndexde la structureXINPUT_KEYSTROKE. Sinon, un dépassement de mémoire tampon pourrait se produire. - Quelques nouvelles fonctions ont été ajoutées (voir ci-après); elles ne devraient vous intéresser que si vous avez l’intention de continuer à utiliser le wrapper XInput dans du code de production.
Utilisation de XInputOnGameInput dans du code de production
Le wrapper XInputOnGameInput est conçu pour être performant et sans verrou, héritant de toutes les optimisations de performances de l’API GameInput; il convient donc à une utilisation dans du code de production. Il hérite aussi de la prise en charge plus vaste des périphériques de GameInput (comme les manettes HID populaires) et ajoute les nouvelles fonctions suivantes à l’API :-
XInputSetStateExest semblable àXInputSetState, mais ajoute la prise en charge des moteurs des gâchettes. -
XInputGetStateWithTokenest semblable àXInputGetState, mais permet à l’appelant de fournir un jeton de pipeline d’images D3DX pour associer une lecture d’entrée précise à une image graphique en vue d’une analyse ultérieure dans PIX.[!NOTE] Dans la version préliminaire de mai,
XInputGetStateWithTokense comporte actuellement de façon identique àXInputGetState, car le code GameInput sous-jacent n’est pas entièrement implémenté. -
XInputGetDeviceIdretourne leAPP_LOCAL_DEVICE_IDdu périphérique associé à un index d’utilisateur donné. Le passage de cet ID à la méthode FindDeviceFromId de IGameInput retourne l’interface IGameInputDevice correspondant à cet index d’utilisateur. Celle-ci peut ensuite être utilisée pour accéder à des fonctionnalités supplémentaires de l’API GameInput qui ne sont pas exposées par le wrapper XInput.
Optimisation du code du wrapper
Par défaut, le wrapper XInputOnGameInput est configuré pour être directement compatible avec l’ancienne API XInput. Les jeux qui n’ont pas besoin d’un comportement entièrement compatible peuvent ajuster le comportement et les performances du wrapper en définissant l’une ou l’autre des macros de préprocesseur suivantes :XINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION
Par défaut, le wrapper XInput initialise automatiquement et de façon différée l’API GameInput sous-jacente la première fois que l’une des fonctions du wrapper est appelée. Cela garantit une compatibilité directe avec le code XInput existant, mais présente plusieurs inconvénients mineurs :- Le temps d’exécution du premier appel de fonction du wrapper XInput sera plus long que d’habitude.
- Chaque fonction du wrapper XInput doit vérifier, à chaque appel, si l’initialisation différée a été effectuée. Il s’agit d’un simple test d’une variable globale; le prédicteur de branchement devrait donc atténuer le coût, mais il s’agit tout de même d’une surcharge supplémentaire.
- Bien que cela ne devrait jamais échouer, il n’y a aucun moyen de savoir si l’initialisation différée de l’API GameInput sous-jacente a réussi.
- L’instance IGameInput sous-jacente n’est pas libérée avant le nettoyage des variables globales du wrapper XInput (soit en raison du déchargement du module, soit en raison de l’arrêt du processus).
XINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION. Cela ajoute deux nouvelles fonctions,XInputOnGameInputInitialize etXInputOnGameInputUninitialize, qui peuvent être appelées pour contrôler précisément le moment de l’initialisation et de l’arrêt.
XINPUT_ON_GAMEINPUT_NO_XINPUTENABLE
Le code requis pour implémenter la fonctionXInputEnable ajoute une surcharge à chaque appel des fonctionsXInputGetState,XInputGetStateWithToken,XInputSetState,XInputSetStateEx etXInputGetKeystroke. Si votre code n’appelle pasXInputEnable, ou si cet appel peut facilement être éliminé de votre code, la définition de la macroXINPUT_ON_GAMEINPUT_NO_XINPUTENABLE supprimera la prise en charge deXInputEnable et la surcharge associée. Le code GameInput sous-jacent exécute de toute façon automatiquement la fonctionnalité deXInputEnable lors des changements de focus; la plupart des jeux voudront donc définir cette macro s’ils le peuvent.
XINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE
Le code requis pour implémenter la fonctionXInputGetKeystroke ajoute quelques fonctions et variables supplémentaires à l’implémentation du wrapper. Il n’ajoute aucune surcharge aux autres fonctions de l’API XInput, mais si votre code n’appelle pasXInputGetKeystroke, vous pouvez définir la macroXINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE pour réduire légèrement la taille du code et des données du wrapper XInput.
