1
0
mirror of https://github.com/libretro/RetroArch synced 2025-03-25 16:44:01 +00:00

DOS: initial input/joypad driver

This commit is contained in:
Brad Parker 2017-01-24 00:55:55 -05:00
parent 793c894abb
commit 57949227df
15 changed files with 537 additions and 1 deletions

@ -1272,7 +1272,9 @@ ifeq ($(HAVE_COCOA),1)
endif
ifneq ($(findstring DOS,$(OS)),)
OBJ += gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o
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
ifeq ($(HAVE_MENU_COMMON), 1)
OBJ += menu/drivers_display/menu_display_vga.o

@ -112,6 +112,7 @@ enum input_driver_enum
INPUT_COCOA,
INPUT_QNX,
INPUT_RWEBINPUT,
INPUT_DOS,
INPUT_NULL
};
@ -129,6 +130,7 @@ enum joypad_driver_enum
JOYPAD_LINUXRAW,
JOYPAD_ANDROID,
JOYPAD_SDL,
JOYPAD_DOS,
JOYPAD_HID,
JOYPAD_QNX,
JOYPAD_NULL
@ -320,6 +322,8 @@ enum record_driver_enum
#define INPUT_DEFAULT_DRIVER INPUT_SDL
#elif defined(HAVE_SDL2)
#define INPUT_DEFAULT_DRIVER INPUT_SDL2
#elif defined(DJGPP)
#define INPUT_DEFAULT_DRIVER INPUT_DOS
#else
#define INPUT_DEFAULT_DRIVER INPUT_NULL
#endif
@ -348,6 +352,8 @@ enum record_driver_enum
#define JOYPAD_DEFAULT_DRIVER JOYPAD_ANDROID
#elif defined(HAVE_SDL) || defined(HAVE_SDL2)
#define JOYPAD_DEFAULT_DRIVER JOYPAD_SDL
#elif defined(DJGPP)
#define JOYPAD_DEFAULT_DRIVER JOYPAD_DOS
#elif defined(HAVE_HID)
#define JOYPAD_DEFAULT_DRIVER JOYPAD_HID
#elif defined(__QNX__)

@ -376,6 +376,8 @@ const char *config_get_default_input(void)
return "qnx_input";
case INPUT_RWEBINPUT:
return "rwebinput";
case INPUT_DOS:
return "dos";
case INPUT_NULL:
break;
}
@ -432,6 +434,8 @@ const char *config_get_default_joypad(void)
return "hid";
case JOYPAD_QNX:
return "qnx";
case JOYPAD_DOS:
return "dos";
case JOYPAD_NULL:
break;
}

@ -0,0 +1,72 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdio.h>
#include "../frontend_driver.h"
static void frontend_dos_init(void *data)
{
printf("Loading RetroArch...\n");
}
static void frontend_dos_shutdown(bool unused)
{
(void)unused;
}
static int frontend_dos_get_rating(void)
{
return -1;
}
enum frontend_architecture frontend_dos_get_architecture(void)
{
return FRONTEND_ARCH_X86;
}
static void frontend_dos_get_env_settings(int *argc, char *argv[],
void *data, void *params_data)
{
}
frontend_ctx_driver_t frontend_ctx_dos = {
frontend_dos_get_env_settings,/* environment_get */
frontend_dos_init, /* init */
NULL, /* deinit */
NULL, /* exitspawn */
NULL, /* process_args */
NULL, /* exec */
NULL, /* set_fork */
frontend_dos_shutdown, /* shutdown */
NULL, /* get_name */
NULL, /* get_os */
frontend_dos_get_rating, /* get_rating */
NULL, /* load_content */
frontend_dos_get_architecture,/* get_architecture */
NULL, /* get_powerstate */
NULL, /* parse_drive_list */
NULL, /* get_mem_total */
NULL, /* get_mem_free */
NULL, /* install_signal_handler */
NULL, /* get_sighandler_state */
NULL, /* set_sighandler_state */
NULL, /* destroy_sighandler_state */
NULL, /* attach_console */
NULL, /* detach_console */
"dos",
};

