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 ...