diff --git a/Makefile.common b/Makefile.common index bdceae0169..8be45a85e3 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1273,7 +1273,7 @@ endif ifneq ($(findstring DOS,$(OS)),) OBJ += gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o \ input/drivers/dos_input.o input/drivers_joypad/dos_joypad.o \ - frontend/drivers/platform_dos.o + frontend/drivers/platform_dos.o input/drivers_keyboard/keyboard_event_dos.o ifeq ($(HAVE_MENU_COMMON), 1) OBJ += menu/drivers_display/menu_display_vga.o diff --git a/input/drivers/dos_input.c b/input/drivers/dos_input.c index e9b65ad98d..b73f0f73ab 100644 --- a/input/drivers/dos_input.c +++ b/input/drivers/dos_input.c @@ -14,16 +14,17 @@ * If not, see . */ +#include #include #include "../input_driver.h" +#include "../input_keymaps.h" #include "../input_joypad_driver.h" +#include "../drivers_keyboard/keyboard_event_dos.h" typedef struct dos_input { const input_device_driver_t *joypad; - unsigned char normal_keys[256]; - unsigned char extended_keys[256]; } dos_input_t; static void dos_input_poll(void *data) @@ -48,7 +49,10 @@ static int16_t dos_input_state(void *data, switch (device) { case RETRO_DEVICE_JOYPAD: - return input_joypad_pressed(dos->joypad, joypad_info, port, binds[port], id); + return input_joypad_pressed(dos->joypad, joypad_info, port, binds[port], id) || + dos_keyboard_port_input_pressed(binds[port], id); + case RETRO_DEVICE_KEYBOARD: + return dos_keyboard_port_input_pressed(binds[port], id); } return 0; @@ -61,6 +65,8 @@ static void dos_input_free_input(void *data) if (dos && dos->joypad) dos->joypad->destroy(); + dos_keyboard_free(); + if (data) free(data); } @@ -72,8 +78,12 @@ static void* dos_input_init(const char *joypad_driver) if (!dos) return NULL; + dos_keyboard_free(); + dos->joypad = input_joypad_init_driver(joypad_driver, dos); + input_keymaps_init_keyboard_lut(rarch_key_map_dos); + return dos; } @@ -87,7 +97,6 @@ static uint64_t dos_input_get_capabilities(void *data) uint64_t caps = 0; caps |= UINT64_C(1) << RETRO_DEVICE_JOYPAD; - caps |= UINT64_C(1) << RETRO_DEVICE_KEYBOARD; return caps; } diff --git a/input/drivers_joypad/dos_joypad.c b/input/drivers_joypad/dos_joypad.c index 05f07b766d..686db8238e 100644 --- a/input/drivers_joypad/dos_joypad.c +++ b/input/drivers_joypad/dos_joypad.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -30,19 +29,17 @@ #include "../input_joypad_driver.h" #include "../input_driver.h" #include "../input_config.h" +#include "../input_keyboard.h" +#include "../input_keymaps.h" #include "../../tasks/tasks_internal.h" - -#define MAX_PADS 1 +#include "../drivers_keyboard/keyboard_event_dos.h" #define END_FUNC(x) static void x##_End() { } #define LOCK_VAR(x) LockData((void*)&x, sizeof(x)) #define LOCK_FUNC(x) LockCode(x, (int)x##_End - (int)x) -static uint64_t dos_key_state[MAX_PADS]; - -static unsigned char normal_keys[256]; -static unsigned char extended_keys[256]; +static uint16_t normal_keys[LAST_KEYCODE + 1]; static _go32_dpmi_seginfo old_kbd_int; static _go32_dpmi_seginfo kbd_int; @@ -85,7 +82,7 @@ int LockCode(void *a, int size) static void keyb_int(void) { - static unsigned char buffer; + static unsigned char buffer = 0; unsigned char rawcode; unsigned char make_break; int scancode; @@ -99,14 +96,14 @@ static void keyb_int(void) /* second byte of an extended key */ if (scancode < 0x60) { - extended_keys[scancode] = make_break; + normal_keys[scancode | (1 << 8)] = make_break; } buffer = 0; } else if (buffer >= 0xE1 && buffer <= 0xE2) { - buffer = 0; /* ingore these extended keys */ + buffer = 0; /* ignore these extended keys */ } else if (rawcode >= 0xE0 && rawcode <= 0xE2) { @@ -126,10 +123,10 @@ static void hook_keyb_int(void) _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_int); memset(&kbd_int, 0, sizeof(kbd_int)); + memset(normal_keys, 0, sizeof(normal_keys)); LOCK_FUNC(keyb_int); LOCK_VAR(normal_keys); - LOCK_VAR(extended_keys); kbd_int.pm_selector = _go32_my_cs(); kbd_int.pm_offset = (uint32_t)&keyb_int; @@ -170,8 +167,6 @@ static void dos_joypad_autodetect_add(unsigned autoconf_pad) static bool dos_joypad_init(void *data) { - memset(dos_key_state, 0, sizeof(dos_key_state)); - hook_keyb_int(); dos_joypad_autodetect_add(0); @@ -183,44 +178,64 @@ static bool dos_joypad_init(void *data) static bool dos_joypad_button(unsigned port_num, uint16_t key) { + uint16_t *buf = dos_keyboard_state_get(port_num); + if (port_num >= MAX_PADS) return false; - return (dos_key_state[port_num] & (UINT64_C(1) << key)); -} + switch (key) + { + case RETRO_DEVICE_ID_JOYPAD_A: + return buf[DOSKEY_x]; + case RETRO_DEVICE_ID_JOYPAD_B: + return buf[DOSKEY_z]; + case RETRO_DEVICE_ID_JOYPAD_X: + return buf[DOSKEY_s]; + case RETRO_DEVICE_ID_JOYPAD_Y: + return buf[DOSKEY_a]; + case RETRO_DEVICE_ID_JOYPAD_SELECT: + return buf[DOSKEY_RSHIFT]; + case RETRO_DEVICE_ID_JOYPAD_START: + return buf[DOSKEY_RETURN]; + case RETRO_DEVICE_ID_JOYPAD_UP: + return buf[DOSKEY_UP]; + case RETRO_DEVICE_ID_JOYPAD_DOWN: + return buf[DOSKEY_DOWN]; + case RETRO_DEVICE_ID_JOYPAD_LEFT: + return buf[DOSKEY_LEFT]; + case RETRO_DEVICE_ID_JOYPAD_RIGHT: + return buf[DOSKEY_RIGHT]; + } -static uint64_t dos_joypad_get_buttons(unsigned port_num) -{ - if (port_num >= MAX_PADS) - return 0; - return dos_key_state[port_num]; + return false; } static void dos_joypad_poll(void) { uint32_t i; - for (i = 0; i < MAX_PADS; i++) + for (i = 0; i <= MAX_PADS; i++) { - uint64_t *cur_state = &dos_key_state[i]; + uint16_t *cur_state = dos_keyboard_state_get(i); + uint32_t key; - *cur_state = 0; - *cur_state |= extended_keys[75] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT : 0; - *cur_state |= extended_keys[77] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT : 0; - *cur_state |= extended_keys[72] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP : 0; - *cur_state |= extended_keys[80] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN : 0; - *cur_state |= normal_keys[28] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START : 0; /* ENTER */ - *cur_state |= normal_keys[54] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT : 0; /* RSHIFT */ - *cur_state |= normal_keys[44] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B : 0; /* Z */ - *cur_state |= normal_keys[45] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A : 0; /* X */ - *cur_state |= normal_keys[30] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y : 0; /* A */ - *cur_state |= normal_keys[31] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X : 0; /* S */ + for (key = 0; key < LAST_KEYCODE; key++) + { + if (cur_state[key] != normal_keys[key]) + { + unsigned code = input_keymaps_translate_keysym_to_rk(key); + + input_keyboard_event(normal_keys[key], code, code, 0, RETRO_DEVICE_KEYBOARD); + } + } + + memcpy(cur_state, normal_keys, sizeof(normal_keys)); } } static bool dos_joypad_query_pad(unsigned pad) { - return pad < MAX_USERS && dos_key_state[pad]; + return (pad < MAX_USERS); } static int16_t dos_joypad_axis(unsigned port_num, uint32_t joyaxis) @@ -238,7 +253,7 @@ input_device_driver_t dos_joypad = { dos_joypad_query_pad, dos_joypad_destroy, dos_joypad_button, - dos_joypad_get_buttons, + NULL, dos_joypad_axis, dos_joypad_poll, NULL, diff --git a/input/drivers_keyboard/keyboard_event_dos.c b/input/drivers_keyboard/keyboard_event_dos.c new file mode 100644 index 0000000000..f7f8f373ef --- /dev/null +++ b/input/drivers_keyboard/keyboard_event_dos.c @@ -0,0 +1,56 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +#include "keyboard_event_dos.h" +#include "../input_keymaps.h" + +#define MAX_KEYS LAST_KEYCODE + 1 + +// First ports are used to keeping track of gamepad states. Last port is used for keyboard state +static uint16_t dos_key_state[MAX_PADS+1][MAX_KEYS]; + +bool dos_keyboard_port_input_pressed(const struct retro_keybind *binds, unsigned id) +{ + if (id < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[id]; + unsigned key = input_keymaps_translate_rk_to_keysym(bind->key); + return dos_key_state[DOS_KEYBOARD_PORT][key]; + } + return false; +} + +bool dos_keyboard_input_pressed(unsigned key) +{ + unsigned keysym = input_keymaps_translate_rk_to_keysym(key); + return dos_key_state[DOS_KEYBOARD_PORT][keysym]; +} + +uint16_t *dos_keyboard_state_get(unsigned port) +{ + return dos_key_state[port]; +} + +void dos_keyboard_free(void) +{ + unsigned i, j; + + for (i = 0; i < MAX_PADS; i++) + for (j = 0; j < MAX_KEYS; j++) + dos_key_state[i][j] = 0; +} diff --git a/input/drivers_keyboard/keyboard_event_dos.h b/input/drivers_keyboard/keyboard_event_dos.h new file mode 100644 index 0000000000..0cecb85576 --- /dev/null +++ b/input/drivers_keyboard/keyboard_event_dos.h @@ -0,0 +1,137 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef _KEYBOARD_EVENT_DOS_H +#define _KEYBOARD_EVENT_DOS_H + +#include "../input_driver.h" + +/* + * Key codes. + */ +enum { + DOSKEY_ESCAPE = 0x1, + DOSKEY_F1 = 0x3b, + DOSKEY_F2 = 0x3c, + DOSKEY_F3 = 0x3d, + DOSKEY_F4 = 0x3e, + DOSKEY_F5 = 0x3f, + DOSKEY_F6 = 0x40, + DOSKEY_F7 = 0x41, + DOSKEY_F8 = 0x42, + DOSKEY_F9 = 0x43, + DOSKEY_F10 = 0x44, + + DOSKEY_BACKQUOTE = 0x29, + DOSKEY_1 = 0x2, + DOSKEY_2 = 0x3, + DOSKEY_3 = 0x4, + DOSKEY_4 = 0x5, + DOSKEY_5 = 0x6, + DOSKEY_6 = 0x7, + DOSKEY_7 = 0x8, + DOSKEY_8 = 0x9, + DOSKEY_9 = 0xa, + DOSKEY_0 = 0xb, + DOSKEY_MINUS = 0xc, + DOSKEY_EQUAL = 0xd, + DOSKEY_BACKSPACE = 0xe, + + DOSKEY_TAB = 0xf, + DOSKEY_q = 0x10, + DOSKEY_w = 0x11, + DOSKEY_e = 0x12, + DOSKEY_r = 0x13, + DOSKEY_t = 0x14, + DOSKEY_y = 0x15, + DOSKEY_u = 0x16, + DOSKEY_i = 0x17, + DOSKEY_o = 0x18, + DOSKEY_p = 0x19, + DOSKEY_LBRACKET = 0x1a, + DOSKEY_RBRACKET = 0x1b, + DOSKEY_BACKSLASH = 0x2b, + + DOSKEY_CAPSLOCK = 0x3a, + DOSKEY_a = 0x1e, + DOSKEY_s = 0x1f, + DOSKEY_d = 0x20, + DOSKEY_f = 0x21, + DOSKEY_g = 0x22, + DOSKEY_h = 0x23, + DOSKEY_j = 0x24, + DOSKEY_k = 0x25, + DOSKEY_l = 0x26, + DOSKEY_SEMICOLON = 0x27, + DOSKEY_QUOTE = 0x28, + DOSKEY_RETURN = 0x1c, + + DOSKEY_LSHIFT = 0x2a, + DOSKEY_z = 0x2c, + DOSKEY_x = 0x2d, + DOSKEY_c = 0x2e, + DOSKEY_v = 0x2f, + DOSKEY_b = 0x30, + DOSKEY_n = 0x31, + DOSKEY_m = 0x32, + DOSKEY_COMMA = 0x33, + DOSKEY_PERIOD = 0x34, + DOSKEY_SLASH = 0x35, + DOSKEY_RSHIFT = 0x36, + + DOSKEY_LCTRL = 0x1d, + DOSKEY_LSUPER = 0x15b, + DOSKEY_LALT = 0x38, + DOSKEY_SPACE = 0x39, + DOSKEY_RALT = 0x138, + DOSKEY_RSUPER = 0x15c, + DOSKEY_MENU = 0x15d, + DOSKEY_RCTRL = 0x11d, + + DOSKEY_UP = 0x148, + DOSKEY_DOWN = 0x150, + DOSKEY_LEFT = 0x14b, + DOSKEY_RIGHT = 0x14d, + + DOSKEY_HOME = 0x147, + DOSKEY_END = 0x14f, + DOSKEY_PGUP = 0x149, + DOSKEY_PGDN = 0x151, +}; + +#include + +#include + +#define LAST_KEYCODE 0x1ff + +#ifndef MAX_PADS +#define MAX_PADS 1 +#endif + +#define DOS_KEYBOARD_PORT MAX_PADS + +bool dos_keyboard_port_input_pressed(const struct retro_keybind *binds, unsigned id); + +bool dos_keyboard_input_pressed(unsigned key); + +uint16_t *dos_keyboard_state_get(unsigned port); + +void dos_keyboard_init(void); + +void dos_keyboard_free(void); + +#endif diff --git a/input/input_keymaps.c b/input/input_keymaps.c index a6317b254f..eb5566b851 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -32,6 +32,10 @@ #include "drivers_keyboard/keyboard_event_android.h" #endif +#ifdef DJGPP +#include "drivers_keyboard/keyboard_event_dos.h" +#endif + #ifdef __QNX__ #include #endif @@ -1311,6 +1315,100 @@ const struct rarch_key_map rarch_key_map_apple_hid[] = { }; #endif +#ifdef DJGPP +const struct rarch_key_map rarch_key_map_dos[] = { + { DOSKEY_ESCAPE, RETROK_ESCAPE }, + { DOSKEY_F1, RETROK_F1 }, + { DOSKEY_F2, RETROK_F2 }, + { DOSKEY_F3, RETROK_F3 }, + { DOSKEY_F4, RETROK_F4 }, + { DOSKEY_F5, RETROK_F5 }, + { DOSKEY_F6, RETROK_F6 }, + { DOSKEY_F7, RETROK_F7 }, + { DOSKEY_F8, RETROK_F8 }, + { DOSKEY_F9, RETROK_F9 }, + { DOSKEY_F10, RETROK_F10 }, + + { DOSKEY_BACKQUOTE, RETROK_BACKQUOTE }, + { DOSKEY_1, RETROK_1 }, + { DOSKEY_2, RETROK_2 }, + { DOSKEY_3, RETROK_3 }, + { DOSKEY_4, RETROK_4 }, + { DOSKEY_5, RETROK_5 }, + { DOSKEY_6, RETROK_6 }, + { DOSKEY_7, RETROK_7 }, + { DOSKEY_8, RETROK_8 }, + { DOSKEY_9, RETROK_9 }, + { DOSKEY_0, RETROK_0 }, + { DOSKEY_MINUS, RETROK_MINUS }, + { DOSKEY_EQUAL, RETROK_EQUALS }, + { DOSKEY_BACKSPACE, RETROK_BACKSPACE }, + + { DOSKEY_TAB, RETROK_TAB }, + { DOSKEY_q, RETROK_q }, + { DOSKEY_w, RETROK_w }, + { DOSKEY_e, RETROK_e }, + { DOSKEY_r, RETROK_r }, + { DOSKEY_t, RETROK_t }, + { DOSKEY_y, RETROK_y }, + { DOSKEY_u, RETROK_u }, + { DOSKEY_i, RETROK_i }, + { DOSKEY_o, RETROK_o }, + { DOSKEY_p, RETROK_p }, + { DOSKEY_LBRACKET, RETROK_LEFTBRACKET }, + { DOSKEY_RBRACKET, RETROK_RIGHTBRACKET }, + { DOSKEY_BACKSLASH, RETROK_BACKSLASH }, + + { DOSKEY_CAPSLOCK, RETROK_CAPSLOCK }, + { DOSKEY_a, RETROK_a }, + { DOSKEY_s, RETROK_s }, + { DOSKEY_d, RETROK_d }, + { DOSKEY_f, RETROK_f }, + { DOSKEY_g, RETROK_g }, + { DOSKEY_h, RETROK_h }, + { DOSKEY_j, RETROK_j }, + { DOSKEY_k, RETROK_k }, + { DOSKEY_l, RETROK_l }, + { DOSKEY_SEMICOLON, RETROK_SEMICOLON }, + { DOSKEY_QUOTE, RETROK_QUOTE }, + { DOSKEY_RETURN, RETROK_RETURN }, + + { DOSKEY_LSHIFT, RETROK_LSHIFT }, + { DOSKEY_z, RETROK_z }, + { DOSKEY_x, RETROK_x }, + { DOSKEY_c, RETROK_c }, + { DOSKEY_v, RETROK_v }, + { DOSKEY_b, RETROK_b }, + { DOSKEY_n, RETROK_n }, + { DOSKEY_m, RETROK_m }, + { DOSKEY_COMMA, RETROK_COMMA }, + { DOSKEY_PERIOD, RETROK_PERIOD }, + { DOSKEY_SLASH, RETROK_SLASH }, + { DOSKEY_RSHIFT, RETROK_RSHIFT }, + + { DOSKEY_LCTRL, RETROK_LCTRL }, + { DOSKEY_LSUPER, RETROK_LSUPER }, + { DOSKEY_LALT, RETROK_LALT }, + { DOSKEY_SPACE, RETROK_SPACE }, + { DOSKEY_RALT, RETROK_RALT }, + { DOSKEY_RSUPER, RETROK_RSUPER }, + { DOSKEY_MENU, RETROK_MENU }, + { DOSKEY_RCTRL, RETROK_RCTRL }, + + { DOSKEY_UP, RETROK_UP }, + { DOSKEY_DOWN, RETROK_DOWN }, + { DOSKEY_LEFT, RETROK_LEFT }, + { DOSKEY_RIGHT, RETROK_RIGHT }, + + { DOSKEY_HOME, RETROK_HOME }, + { DOSKEY_END, RETROK_END }, + { DOSKEY_PGUP, RETROK_PAGEUP }, + { DOSKEY_PGDN, RETROK_PAGEDOWN }, + + { 0, RETROK_UNKNOWN } +}; +#endif + static enum retro_key rarch_keysym_lut[RETROK_LAST]; /** diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 4e7b5dab32..6d7fc99892 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -57,6 +57,7 @@ extern const struct rarch_key_map rarch_key_map_linux[]; extern const struct rarch_key_map rarch_key_map_apple_hid[]; extern const struct rarch_key_map rarch_key_map_android[]; extern const struct rarch_key_map rarch_key_map_qnx[]; +extern const struct rarch_key_map rarch_key_map_dos[]; /** * input_keymaps_init_keyboard_lut: