From: Toni Wilen Date: Sat, 20 Oct 2018 11:56:31 +0000 (+0300) Subject: D3D overlay graphics updates. X-Git-Tag: 4100~51 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=01310b4ffde96b4fa7371e193b30152a63f1a2a8;p=francis%2Fwinuae.git D3D overlay graphics updates. --- diff --git a/od-win32/cloanto/RetroPlatformIPC-doc.txt b/od-win32/cloanto/RetroPlatformIPC-doc.txt index 8e8c738e..5be32825 100644 --- a/od-win32/cloanto/RetroPlatformIPC-doc.txt +++ b/od-win32/cloanto/RetroPlatformIPC-doc.txt @@ -9,7 +9,7 @@ : assigned or transferred by contract. Authors : os, m Created : 2007-08-23 10:08:25 - Updated : 2018-10-04 16:40:44 + Updated : 2018-10-19 16:01:23 Comment : Reference for RetroPlatformIPC.h (RP Player interprocess communication include file) *****************************************************************************/ @@ -495,6 +495,36 @@ Response: RawInput RI_MOUSE_BUTTON_* flags or 0 +Message: + RP_IPC_TO_HOST_MOUSEMOVE +Description: + the guest sends this message to forward mouse move events; + mouse events forwarding is off by default and is enabled + by the RP_IPC_TO_GUEST_SENDMOUSEEVENTS message; + the screen coordinate range is the same used for screen overlays + (e.g. lLeft and lTop fields of the RPSCREENOVERLAY structure) +Data sent: + LPARAM = screen coordinates combined with the MAKELONG macro (i.e. MAKELONG(x,y)) +Response: + none + + +Message: + RP_IPC_TO_HOST_MOUSEBUTTON +Description: + the guest sends this message to forward mouse button events; + mouse events forwarding is off by default and is enabled + by the RP_IPC_TO_GUEST_SENDMOUSEEVENTS message; + the screen coordinate range is the same used for screen overlays + (e.g. lLeft and lTop fields of the RPSCREENOVERLAY structure) +Data sent: + WPARAM = mouse buttons state + (bit 0 = left button state, bit 1 = right button state, ...) + LPARAM = screen coordinates combined with the MAKELONG macro (i.e. MAKELONG(x,y)) +Response: + none + + Messages: RP_IPC_TO_HOST_PRIVATE_REGISTER RP_IPC_TO_HOST_PRIVATE_SHAREDEVENT @@ -503,6 +533,7 @@ Messages: RP_IPC_TO_HOST_PRIVATE_GUESTEVENT RP_IPC_TO_HOST_PRIVATE_KEYPROMPT RP_IPC_TO_HOST_PRIVATE_CLOSEKBDWIN + RP_IPC_TO_HOST_PRIVATE_MENUEVENT Description: these are private messages, sent by code in RPGuest.dll @@ -813,20 +844,53 @@ Response: Message: RP_IPC_TO_GUEST_SCREENOVERLAY Description: - This message sets or clears a screen overlay (an image that the guest + This message creates a screen overlay (an image that the guest renders on top of the emulated system screen). Multiple screen overlays can be set and simultaneously displayed on the screen (see the dwIndex field of the RPSCREENOVERLAY structure). - When the lWidth and lHeight fields of the RPSCREENOVERLAY structure - are set to a non-zero value, an overlay is defined or updated; - if the two fields are set to 0, the overlay specified - by the dwIndex field is removed from screen + NOTE: guests that support screen overlays must set the + RP_FEATURE_SCREENOVERLAY flag in the startup RP_IPC_TO_HOST_FEATURES message. Data sent: pData = a RPSCREENOVERLAY structure containing overlay information and image data Response: LRESULT = 1, if the guest successfully executed the command, or 0 otherwise +Message: + RP_IPC_TO_GUEST_MOVESCREENOVERLAY +Description: + This message moves a previously defined screen overlay to a specified position. +Data sent: + WPARAM = screen overlay index + LPARAM = screen coordinates combined with the MAKELONG macro (i.e. MAKELONG(x,y)) +Response: + LRESULT = 1, if the guest successfully executed the command, or 0 otherwise + + +Message: + RP_IPC_TO_GUEST_DELETESCREENOVERLAY +Description: + This message deletes a previously defined screen overlay. +Data sent: + WPARAM = screen overlay index +Response: + LRESULT = 1, if the guest successfully executed the command, or 0 otherwise + + +Message: + RP_IPC_TO_GUEST_SENDMOUSEEVENTS +Description: + The host sends this message to ask the guest to enable/disable + mouse events forwarding; this is typically done when the emulation is paused + and the host wnats to handle mouse navigation of screen overlays; + see RP_IPC_TO_HOST_MOUSEMOVE and RP_IPC_TO_HOST_MOUSEBUTTON + for additional information. +Data sent: + WPARAM = set to 1 to enable mouse events forwarding, or 0 to disable it +Response: + LRESULT = 1 if the guest acknowledged the command or 0 otherwise + + Messages: RP_IPC_TO_GUEST_PRIVATE_STARTUP RP_IPC_TO_GUEST_PRIVATE_TYPECLIP @@ -836,6 +900,7 @@ Messages: RP_IPC_TO_GUEST_PRIVATE_INPUTDEVICES RP_IPC_TO_GUEST_PRIVATE_NOKEYPROMPT RP_IPC_TO_GUEST_PRIVATE_KEYBOARDWINDOW + RP_IPC_TO_GUEST_PRIVATE_MENUMODE Description: these are private messages, received by code in RPGuest.dll; they never reach the message function in guest code diff --git a/od-win32/cloanto/RetroPlatformIPC.h b/od-win32/cloanto/RetroPlatformIPC.h index f0bf9ddb..39b7f02d 100644 --- a/od-win32/cloanto/RetroPlatformIPC.h +++ b/od-win32/cloanto/RetroPlatformIPC.h @@ -9,7 +9,7 @@ : Software Foundation. Authors : os, m Created : 2007-08-27 13:55:49 - Updated : 2018-10-04 16:26:12 + Updated : 2018-10-19 15:58:12 Comment : RetroPlatform Player interprocess communication include file *****************************************************************************/ @@ -65,6 +65,9 @@ #define RP_IPC_TO_HOST_PRIVATE_KEYREMINDER (WM_APP + 35) // introduced in RetroPlatform API 7.2 #define RP_IPC_TO_HOST_RAWINPUT_EVENT (WM_APP + 36) // introduced in RetroPlatform API 7.3 #define RP_IPC_TO_HOST_PRIVATE_CLOSEKBDWIN (WM_APP + 37) // introduced in RetroPlatform API 7.4 +#define RP_IPC_TO_HOST_MOUSEMOVE (WM_APP + 38) // introduced in RetroPlatform API 7.5 +#define RP_IPC_TO_HOST_MOUSEBUTTON (WM_APP + 39) // introduced in RetroPlatform API 7.5 +#define RP_IPC_TO_HOST_PRIVATE_MENUEVENT (WM_APP + 40) // introduced in RetroPlatform API 7.5 // **************************************************************************** // Host-to-Guest Messages @@ -98,6 +101,10 @@ #define RP_IPC_TO_GUEST_PRIVATE_KEYREMINDER (WM_APP + 229) // introduced in RetroPlatform API 7.2 #define RP_IPC_TO_GUEST_PRIVATE_KEYBOARDWINDOW (WM_APP + 230) // introduced in RetroPlatform API 7.4 #define RP_IPC_TO_GUEST_SCREENOVERLAY (WM_APP + 231) // introduced in RetroPlatform API 7.5 +#define RP_IPC_TO_GUEST_MOVESCREENOVERLAY (WM_APP + 232) // introduced in RetroPlatform API 7.5 +#define RP_IPC_TO_GUEST_DELETESCREENOVERLAY (WM_APP + 233) // introduced in RetroPlatform API 7.5 +#define RP_IPC_TO_GUEST_SENDMOUSEEVENTS (WM_APP + 234) // introduced in RetroPlatform API 7.5 +#define RP_IPC_TO_GUEST_PRIVATE_MENUMODE (WM_APP + 235) // introduced in RetroPlatform API 7.5 // **************************************************************************** // Message Data Structures and Defines @@ -133,6 +140,7 @@ #define RP_FEATURE_MEMORY_ADVANCED 0x04000000 // Memory I/O advanced features: Watch, Find, Alert, Freeze, Lock, Unlock, Off (must set both flags if full set is supported!) #define RP_FEATURE_SCREENCAPTURE 0x08000000 // new screen capture functionality is available (see RP_IPC_TO_GUEST_SCREENCAPTURE message) #define RP_FEATURE_RAWINPUT_EVENT 0x10000000 // RawInput mouse buttons events are forwarded via RP_IPC_TO_HOST_RAWINPUT_EVENT messages +#define RP_FEATURE_SCREENOVERLAY 0x20000000 // supports screen overlays typedef struct RPScreenMode { @@ -514,6 +522,16 @@ typedef struct RPScreenOverlay // RPSCREENOVERLAY dwFormat #define RPSOPF_32BIT_BGRA 0 // 4 bytes per pixel (blue, green, red, alpha) + +// RP_IPC_TO_HOST_PRIVATE_MENUEVENT wParam +#define RP_MENU_EVENT_RIGHT 1 +#define RP_MENU_EVENT_LEFT 2 +#define RP_MENU_EVENT_DOWN 3 +#define RP_MENU_EVENT_UP 4 +#define RP_MENU_EVENT_SELECT 5 +#define RP_MENU_EVENT_BACK 6 + + // Legacy Compatibility #ifndef RP_NO_LEGACY // Changed in 7.0 diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 4f496125..6285ca21 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -128,6 +128,12 @@ struct shaderdata D3DXHANDLE framecounterHandle; }; +struct d3d9overlay +{ + int x, y; + LPDIRECT3DTEXTURE9 tex; +}; + #define MAX_SHADERS (2 * MAX_FILTERSHADERS + 2) #define SHADER_POST 0 @@ -155,6 +161,7 @@ struct d3dstruct float mask2texture_wwx, mask2texture_hhx, mask2texture_minusx, mask2texture_minusy; float mask2texture_multx, mask2texture_multy, mask2texture_offsetw; LPDIRECT3DTEXTURE9 cursorsurfaced3d; + struct d3d9overlay extoverlays[EXTOVERLAYS]; IDirect3DVertexBuffer9 *vertexBuffer; ID3DXSprite *sprite; HWND d3dhwnd; @@ -2417,6 +2424,13 @@ static void invalidatedeviceobjects (struct d3dstruct *d3d) d3d->cursorsurfaced3d->Release (); d3d->cursorsurfaced3d = NULL; } + for (int i = 0; i < EXTOVERLAYS; i++) { + struct d3d9overlay *o = &d3d->extoverlays[i]; + if (o->tex) { + o->tex->Release(); + o->tex = NULL; + } + } for (int i = 0; i < MAX_SHADERS; i++) { if (d3d->shaders[i].pEffect) { d3d->shaders[i].pEffect->Release (); @@ -3696,6 +3710,15 @@ static void D3D_render2(struct d3dstruct *d3d, int mode) v.z = 0; d3d->sprite->Draw(d3d->ledtexture, NULL, NULL, &v, 0xffffffff); } + for (int i = 0; i < EXTOVERLAYS; i++) { + struct d3d9overlay *o = &d3d->extoverlays[i]; + if (o->tex) { + v.x = o->x; + v.y = o->y; + v.z = 0; + d3d->sprite->Draw(o->tex, NULL, NULL, &v, 0xffffffff); + } + } d3d->sprite->End(); } #endif @@ -3918,11 +3941,11 @@ static void xD3D_refresh (int monid) if (!isd3d (d3d)) return; - D3D_render2 (d3d, true); - D3D_showframe2 (d3d, true); - D3D_render2 (d3d, true); - D3D_showframe2 (d3d, true); - createscanlines (d3d, 0); + createscanlines(d3d, 0); + for (int i = 0; i < 2; i++) { + D3D_render2(d3d, true); + D3D_showframe2(d3d, true); + } } void D3D_getpixelformat (int depth, int *rb, int *gb, int *bb, int *rs, int *gs, int *bs, int *ab, int *as, int *a) @@ -4113,6 +4136,59 @@ static bool xD3D_run(int monid) return false; } +static bool xD3D_extoverlay(struct extoverlay *ext) +{ + struct d3dstruct *d3d = &d3ddata[0]; + D3DLOCKED_RECT locked; + HRESULT hr; + + if (ext->idx >= EXTOVERLAYS) + return false; + + write_log(_T("extoverlay %d: x=%d y=%d %d*%d\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height); + + struct d3d9overlay *s = &d3d->extoverlays[ext->idx]; + + if (!s->tex && (ext->width <= 0 || ext->height <= 0)) + return false; + + if (!ext->data && s->tex && (ext->width == 0 || ext->height == 0)) { + s->x = ext->xpos; + s->y = ext->ypos; + return true; + } + + if (s->tex) { + s->tex->Release(); + s->tex = NULL; + } + + if (ext->width <= 0 || ext->height <= 0) + return true; + + s->tex = createtext(d3d, ext->width, ext->height, D3DFMT_A8R8G8B8); + + if (!s->tex) + return false; + + s->x = ext->xpos; + s->y = ext->ypos; + + hr = s->tex->LockRect(0, &locked, NULL, 0); + if (FAILED(hr)) { + write_log(_T("extoverlay LockRect failed %08x\n"), hr); + s->tex->Release(); + s->tex = NULL; + return false; + } + for (int y = 0; y < ext->height; y++) { + memcpy((uae_u8*)locked.pBits + y * locked.Pitch, ext->data + y * ext->width * 4, ext->width * 4); + } + s->tex->UnlockRect(0); + + return true; +} + void d3d9_select(void) { D3D_free = xD3D_free; @@ -4142,6 +4218,7 @@ void d3d9_select(void) D3D_debug = xD3D_debug; D3D_led = xD3D_led; D3D_getscanline = xD3D_getscanline; + D3D_extoverlay = xD3D_extoverlay; } #endif diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index 88f2c443..dd7bd5da 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -4558,8 +4558,10 @@ static void xD3D11_refresh(int monid) return; createscanlines(d3d, 0); - if (xD3D11_renderframe(monid, true, true)) { - xD3D11_showframe(monid); + for (int i = 0; i < 2; i++) { + if (xD3D11_renderframe(monid, true, true)) { + xD3D11_showframe(monid); + } } clearcnt = 0; } @@ -5020,12 +5022,25 @@ static bool xD3D11_extoverlay(struct extoverlay *ext) if (ext->idx >= EXTOVERLAYS) return false; - write_log(_T("extoverlay %d: x=%d y=%d %d*%d\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height); + write_log(_T("extoverlay %d: x=%d y=%d %d*%d data=%p\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height, ext->data); struct d3d11sprite *s = &d3d->extoverlays[ext->idx]; + if (!s->enabled && (ext->width <= 0 || ext->height <= 0)) + return false; + + if (!ext->data && s->enabled && (ext->width == 0 || ext->height == 0)) { + s->x = ext->xpos; + s->y = ext->ypos; + return true; + } + freesprite(s); - if (!allocsprite(d3d, &d3d->extoverlays[ext->idx], ext->width, ext->height, true)) + + if (ext->width <= 0 || ext->height <= 0) + return true; + + if (!allocsprite(d3d, s, ext->width, ext->height, true)) return false; s->enabled = true; diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index c943fe2f..9a3e61b1 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -63,6 +63,8 @@ static DWORD storeflags; static int screenmode_request; static HWND guestwindow; static int hwndset_delay; +static int sendmouseevents; +static int mouseevent_x, mouseevent_y, mouseevent_buttons; static int cando (void) { @@ -114,6 +116,8 @@ static const TCHAR *getmsg (int msg) case RP_IPC_TO_HOST_HOSTVERSION: return _T("RP_IPC_TO_HOST_HOSTVERSION"); case RP_IPC_TO_HOST_INPUTDEVICE: return _T("RP_IPC_TO_HOST_INPUTDEVICE"); case RP_IPC_TO_HOST_KEYBOARDLAYOUT: return _T("RP_IPC_TO_HOST_KEYBOARDLAYOUT"); + case RP_IPC_TO_HOST_MOUSEMOVE: return _T("RP_IPC_TO_HOST_MOUSEMOVE"); + case RP_IPC_TO_HOST_MOUSEBUTTON: return _T("RP_IPC_TO_HOST_MOUSEBUTTON"); case RP_IPC_TO_GUEST_CLOSE: return _T("RP_IPC_TO_GUEST_CLOSE"); case RP_IPC_TO_GUEST_SCREENMODE: return _T("RP_IPC_TO_GUEST_SCREENMODE"); @@ -136,6 +140,9 @@ static const TCHAR *getmsg (int msg) case RP_IPC_TO_GUEST_SHOWOPTIONS: return _T("RP_IPC_TO_GUEST_SHOWOPTIONS"); case RP_IPC_TO_GUEST_DEVICEACTIVITY: return _T("RP_IPC_TO_GUEST_DEVICEACTIVITY"); case RP_IPC_TO_GUEST_SCREENOVERLAY: return _T("RP_IPC_TO_GUEST_SCREENOVERLAY"); + case RP_IPC_TO_GUEST_DELETESCREENOVERLAY: return _T("RP_IPC_TO_GUEST_DELETESCREENOVERLAY"); + case RP_IPC_TO_GUEST_MOVESCREENOVERLAY: return _T("RP_IPC_TO_GUEST_MOVESCREENOVERLAY"); + case RP_IPC_TO_GUEST_SENDMOUSEEVENTS: return _T("RP_IPC_TO_GUEST_SENDMOUSEEVENTS"); default: return _T("UNKNOWN"); } } @@ -1168,6 +1175,36 @@ void parse_guest_event(const TCHAR *ss) xfree(s); } +static int movescreenoverlay(WPARAM wParam, LPARAM lParam) +{ + struct extoverlay eo = { 0 }; + if (!D3D_extoverlay) + return 0; + eo.idx = wParam; + eo.xpos = LOWORD(lParam); + eo.ypos = HIWORD(lParam); + int ret = D3D_extoverlay(&eo); + if (pause_emulation) { + D3D_refresh(0); + } + return ret; +} + +static int deletescreenoverlay(WPARAM wParam) +{ + struct extoverlay eo = { 0 }; + if (!D3D_extoverlay) + return 0; + eo.idx = wParam; + eo.width = -1; + eo.height = -1; + int ret = D3D_extoverlay(&eo); + if (pause_emulation) { + D3D_refresh(0); + } + return ret; +} + static int screenoverlay(LPCVOID pData) { struct RPScreenOverlay *rpo = (struct RPScreenOverlay*)pData; @@ -1182,7 +1219,11 @@ static int screenoverlay(LPCVOID pData) eo.width = rpo->lWidth; eo.height = rpo->lHeight; eo.data = rpo->btData; - return D3D_extoverlay(&eo) ? 1 : 0; + int ret = D3D_extoverlay(&eo); + if (pause_emulation) { + D3D_refresh(0); + } + return ret; } static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM lParam, @@ -1407,6 +1448,18 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM return deviceactivity(wParam, lParam); case RP_IPC_TO_GUEST_SCREENOVERLAY: return screenoverlay(pData); + case RP_IPC_TO_GUEST_DELETESCREENOVERLAY: + return deletescreenoverlay(wParam); + case RP_IPC_TO_GUEST_MOVESCREENOVERLAY: + return movescreenoverlay(wParam, lParam); + case RP_IPC_TO_GUEST_SENDMOUSEEVENTS: + sendmouseevents = wParam; + if (sendmouseevents) { + LRESULT lr = NULL; + LPARAM lp = MAKELONG(mouseevent_x, mouseevent_y); + RPSendMessage(RP_IPC_TO_HOST_MOUSEMOVE, 0, lp, NULL, 0, &guestinfo, &lr); + } + return 1; } return FALSE; } @@ -1566,7 +1619,7 @@ static void sendfeatures (void) feat = RP_FEATURE_POWERLED | RP_FEATURE_SCREEN1X | RP_FEATURE_FULLSCREEN; feat |= RP_FEATURE_PAUSE | RP_FEATURE_TURBO_CPU | RP_FEATURE_TURBO_FLOPPY | RP_FEATURE_VOLUME | RP_FEATURE_SCREENCAPTURE; - feat |= RP_FEATURE_STATE | RP_FEATURE_DEVICEREADWRITE; + feat |= RP_FEATURE_STATE | RP_FEATURE_DEVICEREADWRITE | RP_FEATURE_SCREENOVERLAY; if (WIN32GFX_IsPicassoScreen(mon)) { if (currprefs.gfx_api) feat |= RP_FEATURE_SCREEN2X | RP_FEATURE_SCREEN3X | RP_FEATURE_SCREEN4X; @@ -1612,6 +1665,9 @@ void rp_fixup_options (struct uae_prefs *p) write_log (_T("rp_fixup_options(escapekey=%d,escapeholdtime=%d,screenmode=%d,inputmode=%d)\n"), rp_rpescapekey, rp_rpescapeholdtime, rp_screenmode, rp_inputmode); + sendmouseevents = 0; + mouseevent_x = mouseevent_y = 0; + mouseevent_buttons = 0; max_horiz_dbl = currprefs.gfx_max_horizontal; max_vert_dbl = currprefs.gfx_max_vertical; maxjports = (rp_version * 256 + rp_revision) >= 2 * 256 + 3 ? MAX_JPORTS : 2; @@ -2132,6 +2188,31 @@ USHORT rp_rawbuttons(LPARAM lParam, USHORT usButtonFlags) return usButtonFlags; } +bool rp_mouseevent(int x, int y, int buttons, int buttonmask) +{ + if (!sendmouseevents) { + if (x > -30000 && y > -30000) { + mouseevent_x = x; + mouseevent_y = y; + } + return false; + } + LRESULT lr; + if (x > -30000 && y > -30000 && (x != mouseevent_x || y != mouseevent_y)) { + LPARAM lParam = MAKELONG(x, y); + RPSendMessage(RP_IPC_TO_HOST_MOUSEMOVE, 0, lParam, NULL, 0, &guestinfo, &lr); + mouseevent_x = x; + mouseevent_y = y; + } + if (buttons >= 0 && (buttons & buttonmask) != (mouseevent_buttons & buttonmask)) { + LPARAM lParam = MAKELONG(mouseevent_x, mouseevent_y); + mouseevent_buttons &= ~buttonmask; + mouseevent_buttons |= buttons & buttonmask; + RPSendMessage(RP_IPC_TO_HOST_MOUSEBUTTON, mouseevent_buttons, lParam, NULL, 0, &guestinfo, &lr); + } + return true; +} + int rp_isactive (void) { return initialized; diff --git a/od-win32/rp.h b/od-win32/rp.h index 58aab764..d1a532c9 100644 --- a/od-win32/rp.h +++ b/od-win32/rp.h @@ -20,6 +20,7 @@ extern void rp_rtg_switch (void); extern void rp_screenmode_changed (void); extern void rp_keymap(TrapContext*, uaecptr, uae_u32); extern USHORT rp_rawbuttons(LPARAM lParam, USHORT usButtonFlags); +extern bool rp_mouseevent(int x, int y, int buttons, int buttonmask); extern TCHAR *rp_param; extern int rp_rpescapekey; diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 95575c58..6fabcef6 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -1880,6 +1880,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_LBUTTONUP: + rp_mouseevent(-32768, -32768, 0, 1); if (dinput_winmouse() >= 0 && isfocus()) { if (log_winmouse) write_log(_T("WM_LBUTTONUP\n")); @@ -1888,6 +1889,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: + rp_mouseevent(-32768, -32768, 1, 1); if (!mouseactive && !gui_active && (!mousehack_alive() || currprefs.input_tablet != TABLET_MOUSEHACK || (currprefs.input_tablet == TABLET_MOUSEHACK && !(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) || isfullscreen() > 0)) { // borderless = do not capture with single-click if (ignorelbutton) { @@ -1909,6 +1911,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, } return 0; case WM_RBUTTONUP: + rp_mouseevent(-32768, -32768, 0, 2); if (dinput_winmouse() >= 0 && isfocus()) { if (log_winmouse) write_log(_T("WM_RBUTTONUP\n")); @@ -1917,6 +1920,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + rp_mouseevent(-32768, -32768, 2, 2); if (dinput_winmouse() >= 0 && isfocus() > 0) { if (log_winmouse) write_log(_T("WM_RBUTTONDOWN\n")); @@ -1924,6 +1928,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, } return 0; case WM_MBUTTONUP: + rp_mouseevent(-32768, -32768, 0, 4); if (!(currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON)) { if (log_winmouse) write_log(_T("WM_MBUTTONUP\n")); @@ -1933,6 +1938,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: + rp_mouseevent(-32768, -32768, 4, 4); if (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) { activationtoggle(mon->monitor_id, true); } else { @@ -2147,6 +2153,10 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, if (log_winmouse) write_log (_T("WM_MOUSEMOVE MON=%d NUM=%d ACT=%d FOCUS=%d CLIP=%d CAP=%d FS=%d %dx%d %dx%d\n"), mon->monitor_id, wm, mouseactive, focus, mon_cursorclipped, recapture, isfullscreen (), mx, my, mon->mouseposx, mon->mouseposy); + + if (rp_mouseevent(mx, my, -1, -1)) + return 0; + mx -= mon->mouseposx; my -= mon->mouseposy;