[PATCH 0/3] MR10560: mciavi32: A couple of presentation fixes.
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/winmm/tests/mci.c | 90 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c index d4a131b1514..ed93c8c0d6e 100644 --- a/dlls/winmm/tests/mci.c +++ b/dlls/winmm/tests/mci.c @@ -1902,6 +1902,95 @@ static void test_avi_end_position(void) ok(ret, "Failed to delete %s, error %lu.\n", debugstr_w(filename), GetLastError()); } +static void test_scaling(HWND hwnd) +{ + const WCHAR *filename = load_resource(L"test.avi"); + static const RECT orig_rect = { 0, 0, 32, 24 }; + static const struct + { + BOOL parent; + DWORD style; + } + tests[] = + { + { TRUE, WS_CHILD }, + { TRUE, WS_POPUP }, + { FALSE, WS_POPUP }, + { TRUE, WS_POPUP | WS_CHILD }, + }; + static const SIZE sizes[] = + { + { 12, 12 }, + { 31, 48 }, + { 33, 25 }, + { 50, 50 }, + }; + + MCI_PARMS_UNION parm = { 0 }; + HWND video_window; + MCIDEVICEID id; + MCIERROR err; + DWORD open_flags; + RECT r, new_rect; + unsigned int i, j; + BOOL bret; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("test %d", i); + parm.dgv_open.lpstrDeviceType = (WCHAR *)L"AVIVideo"; + parm.dgv_open.lpstrElementName = (WCHAR *)filename; + parm.dgv_open.hWndParent = hwnd; + parm.dgv_open.dwStyle = tests[i].style; + open_flags = MCI_OPEN_ELEMENT | MCI_DGV_OPEN_WS | MCI_OPEN_TYPE; + if (tests[i].parent) + open_flags |= MCI_DGV_OPEN_PARENT; + + err = mciSendCommandW(0, MCI_OPEN, open_flags, (DWORD_PTR)&parm); + if (err == MCIERR_DEVICE_OPEN) + { + /* Sometimes on Testbot that won't open at once, needs some cooldown after previous tests. */ + Sleep(50); + err = mciSendCommandW(0, MCI_OPEN, open_flags, (DWORD_PTR)&parm); + } + ok(!err, "got %s.\n", dbg_mcierr(err)); + id = parm.dgv_open.wDeviceID; + + parm.status.dwItem = MCI_DGV_STATUS_HWND; + err = mciSendCommandA(id, MCI_STATUS, MCI_STATUS_ITEM, (DWORD_PTR)&parm); + ok(!err,"got %s\n", dbg_mcierr(err)); + video_window = (HWND)parm.status.dwReturn; + ok(!!video_window, "got NULL.\n"); + GetClientRect(video_window, &r); + ok(EqualRect(&r, &orig_rect), "got %s, expected %s.\n", wine_dbgstr_rect(&r), wine_dbgstr_rect(&orig_rect)); + + err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION | MCI_WAIT, (DWORD_PTR)&parm); + ok(!err, "got %s.\n", dbg_mcierr(err)); + ok(EqualRect(&parm.where.rc, &orig_rect), "got %s, expected %s.\n", wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&orig_rect)); + + for (j = 0; j < ARRAY_SIZE(sizes); ++j) + { + SetRect(&new_rect, 0, 0, sizes[j].cx, sizes[j].cy); + MoveWindow(video_window, 0, 0, new_rect.right, new_rect.bottom, FALSE); + + GetClientRect(video_window, &r); + ok(EqualRect(&r, &new_rect), "got %s, expected %s.\n", wine_dbgstr_rect(&r), wine_dbgstr_rect(&new_rect)); + /* There might be a delay between window size change and the change in destination rectangle on Windows. */ + Sleep(30); + err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION | MCI_WAIT, (DWORD_PTR)&parm); + ok(!err, "Got %s.\n", dbg_mcierr(err)); + todo_wine ok(EqualRect(&parm.where.rc, &new_rect), "got %s, expected %s.\n", + wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&new_rect)); + } + err = mciSendCommandW(id, MCI_CLOSE, 0, 0); + ok(!err, "Got %s.\n", dbg_mcierr(err)); + winetest_pop_context(); + } + + bret = DeleteFileW(filename); + ok(bret, "Got error %lu.\n", GetLastError()); +} + START_TEST(mci) { char curdir[MAX_PATH], tmpdir[MAX_PATH]; @@ -1924,6 +2013,7 @@ START_TEST(mci) test_AutoOpenWAVE(hwnd); test_playTypeMpegvideo(hwnd); test_asyncWaveTypeMpegvideo(hwnd); + test_scaling(hwnd); }else skip("No output devices available, skipping all output tests\n"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10560
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/mciavi32/wnd.c | 14 ++++++++++++++ dlls/winmm/tests/mci.c | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dlls/mciavi32/wnd.c b/dlls/mciavi32/wnd.c index 643478f018d..bf3b23e393a 100644 --- a/dlls/mciavi32/wnd.c +++ b/dlls/mciavi32/wnd.c @@ -78,6 +78,20 @@ static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA } return 1; + case WM_SIZE: + { + WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongW(hWnd, 0)); + + if (!wma) + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + + EnterCriticalSection(&wma->cs); + wma->dest.right = LOWORD(lParam); + wma->dest.bottom = HIWORD(lParam); + LeaveCriticalSection(&wma->cs); + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + default: return DefWindowProcW(hWnd, uMsg, wParam, lParam); } diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c index ed93c8c0d6e..64121421aca 100644 --- a/dlls/winmm/tests/mci.c +++ b/dlls/winmm/tests/mci.c @@ -1979,7 +1979,7 @@ static void test_scaling(HWND hwnd) Sleep(30); err = mciSendCommandW(id, MCI_WHERE, MCI_DGV_WHERE_DESTINATION | MCI_WAIT, (DWORD_PTR)&parm); ok(!err, "Got %s.\n", dbg_mcierr(err)); - todo_wine ok(EqualRect(&parm.where.rc, &new_rect), "got %s, expected %s.\n", + ok(EqualRect(&parm.where.rc, &new_rect), "got %s, expected %s.\n", wine_dbgstr_rect(&parm.where.rc), wine_dbgstr_rect(&new_rect)); } err = mciSendCommandW(id, MCI_CLOSE, 0, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10560
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/mciavi32/mciavi.c | 2 ++ dlls/mciavi32/mmoutput.c | 17 +++++++++++------ dlls/mciavi32/private_mciavi.h | 2 ++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dlls/mciavi32/mciavi.c b/dlls/mciavi32/mciavi.c index 5706b60472b..cf0dbe54712 100644 --- a/dlls/mciavi32/mciavi.c +++ b/dlls/mciavi32/mciavi.c @@ -175,6 +175,8 @@ static void MCIAVI_CleanUp(WINE_MCIAVI* wma) free(wma->lpFileName); wma->lpFileName = NULL; + DrawDibClose(wma->hdd); + free(wma->lpVideoIndex); wma->lpVideoIndex = NULL; free(wma->lpAudioIndex); diff --git a/dlls/mciavi32/mmoutput.c b/dlls/mciavi32/mmoutput.c index 1a3945a60cd..b064d151b46 100644 --- a/dlls/mciavi32/mmoutput.c +++ b/dlls/mciavi32/mmoutput.c @@ -472,6 +472,14 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma) } paint_frame: + if (!(wma->hdd = DrawDibOpen())) + { + ERR("DrawDibOpen() failed.\n"); + free(wma->outdata); + wma->outdata = NULL; + return FALSE; + } + hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0; if (hDC) { @@ -631,12 +639,9 @@ double MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) pBitmapInfo = (LPBITMAPINFO)wma->inbih; } - StretchDIBits(hDC, - wma->dest.left, wma->dest.top, - wma->dest.right - wma->dest.left, wma->dest.bottom - wma->dest.top, - wma->source.left, wma->source.top, - wma->source.right - wma->source.left, wma->source.bottom - wma->source.top, - pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY); + DrawDibDraw(wma->hdd, hDC, wma->dest.left, wma->dest.top, wma->dest.right - wma->dest.left, wma->dest.bottom - wma->dest.top, + &pBitmapInfo->bmiHeader, pBitmapData, + wma->source.left, wma->source.top, wma->source.right - wma->source.left, wma->source.bottom - wma->source.top, 0); return (wma->ash_video.dwScale / (double)wma->ash_video.dwRate) * 1000000; } diff --git a/dlls/mciavi32/private_mciavi.h b/dlls/mciavi32/private_mciavi.h index 806804714a5..32c6189cdcc 100644 --- a/dlls/mciavi32/private_mciavi.h +++ b/dlls/mciavi32/private_mciavi.h @@ -84,6 +84,8 @@ typedef struct { /* data for the background mechanism */ CRITICAL_SECTION cs; HANDLE hStopEvent; + /* data for presentation */ + HDRAWDIB hdd; } WINE_MCIAVI; extern HINSTANCE MCIAVI_hInstance; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10560
Fixes small and displaced intro videos in Resident Evil (1996). The game has 320x240 videos. By default the game is started in native resolution and ddraw.dll shipped alongside the game fixes some compatibility issues (without that it fails to start on Windows the same way as on Wine), along with scaling to native resolution. After doing MCI_OPEN the game gets MCI window and resizes it to 639x479 centered withing the parent main window. That currently has no effect on Wine's rendering size and is fixed by patch 2. Then, while video becomes bigger and centered it is still too small, on Windows it is fullscreen. The shipped ddraw.dll not only scales through ddraw API but also hotpatches StretchBlt and scales that also in some way. But mciavi32 uses StretchDIBits currently which is not hotpatched. So most likely Windows is not using StretchDIBits there in MCI. That is already implemented in compatible way in msvfw32 and msvfw32 is used from mciavi32, so just using msvfw32 presentation function looks most straightforward. I omitted the tests with overlapped windows because the resulting size of the window is hardly predictable both on Windows and Wine. While MCI destination rectangle changes for those as well. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10560#note_135011
participants (2)
-
Paul Gofman -
Paul Gofman (@gofman)