Gestion de l'input

Écrit le 03/07/2003 par Bicou
Dernière mise à jour : 30/01/2006

Introduction

Ce tutorial vous permettra de créer une fonction assignée à une touche qui apparaîtra dans le menu Configuration>Contrôles.

Comprendre le tut

En fait nous allons dans le fichier qui gère les touches dans Half-Life, on crée une nouvelle variable, et deux fonctions (une qui sera lancée quand on appuie sur la touche, l'autre quand on la relâche). On va relier ces deux fonctions à deux commandes (en fait la même mais qui est double : ex. +attack et -attack). En dehors du code on va modifier un fichier pour dire au launcher (hl.exe) qu'on a créé une nouvelle commande, et que donc il faut l'ajouter dans Configuration > Contrôles.

Les modifications dans la DLL client

Commencez par ouvrir cl_dlls/input.cpp, allez à la ligne 92 et ajoutez :

kbutton_t        in_matouche; //bicou

On a créé notre variable. Maintenant, on va associer deux fonctions : une pour la touche enfoncée, une pour la touche relâchée.

//Bicou -debut
void IN_MaToucheDown( void ) // La fonction qui est lancée quand vous appuyez sur la touche
{
    KeyDown(&in_matouche);

    if ( gViewPort ) //si vous utilisez la classe TeamFortressViewPort,
                              // sinon c'est gHUD pour la classe CHud
        gViewPort->m_pMonMenu->setvisible( true ); //si votre menu s'appelle m_pMonMenu
}

void IN_MaToucheUp( void ) // ...quand la touche est relâchée
{
    KeyUp(&in_matouche);

    if ( gViewPort )
        gViewPort->m_pMonMenu->setVisible( false );
}
//Bicou -fin 

Du coup, quand vous appuyez, ça lance IN_MaToucheDown(), sinon c'est IN_MaToucheUp().
On peut mettre ce qu'on veut dans ces deux fonctions, mais attention, on est du côté client.

Maintenant, on va définir quelle est la commande :
Toujours dans input.cpp, ligne 929, dans la fonction InitInput() :

gEngfuncs.pfnAddCommandmmand ("+break",IN_BreakDown);
gEngfuncs.pfnAddCommand ("-break",IN_BreakUp);
gEngfuncs.pfnAddCommand ("+macommande", IN_MaToucheDown); //bicou
gEngfuncs.pfnAddCommand ("-macommande", IN_MaToucheUp); //bicou

Là, on a dit au moteur de relier la commande « +macommande » à la fonction IN_MaToucheDown() et
« -macommande » à la fonction IN_MaToucheUp().

Les modifications en dehors du code

On travaille dans le répertoire gfx/shell. Vous devez avoir trois fichiers *.lst (ça veut dire list).
Ouvrez kb_act.lst :

"+macommande"    "Nom de ma Commande"
"+forward"        "Avancer"
"+back"          "Reculer"

En fait on a donné un nom à notre commande. Ce nom est affiché dans le menu Configuration->Contrôles dans Half-life.
Maintenant, kb_def.lst :

"h"              "+macommande"
"w"              "+forward"
"UPARROW"        "+forward"

On a défini la touche par défaut associée à notre commande (si on clique sur le bouton « Prédéfinis »).
Allez dans le fichier kb_keys.lst pour savoir quel est le nom de la touche, si besoin.

NB: on n'a pas besoin de définir -macommande : le moteur se démerde ;-)

Macros

Les macros sont les « fonctions » créées avec #define.

Il existe donc des macros qui facilitent l'ajout de commandes dans les classes dérivées de CHudBase. Les voici :

#define HOOK_COMMAND(x, y) gEngfuncs.pfnAddCommand( x, __CmdFunc_##y );
#define DECLARE_COMMAND(y, x) void __CmdFunc_##x( void )
         {
             gHUD.##y.UserCmd_##x( );
         }

DECLARE_COMMAND va donc créer une fonction. Prenons un exemple :

DECLARE_COMMAND(m_Fog, SwapFog);

équivaut à

void __CmdFunc_SwapFog( void )
{
    gHUD.m_Fog.UserCmd_SwapFog( );
}

Il faut donc avoir créé la fonction UserCmd_SwapFog dans la classe de m_Fog (suivez ce tut pour avoir cette classe). C'est cette fonction qui sera lancée lorsqu'on appuiera sur la touche (ça équivaut à IN_MaToucheDown).

HOOK_COMMAND va donc appeler une fonction. Reprenons l'exemple :

HOOK_COMMAND( "swapfog", SwapFog );

équivaut à :

gEngfuncs.pfnAddCommand( "swapfog", __CmdFunc_SpawFog );

Ca relie donc la commande « swapfog » à la fonction __CmdFunc_SpawFog.

Dans UserCmd_SwapFog on pourrait dire de ne pas afficher le fog, ainsi lorsqu'on appuie sur la touche reliée à « swapfog », ça va « éteindre » le fog, si on rappuie ça le « rallume ». Super non ?

Ce sont ces macros qui sont utilisées dans les classes dérivées de ChudBase à la place de ce qu'on a vu plus haut.