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);
|
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)
|
static HRESULT WINAPI ddraw7_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
|
||||||
{
|
{
|
||||||
struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
|
struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
|
||||||
struct wined3d_display_mode mode;
|
struct wined3d_raster_status raster_status;
|
||||||
static BOOL hide = FALSE;
|
|
||||||
DWORD time, frame_progress, lines;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("iface %p, line %p.\n", iface, Scanline);
|
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();
|
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();
|
wined3d_mutex_unlock();
|
||||||
if (FAILED(hr))
|
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;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fake the line sweeping of the monitor */
|
*Scanline = raster_status.scan_line;
|
||||||
/* FIXME: We should synchronize with a source to keep the refresh rate */
|
|
||||||
|
|
||||||
/* Simulate a 60Hz display */
|
if (raster_status.in_vblank)
|
||||||
time = GetTickCount();
|
|
||||||
frame_progress = time & 15; /* time % (1000 / 60) */
|
|
||||||
if (!frame_progress)
|
|
||||||
{
|
|
||||||
*Scanline = 0;
|
|
||||||
return DDERR_VERTICALBLANKINPROGRESS;
|
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;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3225,6 +3225,53 @@ HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
|
||||||
return WINED3D_OK;
|
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,
|
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)
|
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,
|
HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
|
||||||
struct wined3d_raster_status *raster_status)
|
struct wined3d_raster_status *raster_status)
|
||||||
{
|
{
|
||||||
static BOOL warned;
|
TRACE("swapchain %p, raster_status %p.\n", swapchain, raster_status);
|
||||||
LARGE_INTEGER counter, freq_per_sec;
|
|
||||||
LONGLONG freq_per_frame, freq_per_line;
|
|
||||||
struct wined3d_display_mode mode;
|
|
||||||
|
|
||||||
/* No OpenGL equivalent */
|
return wined3d_get_adapter_raster_status(swapchain->device->wined3d,
|
||||||
if (!warned)
|
swapchain->device->adapter->ordinal, raster_status);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CDECL wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain,
|
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_identifier(ptr long long ptr)
|
||||||
@ cdecl wined3d_get_adapter_mode_count(ptr long long long)
|
@ cdecl wined3d_get_adapter_mode_count(ptr long long long)
|
||||||
@ cdecl wined3d_get_adapter_monitor(ptr 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_get_device_caps(ptr long long ptr)
|
||||||
@ cdecl wined3d_incref(ptr)
|
@ cdecl wined3d_incref(ptr)
|
||||||
@ cdecl wined3d_register_software_device(ptr 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,
|
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);
|
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);
|
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,
|
HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
|
||||||
enum wined3d_device_type device_type, WINED3DCAPS *caps);
|
enum wined3d_device_type device_type, WINED3DCAPS *caps);
|
||||||
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
|
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
|
||||||
|
|
Loading…
Reference in New Issue