]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
D3D overlay graphics updates.
authorToni Wilen <twilen@winuae.net>
Sat, 20 Oct 2018 11:56:31 +0000 (14:56 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 20 Oct 2018 11:56:31 +0000 (14:56 +0300)
od-win32/cloanto/RetroPlatformIPC-doc.txt
od-win32/cloanto/RetroPlatformIPC.h
od-win32/direct3d.cpp
od-win32/direct3d11.cpp
od-win32/rp.cpp
od-win32/rp.h
od-win32/win32.cpp

index 8e8c738ef3b0f9887e1ee54e2a62a06708c0b1d7..5be3282517ade4081a763f54600cf693aef2cb18 100644 (file)
@@ -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
index f0bf9ddbd615f21672241877238ecf7edb74e43b..39b7f02d885c50c390e504824269a8ddde56da5b 100644 (file)
@@ -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
 #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
 #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
index 4f49612582954fcdd5c818624eea23affecbc399..6285ca21e1cf89e327c280b7390cc6abf845da1f 100644 (file)
@@ -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
index 88f2c443bea55d86a0bf45b7a1e09af02fe72e93..dd7bd5da1c56722d8838eac4be0b34789042d774 100644 (file)
@@ -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;
index c943fe2f7a3a0f6920f636d2d71218d78245bb47..9a3e61b1ed84589d007f3c529b1d9080dbb8215e 100644 (file)
@@ -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;
index 58aab764e95a21d1a694b3f923ecee797583e0bc..d1a532c9166c7d95c152019f35f6fd9e4d5fa177 100644 (file)
@@ -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;
index 95575c58ae2e4d042b22744eced27ad93346012e..6fabcef66c78c770ef1548781844ff5c9167a506 100644 (file)
@@ -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;