wine/dlls/wined3d/directx.c

295 lines
10 KiB
C
Raw Normal View History

/*
* IWineD3D implementation
*
* Copyright 2002-2004 Jason Edmeades
* Copyright 2003-2004 Raphael Junqueira
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Compile time diagnostics: */
/* Uncomment this to force only a single display mode to be exposed: */
/*#define DEBUG_SINGLE_MODE*/
#include "config.h"
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
UINT WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
/* FIXME: Set to one for now to imply the display */
TRACE_(d3d_caps)("(%p): Mostly stub, only returns primary display\n", This);
return 1;
}
HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
return D3D_OK;
}
HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
FIXME_(d3d_caps)("(%p)->(Adptr:%d)\n", This, Adapter);
if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
return NULL;
}
return D3D_OK;
}
/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
of the same bpp but different resolutions */
/* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, D3DFORMAT Format) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
return 0;
}
if (Adapter == 0) { /* Display */
int i = 0;
int j = 0;
#if !defined( DEBUG_SINGLE_MODE )
DEVMODEW DevModeW;
/* Work out the current screen bpp */
HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
int bpp = GetDeviceCaps(hdc, BITSPIXEL);
DeleteDC(hdc);
while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
j++;
switch (Format)
{
case D3DFMT_UNKNOWN:
i++;
break;
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
if (min(DevModeW.dmBitsPerPel, bpp) == 32) i++;
break;
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
case D3DFMT_R5G6B5:
if (min(DevModeW.dmBitsPerPel, bpp) == 16) i++;
break;
default:
/* Skip other modes as they do not match requested format */
break;
}
}
#else
i = 1;
j = 1;
#endif
TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
return i;
} else {
FIXME_(d3d_caps)("Adapter not primary display\n");
}
return 0;
}
/* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
/* Validate the parameters as much as possible */
if (NULL == pMode ||
Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
Mode >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
return D3DERR_INVALIDCALL;
}
if (Adapter == 0) { /* Display */
#if !defined( DEBUG_SINGLE_MODE )
DEVMODEW DevModeW;
int ModeIdx = 0;
/* Work out the current screen bpp */
HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
int bpp = GetDeviceCaps(hdc, BITSPIXEL);
DeleteDC(hdc);
/* If we are filtering to a specific format, then need to skip all unrelated
modes, but if mode is irrelevant, then we can use the index directly */
if (Format == D3DFMT_UNKNOWN)
{
ModeIdx = Mode;
} else {
int i = 0;
int j = 0;
DEVMODEW DevModeWtmp;
while ((Mode+1) < i && EnumDisplaySettingsExW(NULL, j, &DevModeWtmp, 0)) {
j++;
switch (Format)
{
case D3DFMT_UNKNOWN:
i++;
break;
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
if (min(DevModeWtmp.dmBitsPerPel, bpp) == 32) i++;
break;
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
case D3DFMT_R5G6B5:
if (min(DevModeWtmp.dmBitsPerPel, bpp) == 16) i++;
break;
default:
/* Skip other modes as they do not match requested format */
break;
}
}
ModeIdx = j;
}
/* Now get the display mode via the calculated index */
if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0))
{
pMode->Width = DevModeW.dmPelsWidth;
pMode->Height = DevModeW.dmPelsHeight;
bpp = min(DevModeW.dmBitsPerPel, bpp);
pMode->RefreshRate = D3DADAPTER_DEFAULT;
if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
{
pMode->RefreshRate = DevModeW.dmDisplayFrequency;
}
if (Format == D3DFMT_UNKNOWN)
{
switch (bpp) {
case 8: pMode->Format = D3DFMT_R3G3B2; break;
case 16: pMode->Format = D3DFMT_R5G6B5; break;
case 24: /* pMode->Format = D3DFMT_R5G6B5; break;*/ /* Make 24bit appear as 32 bit */
case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
default: pMode->Format = D3DFMT_UNKNOWN;
}
} else {
pMode->Format = Format;
}
}
else
{
TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
return D3DERR_INVALIDCALL;
}
#else
/* Return one setting of the format requested */
if (Mode > 0) return D3DERR_INVALIDCALL;
pMode->Width = 800;
pMode->Height = 600;
pMode->RefreshRate = D3DADAPTER_DEFAULT;
pMode->Format = (Format==D3DFMT_UNKNOWN)?D3DFMT_A8R8G8B8:Format;
bpp = 32;
#endif
TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format), bpp);
} else {
FIXME_(d3d_caps)("Adapter not primary display\n");
}
return D3D_OK;
}
HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, D3DDISPLAYMODE* pMode) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
if (NULL == pMode ||
Adapter >= IWineD3D_GetAdapterCount(iface)) {
return D3DERR_INVALIDCALL;
}
if (Adapter == 0) { /* Display */
int bpp = 0;
DEVMODEW DevModeW;
EnumDisplaySettingsExW(NULL, (DWORD)-1, &DevModeW, 0);
pMode->Width = DevModeW.dmPelsWidth;
pMode->Height = DevModeW.dmPelsHeight;
bpp = DevModeW.dmBitsPerPel;
pMode->RefreshRate = D3DADAPTER_DEFAULT;
if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
{
pMode->RefreshRate = DevModeW.dmDisplayFrequency;
}
switch (bpp) {
case 8: pMode->Format = D3DFMT_R3G3B2; break;
case 16: pMode->Format = D3DFMT_R5G6B5; break;
case 24: /*pMode->Format = D3DFMT_R5G6B5; break;*/ /* Make 24bit appear as 32 bit */
case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
default: pMode->Format = D3DFMT_UNKNOWN;
}
} else {
FIXME_(d3d_caps)("Adapter not primary display\n");
}
TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
return D3D_OK;
}
/* IUnknown parts follow: */
HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
{
return E_NOINTERFACE;
}
ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
FIXME("(%p) : AddRef increasing from %ld\n", This, This->ref);
return InterlockedIncrement(&This->ref);
}
ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
ULONG ref;
TRACE("(%p) : Releasing from %ld\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
if (ref == 0) HeapFree(GetProcessHeap(), 0, This);
return ref;
}
/* VTbl definition */
IWineD3DVtbl IWineD3D_Vtbl =
{
IWineD3DImpl_QueryInterface,
IWineD3DImpl_AddRef,
IWineD3DImpl_Release,
IWineD3DImpl_GetAdapterCount,
IWineD3DImpl_RegisterSoftwareDevice,
IWineD3DImpl_GetAdapterMonitor,
IWineD3DImpl_GetAdapterModeCount,
IWineD3DImpl_EnumAdapterModes,
IWineD3DImpl_GetAdapterDisplayMode
};