static int tin_w, tin_h, tout_w, tout_h, window_h, window_w;
static int t_depth, dmult, dmultx;
static int required_sl_texture_w, required_sl_texture_h;
-static int vsync2, guimode, maxscanline;
+static int vsync2, guimode, maxscanline, variablerefresh;
static int resetcount;
static double cursor_x, cursor_y;
static bool cursor_v, cursor_scale;
modeex.Format = mode.Format;
vsync2 = 0;
+ variablerefresh = ap.gfx_vsync < 0;
int hzmult = 0;
if (isfullscreen () > 0) {
dpp.FullScreen_RefreshRateInHz = getrefreshrate (modeex.Width, modeex.Height);
if (forcedframelatency >= 0)
hr = d3ddevex->SetMaximumFrameLatency (forcedframelatency);
else if (dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE && (v > 1 || !vsync))
- hr = d3ddevex->SetMaximumFrameLatency (vsync ? (hzmult < 0 && !ap.gfx_strobo ? 2 : 1) : 0);
+ hr = d3ddevex->SetMaximumFrameLatency (vsync ? (hzmult < 0 && !ap.gfx_strobo && !variablerefresh ? 2 : 1) : 0);
if (FAILED (hr))
write_log (_T("%s: SetMaximumFrameLatency() failed: %s\n"), D3DHEAD, D3D_ErrorString (hr));
}
if (!isd3d ())
return;
if (currprefs.turbo_emulation) {
- if (!(dpp.PresentationInterval & D3DPRESENT_INTERVAL_IMMEDIATE) && wasstilldrawing_broken) {
+ if ((!(dpp.PresentationInterval & D3DPRESENT_INTERVAL_IMMEDIATE) || variablerefresh) && wasstilldrawing_broken) {
static int frameskip;
if (currprefs.turbo_emulation && frameskip-- > 0)
return;
- frameskip = 50;
+ frameskip = 10;
}
D3D_showframe2 (false);
} else {
if (vsync2 == -1 && !currprefs.turbo_emulation) {
D3D_showframe2 (true);
}
+ flushgpu(true);
}
- flushgpu (true);
}
void D3D_showframe_special (int mode)
int scalepicasso;
static double remembered_vblank;
static volatile int vblankthread_mode, vblankthread_counter;
+static int deskhz;
struct winuae_currentmode {
unsigned int flags;
int w = GetSystemMetrics (SM_CXSCREEN);
int h = GetSystemMetrics (SM_CYSCREEN);
+ int wv = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ int hv = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int b = 0;
+
+ deskhz = 0;
+
HDC hdc = GetDC (NULL);
if (hdc) {
b = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
ReleaseDC (NULL, hdc);
}
- write_log (_T("Desktop: W=%d H=%d B=%d. CXVS=%d CYVS=%d\n"), w, h, b,
- GetSystemMetrics (SM_CXVIRTUALSCREEN), GetSystemMetrics (SM_CYVIRTUALSCREEN));
-
md = Displays;
while (md->monitorname) {
md->DisplayModes = xmalloc (struct PicassoResolution, MAX_PICASSO_MODES);
int idx2 = 0;
while (md->DisplayModes[idx2].depth >= 0 && !found) {
struct PicassoResolution *pr = &md->DisplayModes[idx2];
+ if (dm.dmPelsWidth == w && dm.dmPelsHeight == h && dm.dmBitsPerPel == b) {
+ if (dm.dmDisplayFrequency > deskhz)
+ deskhz = dm.dmDisplayFrequency;
+ }
if (pr->res.width == dm.dmPelsWidth && pr->res.height == dm.dmPelsHeight && pr->depth == dm.dmBitsPerPel / 8) {
for (i = 0; pr->refresh[i]; i++) {
if (pr->refresh[i] == dm.dmDisplayFrequency) {
write_log (_T("%d display modes.\n"), i);
md++;
}
+ write_log(_T("Desktop: W=%d H=%d B=%d HZ=%d. CXVS=%d CYVS=%d\n"), w, h, b, deskhz, wv, hv);
+
}
/* DirectX will fail with "Mode not supported" if we try to switch to a full
void show_screen_special (void)
{
+ if (!screen_is_initialized)
+ return;
if (currentmode->flags & DM_D3D) {
gfx_lock();
D3D_showframe_special (1);
}
}
static frame_time_t strobo_time;
+static volatile bool strobo_active;
static void CALLBACK blackinsertion_cb(
UINT uTimerID,
DWORD_PTR dw2
)
{
- if (!screen_is_initialized)
- return;
- for (;;) {
- frame_time_t ct = read_processor_time();
- if ((int)strobo_time - (int)ct <= 0 || (int)strobo_time - (int)ct > vsynctimebase / 2) {
- break;
+ if (screen_is_initialized) {
+ while (strobo_active) {
+ frame_time_t ct = read_processor_time();
+ int diff = (int)strobo_time - (int)ct;
+ if (diff < -vsynctimebase / 2) {
+ break;
+ }
+ if (diff <= 0) {
+ show_screen_special();
+ break;
+ }
+ if (diff > vsynctimebase / 4) {
+ break;
+ }
}
}
- if (!screen_is_initialized)
- return;
- show_screen_special();
+ strobo_active = false;
}
+double target_adjust_vblank_hz(double hz)
+{
+ int maxrate;
+ if (!currprefs.lightboost_strobo)
+ return hz;
+ if (isfullscreen() > 0) {
+ maxrate = currentmode->freq;
+ } else {
+ maxrate = deskhz;
+ }
+ double nhz = hz * 2.0;
+ if (nhz >= maxrate - 1 && nhz < maxrate + 1)
+ hz -= 0.5;
+ return hz;
+}
void show_screen (int mode)
{
+ strobo_active = false;
gfx_lock();
if (mode == 2) {
if (currentmode->flags & DM_D3D) {
}
if (currentmode->flags & DM_D3D) {
struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
- if (isfullscreen() > 0 && isvsync() == 0 && ap->gfx_strobo && ap->gfx_refreshrate > 80) {
- //if (isvsync() == 0 && ap->gfx_strobo) {
+ if (ap->gfx_vsync < 0 && ap->gfx_strobo) {
+ double vblank = vblank_hz;
+ if (WIN32GFX_IsPicassoScreen()) {
+ if (currprefs.win32_rtgvblankrate > 0)
+ vblank = currprefs.win32_rtgvblankrate;
+ }
+ bool ok = true;
int ratio = currprefs.lightboost_strobo_ratio;
- int ms = 1000 / vblank_hz;
+ int ms = 1000 / vblank;
int waitms = ms * ratio / 100 - 1;
- strobo_time = read_processor_time() + vsynctimebase * ratio / 100;
- timeSetEvent(waitms, 0, blackinsertion_cb, NULL, TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+ int maxrate;
+ if (isfullscreen() > 0) {
+ maxrate = currentmode->freq;
+ } else {
+ maxrate = deskhz;
+ }
+ if (maxrate > 0) {
+ double rate = vblank * 2.0;
+ rate *= ratio > 50 ? ratio / 50.0 : 50.0 / ratio;
+ if (rate > maxrate + 1.0)
+ ok = false;
+ }
+ if (ok) {
+ strobo_time = read_processor_time() + vsynctimebase * ratio / 100;
+ strobo_active = true;
+ timeSetEvent(waitms, 0, blackinsertion_cb, NULL, TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+ }
}
D3D_showframe();
#ifdef GFXFILTER