From f675f42833e8cfe057ae3b172410a559e5296459 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 6 May 2012 13:49:39 +0300 Subject: [PATCH] 2410b14 --- custom.cpp | 99 +++++++++++++++++++++++------------- hardfile.cpp | 2 +- od-win32/picasso96_win.cpp | 2 +- od-win32/win32.h | 4 +- od-win32/win32gfx.cpp | 44 +++++++++------- od-win32/win32gui.cpp | 74 ++++++++++++++++++++++----- od-win32/winuaechangelog.txt | 8 +++ zfile.cpp | 2 +- 8 files changed, 165 insertions(+), 70 deletions(-) diff --git a/custom.cpp b/custom.cpp index a63ce923..e21199cf 100644 --- a/custom.cpp +++ b/custom.cpp @@ -139,7 +139,7 @@ static int next_lineno, prev_lineno; static enum nln_how nextline_how; static int lof_changed = 0, lof_changing = 0, interlace_changed = 0; static int scandoubled_line; -static bool vsync_rendered, frame_shown; +static bool vsync_rendered, frame_rendered, frame_shown; static int vsynctimeperline; static int jitcount = 0; static int frameskiptime; @@ -5222,11 +5222,26 @@ static void framewait (void) if (vs > 0) { + int t; curr_time = read_processor_time (); vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase; - vsynctimeperline = vsynctimebase / (maxvpos_nom + 1); - render_screen (); - show_screen (); + if (!frame_rendered) + frame_rendered = render_screen (); + if (!frame_shown) + show_screen (); + t = read_processor_time () - curr_time; + if (t < 0) + t = 0; + t += frameskipt; + if (t > vsynctimebase / 2) + t = vsynctimebase / 2; + if (currprefs.m68k_speed < 0) { + vsynctimeperline = (vsynctimebase - t * 2) / (maxvpos_nom + 1); + } else { + vsynctimeperline = (vsynctimebase - t * 2) / 3; + } + if (vsynctimeperline < 1) + vsynctimeperline = 1; frame_shown = true; return; @@ -5290,15 +5305,11 @@ static void framewait (void) 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) { - vsync_busywait_end (&flipdelay); - if (extraframewait) - sleep_millis_main (extraframewait); - } + frame_rendered = render_screen (); + curr_time = vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); + vsync_busywait_end (&flipdelay); + if (extraframewait) + sleep_millis_main (extraframewait); now = read_processor_time (); adjust = (int)now - (int)curr_time; if (adjust < 0) @@ -5324,10 +5335,12 @@ static void framewait (void) } vsynctimeperline = (max - skipcnt * 2) / 3; - if (vsynctimeperline < 1) + //if (vsynctimeperline < 1) vsynctimeperline = 1; vsyncmaxtime = now + max; + //write_log (L"%d ", vsynctimeperline); + frame_shown = true; } @@ -5370,9 +5383,13 @@ static void framewait (void) } else { - bool didrender = false; - if (!picasso_on) - didrender = render_screen (); + int t = 0; + + if (!frame_rendered && !picasso_on) { + start = read_processor_time (); + frame_rendered = render_screen (); + t = read_processor_time () - start; + } for (;;) { double v = rpt_vsync () / (syncbase / 1000.0); if (v >= -4) @@ -5387,9 +5404,16 @@ static void framewait (void) curr_time = read_processor_time (); vsyncmintime = curr_time; vsyncmaxtime = vsyncwaittime = curr_time + vsynctimebase; - vsynctimeperline = vsynctimebase / (maxvpos_nom + 1); - if (didrender) + if (frame_rendered) { show_screen (); + t += read_processor_time () - curr_time; + } + t += frameskipt; + vsynctimeperline = (vsynctimebase - (t + frameskipt)) / 3; + if (vsynctimeperline < 0) + vsynctimeperline = 0; + else if (vsynctimeperline > vsynctimebase / 3) + vsynctimeperline = vsynctimebase / 3; frame_shown = true; } @@ -5482,17 +5506,28 @@ static void vsync_handler_pre (void) start = read_processor_time (); vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3); vsync_rendered = true; - if (vblank_hz_state) { - render_screen (); - if (!frame_shown) { - frame_shown = true; - show_screen_maybe (isvsync_chipset () >= 0); - } - } end = read_processor_time (); frameskiptime += end - start; } + framewait (); + + if (!picasso_on) { + if (!frame_rendered && vblank_hz_state) { + frame_rendered = render_screen (); + if (frame_rendered && !frame_shown) { + frame_shown = show_screen_maybe (isvsync_chipset () >= 0); + } + } + } + + fpscounter (); + + + vsync_rendered = false; + frame_shown = false; + frame_rendered = false; + if (vblank_hz_mult > 0) vblank_hz_state ^= 1; else @@ -5507,16 +5542,9 @@ static void vsync_handler_post (void) { static frame_time_t prevtime; - vsync_rendered = false; - frame_shown = false; - //write_log (_T("%d %d %d\n"), vsynctimebase, read_processor_time () - vsyncmintime, read_processor_time () - prevtime); prevtime = read_processor_time (); - fpscounter (); - - framewait (); - #if CUSTOM_DEBUG > 1 if ((intreq & 0x0020) && (intena & 0x0020)) write_log (_T("vblank interrupt not cleared\n")); @@ -6038,8 +6066,9 @@ static void hsync_handler_post (bool onvsync) frame_time_t rpt = read_processor_time (); vsyncmintime += vsynctimeperline; // sleep if more than 2ms "free" time - if (!vblank_found_chipset && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0) { + while (!vblank_found_chipset && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { sleep_millis_main (1); + rpt = read_processor_time (); } } } @@ -6153,7 +6182,7 @@ static void hsync_handler_post (bool onvsync) vsync_rendered = true; vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3); if (vblank_hz_state) { - render_screen (); + frame_rendered = render_screen (); } frame_shown = true; end = read_processor_time (); diff --git a/hardfile.cpp b/hardfile.cpp index d9ef11e6..a7f56b99 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -1563,7 +1563,7 @@ static uae_u32 REGPARAM2 hardfile_open (TrapContext *context) } } if (unit < 1000 || is_hardfile (unit) == FILESYS_VIRTUAL || is_hardfile (unit) == FILESYS_CD) - err = 50; /* HFERR_NoBoard */ + err = 50; /* c */ } else { err = IOERR_BADLENGTH; } diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 7bb5a07c..40d89470 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -681,7 +681,7 @@ static void rtg_show (void) } static void rtg_clear (void) { - rtg_clear_flag = 3; + rtg_clear_flag = 4; } static void picasso_handle_vsync2 (void) diff --git a/od-win32/win32.h b/od-win32/win32.h index 4b197877..5e2ee498 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("13") -#define WINUAEDATE MAKEBD(2012, 5, 5) +#define WINUAEBETA _T("14") +#define WINUAEDATE MAKEBD(2012, 5, 6) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") #define WINUAEREV _T("") diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index b16c7e46..a118d5ed 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -2548,6 +2548,7 @@ static int frame_usage, frame_usage_avg, frame_usage_total; extern int log_vsync; static bool dooddevenskip; static volatile bool vblank_skipeveryother; +static int vblank_flip_delay; static bool vblanklaceskip (void) { @@ -2733,26 +2734,14 @@ frame_time_t vsync_busywait_end (int *flipdelay) 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; + *flipdelay = vblank_flip_delay; return vblank_prev_time + vblankbasefull; } } @@ -2772,6 +2761,7 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) int ti; frame_time_t t; frame_time_t prevtime = vblank_prev_time; + struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; dooddevenskip = false; @@ -2823,6 +2813,7 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) } else { bool doskip = false; + vblank_flip_delay = 0; if (!framelost && t - prevtime > vblankbasefull) { framelost = true; frame_missed++; @@ -2835,14 +2826,33 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) } if (!doskip) { + int vp; while (!framelost && read_processor_time () - prevtime < vblankbasewait1) { vsync_sleep (false); } - int vp = vblank_wait (); + prevvblankpos = 0; + vp = vblank_wait (); if (vp >= -1) { vblank_prev_time = read_processor_time (); - if (vp > 0) - vblank_prev_time -= (vblankbasefull * vp / maxscanline) / (vblank_skipeveryother ? 2 : 1 ); + if (ap->gfx_vflip == 0) { + show_screen (); + vblank_flip_delay = (read_processor_time () - vblank_prev_time) / (vblank_skipeveryother ? 2 : 1); + if (vblank_flip_delay < 0) + vblank_flip_delay = 0; + else if (vblank_flip_delay > vblankbasefull * 2 / 3) + vblank_flip_delay = vblankbasefull * 2 / 3; + } + for (;;) { + if (!getvblankpos (&vp)) + break; + if (vp > 0) + break; + sleep_millis (1); + } + if (ap->gfx_vflip != 0) { + show_screen (); + } + vblank_prev_time -= (vblankbasefull * vp / maxscanline) / (vblank_skipeveryother ? 2 : 1 ); v = true; } } else { @@ -3011,7 +3021,7 @@ skip: tsum2 = tsum / div; vblankbasefull = (syncbase / tsum2); - vblankbasewait1 = (syncbase / tsum2) * 75 / 100; + vblankbasewait1 = (syncbase / tsum2) * 70 / 100; vblankbasewait2 = (syncbase / tsum2) * 55 / 100; vblankbasewait3 = (syncbase / tsum2) * 99 / 100 - syncbase / (250 * (vblank_skipeveryother ? 1 : 2)); // at least 2ms before vblank vblankbaselace = lace; diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index d50d9e50..b0fee77a 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -5389,27 +5389,71 @@ static void enable_for_chipsetdlg (HWND hDlg) ew (hDlg, IDC_CS_EXT, workprefs.cs_compatible ? TRUE : FALSE); } +static const int fakerefreshrates[] = { 50, 60, 100, 120, 0 }; +struct storedrefreshrate +{ + int rate, type; +}; +static struct storedrefreshrate storedrefreshrates[MAX_REFRESH_RATES + 4 + 1]; + + static void init_frequency_combo (HWND hDlg, int dmode) { - int i; + int i, j, freq; TCHAR hz[20], hz2[20], txt[100]; LRESULT index; struct MultiDisplay *md = getdisplay (&workprefs); + i = 0; index = 0; + while (dmode >= 0 && (freq = md->DisplayModes[dmode].refresh[i]) > 0 && index < MAX_REFRESH_RATES) { + storedrefreshrates[index].rate = freq; + storedrefreshrates[index++].type = md->DisplayModes[dmode].refreshtype[i]; + i++; + } + if (workprefs.gfx_apmode[0].gfx_vsyncmode == 0 && workprefs.gfx_apmode[0].gfx_vsync) { + i = 0; + while ((freq = fakerefreshrates[i]) > 0 && index < MAX_REFRESH_RATES) { + for (j = 0; j < index; j++) { + if (storedrefreshrates[j].rate == freq) + break; + } + if (j == index) { + storedrefreshrates[index].rate = -freq; + storedrefreshrates[index++].type = 0; + } + i++; + } + } + storedrefreshrates[index].rate = 0; + for (i = 0; i < index; i++) { + for (j = i + 1; j < index; j++) { + if (abs (storedrefreshrates[i].rate) >= abs (storedrefreshrates[j].rate)) { + struct storedrefreshrate srr; + memcpy (&srr, &storedrefreshrates[i], sizeof (struct storedrefreshrate)); + memcpy (&storedrefreshrates[i], &storedrefreshrates[j], sizeof (struct storedrefreshrate)); + memcpy (&storedrefreshrates[j], &srr, sizeof (struct storedrefreshrate)); + } + } + } + hz[0] = hz2[0] = 0; SendDlgItemMessage(hDlg, IDC_REFRESHRATE, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString (IDS_VSYNC_DEFAULT, txt, sizeof (txt) / sizeof (TCHAR)); SendDlgItemMessage(hDlg, IDC_REFRESHRATE, CB_ADDSTRING, 0, (LPARAM)txt); - for (i = 0; md->DisplayModes[dmode].refresh[i] > 0; i++) { - int freq = md->DisplayModes[dmode].refresh[i]; - int type = md->DisplayModes[dmode].refreshtype[i]; - _stprintf (hz, _T("%dHz"), freq); + for (i = 0; i < index; i++) { + freq = storedrefreshrates[i].rate; + if (freq < 0) { + freq = -freq; + _stprintf (hz, L"(%dHz)", freq); + } else { + _stprintf (hz, L"%dHz", freq); + } if (freq == 50 || freq == 100) - _tcscat (hz, _T(" PAL")); + _tcscat (hz, L" PAL"); if (freq == 60 || freq == 120) - _tcscat (hz, _T(" NTSC")); - if (type) - _tcscat (hz, _T(" (*)")); + _tcscat (hz, L" NTSC"); + if (storedrefreshrates[i].type) + _tcscat (hz, L" (*)"); if (abs (workprefs.gfx_apmode[0].gfx_refreshrate) == freq) _tcscpy (hz2, hz); SendDlgItemMessage (hDlg, IDC_REFRESHRATE, CB_ADDSTRING, 0, (LPARAM)hz); @@ -5888,7 +5932,8 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l workprefs.gfx_framerate = SendDlgItemMessage (hDlg, IDC_FRAMERATE, TBM_GETPOS, 0, 0); i = SendDlgItemMessage (hDlg, IDC_SCREENMODE_NATIVE2, CB_GETCURSEL, 0, 0); - int oldmode = workprefs.gfx_apmode[0].gfx_vsyncmode; + int oldvsmode = workprefs.gfx_apmode[0].gfx_vsyncmode; + int oldvs = workprefs.gfx_apmode[0].gfx_vsync; workprefs.gfx_apmode[0].gfx_vsync = 0; workprefs.gfx_apmode[0].gfx_vsyncmode = 0; if (i > 0) { @@ -5991,10 +6036,13 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l dmode++; } if (md->DisplayModes[dmode].residx != posn1) - dmode = i; + dmode = i; } } + if (oldvsmode != workprefs.gfx_apmode[0].gfx_vsyncmode || oldvs != workprefs.gfx_apmode[0].gfx_vsync) + init_frequency_combo (hDlg, dmode); + if (msg == WM_COMMAND && HIWORD (wParam) == CBN_SELCHANGE) { if (LOWORD (wParam) == IDC_DISPLAYSELECT) { @@ -6023,7 +6071,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l /* Set the Int boxes */ SetDlgItemInt (hDlg, IDC_XSIZE, workprefs.gfx_size_win.width, FALSE); SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_size_win.height, FALSE); - init_frequency_combo (hDlg, i); + init_frequency_combo (hDlg, dmode); } else if (LOWORD (wParam) == IDC_REFRESHRATE && dmode >= 0) { LRESULT posn1; posn1 = SendDlgItemMessage (hDlg, IDC_REFRESHRATE, CB_GETCURSEL, 0, 0); @@ -6033,7 +6081,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l workprefs.gfx_apmode[0].gfx_refreshrate = 0; } else { posn1--; - workprefs.gfx_apmode[0].gfx_refreshrate = md->DisplayModes[dmode].refresh[posn1]; + workprefs.gfx_apmode[0].gfx_refreshrate = storedrefreshrates[posn1].rate; } values_to_displaydlg (hDlg); } else if (LOWORD (wParam) == IDC_DA_MODE) { diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 5df3e2f7..8d390180 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -2,6 +2,14 @@ - restore only single input target to default. - hdd from command line +Beta 14: (RC3) + +- Cycle-exact/approximate CPU speed non-vsync b1 sound sync update didn't work, it did nothing. +- Some more low latency vsync timing updates, improved dynamic adjusment. +- Legacy vsync slowdown problems fixed (2.4.0) +- Restored (50Hz) and (60Hz) fake rates that were removed in 2.4.0. Only available in legacy vsync mode. +- RTG + low latency vsync was not stable. + Beta 13: (RC2) - Possible improvement for low latency no buffer mode tearing problem. diff --git a/zfile.cpp b/zfile.cpp index 77c63eb0..7d4e94ea 100644 --- a/zfile.cpp +++ b/zfile.cpp @@ -1984,7 +1984,7 @@ struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 { struct zfile *l; l = zfile_create (prev); - l->name = name ? my_strdup (name) : _T(""); + l->name = my_strdup (name ? name : _T("")); if (size) { l->data = xcalloc (uae_u8, size); if (!l->data) { -- 2.47.3