ddraw: Implement ddraw7_GetScanLine() on top of wined3d_get_adapter_raster_status().
This commit is contained in:
parent
9877df9aeb
commit
2bfc5214be
|
@ -1931,60 +1931,28 @@ static HRESULT WINAPI ddraw1_WaitForVerticalBlank(IDirectDraw *iface, DWORD flag
|
|||
return ddraw7_WaitForVerticalBlank(&ddraw->IDirectDraw7_iface, flags, event);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirectDraw7::GetScanLine
|
||||
*
|
||||
* Returns the scan line that is being drawn on the monitor
|
||||
*
|
||||
* Parameters:
|
||||
* Scanline: Address to write the scan line value to
|
||||
*
|
||||
* Returns:
|
||||
* Always returns DD_OK
|
||||
*
|
||||
*****************************************************************************/
|
||||
static HRESULT WINAPI ddraw7_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
|
||||
{
|
||||
struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
|
||||
struct wined3d_display_mode mode;
|
||||
static BOOL hide = FALSE;
|
||||
DWORD time, frame_progress, lines;
|
||||
struct wined3d_raster_status raster_status;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, line %p.\n", iface, Scanline);
|
||||
|
||||
/* This function is called often, so print the fixme only once */
|
||||
if(!hide)
|
||||
{
|
||||
FIXME("iface %p, line %p partial stub!\n", iface, Scanline);
|
||||
hide = TRUE;
|
||||
}
|
||||
|
||||
wined3d_mutex_lock();
|
||||
hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL);
|
||||
hr = wined3d_get_adapter_raster_status(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &raster_status);
|
||||
wined3d_mutex_unlock();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Failed to get display mode, hr %#x.\n", hr);
|
||||
WARN("Failed to get raster status, hr %#x.\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* Fake the line sweeping of the monitor */
|
||||
/* FIXME: We should synchronize with a source to keep the refresh rate */
|
||||
*Scanline = raster_status.scan_line;
|
||||
|
||||
/* Simulate a 60Hz display */
|
||||
time = GetTickCount();
|
||||
frame_progress = time & 15; /* time % (1000 / 60) */
|
||||
if (!frame_progress)
|
||||
{
|
||||
*Scanline = 0;
|
||||
if (raster_status.in_vblank)
|
||||
return DDERR_VERTICALBLANKINPROGRESS;
|
||||
}
|
||||
|
||||
/* Convert frame_progress to estimated scan line. Return any line from
|
||||
* block determined by time. Some lines may be never returned */
|
||||
lines = mode.height / 15;
|
||||
*Scanline = (frame_progress - 1) * lines + time % lines;
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -3225,6 +3225,53 @@ HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
|
|||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
struct wined3d_raster_status *raster_status)
|
||||
{
|
||||
LONGLONG freq_per_frame, freq_per_line;
|
||||
LARGE_INTEGER counter, freq_per_sec;
|
||||
struct wined3d_display_mode mode;
|
||||
static UINT once;
|
||||
|
||||
if (!once++)
|
||||
FIXME("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
|
||||
wined3d, adapter_idx, raster_status);
|
||||
else
|
||||
WARN("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
|
||||
wined3d, adapter_idx, raster_status);
|
||||
|
||||
/* Obtaining the raster status is a widely implemented but optional
|
||||
* feature. When this method returns OK StarCraft 2 expects the
|
||||
* raster_status->InVBlank value to actually change over time.
|
||||
* And Endless Alice Crysis doesn't care even if this method fails.
|
||||
* Thus this method returns OK and fakes raster_status by
|
||||
* QueryPerformanceCounter. */
|
||||
|
||||
if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
if (FAILED(wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, NULL)))
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
if (mode.refresh_rate == DEFAULT_REFRESH_RATE)
|
||||
mode.refresh_rate = 60;
|
||||
|
||||
freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate;
|
||||
/* Assume 20 scan lines in the vertical blank. */
|
||||
freq_per_line = freq_per_frame / (mode.height + 20);
|
||||
raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line;
|
||||
if (raster_status->scan_line < mode.height)
|
||||
raster_status->in_vblank = FALSE;
|
||||
else
|
||||
{
|
||||
raster_status->scan_line = 0;
|
||||
raster_status->in_vblank = TRUE;
|
||||
}
|
||||
|
||||
TRACE("Returning fake value, in_vblank %u, scan_line %u.\n",
|
||||
raster_status->in_vblank, raster_status->scan_line);
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
|
||||
const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
|
||||
{
|
||||
|
|
|
@ -220,47 +220,10 @@ HRESULT CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *
|
|||
HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
|
||||
struct wined3d_raster_status *raster_status)
|
||||
{
|
||||
static BOOL warned;
|
||||
LARGE_INTEGER counter, freq_per_sec;
|
||||
LONGLONG freq_per_frame, freq_per_line;
|
||||
struct wined3d_display_mode mode;
|
||||
TRACE("swapchain %p, raster_status %p.\n", swapchain, raster_status);
|
||||
|
||||
/* No OpenGL equivalent */
|
||||
if (!warned)
|
||||
{
|
||||
FIXME("swapchain %p, raster_status %p semi-stub!\n", swapchain, raster_status);
|
||||
warned = TRUE;
|
||||
}
|
||||
|
||||
/* Obtaining the raster status is a widely implemented but optional
|
||||
* feature. When this method returns OK StarCraft 2 expects the
|
||||
* raster_status->InVBlank value to actually change over time.
|
||||
* And Endless Alice Crysis doesn't care even if this method fails.
|
||||
* Thus this method returns OK and fakes raster_status by
|
||||
* QueryPerformanceCounter. */
|
||||
|
||||
if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (FAILED(wined3d_swapchain_get_display_mode(swapchain, &mode, NULL)))
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
if (mode.refresh_rate == DEFAULT_REFRESH_RATE)
|
||||
mode.refresh_rate = 60;
|
||||
|
||||
freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate;
|
||||
/* Assume 20 scan lines in the vertical blank */
|
||||
freq_per_line = freq_per_frame / (mode.height + 20);
|
||||
raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line;
|
||||
if (raster_status->scan_line < mode.height)
|
||||
raster_status->in_vblank = FALSE;
|
||||
else
|
||||
{
|
||||
raster_status->scan_line = 0;
|
||||
raster_status->in_vblank = TRUE;
|
||||
}
|
||||
TRACE("Returning fake value, in_vblank %u, scan_line %u.\n",
|
||||
raster_status->in_vblank, raster_status->scan_line);
|
||||
return WINED3D_OK;
|
||||
return wined3d_get_adapter_raster_status(swapchain->device->wined3d,
|
||||
swapchain->device->adapter->ordinal, raster_status);
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
@ cdecl wined3d_get_adapter_identifier(ptr long long ptr)
|
||||
@ cdecl wined3d_get_adapter_mode_count(ptr long long long)
|
||||
@ cdecl wined3d_get_adapter_monitor(ptr long)
|
||||
@ cdecl wined3d_get_adapter_raster_status(ptr long ptr)
|
||||
@ cdecl wined3d_get_device_caps(ptr long long ptr)
|
||||
@ cdecl wined3d_incref(ptr)
|
||||
@ cdecl wined3d_register_software_device(ptr ptr)
|
||||
|
|
|
@ -2045,6 +2045,8 @@ HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UI
|
|||
UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering);
|
||||
HMONITOR __cdecl wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx);
|
||||
HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
struct wined3d_raster_status *raster_status);
|
||||
HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
enum wined3d_device_type device_type, WINED3DCAPS *caps);
|
||||
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
|
||||
|
|
Loading…
Reference in New Issue