From f7f54f0d047f04191431631ceaf44acfe83217da Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Fri, 6 Aug 2021 23:38:46 +0100 Subject: [PATCH] Implement keyboard input on RISC OS Partially based on a patch from http://www.riscos.info/websvn/listing.php?repname=gccsdk&path=%2Ftrunk%2Fautobuilder%2Flibraries%2Fsdl%2Flibsdl2%2F&rev=7174#a6401c766f408f1ea356e6977894cc6a5 Currently lacks support for mapping scancodes to keycodes. --- src/video/riscos/SDL_riscosevents.c | 108 +++++++++++++++++- src/video/riscos/SDL_riscosevents_c.h | 2 + src/video/riscos/SDL_riscosvideo.c | 17 +++ src/video/riscos/SDL_riscosvideo.h | 7 ++ src/video/riscos/scancodes_riscos.h | 158 ++++++++++++++++++++++++++ 5 files changed, 288 insertions(+), 4 deletions(-) create mode 100644 src/video/riscos/scancodes_riscos.h diff --git a/src/video/riscos/SDL_riscosevents.c b/src/video/riscos/SDL_riscosevents.c index 3c428f51e..b571d759b 100644 --- a/src/video/riscos/SDL_riscosevents.c +++ b/src/video/riscos/SDL_riscosevents.c @@ -22,18 +22,118 @@ #if SDL_VIDEO_DRIVER_RISCOS -/* Being a null driver, there's no event stream. We just define stubs for - most of the API. */ - #include "../../events/SDL_events_c.h" +#include "SDL_log.h" #include "SDL_riscosvideo.h" #include "SDL_riscosevents_c.h" +#include "scancodes_riscos.h" + +#include + +static SDL_Scancode +SDL_RISCOS_translate_keycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (keycode < SDL_arraysize(riscos_scancode_table)) { + scancode = riscos_scancode_table[keycode]; + + if (scancode == SDL_SCANCODE_UNKNOWN) { + SDL_Log("The key you just pressed is not recognized by SDL: %d", keycode); + } + } + + return scancode; +} + +void +RISCOS_PollKeyboard(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + Uint8 key = 2; + int i; + + /* Check for key releases */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] != 255) { + if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i])); + driverdata->key_pressed[i] = 255; + } + } + } + + /* Check for key presses */ + while (key < 0xff) { + SDL_bool already_pressed = SDL_FALSE; + key = _kernel_osbyte(121, key + 1, 0) & 0xff; + switch (key) { + case 255: + /* Ignore mouse keys */ + case 9: + case 10: + case 11: + /* Ignore keys with multiple INKEY codes */ + case 24: + case 40: + case 71: + case 87: + break; + + default: + /* Do we already know of this key? */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] == key) { + already_pressed = SDL_TRUE; + break; + } + } + + if (!already_pressed) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key)); + /* Record the press so we can detect release later. */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] == 255) { + driverdata->key_pressed[i] = key; + break; + } + } + } + } + } +} + +int +RISCOS_InitEvents(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; + int i, status; + + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) + driverdata->key_pressed[i] = 255; + + status = (_kernel_osbyte(202, 0, 255) & 0xFF); + SDL_ToggleModState(KMOD_NUM, (status & (1 << 2)) == 0); + SDL_ToggleModState(KMOD_CAPS, (status & (1 << 4)) == 0); + + /* Disable escape. */ + _kernel_osbyte(229, 1, 0); + + return 0; +} void RISCOS_PumpEvents(_THIS) { - /* do nothing. */ + RISCOS_PollKeyboard(_this); +} + +void +RISCOS_QuitEvents(_THIS) +{ + /* Re-enable escape. */ + _kernel_osbyte(229, 0, 0); } #endif /* SDL_VIDEO_DRIVER_RISCOS */ diff --git a/src/video/riscos/SDL_riscosevents_c.h b/src/video/riscos/SDL_riscosevents_c.h index 373bb724e..204ee34f4 100644 --- a/src/video/riscos/SDL_riscosevents_c.h +++ b/src/video/riscos/SDL_riscosevents_c.h @@ -26,7 +26,9 @@ #include "SDL_riscosvideo.h" +extern int RISCOS_InitEvents(_THIS); extern void RISCOS_PumpEvents(_THIS); +extern void RISCOS_QuitEvents(_THIS); #endif /* SDL_riscosevents_c_h_ */ diff --git a/src/video/riscos/SDL_riscosvideo.c b/src/video/riscos/SDL_riscosvideo.c index 5907944af..5b481e60d 100644 --- a/src/video/riscos/SDL_riscosvideo.c +++ b/src/video/riscos/SDL_riscosvideo.c @@ -45,6 +45,7 @@ static void RISCOS_VideoQuit(_THIS); static void RISCOS_DeleteDevice(SDL_VideoDevice * device) { + SDL_free(device->driverdata); SDL_free(device); } @@ -52,6 +53,7 @@ static SDL_VideoDevice * RISCOS_CreateDevice(int devindex) { SDL_VideoDevice *device; + SDL_VideoData *phdata; /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); @@ -60,6 +62,16 @@ RISCOS_CreateDevice(int devindex) return (0); } + /* Initialize internal data */ + phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + if (phdata == NULL) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + + device->driverdata = phdata; + /* Set the function pointers */ device->VideoInit = RISCOS_VideoInit; device->VideoQuit = RISCOS_VideoQuit; @@ -89,6 +101,10 @@ VideoBootStrap RISCOS_bootstrap = { static int RISCOS_VideoInit(_THIS) { + if (RISCOS_InitEvents(_this) < 0) { + return -1; + } + if (RISCOS_InitModes(_this) < 0) { return -1; } @@ -100,6 +116,7 @@ RISCOS_VideoInit(_THIS) static void RISCOS_VideoQuit(_THIS) { + RISCOS_QuitEvents(_this); } #endif /* SDL_VIDEO_DRIVER_RISCOS */ diff --git a/src/video/riscos/SDL_riscosvideo.h b/src/video/riscos/SDL_riscosvideo.h index 5bf4b144c..7be93afc3 100644 --- a/src/video/riscos/SDL_riscosvideo.h +++ b/src/video/riscos/SDL_riscosvideo.h @@ -25,6 +25,13 @@ #include "../SDL_sysvideo.h" +#define RISCOS_MAX_KEYS_PRESSED 6 + +typedef struct SDL_VideoData +{ + Uint8 key_pressed[RISCOS_MAX_KEYS_PRESSED]; +} SDL_VideoData; + #endif /* SDL_riscosvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/scancodes_riscos.h b/src/video/riscos/scancodes_riscos.h new file mode 100644 index 000000000..23d77e2e9 --- /dev/null +++ b/src/video/riscos/scancodes_riscos.h @@ -0,0 +1,158 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_scancode.h" + +/* RISC OS key code to SDL_Keycode mapping table + Sources: + - https://www.riscosopen.org/wiki/documentation/show/Keyboard Scan Codes +*/ +/* *INDENT-OFF* */ +static SDL_Scancode const riscos_scancode_table[] = { + /* 0 */ SDL_SCANCODE_UNKNOWN, /* Shift */ + /* 1 */ SDL_SCANCODE_UNKNOWN, /* Ctrl */ + /* 2 */ SDL_SCANCODE_UNKNOWN, /* Alt */ + /* 3 */ SDL_SCANCODE_LSHIFT, + /* 4 */ SDL_SCANCODE_LCTRL, + /* 5 */ SDL_SCANCODE_LALT, + /* 6 */ SDL_SCANCODE_RSHIFT, + /* 7 */ SDL_SCANCODE_RCTRL, + /* 8 */ SDL_SCANCODE_RALT, + /* 9 */ SDL_SCANCODE_UNKNOWN, /* Left mouse */ + /* 10 */ SDL_SCANCODE_UNKNOWN, /* Center mouse */ + /* 11 */ SDL_SCANCODE_UNKNOWN, /* Right mouse */ + /* 12 */ SDL_SCANCODE_UNKNOWN, + /* 13 */ SDL_SCANCODE_UNKNOWN, + /* 14 */ SDL_SCANCODE_UNKNOWN, + /* 15 */ SDL_SCANCODE_UNKNOWN, + /* 16 */ SDL_SCANCODE_Q, + /* 17 */ SDL_SCANCODE_3, + /* 18 */ SDL_SCANCODE_4, + /* 19 */ SDL_SCANCODE_5, + /* 20 */ SDL_SCANCODE_F4, + /* 21 */ SDL_SCANCODE_8, + /* 22 */ SDL_SCANCODE_F7, + /* 23 */ SDL_SCANCODE_MINUS, + /* 24 */ SDL_SCANCODE_6, /* Duplicate of 52 */ + /* 25 */ SDL_SCANCODE_LEFT, + /* 26 */ SDL_SCANCODE_KP_6, + /* 27 */ SDL_SCANCODE_KP_7, + /* 28 */ SDL_SCANCODE_F11, + /* 29 */ SDL_SCANCODE_F12, + /* 30 */ SDL_SCANCODE_F10, + /* 31 */ SDL_SCANCODE_SCROLLLOCK, + /* 32 */ SDL_SCANCODE_PRINTSCREEN, + /* 33 */ SDL_SCANCODE_W, + /* 34 */ SDL_SCANCODE_E, + /* 35 */ SDL_SCANCODE_T, + /* 36 */ SDL_SCANCODE_7, + /* 37 */ SDL_SCANCODE_I, + /* 38 */ SDL_SCANCODE_9, + /* 39 */ SDL_SCANCODE_0, + /* 40 */ SDL_SCANCODE_MINUS, /* Duplicate of 23 */ + /* 41 */ SDL_SCANCODE_DOWN, + /* 42 */ SDL_SCANCODE_KP_8, + /* 43 */ SDL_SCANCODE_KP_9, + /* 44 */ SDL_SCANCODE_PAUSE, + /* 45 */ SDL_SCANCODE_GRAVE, + /* 46 */ SDL_SCANCODE_CURRENCYUNIT, + /* 47 */ SDL_SCANCODE_BACKSPACE, + /* 48 */ SDL_SCANCODE_1, + /* 49 */ SDL_SCANCODE_2, + /* 50 */ SDL_SCANCODE_D, + /* 51 */ SDL_SCANCODE_R, + /* 52 */ SDL_SCANCODE_6, + /* 53 */ SDL_SCANCODE_U, + /* 54 */ SDL_SCANCODE_O, + /* 55 */ SDL_SCANCODE_P, + /* 56 */ SDL_SCANCODE_LEFTBRACKET, + /* 57 */ SDL_SCANCODE_UP, + /* 58 */ SDL_SCANCODE_KP_PLUS, + /* 59 */ SDL_SCANCODE_KP_MINUS, + /* 60 */ SDL_SCANCODE_KP_ENTER, + /* 61 */ SDL_SCANCODE_INSERT, + /* 62 */ SDL_SCANCODE_HOME, + /* 63 */ SDL_SCANCODE_PAGEUP, + /* 64 */ SDL_SCANCODE_CAPSLOCK, + /* 65 */ SDL_SCANCODE_A, + /* 66 */ SDL_SCANCODE_X, + /* 67 */ SDL_SCANCODE_F, + /* 68 */ SDL_SCANCODE_Y, + /* 69 */ SDL_SCANCODE_J, + /* 70 */ SDL_SCANCODE_K, + /* 71 */ SDL_SCANCODE_2, /* Duplicate of 49 */ + /* 72 */ SDL_SCANCODE_SEMICOLON, /* Duplicate of 87 */ + /* 73 */ SDL_SCANCODE_RETURN, + /* 74 */ SDL_SCANCODE_KP_DIVIDE, + /* 75 */ SDL_SCANCODE_UNKNOWN, + /* 76 */ SDL_SCANCODE_KP_PERIOD, + /* 77 */ SDL_SCANCODE_NUMLOCKCLEAR, + /* 78 */ SDL_SCANCODE_PAGEDOWN, + /* 79 */ SDL_SCANCODE_APOSTROPHE, + /* 80 */ SDL_SCANCODE_UNKNOWN, + /* 81 */ SDL_SCANCODE_S, + /* 82 */ SDL_SCANCODE_C, + /* 83 */ SDL_SCANCODE_G, + /* 84 */ SDL_SCANCODE_H, + /* 85 */ SDL_SCANCODE_N, + /* 86 */ SDL_SCANCODE_L, + /* 87 */ SDL_SCANCODE_SEMICOLON, + /* 88 */ SDL_SCANCODE_RIGHTBRACKET, + /* 89 */ SDL_SCANCODE_DELETE, + /* 90 */ SDL_SCANCODE_KP_HASH, + /* 91 */ SDL_SCANCODE_KP_MULTIPLY, + /* 92 */ SDL_SCANCODE_UNKNOWN, + /* 93 */ SDL_SCANCODE_EQUALS, + /* 94 */ SDL_SCANCODE_NONUSBACKSLASH, + /* 95 */ SDL_SCANCODE_UNKNOWN, + /* 96 */ SDL_SCANCODE_TAB, + /* 97 */ SDL_SCANCODE_Z, + /* 98 */ SDL_SCANCODE_SPACE, + /* 99 */ SDL_SCANCODE_V, + /* 100 */ SDL_SCANCODE_B, + /* 101 */ SDL_SCANCODE_M, + /* 102 */ SDL_SCANCODE_COMMA, + /* 103 */ SDL_SCANCODE_PERIOD, + /* 104 */ SDL_SCANCODE_SLASH, + /* 105 */ SDL_SCANCODE_END, + /* 106 */ SDL_SCANCODE_KP_0, + /* 107 */ SDL_SCANCODE_KP_1, + /* 108 */ SDL_SCANCODE_KP_3, + /* 109 */ SDL_SCANCODE_UNKNOWN, + /* 110 */ SDL_SCANCODE_UNKNOWN, + /* 111 */ SDL_SCANCODE_UNKNOWN, + /* 112 */ SDL_SCANCODE_ESCAPE, + /* 113 */ SDL_SCANCODE_F1, + /* 114 */ SDL_SCANCODE_F2, + /* 115 */ SDL_SCANCODE_F3, + /* 116 */ SDL_SCANCODE_F5, + /* 117 */ SDL_SCANCODE_F6, + /* 118 */ SDL_SCANCODE_F8, + /* 119 */ SDL_SCANCODE_F9, + /* 120 */ SDL_SCANCODE_BACKSLASH, + /* 121 */ SDL_SCANCODE_RIGHT, + /* 122 */ SDL_SCANCODE_KP_4, + /* 123 */ SDL_SCANCODE_KP_5, + /* 124 */ SDL_SCANCODE_KP_2, + /* 125 */ SDL_SCANCODE_LGUI, + /* 126 */ SDL_SCANCODE_RGUI, + /* 127 */ SDL_SCANCODE_MENU +}; +/* *INDENT-ON* */