From 47d163d152fc8c0603a99c69a178179ad406a5f4 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 18 Apr 2018 21:21:07 +0300 Subject: [PATCH] Full-window virtual multi-monitor support. --- main.cpp | 4 +-- od-win32/direct3d.cpp | 20 +++++++------- od-win32/direct3d11.cpp | 9 ++++--- od-win32/dxwrap.cpp | 2 +- od-win32/dxwrap.h | 1 + od-win32/rp.cpp | 2 +- od-win32/win32.cpp | 2 +- od-win32/win32_scaler.cpp | 8 +++--- od-win32/win32gfx.cpp | 55 +++++++++++++++++++++++++++++---------- od-win32/win32gfx.h | 2 +- od-win32/win32gui.cpp | 21 ++++++++------- 11 files changed, 79 insertions(+), 47 deletions(-) diff --git a/main.cpp b/main.cpp index 4acd8004..8aefd56f 100644 --- a/main.cpp +++ b/main.cpp @@ -416,9 +416,9 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig) rbc->monitor_id = 0; error_log(_T("Multi virtual monitor support requires Direct3D mode.")); } - if (isfullscreen() != 0) { + if (isfullscreen() > 0) { rbc->monitor_id = 0; - error_log(_T("Multi virtual monitor support requires windowed mode.")); + error_log(_T("Multi virtual monitor support is not available in fullscreen mode.")); } } if (rbc->rtgmem_size > max_z3fastmem && rbc->rtgmem_type == GFXBOARD_UAE_Z3) { diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 70848837..50f8dc07 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -245,34 +245,34 @@ static int ddraw_fs_hack_init (struct d3dstruct *d3d) HRESULT hr; struct MultiDisplay *md; - ddraw_fs_hack_free (d3d); - DirectDraw_get_GUIDs (); - md = getdisplay (&currprefs); + ddraw_fs_hack_free(d3d); + DirectDraw_get_GUIDs(); + md = getdisplay(&currprefs, 0); if (!md) return 0; - hr = DirectDrawCreateEx (md->primary ? NULL : &md->ddguid, (LPVOID*)&d3d->ddraw, IID_IDirectDraw7, NULL); + hr = DirectDrawCreateEx(md->primary ? NULL : &md->ddguid, (LPVOID*)&d3d->ddraw, IID_IDirectDraw7, NULL); if (FAILED (hr)) { write_log (_T("DirectDrawCreateEx failed, %s\n"), DXError (hr)); return 0; } d3d->ddraw_fs = 1; - hr = d3d->ddraw->SetCooperativeLevel (d3d->d3dhwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = d3d->ddraw->SetCooperativeLevel(d3d->d3dhwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (hr)) { write_log (_T("IDirectDraw7_SetCooperativeLevel SET: %s\n"), DXError (hr)); ddraw_fs_hack_free (d3d); return 0; } - hr = d3d->ddraw->SetDisplayMode (d3d->dpp.BackBufferWidth, d3d->dpp.BackBufferHeight, d3d->t_depth, d3d->dpp.FullScreen_RefreshRateInHz, 0); + hr = d3d->ddraw->SetDisplayMode(d3d->dpp.BackBufferWidth, d3d->dpp.BackBufferHeight, d3d->t_depth, d3d->dpp.FullScreen_RefreshRateInHz, 0); if (FAILED (hr)) { write_log (_T("1:IDirectDraw7_SetDisplayMode: %s\n"), DXError (hr)); if (d3d->dpp.FullScreen_RefreshRateInHz && isvsync_chipset () < 0) { - hr = d3d->ddraw->SetDisplayMode (d3d->dpp.BackBufferWidth, d3d->dpp.BackBufferHeight, d3d->t_depth, 0, 0); + hr = d3d->ddraw->SetDisplayMode(d3d->dpp.BackBufferWidth, d3d->dpp.BackBufferHeight, d3d->t_depth, 0, 0); if (FAILED (hr)) write_log (_T("2:IDirectDraw7_SetDisplayMode: %s\n"), DXError (hr)); } if (FAILED (hr)) { write_log (_T("IDirectDraw7_SetDisplayMode: %s\n"), DXError (hr)); - ddraw_fs_hack_free (d3d); + ddraw_fs_hack_free(d3d); return 0; } } @@ -1641,7 +1641,7 @@ static int createmask2texture (struct d3dstruct *d3d, const TCHAR *filename) d3d->mask2texture_offsetw = 0; if (isfullscreen () > 0) { - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, mon->monitor_id); float deskw = md->rect.right - md->rect.left; float deskh = md->rect.bottom - md->rect.top; //deskw = 800; deskh = 600; @@ -2351,7 +2351,7 @@ static void xD3D_vblank_reset (double freq) static int getd3dadapter (IDirect3D9 *id3d) { - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, 0); int num = id3d->GetAdapterCount (); HMONITOR winmon; POINT pt; diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index 231a13ae..51edfb92 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -2496,7 +2496,7 @@ static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) d3d->mask2texture_offsetw = 0; if (isfs(d3d) > 0) { - struct MultiDisplay *md = getdisplay(&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, mon->monitor_id); float deskw = md->rect.right - md->rect.left; float deskh = md->rect.bottom - md->rect.top; //deskw = 800; deskh = 600; @@ -3127,12 +3127,15 @@ static void do_present(struct d3d11struct *d3d, int black) syncinterval = 0; } if (currprefs.turbo_emulation) { - presentFlags |= DXGI_PRESENT_DO_NOT_WAIT; + if (os_win8) + presentFlags |= DXGI_PRESENT_DO_NOT_WAIT; syncinterval = 0; } d3d->syncinterval = syncinterval; hr = d3d->m_swapChain->Present(syncinterval, presentFlags); + if (FAILED(hr)) + write_log(_T("%08x\n"), hr); if (currprefs.turbo_emulation && hr == DXGI_ERROR_WAS_STILL_DRAWING) hr = S_OK; if (FAILED(hr) && hr != DXGI_STATUS_OCCLUDED) { @@ -3209,7 +3212,7 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t d3d->scrformat = DXGI_FORMAT_B8G8R8A8_UNORM; d3d->dmultx = mmult; - struct MultiDisplay *md = getdisplay(&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, monid); POINT pt; pt.x = (md->rect.right - md->rect.left) / 2 + md->rect.left; pt.y = (md->rect.bottom - md->rect.top) / 2 + md->rect.top; diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index 88bcf545..f8f3ff9b 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -1207,7 +1207,7 @@ int DirectDraw_Start (void) guid = NULL; if (isfullscreen ()) { - MultiDisplay *md = getdisplay (&currprefs); + MultiDisplay *md = getdisplay(&currprefs, 0); int disp = md - Displays; if (disp < 0) disp = 0; diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 87277764..c29e56fa 100644 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -104,6 +104,7 @@ struct AmigaMonitor { int monitor_id; HWND hAmigaWnd; HWND hMainWnd; + struct MultiDisplay *md; RECT amigawin_rect, mainwin_rect; RECT amigawinclip_rect; diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index cc4398b5..549c6028 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -874,7 +874,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) fs = 1; } p->gf[0].gfx_filter_autoscale = AUTOSCALE_CENTER; - disp = getdisplay (p); + disp = getdisplay(p, 0); if (log_rp & 2) { write_log (_T("SET_RPSM: %08X %dx%d %dx%d hres=%d vres=%d disp=%d fs=%d smm=%d\n"), diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 9a838637..c33f05f8 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -3879,7 +3879,7 @@ void target_fixup_options (struct uae_prefs *p) nojoy = true; } - struct MultiDisplay *md = getdisplay (p); + struct MultiDisplay *md = getdisplay(p, 0); for (int j = 0; j < MAX_AMIGADISPLAYS; j++) { if (p->gfx_monitor[j].gfx_size_fs.special == WH_NATIVE) { int i; diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 1bf87066..b83c2fc7 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -64,10 +64,10 @@ void getfilteroffset(int monid, float *dx, float *dy, float *mx, float *my) *my = filterymult; } -static void getinit (void) +static void getinit(int monid) { - if (isfullscreen ()) { - struct MultiDisplay *md = getdisplay (&currprefs); + if (isfullscreen()) { + struct MultiDisplay *md = getdisplay(&currprefs, monid); deskw = md->rect.right - md->rect.left; deskh = md->rect.bottom - md->rect.top; @@ -262,7 +262,7 @@ void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int fpux_save (&fpuv); - getinit (); + getinit(monid); aws = aw * scale; ahs = ah * scale; //write_log (_T("%d %d %d\n"), dst_width, temp_width, aws); diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 0733b49e..2db058d1 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -190,15 +190,18 @@ static struct MultiDisplay *getdisplay2(struct uae_prefs *p, int index) display = 0; return &Displays[display]; } -struct MultiDisplay *getdisplay (struct uae_prefs *p) +struct MultiDisplay *getdisplay(struct uae_prefs *p, int monid) { + struct AmigaMonitor *mon = &AMonitors[monid]; + if (monid > 0 && mon->md) + return mon->md; return getdisplay2(p, -1); } void desktop_coords(int monid, int *dw, int *dh, int *ax, int *ay, int *aw, int *ah) { struct AmigaMonitor *mon = &AMonitors[monid]; - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, monid); *dw = md->rect.right - md->rect.left; *dh = md->rect.bottom - md->rect.top; @@ -337,7 +340,7 @@ int target_get_display_scanline(int displayindex) { if (pD3DKMTGetScanLine) { D3DKMT_GETSCANLINE sl = { 0 }; - struct MultiDisplay *md = displayindex < 0 ? getdisplay(&currprefs) : &Displays[displayindex]; + struct MultiDisplay *md = displayindex < 0 ? getdisplay(&currprefs, 0) : &Displays[displayindex]; if (!md->HasAdapterData) return -11; sl.VidPnSourceId = md->VidPnSourceId; @@ -383,7 +386,7 @@ static bool get_display_vblank_params(int displayindex, int *activeheightp, int pDisplayConfigGetDeviceInfo = (DISPLAYCONFIGGETDEVICEINFO)GetProcAddress(GetModuleHandle(_T("user32.dll")), "DisplayConfigGetDeviceInfo"); if (!pQueryDisplayConfig || !pGetDisplayConfigBufferSizes || !pDisplayConfigGetDeviceInfo) return false; - struct MultiDisplay *md = displayindex < 0 ? getdisplay (&currprefs) : &Displays[displayindex]; + struct MultiDisplay *md = displayindex < 0 ? getdisplay(&currprefs, 0) : &Displays[displayindex]; UINT32 pathCount, modeCount; bool ret = false; if (pGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount) == ERROR_SUCCESS) { @@ -515,7 +518,7 @@ static void display_param_init(struct AmigaMonitor *mon) vsync_activeheight = mon->currentmode.current_height; } - wait_vblank_display = getdisplay(&currprefs); + wait_vblank_display = getdisplay(&currprefs, mon->monitor_id); if (!wait_vblank_display || !wait_vblank_display->HasAdapterData) { write_log(_T("Selected display mode does not have adapter data!\n")); } @@ -528,7 +531,7 @@ const TCHAR *target_get_display_name (int num, bool friendlyname) { if (num <= 0) return NULL; - struct MultiDisplay *md = getdisplay2 (NULL, num - 1); + struct MultiDisplay *md = getdisplay2(NULL, num - 1); if (!md) return NULL; if (friendlyname) @@ -619,7 +622,7 @@ int getrefreshrate(int monid, int width, int height) if (ap->gfx_refreshrate <= 0) return 0; - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, monid); for (int i = 0; md->DisplayModes[i].depth >= 0; i++) { struct PicassoResolution *pr = &md->DisplayModes[i]; if (pr->res.width == width && pr->res.height == height) { @@ -1817,7 +1820,7 @@ static void closeblankwindows (void) } static void createblankwindows (void) { - struct MultiDisplay *mdx = getdisplay (&currprefs); + struct MultiDisplay *mdx = getdisplay(&currprefs, 0); int i; if (!currprefs.win32_blankmonitors) @@ -1913,7 +1916,7 @@ static void updatemodes(struct AmigaMonitor *mon) if (flags & DM_SWSCALE) mon->currentmode.fullfill = 1; if (flags & DM_W_FULLSCREEN) { - RECT rc = getdisplay (&currprefs)->rect; + RECT rc = getdisplay(&currprefs, mon->monitor_id)->rect; mon->currentmode.native_width = rc.right - rc.left; mon->currentmode.native_height = rc.bottom - rc.top; mon->currentmode.current_width = mon->currentmode.native_width; @@ -2840,7 +2843,7 @@ bool vsync_switchmode(int monid, int hz) int w = mon->currentmode.native_width; int h = mon->currentmode.native_height; int d = mon->currentmode.native_depth / 8; - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, monid); struct PicassoResolution *found; int newh, i, cnt; bool preferdouble = 0, preferlace = 0; @@ -3365,7 +3368,7 @@ static int getbestmode(struct AmigaMonitor *mon, int nextbest) int index = -1; for(;;) { - md = getdisplay2 (&currprefs, index); + md = getdisplay2(&currprefs, index); if (!md) return 0; ratio = mon->currentmode.native_width > mon->currentmode.native_height ? 1 : 0; @@ -3507,9 +3510,33 @@ static int create_windows_2(struct AmigaMonitor *mon) int cyborder = GetSystemMetrics (SM_CYFRAME); int gap = 0; int x, y, w, h; - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md; int sbheight; + md = getdisplay(&currprefs, mon->monitor_id); + if (mon->monitor_id && fsw) { + struct MultiDisplay *md2 = NULL; + int idx = 0; + for (;;) { + md2 = getdisplay2(&currprefs, idx); + if (md2 == md) + break; + if (!md2) + break; + idx++; + } + for (int i = 0; i <= mon->monitor_id; i++) { + md2 = getdisplay2(&currprefs, idx); + if (!md2) + idx = 0; + else + idx++; + } + if (md2) + md = md2; + } + mon->md = md; + sbheight = currprefs.win32_statusbar ? getstatuswindowheight(mon->monitor_id) : 0; if (mon->hAmigaWnd) { @@ -3877,7 +3904,7 @@ retry: tmp_depth = mon->currentmode.current_depth; if (mon->currentmode.flags & DM_W_FULLSCREEN) { - RECT rc = getdisplay (&currprefs)->rect; + RECT rc = getdisplay(&currprefs, mon->monitor_id)->rect; mon->currentmode.native_width = rc.right - rc.left; mon->currentmode.native_height = rc.bottom - rc.top; } @@ -4162,7 +4189,7 @@ void updatewinfsmode(int monid, struct uae_prefs *p) } else { p->gfx_monitor[monid].gfx_size = p->gfx_monitor[monid].gfx_size_win; } - md = getdisplay (p); + md = getdisplay(p, monid); set_config_changed (); } diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index e5af53ed..50acf809 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -42,6 +42,6 @@ extern void unlockscr3d(struct vidbuffer *vb); void DX_Fill(struct AmigaMonitor*, int dstx, int dsty, int width, int height, uae_u32 color); void DX_Blit(int x, int y, int w, int h); void centerdstrect(struct AmigaMonitor*, RECT *); -struct MultiDisplay *getdisplay (struct uae_prefs *p); +struct MultiDisplay *getdisplay(struct uae_prefs *p, int monid); extern int getrefreshrate(int monid, int width, int height); #endif diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index bc78e8eb..5b3e6da3 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -2384,7 +2384,7 @@ static UINT_PTR CALLBACK ofnhook (HWND hDlg, UINT message, WPARAM wParam, LPARAM } write_log (_T("OFNHOOK POST\n")); hWnd = GetParent (hDlg); - md = getdisplay (&currprefs); + md = getdisplay(&currprefs, mon->monitor_id); if (!md) return FALSE; w2 = WIN32GFX_GetWidth(mon); @@ -6891,7 +6891,7 @@ static void init_frequency_combo (HWND hDlg, int dmode) int i, j, freq; TCHAR hz[20], hz2[20], txt[100]; LRESULT index; - struct MultiDisplay *md = getdisplay (&workprefs); + struct MultiDisplay *md = getdisplay(&workprefs, 0); i = 0; index = 0; while (dmode >= 0 && (freq = md->DisplayModes[dmode].refresh[i]) > 0 && index < MAX_REFRESH_RATES) { @@ -6969,7 +6969,7 @@ static void init_frequency_combo (HWND hDlg, int dmode) static int display_mode_index (uae_u32 x, uae_u32 y, uae_u32 d) { int i, j; - struct MultiDisplay *md = getdisplay (&workprefs); + struct MultiDisplay *md = getdisplay(&workprefs, 0); j = 0; for (i = 0; md->DisplayModes[i].depth >= 0; i++) { @@ -7110,7 +7110,7 @@ static void init_display_mode (HWND hDlg) { int d, d2, index; int i, cnt; - struct MultiDisplay *md = getdisplay (&workprefs); + struct MultiDisplay *md = getdisplay(&workprefs, 0); struct monconfig *gm = &workprefs.gfx_monitor[0]; switch (workprefs.color_mode) @@ -7422,7 +7422,7 @@ static void init_resolution_combo (HWND hDlg) { int i, idx; TCHAR tmp[MAX_DPATH]; - struct MultiDisplay *md = getdisplay (&workprefs); + struct MultiDisplay *md = getdisplay(&workprefs, 0); idx = -1; SendDlgItemMessage(hDlg, IDC_RESOLUTION, CB_RESETCONTENT, 0, 0); @@ -7687,7 +7687,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l int dmode = -1; bool native = false; - struct MultiDisplay *md = getdisplay (&workprefs); + struct MultiDisplay *md = getdisplay(&workprefs, 0); posn1 = SendDlgItemMessage (hDlg, IDC_RESOLUTION, CB_GETCURSEL, 0, 0); LRESULT posn2 = SendDlgItemMessage (hDlg, IDC_RESOLUTIONDEPTH, CB_GETCURSEL, 0, 0); if (posn1 != CB_ERR) { @@ -19789,13 +19789,14 @@ static int dialog_x_offset, dialog_y_offset; static bool dodialogmousemove(void) { + int monid = 0; if (full_property_sheet || isfullscreen () <= 0) return false; - if (isfullscreen () > 0 && currprefs.gfx_monitor[0].gfx_size_fs.width > gui_width && currprefs.gfx_monitor[0].gfx_size.height > gui_height) + if (isfullscreen () > 0 && currprefs.gfx_monitor[monid].gfx_size_fs.width > gui_width && currprefs.gfx_monitor[monid].gfx_size.height > gui_height) return false; if (currprefs.gfx_api == 2) return false; - struct MultiDisplay *mdc = getdisplay (&currprefs); + struct MultiDisplay *mdc = getdisplay(&currprefs, monid); for (int i = 0; Displays[i].monitorid; i++) { struct MultiDisplay *md = &Displays[i]; if (md->rect.right - md->rect.left >= 800 && md->rect.bottom - md->rect.top >= 600 && md != mdc) @@ -19809,7 +19810,7 @@ static void centerWindow (HWND hDlg) RECT rc, rcDlg, rcOwner; int x = 0, y = 0; POINT pt1, pt2; - struct MultiDisplay *mdc = getdisplay (&currprefs); + struct MultiDisplay *mdc = getdisplay(&currprefs, 0); HWND owner = GetParent (hDlg); if (owner == NULL) @@ -20699,7 +20700,7 @@ static int GetSettings (int all_options, HWND hwnd) gui_width = GetSystemMetrics(SM_CXSCREEN); gui_height = GetSystemMetrics(SM_CYSCREEN); if (isfullscreen() > 0) { - struct MultiDisplay *md = getdisplay (&currprefs); + struct MultiDisplay *md = getdisplay(&currprefs, 0); int w = md->rect.right - md->rect.left; int h = md->rect.bottom - md->rect.top; write_log(_T("GUI Fullscreen, screen size %dx%d (%dx%d)\n"), w, h, start_gui_width, start_gui_height); -- 2.47.3