]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2400b6
authorToni Wilen <twilen@winuae.net>
Thu, 22 Dec 2011 17:22:27 +0000 (19:22 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 22 Dec 2011 17:22:27 +0000 (19:22 +0200)
25 files changed:
audio.cpp
cfgfile.cpp
custom.cpp
drawing.cpp
gfxutil.cpp
include/events_jit.h
include/options.h
include/xwin.h
main.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/dxwrap.cpp
od-win32/dxwrap.h
od-win32/picasso96_win.cpp
od-win32/picasso96_win.h
od-win32/resources/resource
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/sounddep/sound.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gfx.h
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt

index 457ada09c779c65ae09c60dd48ec01a696730b7f..dd31a7e3cb5ce0db29bd8d9f42c02496f22f4a6b 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -1490,7 +1490,6 @@ static int sound_prefs_changed (void)
                return 0;
        if (changed_prefs.produce_sound != currprefs.produce_sound
                || changed_prefs.win32_soundcard != currprefs.win32_soundcard
-               || changed_prefs.win32_soundexclusive != currprefs.win32_soundexclusive
                || changed_prefs.sound_stereo != currprefs.sound_stereo
                || changed_prefs.sound_maxbsiz != currprefs.sound_maxbsiz
                || changed_prefs.sound_freq != currprefs.sound_freq
@@ -1564,7 +1563,6 @@ void set_audio (void)
 
        currprefs.produce_sound = changed_prefs.produce_sound;
        currprefs.win32_soundcard = changed_prefs.win32_soundcard;
-       currprefs.win32_soundexclusive = changed_prefs.win32_soundexclusive;
        currprefs.sound_stereo = changed_prefs.sound_stereo;
        currprefs.sound_auto = changed_prefs.sound_auto;
        currprefs.sound_freq = changed_prefs.sound_freq;
index 860fe3819911c3a89205ccbbee62049fd0fe127a..f5a2c2689524fc7f3967e35509aaf7207596cad2 100644 (file)
@@ -795,7 +795,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool (f, L"clipboard_sharing", p->clipboard_sharing);
 
        cfgfile_write (f, L"gfx_display", L"%d", p->gfx_display);
-       cfgfile_write_str (f, L"gfx_display_name", p->gfx_display_name);
+       cfgfile_dwrite_str (f, L"gfx_display_name", p->gfx_display_name);
        cfgfile_write (f, L"gfx_framerate", L"%d", p->gfx_framerate);
        cfgfile_write (f, L"gfx_width", L"%d", p->gfx_size_win.width); /* compatibility with old versions */
        cfgfile_write (f, L"gfx_height", L"%d", p->gfx_size_win.height); /* compatibility with old versions */
@@ -811,6 +811,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite (f, L"gfx_autoresolution_min_horizontal", horizmode[p->gfx_autoresolution_minh + 1]);
 
        cfgfile_write (f, L"gfx_backbuffers", L"%d", p->gfx_backbuffers);
+       cfgfile_write (f, L"gfx_backbuffers_rtg", L"%d", p->gfx_rtg_backbuffers);
        cfgfile_write_str (f, L"gfx_vsync", vsyncmodes[p->gfx_avsync]);
        cfgfile_write_str (f, L"gfx_vsyncmode", vsyncmodes2[p->gfx_avsyncmode]);
        cfgfile_write_str (f, L"gfx_vsync_picasso", vsyncmodes[p->gfx_pvsync]);
@@ -1476,6 +1477,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                || cfgfile_intval (option, value, L"gfx_refreshrate", &p->gfx_refreshrate, 1)
                || cfgfile_yesno (option, value, L"gfx_autoresolution", &p->gfx_autoresolution)
                || cfgfile_intval (option, value, L"gfx_backbuffers", &p->gfx_backbuffers, 1)
+               || cfgfile_intval (option, value, L"gfx_backbuffers_rtg", &p->gfx_rtg_backbuffers, 1)
                
                || cfgfile_intval (option, value, L"gfx_center_horizontal_position", &p->gfx_xcenter_pos, 1)
                || cfgfile_intval (option, value, L"gfx_center_vertical_position", &p->gfx_ycenter_pos, 1)
@@ -3967,6 +3969,7 @@ void default_prefs (struct uae_prefs *p, int type)
        p->color_mode = 2;
        p->gfx_blackerthanblack = 0;
        p->gfx_backbuffers = 1;
+       p->gfx_rtg_backbuffers = 2;
 
        target_default_options (p, type);
 
index df6ae35deae65fcdd9c4d842d35c5e9d10cb4ed9..a4c8e99eaea51acc76df9b958ef9a4af172a6566 100644 (file)
@@ -126,6 +126,7 @@ long cycles_to_hsync_event;
 unsigned long int vsync_cycles;
 static int extra_cycle;
 unsigned long start_cycles;
+bool vsync_check;
 
 static int rpt_did_reset;
 struct ev eventtab[ev_max];
@@ -2735,7 +2736,7 @@ void compute_vsynctime (void)
        fake_vblank_hz = 0;
        if (abs (currprefs.chipset_refreshrate) > 0.1) {
                vblank_hz = currprefs.chipset_refreshrate;
-               if (isvsync ()) {
+               if (isvsync_chipset ()) {
                        vblank_skip = 1;
                        if (!fake_vblank_hz && getvsyncrate (vblank_hz) != vblank_hz) {
                                vblank_hz = getvsyncrate (vblank_hz);
@@ -2884,17 +2885,17 @@ void init_hz (bool fullinit)
                        (cr->lace < 0 || (cr->lace > 0 && islace) || (cr->lace == 0 && !islace)) &&
                        (cr->framelength < 0 || (cr->framelength > 0 && lof_store) || (cr->framelength == 0 && !lof_store) || (cr->framelength >= 0 && islace)) &&
                        ((cr->rtg && picasso_on) || (!cr->rtg && !picasso_on)) &&
-                       (cr->vsync < 0 || (cr->vsync > 0 && isvsync ()) || (cr->vsync == 0 && !isvsync ()))) {
+                       (cr->vsync < 0 || (cr->vsync > 0 && isvsync_chipset ()) || (cr->vsync == 0 && !isvsync_chipset ()))) {
                                double v = -1;
 
                                if (!picasso_on) {
-                                       if (isvsync ()) {
+                                       if (isvsync_chipset ()) {
                                                if (i == CHIPSET_REFRESH_PAL || i == CHIPSET_REFRESH_NTSC) {
                                                        if ((abs (vblank_hz - 50) < 1 || abs (vblank_hz - 60) < 1) && currprefs.gfx_avsync == 2 && currprefs.gfx_afullscreen > 0) {
                                                                vsync_switchmode (vblank_hz > 55 ? 60 : 50);
                                                        }
                                                }
-                                               if (isvsync () < 0) {
+                                               if (isvsync_chipset () < 0) {
                                                        double v2;
                                                        v2 = vblank_calibrate (cr->locked ? vblank_hz : cr->rate, cr->locked);
                                                        if (!cr->locked)
@@ -5102,7 +5103,7 @@ static void framewait (void)
 {
        frame_time_t curr_time;
        frame_time_t start;
-       int vs = isvsync ();
+       int vs = isvsync_chipset ();
 
        if (vs > 0) {
                vsyncmintime = vsynctime;
@@ -5117,7 +5118,7 @@ static void framewait (void)
                if (vs == -2) {
 
                        curr_time = vsync_busywait_end ();
-                       vsync_busywait_do (&freetime);
+                       vsync_busywait_do (NULL);
                        curr_time = read_processor_time ();
                        vsyncmintime = curr_time + vsynctime;
                        vsync_busywait_start ();
@@ -5209,7 +5210,8 @@ static void vsync_handler_pre (void)
        handle_events ();
 
 #ifdef PICASSO96
-       picasso_handle_vsync ();
+       if (isvsync_rtg () >= 0)
+               picasso_handle_vsync ();
 #endif
        audio_vsync ();
        blkdev_vsync ();
@@ -5249,7 +5251,7 @@ static void vsync_handler_post (void)
 
        fpscounter ();
 
-       if (!isvsync ()
+       if (!isvsync_chipset ()
 #ifdef AVIOUTPUT
                && ((avioutput_framelimiter && avioutput_enabled) || !avioutput_enabled)
 #endif
@@ -5346,7 +5348,7 @@ static void frh_handler (void)
                /* Allow this to be one frame's worth of cycles out */
                while (diff32 (curr_time, vsyncmintime + vsynctime) > 0) {
                        vsyncmintime += vsynctime * N_LINES / maxvpos_nom;
-                       if (currprefs.turbo_emulation || thread_vblank_found)
+                       if (currprefs.turbo_emulation || vblank_found_chipset || vblank_found_rtg)
                                break;
                }
        }
@@ -5860,11 +5862,17 @@ static void hsync_handler_post (bool onvsync)
                diw_change--;
 
 
-       if (is_lastline && isvsync () == -2 && !vsync_rendered) {
+       if (is_lastline && isvsync_chipset () == -2 && !vsync_rendered) {
                /* last line, render the frame as early as possible */
                vsync_rendered = true;
                vsync_handle_redraw (lof_store, lof_changed);
                render_screen ();
+               show_screen_maybe ();
+               vsync_check = true;
+       }
+       if (isvsync_rtg () < 0) {
+               if (vblank_found_rtg || vsync_busywait_check () == false)
+                       picasso_handle_vsync ();
        }
 
 #if 0
index a5cec3072922c0576783b160c2c553420af66756..320c2621117e578760ceab12a212fcbe485b8279 100644 (file)
@@ -1836,7 +1836,7 @@ STATIC_INLINE void do_flush_screen (struct vidbuffer *vb, int start, int stop)
        unlockscr (vb);
        if (start <= stop)
                flush_screen (vb, start, stop);
-       else if (isvsync ())
+       else if (isvsync_chipset ())
                flush_screen (vb, 0, 0); /* vsync mode */
 }
 
@@ -2771,7 +2771,7 @@ void vsync_handle_redraw (int long_frame, int lof_changed)
                else if (currprefs.cpu_cycle_exact)
                        init_hardware_for_drawing_frame ();
        } else {
-               if (isvsync ())
+               if (isvsync_chipset ())
                        flush_screen (gfxvidinfo.inbuffer, 0, 0); /* vsync mode */
        }
        gui_flicker_led (-1, 0, 0);
@@ -2926,7 +2926,7 @@ void drawing_init (void)
        reset_drawing ();
 }
 
-int isvsync (void)
+int isvsync_chipset (void)
 {
        if (picasso_on || !currprefs.gfx_avsync || (currprefs.gfx_avsync == 0 && !currprefs.gfx_afullscreen))
                return 0;
@@ -2934,3 +2934,20 @@ int isvsync (void)
                return 1;
        return currprefs.m68k_speed < 0 ? -2 : -1;
 }
+
+int isvsync_rtg (void)
+{
+       if (!picasso_on || !currprefs.gfx_pvsync || (currprefs.gfx_pvsync == 0 && !currprefs.gfx_pfullscreen))
+               return 0;
+       if (currprefs.gfx_pvsyncmode == 0)
+               return 1;
+       return currprefs.m68k_speed < 0 ? -2 : -1;
+}
+
+int isvsync (void)
+{
+       if (picasso_on)
+               return isvsync_rtg ();
+       else
+               return isvsync_chipset ();
+}
index 4ff0b5ff47c2d137567ce5448b0231383f6183b1..7690ce09c8409b5299426bdc0e6fb4107dd6b19b 100644 (file)
@@ -56,6 +56,8 @@ int bits_in_mask (unsigned long mask)
 int mask_shift (unsigned long mask)
 {
        int n = 0;
+       if (!mask)
+               return 0;
        while (!(mask & 1)) {
                n++;
                mask >>= 1;
index 3f5bac885a66691def6367b8a7dc18b802aa7515..c61f370496fc64bec71501384127a869046cc57e 100644 (file)
@@ -58,11 +58,11 @@ STATIC_INLINE void set_cycles (unsigned long int x)
 #endif
 }
 
-extern volatile bool thread_vblank_found;
+extern volatile bool vblank_found_chipset, vblank_found_rtg;
 
 STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add)
 {
-       if (thread_vblank_found && pissoff > 0)
+       if (vblank_found_chipset && pissoff > 0)
                cycles_do_special ();
 
        if ((pissoff -= cycles_to_add) >= 0)
@@ -76,7 +76,7 @@ STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add)
                int v = rpt - vsyncmintime;
                if (v > (int)syncbase || v < -((int)syncbase))
                        vsyncmintime = rpt;
-               if (v < 0 && !thread_vblank_found && !currprefs.turbo_emulation) {
+               if (v < 0 && !vblank_found_chipset && !currprefs.turbo_emulation) {
                        pissoff = pissoff_value * CYCLE_UNIT;
                        return;
                }
index 23c51bc5bdf14ae7e42bebf17208fb36b95ba8f4..88ddbd068aaed345de98ca8b5e6b4c8c5fa0f67c 100644 (file)
@@ -253,6 +253,7 @@ struct uae_prefs {
        int gfx_saturation, gfx_luminance, gfx_contrast, gfx_gamma;
        bool gfx_blackerthanblack;
        int gfx_backbuffers;
+       int gfx_rtg_backbuffers;
        int gfx_api;
        int color_mode;
 
@@ -439,7 +440,6 @@ struct uae_prefs {
        int win32_uaescsimode;
        int win32_soundcard;
        int win32_samplersoundcard;
-       bool win32_soundexclusive;
        bool win32_norecyclebin;
        int win32_specialkey;
        int win32_guikey;
index 85440ea1a536b08f2c69fdec0ec1dac4a6839805..9cc7510bef8933ca8b6739e5db85c874e48dca48 100644 (file)
@@ -31,10 +31,13 @@ extern bool vsync_switchmode (int);
 extern frame_time_t vsync_busywait_end (void);
 extern bool vsync_busywait_do (int*);
 extern void vsync_busywait_start (void);
+bool vsync_busywait_check (void);
 extern double vblank_calibrate (double, bool);
 extern void doflashscreen (void);
 extern int flashscreen;
 extern void updatedisplayarea (void);
+extern int isvsync_chipset (void);
+extern int isvsync_rtg (void);
 extern int isvsync (void);
 
 extern void flush_line (struct vidbuffer*, int);
@@ -43,6 +46,7 @@ extern void flush_screen (struct vidbuffer*, int, int);
 extern void flush_clear_screen (struct vidbuffer*);
 extern bool render_screen (void);
 extern void show_screen (void);
+extern bool show_screen_maybe (void);
 
 extern int lockscr (struct vidbuffer*, bool);
 extern void unlockscr (struct vidbuffer*);
index 80c47d93f79c2171ed8a6d0392b885ff1f4ea4c8..f0b82357ed3d735e5c344af06f19cae434a43f1c 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -133,6 +133,10 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs)
        fixup_prefs_dim2 (&prefs->gfx_size_win);
        if (prefs->gfx_filter == 0 && prefs->gfx_filter_autoscale && !prefs->gfx_api)
                prefs->gfx_filter = 1;
+       if (prefs->gfx_avsync)
+               prefs->gfx_avsyncmode = 1;
+       if (prefs->gfx_pvsync)
+               prefs->gfx_pvsyncmode = 1;
 }
 
 void fixup_cpu (struct uae_prefs *p)
index 3d1f1f0f245124af20422bd15dd9b8dfebe14e8a..281d8046ffa9e72b678d90e49ff9775a39279761 100644 (file)
@@ -62,7 +62,7 @@ static ID3DXSprite *sprite;
 static HWND d3dhwnd;
 static int devicelost;
 static int locked, fulllocked;
-static int cursor_offset_x, cursor_offset_y;
+static int cursor_offset_x, cursor_offset_y, cursor_offset2_x, cursor_offset2_y;
 static float maskmult_x, maskmult_y;
 static RECT mask2rect;
 
@@ -82,7 +82,8 @@ static int t_depth, mult, multx;
 static int required_sl_texture_w, required_sl_texture_h;
 static int vsync2, guimode, maxscanline;
 static int resetcount;
-static int cursor_x, cursor_y, cursor_v;
+static double cursor_x, cursor_y;
+static bool cursor_v;
 
 #define NUMVERTICES 8
 #define D3DFVF_TLVERTEX D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1
@@ -1790,7 +1791,7 @@ static int restoredeviceobjects (void)
 
        int curw = CURSORMAXWIDTH, curh = CURSORMAXHEIGHT;
        cursorsurfaced3d = createtext (curw, curh, D3DFMT_A8R8G8B8);
-       cursor_v = 0;
+       cursor_v = false;
 
        vbsize = sizeof (struct TLVERTEX) * NUMVERTICES;
        if (FAILED (hr = d3ddev->CreateVertexBuffer (vbsize, D3DUSAGE_WRITEONLY,
@@ -1838,8 +1839,6 @@ void D3D_free (void)
        ddraw_fs_hack_free ();
 }
 
-static int prevvblankpos;
-
 bool D3D_getvblankpos (int *vpos)
 {
        HRESULT hr;
@@ -1856,70 +1855,11 @@ bool D3D_getvblankpos (int *vpos)
        if (rt.ScanLine > maxscanline)
                maxscanline = rt.ScanLine;
        *vpos = rt.ScanLine;
-       prevvblankpos = rt.ScanLine;
        if (rt.InVBlank != 0)
                *vpos = -1;
        return true;
 }
 
-bool D3D_waitvblankstate (bool state, int *maxvpos)
-{
-       int vpos;
-       for (;;) {
-               int omax = maxscanline;
-               if (!D3D_getvblankpos (&vpos))
-                       return false;
-               while (omax != maxscanline) {
-                       omax = maxscanline;
-                       if (!D3D_getvblankpos (&vpos))
-                               return false;
-               }
-               if (maxvpos)
-                       *maxvpos = maxscanline;
-               if (vpos < 0) {
-                       if (state)
-                               return true;
-               } else {
-                       if (!state)
-                               return true;
-               }
-       }
-}
-
-bool D3D_vblank_busywait (void)
-{
-       int vpos;
-
-       for (;;) {
-               int opos = prevvblankpos;
-               if (!D3D_getvblankpos (&vpos))
-                       return false;
-               if (opos > maxscanline / 2 && vpos < maxscanline / 5)
-                       return true;
-               if (vpos <= 0)
-                       return true;
-       }
-}
-
-bool D3D_vblank_getstate (bool *state)
-{
-       int vpos, opos;
-
-       opos = prevvblankpos;
-       if (!D3D_getvblankpos (&vpos))
-               return false;
-       if (opos > maxscanline / 2 && vpos < maxscanline / 5) {
-               *state = true;
-               return true;
-       }
-       if (vpos <= 0) {
-               *state = true;
-               return true;
-       }
-       *state = false;
-       return true;
-}
-
 
 const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth, int mmult)
 {
@@ -1933,7 +1873,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        typedef HRESULT (WINAPI *LPDIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
        LPDIRECT3DCREATE9EX d3dexp = NULL;
        int vsync = isvsync ();
-
+       int bb = picasso_on ? currprefs.gfx_rtg_backbuffers : currprefs.gfx_backbuffers;
 
        D3D_free2 ();
        if (!currprefs.gfx_api) {
@@ -2006,12 +1946,12 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        memset (&dpp, 0, sizeof (dpp));
        dpp.Windowed = isfullscreen () <= 0;
        dpp.BackBufferFormat = mode.Format;
-       dpp.BackBufferCount = currprefs.gfx_backbuffers;
+       dpp.BackBufferCount = bb;
        dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
        dpp.BackBufferWidth = w_w;
        dpp.BackBufferHeight = w_h;
-       dpp.PresentationInterval = dpp.BackBufferCount <= 1 || dpp.Windowed ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;
+       dpp.PresentationInterval = dpp.BackBufferCount == 0 || dpp.Windowed ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;
 
        modeex.Width = w_w;
        modeex.Height = w_h;
@@ -2037,7 +1977,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        d3dhwnd = ahwnd;
        t_depth = depth;
 
-       flags = D3DCREATE_FPU_PRESERVE;
+       flags = D3DCREATE_FPU_PRESERVE | D3DCREATE_MULTITHREADED;
        // Check if hardware vertex processing is available
        if(d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
                flags |= D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
@@ -2121,7 +2061,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
                dpp.Windowed ? L"" : L" FS",
                vsync, dpp.BackBufferCount,
                dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE ? L"I" : L"F",
-               currprefs.gfx_backbuffers == 0 ? L"E" : L"", 
+               bb == 0 ? L"E" : L"", 
                t_depth, adapter
        );
 
@@ -2183,15 +2123,13 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        maxscanline = 0;
        d3d_enabled = 1;
 
-       if (vsync < 0) {
-               if (currprefs.gfx_backbuffers == 0) {
-                       hr = d3ddev->CreateQuery(D3DQUERYTYPE_EVENT, &query);
-                       if (FAILED (hr))
-                               write_log (L"%s: CreateQuery(D3DQUERYTYPE_EVENT) failed: %s\n", D3DHEAD, D3D_ErrorString (hr));
-               }
+       if (vsync < 0 && bb == 0) {
+               hr = d3ddev->CreateQuery(D3DQUERYTYPE_EVENT, &query);
+               if (FAILED (hr))
+                       write_log (L"%s: CreateQuery(D3DQUERYTYPE_EVENT) failed: %s\n", D3DHEAD, D3D_ErrorString (hr));
        }
        if (d3ddevex) {
-               hr = d3ddevex->SetMaximumFrameLatency (vsync < 0 ? 1 : 0);
+               hr = d3ddevex->SetMaximumFrameLatency (vsync < 0 && bb == 0 ? 1 : 0);
                if (FAILED (hr))
                        write_log (L"%s: SetMaximumFrameLatency() failed: %s\n", D3DHEAD, D3D_ErrorString (hr));
        }
@@ -2427,9 +2365,9 @@ static void D3D_render2 (void)
                if (cursorsurfaced3d && cursor_v) {
                        D3DXMATRIXA16 t;
 
-                       MatrixScaling (&t, ((float)(window_w) / (tout_w + 2 * cursor_offset_x)), ((float)(window_h) / (tout_h + 2 * cursor_offset_y)), 0);
-                       v.x = cursor_x + cursor_offset_x;
-                       v.y = cursor_y + cursor_offset_y;
+                       MatrixScaling (&t, ((float)(window_w) / (tout_w + 2 * cursor_offset2_x)), ((float)(window_h) / (tout_h + 2 * cursor_offset2_y)), 0);
+                       v.x = cursor_x + cursor_offset2_x;
+                       v.y = cursor_y + cursor_offset2_y;
                        v.z = 0;
                        sprite->SetTransform (&t);
                        sprite->Draw (cursorsurfaced3d, NULL, NULL, &v, 0xffffffff);
@@ -2535,10 +2473,13 @@ static void D3D_render2 (void)
                write_log (L"%s: EndScene() %s\n", D3DHEAD, D3D_ErrorString (hr));
 }
 
-void D3D_setcursor (int x, int y, int visible)
+void D3D_setcursor (int x, int y, int width, int height, bool visible)
 {
-       cursor_x = x;
-       cursor_y = y;
+       cursor_offset2_x = cursor_offset_x * window_w / width;
+       cursor_offset2_y = cursor_offset_y * window_h / height;
+
+       cursor_x = x * window_w / width;
+       cursor_y = y * window_h / height;
        cursor_v = visible;
 }
 
index 25b01f2a7d764b1c3a3649a209de6501e41c973c..2abf5fd56b04f56d94bf7c9400b10313a15cf6b7 100644 (file)
@@ -15,10 +15,7 @@ extern int D3D_needreset (void);
 extern void D3D_clear (void);
 extern int D3D_canshaders (void);
 extern int D3D_goodenough (void);
-extern void D3D_setcursor (int x, int y, int visible);
-extern bool D3D_vblank_busywait (void);
-extern bool D3D_waitvblankstate (bool, int*);
-extern bool D3D_vblank_getstate (bool *state);
+extern void D3D_setcursor (int x, int y, int width, int height, bool visible);
 extern bool D3D_getvblankpos (int *vpos);
 extern double D3D_getrefreshrate (void);
 extern LPDIRECT3DTEXTURE9 cursorsurfaced3d;
index 4b5ce79090cad4bd72d5038d464f74f99e7f3c16..1eb7f2f6f05d20646b9fa05ea24a82978631e01f 100644 (file)
@@ -334,6 +334,7 @@ HRESULT DirectDraw_CreateMainSurface (int width, int height)
        HRESULT ddrval;
        DDSURFACEDESC2 desc = { 0 };
        LPDIRECTDRAWSURFACE7 surf;
+       int bb = WIN32GFX_IsPicassoScreen () ? currprefs.gfx_rtg_backbuffers : currprefs.gfx_backbuffers;
 
        width = (width + 7) & ~7;
        desc.dwSize = sizeof (desc);
@@ -345,7 +346,7 @@ HRESULT DirectDraw_CreateMainSurface (int width, int height)
                DWORD oldflags = desc.dwFlags;
                desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
                desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;
-               desc.dwBackBufferCount = currprefs.gfx_backbuffers == 0 ? 1 : currprefs.gfx_backbuffers;
+               desc.dwBackBufferCount = bb == 0 ? 1 : bb;
                if (desc.dwBackBufferCount > 0) {
                        ddrval = IDirectDraw7_CreateSurface (dxdata.maindd, &desc, &dxdata.primary, NULL);
                        if (SUCCEEDED (ddrval)) {
@@ -904,10 +905,11 @@ static void flip (void)
 {
        int result = 0;
        HRESULT ddrval = DD_OK;
-       DWORD flags = DDFLIP_WAIT;
+       DWORD flags = DDFLIP_DONOTWAIT;
        int vsync = isvsync ();
+       int bb = WIN32GFX_IsPicassoScreen () ? currprefs.gfx_rtg_backbuffers : currprefs.gfx_backbuffers;
 
-       if (currprefs.turbo_emulation || (vsync && currprefs.gfx_backbuffers <= 1))
+       if (currprefs.turbo_emulation || (vsync && bb == 0))
                flags |= DDFLIP_NOVSYNC;
        if (dxdata.backbuffers == 2) {
                DirectDraw_Blit (dxdata.flipping[1], dxdata.flipping[0]);
@@ -927,7 +929,9 @@ static void flip (void)
                        ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags| DDFLIP_NOVSYNC);
                }
        } else if(dxdata.backbuffers == 1) {
-               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_NOVSYNC);
+               if (!vsync)
+                       flags |= DDFLIP_NOVSYNC;
+               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
                DirectDraw_Blit (dxdata.flipping[0], dxdata.primary);
        }
        if (ddrval == DDERR_SURFACELOST) {
@@ -1208,45 +1212,32 @@ void dx_check (void)
        dxdata.islost = 1;
 }
 
-bool DirectDraw_waitvblankstate (bool state, int *maxvpos)
+bool DD_getvblankpos (int *vpos)
 {
-       BOOL vb;
        HRESULT hr;
+       DWORD sl;
+       BOOL vbs;
 
-       if (maxvpos)
-               *maxvpos = -1;
+       *vpos = -2;
        if ((dxdata.primary == NULL && dxdata.fsmodeset > 0) || dxdata.islost || !dxdata.maindd)
                return false;
-       for (;;) {
-               hr = IDirectDraw7_GetVerticalBlankStatus (dxdata.maindd, &vb);
-               if (FAILED (hr)) {
-                       write_log (L"IDirectDraw7_GetVerticalBlankStatus %s\n", DXError (hr));
-                       return false;
-               }
-               if ((vb && state) || (!vb && !state))
-                       return true;
-       }
-}
-
-bool DirectDraw_vblank_busywait (void)
-{
-       if (!DirectDraw_waitvblankstate (true, NULL))
-               return false;
-       return true;
-}
-
-bool DirectDraw_getvblankstate (bool *state)
-{
-       BOOL vb;
-       HRESULT hr;
-
-       if ((dxdata.primary == NULL && dxdata.fsmodeset > 0) || dxdata.islost || !dxdata.maindd)
-               return false;
-       hr = IDirectDraw7_GetVerticalBlankStatus (dxdata.maindd, &vb);
+       hr = IDirectDraw7_GetVerticalBlankStatus (dxdata.maindd, &vbs);
        if (FAILED (hr)) {
-               write_log (L"IDirectDraw7_GetVerticalBlankStatus %s\n", DXError (hr));
+               write_log (L"IDirectDraw7_GetVerticalBlankStatus() failed, %s\n", DXError (hr));
                return false;
        }
-       *state = vb != 0;
+       sl = -2;
+       if (!vbs) {
+               hr = IDirectDraw7_GetScanLine (dxdata.maindd, &sl);
+               if (hr == 0x88760219) { // "vertical blank is in progress"
+                       vbs = TRUE;
+               } else if (FAILED (hr) ) {
+                       write_log (L"IDirectDraw7_GetScanLine() failed, %s\n", DXError (hr));
+                       return false;
+               }
+       }
+       *vpos = sl;
+       if (vbs)
+               *vpos = -1;
        return true;
 }
index ba67a1f893fec9c4d6686e870629d0547ce3758e..b827eeaae515d967ee5bede3f51004db9e4ae11e 100644 (file)
@@ -67,9 +67,11 @@ struct PicassoResolution
 extern GUID *displayGUID;
 
 struct MultiDisplay {
-       int primary, disabled, gdi;
+       bool primary;
        GUID guid;
-       TCHAR *name, *name2, *name3;
+       TCHAR *adaptername, *adapterid, *adapterkey;
+       TCHAR *monitorname, *monitorid;
+       TCHAR *fullname;
        struct PicassoResolution *DisplayModes;
        RECT rect;
 };
@@ -129,9 +131,7 @@ int DirectDraw_BlitRectCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAW
 void DirectDraw_FillSurface (LPDIRECTDRAWSURFACE7 dst, RECT *rect, uae_u32 color);
 void DirectDraw_Fill (RECT *rect, uae_u32 color);
 void DirectDraw_FillPrimary (void);
-bool DirectDraw_vblank_busywait (void);
-bool DirectDraw_waitvblankstate (bool, int*);
-bool DirectDraw_getvblankstate (bool*);
+bool DD_getvblankpos (int *vpos);
 
 void dx_check (void);
 int dx_islost (void);
index 05d9fda827381c4b45bb1154325fc17c4683a859..8b4599bf57c33ca4decc1962f808eccfc90a0d26 100644 (file)
@@ -131,7 +131,7 @@ static HCURSOR wincursor;
 static int wincursor_shown;
 static uaecptr boardinfo, ABI_interrupt;
 static int interrupt_enabled;
-int p96vblank;
+double p96vblank;
 
 static int uaegfx_old, uaegfx_active;
 static uae_u32 reserved_gfxmem;
@@ -581,6 +581,7 @@ static void setupcursor (void)
        D3DLOCKED_RECT locked;
        HRESULT hr;
 
+       gfx_lock ();
        setupcursor_needed = 1;
        if (cursorsurfaced3d) {
                if (SUCCEEDED (hr = cursorsurfaced3d->LockRect (0, &locked, NULL, 0))) {
@@ -602,11 +603,11 @@ static void setupcursor (void)
                        cursorsurfaced3d->UnlockRect (0);
                        setupcursor_needed = 0;
                        P96TRACE_SPR((L"cursorsurface3d updated\n"));
-                       return;
                } else {
                        P96TRACE_SPR((L"cursorsurfaced3d LockRect() failed %08x\n", hr));
                }
        }
+       gfx_unlock ();
 }
 
 static void disablemouse (void)
@@ -617,7 +618,7 @@ static void disablemouse (void)
                return;
        if (!currprefs.gfx_api)
                return;
-       D3D_setcursor (0, 0, 0);
+       D3D_setcursor (0, 0, 0, 0, false);
 }
 
 static int newcursor_x, newcursor_y;
@@ -640,7 +641,7 @@ static void mouseupdate (void)
 
        if (!currprefs.gfx_api)
                return;
-       D3D_setcursor (x, y, cursorvisible);
+       D3D_setcursor (x, y, picasso96_state.Width, picasso96_state.Height, cursorvisible);
 }
 
 static int framecnt;
@@ -652,7 +653,7 @@ static int doskip (void)
        return framecnt > 0;
 }
 
-static void picasso_trigger_vblank (void)
+void picasso_trigger_vblank (void)
 {
        if (!ABI_interrupt || !uaegfx_base || !interrupt_enabled || currprefs.win32_rtgvblankrate < -1)
                return;
@@ -662,19 +663,26 @@ static void picasso_trigger_vblank (void)
                INTREQ (0x8000 | 0x0008);
 }
 
-static int isvsync (void)
+static bool rtg_render (void)
 {
-       if (currprefs.gfx_pfullscreen && currprefs.gfx_pvsync)
-               return 1;
-       if (currprefs.gfx_pvsync && currprefs.gfx_pvsyncmode)
-               return -1;
-       return 0;
+       int flushed = 0;
+       if (doskip () && p96skipmode == 0) {
+               ;
+       } else {
+               flushed = flushpixels ();
+       }
+       return flushed == 0;
+}
+static void rtg_show (void)
+{
+       gfx_unlock_picasso ();
 }
 
-void picasso_handle_vsync (void)
+static void picasso_handle_vsync2 (void)
 {
        static int vsynccnt;
        int thisisvsync = 1;
+       int vsync = isvsync_rtg ();
 
 #ifdef RETROPLATFORM
        rp_vsync ();
@@ -684,38 +692,50 @@ void picasso_handle_vsync (void)
        if (!picasso_on)
                createwindowscursor (0, 0, 0, 0, 0, 1);
 
-       if (currprefs.chipset_refreshrate >= 100.0) {
+       if (vsync >= 0 && currprefs.chipset_refreshrate >= 85) {
                vsynccnt++;
                if (vsynccnt < 2)
                        thisisvsync = 0;
                vsynccnt = 0;
        }
 
-       if (thisisvsync && currprefs.win32_rtgvblankrate == 0 && !isvsync ())
+       if (thisisvsync && currprefs.win32_rtgvblankrate == 0 && !vsync)
                picasso_trigger_vblank ();
 
        if (!picasso_on)
                return;
-       if (dx_islost ())
-               return;
 
        framecnt++;
        mouseupdate ();
 
        if (thisisvsync) {
-               int flushed = 0;
-               if (doskip () && p96skipmode == 0) {
-                       ;
-               } else {
-                       flushed = flushpixels ();
-               }
-               if (!flushed)
-                       gfx_unlock_picasso ();
+               if (rtg_render ())
+                       rtg_show ();
        }
        if (setupcursor_needed)
                setupcursor ();
 }
 
+void picasso_handle_vsync (void)
+{
+       int vsync = isvsync_rtg ();
+
+       if (vsync == -2) {
+               vsync_busywait_end ();
+               vsync_busywait_do (NULL);
+               framecnt++;
+               bool rendered = rtg_render ();
+               picasso_trigger_vblank ();
+               clipboard_vsync ();
+               vsync_busywait_start ();
+               mouseupdate ();
+               if (rendered)
+                       rtg_show ();
+       } else {
+               picasso_handle_vsync2 ();
+       }
+}
+
 static int set_panning_called = 0;
 
 
@@ -1530,7 +1550,7 @@ exit:
                if (GetCursor () != NULL)
                        SetCursor (NULL);
        } else {
-               if (wincursor == oldwincursor)
+               if (wincursor == oldwincursor && normalcursor != NULL)
                        SetCursor (normalcursor);
        }
        if (oldwincursor)
@@ -3233,25 +3253,15 @@ static uae_u32 REGPARAM2 picasso_SetDisplay (TrapContext *ctx)
 void picasso_handle_hsync (void)
 {
        static int p96hsync;
+       int vsync = isvsync_rtg ();
 
        if (currprefs.gfxmem_size == 0)
                return;
-       if (currprefs.win32_rtgvblankrate == 0 && !isvsync ())
+       if (currprefs.win32_rtgvblankrate == 0 && !vsync)
                return;
-       if (WIN32GFX_IsPicassoScreen () && isvsync ()) {
-               int vbs = DirectDraw_GetVerticalBlankStatus ();
-               if (vbs <= 0) {
-                       if (p96hsync > 0)
-                               p96hsync = -1;
-                       return;
-               } else {
-                       if (p96hsync >= 0)
-                               return;
-                       p96hsync = 0;
-               }
-       } else {
-               p96hsync--;
-       }
+       if (vsync == -2)
+               return;
+       p96hsync--;
        if (p96hsync <= 0) {
                picasso_trigger_vblank ();
                p96hsync = p96syncrate;
@@ -3260,14 +3270,14 @@ void picasso_handle_hsync (void)
 
 void init_hz_p96 (void)
 {
-       if (currprefs.win32_rtgvblankrate < 0 || isvsync ())  {
+       if (currprefs.win32_rtgvblankrate < 0 || isvsync_rtg ())  {
                double rate = getcurrentvblankrate ();
                if (rate < 0)
-                       p96vblank = (int)(vblank_hz + 0.5);
+                       p96vblank = vblank_hz;
                else
-                       p96vblank = (int)(getcurrentvblankrate () + 0.5);
+                       p96vblank = getcurrentvblankrate ();
        } else if (currprefs.win32_rtgvblankrate == 0) {
-               p96vblank = (int)(vblank_hz + 0.5);
+               p96vblank = vblank_hz;
        } else {
                p96vblank = currprefs.win32_rtgvblankrate;
        }
@@ -3276,7 +3286,7 @@ void init_hz_p96 (void)
        if (p96vblank >= 300)
                p96vblank = 300;
        p96syncrate = maxvpos_nom * vblank_hz / p96vblank;
-       write_log (L"P96FREQ: %d*%.4f = %.4f / %d = %d\n", maxvpos_nom, vblank_hz, maxvpos_nom * vblank_hz, p96vblank, p96syncrate);
+       write_log (L"P96FREQ: %d*%.4f = %.4f / %.1f = %d\n", maxvpos_nom, vblank_hz, maxvpos_nom * vblank_hz, p96vblank, p96syncrate);
 }
 
 /* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */
@@ -3949,7 +3959,8 @@ static int flushpixels (void)
        if (!currprefs.gfx_api && (currprefs.leds_on_screen & STATUSLINE_RTG)) {
                if (dst == NULL) {
                        dst = gfx_lock_picasso (false);
-                       lock = 1;
+                       if (dst)
+                               lock = 1;
                }
                if (dst) {
                        statusline (dst);
index 09c3f616e3b0d92acd107a409a54d0f7f613eb07..e8dfa5793c4f11f4fe1782c008f09fff3013b2fd 100644 (file)
@@ -553,6 +553,8 @@ extern void picasso_refresh (void);
 extern void picasso_handle_vsync (void);
 extern void init_hz_p96 (void);
 extern void picasso_handle_hsync (void);
+extern void picasso_handle_vsync (void);
+extern void picasso_trigger_vblank (void);
 extern void picasso_reset (void);
 extern int picasso_setwincursor (void);
 extern int picasso_palette (void);
index 284804e528237327adf242719006d41437d145cd..2eebbf6f4384ab4e7c8e9d87cb9122434a98b17c 100644 (file)
 #define IDC_SOUND_AUTO                  1709
 #define IDC_FILTERKEEPASPECT            1709
 #define IDC_CS_RTC                      1710
-#define IDC_SOUND_EXCLUSIVE             1710
 #define IDC_CS_CIAA_TOD1                1711
 #define IDC_CS_CIAA_TOD2                1712
 #define IDC_CS_EXT                      1712
index 59cfbcb6c0b172dda6da58c3d279e5d1f92ea6d1..ddedae92199351390596b2b856274c4d0c565562 100644 (file)
@@ -115,9 +115,9 @@ STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 FONT 8, "MS Sans Serif", 0, 0, 0x1\r
 BEGIN\r
     GROUPBOX        "Screen",IDC_SCREENRESTEXT,4,0,292,67,BS_LEFT\r
-    COMBOBOX        IDC_DISPLAYSELECT,59,10,225,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_DISPLAYSELECT,10,10,279,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     COMBOBOX        IDC_RESOLUTION,59,27,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
-    COMBOBOX        IDC_REFRESHRATE,187,27,97,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_REFRESHRATE,187,27,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     EDITTEXT        IDC_XSIZE,59,48,48,12,ES_NUMBER\r
     EDITTEXT        IDC_YSIZE,114,48,47,12,ES_NUMBER\r
     GROUPBOX        "Settings",IDC_SETTINGSTEXT,4,73,209,137\r
@@ -147,8 +147,8 @@ BEGIN
     COMBOBOX        IDC_LORES,103,152,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "Remove interlace artifacts",IDC_FLICKERFIXER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,139,99,10\r
     RTEXT           "Windowed:",IDC_STATIC,13,46,40,15,SS_CENTERIMAGE\r
-    RTEXT           "Fullscreen:",IDC_STATIC,13,19,40,15,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_DISPLAY_BUFFERCNT,187,47,97,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
+    RTEXT           "Fullscreen:",IDC_STATIC,11,27,40,15,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_DISPLAY_BUFFERCNT,187,47,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "Resolution autoswitch",IDC_AUTORESOLUTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,139,89,10\r
     EDITTEXT        IDC_DA_TEXT,167,218,46,12,ES_AUTOHSCROLL | ES_READONLY\r
     COMBOBOX        IDC_SCREENMODE_NATIVE2,112,85,95,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
@@ -324,12 +324,12 @@ BEGIN
     CONTROL         "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,35,101,10\r
     CONTROL         "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,53,102,10\r
     CONTROL         "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,71,102,10\r
-    GROUPBOX        "Volume",IDC_STATIC,132,36,164,31\r
-    CONTROL         "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,44,105,20\r
-    EDITTEXT        IDC_SOUNDVOLUME2,247,47,40,12,ES_CENTER | ES_READONLY\r
-    GROUPBOX        "Sound Buffer Size",IDC_STATIC,132,73,164,31\r
-    CONTROL         "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,81,105,19\r
-    EDITTEXT        IDC_SOUNDBUFFERMEM,247,84,40,12,ES_CENTER | ES_READONLY\r
+    GROUPBOX        "Volume",IDC_STATIC,132,20,164,31\r
+    CONTROL         "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,29,105,20\r
+    EDITTEXT        IDC_SOUNDVOLUME2,247,32,40,12,ES_CENTER | ES_READONLY\r
+    GROUPBOX        "Sound Buffer Size",IDC_STATIC,132,59,164,31\r
+    CONTROL         "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,67,105,19\r
+    EDITTEXT        IDC_SOUNDBUFFERMEM,247,70,40,12,ES_CENTER | ES_READONLY\r
     GROUPBOX        "Settings",IDC_SOUNDINTERPOLATION2,6,106,290,60\r
     LTEXT           "Frequency:",IDC_SOUNDFREQTXT,11,140,53,8,SS_CENTERIMAGE\r
     COMBOBOX        IDC_SOUNDFREQ,13,149,51,75,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
@@ -351,7 +351,6 @@ BEGIN
     COMBOBOX        IDC_SOUNDSWAP,73,149,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
     LTEXT           "Swap channels:",IDC_SOUNDSWAPTXT,74,140,61,8,SS_CENTERIMAGE\r
     CONTROL         "Automatic switching",IDC_SOUND_AUTO,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,14,89,103,10\r
-    CONTROL         "Exclusive mode",IDC_SOUND_EXCLUSIVE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,137,25,154,10\r
     CONTROL         "DirectSound",IDC_SOUND_DS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,181,55,10\r
     CONTROL         "WASAPI",IDC_SOUND_WASAPI,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,193,53,10\r
     CONTROL         "OpenAL",IDC_SOUND_OPENAL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,205,53,10\r
index 63d1f3ca3f3b8957edc725f5ddb6b012ec607b12..1824a75f7604d3349cf0c64dcfa572f95611e3d0 100644 (file)
@@ -433,6 +433,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
        minimized = 0;
        if (display) {
                p->gfx_display = display;
+               p->gfx_display_name[0] = 0;
                if (sm->dwScreenMode & RP_SCREENMODE_FULLWINDOW)
                        fs = 2;
                else
index e2e54459c6ccf820b7e1c7cda43e286314d7b507..e1e5aea558483dbf82c795b4d201b9783fac07ca 100644 (file)
@@ -427,7 +427,7 @@ void set_volume_sound_device (struct sound_data *sd, int volume, int mute)
                hr = IDirectSoundBuffer_SetVolume (s->lpDSBsecondary, vol);
                if (FAILED (hr))
                        write_log (L"DSSOUND: SetVolume(%d) failed: %s\n", vol, DXError (hr));
-       } else if (sd->devicetype == SOUND_DEVICE_WASAPI) {
+       } else if (sd->devicetype == SOUND_DEVICE_WASAPI || sd->devicetype == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
                if (s->pAudioVolume) {
                        float vol = 0.0;
                        if (volume < 100 && !mute)
@@ -1115,7 +1115,7 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
        v /= 2;
        if (sd->sndbufsize > v)
                sd->sndbufsize = v;
-       s->wasapigoodsize =s->bufferFrameCount / 2;
+       s->wasapigoodsize = s->bufferFrameCount / 2;
        s->sndbufframes = sd->sndbufsize / sd->samplesize;
 
        write_log(L"WASAPI: '%s'\nWASAPI: EX=%d CH=%d FREQ=%d BUF=%d (%d)\n",
@@ -1284,23 +1284,25 @@ error:
        return 0;
 }
 
-int open_sound_device (struct sound_data *sd, int index, int exclusive, int bufsize, int freq, int channels)
+int open_sound_device (struct sound_data *sd, int index, int bufsize, int freq, int channels)
 {
        int ret = 0;
        struct sound_dp *sdp = xcalloc (struct sound_dp, 1);
+       int type = sound_devices[index]->type;
+       
        sd->data = sdp;
        sd->sndbufsize = bufsize;
        sd->freq = freq;
        sd->channels = channels;
        sd->paused = 1;
-       if (sound_devices[index]->type == SOUND_DEVICE_AL)
+       if (type == SOUND_DEVICE_AL)
                ret = open_audio_al (sd, index);
-       else if (sound_devices[index]->type == SOUND_DEVICE_DS)
+       else if (type == SOUND_DEVICE_DS)
                ret = open_audio_ds (sd, index);
-       else if (sound_devices[index]->type == SOUND_DEVICE_PA)
+       else if (type == SOUND_DEVICE_PA)
                ret = open_audio_pa (sd, index);
-       else if (sound_devices[index]->type == SOUND_DEVICE_WASAPI)
-               ret = open_audio_wasapi (sd, index, exclusive);
+       else if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE)
+               ret = open_audio_wasapi (sd, index, type == SOUND_DEVICE_WASAPI_EXCLUSIVE);
        sd->samplesize = sd->channels * 2;
        return ret;
 }
@@ -1313,7 +1315,7 @@ void close_sound_device (struct sound_data *sd)
                close_audio_ds (sd);
        else if (sd->devicetype == SOUND_DEVICE_PA)
                close_audio_pa (sd);
-       else if (sd->devicetype == SOUND_DEVICE_WASAPI)
+       else if (sd->devicetype == SOUND_DEVICE_WASAPI || sd->devicetype == SOUND_DEVICE_WASAPI_EXCLUSIVE)
                close_audio_wasapi (sd);
        xfree (sd->data);
        sd->data = NULL;
@@ -1327,7 +1329,7 @@ void pause_sound_device (struct sound_data *sd)
                pause_audio_ds (sd);
        else if (sd->devicetype == SOUND_DEVICE_PA)
                pause_audio_pa (sd);
-       else if (sd->devicetype == SOUND_DEVICE_WASAPI)
+       else if (sd->devicetype == SOUND_DEVICE_WASAPI || sd->devicetype == SOUND_DEVICE_WASAPI_EXCLUSIVE)
                pause_audio_wasapi (sd);
 }
 void resume_sound_device (struct sound_data *sd)
@@ -1338,7 +1340,7 @@ void resume_sound_device (struct sound_data *sd)
                resume_audio_ds (sd);
        else if (sd->devicetype == SOUND_DEVICE_PA)
                resume_audio_pa (sd);
-       else if (sd->devicetype == SOUND_DEVICE_WASAPI)
+       else if (sd->devicetype == SOUND_DEVICE_WASAPI || sd->devicetype == SOUND_DEVICE_WASAPI_EXCLUSIVE)
                resume_audio_wasapi (sd);
        sd->paused = 0;
 }
@@ -1367,7 +1369,7 @@ static int open_sound (void)
        if (currprefs.win32_soundcard >= num)
                currprefs.win32_soundcard = changed_prefs.win32_soundcard = 0;
        ch = get_audio_nativechannels (currprefs.sound_stereo);
-       ret = open_sound_device (sdp, currprefs.win32_soundcard, currprefs.win32_soundexclusive, size, currprefs.sound_freq, ch);
+       ret = open_sound_device (sdp, currprefs.win32_soundcard, size, currprefs.sound_freq, ch);
        if (!ret)
                return 0;
        currprefs.sound_freq = changed_prefs.sound_freq = sdp->freq;
@@ -1653,7 +1655,7 @@ int blocking_sound_device (struct sound_data *sd)
                        return 0;
                return 1;
 
-       } else if (sd->devicetype == SOUND_DEVICE_WASAPI) {
+       } else if (sd->devicetype == SOUND_DEVICE_WASAPI || sd->devicetype == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
 
                //      if (WaitForSingleObject (s->wasapihandle, 0) == WAIT_TIMEOUT)
                //          return 0;
@@ -1984,7 +1986,7 @@ void send_sound (struct sound_data *sd, uae_u16 *sndbuffer)
                finish_sound_buffer_ds (sd, sndbuffer);
        else if (sd->devicetype == SOUND_DEVICE_PA)
                finish_sound_buffer_pa (sd, sndbuffer);
-       else if (sd->devicetype == SOUND_DEVICE_WASAPI)
+       else if (sd->devicetype == SOUND_DEVICE_WASAPI || sd->devicetype == SOUND_DEVICE_WASAPI_EXCLUSIVE)
                finish_sound_buffer_wasapi (sd, sndbuffer);
 }
 
@@ -2055,7 +2057,7 @@ static void wasapi_enum (struct sound_device **sdp)
        HRESULT hr;
        IMMDeviceEnumerator *enumerator;
        IMMDeviceCollection *col;
-       int i, cnt;
+       int i, cnt, cnt2, start;
 
        write_log (L"Enumerating WASAPI devices...\n");
        for (cnt = 0; cnt < MAX_SOUND_DEVICES; cnt++) {
@@ -2064,6 +2066,7 @@ static void wasapi_enum (struct sound_device **sdp)
        }
        if (cnt >= MAX_SOUND_DEVICES)
                return;
+       start = cnt;
 
        hr = CoCreateInstance (__uuidof(MMDeviceEnumerator), NULL,
                CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&enumerator);
@@ -2095,19 +2098,17 @@ static void wasapi_enum (struct sound_device **sdp)
                                                dev->Release ();
                                        }
                                        if (devid && devname) {
-                                               TCHAR tmp[MAX_DPATH];
                                                if (i == 0) {
                                                        sdp[cnt] = xcalloc (struct sound_device, 1);
-                                                       sdp[cnt]->cfgname = my_strdup (L"WASAPI:Default Audio Device");
+                                                       sdp[cnt]->cfgname = my_strdup (L"Default Audio Device");
                                                        sdp[cnt]->type = SOUND_DEVICE_WASAPI;
                                                        sdp[cnt]->name = my_strdup (L"Default Audio Device");
                                                        sdp[cnt]->alname = NULL;
                                                        cnt++;
                                                }
                                                if (cnt < MAX_SOUND_DEVICES) {
-                                                       _stprintf (tmp, L"WASAPI:%s", devname);
                                                        sdp[cnt] = xcalloc (struct sound_device, 1);
-                                                       sdp[cnt]->cfgname = my_strdup (tmp);
+                                                       sdp[cnt]->cfgname = my_strdup (devname);
                                                        sdp[cnt]->type = SOUND_DEVICE_WASAPI;
                                                        sdp[cnt]->name = my_strdup (devname);
                                                        sdp[cnt]->alname = my_strdup (devid);
@@ -2122,6 +2123,21 @@ static void wasapi_enum (struct sound_device **sdp)
                }
                enumerator->Release ();
        }
+       cnt2 = cnt;
+       for (i = start; i < cnt2; i++) {
+               TCHAR buf[1000];
+               _stprintf (buf, L"WASAPIX:%s", sdp[i]->cfgname);
+               sdp[cnt] = xcalloc (struct sound_device, 1);
+               sdp[cnt]->cfgname = my_strdup (buf);
+               sdp[cnt]->name = my_strdup (sdp[i]->name);
+               sdp[cnt]->alname = sdp[i]->alname ? my_strdup (sdp[i]->alname) : NULL;
+               _stprintf (buf, L"WASAPI:%s", sdp[i]->cfgname);
+               sdp[cnt]->type = SOUND_DEVICE_WASAPI_EXCLUSIVE;
+               xfree (sdp[i]->cfgname);
+               sdp[i]->cfgname = my_strdup (buf);
+               cnt++;
+       }
+
 }
 
 static void OpenALEnumerate (struct sound_device **sds, const char *pDeviceNames, const char *ppDefaultDevice, int skipdetect)
index 7a0ea4bfe1e2df8f7f2d0b54d88ea1e8e4f875e3..fc186fe0d02f79efefbb83e17c175446ab8f59c1 100644 (file)
@@ -2782,7 +2782,6 @@ void target_default_options (struct uae_prefs *p, int type)
                p->win32_ctrl_F11_is_quit = 0;
                p->win32_soundcard = 0;
                p->win32_samplersoundcard = -1;
-               p->win32_soundexclusive = 0;
                p->win32_minimize_inactive = 0;
                p->win32_active_priority = 1;
                p->win32_inactive_priority = 2;
@@ -2889,14 +2888,13 @@ void target_save_options (struct zfile *f, struct uae_prefs *p)
        cfgfile_target_dwrite_bool (f, L"borderless", p->win32_borderless);
        cfgfile_target_dwrite_str (f, L"uaescsimode", scsimode[p->win32_uaescsimode]);
        cfgfile_target_dwrite_str (f, L"statusbar", statusbarmode[p->win32_statusbar]);
-       cfgfile_target_dwrite (f, L"soundcard", L"%d", p->win32_soundcard);
+       cfgfile_target_write (f, L"soundcard", L"%d", p->win32_soundcard);
        if (p->win32_soundcard >= 0 && p->win32_soundcard < MAX_SOUND_DEVICES && sound_devices[p->win32_soundcard])
-               cfgfile_target_dwrite_str (f, L"soundcardname", sound_devices[p->win32_soundcard]->cfgname);
-       cfgfile_target_dwrite_bool (f, L"soundcard_exclusive", p->win32_soundexclusive);
+               cfgfile_target_write_str (f, L"soundcardname", sound_devices[p->win32_soundcard]->cfgname);
        if (p->win32_samplersoundcard >= 0 && p->win32_samplersoundcard < MAX_SOUND_DEVICES) {
-               cfgfile_target_dwrite (f, L"samplersoundcard", L"%d", p->win32_samplersoundcard);
+               cfgfile_target_write (f, L"samplersoundcard", L"%d", p->win32_samplersoundcard);
                if (record_devices[p->win32_samplersoundcard])
-                       cfgfile_target_dwrite_str (f, L"samplersoundcardname", record_devices[p->win32_samplersoundcard]->cfgname);
+                       cfgfile_target_write_str (f, L"samplersoundcardname", record_devices[p->win32_samplersoundcard]->cfgname);
        }
 
        cfgfile_target_dwrite (f, L"cpu_idle", L"%d", p->cpu_idle);
@@ -2942,7 +2940,7 @@ static const TCHAR *obsolete[] = {
        L"killwinkeys", L"sound_force_primary", L"iconified_highpriority",
        L"sound_sync", L"sound_tweak", L"directx6", L"sound_style",
        L"file_path", L"iconified_nospeed", L"activepriority", L"magic_mouse",
-       L"filesystem_codepage", L"aspi", L"no_overlay",
+       L"filesystem_codepage", L"aspi", L"no_overlay", L"soundcard_exclusive",
        0
 };
 
@@ -2970,7 +2968,6 @@ int target_parse_option (struct uae_prefs *p, const TCHAR *option, const TCHAR *
                || cfgfile_intval (option, value, L"midiout_device", &p->win32_midioutdev, 1)
                || cfgfile_intval (option, value, L"midiin_device", &p->win32_midiindev, 1)
                || cfgfile_intval (option, value, L"samplersoundcard", &p->win32_samplersoundcard, 1)
-               || cfgfile_yesno (option, value, L"soundcard_exclusive", &p->win32_soundexclusive)
                || cfgfile_yesno (option, value, L"notaskbarbutton", &p->win32_notaskbarbutton)
                || cfgfile_yesno (option, value, L"always_on_top", &p->win32_alwaysontop)
                || cfgfile_yesno (option, value, L"powersavedisabled", &p->win32_powersavedisabled)
@@ -3562,6 +3559,9 @@ static int shell_associate_2 (const TCHAR *extension, TCHAR *shellcommand, TCHAR
        const TCHAR *defprogid;
        UAEREG *fkey;
 
+       if (!icon)
+               icon = IDI_APPICON;
+
        _tcscpy (progid2, progid);
        _tcscat (progid2, ext2 ? ext2 : extension);
        if (os_winnt_admin > 1)
@@ -3609,10 +3609,11 @@ static int shell_associate_2 (const TCHAR *extension, TCHAR *shellcommand, TCHAR
        }
        cc = NULL;
        struct contextcommand ccs[2];
+       memset (ccs, 0, sizeof ccs);
        if ((command || shellcommand)) {
                ccs[0].command = command;
                ccs[0].shellcommand = shellcommand;
-               ccs[1].command = NULL;
+               ccs[0].icon = IDI_APPICON;
                cc = &ccs[0];
        }
        if (cc) {
@@ -3746,15 +3747,15 @@ static void associate_init_extensions (void)
                TCHAR rpath[MAX_DPATH];
                HKEY rkey = HKEY_LOCAL_MACHINE;
                HKEY key1;
-               int setit = 1;
+               bool setit = true;
 
                _tcscpy (rpath, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\winuae.exe");
                if (RegOpenKeyEx (rkey, rpath, 0, KEY_READ, &key1) == ERROR_SUCCESS) {
                        TCHAR tmp[MAX_DPATH];
                        DWORD size = sizeof tmp / sizeof (TCHAR);
                        if (RegQueryValueEx (key1, NULL, NULL, NULL, (LPBYTE)tmp, &size) == ERROR_SUCCESS) {
-                               if (!_tcscmp (tmp, _wpgmptr))
-                                       setit = 0;
+                               if (!_tcsicmp (tmp, _wpgmptr))
+                                       setit = false;
                        }
                        RegCloseKey (key1);
                }
@@ -3763,6 +3764,9 @@ static void associate_init_extensions (void)
                                DWORD val = 1;
                                RegSetValueEx (key1, L"", 0, REG_SZ, (CONST BYTE *)_wpgmptr, (_tcslen (_wpgmptr) + 1) * sizeof (TCHAR));
                                RegSetValueEx (key1, L"UseUrl", 0, REG_DWORD, (LPBYTE)&val, sizeof val);
+                               _tcscpy (rpath, start_path_exe);
+                               rpath[_tcslen (rpath) - 1] = 0;
+                               RegSetValueEx (key1, L"Path", 0, REG_SZ, (CONST BYTE *)rpath, (_tcslen (rpath) + 1) * sizeof (TCHAR));
                                RegCloseKey (key1);
                                SHChangeNotify (SHCNE_ASSOCCHANGED, 0, 0, 0); 
                        }
@@ -4996,12 +5000,12 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
                enumerate_sound_devices ();
                for (i = 0; i < MAX_SOUND_DEVICES && sound_devices[i]; i++) {
                        int type = sound_devices[i]->type;
-                       write_log (L"%d:%s: %s\n", i, type == SOUND_DEVICE_DS ? L"DS" : (type == SOUND_DEVICE_AL ? L"AL" : (type == SOUND_DEVICE_WASAPI ? L"WA" : L"PA")), sound_devices[i]->name);
+                       write_log (L"%d:%s: %s\n", i, type == SOUND_DEVICE_DS ? L"DS" : (type == SOUND_DEVICE_AL ? L"AL" : (type == SOUND_DEVICE_WASAPI ? L"WA" : (type == SOUND_DEVICE_WASAPI_EXCLUSIVE ? L"WX" : L"PA"))), sound_devices[i]->name);
                }
                write_log (L"Enumerating recording devices:\n");
                for (i = 0; i < MAX_SOUND_DEVICES && record_devices[i]; i++) {
                        int type = record_devices[i]->type;
-                       write_log (L"%d:%s: %s\n", i, type == SOUND_DEVICE_DS ? L"DS" : (type == SOUND_DEVICE_AL ? L"AL" : (type == SOUND_DEVICE_WASAPI ? L"WA" : L"PA")), record_devices[i]->name);
+                       write_log (L"%d:%s: %s\n", i, type == SOUND_DEVICE_DS ? L"DS" : (type == SOUND_DEVICE_AL ? L"AL" : (type == SOUND_DEVICE_WASAPI ? L"WA" : (type == SOUND_DEVICE_WASAPI_EXCLUSIVE ? L"WX" : L"PA"))), record_devices[i]->name);
                }
                write_log (L"done\n");
                memset (&devmode, 0, sizeof (devmode));
index bc1b96b0597451143d04cd49096227cece5555c1..ff3f8802d35a810cd015339dffe2716693175334 100644 (file)
@@ -19,8 +19,8 @@
 #define LANG_DLL 1
 
 //#define WINUAEBETA L""
-#define WINUAEBETA L"Beta 5"
-#define WINUAEDATE MAKEBD(2011, 12, 18)
+#define WINUAEBETA L"Beta 6"
+#define WINUAEDATE MAKEBD(2011, 12, 22)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
@@ -160,6 +160,7 @@ extern LONG WINAPI WIN32_ExceptionFilter (struct _EXCEPTION_POINTERS *pException
 #define SOUND_DEVICE_AL 2
 #define SOUND_DEVICE_PA 3
 #define SOUND_DEVICE_WASAPI 4
+#define SOUND_DEVICE_WASAPI_EXCLUSIVE 5
 
 struct sound_device
 {
index 5f7ddc98be7d2948cb879662ad15d18ef3d43f46..d5414eb07f430a4e19b6e04c7ff42669c5228241 100644 (file)
@@ -78,7 +78,6 @@ struct uae_filter *usedfilter;
 static int scalepicasso;
 static double remembered_vblank;
 static volatile int vblankthread_mode, vblankthread_counter;
-static CRITICAL_SECTION cs_render;
 
 struct winuae_currentmode {
        unsigned int flags;
@@ -117,16 +116,38 @@ extern int reopen (int);
 #define VBLANKTH_ACTIVE 4
 #define VBLANKTH_ACTIVE_START 5
 
+static volatile bool vblank_found;
+static volatile int flipthread_mode;
+volatile bool vblank_found_chipset, vblank_found_rtg;
+static HANDLE flipevent;
+static CRITICAL_SECTION screen_cs;
+
+void gfx_lock (void)
+{
+       EnterCriticalSection (&screen_cs);
+}
+void gfx_unlock (void)
+{
+       LeaveCriticalSection (&screen_cs);
+}
+
 static void changevblankthreadmode (int newmode)
 {
        int t = vblankthread_counter;
-       thread_vblank_found = false;
+       vblank_found = false;
+       vblank_found_chipset = vblank_found_rtg = false;
        if (vblankthread_mode <= 0 || vblankthread_mode == newmode)
                return;
        vblankthread_mode = newmode;
+       if (newmode == VBLANKTH_KILL) {
+               flipthread_mode = 0;
+               SetEvent(flipevent);
+               while (flipthread_mode == 0)
+                       sleep_millis (1);
+               CloseHandle(flipevent);
+       }
        while (t == vblankthread_counter && vblankthread_mode > 0)
                sleep_millis (1);
-       thread_vblank_found = false;
 }
 
 int WIN32GFX_IsPicassoScreen (void)
@@ -205,11 +226,11 @@ struct MultiDisplay *getdisplay (struct uae_prefs *p)
        int display = p->gfx_display - 1;
 
        i = 0;
-       while (Displays[i].name) {
+       while (Displays[i].monitorname) {
                struct MultiDisplay *md = &Displays[i];
-               if (p->gfx_display_name[0] && !_tcscmp (md->name, p->gfx_display_name))
+               if (p->gfx_display_name[0] && !_tcscmp (md->adaptername, p->gfx_display_name))
                        return md;
-               if (p->gfx_display_name[0] && !_tcscmp (md->name2, p->gfx_display_name))
+               if (p->gfx_display_name[0] && !_tcscmp (md->adaptername, p->gfx_display_name))
                        return md;
                i++;
        }
@@ -306,7 +327,8 @@ static int rgbformat_bits (RGBFTYPE t)
 }
 
 static int set_ddraw_2 (void)
-{HRESULT ddrval;
+{
+       HRESULT ddrval;
        int bits = (currentmode->current_depth + 7) & ~7;
        int width = currentmode->native_width;
        int height = currentmode->native_height;
@@ -523,16 +545,16 @@ static BOOL CALLBACK monitorEnumProc (HMONITOR h, HDC hdc, LPRECT rect, LPARAM d
        MONITORINFOEX lpmi;
        lpmi.cbSize = sizeof lpmi;
        GetMonitorInfo(h, (LPMONITORINFO)&lpmi);
-       while (md - Displays < MAX_DISPLAYS) {
-               if (!_tcscmp (md->name3, lpmi.szDevice)) {
+       while (md - Displays < MAX_DISPLAYS && md->monitorid[0]) {
+               if (!_tcscmp (md->adapterid, lpmi.szDevice)) {
                        TCHAR tmp[1000];
                        md->rect = lpmi.rcMonitor;
                        if (md->rect.left == 0 && md->rect.top == 0)
-                               _stprintf (tmp, L"%s (%d*%d)", md->name, md->rect.right - md->rect.left, md->rect.bottom - md->rect.top);
+                               _stprintf (tmp, L"%s (%d*%d)", md->monitorname, md->rect.right - md->rect.left, md->rect.bottom - md->rect.top);
                        else
-                               _stprintf (tmp, L"%s (%d*%d) [%d*%d]", md->name, md->rect.right - md->rect.left, md->rect.bottom - md->rect.top, md->rect.left, md->rect.top);
-                       xfree (md->name);
-                       md->name = my_strdup (tmp);
+                               _stprintf (tmp, L"%s (%d*%d) [%d*%d]", md->monitorname, md->rect.right - md->rect.left, md->rect.bottom - md->rect.top, md->rect.left, md->rect.top);
+                       xfree (md->fullname);
+                       md->fullname = my_strdup (tmp);
                        return TRUE;
                }
                md++;
@@ -549,81 +571,73 @@ void enumeratedisplays (void)
        while (EnumDisplayDevices (NULL, adapterindex, &add, 0)) {
                int monitorindex = 0;
                adapterindex++;
+               if (!(add.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
+                       continue;
                if (add.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
                        continue;
+               if (md - Displays >= MAX_DISPLAYS)
+                       return;
                DISPLAY_DEVICE mdd;
                mdd.cb = sizeof mdd;
                while (EnumDisplayDevices (add.DeviceName, monitorindex, &mdd, 0)) {
                        monitorindex++;
                        if (md - Displays >= MAX_DISPLAYS)
                                return;
-                       md->name3 = my_strdup (add.DeviceName);
-                       md->name2 = my_strdup (mdd.DeviceKey);
-                       md->name = my_strdup (mdd.DeviceString);
+                       if (!(mdd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
+                               continue;
+                       if (mdd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
+                               continue;
+                       md->adaptername = my_strdup (add.DeviceString);
+                       md->adapterid = my_strdup (add.DeviceName);
+                       md->adapterkey = my_strdup (add.DeviceID);
+                       md->monitorname = my_strdup (mdd.DeviceString);
+                       md->monitorid = my_strdup (mdd.DeviceKey);
                        if (add.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
-                               md->primary = 1;
+                               md->primary = true;
                        md++;
                }
+               if (md - Displays >= MAX_DISPLAYS)
+                       return;
+               if (monitorindex == 0) {
+                       md->adaptername = my_strdup (add.DeviceString);
+                       md->adapterid = my_strdup (add.DeviceName);
+                       md->adapterkey = my_strdup (add.DeviceID);
+                       md->monitorname = my_strdup (add.DeviceString);
+                       md->monitorid = my_strdup (add.DeviceKey);
+                       md->primary = true;
+               }
        }
        EnumDisplayMonitors (NULL, NULL, monitorEnumProc, NULL);
 }
 
-static int makesort (struct MultiDisplay *md)
-{
-       int v;
-
-       v = md->rect.top * 65536 + md->rect.left;
-       if (md->primary)
-               v = 0x80000001;
-       if (md->rect.top == 0 && md->rect.left == 0)
-               v = 0x80000000;
-       return v;
-}
-
 void sortdisplays (void)
 {
-       struct MultiDisplay *md1, *md2, tmp;
+       struct MultiDisplay *md1;
        int i, idx;
 
-       md1 = Displays;
-       while (md1->name) {
-               int sort1 = makesort (md1);
-               md2 = md1 + 1;
-               while (md2->name) {
-                       int sort2 = makesort (md2);
-                       if (sort1 > sort2) {
-                               memcpy (&tmp, md1, sizeof (tmp));
-                               memcpy (md1, md2, sizeof (tmp));
-                               memcpy (md2, &tmp, sizeof (tmp));
-                       }
-                       md2++;
-               }
-               md1++;
+       int w = GetSystemMetrics (SM_CXSCREEN);
+       int h = GetSystemMetrics (SM_CYSCREEN);
+       int b = 0;
+       HDC hdc = GetDC (NULL);
+       if (hdc) {
+               b = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
+               ReleaseDC (NULL, hdc);
        }
+       write_log (L"Desktop: W=%d H=%d B=%d. CXVS=%d CYVS=%d\n", w, h, b,
+               GetSystemMetrics (SM_CXVIRTUALSCREEN), GetSystemMetrics (SM_CYVIRTUALSCREEN));
 
        md1 = Displays;
-       while (md1->name) {
+       while (md1->monitorname) {
                md1->DisplayModes = xmalloc (struct PicassoResolution, MAX_PICASSO_MODES);
                md1->DisplayModes[0].depth = -1;
-               md1->disabled = 1;
-               int w = GetSystemMetrics (SM_CXSCREEN);
-               int h = GetSystemMetrics (SM_CYSCREEN);
-               HDC hdc = GetDC (NULL);
-               int b = 0;
-               
-               if (hdc) {
-                       b = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
-                       ReleaseDC (NULL, hdc);
-               }
-
-               write_log (L"Desktop: W=%d H=%d B=%d. CXVS=%d CYVS=%d\n", w, h, b,
-                       GetSystemMetrics (SM_CXVIRTUALSCREEN), GetSystemMetrics (SM_CYVIRTUALSCREEN));
+
+               write_log (L"%s [%s]\n", md1->adaptername, md1->monitorname);
                for (int mode = 0; mode < 2; mode++) {
                        DEVMODE dm;
                        dm.dmSize = sizeof dm;
                        dm.dmDriverExtra = 0;
                        idx = 0;
-                       while (EnumDisplaySettingsEx (md1->name3, idx, &dm, mode ? EDS_RAWMODE : 0)) {
+                       while (EnumDisplaySettingsEx (md1->adapterid, idx, &dm, mode ? EDS_RAWMODE : 0)) {
                                int found = 0;
                                int idx2 = 0;
                                while (md1->DisplayModes[idx2].depth >= 0 && !found) {
@@ -659,12 +673,10 @@ void sortdisplays (void)
                //dhack();
                sortmodes (md1);
                modesList (md1);
-               if (md1->DisplayModes[0].depth >= 0)
-               md1->disabled = 0;
                i = 0;
                while (md1->DisplayModes[i].depth > 0)
                        i++;
-               write_log (L"'%s', %d display modes (%s)\n", md1->name, i, md1->disabled ? L"disabled" : L"enabled");
+               write_log (L"%d display modes.\n", i);
                md1++;
        }
 }
@@ -799,7 +811,7 @@ bool render_screen (void)
                return render_ok;
        flushymin = 0;
        flushymax = currentmode->amiga_height;
-       EnterCriticalSection (&cs_render);
+       EnterCriticalSection (&screen_cs);
        if (currentmode->flags & DM_D3D) {
                v = D3D_renderframe ();
 #ifdef GFXFILTER
@@ -810,28 +822,38 @@ bool render_screen (void)
        } else if (currentmode->flags & DM_DDRAW) {
                v = true;
        }
-       LeaveCriticalSection (&cs_render);
        render_ok = v;
+       LeaveCriticalSection (&screen_cs);
        return render_ok;
 }
 
+bool show_screen_maybe (void)
+{
+       int bb = picasso_on ? currprefs.gfx_rtg_backbuffers : currprefs.gfx_backbuffers;
+       if (!bb)
+               return false;
+       SetEvent (flipevent);
+       return true;
+}
+
 void show_screen (void)
 {
-       if (picasso_on || dx_islost ())
-               return;
        if (!render_ok)
                return;
-       EnterCriticalSection (&cs_render);
+       EnterCriticalSection (&screen_cs);
        if (currentmode->flags & DM_D3D) {
                D3D_showframe ();
 #ifdef GFXFILTER
        } else if (currentmode->flags & DM_SWSCALE) {
-               DirectDraw_Flip (1);
+               if (!dx_islost () && !picasso_on)
+                       DirectDraw_Flip (1);
 #endif
        } else if (currentmode->flags & DM_DDRAW) {
-               DirectDraw_Flip (1);
+               if (!dx_islost () && !picasso_on)
+                       DirectDraw_Flip (1);
        }
-       LeaveCriticalSection (&cs_render);
+       LeaveCriticalSection (&screen_cs);
+       render_ok = false;
 }
 
 static uae_u8 *ddraw_dolock (void)
@@ -979,8 +1001,9 @@ void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_hei
 
        int srcratio, dstratio;
        int srcwidth, srcheight;
-               srcwidth = picasso96_state.Width;
-               srcheight = picasso96_state.Height;
+       srcwidth = picasso96_state.Width;
+       srcheight = picasso96_state.Height;
+
        if (currprefs.win32_rtgscaleaspectratio < 0) {
                // automatic
                srcratio = picasso96_state.Width * 256 / picasso96_state.Height;
@@ -993,6 +1016,7 @@ void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_hei
                dstratio = (currprefs.win32_rtgscaleaspectratio >> 8) * 256 / (currprefs.win32_rtgscaleaspectratio & 0xff);
                srcratio = srcwidth * 256 / srcheight;
        }
+
        if (srcratio == dstratio) {
                SetRect (dr, 0, 0, srcwidth, srcheight);
        } else if (srcratio > dstratio) {
@@ -1004,12 +1028,15 @@ void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_hei
                SetRect (dr, 0, 0, xx, picasso96_state.Height);
                picasso_offset_x = (picasso96_state.Width - xx) / 2;
        }
+
        OffsetRect (zr, picasso_offset_x, picasso_offset_y);
        picasso_offset_mx = picasso96_state.Width * 1000 / (dr->right - dr->left);
        picasso_offset_my = picasso96_state.Height * 1000 / (dr->bottom - dr->top);
 }
 
-uae_u8 *gfx_lock_picasso (int fullupdate)
+static bool rtg_locked;
+
+static uae_u8 *gfx_lock_picasso2 (int fullupdate)
 {
        if (currprefs.gfx_api) {
                int pitch;
@@ -1025,17 +1052,39 @@ uae_u8 *gfx_lock_picasso (int fullupdate)
                return DirectDraw_GetSurfacePointer ();
        }
 }
+uae_u8 *gfx_lock_picasso (int fullupdate)
+{
+       if (rtg_locked) {
+               write_log (L"rtg already locked!\n");
+               abort ();
+       }
+       EnterCriticalSection (&screen_cs);
+       uae_u8 *p = gfx_lock_picasso2 (fullupdate);
+       if (!p)
+               LeaveCriticalSection (&screen_cs);
+       else
+               rtg_locked = true;
+       return p;
+}
 
 void gfx_unlock_picasso (void)
 {
+       if (!rtg_locked)
+               EnterCriticalSection (&screen_cs);
+       rtg_locked = false;
        if (currprefs.gfx_api) {
                if (p96_double_buffer_needs_flushing) {
                        D3D_flushtexture (p96_double_buffer_first, p96_double_buffer_last);
                        p96_double_buffer_needs_flushing = 0;
                }
                D3D_unlocktexture ();
-               if (D3D_renderframe ())
-                       D3D_showframe ();
+               if (D3D_renderframe ()) {
+                       render_ok = true;
+                       if (currprefs.gfx_rtg_backbuffers == 0 || isvsync_rtg () >= 0)
+                               show_screen ();
+                       else
+                               SetEvent (flipevent);
+               }
        } else {
                DirectDraw_SurfaceUnlock ();
                if (p96_double_buffer_needs_flushing) {
@@ -1045,6 +1094,7 @@ void gfx_unlock_picasso (void)
                        p96_double_buffer_needs_flushing = 0;
                }
        }
+       LeaveCriticalSection (&screen_cs);
 }
 
 static void close_hwnds (void)
@@ -1301,6 +1351,7 @@ int check_prefs_changed_gfx (void)
        c |= _tcscmp (currprefs.gfx_display_name, changed_prefs.gfx_display_name) ? (2|4|8) : 0;
        c |= currprefs.gfx_blackerthanblack != changed_prefs.gfx_blackerthanblack ? (2 | 8) : 0;
        c |= currprefs.gfx_backbuffers != changed_prefs.gfx_backbuffers ? (2 | 8) : 0;
+       c |= currprefs.gfx_rtg_backbuffers != changed_prefs.gfx_rtg_backbuffers ? (2 | 8) : 0;
 
        c |= currprefs.win32_alwaysontop != changed_prefs.win32_alwaysontop ? 32 : 0;
        c |= currprefs.win32_notaskbarbutton != changed_prefs.win32_notaskbarbutton ? 32 : 0;
@@ -1366,6 +1417,7 @@ int check_prefs_changed_gfx (void)
                _tcscpy (currprefs.gfx_display_name, changed_prefs.gfx_display_name);
                currprefs.gfx_blackerthanblack = changed_prefs.gfx_blackerthanblack;
                currprefs.gfx_backbuffers = changed_prefs.gfx_backbuffers;
+               currprefs.gfx_rtg_backbuffers = changed_prefs.gfx_rtg_backbuffers;
 
                currprefs.win32_alwaysontop = changed_prefs.win32_alwaysontop;
                currprefs.win32_notaskbarbutton = changed_prefs.win32_notaskbarbutton;
@@ -1841,6 +1893,8 @@ void gfx_set_picasso_state (int on)
        } else {
                open_screen (); // reopen everything
        }
+       if (on && isvsync_rtg () < 0)
+               vblank_calibrate (0, false);
 end:
 #ifdef RETROPLATFORM
        rp_set_hwnd (hAmigaWnd);
@@ -1918,13 +1972,13 @@ void machdep_free (void)
 
 int graphics_init (void)
 {
-       InitializeCriticalSection (&cs_render);
        gfxmode_reset ();
        return open_windows (1);
 }
 
 int graphics_setup (void)
 {
+       InitializeCriticalSection (&screen_cs);
 #ifdef PICASSO96
        InitPicasso96 ();
 #endif
@@ -2142,27 +2196,11 @@ static int getbestmode (int nextbest)
        return 0;
 }
 
+static bool threaded_vsync = false;
+static volatile frame_time_t vblank_prev_time, thread_vblank_time;
+
+#include <process.h>
 
-static bool waitvblankstate (bool state, int *maxvpos)
-{
-       if (currprefs.gfx_api) {
-               return D3D_waitvblankstate (state, maxvpos);
-       } else {
-               return DirectDraw_waitvblankstate (state, maxvpos);
-       }
-}
-static bool getvblankstate (bool *state)
-{
-       if (currprefs.gfx_api) {
-               if (!D3D_vblank_getstate (state))
-                       return false;
-               return true;
-       } else {
-               if (!DirectDraw_getvblankstate (state))
-                       return false;
-               return true;
-       }
-}
 double getcurrentvblankrate (void)
 {
        if (remembered_vblank)
@@ -2172,28 +2210,100 @@ double getcurrentvblankrate (void)
        else
                return DirectDraw_CurrentRefreshRate ();
 }
-static int getvblankpos (void)
+
+static int maxscanline, prevvblankpos;
+
+static bool getvblankpos (int *vp)
 {
-       int vpos = -2;
+       int sl;
+       *vp = -2;
        if (currprefs.gfx_api) {
-               if (!D3D_getvblankpos (&vpos))
-                       return -2;
-               return vpos;
+               if (!D3D_getvblankpos (&sl))
+                       return false;
        } else {
-               bool state;
-               if (!DirectDraw_getvblankstate (&state))
-                       return -2;
-               return state ? -1 : 0;
+               if (!DD_getvblankpos (&sl))
+                       return false;
        }
+       prevvblankpos = sl;
+       if (sl > maxscanline)
+               maxscanline = sl;
+       *vp = sl;
+       return true;
 }
 
-static bool threaded_vsync = false;
-volatile bool thread_vblank_found;
-static volatile frame_time_t vblank_prev_time, thread_vblank_time;
+static bool waitvblankstate (bool state, int *maxvpos)
+{
+       int vp;
+       for (;;) {
+               int omax = maxscanline;
+               if (!getvblankpos (&vp))
+                       return false;
+               while (omax != maxscanline) {
+                       omax = maxscanline;
+                       if (!getvblankpos (&vp))
+                               return false;
+               }
+               if (maxvpos)
+                       *maxvpos = maxscanline;
+               if (vp < 0) {
+                       if (state)
+                               return true;
+               } else {
+                       if (!state)
+                               return true;
+               }
+       }
+}
+
+bool vblank_busywait (void)
+{
+       int vp;
+
+       for (;;) {
+               int opos = prevvblankpos;
+               if (!getvblankpos (&vp))
+                       return false;
+               if (opos > maxscanline / 2 && vp < maxscanline / 5)
+                       return true;
+               if (vp <= 0)
+                       return true;
+       }
+}
+
+bool vblank_getstate (bool *state)
+{
+       int vp, opos;
+
+       opos = prevvblankpos;
+       if (!getvblankpos (&vp))
+               return false;
+       if (opos > maxscanline / 2 && vp < maxscanline / 5) {
+               *state = true;
+               return true;
+       }
+       if (vp <= 0) {
+               *state = true;
+               return true;
+       }
+       *state = false;
+       return true;
+}
 
-#include <process.h>
 
-static void _cdecl vblankthread (void *dummy)
+static unsigned int __stdcall flipthread (void *dummy)
+{
+       SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
+       while (flipthread_mode) {
+               WaitForSingleObject (flipevent, INFINITE);
+               if (flipthread_mode == 0)
+                       break;
+               show_screen ();
+       }
+       flipthread_mode = -1;
+       return 0;
+}
+
+static unsigned int __stdcall vblankthread (void *dummy)
 {
        while (vblankthread_mode > VBLANKTH_KILL) {
                vblankthread_counter++;
@@ -2211,8 +2321,8 @@ static void _cdecl vblankthread (void *dummy)
                } else if (vblankthread_mode == VBLANKTH_ACTIVE_START) {
                        // do not start until vblank has been passed
                        bool vb = false;
-                       getvblankstate (&vb);
-                       bool ok = getvblankstate (&vb);
+                       vblank_getstate (&vb);
+                       bool ok = vblank_getstate (&vb);
                        if (vb == false)
                                vblankthread_mode = VBLANKTH_ACTIVE;
                        else
@@ -2221,44 +2331,58 @@ static void _cdecl vblankthread (void *dummy)
                        // busy wait mode
                        frame_time_t t = read_processor_time ();
                        bool donotwait = false;
-                       if (!thread_vblank_found) {
+                       if (!vblank_found) {
                                if (t - thread_vblank_time > vblankbasewait2) {
                                        bool vb = false;
-                                       bool ok = getvblankstate (&vb);
+                                       bool ok = vblank_getstate (&vb);
                                        if (!ok || vb) {
-                                               thread_vblank_found = true;
-                                               show_screen ();
+                                               vblank_found = true;
+                                               if (isvsync_chipset () < 0) {
+                                                       vblank_found_chipset = true;
+                                                       if (!currprefs.gfx_backbuffers)
+                                                               show_screen ();
+                                               } else if (isvsync_rtg () < 0) {
+                                                       vblank_found_rtg = true;
+                                               }
                                                //write_log (L"%d\n", t - thread_vblank_time);
                                                thread_vblank_time = t;
                                                vblankthread_mode = VBLANKTH_ACTIVE_WAIT;
                                        }
-                                       if (t - thread_vblank_time > vblankbasewait3 && cpu_number > 2)
+                                       if (t - thread_vblank_time > vblankbasewait3)
                                                donotwait = true;
                                }
                        }
                        if (t - vblank_prev_time > vblankbasefull * 3)
                                vblankthread_mode = VBLANKTH_IDLE;
-                       if (!donotwait)
+                       if (!donotwait || currprefs.gfx_backbuffers || picasso_on)
                                sleep_millis (1);
                } else {
                        break;
                }
        }
        vblankthread_mode = -1;
+       return 0;
 }
 
 static int frame_missed, frame_counted, frame_errors;
 static int frame_usage, frame_usage_avg, frame_usage_total;
 extern int log_vsync;
 
+bool vsync_busywait_check (void)
+{
+       return vblankthread_mode == VBLANKTH_ACTIVE || vblankthread_mode == VBLANKTH_ACTIVE_WAIT;
+}
+
 frame_time_t vsync_busywait_end (void)
 {
-       while (!thread_vblank_found && vblankthread_mode == VBLANKTH_ACTIVE)
+       while (!vblank_found && vblankthread_mode == VBLANKTH_ACTIVE)
                sleep_millis (1);
        changevblankthreadmode (VBLANKTH_ACTIVE_WAIT);
        for (;;) {
-               int vpos = getvblankpos ();
-               if (vpos != -1) {
+               int vp;
+               getvblankpos (&vp);
+               if (vp != -1) {
+                       //write_log (L"%d ", vpos);
                        break;
                }
        }
@@ -2294,7 +2418,8 @@ bool vsync_busywait_do (int *freetime)
                console_out_f(L"F:%8d M:%8d E:%8d %3d%% (%3d%%) %10d\r", frame_counted, frame_missed, frame_errors, frame_usage, frame_usage_avg, (t - vblank_prev_time) - vblankbasefull);
        }
 
-       *freetime = 0;
+       if (freetime)
+               *freetime = 0;
        if (currprefs.turbo_emulation) {
                frame_missed++;
                return true;
@@ -2306,7 +2431,8 @@ bool vsync_busywait_do (int *freetime)
        else if (frame_usage < 0)
                frame_usage = 0;
        frame_usage_total += frame_usage;
-       *freetime = frame_usage;
+       if (freetime)
+               *freetime = frame_usage;
        if (frame_counted)
                frame_usage_avg = frame_usage_total / frame_counted;
 
@@ -2329,11 +2455,7 @@ bool vsync_busywait_do (int *freetime)
                        sleep_millis_main (1);
 
                framelost = false;
-               if (currprefs.gfx_api) {
-                       v = D3D_vblank_busywait ();
-               } else {
-                       v = DirectDraw_vblank_busywait ();
-               }
+               vblank_busywait ();
        }
 
        if (v) {
@@ -2345,6 +2467,16 @@ bool vsync_busywait_do (int *freetime)
        return false;
 }
 
+static struct remembered_vsync *vsyncmemory;
+
+struct remembered_vsync
+{
+       struct remembered_vsync *next;
+       int width, height, depth, rate, mode;
+       bool rtg;
+       double remembered_rate;
+};
+
 double vblank_calibrate (double approx_vblank, bool waitonly)
 {
        frame_time_t t1, t2;
@@ -2352,26 +2484,53 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
        int maxcnt, maxtotal, total, cnt, tcnt2;
        HANDLE th;
        int maxvpos, div;
+       int width, height, depth, rate, mode;
+       struct remembered_vsync *rv;
+       double rval = -1;
+
+       if (picasso_on) {
+               width = picasso96_state.Width;
+               height = picasso96_state.Height;
+               depth = picasso96_state.BytesPerPixel;
+       } else {
+               width = currentmode->native_width;
+               height = currentmode->native_height;
+               depth = (currentmode->native_depth + 7) / 8;
+       }
+       rate = currprefs.gfx_refreshrate;
+       mode = isfullscreen ();
+       rv = vsyncmemory;
+       while (rv) {
+               if (rv->width == width && rv->height == height && rv->depth == depth && rv->rate == rate && rv->mode == mode && rv->rtg == picasso_on) {
+                       approx_vblank = rv->remembered_rate;
+                       rval = approx_vblank;
+                       waitonly = true;
+                       write_log (L"VSync calibration: remembered rate %.6fHz\n", rval);
+                       break;
+               }
+               rv = rv->next;
+       }
        
-       threaded_vsync = (cpu_number > 1 && currprefs.m68k_speed < 0);
+       threaded_vsync = isvsync () == -2;
 
-       if (remembered_vblank > 0 && (!threaded_vsync || (threaded_vsync && vblankthread_mode > 0)))
-               return remembered_vblank;
        if (waitonly) {
                vblankbasefull = syncbase / approx_vblank;
                vblankbasewait = (syncbase / approx_vblank) * 3 / 4;
-               vblankbasewait2 = (syncbase / approx_vblank) * 7 / 10;
-               vblankbasewait3 = (syncbase / approx_vblank) * 9 / 10;
-               remembered_vblank = -1;
-               return -1;
+               vblankbasewait2 = (syncbase / approx_vblank) * 70 / 100;
+               vblankbasewait3 = (syncbase / approx_vblank) * 90 / 100;
+               return rval;
        }
 
        th = GetCurrentThread ();
        int oldpri = GetThreadPriority (th);
        SetThreadPriority (th, THREAD_PRIORITY_HIGHEST);
        if (vblankthread_mode <= VBLANKTH_KILL) {
+               unsigned th;
                vblankthread_mode = VBLANKTH_CALIBRATE;
-               _beginthread (&vblankthread, 0, 0);
+               _beginthreadex (NULL, 0, vblankthread, 0, 0, &th);
+               flipthread_mode = 1;
+               flipevent = CreateEvent (NULL, FALSE, FALSE, NULL);
+               _beginthreadex (NULL, 0, flipthread, 0, 0, &th);
        } else {
                changevblankthreadmode (VBLANKTH_CALIBRATE);
        }
@@ -2434,6 +2593,22 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
        write_log (L"VSync calibration: %.6fHz/%d=%.6fHz. MaxV=%d Units=%d Mode=%s\n", tsum, div, tsum2, maxvpos, vblankbasefull, threaded_vsync ? L"threaded" : L"normal");
        remembered_vblank = tsum2;
        vblank_prev_time = read_processor_time ();
+       
+       rv = xcalloc (struct remembered_vsync, 1);
+       rv->width = width;
+       rv->height = height;
+       rv->depth = depth;
+       rv->rate = rate;
+       rv->mode = isfullscreen ();
+       rv->rtg = picasso_on;
+       rv->remembered_rate = tsum2;
+       if (vsyncmemory == NULL) {
+               vsyncmemory = rv;
+       } else {
+               rv->next = vsyncmemory;
+               vsyncmemory = rv;
+       } 
+       
        return tsum;
 fail:
        write_log (L"VSync calibration failed\n");
@@ -2696,7 +2871,7 @@ static int set_ddraw (void)
        return 1;
 }
 
-static void allocsoftbuffer(struct vidbuffer *buf, int flags, int width, int height, int depth)
+static void allocsoftbuffer (struct vidbuffer *buf, int flags, int width, int height, int depth)
 {
 
        buf->pixbytes = (depth + 7) / 8;
@@ -2754,7 +2929,7 @@ static BOOL doInit (void)
        int tmp_depth;
        int ret = 0;
 
-       remembered_vblank = 0;
+       remembered_vblank = -1;
        if (wasfullwindow_a == 0)
                wasfullwindow_a = currprefs.gfx_afullscreen == GFX_FULLWINDOW ? 1 : -1;
        if (wasfullwindow_p == 0)
@@ -2992,10 +3167,6 @@ void updatewinfsmode (struct uae_prefs *p)
                p->gfx_size = p->gfx_size_win;
        }
        md = getdisplay (p);
-       if (md->disabled) {
-               p->gfx_display = 0;
-               md = getdisplay (p);
-       }
        config_changed = 1;
 }
 
index 2ad4261edef322e0dacb53d851de3a51684ecdf7..509dc202b706cf97a576adda52aa952834615a6a 100644 (file)
@@ -33,6 +33,8 @@ extern void releasehdc (HDC hdc);
 extern void close_windows (void);
 extern void updatewinfsmode (struct uae_prefs *p);
 extern int is3dmode (void);
+extern void gfx_lock (void);
+extern void gfx_unlock (void);
 
 void DX_Fill (int dstx, int dsty, int width, int height, uae_u32 color);
 void DX_Blit (int x, int y, int w, int h);
index 0bc09c9b145b7a33e2bb8ca96cadb2e5f73fad11..402f7751d485e2ba057b62a053a66391fd0461ad 100644 (file)
@@ -5652,10 +5652,12 @@ static void values_to_displaydlg (HWND hDlg)
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE, CB_ADDSTRING, 0, (LPARAM)buffer);
 
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)L"-");
+#if 0
        WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC, buffer, sizeof buffer / sizeof (TCHAR));
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)buffer);
        WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC_AUTOSWITCH, buffer, sizeof buffer / sizeof (TCHAR));
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)buffer);
+#endif
        WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC2, buffer, sizeof buffer / sizeof (TCHAR));
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)buffer);
        WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC2_AUTOSWITCH, buffer, sizeof buffer / sizeof (TCHAR));
@@ -5664,7 +5666,7 @@ static void values_to_displaydlg (HWND hDlg)
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE, CB_SETCURSEL,
                workprefs.gfx_afullscreen, 0);
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_SETCURSEL,
-               workprefs.gfx_avsync == 0 ? 0 : workprefs.gfx_avsync + workprefs.gfx_avsyncmode * 2, 0);
+               workprefs.gfx_avsync, 0);
 
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG, CB_RESETCONTENT, 0, 0);
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_RESETCONTENT, 0, 0);
@@ -5677,15 +5679,21 @@ static void values_to_displaydlg (HWND hDlg)
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG, CB_ADDSTRING, 0, (LPARAM)buffer);
 
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)L"-");
+#if 0
        WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC, buffer, sizeof buffer / sizeof (TCHAR));
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer);
        WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC_AUTOSWITCH, buffer, sizeof buffer / sizeof (TCHAR));
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer);
+#endif
+       WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC2, buffer, sizeof buffer / sizeof (TCHAR));
+       SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer);
+       WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC2_AUTOSWITCH, buffer, sizeof buffer / sizeof (TCHAR));
+       SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer);
 
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG, CB_SETCURSEL,
                workprefs.gfx_pfullscreen, 0);
        SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_SETCURSEL,
-               workprefs.gfx_pvsync == 0 ? 0 : workprefs.gfx_pvsync + workprefs.gfx_pvsyncmode, 0);
+               workprefs.gfx_pvsync, 0);
 
        SendDlgItemMessage(hDlg, IDC_LORES, CB_RESETCONTENT, 0, 0);
        WIN32GUI_LoadUIString(IDS_RES_LORES, buffer, sizeof buffer / sizeof (TCHAR));
@@ -5735,19 +5743,75 @@ static void init_resolution_combo (HWND hDlg)
                }
        }
 }
+
 static void init_displays_combo (HWND hDlg)
 {
-       int i = 0;
+       TCHAR *adapter = L"";
+       struct MultiDisplay *md = Displays;
+       int cnt = 0, cnt2 = 0;
+       int displaynum;
+       int idx = 0;
+
+       displaynum = workprefs.gfx_display - 1;
+       if (displaynum < 0)
+               displaynum = 0;
        SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_RESETCONTENT, 0, 0);
-       while (Displays[i].name) {
-               SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_ADDSTRING, 0, (LPARAM)Displays[i].name);
-               i++;
+       while (md->monitorname) {
+               if (_tcscmp (md->adapterkey, adapter) != 0) {
+                       SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_ADDSTRING, 0, (LPARAM)md->adaptername);
+                       adapter = md->adapterkey;
+                       cnt++;
+               }
+               TCHAR buf[MAX_DPATH];
+               _stprintf (buf, L"  %s", md->fullname);
+               SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_ADDSTRING, 0, (LPARAM)buf);
+               if (displaynum == cnt2)
+                       idx = cnt;
+               md++;
+               cnt2++;
+               cnt++;
+       }
+       SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_SETCURSEL, idx, 0);
+}
+
+static void get_displays_combo (HWND hDlg)
+{
+       struct MultiDisplay *md = Displays;
+       LRESULT posn;
+       TCHAR *adapter = L"";
+       int cnt = 0, cnt2 = 0;
+       int displaynum;
+
+       posn = SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_GETCURSEL, 0, 0);
+       if (posn == CB_ERR)
+               return;
+
+       displaynum = workprefs.gfx_display - 1;
+       if (displaynum < 0)
+               displaynum = 0;
+       while (md->monitorname) {
+               int foundnum = -1;
+               if (_tcscmp (md->adapterkey, adapter) != 0) {
+                       adapter = md->adapterkey;
+                       if (posn == cnt)
+                               foundnum = cnt2;
+                       cnt++;
+               }
+               if (posn == cnt)
+                       foundnum = cnt2;
+               if (foundnum >= 0) {
+                       if (foundnum == displaynum)
+                               return;
+                       workprefs.gfx_display = foundnum + 1;
+                       init_displays_combo (hDlg);
+                       init_resolution_combo (hDlg);
+                       init_display_mode (hDlg);
+                       return;
+               }
+               cnt++;
+               cnt2++;
+               md++;
        }
