1

[La recherche sur le forum Prog C de "keytest" n'ayant donné aucun résultat]

smile Bonjour à tous smile

Voilà, j'ai pris une bonne matinée pour essayer de toucher à un domaine nouveau pour moi, la gestion des touches à bas niveau. Pourquoi une bonne matinée ... pour avoir la garantie que je planterais ma calculatrice le moins possible. (Après, bien sûr, cela ne dépend que de moi ... sad sad sad ) .

Donc, j'ai remarqué qu'il y a la fonction _keytestOptimized (associée à BEGIN_KEYTEST et END_KEYTEST) pour lire un ensemble de touches sur la même ligne; et _keytest seule pour lire des touches diverses.

Alors moi, ce que je me demande (étant donné que la touche ESC est bien pauvre esseulée sur sa ligne 6, ce qui évidemment - même pour un simple test - n'arrange pas mes affaires sad sad sad ) quelle est la meilleure solution pour effectuer des lectures combinées de ligne : ligne 0 + ligne 6 par exemple ? _keytest seule ? combinaison _keytest et _keytest_optimized ? combinaison de _keytest_optimized ?

Merci d'avance pour ceux qui auront pu me répondre smile smile smile

P.S : je veux programmer sous GTC : y a-t-il un bug connu à ce sujet ? sad sad sad
Le gentil timide du 64

2

En attendant : Diamond remplacera ESC sad
En fait, les touches retournées par _rowread, sont-elles les mêmes que ngetchx ? (Je n'ai
pas vu la doc de TIGCC le préciser) .

Je n'ai pas peur des claques ... si ma question est bête, n'hésitez pas à me le dire .
Le gentil timide du 64

3

> les touches retournées par _rowread, sont-elles les mêmes que ngetchx ?
Non smile
ngetchx et GKeyIn sont des fonctions de haut niveau (code de touche évolué), _rowread et _keytest sont des fonctions de bas niveau (est-ce que la touche, ou le groupe de touches, est enfoncée ?).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

4

Merci Lionel smile

Voilà un programme court que j'ai testé sur GTC :
--- il ne déplace "A" de une unité à chaque pression de touche, comme je le désire
--- des touches dont je n'ai pas défini le comportement agissent également (ceci explique peut être cela) : ENTER et ESC par exemple sad
--- preos a du intercepter un crash à la fin du programme.

Pouvez-vous m'expliquer (et non corriger si possible) mes erreurs s'il vous plait ?

#define USE_TI89
#define SAVE_SCREEN

#include <kbd.h>
#include <graph.h>
#include <printf.h>

void _main(){
   char toRefresh = 0;
   char xA = 10;
   char yA = 50;
   short touche;

   [ajout 1 : section declaration]   

   [ajout 2 : section coupure interruption]

   while(1){
      toRefresh = 0;
      BEGIN_KEYTEST
      if (_keytest_optimized(RR_LEFT)){
          xA -= 1;
          toRefresh = 1;
      }
     else if (_keytest_optimized(RR_RIGHT)){
          xA += 1;
          toRefresh = 1;
      }
     else if (_keytest_optimized(RR_UP)){
          yA -= 1;
          toRefresh = 1;
      }
      else if (_keytest_optimized(RR_DOWN)){
          yA += 1;
          toRefresh = 1;
      }
      else if (_keytest_optimized(RR_DIAMOND)){
          exit(1);
      }
      END_KEYTEST
      if (toRefresh > 0){
          ClrScr();
          printf_xy(xA,yA,"A");
      }
   }

   [ajout 3 : section rétablissement interruption]

}



Ce n'est pas une question d'inversion de ligne par hasard ? (Je n'ai pas assez lu la doc à ce sujet)
Le gentil timide du 64

5

Tu n'as pas redirigé les interruptions 1 principalement et 5, qui interfèrent avec la lecture _rowread / _keytest.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

6

Merci beaucoup smile
Je plonge de suite dans la doc de TIGCC pour remédier à cela.
A noter que si je parviens à y remédier, je ne devrais pas poster la solution, la doc devant suffire d'elle-même, et ce programme n'étant pas une application mais un simple test smile smile smile
Je posterais juste pour dire si j'ai réussi et éventuellement demander ce qui ne m'aurait pas semblé assez compréhensible dans la doc.
Le gentil timide du 64

7

Je sais comment faire ... mais le programme plante encore.
(Voir le post ./4 pour les positions des ajouts ) :

[ajout 1 : section déclaration]

INT_HANDLER save_autoint_1;
INT_HANDLER save_autoint_5;

[ajout 2 : section coupure interruption]

/* sauver et couper les interruptions blocantes */
save_autoint_1 = GetIntVec(AUTO_INT_1);
save_autoint_5 = GetIntVec(AUTO_INT_5);
SetIntVec(AUTO_INT_1, DUMMY_HANDLER);
SetIntVec(AUTO_INT_5, DUMMY_HANDLER);

[ajout 3 : section rétablissement interruption]

/* restaurer les interruptions blocantes */
SetIntVec(AUTO_INT_1, save_autoint_1);

SetIntVec(AUTO_INT_5, save_autoint_5);


Pouvez-vous m'aider s'il vous plaît. (Cette fois-ci, le crash n'a pas pu être intercepté par PreOS)
Le gentil timide du 64

8

peut-être que ça plante parce que tu sors de l'écran ? printf_xy peut corrompre la mémoire si une partie du texte dépasse de l'écran smile pour résoudre ça il faut que tu prennes une routine clippée pour afficher ton curseur... (cf les libs graphiques comme extgraph ou genlib)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

9

Merci Pollux smile Le problème avec les modifs apportés, c'est que je n'ai même pas quitté l'écran HOME.
Printf_xy même pour un simple test pour écrire des jeux ... j'éviterais à l'avenir sad sad sad

En parlant de genlib et extgraph, j'ai vu dans le repertoire zheader de ma calculatrice des fichiers hdr (header je suppose) nommés gen et extgraph, mais je ne sais pas toutefois si je peux les inclure directement par des appels du genre #include <gen.h> ... Est-ce possible ?

(Sinon, j'ai téléchargé les versions PC, pour les docs)

... J'ai ma réponse : OUI smile smile smile
Le gentil timide du 64

10

J'ai testé avec la librairie extgraph ... et c'était bien la fonction printf_xy qui bloquait.
En outre, cette fois-ci, seules les touches que j'ai vraiment programmées interagissent.

Mais
1) Il peut arriver de temps en temps d'obtenir un message d'erreur, par boite de dialogue, UNKNOWN ERROR CODE
2) Il semble que xA et yA ne soient pas vraiment incrémentés de 1 unité, comme je le désirais, mais de beaucoup plus .
Le gentil timide du 64

11

12

Salut Martial smile

2) Oui mais pourtant j'effectue une simple pression de touche sad
Ne faut-il pas masquer la colonne utilisée, et ne pas me contenter simplement d'appeler _keytest_optimized(RR_XX) ?
Je suis sûr d'avoir lu quelque chose de ce genre quelque part.
Le gentil timide du 64

13

Il faut mettre une boucle d'attente, sinon ça va trop vite.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

14

Très bien, Martial et Lionel, je vous écoute.
Je vais rajouter une simple boucle for (de toute façon, pour me baser sur les AUTO-INT ... c'est raté) .

...
Non, j'ai fait deux boucles imbriquées allant de 0 à 2^32-1 ... et rien ne change. Il y a une anomalie dans mon programme à coup sûr. sad
Le gentil timide du 64

15

si tes boucles ne font rien, il est possible que le compilateur les supprime, pour optimiser (pourquoi laisser des boucles - qui prennent du temps - si elles ne font aucun traitement ? )

du genre, il y a des chances que le compilateur supprime quelque chose de ce style :
int i;
for (i=0 ; i<1000 ; i++) {}


Une solution pour éviter cette optimisation (si le problème vient bien de là) serait de passer ta variable en "volatile" :
volatile int i;
for (i=0 ; i<1000 ; i++) {}


Mais ça reste une solution crade...
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

16

17

Martial Demolins (./16) :
mais le but est d'apprendre à se servir du clavier et non de releaser qqchose de propre.

en mettant une attente, rien ne garanti que la pression sur la touche ne sera tout de même pas plusieurs fois détectée : suffit de laisser appuyé suffisament (ou trop, selon le point de vue) longtemps.

Pour être certain qu'il n'y a eu qu'une pression sur la touche, il vaudrait mieux mettre en place un système qui détecte les changements d'état de la touche (un "clic" sur la touche équivalent à une succession de l'état "relaché", "appuyé" et "relaché")ok
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

18

19

Si tu lis ceci :
LinkOf64100 (./10) :
2) Il semble que xA et yA ne soient pas vraiment incrémentés de 1 unité, comme je le désirais,

LinkOf64100 (./12) :
2) Oui mais pourtant j'effectue une simple pression de touche frown.gif


il semble vouloir avec un pas de "une unité".
Auquel cas, avec _rowread et équivalents, il n'y a pas trop le choix ^^ok
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

20

Martial Demolins (./18) :
comment faire compliqué quand on peut faire simple hehe

oui enfin d'un autre côté c'est quand même mieux d'implémenter quelque chose de fiable et élégant (attendre qu'on relâche) plutôt qu'une vieille bidouille pas fiable du tout (la boucle vide) tongue (d'autant plus que ça n'est pas plus compliqué, je trouve, en fait embarrassed)

21

22

Non Martial, ne t'en fais pas, peu importe la difficulté ... je mettrais le temps qu'il faut, je mettrais en place les méthodes qu'il faut : tant que je dispose de la solution la plus efficace. Je suis prêt à essayer la solution de squale92 smile smile smile
Mieux vaut prendre son temps et faire efficace, que de vouloir aller vite à tout prix, et faire un programme peu performant.

Pour preuve : avant de me lancer sur les _rowread et _keytest, j'ai pris une bonne matinée à étudier la doc TIGCC sur les header <kbd.h> et <compat.h> ! Donc, je suis quelqu'un prêt à prendre son temps, pourvu que le résultat se rapproche de la perfection. (Seule exception à la règle : côté graphisme ... ce n'est vraiment pas mon fort)

Ne t'en fait pas, je suis prêt à essayer ... et à réussir, en persévérant éventuellement si je n'y arrive pas des le premières tentatives . smile

Mais je prends tout de même note de ta solution smile
Le gentil timide du 64

23

Ca y est !
J'ai trouvé un système pour forcer le curseur (triangle) à avancer d'une unité à chaque fois que l'on appuie dessus, y compris si j'effectue plusieurs appuis rapides et successifs :
1) j'utilise un énumération etatAppuisTouche {STATE_1ST_RELEASE = 0, STATE_PUSHED, STATE_2ND_RELEASE}
2) dans le mapping de touches du BEGIN_KEYTEST, chaque touche définie affecte le statut de la vairable de typ etatAppuiTouche
3) le mapping autres touches affecte lui-aussi la variable de type etatAppuiTouche

