From 0a8a85e29c5e4053cbead6fd2490922f34719723 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 8 Jul 2018 18:05:30 +0300 Subject: [PATCH] Lagless vsync updates (100/120Hz, BFI) --- custom.cpp | 290 ++++++++++++++++++++++++++-------------- main.cpp | 2 +- od-win32/direct3d.cpp | 10 +- od-win32/direct3d11.cpp | 54 +++++--- od-win32/win32gfx.cpp | 20 ++- 5 files changed, 251 insertions(+), 125 deletions(-) diff --git a/custom.cpp b/custom.cpp index 71ddf146..c683f383 100644 --- a/custom.cpp +++ b/custom.cpp @@ -7465,7 +7465,7 @@ static bool framewait (void) if (!frame_shown) { show_screen(0, 1); if (currprefs.gfx_apmode[0].gfx_strobo) - show_screen(0, 2); + show_screen(0, 4); } maybe_process_pull_audio(); @@ -8297,37 +8297,97 @@ static int display_slice_lines; static int display_slices; static bool display_rendered; -static bool linesync_beam_single(void) +static bool linesync_beam_single_dual(void) { frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase; + int vp; if (is_last_line()) { do_render_slice(-1, 0, vpos); while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { maybe_process_pull_audio(); target_spin(0); - int vp = target_get_display_scanline(-1); + vp = target_get_display_scanline(-1); if (vp >= 0) break; } + vsyncmintime = read_processor_time() + vsynctimebase; vsync_clear(); while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { maybe_process_pull_audio(); - int vp = target_get_display_scanline(-1); + vp = target_get_display_scanline(-1); if (vp >= vsync_activeheight - 1 || vp < 0) break; scanlinesleep(vp, vsync_activeheight - 1); } + frame_rendered = true; + frame_shown = true; + do_display_slice(); + int vv = vsync_vblank; + while (vv >= 85) { + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + vp = target_get_display_scanline(-1); + if (vp < vsync_activeheight / 2) + break; + } + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight / 2) + break; + } + show_screen(0, 3); + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight - 1 || vp < vsync_activeheight / 2) + break; + } + show_screen(0, 2); + vv -= currprefs.ntscmode ? 60 : 50; + } + return true; + } + return false; +} + +static bool linesync_beam_single_single(void) +{ + frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase; + int vp; + + if (is_last_line()) { + do_render_slice(-1, 0, vpos); while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { maybe_process_pull_audio(); target_spin(0); - int vp = target_get_display_scanline(-1); - if (vp < 0) + vp = target_get_display_scanline(-1); + if (vp >= 0) + break; + } + vsync_clear(); + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight - 1 || vp < 0) break; + scanlinesleep(vp, vsync_activeheight - 1); } frame_rendered = true; frame_shown = true; - return do_display_slice(); + do_display_slice(); + while (vp >= vsync_activeheight / 2 && !currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + vp = target_get_display_scanline(-1); + if (vp < vsync_activeheight / 2) + break; + } + return true; } return false; } @@ -8339,21 +8399,23 @@ static bool linesync_beam_multi_dual(void) bool was_syncline = is_syncline != 0; events_reset_syncline(); - if (vpos == 0) { + if (vpos == 0 && !was_syncline) { int firstline, lastline; linesync_first_last_line(&firstline, &lastline); display_slices = currprefs.gfx_display_sections; - if (display_slices <= 0) + if (!display_slices) display_slices = 1; display_slice_cnt = 0; vsyncnextscanline = vsync_activeheight / display_slices + 1; + vsyncnextscanline_add = vsync_activeheight / display_slices; display_slice_lines = (lastline - firstline) / display_slices + 1; - nextwaitvpos = firstline + display_slice_lines; + nextwaitvpos = firstline + display_slice_lines + display_slice_lines / 2; if (display_slices <= 1) - nextwaitvpos = maxvpos_display + 1; + nextwaitvpos = lastline + 1; if (display_slices <= 2 && vsyncnextscanline > vsync_activeheight * 2 / 3) vsyncnextscanline = vsync_activeheight * 2 / 3; + display_rendered = false; frame_rendered = true; frame_shown = true; @@ -8370,15 +8432,15 @@ static bool linesync_beam_multi_dual(void) do_render_slice(is_last_line() ? 1 : 2, display_slice_cnt, vpos); display_rendered = true; } + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { - frame_time_t rpt = read_processor_time(); - if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -vsynctimebase * 2) { - vsyncmintime = rpt + vsynctimebase; - break; - } maybe_process_pull_audio(); target_spin(0); + int vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight - 1 || vp < 0) + break; } + do_display_slice(); display_rendered = false; input_read_done = true; @@ -8407,22 +8469,48 @@ static bool linesync_beam_multi_dual(void) scanlinesleep(vp, vsyncnextscanline); } do_display_slice(); - input_read_done = true; - display_rendered = false; } - vsyncnextscanline += vsync_activeheight / display_slices; - vsync_clear(); if (is_last_line()) { - // wait until about middle of second frame - while (!currprefs.turbo_emulation) { - frame_time_t rpt = read_processor_time(); - if ((int)rpt - ((int)vsyncmintime - vsynctimebase * 1 / 4) >= 0) + // wait extra frames + int vv = vsync_vblank; + for(;;) { + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + int vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight - 1 || vp < 0) + break; + } + show_screen(0, 3); + show_screen(0, 2); + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + int vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight / 2) + break; + } + vv -= currprefs.ntscmode ? 60 : 50; + if (vv < 85) break; - maybe_process_pull_audio(); - target_spin(0); + + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + maybe_process_pull_audio(); + target_spin(0); + int vp = target_get_display_scanline(-1); + if (vp < vsync_activeheight / 2 && vp >= 0) + break; + } } + } + + input_read_done = true; + display_rendered = false; + + vsyncnextscanline += vsync_activeheight / display_slices; + vsync_clear(); } nextwaitvpos += display_slice_lines; @@ -8433,8 +8521,7 @@ static bool linesync_beam_multi_dual(void) return input_read_done; } - -static bool linesync_beam_vrr(void) +static bool linesync_beam_multi_single(void) { frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase; bool input_read_done = false; @@ -8472,6 +8559,17 @@ static bool linesync_beam_vrr(void) do_render_slice(1, display_slice_cnt, vpos); display_rendered = true; } + // if 2 slices: make sure we are out of vblank. + if (display_slices <= 2) { + while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { + int vp = target_get_display_scanline(-1); + if (vp != -1) + break; + maybe_process_pull_audio(); + target_spin(0); + } + vsync_clear(); + } while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { int vp = target_get_display_scanline(-1); @@ -8501,52 +8599,54 @@ static bool linesync_beam_vrr(void) if (display_slice_cnt == 0) { if (!currprefs.turbo_emulation) { + if (!was_syncline) { + do_render_slice(2, display_slice_cnt, vpos - 1); + display_rendered = true; + } - frame_time_t rpt; - for (;;) { - rpt = read_processor_time(); - if ((int)rpt - (int)(vsyncmintime - vsynctimebase * 2 / 3) >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase) - break; + // flip slightly early because flip regularly gets delayed if done during vblank + int lastflipline = vsync_activeheight - vsyncnextscanline_add / 3; + while (sync_timeout_check(maxtime)) { + int vp = target_get_display_scanline(-1); maybe_process_pull_audio(); + if (vp < vsync_activeheight / 2 || vp >= lastflipline) + break; if (currprefs.m68k_speed < 0 && !was_syncline) { - is_syncline = -1; - is_syncline_end = target_get_display_scanline(-1); + is_syncline_end = lastflipline; + is_syncline = -2; return 0; } target_spin(0); +#if LLV_DEBUG + write_log(_T("2:%d:%d:%d:%d."), vpos, vp, nextwaitvpos, vsyncnextscanline); +#endif } + do_display_slice(); + display_rendered = false; + input_read_done = true; - if (!was_syncline) { - do_render_slice(2, display_slice_cnt, vpos - 1); - display_rendered = true; - } - - for (;;) { - rpt = read_processor_time(); - if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase) +#if 1 + // if flipped before vblank, wait for vblank + while (sync_timeout_check(maxtime)) { + int vp = target_get_display_scanline(-1); + if (vp < vsync_activeheight / 2) break; - maybe_process_pull_audio(); if (currprefs.m68k_speed < 0 && !was_syncline) { is_syncline = -1; - is_syncline_end = target_get_display_scanline(-1); + is_syncline_end = vp; return 0; } + maybe_process_pull_audio(); target_spin(0); } - - if ((int)rpt - (int)vsyncmintime < vsynctimebase && (int)rpt - (int)vsyncmintime > -vsynctimebase) { - vsyncmintime += vsynctimebase; - } else { - vsyncmintime = rpt + vsynctimebase; - } - do_display_slice(); - display_rendered = false; - input_read_done = true; +#endif } } else { - if (!currprefs.turbo_emulation) { + // skip if too close + int vp2 = target_get_display_scanline(-1); + if (!currprefs.turbo_emulation && (currprefs.m68k_speed < 0 || vp2 < vsyncnextscanline - vsyncnextscanline_add / 10)) { if (!was_syncline && !display_rendered) { do_render_slice(0, display_slice_cnt, vpos - 1); display_rendered = true; @@ -8591,8 +8691,7 @@ static bool linesync_beam_vrr(void) return input_read_done; } - -static bool linesync_beam_multi_single(void) +static bool linesync_beam_vrr(void) { frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase; bool input_read_done = false; @@ -8630,17 +8729,6 @@ static bool linesync_beam_multi_single(void) do_render_slice(1, display_slice_cnt, vpos); display_rendered = true; } - // if 2 slices: make sure we are out of vblank. - if (display_slices <= 2) { - while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { - int vp = target_get_display_scanline(-1); - if (vp != -1) - break; - maybe_process_pull_audio(); - target_spin(0); - } - vsync_clear(); - } while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { int vp = target_get_display_scanline(-1); @@ -8670,54 +8758,52 @@ static bool linesync_beam_multi_single(void) if (display_slice_cnt == 0) { if (!currprefs.turbo_emulation) { - if (!was_syncline) { - do_render_slice(2, display_slice_cnt, vpos - 1); - display_rendered = true; - } - // flip slightly early because flip regularly gets delayed if done during vblank - int lastflipline = vsync_activeheight - vsyncnextscanline_add / 3; - while (sync_timeout_check(maxtime)) { - int vp = target_get_display_scanline(-1); - maybe_process_pull_audio(); - if (vp < vsync_activeheight / 2 || vp >= lastflipline) + frame_time_t rpt; + for (;;) { + rpt = read_processor_time(); + if ((int)rpt - (int)(vsyncmintime - vsynctimebase * 2 / 3) >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase) break; + maybe_process_pull_audio(); if (currprefs.m68k_speed < 0 && !was_syncline) { - is_syncline_end = lastflipline; - is_syncline = -2; + is_syncline = -1; + is_syncline_end = target_get_display_scanline(-1); return 0; } target_spin(0); -#if LLV_DEBUG - write_log(_T("2:%d:%d:%d:%d."), vpos, vp, nextwaitvpos, vsyncnextscanline); -#endif } - do_display_slice(); - display_rendered = false; - input_read_done = true; -#if 1 - // if flipped before vblank, wait for vblank - while (sync_timeout_check(maxtime)) { - int vp = target_get_display_scanline(-1); - if (vp < vsync_activeheight / 2) + if (!was_syncline) { + do_render_slice(2, display_slice_cnt, vpos - 1); + display_rendered = true; + } + + for (;;) { + rpt = read_processor_time(); + if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase) break; + maybe_process_pull_audio(); if (currprefs.m68k_speed < 0 && !was_syncline) { is_syncline = -1; - is_syncline_end = vp; + is_syncline_end = target_get_display_scanline(-1); return 0; } - maybe_process_pull_audio(); target_spin(0); } -#endif + + if ((int)rpt - (int)vsyncmintime < vsynctimebase && (int)rpt - (int)vsyncmintime > -vsynctimebase) { + vsyncmintime += vsynctimebase; + } else { + vsyncmintime = rpt + vsynctimebase; + } + do_display_slice(); + display_rendered = false; + input_read_done = true; } } else { - // skip if too close - int vp2 = target_get_display_scanline(-1); - if (!currprefs.turbo_emulation && (currprefs.m68k_speed < 0 || vp2 < vsyncnextscanline - vsyncnextscanline_add / 10)) { + if (!currprefs.turbo_emulation) { if (!was_syncline && !display_rendered) { do_render_slice(0, display_slice_cnt, vpos - 1); display_rendered = true; @@ -8770,7 +8856,10 @@ void vsync_event_done(void) return; } if (currprefs.gfx_display_sections <= 1) { - linesync_beam_single(); + if (vsync_vblank >= 85) + linesync_beam_single_dual(); + else + linesync_beam_single_single(); } else { if (currprefs.gfx_variable_sync) linesync_beam_vrr(); @@ -8930,7 +9019,10 @@ static void hsync_handler_post (bool onvsync) if (isvsync_chipset() < 0) { if (currprefs.gfx_display_sections <= 1) { - input_read_done = linesync_beam_single(); + if (vsync_vblank >= 85) + input_read_done = linesync_beam_single_dual(); + else + input_read_done = linesync_beam_single_single(); } else { if (currprefs.gfx_variable_sync) input_read_done = linesync_beam_vrr(); diff --git a/main.cpp b/main.cpp index abc7f51a..8c048ec6 100644 --- a/main.cpp +++ b/main.cpp @@ -181,7 +181,7 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs) if (ap->gfx_vsyncmode) { if (ap->gfx_fullscreen != 0) { ap->gfx_backbuffers = 1; - ap->gfx_strobo = false; + ap->gfx_strobo = prefs->lightboost_strobo; } else { ap->gfx_vsyncmode = 0; ap->gfx_vsync = 0; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 8b95d7cb..bcb78623 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -3896,9 +3896,13 @@ static void xD3D_showframe_special (int monid, int mode) return; if (pause_emulation) return; - hr = d3d->d3ddev->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0); - D3D_showframe2 (d3d, true); - flushgpu (d3d,true); + if (mode == 2) { + hr = d3d->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0); + } + if (mode == 1) { + D3D_showframe2(d3d, true); + } + flushgpu(d3d, true); } static void xD3D_refresh (int monid) diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index 63e62e6c..6e0e9f5a 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -262,7 +262,6 @@ struct d3d11struct bool blackscreen; int framecount; UINT syncinterval; - bool flipped; float vblank; DWM_FRAME_COUNT lastframe; int frames_since_init; @@ -3154,23 +3153,24 @@ static bool device_error(struct d3d11struct *d3d) return false; } -static void do_present(struct d3d11struct *d3d, int black) +static void do_black(struct d3d11struct *d3d) +{ + float color[4]; + color[0] = 0; + color[1] = 0; + color[2] = 0; + color[3] = 0; + // Clear the back buffer. + d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); +} + +static void do_present(struct d3d11struct *d3d) { struct amigadisplay *ad = &adisplays[d3d - d3d11data]; struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; HRESULT hr; UINT presentFlags = 0; - if (black) { - float color[4]; - color[0] = 0; - color[1] = 0; - color[2] = 0; - color[3] = 0; - // Clear the back buffer. - d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); - } - int vsync = isvsync(); UINT syncinterval = d3d->vblankintervals; // only if no vsync or low latency vsync @@ -3180,7 +3180,6 @@ static void do_present(struct d3d11struct *d3d, int black) syncinterval = 0; } } - d3d->flipped = true; if (!vsync) { if (apm->gfx_backbuffers == 0 || (presentFlags & DXGI_PRESENT_ALLOW_TEARING) || (apm->gfx_vflip == 0 && isfs(d3d) <= 0) || (isfs(d3d) > 0 && apm->gfx_vsyncmode)) syncinterval = 0; @@ -3195,6 +3194,7 @@ static void do_present(struct d3d11struct *d3d, int black) presentFlags |= DXGI_PRESENT_DO_NOT_WAIT; syncinterval = 0; } + hr = d3d->m_swapChain->Present(syncinterval, presentFlags); if (currprefs.turbo_emulation && hr == DXGI_ERROR_WAS_STILL_DRAWING) hr = S_OK; @@ -3583,6 +3583,12 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t if (d3d->swapChainDesc.BufferCount < 2) d3d->swapChainDesc.BufferCount = 2; + if (d3d->swapChainDesc.BufferCount > 2 && isfullscreen() <= 0 && !apm->gfx_vsync) { + write_log(_T("Switch from triple buffer to double buffer (%d).\n"), apm->gfx_vflip); + d3d->swapChainDesc.BufferCount = 2; + apm->gfx_vflip = 0; + } + d3d->swapChainDesc.SwapEffect = os_win8 ? (os_win10 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) : DXGI_SWAP_EFFECT_SEQUENTIAL; if (apm->gfx_vsyncmode && isfs(d3d) > 0 && !os_win10) { d3d->swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; @@ -3608,7 +3614,7 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t int vsync = isvsync(); int hzmult = 0; getvsyncrate(monid, *freq, &hzmult); - if (hzmult < 0 && !currprefs.gfx_variable_sync) { + if (hzmult < 0 && !currprefs.gfx_variable_sync && apm->gfx_vsyncmode == 0) { if (!apm->gfx_strobo) { d3d->vblankintervals = 2; } else { @@ -3916,9 +3922,7 @@ static void EndScene(struct d3d11struct *d3d) } SetEvent(flipevent); #endif - do_present(d3d, 0); - if (d3d->blackscreen) - do_present(d3d, 1); + do_present(d3d); } static void TextureShaderClass_RenderShader(struct d3d11struct *d3d) @@ -4457,6 +4461,20 @@ static bool xD3D11_renderframe(int monid, int mode, bool immediate) return true; } +static void xD3D11_showframe_special(int monid, int mode) +{ + struct d3d11struct *d3d = &d3d11data[monid]; + + if (d3d->invalidmode || d3d->delayedfs || !d3d->texture2d || !d3d->d3dinit_done) + return; + if (!d3d->m_swapChain) + return; + if (mode == 1) + do_present(d3d); + if (mode == 2) + do_black(d3d); +} + static void xD3D11_showframe(int monid) { struct d3d11struct *d3d = &d3d11data[monid]; @@ -4972,7 +4990,7 @@ void d3d11_select(void) D3D_flushtexture = xD3D11_flushtexture; D3D_showframe = xD3D11_showframe; - D3D_showframe_special = NULL; + D3D_showframe_special = xD3D11_showframe_special; D3D_guimode = xD3D11_guimode; D3D_getDC = xD3D_getDC; D3D_isenabled = xD3D11_isenabled; diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 04884d97..97b49af5 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -513,6 +513,8 @@ static void display_param_init(struct AmigaMonitor *mon) vsync_vblank = 0; vsync_hblank = 0; get_display_vblank_params(-1, &vsync_activeheight, &vsync_totalheight, &vsync_vblank, &vsync_hblank); + if (vsync_vblank <= 0) + vsync_vblank = mon->currentmode.freq; // GPU scaled mode? if (vsync_activeheight > mon->currentmode.current_height) { float m = (float)vsync_activeheight / mon->currentmode.current_height; @@ -1439,10 +1441,19 @@ void show_screen(int monid, int mode) struct amigadisplay *ad = &adisplays[monid]; strobo_active = false; strobo_active2 = false; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + gfx_lock(); - if (mode == 2) { - if ((mon->currentmode.flags & DM_D3D) && D3D_showframe_special) { - D3D_showframe_special(0, 1); + if (mode == 2 || mode == 3 || mode == 4) { + if ((mon->currentmode.flags & DM_D3D) && D3D_showframe_special && ap->gfx_strobo) { + if (mode == 4) { + // erase + render + D3D_showframe_special(0, 2); + D3D_showframe_special(0, 1); + } else { + // erase or render + D3D_showframe_special(0, mode == 3 ? 2 : 1); + } } gfx_unlock(); return; @@ -1452,7 +1463,7 @@ void show_screen(int monid, int mode) return; } if (mon->currentmode.flags & DM_D3D) { - struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; +#if 0 if (ap->gfx_vsync < 0 && ap->gfx_strobo && currprefs.gfx_api < 2) { float vblank = vblank_hz; if (WIN32GFX_IsPicassoScreen(mon)) { @@ -1481,6 +1492,7 @@ void show_screen(int monid, int mode) timeSetEvent(waitms, 0, blackinsertion_cb, NULL, TIME_ONESHOT | TIME_CALLBACK_FUNCTION); } } +#endif D3D_showframe(monid); if (monid == 0) strobo_active2 = true; -- 2.47.3