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: