diff --git a/config.def.h b/config.def.h index f57d6897df..9996c43f64 100644 --- a/config.def.h +++ b/config.def.h @@ -60,7 +60,6 @@ //////////////////////// #define INPUT_SDL 7 #define INPUT_X 12 -#define INPUT_DINPUT 16 //////////////////////// #if defined(HAVE_SDL) @@ -99,9 +98,7 @@ #error "Need at least one audio driver!" #endif -#if defined(HAVE_DINPUT) -#define INPUT_DEFAULT_DRIVER INPUT_DINPUT -#elif defined(HAVE_SDL) +#if defined(HAVE_SDL) #define INPUT_DEFAULT_DRIVER INPUT_SDL #elif defined(HAVE_XVIDEO) #define INPUT_DEFAULT_DRIVER INPUT_X diff --git a/driver.c b/driver.c index e3ca32ec47..4cc7518173 100644 --- a/driver.c +++ b/driver.c @@ -81,9 +81,6 @@ static const input_driver_t *input_drivers[] = { #ifdef HAVE_XVIDEO &input_x, #endif -#ifdef HAVE_DINPUT - &input_dinput, -#endif }; static void find_audio_driver(void) diff --git a/driver.h b/driver.h index ebf225ead2..09de73952b 100644 --- a/driver.h +++ b/driver.h @@ -164,7 +164,6 @@ extern const video_driver_t video_sdl; extern const video_driver_t video_ext; extern const input_driver_t input_sdl; extern const input_driver_t input_x; -extern const input_driver_t input_dinput; //////////////////////////////////////////////// #endif diff --git a/input/dinput.c b/input/dinput.c index 7cd092c972..a98497b927 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -23,59 +23,10 @@ #include #include -struct sdl_dinput_map +void sdl_dinput_free(sdl_dinput_t *di) { - int sdl; - int di; -}; - -static const struct sdl_dinput_map key_map[] = { - { SDLK_a, DIK_A }, - { SDLK_b, DIK_B }, - { SDLK_c, DIK_C }, - { SDLK_d, DIK_D }, - { SDLK_e, DIK_E }, - { SDLK_f, DIK_F }, - { SDLK_g, DIK_G }, - { SDLK_h, DIK_H }, - { SDLK_i, DIK_I }, - { SDLK_j, DIK_J }, - { SDLK_k, DIK_K }, - { SDLK_l, DIK_L }, - { SDLK_m, DIK_M }, - { SDLK_n, DIK_N }, - { SDLK_o, DIK_O }, - { SDLK_p, DIK_P }, - { SDLK_q, DIK_Q }, - { SDLK_r, DIK_R }, - { SDLK_s, DIK_S }, - { SDLK_t, DIK_T }, - { SDLK_u, DIK_U }, - { SDLK_v, DIK_V }, - { SDLK_w, DIK_W }, - { SDLK_x, DIK_X }, - { SDLK_y, DIK_Y }, - { SDLK_z, DIK_Z }, - { SDLK_LEFT, DIK_LEFT }, - { SDLK_RIGHT, DIK_RIGHT }, - { SDLK_UP, DIK_UP }, - { SDLK_DOWN, DIK_DOWN }, - { SDLK_ESCAPE, DIK_ESCAPE }, - { SDLK_RETURN, DIK_RETURN }, - { SDLK_BACKSPACE, DIK_BACKSPACE }, -}; - -static void sdl_dinput_free(void *data) -{ - sdl_dinput_t *di = data; if (di) { - if (di->keyboard) - { - IDirectInputDevice8_Unacquire(di->keyboard); - IDirectInputDevice8_Release(di->keyboard); - } - for (unsigned i = 0; i < MAX_PLAYERS; i++) { if (di->joypad[i]) @@ -141,7 +92,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) return DIENUM_CONTINUE; } -static void *sdl_dinput_init(void) +sdl_dinput_t* sdl_dinput_init(void) { sdl_dinput_t *di = calloc(1, sizeof(*di)); if (!di) @@ -165,22 +116,6 @@ static void *sdl_dinput_init(void) goto error; } - if (FAILED(IDirectInput8_CreateDevice(di->ctx, &GUID_SysKeyboard, &di->keyboard, NULL))) - { - SSNES_ERR("Failed to init DirectInput keyboard.\n"); - goto error; - } - - IDirectInputDevice8_SetDataFormat(di->keyboard, &c_dfDIKeyboard); - IDirectInputDevice8_SetCooperativeLevel(di->keyboard, di->hWnd, - DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); - - if (FAILED(IDirectInputDevice8_Acquire(di->keyboard))) - { - SSNES_ERR("Failed to acquire keyboard.\n"); - goto error; - } - IDirectInput8_EnumDevices(di->ctx, DI8DEVCLASS_GAMECTRL, enum_joypad_cb, di, DIEDFL_ATTACHEDONLY); return di; @@ -190,51 +125,7 @@ error: return NULL; } -static void sdl_poll_mouse(sdl_dinput_t *di) -{ - int _x, _y; - Uint8 btn = SDL_GetRelativeMouseState(&_x, &_y); - di->mouse_x = _x; - di->mouse_y = _y; - di->mouse_l = SDL_BUTTON(SDL_BUTTON_LEFT) & btn ? 1 : 0; - di->mouse_r = SDL_BUTTON(SDL_BUTTON_RIGHT) & btn ? 1 : 0; - di->mouse_m = SDL_BUTTON(SDL_BUTTON_MIDDLE) & btn ? 1 : 0; -} - -static void sdl_poll(sdl_dinput_t *di) -{ - SDL_PumpEvents(); - sdl_poll_mouse(di); - - SDL_Event event; - while (SDL_PollEvent(&event)) - { - switch (event.type) - { - case SDL_QUIT: - if (di->quitting) - { - *di->quitting = true; - return; - } - break; - - case SDL_VIDEORESIZE: - if (di->should_resize) - { - *di->new_width = event.resize.w; - *di->new_height = event.resize.h; - *di->should_resize = true; - } - break; - - default: - break; - } - } -} - -static bool dinput_joykey_pressed(sdl_dinput_t *di, int port_num, uint16_t joykey) +static bool dinput_joykey_pressed(sdl_dinput_t *di, unsigned port_num, uint16_t joykey) { if (joykey == NO_BTN) return false; @@ -270,7 +161,7 @@ static bool dinput_joykey_pressed(sdl_dinput_t *di, int port_num, uint16_t joyke } else { - unsigned elems = sizeof(di->joy_state[port_num].rgbButtons) / sizeof(di->joy_state[port_num].rgbButtons[0]); + unsigned elems = sizeof(di->joy_state[0].rgbButtons) / sizeof(di->joy_state[0].rgbButtons[0]); if (joykey < elems) return di->joy_state[port_num].rgbButtons[joykey]; @@ -279,7 +170,7 @@ static bool dinput_joykey_pressed(sdl_dinput_t *di, int port_num, uint16_t joyke return false; } -static bool dinput_joyaxis_pressed(sdl_dinput_t *di, int port_num, uint32_t joyaxis) +static bool dinput_joyaxis_pressed(sdl_dinput_t *di, unsigned port_num, uint32_t joyaxis) { if (joyaxis == AXIS_NONE) return false; @@ -322,83 +213,8 @@ static bool dinput_joyaxis_pressed(sdl_dinput_t *di, int port_num, uint32_t joya return false; } -static int16_t sdl_mouse_device_state(sdl_dinput_t *sdl, bool port, unsigned id) +bool sdl_dinput_pressed(sdl_dinput_t *di, unsigned port_num, const struct snes_keybind *key) { - // Might implement support for joypad mapping later. - (void)port; - switch (id) - { - case SNES_DEVICE_ID_MOUSE_LEFT: - return sdl->mouse_l; - case SNES_DEVICE_ID_MOUSE_RIGHT: - return sdl->mouse_r; - case SNES_DEVICE_ID_MOUSE_X: - return sdl->mouse_x; - case SNES_DEVICE_ID_MOUSE_Y: - return sdl->mouse_y; - default: - return 0; - } -} - -// TODO: Missing some controllers, but hey :) -static int16_t sdl_scope_device_state(sdl_dinput_t *sdl, unsigned id) -{ - switch (id) - { - case SNES_DEVICE_ID_SUPER_SCOPE_X: - return sdl->mouse_x; - case SNES_DEVICE_ID_SUPER_SCOPE_Y: - return sdl->mouse_y; - case SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER: - return sdl->mouse_l; - case SNES_DEVICE_ID_SUPER_SCOPE_CURSOR: - return sdl->mouse_m; - case SNES_DEVICE_ID_SUPER_SCOPE_TURBO: - return sdl->mouse_r; - default: - return 0; - } -} - -// TODO: Support two players. -static int16_t sdl_justifier_device_state(sdl_dinput_t *sdl, unsigned index, unsigned id) -{ - if (index == 0) - { - switch (id) - { - case SNES_DEVICE_ID_JUSTIFIER_X: - return sdl->mouse_x; - case SNES_DEVICE_ID_JUSTIFIER_Y: - return sdl->mouse_y; - case SNES_DEVICE_ID_JUSTIFIER_TRIGGER: - return sdl->mouse_l; - case SNES_DEVICE_ID_JUSTIFIER_START: - return sdl->mouse_r; - default: - return 0; - } - } - else - return 0; -} - -static bool dinput_key_pressed(sdl_dinput_t *di, int key) -{ - for (unsigned i = 0; i < sizeof(key_map) / sizeof(struct sdl_dinput_map); i++) - { - if (key == key_map[i].sdl) - return di->di_state[key_map[i].di] & 0x80; - } - - return false; -} - -static bool dinput_is_pressed(sdl_dinput_t *di, int port_num, const struct snes_keybind *key) -{ - if (dinput_key_pressed(di, key->key)) - return true; if (di->joypad[port_num] == NULL) return false; if (dinput_joykey_pressed(di, port_num, key->joykey)) @@ -409,67 +225,8 @@ static bool dinput_is_pressed(sdl_dinput_t *di, int port_num, const struct snes_ return false; } -static int16_t joypad_device_state(sdl_dinput_t *di, const struct snes_keybind **binds, int port_num, int id) +void sdl_dinput_poll(sdl_dinput_t *di) { - const struct snes_keybind *snes_keybinds = binds[port_num]; - - for (int i = 0; snes_keybinds[i].id != -1; i++) - { - if (snes_keybinds[i].id == id) - return dinput_is_pressed(di, port_num, &snes_keybinds[i]) ? 1 : 0; - } - - return 0; -} - -static bool sdl_dinput_pressed(void *data, int key) -{ - const struct snes_keybind *binds = g_settings.input.binds[0]; - for (int i = 0; binds[i].id != -1; i++) - { - if (binds[i].key == key) - return dinput_is_pressed(data, 0, &binds[i]); - } - return false; -} - -static int16_t sdl_dinput_state(void *data, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id) -{ - switch (device) - { - case SNES_DEVICE_JOYPAD: - return joypad_device_state(data, binds, (port == SNES_PORT_1) ? 0 : 1, id); - case SNES_DEVICE_MULTITAP: - return joypad_device_state(data, binds, (port == SNES_PORT_2) ? 1 + index : 0, id); - - case SNES_DEVICE_MOUSE: - return sdl_mouse_device_state(data, port, id); - case SNES_DEVICE_SUPER_SCOPE: - return sdl_scope_device_state(data, id); - case SNES_DEVICE_JUSTIFIER: - case SNES_DEVICE_JUSTIFIERS: - return sdl_justifier_device_state(data, index, id); - - default: - return 0; - } -} - -static void sdl_dinput_poll(void *data) -{ - sdl_dinput_t *di = data; - - sdl_poll(di); // Poll SDL specific things needed for SDL/GL driver. - - // Keyboard - memset(di->di_state, 0, sizeof(di->di_state)); - if (FAILED(IDirectInputDevice8_GetDeviceState(di->keyboard, sizeof(di->di_state), di->di_state))) - { - IDirectInputDevice8_Acquire(di->keyboard); - if (FAILED(IDirectInputDevice8_GetDeviceState(di->keyboard, sizeof(di->di_state), di->di_state))) - memset(di->di_state, 0, sizeof(di->di_state)); - } - memset(di->joy_state, 0, sizeof(di->joy_state)); for (unsigned i = 0; i < MAX_PLAYERS; i++) { @@ -486,11 +243,3 @@ static void sdl_dinput_poll(void *data) } } -const input_driver_t input_dinput = { - .init = sdl_dinput_init, - .poll = sdl_dinput_poll, - .input_state = sdl_dinput_state, - .key_pressed = sdl_dinput_pressed, - .free = sdl_dinput_free, - .ident = "dinput" -}; diff --git a/input/sdl.c b/input/sdl.c index 565fad463f..d4955f8065 100644 --- a/input/sdl.c +++ b/input/sdl.c @@ -25,12 +25,22 @@ #include #include "ssnes_sdl_input.h" + static void* sdl_input_init(void) { sdl_input_t *sdl = calloc(1, sizeof(*sdl)); if (!sdl) return NULL; +#ifdef HAVE_DINPUT + sdl->di = sdl_dinput_init(); + if (!sdl->di) + { + free(sdl); + SSNES_ERR("Failed to init SDL/DInput.\n"); + return NULL; + } +#else if (SDL_Init(SDL_INIT_JOYSTICK) < 0) return NULL; @@ -60,9 +70,9 @@ static void* sdl_input_init(void) sdl->num_hats[i] = SDL_JoystickNumHats(sdl->joysticks[i]); } } +#endif sdl->use_keyboard = true; - return sdl; } @@ -78,6 +88,7 @@ static bool sdl_key_pressed(int key) return keymap[key]; } +#ifndef HAVE_DINPUT static bool sdl_joykey_pressed(sdl_input_t *sdl, int port_num, uint16_t joykey) { // Check hat. @@ -140,17 +151,23 @@ static bool sdl_axis_pressed(sdl_input_t *sdl, int port_num, uint32_t joyaxis) return false; } +#endif static bool sdl_is_pressed(sdl_input_t *sdl, int port_num, const struct snes_keybind *key) { if (sdl->use_keyboard && sdl_key_pressed(key->key)) return true; + +#ifdef HAVE_DINPUT + return sdl_dinput_pressed(sdl->di, port_num, key); +#else if (sdl->joysticks[port_num] == NULL) return false; if (sdl_joykey_pressed(sdl, port_num, key->joykey)) return true; if (sdl_axis_pressed(sdl, port_num, key->joyaxis)) return true; +#endif return false; } @@ -159,7 +176,7 @@ static bool sdl_bind_button_pressed(void *data, int key) { // Only let player 1 use special binds called from main loop. const struct snes_keybind *binds = g_settings.input.binds[0]; - for (int i = 0; binds[i].id != -1; i++) + for (unsigned i = 0; binds[i].id != -1; i++) { if (binds[i].id == key) return sdl_is_pressed(data, 0, &binds[i]); @@ -172,7 +189,7 @@ static int16_t sdl_joypad_device_state(sdl_input_t *sdl, const struct snes_keybi { const struct snes_keybind *snes_keybinds = binds[port_num]; - for (int i = 0; snes_keybinds[i].id != -1; i++) + for (unsigned i = 0; snes_keybinds[i].id != -1; i++) { if (snes_keybinds[i].id == id) return sdl_is_pressed(sdl, port_num, &snes_keybinds[i]) ? 1 : 0; @@ -181,10 +198,8 @@ static int16_t sdl_joypad_device_state(sdl_input_t *sdl, const struct snes_keybi return 0; } -static int16_t sdl_mouse_device_state(sdl_input_t *sdl, bool port, unsigned id) +static int16_t sdl_mouse_device_state(sdl_input_t *sdl, unsigned id) { - // Might implement support for joypad mapping later. - (void)port; switch (id) { case SNES_DEVICE_ID_MOUSE_LEFT: @@ -252,7 +267,7 @@ static int16_t sdl_input_state(void *data, const struct snes_keybind **binds, bo case SNES_DEVICE_MULTITAP: return sdl_joypad_device_state(data, binds, (port == SNES_PORT_2) ? 1 + index : 0, id); case SNES_DEVICE_MOUSE: - return sdl_mouse_device_state(data, port, id); + return sdl_mouse_device_state(data, id); case SNES_DEVICE_SUPER_SCOPE: return sdl_scope_device_state(data, id); case SNES_DEVICE_JUSTIFIER: @@ -273,14 +288,19 @@ static void sdl_input_free(void *data) while (SDL_PollEvent(&event)); sdl_input_t *sdl = data; + +#ifdef HAVE_DINPUT + sdl_dinput_free(sdl->di); +#else for (int i = 0; i < MAX_PLAYERS; i++) { if (sdl->joysticks[i]) SDL_JoystickClose(sdl->joysticks[i]); } + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +#endif free(data); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } } diff --git a/input/ssnes_dinput.h b/input/ssnes_dinput.h index 26b9b39e6d..fd2cdaee97 100644 --- a/input/ssnes_dinput.h +++ b/input/ssnes_dinput.h @@ -19,26 +19,27 @@ #define __SSNES_DINPUT_H #include - +#include #include "general.h" + +// Piggyback joypad driver for SDL. + typedef struct sdl_dinput { HWND hWnd; - IDirectInput8 *ctx; - IDirectInputDevice8 *keyboard; - uint8_t di_state[256]; - IDirectInputDevice8 *joypad[MAX_PLAYERS]; unsigned joypad_cnt; DIJOYSTATE2 joy_state[MAX_PLAYERS]; - - bool *quitting; - bool *should_resize; - unsigned *new_width; - unsigned *new_height; - - int16_t mouse_x, mouse_y, mouse_l, mouse_r, mouse_m; } sdl_dinput_t; +sdl_dinput_t *sdl_dinput_init(void); +void sdl_dinput_free(sdl_dinput_t *di); + +bool sdl_dinput_pressed(sdl_dinput_t *di, unsigned port_num, + const struct snes_keybind *key); + +void sdl_dinput_poll(sdl_dinput_t *di); + + #endif diff --git a/input/ssnes_sdl_input.h b/input/ssnes_sdl_input.h index 6f1ee6769f..ca425dc521 100644 --- a/input/ssnes_sdl_input.h +++ b/input/ssnes_sdl_input.h @@ -20,13 +20,23 @@ #include "SDL.h" #include "general.h" + +#ifdef HAVE_DINPUT +#include "ssnes_dinput.h" +#endif + typedef struct sdl_input { +#ifdef HAVE_DINPUT + sdl_dinput_t *di; +#else SDL_Joystick *joysticks[MAX_PLAYERS]; unsigned num_axes[MAX_PLAYERS]; unsigned num_buttons[MAX_PLAYERS]; unsigned num_hats[MAX_PLAYERS]; unsigned num_joysticks; +#endif + bool use_keyboard; // A video driver could pre-init with the SDL driver and have it handle resizing events... @@ -36,6 +46,7 @@ typedef struct sdl_input unsigned *new_height; int16_t mouse_x, mouse_y; int16_t mouse_l, mouse_r, mouse_m; + } sdl_input_t; #endif diff --git a/settings.c b/settings.c index 71e131abb8..1d62d0316c 100644 --- a/settings.c +++ b/settings.c @@ -92,9 +92,6 @@ static void set_defaults(void) switch (INPUT_DEFAULT_DRIVER) { - case INPUT_DINPUT: - def_input = "dinput"; - break; case INPUT_SDL: def_input = "sdl"; break;