[Librairie C] Contrôle avancé du clavier V2 corrigée
Posté le 30/08/2014 20:29
L'avantage que possède la programmation en C/C++ est d'avoir accès à toutes les touches du clavier rapidement, mais de base la gestion du clavier reste assez primaire.
Je vous présente ma librairie que j'utilise pour gérer efficacement le clavier. Elle est à télécharger en
fichier joint
Première étape :
Il faut inclure input.h dans vos fichier .c
Chaque touche est associée à un mot clef. Par exemple la touche "flèche gauche" correspond à K_LEFT.
Pour voir le nom de chaque touche, il suffit de regarder dans "input.h"
Liste des fonctions :
void input_update()
Cette fonction mets à jour le clavier en enregistrant l'état actuel de toutes les touches.
Il faut appeler cette méthode une seule fois par frame car une fois qu'elle à été appelée toutes les fonctions qui suivent seront mise à jour.
int input_any_key()
Cette fonction renvoie 1 si une touche quelconque est pressée, 0 sinon.
int input_press(char key)
Cette fonction renvoie l'état de la touche demandée.
1 si la touche est pressé, 0 sinon.
int input_trigger(char key)
Cette fonction très utile renvoie 1 au moment où la touche est appuyée puis renvoie 0, même si la touche est encore pressée.
Elle envoie une impulsion au moment où on appuie.
int input_release(char key)
Envoie une impulsion au moment où on relâche la touche.
int input_hold_short(char key)
Cette fonction renvoie 1 si la touche est pressée depuis un court instant, 0 sinon.
int input_hold_long(char key)
Cette fonction renvoie 1 si la touche est pressée depuis un long instant, 0 sinon.
int input_repeat(char key)
Fonction extrêmement utile ! Pour les curseurs notamment !
Au moment où on appuie la fonction renvoie 1, puis 0. Si on reste appuyé la fonction renvoie des impulsions à intervalle réguliers.
Exemple : On reste appuyé sur la flèche du bas pour déplacer un curseur, par exemple dans un menu.
Le curseur descend d'un seul cran, attend quelques instants, puis descend à intervalle régulier cran par cran.
cela permet de choisir précisément tout en allant vite. C'est le même principe que les touches d'un ordinateur.
int input_repeat_short(char key)
Même principe que input_repeat() mais avec des intervalles plus court.
int input_dir4()
Cette fonction renvoie la direction pointée par les touches fléchées selon la disposition du pavé numérique sans prendre en compte les diagonales.
Renvoie 0 si aucune touche fléchée n'est pressée.
Exemple : si on appuie sur la flèche de droite, la fonction renvoie 6.
int input_dir8()
Même principe que input_dir4() mais prend en compte les diagonales.
Pavé numérique
Pavé numérique
Utilisation :
Il n'est pas utile et même fortement inutile d'ailleurs d'appeler input_update chaque fois avant d'utiliser les fonctions input_
Il faut l'appeler une seule fois par frame.
Le mieux est de suivre un code de ce type :
while (1) // Boucle principale
{
input_update(); // On mets à jour l'etat du clavier
...
if (input_trigger(K_LEFT))
{
...
}
if (input_repeat(K_SHIFT))
{
...
}
...
setFps(); // conseille
}
Il est conseillé de combiner cela avec une régulation des FPS : voir
ici
Et voilà !
J'ai repris key_down() écrit par je ne sais pas qui, donc il me semble que c'est compatible SH4
Fichier joint
Citer : Posté le 01/09/2014 21:19 | #
Au fait, tu pourrais retourner et prendre des int quand même.
La norme veut qu'on n'utilise des char que lorsqu'il s'agit vraiment de caractères.
Et ne me dites pas que c'est pour économiser la mémoire : ça ne sert à rien du tout.
Citer : Posté le 02/09/2014 16:13 | #
Il n'y a pas de petites économies !
Coïncidence ? Je ne pense pas.
Citer : Posté le 02/09/2014 16:19 | #
Ben ça ne sert vraiment à rien :mmm:, dans le sens ou l'argument (ou la valeur de retour d'ailleurs) est placé dans un registre, donc que ce soit un soit ou un char, il n'a pas de différence ;).
Citer : Posté le 02/09/2014 16:21 | #
(C'était un petit troll )
Coïncidence ? Je ne pense pas.
Citer : Posté le 02/09/2014 16:27 | #
Ben ça ne sert vraiment à rien :mmm:, dans le sens ou l'argument (ou la valeur de retour d'ailleurs) est placé dans un registre, donc que ce soit un oit ou un char, il n'a pas de différence ;).
Oui, et ?
Cet argument va peut-être en faveur des int, mais pas en défaveur des chars...
Citer : Posté le 02/09/2014 17:49 | #
La norme veut qu'on n'utilise des char que lorsqu'il s'agit vraiment de caractères.
Et je répondais simplement à Dark0300, je ne savais pas si il trollait (ce qui était le cas apparemment ), en justifiant qu'il n'y avait vraiment pas d'économie en utilisant un char plutôt qu'un int.
D'ailleurs je ne cherchais pas à donner d'avantage à l'un ou à l'autre dans mon explication , je justifiais seulement seulement quelque chose :mmm:...
Citer : Posté le 02/09/2014 18:17 | #
Il faudrait peut-être renommer le sujet, il s'agit plus de l'explication d'une bibliotheque qu'un vrai tutoriel sur une gestion parfaite des entrées utilisateur
envie de plonger dans la mer pour ramasser des tresors? => ballon sea
envie de sauver l'univers dans un jeu avec une longue durée de vie? => saviors of the future
un add-in addictif avec plein de secret et de trophées => evasion survival
un shmup bien dur et sadique => saviors 2
merci a tout le monde pour son soutien
zelda prizm de smashmaster (en esperant qu'il puisse le finir)
les tests de marmotti
un RPG de dark storm
(dont je connais le nom, mais pas vous )Arcuz !Citer : Posté le 02/09/2014 18:29 | #
Je suis d'accord avec dodormeur !
Coïncidence ? Je ne pense pas.
Citer : Posté le 02/09/2014 21:54 | #
J'ai pas mon ordi Drac0300 donc je peux pas regarder ce qui cloche. Je verrai cela samedi
C'est vrai que c'est plus propre de retourner des int, je modifierai.
Pour le tutoriel j'ai hésité, je ne savais pas trop comment appeler ça.
Citer : Posté le 02/09/2014 22:14 | #
Ben un machin du genre "[bibliotheque] easy_keyboard" (easy_input est déjà pris )
envie de plonger dans la mer pour ramasser des tresors? => ballon sea
envie de sauver l'univers dans un jeu avec une longue durée de vie? => saviors of the future
un add-in addictif avec plein de secret et de trophées => evasion survival
un shmup bien dur et sadique => saviors 2
merci a tout le monde pour son soutien
zelda prizm de smashmaster (en esperant qu'il puisse le finir)
les tests de marmotti
un RPG de dark storm
(dont je connais le nom, mais pas vous )Arcuz !Citer : Posté le 03/09/2014 21:15 | #
Sur le SDK, input_trigger(K_SHIFT); ne marche pas alors que je met tous le temps input_update ( à chaque frame) et le SDK ne me donne aucune erreur
Citer : Posté le 03/09/2014 22:18 | #
@florian : drac a fait la même remarque, je regarde cela samedi
input_press(K_SHIFT) fonctionne bien ? Si oui je vois où peut être le problème.
Citer : Posté le 04/09/2014 07:17 | #
La fonction marche sur le SDK avec la touche EXE mais pas SHIFT
Citer : Posté le 04/09/2014 12:46 | #
J'ai fait cette remarque moi ?
Coïncidence ? Je ne pense pas.
Citer : Posté le 05/09/2014 10:08 | #
Doncla fonction ici présente key_down fonctionne sur SH3/4? Je note et je prends, merci. (Le reste ne m'intéresse guère, j'ai implémenté déjà un système similaire.) Je dois remercier qui pour avoir adapté cette fonction sur SH4?
Citer : Posté le 07/09/2014 16:38 | #
J'ai regardé le code, j'ai optimisé quelques trucs, notamment un gain de 70 octets de mémoire.
Par contre l'erreur de EXE SHIFT ou ALPHA... J'arrive pas à voir ce qui cloche. Je continue de regarder ça cette semaine et dès que je trouve d'où l'erreur provient je la corrige.
Citer : Posté le 07/09/2014 18:10 | #
Curieux, quand je prenais la fonction en question (key_down) seule, j'arrivais à utiliser les touches comme Shift.
Ajouté le 07/09/2014 à 18:36 :
Autres choses !
- Dans un .c, si il y a des fonctions ou variables globales que tu ne veux pas qu'on accède depuis ailleurs, passe-les en static, c'est plus ou moins l'équivalent d'un private en langage objet. (Ca et ne pas mettre son prototype dans le .h aide aussi).
- Ca aussi?
static unsigned char last_key[79] = {0};
static unsigned char current_key[79] = {0};
//...
for (i=0; i <=79; i++)
Bien, la lecture out of bounds? Si tu as un tableau de n éléments, le dernier élément est en index n-1, fais gaffe!.
- Tu as un tableau de 79 touches, or pleins de slots touches ne sont ni utilisées ni le tableau accède à toutes les touches définies. Oui, un chiffre écrit de cette manière ( 0Xff) est un chiffre hexa. Donc, par exemple Shift, a pour valeur 104.
- Ceci :
{
current_key[i] += 1;
if (current_key[i] == 255) current_key[i] = 254;
} else {
current_key[i] = 0;
}
est bien plus simple ainsi
if (key_down(i))
{
if (current_key[i] < 255)
current_key[i]++; // (ou ++current_key[i]; Je pense qu'ici, le compilo fait l'optimisation. Au moins ça...)
} else {
current_key[i] = 0;
}
Et si tu veux la version crade :
current_key[i] += key_down(i) ? (current_key[i] < 255 ? 1 : 0) : ~current_key[i];
//version alternative
current_key[i] = key_down(i) ? (current_key[i] < 255 ? current_key[i]+1 : 255) : 0;
// tiens j'ai une idée à la con
// current_key ^ 255 ? current_key[i]++ : 255; // En gros, !(a xor b) revient à faire a == b
current_key[i] = key_down(i) ? (current_key[i] ^ 255 ? current_key[i]+1 : 255) : 0; // ~ est inutilisable dans le cas ou current_key[i] == 0
Bon, j'vais arrêter là, j'aime bien tripatouiller avec les opérateurs bizarres (trop d'Axe Parser...)
Citer : Posté le 07/09/2014 22:15 | #
Whaw ! Merci Eiyeron !
C'est vrai qu'il y a plein d'erreurs...
J'avais même pas vu pour l'héxa... Je suis con parce que pour faire la lib j'ai pas copié le code qui marchait bien pour mon programme, j'avais une erreur de compilation sur un pointeur void juste quand je faisait un copié coller, c'était bizarre... Bref j'ai repris le code Pierollt de Gravity Duck que j'avais ouvert au même moment, sauf que malgré l'apparence il est pas du tout pareil... Du coup là j'ai repris le code que j'avais avant où les touches sont bien entre 31 et 79 (en décimal !!! ) (celui de useful de Dodormeur)
J'en ai corrigé pas mal aujourd'hui, surtout j'ai réduit la taille des tableaux (décalage de 31)
Bref j'ai fait le con en adaptant ma lib pour "le grand public" j'ai testé pour deux trois touches sa fonctionnait. De la chance au final.
Je corrige tout dès que possible.
Merci
Citer : Posté le 07/09/2014 22:16 | #
TU veux qu'on reparle d'ECode, la lib que je n'ai quasiment pas testé?
D'ailleurs, elle n'a plus trop raison d'exister celle-là.
Citer : Posté le 07/09/2014 22:16 | #
Et sinon ça veut dire quoi le
~current_key
et le
++current_key // par rapport au current_key++
Citer : Posté le 07/09/2014 22:19 | #
~integer == not binaire
Et ++nombre == nombre += 1 à la différence près que
int a = 5;
tableau[++a] // va fetcher tableau[6]
printf("%d", a); // va afficher 6
n'est pas la même chose que
int a = 5;
tableau[a++] // va fetcher tableau[5]
printf("%d", a); // va afficher 6
++nombre s'execute généralement avant l'instruction suivante alors que nombre++ le fait après.