Texel |
|
La souris
Téléchargez un code source pour ce tutorial ICI.
Pour utiliser la souris avec Direct Input, il faut passé par ces étapes: 1.Créer un objet DirectInput :Cet objet est l'interface principale qui permet d'utiliser une ou plusieurs unités d'entrées. 2.Créer un objet DirectInputDevice : Cet objet représente une unité d'entrée. Si votre programme utilise le clavier et la souris, vous devez créer deux de ces objets (un pour le clavier et un pour la souris). 3.Définir un format de donné pour l'objet DirectInputDevice : Cette opération vous permet de définir le nom des constantes qui représenteront les infos de la souris (exemple: DIMOFS_BUTTON0 représente le bouton gauche). Nous n'expliquerons que le format de donné standard, mais il est possible de s'en créer un personnalisé. 4.Définir le comportement de l'unité d'entée : C'est à dire définir son niveau de coopération (pour donnée l'accès exclusif de l'unité à notre application ou bien pour permettre à d'autres applications de l'utiliser) . 5.Préparation d’un tampon. 6.Obtenir un accès à la souris. 7.Récupérer les informations de la souris (position…). 8.Libérer toutes les interfaces DirectInput Important: N'oublier pas dans vos programmes d'inclure "dinput.h", de rajouter la ligne #define INITGUID devant l'inclusion des fichiers ( pour les identificateurs GUID), et de linker la librairie dinput8.lib. Etape 1: Création d'un objet DirectInput Après avoir déclarer un objet DirectInput de type LPDIRECTINPUT8 en variable globale, on appel la fonction suivante:
Le deuxième paramètre est une constante pour le numéro de la version de DirectInput que l'on désire utiliser. On lui passe simplement la constante DIRECTINPUT_VERSION pour utiliser la dernière version.
Le troisième paramètre est nouveau dans DirectX 8. C'est l'identifiant du numéro de version de l'interface DirectInput désiré. Son utilité par rapport au paramètre précédant n'est pas très claire. Le quatrième argument est l'objet DirectInput que nous avons déclarer en variable globale. Le dernier paramètre prend la valeur NULL dans la très grande majorité des cas. L'interface que nous venons de créer possède plusieurs méthodes dont: CreateDevice(): Pour Créer une unité d'entrée EnumDevices(): Pour détecter les périphériques installés GetDeviceStatus(): Pour détecter si le périphérique est connecter au PC RunControlPanel(); Lance le panneau de configuration standard Release(); Libère l'interface Attention: Si vous utilisez plusieurs unités d'entrer gérer par DirectInput dans votre programme, vous n'avez besoin de créer qu'un seul objet DirectInput (contrairement aux objets DirectInputDevice). Si vous devez utiliser DirectX 7, remplacez les interfaces par LPDIRECTINPUT et LPDIRECTINPUTDEVICE et utilisez la fonction suivante:
Etape 2: Créer un objet DirectInputDevice Partant du principe que l'utilisateur à une souris (pour savoir comment détecter la présence d'une unité d'entrée allez lire le tutorial sur le joystick), on appel la méthode IDirectInput8::CreateDevice de l'interface DirectInput que l'on vient de créer.
Pour le clavier le premier argument est GUID_SysMouse. Le deuxième argument est l'objet DirectInputDevice déclarer une variable globale et de type LPDIRECTINPUTDEVICE Etape 3: Définir un format de donné pour l'objet DirectInputDevice Pour définir le format de donné, on utilise cette méthode :
L’argument est soit une structure de type DIDATAFORMAT (pour un format de donné personnalisé) soit la variable prédéfini : c_dfDIMouse (pour utiliser le format de donné standard). Si vous choisissez d’utiliser un format de donné personnalisé, vous devez remplir la structure (lisez pour ça la doc du SDK). Si vous utilisez le format de donné standard, les boutons des coordonnées de la souris auront des constantes standards pour les identifier (disponible dans la doc du SDK). Exemple : DIMOFS_BUTTON0 pour le bouton gauche. Etape 4 : Définir le comportement de l'unité d'entée Cette étape s'effectue grâce à la méthode IDirectInputDevice8::SetCooperativeLevel:
Contrairement au clavier on peut donner un accès exclusif à la souris pour nos applications. C’est pourquoi les drapeaux les plus souvent utilisés et combinés sont DISCL_FOREGROUND|DISCL_EXCLUSIVE. Etape 5 : Préparation d'un tampon. La souris fonctionne différemment du clavier. En effet, on ne détecte pas l'état de la souris à un instant t, mais les derniers mouvements qu'elle à effectuée.Il faut donc utiliser un tampon qui gérer toutes ces informations relatives. Mais d'abord, il faut connaître tous les mouvements de la souris à chaque instant. C'est pourquoi il faut créer ce que l'on appel un événement qui envoi des signaux à l'interface DirectInputDevice. Pour cela, on écrit ces deux lignes de code:
Note: pMouse est notre interface DirectInputDevice. Maintenant vous n'avez pas à créer le tampon mais à définir sa taille. Il faut pour cela remplir une structure de type DIPROPWORD de la façon suivante:
On passe ensuite la taille du tampon à l'interface par la méthode IDirectInputDevice8::SetProperty de la façon suivante:
Le premier argument est la propriété que l'on veut établir. Nous, on s'intéresse à la taille du tampon d'où la constante DIPROP_BUFFERSIZE. Le deuxième argument est l'adresse de la structure qui contient l'info. Etape 6 : Obtenir un accès à l'unité d'entrées. La méthode IDirectInputDevice8::Acquire suffit. Elle n’a pas d’arguments. Cette acquisition sera perdu si votre fenêtre n'est plus active. Il vous faut donc gérer ce problème avec le message WM_ACTIVATE de votre procédure de fenêtre (cf. code source). Etape 7 : Récupérer les informations de la souris Les six étapes précédentes se faisaient à l’initialisation. La suite se fait dans la boucle de jeu. Pour avoir les infos de la souris à un moment précis (coordonnées et boutons pressés) , il faut les récupérer du tampon et les stocker dans une structure de type DIDEVICEDATA (donc à déclarer). Apparemment, il faut la mette à zéro avec memset avant chaque mise à jours pour éviter les bugs. Pour cela on utilise la méthode IDirectInputDevice8::GetDeviceState. Pour la souris, cette méthode a quatre paramètres alors quelle en avait seulement deux pour le clavier.
La structure est bien sûr la structure de type DIDEVICEDATA. Le troisième argument est l'adresse d'une variable de type DWORD que vous devez déclarer et initialiser à 1 pour ne récupérer qu'un seul élément des données de la souris. C'est à dire qu'on ne lit qu'une information sur l'état de la souris lors de l'appel de la méthode. Le dernier argument est à mettre à 0. Sinon, DIGDD_PEEK permet de garder l'élément lu, dans le buffer. Le troisième paramètre de la méthode si dessus a permis de stocker une seule information relative à la souris dans le champ dwData de la structure. On ne sait pas quelle est cette information (variation de sa coordonnée en x ? en y ? état d'un bouton ? ). Pour savoir quelle est cette information, on regarde le contenu du champ dwOfs de la structure de type DIDEVICEDATA envoyé à la méthode. Si ce champ est égal à la constante DIMOFS_X, l'info stockée dans la structure est la variation de la distance parcourue par la souris en x (idem en y avec DIMOFS_Y). Pour les boutons les constantes sont DIMOFS_BUTTON0 et DIMOFS_BUTTON1. Pour mettre à jours la position d'un objet dirigé par la souris, il suffit d'ajouté à ses coordonnées x (ou y), la valeur du champ dwData lorsque le champ dwOfs est égal à DIMOFS_X ( ou DIMOFS_Y). Pour les boutons, c'est la même chose que pour le clavier (opérateur AND et 0x80) en remplaçant le buffer par le champ dwData de la structure. Pour vous éclaircir les idées, regardez le code source que vous pouvez télécharger tout en haut de cette page. Attention: ne récupérer les infos de la souris que si vous y avez accès. Etape 8 : Libérer toutes les interfaces DirectInput Avant la fermeture de l’application il ne faut surtout pas oublier: 1.De « déacquérir » les interfaces DirectInputDevice par la méthode IDirectInputDevice8::Unacquire (sans argument). 2.De libérer les interfaces DirectInputDevice par la méthode IDirectInputDevice8::Release (sans argument). 3.De libérer l'objet DirectInput. |