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;
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;
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)
}
vsynctimeperline = (max - skipcnt * 2) / 3;
- if (vsynctimeperline < 1)
+ //if (vsynctimeperline < 1)
vsynctimeperline = 1;
vsyncmaxtime = now + max;
+ //write_log (L"%d ", vsynctimeperline);
+
frame_shown = true;
}
} 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)
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;
}
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
{
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"));
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 ();
}
}
}
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 ();
}
}
if (unit < 1000 || is_hardfile (unit) == FILESYS_VIRTUAL || is_hardfile (unit) == FILESYS_CD)
- err = 50; /* HFERR_NoBoard */
+ err = 50; /* c */
} else {
err = IOERR_BADLENGTH;
}
}
static void rtg_clear (void)
{
- rtg_clear_flag = 3;
+ rtg_clear_flag = 4;
}
static void picasso_handle_vsync2 (void)
#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("")
extern int log_vsync;
static bool dooddevenskip;
static volatile bool vblank_skipeveryother;
+static int vblank_flip_delay;
static bool vblanklaceskip (void)
{
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;
}
}
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;
} else {
bool doskip = false;
+ vblank_flip_delay = 0;
if (!framelost && t - prevtime > vblankbasefull) {
framelost = true;
frame_missed++;
}
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 {
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;
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);
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) {
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) {
/* 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);
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) {
- 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.
{
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) {