1999-01-03 18:00:19 +01:00
|
|
|
/* Direct3D Viewport
|
2002-03-10 00:29:33 +01:00
|
|
|
* Copyright (c) 1998 Lionel ULMER
|
|
|
|
*
|
|
|
|
* This file contains the implementation of Direct3DViewport2.
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2003-09-06 01:08:26 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
2003-01-07 21:36:20 +01:00
|
|
|
#define NONAMELESSUNION
|
|
|
|
#define NONAMELESSSTRUCT
|
2005-05-27 22:17:35 +02:00
|
|
|
|
|
|
|
#define CONST_VTABLE
|
|
|
|
|
1999-03-14 17:35:05 +01:00
|
|
|
#include "windef.h"
|
2003-09-06 01:08:26 +02:00
|
|
|
#include "winbase.h"
|
1999-01-03 18:00:19 +01:00
|
|
|
#include "winerror.h"
|
2002-12-05 21:33:07 +01:00
|
|
|
#include "objbase.h"
|
2003-09-06 01:08:26 +02:00
|
|
|
#include "wingdi.h"
|
1999-01-03 18:00:19 +01:00
|
|
|
#include "ddraw.h"
|
|
|
|
#include "d3d.h"
|
2002-03-10 00:29:33 +01:00
|
|
|
#include "wine/debug.h"
|
1999-01-03 18:00:19 +01:00
|
|
|
|
|
|
|
#include "d3d_private.h"
|
|
|
|
|
2002-03-10 00:29:33 +01:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
|
1999-04-19 16:56:29 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
static void activate(IDirect3DViewportImpl* This) {
|
|
|
|
IDirect3DLightImpl* light;
|
2003-05-20 01:03:38 +02:00
|
|
|
D3DVIEWPORT7 vp;
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
/* Activate all the lights associated with this context */
|
|
|
|
light = This->lights;
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
while (light != NULL) {
|
|
|
|
light->activate(light);
|
|
|
|
light = light->next;
|
|
|
|
}
|
2003-05-20 01:03:38 +02:00
|
|
|
|
|
|
|
/* And copy the values in the structure used by the device */
|
|
|
|
if (This->use_vp2) {
|
|
|
|
vp.dwX = This->viewports.vp2.dwX;
|
|
|
|
vp.dwY = This->viewports.vp2.dwY;
|
|
|
|
vp.dwHeight = This->viewports.vp2.dwHeight;
|
|
|
|
vp.dwWidth = This->viewports.vp2.dwWidth;
|
|
|
|
vp.dvMinZ = This->viewports.vp2.dvMinZ;
|
|
|
|
vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
|
|
|
|
} else {
|
|
|
|
vp.dwX = This->viewports.vp1.dwX;
|
|
|
|
vp.dwY = This->viewports.vp1.dwY;
|
|
|
|
vp.dwHeight = This->viewports.vp1.dwHeight;
|
|
|
|
vp.dwWidth = This->viewports.vp1.dwWidth;
|
|
|
|
vp.dvMinZ = This->viewports.vp1.dvMinZ;
|
|
|
|
vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* And also set the viewport */
|
|
|
|
IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
|
2002-11-21 22:04:16 +01:00
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
|
|
|
|
{
|
|
|
|
TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
|
|
|
|
lpvp->dwSize, lpvp->dwX, lpvp->dwY);
|
|
|
|
TRACE(" - dwWidth = %ld dwHeight = %ld\n",
|
|
|
|
lpvp->dwWidth, lpvp->dwHeight);
|
|
|
|
TRACE(" - dvScaleX = %f dvScaleY = %f\n",
|
|
|
|
lpvp->dvScaleX, lpvp->dvScaleY);
|
|
|
|
TRACE(" - dvMaxX = %f dvMaxY = %f\n",
|
|
|
|
lpvp->dvMaxX, lpvp->dvMaxY);
|
|
|
|
TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
|
|
|
|
lpvp->dvMinZ, lpvp->dvMaxZ);
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
|
|
|
|
lpvp->dwSize, lpvp->dwX, lpvp->dwY);
|
|
|
|
TRACE(" - dwWidth = %ld dwHeight = %ld\n",
|
|
|
|
lpvp->dwWidth, lpvp->dwHeight);
|
|
|
|
TRACE(" - dvClipX = %f dvClipY = %f\n",
|
|
|
|
lpvp->dvClipX, lpvp->dvClipY);
|
|
|
|
TRACE(" - dvClipWidth = %f dvClipHeight = %f\n",
|
|
|
|
lpvp->dvClipWidth, lpvp->dvClipHeight);
|
|
|
|
TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
|
|
|
|
lpvp->dvMinZ, lpvp->dvMaxZ);
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
REFIID riid,
|
|
|
|
LPVOID* obp)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
|
|
|
|
|
|
|
|
*obp = NULL;
|
|
|
|
|
|
|
|
if ( IsEqualGUID(&IID_IUnknown, riid) ||
|
|
|
|
IsEqualGUID(&IID_IDirect3DViewport, riid) ||
|
|
|
|
IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
|
|
|
|
IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
|
|
|
|
IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
|
|
|
|
*obp = ICOM_INTERFACE(This, IDirect3DViewport3);
|
|
|
|
TRACE(" Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
|
|
|
|
return OLE_E_ENUM_NOMORE;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
ULONG WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
2005-01-09 18:29:21 +01:00
|
|
|
ULONG ref = InterlockedIncrement(&This->ref);
|
|
|
|
|
|
|
|
TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
|
|
|
|
|
|
|
|
return ref;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
ULONG WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
2005-01-09 18:29:21 +01:00
|
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
|
|
|
TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
|
|
|
|
|
|
|
|
if (!ref) {
|
2002-11-21 22:04:16 +01:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-01-09 18:29:21 +01:00
|
|
|
return ref;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECT3D lpDirect3D)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPD3DVIEWPORT lpData)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
DWORD dwSize;
|
|
|
|
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
|
|
|
|
if (This->use_vp2 != 0) {
|
|
|
|
ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
}
|
|
|
|
dwSize = lpData->dwSize;
|
|
|
|
memset(lpData, 0, dwSize);
|
|
|
|
memcpy(lpData, &(This->viewports.vp1), dwSize);
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
if (TRACE_ON(ddraw)) {
|
2002-11-30 20:12:32 +01:00
|
|
|
TRACE(" returning D3DVIEWPORT :\n");
|
2002-11-21 22:04:16 +01:00
|
|
|
_dump_D3DVIEWPORT(lpData);
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPD3DVIEWPORT lpData)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
2003-10-14 03:16:42 +02:00
|
|
|
LPDIRECT3DVIEWPORT3 current_viewport;
|
2002-11-21 22:04:16 +01:00
|
|
|
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
if (TRACE_ON(ddraw)) {
|
|
|
|
TRACE(" getting D3DVIEWPORT :\n");
|
|
|
|
_dump_D3DVIEWPORT(lpData);
|
|
|
|
}
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
This->use_vp2 = 0;
|
|
|
|
memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
|
|
|
|
memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
|
2003-06-05 01:39:13 +02:00
|
|
|
|
2005-01-10 14:29:24 +01:00
|
|
|
/* Tests on two games show that these values are never used properly so override
|
2003-06-05 01:39:13 +02:00
|
|
|
them with proper ones :-)
|
|
|
|
*/
|
|
|
|
This->viewports.vp1.dvMinZ = 0.0;
|
|
|
|
This->viewports.vp1.dvMaxZ = 1.0;
|
2003-10-14 03:16:42 +02:00
|
|
|
|
|
|
|
if (This->active_device) {
|
|
|
|
IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport);
|
|
|
|
if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
|
|
|
|
This->activate(This);
|
|
|
|
IDirect3DViewport3_Release(current_viewport);
|
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
return DD_OK;
|
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
DWORD dwVertexCount,
|
|
|
|
LPD3DTRANSFORMDATA lpData,
|
|
|
|
DWORD dwFlags,
|
|
|
|
LPDWORD lpOffScreen)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
|
2004-08-02 20:27:32 +02:00
|
|
|
if (lpOffScreen)
|
|
|
|
*lpOffScreen = 0;
|
2002-11-21 22:04:16 +01:00
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
DWORD dwElementCount,
|
|
|
|
LPD3DLIGHTDATA lpData)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
|
|
|
|
return DD_OK;
|
|
|
|
}
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
D3DMATERIALHANDLE hMat)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
2002-12-24 02:07:21 +01:00
|
|
|
TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
|
|
|
|
|
|
|
|
This->background = (IDirect3DMaterialImpl *) hMat;
|
|
|
|
TRACE(" setting background color : %f %f %f %f\n",
|
|
|
|
This->background->mat.u.diffuse.u1.r,
|
|
|
|
This->background->mat.u.diffuse.u2.g,
|
|
|
|
This->background->mat.u.diffuse.u3.b,
|
|
|
|
This->background->mat.u.diffuse.u4.a);
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
return DD_OK;
|
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPD3DMATERIALHANDLE lphMat,
|
|
|
|
LPBOOL lpValid)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
|
|
|
|
return DD_OK;
|
|
|
|
}
|
1999-01-23 13:33:16 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECTDRAWSURFACE lpDDSurface)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
|
|
|
|
return DD_OK;
|
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECTDRAWSURFACE* lplpDDSurface,
|
|
|
|
LPBOOL lpValid)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
DWORD dwCount,
|
|
|
|
LPD3DRECT lpRects,
|
|
|
|
DWORD dwFlags)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
2002-12-24 02:07:21 +01:00
|
|
|
DWORD color = 0x00000000;
|
|
|
|
|
2002-12-24 02:03:04 +01:00
|
|
|
TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
|
|
|
|
if (This->active_device == NULL) {
|
|
|
|
ERR(" Trying to clear a viewport not attached to a device !\n");
|
|
|
|
return D3DERR_VIEWPORTHASNODEVICE;
|
|
|
|
}
|
2002-12-24 02:07:21 +01:00
|
|
|
if (dwFlags & D3DCLEAR_TARGET) {
|
|
|
|
if (This->background == NULL) {
|
|
|
|
ERR(" Trying to clear the color buffer without background material !\n");
|
|
|
|
} else {
|
|
|
|
color =
|
|
|
|
((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
|
|
|
|
((int) ((This->background->mat.u.diffuse.u2.g) * 255) << 8) |
|
|
|
|
((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) |
|
|
|
|
((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return This->active_device->clear(This->active_device, dwCount, lpRects,
|
|
|
|
dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
|
|
|
|
color, 1.0, 0x00000000);
|
2002-11-21 22:04:16 +01:00
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECT3DLIGHT lpDirect3DLight)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
|
2003-01-21 00:24:05 +01:00
|
|
|
DWORD i = 0;
|
|
|
|
DWORD map = This->map_lights;
|
2002-11-21 22:04:16 +01:00
|
|
|
|
|
|
|
TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
|
|
|
|
|
2003-01-21 00:24:05 +01:00
|
|
|
if (This->num_lights >= 8)
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
|
|
|
|
/* Find a light number and update both light and viewports objects accordingly */
|
|
|
|
while(map&1) {
|
|
|
|
map>>=1;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
lpDirect3DLightImpl->dwLightIndex = i;
|
|
|
|
This->num_lights++;
|
|
|
|
This->map_lights |= 1<<i;
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
/* Add the light in the 'linked' chain */
|
|
|
|
lpDirect3DLightImpl->next = This->lights;
|
|
|
|
This->lights = lpDirect3DLightImpl;
|
|
|
|
|
2003-01-21 00:24:05 +01:00
|
|
|
/* Attach the light to the viewport */
|
|
|
|
lpDirect3DLightImpl->active_viewport = This;
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
/* If active, activate the light */
|
|
|
|
if (This->active_device != NULL) {
|
|
|
|
lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECT3DLIGHT lpDirect3DLight)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
|
|
|
|
IDirect3DLightImpl *cur_light, *prev_light = NULL;
|
|
|
|
|
|
|
|
TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
|
|
|
|
cur_light = This->lights;
|
|
|
|
while (cur_light != NULL) {
|
|
|
|
if (cur_light == lpDirect3DLightImpl) {
|
|
|
|
lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
|
|
|
|
if (prev_light == NULL) This->lights = cur_light->next;
|
|
|
|
else prev_light->next = cur_light->next;
|
2003-01-21 00:24:05 +01:00
|
|
|
/* Detach the light to the viewport */
|
|
|
|
cur_light->active_viewport = NULL;
|
|
|
|
This->num_lights--;
|
|
|
|
This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
|
2002-11-21 22:04:16 +01:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
prev_light = cur_light;
|
|
|
|
cur_light = cur_light->next;
|
|
|
|
}
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECT3DLIGHT lpDirect3DLight,
|
|
|
|
LPDIRECT3DLIGHT* lplpDirect3DLight,
|
|
|
|
DWORD dwFlags)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPD3DVIEWPORT2 lpData)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
DWORD dwSize;
|
|
|
|
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
|
|
|
|
if (This->use_vp2 != 1) {
|
|
|
|
ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
}
|
|
|
|
dwSize = lpData->dwSize;
|
|
|
|
memset(lpData, 0, dwSize);
|
|
|
|
memcpy(lpData, &(This->viewports.vp2), dwSize);
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
if (TRACE_ON(ddraw)) {
|
2002-11-30 20:12:32 +01:00
|
|
|
TRACE(" returning D3DVIEWPORT2 :\n");
|
2002-11-21 22:04:16 +01:00
|
|
|
_dump_D3DVIEWPORT2(lpData);
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPD3DVIEWPORT2 lpData)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
2003-10-14 03:16:42 +02:00
|
|
|
LPDIRECT3DVIEWPORT3 current_viewport;
|
2002-11-21 22:04:16 +01:00
|
|
|
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
if (TRACE_ON(ddraw)) {
|
|
|
|
TRACE(" getting D3DVIEWPORT2 :\n");
|
|
|
|
_dump_D3DVIEWPORT2(lpData);
|
|
|
|
}
|
|
|
|
|
|
|
|
This->use_vp2 = 1;
|
|
|
|
memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
|
|
|
|
memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
|
2003-10-14 03:16:42 +02:00
|
|
|
|
|
|
|
if (This->active_device) {
|
|
|
|
IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport);
|
|
|
|
if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
|
|
|
|
This->activate(This);
|
|
|
|
IDirect3DViewport3_Release(current_viewport);
|
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECTDRAWSURFACE4 lpDDS)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
|
|
|
|
return DD_OK;
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
LPDIRECTDRAWSURFACE4* lplpDDS,
|
|
|
|
LPBOOL lpValid)
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
|
|
|
|
return DD_OK;
|
|
|
|
}
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
HRESULT WINAPI
|
|
|
|
Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
|
|
|
|
DWORD dwCount,
|
|
|
|
LPD3DRECT lpRects,
|
|
|
|
DWORD dwFlags,
|
|
|
|
DWORD dwColor,
|
|
|
|
D3DVALUE dvZ,
|
|
|
|
DWORD dwStencil)
|
|
|
|
{
|
|
|
|
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
|
|
|
TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
|
2002-12-24 02:03:04 +01:00
|
|
|
if (This->active_device == NULL) {
|
|
|
|
ERR(" Trying to clear a viewport not attached to a device !\n");
|
|
|
|
return D3DERR_VIEWPORTHASNODEVICE;
|
2002-09-29 20:00:43 +02:00
|
|
|
}
|
2002-12-24 02:03:04 +01:00
|
|
|
return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
|
1999-01-03 18:00:19 +01:00
|
|
|
}
|
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
|
|
|
|
# define XCAST(fun) (typeof(VTABLE_IDirect3DViewport3.fun))
|
|
|
|
#else
|
|
|
|
# define XCAST(fun) (void*)
|
|
|
|
#endif
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2005-05-27 22:17:35 +02:00
|
|
|
static const IDirect3DViewport3Vtbl VTABLE_IDirect3DViewport3 =
|
1999-01-03 18:00:19 +01:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
|
|
|
|
XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
|
|
|
|
XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
|
|
|
|
XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
|
|
|
|
XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
|
|
|
|
XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
|
|
|
|
XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
|
|
|
|
XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
|
|
|
|
XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
|
|
|
|
XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
|
|
|
|
XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
|
|
|
|
XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
|
2002-12-24 02:03:04 +01:00
|
|
|
XCAST(Clear) Main_IDirect3DViewportImpl_3_2_1_Clear,
|
2002-11-21 22:04:16 +01:00
|
|
|
XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
|
|
|
|
XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
|
|
|
|
XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
|
|
|
|
XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
|
|
|
|
XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
|
|
|
|
XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
|
|
|
|
XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
|
2002-12-24 02:03:04 +01:00
|
|
|
XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2,
|
2002-11-21 22:04:16 +01:00
|
|
|
};
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
|
|
|
|
#undef XCAST
|
|
|
|
#endif
|
2002-06-01 01:06:46 +02:00
|
|
|
|
1999-01-03 18:00:19 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2003-06-05 01:31:39 +02:00
|
|
|
HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
|
1999-05-22 13:41:38 +02:00
|
|
|
{
|
2002-11-21 22:04:16 +01:00
|
|
|
IDirect3DViewportImpl *object;
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
|
|
|
|
if (object == NULL) return DDERR_OUTOFMEMORY;
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
object->ref = 1;
|
|
|
|
object->d3d = d3d;
|
|
|
|
object->activate = activate;
|
|
|
|
object->use_vp2 = 0xFF;
|
|
|
|
object->next = NULL;
|
|
|
|
object->lights = NULL;
|
2003-01-21 00:24:05 +01:00
|
|
|
object->num_lights = 0;
|
|
|
|
object->map_lights = 0;
|
2002-11-21 22:04:16 +01:00
|
|
|
|
|
|
|
ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
*obj = object;
|
1999-01-03 18:00:19 +01:00
|
|
|
|
2002-11-21 22:04:16 +01:00
|
|
|
TRACE(" creating implementation at %p.\n", *obj);
|
|
|
|
|
|
|
|
return D3D_OK;
|
|
|
|
}
|