-       if (workprefs.gfx_display > i)
-               workprefs.gfx_display = 0;
-       if (workprefs.gfx_display < 1)
-               workprefs.gfx_display = 1;
-       SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_SETCURSEL, workprefs.gfx_display - 1, 0);
 }
 
 static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -5775,7 +5839,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
        if (i > 0) {
                i--;
                workprefs.gfx_avsync = (i & 1) + 1;
-               workprefs.gfx_avsyncmode = i >= 2 ? 1 : 0;
+               workprefs.gfx_avsyncmode = 1;
        }
 
        workprefs.gfx_pfullscreen = SendDlgItemMessage (hDlg, IDC_SCREENMODE_RTG, CB_GETCURSEL, 0, 0);
@@ -5784,8 +5848,8 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
        workprefs.gfx_pvsyncmode = 0;
        if (i > 0) {
                i--;
-               workprefs.gfx_pvsync = 1;
-               workprefs.gfx_pvsyncmode = i >= 1 ? 1 : 0;
+               workprefs.gfx_pvsync = (i & 1) + 1;
+               workprefs.gfx_pvsyncmode = 1;
        }
        
        bool updaterate = false, updateslider = false;
@@ -5879,14 +5943,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
        if (msg == WM_COMMAND && HIWORD (wParam) == CBN_SELCHANGE)
        {
                if (LOWORD (wParam) == IDC_DISPLAYSELECT) {
-                       posn = SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_GETCURSEL, 0, 0);
-                       if (posn != CB_ERR && posn + 1 != workprefs.gfx_display) {
-                               if (Displays[posn].disabled)
-                                       posn = 0;
-                               workprefs.gfx_display = posn + 1;
-                               init_resolution_combo (hDlg);
-                               init_display_mode (hDlg);
-                       }
+                       get_displays_combo (hDlg);
                        return;
                } else if (LOWORD (wParam) == IDC_LORES) {
                        posn = SendDlgItemMessage (hDlg, IDC_LORES, CB_GETCURSEL, 0, 0);
@@ -8074,7 +8131,7 @@ extern int soundpercent;
 
 static void update_soundgui (HWND hDlg)
 {
-       int bufsize, canexc;
+       int bufsize;
        TCHAR txt[20];
 
        bufsize = exact_log2 (workprefs.sound_maxbsiz / 1024);
@@ -8088,13 +8145,6 @@ static void update_soundgui (HWND hDlg)
        SendDlgItemMessage (hDlg, IDC_SOUNDDRIVEVOLUME, TBM_SETPOS, TRUE, 100 - workprefs.dfxclickvolume);
        _stprintf (txt, L"%d%%", 100 - workprefs.dfxclickvolume);
        SetDlgItemText (hDlg, IDC_SOUNDDRIVEVOLUME2, txt);
-
-       canexc = sound_devices[workprefs.win32_soundcard]->type == SOUND_DEVICE_WASAPI;
-       ew (hDlg, IDC_SOUND_EXCLUSIVE, canexc);
-       if (!canexc)
-               workprefs.win32_soundexclusive = 0;
-       CheckDlgButton (hDlg, IDC_SOUND_EXCLUSIVE, workprefs.win32_soundexclusive);
-
 }
 
 static int soundfreqs[] = { 11025, 15000, 22050, 32000, 44100, 48000, 0 };
@@ -8311,7 +8361,6 @@ static void values_from_sounddlg (HWND hDlg)
        }
 
        workprefs.sound_interpol = SendDlgItemMessage (hDlg, IDC_SOUNDINTERPOLATION, CB_GETCURSEL, 0, 0);
