diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c
index c7397d39d8..31f86cadb5 100644
--- a/input/drivers/winraw_input.c
+++ b/input/drivers/winraw_input.c
@@ -1,764 +1,858 @@
-/* RetroArch - A frontend for libretro.
- * 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 .
- */
-
-#include
-
-#include "../input_driver.h"
-#include "../input_keymaps.h"
-
-#include "../../configuration.h"
-#include "../../gfx/video_driver.h"
-#include "../../verbosity.h"
-
-typedef struct
-{
- uint8_t keys[256];
-} winraw_keyboard_t;
-
-typedef struct
-{
- HANDLE hnd;
- LONG x, y, dlt_x, dlt_y;
- LONG whl_u, whl_d;
- bool btn_l, btn_m, btn_r, btn_b4, btn_b5;
-} winraw_mouse_t;
-
-typedef struct
-{
- bool kbd_mapp_block;
- bool mouse_grab;
- winraw_keyboard_t keyboard;
- HWND window;
- winraw_mouse_t *mice;
- const input_device_driver_t *joypad;
-} winraw_input_t;
-
-static winraw_keyboard_t *g_keyboard = NULL;
-static winraw_mouse_t *g_mice = NULL;
-static unsigned g_mouse_cnt = 0;
-static bool g_mouse_xy_mapping_ready = false;
-static double g_view_abs_ratio_x = 0.0;
-static double g_view_abs_ratio_y = 0.0;
-
-static HWND winraw_create_window(WNDPROC wnd_proc)
-{
- HWND wnd;
- WNDCLASSA wc = {0};
-
- wc.hInstance = GetModuleHandleA(NULL);
-
- if (!wc.hInstance)
- {
- RARCH_ERR("[WINRAW]: GetModuleHandleA failed with error %lu.\n", GetLastError());
- return NULL;
- }
-
- wc.lpfnWndProc = wnd_proc;
- wc.lpszClassName = "winraw-input";
- if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
- {
- RARCH_ERR("[WINRAW]: RegisterClassA failed with error %lu.\n", GetLastError());
- return NULL;
- }
-
- wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0,
- HWND_MESSAGE, NULL, NULL, NULL);
- if (!wnd)
- {
- RARCH_ERR("[WINRAW]: CreateWindowExA failed with error %lu.\n", GetLastError());
- goto error;
- }
-
- return wnd;
-
-error:
- UnregisterClassA(wc.lpszClassName, NULL);
- return NULL;
-}
-
-static void winraw_destroy_window(HWND wnd)
-{
- BOOL r;
-
- if (!wnd)
- return;
-
- r = DestroyWindow(wnd);
-
- if (!r)
- {
- RARCH_WARN("[WINRAW]: DestroyWindow failed with error %lu.\n", GetLastError());
- }
-
- r = UnregisterClassA("winraw-input", NULL);
-
- if (!r)
- {
- RARCH_WARN("[WINRAW]: UnregisterClassA failed with error %lu.\n", GetLastError());
- }
-}
-
-static bool winraw_set_keyboard_input(HWND window)
-{
- RAWINPUTDEVICE rid;
- BOOL r;
-
- rid.dwFlags = window ? 0 : RIDEV_REMOVE;
- rid.hwndTarget = window;
- rid.usUsagePage = 0x01; /* generic desktop */
- rid.usUsage = 0x06; /* keyboard */
-
- r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
-
- if (!r)
- {
- RARCH_ERR("[WINRAW]: RegisterRawInputDevices failed with error %lu.\n", GetLastError());
- return false;
- }
-
- return true;
-}
-
-static void winraw_log_mice_info(winraw_mouse_t *mice, unsigned mouse_cnt)
-{
- UINT r;
- unsigned i;
- char name[256];
- UINT name_size = sizeof(name);
-
- for (i = 0; i < mouse_cnt; ++i)
- {
- r = GetRawInputDeviceInfoA(mice[i].hnd, RIDI_DEVICENAME, name, &name_size);
- if (r == (UINT)-1 || r == 0)
- name[0] = '\0';
- RARCH_LOG("[WINRAW]: Mouse #%u %s.\n", i, name);
- }
-}
-
-static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt)
-{
- UINT i;
- POINT crs_pos;
- winraw_mouse_t *mice_r = NULL;
- unsigned mouse_cnt_r = 0;
- RAWINPUTDEVICELIST *devs = NULL;
- UINT dev_cnt = 0;
- UINT r = GetRawInputDeviceList(
- NULL, &dev_cnt, sizeof(RAWINPUTDEVICELIST));
-
- if (r == (UINT)-1)
- {
- RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError());
- goto error;
- }
-
- devs = (RAWINPUTDEVICELIST*)malloc(dev_cnt * sizeof(RAWINPUTDEVICELIST));
- if (!devs)
- goto error;
-
- dev_cnt = GetRawInputDeviceList(devs, &dev_cnt, sizeof(RAWINPUTDEVICELIST));
- if (dev_cnt == (UINT)-1)
- {
- RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError());
- goto error;
- }
-
- for (i = 0; i < dev_cnt; ++i)
- mouse_cnt_r += devs[i].dwType == RIM_TYPEMOUSE ? 1 : 0;
-
- if (mouse_cnt_r)
- {
- mice_r = (winraw_mouse_t*)calloc(1, mouse_cnt_r * sizeof(winraw_mouse_t));
- if (!mice_r)
- goto error;
-
- if (!GetCursorPos(&crs_pos))
- goto error;
-
- for (i = 0; i < mouse_cnt_r; ++i)
- {
- mice_r[i].x = crs_pos.x;
- mice_r[i].y = crs_pos.y;
- }
- }
-
- /* count is already checked, so this is safe */
- for (i = mouse_cnt_r = 0; i < dev_cnt; ++i)
- {
- if (devs[i].dwType == RIM_TYPEMOUSE)
- mice_r[mouse_cnt_r++].hnd = devs[i].hDevice;
- }
-
- winraw_log_mice_info(mice_r, mouse_cnt_r);
-
- *mice = mice_r;
- *mouse_cnt = mouse_cnt_r;
-
- return true;
-
-error:
- free(devs);
- free(mice_r);
- *mice = NULL;
- *mouse_cnt = 0;
- return false;
-}
-
-static bool winraw_set_mouse_input(HWND window, bool grab)
-{
- RAWINPUTDEVICE rid;
- BOOL r;
-
- if (window)
- rid.dwFlags = grab ? RIDEV_CAPTUREMOUSE : 0;
- else
- rid.dwFlags = RIDEV_REMOVE;
-
- rid.hwndTarget = window;
- rid.usUsagePage = 0x01; /* generic desktop */
- rid.usUsage = 0x02; /* mouse */
-
- r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
-
- if (!r)
- {
- RARCH_ERR("[WINRAW]: RegisterRawInputDevice failed with error %lu.\n", GetLastError());
- return false;
- }
-
- return true;
-}
-
-static int16_t winraw_mouse_state(winraw_input_t *wr,
- unsigned port, bool abs, unsigned id)
-{
- unsigned i;
- settings_t *settings = config_get_ptr();
- winraw_mouse_t *mouse = NULL;
-
- if (port >= MAX_USERS)
- return 0;
-
- for (i = 0; i < g_mouse_cnt; ++i)
- {
- if (i == settings->uints.input_mouse_index[port])
- {
- mouse = &wr->mice[i];
- break;
- }
- }
-
- if (!mouse)
- return 0;
-
- switch (id)
- {
- case RETRO_DEVICE_ID_MOUSE_X:
- return abs ? mouse->x : mouse->dlt_x;
- case RETRO_DEVICE_ID_MOUSE_Y:
- return abs ? mouse->y : mouse->dlt_y;
- case RETRO_DEVICE_ID_MOUSE_LEFT:
- return mouse->btn_l ? 1 : 0;
- case RETRO_DEVICE_ID_MOUSE_RIGHT:
- return mouse->btn_r ? 1 : 0;
- case RETRO_DEVICE_ID_MOUSE_WHEELUP:
- return mouse->whl_u ? 1 : 0;
- case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
- return mouse->whl_d ? 1 : 0;
- case RETRO_DEVICE_ID_MOUSE_MIDDLE:
- return mouse->btn_m ? 1 : 0;
- case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
- return mouse->btn_b4 ? 1 : 0;
- case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
- return mouse->btn_b5 ? 1 : 0;
- }
-
- return 0;
-}
-
-static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key)
-{
- unsigned i;
- bool result;
- winraw_mouse_t *mouse = NULL;
- settings_t *settings = config_get_ptr();
-
- if (port >= MAX_USERS)
- return false;
-
- for (i = 0; i < g_mouse_cnt; ++i)
- {
- if (i == settings->uints.input_mouse_index[port])
- {
- mouse = &wr->mice[i];
- break;
- }
- }
-
- if (!mouse)
- return false;
-
- switch ( key )
- {
-
- case RETRO_DEVICE_ID_MOUSE_LEFT:
- return mouse->btn_l;
- case RETRO_DEVICE_ID_MOUSE_RIGHT:
- return mouse->btn_r;
- case RETRO_DEVICE_ID_MOUSE_MIDDLE:
- return mouse->btn_m;
- case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
- return mouse->btn_b4;
- case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
- return mouse->btn_b5;
- case RETRO_DEVICE_ID_MOUSE_WHEELUP:
- return mouse->whl_u;
- case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
- return mouse->whl_d;
- }
-
- return false;
-}
-
-static int16_t winraw_joypad_state(winraw_input_t *wr,
- rarch_joypad_info_t joypad_info,
- const struct retro_keybind *binds,
- unsigned port, unsigned id)
-{
- const struct retro_keybind *bind = &binds[id];
- unsigned key = rarch_keysym_lut[(enum retro_key)bind->key];
-
- if (!wr->kbd_mapp_block && (bind->key < RETROK_LAST) && wr->keyboard.keys[key])
- return 1;
-
- if (binds && binds[id].valid && winraw_mbutton_pressed(wr, port, bind->mbutton))
- return 1;
-
- return input_joypad_pressed(wr->joypad, joypad_info, port, binds, id);
-}
-
-static void winraw_init_mouse_xy_mapping()
-{
- struct video_viewport viewport;
- int center_x;
- int center_y;
- unsigned i;
-
- if (video_driver_get_viewport_info(&viewport))
- {
- center_x = viewport.x + viewport.width / 2;
- center_y = viewport.y + viewport.height / 2;
-
- for (i = 0; i < g_mouse_cnt; ++i)
- {
- g_mice[i].x = center_x;
- g_mice[i].y = center_y;
- }
-
- g_view_abs_ratio_x = (double)viewport.full_width / 65535.0;
- g_view_abs_ratio_y = (double)viewport.full_height / 65535.0;
-
- g_mouse_xy_mapping_ready = true;
- }
-}
-
-static int16_t winraw_lightgun_state(winraw_input_t *wr,
- unsigned port, unsigned id)
-{
- unsigned i;
- settings_t *settings = config_get_ptr();
- winraw_mouse_t *mouse = NULL;
-
- if (port >= MAX_USERS)
- return 0;
-
- for (i = 0; i < g_mouse_cnt; ++i)
- {
- if (i == settings->uints.input_mouse_index[port])
- {
- mouse = &wr->mice[i];
- break;
- }
- }
-
- if (!mouse)
- return 0;
-
- switch (id)
- {
- case RETRO_DEVICE_ID_LIGHTGUN_X:
- return mouse->dlt_x;
- case RETRO_DEVICE_ID_LIGHTGUN_Y:
- return mouse->dlt_y;
- case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
- return mouse->btn_l ? 1 : 0;
- case RETRO_DEVICE_ID_LIGHTGUN_CURSOR:
- return mouse->btn_m ? 1 : 0;
- case RETRO_DEVICE_ID_LIGHTGUN_TURBO:
- return mouse->btn_r ? 1 : 0;
- case RETRO_DEVICE_ID_LIGHTGUN_START:
- return (mouse->btn_m && mouse->btn_r) ? 1 : 0;
- case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
- return mouse->btn_m && mouse->btn_l ? 1 : 0;
- }
-
- return 0;
-}
-
-static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state)
-{
- POINT crs_pos;
-
- if (state->usFlags & MOUSE_MOVE_ABSOLUTE)
- {
- if (g_mouse_xy_mapping_ready)
- {
- state->lLastX = (LONG)(g_view_abs_ratio_x * state->lLastX);
- state->lLastY = (LONG)(g_view_abs_ratio_y * state->lLastY);
- InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX - mouse->x);
- InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY - mouse->y);
- mouse->x = state->lLastX;
- mouse->y = state->lLastY;
- }
- else
- winraw_init_mouse_xy_mapping();
- }
- else if (state->lLastX || state->lLastY)
- {
- InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX);
- InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY);
-
- if (!GetCursorPos(&crs_pos))
- {
- RARCH_WARN("[WINRAW]: GetCursorPos failed with error %lu.\n", GetLastError());
- }
- else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos))
- {
- RARCH_WARN("[WINRAW]: ScreenToClient failed with error %lu.\n", GetLastError());
- }
- else
- {
- mouse->x = crs_pos.x;
- mouse->y = crs_pos.y;
- }
- }
-
- if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
- mouse->btn_l = true;
- else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
- mouse->btn_l = false;
-
- if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
- mouse->btn_m = true;
- else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
- mouse->btn_m = false;
-
- if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
- mouse->btn_r = true;
- else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
- mouse->btn_r = false;
-
- if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
- mouse->btn_b4 = true;
- else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
- mouse->btn_b4 = false;
-
- if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
- mouse->btn_b5 = true;
- else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
- mouse->btn_b5 = false;
-
- if (state->usButtonFlags & RI_MOUSE_WHEEL)
- {
- if ((SHORT)state->usButtonData > 0)
- InterlockedExchange(&mouse->whl_u, 1);
- else if ((SHORT)state->usButtonData < 0)
- InterlockedExchange(&mouse->whl_d, 1);
- }
-}
-
-static LRESULT CALLBACK winraw_callback(HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
-{
- static uint8_t data[1024];
- UINT r;
- unsigned i;
- RAWINPUT *ri = (RAWINPUT*)data;
- UINT size = sizeof(data);
-
- if (msg != WM_INPUT)
- return DefWindowProcA(wnd, msg, wpar, lpar);
-
- /* app is in the background */
+/* RetroArch - A frontend for libretro.
+ * 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 .
+ */
+
+#include
+
+#include "../input_driver.h"
+#include "../input_keymaps.h"
+
+#include "../../configuration.h"
+#include "../../gfx/video_driver.h"
+#include "../../verbosity.h"
+
+typedef struct
+{
+ uint8_t keys[256];
+} winraw_keyboard_t;
+
+typedef struct
+{
+ HANDLE hnd;
+ LONG x, y, dlt_x, dlt_y;
+ LONG whl_u, whl_d;
+ bool btn_l, btn_m, btn_r, btn_b4, btn_b5;
+} winraw_mouse_t;
+
+typedef struct
+{
+ bool kbd_mapp_block;
+ bool mouse_grab;
+ winraw_keyboard_t keyboard;
+ HWND window;
+ winraw_mouse_t *mice;
+ const input_device_driver_t *joypad;
+} winraw_input_t;
+
+static winraw_keyboard_t *g_keyboard = NULL;
+static winraw_mouse_t *g_mice = NULL;
+static unsigned g_mouse_cnt = 0;
+static bool g_mouse_xy_mapping_ready = false;
+static double g_view_abs_ratio_x = 0.0;
+static double g_view_abs_ratio_y = 0.0;
+
+static HWND winraw_create_window(WNDPROC wnd_proc)
+{
+ HWND wnd;
+ WNDCLASSA wc = {0};
+
+ wc.hInstance = GetModuleHandleA(NULL);
+
+ if (!wc.hInstance)
+ {
+ RARCH_ERR("[WINRAW]: GetModuleHandleA failed with error %lu.\n", GetLastError());
+ return NULL;
+ }
+
+ wc.lpfnWndProc = wnd_proc;
+ wc.lpszClassName = "winraw-input";
+ if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
+ {
+ RARCH_ERR("[WINRAW]: RegisterClassA failed with error %lu.\n", GetLastError());
+ return NULL;
+ }
+
+ wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0,
+ HWND_MESSAGE, NULL, NULL, NULL);
+ if (!wnd)
+ {
+ RARCH_ERR("[WINRAW]: CreateWindowExA failed with error %lu.\n", GetLastError());
+ goto error;
+ }
+
+ return wnd;
+
+error:
+ UnregisterClassA(wc.lpszClassName, NULL);
+ return NULL;
+}
+
+static void winraw_destroy_window(HWND wnd)
+{
+ BOOL r;
+
+ if (!wnd)
+ return;
+
+ r = DestroyWindow(wnd);
+
+ if (!r)
+ {
+ RARCH_WARN("[WINRAW]: DestroyWindow failed with error %lu.\n", GetLastError());
+ }
+
+ r = UnregisterClassA("winraw-input", NULL);
+
+ if (!r)
+ {
+ RARCH_WARN("[WINRAW]: UnregisterClassA failed with error %lu.\n", GetLastError());
+ }
+}
+
+static bool winraw_set_keyboard_input(HWND window)
+{
+ RAWINPUTDEVICE rid;
+ BOOL r;
+
+ rid.dwFlags = window ? 0 : RIDEV_REMOVE;
+ rid.hwndTarget = window;
+ rid.usUsagePage = 0x01; /* generic desktop */
+ rid.usUsage = 0x06; /* keyboard */
+
+ r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
+
+ if (!r)
+ {
+ RARCH_ERR("[WINRAW]: RegisterRawInputDevices failed with error %lu.\n", GetLastError());
+ return false;
+ }
+
+ return true;
+}
+
+static void winraw_log_mice_info(winraw_mouse_t *mice, unsigned mouse_cnt)
+{
+ UINT r;
+ unsigned i;
+ char name[256];
+ UINT name_size = sizeof(name);
+
+ for (i = 0; i < mouse_cnt; ++i)
+ {
+ r = GetRawInputDeviceInfoA(mice[i].hnd, RIDI_DEVICENAME, name, &name_size);
+ if (r == (UINT)-1 || r == 0)
+ name[0] = '\0';
+ RARCH_LOG("[WINRAW]: Mouse #%u %s.\n", i, name);
+ }
+}
+
+static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt)
+{
+ UINT i;
+ POINT crs_pos;
+ winraw_mouse_t *mice_r = NULL;
+ unsigned mouse_cnt_r = 0;
+ RAWINPUTDEVICELIST *devs = NULL;
+ UINT dev_cnt = 0;
+ UINT r = GetRawInputDeviceList(
+ NULL, &dev_cnt, sizeof(RAWINPUTDEVICELIST));
+
+ if (r == (UINT)-1)
+ {
+ RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError());
+ goto error;
+ }
+
+ devs = (RAWINPUTDEVICELIST*)malloc(dev_cnt * sizeof(RAWINPUTDEVICELIST));
+ if (!devs)
+ goto error;
+
+ dev_cnt = GetRawInputDeviceList(devs, &dev_cnt, sizeof(RAWINPUTDEVICELIST));
+ if (dev_cnt == (UINT)-1)
+ {
+ RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError());
+ goto error;
+ }
+
+ for (i = 0; i < dev_cnt; ++i)
+ mouse_cnt_r += devs[i].dwType == RIM_TYPEMOUSE ? 1 : 0;
+
+ if (mouse_cnt_r)
+ {
+ mice_r = (winraw_mouse_t*)calloc(1, mouse_cnt_r * sizeof(winraw_mouse_t));
+ if (!mice_r)
+ goto error;
+
+ if (!GetCursorPos(&crs_pos))
+ goto error;
+
+ for (i = 0; i < mouse_cnt_r; ++i)
+ {
+ mice_r[i].x = crs_pos.x;
+ mice_r[i].y = crs_pos.y;
+ }
+ }
+
+ /* count is already checked, so this is safe */
+ for (i = mouse_cnt_r = 0; i < dev_cnt; ++i)
+ {
+ if (devs[i].dwType == RIM_TYPEMOUSE)
+ mice_r[mouse_cnt_r++].hnd = devs[i].hDevice;
+ }
+
+ winraw_log_mice_info(mice_r, mouse_cnt_r);
+
+ *mice = mice_r;
+ *mouse_cnt = mouse_cnt_r;
+
+ return true;
+
+error:
+ free(devs);
+ free(mice_r);
+ *mice = NULL;
+ *mouse_cnt = 0;
+ return false;
+}
+
+static bool winraw_set_mouse_input(HWND window, bool grab)
+{
+ RAWINPUTDEVICE rid;
+ BOOL r;
+
+ if (window)
+ rid.dwFlags = grab ? RIDEV_CAPTUREMOUSE : 0;
+ else
+ rid.dwFlags = RIDEV_REMOVE;
+
+ rid.hwndTarget = window;
+ rid.usUsagePage = 0x01; /* generic desktop */
+ rid.usUsage = 0x02; /* mouse */
+
+ r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));
+
+ if (!r)
+ {
+ RARCH_ERR("[WINRAW]: RegisterRawInputDevice failed with error %lu.\n", GetLastError());
+ return false;
+ }
+
+ return true;
+}
+
+static int16_t winraw_lightgun_aiming_state(winraw_input_t *wr,
+ unsigned port, unsigned id)
+{
+ const int edge_detect = 32700;
+ struct video_viewport vp;
+ bool inside = false;
+ unsigned i;
+ settings_t *settings = config_get_ptr();
+ winraw_mouse_t *mouse = NULL;
+ int16_t res_x = 0;
+ int16_t res_y = 0;
+ int16_t res_screen_x = 0;
+ int16_t res_screen_y = 0;
+
+ if (port >= MAX_USERS)
+ return 0;
+
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ if (i == settings->uints.input_mouse_index[port])
+ {
+ mouse = &wr->mice[i];
+ break;
+ }
+ }
+
+ if (!mouse)
+ return 0;
+
+ vp.x = 0;
+ vp.y = 0;
+ vp.width = 0;
+ vp.height = 0;
+ vp.full_width = 0;
+ vp.full_height = 0;
+
+ if ( !( video_driver_translate_coord_viewport_wrap(
+ &vp, mouse->x, mouse->y, &res_x, &res_y, &res_screen_x, &res_screen_y ) ) )
+ {
+ return 0;
+ }
+
+ inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect);
+
+ switch ( id )
+ {
+ case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
+ return inside ? res_x : 0;
+ case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
+ return inside ? res_y : 0;
+ case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
+ return !inside;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int16_t winraw_mouse_state(winraw_input_t *wr,
+ unsigned port, bool abs, unsigned id)
+{
+ unsigned i;
+ settings_t *settings = config_get_ptr();
+ winraw_mouse_t *mouse = NULL;
+
+ if (port >= MAX_USERS)
+ return 0;
+
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ if (i == settings->uints.input_mouse_index[port])
+ {
+ mouse = &wr->mice[i];
+ break;
+ }
+ }
+
+ if (!mouse)
+ return 0;
+
+ switch (id)
+ {
+ case RETRO_DEVICE_ID_MOUSE_X:
+ return abs ? mouse->x : mouse->dlt_x;
+ case RETRO_DEVICE_ID_MOUSE_Y:
+ return abs ? mouse->y : mouse->dlt_y;
+ case RETRO_DEVICE_ID_MOUSE_LEFT:
+ return mouse->btn_l ? 1 : 0;
+ case RETRO_DEVICE_ID_MOUSE_RIGHT:
+ return mouse->btn_r ? 1 : 0;
+ case RETRO_DEVICE_ID_MOUSE_WHEELUP:
+ return mouse->whl_u ? 1 : 0;
+ case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
+ return mouse->whl_d ? 1 : 0;
+ case RETRO_DEVICE_ID_MOUSE_MIDDLE:
+ return mouse->btn_m ? 1 : 0;
+ case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
+ return mouse->btn_b4 ? 1 : 0;
+ case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
+ return mouse->btn_b5 ? 1 : 0;
+ }
+
+ return 0;
+}
+
+static bool winraw_keyboard_pressed(winraw_input_t *wr, unsigned key)
+{
+ unsigned k = rarch_keysym_lut[(enum retro_key)key];
+ return wr->keyboard.keys[k];
+}
+
+static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key)
+{
+ unsigned i;
+ bool result;
+ winraw_mouse_t *mouse = NULL;
+ settings_t *settings = config_get_ptr();
+
+ if (port >= MAX_USERS)
+ return false;
+
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ if (i == settings->uints.input_mouse_index[port])
+ {
+ mouse = &wr->mice[i];
+ break;
+ }
+ }
+
+ if (!mouse)
+ return false;
+
+ switch ( key )
+ {
+
+ case RETRO_DEVICE_ID_MOUSE_LEFT:
+ return mouse->btn_l;
+ case RETRO_DEVICE_ID_MOUSE_RIGHT:
+ return mouse->btn_r;
+ case RETRO_DEVICE_ID_MOUSE_MIDDLE:
+ return mouse->btn_m;
+ case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
+ return mouse->btn_b4;
+ case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
+ return mouse->btn_b5;
+ case RETRO_DEVICE_ID_MOUSE_WHEELUP:
+ return mouse->whl_u;
+ case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
+ return mouse->whl_d;
+ }
+
+ return false;
+}
+
+static bool winraw_is_pressed(winraw_input_t *wr,
+ rarch_joypad_info_t joypad_info,
+ const struct retro_keybind *binds,
+ unsigned port, unsigned id)
+{
+ const struct retro_keybind *bind = &binds[id];
+
+ if (!wr->kbd_mapp_block && (bind->key < RETROK_LAST) && winraw_keyboard_pressed(wr, bind->key))
+ return true;
+ if (binds && binds[id].valid)
+ {
+ if (winraw_mbutton_pressed(wr, port, bind->mbutton))
+ return true;
+ if (input_joypad_pressed(wr->joypad, joypad_info, port, binds, id))
+ return true;
+ }
+
+ return false;
+}
+
+static void winraw_init_mouse_xy_mapping()
+{
+ struct video_viewport viewport;
+ int center_x;
+ int center_y;
+ unsigned i;
+
+ if (video_driver_get_viewport_info(&viewport))
+ {
+ center_x = viewport.x + viewport.width / 2;
+ center_y = viewport.y + viewport.height / 2;
+
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ g_mice[i].x = center_x;
+ g_mice[i].y = center_y;
+ }
+
+ g_view_abs_ratio_x = (double)viewport.full_width / 65535.0;
+ g_view_abs_ratio_y = (double)viewport.full_height / 65535.0;
+
+ g_mouse_xy_mapping_ready = true;
+ }
+}
+
+static int16_t winraw_deprecated_lightgun_state(winraw_input_t *wr,
+ unsigned port, unsigned id)
+{
+ unsigned i;
+ settings_t *settings = config_get_ptr();
+ winraw_mouse_t *mouse = NULL;
+
+ if (port >= MAX_USERS)
+ return 0;
+
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ if (i == settings->uints.input_mouse_index[port])
+ {
+ mouse = &wr->mice[i];
+ break;
+ }
+ }
+
+ if (!mouse)
+ return 0;
+
+ switch (id)
+ {
+ case RETRO_DEVICE_ID_LIGHTGUN_X:
+ return mouse->dlt_x;
+ case RETRO_DEVICE_ID_LIGHTGUN_Y:
+ return mouse->dlt_y;
+ }
+
+ return 0;
+}
+
+static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state)
+{
+ POINT crs_pos;
+
+ if (state->usFlags & MOUSE_MOVE_ABSOLUTE)
+ {
+ if (g_mouse_xy_mapping_ready)
+ {
+ state->lLastX = (LONG)(g_view_abs_ratio_x * state->lLastX);
+ state->lLastY = (LONG)(g_view_abs_ratio_y * state->lLastY);
+ InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX - mouse->x);
+ InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY - mouse->y);
+ mouse->x = state->lLastX;
+ mouse->y = state->lLastY;
+ }
+ else
+ winraw_init_mouse_xy_mapping();
+ }
+ else if (state->lLastX || state->lLastY)
+ {
+ InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX);
+ InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY);
+
+ if (!GetCursorPos(&crs_pos))
+ {
+ RARCH_WARN("[WINRAW]: GetCursorPos failed with error %lu.\n", GetLastError());
+ }
+ else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos))
+ {
+ RARCH_WARN("[WINRAW]: ScreenToClient failed with error %lu.\n", GetLastError());
+ }
+ else
+ {
+ mouse->x = crs_pos.x;
+ mouse->y = crs_pos.y;
+ }
+ }
+
+ if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
+ mouse->btn_l = true;
+ else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
+ mouse->btn_l = false;
+
+ if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
+ mouse->btn_m = true;
+ else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
+ mouse->btn_m = false;
+
+ if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
+ mouse->btn_r = true;
+ else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
+ mouse->btn_r = false;
+
+ if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
+ mouse->btn_b4 = true;
+ else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
+ mouse->btn_b4 = false;
+
+ if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
+ mouse->btn_b5 = true;
+ else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
+ mouse->btn_b5 = false;
+
+ if (state->usButtonFlags & RI_MOUSE_WHEEL)
+ {
+ if ((SHORT)state->usButtonData > 0)
+ InterlockedExchange(&mouse->whl_u, 1);
+ else if ((SHORT)state->usButtonData < 0)
+ InterlockedExchange(&mouse->whl_d, 1);
+ }
+}
+
+static LRESULT CALLBACK winraw_callback(HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar)
+{
+ static uint8_t data[1024];
+ UINT r;
+ unsigned i;
+ RAWINPUT *ri = (RAWINPUT*)data;
+ UINT size = sizeof(data);
+
+ if (msg != WM_INPUT)
+ return DefWindowProcA(wnd, msg, wpar, lpar);
+
+ /* app is in the background */
if (GET_RAWINPUT_CODE_WPARAM(wpar) != RIM_INPUT)
- goto end;
-
- r = GetRawInputData((HRAWINPUT)lpar, RID_INPUT,
- data, &size, sizeof(RAWINPUTHEADER));
- if (r == (UINT)-1)
- {
- RARCH_WARN("[WINRAW]: GetRawInputData failed with error %lu.\n",
- GetLastError());
- goto end;
- }
-
- if (ri->header.dwType == RIM_TYPEKEYBOARD)
- {
- if (ri->data.keyboard.Message == WM_KEYDOWN)
- g_keyboard->keys[ri->data.keyboard.VKey] = 1;
- else if (ri->data.keyboard.Message == WM_KEYUP)
- g_keyboard->keys[ri->data.keyboard.VKey] = 0;
- }
- else if (ri->header.dwType == RIM_TYPEMOUSE)
- {
- for (i = 0; i < g_mouse_cnt; ++i)
- {
- if (g_mice[i].hnd == ri->header.hDevice)
- {
- winraw_update_mouse_state(&g_mice[i], &ri->data.mouse);
- break;
- }
- }
- }
-
-end:
- DefWindowProcA(wnd, msg, wpar, lpar);
- return 0;
-}
-
-static void *winraw_init(const char *joypad_driver)
-{
- bool r;
- winraw_input_t *wr = (winraw_input_t *)
- calloc(1, sizeof(winraw_input_t));
- g_keyboard = (winraw_keyboard_t*)
- calloc(1, sizeof(winraw_keyboard_t));
-
- if (!wr || !g_keyboard)
- goto error;
-
- RARCH_LOG("[WINRAW]: Initializing input driver... \n");
-
- input_keymaps_init_keyboard_lut(rarch_key_map_winraw);
-
- wr->window = winraw_create_window(winraw_callback);
- if (!wr->window)
- goto error;
-
- r = winraw_init_devices(&g_mice, &g_mouse_cnt);
- if (!r)
- goto error;
-
- if (!g_mouse_cnt)
- {
- RARCH_LOG("[WINRAW]: Mouse unavailable.\n");
- }
- else
- {
- wr->mice = (winraw_mouse_t*)
- malloc(g_mouse_cnt * sizeof(winraw_mouse_t));
- if (!wr->mice)
- goto error;
-
- memcpy(wr->mice, g_mice, g_mouse_cnt * sizeof(winraw_mouse_t));
- }
-
- r = winraw_set_keyboard_input(wr->window);
- if (!r)
- goto error;
-
- r = winraw_set_mouse_input(wr->window, false);
- if (!r)
- goto error;
-
- wr->joypad = input_joypad_init_driver(joypad_driver, wr);
-
- return wr;
-
-error:
- if (wr && wr->window)
- {
- winraw_set_mouse_input(NULL, false);
- winraw_set_keyboard_input(NULL);
- winraw_destroy_window(wr->window);
- }
- free(g_keyboard);
- free(g_mice);
- if (wr)
- free(wr->mice);
- free(wr);
- return NULL;
-}
-
-static void winraw_poll(void *d)
-{
- unsigned i;
- winraw_input_t *wr = (winraw_input_t*)d;
-
- memcpy(&wr->keyboard, g_keyboard, sizeof(winraw_keyboard_t));
-
- /* following keys are not handled by windows raw input api */
- wr->keyboard.keys[VK_LCONTROL] = GetAsyncKeyState(VK_LCONTROL) >> 1 ? 1 : 0;
- wr->keyboard.keys[VK_RCONTROL] = GetAsyncKeyState(VK_RCONTROL) >> 1 ? 1 : 0;
- wr->keyboard.keys[VK_LMENU] = GetAsyncKeyState(VK_LMENU) >> 1 ? 1 : 0;
- wr->keyboard.keys[VK_RMENU] = GetAsyncKeyState(VK_RMENU) >> 1 ? 1 : 0;
- wr->keyboard.keys[VK_LSHIFT] = GetAsyncKeyState(VK_LSHIFT) >> 1 ? 1 : 0;
- wr->keyboard.keys[VK_RSHIFT] = GetAsyncKeyState(VK_RSHIFT) >> 1 ? 1 : 0;
-
- for (i = 0; i < g_mouse_cnt; ++i)
- {
- wr->mice[i].x = g_mice[i].x;
- wr->mice[i].y = g_mice[i].y;
- wr->mice[i].dlt_x = InterlockedExchange(&g_mice[i].dlt_x, 0);
- wr->mice[i].dlt_y = InterlockedExchange(&g_mice[i].dlt_y, 0);
- wr->mice[i].whl_u = InterlockedExchange(&g_mice[i].whl_u, 0);
- wr->mice[i].whl_d = InterlockedExchange(&g_mice[i].whl_d, 0);
- wr->mice[i].btn_l = g_mice[i].btn_l;
- wr->mice[i].btn_m = g_mice[i].btn_m;
- wr->mice[i].btn_r = g_mice[i].btn_r;
- wr->mice[i].btn_b4 = g_mice[i].btn_b4;
- wr->mice[i].btn_b5 = g_mice[i].btn_b5;
- }
-
- if (wr->joypad)
- wr->joypad->poll();
-}
-
-static int16_t winraw_input_state(void *d,
- rarch_joypad_info_t joypad_info,
- const struct retro_keybind **binds,
- unsigned port, unsigned device, unsigned index, unsigned id)
-{
- winraw_input_t *wr = (winraw_input_t*)d;
-
- switch (device)
- {
- case RETRO_DEVICE_KEYBOARD:
- if (id < RETROK_LAST)
- {
- unsigned key = rarch_keysym_lut[(enum retro_key)id];
- return wr->keyboard.keys[key];
- }
- break;
- case RETRO_DEVICE_MOUSE:
- return winraw_mouse_state(wr, port, false, id);
- case RARCH_DEVICE_MOUSE_SCREEN:
- return winraw_mouse_state(wr, port, true, id);
- case RETRO_DEVICE_JOYPAD:
- return winraw_joypad_state(wr, joypad_info, binds[port], port, id);
- case RETRO_DEVICE_ANALOG:
- if (binds[port])
- return input_joypad_analog(wr->joypad, joypad_info,
- port, index, id, binds[port]);
- break;
- case RETRO_DEVICE_LIGHTGUN:
- return winraw_lightgun_state(wr, port, id);
- }
-
- return 0;
-}
-
-static bool winraw_meta_key_pressed(void *u1, int u2)
-{
- return false;
-}
-
-static void winraw_free(void *d)
-{
- winraw_input_t *wr = (winraw_input_t*)d;
-
- if (wr->joypad)
- wr->joypad->destroy();
- winraw_set_mouse_input(NULL, false);
- winraw_set_keyboard_input(NULL);
- winraw_destroy_window(wr->window);
- free(g_mice);
- free(g_keyboard);
- free(wr->mice);
- free(wr);
-
- g_mouse_xy_mapping_ready = false;
-}
-
-static uint64_t winraw_get_capabilities(void *u)
-{
- return (1 << RETRO_DEVICE_KEYBOARD) |
- (1 << RETRO_DEVICE_MOUSE) |
- (1 << RETRO_DEVICE_JOYPAD) |
- (1 << RETRO_DEVICE_ANALOG) |
- (1 << RETRO_DEVICE_LIGHTGUN);
-}
-
-static void winraw_grab_mouse(void *d, bool grab)
-{
- bool r = false;
- winraw_input_t *wr = (winraw_input_t*)d;
-
- if (grab == wr->mouse_grab)
- return;
-
- r = winraw_set_mouse_input(wr->window, grab);
- if (!r)
- return;
-
- wr->mouse_grab = grab;
-}
-
-static bool winraw_set_rumble(void *d, unsigned port,
- enum retro_rumble_effect effect, uint16_t strength)
-{
- winraw_input_t *wr = (winraw_input_t*)d;
-
- return input_joypad_set_rumble(wr->joypad, port, effect, strength);
-}
-
-static const input_device_driver_t *winraw_get_joypad_driver(void *d)
-{
- winraw_input_t *wr = (winraw_input_t*)d;
-
- return wr->joypad;
-}
-
-static bool winraw_keyboard_mapping_is_blocked(void *d)
-{
- winraw_input_t *wr = (winraw_input_t*)d;
-
- return wr->kbd_mapp_block;
-}
-
-static void winraw_keyboard_mapping_set_block(void *d, bool block)
-{
- winraw_input_t *wr = (winraw_input_t*)d;
-
- wr->kbd_mapp_block = block;
-}
-
-input_driver_t input_winraw = {
- winraw_init,
- winraw_poll,
- winraw_input_state,
- winraw_meta_key_pressed,
- winraw_free,
- NULL,
- NULL,
- winraw_get_capabilities,
- "raw",
- winraw_grab_mouse,
- NULL,
- winraw_set_rumble,
- winraw_get_joypad_driver,
- NULL,
- winraw_keyboard_mapping_is_blocked,
- winraw_keyboard_mapping_set_block,
-};
+ goto end;
+
+ r = GetRawInputData((HRAWINPUT)lpar, RID_INPUT,
+ data, &size, sizeof(RAWINPUTHEADER));
+ if (r == (UINT)-1)
+ {
+ RARCH_WARN("[WINRAW]: GetRawInputData failed with error %lu.\n",
+ GetLastError());
+ goto end;
+ }
+
+ if (ri->header.dwType == RIM_TYPEKEYBOARD)
+ {
+ if (ri->data.keyboard.Message == WM_KEYDOWN)
+ g_keyboard->keys[ri->data.keyboard.VKey] = 1;
+ else if (ri->data.keyboard.Message == WM_KEYUP)
+ g_keyboard->keys[ri->data.keyboard.VKey] = 0;
+ }
+ else if (ri->header.dwType == RIM_TYPEMOUSE)
+ {
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ if (g_mice[i].hnd == ri->header.hDevice)
+ {
+ winraw_update_mouse_state(&g_mice[i], &ri->data.mouse);
+ break;
+ }
+ }
+ }
+
+end:
+ DefWindowProcA(wnd, msg, wpar, lpar);
+ return 0;
+}
+
+static void *winraw_init(const char *joypad_driver)
+{
+ bool r;
+ winraw_input_t *wr = (winraw_input_t *)
+ calloc(1, sizeof(winraw_input_t));
+ g_keyboard = (winraw_keyboard_t*)
+ calloc(1, sizeof(winraw_keyboard_t));
+
+ if (!wr || !g_keyboard)
+ goto error;
+
+ RARCH_LOG("[WINRAW]: Initializing input driver... \n");
+
+ input_keymaps_init_keyboard_lut(rarch_key_map_winraw);
+
+ wr->window = winraw_create_window(winraw_callback);
+ if (!wr->window)
+ goto error;
+
+ r = winraw_init_devices(&g_mice, &g_mouse_cnt);
+ if (!r)
+ goto error;
+
+ if (!g_mouse_cnt)
+ {
+ RARCH_LOG("[WINRAW]: Mouse unavailable.\n");
+ }
+ else
+ {
+ wr->mice = (winraw_mouse_t*)
+ malloc(g_mouse_cnt * sizeof(winraw_mouse_t));
+ if (!wr->mice)
+ goto error;
+
+ memcpy(wr->mice, g_mice, g_mouse_cnt * sizeof(winraw_mouse_t));
+ }
+
+ r = winraw_set_keyboard_input(wr->window);
+ if (!r)
+ goto error;
+
+ r = winraw_set_mouse_input(wr->window, false);
+ if (!r)
+ goto error;
+
+ wr->joypad = input_joypad_init_driver(joypad_driver, wr);
+
+ return wr;
+
+error:
+ if (wr && wr->window)
+ {
+ winraw_set_mouse_input(NULL, false);
+ winraw_set_keyboard_input(NULL);
+ winraw_destroy_window(wr->window);
+ }
+ free(g_keyboard);
+ free(g_mice);
+ if (wr)
+ free(wr->mice);
+ free(wr);
+ return NULL;
+}
+
+static void winraw_poll(void *d)
+{
+ unsigned i;
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ memcpy(&wr->keyboard, g_keyboard, sizeof(winraw_keyboard_t));
+
+ /* following keys are not handled by windows raw input api */
+ wr->keyboard.keys[VK_LCONTROL] = GetAsyncKeyState(VK_LCONTROL) >> 1 ? 1 : 0;
+ wr->keyboard.keys[VK_RCONTROL] = GetAsyncKeyState(VK_RCONTROL) >> 1 ? 1 : 0;
+ wr->keyboard.keys[VK_LMENU] = GetAsyncKeyState(VK_LMENU) >> 1 ? 1 : 0;
+ wr->keyboard.keys[VK_RMENU] = GetAsyncKeyState(VK_RMENU) >> 1 ? 1 : 0;
+ wr->keyboard.keys[VK_LSHIFT] = GetAsyncKeyState(VK_LSHIFT) >> 1 ? 1 : 0;
+ wr->keyboard.keys[VK_RSHIFT] = GetAsyncKeyState(VK_RSHIFT) >> 1 ? 1 : 0;
+
+ for (i = 0; i < g_mouse_cnt; ++i)
+ {
+ wr->mice[i].x = g_mice[i].x;
+ wr->mice[i].y = g_mice[i].y;
+ wr->mice[i].dlt_x = InterlockedExchange(&g_mice[i].dlt_x, 0);
+ wr->mice[i].dlt_y = InterlockedExchange(&g_mice[i].dlt_y, 0);
+ wr->mice[i].whl_u = InterlockedExchange(&g_mice[i].whl_u, 0);
+ wr->mice[i].whl_d = InterlockedExchange(&g_mice[i].whl_d, 0);
+ wr->mice[i].btn_l = g_mice[i].btn_l;
+ wr->mice[i].btn_m = g_mice[i].btn_m;
+ wr->mice[i].btn_r = g_mice[i].btn_r;
+ wr->mice[i].btn_b4 = g_mice[i].btn_b4;
+ wr->mice[i].btn_b5 = g_mice[i].btn_b5;
+ }
+
+ if (wr->joypad)
+ wr->joypad->poll();
+}
+
+static int16_t winraw_input_state(void *d,
+ rarch_joypad_info_t joypad_info,
+ const struct retro_keybind **binds,
+ unsigned port, unsigned device, unsigned index, unsigned id)
+{
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ switch (device)
+ {
+ case RETRO_DEVICE_JOYPAD:
+ if (id < RARCH_BIND_LIST_END)
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, id);
+ break;
+ case RETRO_DEVICE_KEYBOARD:
+ return (id < RETROK_LAST) && winraw_keyboard_pressed(wr, id);
+ case RETRO_DEVICE_MOUSE:
+ return winraw_mouse_state(wr, port, false, id);
+ case RARCH_DEVICE_MOUSE_SCREEN:
+ return winraw_mouse_state(wr, port, true, id);
+ case RETRO_DEVICE_ANALOG:
+ if (binds[port])
+ return input_joypad_analog(wr->joypad, joypad_info,
+ port, index, id, binds[port]);
+ break;
+ case RETRO_DEVICE_LIGHTGUN:
+ switch ( id )
+ {
+ /*aiming*/
+ case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
+ case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
+ case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
+ return winraw_lightgun_aiming_state( wr, port, id );
+
+ /*buttons*/
+ case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_TRIGGER);
+ case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_RELOAD);
+ case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_A);
+ case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_B);
+ case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_C);
+ case RETRO_DEVICE_ID_LIGHTGUN_START:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START);
+ case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_SELECT);
+ case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_UP);
+ case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_DOWN);
+ case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_LEFT);
+ case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_RIGHT);
+
+ /*deprecated*/
+ case RETRO_DEVICE_ID_LIGHTGUN_X:
+ case RETRO_DEVICE_ID_LIGHTGUN_Y:
+ return winraw_deprecated_lightgun_state(wr, port, id);
+ case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
+ return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static bool winraw_meta_key_pressed(void *u1, int u2)
+{
+ return false;
+}
+
+static void winraw_free(void *d)
+{
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ if (wr->joypad)
+ wr->joypad->destroy();
+ winraw_set_mouse_input(NULL, false);
+ winraw_set_keyboard_input(NULL);
+ winraw_destroy_window(wr->window);
+ free(g_mice);
+ free(g_keyboard);
+ free(wr->mice);
+ free(wr);
+
+ g_mouse_xy_mapping_ready = false;
+}
+
+static uint64_t winraw_get_capabilities(void *u)
+{
+ return (1 << RETRO_DEVICE_KEYBOARD) |
+ (1 << RETRO_DEVICE_MOUSE) |
+ (1 << RETRO_DEVICE_JOYPAD) |
+ (1 << RETRO_DEVICE_ANALOG) |
+ (1 << RETRO_DEVICE_LIGHTGUN);
+}
+
+static void winraw_grab_mouse(void *d, bool grab)
+{
+ bool r = false;
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ if (grab == wr->mouse_grab)
+ return;
+
+ r = winraw_set_mouse_input(wr->window, grab);
+ if (!r)
+ return;
+
+ wr->mouse_grab = grab;
+}
+
+static bool winraw_set_rumble(void *d, unsigned port,
+ enum retro_rumble_effect effect, uint16_t strength)
+{
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ return input_joypad_set_rumble(wr->joypad, port, effect, strength);
+}
+
+static const input_device_driver_t *winraw_get_joypad_driver(void *d)
+{
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ return wr->joypad;
+}
+
+static bool winraw_keyboard_mapping_is_blocked(void *d)
+{
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ return wr->kbd_mapp_block;
+}
+
+static void winraw_keyboard_mapping_set_block(void *d, bool block)
+{
+ winraw_input_t *wr = (winraw_input_t*)d;
+
+ wr->kbd_mapp_block = block;
+}
+
+input_driver_t input_winraw = {
+ winraw_init,
+ winraw_poll,
+ winraw_input_state,
+ winraw_meta_key_pressed,
+ winraw_free,
+ NULL,
+ NULL,
+ winraw_get_capabilities,
+ "raw",
+ winraw_grab_mouse,
+ NULL,
+ winraw_set_rumble,
+ winraw_get_joypad_driver,
+ NULL,
+ winraw_keyboard_mapping_is_blocked,
+ winraw_keyboard_mapping_set_block,
+};