]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Full-window virtual multi-monitor support.
authorToni Wilen <twilen@winuae.net>
Wed, 18 Apr 2018 18:21:07 +0000 (21:21 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 18 Apr 2018 18:21:07 +0000 (21:21 +0300)
main.cpp
od-win32/direct3d.cpp
od-win32/direct3d11.cpp
od-win32/dxwrap.cpp
od-win32/dxwrap.h
od-win32/rp.cpp
od-win32/win32.cpp
od-win32/win32_scaler.cpp
od-win32/win32gfx.cpp
od-win32/win32gfx.h
od-win32/win32gui.cpp

index 4acd80046e7f3406d46dddd0ad3c8109029ef2c9..8aefd56f3016f7eb6c33d0bfc89d03e89ab74b31 100644 (file)
--- 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) {
index 70848837a7180356c11640588c59b1194703e82e..50f8dc07a7222fcf858f68a81a84e06facc4dc44 100644 (file)
@@ -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;
index 231a13aeba0728e3c44f83cb8cf9f9a22115e060..51edfb92951bbbea6ab1a738e339af8e8dd54e4a 100644 (file)
@@ -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;
index 88bcf54523fa9a98900d3eb7b5105644bab776d1..f8f3ff9b6d37a43d575dd4bc5cedb6daa0331248 100644 (file)
@@ -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;
index 8727776480eebb28041e5fa5ce068fa049f2e7fe..c29e56fa5b9d98dd0afffbfc504ecd885b23a39b 100644 (file)
@@ -104,6 +104,7 @@ struct AmigaMonitor {
        int monitor_id;
        HWND hAmigaWnd;
        HWND hMainWnd;
+       struct MultiDisplay *md;
 
        RECT amigawin_rect, mainwin_rect;
        RECT amigawinclip_rect;
index cc4398b5e80eecdd94284b06d091ba72a2605704..549c60287f82d16eb68dd2799a81365ea40e8afb 100644 (file)
@@ -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"),
index 9a8386379992146e4ee641412b3a2df9e5d54af7..c33f05f8174309ff52e8c78baed0244721aac9ab 100644 (file)
@@ -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;
index 1bf87066c4959a630beddf90e28f68561e71c7b0..b83c2fc71badf7d68ebfa5784f0b6ba3b601d0bc 100644 (file)
@@ -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);
index 0733b49e24d48de955a71d7c37adb8b9daf90eaf..2db058d1d610d48fd4716247833d5d0bb4f1fa8a 100644 (file)
@@ -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 ();
 }
 
index e5af53ed631fdabcf3a6bf495c63ae5b08542df7..50acf8099784147c5f9906133724453836a6efa8 100644 (file)
@@ -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
index bc78e8eb30e3c137a96d15193aae9bd156892170..5b3e6da36e12f53fa50d0138869c1ec9c769b087 100644 (file)
@@ -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);