mirror of
https://github.com/libretro/RetroArch
synced 2025-03-02 19:13:34 +00:00
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,
|
||||
WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
@ -226,7 +233,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dinput_handle_message(dinput, message, wparam, lparam))
|
||||
return 0;
|
||||
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)
|
||||
{
|
||||
void *dinput = input_dinput.init();
|
||||
dinput = input_dinput.init();
|
||||
*input = dinput ? &input_dinput : NULL;
|
||||
*input_data = dinput;
|
||||
}
|
||||
|
@ -60,11 +60,17 @@ namespace Monitor
|
||||
static unsigned cur_mon_id;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
namespace Callback
|
||||
{
|
||||
static bool quit = false;
|
||||
static D3DVideo *curD3D = nullptr;
|
||||
static HRESULT d3d_err;
|
||||
static void *dinput;
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
@ -98,10 +104,9 @@ namespace Callback
|
||||
if (new_width && new_height)
|
||||
curD3D->resize(new_width, new_height);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1317,9 +1322,9 @@ static void *d3d9_init(const video_info_t *info, const input_driver_t **input,
|
||||
|
||||
if (input && input_data)
|
||||
{
|
||||
void *dinput = input_dinput.init();
|
||||
*input = dinput ? &input_dinput : nullptr;
|
||||
*input_data = dinput;
|
||||
Callback::dinput = input_dinput.init();
|
||||
*input = Callback::dinput ? &input_dinput : nullptr;
|
||||
*input_data = Callback::dinput;
|
||||
}
|
||||
|
||||
return vid;
|
||||
|
141
input/dinput.c
141
input/dinput.c
@ -27,10 +27,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
// Context has to be global as joypads also ride on this context.
|
||||
static LPDIRECTINPUT8 g_ctx;
|
||||
|
||||
struct pointer_status
|
||||
{
|
||||
int pointer_id;
|
||||
int pointer_x;
|
||||
int pointer_y;
|
||||
struct pointer_status *next;
|
||||
};
|
||||
|
||||
struct dinput_input
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 keyboard;
|
||||
@ -43,6 +52,7 @@ struct dinput_input
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
bool mouse_l, mouse_r, mouse_m;
|
||||
struct pointer_status pointer_head; // dummy head for easier iteration
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
int16_t res_x = 0, res_y = 0, res_screen_x = 0, res_screen_y = 0;
|
||||
bool valid = input_translate_coord_viewport(di->mouse_x, di->mouse_y,
|
||||
int x = check_pos ? check_pos->pointer_x : di->mouse_x;
|
||||
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);
|
||||
|
||||
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:
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return di->mouse_l;
|
||||
return pointer_down;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
struct dinput_input *di = (struct dinput_input*)data;
|
||||
@ -310,6 +441,8 @@ static void dinput_free(void *data)
|
||||
di->joypad->destroy();
|
||||
g_ctx = hold_ctx;
|
||||
|
||||
dinput_clear_pointers(di); // clear any leftover pointers
|
||||
|
||||
if (di->keyboard)
|
||||
IDirectInputDevice8_Release(di->keyboard);
|
||||
|
||||
|
8
media/rarch.manifest
Normal file
8
media/rarch.manifest
Normal file
@ -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 24 "rarch.manifest"
|
||||
|
Loading…
x
Reference in New Issue
Block a user