-       workprefs.win32_soundexclusive = ischecked (hDlg, IDC_SOUND_EXCLUSIVE);
        soundcard = SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_GETCURSEL, 0, 0L);
        if (soundcard != workprefs.win32_soundcard && soundcard != CB_ERR) {
                workprefs.win32_soundcard = soundcard;
@@ -8406,7 +8455,7 @@ static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                TCHAR tmp[MAX_DPATH];
                                int type = sound_devices[card]->type;
                                _stprintf (tmp, L"%s: %s",
-                                       type == SOUND_DEVICE_DS ? L"DSOUND" : (type == SOUND_DEVICE_AL ? L"OpenAL" : (type == SOUND_DEVICE_PA ? L"PortAudio" : L"WASAPI")),
+                                       type == SOUND_DEVICE_DS ? L"DSOUND" : (type == SOUND_DEVICE_AL ? L"OpenAL" : (type == SOUND_DEVICE_PA ? L"PortAudio" : (type == SOUND_DEVICE_WASAPI ? L"WASAPI" : L"WASAPI EX"))),
                                        sound_devices[card]->name);
                                SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_ADDSTRING, 0, (LPARAM)tmp);
                        }
@@ -12876,9 +12925,11 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                *pc = v;
                                SetDlgItemInt (hDlg, IDC_FILTERXLV, v, TRUE);
                        }
