From 4e1fa9facbda0029ec79fb3355f029f900a51b2f Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 5 May 2012 17:02:26 +0300 Subject: [PATCH] 2410b13 --- cfgfile.cpp | 20 +++- custom.cpp | 70 +++++++++++--- filesys.cpp | 2 +- include/options.h | 2 +- include/xwin.h | 2 +- main.cpp | 2 +- od-win32/blkdev_win32_ioctl.cpp | 44 +++++---- od-win32/bsdsock.cpp | 3 + od-win32/direct3d.cpp | 2 +- od-win32/dxwrap.cpp | 3 +- od-win32/fsdb_mywin32.cpp | 1 + od-win32/hardfile_win32.cpp | 2 - od-win32/picasso96_win.cpp | 2 +- od-win32/registry.cpp | 39 ++++++++ od-win32/registry.h | 2 + od-win32/win32.cpp | 11 +-- od-win32/win32.h | 4 +- od-win32/win32gfx.cpp | 158 ++++++++++++++++++++++---------- od-win32/win32gui.cpp | 1 + od-win32/winuaechangelog.txt | 22 +++++ 20 files changed, 290 insertions(+), 102 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index def72097..8e74abb4 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -801,10 +801,12 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_bool (f, _T("native_code"), p->native_code); cfgfile_write (f, _T("gfx_display"), _T("%d"), p->gfx_apmode[APMODE_NATIVE].gfx_display); - cfgfile_write_str (f, _T("gfx_display_name"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display)); + cfgfile_write_str (f, _T("gfx_display_friendlyname"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, true)); + cfgfile_write_str (f, _T("gfx_display_name"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, false)); if (p->gfx_apmode[APMODE_NATIVE].gfx_display != p->gfx_apmode[APMODE_RTG].gfx_display) { cfgfile_write (f, _T("gfx_display_rtg"), _T("%d"), p->gfx_apmode[APMODE_RTG].gfx_display); - cfgfile_write_str (f, _T("gfx_display_name_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display)); + cfgfile_write_str (f, _T("gfx_display_friendlyname_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, true)); + cfgfile_write_str (f, _T("gfx_display_name_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, false)); } cfgfile_write (f, _T("gfx_framerate"), _T("%d"), p->gfx_framerate); cfgfile_write (f, _T("gfx_width"), _T("%d"), p->gfx_size_win.width); /* compatibility with old versions */ @@ -1594,8 +1596,13 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (cfgfile_intval (option, value, _T("gfx_display_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_display, 1)) { return 1; } - if (_tcscmp (option, _T("gfx_display_name")) == 0) { + if (_tcscmp (option, _T("gfx_display_friendlyname")) == 0 || _tcscmp (option, _T("gfx_display_name")) == 0) { TCHAR tmp[MAX_DPATH]; + if (cfgfile_string (option, value, _T("gfx_display_friendlyname"), tmp, sizeof tmp / sizeof (TCHAR))) { + int num = target_get_display (tmp); + if (num >= 0) + p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num; + } if (cfgfile_string (option, value, _T("gfx_display_name"), tmp, sizeof tmp / sizeof (TCHAR))) { int num = target_get_display (tmp); if (num >= 0) @@ -1603,8 +1610,13 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) } return 1; } - if (_tcscmp (option, _T("gfx_display_name_rtg")) == 0) { + if (_tcscmp (option, _T("gfx_display_friendlyname_rtg")) == 0 || _tcscmp (option, _T("gfx_display_name_rtg")) == 0) { TCHAR tmp[MAX_DPATH]; + if (cfgfile_string (option, value, _T("gfx_display_friendlyname_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) { + int num = target_get_display (tmp); + if (num >= 0) + p->gfx_apmode[APMODE_RTG].gfx_display = num; + } if (cfgfile_string (option, value, _T("gfx_display_name_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) { int num = target_get_display (tmp); if (num >= 0) diff --git a/custom.cpp b/custom.cpp index 7c38035c..a63ce923 100644 --- a/custom.cpp +++ b/custom.cpp @@ -2849,6 +2849,9 @@ void compute_framesync (void) v2 = vblank_calibrate (cr->locked ? cr->rate : vblank_hz, cr->locked); if (!cr->locked) v = v2; + } else if (isvsync_chipset () > 0) { + if (currprefs.gfx_apmode[0].gfx_refreshrate) + v = abs (currprefs.gfx_apmode[0].gfx_refreshrate); } } else { if (cr->locked == false) { @@ -5210,6 +5213,10 @@ static void framewait (void) frame_time_t curr_time; frame_time_t start; int vs = isvsync_chipset (); + int frameskipt; + + frameskipt = frameskiptime; + frameskiptime = 0; is_syncline = 0; @@ -5234,38 +5241,61 @@ static void framewait (void) if (vs == -2 || vs == -3) { // fastest possible - int max, adjust; + static int skipcnt; + int max, adjust, flipdelay; frame_time_t now; - curr_time = vsync_busywait_end (); // vsync time + curr_time = vsync_busywait_end (&flipdelay); // vsync time vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); vsync_busywait_start (); + if (flipdelay > skipcnt) + skipcnt = flipdelay; + else + skipcnt -= vsynctimebase / (4 * (maxvpos_nom + 1)); + if (skipcnt > 0) + skipcnt--; + else + skipcnt = 0; + now = read_processor_time (); // current time adjust = (int)now - (int)curr_time; if (adjust < 0) adjust = 0; - if (adjust > vsynctimebase / 3) - adjust = vsynctimebase / 3; + + if (currprefs.gfx_apmode[0].gfx_vflip == 0) { + adjust += skipcnt; + //write_log (L"%d ", skipcnt); + } + + if (adjust > vsynctimebase / 2) + adjust = vsynctimebase / 2; + + max = (vsynctimebase - adjust) * (1000 + currprefs.m68k_speed_throttle) / 1000; + if (max < 1) + max = 1; - max = (vsynctimebase - (adjust * 3 / 2)) * (1000 + currprefs.m68k_speed_throttle) / 1000; vsyncmintime = now; - vsyncwaittime = curr_time + vsynctimebase; + vsyncwaittime = curr_time + (vsynctimebase - 0); vsynctimeperline = max / (maxvpos_nom + 1); + if (vsynctimeperline < 1) + vsynctimeperline = 1; vsyncmaxtime = now + max; } else { - int max, adjust; + static int skipcnt; + int max, adjust, flipdelay; frame_time_t now; + flipdelay = 0; render_screen (); bool show = show_screen_maybe (false); vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); curr_time = read_processor_time (); - if (!show) { - show_screen (); + if (!show) { + vsync_busywait_end (&flipdelay); if (extraframewait) sleep_millis_main (extraframewait); } @@ -5280,7 +5310,22 @@ static void framewait (void) vsyncmintime = now; vsyncwaittime = curr_time + vsynctimebase; - vsynctimeperline = max / 3; + if (currprefs.gfx_apmode[0].gfx_vflip == 0) { + if (flipdelay > skipcnt) + skipcnt = flipdelay; + else + skipcnt -= vsynctimebase / (4 * (maxvpos_nom + 1)); + if (skipcnt > 0) + skipcnt--; + else + skipcnt = 0; + } else { + skipcnt = 0; + } + + vsynctimeperline = (max - skipcnt * 2) / 3; + if (vsynctimeperline < 1) + vsynctimeperline = 1; vsyncmaxtime = now + max; frame_shown = true; @@ -5313,9 +5358,8 @@ static void framewait (void) vsyncmintime = curr_time; #if 0 - max -= frameskiptime; + max -= frameskipt; #endif - frameskiptime = 0; if (max < 0) { max = 0; vsynctimeperline = 1; @@ -5952,6 +5996,7 @@ static void hsync_handler_post (bool onvsync) /* really last line, just run the cpu emulation until whole vsync time has been used */ if (currprefs.m68k_speed_throttle) { vsyncmintime = read_processor_time (); /* end of CPU emulation time */ + is_syncline = 0; } else { vsyncmintime = vsyncmaxtime; /* emulate if still time left */ is_syncline_end = read_processor_time () + vsynctimebase; @@ -6109,7 +6154,6 @@ static void hsync_handler_post (bool onvsync) vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3); if (vblank_hz_state) { render_screen (); - show_screen_maybe (false); } frame_shown = true; end = read_processor_time (); diff --git a/filesys.cpp b/filesys.cpp index 9c012fa3..048dbfd7 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -3570,7 +3570,7 @@ end: static int action_examine_all_do (Unit *unit, uaecptr lock, ExAllKey *eak, uaecptr exalldata, uae_u32 exalldatasize, uae_u32 type, uaecptr control) { - a_inode *aino, *base; + a_inode *aino, *base = NULL; int ok; uae_u32 err; struct fs_dirhandle *d; diff --git a/include/options.h b/include/options.h index 387ddc03..f4668a08 100644 --- a/include/options.h +++ b/include/options.h @@ -545,7 +545,7 @@ extern void target_fixup_options (struct uae_prefs *); extern int target_cfgfile_load (struct uae_prefs *, const TCHAR *filename, int type, int isdefault); extern void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type); extern int target_get_display (const TCHAR*); -extern const TCHAR *target_get_display_name (int); +extern const TCHAR *target_get_display_name (int, bool); extern int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ignorelink, int userconfig); extern int cfgfile_save (struct uae_prefs *p, const TCHAR *filename, int); diff --git a/include/xwin.h b/include/xwin.h index eac0485d..6ab7ea55 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -28,7 +28,7 @@ extern void toggle_fullscreen (int); extern void toggle_mousegrab (void); extern void desktop_coords (int *dw, int *dh, int *x, int *y, int *w, int *h); extern bool vsync_switchmode (int); -extern frame_time_t vsync_busywait_end (void); +extern frame_time_t vsync_busywait_end (int*); extern bool vsync_busywait_do (int*, bool, bool); extern void vsync_busywait_start (void); extern double vblank_calibrate (double, bool); diff --git a/main.cpp b/main.cpp index 20274428..f13f125e 100644 --- a/main.cpp +++ b/main.cpp @@ -175,7 +175,7 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs) } else { // legacy vsync: always wait for flip ap->gfx_vflip = -1; - if (ap->gfx_backbuffers < 1) + if (prefs->gfx_api && ap->gfx_backbuffers < 1) ap->gfx_backbuffers = 1; } } else { diff --git a/od-win32/blkdev_win32_ioctl.cpp b/od-win32/blkdev_win32_ioctl.cpp index 1319bf67..8aaafa0b 100644 --- a/od-win32/blkdev_win32_ioctl.cpp +++ b/od-win32/blkdev_win32_ioctl.cpp @@ -1209,27 +1209,31 @@ static int sys_cddev_open (struct dev_info_ioctl *ciw, int unitnum) _tcscpy (ciw->di.vendorid, _T("UAE")); _stprintf (ciw->di.productid, _T("SCSI CD%d IMG"), unitnum); _tcscpy (ciw->di.revision, _T("0.1")); + memset (inquiry, 0, sizeof inquiry); if (spti_inquiry (ciw, unitnum, inquiry)) { - char tmp[20]; - TCHAR *s; - memcpy (tmp, inquiry + 8, 8); - tmp[8] = 0; - s = au (tmp); - trim (s); - _tcscpy (ciw->di.vendorid, s); - xfree (s); - memcpy (tmp, inquiry + 16, 16); - tmp[16] = 0; - s = au (tmp); - trim (s); - _tcscpy (ciw->di.productid, s); - xfree (s); - memcpy (tmp, inquiry + 32, 4); - tmp[4] = 0; - s = au (tmp); - trim (s); - _tcscpy (ciw->di.revision, s); - xfree (s); + // check also that device type is non-zero and it is removable + if ((inquiry[0] & 31) && (inquiry[1] & 0x80) && inquiry[8]) { + char tmp[20]; + TCHAR *s; + memcpy (tmp, inquiry + 8, 8); + tmp[8] = 0; + s = au (tmp); + trim (s); + _tcscpy (ciw->di.vendorid, s); + xfree (s); + memcpy (tmp, inquiry + 16, 16); + tmp[16] = 0; + s = au (tmp); + trim (s); + _tcscpy (ciw->di.productid, s); + xfree (s); + memcpy (tmp, inquiry + 32, 4); + tmp[4] = 0; + s = au (tmp); + trim (s); + _tcscpy (ciw->di.revision, s); + xfree (s); + } close_createfile (ciw); } diff --git a/od-win32/bsdsock.cpp b/od-win32/bsdsock.cpp index c8fc3d7c..66ef10bc 100644 --- a/od-win32/bsdsock.cpp +++ b/od-win32/bsdsock.cpp @@ -2402,6 +2402,8 @@ static int run_get_thread(TrapContext *context, SB, struct threadargs *args) static void release_get_thread(int index) { + if (index < 0) + return; bsd->threadGetargs_inuse[index] = GET_STATE_REALLY_DONE; } @@ -2424,6 +2426,7 @@ void host_gethostbynameaddr (TrapContext *context, SB, uae_u32 name, uae_u32 nam // InternetSetOption(0,INTERNET_OPTION_SETTINGS_CHANGED,&on,strlen(&on)); // Do not use: Causes locks with some machines + tindex = -1; memset(&args, 0, sizeof (args)); argsp = &args; argsp->wscnt = ++wscounter; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index b0c66dc6..7a9ee306 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -2220,7 +2220,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) D3DHEAD, (d3dCaps.PixelShaderVersion >> 8) & 0xff, d3dCaps.PixelShaderVersion & 0xff, (d3dCaps.VertexShaderVersion >> 8) & 0xff, d3dCaps.VertexShaderVersion & 0xff, - max_texture_w, max_texture_h, + modeex.Width, modeex.Height, dpp.FullScreen_RefreshRateInHz, dpp.Windowed ? _T("") : _T(" FS"), vsync, ap->gfx_backbuffers, diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index bee31888..aaaccc69 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -348,7 +348,8 @@ HRESULT DirectDraw_CreateMainSurface (int width, int height) DWORD oldflags = desc.dwFlags; desc.dwFlags |= DDSD_BACKBUFFERCOUNT; desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; - desc.dwBackBufferCount = ap->gfx_backbuffers == 0 ? 1 : ap->gfx_backbuffers; + //desc.dwBackBufferCount = ap->gfx_backbuffers == 0 ? 1 : ap->gfx_backbuffers; + desc.dwBackBufferCount = ap->gfx_backbuffers; if (desc.dwBackBufferCount > 0) { ddrval = IDirectDraw7_CreateSurface (dxdata.maindd, &desc, &dxdata.primary, NULL); if (SUCCEEDED (ddrval)) { diff --git a/od-win32/fsdb_mywin32.cpp b/od-win32/fsdb_mywin32.cpp index 1a7cab87..e087da4a 100644 --- a/od-win32/fsdb_mywin32.cpp +++ b/od-win32/fsdb_mywin32.cpp @@ -355,6 +355,7 @@ int dos_errno (void) case ERROR_INVALID_HANDLE: case ERROR_BAD_NETPATH: case ERROR_DEV_NOT_EXIST: + case ERROR_INVALID_PARAMETER: return ERROR_OBJECT_NOT_AROUND; case ERROR_HANDLE_DISK_FULL: diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index 3cadbecf..174b71c5 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -1745,7 +1745,6 @@ static INT_PTR CALLBACK ProgressDialogProc (HWND hDlg, UINT msg, WPARAM wParam, progressdialogactive = 0; return TRUE; case WM_CLOSE: - DestroyWindow(hDlg); if (progressdialogreturn < 0) progressdialogreturn = 0; return TRUE; @@ -1756,7 +1755,6 @@ static INT_PTR CALLBACK ProgressDialogProc (HWND hDlg, UINT msg, WPARAM wParam, { case IDCANCEL: progressdialogreturn = 0; - DestroyWindow (hDlg); return TRUE; } break; diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 44269bba..7bb5a07c 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -693,7 +693,7 @@ static void picasso_handle_vsync2 (void) bool rendered = false; if (vsync < 0) { - vsync_busywait_end (); + vsync_busywait_end (NULL); vsync_busywait_do (NULL, false, false); } diff --git a/od-win32/registry.cpp b/od-win32/registry.cpp index 32dcd6ec..099b32a4 100644 --- a/od-win32/registry.cpp +++ b/od-win32/registry.cpp @@ -87,6 +87,45 @@ int regqueryint (UAEREG *root, const TCHAR *name, int *val) } } +int regsetlonglong (UAEREG *root, const TCHAR *name, ULONGLONG val) +{ + if (inimode) { + DWORD ret; + TCHAR tmp[100]; + _stprintf (tmp, _T("%I64d"), val); + ret = WritePrivateProfileString (gs (root), name, tmp, inipath); + return ret; + } else { + ULONGLONG v = val; + HKEY rk = gr (root); + if (!rk) + return 0; + return RegSetValueEx(rk, name, 0, REG_QWORD, (CONST BYTE*)&v, sizeof (ULONGLONG)) == ERROR_SUCCESS; + } +} + +int regquerylonglong (UAEREG *root, const TCHAR *name, ULONGLONG *val) +{ + if (inimode) { + int ret = 0; + TCHAR tmp[100]; + GetPrivateProfileString (gs (root), name, PUPPA, tmp, sizeof (tmp) / sizeof (TCHAR), inipath); + if (_tcscmp (tmp, PUPPA)) { + *val = _tstoi64 (tmp); + ret = 1; + } + return ret; + } else { + DWORD dwType = REG_QWORD; + DWORD size = sizeof (ULONGLONG); + HKEY rk = gr (root); + if (!rk) + return 0; + return RegQueryValueEx (rk, name, 0, &dwType, (LPBYTE)val, &size) == ERROR_SUCCESS; + } +} + + int regquerystr (UAEREG *root, const TCHAR *name, TCHAR *str, int *size) { if (inimode) { diff --git a/od-win32/registry.h b/od-win32/registry.h index 49512588..2d248813 100644 --- a/od-win32/registry.h +++ b/od-win32/registry.h @@ -13,6 +13,8 @@ extern int regsetstr (UAEREG*, const TCHAR *name, const TCHAR *str); extern int regsetint (UAEREG*, const TCHAR *name, int val); extern int regqueryint (UAEREG*, const TCHAR *name, int *val); extern int regquerystr (UAEREG*, const TCHAR *name, TCHAR *str, int *size); +extern int regsetlonglong (UAEREG *root, const TCHAR *name, ULONGLONG val); +extern int regquerylonglong (UAEREG *root, const TCHAR *name, ULONGLONG *val); extern int regdelete (UAEREG*, const TCHAR *name); extern void regdeletetree (UAEREG*, const TCHAR *name); diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 4d2d33f8..00a708d7 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -4058,7 +4058,7 @@ static int betamessage (void) ULARGE_INTEGER sft64; struct tm *t; __int64 ltime; - DWORD dwType, size, data; + DWORD dwType, size; ft64.QuadPart = 0; for (;;) { @@ -4079,7 +4079,7 @@ static int betamessage (void) ft64.HighPart = ft.dwHighDateTime; dwType = REG_QWORD; size = sizeof regft64; - if (RegQueryValueEx (hWinUAEKey, _T("BetaToken"), 0, &dwType, (LPBYTE)®ft64, &size) != ERROR_SUCCESS) + if (!regquerylonglong (NULL, _T("BetaToken"), ®ft64)) break; GetSystemTime(&st); SystemTimeToFileTime(&st, &sft); @@ -4095,18 +4095,17 @@ static int betamessage (void) if (h != INVALID_HANDLE_VALUE) CloseHandle (h); if (showmsg) { - int r; + int r, data; TCHAR title[MAX_DPATH]; dwType = REG_DWORD; size = sizeof data; - if (hWinUAEKey && RegQueryValueEx (hWinUAEKey, _T("Beta_Just_Shut_Up"), 0, &dwType, (LPBYTE)&data, &size) == ERROR_SUCCESS) { + if (regqueryint (NULL, _T("Beta_Just_Shut_Up"), &data)) { if (data == 68000 + 10) { write_log (_T("I was told to shut up :(\n")); return 1; } } - _time64 (<ime); t = _gmtime64 (<ime); /* "expire" in 1 month */ @@ -4120,7 +4119,7 @@ static int betamessage (void) return 0; if (ft64.QuadPart > 0) { regft64 = ft64.QuadPart; - RegSetValueEx (hWinUAEKey, _T("BetaToken"), 0, REG_QWORD, (LPBYTE)®ft64, sizeof regft64); + regsetlonglong (NULL, _T("BetaToken"), regft64); } } #endif diff --git a/od-win32/win32.h b/od-win32/win32.h index ab75413a..4b197877 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,8 +19,8 @@ #define LANG_DLL 1 //#define WINUAEBETA _T("") -#define WINUAEBETA _T("12") -#define WINUAEDATE MAKEBD(2012, 5, 1) +#define WINUAEBETA _T("13") +#define WINUAEDATE MAKEBD(2012, 5, 5) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") #define WINUAEREV _T("") diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 223d304b..b16c7e46 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -125,7 +125,7 @@ static volatile bool vblank_found; static volatile int flipthread_mode; volatile bool vblank_found_chipset; volatile bool vblank_found_rtg; -static HANDLE flipevent, flipevent2; +static HANDLE flipevent, flipevent2, vblankwaitevent; static volatile int flipevent_mode; static CRITICAL_SECTION screen_cs; @@ -173,8 +173,10 @@ static void changevblankthreadmode_do (int newmode, bool fast) sleep_millis_main (1); CloseHandle (flipevent); CloseHandle (flipevent2); + CloseHandle (vblankwaitevent); flipevent = NULL; flipevent2 = NULL; + vblankwaitevent = NULL; } if (!fast) { while (t == vblankthread_counter && vblankthread_mode > 0); @@ -296,25 +298,36 @@ void desktop_coords (int *dw, int *dh, int *ax, int *ay, int *aw, int *ah) int target_get_display (const TCHAR *name) { + int oldfound = -1; + int found = -1; for (int i = 0; Displays[i].monitorname; i++) { struct MultiDisplay *md = &Displays[i]; if (!_tcscmp (md->adapterid, name)) - return i + 1; + found = i + 1; if (!_tcscmp (md->adaptername, name)) - return i + 1; + found = i + 1; if (!_tcscmp (md->monitorname, name)) - return i + 1; + found = i + 1; + if (!_tcscmp (md->monitorid, name)) + found = i + 1; + if (found >= 0) { + if (oldfound != found) + return -1; + oldfound = found; + } } return -1; } -const TCHAR *target_get_display_name (int num) +const TCHAR *target_get_display_name (int num, bool friendlyname) { if (num <= 0) return NULL; struct MultiDisplay *md = getdisplay2 (NULL, num - 1); if (!md) return NULL; - return md->monitorname; + if (friendlyname) + return md->monitorname; + return md->monitorid; } void centerdstrect (RECT *dr) @@ -897,7 +910,7 @@ void flush_screen (struct vidbuffer *vb, int a, int b) { } -static bool render_ok; +static volatile bool render_ok; bool render_screen (void) { @@ -946,18 +959,22 @@ bool show_screen_maybe (bool show) show_screen (); return false; } +#if 0 if (ap->gfx_vflip < 0) { doflipevent (); return true; } +#endif return false; } void show_screen (void) { - if (!render_ok) - return; EnterCriticalSection (&screen_cs); + if (!render_ok) { + LeaveCriticalSection (&screen_cs); + return; + } if (currentmode->flags & DM_D3D) { D3D_showframe (); #ifdef GFXFILTER @@ -2368,6 +2385,7 @@ end: } static volatile frame_time_t vblank_prev_time, thread_vblank_time; +static volatile int vblank_found_flipdelay; #include @@ -2460,7 +2478,7 @@ static int vblank_wait (void) int opos = prevvblankpos; if (!getvblankpos (&vp)) return -2; - if (opos > maxscanline / 2 && vp < maxscanline / 3) + if (opos > (maxscanline + minscanline) / 2 && vp < (maxscanline + minscanline) / 3) return vp; if (vp <= 0) return vp; @@ -2478,7 +2496,7 @@ static bool vblank_getstate (bool *state, int *pvp) return false; if (pvp) *pvp = vp; - if (opos > maxscanline / 2 && vp < maxscanline / 3) { + if (opos > (maxscanline + minscanline) / 2 && vp < (maxscanline + minscanline) / 3) { *state = true; return true; } @@ -2509,7 +2527,14 @@ static unsigned int __stdcall flipthread (void *dummy) WaitForSingleObject (flipevent, INFINITE); if (flipthread_mode == 0) break; + frame_time_t t = read_processor_time (); + while (!render_ok) { + sleep_millis (1); + if (read_processor_time () - t > vblankbasefull) + break; + } show_screen (); + render_ok = false; flipevent_mode = 0; SetEvent (flipevent2); } @@ -2537,7 +2562,6 @@ static bool vblanklaceskip (void) static unsigned int __stdcall vblankthread (void *dummy) { - bool vblank_first_time = false; bool firstvblankbasewait2; frame_time_t vblank_prev_time2; bool doflipped; @@ -2557,31 +2581,27 @@ static unsigned int __stdcall vblankthread (void *dummy) Sleep (100); } else if (mode == VBLANKTH_ACTIVE_WAIT) { sleep_millis (1); + ResetEvent (vblankwaitevent); } else if (mode == VBLANKTH_ACTIVE_START) { // do not start until vblank has been passed int vp; - getvblankpos (&vp); - if (vp > maxscanline / 2) { - sleep_millis (1); + if (!getvblankpos (&vp)) { + // bad things happening + vblankthread_mode = VBLANKTH_ACTIVE; continue; } - if (!vblank_first_time) { - frame_time_t rpt = read_processor_time (); - if (vp <= 0) { - vblank_prev_time2 = rpt; - } else { - vblank_prev_time2 = rpt - (vblankbasefull * vp / maxscanline) / (vblank_skipeveryother ? 2 : 1 ); - } - vblank_first_time = true; - } if (vp <= 0) { sleep_millis (1); continue; } + if (vp > maxscanline / 2) + vp = maxscanline / 2; + frame_time_t rpt = read_processor_time (); + vblank_prev_time2 = rpt - (vblankbasefull * vp / maxscanline) / (vblank_skipeveryother ? 2 : 1); vblank_prev_time = vblank_prev_time2; - vblank_first_time = false; firstvblankbasewait2 = false; prevvblankpos = 0; + vblank_found_flipdelay = 0; doflipped = false; if (vblank_skipeveryother) // wait for first vblank in skip frame mode (100Hz+) vblankthread_mode = VBLANKTH_ACTIVE_SKIPFRAME; @@ -2591,15 +2611,16 @@ static unsigned int __stdcall vblankthread (void *dummy) int vp; sleep_millis (1); getvblankpos (&vp); - if (vp >= maxscanline / 2) + if (vp >= (maxscanline + minscanline) / 2) vblankthread_mode = VBLANKTH_ACTIVE_SKIPFRAME2; + // something is wrong? if (read_processor_time () - vblank_prev_time2 > vblankbasefull * 2) vblankthread_mode = VBLANKTH_ACTIVE; } else if (mode == VBLANKTH_ACTIVE_SKIPFRAME2) { int vp; sleep_millis (1); getvblankpos (&vp); - if (vp > 0 && vp < maxscanline / 2) { + if (vp > 0 && vp < (maxscanline + minscanline) / 2) { prevvblankpos = 0; vblankthread_mode = VBLANKTH_ACTIVE; } @@ -2637,7 +2658,19 @@ static unsigned int __stdcall vblankthread (void *dummy) if (vs < 0) { vblank_found_chipset = true; if (!ap->gfx_vflip) { + while (!render_ok) { + sleep_millis (1); + if (read_processor_time () - t > vblankbasefull) + break; + } show_screen (); + render_ok = false; + int delay = (read_processor_time () - t) / (vblank_skipeveryother ? 2 : 1); + if (delay < 0) + delay = 0; + else if (delay > vblankbasefull * 2 / 3) + delay = vblankbasefull * 2 / 3; + vblank_found_flipdelay = delay; } } vblank_found_rtg2 = true; @@ -2662,9 +2695,9 @@ static unsigned int __stdcall vblankthread (void *dummy) thread_vblank_time = thread_vblank_time2; vblank_found_rtg = vblank_found_rtg2; vblank_found = vblank_found2; + SetEvent (vblankwaitevent); vblankthread_mode = VBLANKTH_ACTIVE_WAIT; } else if (!donotwait || ap->gfx_vflip || picasso_on) { -// } else if (!donotwait || picasso_on) { sleep_millis (1); } } else { @@ -2675,23 +2708,53 @@ static unsigned int __stdcall vblankthread (void *dummy) return 0; } -frame_time_t vsync_busywait_end (void) + +static bool isthreadedvsync (void) { - frame_time_t prev; - for (;;) { - int v = vblankthread_mode; - if (v != VBLANKTH_ACTIVE_START && v != VBLANKTH_ACTIVE_SKIPFRAME && v != VBLANKTH_ACTIVE_SKIPFRAME2) - break; - sleep_millis_main (1); - } - prev = vblank_prev_time; - if (!dooddevenskip) { - while (vblankthread_mode == VBLANKTH_ACTIVE) { - vsync_sleep (currprefs.m68k_speed < 0 || currprefs.m68k_speed_throttle < 0); + return isvsync_chipset () <= -2 || isvsync_rtg () < 0; +} + +frame_time_t vsync_busywait_end (int *flipdelay) +{ + if (isthreadedvsync ()) { + + frame_time_t prev; + for (;;) { + int v = vblankthread_mode; + if (v != VBLANKTH_ACTIVE_START && v != VBLANKTH_ACTIVE_SKIPFRAME && v != VBLANKTH_ACTIVE_SKIPFRAME2) + break; + sleep_millis_main (1); } + prev = vblank_prev_time; + if (!dooddevenskip) { + if (vblankthread_mode == VBLANKTH_ACTIVE) { + frame_time_t t = read_processor_time (); + while (vblankthread_mode == VBLANKTH_ACTIVE) + WaitForSingleObject (vblankwaitevent, 10); + idletime += read_processor_time () - t; + } + #if 0 + while (vblankthread_mode == VBLANKTH_ACTIVE) { + vsync_sleep (currprefs.m68k_speed < 0 || currprefs.m68k_speed_throttle < 0); + } + #endif + } + if (flipdelay) + *flipdelay = vblank_found_flipdelay; + changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); + return prev + vblankbasefull; + } else { + int delay; + show_screen (); + delay = (read_processor_time () - vblank_prev_time) / (vblank_skipeveryother ? 2 : 1); + if (delay < 0) + delay = 0; + else if (delay > vblankbasefull * 2 / 3) + delay = vblankbasefull * 2 / 3; + if (flipdelay) + *flipdelay = delay; + return vblank_prev_time + vblankbasefull; } - changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); - return prev + vblankbasefull; } void vsync_busywait_start (void) @@ -2701,10 +2764,6 @@ void vsync_busywait_start (void) changevblankthreadmode_fast (VBLANKTH_ACTIVE_START); } -static bool isthreadedvsync (void) -{ - return isvsync_chipset () <= -2 || isvsync_rtg () < 0; -} bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) { @@ -2732,7 +2791,7 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) return true; } - if (log_vsync) { + if (0 || log_vsync) { console_out_f(_T("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); } @@ -2809,7 +2868,7 @@ struct remembered_vsync int width, height, depth, rate, mode; bool rtg, lace; double remembered_rate, remembered_rate2; - int maxscanline, maxvpos; + int maxscanline, minscanline, maxvpos; }; double vblank_calibrate (double approx_vblank, bool waitonly) @@ -2844,6 +2903,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly) approx_vblank = rv->remembered_rate2; tsum = rval = rv->remembered_rate; maxscanline = rv->maxscanline; + minscanline = rv->minscanline; maxvpos = rv->maxvpos; lace = rv->lace; waitonly = true; @@ -2864,6 +2924,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly) flipevent_mode = 0; flipevent = CreateEvent (NULL, FALSE, FALSE, NULL); flipevent2 = CreateEvent (NULL, FALSE, FALSE, NULL); + vblankwaitevent = CreateEvent (NULL, FALSE, FALSE, NULL); _beginthreadex (NULL, 0, flipthread, 0, 0, &th); } else { changevblankthreadmode (VBLANKTH_CALIBRATE); @@ -2972,6 +3033,7 @@ skip: rv->remembered_rate = tsum; rv->remembered_rate2 = tsum2; rv->maxscanline = maxscanline; + rv->minscanline = minscanline; rv->maxvpos = maxvpos; rv->lace = lace; if (vsyncmemory == NULL) { diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index de4336af..d50d9e50 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -12320,6 +12320,7 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM switch (wParam) { case IDC_INPUTREMAP: + input_selected_event = -1; input_find (hDlg, 0, true); break; case IDC_INPUTTEST: diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 9691d294..5df3e2f7 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -2,8 +2,30 @@ - restore only single input target to default. - hdd from command line +Beta 13: (RC2) + +- Possible improvement for low latency no buffer mode tearing problem. + - Fastest possible CPU: very simple dynamic flip delay timing adjustment. Reduces tearing (and slows + down CPU emulation speed) but won't fix it completely. Difficult problem to solve 100% without + losing too much CPU speed. Currently only way to remove tearing is to reduce CPU speed. + - Cycle-exact/approximate CPU: Tearing problem on some systems should be fixed. +- Fastes possible low latency vsync sometimes flipped buffers before or during internal frame rendering, + usual result was same frame being shown multiple times. +- Legacy vsync refresh rate didn't override internal chipset refresh rate causing very bad slow down + if rates didn't match. +- Map directory filesystem Windows error ERROR_INVALID_PARAMETER to AOS ERROR_OBJECT_NOT_AROUND, + GetFreeSpace("path to empty CD drive") returns this code on some systems. +- Validate SCSI INQUIRY data before using it when requesting IOCTL CDROM vendor and product names. + It seems query can return success without returning any data in some situations. +- Store beta dialog state to winuae.ini if enabled. +- Random bsdsocket crash when calling gethostbyname() with numeric IP address. (2.4.0) +- Allow again zero back buffers in DirectDraw mode, 2.3.3 allowed this configuration. +- Canceling HD HDF cloning froze the GUI. (Possibly Vista and newer only) +- Store also monitor's system specific id string to config file, system can have multiple identical monitors. + Beta 12: (RC1) +- More Fastest possible + low latency vsync tweaks. - Ignore sprite 0 (normally mouse pointer) when calculating autoscale position and size. - Custom Input event editor usually crashed. - CD32 boot screen autoscale improved. -- 2.47.3