mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-12-21 23:29:35 +00:00
224 lines
5.2 KiB
C++
224 lines
5.2 KiB
C++
#include "opencv-keyboard.h"
|
|
|
|
/*
|
|
* OpenCV doesn't support very sophisticated keyboard interaction.
|
|
* You can't query modifier keys; you don't get up-and-down
|
|
* events. There's just a simple "has any key been pressed" method.
|
|
*/
|
|
|
|
#include "opencv2/core/core.hpp"
|
|
#include "opencv2/imgproc/imgproc.hpp"
|
|
#include "opencv2/highgui/highgui.hpp"
|
|
#include "opencv2/calib3d/calib3d.hpp"
|
|
#include "opencv2/features2d/features2d.hpp"
|
|
|
|
using namespace cv;
|
|
using namespace std;
|
|
|
|
OpenCVKeyboard::OpenCVKeyboard(VMKeyboard *k) : PhysicalKeyboard(k)
|
|
{
|
|
}
|
|
|
|
OpenCVKeyboard::~OpenCVKeyboard()
|
|
{
|
|
}
|
|
|
|
typedef struct {
|
|
int8_t actualKey;
|
|
bool shifted;
|
|
} keymapChar;
|
|
|
|
// keymap starts at space (32), ends at delete (127).
|
|
// Note that this maps them based on what the Apple //e expects. It's the
|
|
// same as a modern US keyboard.
|
|
const keymapChar keymap[96] =
|
|
{ { ' ', false }, // space
|
|
{ '1', true }, // !
|
|
{ '\'', true }, // "
|
|
{ '3', true }, // #
|
|
{ '4', true }, // $
|
|
{ '5', true }, // %
|
|
{ '7', true }, // &
|
|
{ '\'', false}, // '
|
|
{ '9', true }, // (
|
|
{ '0', true }, // )
|
|
{ '8', true }, // *
|
|
{ '=', true }, // +
|
|
{ ',', false }, // ,
|
|
{ '-', false }, // -
|
|
{ '.', false }, // .
|
|
{ '/', false }, // /
|
|
{ '0', false }, // 0
|
|
{ '1', false }, // 1
|
|
{ '2', false }, // 2
|
|
{ '3', false }, // 3
|
|
{ '4', false }, // 4
|
|
{ '5', false }, // 5
|
|
{ '6', false }, // 6
|
|
{ '7', false }, // 7
|
|
{ '8', false }, // 8
|
|
{ '9', false }, // 9
|
|
{ ':', true }, // :
|
|
{ ';', false }, // ;
|
|
{ ',', true }, // <
|
|
{ '=', false }, // =
|
|
{ '.', true }, // >
|
|
{ '/', true }, // ?
|
|
{ '2', true }, // @
|
|
{ 'A', true }, // A
|
|
{ 'B', true }, // B
|
|
{ 'C', true }, // C
|
|
{ 'D', true }, // D
|
|
{ 'E', true }, // E
|
|
{ 'F', true }, // F
|
|
{ 'G', true }, // G
|
|
{ 'H', true }, // H
|
|
{ 'I', true }, // I
|
|
{ 'J', true }, // J
|
|
{ 'K', true }, // K
|
|
{ 'L', true }, // L
|
|
{ 'M', true }, // M
|
|
{ 'N', true }, // N
|
|
{ 'O', true }, // O
|
|
{ 'P', true }, // P
|
|
{ 'Q', true }, // Q
|
|
{ 'R', true }, // R
|
|
{ 'S', true }, // S
|
|
{ 'T', true }, // T
|
|
{ 'U', true }, // U
|
|
{ 'V', true }, // V
|
|
{ 'W', true }, // W
|
|
{ 'X', true }, // X
|
|
{ 'Y', true }, // Y
|
|
{ 'Z', true }, // Z
|
|
#ifndef TEENSYDUINO
|
|
{ LA, false }, // [
|
|
#else
|
|
{ '[', false }, // [
|
|
#endif
|
|
{ '\\', false}, // \ ...
|
|
#ifndef TEENSYDUINO
|
|
{ RA, false }, // ]
|
|
#else
|
|
{ ']', false }, // ]
|
|
#endif
|
|
{ '6', true }, // ^
|
|
{ '-', true }, // _
|
|
{ '`', false }, // `
|
|
{ 'A', false }, // a
|
|
{ 'B', false }, // b
|
|
{ 'C', false }, // c
|
|
{ 'D', false }, // d
|
|
{ 'E', false }, // e
|
|
{ 'F', false }, // f
|
|
{ 'G', false }, // g
|
|
{ 'H', false }, // h
|
|
{ 'I', false }, // i
|
|
{ 'J', false }, // j
|
|
{ 'K', false }, // k
|
|
{ 'L', false }, // l
|
|
{ 'M', false }, // m
|
|
{ 'N', false }, // n
|
|
{ 'O', false }, // o
|
|
{ 'P', false }, // p
|
|
{ 'Q', false }, // q
|
|
{ 'R', false }, // r
|
|
{ 'S', false }, // s
|
|
{ 'T', false }, // t
|
|
{ 'U', false }, // u
|
|
{ 'V', false }, // v
|
|
{ 'W', false }, // w
|
|
{ 'X', false }, // x
|
|
{ 'Y', false }, // y
|
|
{ 'Z', false }, // z
|
|
{ '[', true }, // {
|
|
{ '\\', true }, // |
|
|
{ ']', true }, // }
|
|
{ '`', true }, // ~
|
|
{ DEL, false } // delete
|
|
};
|
|
|
|
void OpenCVKeyboard::maintainKeyboard()
|
|
{
|
|
static int invalidCount = 0;
|
|
int c = cv::waitKey(1);
|
|
// OpenCV relies on KeyRepeat to deliver individual presses. We want
|
|
// to guess about "it's still down": so, unless we get > 3 invalid
|
|
// "-1" values in a row, we're gonna assume it's still pressed.
|
|
if (c == -1) {
|
|
invalidCount++;
|
|
if (invalidCount < 4) {
|
|
return;
|
|
}
|
|
} else {
|
|
invalidCount = 0;
|
|
}
|
|
|
|
if (c == -1) {
|
|
if (lastKey >= ' ' && lastKey <= 127) {
|
|
vmkeyboard->keyReleased(keymap[lastKey-' '].actualKey);
|
|
if (keymap[lastKey-' '].shifted) {
|
|
vmkeyboard->keyReleased(LSHFT);
|
|
}
|
|
} else {
|
|
vmkeyboard->keyReleased(lastKey);
|
|
}
|
|
|
|
lastKey = -1;
|
|
return;
|
|
}
|
|
|
|
|
|
if (c == 0xF700) {
|
|
c = UARR; // up
|
|
} else if (c == 0xF701) {
|
|
c = DARR; // down
|
|
} else if (c == 0xF702) {
|
|
c = LARR; // left
|
|
} else if (c == 0xF703) {
|
|
c = RARR; // right
|
|
}
|
|
|
|
// If we're already repeating this key, do nothing
|
|
if (lastKey != -1 &&
|
|
lastKey == c) {
|
|
return;
|
|
}
|
|
|
|
// If it's a different key, then do a key up
|
|
if (lastKey != -1) {
|
|
if (lastKey >= ' ' && lastKey <= 127) {
|
|
vmkeyboard->keyReleased(keymap[lastKey-' '].actualKey);
|
|
if (keymap[lastKey-' '].shifted) {
|
|
vmkeyboard->keyReleased(LSHFT);
|
|
}
|
|
} else {
|
|
vmkeyboard->keyReleased(lastKey);
|
|
}
|
|
|
|
lastKey = -1;
|
|
}
|
|
|
|
// Now it's a new keypress - do a key down
|
|
|
|
if (c >= ' ' && c <= 127) {
|
|
if (keymap[c-' '].shifted) {
|
|
vmkeyboard->keyDepressed(LSHFT);
|
|
}
|
|
vmkeyboard->keyDepressed(keymap[c-' '].actualKey);
|
|
|
|
lastKey = c;
|
|
return;
|
|
}
|
|
|
|
// Any other key that could have been reported:
|
|
// ESC RET TAB LA RA LARR RARR DARR UARR
|
|
vmkeyboard->keyDepressed(c);
|
|
|
|
// anything else isn't reported by OpenCV, so we can't report it
|
|
// specifically. So these are ignored:
|
|
// _CTRL LSHFT RSHFT LOCK LA RA
|
|
|
|
lastKey = c;
|
|
}
|