-                       init_colors ();
-                       notice_new_xcolors ();
-                       reset_drawing ();
+                       if (!full_property_sheet) {
+                               init_colors ();
+                               notice_new_xcolors ();
+                               reset_drawing ();
+                       }
                        updatedisplayarea ();
                        WIN32GFX_WindowMove ();
                        recursive--;
@@ -14560,13 +14611,13 @@ void gui_led (int led, int on)
                on &= 1;
        } else if (led == LED_FPS) {
                double fps = (double)gui_data.fps / 10.0;
-               extern int p96vblank;
+               extern double p96vblank;
                pos = 2;
                ptr = drive_text + pos * 16;
                if (fps > 999.9)
                        fps = 999.9;
                if (picasso_on)
-                       _stprintf (ptr, L"%d [%.1f]", p96vblank, fps);
+                       _stprintf (ptr, L"%.1f [%.1f]", p96vblank, fps);
                else
                        _stprintf (ptr, L"FPS: %.1f", fps);
                if (pause_emulation) {
index 66528833e10d41f767868f06fae2c7bf7ae07d28..06d768d411813bca33ba04431cfa17b448ef1dd7 100644 (file)
@@ -1,4 +1,18 @@
 
+Beta 6:
+
+New vsync should finally work in all modes.
+
+- Removed sound exclusive checkbox, WASAPI exclusive modes are now listed in select menu.
+- New RTG vsync using low latency sync method, currently always triple buffered.
+- Display selection GUI changed again, now lists both display adapter(s) and connected monitor(s).
+- Associated ".uae" didn't set correct icon id (right click on .uae shows wrong or missing icon). Reset .uae association again to fix it.
+- Fixed filter panel hang in some situations before emulation was started.
+- Low latency vsync keeps list of modes that have already been calibrated, switching back to remembered mode uses stored calibration value.
+- Unreliable old-style vsync options are gone. Replaced by low latency + double or triple buffered mode.
+- DirectDraw low latency vsync fully implemented.
+- RTG hardware cursor positioning fixed in aspect ratio corrected full window modes.
+
 Beta 5:
 
 - Removed obsolete fake (50), (60), (100) and (120) refresh rates.
@@ -10,7 +24,7 @@ Beta 5:
 - Fixed Sound panel crash if sound card id stored in configuration file was larger than available number of sound card drivers.
 - Handle situation where PortAudio Pa_IsFormatSupported() returns true but Pa_OpenStream() fails with paInvalidSampleRate.
   (Usually seems to happen when requesting 44100Hz but hardware supports only 48000Hz) 
-- VSync sound syncronization improved (All types: DirectSound, WASAPI, OpenAL and PortAudio)
+- VSync sound syncronization improved (All types: DirectSound, WASAPI, OpenAL and PortAudio). Note that buffer settings are not same between device types.
 - SND% blue/yellow/red flickering fix, previously flickering speed changed depending on buffer size.
 - More fastest possible/JIT low latency vsync updates.