aiie/sdl/sdl-keyboard.cpp

257 lines
6.2 KiB
C++

#include "sdl-keyboard.h"
#include "sdl-paddles.h"
#include "sdl-mouse.h"
#include "globals.h"
#include "sdl-display.h"
SDLKeyboard::SDLKeyboard(VMKeyboard *k) : PhysicalKeyboard(k)
{
}
SDLKeyboard::~SDLKeyboard()
{
}
typedef struct {
int8_t actualKey;
bool shifted;
} keymapChar;
void SDLKeyboard::handleKeypress(SDL_KeyboardEvent *key)
{
bool releaseEvent = key->type == SDL_KEYUP;
if (key->type == SDL_KEYDOWN &&
key->keysym.sym == SDLK_F10) {
// Invoke BIOS
g_biosInterrupt = true;
return;
}
if ( (key->keysym.sym >= 'a' && key->keysym.sym <= 'z') ||
(key->keysym.sym >= '0' && key->keysym.sym <= '9') ||
key->keysym.sym == '-' ||
key->keysym.sym == '=' ||
key->keysym.sym == '[' ||
key->keysym.sym == '`' ||
key->keysym.sym == ']' ||
key->keysym.sym == '\\' ||
key->keysym.sym == ';' ||
key->keysym.sym == '\'' ||
key->keysym.sym == ',' ||
key->keysym.sym == '.' ||
key->keysym.sym == '/' ||
key->keysym.sym == ' ' ||
key->keysym.sym == 27 || // ESC
key->keysym.sym == 13 || // return
key->keysym.sym == 9) { // tab
// Simple keypresses
if (key->keysym.mod & (KMOD_LCTRL|KMOD_RCTRL)) {
key->keysym.sym -= ('a'-1);
}
if (releaseEvent)
vmkeyboard->keyReleased(key->keysym.sym);
else
vmkeyboard->keyDepressed(key->keysym.sym);
return;
}
// delete key
if (key->keysym.sym == 8) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_DEL);
else
vmkeyboard->keyDepressed(PK_DEL);
return;
}
//modifier handling
if (key->keysym.sym == SDLK_CAPSLOCK) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_LOCK);
else
vmkeyboard->keyDepressed(PK_LOCK);
}
if (key->keysym.sym == SDLK_LSHIFT ||
key->keysym.sym == SDLK_RSHIFT) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_LSHFT);
else
vmkeyboard->keyDepressed(PK_LSHFT);
}
// arrows
if (key->keysym.sym == SDLK_LEFT) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_LARR);
else
vmkeyboard->keyDepressed(PK_LARR);
}
if (key->keysym.sym == SDLK_RIGHT) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_RARR);
else
vmkeyboard->keyDepressed(PK_RARR);
}
if (key->keysym.sym == SDLK_LEFT) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_LARR);
else
vmkeyboard->keyDepressed(PK_LARR);
}
if (key->keysym.sym == SDLK_UP) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_UARR);
else
vmkeyboard->keyDepressed(PK_UARR);
}
if (key->keysym.sym == SDLK_DOWN) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_DARR);
else
vmkeyboard->keyDepressed(PK_DARR);
}
// Paddles
if (key->keysym.sym == SDLK_LGUI) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_LA);
else
vmkeyboard->keyDepressed(PK_LA);
}
if (key->keysym.sym == SDLK_RGUI) {
if (releaseEvent)
vmkeyboard->keyReleased(PK_RA);
else
vmkeyboard->keyDepressed(PK_RA);
}
}
void SDLKeyboard::maintainKeyboard()
{
SDL_Event event;
if (SDL_PollEvent( &event )) {
// Handle keydown/keyup (and quit, incidentally)
switch (event.type) {
case SDL_KEYDOWN:
case SDL_KEYUP:
// Don't handle repeats; we have our own repeat code
if (event.key.repeat == 0)
handleKeypress(&event.key);
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
((SDLMouse *)g_mouse)->mouseButtonEvent(event.type == SDL_MOUSEBUTTONDOWN);
break;
case SDL_MOUSEMOTION:
// We are handling the SDL input loop, so need to pass this off to the paddles. :/
// FIXME: nasty rooting around in other objects and typecasting.
// FIXME: event.motion.state & SDL_BUTTON_LMASK, et al?
((SDLPaddles *)g_paddles)->gotMouseMovement(event.motion.x, event.motion.y);
((SDLMouse *)g_mouse)->gotMouseEvent(event.motion.state, // button
event.motion.xrel, event.motion.yrel);
break;
// FIXME: this really doesn't belong here. The mouse kinda
// didn't belong here, but this REALLY is wrong.
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
((SDLDisplay *)g_display)->windowResized(event.window.data1, event.window.data2);
}
break;
case SDL_QUIT:
exit(0);
}
}
}
bool hasKeyPending;
uint8_t keyPending;
bool SDLKeyboard::kbhit()
{
SDL_Event event;
if (SDL_PollEvent( &event )) {
if (event.type == SDL_QUIT) {
exit(0);
}
if (event.type == SDL_MOUSEMOTION) {
// We are handling the SDL input loop, so need to pass this off to the paddles. :/
// FIXME: nasty rooting around in other objects and typecasting.
// FIXME: event.motion.state & SDL_BUTTON_LMASK, et al?
((SDLPaddles *)g_paddles)->gotMouseMovement(event.motion.x, event.motion.y);
((SDLMouse *)g_mouse)->gotMouseEvent(event.motion.state, // button
event.motion.xrel, event.motion.yrel);
} else if (event.type == SDL_KEYDOWN) {
SDL_KeyboardEvent *key = &event.key;
if ( (key->keysym.sym >= 'a' && key->keysym.sym <= 'z') ||
(key->keysym.sym >= '0' && key->keysym.sym <= '9') ||
key->keysym.sym == '-' ||
key->keysym.sym == '=' ||
key->keysym.sym == '[' ||
key->keysym.sym == '`' ||
key->keysym.sym == ']' ||
key->keysym.sym == '\\' ||
key->keysym.sym == ';' ||
key->keysym.sym == '\'' ||
key->keysym.sym == ',' ||
key->keysym.sym == '.' ||
key->keysym.sym == '/' ||
key->keysym.sym == ' ' ||
key->keysym.sym == 27 || // ESC
key->keysym.sym == 13 || // return
key->keysym.sym == 9) { // tab
keyPending = key->keysym.sym;
hasKeyPending = true;
} else {
switch (key->keysym.sym) {
case SDLK_UP:
keyPending = PK_UARR;
hasKeyPending = true;
break;
case SDLK_DOWN:
keyPending = PK_DARR;
hasKeyPending = true;
break;
case SDLK_RIGHT:
keyPending = PK_RARR;
hasKeyPending = true;
break;
case SDLK_LEFT:
keyPending = PK_LARR;
hasKeyPending = true;
break;
}
}
}
}
return hasKeyPending;
}
int8_t SDLKeyboard::read()
{
// Meh
hasKeyPending = false;
return keyPending;
}