From: Toni Wilen Date: Sun, 4 Nov 2018 14:22:25 +0000 (+0200) Subject: RP overlay/mouse event updates. X-Git-Tag: 4100~38 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=d4c6e5c967cf9fde3b7be6c69ec3224883eb4c25;p=francis%2Fwinuae.git RP overlay/mouse event updates. --- diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index 1260ae5c..2dcfc7de 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -2162,6 +2162,8 @@ static void handle_rawinput_2 (RAWINPUT *raw, LPARAM lParam) if (num == num_mouse) return; + if (rp_ismouseevent()) + return; if (isfocus () > 0 || istest) { static int lastx[MAX_INPUT_DEVICES], lasty[MAX_INPUT_DEVICES]; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 6285ca21..66c92c5e 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -130,6 +130,8 @@ struct shaderdata struct d3d9overlay { + struct d3d9overlay *next; + int id; int x, y; LPDIRECT3DTEXTURE9 tex; }; @@ -161,7 +163,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]; + struct d3d9overlay *extoverlays; IDirect3DVertexBuffer9 *vertexBuffer; ID3DXSprite *sprite; HWND d3dhwnd; @@ -2424,13 +2426,15 @@ 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; - } + struct d3d9overlay *ov = d3d->extoverlays; + while (ov) { + struct d3d9overlay *next = ov->next; + if (ov->tex) + ov->tex->Release(); + xfree(ov); + ov = next; } + d3d->extoverlays = NULL; for (int i = 0; i < MAX_SHADERS; i++) { if (d3d->shaders[i].pEffect) { d3d->shaders[i].pEffect->Release (); @@ -3710,14 +3714,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; + struct d3d9overlay *ov = d3d->extoverlays; + while (ov) { + if (ov->tex) { + v.x = ov->x; + v.y = ov->y; v.z = 0; - d3d->sprite->Draw(o->tex, NULL, NULL, &v, 0xffffffff); + d3d->sprite->Draw(ov->tex, NULL, NULL, &v, 0xffffffff); } + ov = ov->next; } d3d->sprite->End(); } @@ -4139,52 +4144,86 @@ static bool xD3D_run(int monid) static bool xD3D_extoverlay(struct extoverlay *ext) { struct d3dstruct *d3d = &d3ddata[0]; + struct d3d9overlay *ov, *ovprev, *ov2; + LPDIRECT3DTEXTURE9 s; 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); + s = NULL; + ov = d3d->extoverlays; + ovprev = NULL; + while (ov) { + if (ov->id == ext->idx) { + s = ov->tex; + break; + } + ovprev = ov; + ov = ov->next; + } - struct d3d9overlay *s = &d3d->extoverlays[ext->idx]; + write_log(_T("extoverlay %d: x=%d y=%d %d*%d data=%p ovl=%p\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height, ext->data, ov); - if (!s->tex && (ext->width <= 0 || ext->height <= 0)) + if (!s && (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; + if (!ext->data && s && (ext->width == 0 || ext->height == 0)) { + ov->x = ext->xpos; + ov->y = ext->ypos; return true; } - if (s->tex) { - s->tex->Release(); - s->tex = NULL; + if (ov && s) { + if (ovprev) { + ovprev->next = ov->next; + } else { + d3d->extoverlays = ov->next; + } + s->Release(); + xfree(ov); + if (ext->width <= 0 || ext->height <= 0) + return true; } if (ext->width <= 0 || ext->height <= 0) - return true; - - s->tex = createtext(d3d, ext->width, ext->height, D3DFMT_A8R8G8B8); + return false; - if (!s->tex) + ov = xcalloc(d3d9overlay, 1); + s = createtext(d3d, ext->width, ext->height, D3DFMT_A8R8G8B8); + if (!s) { + xfree(ov); return false; + } - s->x = ext->xpos; - s->y = ext->ypos; + ov->tex = s; + ov->id = ext->idx; - 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; + ov2 = d3d->extoverlays; + ovprev = NULL; + for (;;) { + if (ov2 == NULL || ov2->id >= ov->id) { + if (ov2 == d3d->extoverlays) { + d3d->extoverlays = ov; + ov->next = ov2; + } else { + ov->next = ovprev->next; + ovprev->next = ov; + } + break; + } + ovprev = ov2; + ov2 = ov2->next; } - 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); + + ov->x = ext->xpos; + ov->y = ext->ypos; + + hr = s->LockRect(0, &locked, NULL, 0); + if (SUCCEEDED(hr)) { + 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->UnlockRect(0); } - s->tex->UnlockRect(0); return true; } diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 3d2dafa9..9f4ce5e0 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -1,5 +1,4 @@ -#define EXTOVERLAYS 4 struct extoverlay { int idx; diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index dd7bd5da..74221773 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -193,6 +193,13 @@ struct d3d11sprite bool bilinear; }; +struct d3doverlay +{ + struct d3doverlay *next; + int id; + struct d3d11sprite s; +}; + struct d3d11struct { IDXGISwapChain1 *m_swapChain; @@ -273,7 +280,7 @@ struct d3d11struct int mask2textureledoffsets[9 * 2]; struct d3d11sprite blanksprite; - struct d3d11sprite extoverlays[EXTOVERLAYS]; + struct d3doverlay *extoverlays; float mask2texture_w, mask2texture_h, mask2texture_ww, mask2texture_wh; float mask2texture_wwx, mask2texture_hhx, mask2texture_minusx, mask2texture_minusy; @@ -1657,6 +1664,8 @@ static void FreeTexture2D(ID3D11Texture2D **t, ID3D11ShaderResourceView **v) static void freesprite(struct d3d11sprite *s) { + if (!s) + return; FreeTexture2D(&s->texture, &s->texturerv); if (s->pixelshader) @@ -1732,10 +1741,14 @@ static void FreeTextures(struct d3d11struct *d3d) } freesprite(&d3d->mask2textureled_power_dim); freesprite(&d3d->blanksprite); - for (int i = 0; i < EXTOVERLAYS; i++) { - freesprite(&d3d->extoverlays[i]); - } - + struct d3doverlay *ov = d3d->extoverlays; + while (ov) { + struct d3doverlay *next = ov->next; + freesprite(&ov->s); + xfree(ov); + ov = next; + } + d3d->extoverlays = NULL; for (int i = 0; i < MAX_SHADERS; i++) { freeshaderdata(&d3d->shaders[i]); } @@ -4238,9 +4251,10 @@ static bool TextureShaderClass_Render(struct d3d11struct *d3d) RenderSprite(d3d, &d3d->osd); - for (int i = 0; i < EXTOVERLAYS; i++) { - if (d3d->extoverlays[i].enabled) - RenderSprite(d3d, &d3d->extoverlays[i]); + struct d3doverlay *ov = d3d->extoverlays; + while (ov) { + RenderSprite(d3d, &ov->s); + ov = ov->next; } return true; @@ -5016,50 +5030,88 @@ static bool xD3D11_run(int monid) static bool xD3D11_extoverlay(struct extoverlay *ext) { struct d3d11struct *d3d = &d3d11data[0]; + struct d3doverlay *ov, *ovprev, *ov2; + struct d3d11sprite *s; D3D11_MAPPED_SUBRESOURCE map; HRESULT hr; - if (ext->idx >= EXTOVERLAYS) - return false; - - 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); + s = NULL; + ov = d3d->extoverlays; + ovprev = NULL; + while (ov) { + if (ov->id == ext->idx) { + s = &ov->s; + break; + } + ovprev = ov; + ov = ov->next; + } - struct d3d11sprite *s = &d3d->extoverlays[ext->idx]; + write_log(_T("extoverlay %d: x=%d y=%d %d*%d data=%p ovl=%p\n"), ext->idx, ext->xpos, ext->ypos, ext->width, ext->height, ext->data, ov); - if (!s->enabled && (ext->width <= 0 || ext->height <= 0)) + if (!s && (ext->width <= 0 || ext->height <= 0)) return false; - if (!ext->data && s->enabled && (ext->width == 0 || ext->height == 0)) { + if (!ext->data && s && (ext->width == 0 || ext->height == 0)) { s->x = ext->xpos; s->y = ext->ypos; return true; } - freesprite(s); + if (ov && s) { + if (ovprev) { + ovprev->next = ov->next; + } else { + d3d->extoverlays = ov->next; + } + freesprite(s); + xfree(ov); + if (ext->width <= 0 || ext->height <= 0) + return true; + } if (ext->width <= 0 || ext->height <= 0) - return true; + return false; + + ov = xcalloc(d3doverlay, 1); + s = &ov->s; - if (!allocsprite(d3d, s, ext->width, ext->height, true)) + if (!allocsprite(d3d, s, ext->width, ext->height, true)) { + xfree(ov); return false; + } + + ov->id = ext->idx; + + ov2 = d3d->extoverlays; + ovprev = NULL; + for(;;) { + if (ov2 == NULL || ov2->id >= ov->id) { + if (ov2 == d3d->extoverlays) { + d3d->extoverlays = ov; + ov->next = ov2; + } else { + ov->next = ovprev->next; + ovprev->next = ov; + } + break; + } + ovprev = ov2; + ov2 = ov2->next; + } s->enabled = true; s->x = ext->xpos; s->y = ext->ypos; hr = d3d->m_deviceContext->Map(s->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - if (FAILED(hr)) { - write_log(_T("extoverlay Map failed %08x\n"), hr); - freesprite(s); - return false; - } - - for (int y = 0; y < s->height; y++) { - memcpy((uae_u8*)map.pData + y * map.RowPitch, ext->data + y * ext->width * 4, ext->width * 4); + if (SUCCEEDED(hr)) { + for (int y = 0; y < s->height; y++) { + memcpy((uae_u8*)map.pData + y * map.RowPitch, ext->data + y * ext->width * 4, ext->width * 4); + } + d3d->m_deviceContext->Unmap(s->texture, 0); } - d3d->m_deviceContext->Unmap(s->texture, 0); - return true; } diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index 9a3e61b1..4e3187a7 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -1619,7 +1619,9 @@ 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 | RP_FEATURE_SCREENOVERLAY; + feat |= RP_FEATURE_STATE | RP_FEATURE_DEVICEREADWRITE; + if (currprefs.gfx_api) + feat |= RP_FEATURE_SCREENOVERLAY; if (WIN32GFX_IsPicassoScreen(mon)) { if (currprefs.gfx_api) feat |= RP_FEATURE_SCREEN2X | RP_FEATURE_SCREEN3X | RP_FEATURE_SCREEN4X; @@ -2188,8 +2190,55 @@ USHORT rp_rawbuttons(LPARAM lParam, USHORT usButtonFlags) return usButtonFlags; } +bool rp_ismouseevent(void) +{ + return sendmouseevents != 0; +} + bool rp_mouseevent(int x, int y, int buttons, int buttonmask) { +#if 0 + uae_u8 *data; + static int ovl_idx = 10; + static int ovl_add; + if (buttons > 0 && (buttons & 1)) { + data = xcalloc(uae_u8, 10 * 10 * 4); + for (int i = 0; i < 10 * 10; i++) { + data[i * 4 + 0] = 0xff; + data[i * 4 + 1] = 0xff; + data[i * 4 + 2] = 0x00; + data[i * 4 + 3] = 0xff; + } + + struct extoverlay eo = { 0 }; + eo.idx = ovl_idx; + eo.xpos = 100 + ovl_idx * 50; + eo.ypos = 100; + eo.width = 10; + eo.height = 10; + eo.data = data; + int ret = D3D_extoverlay(&eo); + ovl_idx--; + } + if (buttons > 0 && (buttons & 2)) { + struct extoverlay eo = { 0 }; + ovl_idx++; + eo.idx = ovl_idx; + eo.width = -1; + eo.height = -1; + int ret = D3D_extoverlay(&eo); + } + + for (int i = 0; i < ovl_idx; i++) { + struct extoverlay eo = { 0 }; + eo.idx = i; + eo.xpos = 100 + i * 50; + eo.ypos = 100 + ovl_add * (i + 1); + int ret = D3D_extoverlay(&eo); + } + ovl_add++; +#endif + if (!sendmouseevents) { if (x > -30000 && y > -30000) { mouseevent_x = x; diff --git a/od-win32/rp.h b/od-win32/rp.h index d1a532c9..987976a9 100644 --- a/od-win32/rp.h +++ b/od-win32/rp.h @@ -21,6 +21,7 @@ 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 bool rp_ismouseevent(void); extern TCHAR *rp_param; extern int rp_rpescapekey; diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 6fabcef6..34ad3855 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -1880,77 +1880,83 @@ 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")); - setmousebuttonstate(dinput_winmouse(), 0, 0); + if (!rp_mouseevent(-32768, -32768, 0, 1)) { + if (dinput_winmouse() >= 0 && isfocus()) { + if (log_winmouse) + write_log(_T("WM_LBUTTONUP\n")); + setmousebuttonstate(dinput_winmouse(), 0, 0); + } } 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) { - ignorelbutton = 0; - if (currprefs.win32_borderless) + if (!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) { + ignorelbutton = 0; + if (currprefs.win32_borderless) + return 0; + } + if (message == WM_LBUTTONDOWN && isfullscreen() == 0 && currprefs.win32_borderless && !rp_isactive()) { + // full-window drag + SendMessage(mon->hAmigaWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); return 0; + } + if (!pause_emulation || currprefs.win32_active_nocapture_pause) + setmouseactive(mon->monitor_id, (message == WM_LBUTTONDBLCLK || isfullscreen() > 0) ? 2 : 1); + } else if (dinput_winmouse() >= 0 && isfocus()) { + if (log_winmouse) + write_log(_T("WM_LBUTTONDOWN\n")); + setmousebuttonstate(dinput_winmouse(), 0, 1); } - if (message == WM_LBUTTONDOWN && isfullscreen() == 0 && currprefs.win32_borderless && !rp_isactive()) { - // full-window drag - SendMessage(mon->hAmigaWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); - return 0; - } - if (!pause_emulation || currprefs.win32_active_nocapture_pause) - setmouseactive(mon->monitor_id, (message == WM_LBUTTONDBLCLK || isfullscreen() > 0) ? 2 : 1); - } else if (dinput_winmouse() >= 0 && isfocus()) { - if (log_winmouse) - write_log(_T("WM_LBUTTONDOWN\n")); - setmousebuttonstate(dinput_winmouse(), 0, 1); } 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")); - setmousebuttonstate(dinput_winmouse(), 1, 0); + if (!rp_mouseevent(-32768, -32768, 0, 2)) { + if (dinput_winmouse() >= 0 && isfocus()) { + if (log_winmouse) + write_log(_T("WM_RBUTTONUP\n")); + setmousebuttonstate(dinput_winmouse(), 1, 0); + } } 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")); - setmousebuttonstate(dinput_winmouse(), 1, 1); + if (!rp_mouseevent(-32768, -32768, 2, 2)) { + if (dinput_winmouse() >= 0 && isfocus() > 0) { + if (log_winmouse) + write_log(_T("WM_RBUTTONDOWN\n")); + setmousebuttonstate(dinput_winmouse(), 1, 1); + } } 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")); - if (dinput_winmouse() >= 0 && isfocus()) - setmousebuttonstate(dinput_winmouse(), 2, 0); + if (!rp_mouseevent(-32768, -32768, 0, 4)) { + if (!(currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON)) { + if (log_winmouse) + write_log(_T("WM_MBUTTONUP\n")); + if (dinput_winmouse() >= 0 && isfocus()) + setmousebuttonstate(dinput_winmouse(), 2, 0); + } } 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 { - if (dinput_winmouse() >= 0 && isfocus() > 0) { - if (log_winmouse) - write_log(_T("WM_MBUTTONDOWN\n")); - setmousebuttonstate(dinput_winmouse(), 2, 1); + if (!rp_mouseevent(-32768, -32768, 4, 4)) { + if (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) { + activationtoggle(mon->monitor_id, true); + } else { + if (dinput_winmouse() >= 0 && isfocus() > 0) { + if (log_winmouse) + write_log(_T("WM_MBUTTONDOWN\n")); + setmousebuttonstate(dinput_winmouse(), 2, 1); + } } } return 0; case WM_XBUTTONUP: - if (dinput_winmouse() >= 0 && isfocus()) { + if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus()) { if (log_winmouse) write_log(_T("WM_XBUTTONUP %08x\n"), wParam); handleXbutton(wParam, 0); @@ -1959,7 +1965,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: - if (dinput_winmouse() >= 0 && isfocus() > 0) { + if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus() > 0) { if (log_winmouse) write_log(_T("WM_XBUTTONDOWN %08x\n"), wParam); handleXbutton(wParam, 1); @@ -1967,7 +1973,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, } return 0; case WM_MOUSEWHEEL: - if (dinput_winmouse() >= 0 && isfocus() > 0) { + if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus() > 0) { int val = ((short)HIWORD(wParam)); if (log_winmouse) write_log(_T("WM_MOUSEWHEEL %08x\n"), wParam); @@ -1980,7 +1986,7 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, } return 0; case WM_MOUSEHWHEEL: - if (dinput_winmouse() >= 0 && isfocus() > 0) { + if (!rp_ismouseevent() && dinput_winmouse() >= 0 && isfocus() > 0) { int val = ((short)HIWORD(wParam)); if (log_winmouse) write_log(_T("WM_MOUSEHWHEEL %08x\n"), wParam);