Article     Discussion     Modifier     Historique     Forums     Salon IRC

Gérer le clavier et la souris avec DirectInput

Un article de Games Creators Network.



Attention


Cet article est en attente du choix d'une licence par son auteur. Elle n'est pas soumise à la licence par défaut du GCN.

Cela signifie entre autre chose que si vous n'êtes pas l'auteur de cet article, vous n'avez probablement pas le droit de le modifier.


Maintenant que vous maîtrisez l'affichage des graphismes de votre jeu, il est temps de pouvoir interagir avec. Dans ce tutoriel nous allons donc apprendre à utiliser le clavier et la souris, qui sont vraiment des choses aisées. Comme l'utilisation des deux périphériques est très proche au niveau de DirectX, la plupart du temps il n'y aura qu'une seule explication du fonctionnement des fonctions propres aux interfaces de DirectInput.

Sommaire

[modifier] Initialisation de DirectInput

L'initialisation de l'objet DirectInput ne nécessite qu'une ligne de commande:

 LPDIRECTINPUT lpdi;
 DirectInputCreate(hInstance,DIRECTINPUT_VERSION,& lpdi,NULL);


LPDIRECTINPUT : C'est l'objet qui contrôle DirectInput. Il sert à créer les différents périphériques.

DirectInputCreate : C'est la fonction d'initialisation de DirectInput. Le premier paramètre est l'instance de l'application. le deuxième est le version de DirectInput à utiliser (ici la version courante). Le troisième est l'adresse de l'objet DirectInput à initialiser. Le quatrième vaut toujours NULL.

[modifier] Création des périphériques

La création d'un périphérique est un peu plus longue. Il y a très peu de différences entre la souris et le clavier donc chaque fonction ne sera détaillée qu'une fois, et les différences entre le clavier et la souris seront immédiatement énumérées. Voyons les étapes à suivre :

[modifier] Création du périphérique

 LPDIRECTINPUTDEVICE lpdiPeriph;
 lpdi-> CreateDevice(GUID_SysPeriph,& lpdiPeriph,NULL);


LPDIRECTINPUTDEVICE : C'est l'interface de DirectInput pour les périphériques.

CreateDevice : Fonction membre de l'interface IDirectInput. Elle sert à créer un périphérique. Le premier paramètre est le GUID du périphérique. Pour le clavier il faut mettre GUID_SysKeyboardet pour le souris GUID_SysMouse. Le second paramètre est l'adresse du périphérique à créer. Et le troisième paramètre est toujours NULL.

[modifier] Sélection du format de stockage des données

 lpdiPeriph-> SetDataFormat(& Format);

SetDataFormat : Fonction membre de l'objet LPDIRECTINPUTDEVICE. Son unique paramètre est le format de données. Il faut remplacer 'Format' par c_dfDIKeyboard pour le clavier et parc_dfDIMouse pour la souris.

[modifier] Initialisation du tampon de données

 DIPROPDWORD dipw=
 {
 // En-tête
 {
  sizeof(DIPROPDWORD),
  sizeof(DIPROPHEADER),
  0,
  DIPH_DEVICE,
 },
 // Données
 BUFFERSIZE
 };
 lpdiPeriph-> SetProperty(DIPROP_BUFFERSIZE,& dipw.diph);


DIPROPDWORD : Structure utilisée par DirectInput pour initialiser les propriétés du tampon de données. La seule chose qui est à modifier pour passer de la souris au clavier est la valeur de 'BUFFERSIZE'. Pour le clavier il vaut mieux mettre 32et pour la souris 16. Mais cela est une affaire de préférence. BUFFERSIZE est le nombre d'entrées maximales dans le tampon. Donc plus il est élevé et plus vous pouvez stocker de données avant de les lire.

SetProperty : Fonction membre de l'objet LPDIRECTINPUTDEVICE. Son premier paramètres est à mettre à DIPROP_BUFFERSIZE pour une entrée avec tampon (celle expliquée dans cet article car c'est le seule d'utile). Le second paramètre est l'adresse du membre diph de la structure DIPROPDWORD. Ne me demandez pas pourquoi. C'est comme cela et ça marche parfaitement.

[modifier] Définition du niveau coopératif

 lpdiPeriph-> SetCooperativeLevel(MainWindowHandle,COOP_LEVEL);