Mais une source parlera d'elle-même :

#define USE_TI89
#define SAVE_SCREEN

#include <intr.h>
#include <kbd.h>
#include <graph.h>
#include <printf.h>
#include <extgraph.h>

typedef struct {
    char dx;
    char dy;
} vecteur;

typedef enum {TCH_GAUCHE = 0, TCH_DROITE, TCH_HAUT, TCH_BAS, TCH_DIAMOND}       
idTouche;

typedef enum {STATE_1ST_RELEASE = 0, STATE_PUSHED = 1, STATE_2ND_RELEASE = 2} etatAppuiTouche;

void _main(){
   char toRefresh = 0;
   char xA = 1,  xA_Ans = xA;
   char yA = 50, yA_Ans = yA;
   
   idTouche touche, toucheAns;
   etatAppuiTouche pressedState = STATE_1ST_RELEASE;

   vecteur mouvement;

   INT_HANDLER save_autoint_1;
   INT_HANDLER save_autoint_5;

   static unsigned char curseur [4] = {0x18,0x3C,0x7E,0xFF};
   
   /* sauver les interruptions blocantes */
   save_autoint_1 = GetIntVec(AUTO_INT_1);
   save_autoint_5 = GetIntVec(AUTO_INT_5);
   /* coupure des interruptions blocantes */
   SetIntVec(AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec(AUTO_INT_5, DUMMY_HANDLER);

   ClrScr();
   Sprite8_XOR(xA,yA,4,curseur,LCD_MEM);
   while(1){
      toRefresh = 0;
      toucheAns = touche;
      BEGIN_KEYTEST
      if (_keytest_optimized(RR_LEFT)){
          if(pressedState == STATE_1ST_RELEASE){
             pressedState = STATE_PUSHED;
          }
          else if(pressedState == STATE_PUSHED){
              if(1){
                  mouvement.dx = -1;
                  mouvement.dy = 0;
                  pressedState = STATE_2ND_RELEASE;
              }
          }
          touche = TCH_GAUCHE;
      }
     else if (_keytest_optimized(RR_RIGHT)){
          if(pressedState == STATE_1ST_RELEASE){
             pressedState = STATE_PUSHED;
          }
          else if(pressedState == STATE_PUSHED){
              if(1){
                  mouvement.dx = 1;
                  mouvement.dy = 0;
                  pressedState = STATE_2ND_RELEASE;
              }
          }
          touche = TCH_DROITE;
      }
     else if (_keytest_optimized(RR_UP)){
          if(pressedState == STATE_1ST_RELEASE){
             pressedState = STATE_PUSHED;
          }
          else if(pressedState == STATE_PUSHED){
              if(1){
                  mouvement.dx = 0;
                  mouvement.dy = -1;
                  pressedState = STATE_2ND_RELEASE;
              }
          }
          touche = TCH_HAUT;
      }
      else if (_keytest_optimized(RR_DOWN)){
          if(pressedState == STATE_1ST_RELEASE){
             pressedState = STATE_PUSHED;
          }
          else if(pressedState == STATE_PUSHED){
              if(1){
                  mouvement.dx = 0;
                  mouvement.dy = 1;
                  pressedState = STATE_2ND_RELEASE;
              }
          }
          touche = TCH_BAS;
      }
      else if (_keytest_optimized(RR_DIAMOND)){
          exit(1);
      }
      /* autres touches ou pas d'appui */
      else {
           if(pressedState == STATE_2ND_RELEASE){
                xA += mouvement.dx;
                yA += mouvement.dy;
                toRefresh = 1;
                pressedState = STATE_1ST_RELEASE;
           }
      }
      END_KEYTEST
      if (toRefresh > 0){
          Sprite8_XOR(xA_ans,yA_ans,4,curseur,LCD_MEM);
          Sprite8_XOR(xA,yA,4,curseur,LCD_MEM);
          xA = xA_ans; yA = yA_ans;
      }
   }

   /* restaurer les interruptions blocantes */
   SetIntVec(AUTO_INT_1, save_autoint_1);
   SetIntVec(AUTO_INT_5, save_autoint_5);
}





Il ne me manque plus qu'à autoriser, non PROGRAMMER un éventuelle appui prolongé de touche (donc temps appui > .5s) .

Cette programmation , qui demeure propre, n'en est pas moins paradoxale. Mais qui a dit qu'on devait toujours programmer de la même manière ? Moi je pense qu'avec un domaine aussi compliqué que la lecture des touches en bas niveau, je serais amené à varier chaque programme, selon mes besoins spécifiques ...
Le gentil timide du 64

24

25

j'ai rien lu au topic, mais je voulais juste dire que ça sert à rien d'optimiser la lecture du clavier, _keytest suffit largement.

26

Martial, merci smile C'est peut être plus dur, mais d'après Squale92, c'est plus efficace.

Jyaif >> Merci smile . Ca ne sert peut être à rien, mais au moins comme ça je pourrais dire : "smile OUI, Linkof64100, TU SAIS LE FAIRE smile"
Le gentil timide du 64

27

il parlait juste du fait d'utiliser _keytest_optimized au lieu de _keytest smile ben oui et non, si y a que 4 touches ça fait aucune différence mais si y en a bcp plus _keytest risque de ralentir pas mal ^^

à mon avis tu devrais surtout éviter de dupliquer le code comme tu l'as fait, et regrouper le code dupliqué soit dans une fonction soit si c'est pas possible dans un #define happy

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

28

Oui tu as raison. Cela améliorerait la lisibilité. smile
Le gentil timide du 64

29

30

Enfin la taille du code, je dirais qu'à première vue, étant donné que je privilégias le #define, non. Mais comme tu me le fais remarquer, passer par une fonction est la meilleure des deux solutions. smile

Oups ... j'ai du mal à factoriser le code en fonction à cause de la macro PSEUDO_CONST_KBD : si je dois la remplacer à chaque fois, ce n'est plus une fonction.
En Macro ça ne passe pas non plus sad
Le gentil timide du 64