Étape 3: Obtenir l’entrée de manette de jeu
Maintenant, que nous savons comment envoyer les informations à l’Arduino, nous avons seulement besoin d’apprendre à acquérir l’entrée de la manette de jeu XBOX.
Dans cette section nous apprendrons les rudiments du XInput et écrire un programme très simple qui affiche l’état actuel de manette de jeu à la sortie de la console. Nous apprendrons également certains aspects importants de prétraitement sur les valeurs d’entrée pour éviter les gammes d’entrée joystick problématique (« zones mortes »).
LES PRINCIPES DE BASE
XInput API fournit les moyens de se saisir de XBOX 360 contrôleurs et comprend une variété d’outils pour définir les effets de contrôleur (farce feedback), traiter les entrées/sorties audio pour casques gaming et faire d’autres choses cool.
XInput prend en charge jusqu'à 4 contrôleurs, mais dans notre situation seulement contrôleur #0 sera utilisé comme valeur par défaut.
Pour mettre à jour l’état actuel de la manette de jeu, nous allons utiliser XInputGetState() fonction. Elle prend 2 paramètres : l’ID de la manette de jeu (ce qui est de 0 dans la plupart des cas) et le pointeur vers la variable d’État XInput. La valeur de retour de XInputGetState peut être utilisée pour vérifier la disponibilité de la manette. La valeur de ERR_SUCCESS signifie que la manette est sur, et XInput État a maintenant son état actuel.
XINPUT_STATE se compose des éléments suivants :
typedef struct _XINPUT_STATE { DWORD dwPacketNumber; XINPUT_GAMEPAD Gamepad; } XINPUT_STATE;
dwPacketNumber indique si l’état de la manette de jeu a changé.
Manette de jeu est un type de données qui représente l’état actuel de manette de jeu, y compris le stick analogique des positions, valeurs de déclenchement, drapeaux D-pad et le bouton.
typedef struct _XINPUT_GAMEPAD { WORD wButtons; BYTE bLeftTrigger; BYTE bRightTrigger; SHORT sThumbLX; SHORT sThumbLY; SHORT sThumbRX; SHORT sThumbRY; } XINPUT_GAMEPAD;
sThumbLX, sThumbLY, sThumbRX et sThumbRY sont des entiers signés 16 bits, qui prennent des valeurs de −32, 768 à 32 767. Ils correspondent à des positions actuelles de joystick.
bLeftTrigger et bRightTrigger prennent des valeurs dans la plage 0.. 255.
wButtons représente l’état de tous les boutons d’une manette XBox, où chaque bit correspond à l’état actuel de chaque bouton individuel. Si nous voulons vérifier si le bouton de X a été enfoncé, il faut effectuer les opérations suivantes :
XINPUT_STATE gpState; // Create state variable memset(&gpState,0,sizeof(XINPUT_STATE)); // Reset state DWORD res = XInputGetState(0,&gpState); // Get new state if(gpState.wButtons & 0x4000 ) { printf("Xplosive kick!\n"); }
La liste suivante répertorie tous les boutons et leurs masques de bits correspondants :
XINPUT_GAMEPAD_DPAD_UP 0x0001 XINPUT_GAMEPAD_DPAD_DOWN 0x0002 XINPUT_GAMEPAD_DPAD_LEFT 0x0004 XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 XINPUT_GAMEPAD_START 0x0010 XINPUT_GAMEPAD_BACK 0x0020 XINPUT_GAMEPAD_LEFT_THUMB 0x0040 // These are thumbstick buttons XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 // Left bumper XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 // Right bumper XINPUT_GAMEPAD_A 0x1000 XINPUT_GAMEPAD_B 0x2000 XINPUT_GAMEPAD_X 0x4000 XINPUT_GAMEPAD_Y 0x8000
PRATIQUONS LE
À ce stade, nous avons tous les outils que nécessaires pour écrire notre premier programme avec XInput. Il sera ridiculement simple, mais il vous aidera à comprendre comment ce processus fonctionne et quels éléments de XInput, nous avons besoin.
#include "stdafx.h" #include <Windows.h> #include <XInput.h> #pragma comment(lib, "XInput.lib") // required for linker int _tmain(int argc, _TCHAR* argv[]) { XINPUT_STATE gpState; // Gamepad state int player = -1; // Gamepad ID // Polling all 4 gamepads to see who's alive for(int i=0;i<4;i++) { DWORD res = XInputGetState(i,&gpState); // Getting state if(res==ERROR_SUCCESS) // If alive - print message { printf("Controller #%d is ON!\n",i+1); player = i; // Assign last alive gamepad as active } } if(player<0) // If player==-1 in other words... { printf("Haven't found any gamepads...\n"); } else { while(true) { system("CLS"); // Clear screen memset(&gpState,0,sizeof(XINPUT_STATE)); // Reset state DWORD res = XInputGetState(0,&gpState); // Get new state printf("LX\tLY\tRX\tRY\tLTrig\tRTrig\tButtons\n"); // Print header // Thumbstick values are divided by 256 for better consistency printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\n", gpState.Gamepad.sThumbLX/256, gpState.Gamepad.sThumbLY/256, gpState.Gamepad.sThumbRX/256, gpState.Gamepad.sThumbRY/256, gpState.Gamepad.bLeftTrigger, gpState.Gamepad.bRightTrigger, gpState.Gamepad.wButtons); } } system("PAUSE"); return 0; }
Une fois que vous générez la solution et exécutez votre programme, vous verrez la sortie changer lorsque vous déplacez des Sticks, ou boutons de commande de votre manette. Nous vous enverrons ces données à la carte Arduino dans la section suivante de ce didacticiel.
En ce moment, je veux que vous faites attention à la sortie, lorsque vous ne font rien. Valeurs de LX, LY et RX, RY ne sont pas égales à 0, que nous attendons qu’ils. Dans ce cas pour un certain nombre de raisons, mais ce qui importe le plus, c’est que nous sommes conscients de ce phénomène !
Ces fluctuations et incohérences dans les valeurs sont appelées « zones mortes ». Pour se débarrasser de cette anomalie méchante, nous avons besoin de trouver la plus petite valeur marginale au cours de laquelle on peut considérer que le Stick est en fait poussé dans une direction.
Pour ce faire, nous devons définir un seuil de deadzone et comparez-la aux valeurs actuelles. Découvrez la référence MSDN pour plus d’informations.
Pendant ce temps, utilisez cet exemple de code pour corriger ces valeurs :
float LX = gpState.Gamepad.sThumbLX; // Get LX float LY = gpState.Gamepad.sThumbLY; // Get LY magnitude = sqrt(LX*LX+LY*LY); // Calculate the radius of current position if(magnitude < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) // Inside dead zone? { // Set all to 0 LX=0.0; LY=0.0; } // Do the same for RX and RY
Il y a aussi des valeurs prédéfinies de zone morte pour les sticks gauche et droite et les déclencheurs. Vous pouvez utiliser ces, ou définir vos propres seuils (dans mon cas ~ 6500 a travaillé pour le stick gauche et droit), mais n’oubliez pas que ces valeurs dépendent en grande partie comment beat-up votre manette est !
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 #define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 #define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
LECTURES COMPLÉMENTAIRES
La ressource supplémentaire seulement je vais vous parler est celle-ci: API de contrôleur de jeu XInput
Il a tout ce que vous devez savoir sur XInput, y compris la référence complète et utile guide de programmation.
C’est tout pour cette partie. Maintenant, nous allons essayer de combiner nos compétences en programmation à distance des gamepads et connexions série à contrôle Arduino!!! ... dans le cas où vous avez oublié où nous avons commencé...