commit
593bcf9b29
|
@ -175,6 +175,13 @@ static void create_gl_context(HWND hwnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
static void *dinput;
|
||||||
|
|
||||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||||
WPARAM wparam, LPARAM lparam)
|
WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
|
@ -226,7 +233,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (dinput_handle_message(dinput, message, wparam, lparam))
|
||||||
|
return 0;
|
||||||
return DefWindowProc(hwnd, message, wparam, lparam);
|
return DefWindowProc(hwnd, message, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +520,7 @@ static void gfx_ctx_destroy(void)
|
||||||
|
|
||||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||||
{
|
{
|
||||||
void *dinput = input_dinput.init();
|
dinput = input_dinput.init();
|
||||||
*input = dinput ? &input_dinput : NULL;
|
*input = dinput ? &input_dinput : NULL;
|
||||||
*input_data = dinput;
|
*input_data = dinput;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,11 +60,17 @@ namespace Monitor
|
||||||
static unsigned cur_mon_id;
|
static unsigned cur_mon_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
namespace Callback
|
namespace Callback
|
||||||
{
|
{
|
||||||
static bool quit = false;
|
static bool quit = false;
|
||||||
static D3DVideo *curD3D = nullptr;
|
static D3DVideo *curD3D = nullptr;
|
||||||
static HRESULT d3d_err;
|
static HRESULT d3d_err;
|
||||||
|
static void *dinput;
|
||||||
|
|
||||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
|
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
|
||||||
WPARAM wParam, LPARAM lParam)
|
WPARAM wParam, LPARAM lParam)
|
||||||
|
@ -98,10 +104,9 @@ namespace Callback
|
||||||
if (new_width && new_height)
|
if (new_width && new_height)
|
||||||
curD3D->resize(new_width, new_height);
|
curD3D->resize(new_width, new_height);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
||||||
}
|
}
|
||||||
|
if (dinput_handle_message(dinput, message, wParam, lParam))
|
||||||
|
return 0;
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1317,9 +1322,9 @@ static void *d3d9_init(const video_info_t *info, const input_driver_t **input,
|
||||||
|
|
||||||
if (input && input_data)
|
if (input && input_data)
|
||||||
{
|
{
|
||||||
void *dinput = input_dinput.init();
|
Callback::dinput = input_dinput.init();
|
||||||
*input = dinput ? &input_dinput : nullptr;
|
*input = Callback::dinput ? &input_dinput : nullptr;
|
||||||
*input_data = dinput;
|
*input_data = Callback::dinput;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vid;
|
return vid;
|
||||||
|
|
141
input/dinput.c
141
input/dinput.c
|
@ -27,10 +27,19 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
|
||||||
// Context has to be global as joypads also ride on this context.
|
// Context has to be global as joypads also ride on this context.
|
||||||
static LPDIRECTINPUT8 g_ctx;
|
static LPDIRECTINPUT8 g_ctx;
|
||||||
|
|
||||||
|
struct pointer_status
|
||||||
|
{
|
||||||
|
int pointer_id;
|
||||||
|
int pointer_x;
|
||||||
|
int pointer_y;
|
||||||
|
struct pointer_status *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct dinput_input
|
struct dinput_input
|
||||||
{
|
{
|
||||||
LPDIRECTINPUTDEVICE8 keyboard;
|
LPDIRECTINPUTDEVICE8 keyboard;
|
||||||
|
@ -43,6 +52,7 @@ struct dinput_input
|
||||||
int mouse_x;
|
int mouse_x;
|
||||||
int mouse_y;
|
int mouse_y;
|
||||||
bool mouse_l, mouse_r, mouse_m;
|
bool mouse_l, mouse_r, mouse_m;
|
||||||
|
struct pointer_status pointer_head; // dummy head for easier iteration
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dinput_joypad
|
struct dinput_joypad
|
||||||
|
@ -234,11 +244,22 @@ static int16_t dinput_mouse_state(struct dinput_input *di, unsigned id)
|
||||||
|
|
||||||
static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, unsigned id, bool screen)
|
static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, unsigned id, bool screen)
|
||||||
{
|
{
|
||||||
if (index != 0)
|
int16_t res_x = 0, res_y = 0, res_screen_x = 0, res_screen_y = 0;
|
||||||
|
unsigned num = 0;
|
||||||
|
struct pointer_status *check_pos = di->pointer_head.next;
|
||||||
|
while (check_pos && num < index)
|
||||||
|
{
|
||||||
|
num++;
|
||||||
|
check_pos = check_pos->next;
|
||||||
|
}
|
||||||
|
if (!check_pos && index > 0) // index = 0 has mouse fallback
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int16_t res_x = 0, res_y = 0, res_screen_x = 0, res_screen_y = 0;
|
int x = check_pos ? check_pos->pointer_x : di->mouse_x;
|
||||||
bool valid = input_translate_coord_viewport(di->mouse_x, di->mouse_y,
|
int y = check_pos ? check_pos->pointer_y : di->mouse_y;
|
||||||
|
bool pointer_down = check_pos ? true : di->mouse_l;
|
||||||
|
|
||||||
|
bool valid = input_translate_coord_viewport(x, y,
|
||||||
&res_x, &res_y, &res_screen_x, &res_screen_y);
|
&res_x, &res_y, &res_screen_x, &res_screen_y);
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
|
@ -262,7 +283,7 @@ static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, uns
|
||||||
case RETRO_DEVICE_ID_POINTER_Y:
|
case RETRO_DEVICE_ID_POINTER_Y:
|
||||||
return res_y;
|
return res_y;
|
||||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||||
return di->mouse_l;
|
return pointer_down;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -299,6 +320,116 @@ static int16_t dinput_input_state(void *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// these are defined in later SDKs, thus ifdeffed
|
||||||
|
#ifndef WM_POINTERUPDATE
|
||||||
|
#define WM_POINTERUPDATE 0x0245
|
||||||
|
#endif
|
||||||
|
#ifndef WM_POINTERDOWN
|
||||||
|
#define WM_POINTERDOWN 0x0246
|
||||||
|
#endif
|
||||||
|
#ifndef WM_POINTERUP
|
||||||
|
#define WM_POINTERUP 0x0247
|
||||||
|
#endif
|
||||||
|
#ifndef GET_POINTERID_WPARAM
|
||||||
|
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// stores x/y in client coordinates
|
||||||
|
void dinput_pointer_store_pos(struct pointer_status *pointer, WPARAM lParam)
|
||||||
|
{
|
||||||
|
POINT point;
|
||||||
|
point.x = GET_X_LPARAM(lParam);
|
||||||
|
point.y = GET_Y_LPARAM(lParam);
|
||||||
|
ScreenToClient((HWND)driver.video_window, &point);
|
||||||
|
pointer->pointer_x = point.x;
|
||||||
|
pointer->pointer_y = point.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dinput_add_pointer(struct dinput_input *di, struct pointer_status *new_pointer)
|
||||||
|
{
|
||||||
|
new_pointer->next = NULL;
|
||||||
|
struct pointer_status *insert_pos = &di->pointer_head;
|
||||||
|
while (insert_pos->next)
|
||||||
|
insert_pos = insert_pos->next;
|
||||||
|
insert_pos->next = new_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dinput_delete_pointer(struct dinput_input *di, int pointer_id)
|
||||||
|
{
|
||||||
|
struct pointer_status *check_pos = &di->pointer_head;
|
||||||
|
while (check_pos && check_pos->next)
|
||||||
|
{
|
||||||
|
if (check_pos->next->pointer_id == pointer_id)
|
||||||
|
{
|
||||||
|
struct pointer_status *to_delete = check_pos->next;
|
||||||
|
check_pos->next = check_pos->next->next;
|
||||||
|
free(to_delete);
|
||||||
|
}
|
||||||
|
check_pos = check_pos->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pointer_status *dinput_find_pointer(struct dinput_input *di, int pointer_id)
|
||||||
|
{
|
||||||
|
struct pointer_status *check_pos = di->pointer_head.next;
|
||||||
|
while (check_pos)
|
||||||
|
{
|
||||||
|
if (check_pos->pointer_id == pointer_id)
|
||||||
|
break;
|
||||||
|
check_pos = check_pos->next;
|
||||||
|
}
|
||||||
|
return check_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dinput_clear_pointers(struct dinput_input *di)
|
||||||
|
{
|
||||||
|
struct pointer_status *pointer = &di->pointer_head;
|
||||||
|
while (pointer->next)
|
||||||
|
{
|
||||||
|
struct pointer_status *del = pointer->next;
|
||||||
|
pointer->next = pointer->next->next;
|
||||||
|
free(del);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
struct dinput_input *di = (struct dinput_input *)dinput;
|
||||||
|
/* WM_POINTERDOWN arrives for each new touch event with a new id - add to list
|
||||||
|
WM_POINTERUP arrives once the pointer is no longer down - remove from list
|
||||||
|
WM_POINTERUPDATE arrives for both pressed and hovering pointers - ignore hovering
|
||||||
|
*/
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_POINTERDOWN:
|
||||||
|
{
|
||||||
|
struct pointer_status *new_pointer = (struct pointer_status *)malloc(sizeof(struct pointer_status));
|
||||||
|
new_pointer->pointer_id = GET_POINTERID_WPARAM(wParam);
|
||||||
|
dinput_pointer_store_pos(new_pointer, lParam);
|
||||||
|
dinput_add_pointer(di, new_pointer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_POINTERUP:
|
||||||
|
{
|
||||||
|
int pointer_id = GET_POINTERID_WPARAM(wParam);
|
||||||
|
dinput_delete_pointer(di, pointer_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_POINTERUPDATE:
|
||||||
|
{
|
||||||
|
int pointer_id = GET_POINTERID_WPARAM(wParam);
|
||||||
|
struct pointer_status *pointer = dinput_find_pointer(di, pointer_id);
|
||||||
|
if (pointer)
|
||||||
|
dinput_pointer_store_pos(pointer, lParam);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void dinput_free(void *data)
|
static void dinput_free(void *data)
|
||||||
{
|
{
|
||||||
struct dinput_input *di = (struct dinput_input*)data;
|
struct dinput_input *di = (struct dinput_input*)data;
|
||||||
|
@ -310,6 +441,8 @@ static void dinput_free(void *data)
|
||||||
di->joypad->destroy();
|
di->joypad->destroy();
|
||||||
g_ctx = hold_ctx;
|
g_ctx = hold_ctx;
|
||||||
|
|
||||||
|
dinput_clear_pointers(di); // clear any leftover pointers
|
||||||
|
|
||||||
if (di->keyboard)
|
if (di->keyboard)
|
||||||
IDirectInputDevice8_Release(di->keyboard);
|
IDirectInputDevice8_Release(di->keyboard);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
|
</assembly>
|
|
@ -1 +1,2 @@
|
||||||
1 ICON "retroarch-icon.ico"
|
1 ICON "retroarch-icon.ico"
|
||||||
|
1 24 "rarch.manifest"
|
||||||
|
|
Loading…
Reference in New Issue