I have found the problem with GTA: The game kinda sample the keyboard state, so if the key remain pressed for a few time it won't be recognized. I got that insight when I realized that sometimes the game recognized one of the keys (like A that makes the character move left).
By analyzing Digispark.h I have noticed that the SendKeyStroke function sends a key up right after the key pressed.
void sendKeyStroke(byte keyStroke, byte modifiers) {
while (!usbInterruptIsReady()) {
usbPoll();
_delay_ms(5);
}
memset(reportBuffer, 0, sizeof(reportBuffer));
reportBuffer[0] = modifiers;
reportBuffer[1] = keyStroke;
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
while (!usbInterruptIsReady()) {
usbPoll();
_delay_ms(5);
}
/* HERE WAS THE PROBLEM WITH GTA */
// This stops endlessly repeating keystrokes:
memset(reportBuffer, 0, sizeof(reportBuffer));
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
To solve that without messing with the Digispark routines I have simply copied the code into my sketch and ripped off the last two lines of code that send the zero (no key).
The compiler complained about a missing definition of reportBuffer variable. Strangely enough the definition of such variable is not defined on DigiKeyboard.h. (it is defined in DigiMouse.h and DigiJoystick.h though!).
To fix it I have just created the variable and it compiled (and worked as well).
////////////////////////////////////////////////
// __ __ _ _ _
// \ \ / /_ _ _ _(_)__ _| |__| |___ ___
// \ V / _` | '_| / _` | '_ \ / -_|_-<
// \_/\__,_|_| |_\__,_|_.__/_\___/__/
//
uint8_t ticks = 0;
uint8_t lastkey = 0;
uint8_t temp, key;
uchar reportBuffer[2];
I have also added a custom 'print' function that for each character sent to host it waits a small delay and then sends a zero (no press). // Print a string to the host, and add a key up after a delay
void DigiKeyboard_print ( char *str ) {
uint8_t data;
while (*str) {
data = pgm_read_byte_near(ascii_to_scan_code_table + (*str++ - 8));
sendKeyStroke_nostop(data & 0b01111111, data >> 7 ? MOD_SHIFT_RIGHT : 0);
DigiKeyboard.delay(50);
sendKeyStroke_nostop(0,0);
}
}
I have fiddled with this delay and found that 20ms is not enough but 50ms is fine. Bug Busted!!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.