@ -63,6 +63,9 @@ static frontend_ctx_driver_t *frontend_ctx_drivers[] = {
#endif
#ifdef XENON
&frontend_ctx_xenon,
#endif
#ifdef DJGPP
&frontend_ctx_dos,
#endif
&frontend_ctx_null,
NULL

@ -104,6 +104,7 @@ extern frontend_ctx_driver_t frontend_ctx_ctr;
extern frontend_ctx_driver_t frontend_ctx_win32;
extern frontend_ctx_driver_t frontend_ctx_xenon;
extern frontend_ctx_driver_t frontend_ctx_emscripten;
extern frontend_ctx_driver_t frontend_ctx_dos;
extern frontend_ctx_driver_t frontend_ctx_null;
/**

@ -354,6 +354,8 @@ VIDEO DRIVER
#include "../gfx/drivers/ctr_gfx.c"
#elif defined(XENON)
#include "../gfx/drivers/xenon360_gfx.c"
#elif defined(DJGPP)
#include "../gfx/drivers/vga_gfx.c"
#endif
#include "../gfx/drivers/nullgfx.c"
@ -466,6 +468,9 @@ INPUT
#include "../input/drivers_joypad/qnx_joypad.c"
#elif defined(EMSCRIPTEN)
#include "../input/drivers/rwebinput_input.c"
#elif defined(DJGPP)
#include "../input/drivers/dos_input.c"
#include "../input/drivers_joypad/dos_joypad.c"
#endif
#ifdef HAVE_DINPUT
@ -788,6 +793,8 @@ FRONTEND
#include "../frontend/drivers/platform_linux.c"
#elif defined(BSD) && !defined(__MACH__)
#include "../frontend/drivers/platform_bsd.c"
#elif defined(DJGPP)
#include "../frontend/drivers/platform_dos.c"
#endif
#include "../frontend/drivers/platform_null.c"

137
input/drivers/dos_input.c Normal file

@ -0,0 +1,137 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include "../input_driver.h"
#include "../input_joypad_driver.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)
{
dos_input_t *dos = (dos_input_t*)data;
if (dos->joypad)
dos->joypad->poll();
}
static int16_t dos_input_state(void *data,
rarch_joypad_info_t joypad_info,
const struct retro_keybind **binds,
unsigned port, unsigned device,
unsigned idx, unsigned id)
{
dos_input_t *dos = (dos_input_t*)data;
if (port > 0)
return 0;
switch (device)
{
case RETRO_DEVICE_JOYPAD:
return input_joypad_pressed(dos->joypad, joypad_info, port, binds[port], id);
}
return 0;
}
static void dos_input_free_input(void *data)
{
dos_input_t *dos = (dos_input_t*)data;
if (dos && dos->joypad)
dos->joypad->destroy();
if (data)
free(data);
}
static void* dos_input_init(const char *joypad_driver)
{
dos_input_t *dos = (dos_input_t*)calloc(1, sizeof(*dos));
if (!dos)
return NULL;
dos->joypad = input_joypad_init_driver(joypad_driver, dos);
return dos;
}
static bool dos_input_meta_key_pressed(void *data, int key)
{
return false;
}
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;
}
static const input_device_driver_t *dos_input_get_joypad_driver(void *data)
{
dos_input_t *dos = (dos_input_t*)data;
if (dos)
return dos->joypad;
return NULL;
}
static void dos_input_grab_mouse(void *data, bool state)
{
(void)data;
(void)state;
}
static bool dos_input_set_rumble(void *data, unsigned port,
enum retro_rumble_effect effect, uint16_t strength)
{
(void)data;
(void)port;
(void)effect;
(void)strength;
return false;
}
input_driver_t input_dos = {
dos_input_init,
dos_input_poll,
dos_input_state,
dos_input_meta_key_pressed,
dos_input_free_input,
NULL,
NULL,
dos_input_get_capabilities,
"dos",
dos_input_grab_mouse,
NULL,
dos_input_set_rumble,
dos_input_get_joypad_driver,
NULL,
NULL,
NULL
};

@ -184,6 +184,7 @@ static bool ctr_joypad_query_pad(unsigned pad)
static void ctr_joypad_destroy(void)
{
unhook_keyb_int();
}
input_device_driver_t ctr_joypad = {

@ -0,0 +1,268 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#include <pc.h>
#include <dos.h>
#include <go32.h>
#include <dpmi.h>
#include <sys/segments.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libretro.h>
#include "../input_joypad_driver.h"
#include "../input_driver.h"
#include "../input_config.h"
#include "../../tasks/tasks_internal.h"
#define MAX_PADS 1
#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 _go32_dpmi_seginfo old_kbd_int;
static _go32_dpmi_seginfo kbd_int;
int LockData(void *a, int size)
{
uint32_t baseaddr;
__dpmi_meminfo region;
if (__dpmi_get_segment_base_address(_my_ds(), &baseaddr) == -1)
return -1;
region.handle = 0;
region.size = size;
region.address = baseaddr + (uint32_t)a;
if (__dpmi_lock_linear_region(&region) == -1)
return -1;
return 0;
}
int LockCode(void *a, int size)
{
uint32_t baseaddr;
__dpmi_meminfo region;
if (__dpmi_get_segment_base_address(_my_cs(), &baseaddr) == -1)
return (-1);
region.handle = 0;
region.size = size;
region.address = baseaddr + (uint32_t)a;
if (__dpmi_lock_linear_region(&region) == -1)
return (-1);
return 0;
}
static void keyb_int(void)
{
static unsigned char buffer;
unsigned char rawcode;
unsigned char make_break;
int scancode;
rawcode = inp(0x60); /* read scancode from keyboard controller */
make_break = !(rawcode & 0x80); /* bit 7: 0 = make, 1 = break */
scancode = rawcode & 0x7F;
if (buffer == 0xE0)
{
/* second byte of an extended key */
if (scancode < 0x60)
{
extended_keys[scancode] = make_break;
}
buffer = 0;
}
else if (buffer >= 0xE1 && buffer <= 0xE2)
{
buffer = 0; /* ingore these extended keys */
}
else if (rawcode >= 0xE0 && rawcode <= 0xE2)
{
buffer = rawcode; /* first byte of an extended key */
}
else if (scancode < 0x60)
{
normal_keys[scancode] = make_break;
}
outp(0x20, 0x20); /* must send EOI to finish interrupt */
}
END_FUNC(keyb_int)
/*static void free_keyb_buf()
{
*(char*)(0x0040001A) = 0x20;
*(char*)(0x0040001C) = 0x20;
}*/
static void hook_keyb_int(void)
{
_go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_int);
memset(&kbd_int, 0, sizeof(kbd_int));
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;
_go32_dpmi_allocate_iret_wrapper(&kbd_int);
_go32_dpmi_set_protected_mode_interrupt_vector(9, &kbd_int);
}
static void unhook_keyb_int(void)
{
if (old_kbd_int.pm_offset)
{
_go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_int);
_go32_dpmi_free_iret_wrapper(&kbd_int);
memset(&old_kbd_int, 0, sizeof(old_kbd_int));
}
}
static const char *dos_joypad_name(unsigned pad)
{
return "DOS Controller";
}
static void dos_joypad_autodetect_add(unsigned autoconf_pad)
{
if (!input_autoconfigure_connect(
dos_joypad_name(autoconf_pad),
NULL,
dos_joypad.ident,
autoconf_pad,
0,
0
))
input_config_set_device_name(autoconf_pad, dos_joypad_name(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);
(void)data;
return true;
}
static bool dos_joypad_button(unsigned port_num, uint16_t key)
{
if (port_num >= MAX_PADS)
return false;
return (dos_key_state[port_num] & (UINT64_C(1) << key));
}
static uint64_t dos_joypad_get_buttons(unsigned port_num)
{
if (port_num >= MAX_PADS)
return 0;
return dos_key_state[port_num];
}
static void dos_joypad_poll(void)
{
uint32_t i;
for (i = 0; i < MAX_PADS; i++)
{
uint64_t *cur_state = &dos_key_state[i];
*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 */
*cur_state |= normal_keys[1] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X : 0; /* S */
/**cur_state |= pad.b ? RETRO_DEVICE_ID_JOYPAD_A : 0;
*cur_state |= pad.a ? RETRO_DEVICE_ID_JOYPAD_B : 0;
*cur_state |= pad.y ? RETRO_DEVICE_ID_JOYPAD_X : 0;
*cur_state |= pad.x ? RETRO_DEVICE_ID_JOYPAD_Y : 0;
*cur_state |= pad.left ? RETRO_DEVICE_ID_JOYPAD_LEFT : 0;
*cur_state |= pad.right ? RETRO_DEVICE_ID_JOYPAD_RIGHT : 0;
*cur_state |= pad.up ? RETRO_DEVICE_ID_JOYPAD_UP : 0;
*cur_state |= pad.start ? RETRO_DEVICE_ID_JOYPAD_START : 0;
*cur_state |= pad.back ? RETRO_DEVICE_ID_JOYPAD_SELECT : 0;
*cur_state |= pad.lt ? RETRO_DEVICE_ID_JOYPAD_L : 0;
*cur_state |= pad.rt ? RETRO_DEVICE_ID_JOYPAD_R : 0;*/
}
/*free_keyb_buf();*/
}
static bool dos_joypad_query_pad(unsigned pad)
{
return pad < MAX_USERS && dos_key_state[pad];
}
static int16_t dos_joypad_axis(unsigned port_num, uint32_t joyaxis)
{
return 0;
}
static void dos_joypad_destroy(void)
{
unhook_keyb_int();
}
input_device_driver_t dos_joypad = {
dos_joypad_init,
dos_joypad_query_pad,
dos_joypad_destroy,
dos_joypad_button,
dos_joypad_get_buttons,
dos_joypad_axis,
dos_joypad_poll,
NULL,
dos_joypad_name,
"dos",
};

@ -195,6 +195,30 @@ DECL_AXIS(r_x_minus, -2) \
DECL_AXIS(r_y_plus, -3) \
DECL_AXIS(r_y_minus, +3)
#define DOSINPUT_DEFAULT_BINDS \
DECL_BTN(a, 8) \
DECL_BTN(b, 0) \
DECL_BTN(x, 9) \
DECL_BTN(y, 1) \
DECL_BTN(start, 3) \
DECL_BTN(select, 2) \
DECL_BTN(up, 4) \
DECL_BTN(down, 5) \
DECL_BTN(left, 6) \
DECL_BTN(right, 7) \
DECL_BTN(l, 10) \
DECL_BTN(r, 11) \
DECL_BTN(l2, 12) \
DECL_BTN(r2, 13) \
DECL_AXIS(l_x_plus, +0) \
DECL_AXIS(l_x_minus, -0) \
DECL_AXIS(l_y_plus, +1) \
DECL_AXIS(l_y_minus, -1) \
DECL_AXIS(r_x_plus, +2) \
DECL_AXIS(r_x_minus, -2) \
DECL_AXIS(r_y_plus, -3) \
DECL_AXIS(r_y_minus, +3)
#ifdef WIIU
#define WIIUINPUT_GAMEPAD_DEFAULT_BINDS \
@ -503,6 +527,9 @@ const char* const input_builtin_autoconfs[] =
#ifdef _3DS
DECL_AUTOCONF_DEVICE("3DS Controller", "ctr", CTRINPUT_DEFAULT_BINDS),
#endif
#ifdef DJGPP
DECL_AUTOCONF_DEVICE("DOS Controller", "dos", DOSINPUT_DEFAULT_BINDS),
#endif
#ifdef GEKKO
DECL_AUTOCONF_DEVICE("GameCube Controller", "gx", GXINPUT_GAMECUBE_DEFAULT_BINDS),
#ifdef HW_RVL

@ -89,6 +89,9 @@ static const input_driver_t *input_drivers[] = {
#endif
#ifdef EMSCRIPTEN
&input_rwebinput,
#endif
#ifdef DJGPP
&input_dos,
#endif
&input_null,
NULL,

@ -327,6 +327,7 @@ extern input_driver_t input_udev;
extern input_driver_t input_cocoa;
extern input_driver_t input_qnx;
extern input_driver_t input_rwebinput;
extern input_driver_t input_dos;
extern input_driver_t input_null;
RETRO_END_DECLS

@ -78,6 +78,9 @@ static input_device_driver_t *joypad_drivers[] = {
#ifdef HAVE_MFI
&mfi_joypad,
#endif
#ifdef DJGPP
&dos_joypad,
#endif
#ifdef HAVE_HID
&hid_joypad,
#endif

@ -236,6 +236,7 @@ extern input_device_driver_t android_joypad;
extern input_device_driver_t qnx_joypad;
extern input_device_driver_t null_joypad;
extern input_device_driver_t mfi_joypad;
extern input_device_driver_t dos_joypad;
RETRO_END_DECLS