From: Toni Wilen Date: Thu, 22 Dec 2011 17:22:27 +0000 (+0200) Subject: 2400b6 X-Git-Tag: 2400~22 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=ce3438ef12176e9b05918f786c55cc23fe383c7e;p=francis%2Fwinuae.git 2400b6 --- diff --git a/audio.cpp b/audio.cpp index 457ada09..dd31a7e3 100644 --- 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; diff --git a/cfgfile.cpp b/cfgfile.cpp index 860fe381..f5a2c268 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -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); diff --git a/custom.cpp b/custom.cpp index df6ae35d..a4c8e99e 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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 diff --git a/drawing.cpp b/drawing.cpp index a5cec307..320c2621 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -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 (); +} diff --git a/gfxutil.cpp b/gfxutil.cpp index 4ff0b5ff..7690ce09 100644 --- a/gfxutil.cpp +++ b/gfxutil.cpp @@ -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; diff --git a/include/events_jit.h b/include/events_jit.h index 3f5bac88..c61f3704 100644 --- a/include/events_jit.h +++ b/include/events_jit.h @@ -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; } diff --git a/include/options.h b/include/options.h index 23c51bc5..88ddbd06 100644 --- a/include/options.h +++ b/include/options.h @@ -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; diff --git a/include/xwin.h b/include/xwin.h index 85440ea1..9cc7510b 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -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*); diff --git a/main.cpp b/main.cpp index 80c47d93..f0b82357 100644 --- 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) diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 3d1f1f0f..281d8046 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -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; } diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 25b01f2a..2abf5fd5 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -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; diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index 4b5ce790..1eb7f2f6 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -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; } diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index ba67a1f8..b827eeaa 100644 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -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); diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 05d9fda8..8b4599bf 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -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); diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index 09c3f616..e8dfa579 100644 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -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); diff --git a/od-win32/resources/resource b/od-win32/resources/resource index 284804e5..2eebbf6f 100644 --- a/od-win32/resources/resource +++ b/od-win32/resources/resource @@ -932,7 +932,6 @@ #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 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 59cfbcb6..ddedae92 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -115,9 +115,9 @@ STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN GROUPBOX "Screen",IDC_SCREENRESTEXT,4,0,292,67,BS_LEFT - COMBOBOX IDC_DISPLAYSELECT,59,10,225,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DISPLAYSELECT,10,10,279,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_RESOLUTION,59,27,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_REFRESHRATE,187,27,97,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_REFRESHRATE,187,27,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP EDITTEXT IDC_XSIZE,59,48,48,12,ES_NUMBER EDITTEXT IDC_YSIZE,114,48,47,12,ES_NUMBER GROUPBOX "Settings",IDC_SETTINGSTEXT,4,73,209,137 @@ -147,8 +147,8 @@ BEGIN COMBOBOX IDC_LORES,103,152,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "Remove interlace artifacts",IDC_FLICKERFIXER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,139,99,10 RTEXT "Windowed:",IDC_STATIC,13,46,40,15,SS_CENTERIMAGE - RTEXT "Fullscreen:",IDC_STATIC,13,19,40,15,SS_CENTERIMAGE - COMBOBOX IDC_DISPLAY_BUFFERCNT,187,47,97,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + RTEXT "Fullscreen:",IDC_STATIC,11,27,40,15,SS_CENTERIMAGE + COMBOBOX IDC_DISPLAY_BUFFERCNT,187,47,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "Resolution autoswitch",IDC_AUTORESOLUTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,139,89,10 EDITTEXT IDC_DA_TEXT,167,218,46,12,ES_AUTOHSCROLL | ES_READONLY COMBOBOX IDC_SCREENMODE_NATIVE2,112,85,95,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP @@ -324,12 +324,12 @@ BEGIN CONTROL "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,35,101,10 CONTROL "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,53,102,10 CONTROL "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,71,102,10 - GROUPBOX "Volume",IDC_STATIC,132,36,164,31 - CONTROL "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,44,105,20 - EDITTEXT IDC_SOUNDVOLUME2,247,47,40,12,ES_CENTER | ES_READONLY - GROUPBOX "Sound Buffer Size",IDC_STATIC,132,73,164,31 - CONTROL "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,81,105,19 - EDITTEXT IDC_SOUNDBUFFERMEM,247,84,40,12,ES_CENTER | ES_READONLY + GROUPBOX "Volume",IDC_STATIC,132,20,164,31 + CONTROL "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,29,105,20 + EDITTEXT IDC_SOUNDVOLUME2,247,32,40,12,ES_CENTER | ES_READONLY + GROUPBOX "Sound Buffer Size",IDC_STATIC,132,59,164,31 + CONTROL "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,67,105,19 + EDITTEXT IDC_SOUNDBUFFERMEM,247,70,40,12,ES_CENTER | ES_READONLY GROUPBOX "Settings",IDC_SOUNDINTERPOLATION2,6,106,290,60 LTEXT "Frequency:",IDC_SOUNDFREQTXT,11,140,53,8,SS_CENTERIMAGE COMBOBOX IDC_SOUNDFREQ,13,149,51,75,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP @@ -351,7 +351,6 @@ BEGIN COMBOBOX IDC_SOUNDSWAP,73,149,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Swap channels:",IDC_SOUNDSWAPTXT,74,140,61,8,SS_CENTERIMAGE CONTROL "Automatic switching",IDC_SOUND_AUTO,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,14,89,103,10 - CONTROL "Exclusive mode",IDC_SOUND_EXCLUSIVE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,137,25,154,10 CONTROL "DirectSound",IDC_SOUND_DS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,181,55,10 CONTROL "WASAPI",IDC_SOUND_WASAPI,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,193,53,10 CONTROL "OpenAL",IDC_SOUND_OPENAL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,205,53,10 diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index 63d1f3ca..1824a75f 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -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 diff --git a/od-win32/sounddep/sound.cpp b/od-win32/sounddep/sound.cpp index e2e54459..e1e5aea5 100644 --- a/od-win32/sounddep/sound.cpp +++ b/od-win32/sounddep/sound.cpp @@ -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) diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 7a0ea4bf..fc186fe0 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -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)); diff --git a/od-win32/win32.h b/od-win32/win32.h index bc1b96b0..ff3f8802 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -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 { diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 5f7ddc98..d5414eb0 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -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 -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 -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; } diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index 2ad4261e..509dc202 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -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); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 0bc09c9b..402f7751 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -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) { diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 66528833..06d768d4 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -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.