SetCooperativeLevel : Fonction membre de l'objet LPDIRECTINPUTDEVICE. Elle sert à définir la manière dont le périphérique agit par rapport aux autres applications. Le premier paramètre est le handle de l'application. Le second est une liste d'indicateur. Il faut remplacer 'COOP_LEVEL' par DISCL_NONEXCLUSIVE | DISCL_BACKGROUND pour le clavier (le clavier peut servir dans d'autres programmes) ou par DISCL_EXCLUSIVE | DISCL_FOREGROUNDpour la souris (la souris appartient au programme, elle est 'volée' à Windows).

[modifier] Acquisition du périphérique (la touche finale)

 lpdiPeriph-> Acquire();

Acquire : Fonction membre de l'objet LPDIRECTINPUTDEVICE. On ne peut utiliser le périphérique que ci cette commande à réussi.

[modifier] Lecture des périphériques

Maintenant que nous avons crée nos périphériques, il faut être capable de les lires. La chose est très aisée et la différence entre le clavier et la souris est minime ici aussi. Voici comment il faut procéder :

 DIDEVICEOBJECTDATA buffer[BUFFERSIZE];
 DWORD dwItems=BUFFERSIZE;
 // On lit
 lpdiPeriph-> GetDeviceData(sizeof(DIDEVICEOBJECTDATA),buffer,& dwItems,0);
 // Et on traite
 for(DWORD d=0;d< dwItems;d++)
 {
  switch(buffer[d].dwOfs)
  {
   // Traitement différent selon que l'on utilise le clavier ou la souris
  }
 }

DIDEVICEOBJECTDATA : Structure pour le tampon de données. C'est dans un tableau de ce type que l'on récupère les informations sur le périphérique.

GetDeviceData : Fonction membre de l'objet périphérique. Elle sert à lire les données et à les stocker dans le buffer. Le premier paramètre est la taille d'une donnée (un sizeof du type de donnée suffit). Le deuxième paramètre est buffer recevant les données. Le troisième paramètre est l'adresse d'un DWORD contenant le nombre d'éléments à lire et dans lequel sera stocké le nombre d'éléments lus. Enfin, on fixe généralement le dernier paramètre à 0 pour que les données soient effectivement vidées du périphérique.

Pour savoir quelles données ont été lues, il suffit de consulter 2 membres de DIDEVICEOBJECTDATA : dwOfspour savoir quelle touche ou bouton a changé d'état et dwDatapour savoir si on vient de relâcher ou d'enfoncer l'élément.

dwData vaut 0x80 si on vient d'enfoncer l'élément lu et autre chose sinon.

dwOfs vaut l'une des constantes DIK_* pour le clavier et DIMOFS_* pour la souris. La liste complète de ces constantes se trouve dans l'aide de DirectX. A vous d'agir en conséquence pour chaque événement.

Petite précision pour la souris. DIMOFS_X contient la valeur du déplacement horizontal en pixels de la souris et non ses cordonnées. Il est positif si la souris vas vers la droite et négatif vers la gauche. Il en vas de même pour DIMOFS_Y pour le déplacement vertical (Haut=négatif et Bas=Positif).

Pour ce qui est de la gestion, mon approche personnelle est de créer une classe pour le périphérique et de stocker les données qui m'intéressent. de cette façon je peux savoir à tout moment quel est l'état actuel de mon clavier ou de ma souris et je peux interagir dessus directement dans le code.

[modifier] Conclusion

Je pense qu'avec ceci la gestion de la souris et du clavier ne devrait plus vous poser de problèmes. Je joint à ce tutoriel non pas un programme exemple, mais plutôt deux exemple de classe pour le clavier et la souris, ainsi qu'un exemple de fonction d'initialisation de DirectInput. J'espère avoir été assez clair et je me tient à votre disposition pour tout renseignement complémentaire.


Ce document a été publié sur la version 3 du G.C.N. par Kain.

  • Auteur Original : Kain
  • Date de publication : 9 janvier 2002

 

Rechercher
Installer l'extension de recherche Plus d'informations

 

Comprendre
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. - Benjamin Franklin

 

Partager
La connaissance est la seule chose qui s'accroit lorsqu'on la partage. - Sacha Boudjema

 

Créer
L'imagination est plus importante que la connaissance. - Albert Einstein

 

 

Le wiki en images Le wiki en images Image du mois: «Snowball: un prototype de jeu développé avec NeL.