- Clean up all the D3D COM handling (but the underlaying code is still
  as ugly as before).
- Handle properly (ie as on real Windows) negative values in
  rectangles during blitting.

diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in
index 3c5e88b..79e4622 100644
--- a/dlls/ddraw/Makefile.in
+++ b/dlls/ddraw/Makefile.in
@@ -18,6 +18,7 @@
 	d3dlight.c \
 	d3dmaterial.c \
 	d3dtexture.c \
+	d3dvertexbuffer.c \
 	d3dviewport.c \
 	direct3d/main.c \
 	direct3d/mesa.c \
diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h
index 610c237..284b5f9 100644
--- a/dlls/ddraw/d3d_private.h
+++ b/dlls/ddraw/d3d_private.h
@@ -30,300 +30,121 @@
  * Predeclare the interface implementation structures
  */
 typedef struct IDirect3DImpl IDirect3DImpl;
-typedef struct IDirect3D2Impl IDirect3D2Impl;
-typedef struct IDirect3D3Impl IDirect3D3Impl;
-
 typedef struct IDirect3DLightImpl IDirect3DLightImpl;
-typedef struct IDirect3DMaterial2Impl IDirect3DMaterial2Impl;
-typedef struct IDirect3DTexture2Impl IDirect3DTexture2Impl;
-typedef struct IDirect3DViewport2Impl IDirect3DViewport2Impl;
+typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl;
+typedef struct IDirect3DTextureImpl IDirect3DTextureImpl;
+typedef struct IDirect3DViewportImpl IDirect3DViewportImpl;
 typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl;
 typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;
-typedef struct IDirect3DDevice2Impl IDirect3DDevice2Impl;
+typedef struct IDirect3DVertexBufferImpl IDirect3DVertexBufferImpl;
 
 #include "ddraw_private.h"
 
-extern ICOM_VTABLE(IDirect3D)	mesa_d3dvt;
-extern ICOM_VTABLE(IDirect3D2)	mesa_d3d2vt;
-extern ICOM_VTABLE(IDirect3D3)  mesa_d3d3vt;
-
 /*****************************************************************************
- * IDirect3D implementation structure
+ * IDirect3D implementation structure.
+ * This is common for interfaces 1, 2, 3 and 7.
  */
 struct IDirect3DImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3D);
+    ICOM_VFIELD_MULTI(IDirect3D7);
+    ICOM_VFIELD_MULTI(IDirect3D3);
+    ICOM_VFIELD_MULTI(IDirect3D2);
+    ICOM_VFIELD_MULTI(IDirect3D);
     DWORD                   ref;
     /* IDirect3D fields */
     IDirectDrawImpl*	ddraw;
-    LPVOID		private;
 };
 
 /*****************************************************************************
- * IDirect3D2 implementation structure
- */
-struct IDirect3D2Impl
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3D2);
-    DWORD                    ref;
-    /* IDirect3D2 fields */
-    IDirectDrawImpl*	ddraw;
-    LPVOID		private;
-};
-
-struct IDirect3D3Impl
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3D3);
-    DWORD                    ref;
-    /* IDirect3D2 fields */
-    IDirectDrawImpl*    ddraw;
-    LPVOID              private;
-    /* IDirect3D3 fields */
-};
-
-
-extern HRESULT WINAPI IDirect3DImpl_QueryInterface(
-    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
-);
-extern ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface);
-extern ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
-;
-extern HRESULT WINAPI IDirect3DImpl_Initialize(LPDIRECT3D iface,REFIID refiid);
-extern HRESULT WINAPI IDirect3DImpl_EnumDevices(
-    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-);
-extern HRESULT WINAPI IDirect3DImpl_CreateLight(
-    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
-);
-extern HRESULT WINAPI IDirect3DImpl_CreateMaterial(
-    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
-);
-extern HRESULT WINAPI IDirect3DImpl_CreateViewport(
-    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
-);
-extern HRESULT WINAPI IDirect3DImpl_FindDevice(
-    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
-    LPD3DFINDDEVICERESULT lpfinddevrst)
-;
-extern HRESULT WINAPI IDirect3D2Impl_QueryInterface(LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj);
-extern ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface);
-extern ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface);
-extern HRESULT WINAPI IDirect3D2Impl_EnumDevices(
-    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-);
-extern HRESULT WINAPI IDirect3D2Impl_CreateLight(
-    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
-);
-extern HRESULT WINAPI IDirect3D2Impl_CreateMaterial(
-    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
-);
-extern HRESULT WINAPI IDirect3D2Impl_CreateViewport(
-    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
-);
-extern HRESULT WINAPI IDirect3D2Impl_FindDevice(
-    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
-    LPD3DFINDDEVICERESULT lpfinddevrst);
-extern HRESULT WINAPI IDirect3D2Impl_CreateDevice(
-    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
-    LPDIRECT3DDEVICE2 *device);
-
-/*****************************************************************************
  * IDirect3DLight implementation structure
  */
 struct IDirect3DLightImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DLight);
-    DWORD                        ref;
+    ICOM_VFIELD_MULTI(IDirect3DLight);
+    DWORD ref;
     /* IDirect3DLight fields */
-    union {
-        IDirect3DImpl*  d3d1;
-        IDirect3D2Impl* d3d2;
-    } d3d;
-    int                 type;
+    IDirect3DImpl *d3d;
 
-    D3DLIGHT2           light;
+    D3DLIGHT2 light;
 
     /* Chained list used for adding / removing from viewports */
-    IDirect3DLightImpl *next, *prev;
+    IDirect3DLightImpl *next;
 
     /* Activation function */
     void (*activate)(IDirect3DLightImpl*);
-    int                 is_active;
-
-    LPVOID		private;
+    void (*desactivate)(IDirect3DLightImpl*);
+    void (*update)(IDirect3DLightImpl*);
 };
 
 /*****************************************************************************
- * IDirect3DMaterial2 implementation structure
+ * IDirect3DMaterial implementation structure
  */
-struct IDirect3DMaterial2Impl
+struct IDirect3DMaterialImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DMaterial2);
-    DWORD                            ref;
+    ICOM_VFIELD_MULTI(IDirect3DMaterial3);
+    ICOM_VFIELD_MULTI(IDirect3DMaterial2);
+    ICOM_VFIELD_MULTI(IDirect3DMaterial);
+    DWORD  ref;
     /* IDirect3DMaterial2 fields */
-    union {
-        IDirect3DImpl*        d3d1;
-        IDirect3D2Impl*       d3d2;
-    } d3d;
-    union {
-        IDirect3DDeviceImpl*  active_device1;
-        IDirect3DDevice2Impl* active_device2;
-    } device;
-    int                       use_d3d2;
+    IDirect3DImpl *d3d;
+    IDirect3DDeviceImpl *active_device;
 
-    D3DMATERIAL               mat;
+    D3DMATERIAL mat;
 
-    void (*activate)(IDirect3DMaterial2Impl* this);
-    LPVOID			private;
+    void (*activate)(IDirect3DMaterialImpl* this);
 };
 
 /*****************************************************************************
- * IDirect3DTexture2 implementation structure
+ * IDirect3DTexture implementation structure
  */
-struct IDirect3DTexture2Impl
+struct IDirect3DTextureImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DTexture2);
-    DWORD                           ref;
-    /* IDirect3DTexture2 fields */
-    void*			D3Ddevice; /* (void *) to use the same pointer
-					    * for both Direct3D and Direct3D2 */
-    IDirectDrawSurfaceImpl*	surface;
-    LPVOID			private;
+    ICOM_VFIELD_MULTI(IDirect3DTexture2);
+    ICOM_VFIELD_MULTI(IDirect3DTexture);
+    DWORD ref;
+    /* IDirect3DTexture fields */
+    IDirect3DImpl *d3d;
+    IDirect3DDeviceImpl *d3ddevice;
+    IDirectDrawSurfaceImpl *surface;
 };
 
-extern HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(
-    LPDIRECT3DTEXTURE2 iface, REFIID riid, LPVOID* ppvObj
-);
-extern ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface);
-extern ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface);
-extern HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
-						 LPDIRECT3DDEVICE lpD3DDevice,
-						 LPD3DTEXTUREHANDLE lpHandle)
-;
-extern HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
-					  LPDIRECT3DDEVICE lpD3DDevice,
-					  LPDIRECTDRAWSURFACE lpSurface)
-;
-extern HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface);
-extern HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(
-    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DDEVICE2 lpD3DDevice2,
-    LPD3DTEXTUREHANDLE lpHandle
-);
-extern HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(
-    LPDIRECT3DTEXTURE2 iface, DWORD dwStart, DWORD dwCount
-);
-extern HRESULT WINAPI IDirect3DTexture2Impl_Load(
-    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DTEXTURE2 lpD3DTexture2
-);
-
 /*****************************************************************************
- * IDirect3DViewport2 implementation structure
+ * IDirect3DViewport implementation structure
  */
-struct IDirect3DViewport2Impl
+struct IDirect3DViewportImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DViewport2);
-    DWORD                            ref;
-    /* IDirect3DViewport2 fields */
-    union {
-        IDirect3DImpl*        d3d1;
-        IDirect3D2Impl*       d3d2;
-    } d3d;
+    ICOM_VFIELD_MULTI(IDirect3DViewport3);
+    DWORD ref;
+    /* IDirect3DViewport fields */
+    IDirect3DImpl *d3d;
     /* If this viewport is active for one device, put the device here */
+    IDirect3DDeviceImpl *active_device;
+
+    int use_vp2;
     union {
-        IDirect3DDeviceImpl*	active_device1;
-        IDirect3DDevice2Impl*	active_device2;
-    } device;
-    int				use_d3d2;
+        D3DVIEWPORT vp1;
+	D3DVIEWPORT2 vp2;
+    } viewports;
 
-    union {
-        D3DVIEWPORT		vp1;
-        D3DVIEWPORT2		vp2;
-    } viewport;
-    int				use_vp2;
+    /* Activation function */
+    void (*activate)(IDirect3DViewportImpl*);
 
-  /* Activation function */
-  void (*activate)(IDirect3DViewport2Impl*);
+    /* Field used to chain viewports together */
+    IDirect3DViewportImpl *next;
 
-  /* Field used to chain viewports together */
-  IDirect3DViewport2Impl*	next;
-
-  /* Lights list */
-  IDirect3DLightImpl*		lights;
-
-  LPVOID			private;
+    /* Lights list */
+    IDirect3DLightImpl *lights;
 };
 
-extern HRESULT WINAPI IDirect3DViewport2Impl_QueryInterface(
-    LPDIRECT3DVIEWPORT2 iface, REFIID riid, LPVOID* ppvObj
-);
-extern ULONG WINAPI IDirect3DViewport2Impl_AddRef(LPDIRECT3DVIEWPORT2 iface)
-;
-extern ULONG WINAPI IDirect3DViewport2Impl_Release(LPDIRECT3DVIEWPORT2 iface)
-;
-extern HRESULT WINAPI IDirect3DViewport2Impl_Initialize(
-    LPDIRECT3DVIEWPORT2 iface, LPDIRECT3D d3d
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_GetViewport(
-    LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT lpvp
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_SetViewport(
-    LPDIRECT3DVIEWPORT2 iface,LPD3DVIEWPORT lpvp
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_TransformVertices(
-    LPDIRECT3DVIEWPORT2 iface,DWORD dwVertexCount,LPD3DTRANSFORMDATA lpData,
-    DWORD dwFlags,LPDWORD lpOffScreen
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_LightElements(
-    LPDIRECT3DVIEWPORT2 iface,DWORD dwElementCount,LPD3DLIGHTDATA lpData
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_SetBackground(
-    LPDIRECT3DVIEWPORT2 iface, D3DMATERIALHANDLE hMat
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_GetBackground(
-    LPDIRECT3DVIEWPORT2 iface,LPD3DMATERIALHANDLE lphMat,LPBOOL lpValid
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_SetBackgroundDepth(
-    LPDIRECT3DVIEWPORT2 iface,LPDIRECTDRAWSURFACE lpDDSurface
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_GetBackgroundDepth(
-    LPDIRECT3DVIEWPORT2 iface,LPDIRECTDRAWSURFACE* lplpDDSurface,LPBOOL lpValid
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_Clear(
-    LPDIRECT3DVIEWPORT2 iface, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_AddLight(
-    LPDIRECT3DVIEWPORT2 iface,LPDIRECT3DLIGHT lpLight
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_DeleteLight(
-    LPDIRECT3DVIEWPORT2 iface,LPDIRECT3DLIGHT lpLight
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_NextLight(
-    LPDIRECT3DVIEWPORT2 iface, LPDIRECT3DLIGHT lpLight,
-    LPDIRECT3DLIGHT* lplpLight, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_GetViewport2(
-    LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT2 lpViewport2
-);
-extern HRESULT WINAPI IDirect3DViewport2Impl_SetViewport2(
-    LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT2 lpViewport2
-);
-
 /*****************************************************************************
  * IDirect3DExecuteBuffer implementation structure
  */
 struct IDirect3DExecuteBufferImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DExecuteBuffer);
-    DWORD                                ref;
+    ICOM_VFIELD_MULTI(IDirect3DExecuteBuffer);
+    DWORD ref;
     /* IDirect3DExecuteBuffer fields */
+    IDirect3DImpl *d3d;
     IDirect3DDeviceImpl* d3ddev;
 
     D3DEXECUTEBUFFERDESC desc;
@@ -337,241 +158,44 @@
        data buffer */
     BOOL need_free;
 
-    void (*execute)(IDirect3DExecuteBuffer* this,
-                    IDirect3DDevice* dev,
-                    IDirect3DViewport* vp);
-    LPVOID private;
+    void (*execute)(IDirect3DExecuteBufferImpl* this,
+                    IDirect3DDeviceImpl* dev,
+                    IDirect3DViewportImpl* vp);
 };
-extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
 
 /*****************************************************************************
  * IDirect3DDevice implementation structure
  */
 struct IDirect3DDeviceImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DDevice);
-    DWORD                         ref;
+    ICOM_VFIELD_MULTI(IDirect3DDevice7);
+    ICOM_VFIELD_MULTI(IDirect3DDevice3);
+    ICOM_VFIELD_MULTI(IDirect3DDevice2);
+    ICOM_VFIELD_MULTI(IDirect3DDevice);
+    DWORD  ref;
     /* IDirect3DDevice fields */
-    IDirect3DImpl*          d3d;
-    IDirectDrawSurfaceImpl* surface;
+    IDirect3DImpl *d3d;
+    IDirectDrawSurfaceImpl *surface;
 
-    IDirect3DViewport2Impl*  viewport_list;
-    IDirect3DViewport2Impl*  current_viewport;
-    IDirect3DTexture2Impl*   current_texture;
+    IDirect3DViewportImpl *viewport_list;
+    IDirect3DViewportImpl *current_viewport;
+    IDirect3DTextureImpl *current_texture;
 
     void (*set_context)(IDirect3DDeviceImpl*);
-    LPVOID		private;
 };
 
 /*****************************************************************************
- * IDirect3DDevice2 implementation structure
+ * IDirect3DVertexBuffer implementation structure
  */
-struct IDirect3DDevice2Impl
+struct IDirect3DVertexBufferImpl
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirect3DDevice2);
-    DWORD                          ref;
-    /* IDirect3DDevice fields */
-    IDirect3D2Impl*         d3d;
-    IDirectDrawSurfaceImpl* surface;
-
-    IDirect3DViewport2Impl* viewport_list;
-    IDirect3DViewport2Impl* current_viewport;
-    IDirect3DTexture2Impl*  current_texture;
-
-    void (*set_context)(IDirect3DDevice2Impl*);
-    LPVOID		private;
+    ICOM_VFIELD_MULTI(IDirect3DVertexBuffer7);
+    ICOM_VFIELD_MULTI(IDirect3DVertexBuffer);
+    DWORD ref;
+    IDirect3DImpl *d3d;
 };
-extern HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(
-    LPDIRECT3DDEVICE2 iface, REFIID riid, LPVOID* ppvObj
-);
-extern ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface);
-extern ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
-;
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(
-    LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
-    LPD3DDEVICEDESC lpdeschard
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(
-    LPDIRECT3DDEVICE2 iface,LPDIRECT3DTEXTURE2 lptex1,LPDIRECT3DTEXTURE2 lptex2
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetStats(
-    LPDIRECT3DDEVICE2 iface, LPD3DSTATS lpstats)
-;
-extern HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp)
-;
-extern HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp,
-    LPDIRECT3DVIEWPORT2* lplpvp, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(
-    LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface);
-extern HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 *lplpvp
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(
-    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(
-    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE *lplpdds
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_Begin(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvert, DWORD numvert, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_Vertex(
-    LPDIRECT3DDEVICE2 iface,LPVOID lpvert
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface, WORD index);
-extern HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,DWORD dwFlags);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(
-    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE d3drs, LPDWORD lprstate
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(
-    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
-    DWORD dwRenderState
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(
-    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE d3dls, LPDWORD lplstate
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(
-    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
-    DWORD dwLightState
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
-    DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(
-    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
-);
-extern HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(
-    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(
-    LPDIRECT3DDEVICE iface, REFIID riid, LPVOID* ppvObj
-);
-extern ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface);
-extern ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface);
-extern HRESULT WINAPI IDirect3DDeviceImpl_Initialize(
-    LPDIRECT3DDEVICE iface, LPDIRECT3D lpd3d, LPGUID lpGUID,
-    LPD3DDEVICEDESC lpd3ddvdesc
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(
-    LPDIRECT3DDEVICE iface, LPD3DDEVICEDESC lpD3DHWDevDesc,
-    LPD3DDEVICEDESC lpD3DSWDevDesc
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DTEXTURE lpD3DTex1,
-    LPDIRECT3DTEXTURE lpD3DTex2
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(
-    LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
-    LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_GetStats(
-    LPDIRECT3DDEVICE iface, LPD3DSTATS lpD3DStats
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_Execute(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp,
-    LPDIRECT3DVIEWPORT* lplpvp, DWORD dwFlags
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_Pick(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags, LPD3DRECT lpRect
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(
-    LPDIRECT3DDEVICE iface, LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(
-    LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
-    LPVOID lpArg
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(
-    LPDIRECT3DDEVICE iface, LPD3DMATRIXHANDLE lpD3DMatHandle
-)
-;
-extern HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(
-    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle,
-    const LPD3DMATRIX lpD3DMatrix)
-;
-extern HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(
-    LPDIRECT3DDEVICE iface,D3DMATRIXHANDLE D3DMatHandle,LPD3DMATRIX lpD3DMatrix
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(
-    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle
-);
-extern HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
-;
-extern HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
-;
-extern HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(
-    LPDIRECT3DDEVICE iface, LPDIRECT3D *lpDirect3D
-);
 
-/* All non-static functions 'exported' by various sub-objects */
-extern LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurfaceImpl* surf);
-extern LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurfaceImpl* surf);
-
-extern LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1);
-extern LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2);
-
-extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
-
-extern LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1);
-extern LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2);
-
-extern LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1);
-extern LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2);
-
-extern int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device);
-extern int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
-extern int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
-extern int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d);
-
-
+/* Various dump functions */
 extern const char *_get_renderstate(D3DRENDERSTATETYPE type);
 
 #define dump_mat(mat) \
diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c
index 7478268..617c2f3 100644
--- a/dlls/ddraw/d3ddevice/main.c
+++ b/dlls/ddraw/d3ddevice/main.c
@@ -30,702 +30,1688 @@
 #include "wine/debug.h"
 
 #include "d3d_private.h"
+#include "main.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-/*******************************************************************************
- *				IDirect3DDevice2
- */
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3DDEVICE7 iface,
+                                                   REFIID riid,
+                                                   LPVOID* obp)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp);
 
-HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(
-    LPDIRECT3DDEVICE2 iface, REFIID riid, LPVOID* ppvObj
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-    return S_OK;
+    *obp = NULL;
+
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+	*obp = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DDevice, riid ) ) {
+        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+        *obp = ICOM_INTERFACE(This, IDirect3DDevice);
+	TRACE("  Creating IDirect3DDevice interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DDevice2, riid ) ) {
+        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+        *obp = ICOM_INTERFACE(This, IDirect3DDevice2);
+	TRACE("  Creating IDirect3DDevice2 interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DDevice3, riid ) ) {
+        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+        *obp = ICOM_INTERFACE(This, IDirect3DDevice3);
+	TRACE("  Creating IDirect3DDevice3 interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DDevice7, riid ) ) {
+        IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
+        *obp = ICOM_INTERFACE(This, IDirect3DDevice7);
+	TRACE("  Creating IDirect3DDevice7 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;
 }
 
-ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
+ULONG WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef(LPDIRECT3DDEVICE7 iface)
 {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
-
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
     return ++(This->ref);
 }
 
-
-
-ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
+ULONG WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
 {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
     if (!--(This->ref)) {
 	/* Release texture associated with the device */ 
-	if (This->current_texture)
-	    IDirect3DTexture2Impl_Release((LPDIRECT3DTEXTURE2)This->current_texture);
+	if (This->current_texture != NULL)
+	    IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture, IDirect3DTexture2));
 	    	  
-	HeapFree(GetProcessHeap(),0,This);
+	HeapFree(GetProcessHeap(), 0, This);
 	return 0;
     }
     return This->ref;
 }
 
-
-/*** IDirect3DDevice2 methods ***/
-HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(
-    LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
-    LPD3DDEVICEDESC lpdeschard
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p,%p), stub!\n", This, lpdescsoft, lpdeschard);
-    return DD_OK;
-}
-
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(
-    LPDIRECT3DDEVICE2 iface,LPDIRECT3DTEXTURE2 lpD3DTex1,LPDIRECT3DTEXTURE2 lpD3DTex2
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    IDirect3DTexture2Impl tmp;
-    TRACE("(%p)->(%p,%p)\n", This, lpD3DTex1, lpD3DTex2);
-
-    tmp = *(IDirect3DTexture2Impl*)lpD3DTex1;
-    *(IDirect3DTexture2Impl*)lpD3DTex1 = *(IDirect3DTexture2Impl*)lpD3DTex2;
-    *(IDirect3DTexture2Impl*)lpD3DTex2 = tmp;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetStats(
-    LPDIRECT3DDEVICE2 iface, LPD3DSTATS lpstats)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
+                                   LPD3DDEVICEDESC7 lpD3DHELDevDesc)
 {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lpstats);
-
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DHELDevDesc);
     return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    TRACE("(%p)->(%p)\n", This, ilpvp);
-
-    /* Adds this viewport to the viewport list */
-    ilpvp->next = This->viewport_list;
-    This->viewport_list = ilpvp;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
+                                                 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
+                                                 LPVOID lpArg)
 {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    IDirect3DViewport2Impl *cur, *prev;
-    TRACE("(%p)->(%p)\n", This, lpvp);
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DEnumPixelProc, lpArg);
+    return DD_OK;
+}
 
-    /* Finds this viewport in the list */
-    prev = NULL;
-    cur = This->viewport_list;
-    while ((cur != NULL) && (cur != ilpvp)) {
-	prev = cur;
-	cur = cur->next;
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene(LPDIRECT3DDEVICE7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(): stub!\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene(LPDIRECT3DDEVICE7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(): stub!\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D(LPDIRECT3DDEVICE7 iface,
+						LPDIRECT3D7* lplpDirect3D3)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3D3);
+
+    *lplpDirect3D3 = ICOM_INTERFACE(This->d3d, IDirect3D7);
+    TRACE(" returning interface %p\n", *lplpDirect3D3);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget(LPDIRECT3DDEVICE7 iface,
+						 LPDIRECTDRAWSURFACE7 lpNewRenderTarget,
+						 DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpNewRenderTarget, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget(LPDIRECT3DDEVICE7 iface,
+						 LPDIRECTDRAWSURFACE7* lplpRenderTarget)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lplpRenderTarget);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_Clear(LPDIRECT3DDEVICE7 iface,
+                                 DWORD dwCount,
+                                 LPD3DRECT lpRects,
+                                 DWORD dwFlags,
+                                 D3DCOLOR dwColor,
+                                 D3DVALUE dvZ,
+                                 DWORD dwStencil)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags, (DWORD) dwColor, dvZ, dwStencil);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dtstTransformStateType, lpD3DMatrix);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform(LPDIRECT3DDEVICE7 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dtstTransformStateType, lpD3DMatrix);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DVIEWPORT7 lpData)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpData);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform(LPDIRECT3DDEVICE7 iface,
+                                                   D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                                   LPD3DMATRIX lpD3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dtstTransformStateType, lpD3DMatrix);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetViewport(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DVIEWPORT7 lpData)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpData);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DMATERIAL7 lpMat)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpMat);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetMaterial(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DMATERIAL7 lpMat)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpMat);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
+                                    DWORD dwLightIndex,
+                                    LPD3DLIGHT7 lpLight)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwLightIndex, lpLight);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetLight(LPDIRECT3DDEVICE7 iface,
+                                    DWORD dwLightIndex,
+                                    LPD3DLIGHT7 lpLight)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwLightIndex, lpLight);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
+                                                D3DRENDERSTATETYPE dwRenderStateType,
+                                                DWORD dwRenderState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%08lx): stub!\n", This, iface, dwRenderStateType, dwRenderState);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
+                                                D3DRENDERSTATETYPE dwRenderStateType,
+                                                LPDWORD lpdwRenderState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dwRenderStateType, lpdwRenderState);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_BeginStateBlock(LPDIRECT3DDEVICE7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(): stub!\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_EndStateBlock(LPDIRECT3DDEVICE7 iface,
+                                         LPDWORD lpdwBlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpdwBlockHandle);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_PreLoad(LPDIRECT3DDEVICE7 iface,
+                                   LPDIRECTDRAWSURFACE7 lpddsTexture)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpddsTexture);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
+                                            D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                            DWORD d3dvtVertexType,
+                                            LPVOID lpvVertices,
+                                            DWORD dwVertexCount,
+                                            DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
+                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                   DWORD d3dvtVertexType,
+                                                   LPVOID lpvVertices,
+                                                   DWORD dwVertexCount,
+                                                   LPWORD dwIndices,
+                                                   DWORD dwIndexCount,
+                                                   DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus(LPDIRECT3DDEVICE7 iface,
+                                               LPD3DCLIPSTATUS lpD3DClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DClipStatus);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus(LPDIRECT3DDEVICE7 iface,
+                                               LPD3DCLIPSTATUS lpD3DClipStatus)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DClipStatus);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
+                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                   DWORD dwVertexType,
+                                                   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                   DWORD dwVertexCount,
+                                                   DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
+                                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                          DWORD dwVertexType,
+                                                          LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                          DWORD dwVertexCount,
+                                                          LPWORD lpIndex,
+                                                          DWORD dwIndexCount,
+                                                          DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
+                                           D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                           LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
+                                           DWORD dwStartVertex,
+                                           DWORD dwNumVertices,
+                                           DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
+                                                  D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                  LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
+                                                  DWORD dwStartVertex,
+                                                  DWORD dwNumVertices,
+                                                  LPWORD lpwIndices,
+                                                  DWORD dwIndexCount,
+                                                  DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility(LPDIRECT3DDEVICE7 iface,
+                                                      LPD3DVECTOR lpCenters,
+                                                      LPD3DVALUE lpRadii,
+                                                      DWORD dwNumSpheres,
+                                                      DWORD dwFlags,
+                                                      LPDWORD lpdwReturnValues)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p,%p,%08lx,%08lx,%p): stub!\n", This, iface, lpCenters, lpRadii, dwNumSpheres, dwFlags, lpdwReturnValues);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetTexture(LPDIRECT3DDEVICE7 iface,
+                                      DWORD dwStage,
+                                      LPDIRECTDRAWSURFACE7* lpTexture)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwStage, lpTexture);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetTexture(LPDIRECT3DDEVICE7 iface,
+                                      DWORD dwStage,
+                                      LPDIRECTDRAWSURFACE7 lpTexture)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwStage, lpTexture);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState(LPDIRECT3DDEVICE7 iface,
+                                                   DWORD dwStage,
+                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                   LPDWORD lpdwState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%08x,%p): stub!\n", This, iface, dwStage, d3dTexStageStateType, lpdwState);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
+                                                   DWORD dwStage,
+                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                   DWORD dwState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%08x,%08lx): stub!\n", This, iface, dwStage, d3dTexStageStateType, dwState);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_ValidateDevice(LPDIRECT3DDEVICE7 iface,
+                                             LPDWORD lpdwPasses)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpdwPasses);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_ApplyStateBlock(LPDIRECT3DDEVICE7 iface,
+                                           DWORD dwBlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_CaptureStateBlock(LPDIRECT3DDEVICE7 iface,
+                                             DWORD dwBlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_DeleteStateBlock(LPDIRECT3DDEVICE7 iface,
+                                            DWORD dwBlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_CreateStateBlock(LPDIRECT3DDEVICE7 iface,
+                                            D3DSTATEBLOCKTYPE d3dsbType,
+                                            LPDWORD lpdwBlockHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, d3dsbType, lpdwBlockHandle);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface,
+                                LPDIRECTDRAWSURFACE7 lpDestTex,
+                                LPPOINT lpDestPoint,
+                                LPDIRECTDRAWSURFACE7 lpSrcTex,
+                                LPRECT lprcSrcRect,
+                                DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%p,%p,%p,%p,%08lx): stub!\n", This, iface, lpDestTex, lpDestPoint, lpSrcTex, lprcSrcRect, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
+                                       DWORD dwLightIndex,
+                                       BOOL bEnable)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%d): stub!\n", This, iface, dwLightIndex, bEnable);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetLightEnable(LPDIRECT3DDEVICE7 iface,
+                                          DWORD dwLightIndex,
+                                          BOOL* pbEnable)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwLightIndex, pbEnable);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface,
+                                        DWORD dwIndex,
+                                        D3DVALUE* pPlaneEquation)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwIndex, pPlaneEquation);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface,
+                                        DWORD dwIndex,
+                                        D3DVALUE* pPlaneEquation)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwIndex, pPlaneEquation);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface,
+                                   DWORD dwDevInfoID,
+                                   LPVOID pDevInfoStruct,
+                                   DWORD dwSize)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
+                                         LPD3DDEVICEDESC lpD3DHWDevDesc,
+                                         LPD3DDEVICEDESC lpD3DHELDevDesc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_GetStats(LPDIRECT3DDEVICE3 iface,
+                                          LPD3DSTATS lpD3DStats)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DStats);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport(LPDIRECT3DDEVICE3 iface,
+					     LPDIRECT3DVIEWPORT3 lpDirect3DViewport3)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
+    
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
+
+    lpDirect3DViewportImpl->next = This->viewport_list;
+    This->viewport_list = lpDirect3DViewportImpl;
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport(LPDIRECT3DDEVICE3 iface,
+						LPDIRECT3DVIEWPORT3 lpDirect3DViewport3)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
+    IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
+  
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
+
+    cur_viewport = This->viewport_list;
+    while (cur_viewport != NULL) {
+        if (cur_viewport == lpDirect3DViewportImpl) {
+	    if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
+	    else prev_viewport->next = cur_viewport->next;
+	    /* TODO : add desactivate of the viewport and all associated lights... */
+	    return DD_OK;
+	}
+	prev_viewport = cur_viewport;
+	cur_viewport = cur_viewport->next;
     }
-    if (cur == NULL)
-	return DDERR_INVALIDOBJECT;
-
-    /* And remove it */
-    if (prev == NULL)
-	This->viewport_list = cur->next;
-    else
-	prev->next = cur->next;
-    return DD_OK;
+    
+    return DDERR_INVALIDPARAMS;
 }
 
-HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp,
-    LPDIRECT3DVIEWPORT2* lplpvp, DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
-    TRACE("(%p)->(%p,%p,%08lx)\n", This, lpvp, lpvp, dwFlags);
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport(LPDIRECT3DDEVICE3 iface,
+					      LPDIRECT3DVIEWPORT3 lpDirect3DViewport3,
+					      LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3,
+					      DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    IDirect3DViewportImpl *res = NULL;
 
+    TRACE("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport3, lplpDirect3DViewport3, dwFlags);
+    
     switch (dwFlags) {
-    case D3DNEXT_NEXT:
-	*ilplpvp = ilpvp->next;
-	break;
-    case D3DNEXT_HEAD:
-	*ilplpvp = This->viewport_list;
-	break;
-    case D3DNEXT_TAIL:
-	ilpvp = This->viewport_list;
-	while (ilpvp->next != NULL)
-	    ilpvp = ilpvp->next;
-	*ilplpvp = ilpvp;
-	break;
-    default:
-	return DDERR_INVALIDPARAMS;
+        case D3DNEXT_NEXT: {
+	    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
+	    res = lpDirect3DViewportImpl->next;
+	} break;
+	case D3DNEXT_HEAD: {
+	    res = This->viewport_list;
+	} break;
+	case D3DNEXT_TAIL: {
+	    IDirect3DViewportImpl *cur_viewport = This->viewport_list;
+	    if (cur_viewport != NULL) {
+	        while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
+	    }
+	    res = cur_viewport;
+	} break;
+	default:
+	    *lplpDirect3DViewport3 = NULL;
+	    return DDERR_INVALIDPARAMS;
     }
+    *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
     return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(
-    LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p,%p), stub!\n", This, cb, context);
-
-    return DD_OK; /* no texture formats in stub implementation */
-}
-
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface,
+						 LPDIRECT3DVIEWPORT3 lpDirect3DViewport3)
 {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-
-    FIXME("(%p)->(), stub!\n", This);
-
-    /* Here, we should get the DDraw surface and 'copy it' to the
-     OpenGL surface.... */
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
-{
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(): stub\n", This);
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    TRACE("(%p)->(%p)\n", This, lpd3d2);
-    *lpd3d2 = (LPDIRECT3D2)This->d3d;
-    return DD_OK;
-}
-
-/*** DrawPrimitive API ***/
-HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    TRACE("(%p)->(%p)\n", This, ilpvp);
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3);
 
     /* Should check if the viewport was added or not */
 
     /* Set this viewport as the current viewport */
-    This->current_viewport = ilpvp;
+    This->current_viewport = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3);
 
     /* Activate this viewport */
-    ilpvp->device.active_device2 = This;
-    ilpvp->activate(ilpvp);
-
+    This->current_viewport->active_device = This;
+    This->current_viewport->activate(This->current_viewport);    
+    
     return DD_OK;
 }
 
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(
-    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 *lplpvp
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lplpvp);
-
-    /* Returns the current viewport */
-    *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(
-    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(
-    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE *lplpdds
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    TRACE("(%p)->(%p)\n", This, lplpdds);
-
-    /* Returns the current rendering target (the surface on wich we render) */
-    *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_Begin(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvert, DWORD numvert, DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_Vertex(
-    LPDIRECT3DDEVICE2 iface,LPVOID lpvert
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lpvert);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface, WORD index) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d): stub\n", This, index);
-
-    return DD_OK;
-}
-
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,DWORD dwFlags) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%08lx): stub\n", This, dwFlags);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(
-    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE d3drs, LPDWORD lprstate
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(
-    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
-    DWORD dwRenderState
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-
-    FIXME("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(
-    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE d3dls, LPDWORD lplstate
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
-
-    return DD_OK;
-}
-
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(
-    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
-    DWORD dwLightState
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%p),stub!\n",This,d3dts,lpmatrix);
-    return DD_OK;
-}
-
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
-
-    return DD_OK;
-}
-
-
-
-HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-
-  FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
-
-  return D3D_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
-    DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
-    return D3D_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(
-    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lpcs);
-
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(
-    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
-) {
-    ICOM_THIS(IDirect3DDevice2Impl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lpcs);
-
-    return DD_OK;
-}
-
-/*******************************************************************************
- *				Direct3DDevice
- */
-HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(
-    LPDIRECT3DDEVICE iface, REFIID riid, LPVOID* ppvObj
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-    return S_OK;
-}
-
-ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface,
+						 LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3)
 {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3DViewport3);
 
-    return ++(This->ref);
+    *lplpDirect3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
+    TRACE(" returning interface %p\n", *lplpDirect3DViewport3);
+    
+    return DD_OK;
 }
 
-ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_Begin(LPDIRECT3DDEVICE3 iface,
+                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                 DWORD dwVertexTypeDesc,
+                                 DWORD dwFlags)
 {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (!--(This->ref)) {
-	/* Release texture associated with the device */ 
-	if (This->current_texture)
-	    IDirect3DTexture2Impl_Release((LPDIRECT3DTEXTURE2)This->current_texture);
-	    
-	HeapFree(GetProcessHeap(),0,This);
-	return 0;
-    }
-    return This->ref;
-}
-
-HRESULT WINAPI IDirect3DDeviceImpl_Initialize(
-    LPDIRECT3DDEVICE iface, LPDIRECT3D lpd3d, LPGUID lpGUID,
-    LPD3DDEVICEDESC lpd3ddvdesc
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
-
-    return DDERR_ALREADYINITIALIZED;
-}
-
-
-HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(
-    LPDIRECT3DDEVICE iface, LPD3DDEVICEDESC lpD3DHWDevDesc,
-    LPD3DDEVICEDESC lpD3DSWDevDesc
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
-
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08x,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexTypeDesc, dwFlags);
     return DD_OK;
 }
 
-
-HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DTEXTURE lpD3DTex1,
-    LPDIRECT3DTEXTURE lpD3DTex2
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    IDirect3DTexture2Impl tmp;
-    TRACE("(%p)->(%p,%p)\n", This, lpD3DTex1, lpD3DTex2);
-
-    tmp = *(IDirect3DTexture2Impl*)lpD3DTex1;
-    *(IDirect3DTexture2Impl*)lpD3DTex1 = *(IDirect3DTexture2Impl*)lpD3DTex2;
-    *(IDirect3DTexture2Impl*)lpD3DTex2 = tmp;
-
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_BeginIndexed(LPDIRECT3DDEVICE3 iface,
+                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                        DWORD d3dvtVertexType,
+                                        LPVOID lpvVertices,
+                                        DWORD dwNumVertices,
+                                        DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
     return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(
-    LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
-    LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p,%p,%p): stub\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_Vertex(LPDIRECT3DDEVICE3 iface,
+                                     LPVOID lpVertexType)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpVertexType);
     return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DDeviceImpl_GetStats(
-    LPDIRECT3DDEVICE iface, LPD3DSTATS lpD3DStats
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lpD3DStats);
-
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_Index(LPDIRECT3DDEVICE3 iface,
+                                    WORD wVertexIndex)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%04x): stub!\n", This, iface, wVertexIndex);
     return DD_OK;
 }
 
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_End(LPDIRECT3DDEVICE3 iface,
+                                  DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwFlags);
+    return DD_OK;
+}
 
-HRESULT WINAPI IDirect3DDeviceImpl_Execute(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%p,%p,%08ld)\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface,
+                                            D3DLIGHTSTATETYPE dwLightStateType,
+                                            LPDWORD lpdwLightState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dwLightStateType, lpdwLightState);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
+                                            D3DLIGHTSTATETYPE dwLightStateType,
+                                            DWORD dwLightState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08x,%08lx): stub!\n", This, iface, dwLightStateType, dwLightState);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB(LPDIRECT3DDEVICE3 iface,
+                                           D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                           LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
+                                           DWORD dwStartVertex,
+                                           DWORD dwNumVertices,
+                                           DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE3 iface,
+                                                  D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                  LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
+                                                  LPWORD lpwIndices,
+                                                  DWORD dwIndexCount,
+                                                  DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08x,%p,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, lpwIndices, dwIndexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_GetTexture(LPDIRECT3DDEVICE3 iface,
+                                      DWORD dwStage,
+                                      LPDIRECT3DTEXTURE2* lplpTexture2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwStage, lplpTexture2);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
+                                      DWORD dwStage,
+                                      LPDIRECT3DTEXTURE2 lpTexture2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwStage, lpTexture2);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
+                                              LPDIRECT3DTEXTURE2 lpD3DTex1,
+                                              LPDIRECT3DTEXTURE2 lpD3DTex2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DTex1, lpD3DTex2);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface,
+                                        LPDIRECT3DVIEWPORT2 lpDirect3DViewport2,
+                                        LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2,
+                                        DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport2, lplpDirect3DViewport2, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
+                                                 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
+                                                 LPVOID lpArg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DEnumTextureProc, lpArg);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_Begin(LPDIRECT3DDEVICE2 iface,
+                                 D3DPRIMITIVETYPE d3dpt,
+                                 D3DVERTEXTYPE dwVertexTypeDesc,
+                                 DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%08x,%08x,%08lx): stub!\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_BeginIndexed(LPDIRECT3DDEVICE2 iface,
+                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                        D3DVERTEXTYPE d3dvtVertexType,
+                                        LPVOID lpvVertices,
+                                        DWORD dwNumVertices,
+                                        DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
+                                         D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                         D3DVERTEXTYPE d3dvtVertexType,
+                                         LPVOID lpvVertices,
+                                         DWORD dwVertexCount,
+                                         DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
+                                                D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                D3DVERTEXTYPE d3dvtVertexType,
+                                                LPVOID lpvVertices,
+                                                DWORD dwVertexCount,
+                                                LPWORD dwIndices,
+                                                DWORD dwIndexCount,
+                                                DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_Initialize(LPDIRECT3DDEVICE iface,
+                                      LPDIRECT3D lpDirect3D,
+                                      LPGUID lpGUID,
+                                      LPD3DDEVICEDESC lpD3DDVDesc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p/%p)->(%p,%p,%p): stub!\n", This, iface, lpDirect3D, lpGUID, lpD3DDVDesc);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_SwapTextureHandles(LPDIRECT3DDEVICE iface,
+                                              LPDIRECT3DTEXTURE lpD3Dtex1,
+                                              LPDIRECT3DTEXTURE lpD3DTex2)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3Dtex1, lpD3DTex2);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
+                                               LPD3DEXECUTEBUFFERDESC lpDesc,
+                                               LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
+                                               IUnknown* pUnkOuter)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p/%p)->(%p,%p,%p): stub!\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_Execute(LPDIRECT3DDEVICE iface,
+                                   LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+                                   LPDIRECT3DVIEWPORT lpDirect3DViewport,
+                                   DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DExecuteBufferImpl *lpDirect3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, lpDirect3DExecuteBuffer);
+    IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport);
+    
+    TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
 
     /* Put this as the default context */
 
     /* Execute... */
-    ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, (IDirect3DViewport*)lpDirect3DViewport);
+    lpDirect3DExecuteBufferImpl->execute(lpDirect3DExecuteBufferImpl, This, lpDirect3DViewportImpl);
 
     return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    TRACE("(%p)->(%p)\n", This, ilpvp);
-
-    /* Adds this viewport to the viewport list */
-    ilpvp->next = This->viewport_list;
-    This->viewport_list = ilpvp;
-
-    return DD_OK;
-}
-
-
-
-HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    IDirect3DViewport2Impl *cur, *prev;
-    TRACE("(%p)->(%p)\n", This, lpvp);
-
-    /* Finds this viewport in the list */
-    prev = NULL;
-    cur = This->viewport_list;
-    while ((cur != NULL) && (cur != ilpvp)) {
-	prev = cur;
-	cur = cur->next;
-    }
-    if (cur == NULL)
-	return DDERR_INVALIDOBJECT;
-
-    /* And remove it */
-    if (prev == NULL)
-	This->viewport_list = cur->next;
-    else
-	prev->next = cur->next;
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp,
-    LPDIRECT3DVIEWPORT* lplpvp, DWORD dwFlags
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-    IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
-    TRACE("(%p)->(%p,%p,%08lx)\n", This, ilpvp, ilplpvp, dwFlags);
-
-    switch (dwFlags) {
-    case D3DNEXT_NEXT:
-	*ilplpvp = ilpvp->next;
-	break;
-    case D3DNEXT_HEAD:
-	*ilplpvp = This->viewport_list;
-	break;
-    case D3DNEXT_TAIL:
-	ilpvp = This->viewport_list;
-	while (ilpvp->next != NULL)
-	    ilpvp = ilpvp->next;
-	*ilplpvp = ilpvp;
-	break;
-    default:
-	return DDERR_INVALIDPARAMS;
-    }
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDeviceImpl_Pick(
-    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags, LPD3DRECT lpRect
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags, lpRect);
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(
-    LPDIRECT3DDEVICE iface, LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
-
-    return DD_OK;
-}
-
-
-HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(
-    LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
-    LPVOID lpArg
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
-    return D3D_OK;
-}
-
-
-HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(
-    LPDIRECT3DDEVICE iface, LPD3DMATRIXHANDLE lpD3DMatHandle
-)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface,
+                                        LPDIRECT3DVIEWPORT lpDirect3DViewport,
+                                        LPDIRECT3DVIEWPORT* lplpDirect3DViewport,
+                                        DWORD dwFlags)
 {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%p)\n", This, lpD3DMatHandle);
-
-    *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
-
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport, lplpDirect3DViewport, dwFlags);
     return DD_OK;
 }
 
-
-HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(
-    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle,
-    const LPD3DMATRIX lpD3DMatrix)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_Pick(LPDIRECT3DDEVICE iface,
+                                LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+                                LPDIRECT3DVIEWPORT lpDirect3DViewport,
+                                DWORD dwFlags,
+                                LPD3DRECT lpRect)
 {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p/%p)->(%p,%p,%08lx,%p): stub!\n", This, iface, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags, lpRect);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_GetPickRecords(LPDIRECT3DDEVICE iface,
+                                          LPDWORD lpCount,
+                                          LPD3DPICKRECORD lpD3DPickRec)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpCount, lpD3DPickRec);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_CreateMatrix(LPDIRECT3DDEVICE iface,
+                                        LPD3DMATRIXHANDLE lpD3DMatHandle)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DMatHandle);
+
+    *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
+    TRACE(" returning matrix handle %p\n", (void *) *lpD3DMatHandle);
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_SetMatrix(LPDIRECT3DDEVICE iface,
+                                     D3DMATRIXHANDLE D3DMatHandle,
+                                     LPD3DMATRIX lpD3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, (DWORD) D3DMatHandle, lpD3DMatrix);
 
     dump_mat(lpD3DMatrix);
-    *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
+    *((D3DMATRIX *) D3DMatHandle) = *lpD3DMatrix;   
+    
     return DD_OK;
 }
 
-
-HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(
-    LPDIRECT3DDEVICE iface,D3DMATRIXHANDLE D3DMatHandle,LPD3DMATRIX lpD3DMatrix
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_GetMatrix(LPDIRECT3DDEVICE iface,
+                                     D3DMATRIXHANDLE D3DMatHandle,
+                                     LPD3DMATRIX lpD3DMatrix)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, (DWORD) D3DMatHandle, lpD3DMatrix);
 
     *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
-
+    
     return DD_OK;
 }
 
-
-HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(
-    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%08lx)\n", This, d3dMatHandle);
-    HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
-    return DD_OK;
-}
-
-
-HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_DeleteMatrix(LPDIRECT3DDEVICE iface,
+                                        D3DMATRIXHANDLE D3DMatHandle)
 {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(): stub\n", This);
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) D3DMatHandle);
+
+    HeapFree(GetProcessHeap(), 0, (void *) D3DMatHandle);
+    
     return DD_OK;
 }
 
-/* This is for the moment copy-pasted from IDirect3DDevice2...
-   Will make a common function ... */
-HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_QueryInterface(LPDIRECT3DDEVICE3 iface,
+                                           REFIID riid,
+                                           LPVOID* obp)
 {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(): stub\n", This);
-    return DD_OK;
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                           riid,
+                                           obp);
 }
 
-HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(
-    LPDIRECT3DDEVICE iface, LPDIRECT3D *lpDirect3D
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    FIXME("(%p)->(%p): stub\n", This, lpDirect3D);
-
-    return DD_OK;
-}
-
-/*******************************************************************************
- *				Direct3DDevice VTable
- */
-static ICOM_VTABLE(IDirect3DDevice) WINE_UNUSED d3d_d3ddevice_vtbl =
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_QueryInterface(LPDIRECT3DDEVICE2 iface,
+                                           REFIID riid,
+                                           LPVOID* obp)
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirect3DDeviceImpl_QueryInterface,
-  IDirect3DDeviceImpl_AddRef,
-  IDirect3DDeviceImpl_Release,
-  IDirect3DDeviceImpl_Initialize,
-  IDirect3DDeviceImpl_GetCaps,
-  IDirect3DDeviceImpl_SwapTextureHandles,
-  IDirect3DDeviceImpl_CreateExecuteBuffer,
-  IDirect3DDeviceImpl_GetStats,
-  IDirect3DDeviceImpl_Execute,
-  IDirect3DDeviceImpl_AddViewport,
-  IDirect3DDeviceImpl_DeleteViewport,
-  IDirect3DDeviceImpl_NextViewport,
-  IDirect3DDeviceImpl_Pick,
-  IDirect3DDeviceImpl_GetPickRecords,
-  IDirect3DDeviceImpl_EnumTextureFormats,
-  IDirect3DDeviceImpl_CreateMatrix,
-  IDirect3DDeviceImpl_SetMatrix,
-  IDirect3DDeviceImpl_GetMatrix,
-  IDirect3DDeviceImpl_DeleteMatrix,
-  IDirect3DDeviceImpl_BeginScene,
-  IDirect3DDeviceImpl_EndScene,
-  IDirect3DDeviceImpl_GetDirect3D,
-};
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                           riid,
+                                           obp);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_QueryInterface(LPDIRECT3DDEVICE iface,
+                                           REFIID riid,
+                                           LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface),
+                                           riid,
+                                           obp);
+}
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_3_AddRef(LPDIRECT3DDEVICE3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_2_AddRef(LPDIRECT3DDEVICE2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_1_AddRef(LPDIRECT3DDEVICE iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_3_Release(LPDIRECT3DDEVICE3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_2_Release(LPDIRECT3DDEVICE2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_1_Release(LPDIRECT3DDEVICE iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_AddViewport(LPDIRECT3DDEVICE2 iface,
+					LPDIRECT3DVIEWPORT2 lpDirect3DViewport2)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2);
+    return IDirect3DDevice3_AddViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+					(LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_AddViewport(LPDIRECT3DDEVICE iface,
+					LPDIRECT3DVIEWPORT lpDirect3DViewport)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport);
+    return IDirect3DDevice3_AddViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
+					(LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_DeleteViewport(LPDIRECT3DDEVICE2 iface,
+					   LPDIRECT3DVIEWPORT2 lpDirect3DViewport2)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2);
+    return IDirect3DDevice3_DeleteViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+					   (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_DeleteViewport(LPDIRECT3DDEVICE iface,
+					   LPDIRECT3DVIEWPORT lpDirect3DViewport)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport);
+    return IDirect3DDevice3_DeleteViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
+					   (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE3 iface,
+					 LPDIRECT3DVIEWPORT2 lpDirect3DViewport2,
+					 LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2,
+					 DWORD dwFlags)
+{
+    TRACE("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2, lplpDirect3DViewport2, dwFlags);
+    return IDirect3DDevice3_NextViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+					 (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */,
+					 (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport2,
+					 dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE3 iface,
+					 LPDIRECT3DVIEWPORT lpDirect3DViewport,
+					 LPDIRECT3DVIEWPORT* lplpDirect3DViewport,
+					 DWORD dwFlags)
+{
+    TRACE("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport, lplpDirect3DViewport, dwFlags);
+    return IDirect3DDevice3_NextViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
+					 (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */,
+					 (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport,
+					 dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetDirect3D(LPDIRECT3DDEVICE3 iface,
+					LPDIRECT3D3* lplpDirect3D3)
+{
+    HRESULT ret;
+    LPDIRECT3D7 ret_ptr;
+  
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D3);
+    ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+				       &ret_ptr);
+    *lplpDirect3D3 = COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D7, IDirect3D3, ret_ptr);
+    TRACE(" returning interface %p\n", *lplpDirect3D3);
+    return ret;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetDirect3D(LPDIRECT3DDEVICE2 iface,
+					LPDIRECT3D2* lplpDirect3D2)
+{
+    HRESULT ret;
+    LPDIRECT3D7 ret_ptr;
+  
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D2);
+    ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+				       &ret_ptr);
+    *lplpDirect3D2 = COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D7, IDirect3D2, ret_ptr);
+    TRACE(" returning interface %p\n", *lplpDirect3D2);
+    return ret;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetDirect3D(LPDIRECT3DDEVICE iface,
+					LPDIRECT3D* lplpDirect3D)
+{
+    HRESULT ret;
+    LPDIRECT3D7 ret_ptr;
+  
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D);
+    ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface),
+				       &ret_ptr);
+    *lplpDirect3D = COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D7, IDirect3D, ret_ptr);
+    TRACE(" returning interface %p\n", *lplpDirect3D);
+    return ret;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
+					       LPDIRECT3DVIEWPORT2 lpDirect3DViewport2)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2);
+    return IDirect3DDevice3_SetCurrentViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+					       (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
+					       LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lplpDirect3DViewport2);
+    return IDirect3DDevice3_GetCurrentViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+					       (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(LPDIRECT3DDEVICE3 iface,
+                                               LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
+                                               LPVOID lpArg)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DEnumPixelProc, lpArg);
+    return IDirect3DDevice7_EnumTextureFormats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                               lpD3DEnumPixelProc,
+                                               lpArg);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_BeginScene(LPDIRECT3DDEVICE3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_BeginScene(LPDIRECT3DDEVICE2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_BeginScene(LPDIRECT3DDEVICE iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_EndScene(LPDIRECT3DDEVICE3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_EndScene(LPDIRECT3DDEVICE2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_EndScene(LPDIRECT3DDEVICE iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
+    return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTransform(LPDIRECT3DDEVICE3 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
+    return IDirect3DDevice7_SetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                         dtstTransformStateType,
+                                         lpD3DMatrix);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetTransform(LPDIRECT3DDEVICE2 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
+    return IDirect3DDevice7_SetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                         dtstTransformStateType,
+                                         lpD3DMatrix);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTransform(LPDIRECT3DDEVICE3 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
+    return IDirect3DDevice7_GetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                         dtstTransformStateType,
+                                         lpD3DMatrix);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetTransform(LPDIRECT3DDEVICE2 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
+    return IDirect3DDevice7_GetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                         dtstTransformStateType,
+                                         lpD3DMatrix);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(LPDIRECT3DDEVICE3 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
+    return IDirect3DDevice7_MultiplyTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                              dtstTransformStateType,
+                                              lpD3DMatrix);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix);
+    return IDirect3DDevice7_MultiplyTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                              dtstTransformStateType,
+                                              lpD3DMatrix);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetRenderState(LPDIRECT3DDEVICE3 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           DWORD dwRenderState)
+{
+    TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, dwRenderState);
+    return IDirect3DDevice7_SetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                           dwRenderStateType,
+                                           dwRenderState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetRenderState(LPDIRECT3DDEVICE2 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           DWORD dwRenderState)
+{
+    TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, dwRenderState);
+    return IDirect3DDevice7_SetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                           dwRenderStateType,
+                                           dwRenderState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetRenderState(LPDIRECT3DDEVICE3 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           LPDWORD lpdwRenderState)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, lpdwRenderState);
+    return IDirect3DDevice7_GetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                           dwRenderStateType,
+                                           lpdwRenderState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetRenderState(LPDIRECT3DDEVICE2 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           LPDWORD lpdwRenderState)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, lpdwRenderState);
+    return IDirect3DDevice7_GetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                           dwRenderStateType,
+                                           lpdwRenderState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(LPDIRECT3DDEVICE3 iface,
+                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                          DWORD d3dvtVertexType,
+                                          LPVOID lpvVertices,
+                                          DWORD dwVertexCount,
+                                          DWORD dwFlags)
+{
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
+    return IDirect3DDevice7_DrawPrimitive(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                          d3dptPrimitiveType,
+                                          d3dvtVertexType,
+                                          lpvVertices,
+                                          dwVertexCount,
+                                          dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(LPDIRECT3DDEVICE3 iface,
+                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                 DWORD d3dvtVertexType,
+                                                 LPVOID lpvVertices,
+                                                 DWORD dwVertexCount,
+                                                 LPWORD dwIndices,
+                                                 DWORD dwIndexCount,
+                                                 DWORD dwFlags)
+{
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
+    return IDirect3DDevice7_DrawIndexedPrimitive(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                                 d3dptPrimitiveType,
+                                                 d3dvtVertexType,
+                                                 lpvVertices,
+                                                 dwVertexCount,
+                                                 dwIndices,
+                                                 dwIndexCount,
+                                                 dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetClipStatus(LPDIRECT3DDEVICE3 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
+    return IDirect3DDevice7_SetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                          lpD3DClipStatus);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetClipStatus(LPDIRECT3DDEVICE2 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
+    return IDirect3DDevice7_SetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                          lpD3DClipStatus);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetClipStatus(LPDIRECT3DDEVICE3 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
+    return IDirect3DDevice7_GetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                          lpD3DClipStatus);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetClipStatus(LPDIRECT3DDEVICE2 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus);
+    return IDirect3DDevice7_GetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                          lpD3DClipStatus);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
+                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                 DWORD dwVertexType,
+                                                 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                 DWORD dwVertexCount,
+                                                 DWORD dwFlags)
+{
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
+    return IDirect3DDevice7_DrawPrimitiveStrided(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                                 d3dptPrimitiveType,
+                                                 dwVertexType,
+                                                 lpD3DDrawPrimStrideData,
+                                                 dwVertexCount,
+                                                 dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
+                                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                        DWORD dwVertexType,
+                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                        DWORD dwVertexCount,
+                                                        LPWORD lpIndex,
+                                                        DWORD dwIndexCount,
+                                                        DWORD dwFlags)
+{
+    TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
+    return IDirect3DDevice7_DrawIndexedPrimitiveStrided(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                                        d3dptPrimitiveType,
+                                                        dwVertexType,
+                                                        lpD3DDrawPrimStrideData,
+                                                        dwVertexCount,
+                                                        lpIndex,
+                                                        dwIndexCount,
+                                                        dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(LPDIRECT3DDEVICE3 iface,
+                                                    LPD3DVECTOR lpCenters,
+                                                    LPD3DVALUE lpRadii,
+                                                    DWORD dwNumSpheres,
+                                                    DWORD dwFlags,
+                                                    LPDWORD lpdwReturnValues)
+{
+    TRACE("(%p)->(%p,%p,%08lx,%08lx,%p) thunking to IDirect3DDevice7 interface.\n", iface, lpCenters, lpRadii, dwNumSpheres, dwFlags, lpdwReturnValues);
+    return IDirect3DDevice7_ComputeSphereVisibility(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                                    lpCenters,
+                                                    lpRadii,
+                                                    dwNumSpheres,
+                                                    dwFlags,
+                                                    lpdwReturnValues);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(LPDIRECT3DDEVICE3 iface,
+                                                 DWORD dwStage,
+                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                 LPDWORD lpdwState)
+{
+    TRACE("(%p)->(%08lx,%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, d3dTexStageStateType, lpdwState);
+    return IDirect3DDevice7_GetTextureStageState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                                 dwStage,
+                                                 d3dTexStageStateType,
+                                                 lpdwState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(LPDIRECT3DDEVICE3 iface,
+                                                 DWORD dwStage,
+                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                 DWORD dwState)
+{
+    TRACE("(%p)->(%08lx,%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, d3dTexStageStateType, dwState);
+    return IDirect3DDevice7_SetTextureStageState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                                 dwStage,
+                                                 d3dTexStageStateType,
+                                                 dwState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_ValidateDevice(LPDIRECT3DDEVICE3 iface,
+                                           LPDWORD lpdwPasses)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpdwPasses);
+    return IDirect3DDevice7_ValidateDevice(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                           lpdwPasses);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetCaps(LPDIRECT3DDEVICE2 iface,
+                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
+                                    LPD3DDEVICEDESC lpD3DHELDevDesc)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
+    return IDirect3DDevice3_GetCaps(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                    lpD3DHWDevDesc,
+                                    lpD3DHELDevDesc);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetCaps(LPDIRECT3DDEVICE iface,
+                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
+                                    LPD3DDEVICEDESC lpD3DHELDevDesc)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
+    return IDirect3DDevice3_GetCaps(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
+                                    lpD3DHWDevDesc,
+                                    lpD3DHELDevDesc);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetStats(LPDIRECT3DDEVICE2 iface,
+                                     LPD3DSTATS lpD3DStats)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DStats);
+    return IDirect3DDevice3_GetStats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                     lpD3DStats);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetStats(LPDIRECT3DDEVICE iface,
+                                     LPD3DSTATS lpD3DStats)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DStats);
+    return IDirect3DDevice3_GetStats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface),
+                                     lpD3DStats);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(LPDIRECT3DDEVICE3 iface,
+                                            LPDIRECTDRAWSURFACE4 lpNewRenderTarget,
+                                            DWORD dwFlags)
+{
+    TRACE("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, lpNewRenderTarget, dwFlags);
+    return IDirect3DDevice7_SetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                            (LPDIRECTDRAWSURFACE7) lpNewRenderTarget /* No cast needed as DSurf4 == DSurf7 */,
+                                            dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(LPDIRECT3DDEVICE3 iface,
+                                            LPDIRECTDRAWSURFACE4* lplpRenderTarget)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpRenderTarget);
+    return IDirect3DDevice7_GetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface),
+                                            (LPDIRECTDRAWSURFACE7*) lplpRenderTarget /* No cast needed as DSurf4 == DSurf7 */);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
+                                            LPDIRECTDRAWSURFACE lpNewRenderTarget,
+                                            DWORD dwFlags)
+{
+    TRACE("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, lpNewRenderTarget, dwFlags);
+    return IDirect3DDevice7_SetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+                                            COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface3, IDirectDrawSurface7, lpNewRenderTarget),
+                                            dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
+                                            LPDIRECTDRAWSURFACE* lplpRenderTarget)
+{
+    HRESULT ret;
+    LPDIRECTDRAWSURFACE7 ret_val;
+  
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpRenderTarget);
+    ret = IDirect3DDevice7_GetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface),
+					   &ret_val);
+    *lplpRenderTarget = (LPDIRECTDRAWSURFACE) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, ret_val);
+    TRACE(" returning interface %p\n", *lplpRenderTarget);
+    return ret;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Vertex(LPDIRECT3DDEVICE2 iface,
+                                   LPVOID lpVertexType)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpVertexType);
+    return IDirect3DDevice3_Vertex(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                   lpVertexType);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Index(LPDIRECT3DDEVICE2 iface,
+                                  WORD wVertexIndex)
+{
+    TRACE("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", iface, wVertexIndex);
+    return IDirect3DDevice3_Index(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                  wVertexIndex);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_End(LPDIRECT3DDEVICE2 iface,
+                                DWORD dwFlags)
+{
+    TRACE("(%p)->(%08lx) thunking to IDirect3DDevice3 interface.\n", iface, dwFlags);
+    return IDirect3DDevice3_End(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                dwFlags);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetLightState(LPDIRECT3DDEVICE2 iface,
+                                          D3DLIGHTSTATETYPE dwLightStateType,
+                                          LPDWORD lpdwLightState)
+{
+    TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", iface, dwLightStateType, lpdwLightState);
+    return IDirect3DDevice3_GetLightState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                          dwLightStateType,
+                                          lpdwLightState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetLightState(LPDIRECT3DDEVICE2 iface,
+                                          D3DLIGHTSTATETYPE dwLightStateType,
+                                          DWORD dwLightState)
+{
+    TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, dwLightStateType, dwLightState);
+    return IDirect3DDevice3_SetLightState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface),
+                                          dwLightStateType,
+                                          dwLightState);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(LPDIRECT3DDEVICE iface,
+                                               LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
+                                               LPVOID lpArg)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", iface, lpD3DEnumTextureProc, lpArg);
+    return IDirect3DDevice2_EnumTextureFormats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, iface),
+                                               lpD3DEnumTextureProc,
+                                               lpArg);
+}
diff --git a/dlls/ddraw/d3ddevice/main.h b/dlls/ddraw/d3ddevice/main.h
new file mode 100644
index 0000000..3ce3f66
--- /dev/null
+++ b/dlls/ddraw/d3ddevice/main.h
@@ -0,0 +1,759 @@
+/*
+ * Copyright 2002 Lionel Ulmer
+ *
+ * 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
+ */
+
+#include "config.h"
+
+/* This is defined here so as to be able to put them in 'drivers' */
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3DDEVICE7 iface,
+                                                   REFIID riid,
+                                                   LPVOID* obp);
+
+ULONG WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef(LPDIRECT3DDEVICE7 iface);
+
+ULONG WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
+                                   LPD3DDEVICEDESC7 lpD3DHELDevDesc);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
+                                                 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
+                                                 LPVOID lpArg);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene(LPDIRECT3DDEVICE7 iface);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene(LPDIRECT3DDEVICE7 iface);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D(LPDIRECT3DDEVICE7 iface,
+						LPDIRECT3D7* lplpDirect3D3);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget(LPDIRECT3DDEVICE7 iface,
+						 LPDIRECTDRAWSURFACE7 lpNewRenderTarget,
+						 DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget(LPDIRECT3DDEVICE7 iface,
+						 LPDIRECTDRAWSURFACE7* lplpRenderTarget);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_Clear(LPDIRECT3DDEVICE7 iface,
+                                 DWORD dwCount,
+                                 LPD3DRECT lpRects,
+                                 DWORD dwFlags,
+                                 D3DCOLOR dwColor,
+                                 D3DVALUE dvZ,
+                                 DWORD dwStencil);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform(LPDIRECT3DDEVICE7 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DVIEWPORT7 lpData);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform(LPDIRECT3DDEVICE7 iface,
+                                                   D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                                   LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetViewport(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DVIEWPORT7 lpData);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DMATERIAL7 lpMat);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetMaterial(LPDIRECT3DDEVICE7 iface,
+                                       LPD3DMATERIAL7 lpMat);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
+                                    DWORD dwLightIndex,
+                                    LPD3DLIGHT7 lpLight);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetLight(LPDIRECT3DDEVICE7 iface,
+                                    DWORD dwLightIndex,
+                                    LPD3DLIGHT7 lpLight);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
+                                                D3DRENDERSTATETYPE dwRenderStateType,
+                                                DWORD dwRenderState);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
+                                                D3DRENDERSTATETYPE dwRenderStateType,
+                                                LPDWORD lpdwRenderState);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_BeginStateBlock(LPDIRECT3DDEVICE7 iface);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_EndStateBlock(LPDIRECT3DDEVICE7 iface,
+                                         LPDWORD lpdwBlockHandle);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_PreLoad(LPDIRECT3DDEVICE7 iface,
+                                   LPDIRECTDRAWSURFACE7 lpddsTexture);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
+                                            D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                            DWORD d3dvtVertexType,
+                                            LPVOID lpvVertices,
+                                            DWORD dwVertexCount,
+                                            DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
+                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                   DWORD d3dvtVertexType,
+                                                   LPVOID lpvVertices,
+                                                   DWORD dwVertexCount,
+                                                   LPWORD dwIndices,
+                                                   DWORD dwIndexCount,
+                                                   DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus(LPDIRECT3DDEVICE7 iface,
+                                               LPD3DCLIPSTATUS lpD3DClipStatus);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus(LPDIRECT3DDEVICE7 iface,
+                                               LPD3DCLIPSTATUS lpD3DClipStatus);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
+                                                   D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                   DWORD dwVertexType,
+                                                   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                   DWORD dwVertexCount,
+                                                   DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
+                                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                          DWORD dwVertexType,
+                                                          LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                          DWORD dwVertexCount,
+                                                          LPWORD lpIndex,
+                                                          DWORD dwIndexCount,
+                                                          DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
+                                           D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                           LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
+                                           DWORD dwStartVertex,
+                                           DWORD dwNumVertices,
+                                           DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
+                                                  D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                  LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
+                                                  DWORD dwStartVertex,
+                                                  DWORD dwNumVertices,
+                                                  LPWORD lpwIndices,
+                                                  DWORD dwIndexCount,
+                                                  DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility(LPDIRECT3DDEVICE7 iface,
+                                                      LPD3DVECTOR lpCenters,
+                                                      LPD3DVALUE lpRadii,
+                                                      DWORD dwNumSpheres,
+                                                      DWORD dwFlags,
+                                                      LPDWORD lpdwReturnValues);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetTexture(LPDIRECT3DDEVICE7 iface,
+                                      DWORD dwStage,
+                                      LPDIRECTDRAWSURFACE7* lpTexture);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetTexture(LPDIRECT3DDEVICE7 iface,
+                                      DWORD dwStage,
+                                      LPDIRECTDRAWSURFACE7 lpTexture);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState(LPDIRECT3DDEVICE7 iface,
+                                                   DWORD dwStage,
+                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                   LPDWORD lpdwState);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
+                                                   DWORD dwStage,
+                                                   D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                   DWORD dwState);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_3T_ValidateDevice(LPDIRECT3DDEVICE7 iface,
+                                             LPDWORD lpdwPasses);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_ApplyStateBlock(LPDIRECT3DDEVICE7 iface,
+                                           DWORD dwBlockHandle);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_CaptureStateBlock(LPDIRECT3DDEVICE7 iface,
+                                             DWORD dwBlockHandle);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_DeleteStateBlock(LPDIRECT3DDEVICE7 iface,
+                                            DWORD dwBlockHandle);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_CreateStateBlock(LPDIRECT3DDEVICE7 iface,
+                                            D3DSTATEBLOCKTYPE d3dsbType,
+                                            LPDWORD lpdwBlockHandle);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface,
+                                LPDIRECTDRAWSURFACE7 lpDestTex,
+                                LPPOINT lpDestPoint,
+                                LPDIRECTDRAWSURFACE7 lpSrcTex,
+                                LPRECT lprcSrcRect,
+                                DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
+                                       DWORD dwLightIndex,
+                                       BOOL bEnable);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetLightEnable(LPDIRECT3DDEVICE7 iface,
+                                          DWORD dwLightIndex,
+                                          BOOL* pbEnable);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface,
+                                        DWORD dwIndex,
+                                        D3DVALUE* pPlaneEquation);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface,
+                                        DWORD dwIndex,
+                                        D3DVALUE* pPlaneEquation);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface,
+                                   DWORD dwDevInfoID,
+                                   LPVOID pDevInfoStruct,
+                                   DWORD dwSize);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
+                                         LPD3DDEVICEDESC lpD3DHWDevDesc,
+                                         LPD3DDEVICEDESC lpD3DHELDevDesc);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_GetStats(LPDIRECT3DDEVICE3 iface,
+                                          LPD3DSTATS lpD3DStats);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport(LPDIRECT3DDEVICE3 iface,
+					     LPDIRECT3DVIEWPORT3 lpDirect3DViewport3);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport(LPDIRECT3DDEVICE3 iface,
+						LPDIRECT3DVIEWPORT3 lpDirect3DViewport3);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport(LPDIRECT3DDEVICE3 iface,
+					      LPDIRECT3DVIEWPORT3 lpDirect3DViewport3,
+					      LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3,
+					      DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface,
+						 LPDIRECT3DVIEWPORT3 lpDirect3DViewport3);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface,
+						 LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_Begin(LPDIRECT3DDEVICE3 iface,
+                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                 DWORD dwVertexTypeDesc,
+                                 DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_BeginIndexed(LPDIRECT3DDEVICE3 iface,
+                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                        DWORD d3dvtVertexType,
+                                        LPVOID lpvVertices,
+                                        DWORD dwNumVertices,
+                                        DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_Vertex(LPDIRECT3DDEVICE3 iface,
+                                     LPVOID lpVertexType);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_Index(LPDIRECT3DDEVICE3 iface,
+                                    WORD wVertexIndex);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_End(LPDIRECT3DDEVICE3 iface,
+                                  DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface,
+                                            D3DLIGHTSTATETYPE dwLightStateType,
+                                            LPDWORD lpdwLightState);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
+                                            D3DLIGHTSTATETYPE dwLightStateType,
+                                            DWORD dwLightState);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB(LPDIRECT3DDEVICE3 iface,
+                                           D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                           LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
+                                           DWORD dwStartVertex,
+                                           DWORD dwNumVertices,
+                                           DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE3 iface,
+                                                  D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                  LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,
+                                                  LPWORD lpwIndices,
+                                                  DWORD dwIndexCount,
+                                                  DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_GetTexture(LPDIRECT3DDEVICE3 iface,
+                                      DWORD dwStage,
+                                      LPDIRECT3DTEXTURE2* lplpTexture2);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
+                                      DWORD dwStage,
+                                      LPDIRECT3DTEXTURE2 lpTexture2);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
+                                              LPDIRECT3DTEXTURE2 lpD3DTex1,
+                                              LPDIRECT3DTEXTURE2 lpD3DTex2);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
+                                                 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
+                                                 LPVOID lpArg);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_Begin(LPDIRECT3DDEVICE2 iface,
+                                 D3DPRIMITIVETYPE d3dpt,
+                                 D3DVERTEXTYPE dwVertexTypeDesc,
+                                 DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_BeginIndexed(LPDIRECT3DDEVICE2 iface,
+                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                        D3DVERTEXTYPE d3dvtVertexType,
+                                        LPVOID lpvVertices,
+                                        DWORD dwNumVertices,
+                                        DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
+                                         D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                         D3DVERTEXTYPE d3dvtVertexType,
+                                         LPVOID lpvVertices,
+                                         DWORD dwVertexCount,
+                                         DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
+                                                D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                D3DVERTEXTYPE d3dvtVertexType,
+                                                LPVOID lpvVertices,
+                                                DWORD dwVertexCount,
+                                                LPWORD dwIndices,
+                                                DWORD dwIndexCount,
+                                                DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_Initialize(LPDIRECT3DDEVICE iface,
+                                      LPDIRECT3D lpDirect3D,
+                                      LPGUID lpGUID,
+                                      LPD3DDEVICEDESC lpD3DDVDesc);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_SwapTextureHandles(LPDIRECT3DDEVICE iface,
+                                              LPDIRECT3DTEXTURE lpD3Dtex1,
+                                              LPDIRECT3DTEXTURE lpD3DTex2);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
+                                               LPD3DEXECUTEBUFFERDESC lpDesc,
+                                               LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
+                                               IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_Execute(LPDIRECT3DDEVICE iface,
+                                   LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+                                   LPDIRECT3DVIEWPORT lpDirect3DViewport,
+                                   DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_Pick(LPDIRECT3DDEVICE iface,
+                                LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+                                LPDIRECT3DVIEWPORT lpDirect3DViewport,
+                                DWORD dwFlags,
+                                LPD3DRECT lpRect);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_GetPickRecords(LPDIRECT3DDEVICE iface,
+                                          LPDWORD lpCount,
+                                          LPD3DPICKRECORD lpD3DPickRec);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_CreateMatrix(LPDIRECT3DDEVICE iface,
+                                        LPD3DMATRIXHANDLE lpD3DMatHandle);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_SetMatrix(LPDIRECT3DDEVICE iface,
+                                     D3DMATRIXHANDLE D3DMatHandle,
+                                     LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_GetMatrix(LPDIRECT3DDEVICE iface,
+                                     D3DMATRIXHANDLE D3DMatHandle,
+                                     LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Main_IDirect3DDeviceImpl_1_DeleteMatrix(LPDIRECT3DDEVICE iface,
+                                        D3DMATRIXHANDLE D3DMatHandle);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_QueryInterface(LPDIRECT3DDEVICE3 iface,
+                                           REFIID riid,
+                                           LPVOID* obp);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_QueryInterface(LPDIRECT3DDEVICE2 iface,
+                                           REFIID riid,
+                                           LPVOID* obp);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_QueryInterface(LPDIRECT3DDEVICE iface,
+                                           REFIID riid,
+                                           LPVOID* obp);
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_3_AddRef(LPDIRECT3DDEVICE3 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_2_AddRef(LPDIRECT3DDEVICE2 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_1_AddRef(LPDIRECT3DDEVICE iface);
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_3_Release(LPDIRECT3DDEVICE3 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_2_Release(LPDIRECT3DDEVICE2 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DDeviceImpl_1_Release(LPDIRECT3DDEVICE iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_AddViewport(LPDIRECT3DDEVICE2 iface,
+					LPDIRECT3DVIEWPORT2 lpDirect3DViewport2);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_AddViewport(LPDIRECT3DDEVICE iface,
+					LPDIRECT3DVIEWPORT lpDirect3DViewport);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_DeleteViewport(LPDIRECT3DDEVICE2 iface,
+					   LPDIRECT3DVIEWPORT2 lpDirect3DViewport2);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_DeleteViewport(LPDIRECT3DDEVICE iface,
+					   LPDIRECT3DVIEWPORT lpDirect3DViewport);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE3 iface,
+					 LPDIRECT3DVIEWPORT2 lpDirect3DViewport2,
+					 LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2,
+					 DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE3 iface,
+					 LPDIRECT3DVIEWPORT lpDirect3DViewport,
+					 LPDIRECT3DVIEWPORT* lplpDirect3DViewport,
+					 DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetDirect3D(LPDIRECT3DDEVICE3 iface,
+					LPDIRECT3D3* lplpDirect3D3);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetDirect3D(LPDIRECT3DDEVICE2 iface,
+					LPDIRECT3D2* lplpDirect3D2);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetDirect3D(LPDIRECT3DDEVICE iface,
+					LPDIRECT3D* lplpDirect3D);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
+					       LPDIRECT3DVIEWPORT2 lpDirect3DViewport2);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
+					       LPDIRECT3DVIEWPORT2* lpDirect3DViewport2);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(LPDIRECT3DDEVICE3 iface,
+                                               LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
+                                               LPVOID lpArg);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_BeginScene(LPDIRECT3DDEVICE3 iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_BeginScene(LPDIRECT3DDEVICE2 iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_BeginScene(LPDIRECT3DDEVICE iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_EndScene(LPDIRECT3DDEVICE3 iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_EndScene(LPDIRECT3DDEVICE2 iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_EndScene(LPDIRECT3DDEVICE iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTransform(LPDIRECT3DDEVICE3 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetTransform(LPDIRECT3DDEVICE2 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTransform(LPDIRECT3DDEVICE3 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetTransform(LPDIRECT3DDEVICE2 iface,
+                                         D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                         LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(LPDIRECT3DDEVICE3 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
+                                              D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                              LPD3DMATRIX lpD3DMatrix);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetRenderState(LPDIRECT3DDEVICE3 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           DWORD dwRenderState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetRenderState(LPDIRECT3DDEVICE2 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           DWORD dwRenderState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetRenderState(LPDIRECT3DDEVICE3 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           LPDWORD lpdwRenderState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetRenderState(LPDIRECT3DDEVICE2 iface,
+                                           D3DRENDERSTATETYPE dwRenderStateType,
+                                           LPDWORD lpdwRenderState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(LPDIRECT3DDEVICE3 iface,
+                                          D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                          DWORD d3dvtVertexType,
+                                          LPVOID lpvVertices,
+                                          DWORD dwVertexCount,
+                                          DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(LPDIRECT3DDEVICE3 iface,
+                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                 DWORD d3dvtVertexType,
+                                                 LPVOID lpvVertices,
+                                                 DWORD dwVertexCount,
+                                                 LPWORD dwIndices,
+                                                 DWORD dwIndexCount,
+                                                 DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetClipStatus(LPDIRECT3DDEVICE3 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetClipStatus(LPDIRECT3DDEVICE2 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetClipStatus(LPDIRECT3DDEVICE3 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetClipStatus(LPDIRECT3DDEVICE2 iface,
+                                          LPD3DCLIPSTATUS lpD3DClipStatus);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
+                                                 D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                 DWORD dwVertexType,
+                                                 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                 DWORD dwVertexCount,
+                                                 DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE3 iface,
+                                                        D3DPRIMITIVETYPE d3dptPrimitiveType,
+                                                        DWORD dwVertexType,
+                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+                                                        DWORD dwVertexCount,
+                                                        LPWORD lpIndex,
+                                                        DWORD dwIndexCount,
+                                                        DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(LPDIRECT3DDEVICE3 iface,
+                                                    LPD3DVECTOR lpCenters,
+                                                    LPD3DVALUE lpRadii,
+                                                    DWORD dwNumSpheres,
+                                                    DWORD dwFlags,
+                                                    LPDWORD lpdwReturnValues);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(LPDIRECT3DDEVICE3 iface,
+                                                 DWORD dwStage,
+                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                 LPDWORD lpdwState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(LPDIRECT3DDEVICE3 iface,
+                                                 DWORD dwStage,
+                                                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
+                                                 DWORD dwState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_ValidateDevice(LPDIRECT3DDEVICE3 iface,
+                                           LPDWORD lpdwPasses);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetCaps(LPDIRECT3DDEVICE2 iface,
+                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
+                                    LPD3DDEVICEDESC lpD3DHELDevDesc);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetCaps(LPDIRECT3DDEVICE iface,
+                                    LPD3DDEVICEDESC lpD3DHWDevDesc,
+                                    LPD3DDEVICEDESC lpD3DHELDevDesc);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetStats(LPDIRECT3DDEVICE2 iface,
+                                     LPD3DSTATS lpD3DStats);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_GetStats(LPDIRECT3DDEVICE iface,
+                                     LPD3DSTATS lpD3DStats);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(LPDIRECT3DDEVICE3 iface,
+                                            LPDIRECTDRAWSURFACE4 lpNewRenderTarget,
+                                            DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(LPDIRECT3DDEVICE3 iface,
+                                            LPDIRECTDRAWSURFACE4* lplpRenderTarget);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
+                                            LPDIRECTDRAWSURFACE lpNewRenderTarget,
+                                            DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
+                                            LPDIRECTDRAWSURFACE* lplpRenderTarget);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Vertex(LPDIRECT3DDEVICE2 iface,
+                                   LPVOID lpVertexType);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_Index(LPDIRECT3DDEVICE2 iface,
+                                  WORD wVertexIndex);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_End(LPDIRECT3DDEVICE2 iface,
+                                DWORD dwFlags);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_GetLightState(LPDIRECT3DDEVICE2 iface,
+                                          D3DLIGHTSTATETYPE dwLightStateType,
+                                          LPDWORD lpdwLightState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_2_SetLightState(LPDIRECT3DDEVICE2 iface,
+                                          D3DLIGHTSTATETYPE dwLightStateType,
+                                          DWORD dwLightState);
+
+HRESULT WINAPI
+Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(LPDIRECT3DDEVICE iface,
+                                               LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
+                                               LPVOID lpArg);
diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c
index f5205ad..0395cd3 100644
--- a/dlls/ddraw/d3ddevice/mesa.c
+++ b/dlls/ddraw/d3ddevice/mesa.c
@@ -31,13 +31,47 @@
 #include "wine/debug.h"
 
 #include "mesa_private.h"
+#include "main.h"
 
 #include "x11drv.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable;
-ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3;
+/* They are non-static as they are used by Direct3D in the creation function */
+const GUID IID_D3DDEVICE_OpenGL = {
+  0x31416d44,
+  0x86ae,
+  0x11d2,
+  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
+};
+
+const GUID IID_D3DDEVICE2_OpenGL = {
+  0x31416d44,
+  0x86ae,
+  0x11d2,
+  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfb }
+};
+
+const GUID IID_D3DDEVICE3_OpenGL = {
+  0x31416d44,
+  0x86ae,
+  0x11d2,
+  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfc }
+};
+
+const GUID IID_D3DDEVICE7_OpenGL = {
+  0x31416d44,
+  0x86ae,
+  0x11d2,
+  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfd }
+};
+
+const GUID IID_D3DDEVICE_Default = {
+  0x00000000,
+  0x0000,
+  0x0000,
+  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
+};
 
 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
    on Mesa's home page) or version 3.1b.
@@ -45,8 +79,6 @@
    Version 3.1b2 should correct this bug */
 #undef HAVE_BUGGY_MESAGL
 
-#define D3DDPRIVATE(x) mesa_d3dd_private *odev=((mesa_d3dd_private*)x->private)
-
 #ifndef HAVE_GLEXT_PROTOTYPES
 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
@@ -55,10 +87,10 @@
 #endif
 
 static const float id_mat[16] = {
-  1.0, 0.0, 0.0, 0.0,
-  0.0, 1.0, 0.0, 0.0,
-  0.0, 0.0, 1.0, 0.0,
-  0.0, 0.0, 0.0, 1.0
+    1.0, 0.0, 0.0, 0.0,
+    0.0, 1.0, 0.0, 0.0,
+    0.0, 0.0, 1.0, 0.0,
+    0.0, 0.0, 0.0, 1.0
 };
 
 /* retrieve the X display to use on a given DC */
@@ -100,15 +132,8 @@
 /*******************************************************************************
  *				OpenGL static functions
  */
-static void set_context(IDirect3DDevice2Impl* This) {
-#if COMPILABLE
-    D3DDPRIVATE(This);
-
-    if (glXMakeCurrent(gdi_display,ddpriv->drawable, odev->ctx) == False) {
-	ERR("Error in setting current context (context %p drawable %ld)!\n",
-	    odev->ctx, ddpriv->drawable);
-    }
-#endif
+static void set_context(IDirect3DDeviceImpl* This) {
+#if 0
     D3DDPRIVATE(This);
 
     ENTER_GL();
@@ -118,939 +143,956 @@
 	    odev->ctx, odev->drawable);
     }
     LEAVE_GL();
+#else
+    ERR("This function should not be called in the current state of the code...\n");
+#endif
 }
 
 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
 {
-  pc->dwSize = sizeof(*pc);
-  pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
-    D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
-  pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
-    D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
-  pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
-  pc->dwSrcBlendCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwAlphaCmpCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwShadeCaps = 0xFFFFFFFF;     /* FIXME: need REAL values */
-  pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
-    D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
-  pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
-    D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
-  pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
-  pc->dwStippleWidth = 32;
-  pc->dwStippleHeight = 32;
+    pc->dwSize = sizeof(*pc);
+    pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
+      D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
+    pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
+      D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
+    pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
+    pc->dwSrcBlendCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
+    pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
+    pc->dwAlphaCmpCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
+    pc->dwShadeCaps = 0xFFFFFFFF;     /* FIXME: need REAL values */
+    pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
+      D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
+    pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
+      D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
+    pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
+    pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
+    pc->dwStippleWidth = 32;
+    pc->dwStippleHeight = 32;
 }
 
-static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
+static void fill_opengl_caps(D3DDEVICEDESC *d1)
 {
-  /* GLint maxlight; */
+    /* GLint maxlight; */
 
-  d1->dwSize  = sizeof(*d1);
-  d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
-    | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
-  d1->dcmColorModel = D3DCOLOR_RGB;
-  d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
-    D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
+    d1->dwSize  = sizeof(*d1);
+    d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
+      | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
+    d1->dcmColorModel = D3DCOLOR_RGB;
+    d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
+      D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
       D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
-  d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
-  d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
-  d1->bClipping = TRUE;
-  d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
-  d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
-  d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
-  d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
-  fill_opengl_primcaps(&(d1->dpcLineCaps));
-  fill_opengl_primcaps(&(d1->dpcTriCaps));
-  d1->dwDeviceRenderBitDepth  = DDBD_16;
-  d1->dwDeviceZBufferBitDepth = DDBD_16;
-  d1->dwMaxBufferSize = 0;
-  d1->dwMaxVertexCount = 65536;
-  d1->dwMinTextureWidth  = 1;
-  d1->dwMinTextureHeight = 1;
-  d1->dwMaxTextureWidth  = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
-  d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
-  d1->dwMinStippleWidth  = 1;
-  d1->dwMinStippleHeight = 1;
-  d1->dwMaxStippleWidth  = 32;
-  d1->dwMaxStippleHeight = 32;
-
-  d2->dwSize  = sizeof(*d2);
-  d2->dwFlags = 0;
+    d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
+    d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
+    d1->bClipping = TRUE;
+    d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
+    d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
+    d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
+    d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
+    fill_opengl_primcaps(&(d1->dpcLineCaps));
+    fill_opengl_primcaps(&(d1->dpcTriCaps));
+    d1->dwDeviceRenderBitDepth  = DDBD_16;
+    d1->dwDeviceZBufferBitDepth = DDBD_16;
+    d1->dwMaxBufferSize = 0;
+    d1->dwMaxVertexCount = 65536;
+    d1->dwMinTextureWidth  = 1;
+    d1->dwMinTextureHeight = 1;
+    d1->dwMaxTextureWidth  = 1024;
+    d1->dwMaxTextureHeight = 1024;
+    d1->dwMinStippleWidth  = 1;
+    d1->dwMinStippleHeight = 1;
+    d1->dwMaxStippleWidth  = 32;
+    d1->dwMaxStippleHeight = 32;
 }
 
-static void fill_device_capabilities(IDirectDrawImpl* ddraw) {
-#if COMPILABLE
-  x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
-  const char *ext_string;
-  Mesa_DeviceCapabilities *devcap;
+static void fill_device_capabilities(IDirectDrawImpl* ddraw)
+{
+#if 0 /* TODO : fix this... */
+    x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
+    const char *ext_string;
+    Mesa_DeviceCapabilities *devcap;
 
-  private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
-  devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
+    private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
+    devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
 
-  ENTER_GL();
-  ext_string = glGetString(GL_EXTENSIONS);
-  /* Query for the ColorTable Extension */
-  if (strstr(ext_string, "GL_EXT_paletted_texture")) {
-    devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
-    TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
-  } else {
-    TRACE("Color table extension not found.\n");
-  }
-  LEAVE_GL();
+    ENTER_GL();
+    ext_string = glGetString(GL_EXTENSIONS);
+    /* Query for the ColorTable Extension */
+    if (strstr(ext_string, "GL_EXT_paletted_texture")) {
+        devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
+	TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
+    } else {
+        TRACE("Color table extension not found.\n");
+    }
+    LEAVE_GL();
 #endif
 }
 
-int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
-  D3DDEVICEDESC	d1,d2;
-  TRACE(" Enumerating OpenGL D3D2 device (IID %s).\n", debugstr_guid(&IID_D3DDEVICE2_OpenGL));
-  fill_opengl_caps(&d1, &d2);
-  return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D2 using OpenGL","direct3d",&d1,&d2,context);
-}
 
-int
-is_OpenGL(
-    REFCLSID rguid, IDirectDrawSurfaceImpl* surface,
-    IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d
-) {
-  mesa_d3dd_private *odev = NULL;
-  HDC device_context;
-  XVisualInfo *vis;
-  int num;
-  XVisualInfo template;
-  IDirectDrawSurfaceImpl* surf;
 
-  TRACE("rguid = %s, surface = %p, &device = %p, d3d = %p\n",debugstr_guid(rguid),surface,device,d3d);
-  if (/* Default device */
-      (rguid == NULL) ||
-      /* HAL Device */
-      (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
-      /* OpenGL Device */
-      (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
-
-    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DDevice2Impl));
-    (*device)->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dd_private));
-    odev = (mesa_d3dd_private*)(*device)->private;
-    (*device)->ref = 1;
-    ICOM_VTBL(*device) = &OpenGL_vtable;
-    (*device)->d3d = d3d;
-    (*device)->surface = surface;
-    (*device)->viewport_list = NULL;
-    (*device)->current_viewport = NULL;
-    (*device)->current_texture = NULL;
-    (*device)->set_context = set_context;
-
-    TRACE("Creating OpenGL device for surface %p\n", surface);
-    /* Create the OpenGL context */
-    /* First get the correct visual */
-    /* Create the context */
-      
-    device_context = GetDC((*device)->surface->ddraw_owner->window);
-    odev->gdi_display = get_display(device_context);
-    odev->drawable = get_drawable(device_context);
-    ReleaseDC((*device)->surface->ddraw_owner->window,device_context);
-    ENTER_GL();
-
-    template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
-    vis = XGetVisualInfo(odev->gdi_display, VisualIDMask, &template, &num);
-    if (vis == NULL)
-      ERR("No visual found !\n");
-    else
-      TRACE("Visual found\n");
-
-    odev->ctx = glXCreateContext(odev->gdi_display, vis,
-				   NULL, GL_TRUE);
-
-    if (odev->ctx == NULL)
-      ERR("Error in context creation !\n");
-    else
-      TRACE("Context created (%p)\n", odev->ctx);
-
-    /* Look for the front buffer and override its surface's Flip method (if in double buffering) */ 
-    for (surf = surface; surf != NULL; surf = surf->surface_owner)
-        if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	    == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	{
-            surface->surface_owner->aux_ctx  = (LPVOID)odev->gdi_display;
-            surface->surface_owner->aux_data = (LPVOID)odev->drawable;
-            surface->surface_owner->aux_flip = opengl_flip;
-            break;
-        }
-
-    odev->rs.src = GL_ONE;
-    odev->rs.dst = GL_ZERO;
-    odev->rs.mag = GL_NEAREST;
-    odev->rs.min = GL_NEAREST;
-    odev->vt     = 0;
-
-    /* Allocate memory for the matrices */
-    odev->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-    odev->view_mat  = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-    odev->proj_mat  = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
-
-    memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
-    memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
-    memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
-
-    /* Initialisation */
-    TRACE("Setting current context\n");
-    LEAVE_GL();
-    (*device)->set_context(*device);
-    ENTER_GL();
-    TRACE("Current context set\n");
-    glClearColor(0.0, 0.0, 0.0, 0.0);
-    glColor3f(1.0, 1.0, 1.0);
-    LEAVE_GL();
-
-    fill_device_capabilities(d3d->ddraw);
-
-    TRACE("OpenGL device created \n");
-    return 1;
-  }
-  FIXME("bad IID %s\n",debugstr_guid(rguid));
-  /* This is not the OpenGL UID */
-  return 0;
-}
-
-/*******************************************************************************
- *				MESA IDirect3DDevice2
- */
-static ULONG WINAPI MESA_IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
+HRESULT d3device_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD interface_version)
 {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+    D3DDEVICEDESC d1, d2;
+    char buf[256];
+    const void *iid = NULL;
 
-  if (!--(This->ref)) {
-    D3DDPRIVATE(This);
+    switch (interface_version) {
+        case 1: iid = &IID_D3DDEVICE_OpenGL; break;
+	case 2: iid = &IID_D3DDEVICE2_OpenGL; break;
+	case 3: iid = &IID_D3DDEVICE3_OpenGL; break;
+	case 7: iid = &IID_D3DDEVICE7_OpenGL; break;
+    }
+    strcpy(buf, "WINE Direct3DX using OpenGL");
+    buf[13] = '0' + interface_version;
 
-    ENTER_GL();
-    glXDestroyContext(odev->gdi_display, odev->ctx);
-    LEAVE_GL();
-    HeapFree(GetProcessHeap(),0,This->private);
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-  return This->ref;
+    fill_opengl_caps(&d1);
+    d2 = d1;
+
+    TRACE(" enumerating OpenGL D3DDevice%ld interface (IID %s).\n", interface_version, debugstr_guid(iid));
+    return cb((LPGUID) iid, buf, "direct3d", &d1, &d2, context);
 }
 
-/*** IDirect3DDevice2 methods ***/
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_GetCaps(
-    LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
-    LPD3DDEVICEDESC lpdeschard
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
-  fill_opengl_caps(lpdescsoft, lpdeschard);
-  return DD_OK;
+ULONG WINAPI
+GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
+    
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (!--(This->ref)) {
+	/* Release texture associated with the device */ 
+	if (This->current_texture != NULL)
+	    IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture, IDirect3DTexture2));
+	    	  
+	ENTER_GL();
+	glXDestroyContext(glThis->display, glThis->gl_context);
+	LEAVE_GL();
+
+	HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    return This->ref;
 }
 
-static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
-					  LPVOID context) {
-  DDSURFACEDESC sdesc;
-  LPDDPIXELFORMAT pformat;
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
+				       LPD3DDEVICEDESC lpD3DHWDevDesc,
+				       LPD3DDEVICEDESC lpD3DHELDevDesc)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    D3DDEVICEDESC desc;
+    DWORD dwSize;
 
-  /* Do the texture enumeration */
-  sdesc.dwSize = sizeof(DDSURFACEDESC);
-  sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
-  sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
-  pformat = &(sdesc.ddpfPixelFormat);
-  pformat->dwSize = sizeof(DDPIXELFORMAT);
-  pformat->dwFourCC = 0;
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
 
-  TRACE("Enumerating GL_RGBA unpacked (32)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u1.dwRGBBitCount = 32;
-  pformat->u2.dwRBitMask =         0xFF000000;
-  pformat->u3.dwGBitMask =         0x00FF0000;
-  pformat->u4.dwBBitMask =        0x0000FF00;
-  pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
-  if (cb(&sdesc, context) == 0)
+    fill_opengl_caps(&desc);
+    dwSize = lpD3DHWDevDesc->dwSize;
+    memset(lpD3DHWDevDesc, 0, dwSize);
+    memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
+
+    dwSize = lpD3DHELDevDesc->dwSize;
+    memset(lpD3DHELDevDesc, 0, dwSize);
+    memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
+
+    TRACE(" returning caps : TODO\n");
+
     return DD_OK;
+}
 
-  TRACE("Enumerating GL_RGB unpacked (24)\n");
-  pformat->dwFlags = DDPF_RGB;
-  pformat->u1.dwRGBBitCount = 24;
-  pformat->u2.dwRBitMask =  0x00FF0000;
-  pformat->u3.dwGBitMask =  0x0000FF00;
-  pformat->u4.dwBBitMask = 0x000000FF;
-  pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
+static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
+					  LPD3DENUMPIXELFORMATSCALLBACK cb_2,
+					  LPVOID context)
+{
+    DDSURFACEDESC sdesc;
+    LPDDPIXELFORMAT pformat;
+
+    /* Do the texture enumeration */
+    sdesc.dwSize = sizeof(DDSURFACEDESC);
+    sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
+    sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+    pformat = &(sdesc.ddpfPixelFormat);
+    pformat->dwSize = sizeof(DDPIXELFORMAT);
+    pformat->dwFourCC = 0;
+
+    TRACE("Enumerating GL_RGBA unpacked (32)\n");
+    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+    pformat->u1.dwRGBBitCount = 32;
+    pformat->u2.dwRBitMask =         0xFF000000;
+    pformat->u3.dwGBitMask =         0x00FF0000;
+    pformat->u4.dwBBitMask =        0x0000FF00;
+    pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
+
+    TRACE("Enumerating GL_RGB unpacked (24)\n");
+    pformat->dwFlags = DDPF_RGB;
+    pformat->u1.dwRGBBitCount = 24;
+    pformat->u2.dwRBitMask =  0x00FF0000;
+    pformat->u3.dwGBitMask =  0x0000FF00;
+    pformat->u4.dwBBitMask = 0x000000FF;
+    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
 
 #ifndef HAVE_BUGGY_MESAGL
-  /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
-     so that future version will work great. */
-  TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
-  pformat->dwFlags = DDPF_RGB;
-  pformat->u1.dwRGBBitCount = 16;
-  pformat->u2.dwRBitMask =  0x0000F800;
-  pformat->u3.dwGBitMask =  0x000007E0;
-  pformat->u4.dwBBitMask = 0x0000001F;
-  pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
+    /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
+       so that future version will work great. */
+    TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
+    pformat->dwFlags = DDPF_RGB;
+    pformat->u1.dwRGBBitCount = 16;
+    pformat->u2.dwRBitMask =  0x0000F800;
+    pformat->u3.dwGBitMask =  0x000007E0;
+    pformat->u4.dwBBitMask = 0x0000001F;
+    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
 
-  TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u1.dwRGBBitCount = 16;
-  pformat->u2.dwRBitMask =         0x0000F800;
-  pformat->u3.dwGBitMask =         0x000007C0;
-  pformat->u4.dwBBitMask =        0x0000003E;
-  pformat->u5.dwRGBAlphaBitMask = 0x00000001;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
+    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
+    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+    pformat->u1.dwRGBBitCount = 16;
+    pformat->u2.dwRBitMask =         0x0000F800;
+    pformat->u3.dwGBitMask =         0x000007C0;
+    pformat->u4.dwBBitMask =        0x0000003E;
+    pformat->u5.dwRGBAlphaBitMask = 0x00000001;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
 
-  TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u1.dwRGBBitCount = 16;
-  pformat->u2.dwRBitMask =         0x0000F000;
-  pformat->u3.dwGBitMask =         0x00000F00;
-  pformat->u4.dwBBitMask =        0x000000F0;
-  pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
+    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
+    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+    pformat->u1.dwRGBBitCount = 16;
+    pformat->u2.dwRBitMask =         0x0000F000;
+    pformat->u3.dwGBitMask =         0x00000F00;
+    pformat->u4.dwBBitMask =        0x000000F0;
+    pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
 
-  TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
-  pformat->dwFlags = DDPF_RGB;
-  pformat->u1.dwRGBBitCount = 8;
-  pformat->u2.dwRBitMask =        0x000000E0;
-  pformat->u3.dwGBitMask =        0x0000001C;
-  pformat->u4.dwBBitMask =        0x00000003;
-  pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
+    TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
+    pformat->dwFlags = DDPF_RGB;
+    pformat->u1.dwRGBBitCount = 8;
+    pformat->u2.dwRBitMask =        0x000000E0;
+    pformat->u3.dwGBitMask =        0x0000001C;
+    pformat->u4.dwBBitMask =        0x00000003;
+    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
 #endif
 
-  TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u1.dwRGBBitCount = 16;
-  pformat->u2.dwRBitMask =         0x00007C00;
-  pformat->u3.dwGBitMask =         0x000003E0;
-  pformat->u4.dwBBitMask =         0x0000001F;
-  pformat->u5.dwRGBAlphaBitMask =  0x00008000;
-  if (cb(&sdesc, context) == 0)
+    TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
+    pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+    pformat->u1.dwRGBBitCount = 16;
+    pformat->u2.dwRBitMask =         0x00007C00;
+    pformat->u3.dwGBitMask =         0x000003E0;
+    pformat->u4.dwBBitMask =         0x0000001F;
+    pformat->u5.dwRGBAlphaBitMask =  0x00008000;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
+
+    TRACE("Enumerating Paletted (8)\n");
+    pformat->dwFlags = DDPF_PALETTEINDEXED8;
+    pformat->u1.dwRGBBitCount = 8;
+    pformat->u2.dwRBitMask =  0x00000000;
+    pformat->u3.dwGBitMask =  0x00000000;
+    pformat->u4.dwBBitMask = 0x00000000;
+    pformat->u5.dwRGBAlphaBitMask = 0x00000000;
+    if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+    if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
+
+    TRACE("End of enumeration\n");
     return DD_OK;
+}
 
-  TRACE("Enumerating Paletted (8)\n");
-  pformat->dwFlags = DDPF_PALETTEINDEXED8;
-  pformat->u1.dwRGBBitCount = 8;
-  pformat->u2.dwRBitMask =  0x00000000;
-  pformat->u3.dwGBitMask =  0x00000000;
-  pformat->u4.dwBBitMask = 0x00000000;
-  pformat->u5.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
+					       LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
+					       LPVOID lpArg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
+    return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
+}
+
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
+					       LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
+					       LPVOID lpArg)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
+    return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
+}
+
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
+					      D3DRENDERSTATETYPE dwRenderStateType,
+					      DWORD dwRenderState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
+    TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
+
+    /* Call the render state functions */
+    set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
+
     return DD_OK;
-
-  TRACE("End of enumeration\n");
-
-  return DD_OK;
 }
 
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_EnumTextureFormats(
-    LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, cb, context);
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
+					  D3DLIGHTSTATETYPE dwLightStateType,
+					  DWORD dwLightState)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
+    TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
 
-  return enum_texture_format_OpenGL(cb, context);
-}
+    switch (dwLightStateType) {
+        case D3DLIGHTSTATE_MATERIAL: {  /* 1 */
+	    IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
 
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_BeginScene(
-    LPDIRECT3DDEVICE2 iface
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
+	    if (mat != NULL) {
+	        ENTER_GL();
+		mat->activate(mat);
+		LEAVE_GL();
+	    } else {
+	        ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
+	    }
+	} break;
 
-  FIXME("(%p)->(): stub\n", This);
+	case D3DLIGHTSTATE_AMBIENT: {   /* 2 */
+	    float light[4];
 
-  /* Here, we should get the DDraw surface and 'copy it' to the
-     OpenGL surface.... */
-
-  return DD_OK;
-}
-
-HRESULT WINAPI MESA_IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-
-  FIXME("(%p)->(): stub\n", This);
-
-  /* No need to do anything here... */
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetRenderState(
-    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
-    DWORD dwRenderState
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  D3DDPRIVATE(This);
-
-  TRACE("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
-
-  /* Call the render state functions */
-  set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetLightState(
-    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
-    DWORD dwLightState
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
-
-  switch (dwLightStateType) {
-  case D3DLIGHTSTATE_MATERIAL: {  /* 1 */
-    IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
-
-    if (mat != NULL) {
-      ENTER_GL();
-      mat->activate(mat);
-      LEAVE_GL();
-    } else {
-      TRACE("Zoups !!!\n");
-    }
-  } break;
-
-  case D3DLIGHTSTATE_AMBIENT: {   /* 2 */
-    float light[4];
-
-    light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
-    light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
-    light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
-    light[3] = 1.0;
-    ENTER_GL();
-    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
-    LEAVE_GL();
-  } break;
+	    light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
+	    light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
+	    light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
+	    light[3] = 1.0;
+	    ENTER_GL();
+	    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
+	    LEAVE_GL();
+	} break;
 
 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
-  UNSUP(COLORMODEL);
-  UNSUP(FOGMODE);
-  UNSUP(FOGSTART);
-  UNSUP(FOGEND);
-  UNSUP(FOGDENSITY);
+	UNSUP(COLORMODEL);
+	UNSUP(FOGMODE);
+	UNSUP(FOGSTART);
+	UNSUP(FOGEND);
+	UNSUP(FOGDENSITY);
 #undef UNSUP
-  default:
-    TRACE("Unexpected Light State Type\n");
-    return DDERR_INVALIDPARAMS;
-  }
 
-  return DD_OK;
-}
+	default:
+	    TRACE("Unexpected Light State Type\n");
+	    return DDERR_INVALIDPARAMS;
+    }
 
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetTransform(
-    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts,
-    LPD3DMATRIX lpmatrix
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  D3DDPRIVATE(This);
-
-  FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
-
-  ENTER_GL();
-
-  /* Using a trial and failure approach, I found that the order of
-     Direct3D transformations that works best is :
-
-     ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
-
-     As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
-     OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
-
-     If anyone has a good explanation of the three different matrices in
-     the SDK online documentation, feel free to point it to me. For example,
-     which matrices transform lights ? In OpenGL only the PROJECTION matrix
-     transform the lights, not the MODELVIEW. Using the matrix names, I
-     supposed that PROJECTION and VIEW (all 'camera' related names) do
-     transform lights, but WORLD do not. It may be wrong though... */
-
-  /* After reading through both OpenGL and Direct3D documentations, I
-     thought that D3D matrices were written in 'line major mode' transposed
-     from OpenGL's 'column major mode'. But I found out that a simple memcpy
-     works fine to transfer one matrix format to the other (it did not work
-     when transposing)....
-
-     So :
-      1) are the documentations wrong
-      2) does the matrix work even if they are not read correctly
-      3) is Mesa's implementation of OpenGL not compliant regarding Matrix
-         loading using glLoadMatrix ?
-
-     Anyway, I always use 'conv_mat' to transfer the matrices from one format
-     to the other so that if I ever find out that I need to transpose them, I
-     will able to do it quickly, only by changing the macro conv_mat. */
-
-  switch (d3dts) {
-  case D3DTRANSFORMSTATE_WORLD: {
-    conv_mat(lpmatrix, odev->world_mat);
-    glMatrixMode(GL_MODELVIEW);
-    glLoadMatrixf((float *) odev->world_mat);
-  } break;
-
-  case D3DTRANSFORMSTATE_VIEW: {
-    conv_mat(lpmatrix, odev->view_mat);
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf((float *) odev->proj_mat);
-    glMultMatrixf((float *) odev->view_mat);
-  } break;
-
-  case D3DTRANSFORMSTATE_PROJECTION: {
-    conv_mat(lpmatrix, odev->proj_mat);
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf((float *) odev->proj_mat);
-    glMultMatrixf((float *) odev->view_mat);
-  } break;
-
-  default:
-    break;
-  }
-  LEAVE_GL();
-  return DD_OK;
-}
-
-#define DRAW_PRIMITIVE(MAXVERT,INDEX)					\
-  /* Puts GL in the correct lighting mode */				\
-  if (odev->vt != d3dv) {						\
-    if (odev->vt == D3DVT_TLVERTEX) {					\
-      /* Need to put the correct transformation again */		\
-      glMatrixMode(GL_MODELVIEW);					\
-      glLoadMatrixf((float *) odev->world_mat);                      \
-      glMatrixMode(GL_PROJECTION);					\
-      glLoadMatrixf((float *) odev->proj_mat);	                \
-      glMultMatrixf((float *) odev->view_mat);	                \
-    }									\
-									\
-    switch (d3dv) {							\
-    case D3DVT_VERTEX:							\
-      TRACE("Standard Vertex\n");					\
-      glEnable(GL_LIGHTING);						\
-      break;								\
-									\
-    case D3DVT_LVERTEX:							\
-      TRACE("Lighted Vertex\n");					\
-      glDisable(GL_LIGHTING);						\
-      break;								\
-									\
-    case D3DVT_TLVERTEX: {						\
-      GLdouble height, width, minZ, maxZ;				\
-									\
-      TRACE("Transformed - Lighted Vertex\n");				\
-      /* First, disable lighting */					\
-      glDisable(GL_LIGHTING);						\
-									\
-      /* Then do not put any transformation matrixes */			\
-      glMatrixMode(GL_MODELVIEW);					\
-      glLoadIdentity();							\
-      glMatrixMode(GL_PROJECTION);					\
-      glLoadIdentity();							\
-									\
-      if (This->current_viewport == NULL) {				\
-	ERR("No current viewport !\n");					\
-	/* Using standard values */					\
-	height = 640.0;							\
-	width = 480.0;							\
-	minZ = -10.0;							\
-	maxZ = 10.0;							\
-      } else {								\
-	if (This->current_viewport->use_vp2) {				\
-	  height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight;\
-	  width  = (GLdouble) This->current_viewport->viewport.vp2.dwWidth;\
-	  minZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ;\
-	  maxZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ;\
-	} else {							\
-	  height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight;\
-	  width  = (GLdouble) This->current_viewport->viewport.vp1.dwWidth;\
-	  minZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ;\
-	  maxZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ;\
-	}								\
-      }									\
-									\
-      glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);			\
-    } break;								\
-									\
-    default:								\
-      ERR("Unhandled vertex type\n");					\
-      break;								\
-    }									\
-									\
-    odev->vt = d3dv;							\
-  }									\
-									\
-  switch (d3dp) {							\
-  case D3DPT_POINTLIST:							\
-    TRACE("Start POINTS\n");						\
-    glBegin(GL_POINTS);							\
-    break;								\
-									\
-  case D3DPT_LINELIST:							\
-    TRACE("Start LINES\n");						\
-    glBegin(GL_LINES);							\
-    break;								\
-									\
-  case D3DPT_LINESTRIP:							\
-    TRACE("Start LINE_STRIP\n");					\
-    glBegin(GL_LINE_STRIP);						\
-    break;								\
-									\
-  case D3DPT_TRIANGLELIST:						\
-    TRACE("Start TRIANGLES\n");						\
-    glBegin(GL_TRIANGLES);						\
-    break;								\
-									\
-  case D3DPT_TRIANGLESTRIP:						\
-    TRACE("Start TRIANGLE_STRIP\n");					\
-    glBegin(GL_TRIANGLE_STRIP);						\
-    break;								\
-									\
-  case D3DPT_TRIANGLEFAN:						\
-    TRACE("Start TRIANGLE_FAN\n");					\
-    glBegin(GL_TRIANGLE_FAN);						\
-    break;								\
-									\
-  default:								\
-    TRACE("Unhandled primitive\n");					\
-    break;								\
-  }									\
-									\
-  /* Draw the primitives */						\
-  for (vx_index = 0; vx_index < MAXVERT; vx_index++) {			\
-    switch (d3dv) {							\
-    case D3DVT_VERTEX: {						\
-      D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX;			\
-									\
-      glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);			\
-      glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);				\
-      TRACE("   V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);		\
-    } break;								\
-									\
-    case D3DVT_LVERTEX: {						\
-      D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX;		\
-      DWORD col = vx->u4.color;						\
-									\
-      glColor3f(((col >> 16) & 0xFF) / 255.0,				\
-		((col >>  8) & 0xFF) / 255.0,				\
-		((col >>  0) & 0xFF) / 255.0);				\
-      glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);				\
-      TRACE("  LV: %f %f %f (%02lx %02lx %02lx)\n",			\
-	    vx->u1.x, vx->u2.y, vx->u3.z,				\
-	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));\
-    } break;								\
-									\
-    case D3DVT_TLVERTEX: {						\
-      D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX;		\
-      DWORD col = vx->u5.color;						\
-									\
-      glColor3f(((col >> 16) & 0xFF) / 255.0,				\
-		((col >>  8) & 0xFF) / 255.0,				\
-		((col >>  0) & 0xFF) / 255.0);				\
-      glTexCoord2f(vx->u7.tu, vx->u8.tv);				\
-      if (vx->u4.rhw < 0.01)						\
-	glVertex3f(vx->u1.sx,						\
-		   vx->u2.sy,						\
-		   vx->u3.sz);						\
-      else								\
-	glVertex4f(vx->u1.sx / vx->u4.rhw,				\
-		   vx->u2.sy / vx->u4.rhw,				\
-		   vx->u3.sz / vx->u4.rhw,				\
-		   1.0 / vx->u4.rhw);					\
-      TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",	\
-	    vx->u1.sx, vx->u2.sy, vx->u3.sz,				\
-	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),\
-	    vx->u7.tu, vx->u8.tv, vx->u4.rhw);				\
-    } break;								\
-									\
-    default:								\
-      FIXME("Unhandled vertex type\n");					\
-      break;								\
-    }									\
-  }									\
-									\
-  glEnd();								\
-  TRACE("End\n");
-
-
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_DrawPrimitive(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  D3DDPRIVATE(This);
-  int vx_index;
-
-  TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
-
-  ENTER_GL();
-  DRAW_PRIMITIVE(vertcount, vx_index);
-  LEAVE_GL();
-
-  return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DDevice2Impl_DrawIndexedPrimitive(
-    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
-    LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
-    DWORD dwFlags
-) {
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  D3DDPRIVATE(This);
-  int vx_index;
-
-  TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
-
-  ENTER_GL();
-  DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
-  LEAVE_GL();
-
-  return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DDeviceImpl_CreateExecuteBuffer(
-    LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
-    LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
-) {
-    ICOM_THIS(IDirect3DDeviceImpl,iface);
-    TRACE("(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
-    *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
     return DD_OK;
 }
 
-
-/*******************************************************************************
- *				OpenGL-specific IDirect3DDevice2
- */
-
-/*******************************************************************************
- *				OpenGL-specific VTable
- */
-
-ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable =
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
+                                            D3DTRANSFORMSTATETYPE dtstTransformStateType,
+                                            LPD3DMATRIX lpD3DMatrix)
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirect3DDevice2Impl_QueryInterface,
-  IDirect3DDevice2Impl_AddRef,
-  MESA_IDirect3DDevice2Impl_Release,
-  /*** IDirect3DDevice2 methods ***/
-  MESA_IDirect3DDevice2Impl_GetCaps,
-  IDirect3DDevice2Impl_SwapTextureHandles,
-  IDirect3DDevice2Impl_GetStats,
-  IDirect3DDevice2Impl_AddViewport,
-  IDirect3DDevice2Impl_DeleteViewport,
-  IDirect3DDevice2Impl_NextViewport,
-  MESA_IDirect3DDevice2Impl_EnumTextureFormats,
-  MESA_IDirect3DDevice2Impl_BeginScene,
-  MESA_IDirect3DDevice2Impl_EndScene,
-  IDirect3DDevice2Impl_GetDirect3D,
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
 
-  /*** DrawPrimitive API ***/
-  IDirect3DDevice2Impl_SetCurrentViewport,
-  IDirect3DDevice2Impl_GetCurrentViewport,
+    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
 
-  IDirect3DDevice2Impl_SetRenderTarget,
-  IDirect3DDevice2Impl_GetRenderTarget,
+    ENTER_GL();
 
-  IDirect3DDevice2Impl_Begin,
-  IDirect3DDevice2Impl_BeginIndexed,
-  IDirect3DDevice2Impl_Vertex,
-  IDirect3DDevice2Impl_Index,
-  IDirect3DDevice2Impl_End,
+    /* Using a trial and failure approach, I found that the order of
+       Direct3D transformations that works best is :
 
-  IDirect3DDevice2Impl_GetRenderState,
-  MESA_IDirect3DDevice2Impl_SetRenderState,
-  IDirect3DDevice2Impl_GetLightState,
-  MESA_IDirect3DDevice2Impl_SetLightState,
-  MESA_IDirect3DDevice2Impl_SetTransform,
-  IDirect3DDevice2Impl_GetTransform,
-  IDirect3DDevice2Impl_MultiplyTransform,
+       ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
 
-  MESA_IDirect3DDevice2Impl_DrawPrimitive,
-  MESA_IDirect3DDevice2Impl_DrawIndexedPrimitive,
+       As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
+       OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
 
-  IDirect3DDevice2Impl_SetClipStatus,
-  IDirect3DDevice2Impl_GetClipStatus,
-};
+       If anyone has a good explanation of the three different matrices in
+       the SDK online documentation, feel free to point it to me. For example,
+       which matrices transform lights ? In OpenGL only the PROJECTION matrix
+       transform the lights, not the MODELVIEW. Using the matrix names, I
+       supposed that PROJECTION and VIEW (all 'camera' related names) do
+       transform lights, but WORLD do not. It may be wrong though... */
 
-/*******************************************************************************
- *				Direct3DDevice
- */
-int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
-  D3DDEVICEDESC	d1,d2;
+    /* After reading through both OpenGL and Direct3D documentations, I
+       thought that D3D matrices were written in 'line major mode' transposed
+       from OpenGL's 'column major mode'. But I found out that a simple memcpy
+       works fine to transfer one matrix format to the other (it did not work
+       when transposing)....
 
-  TRACE(" Enumerating OpenGL D3D device (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
+       So :
+         1) are the documentations wrong
+	 2) does the matrix work even if they are not read correctly
+	 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
+            loading using glLoadMatrix ?
 
-  fill_opengl_caps(&d1, &d2);
+       Anyway, I always use 'conv_mat' to transfer the matrices from one format
+       to the other so that if I ever find out that I need to transpose them, I
+       will able to do it quickly, only by changing the macro conv_mat. */
 
-  return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
+    switch (dtstTransformStateType) {
+        case D3DTRANSFORMSTATE_WORLD: {
+	    conv_mat(lpD3DMatrix, glThis->world_mat);
+	    glMatrixMode(GL_MODELVIEW);
+	    glLoadMatrixf((float *) glThis->world_mat);
+	} break;
+
+	case D3DTRANSFORMSTATE_VIEW: {
+	    conv_mat(lpD3DMatrix, glThis->view_mat);
+	    glMatrixMode(GL_PROJECTION);
+	    glLoadMatrixf((float *) glThis->proj_mat);
+	    glMultMatrixf((float *) glThis->view_mat);
+	} break;
+
+	case D3DTRANSFORMSTATE_PROJECTION: {
+	    conv_mat(lpD3DMatrix, glThis->proj_mat);
+	    glMatrixMode(GL_PROJECTION);
+	    glLoadMatrixf((float *) glThis->proj_mat);
+	    glMultMatrixf((float *) glThis->view_mat);
+	} break;
+
+	default:
+	    ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType);
+	    break;
+    }
+    LEAVE_GL();
+
+    return DD_OK;
 }
 
-int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
+inline static void draw_primitive(IDirect3DDeviceGLImpl *glThis, DWORD maxvert, WORD *index,
+				  D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
 {
-  TRACE("rguid = %s, surface = %p, &device = %p\n",debugstr_guid(rguid),surface,device);
-  if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
-    mesa_d3dd_private *odev;
-    HDC device_context;
-    int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
-    XVisualInfo *xvis;
-    IDirectDrawSurfaceImpl* surf;
+    DWORD vx_index;
+  
+    /* Puts GL in the correct lighting mode */
+    if (glThis->vertex_type != d3dvt) {
+        if (glThis->vertex_type == D3DVT_TLVERTEX) {
+	    /* Need to put the correct transformation again */
+	    glMatrixMode(GL_MODELVIEW);
+	    glLoadMatrixf((float *) glThis->world_mat);
+	    glMatrixMode(GL_PROJECTION);
+	    glLoadMatrixf((float *) glThis->proj_mat);
+	    glMultMatrixf((float *) glThis->view_mat);
+	}
 
-    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DDeviceImpl));
-    (*device)->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dd_private));
-    odev = (mesa_d3dd_private*)(*device)->private;
-    (*device)->ref = 1;
-    ICOM_VTBL(*device) = &OpenGL_vtable_dx3;
-    (*device)->d3d = NULL;
-    (*device)->surface = surface;
+	switch (d3dvt) {
+	    case D3DVT_VERTEX:
+	        TRACE("Standard Vertex\n");
+		glEnable(GL_LIGHTING);
+		break;
 
-    (*device)->viewport_list = NULL;
-    (*device)->current_viewport = NULL;
-    (*device)->current_texture = NULL;
+	    case D3DVT_LVERTEX:
+		TRACE("Lighted Vertex\n");
+		glDisable(GL_LIGHTING);
+		break;
 
-    (*device)->set_context = (void*)set_context;
+	    case D3DVT_TLVERTEX: {
+	        GLdouble height, width, minZ, maxZ;
 
-    TRACE("OpenGL device created \n");
+		TRACE("Transformed - Lighted Vertex\n");
+		/* First, disable lighting */
+		glDisable(GL_LIGHTING);
 
-    /* Create the OpenGL context */
-    /* First get the correct visual */
-    /* if (surface->s.backbuffer == NULL)
-       attributeList[3] = None; */
-    device_context = GetDC((*device)->surface->ddraw_owner->window);
-    odev->gdi_display = get_display(device_context);
-    odev->drawable = get_drawable(device_context);
-    ReleaseDC((*device)->surface->ddraw_owner->window,device_context);
+		/* Then do not put any transformation matrixes */
+		glMatrixMode(GL_MODELVIEW);
+		glLoadIdentity();
+		glMatrixMode(GL_PROJECTION);
+		glLoadIdentity();
+
+		if (glThis->parent.current_viewport == NULL) {
+		    ERR("No current viewport !\n");
+		    /* Using standard values */
+		    height = 640.0;
+		    width = 480.0;
+		    minZ = -10.0;
+		    maxZ = 10.0;
+		} else {
+		    if (glThis->parent.current_viewport->use_vp2 == 1) {
+		        height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
+			width  = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
+			minZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
+			maxZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
+		    } else {
+		        height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
+			width  = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
+			minZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
+			maxZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
+		    }
+		}
+
+		glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
+	    } break;
+
+	    default:
+		ERR("Unhandled vertex type\n");
+		break;
+	}
+
+	glThis->vertex_type = d3dvt;
+    }
+
+    switch (d3dpt) {
+        case D3DPT_POINTLIST:
+            TRACE("Start POINTS\n");
+	    glBegin(GL_POINTS);
+	    break;
+
+	case D3DPT_LINELIST:
+	    TRACE("Start LINES\n");
+	    glBegin(GL_LINES);
+	    break;
+
+	case D3DPT_LINESTRIP:
+	    TRACE("Start LINE_STRIP\n");
+	    glBegin(GL_LINE_STRIP);
+	    break;
+
+	case D3DPT_TRIANGLELIST:
+	    TRACE("Start TRIANGLES\n");
+	    glBegin(GL_TRIANGLES);
+	    break;
+
+	case D3DPT_TRIANGLESTRIP:
+	    TRACE("Start TRIANGLE_STRIP\n");
+	    glBegin(GL_TRIANGLE_STRIP);
+	    break;
+
+	case D3DPT_TRIANGLEFAN:
+	    TRACE("Start TRIANGLE_FAN\n");
+	    glBegin(GL_TRIANGLE_FAN);
+	    break;
+
+	default:
+	    TRACE("Unhandled primitive\n");
+	    break;
+    }
+
+    /* Draw the primitives */
+    for (vx_index = 0; vx_index < maxvert; vx_index++) {
+        switch (d3dvt) {
+	    case D3DVT_VERTEX: {
+	        D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
+
+		glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);
+		glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
+		TRACE("   V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);
+	    } break;
+
+	    case D3DVT_LVERTEX: {
+	        D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
+		DWORD col = vx->u4.color;
+
+		glColor3f(((col >> 16) & 0xFF) / 255.0,
+			  ((col >>  8) & 0xFF) / 255.0,
+			  ((col >>  0) & 0xFF) / 255.0);
+		glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
+		TRACE("  LV: %f %f %f (%02lx %02lx %02lx)\n",
+		      vx->u1.x, vx->u2.y, vx->u3.z,
+		      ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));
+	    } break;
+
+	    case D3DVT_TLVERTEX: {
+	        D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
+		DWORD col = vx->u5.color;
+
+		glColor3f(((col >> 16) & 0xFF) / 255.0,
+			  ((col >>  8) & 0xFF) / 255.0,
+			  ((col >>  0) & 0xFF) / 255.0);
+		glTexCoord2f(vx->u7.tu, vx->u8.tv);
+		if (vx->u4.rhw < 0.01)
+		    glVertex3f(vx->u1.sx,
+			       vx->u2.sy,
+			       vx->u3.sz);
+		else
+		    glVertex4f(vx->u1.sx / vx->u4.rhw,
+			       vx->u2.sy / vx->u4.rhw,
+			       vx->u3.sz / vx->u4.rhw,
+			       1.0 / vx->u4.rhw);
+		TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",
+		      vx->u1.sx, vx->u2.sy, vx->u3.sz,
+		      ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),
+		      vx->u7.tu, vx->u8.tv, vx->u4.rhw);
+	    } break;
+
+	    default:
+	        FIXME("Unhandled vertex type\n");
+	        break;
+        }
+    }
+
+    glEnd();
+    TRACE("End\n");
+}
+
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
+				       D3DPRIMITIVETYPE d3dptPrimitiveType,
+				       D3DVERTEXTYPE d3dvtVertexType,
+				       LPVOID lpvVertices,
+				       DWORD dwVertexCount,
+				       DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
+
     ENTER_GL();
-    xvis = glXChooseVisual(odev->gdi_display,
-			   DefaultScreen(odev->gdi_display),
-			   attributeList);
-    if (xvis == NULL)
-      ERR("No visual found !\n");
-    else
-      TRACE("Visual found\n");
-    
-    /* Create the context */
-    odev->ctx = glXCreateContext(odev->gdi_display,
-				 xvis,
-				 NULL,
-				 GL_TRUE);
-    TRACE("Context created\n");
+    draw_primitive((IDirect3DDeviceGLImpl *) This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
+    LEAVE_GL();
+		   
+    return DD_OK;
+}
 
-    /* Look for the front buffer and override its surface's Flip method (if in double buffering) */ 
-    for (surf = surface; surf != NULL; surf = surf->surface_owner)
-        if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	    == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
-	{
-            surface->surface_owner->aux_ctx  = (LPVOID)odev->gdi_display;
-            surface->surface_owner->aux_data = (LPVOID)odev->drawable;
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
+					      D3DPRIMITIVETYPE d3dptPrimitiveType,
+					      D3DVERTEXTYPE d3dvtVertexType,
+					      LPVOID lpvVertices,
+					      DWORD dwVertexCount,
+					      LPWORD dwIndices,
+					      DWORD dwIndexCount,
+					      DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
+    TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
+
+    ENTER_GL();
+    draw_primitive((IDirect3DDeviceGLImpl *) This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
+    LEAVE_GL();
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
+					     LPD3DEXECUTEBUFFERDESC lpDesc,
+					     LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
+					     IUnknown* pUnkOuter)
+{
+    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
+    IDirect3DExecuteBufferImpl *ret;
+    HRESULT ret_value;
+    
+    TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
+
+    ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
+    *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
+
+    TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
+    
+    return ret_value;
+}
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice7.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
+    XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
+    XCAST(GetCaps) Main_IDirect3DDeviceImpl_7_GetCaps,
+    XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
+    XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
+    XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
+    XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
+    XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
+    XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
+    XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
+    XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
+    XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
+    XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
+    XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
+    XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
+    XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
+    XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
+    XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
+    XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
+    XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
+    XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
+    XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
+    XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
+    XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
+    XCAST(DrawPrimitive) Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
+    XCAST(DrawIndexedPrimitive) Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
+    XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
+    XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
+    XCAST(DrawPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
+    XCAST(DrawIndexedPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
+    XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB,
+    XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
+    XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
+    XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
+    XCAST(SetTexture) Main_IDirect3DDeviceImpl_7_SetTexture,
+    XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
+    XCAST(SetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
+    XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
+    XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
+    XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
+    XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
+    XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
+    XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
+    XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
+    XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
+    XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
+    XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
+    XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice3.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
+    XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
+    XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
+    XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
+    XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
+    XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
+    XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
+    XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
+    XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
+    XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
+    XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
+    XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
+    XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
+    XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
+    XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
+    XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
+    XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
+    XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
+    XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
+    XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
+    XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
+    XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
+    XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
+    XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
+    XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
+    XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
+    XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
+    XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
+    XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
+    XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
+    XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
+    XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
+    XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
+    XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
+    XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
+    XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
+    XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
+    XCAST(SetTexture) Main_IDirect3DDeviceImpl_3_SetTexture,
+    XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
+    XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
+    XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice2.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
+    XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
+    XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
+    XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
+    XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
+    XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
+    XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
+    XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
+    XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
+    XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
+    XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
+    XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
+    XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
+    XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
+    XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
+    XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
+    XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
+    XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
+    XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
+    XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
+    XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
+    XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
+    XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
+    XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
+    XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
+    XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
+    XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
+    XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
+    XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
+    XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
+    XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
+    XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DDevice.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
+    XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
+    XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
+    XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
+    XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
+    XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
+    XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
+    XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
+    XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
+    XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
+    XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
+    XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
+    XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
+    XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
+    XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
+    XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
+    XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
+    XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
+    XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
+    XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
+    XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+
+
+HRESULT
+d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
+{
+    IDirect3DDeviceImpl *object;
+    IDirect3DDeviceGLImpl *gl_object;
+    IDirectDrawSurfaceImpl *surf;
+    HDC device_context;
+    XVisualInfo *vis;
+    int num;
+    XVisualInfo template;
+    
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+
+    gl_object = (IDirect3DDeviceGLImpl *) object;
+    
+    object->ref = 1;
+    object->d3d = d3d;
+    object->surface = surface;
+    object->viewport_list = NULL;
+    object->current_viewport = NULL;
+    object->current_texture = NULL;
+    object->set_context = set_context;
+    
+    TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
+
+    device_context = GetDC(surface->ddraw_owner->window);
+    gl_object->display = get_display(device_context);
+    gl_object->drawable = get_drawable(device_context);
+    ReleaseDC(surface->ddraw_owner->window,device_context);
+    
+    ENTER_GL();
+    template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
+    vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
+    if (vis == NULL) {
+        HeapFree(GetProcessHeap(), 0, object);
+        ERR("No visual found !\n");
+	LEAVE_GL();
+	return DDERR_INVALIDPARAMS;
+    } else {
+        TRACE(" visual found\n");
+    }
+
+    gl_object->gl_context = glXCreateContext(gl_object->display, vis,
+					     NULL, GL_TRUE);
+
+    if (gl_object->gl_context == NULL) {
+        HeapFree(GetProcessHeap(), 0, object);
+        ERR("Error in context creation !\n");
+	LEAVE_GL();
+	return DDERR_INVALIDPARAMS;
+    } else {
+        TRACE(" context created (%p)\n", gl_object->gl_context);
+    }
+    
+    /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
+    for (surf = surface; surf != NULL; surf = surf->surface_owner) {
+        if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
+            surface->surface_owner->aux_ctx  = (LPVOID) gl_object->display;
+            surface->surface_owner->aux_data = (LPVOID) gl_object->drawable;
             surface->surface_owner->aux_flip = opengl_flip;
             break;
         }
-	
-    odev->rs.src = GL_ONE;
-    odev->rs.dst = GL_ZERO;
-    odev->rs.mag = GL_NEAREST;
-    odev->rs.min = GL_NEAREST;
+    }
+    
+    gl_object->render_state.src = GL_ONE;
+    gl_object->render_state.dst = GL_ZERO;
+    gl_object->render_state.mag = GL_NEAREST;
+    gl_object->render_state.min = GL_NEAREST;
+    gl_object->vertex_type = 0;
 
-    odev->world_mat = (LPD3DMATRIX) &id_mat;
-    odev->view_mat  = (LPD3DMATRIX) &id_mat;
-    odev->proj_mat  = (LPD3DMATRIX) &id_mat;
+    /* Allocate memory for the matrices */
+    gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
+    gl_object->view_mat  = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
+    gl_object->proj_mat  = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
+
+    memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
+    memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
+    memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
 
     /* Initialisation */
+    TRACE(" setting current context\n");
     LEAVE_GL();
-    (*device)->set_context(*device);
+    object->set_context(object);
     ENTER_GL();
+    TRACE(" current context set\n");
     glClearColor(0.0, 0.0, 0.0, 0.0);
     glColor3f(1.0, 1.0, 1.0);
     LEAVE_GL();
-    fill_device_capabilities((IDirectDrawImpl *) surface->ddraw_owner);
 
-    return 1;
-  }
+    fill_device_capabilities(d3d->ddraw);    
+    
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice,  VTABLE_IDirect3DDevice);
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
+    ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
 
-  /* This is not the OpenGL UID */
-  return DD_OK;
+    *obj = object;
+
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return DD_OK;
 }
-
-static ULONG WINAPI MESA_IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-  if (!--(This->ref)) {
-    D3DDPRIVATE(This);
-    ENTER_GL();
-    glXDestroyContext(odev->gdi_display, odev->ctx);
-    LEAVE_GL();
-    HeapFree(GetProcessHeap(),0,This->private);
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-  return This->ref;
-}
-
-static HRESULT WINAPI MESA_IDirect3DDeviceImpl_EnumTextureFormats(
-    LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
-    LPVOID lpArg)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
-
-  return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
-}
-
-
-static HRESULT WINAPI MESA_IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
-
-  FIXME("(%p)->(): stub\n", This);
-
-  /* We get the pointer to the surface (should be done on flip) */
-  /* odev->zb->pbuf = This->surface->s.surface_desc.u2.lpSurface; */
-
-  return DD_OK;
-}
-
-
-/* This is for the moment copy-pasted from IDirect3DDevice2...
-   Will make a common function ... */
-static HRESULT WINAPI MESA_IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-
-  FIXME("(%p)->(): stub\n", This);
-
-  /* No need to do anything here... */
-
-  return DD_OK;
-}
-
-/*******************************************************************************
- *				Direct3DDevice VTable
- */
-ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 =
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirect3DDeviceImpl_QueryInterface,
-  IDirect3DDeviceImpl_AddRef,
-  MESA_IDirect3DDeviceImpl_Release,
-  IDirect3DDeviceImpl_Initialize,
-  IDirect3DDeviceImpl_GetCaps,
-  IDirect3DDeviceImpl_SwapTextureHandles,
-  MESA_IDirect3DDeviceImpl_CreateExecuteBuffer,
-  IDirect3DDeviceImpl_GetStats,
-  IDirect3DDeviceImpl_Execute,
-  IDirect3DDeviceImpl_AddViewport,
-  IDirect3DDeviceImpl_DeleteViewport,
-  IDirect3DDeviceImpl_NextViewport,
-  IDirect3DDeviceImpl_Pick,
-  IDirect3DDeviceImpl_GetPickRecords,
-  MESA_IDirect3DDeviceImpl_EnumTextureFormats,
-  IDirect3DDeviceImpl_CreateMatrix,
-  IDirect3DDeviceImpl_SetMatrix,
-  IDirect3DDeviceImpl_GetMatrix,
-  IDirect3DDeviceImpl_DeleteMatrix,
-  MESA_IDirect3DDeviceImpl_BeginScene,
-  MESA_IDirect3DDeviceImpl_EndScene,
-  IDirect3DDeviceImpl_GetDirect3D,
-};
diff --git a/dlls/ddraw/d3dexecutebuffer.c b/dlls/ddraw/d3dexecutebuffer.c
index db84a35..8fc1715 100644
--- a/dlls/ddraw/d3dexecutebuffer.c
+++ b/dlls/ddraw/d3dexecutebuffer.c
@@ -29,850 +29,873 @@
 #include "d3d.h"
 #include "wine/debug.h"
 
+#include "d3d_private.h"
 #include "mesa_private.h"
 
-#define D3DDPRIVATE(x) mesa_d3dd_private *odev=((mesa_d3dd_private*)(x)->private)
-
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
 /* Structure to store the 'semi transformed' vertices */
 typedef struct {
-  D3DVALUE x;
-  D3DVALUE y;
-  D3DVALUE z;
-  D3DVALUE w;
+    D3DVALUE x;
+    D3DVALUE y;
+    D3DVALUE z;
+    D3DVALUE w;
 
-  D3DVALUE nx;
-  D3DVALUE ny;
-  D3DVALUE nz;
+    D3DVALUE nx;
+    D3DVALUE ny;
+    D3DVALUE nz;
 
-  D3DVALUE u;
-  D3DVALUE v;
+    D3DVALUE u;
+    D3DVALUE v;
 } OGL_Vertex;
 
 typedef struct {
-  D3DVALUE x;
-  D3DVALUE y;
-  D3DVALUE z;
-  D3DVALUE w;
+    D3DVALUE x;
+    D3DVALUE y;
+    D3DVALUE z;
+    D3DVALUE w;
 
-  D3DCOLOR c;
-  D3DCOLOR sc;
+    D3DCOLOR c;
+    D3DCOLOR sc;
 
-  D3DVALUE u;
-  D3DVALUE v;
+    D3DVALUE u;
+    D3DVALUE v;
 } OGL_LVertex;
 
-static ICOM_VTABLE(IDirect3DExecuteBuffer) executebuffer_vtable;
-
-/*******************************************************************************
- *				ExecuteBuffer static functions
- */
-void _dump_d3dstatus(LPD3DSTATUS lpStatus) {
+static void _dump_d3dstatus(LPD3DSTATUS lpStatus) {
 
 }
 
-void _dump_executedata(LPD3DEXECUTEDATA lpData) {
-  DPRINTF("dwSize : %ld\n", lpData->dwSize);
-  DPRINTF("Vertex      Offset : %ld  Count  : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount);
-  DPRINTF("Instruction Offset : %ld  Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength);
-  DPRINTF("HVertex     Offset : %ld\n", lpData->dwHVertexOffset);
-  _dump_d3dstatus(&(lpData->dsStatus));
+static void _dump_executedata(LPD3DEXECUTEDATA lpData) {
+    DPRINTF("dwSize : %ld\n", lpData->dwSize);
+    DPRINTF("Vertex      Offset : %ld  Count  : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount);
+    DPRINTF("Instruction Offset : %ld  Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength);
+    DPRINTF("HVertex     Offset : %ld\n", lpData->dwHVertexOffset);
+    _dump_d3dstatus(&(lpData->dsStatus));
 }
 
-#define DO_VERTEX(index) 			\
+static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc) {
+
+}
+
+#define DO_VERTEX(index) 			                                \
 {										\
-  glTexCoord2f(vx[index].u,							\
-	       vx[index].v);							\
-  glNormal3f(vx[index].nx,							\
-	     vx[index].ny,							\
-	     vx[index].nz);							\
-  glVertex4f(vx[index].x,						     	\
-	     vx[index].y,							\
-	     vx[index].z,							\
-	     vx[index].w);							\
+    glTexCoord2f(vx[index].u,							\
+   	         vx[index].v);							\
+    glNormal3f(vx[index].nx,							\
+	       vx[index].ny,							\
+	       vx[index].nz);							\
+    glVertex4f(vx[index].x,						     	\
+	       vx[index].y,							\
+	       vx[index].z,							\
+	       vx[index].w);							\
 										\
-  TRACE("   V: %f %f %f %f (%f %f %f) (%f %f)\n",			\
-	vx[index].x, vx[index].y, vx[index].z, vx[index].w,			\
-	vx[index].nx, vx[index].ny, vx[index].nz,				\
-	vx[index].u, vx[index].v);						\
+    TRACE("   V: %f %f %f %f (%f %f %f) (%f %f)\n",			        \
+	  vx[index].x, vx[index].y, vx[index].z, vx[index].w,			\
+	  vx[index].nx, vx[index].ny, vx[index].nz,				\
+	  vx[index].u, vx[index].v);						\
 }
 
 #define DO_LVERTEX(index)							\
 {										\
-  DWORD col = l_vx[index].c;							\
+    DWORD col = l_vx[index].c;							\
   										\
-  glColor3f(((col >> 16) & 0xFF) / 255.0,					\
-	    ((col >>  8) & 0xFF) / 255.0,					\
-	    ((col >>  0) & 0xFF) / 255.0);					\
-  glTexCoord2f(l_vx[index].u,							\
-	       l_vx[index].v);							\
-  glVertex4f(l_vx[index].x,							\
-	     l_vx[index].y,							\
-	     l_vx[index].z,							\
-	     l_vx[index].w);							\
+    glColor3f(((col >> 16) & 0xFF) / 255.0,					\
+	      ((col >>  8) & 0xFF) / 255.0,					\
+	      ((col >>  0) & 0xFF) / 255.0);					\
+    glTexCoord2f(l_vx[index].u,							\
+	         l_vx[index].v);						\
+    glVertex4f(l_vx[index].x,							\
+	       l_vx[index].y,							\
+	       l_vx[index].z,							\
+	       l_vx[index].w);							\
   										\
-  TRACE("  LV: %f %f %f %f (%02lx %02lx %02lx) (%f %f)\n",		\
-	l_vx[index].x, l_vx[index].y, l_vx[index].z, l_vx[index].w,		\
-	((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),	\
-	l_vx[index].u, l_vx[index].v);						\
+    TRACE("  LV: %f %f %f %f (%02lx %02lx %02lx) (%f %f)\n",		        \
+	  l_vx[index].x, l_vx[index].y, l_vx[index].z, l_vx[index].w,		\
+	  ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),	\
+	  l_vx[index].u, l_vx[index].v);					\
 }
 
 #define DO_TLVERTEX(index)							\
 {										\
-  D3DTLVERTEX *vx = &(tl_vx[index]);						\
-  DWORD col = vx->u5.color;							\
+    D3DTLVERTEX *vx = &(tl_vx[index]);						\
+    DWORD col = vx->u5.color;							\
 										\
-  glColor3f(((col >> 16) & 0xFF) / 255.0,					\
-            ((col >>  8) & 0xFF) / 255.0,					\
-            ((col >>  0) & 0xFF) / 255.0);					\
-  glTexCoord2f(vx->u7.tu, vx->u8.tv);						\
-  if (vx->u4.rhw < 0.01)							\
-    glVertex3f(vx->u1.sx,							\
-               vx->u2.sy,							\
-               vx->u3.sz);							\
-  else										\
-    glVertex4f(vx->u1.sx / vx->u4.rhw,						\
-               vx->u2.sy / vx->u4.rhw,						\
-               vx->u3.sz / vx->u4.rhw,						\
-               1.0 / vx->u4.rhw);						\
-  TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",		\
-        vx->u1.sx, vx->u2.sy, vx->u3.sz,						\
-        ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),	\
-        vx->u7.tu, vx->u8.tv, vx->u4.rhw);						\
+    glColor3f(((col >> 16) & 0xFF) / 255.0,					\
+              ((col >>  8) & 0xFF) / 255.0,					\
+              ((col >>  0) & 0xFF) / 255.0);					\
+    glTexCoord2f(vx->u7.tu, vx->u8.tv);						\
+    if (vx->u4.rhw < 0.01)							\
+        glVertex3f(vx->u1.sx,							\
+                   vx->u2.sy,							\
+                   vx->u3.sz);							\
+    else									\
+        glVertex4f(vx->u1.sx / vx->u4.rhw,					\
+                   vx->u2.sy / vx->u4.rhw,					\
+                   vx->u3.sz / vx->u4.rhw,					\
+                   1.0 / vx->u4.rhw);						\
+    TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",		        \
+          vx->u1.sx, vx->u2.sy, vx->u3.sz,					\
+          ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),	\
+          vx->u7.tu, vx->u8.tv, vx->u4.rhw);					\
 }
 
 #define TRIANGLE_LOOP(macro)				\
 {							\
-  glBegin(GL_TRIANGLES); {				\
+    glBegin(GL_TRIANGLES); 				\
     for (i = 0; i < count; i++) {			\
-      LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr;		\
+        LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr;	\
       							\
-      TRACE("  v1: %d  v2: %d  v3: %d\n",	\
-	    ci->u1.v1, ci->u2.v2, ci->u3.v3);		\
-      TRACE("  Flags : ");			\
-      if (TRACE_ON(ddraw)) {				\
-	/* Wireframe */					\
-	if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)	\
-	  DPRINTF("EDGEENABLE1 ");				\
-	if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2)	\
-	  DPRINTF("EDGEENABLE2 ");				\
-	if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)	\
-	  DPRINTF("EDGEENABLE3 ");				\
+        TRACE("  v1: %d  v2: %d  v3: %d\n",	        \
+	      ci->u1.v1, ci->u2.v2, ci->u3.v3);		\
+        TRACE("  Flags : ");			        \
+        if (TRACE_ON(ddraw)) {				\
+	    /* Wireframe */				\
+	    if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)	\
+	        DPRINTF("EDGEENABLE1 ");		\
+	    if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2)	\
+	        DPRINTF("EDGEENABLE2 ");		\
+	    if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)	\
+	        DPRINTF("EDGEENABLE3 ");		\
 							\
-	/* Strips / Fans */				\
-	if (ci->wFlags == D3DTRIFLAG_EVEN)		\
-	  DPRINTF("EVEN ");				\
-	if (ci->wFlags == D3DTRIFLAG_ODD)		\
-	  DPRINTF("ODD ");					\
-	if (ci->wFlags == D3DTRIFLAG_START)		\
-	  DPRINTF("START ");				\
-	if ((ci->wFlags > 0) && (ci->wFlags < 30))	\
-	  DPRINTF("STARTFLAT(%d) ", ci->wFlags);		\
-	DPRINTF("\n");					\
-      }							\
+	    /* Strips / Fans */				\
+	    if (ci->wFlags == D3DTRIFLAG_EVEN)		\
+	        DPRINTF("EVEN ");			\
+	    if (ci->wFlags == D3DTRIFLAG_ODD)		\
+	        DPRINTF("ODD ");			\
+	    if (ci->wFlags == D3DTRIFLAG_START)		\
+	        DPRINTF("START ");			\
+	    if ((ci->wFlags > 0) && (ci->wFlags < 30))	\
+	        DPRINTF("STARTFLAT(%d) ", ci->wFlags);	\
+	    DPRINTF("\n");				\
+        }						\
 							\
-      /* Draw the triangle */				\
-      macro(ci->u1.v1);					\
-      macro(ci->u2.v2);					\
-      macro(ci->u3.v3);					\
+        /* Draw the triangle */				\
+        macro(ci->u1.v1);				\
+        macro(ci->u2.v2);				\
+        macro(ci->u3.v3);				\
 							\
-      instr += size;					\
+        instr += size;					\
     }							\
-  } glEnd();						\
+    glEnd();						\
 }
 
 
-static void execute(LPDIRECT3DEXECUTEBUFFER lpBuff,
-		    LPDIRECT3DDEVICE dev,
-		    LPDIRECT3DVIEWPORT vp) {
-  IDirect3DExecuteBufferImpl* ilpBuff=(IDirect3DExecuteBufferImpl*)lpBuff;
-  IDirect3DViewport2Impl* ivp=(IDirect3DViewport2Impl*)vp;
-  /* DWORD bs = ilpBuff->desc.dwBufferSize; */
-  DWORD vs = ilpBuff->data.dwVertexOffset;
-  /* DWORD vc = ilpBuff->data.dwVertexCount; */
-  DWORD is = ilpBuff->data.dwInstructionOffset;
-  /* DWORD il = ilpBuff->data.dwInstructionLength; */
+static void execute(IDirect3DExecuteBufferImpl *This,
+		    IDirect3DDeviceImpl *lpDevice,
+		    IDirect3DViewportImpl *lpViewport) {
+#if 0
+    IDirect3DExecuteBufferImpl* ilpBuff=(IDirect3DExecuteBufferImpl*)lpBuff;
+    IDirect3DViewport2Impl* ivp=(IDirect3DViewport2Impl*)vp;
+    /* DWORD bs = ilpBuff->desc.dwBufferSize; */
+    DWORD vs = ilpBuff->data.dwVertexOffset;
+    /* DWORD vc = ilpBuff->data.dwVertexCount; */
+    DWORD is = ilpBuff->data.dwInstructionOffset;
+    /* DWORD il = ilpBuff->data.dwInstructionLength; */
+    
+    void *instr = ilpBuff->desc.lpData + is;
+    D3DDPRIVATE((IDirect3DDeviceImpl*)dev);
 
-  void *instr = ilpBuff->desc.lpData + is;
-  D3DDPRIVATE((IDirect3DDeviceImpl*)dev);
+    /* Should check if the viewport was added or not to the device */
 
-  /* Should check if the viewport was added or not to the device */
+    /* Activate the viewport */
+    ivp->device.active_device1 = (IDirect3DDeviceImpl*)dev;
+    ivp->activate(ivp);
 
-  /* Activate the viewport */
-  ivp->device.active_device1 = (IDirect3DDeviceImpl*)dev;
-  ivp->activate(ivp);
+    TRACE("ExecuteData : \n");
+    if (TRACE_ON(ddraw))
+      _dump_executedata(&(ilpBuff->data));
 
-  TRACE("ExecuteData : \n");
-  if (TRACE_ON(ddraw))
-  _dump_executedata(&(ilpBuff->data));
+    ENTER_GL();
 
-  ENTER_GL();
+    while (1) {
+        LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr;
+	BYTE size;
+	WORD count;
+	
+	count = current->wCount;
+	size = current->bSize;
+	instr += sizeof(D3DINSTRUCTION);
+	
+	switch (current->bOpcode) {
+	    case D3DOP_POINT: {
+	        TRACE("POINT-s          (%d)\n", count);
+		instr += count * size;
+	    } break;
 
-  while (1) {
-    LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr;
-    BYTE size;
-    WORD count;
+	    case D3DOP_LINE: {
+	        TRACE("LINE-s           (%d)\n", count);
+		instr += count * size;
+	    } break;
 
-    count = current->wCount;
-    size = current->bSize;
-    instr += sizeof(D3DINSTRUCTION);
+	    case D3DOP_TRIANGLE: {
+	        int i;
+		OGL_Vertex  *vx    = (OGL_Vertex  *) ilpBuff->vertex_data;
+		OGL_LVertex *l_vx  = (OGL_LVertex *) ilpBuff->vertex_data;
+		D3DTLVERTEX *tl_vx = (D3DTLVERTEX *) ilpBuff->vertex_data;
+		TRACE("TRIANGLE         (%d)\n", count);
+		
+		switch (ilpBuff->vertex_type) {
+		    case D3DVT_VERTEX:
+		        /* This time, there is lighting */
+		        glEnable(GL_LIGHTING);
+			
+			/* Use given matrixes */
+			glMatrixMode(GL_MODELVIEW);
+			glLoadIdentity(); /* The model transformation was done during the
+					     transformation phase */
+			glMatrixMode(GL_PROJECTION);
+			TRACE("  Projection Matrix : (%p)\n", odev->proj_mat);
+			dump_mat(odev->proj_mat);
+			TRACE("  View       Matrix : (%p)\n", odev->view_mat);
+			dump_mat(odev->view_mat);
 
-    switch (current->bOpcode) {
-    case D3DOP_POINT: {
-      TRACE("POINT-s          (%d)\n", count);
+			/* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates
+			   are always 0.0 at the front viewing volume and 1.0 at the back with Direct 3D and with
+			   the default behaviour of OpenGL. So, no additional transformation is required. */
+			glLoadMatrixf((float *) odev->proj_mat);
+			glMultMatrixf((float *) odev->view_mat);
+			break;
 
-      instr += count * size;
-    } break;
+		    case D3DVT_LVERTEX:
+			/* No lighting */
+			glDisable(GL_LIGHTING);
 
-    case D3DOP_LINE: {
-      TRACE("LINE-s           (%d)\n", count);
+			/* Use given matrixes */
+			glMatrixMode(GL_MODELVIEW);
+			glLoadIdentity(); /* The model transformation was done during the
+					     transformation phase */
+			glMatrixMode(GL_PROJECTION);
+			
+			TRACE("  Projection Matrix : (%p)\n", odev->proj_mat);
+			dump_mat(odev->proj_mat);
+			TRACE("  View       Matrix : (%p)\n", odev->view_mat);
+			dump_mat(odev->view_mat);
+			
+			/* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates
+			   are always 0 at the front viewing volume and 1 at the back with Direct 3D and with
+			   the default behaviour of OpenGL. So, no additional transformation is required. */
+			glLoadMatrixf((float *) odev->proj_mat);
+			glMultMatrixf((float *) odev->view_mat);
+			break;
 
-      instr += count * size;
-    } break;
+		    case D3DVT_TLVERTEX: {
+		        GLdouble height, width, minZ, maxZ;
+			
+			/* First, disable lighting */
+			glDisable(GL_LIGHTING);
+			
+			/* Then do not put any transformation matrixes */
+			glMatrixMode(GL_MODELVIEW);
+			glLoadIdentity();
+			glMatrixMode(GL_PROJECTION);
+			glLoadIdentity();
+			
+			if (ivp == NULL) {
+			    ERR("No current viewport !\n");
+			    /* Using standard values */
+			    height = 640.0;
+			    width = 480.0;
+			    minZ = -10.0;
+			    maxZ = 10.0;
+			} else {
+			    height = (GLdouble) ivp->viewport.vp1.dwHeight;
+			    width  = (GLdouble) ivp->viewport.vp1.dwWidth;
+			    minZ   = (GLdouble) ivp->viewport.vp1.dvMinZ;
+			    maxZ   = (GLdouble) ivp->viewport.vp1.dvMaxZ;
+			    
+			    if (minZ == maxZ) {
+			        /* I do not know why, but many Dx 3.0 games have minZ = maxZ = 0.0 */
+			        minZ = 0.0;
+				maxZ = 1.0;
+			    }
+			}
+			glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
+		    } break;
 
-    case D3DOP_TRIANGLE: {
-      int i;
+		    default:
+			ERR("Unhandled vertex type !\n");
+			break;
+		}
 
-      OGL_Vertex  *vx    = (OGL_Vertex  *) ilpBuff->vertex_data;
-      OGL_LVertex *l_vx  = (OGL_LVertex *) ilpBuff->vertex_data;
-      D3DTLVERTEX *tl_vx = (D3DTLVERTEX *) ilpBuff->vertex_data;
+		switch (ilpBuff->vertex_type) {
+		    case D3DVT_VERTEX:
+		        TRIANGLE_LOOP(DO_VERTEX);
+			break;
 
-      TRACE("TRIANGLE         (%d)\n", count);
+		    case D3DVT_LVERTEX:
+			TRIANGLE_LOOP(DO_LVERTEX);
+			break;
 
-      switch (ilpBuff->vertex_type) {
-      case D3DVT_VERTEX:
-	/* This time, there is lighting */
-	glEnable(GL_LIGHTING);
+		    case D3DVT_TLVERTEX:
+			TRIANGLE_LOOP(DO_TLVERTEX);
+			break;
 
-      /* Use given matrixes */
-      glMatrixMode(GL_MODELVIEW);
-      glLoadIdentity(); /* The model transformation was done during the
-			   transformation phase */
-      glMatrixMode(GL_PROJECTION);
-	TRACE("  Projection Matrix : (%p)\n", odev->proj_mat);
-	dump_mat(odev->proj_mat);
-	TRACE("  View       Matrix : (%p)\n", odev->view_mat);
-	dump_mat(odev->view_mat);
+		    default:
+			ERR("Unhandled vertex type !\n");
+		}
+	    } break;
 
-	/* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates
-	   are always 0.0 at the front viewing volume and 1.0 at the back with Direct 3D and with
-	   the default behaviour of OpenGL. So, no additional transformation is required. */
-	glLoadMatrixf((float *) odev->proj_mat);
-	glMultMatrixf((float *) odev->view_mat);
-	break;
+	    case D3DOP_MATRIXLOAD:
+	        TRACE("MATRIXLOAD-s     (%d)\n", count);
+	        instr += count * size;
+	        break;
 
-      case D3DVT_LVERTEX:
-	/* No lighting */
-	glDisable(GL_LIGHTING);
+	    case D3DOP_MATRIXMULTIPLY: {
+	        int i;
+		TRACE("MATRIXMULTIPLY   (%d)\n", count);
+		
+		for (i = 0; i < count; i++) {
+		    LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr;
+		    LPD3DMATRIX a = (LPD3DMATRIX) ci->hDestMatrix;
+		    LPD3DMATRIX b = (LPD3DMATRIX) ci->hSrcMatrix1;
+		    LPD3DMATRIX c = (LPD3DMATRIX) ci->hSrcMatrix2;
+		    
+		    TRACE("  Dest : %08lx  Src1 : %08lx  Src2 : %08lx\n",
+			  ci->hDestMatrix, ci->hSrcMatrix1, ci->hSrcMatrix2);
+		    
+		    /* Do the multiplication..
+		       As I am VERY lazy, I let OpenGL do the multiplication for me */
+		    glMatrixMode(GL_PROJECTION);
+		    /* Save the current matrix */
+		    glPushMatrix();
+		    /* Load Matrix one and do the multiplication */
+		    glLoadMatrixf((float *) c);
+		    glMultMatrixf((float *) b);
+		    glGetFloatv(GL_PROJECTION_MATRIX, (float *) a);
+		    /* Restore the current matrix */
+		    glPopMatrix();
+		    
+		    instr += size;
+		}
+	    } break;
 
-	/* Use given matrixes */
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity(); /* The model transformation was done during the
-			     transformation phase */
-	glMatrixMode(GL_PROJECTION);
+	    case D3DOP_STATETRANSFORM: {
+	        int i;
+		TRACE("STATETRANSFORM   (%d)\n", count);
+		
+		for (i = 0; i < count; i++) {
+		    LPD3DSTATE ci = (LPD3DSTATE) instr;
+		    
+		    /* Handle the state transform */
+		    switch (ci->u1.dtstTransformStateType) {
+		        case D3DTRANSFORMSTATE_WORLD: {
+			    TRACE("  WORLD (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
+			    odev->world_mat = (D3DMATRIX*) ci->u2.dwArg[0];
+			} break;
 
-	TRACE("  Projection Matrix : (%p)\n", odev->proj_mat);
-	dump_mat(odev->proj_mat);
-	TRACE("  View       Matrix : (%p)\n", odev->view_mat);
-	dump_mat(odev->view_mat);
+			case D3DTRANSFORMSTATE_VIEW: {
+			    TRACE("  VIEW (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
+			    odev->view_mat = (D3DMATRIX*) ci->u2.dwArg[0];
+			} break;
 
-	/* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates
-	   are always 0 at the front viewing volume and 1 at the back with Direct 3D and with
-	   the default behaviour of OpenGL. So, no additional transformation is required. */
-	glLoadMatrixf((float *) odev->proj_mat);
-	glMultMatrixf((float *) odev->view_mat);
-	break;
+			case D3DTRANSFORMSTATE_PROJECTION: {
+			    TRACE("  PROJECTION (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
+			    odev->proj_mat = (D3DMATRIX*) ci->u2.dwArg[0];
+			} break;
+			  
+			default:
+			    ERR("  Unhandled state transformation !! (%d)\n", (int) ci->u1.dtstTransformStateType);
+			    break;
+		    }
 
-      case D3DVT_TLVERTEX: {
-	GLdouble height, width, minZ, maxZ;
+		    instr += size;
+		}
+	    } break;
 
-        /* First, disable lighting */
-        glDisable(GL_LIGHTING);
+	    case D3DOP_STATELIGHT: {
+	        int i;
+		TRACE("STATELIGHT       (%d)\n", count);
+		
+		for (i = 0; i < count; i++) {
+		    LPD3DSTATE ci = (LPD3DSTATE) instr;
+		    
+		    /* Handle the state transform */
+		    switch (ci->u1.dlstLightStateType) {
+		        case D3DLIGHTSTATE_MATERIAL: {
+			    IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) ci->u2.dwArg[0];
+			    TRACE("  MATERIAL\n");
+			    
+			    if (mat != NULL) {
+			        mat->activate(mat);
+			    } else {
+			        TRACE("    bad Material Handle\n");
+			    }
+			} break ;
 
-        /* Then do not put any transformation matrixes */
-        glMatrixMode(GL_MODELVIEW);
-        glLoadIdentity();
-        glMatrixMode(GL_PROJECTION);
-        glLoadIdentity();
+			case D3DLIGHTSTATE_AMBIENT: {
+			    float light[4];
+			    DWORD dwLightState = ci->u2.dwArg[0];
+			    TRACE("  AMBIENT\n");
+			    
+			    light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
+			    light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
+			    light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
+			    light[3] = 1.0;
+			    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
+			    
+			    TRACE("    R:%02lx G:%02lx B:%02lx A:%02lx\n",
+				  ((dwLightState >> 16) & 0xFF),
+				  ((dwLightState >>  8) & 0xFF),
+				  ((dwLightState >>  0) & 0xFF),
+				  ((dwLightState >> 24) & 0xFF));
+			} break ;
+			  
+			case D3DLIGHTSTATE_COLORMODEL: {
+			    TRACE("  COLORMODEL\n");
+			} break ;
 
-        if (ivp == NULL) {
-          ERR("No current viewport !\n");
-          /* Using standard values */
-          height = 640.0;
-          width = 480.0;
-          minZ = -10.0;
-          maxZ = 10.0;
-        } else {
-          height = (GLdouble) ivp->viewport.vp1.dwHeight;
-          width  = (GLdouble) ivp->viewport.vp1.dwWidth;
-          minZ   = (GLdouble) ivp->viewport.vp1.dvMinZ;
-          maxZ   = (GLdouble) ivp->viewport.vp1.dvMaxZ;
+			case D3DLIGHTSTATE_FOGMODE: {
+			    TRACE("  FOGMODE\n");
+			} break ;
 
-	  if (minZ == maxZ) {
-	    /* I do not know why, but many Dx 3.0 games have minZ = maxZ = 0.0 */
-	    minZ = 0.0;
-	    maxZ = 1.0;
+			case D3DLIGHTSTATE_FOGSTART: {
+			    TRACE("  FOGSTART\n");
+			} break ;
+
+			case D3DLIGHTSTATE_FOGEND: {
+			    TRACE("  FOGEND\n");
+			} break ;
+
+			case D3DLIGHTSTATE_FOGDENSITY: {
+			    TRACE("  FOGDENSITY\n");
+			} break ;
+
+			default:
+			    ERR("  Unhandled light state !! (%d)\n", (int) ci->u1.dlstLightStateType);
+			    break;
+		    }
+		    instr += size;
+	        }
+	    } break;
+
+	    case D3DOP_STATERENDER: {
+	        int i;
+		TRACE("STATERENDER      (%d)\n", count);
+
+		for (i = 0; i < count; i++) {
+		    LPD3DSTATE ci = (LPD3DSTATE) instr;
+		    
+		    /* Handle the state transform */
+		    set_render_state(ci->u1.drstRenderStateType, ci->u2.dwArg[0], &(odev->rs));
+
+		    instr += size;
+		}
+	    } break;
+
+	    case D3DOP_PROCESSVERTICES: {
+	        int i;
+		TRACE("PROCESSVERTICES  (%d)\n", count);
+
+		for (i = 0; i < count; i++) {
+		    LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr;
+
+		    TRACE("  Start : %d Dest : %d Count : %ld\n",
+			  ci->wStart, ci->wDest, ci->dwCount);
+		    TRACE("  Flags : ");
+		    if (TRACE_ON(ddraw)) {
+		        if (ci->dwFlags & D3DPROCESSVERTICES_COPY)
+			    DPRINTF("COPY ");
+			if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
+			    DPRINTF("NOCOLOR ");
+			if (ci->dwFlags == D3DPROCESSVERTICES_OPMASK)
+			    DPRINTF("OPMASK ");
+			if (ci->dwFlags & D3DPROCESSVERTICES_TRANSFORM)
+			    DPRINTF("TRANSFORM ");
+			if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT)
+			    DPRINTF("TRANSFORMLIGHT ");
+			if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
+			    DPRINTF("UPDATEEXTENTS ");
+			DPRINTF("\n");
+		    }
+		    
+		    /* This is where doing Direct3D on top on OpenGL is quite difficult.
+		       This method transforms a set of vertices using the CURRENT state
+		       (lighting, projection, ...) but does not rasterize them.
+		       They will only be put on screen later (with the POINT / LINE and
+		       TRIANGLE op-codes). The problem is that you can have a triangle
+		       with each point having been transformed using another state...
+		       
+		       In this implementation, I will emulate only ONE thing : each
+		       vertex can have its own "WORLD" transformation (this is used in the
+		       TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
+		       execute buffer use the same state.
+		       
+		       If I find applications that change other states, I will try to do a
+		       more 'fine-tuned' state emulation (but I may become quite tricky if
+		       it changes a light position in the middle of a triangle).
+		       
+		       In this case, a 'direct' approach (i.e. without using OpenGL, but
+		       writing our own 3D rasterizer) would be easier. */
+		    
+		    /* The current method (with the hypothesis that only the WORLD matrix
+		       will change between two points) is like this :
+		       - I transform 'manually' all the vertices with the current WORLD
+		         matrix and store them in the vertex buffer
+		       - during the rasterization phase, the WORLD matrix will be set to
+		         the Identity matrix */
+		    
+		    /* Enough for the moment */
+		    if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
+		        int nb;
+			D3DVERTEX  *src = ((LPD3DVERTEX)  (ilpBuff->desc.lpData + vs)) + ci->wStart;
+			OGL_Vertex *dst = ((OGL_Vertex *) (ilpBuff->vertex_data)) + ci->wDest;
+			D3DMATRIX *mat = odev->world_mat;
+			
+			TRACE("  World Matrix : (%p)\n", mat);
+			dump_mat(mat);
+
+			ilpBuff->vertex_type = D3DVT_VERTEX;
+			
+			for (nb = 0; nb < ci->dwCount; nb++) {
+			    /* For the moment, no normal transformation... */
+			    dst->nx = (src->u4.nx * mat->_11) + (src->u5.ny * mat->_21) + (src->u6.nz * mat->_31);
+			    dst->ny = (src->u4.nx * mat->_12) + (src->u5.ny * mat->_22) + (src->u6.nz * mat->_32);
+			    dst->nz = (src->u4.nx * mat->_13) + (src->u5.ny * mat->_23) + (src->u6.nz * mat->_33);
+			    
+			    dst->u  = src->u7.tu;
+			    dst->v  = src->u8.tv;
+			    
+			    /* Now, the matrix multiplication */
+			    dst->x = (src->u1.x * mat->_11) + (src->u2.y * mat->_21) + (src->u3.z * mat->_31) + (1.0 * mat->_41);
+			    dst->y = (src->u1.x * mat->_12) + (src->u2.y * mat->_22) + (src->u3.z * mat->_32) + (1.0 * mat->_42);
+			    dst->z = (src->u1.x * mat->_13) + (src->u2.y * mat->_23) + (src->u3.z * mat->_33) + (1.0 * mat->_43);
+			    dst->w = (src->u1.x * mat->_14) + (src->u2.y * mat->_24) + (src->u3.z * mat->_34) + (1.0 * mat->_44);
+			    
+			    src++;
+			    dst++;
+			}
+		    } else if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORM) {
+		        int nb;
+			D3DLVERTEX *src  = ((LPD3DLVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
+			OGL_LVertex *dst = ((OGL_LVertex *) (ilpBuff->vertex_data)) + ci->wDest;
+			D3DMATRIX *mat = odev->world_mat;
+			
+			TRACE("  World Matrix : (%p)\n", mat);
+			dump_mat(mat);
+			
+			ilpBuff->vertex_type = D3DVT_LVERTEX;
+			
+			for (nb = 0; nb < ci->dwCount; nb++) {
+			    dst->c  = src->u4.color;
+			    dst->sc = src->u5.specular;
+			    dst->u  = src->u6.tu;
+			    dst->v  = src->u7.tv;
+			    
+			    /* Now, the matrix multiplication */
+			    dst->x = (src->u1.x * mat->_11) + (src->u2.y * mat->_21) + (src->u3.z * mat->_31) + (1.0 * mat->_41);
+			    dst->y = (src->u1.x * mat->_12) + (src->u2.y * mat->_22) + (src->u3.z * mat->_32) + (1.0 * mat->_42);
+			    dst->z = (src->u1.x * mat->_13) + (src->u2.y * mat->_23) + (src->u3.z * mat->_33) + (1.0 * mat->_43);
+			    dst->w = (src->u1.x * mat->_14) + (src->u2.y * mat->_24) + (src->u3.z * mat->_34) + (1.0 * mat->_44);
+			    
+			    src++;
+			    dst++;
+			}
+		    } else if (ci->dwFlags == D3DPROCESSVERTICES_COPY) {
+		        D3DTLVERTEX *src = ((LPD3DTLVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
+			D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (ilpBuff->vertex_data)) + ci->wDest;
+			
+			ilpBuff->vertex_type = D3DVT_TLVERTEX;
+			
+			memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX));
+		    } else {
+		        ERR("Unhandled vertex processing !\n");
+		    }
+
+		    instr += size;
+		}
+	    } break;
+
+	    case D3DOP_TEXTURELOAD: {
+	        TRACE("TEXTURELOAD-s    (%d)\n", count);
+
+		instr += count * size;
+	    } break;
+
+	    case D3DOP_EXIT: {
+	        TRACE("EXIT             (%d)\n", count);
+		/* We did this instruction */
+		instr += size;
+		/* Exit this loop */
+		goto end_of_buffer;
+	    } break;
+
+	    case D3DOP_BRANCHFORWARD: {
+	        int i;
+		TRACE("BRANCHFORWARD    (%d)\n", count);
+
+		for (i = 0; i < count; i++) {
+		    LPD3DBRANCH ci = (LPD3DBRANCH) instr;
+
+		    if ((ilpBuff->data.dsStatus.dwStatus & ci->dwMask) == ci->dwValue) {
+		        if (!ci->bNegate) {
+			    TRACE(" Should branch to %ld\n", ci->dwOffset);
+			}
+		    } else {
+		        if (ci->bNegate) {
+			    TRACE(" Should branch to %ld\n", ci->dwOffset);
+			}
+		    }
+
+		    instr += size;
+		}
+	    } break;
+
+	    case D3DOP_SPAN: {
+	        TRACE("SPAN-s           (%d)\n", count);
+
+		instr += count * size;
+	    } break;
+
+	    case D3DOP_SETSTATUS: {
+	        int i;
+		TRACE("SETSTATUS        (%d)\n", count);
+
+		for (i = 0; i < count; i++) {
+		    LPD3DSTATUS ci = (LPD3DSTATUS) instr;
+		    
+		    ilpBuff->data.dsStatus = *ci;
+
+		    instr += size;
+		}
+	    } break;
+
+	    default:
+	        ERR("Unhandled OpCode !!!\n");
+	        /* Try to save ... */
+	        instr += count * size;
+	        break;
 	}
-        }
-
-        glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
-      } break;
-
-      default:
-	ERR("Unhandled vertex type !\n");
-	break;
-      }
-
-      switch (ilpBuff->vertex_type) {
-      case D3DVT_VERTEX:
-	TRIANGLE_LOOP(DO_VERTEX);
-	break;
-
-      case D3DVT_LVERTEX:
-	TRIANGLE_LOOP(DO_LVERTEX);
-	break;
-
-      case D3DVT_TLVERTEX:
-	TRIANGLE_LOOP(DO_TLVERTEX);
-	break;
-
-      default:
-	ERR("Unhandled vertex type !\n");
-      }
-
-    } break;
-
-    case D3DOP_MATRIXLOAD: {
-      TRACE("MATRIXLOAD-s     (%d)\n", count);
-
-      instr += count * size;
-    } break;
-
-    case D3DOP_MATRIXMULTIPLY: {
-      int i;
-      TRACE("MATRIXMULTIPLY   (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr;
-	LPD3DMATRIX a = (LPD3DMATRIX) ci->hDestMatrix;
-	LPD3DMATRIX b = (LPD3DMATRIX) ci->hSrcMatrix1;
-	LPD3DMATRIX c = (LPD3DMATRIX) ci->hSrcMatrix2;
-
-	TRACE("  Dest : %08lx  Src1 : %08lx  Src2 : %08lx\n",
-	      ci->hDestMatrix, ci->hSrcMatrix1, ci->hSrcMatrix2);
-
-	/* Do the multiplication..
-	   As I am VERY lazy, I let OpenGL do the multiplication for me */
-	glMatrixMode(GL_PROJECTION);
-	/* Save the current matrix */
-	glPushMatrix();
-	/* Load Matrix one and do the multiplication */
-	glLoadMatrixf((float *) c);
-	glMultMatrixf((float *) b);
-	glGetFloatv(GL_PROJECTION_MATRIX, (float *) a);
-	/* Restore the current matrix */
-	glPopMatrix();
-
-	instr += size;
-      }
-    } break;
-
-    case D3DOP_STATETRANSFORM: {
-      int i;
-      TRACE("STATETRANSFORM   (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DSTATE ci = (LPD3DSTATE) instr;
-
-	/* Handle the state transform */
-	switch (ci->u1.dtstTransformStateType) {
-	case D3DTRANSFORMSTATE_WORLD: {
-	  TRACE("  WORLD (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
-	  odev->world_mat = (D3DMATRIX*) ci->u2.dwArg[0];
-	} break;
-
-	case D3DTRANSFORMSTATE_VIEW: {
-	  TRACE("  VIEW (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
-	  odev->view_mat = (D3DMATRIX*) ci->u2.dwArg[0];
-	} break;
-
-	case D3DTRANSFORMSTATE_PROJECTION: {
-    	  TRACE("  PROJECTION (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
-	  odev->proj_mat = (D3DMATRIX*) ci->u2.dwArg[0];
-	} break;
-
-	default:
-	  ERR("  Unhandled state transformation !! (%d)\n", (int) ci->u1.dtstTransformStateType);
-	  break;
-
-	}
-
-	instr += size;
-      }
-    } break;
-
-    case D3DOP_STATELIGHT: {
-      int i;
-      TRACE("STATELIGHT       (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DSTATE ci = (LPD3DSTATE) instr;
-
-	/* Handle the state transform */
-	switch (ci->u1.dlstLightStateType) {
-	case D3DLIGHTSTATE_MATERIAL: {
-	  IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) ci->u2.dwArg[0];
-	  TRACE("  MATERIAL\n");
-
-	  if (mat != NULL) {
-	    mat->activate(mat);
-	  } else {
-	    TRACE("    bad Material Handle\n");
-	  }
-	} break ;
-
-	case D3DLIGHTSTATE_AMBIENT: {
-	  float light[4];
-	  DWORD dwLightState = ci->u2.dwArg[0];
-	  TRACE("  AMBIENT\n");
-
-	  light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
-	  light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
-	  light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
-	  light[3] = 1.0;
-	  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
-
-	  TRACE("    R:%02lx G:%02lx B:%02lx A:%02lx\n",
-		((dwLightState >> 16) & 0xFF),
-		((dwLightState >>  8) & 0xFF),
-		((dwLightState >>  0) & 0xFF),
-		((dwLightState >> 24) & 0xFF));
-	} break ;
-
-	case D3DLIGHTSTATE_COLORMODEL: {
-	  TRACE("  COLORMODEL\n");
-	} break ;
-
-	case D3DLIGHTSTATE_FOGMODE: {
-	  TRACE("  FOGMODE\n");
-	} break ;
-
-	case D3DLIGHTSTATE_FOGSTART: {
-	  TRACE("  FOGSTART\n");
-	} break ;
-
-	case D3DLIGHTSTATE_FOGEND: {
-	  TRACE("  FOGEND\n");
-	} break ;
-
-	case D3DLIGHTSTATE_FOGDENSITY: {
-	  TRACE("  FOGDENSITY\n");
-	} break ;
-
-	default:
-	  ERR("  Unhandled light state !! (%d)\n", (int) ci->u1.dlstLightStateType);
-	  break;
-	}
-	instr += size;
-      }
-    } break;
-
-    case D3DOP_STATERENDER: {
-      int i;
-      TRACE("STATERENDER      (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DSTATE ci = (LPD3DSTATE) instr;
-
-	/* Handle the state transform */
-	set_render_state(ci->u1.drstRenderStateType, ci->u2.dwArg[0], &(odev->rs));
-
-	instr += size;
-      }
-    } break;
-
-    case D3DOP_PROCESSVERTICES: {
-      int i;
-      TRACE("PROCESSVERTICES  (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr;
-
-	TRACE("  Start : %d Dest : %d Count : %ld\n",
-	      ci->wStart, ci->wDest, ci->dwCount);
-	TRACE("  Flags : ");
-	if (TRACE_ON(ddraw)) {
-	  if (ci->dwFlags & D3DPROCESSVERTICES_COPY)
-	    DPRINTF("COPY ");
-	  if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
-	    DPRINTF("NOCOLOR ");
-	  if (ci->dwFlags == D3DPROCESSVERTICES_OPMASK)
-	    DPRINTF("OPMASK ");
-	  if (ci->dwFlags & D3DPROCESSVERTICES_TRANSFORM)
-	    DPRINTF("TRANSFORM ");
-	  if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT)
-	    DPRINTF("TRANSFORMLIGHT ");
-	  if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
-	    DPRINTF("UPDATEEXTENTS ");
-	  DPRINTF("\n");
-	}
-
-	/* This is where doing Direct3D on top on OpenGL is quite difficult.
-	   This method transforms a set of vertices using the CURRENT state
-	   (lighting, projection, ...) but does not rasterize them.
-	   They will only be put on screen later (with the POINT / LINE and
-	   TRIANGLE op-codes). The problem is that you can have a triangle
-	   with each point having been transformed using another state...
-
-	   In this implementation, I will emulate only ONE thing : each
-	   vertex can have its own "WORLD" transformation (this is used in the
-	   TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
-	   execute buffer use the same state.
-
-	   If I find applications that change other states, I will try to do a
-	   more 'fine-tuned' state emulation (but I may become quite tricky if
-	   it changes a light position in the middle of a triangle).
-
-	   In this case, a 'direct' approach (i.e. without using OpenGL, but
-	   writing our own 3D rasterizer) would be easier. */
-
-	/* The current method (with the hypothesis that only the WORLD matrix
-	   will change between two points) is like this :
-	    - I transform 'manually' all the vertices with the current WORLD
-	      matrix and store them in the vertex buffer
-	    - during the rasterization phase, the WORLD matrix will be set to
-	      the Identity matrix */
-
-	/* Enough for the moment */
-	if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
-	  int nb;
-	  D3DVERTEX  *src = ((LPD3DVERTEX)  (ilpBuff->desc.lpData + vs)) + ci->wStart;
-	  OGL_Vertex *dst = ((OGL_Vertex *) (ilpBuff->vertex_data)) + ci->wDest;
-	  D3DMATRIX *mat = odev->world_mat;
-
-	  TRACE("  World Matrix : (%p)\n", mat);
-	  dump_mat(mat);
-
-	  ilpBuff->vertex_type = D3DVT_VERTEX;
-
-	  for (nb = 0; nb < ci->dwCount; nb++) {
-	    /* For the moment, no normal transformation... */
-	    dst->nx = (src->u4.nx * mat->_11) + (src->u5.ny * mat->_21) + (src->u6.nz * mat->_31);
-	    dst->ny = (src->u4.nx * mat->_12) + (src->u5.ny * mat->_22) + (src->u6.nz * mat->_32);
-	    dst->nz = (src->u4.nx * mat->_13) + (src->u5.ny * mat->_23) + (src->u6.nz * mat->_33);
-
-	    dst->u  = src->u7.tu;
-	    dst->v  = src->u8.tv;
-
-	    /* Now, the matrix multiplication */
-	    dst->x = (src->u1.x * mat->_11) + (src->u2.y * mat->_21) + (src->u3.z * mat->_31) + (1.0 * mat->_41);
-	    dst->y = (src->u1.x * mat->_12) + (src->u2.y * mat->_22) + (src->u3.z * mat->_32) + (1.0 * mat->_42);
-	    dst->z = (src->u1.x * mat->_13) + (src->u2.y * mat->_23) + (src->u3.z * mat->_33) + (1.0 * mat->_43);
-	    dst->w = (src->u1.x * mat->_14) + (src->u2.y * mat->_24) + (src->u3.z * mat->_34) + (1.0 * mat->_44);
-
-	    src++;
-	    dst++;
-	  }
-	} else if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORM) {
-	  int nb;
-	  D3DLVERTEX *src  = ((LPD3DLVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
-	  OGL_LVertex *dst = ((OGL_LVertex *) (ilpBuff->vertex_data)) + ci->wDest;
-	  D3DMATRIX *mat = odev->world_mat;
-
-	  TRACE("  World Matrix : (%p)\n", mat);
-	  dump_mat(mat);
-
-	  ilpBuff->vertex_type = D3DVT_LVERTEX;
-
-	  for (nb = 0; nb < ci->dwCount; nb++) {
-	    dst->c  = src->u4.color;
-	    dst->sc = src->u5.specular;
-	    dst->u  = src->u6.tu;
-	    dst->v  = src->u7.tv;
-
-	    /* Now, the matrix multiplication */
-	    dst->x = (src->u1.x * mat->_11) + (src->u2.y * mat->_21) + (src->u3.z * mat->_31) + (1.0 * mat->_41);
-	    dst->y = (src->u1.x * mat->_12) + (src->u2.y * mat->_22) + (src->u3.z * mat->_32) + (1.0 * mat->_42);
-	    dst->z = (src->u1.x * mat->_13) + (src->u2.y * mat->_23) + (src->u3.z * mat->_33) + (1.0 * mat->_43);
-	    dst->w = (src->u1.x * mat->_14) + (src->u2.y * mat->_24) + (src->u3.z * mat->_34) + (1.0 * mat->_44);
-
-	    src++;
-	    dst++;
-	  }
-	} else if (ci->dwFlags == D3DPROCESSVERTICES_COPY) {
-	  D3DTLVERTEX *src = ((LPD3DTLVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
-	  D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (ilpBuff->vertex_data)) + ci->wDest;
-
-	  ilpBuff->vertex_type = D3DVT_TLVERTEX;
-
-	  memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX));
-	} else {
-	  ERR("Unhandled vertex processing !\n");
-	}
-
-	instr += size;
-      }
-    } break;
-
-    case D3DOP_TEXTURELOAD: {
-      TRACE("TEXTURELOAD-s    (%d)\n", count);
-
-      instr += count * size;
-    } break;
-
-    case D3DOP_EXIT: {
-      TRACE("EXIT             (%d)\n", count);
-      /* We did this instruction */
-      instr += size;
-      /* Exit this loop */
-      goto end_of_buffer;
-    } break;
-
-    case D3DOP_BRANCHFORWARD: {
-      int i;
-      TRACE("BRANCHFORWARD    (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DBRANCH ci = (LPD3DBRANCH) instr;
-
-	if ((ilpBuff->data.dsStatus.dwStatus & ci->dwMask) == ci->dwValue) {
-	  if (!ci->bNegate) {
-	    TRACE(" Should branch to %ld\n", ci->dwOffset);
-	  }
-	} else {
-	  if (ci->bNegate) {
-	    TRACE(" Should branch to %ld\n", ci->dwOffset);
-	  }
-	}
-
-	instr += size;
-      }
-    } break;
-
-    case D3DOP_SPAN: {
-      TRACE("SPAN-s           (%d)\n", count);
-
-      instr += count * size;
-    } break;
-
-    case D3DOP_SETSTATUS: {
-      int i;
-      TRACE("SETSTATUS        (%d)\n", count);
-
-      for (i = 0; i < count; i++) {
-	LPD3DSTATUS ci = (LPD3DSTATUS) instr;
-
-	ilpBuff->data.dsStatus = *ci;
-
-	instr += size;
-      }
-    } break;
-
-    default:
-      ERR("Unhandled OpCode !!!\n");
-      /* Try to save ... */
-      instr += count * size;
-      break;
     }
-  }
 
- end_of_buffer:
-  LEAVE_GL();
+  end_of_buffer:
+    LEAVE_GL();
+#else
+    FIXME("Need to make this function compile again !!!\n");
+#endif
 }
 
-/*******************************************************************************
- *				ExecuteBuffer Creation functions
- */
-LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc)
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface,
+                                                 REFIID riid,
+                                                 LPVOID* obp)
 {
-  IDirect3DExecuteBufferImpl* eb;
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
 
-  eb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DExecuteBufferImpl));
-  eb->ref = 1;
-  ICOM_VTBL(eb) = &executebuffer_vtable;
-  eb->d3ddev = d3ddev;
+    *obp = NULL;
 
-  /* Initializes memory */
-  eb->desc = *lpDesc;
-
-  /* No buffer given */
-  if (!(eb->desc.dwFlags & D3DDEB_LPDATA))
-    eb->desc.lpData = NULL;
-
-  /* No buffer size given */
-  if (!(lpDesc->dwFlags & D3DDEB_BUFSIZE))
-    eb->desc.dwBufferSize = 0;
-
-  /* Create buffer if asked */
-  if ((eb->desc.lpData == NULL) && (eb->desc.dwBufferSize > 0)) {
-    eb->need_free = TRUE;
-    eb->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,eb->desc.dwBufferSize);
-  } else {
-    eb->need_free = FALSE;
-  }
-
-  /* No vertices for the moment */
-  eb->vertex_data = NULL;
-
-  eb->desc.dwFlags |= D3DDEB_LPDATA;
-
-  eb->execute = execute;
-
-  return (LPDIRECT3DEXECUTEBUFFER)eb;
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+        IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer));
+	*obp = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DMaterial, riid ) ) {
+        IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer));
+        *obp = ICOM_INTERFACE(This, IDirect3DExecuteBuffer);
+	TRACE("  Creating IDirect3DExecuteBuffer 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;
 }
 
-/*******************************************************************************
- *				IDirect3ExecuteBuffer methods
- */
-
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface,
-							    REFIID riid,
-							    LPVOID* ppvObj)
+ULONG WINAPI
+Main_IDirect3DExecuteBufferImpl_1_AddRef(LPDIRECT3DEXECUTEBUFFER iface)
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-
-  return S_OK;
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    FIXME("(%p/%p)->()incrementing from %lu.\n", This, iface, This->ref );
+    return ++(This->ref);
 }
 
-
-
-static ULONG WINAPI IDirect3DExecuteBufferImpl_AddRef(LPDIRECT3DEXECUTEBUFFER iface)
+ULONG WINAPI
+Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface)
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    TRACE("(%p/%p)->()decrementing from %lu.\n", This, iface, This->ref);
+    if (!--(This->ref)) {
+        if ((This->desc.lpData != NULL) && This->need_free)
+	    HeapFree(GetProcessHeap(),0,This->desc.lpData);
+	if (This->vertex_data != NULL)
+	    HeapFree(GetProcessHeap(),0,This->vertex_data);
+	HeapFree(GetProcessHeap(),0,This);
+	return 0;
+    }
 
-  return ++(This->ref);
+    return This->ref;
 }
 
-
-
-static ULONG WINAPI IDirect3DExecuteBufferImpl_Release(LPDIRECT3DEXECUTEBUFFER iface)
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_Initialize(LPDIRECT3DEXECUTEBUFFER iface,
+                                             LPDIRECT3DDEVICE lpDirect3DDevice,
+                                             LPD3DEXECUTEBUFFERDESC lpDesc)
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    TRACE("(%p/%p)->(%p,%p) no-op....\n", This, iface, lpDirect3DDevice, lpDesc);
+    return DD_OK;
+}
 
-  if (!--(This->ref)) {
-    if ((This->desc.lpData != NULL) && This->need_free)
-      HeapFree(GetProcessHeap(),0,This->desc.lpData);
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_Lock(LPDIRECT3DEXECUTEBUFFER iface,
+                                       LPD3DEXECUTEBUFFERDESC lpDesc)
+{
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    DWORD dwSize;
+    TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpDesc);
 
+    dwSize = lpDesc->dwSize;
+    memset(lpDesc, 0, dwSize);
+    memcpy(lpDesc, &This->desc, dwSize);
+    
+    if (TRACE_ON(ddraw)) {
+        TRACE("  Returning description : \n");
+	_dump_D3DEXECUTEBUFFERDESC(lpDesc);
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_Unlock(LPDIRECT3DEXECUTEBUFFER iface)
+{
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    TRACE("(%p/%p)->() no-op...\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
+                                                 LPD3DEXECUTEDATA lpData)
+{
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    DWORD nbvert;
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
+
+    memcpy(&This->data, lpData, lpData->dwSize);
+
+    /* Get the number of vertices in the execute buffer */
+    nbvert = This->data.dwVertexCount;
+    
+    /* Prepares the transformed vertex buffer */
     if (This->vertex_data != NULL)
-      HeapFree(GetProcessHeap(),0,This->vertex_data);
+        HeapFree(GetProcessHeap(), 0, This->vertex_data);
+    This->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(OGL_Vertex));
 
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
+    if (TRACE_ON(ddraw)) {
+        _dump_executedata(lpData);
+    }
 
-  return This->ref;
+    return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_Initialize(LPDIRECT3DEXECUTEBUFFER iface,
-							LPDIRECT3DDEVICE lpDirect3DDevice,
-							LPD3DEXECUTEBUFFERDESC lpDesc)
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
+                                                 LPD3DEXECUTEDATA lpData)
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lpDirect3DDevice, lpDesc);
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    DWORD dwSize;
+    TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpData);
 
-  return DD_OK;
+    dwSize = lpData->dwSize;
+    memset(lpData, 0, dwSize);
+    memcpy(lpData, &This->data, dwSize);
+
+    if (TRACE_ON(ddraw)) {
+        TRACE("Returning data : \n");
+	_dump_executedata(lpData);
+    }
+
+    return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_Lock(LPDIRECT3DEXECUTEBUFFER iface,
-						  LPD3DEXECUTEBUFFERDESC lpDesc)
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_Validate(LPDIRECT3DEXECUTEBUFFER iface,
+                                           LPDWORD lpdwOffset,
+                                           LPD3DVALIDATECALLBACK lpFunc,
+                                           LPVOID lpUserArg,
+                                           DWORD dwReserved)
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  TRACE("(%p)->(%p)\n", This, lpDesc);
-
-  /* Copies the buffer description */
-  *lpDesc = This->desc;
-
-  return DD_OK;
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    FIXME("(%p/%p)->(%p,%p,%p,%08lx): stub!\n", This, iface, lpdwOffset, lpFunc, lpUserArg, dwReserved);
+    return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_Unlock(LPDIRECT3DEXECUTEBUFFER iface)
+HRESULT WINAPI
+Main_IDirect3DExecuteBufferImpl_1_Optimize(LPDIRECT3DEXECUTEBUFFER iface,
+                                           DWORD dwDummy)
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  TRACE("(%p)->()\n", This);
-
-  return DD_OK;
+    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
+    TRACE("(%p/%p)->(%08lx) no-op...\n", This, iface, dwDummy);
+    return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
-							    LPD3DEXECUTEDATA lpData)
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DExecuteBuffer.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DExecuteBuffer) VTABLE_IDirect3DExecuteBuffer =
 {
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  DWORD nbvert;
-
-  TRACE("(%p)->(%p)\n", This, lpData);
-
-  This->data = *lpData;
-
-  /* Get the number of vertices in the execute buffer */
-  nbvert = This->data.dwVertexCount;
-
-  /* Prepares the transformed vertex buffer */
-  if (This->vertex_data != NULL)
-    HeapFree(GetProcessHeap(), 0, This->vertex_data);
-  This->vertex_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,nbvert * sizeof(OGL_Vertex));
-
-
-  if (TRACE_ON(ddraw)) {
-    _dump_executedata(lpData);
-  }
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
-							    LPD3DEXECUTEDATA lpData)
-{
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  TRACE("(%p)->(%p): stub\n", This, lpData);
-
-  *lpData = This->data;
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_Validate(LPDIRECT3DEXECUTEBUFFER iface,
-						      LPDWORD lpdwOffset,
-						      LPD3DVALIDATECALLBACK lpFunc,
-						      LPVOID lpUserArg,
-						      DWORD dwReserved)
-{
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  TRACE("(%p)->(%p,%p,%p,%lu)\n", This, lpdwOffset, lpFunc, lpUserArg, dwReserved);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DExecuteBufferImpl_Optimize(LPDIRECT3DEXECUTEBUFFER iface,
-						      DWORD dwReserved)
-{
-  ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
-  TRACE("(%p)->(%lu)\n", This, dwReserved);
-
-  return DD_OK;
-}
-
-
-/*******************************************************************************
- *				IDirect3DLight VTable
- */
-static ICOM_VTABLE(IDirect3DExecuteBuffer) executebuffer_vtable =
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  IDirect3DExecuteBufferImpl_QueryInterface,
-  IDirect3DExecuteBufferImpl_AddRef,
-  IDirect3DExecuteBufferImpl_Release,
-  /*** IDirect3DExecuteBuffer methods ***/
-  IDirect3DExecuteBufferImpl_Initialize,
-  IDirect3DExecuteBufferImpl_Lock,
-  IDirect3DExecuteBufferImpl_Unlock,
-  IDirect3DExecuteBufferImpl_SetExecuteData,
-  IDirect3DExecuteBufferImpl_GetExecuteData,
-  IDirect3DExecuteBufferImpl_Validate,
-  IDirect3DExecuteBufferImpl_Optimize
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Main_IDirect3DExecuteBufferImpl_1_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DExecuteBufferImpl_1_AddRef,
+    XCAST(Release) Main_IDirect3DExecuteBufferImpl_1_Release,
+    XCAST(Initialize) Main_IDirect3DExecuteBufferImpl_1_Initialize,
+    XCAST(Lock) Main_IDirect3DExecuteBufferImpl_1_Lock,
+    XCAST(Unlock) Main_IDirect3DExecuteBufferImpl_1_Unlock,
+    XCAST(SetExecuteData) Main_IDirect3DExecuteBufferImpl_1_SetExecuteData,
+    XCAST(GetExecuteData) Main_IDirect3DExecuteBufferImpl_1_GetExecuteData,
+    XCAST(Validate) Main_IDirect3DExecuteBufferImpl_1_Validate,
+    XCAST(Optimize) Main_IDirect3DExecuteBufferImpl_1_Optimize,
 };
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirect3DImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc)
+{
+    IDirect3DExecuteBufferImpl* object;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
+
+    ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, VTABLE_IDirect3DExecuteBuffer);
+    
+    object->ref = 1;
+    object->d3d = d3d;
+    object->d3ddev = d3ddev;
+
+    /* Initializes memory */
+    memcpy(&object->desc, &lpDesc, lpDesc->dwSize);
+
+    /* No buffer given */
+    if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
+        object->desc.lpData = NULL;
+
+    /* No buffer size given */
+    if ((lpDesc->dwFlags & D3DDEB_BUFSIZE) == 0)
+        object->desc.dwBufferSize = 0;
+
+    /* Create buffer if asked */
+    if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0)) {
+        object->need_free = TRUE;
+	object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
+    } else {
+        object->need_free = FALSE;
+    }
+
+    /* No vertices for the moment */
+    object->vertex_data = NULL;
+
+    object->desc.dwFlags |= D3DDEB_LPDATA;
+
+    object->execute = execute;
+
+    *obj = object;
+    
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return DD_OK;
+}
diff --git a/dlls/ddraw/d3dlight.c b/dlls/ddraw/d3dlight.c
index 9d23e86..94d77ce 100644
--- a/dlls/ddraw/d3dlight.c
+++ b/dlls/ddraw/d3dlight.c
@@ -1,5 +1,5 @@
 /* Direct3D Light
- * Copyright (c) 1998 Lionel ULMER
+ * Copyright (c) 1998 / 2002 Lionel ULMER
  *
  * This file contains the implementation of Direct3DLight.
  *
@@ -26,242 +26,223 @@
 #include "d3d.h"
 #include "wine/debug.h"
 
+#include "d3d_private.h"
 #include "mesa_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-#define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
+/* First, the 'main' interface... */
+HRESULT WINAPI
+Main_IDirect3DLightImpl_1_QueryInterface(LPDIRECT3DLIGHT iface,
+                                         REFIID riid,
+                                         LPVOID* obp)
+{
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    FIXME("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp);
+    return DD_OK;
+}
 
-static ICOM_VTABLE(IDirect3DLight) light_vtable;
+ULONG WINAPI
+Main_IDirect3DLightImpl_1_AddRef(LPDIRECT3DLIGHT iface)
+{
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
+    return ++(This->ref);
+}
 
-enum {
-  D3D_1,
-  D3D_2
-};
+ULONG WINAPI
+Main_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface)
+{
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (!--(This->ref)) {
+        HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI
+Main_IDirect3DLightImpl_1_Initialize(LPDIRECT3DLIGHT iface,
+                                     LPDIRECT3D lpDirect3D)
+{
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
+    return DD_OK;
+}
+
+/*** IDirect3DLight methods ***/
+static void dump_light(LPD3DLIGHT2 light)
+{
+    DPRINTF("    - dwSize : %ld\n", light->dwSize);
+}
+
+HRESULT WINAPI
+Main_IDirect3DLightImpl_1_SetLight(LPDIRECT3DLIGHT iface,
+                                   LPD3DLIGHT lpLight)
+{
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpLight);
+    if (TRACE_ON(ddraw)) {
+        TRACE("  Light definition : \n");
+	dump_light((LPD3DLIGHT2) lpLight);
+    }
+    memcpy(&This->light, lpLight, lpLight->dwSize);
+    if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
+        This->update(This);        
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DLightImpl_1_GetLight(LPDIRECT3DLIGHT iface,
+                                   LPD3DLIGHT lpLight)
+{
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpLight);
+    if (TRACE_ON(ddraw)) {
+        TRACE("  Returning light definition : \n");
+	dump_light(&This->light);
+    }
+    memcpy(lpLight, &This->light, lpLight->dwSize);
+    return DD_OK;
+}
 
 /*******************************************************************************
  *				Light static functions
  */
 static const float zero_value[] = {
-  0.0, 0.0, 0.0, 0.0
+    0.0, 0.0, 0.0, 0.0
 };
 
 static void update(IDirect3DLightImpl* This) {
-  D3DLPRIVATE(This);
-  switch (This->light.dltType) {
-  case D3DLIGHT_POINT:         /* 1 */
-    TRACE("Activating POINT\n");
-    break;
+    IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This;
+    ENTER_GL();
+    switch (glThis->parent.light.dltType) {
+        case D3DLIGHT_POINT:         /* 1 */
+            TRACE("Activating POINT\n");
+	    break;
 
-  case D3DLIGHT_SPOT:          /* 2 */
-    TRACE("Activating SPOT\n");
-    break;
+	case D3DLIGHT_SPOT:          /* 2 */
+	    TRACE("Activating SPOT\n");
+	    break;
 
-  case D3DLIGHT_DIRECTIONAL: {  /* 3 */
-    float direction[4];
+	case D3DLIGHT_DIRECTIONAL: {  /* 3 */
+	    float direction[4];
 
-    TRACE("Activating DIRECTIONAL\n");
-    TRACE("  direction : %f %f %f\n",
-	  This->light.dvDirection.u1.x,
-	  This->light.dvDirection.u2.y,
-	  This->light.dvDirection.u3.z);
-    _dump_colorvalue(" color    ", This->light.dcvColor);
+	    TRACE("Activating DIRECTIONAL\n");
+	    TRACE("  direction : %f %f %f\n",
+		  glThis->parent.light.dvDirection.u1.x,
+		  glThis->parent.light.dvDirection.u2.y,
+		  glThis->parent.light.dvDirection.u3.z);
+	    _dump_colorvalue(" color    ", glThis->parent.light.dcvColor);
+	    
+	    glLightfv(glThis->light_num, GL_AMBIENT, (float *) zero_value);
+	    glLightfv(glThis->light_num, GL_DIFFUSE, (float *) &(glThis->parent.light.dcvColor));
 
-    glLightfv(dlpriv->light_num, GL_AMBIENT, (float *) zero_value);
-    glLightfv(dlpriv->light_num, GL_DIFFUSE, (float *) &(This->light.dcvColor));
+	    direction[0] = -glThis->parent.light.dvDirection.u1.x;
+	    direction[1] = -glThis->parent.light.dvDirection.u2.y;
+	    direction[2] = -glThis->parent.light.dvDirection.u3.z;
+	    direction[3] = 0.0; /* This is a directional light */
 
-    direction[0] = -This->light.dvDirection.u1.x;
-    direction[1] = -This->light.dvDirection.u2.y;
-    direction[2] = -This->light.dvDirection.u3.z;
-    direction[3] = 0.0; /* This is a directional light */
+	    glLightfv(glThis->light_num, GL_POSITION, (float *) direction);
+	} break;
 
-    glLightfv(dlpriv->light_num, GL_POSITION, (float *) direction);
-  } break;
+	case D3DLIGHT_PARALLELPOINT:  /* 4 */
+	    TRACE("Activating PARRALLEL-POINT\n");
+	    break;
 
-  case D3DLIGHT_PARALLELPOINT:  /* 4 */
-    TRACE("Activating PARRALLEL-POINT\n");
-    break;
-
-  default:
-    TRACE("Not a known Light Type: %d\n",This->light.dltType);
-    break;
-  }
+	default:
+	    WARN("Not a known Light Type: %d\n", glThis->parent.light.dltType);
+	    break;
+    }
+    LEAVE_GL();
 }
 
 static void activate(IDirect3DLightImpl* This) {
-  D3DLPRIVATE(This);
-
-  ENTER_GL();
-  update(This);
-  /* If was not active, activate it */
-  if (This->is_active == 0) {
-    glEnable(dlpriv->light_num);
-    This->is_active = 1;
-  }
-  LEAVE_GL();
-
-  return ;
-}
-
-/*******************************************************************************
- *				Light Creation functions
- */
-LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2)
-{
-  IDirect3DLightImpl* light;
-
-  light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
-  light->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dl_private));
-  light->ref = 1;
-  ICOM_VTBL(light) = &light_vtable;
-  light->d3d.d3d2 = d3d2;
-  light->type = D3D_2;
-
-  light->next = NULL;
-  light->prev = NULL;
-  light->activate = activate;
-  light->is_active = 0;
-
-  return (LPDIRECT3DLIGHT)light;
-}
-
-LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1)
-{
-  IDirect3DLightImpl* light;
-
-  light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
-  light->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dl_private));
-  light->ref = 1;
-  ICOM_VTBL(light) = &light_vtable;
-
-  light->d3d.d3d1 = d3d1;
-  light->type = D3D_1;
-
-  light->next = NULL;
-  light->prev = NULL;
-  light->activate = activate;
-  light->is_active = 0;
-
-  return (LPDIRECT3DLIGHT)light;
-}
-
-/*******************************************************************************
- *				IDirect3DLight methods
- */
-
-static HRESULT WINAPI IDirect3DLightImpl_QueryInterface(LPDIRECT3DLIGHT iface,
-						    REFIID riid,
-						    LPVOID* ppvObj)
-{
-  ICOM_THIS(IDirect3DLightImpl,iface);
-
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-
-  return S_OK;
-}
-
-
-
-static ULONG WINAPI IDirect3DLightImpl_AddRef(LPDIRECT3DLIGHT iface)
-{
-  ICOM_THIS(IDirect3DLightImpl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
-
-  return ++(This->ref);
-}
-
-
-
-static ULONG WINAPI IDirect3DLightImpl_Release(LPDIRECT3DLIGHT iface)
-{
-  ICOM_THIS(IDirect3DLightImpl,iface);
-  TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-  if (!--(This->ref)) {
-    HeapFree(GetProcessHeap(),0,This->private);
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-
-  return This->ref;
-}
-
-/*** IDirect3DLight methods ***/
-static void dump_light(LPD3DLIGHT light)
-{
-  DPRINTF("  dwSize : %ld\n", light->dwSize);
-}
-
-static HRESULT WINAPI IDirect3DLightImpl_GetLight(LPDIRECT3DLIGHT iface,
-					      LPD3DLIGHT lpLight)
-{
-  ICOM_THIS(IDirect3DLightImpl,iface);
-  TRACE("(%p)->(%p)\n", This, lpLight);
-  if (TRACE_ON(ddraw))
-    dump_light(lpLight);
-
-  /* Copies the light structure */
-  switch (This->type) {
-  case D3D_1:
-    *((LPD3DLIGHT)lpLight) = *((LPD3DLIGHT) &(This->light));
-    break;
-  case D3D_2:
-    *((LPD3DLIGHT2)lpLight) = *((LPD3DLIGHT2) &(This->light));
-    break;
-  }
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DLightImpl_SetLight(LPDIRECT3DLIGHT iface,
-					      LPD3DLIGHT lpLight)
-{
-  ICOM_THIS(IDirect3DLightImpl,iface);
-  TRACE("(%p)->(%p)\n", This, lpLight);
-  if (TRACE_ON(ddraw))
-    dump_light(lpLight);
-
-  /* Stores the light */
-  switch (This->type) {
-  case D3D_1:
-    *((LPD3DLIGHT) &(This->light)) = *((LPD3DLIGHT)lpLight);
-    break;
-  case D3D_2:
-    *((LPD3DLIGHT2) &(This->light)) = *((LPD3DLIGHT2)lpLight);
-    break;
-  }
-
-  ENTER_GL();
-  if (This->is_active)
+    IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This;
+    ENTER_GL();
     update(This);
-  LEAVE_GL();
-
-  return DD_OK;
+    /* If was not active, activate it */
+    if ((glThis->parent.light.dwFlags & D3DLIGHT_ACTIVE) == 0) {
+        glEnable(glThis->light_num);
+	glThis->parent.light.dwFlags |= D3DLIGHT_ACTIVE;
+    }
+    LEAVE_GL();
 }
 
-static HRESULT WINAPI IDirect3DLightImpl_Initialize(LPDIRECT3DLIGHT iface,
-						LPDIRECT3D lpDirect3D)
-
-{
-  ICOM_THIS(IDirect3DLightImpl,iface);
-  TRACE("(%p)->(%p)\n", This, lpDirect3D);
-
-  return DDERR_ALREADYINITIALIZED;
+static void desactivate(IDirect3DLightImpl* This) {
+    IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This;
+    ENTER_GL();
+    /* If was not active, activate it */
+    if ((glThis->parent.light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
+        glDisable(glThis->light_num);
+	glThis->parent.light.dwFlags &= ~D3DLIGHT_ACTIVE;
+    }
+    LEAVE_GL();
 }
 
-
-/*******************************************************************************
- *				IDirect3DLight VTable
- */
-static ICOM_VTABLE(IDirect3DLight) light_vtable =
+ULONG WINAPI
+GL_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface)
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  IDirect3DLightImpl_QueryInterface,
-  IDirect3DLightImpl_AddRef,
-  IDirect3DLightImpl_Release,
-  /*** IDirect3DLight methods ***/
-  IDirect3DLightImpl_Initialize,
-  IDirect3DLightImpl_SetLight,
-  IDirect3DLightImpl_GetLight
+    ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
+    IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This;
+    
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (!--(This->ref)) {
+        ((IDirect3DGLImpl *) This->d3d)->light_released(This->d3d, glThis->light_num);
+        HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    return This->ref;
+}
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DLight.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DLight) VTABLE_IDirect3DLight =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Main_IDirect3DLightImpl_1_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DLightImpl_1_AddRef,
+    XCAST(Release) GL_IDirect3DLightImpl_1_Release,
+    XCAST(Initialize) Main_IDirect3DLightImpl_1_Initialize,
+    XCAST(SetLight) Main_IDirect3DLightImpl_1_SetLight,
+    XCAST(GetLight) Main_IDirect3DLightImpl_1_GetLight,
 };
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+
+
+HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirect3DImpl *d3d, GLenum light_num)
+{
+    IDirect3DLightImpl *object;
+    IDirect3DLightGLImpl *gl_object;
+    
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DLightGLImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+    gl_object = (IDirect3DLightGLImpl *) object;
+    
+    object->ref = 1;
+    object->d3d = d3d;
+    object->next = NULL;
+    object->activate = activate;
+    object->desactivate = desactivate;
+    object->update = update;
+    gl_object->light_num = light_num;
+    
+    ICOM_INIT_INTERFACE(object, IDirect3DLight, VTABLE_IDirect3DLight);
+
+    *obj = object;
+
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return D3D_OK;
+}
diff --git a/dlls/ddraw/d3dmaterial.c b/dlls/ddraw/d3dmaterial.c
index ff8dbdd..b06aee1 100644
--- a/dlls/ddraw/d3dmaterial.c
+++ b/dlls/ddraw/d3dmaterial.c
@@ -1,7 +1,7 @@
 /* Direct3D Material
- * Copyright (c) 1998 Lionel ULMER
+ * Copyright (c) 2002 Lionel ULMER
  *
- * This file contains the implementation of Direct3DMaterial2.
+ * This file contains the implementation of Direct3DMaterial.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,25 +26,267 @@
 #include "d3d.h"
 #include "wine/debug.h"
 
+#include "d3d_private.h"
 #include "mesa_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-static ICOM_VTABLE(IDirect3DMaterial2) material2_vtable;
-static ICOM_VTABLE(IDirect3DMaterial) material_vtable;
+static void dump_material(LPD3DMATERIAL mat)
+{
+    DPRINTF("  dwSize : %ld\n", mat->dwSize);
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface(LPDIRECT3DMATERIAL3 iface,
+                                                  REFIID riid,
+                                                  LPVOID* obp)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
+    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
+
+    *obp = NULL;
+
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+        IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
+	*obp = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DMaterial, riid ) ) {
+        IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
+        *obp = ICOM_INTERFACE(This, IDirect3DMaterial);
+	TRACE("  Creating IDirect3DMaterial interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DMaterial2, riid ) ) {
+        IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
+        *obp = ICOM_INTERFACE(This, IDirect3DMaterial2);
+	TRACE("  Creating IDirect3DMaterial2 interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DMaterial3, riid ) ) {
+        IDirect3DMaterial_AddRef(ICOM_INTERFACE(This, IDirect3DMaterial));
+        *obp = ICOM_INTERFACE(This, IDirect3DMaterial3);
+	TRACE("  Creating IDirect3DMaterial3 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;
+}
+
+ULONG WINAPI
+Main_IDirect3DMaterialImpl_3_2T_1T_AddRef(LPDIRECT3DMATERIAL3 iface)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
+    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI
+Main_IDirect3DMaterialImpl_3_2T_1T_Release(LPDIRECT3DMATERIAL3 iface)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (!--(This->ref)) {
+        HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_1_Initialize(LPDIRECT3DMATERIAL iface,
+                                        LPDIRECT3D lpDirect3D)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
+    TRACE("(%p/%p)->(%p) no-op...!\n", This, iface, lpDirect3D);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_1_Reserve(LPDIRECT3DMATERIAL iface)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
+    TRACE("(%p/%p)->() not implemented.\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_1_Unreserve(LPDIRECT3DMATERIAL iface)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface);
+    FIXME("(%p/%p)->() not implemented.\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial(LPDIRECT3DMATERIAL3 iface,
+                                               LPD3DMATERIAL lpMat)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
+    if (TRACE_ON(ddraw))
+        dump_material(lpMat);
+
+    /* Stores the material */
+    memset(&This->mat, 0, sizeof(This->mat));
+    memcpy(&This->mat, lpMat, lpMat->dwSize);
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial(LPDIRECT3DMATERIAL3 iface,
+                                               LPD3DMATERIAL lpMat)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
+    DWORD dwSize;
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
+    if (TRACE_ON(ddraw)) {
+        TRACE("  Returning material : ");
+        dump_material(&This->mat);
+    }
+
+    /* Copies the material structure */
+    dwSize = lpMat->dwSize;
+    memset(lpMat, 0, dwSize);
+    memcpy(lpMat, &This->mat, dwSize);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle(LPDIRECT3DMATERIAL3 iface,
+					     LPDIRECT3DDEVICE3 lpDirect3DDevice3,
+					     LPD3DMATERIALHANDLE lpHandle)
+{
+    ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice3, lpHandle);
+
+    This->active_device = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, lpDirect3DDevice3);
+    *lpHandle = (DWORD) This; /* Warning: this is not 64 bit clean.
+			         Maybe also we need to store this material somewhere in the device ? */
+
+    TRACE(" returning handle %08lx.\n", *lpHandle);
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_2_GetHandle(LPDIRECT3DMATERIAL2 iface,
+					LPDIRECT3DDEVICE2 lpDirect3DDevice2,
+					LPD3DMATERIALHANDLE lpHandle)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice2, lpHandle);
+    return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
+					COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, lpDirect3DDevice2),
+					lpHandle);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_1_GetHandle(LPDIRECT3DMATERIAL iface,
+					LPDIRECT3DDEVICE lpDirect3DDevice,
+					LPD3DMATERIALHANDLE lpHandle)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice, lpHandle);
+    return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
+					COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, lpDirect3DDevice),
+					lpHandle);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_2_QueryInterface(LPDIRECT3DMATERIAL2 iface,
+                                             REFIID riid,
+                                             LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
+                                             riid,
+                                             obp);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_1_QueryInterface(LPDIRECT3DMATERIAL iface,
+                                             REFIID riid,
+                                             LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
+                                             riid,
+                                             obp);
+}
+
+ULONG WINAPI
+Thunk_IDirect3DMaterialImpl_2_AddRef(LPDIRECT3DMATERIAL2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DMaterialImpl_1_AddRef(LPDIRECT3DMATERIAL iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DMaterialImpl_2_Release(LPDIRECT3DMATERIAL2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DMaterialImpl_1_Release(LPDIRECT3DMATERIAL iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface);
+    return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_2_SetMaterial(LPDIRECT3DMATERIAL2 iface,
+                                          LPD3DMATERIAL lpMat)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
+                                          lpMat);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_1_SetMaterial(LPDIRECT3DMATERIAL iface,
+                                          LPD3DMATERIAL lpMat)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
+                                          lpMat);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_2_GetMaterial(LPDIRECT3DMATERIAL2 iface,
+                                          LPD3DMATERIAL lpMat)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface),
+                                          lpMat);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DMaterialImpl_1_GetMaterial(LPDIRECT3DMATERIAL iface,
+                                          LPD3DMATERIAL lpMat)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat);
+    return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface),
+                                          lpMat);
+}
 
 /*******************************************************************************
  *				Matrial2 static functions
  */
-static void activate(IDirect3DMaterial2Impl* This) {
+static void activate(IDirect3DMaterialImpl* This) {
   TRACE("Activating material %p\n", This);
 
   ENTER_GL();
-  /* First, set the rendering context */
-  if (This->use_d3d2)
-    This->device.active_device2->set_context(This->device.active_device2);
-  else
-    This->device.active_device1->set_context(This->device.active_device1);
 
   /* Set the current Material */
   _dump_colorvalue("Diffuse", This->mat.u.diffuse);
@@ -73,201 +315,95 @@
   return ;
 }
 
-/*******************************************************************************
- *				Matrial2 Creation functions
- */
-LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2)
-{
-  IDirect3DMaterial2Impl* mat;
-
-  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2Impl));
-  mat->ref = 1;
-  ICOM_VTBL(mat) = &material2_vtable;
-
-  mat->use_d3d2 = 1;
-  mat->d3d.d3d2 = d3d2;
-
-  mat->activate = activate;
-
-  return (LPDIRECT3DMATERIAL2)mat;
-}
-
-LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1)
-{
-  IDirect3DMaterial2Impl* mat;
-
-  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2Impl));
-  mat->ref = 1;
-  ICOM_VTBL(mat) = (ICOM_VTABLE(IDirect3DMaterial2)*)&material_vtable;
-
-  mat->use_d3d2 = 0;
-  mat->d3d.d3d1 = d3d1;
-
-  mat->activate = activate;
-
-  return (LPDIRECT3DMATERIAL) mat;
-}
-
-/*******************************************************************************
- *				IDirect3DMaterial2 methods
- */
-
-static HRESULT WINAPI IDirect3DMaterial2Impl_QueryInterface(LPDIRECT3DMATERIAL2 iface,
-							REFIID riid,
-							LPVOID* ppvObj)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-
-  return S_OK;
-}
-
-
-
-static ULONG WINAPI IDirect3DMaterial2Impl_AddRef(LPDIRECT3DMATERIAL2 iface)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
-
-  return ++(This->ref);
-}
-
-
-
-static ULONG WINAPI IDirect3DMaterial2Impl_Release(LPDIRECT3DMATERIAL2 iface)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-  if (!--(This->ref)) {
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-
-  return This->ref;
-}
-
-/*** IDirect3DMaterial2 methods ***/
-static void dump_material(LPD3DMATERIAL mat)
-{
-  DPRINTF("  dwSize : %ld\n", mat->dwSize);
-}
-
-static HRESULT WINAPI IDirect3DMaterial2Impl_GetMaterial(LPDIRECT3DMATERIAL2 iface,
-						     LPD3DMATERIAL lpMat)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  TRACE("(%p)->(%p)\n", This, lpMat);
-  if (TRACE_ON(ddraw))
-    dump_material(lpMat);
-
-  /* Copies the material structure */
-  *lpMat = This->mat;
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DMaterial2Impl_SetMaterial(LPDIRECT3DMATERIAL2 iface,
-						     LPD3DMATERIAL lpMat)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  TRACE("(%p)->(%p)\n", This, lpMat);
-  if (TRACE_ON(ddraw))
-    dump_material(lpMat);
-
-  /* Stores the material */
-  This->mat = *lpMat;
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DMaterial2Impl_GetHandle(LPDIRECT3DMATERIAL2 iface,
-						   LPDIRECT3DDEVICE2 lpD3DDevice2,
-						   LPD3DMATERIALHANDLE lpMatHandle)
-
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lpD3DDevice2, lpMatHandle);
-
-  if (This->use_d3d2)
-    This->device.active_device2 = (IDirect3DDevice2Impl*)lpD3DDevice2;
-  else
-    This->device.active_device1 = (IDirect3DDeviceImpl*)lpD3DDevice2;
-
-  *lpMatHandle = (DWORD) This; /* lpD3DDevice2->store_material(This); */
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DMaterialImpl_Reserve(LPDIRECT3DMATERIAL iface)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  FIXME("(%p)->(): stub\n", This);
-
-  return DDERR_INVALIDPARAMS;
-}
-
-static HRESULT WINAPI IDirect3DMaterialImpl_Unreserve(LPDIRECT3DMATERIAL iface)
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  FIXME("(%p)->(): stub\n", This);
-
-  return DDERR_INVALIDPARAMS;
-}
-
-static HRESULT WINAPI IDirect3DMaterialImpl_Initialize(LPDIRECT3DMATERIAL iface,
-						   LPDIRECT3D lpDirect3D)
-
-{
-  ICOM_THIS(IDirect3DMaterial2Impl,iface);
-  TRACE("(%p)->(%p)\n", This, lpDirect3D);
-
-  return DDERR_ALREADYINITIALIZED;
-}
-
-
-/*******************************************************************************
- *				IDirect3DMaterial VTable
- */
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(material_vtable.fun))
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial3.fun))
 #else
-# define XCAST(fun)	(void*)
+# define XCAST(fun)     (void*)
 #endif
 
-static ICOM_VTABLE(IDirect3DMaterial) material_vtable =
+ICOM_VTABLE(IDirect3DMaterial3) VTABLE_IDirect3DMaterial3 =
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  XCAST(QueryInterface)IDirect3DMaterial2Impl_QueryInterface,
-  XCAST(AddRef)IDirect3DMaterial2Impl_AddRef,
-  XCAST(Release)IDirect3DMaterial2Impl_Release,
-  /*** IDirect3DMaterial methods ***/
-  IDirect3DMaterialImpl_Initialize,
-  XCAST(SetMaterial)IDirect3DMaterial2Impl_SetMaterial,
-  XCAST(GetMaterial)IDirect3DMaterial2Impl_GetMaterial,
-  XCAST(GetHandle)IDirect3DMaterial2Impl_GetHandle,
-  IDirect3DMaterialImpl_Reserve,
-  IDirect3DMaterialImpl_Unreserve
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DMaterialImpl_3_2T_1T_AddRef,
+    XCAST(Release) Main_IDirect3DMaterialImpl_3_2T_1T_Release,
+    XCAST(SetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial,
+    XCAST(GetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial,
+    XCAST(GetHandle) Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle,
 };
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
 #undef XCAST
 #endif
 
-/*******************************************************************************
- *				IDirect3DMaterial2 VTable
- */
-static ICOM_VTABLE(IDirect3DMaterial2) material2_vtable =
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial2.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DMaterial2) VTABLE_IDirect3DMaterial2 =
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  IDirect3DMaterial2Impl_QueryInterface,
-  IDirect3DMaterial2Impl_AddRef,
-  IDirect3DMaterial2Impl_Release,
-  /*** IDirect3DMaterial methods ***/
-  IDirect3DMaterial2Impl_SetMaterial,
-  IDirect3DMaterial2Impl_GetMaterial,
-  IDirect3DMaterial2Impl_GetHandle
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_2_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DMaterialImpl_2_AddRef,
+    XCAST(Release) Thunk_IDirect3DMaterialImpl_2_Release,
+    XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_2_SetMaterial,
+    XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_2_GetMaterial,
+    XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_2_GetHandle,
 };
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DMaterial.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DMaterial) VTABLE_IDirect3DMaterial =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_1_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DMaterialImpl_1_AddRef,
+    XCAST(Release) Thunk_IDirect3DMaterialImpl_1_Release,
+    XCAST(Initialize) Main_IDirect3DMaterialImpl_1_Initialize,
+    XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_1_SetMaterial,
+    XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_1_GetMaterial,
+    XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_1_GetHandle,
+    XCAST(Reserve) Main_IDirect3DMaterialImpl_1_Reserve,
+    XCAST(Unreserve) Main_IDirect3DMaterialImpl_1_Unreserve,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+
+
+HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirect3DImpl *d3d)
+{
+    IDirect3DMaterialImpl *object;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DMaterialImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+
+    object->ref = 1;
+    object->d3d = d3d;
+    object->activate = activate;
+    
+    ICOM_INIT_INTERFACE(object, IDirect3DMaterial,  VTABLE_IDirect3DMaterial);
+    ICOM_INIT_INTERFACE(object, IDirect3DMaterial2, VTABLE_IDirect3DMaterial2);
+    ICOM_INIT_INTERFACE(object, IDirect3DMaterial3, VTABLE_IDirect3DMaterial3);
+
+    *obj = object;
+    
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return D3D_OK;
+}
diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c
index f434e2f..c418731 100644
--- a/dlls/ddraw/d3dtexture.c
+++ b/dlls/ddraw/d3dtexture.c
@@ -31,9 +31,6 @@
 
 #include "mesa_private.h"
 
-#define D3DDPRIVATE(x) mesa_d3dd_private*odev=(mesa_d3dd_private*)(x)->private
-#define D3DTPRIVATE(x) mesa_d3dt_private*dtpriv=(mesa_d3dt_private*)(x)->private
-
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
 /* Define this if you want to save to a file all the textures used by a game
@@ -50,7 +47,7 @@
 	char buf[32];										\
 	int x, y;										\
 												\
-	sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
+	sprintf(buf, "%ld.pnm", dtpriv->tex_name);						\
 	f = fopen(buf, "wb");									\
 	fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);			\
 	for (y = 0; y < src_d->dwHeight; y++) {							\
@@ -109,565 +106,627 @@
 #define SNOOP_5551()
 #endif
 
-extern ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable;
-extern ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable;
-
-/*******************************************************************************
- *				Texture2 Creation functions
- */
-LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurfaceImpl* surf)
-{
-  IDirect3DTexture2Impl* tex;
-
-  tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
-  tex->ref = 1;
-  ICOM_VTBL(tex) = &mesa_texture2_vtable;
-  tex->surface = surf;
-
-  tex->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dt_private));
-
-  return (LPDIRECT3DTEXTURE2)tex;
-}
-
-/*******************************************************************************
- *				Texture Creation functions
- */
-LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurfaceImpl* surf)
-{
-  IDirect3DTexture2Impl* tex;
-
-  tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
-  tex->ref = 1;
-  ICOM_VTBL(tex) = (ICOM_VTABLE(IDirect3DTexture2)*)&mesa_texture_vtable;
-  tex->surface = surf;
-
-  tex->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dt_private));
-
-  return (LPDIRECT3DTEXTURE)tex;
-}
-
 /*******************************************************************************
  *			   IDirectSurface callback methods
  */
-HRESULT WINAPI  SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
+HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
 {
-  DDSURFACEDESC	*tex_d;
-  D3DTPRIVATE(texture);
-  int bpp;
-  GLuint current_texture;
+    DDSURFACEDESC *tex_d;
+    GLuint current_texture;
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture;
+    
+    TRACE("(%p) : colorkey callback\n", texture);
 
-  TRACE("(%p) : colorkey callback\n", texture);
+    /* Get the texture description */
+    tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc);
 
-  /* Get the texture description */
-  tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc);
-  bpp = (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
-	 1 /* 8 bit of palette index */:
-	 tex_d->ddpfPixelFormat.u1.dwRGBBitCount / 8 /* RGB bits for each colors */ );
+    /* Now, save the current texture */
+    ENTER_GL();
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
 
-  /* Now, save the current texture */
-  ENTER_GL();
-  glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
-
-  /* If the GetHandle was not done yet, it's an error */
-  if (dtpriv->tex_name == 0) {
-    ERR("Unloaded texture !\n");
-    LEAVE_GL();
-    return DD_OK;
-  }
-  glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
-
-  if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
-    FIXME("Todo Paletted\n");
-  } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
-    if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
-      FIXME("Todo 3_3_2_0\n");
-    } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
-      if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
-	/* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
-	unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(),
-							    HEAP_ZERO_MEMORY,
-							    tex_d->dwWidth * tex_d->dwHeight * bpp);
-	unsigned short *src = (unsigned short *) tex_d->lpSurface;
-	int x, y;
-
-	for (y = 0; y < tex_d->dwHeight; y++) {
-	  for (x = 0; x < tex_d->dwWidth; x++) {
-	    unsigned short cpixel = src[x + y * tex_d->dwWidth];
-
-	    if ((dwFlags & DDCKEY_SRCBLT) &&
-		(cpixel >= ckey->dwColorSpaceLowValue) &&
-		(cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */
-	      dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000;
-	    else                                         /* Alpha bit is set => this pixel will be seen */
-	      dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001;
-	  }
-	}
-
-	glTexImage2D(GL_TEXTURE_2D,
-		     0,
-		     GL_RGBA,
-		     tex_d->dwWidth, tex_d->dwHeight,
-		     0,
-		     GL_RGBA,
-		     GL_UNSIGNED_SHORT_5_5_5_1,
-		     dest);
-
-	/* Frees the temporary surface */
-	HeapFree(GetProcessHeap(),0,dest);
-      } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
-	FIXME("Todo 5_5_5_1\n");
-      } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
-	FIXME("Todo 4_4_4_4\n");
-      } else {
-	ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
-      }
-    } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
-      FIXME("Todo 8_8_8_0\n");
-    } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
-      FIXME("Todo 8_8_8_8\n");
-    } else {
-      ERR("Unhandled texture format (bad RGB count)\n");
+    /* If the GetHandle was not done yet, it's an error */
+    if (glThis->tex_name == 0) {
+        ERR("Unloaded texture !\n");
+	LEAVE_GL();
+	return DD_OK;
     }
-  } else {
-    ERR("Unhandled texture format (neither RGB nor INDEX)\n");
-  }
-  LEAVE_GL();
+    glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
 
-  return DD_OK;
-}
+    if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+        FIXME("Todo Paletted\n");
+    } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
+        if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+	    FIXME("Todo 3_3_2_0\n");
+	} else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+	    if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
+	        /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
+	        unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(),
+								    HEAP_ZERO_MEMORY,
+								    tex_d->u1.lPitch * tex_d->dwHeight);
+		unsigned short *src = (unsigned short *) tex_d->lpSurface;
+		int x, y;
+		
+		for (y = 0; y < tex_d->dwHeight; y++) {
+		    for (x = 0; x < tex_d->dwWidth; x++) {
+		        unsigned short cpixel = src[x + y * tex_d->dwWidth];
+			
+			if ((dwFlags & DDCKEY_SRCBLT) &&
+			    (cpixel >= ckey->dwColorSpaceLowValue) &&
+			    (cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */
+			    dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000;
+			else                                         /* Alpha bit is set => this pixel will be seen */
+			    dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001;
+		    }
+		}
 
-/*******************************************************************************
- *				IDirect3DTexture2 methods
- */
-
-HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface,
-							REFIID riid,
-							LPVOID* ppvObj)
-{
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-
-  return S_OK;
-}
-
-
-
-ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface)
-{
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
-
-  return ++(This->ref);
-}
-
-
-
-ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface)
-{
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  D3DTPRIVATE(This);
-  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-  if (!--(This->ref)) {
-    /* Delete texture from OpenGL */
-    ENTER_GL();
-    glDeleteTextures(1, &(dtpriv->tex_name));
+		glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGBA,
+			     tex_d->dwWidth, tex_d->dwHeight,
+			     0,
+			     GL_RGBA,
+			     GL_UNSIGNED_SHORT_5_5_5_1,
+			     dest);
+		
+		/* Frees the temporary surface */
+		HeapFree(GetProcessHeap(),0,dest);
+	    } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
+	        FIXME("Todo 5_5_5_1\n");
+	    } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
+	        FIXME("Todo 4_4_4_4\n");
+	    } else {
+	        ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
+	    }
+	} else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
+	    FIXME("Todo 8_8_8_0\n");
+	} else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
+	    FIXME("Todo 8_8_8_8\n");
+	} else {
+	    ERR("Unhandled texture format (bad RGB count)\n");
+	}
+    } else {
+        ERR("Unhandled texture format (neither RGB nor INDEX)\n");
+    }
     LEAVE_GL();
 
-    /* Release surface */
-    IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->surface);
-
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-
-  return This->ref;
+    return DD_OK;
 }
 
-/*** IDirect3DTexture methods ***/
-HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
-						 LPDIRECT3DDEVICE lpD3DDevice,
-						 LPD3DTEXTUREHANDLE lpHandle)
+HRESULT WINAPI
+Main_IDirect3DTextureImpl_2_1T_QueryInterface(LPDIRECT3DTEXTURE2 iface,
+                                              REFIID riid,
+                                              LPVOID* obp)
 {
-    ICOM_THIS(IDirect3DTexture2Impl,iface);
-    D3DTPRIVATE(This);
-    IDirect3DDeviceImpl* ilpD3DDevice=(IDirect3DDeviceImpl*)lpD3DDevice;
-    FIXME("(%p)->(%p,%p): stub\n", This, ilpD3DDevice, lpHandle);
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    TRACE("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp);
 
+    *obp = NULL;
+
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+        IDirect3DTexture_AddRef(ICOM_INTERFACE(This, IDirect3DTexture));
+	*obp = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DTexture, riid ) ) {
+        IDirect3DTexture_AddRef(ICOM_INTERFACE(This, IDirect3DTexture));
+        *obp = ICOM_INTERFACE(This, IDirect3DTexture);
+	TRACE("  Creating IDirect3DTexture interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DTexture2, riid ) ) {
+        IDirect3DTexture_AddRef(ICOM_INTERFACE(This, IDirect3DTexture));
+        *obp = ICOM_INTERFACE(This, IDirect3DTexture2);
+	TRACE("  Creating IDirect3DTexture2 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;
+}
+
+ULONG WINAPI
+Main_IDirect3DTextureImpl_2_1T_AddRef(LPDIRECT3DTEXTURE2 iface)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    FIXME("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI
+Main_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    
+    if (!--(This->ref)) {
+        /* Release surface */
+        IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
+
+	HeapFree(GetProcessHeap(),0,This);
+	return 0;
+    }
+
+    return This->ref;
+}
+
+HRESULT WINAPI
+Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface,
+                                       LPDIRECT3DDEVICE lpDirect3DDevice,
+                                       LPDIRECTDRAWSURFACE lpDDSurface)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface);
+    FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
+                                              DWORD dwStart,
+                                              DWORD dwCount)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface);
+    FIXME("(%p/%p)->(): stub!\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
+					 LPDIRECT3DDEVICE2 lpDirect3DDevice2,
+					 LPD3DTEXTUREHANDLE lpHandle)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpDirect3DDevice2, lpHandle);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
+				    LPDIRECT3DTEXTURE2 lpD3DTexture2)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
+    return DD_OK;
+}
+
+ULONG WINAPI
+GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
+    FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    
+    if (!--(This->ref)) {
+        /* Release surface */
+        IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
+
+	/* And delete texture handle */
+	ENTER_GL();
+	glDeleteTextures(1, &(glThis->tex_name));
+	LEAVE_GL();	
+
+	/* And if this texture was the current one, remove it at the device level */
+	if (This->d3ddevice != NULL)
+	    if (This->d3ddevice->current_texture == This)
+	        This->d3ddevice->current_texture = NULL;
+	
+	HeapFree(GetProcessHeap(),0,This);
+	return 0;
+    }
+
+    return This->ref;
+}
+
+HRESULT WINAPI
+GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
+				       LPDIRECT3DDEVICE2 lpDirect3DDevice2,
+				       LPD3DTEXTUREHANDLE lpHandle)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
+    IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
+    
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
+
+    /* The handle is simply the pointer to the implementation structure */
     *lpHandle = (D3DTEXTUREHANDLE) This;
 
+    TRACE(" returning handle %08lx.\n", *lpHandle);
+    
     /* Now, bind a new texture */
-    ilpD3DDevice->set_context(ilpD3DDevice);
-    This->D3Ddevice = (void *) ilpD3DDevice;
+    This->d3ddevice = lpDeviceImpl;
     ENTER_GL();
-    if (dtpriv->tex_name == 0)
-	glGenTextures(1, &(dtpriv->tex_name));
+    if (glThis->tex_name == 0)
+	glGenTextures(1, &(glThis->tex_name));
     LEAVE_GL();
 
     /* Associate the texture with the device and perform the appropriate AddRef/Release */
     /* FIXME: Is there only one or several textures associated with the device ? */
-    if (ilpD3DDevice->current_texture)
-      IDirect3DTexture2Impl_Release((LPDIRECT3DTEXTURE2)ilpD3DDevice->current_texture);           
-    IDirect3DTexture2Impl_AddRef((LPDIRECT3DTEXTURE2)iface);
-    ilpD3DDevice->current_texture = (IDirect3DTexture2Impl*)iface;   
+    if (lpDeviceImpl->current_texture != NULL)
+        IDirect3DTexture_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture, IDirect3DTexture));           
+    IDirect3DTexture_AddRef(ICOM_INTERFACE(This, IDirect3DTexture));
+    lpDeviceImpl->current_texture = This;
 
-    TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);
+    TRACE("OpenGL texture handle is : %d\n", glThis->tex_name);
 
     return D3D_OK;
 }
 
-HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
-						  LPDIRECT3DDEVICE lpD3DDevice,
-						  LPDIRECTDRAWSURFACE lpSurface)
-{
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  TRACE("(%p)->(%p,%p)\n", This, lpD3DDevice, lpSurface);
-
-  return DDERR_ALREADYINITIALIZED;
-}
-
-HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface)
-{
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  FIXME("(%p)->(): stub\n", This);
-
-  return D3D_OK;
-}
-
-/*** IDirect3DTexture2 methods ***/
-HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface,
-						  LPDIRECT3DDEVICE2 lpD3DDevice2,
-						  LPD3DTEXTUREHANDLE lpHandle)
-{
-    ICOM_THIS(IDirect3DTexture2Impl,iface);
-    D3DTPRIVATE(This);
-    IDirect3DDevice2Impl* ilpD3DDevice2=(IDirect3DDevice2Impl*)lpD3DDevice2;
-    TRACE("(%p)->(%p,%p)\n", This, ilpD3DDevice2, lpHandle);
-
-    /* For 32 bits OSes, handles = pointers */
-    *lpHandle = (D3DTEXTUREHANDLE) This;
-
-    /* Now, bind a new texture */
-    ilpD3DDevice2->set_context(ilpD3DDevice2);
-    This->D3Ddevice = (void *) ilpD3DDevice2;
-    ENTER_GL();
-    if (dtpriv->tex_name == 0)
-	glGenTextures(1, &(dtpriv->tex_name));
-    LEAVE_GL();
-
-    /* Associate the texture with the device and perform the appropriate AddRef/Release */
-    /* FIXME: Is there only one or several textures associated with the device ? */
-    if (ilpD3DDevice2->current_texture)
-      IDirect3DTexture2Impl_Release((LPDIRECT3DTEXTURE2)ilpD3DDevice2->current_texture);           
-    IDirect3DTexture2Impl_AddRef(iface);
-    ilpD3DDevice2->current_texture = (IDirect3DTexture2Impl*)iface;   
-
-    TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);
-
-    return D3D_OK;
-}
-
-/* Common methods */
-HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(
-    LPDIRECT3DTEXTURE2 iface, DWORD dwStart, DWORD dwCount
-) {
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  FIXME("(%p)->(%8ld,%8ld): stub\n", This, dwStart, dwCount);
-
-  return D3D_OK;
-}
-
 /* NOTE : if you experience crashes in this function, you must have a buggy
           version of Mesa. See the file d3dtexture.c for a cure */
-HRESULT WINAPI IDirect3DTexture2Impl_Load(
-    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DTEXTURE2 lpD3DTexture2
-) {
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  D3DTPRIVATE(This);
-  IDirect3DTexture2Impl* ilpD3DTexture2=(IDirect3DTexture2Impl*)lpD3DTexture2;
-  DDSURFACEDESC	*src_d, *dst_d;
-  static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
-				    GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
+HRESULT WINAPI
+GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
+				  LPDIRECT3DTEXTURE2 lpD3DTexture2)
+{
+    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
+    IDirect3DTextureImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpD3DTexture2);
+    DDSURFACEDESC	*src_d, *dst_d;
+    static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
+				      GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
 #if 0
-  static BOOL color_table_queried = FALSE;
+    static BOOL color_table_queried = FALSE;
 #endif
+    
+    TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
+    TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl->surface, This->surface);
 
-  TRACE("(%p)->(%p)\n", This, ilpD3DTexture2);
-  TRACE("Copied surface %p to surface %p\n", ilpD3DTexture2->surface, This->surface);
+    if ( This->surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
+        /* If the surface is not allocated and its location is not yet specified,
+	   force it to video memory */ 
+        if ( !(This->surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
+	    This->surface->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
 
-  if ( This->surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
-    /* If the surface is not allocated and its location is not yet specified,
-       force it to video memory */ 
-    if ( !(This->surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
-      This->surface->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+    /* Suppress the ALLOCONLOAD flag */
+    This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
 
-  /* Suppress the ALLOCONLOAD flag */
-  This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
+    /* Copy one surface on the other */
+    dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc);
+    src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface->surface_desc);
 
-  /* Copy one surface on the other */
-  dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc);
-  src_d = (DDSURFACEDESC *)&(ilpD3DTexture2->surface->surface_desc);
+    /* Install the callbacks to the destination surface */
+    This->surface->texture = This;
+    This->surface->SetColorKey_cb = SetColorKey_cb;
 
-  /* Install the callbacks to the destination surface */
-  This->surface->texture = This;
-  This->surface->SetColorKey_cb = SetColorKey_cb;
-
-  if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
-    /* Should also check for same pixel format, lPitch, ... */
-    ERR("Error in surface sizes\n");
-    return D3DERR_TEXTURE_LOAD_FAILED;
-  } else {
-    /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
-    /* I should put a macro for the calculus of bpp */
-    int bpp = (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
-	       1 /* 8 bit of palette index */:
-	       src_d->ddpfPixelFormat.u1.dwRGBBitCount / 8 /* RGB bits for each colors */ );
-    GLuint current_texture;
-
-    /* Copy the main memry texture into the surface that corresponds to the OpenGL
-       texture object. */
-    memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->dwWidth * src_d->dwHeight * bpp);
-
-    ENTER_GL();
-
-    /* Now, load the texture */
-    /* d3dd->set_context(d3dd); We need to set the context somehow.... */
-    glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
-
-    /* If the GetHandle was not done, get the texture name here */
-    if (dtpriv->tex_name == 0)
-      glGenTextures(1, &(dtpriv->tex_name));
-    glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
-
-    if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
-      /* ****************
-	 Paletted Texture
-	 **************** */
-      IDirectDrawPaletteImpl* pal = ilpD3DTexture2->surface->palette;
-      BYTE table[256][4];
-      int i;
-
-#if 0
-      if (color_table_queried == FALSE) {
-	ptr_ColorTableEXT =
-	  ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
-      }
-#endif
-
-      if (pal == NULL) {
-	ERR("Palettized texture Loading with a NULL palette !\n");
-	LEAVE_GL();
+    if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
+        /* Should also check for same pixel format, u1.lPitch, ... */
+        ERR("Error in surface sizes\n");
 	return D3DERR_TEXTURE_LOAD_FAILED;
-      }
-
-      /* Get the surface's palette */
-      for (i = 0; i < 256; i++) {
-	table[i][0] = pal->palents[i].peRed;
-	table[i][1] = pal->palents[i].peGreen;
-	table[i][2] = pal->palents[i].peBlue;
-	if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
-	    (i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
-	    (i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
-	  table[i][3] = 0x00;
-	else
-	table[i][3] = 0xFF;
-      }
-
-      /* Texture snooping */
-      SNOOP_PALETTED();
-
-      if (ptr_ColorTableEXT != NULL) {
-	/* use Paletted Texture Extension */
-	ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
-			  GL_RGBA,          /* internal format */
-			  256,              /* table size */
-			  GL_RGBA,          /* table format */
-			  GL_UNSIGNED_BYTE, /* table type */
-			  table);           /* the color table */
-
-	glTexImage2D(GL_TEXTURE_2D,       /* target */
-		     0,                   /* level */
-		     GL_COLOR_INDEX8_EXT, /* internal format */
-		     src_d->dwWidth, src_d->dwHeight, /* width, height */
-		     0,                   /* border */
-		     GL_COLOR_INDEX,      /* texture format */
-		     GL_UNSIGNED_BYTE,    /* texture type */
-		     src_d->lpSurface); /* the texture */
-      } else {
-	DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
-	DWORD i;
-	BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
-
-	for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-	  BYTE color = *src++;
-	  *dst++ = table[color][0];
-	  *dst++ = table[color][1];
-	  *dst++ = table[color][2];
-	  *dst++ = table[color][3];
-	}
-
-	glTexImage2D(GL_TEXTURE_2D,
-		     0,
-		     GL_RGBA,
-		     src_d->dwWidth, src_d->dwHeight,
-		     0,
-		     GL_RGBA,
-		     GL_UNSIGNED_BYTE,
-		     surface);
-
-	HeapFree(GetProcessHeap(), 0, surface);
-      }
-    } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
-      /* ************
-	 RGB Textures
-	 ************ */
-      if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
-	/* **********************
-	   GL_UNSIGNED_BYTE_3_3_2
-	   ********************** */
-	glTexImage2D(GL_TEXTURE_2D,
-		     0,
-		     GL_RGB,
-		     src_d->dwWidth, src_d->dwHeight,
-		     0,
-		     GL_RGB,
-		     GL_UNSIGNED_BYTE_3_3_2,
-		     src_d->lpSurface);
-      } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
-	if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
-
-	  /* Texture snooping */
-	  SNOOP_5650();
-
-	  glTexImage2D(GL_TEXTURE_2D,
-		       0,
-		       GL_RGB,
-		       src_d->dwWidth, src_d->dwHeight,
-		       0,
-		       GL_RGB,
-		       GL_UNSIGNED_SHORT_5_6_5,
-		       src_d->lpSurface);
-	} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
-	  /* Texture snooping */
-	  SNOOP_5551();
-
-	  glTexImage2D(GL_TEXTURE_2D,
-		       0,
-		       GL_RGBA,
-		       src_d->dwWidth, src_d->dwHeight,
-		       0,
-		       GL_RGBA,
-		       GL_UNSIGNED_SHORT_5_5_5_1,
-		       src_d->lpSurface);
-	} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
-	  glTexImage2D(GL_TEXTURE_2D,
-		       0,
-		       GL_RGBA,
-		       src_d->dwWidth, src_d->dwHeight,
-		       0,
-		       GL_RGBA,
-		       GL_UNSIGNED_SHORT_4_4_4_4,
-		       src_d->lpSurface);
-	} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
-	  /* Converting the 1555 format in 5551 packed */
-	  WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
-	  DWORD i;
-	  WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
-
-	  for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-	    *dst++ = (((*src & 0x8000) >> 15) |
-		      ((*src & 0x7FFF) <<  1));
-	    src++;
-	  }
-
-	  glTexImage2D(GL_TEXTURE_2D,
-		       0,
-		       GL_RGBA,
-		       src_d->dwWidth, src_d->dwHeight,
-		       0,
-		       GL_RGBA,
-		       GL_UNSIGNED_SHORT_5_5_5_1,
-		       surface);
-
-	  HeapFree(GetProcessHeap(), 0, surface);
-	} else {
-	  ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
-	}
-      } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
-	glTexImage2D(GL_TEXTURE_2D,
-		     0,
-		     GL_RGB,
-		     src_d->dwWidth, src_d->dwHeight,
-		     0,
-		     GL_RGB,
-		     GL_UNSIGNED_BYTE,
-		     src_d->lpSurface);
-      } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
-	glTexImage2D(GL_TEXTURE_2D,
-		     0,
-		     GL_RGBA,
-		     src_d->dwWidth, src_d->dwHeight,
-		     0,
-		     GL_RGBA,
-		     GL_UNSIGNED_BYTE,
-		     src_d->lpSurface);
-      } else {
-	ERR("Unhandled texture format (bad RGB count)\n");
-      }
     } else {
-      ERR("Unhandled texture format (neither RGB nor INDEX)\n");
+        /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
+        /* I should put a macro for the calculus of bpp */
+	GLuint current_texture;
+
+	/* Copy the main memry texture into the surface that corresponds to the OpenGL
+	   texture object. */
+	memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
+
+	ENTER_GL();
+
+	/* Now, load the texture */
+	/* d3dd->set_context(d3dd); We need to set the context somehow.... */
+	glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
+
+	/* If the GetHandle was not done, get the texture name here */
+	if (glThis->tex_name == 0)
+	    glGenTextures(1, &(glThis->tex_name));
+	glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
+
+	if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+	  /* ****************
+	     Paletted Texture
+	     **************** */
+	    IDirectDrawPaletteImpl* pal = lpD3DTextureImpl->surface->palette;
+	    BYTE table[256][4];
+	    int i;
+
+#if 0
+	    if (color_table_queried == FALSE) {
+	        ptr_ColorTableEXT =
+		  ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
+	    }
+#endif
+
+	    if (pal == NULL) {
+	        ERR("Palettized texture Loading with a NULL palette !\n");
+		LEAVE_GL();
+		return D3DERR_TEXTURE_LOAD_FAILED;
+	    }
+
+	    /* Get the surface's palette */
+	    for (i = 0; i < 256; i++) {
+	        table[i][0] = pal->palents[i].peRed;
+		table[i][1] = pal->palents[i].peGreen;
+		table[i][2] = pal->palents[i].peBlue;
+		if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
+		    (i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
+		    (i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
+		    table[i][3] = 0x00;
+		else
+		    table[i][3] = 0xFF;
+	    }
+
+	    /* Texture snooping */
+	    SNOOP_PALETTED();
+
+	    if (ptr_ColorTableEXT != NULL) {
+	        /* use Paletted Texture Extension */
+	        ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
+				  GL_RGBA,          /* internal format */
+				  256,              /* table size */
+				  GL_RGBA,          /* table format */
+				  GL_UNSIGNED_BYTE, /* table type */
+				  table);           /* the color table */
+		
+		glTexImage2D(GL_TEXTURE_2D,       /* target */
+			     0,                   /* level */
+			     GL_COLOR_INDEX8_EXT, /* internal format */
+			     src_d->dwWidth, src_d->dwHeight, /* width, height */
+			     0,                   /* border */
+			     GL_COLOR_INDEX,      /* texture format */
+			     GL_UNSIGNED_BYTE,    /* texture type */
+			     src_d->lpSurface); /* the texture */
+	    } else {
+	        DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+		DWORD i;
+		BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
+		
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    BYTE color = *src++;
+		    *dst++ = table[color][0];
+		    *dst++ = table[color][1];
+		    *dst++ = table[color][2];
+		    *dst++ = table[color][3];
+		}
+		
+		glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGBA,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGBA,
+			     GL_UNSIGNED_BYTE,
+			     surface);
+		
+		HeapFree(GetProcessHeap(), 0, surface);
+	    }
+	} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
+	    /* ************
+	       RGB Textures
+	       ************ */
+	    if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+	        /* **********************
+		   GL_UNSIGNED_BYTE_3_3_2
+		   ********************** */
+	        glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGB,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGB,
+			     GL_UNSIGNED_BYTE_3_3_2,
+			     src_d->lpSurface);
+	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+	        if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
+		  
+		    /* Texture snooping */
+		    SNOOP_5650();
+		    
+		    glTexImage2D(GL_TEXTURE_2D,
+				 0,
+				 GL_RGB,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGB,
+				 GL_UNSIGNED_SHORT_5_6_5,
+				 src_d->lpSurface);
+		} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
+		    /* Texture snooping */
+		    SNOOP_5551();
+		    
+		    glTexImage2D(GL_TEXTURE_2D,
+				 0,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_5_5_5_1,
+				 src_d->lpSurface);
+		} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
+		    glTexImage2D(GL_TEXTURE_2D,
+				 0,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_4_4_4_4,
+				 src_d->lpSurface);
+		} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
+		    /* Converting the 1555 format in 5551 packed */
+		    WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+		    DWORD i;
+		    WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
+		    
+		    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		        *dst++ = (((*src & 0x8000) >> 15) |
+				  ((*src & 0x7FFF) <<  1));
+			src++;
+		    }
+		    
+		    glTexImage2D(GL_TEXTURE_2D,
+				 0,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_5_5_5_1,
+				 surface);
+		    
+		    HeapFree(GetProcessHeap(), 0, surface);
+		} else {
+		    ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
+		}
+	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
+	        glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGB,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGB,
+			     GL_UNSIGNED_BYTE,
+			     src_d->lpSurface);
+	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
+	        glTexImage2D(GL_TEXTURE_2D,
+			     0,
+			     GL_RGBA,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGBA,
+			     GL_UNSIGNED_BYTE,
+			     src_d->lpSurface);
+	    } else {
+	        ERR("Unhandled texture format (bad RGB count)\n");
+	    }
+	} else {
+	    ERR("Unhandled texture format (neither RGB nor INDEX)\n");
+	}
+	
+	glBindTexture(GL_TEXTURE_2D, current_texture);
+	
+	LEAVE_GL();
     }
 
-    glBindTexture(GL_TEXTURE_2D, current_texture);
-
-    LEAVE_GL();
-  }
-
-  return D3D_OK;
+    return D3D_OK;
 }
 
-
-/*******************************************************************************
- *				IDirect3DTexture2 VTable
- */
-ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable =
+HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
+                                            REFIID riid,
+                                            LPVOID* obp)
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  IDirect3DTexture2Impl_QueryInterface,
-  IDirect3DTexture2Impl_AddRef,
-  IDirect3DTexture2Impl_Release,
-  /*** IDirect3DTexture methods ***/
-  IDirect3DTexture2Impl_GetHandle,
-  IDirect3DTexture2Impl_PaletteChanged,
-  IDirect3DTexture2Impl_Load
-};
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DTexture2 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DTexture2_QueryInterface(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+                                            riid,
+                                            obp);
+}
 
-/*******************************************************************************
- *				IDirect3DTexture VTable
- */
+ULONG WINAPI
+Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface);
+    return IDirect3DTexture2_AddRef(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface);
+    return IDirect3DTexture2_Release(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface,
+                                            DWORD dwStart,
+                                            DWORD dwCount)
+{
+    TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
+    return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+                                            dwStart,
+                                            dwCount);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface,
+				       LPDIRECT3DDEVICE lpDirect3DDevice,
+				       LPD3DTEXTUREHANDLE lpHandle)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
+    return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+				       COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
+				       lpHandle);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
+				  LPDIRECT3DTEXTURE lpD3DTexture)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
+    return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+				  COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
+}
+
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(mesa_texture_vtable.fun))
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DTexture2.fun))
 #else
-# define XCAST(fun)	(void*)
+# define XCAST(fun)     (void*)
 #endif
 
-ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable =
+ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 =
 {
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  XCAST(QueryInterface)IDirect3DTexture2Impl_QueryInterface,
-  XCAST(AddRef)IDirect3DTexture2Impl_AddRef,
-  XCAST(Release)IDirect3DTexture2Impl_Release,
-  /*** IDirect3DTexture methods ***/
-  IDirect3DTextureImpl_Initialize,
-  IDirect3DTextureImpl_GetHandle,
-  XCAST(PaletteChanged)IDirect3DTexture2Impl_PaletteChanged,
-  XCAST(Load)IDirect3DTexture2Impl_Load,
-  IDirect3DTextureImpl_Unload
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Main_IDirect3DTextureImpl_2_1T_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DTextureImpl_2_1T_AddRef,
+    XCAST(Release) GL_IDirect3DTextureImpl_2_1T_Release,
+    XCAST(GetHandle) GL_IDirect3DTextureImpl_2_1T_GetHandle,
+    XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
+    XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
 };
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
 #undef XCAST
 #endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DTexture.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DTexture) VTABLE_IDirect3DTexture =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_1_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DTextureImpl_1_AddRef,
+    XCAST(Release) Thunk_IDirect3DTextureImpl_1_Release,
+    XCAST(Initialize) Main_IDirect3DTextureImpl_1_Initialize,
+    XCAST(GetHandle) Thunk_IDirect3DTextureImpl_1_GetHandle,
+    XCAST(PaletteChanged) Thunk_IDirect3DTextureImpl_1_PaletteChanged,
+    XCAST(Load) Thunk_IDirect3DTextureImpl_1_Load,
+    XCAST(Unload) Main_IDirect3DTextureImpl_1_Unload,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+
+
+HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf)
+{
+    IDirect3DTextureImpl *object;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+
+    object->ref = 1;
+    object->d3d = d3d;
+    object->surface = surf;
+    
+    ICOM_INIT_INTERFACE(object, IDirect3DTexture,  VTABLE_IDirect3DTexture);
+    ICOM_INIT_INTERFACE(object, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
+
+    *obj = object;
+
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return D3D_OK;
+}
diff --git a/dlls/ddraw/d3dvertexbuffer.c b/dlls/ddraw/d3dvertexbuffer.c
new file mode 100644
index 0000000..18ec3f7
--- /dev/null
+++ b/dlls/ddraw/d3dvertexbuffer.c
@@ -0,0 +1,300 @@
+/* Direct3D Viewport
+ * Copyright (c) 2002 Lionel ULMER
+ *
+ * This file contains the implementation of Direct3DVertexBuffer COM object
+ *
+ * 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
+ */
+
+#include "config.h"
+#include "windef.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "wine/debug.h"
+
+#include "d3d_private.h"
+#include "mesa_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
+                                                   REFIID riid,
+                                                   LPVOID* obp)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
+
+    /* By default, set the object pointer to NULL */
+    *obp = NULL;
+      
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+        IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
+	*obp = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
+        IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
+        *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
+	TRACE("  Creating IDirect3DVertexBuffer interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
+        IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
+        *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
+	TRACE("  Creating IDirect3DVertexBuffer7 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;
+}
+
+ULONG WINAPI
+Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI
+Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (--(This->ref) == 0) {
+	HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
+                                         DWORD dwFlags,
+                                         LPVOID* lplpData,
+                                         LPDWORD lpdwSize)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    FIXME("(%p/%p)->(%08lx,%p,%p): stub!\n", This, iface, dwFlags, lplpData, lpdwSize);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    FIXME("(%p/%p)->(): stub!\n", This, iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
+                                                 DWORD dwVertexOp,
+                                                 DWORD dwDestIndex,
+                                                 DWORD dwCount,
+                                                 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
+                                                 DWORD dwSrcIndex,
+                                                 LPDIRECT3DDEVICE7 lpD3DDevice,
+                                                 DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
+                                                        LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DVertexBufferDesc);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
+                                          LPDIRECT3DDEVICE7 lpD3DDevice,
+                                          DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
+                                                        DWORD dwVertexOp,
+                                                        DWORD dwDestIndex,
+                                                        DWORD dwCount,
+                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
+                                                        DWORD dwVertexTypeDesc,
+                                                        LPDIRECT3DDEVICE7 lpD3DDevice,
+                                                        DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
+                                                 DWORD dwVertexOp,
+                                                 DWORD dwDestIndex,
+                                                 DWORD dwCount,
+                                                 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
+                                                 DWORD dwSrcIndex,
+                                                 LPDIRECT3DDEVICE3 lpD3DDevice,
+                                                 DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
+                                          LPDIRECT3DDEVICE3 lpD3DDevice,
+                                          DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
+    FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
+                                                 REFIID riid,
+                                                 LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
+                                                 riid,
+                                                 obp);
+}
+
+ULONG WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
+    return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
+    return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
+                                       DWORD dwFlags,
+                                       LPVOID* lplpData,
+                                       LPDWORD lpdwSize)
+{
+    TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
+    return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
+                                       dwFlags,
+                                       lplpData,
+                                       lpdwSize);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
+{
+    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
+    return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
+                                                      LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
+{
+    TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
+    return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
+                                                      lpD3DVertexBufferDesc);
+}
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DVertexBuffer7) VTABLE_IDirect3DVertexBuffer7 =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
+    XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
+    XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
+    XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
+    XCAST(ProcessVertices) Main_IDirect3DVertexBufferImpl_7_ProcessVertices,
+    XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
+    XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_Optimize,
+    XCAST(ProcessVerticesStrided) Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DVertexBuffer) VTABLE_IDirect3DVertexBuffer =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    XCAST(ProcessVertices) Main_IDirect3DVertexBufferImpl_1_ProcessVertices,
+    XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
+    XCAST(Optimize) Main_IDirect3DVertexBufferImpl_1_Optimize,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc)
+{
+    IDirect3DVertexBufferImpl *object;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+
+    object->ref = 1;
+    object->d3d = d3d;
+    
+    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer,  VTABLE_IDirect3DVertexBuffer);
+    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
+
+    *obj = object;
+
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return D3D_OK;
+}
diff --git a/dlls/ddraw/d3dviewport.c b/dlls/ddraw/d3dviewport.c
index 28eae31..3f4c47a 100644
--- a/dlls/ddraw/d3dviewport.c
+++ b/dlls/ddraw/d3dviewport.c
@@ -31,390 +31,497 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-#ifdef HAVE_OPENGL
+static void activate(IDirect3DViewportImpl* This) {
+    IDirect3DLightImpl* light;
 
-#define D3DVPRIVATE(x) mesa_d3dv_private*dvpriv=((mesa_d3dv_private*)x->private)
-#define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
+    /* Activate all the lights associated with this context */
+    light = This->lights;
 
-static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable;
-
-/*******************************************************************************
- *				Viewport1/2 static functions
- */
-static void activate(IDirect3DViewport2Impl* This) {
-  IDirect3DLightImpl* l;
-
-  /* Activate all the lights associated with this context */
-  l = This->lights;
-
-  while (l != NULL) {
-    l->activate(l);
-    l = l->next;
-  }
-}
-
-/*******************************************************************************
- *				Viewport1/2 Creation functions
- */
-LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2)
-{
-  IDirect3DViewport2Impl* vp;
-
-  vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl));
-  vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private));
-  vp->ref = 1;
-  ICOM_VTBL(vp) = &viewport2_vtable;
-  vp->d3d.d3d2 = d3d2;
-  vp->use_d3d2 = 1;
-
-  vp->device.active_device2 = NULL;
-  vp->activate = activate;
-
-  vp->lights = NULL;
-
-  ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0;
-
-  return (LPDIRECT3DVIEWPORT2)vp;
-}
-
-LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1)
-{
-  IDirect3DViewport2Impl* vp;
-
-  vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl));
-  vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private));
-  vp->ref = 1;
-  ICOM_VTBL(vp) = &viewport2_vtable;
-  vp->d3d.d3d1 = d3d1;
-  vp->use_d3d2 = 0;
-
-  vp->device.active_device1 = NULL;
-  vp->activate = activate;
-
-  vp->lights = NULL;
-
-  ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0;
-
-  return (LPDIRECT3DVIEWPORT) vp;
-}
-
-/*******************************************************************************
- *				IDirect3DViewport2 methods
- */
-
-HRESULT WINAPI IDirect3DViewport2Impl_QueryInterface(LPDIRECT3DVIEWPORT2 iface,
-							REFIID riid,
-							LPVOID* ppvObj)
-{
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-
-  return S_OK;
+    while (light != NULL) {
+        light->activate(light);
+	light = light->next;
+    }
 }
 
 
-
-ULONG WINAPI IDirect3DViewport2Impl_AddRef(LPDIRECT3DVIEWPORT2 iface)
+static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
+    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);
+}
 
-  return ++(This->ref);
+static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *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("    - 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);
+}
+
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
+                                                REFIID riid,
+                                                LPVOID* obp)
+{
+    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;
+}
+
+ULONG WINAPI
+Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
+{
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI
+Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
+{
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (!--(This->ref)) {
+        HeapFree(GetProcessHeap(), 0, This);
+	return 0;
+    }
+    return This->ref;
 }
 
 
-
-ULONG WINAPI IDirect3DViewport2Impl_Release(LPDIRECT3DVIEWPORT2 iface)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
+                                            LPDIRECT3D lpDirect3D)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-  if (!--(This->ref)) {
-    HeapFree(GetProcessHeap(),0,This->private);
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-
-  return This->ref;
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
+    return DD_OK;
 }
 
-/*** IDirect3DViewport methods ***/
-HRESULT WINAPI IDirect3DViewport2Impl_Initialize(LPDIRECT3DVIEWPORT2 iface,
-						    LPDIRECT3D d3d)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
+                                             LPD3DVIEWPORT lpData)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, d3d);
+    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);
 
-  return DD_OK;
+    if (TRACE_ON(ddraw)) {
+        TRACE("  returning D3DVIEWPORT :");
+	_dump_D3DVIEWPORT(lpData);
+    }
+    
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_GetViewport(LPDIRECT3DVIEWPORT2 iface,
-						     LPD3DVIEWPORT lpvp)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
+                                             LPD3DVIEWPORT lpData)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpvp);
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
 
-  if (This->use_vp2 != 0)
+    if (TRACE_ON(ddraw)) {
+        TRACE("  getting D3DVIEWPORT :\n");
+	_dump_D3DVIEWPORT(lpData);
+    }
+
+    This->use_vp2 = 0;
+    memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
+    memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
+    return DD_OK;
+}
+
+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);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
+                                               DWORD dwElementCount,
+                                               LPD3DLIGHTDATA lpData)
+{
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
+                                               D3DMATERIALHANDLE hMat)
+{
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, (DWORD) hMat);
+    return DD_OK;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
+                                       DWORD dwCount,
+                                       LPD3DRECT lpRects,
+                                       DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags);
+    return DD_OK;
+}
+
+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);
+    
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
+    
+    /* Add the light in the 'linked' chain */
+    lpDirect3DLightImpl->next = This->lights;
+    This->lights = lpDirect3DLightImpl;
+
+    /* If active, activate the light */
+    if (This->active_device != NULL) {
+        lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
+    }
+    
+    return DD_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
+                                             LPDIRECT3DLIGHT lpDirect3DLight)
+{
+    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;
+	    return DD_OK;
+	}
+	prev_light = cur_light;
+	cur_light = cur_light->next;
+    }
     return DDERR_INVALIDPARAMS;
-
-  *lpvp = This->viewport.vp1;
-
-  return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_SetViewport(LPDIRECT3DVIEWPORT2 iface,
-						     LPD3DVIEWPORT lpvp)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
+                                           LPDIRECT3DLIGHT lpDirect3DLight,
+                                           LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                           DWORD dwFlags)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpvp);
-
-  This->use_vp2 = 0;
-  This->viewport.vp1 = *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);
-
-
-  return DD_OK;
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_TransformVertices(LPDIRECT3DVIEWPORT2 iface,
-							   DWORD dwVertexCount,
-							   LPD3DTRANSFORMDATA lpData,
-							   DWORD dwFlags,
-							   LPDWORD lpOffScreen)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
+                                            LPD3DVIEWPORT2 lpData)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%8ld,%p,%08lx,%p): stub\n",
-	This, dwVertexCount, lpData, dwFlags, lpOffScreen);
+    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);
 
-  return DD_OK;
+    if (TRACE_ON(ddraw)) {
+        TRACE("  returning D3DVIEWPORT2 :");
+	_dump_D3DVIEWPORT2(lpData);
+    }
+    
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_LightElements(LPDIRECT3DVIEWPORT2 iface,
-						       DWORD dwElementCount,
-						       LPD3DLIGHTDATA lpData)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
+                                            LPD3DVIEWPORT2 lpData)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%8ld,%p): stub\n", This, dwElementCount, lpData);
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
 
-  return DD_OK;
+    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);
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_SetBackground(LPDIRECT3DVIEWPORT2 iface,
-						       D3DMATERIALHANDLE hMat)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
+                                                 LPDIRECTDRAWSURFACE4 lpDDS)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%08lx): stub\n", This, (DWORD) hMat);
-
-  return DD_OK;
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_GetBackground(LPDIRECT3DVIEWPORT2 iface,
-						       LPD3DMATERIALHANDLE lphMat,
-						       LPBOOL lpValid)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
+                                                 LPDIRECTDRAWSURFACE4* lplpDDS,
+                                                 LPBOOL lpValid)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lphMat, lpValid);
-
-  return DD_OK;
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface,
-							    LPDIRECTDRAWSURFACE lpDDSurface)
+HRESULT WINAPI
+Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
+                                    DWORD dwCount,
+                                    LPD3DRECT lpRects,
+                                    DWORD dwFlags,
+                                    DWORD dwColor,
+                                    D3DVALUE dvZ,
+                                    DWORD dwStencil)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpDDSurface);
-
-  return DD_OK;
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    FIXME("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface,
-							    LPDIRECTDRAWSURFACE* lplpDDSurface,
-							    LPBOOL lpValid)
+HRESULT WINAPI
+GL_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
+                                       DWORD dwCount,
+                                       LPD3DRECT lpRects,
+                                       DWORD dwFlags)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lplpDDSurface, lpValid);
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    GLboolean ztest;
+    
+    TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
 
-  return DD_OK;
+    if (dwCount != 1) {
+        WARN("  Warning, this function only for now clears the whole screen...\n");
+    }
+    
+    /* Clears the screen */
+    ENTER_GL();
+    glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
+    glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
+    glClear(((dwFlags & D3DCLEAR_TARGET) ? GL_COLOR_BUFFER_BIT : 0) |
+	    ((dwFlags & D3DCLEAR_ZBUFFER) ? GL_DEPTH_BUFFER_BIT : 0));
+    glDepthMask(ztest);
+    LEAVE_GL();
+    
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_Clear(LPDIRECT3DVIEWPORT2 iface,
-					       DWORD dwCount,
-					       LPD3DRECT lpRects,
-					       DWORD dwFlags)
+HRESULT WINAPI
+GL_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
+                                    DWORD dwCount,
+                                    LPD3DRECT lpRects,
+                                    DWORD dwFlags,
+                                    DWORD dwColor,
+                                    D3DVALUE dvZ,
+                                    DWORD dwStencil)
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  GLboolean ztest;
-  FIXME("(%p)->(%8ld,%p,%08lx): stub\n", This, dwCount, lpRects, dwFlags);
+    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
+    GLboolean ztest;
+    GLfloat old_z_clear_value;
+    GLbitfield bitfield = 0;
+    GLint old_stencil_clear_value;
+    GLfloat old_color_clear_value[4];
+    
+    TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
 
-  /* For the moment, ignore the rectangles */
-  if (This->device.active_device1 != NULL) {
-    /* Get the rendering context */
-    if (This->use_d3d2)
-      This->device.active_device2->set_context(This->device.active_device2);
-    else
-      This->device.active_device1->set_context(This->device.active_device1);
-  }
+    if (dwCount != 1) {
+        WARN("  Warning, this function only for now clears the whole screen...\n");
+    }
 
     /* Clears the screen */
     ENTER_GL();
-    glGetBooleanv(GL_DEPTH_TEST, &ztest);
-    glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-    glDepthMask(ztest);
-    LEAVE_GL();
-
-  return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DViewport2Impl_AddLight(LPDIRECT3DVIEWPORT2 iface,
-						  LPDIRECT3DLIGHT lpLight)
-{
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  IDirect3DLightImpl* ilpLight=(IDirect3DLightImpl*)lpLight;
-  FIXME("(%p)->(%p): stub\n", This, ilpLight);
-
-  /* Add the light in the 'linked' chain */
-  ilpLight->next = This->lights;
-  This->lights = ilpLight;
-
-  /* If active, activate the light */
-  if (This->device.active_device1 != NULL) {
-    D3DVPRIVATE(This);
-    D3DLPRIVATE(ilpLight);
-
-    /* Get the rendering context */
-    if (This->use_d3d2)
-      This->device.active_device2->set_context(This->device.active_device2);
-    else
-      This->device.active_device1->set_context(This->device.active_device1);
-
-    /* Activate the light */
-    dlpriv->light_num = dvpriv->nextlight++;
-    ilpLight->activate(ilpLight);
-  }
-
-  return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DViewport2Impl_DeleteLight(LPDIRECT3DVIEWPORT2 iface,
-						     LPDIRECT3DLIGHT lpLight)
-{
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  IDirect3DLightImpl** currentlplpLight;
-  TRACE("(%p)->(%p): stub\n", This, lpLight);
-
-  currentlplpLight = &(This->lights);
-  while(*currentlplpLight) {
-    if (*currentlplpLight == (IDirect3DLightImpl*)lpLight) {
-      *currentlplpLight = (*currentlplpLight)->next;
-      return DD_OK;
+    if (dwFlags & D3DCLEAR_ZBUFFER) {
+        glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
+	glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
+	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
+	glClearDepth(dvZ);
+	TRACE(" Depth value : %f\n", dvZ);
+	bitfield |= GL_DEPTH_BUFFER_BIT;
     }
-    currentlplpLight = &((*currentlplpLight)->next);
-  }
-
-  return DDERR_INVALIDOBJECT;
+    if (dwFlags & D3DCLEAR_STENCIL) {
+        bitfield |= GL_STENCIL_BUFFER_BIT;
+	glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
+	glClearStencil(dwStencil);
+	TRACE(" Stencil value : %ld\n", dwStencil);
+    }    
+    if (dwFlags & D3DCLEAR_TARGET) {
+        bitfield |= GL_COLOR_BUFFER_BIT;
+	glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
+	glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
+		     ((dwColor >>  8) & 0xFF) / 255.0,
+		     ((dwColor >>  0) & 0xFF) / 255.0,
+		     ((dwColor >> 24) & 0xFF) / 255.0);
+	TRACE("Color value (ARGB) : %08lx", dwColor);
+    }
+    
+    glClear(bitfield);
+    
+    if (dwFlags & D3DCLEAR_ZBUFFER) {
+        glDepthMask(ztest);
+	glClearDepth(old_z_clear_value);
+    }
+     if (dwFlags & D3DCLEAR_STENCIL) {
+        bitfield |= GL_STENCIL_BUFFER_BIT;
+	glClearStencil(old_stencil_clear_value);
+    }    
+    if (dwFlags & D3DCLEAR_TARGET) {
+        bitfield |= GL_COLOR_BUFFER_BIT;
+	glClearColor(old_color_clear_value[0],
+		     old_color_clear_value[1],
+		     old_color_clear_value[2],
+		     old_color_clear_value[3]);
+    }
+    
+    LEAVE_GL();
+    
+    return DD_OK;
 }
 
-HRESULT WINAPI IDirect3DViewport2Impl_NextLight(LPDIRECT3DVIEWPORT2 iface,
-						   LPDIRECT3DLIGHT lpLight,
-						   LPDIRECT3DLIGHT* lplpLight,
-						   DWORD dwFlags)
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3DViewport3.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
 {
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpLight, lplpLight, dwFlags);
-
-  return DD_OK;
-}
-
-/*** IDirect3DViewport2 methods ***/
-HRESULT WINAPI IDirect3DViewport2Impl_GetViewport2(LPDIRECT3DVIEWPORT2 iface,
-						      LPD3DVIEWPORT2 lpViewport2)
-{
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  TRACE("(%p)->(%p)\n", This, lpViewport2);
-
-  if (This->use_vp2 != 1)
-    return DDERR_INVALIDPARAMS;
-
-  *lpViewport2 = This->viewport.vp2;
-
-  return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DViewport2Impl_SetViewport2(LPDIRECT3DVIEWPORT2 iface,
-						      LPD3DVIEWPORT2 lpViewport2)
-{
-  ICOM_THIS(IDirect3DViewport2Impl,iface);
-  TRACE("(%p)->(%p)\n", This, lpViewport2);
-
-  TRACE("dwSize = %ld   dwX = %ld   dwY = %ld\n",
-	lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY);
-  TRACE("dwWidth = %ld   dwHeight = %ld\n",
-	lpViewport2->dwWidth, lpViewport2->dwHeight);
-  TRACE("dvClipX = %f   dvClipY = %f\n",
-	lpViewport2->dvClipX, lpViewport2->dvClipY);
-  TRACE("dvClipWidth = %f   dvClipHeight = %f\n",
-	lpViewport2->dvClipWidth, lpViewport2->dvClipHeight);
-  TRACE("dvMinZ = %f   dvMaxZ = %f\n",
-	lpViewport2->dvMinZ, lpViewport2->dvMaxZ);
-
-  This->viewport.vp2 = *lpViewport2;
-  This->use_vp2 = 1;
-
-  return DD_OK;
-}
-
-
-/*******************************************************************************
- *				IDirect3DViewport1/2 VTable
- */
-static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable =
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  /*** IUnknown methods ***/
-  IDirect3DViewport2Impl_QueryInterface,
-  IDirect3DViewport2Impl_AddRef,
-  IDirect3DViewport2Impl_Release,
-  /*** IDirect3DViewport methods ***/
-  IDirect3DViewport2Impl_Initialize,
-  IDirect3DViewport2Impl_GetViewport,
-  IDirect3DViewport2Impl_SetViewport,
-  IDirect3DViewport2Impl_TransformVertices,
-  IDirect3DViewport2Impl_LightElements,
-  IDirect3DViewport2Impl_SetBackground,
-  IDirect3DViewport2Impl_GetBackground,
-  IDirect3DViewport2Impl_SetBackgroundDepth,
-  IDirect3DViewport2Impl_GetBackgroundDepth,
-  IDirect3DViewport2Impl_Clear,
-  IDirect3DViewport2Impl_AddLight,
-  IDirect3DViewport2Impl_DeleteLight,
-  IDirect3DViewport2Impl_NextLight,
-  /*** IDirect3DViewport2 methods ***/
-  IDirect3DViewport2Impl_GetViewport2,
-  IDirect3DViewport2Impl_SetViewport2
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    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,
+    XCAST(Clear) GL_IDirect3DViewportImpl_3_2_1_Clear,
+    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,
+    XCAST(Clear2) GL_IDirect3DViewportImpl_3_Clear2,
 };
 
-#else /* HAVE_OPENGL */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
 
-LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1) {
-  ERR("Should not be called...\n");
-  return NULL;
+
+
+
+HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirect3DImpl *d3d)
+{
+    IDirect3DViewportImpl *object;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+
+    object->ref = 1;
+    object->d3d = d3d;
+    object->activate = activate;
+    object->use_vp2 = 0xFF;
+    object->next = NULL;
+    object->lights = NULL;
+    
+    ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
+
+    *obj = object;
+
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return D3D_OK;
 }
-
-LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-#endif /* HAVE_OPENGL */
diff --git a/dlls/ddraw/ddcomimpl.h b/dlls/ddraw/ddcomimpl.h
index a1be07d..7011770 100644
--- a/dlls/ddraw/ddcomimpl.h
+++ b/dlls/ddraw/ddcomimpl.h
@@ -17,6 +17,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef _DDCOMIMPL_H_
+#define _DDCOMIMPL_H_
+
 #include <stddef.h>
 
 /* Generates the name for a vtable pointer for a given interface. */
@@ -51,3 +54,5 @@
 
 #define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr)	\
 	ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)
+
+#endif /* _DDCOMIMPL_H_ */
diff --git a/dlls/ddraw/ddraw/main.c b/dlls/ddraw/ddraw/main.c
index 981f384..6d9d693 100644
--- a/dlls/ddraw/ddraw/main.c
+++ b/dlls/ddraw/ddraw/main.c
@@ -37,6 +37,7 @@
 #include "wine/debug.h"
 
 #include "ddraw_private.h"
+#include "mesa_private.h" /* To have the D3D creation function */
 #include "ddraw/main.h"
 #include "dclipper/main.h"
 #include "dpalette/main.h"
@@ -139,13 +140,15 @@
     return ref;
 }
 
-/* TODO: need to support IDirect3D. */
 HRESULT WINAPI Main_DirectDraw_QueryInterface(
     LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj
 ) {
     ICOM_THIS(IDirectDrawImpl,iface);
     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
 
+    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
+    *obj = NULL;
+    
     if ( IsEqualGUID( &IID_IUnknown, refiid )
 	 || IsEqualGUID( &IID_IDirectDraw7, refiid ) )
     {
@@ -164,17 +167,53 @@
 	*obj = ICOM_INTERFACE(This, IDirectDraw4);
     }
 #ifdef HAVE_OPENGL
-    else if ( IsEqualGUID( &IID_IDirect3D3, refiid ) )
+    else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
     {
-	return create_direct3d3(obj, This);
+        IDirect3DImpl *d3d_impl;
+	HRESULT ret_value;
+
+	ret_value = direct3d_create(&d3d_impl, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D);
+
+	TRACE(" returning Direct3D interface at %p.\n", *obj);
     }
-    else if ( IsEqualGUID( &IID_IDirect3D2, refiid ) )
+    else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
     {
-	return create_direct3d2(obj, This);
+        IDirect3DImpl *d3d_impl;
+	HRESULT ret_value;
+
+	ret_value = direct3d_create(&d3d_impl, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
+
+	TRACE(" returning Direct3D2 interface at %p.\n", *obj);
     }
-    else if ( IsEqualGUID( &IID_IDirect3D, refiid ) )
+    else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
     {
-	return create_direct3d(obj, This);
+        IDirect3DImpl *d3d_impl;
+	HRESULT ret_value;
+
+	ret_value = direct3d_create(&d3d_impl, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
+
+	TRACE(" returning Direct3D3 interface at %p.\n", *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
+    {
+        IDirect3DImpl *d3d_impl;
+	HRESULT ret_value;
+
+	ret_value = direct3d_create(&d3d_impl, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
+
+	TRACE(" returning Direct3D7 interface at %p.\n", *obj);
     }
 #endif
     else
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index e7a2f3a..1b2b3db 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -280,8 +280,8 @@
     void (*aux_release)(LPVOID ctx, LPVOID data);
     BOOL (*aux_flip)(LPVOID ctx, LPVOID data);
     void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect);
-    struct IDirect3DTexture2Impl*	texture;
-    HRESULT (WINAPI *SetColorKey_cb)(struct IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
+    struct IDirect3DTextureImpl *texture;
+    HRESULT (WINAPI *SetColorKey_cb)(struct IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
 };
 
 /*****************************************************************************
@@ -333,11 +333,6 @@
 extern Convert ModeEmulations[8];
 extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw);
 
-extern HRESULT create_direct3d(LPVOID *obj,IDirectDrawImpl*);
-extern HRESULT create_direct3d2(LPVOID *obj,IDirectDrawImpl*);
-extern HRESULT create_direct3d3(LPVOID *obj,IDirectDrawImpl*);
-extern HRESULT create_direct3d7(LPVOID *obj,IDirectDrawImpl*);
-
 /******************************************************************************
  * Structure conversion (for thunks)
  */
diff --git a/dlls/ddraw/direct3d/main.c b/dlls/ddraw/direct3d/main.c
index c634565..3f1f096 100644
--- a/dlls/ddraw/direct3d/main.c
+++ b/dlls/ddraw/direct3d/main.c
@@ -35,263 +35,466 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-static ICOM_VTABLE(IDirect3D) d3dvt;
-static ICOM_VTABLE(IDirect3D2) d3d2vt;
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3D7 iface,
+                                             REFIID riid,
+                                             LPVOID* obp)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
 
-/*******************************************************************************
- *				IDirect3D
- */
-HRESULT WINAPI IDirect3DImpl_QueryInterface(
-    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    /* FIXME: Not sure if this is correct */
+    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
 
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-    if (( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
-	( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
-	( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    /* By default, set the object pointer to NULL */
+    *obp = NULL;
+      
+    if (( IsEqualGUID( &IID_IDirectDraw,  riid ) ) ||
+	( IsEqualGUID (&IID_IDirectDraw2, riid ) ) ||
+	( IsEqualGUID (&IID_IDirectDraw4, riid ) ) ||
+	( IsEqualGUID( &IID_IDirectDraw7, riid ) )
     ) {
-	*obj = This->ddraw;
-	IDirect3D_AddRef(iface);
-	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
+        HRESULT ret;
+	TRACE("  Creating IDirectDrawX interface by calling DirectDraw function.\n");
+	ret = IDirectDraw_QueryInterface(ICOM_INTERFACE(This->ddraw,IDirectDraw), riid, obp);
+	if (ret == S_OK) {
+	    IDirectDraw_Release(ICOM_INTERFACE(This->ddraw,IDirectDraw));
+	    IDirect3D_AddRef(ICOM_INTERFACE(This,IDirect3D));
+	}
+	return ret;
+    }
+    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
+        IDirect3D_AddRef(ICOM_INTERFACE(This,IDirect3D));
+	*obp = iface;
+	TRACE("  Creating IUnknown interface at %p.\n", *obp);
 	return S_OK;
     }
-    if (( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
-	( IsEqualGUID( &IID_IUnknown,  refiid ) ) ) {
-	*obj = This;
-	IDirect3D_AddRef(iface);
-	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
+    if ( IsEqualGUID( &IID_IDirect3D, riid ) ) {
+        IDirect3D_AddRef(ICOM_INTERFACE(This,IDirect3D));
+        *obp = ICOM_INTERFACE(This, IDirect3D);
+	TRACE("  Creating IDirect3D interface %p\n", *obp);
 	return S_OK;
     }
-    if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
-	IDirect3D2Impl*  d3d;
-
-	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-	d3d->ref = 1;
-	d3d->ddraw = This->ddraw;
-	IDirect3D_AddRef(iface);
-	ICOM_VTBL(d3d) = &d3d2vt;
-	*obj = d3d;
-	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
+    if ( IsEqualGUID( &IID_IDirect3D2, riid ) ) {
+        IDirect3D_AddRef(ICOM_INTERFACE(This,IDirect3D));
+        *obp = ICOM_INTERFACE(This, IDirect3D2);
+	TRACE("  Creating IDirect3D2 interface %p\n", *obp);
 	return S_OK;
     }
-    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    if ( IsEqualGUID( &IID_IDirect3D3, riid ) ) {
+        IDirect3D_AddRef(ICOM_INTERFACE(This,IDirect3D));
+        *obp = ICOM_INTERFACE(This, IDirect3D3);
+	TRACE("  Creating IDirect3D3 interface %p\n", *obp);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3D7, riid ) ) {
+        /* This is not 100 % true as we should not be able to QueryInterface a '7' version from another one.
+	   But well, to factorize the code, why check for application bugs :-) ?
+	 */
+        IDirect3D_AddRef(ICOM_INTERFACE(This,IDirect3D));
+        *obp = ICOM_INTERFACE(This, IDirect3D7);
+	TRACE("  Creating IDirect3D7 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;
 }
 
-ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+ULONG WINAPI
+Main_IDirect3DImpl_7_3T_2T_1T_AddRef(LPDIRECT3D7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
 
     return ++(This->ref);
 }
 
-ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
+ULONG WINAPI
+Main_IDirect3DImpl_7_3T_2T_1T_Release(LPDIRECT3D7 iface)
 {
-    ICOM_THIS(IDirect3DImpl,iface);
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (!--(This->ref)) {
-	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
-	HeapFree(GetProcessHeap(),0,This);
-	return S_OK;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
+    if (--(This->ref) == 0) {
+        IDirectDraw_Release(ICOM_INTERFACE(This->ddraw, IDirectDraw));
+	HeapFree(GetProcessHeap(), 0, This);
+	return 0;
     }
     return This->ref;
 }
 
-HRESULT WINAPI IDirect3DImpl_Initialize(LPDIRECT3D iface,REFIID refiid) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    /* FIXME: Not sure if this is correct */
-    FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
-    return DDERR_ALREADYINITIALIZED;
-}
-
-HRESULT WINAPI IDirect3DImpl_EnumDevices(
-    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3DImpl_CreateLight(
-    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
-    return E_FAIL;
-}
-
-HRESULT WINAPI IDirect3DImpl_CreateMaterial(
-    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
-    return E_FAIL;
-}
-
-HRESULT WINAPI IDirect3DImpl_CreateViewport(
-    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
-
-    return E_FAIL;
-}
-
-HRESULT WINAPI IDirect3DImpl_FindDevice(
-    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
-    LPD3DFINDDEVICERESULT lpfinddevrst)
+HRESULT WINAPI
+Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface,
+                                REFIID riid)
 {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
-    return DD_OK;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D, iface);
+    TRACE("(%p/%p)->(%s) no-op...\n", This, iface, debugstr_guid(riid));
+    return D3D_OK;
 }
 
-/* This is for checking the correctness of the prototypes/functions.
- * Do not remove.
- */
-static ICOM_VTABLE(IDirect3D) WINE_UNUSED d3dvt = {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    IDirect3DImpl_QueryInterface,
-    IDirect3DImpl_AddRef,
-    IDirect3DImpl_Release,
-    IDirect3DImpl_Initialize,
-    IDirect3DImpl_EnumDevices,
-    IDirect3DImpl_CreateLight,
-    IDirect3DImpl_CreateMaterial,
-    IDirect3DImpl_CreateViewport,
-    IDirect3DImpl_FindDevice
-};
-
-/*******************************************************************************
- *				IDirect3D2
- */
-HRESULT WINAPI IDirect3D2Impl_QueryInterface(
-    LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-
-    /* FIXME: Not sure if this is correct */
-
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-    if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
-	 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
-	 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
-	*obj = This->ddraw;
-	IDirect3D2_AddRef(iface);
-
-	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
-
-	return S_OK;
-    }
-    if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
-	 ( IsEqualGUID( &IID_IUnknown,   refiid ) ) ) {
-	*obj = This;
-	IDirect3D2_AddRef(iface);
-
-	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
-	IDirect3DImpl*  d3d;
-
-	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-	d3d->ref = 1;
-	d3d->ddraw = This->ddraw;
-	IDirect3D2_AddRef(iface);
-	ICOM_VTBL(d3d) = &d3dvt;
-	*obj = d3d;
-	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-	return S_OK;
-    }
-    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
-    return OLE_E_ENUM_NOMORE;
-}
-
-ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-
-    return ++(This->ref);
-}
-
-ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (!--(This->ref)) {
-	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
-	HeapFree(GetProcessHeap(),0,This);
-	return S_OK;
-    }
-    return This->ref;
-}
-
-HRESULT WINAPI IDirect3D2Impl_EnumDevices(
-    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
-    return DD_OK;
-}
-
-HRESULT WINAPI IDirect3D2Impl_CreateLight(
-    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
-    return E_FAIL;
-}
-
-HRESULT WINAPI IDirect3D2Impl_CreateMaterial(
-    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
-    return E_FAIL;
-}
-
-HRESULT WINAPI IDirect3D2Impl_CreateViewport(
-    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
-    return E_FAIL;
-}
-
-HRESULT WINAPI IDirect3D2Impl_FindDevice(
-    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
-    LPD3DFINDDEVICERESULT lpfinddevrst)
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface,
+                                       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+                                       LPVOID lpUserArg)
 {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
-    return DD_OK;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg);
+    return D3D_OK;
 }
 
-HRESULT WINAPI IDirect3D2Impl_CreateDevice(
-    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
-    LPDIRECT3DDEVICE2 *device)
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
+                                       LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                       IUnknown* pUnkOuter)
 {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
-    return DDERR_INVALIDPARAMS;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DLight, pUnkOuter);
+    return D3D_OK;
 }
 
-/* This is for checking the correctness of the prototypes/functions.
- * Do not remove.
- */
-static ICOM_VTABLE(IDirect3D2) WINE_UNUSED d3d2vt =
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
+					  LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
+					  IUnknown* pUnkOuter)
 {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    IDirect3D2Impl_QueryInterface,
-    IDirect3D2Impl_AddRef,
-    IDirect3D2Impl_Release,
-    IDirect3D2Impl_EnumDevices,
-    IDirect3D2Impl_CreateLight,
-    IDirect3D2Impl_CreateMaterial,
-    IDirect3D2Impl_CreateViewport,
-    IDirect3D2Impl_FindDevice,
-    IDirect3D2Impl_CreateDevice
-};
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
+					  LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
+					  IUnknown* pUnkOuter)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpD3DViewport3, pUnkOuter);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface,
+                                LPD3DFINDDEVICESEARCH lpD3DDFS,
+                                LPD3DFINDDEVICERESULT lplpD3DDevice)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DDFS, lplpD3DDevice);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_FindDevice(LPDIRECT3D3 iface,
+                                   LPD3DFINDDEVICESEARCH lpD3DDFS,
+                                   LPD3DFINDDEVICERESULT lpD3DFDR)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DDFS, lpD3DFDR);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
+                                  REFCLSID rclsid,
+                                  LPDIRECTDRAWSURFACE lpDDS,
+                                  LPDIRECT3DDEVICE2* lplpD3DDevice2)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D2, iface);
+    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
+                                  REFCLSID rclsid,
+                                  LPDIRECTDRAWSURFACE4 lpDDS,
+                                  LPDIRECT3DDEVICE3* lplpD3DDevice3,
+                                  LPUNKNOWN lpUnk)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    FIXME("(%p/%p)->(%s,%p,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3, lpUnk);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
+                                           REFCLSID riidDevice,
+                                           LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
+                                           LPVOID lpContext)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    FIXME("(%p/%p)->(): stub!\n", This, iface);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
+                                 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
+                                 LPVOID lpUserArg)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
+                                  REFCLSID rclsid,
+                                  LPDIRECTDRAWSURFACE7 lpDDS,
+                                  LPDIRECT3DDEVICE7* lplpD3DDevice)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
+					   LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
+					   LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
+					   DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D7, iface);
+    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags);
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface,
+                                     REFIID riid,
+                                     LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3D7_QueryInterface(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D3, IDirect3D7, iface),
+                                     riid,
+                                     obp);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface,
+                                     REFIID riid,
+                                     LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3D7_QueryInterface(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D7, iface),
+                                     riid,
+                                     obp);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface,
+                                     REFIID riid,
+                                     LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirect3D7_QueryInterface(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D7, iface),
+                                     riid,
+                                     obp);
+}
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_AddRef(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D3, IDirect3D7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_AddRef(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_AddRef(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_Release(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D3, IDirect3D7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_Release(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_Release(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface,
+                                         REFCLSID riidDevice,
+                                         LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
+                                         LPVOID lpContext)
+{
+    TRACE("(%p)->(%s,%p,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
+    return IDirect3D7_EnumZBufferFormats(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D3, IDirect3D7, iface),
+                                         riidDevice,
+                                         lpEnumCallback,
+                                         lpContext);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface)
+{
+    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
+    return IDirect3D7_EvictManagedTextures(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D3, IDirect3D7, iface));
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
+                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+                                  LPVOID lpUserArg)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpEnumDevicesCallback, lpUserArg);
+    return IDirect3D3_EnumDevices(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D3, iface),
+                                  lpEnumDevicesCallback,
+                                  lpUserArg);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
+                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+                                  LPVOID lpUserArg)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpEnumDevicesCallback, lpUserArg);
+    return IDirect3D3_EnumDevices(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D3, iface),
+                                  lpEnumDevicesCallback,
+                                  lpUserArg);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface,
+                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                  IUnknown* pUnkOuter)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter);
+    return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D3, iface),
+                                  lplpDirect3DLight,
+                                  pUnkOuter);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface,
+                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                  IUnknown* pUnkOuter)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter);
+    return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D3, iface),
+                                  lplpDirect3DLight,
+                                  pUnkOuter);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface,
+                                 LPD3DFINDDEVICESEARCH lpD3DDFS,
+                                 LPD3DFINDDEVICERESULT lpD3DFDR)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lpD3DFDR);
+    return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D3, iface),
+                                 lpD3DDFS,
+                                 lpD3DFDR);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface,
+				     LPDIRECT3DMATERIAL* lplpDirect3DMaterial,
+				     IUnknown* pUnkOuter)
+{
+    HRESULT ret;
+    LPDIRECT3DMATERIAL3 ret_val;
+
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial, pUnkOuter);
+    ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D3, iface),
+				    &ret_val,
+				    pUnkOuter);
+
+    *lplpDirect3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial, &ret_val);
+
+    TRACE(" returning interface %p.\n", *lplpDirect3DMaterial);
+    
+    return ret;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface,
+				     LPDIRECT3DVIEWPORT* lplpD3DViewport,
+				     IUnknown* pUnkOuter)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport, pUnkOuter);
+    return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D3, iface),
+				    (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport /* No need to cast here */,
+				    pUnkOuter);
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface,
+				     LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2,
+				     IUnknown* pUnkOuter)
+{
+    HRESULT ret;
+    LPDIRECT3DMATERIAL3 ret_val;
+
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial2, pUnkOuter);
+    ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D3, iface),
+				    &ret_val,
+				    pUnkOuter);
+
+    *lplpDirect3DMaterial2 = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial2, &ret_val);
+
+    TRACE(" returning interface %p.\n", *lplpDirect3DMaterial2);
+    
+    return ret;
+}
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface,
+				     LPDIRECT3DVIEWPORT* lplpD3DViewport2,
+				     IUnknown* pUnkOuter)
+{
+    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport2, pUnkOuter);
+    return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D2, IDirect3D3, iface),
+				     (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport2 /* No need to cast here */,
+				     pUnkOuter);
+}
+
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface,
+					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
+					 LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
+					 DWORD dwFlags,
+					 LPUNKNOWN lpUnk)
+{
+    HRESULT ret;
+    LPDIRECT3DVERTEXBUFFER7 ret_val;
+
+    TRACE("(%p)->(%p,%p,%08lx,%p) thunking to IDirect3D7 interface.\n", iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags, lpUnk);
+    ret = IDirect3D7_CreateVertexBuffer(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D3, IDirect3D7, iface),
+					lpD3DVertBufDesc,
+					&ret_val,
+					dwFlags);
+
+    *lplpD3DVertBuf = COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, IDirect3DVertexBuffer, ret_val);
+
+    TRACE(" returning interface %p.\n", *lplpD3DVertBuf);
+    
+    return ret;
+}
diff --git a/dlls/ddraw/direct3d/main.h b/dlls/ddraw/direct3d/main.h
new file mode 100644
index 0000000..fcd93a9
--- /dev/null
+++ b/dlls/ddraw/direct3d/main.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2002 Lionel Ulmer
+ *
+ * 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
+ */
+
+#include "config.h"
+
+/* This is defined here so as to be able to put them in 'drivers' */
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3D7 iface,
+                                             REFIID riid,
+                                             LPVOID* obp);
+
+ULONG WINAPI
+Main_IDirect3DImpl_7_3T_2T_1T_AddRef(LPDIRECT3D7 iface);
+
+ULONG WINAPI
+Main_IDirect3DImpl_7_3T_2T_1T_Release(LPDIRECT3D7 iface);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
+                                 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
+                                 LPVOID lpUserArg);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
+                                  REFCLSID rclsid,
+                                  LPDIRECTDRAWSURFACE7 lpDDS,
+                                  LPDIRECT3DDEVICE7* lplpD3DDevice);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
+					   LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
+					   LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
+					   DWORD dwFlags);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
+                                           REFCLSID riidDevice,
+                                           LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
+                                           LPVOID lpContext);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface,
+                                       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+                                       LPVOID lpUserArg);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
+                                       LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                       IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
+					  LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
+					  IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
+					  LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
+					  IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_2T_FindDevice(LPDIRECT3D3 iface,
+                                   LPD3DFINDDEVICESEARCH lpD3DDFS,
+                                   LPD3DFINDDEVICERESULT lpD3DFDR);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
+                                  REFCLSID rclsid,
+                                  LPDIRECTDRAWSURFACE4 lpDDS,
+                                  LPDIRECT3DDEVICE3* lplpD3DDevice3,
+                                  LPUNKNOWN lpUnk);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface,
+					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
+					 LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
+					 DWORD dwFlags,
+					 LPUNKNOWN lpUnk);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface,
+				     LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2,
+				     IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface,
+				     LPDIRECT3DVIEWPORT2* lplpD3DViewport2,
+				     IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
+                                  REFCLSID rclsid,
+                                  LPDIRECTDRAWSURFACE lpDDS,
+                                  LPDIRECT3DDEVICE2* lplpD3DDevice2);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface,
+                                REFIID riid);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface,
+				     LPDIRECT3DMATERIAL* lplpDirect3DMaterial,
+				     IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface,
+				     LPDIRECT3DVIEWPORT* lplpD3DViewport,
+				     IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Main_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface,
+                                LPD3DFINDDEVICESEARCH lpD3DDFS,
+                                LPD3DFINDDEVICERESULT lplpD3DDevice);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface,
+                                     REFIID riid,
+                                     LPVOID* obp);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface,
+                                     REFIID riid,
+                                     LPVOID* obp);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface,
+                                     REFIID riid,
+                                     LPVOID* obp);
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface);
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface);
+
+ULONG WINAPI
+Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface,
+                                         REFCLSID riidDevice,
+                                         LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
+                                         LPVOID lpContext);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
+                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+                                  LPVOID lpUserArg);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
+                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+                                  LPVOID lpUserArg);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface,
+                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                  IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface,
+                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
+                                  IUnknown* pUnkOuter);
+
+HRESULT WINAPI
+Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface,
+                                 LPD3DFINDDEVICESEARCH lpD3DDFS,
+                                 LPD3DFINDDEVICERESULT lpD3DFDR);
diff --git a/dlls/ddraw/direct3d/mesa.c b/dlls/ddraw/direct3d/mesa.c
index 5c2dac9..4d7cc3d 100644
--- a/dlls/ddraw/direct3d/mesa.c
+++ b/dlls/ddraw/direct3d/mesa.c
@@ -32,382 +32,342 @@
 #include "winerror.h"
 
 #include "ddraw_private.h"
+#include "d3d_private.h"
 #include "mesa_private.h"
+#include "main.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-/*******************************************************************************
- *				IDirect3D
- */
-static HRESULT WINAPI MESA_IDirect3DImpl_QueryInterface(
-    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    /* FIXME: Not sure if this is correct */
+#define MAX_LIGHTS 8
 
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-    if (( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
-	( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
-	( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
-    ) {
-	*obj = This->ddraw;
-	IDirect3D_AddRef(iface);
-	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
-	return S_OK;
-    }
-    if (( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
-	( IsEqualGUID( &IID_IUnknown,  refiid ) ) ) {
-	*obj = This;
-	IDirect3D_AddRef(iface);
-	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
-	IDirect3D2Impl*  d3d;
-
-	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-	d3d->ref = 1;
-	d3d->ddraw = This->ddraw;
-	IDirect3D_AddRef(iface);
-	ICOM_VTBL(d3d) = &mesa_d3d2vt;
-	*obj = d3d;
-	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-	return S_OK;
-    }
-    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
-    return OLE_E_ENUM_NOMORE;
-}
-
-static ULONG WINAPI MESA_IDirect3DImpl_Release(LPDIRECT3D iface)
+HRESULT WINAPI
+GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
+			       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+			       LPVOID lpUserArg)
 {
-    ICOM_THIS(IDirect3DImpl,iface);
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (!--(This->ref)) {
-	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
-	HeapFree(GetProcessHeap(),0,This);
-	return S_OK;
-    }
-    return This->ref;
-}
-
-static HRESULT WINAPI MESA_IDirect3DImpl_EnumDevices(
-    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
 
     /* Call functions defined in d3ddevices.c */
-    if (!d3d_OpenGL_dx3(cb, context))
+    if (d3device_enumerate(lpEnumDevicesCallback, lpUserArg, 1) != D3DENUMRET_OK)
 	return D3D_OK;
 
     return D3D_OK;
 }
 
-static HRESULT WINAPI MESA_IDirect3DImpl_CreateLight(
-    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
-
-    /* Call the creation function that is located in d3dlight.c */
-    *lplight = d3dlight_create_dx3(This);
-
-    return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DImpl_CreateMaterial(
-    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
-    /* Call the creation function that is located in d3dviewport.c */
-    *lpmaterial = d3dmaterial_create(This);
-    return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DImpl_CreateViewport(
-    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3DImpl,iface);
-    TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
-
-    /* Call the creation function that is located in d3dviewport.c */
-    *lpviewport = d3dviewport_create(This);
-
-    return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3DImpl_FindDevice(
-    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
-    LPD3DFINDDEVICERESULT lpfinddevrst)
+HRESULT WINAPI
+GL_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
+			       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+			       LPVOID lpUserArg)
 {
-    ICOM_THIS(IDirect3DImpl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
-
-    return D3D_OK;
-}
-
-ICOM_VTABLE(IDirect3D) mesa_d3dvt =
-{
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    MESA_IDirect3DImpl_QueryInterface,
-    IDirect3DImpl_AddRef,
-    MESA_IDirect3DImpl_Release,
-    IDirect3DImpl_Initialize,
-    MESA_IDirect3DImpl_EnumDevices,
-    MESA_IDirect3DImpl_CreateLight,
-    MESA_IDirect3DImpl_CreateMaterial,
-    MESA_IDirect3DImpl_CreateViewport,
-    MESA_IDirect3DImpl_FindDevice
-};
-
-/*******************************************************************************
- *				IDirect3D2
- */
-static HRESULT WINAPI MESA_IDirect3D2Impl_QueryInterface(
-    LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-
-    /* FIXME: Not sure if this is correct */
-
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-    if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
-	 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
-	 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
-	*obj = This->ddraw;
-	IDirect3D2_AddRef(iface);
-
-	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
-
-	return S_OK;
-    }
-    if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
-	 ( IsEqualGUID( &IID_IUnknown,   refiid ) ) ) {
-	*obj = This;
-	IDirect3D2_AddRef(iface);
-
-	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
-	IDirect3DImpl*  d3d;
-
-	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-	d3d->ref = 1;
-	d3d->ddraw = This->ddraw;
-	IDirect3D2_AddRef(iface);
-	ICOM_VTBL(d3d) = &mesa_d3dvt;
-	*obj = d3d;
-	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-	return S_OK;
-    }
-    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
-    return OLE_E_ENUM_NOMORE;
-}
-
-static ULONG WINAPI MESA_IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (!--(This->ref)) {
-	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
-	HeapFree(GetProcessHeap(),0,This);
-	return S_OK;
-    }
-    return This->ref;
-}
-
-static HRESULT WINAPI MESA_IDirect3D2Impl_EnumDevices(
-    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D2, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
 
     /* Call functions defined in d3ddevices.c */
-    if (!d3d_OpenGL(cb, context))
+    if (d3device_enumerate(lpEnumDevicesCallback, lpUserArg, 2) != D3DENUMRET_OK)
 	return D3D_OK;
-    return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3D2Impl_CreateLight(
-    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
-
-    /* Call the creation function that is located in d3dlight.c */
-    *lplight = d3dlight_create(This);
 
     return D3D_OK;
 }
 
-static HRESULT WINAPI MESA_IDirect3D2Impl_CreateMaterial(
-    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
-
-    /* Call the creation function that is located in d3dviewport.c */
-    *lpmaterial = d3dmaterial2_create(This);
-
-    return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3D2Impl_CreateViewport(
-    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
-) {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
-
-    /* Call the creation function that is located in d3dviewport.c */
-    *lpviewport = d3dviewport2_create(This);
-
-    return D3D_OK;
-}
-
-static HRESULT WINAPI MESA_IDirect3D2Impl_FindDevice(
-    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
-    LPD3DFINDDEVICERESULT lpfinddevrst)
+HRESULT WINAPI
+GL_IDirect3DImpl_3_EnumDevices(LPDIRECT3D3 iface,
+			       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+			       LPVOID lpUserArg)
 {
-    ICOM_THIS(IDirect3D2Impl,iface);
-    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
+
+    /* Call functions defined in d3ddevices.c */
+    if (d3device_enumerate(lpEnumDevicesCallback, lpUserArg, 3) != D3DENUMRET_OK)
+	return D3D_OK;
+
     return D3D_OK;
 }
 
-static HRESULT WINAPI MESA_IDirect3D2Impl_CreateDevice(
-    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
-    LPDIRECT3DDEVICE2 *device)
+HRESULT WINAPI
+GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
+				     LPDIRECT3DLIGHT* lplpDirect3DLight,
+				     IUnknown* pUnkOuter)
 {
-    ICOM_THIS(IDirect3D2Impl,iface);
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This;
+    int fl;
+    IDirect3DLightImpl *d3dlimpl;
+    HRESULT ret_value;
+    
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DLight, pUnkOuter);
+    for (fl = 0; fl < MAX_LIGHTS; fl++) {
+        if ((glThis->free_lights & (0x01 << fl)) != 0) {
+	    glThis->free_lights &= ~(0x01 << fl);
+	    break;
+	}
+    }
+    if (fl == MAX_LIGHTS) {
+        return DDERR_INVALIDPARAMS; /* No way to say 'max lights reached' ... */
+    }
+    ret_value = d3dlight_create(&d3dlimpl, This, GL_LIGHT0 + fl);
+    *lplpDirect3DLight = ICOM_INTERFACE(d3dlimpl, IDirect3DLight);
 
-    FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
+    return ret_value;
+}
 
-    if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
-	IDirect3D2_AddRef(iface);
+HRESULT WINAPI
+GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
+					LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
+					IUnknown* pUnkOuter)
+{
+    IDirect3DMaterialImpl *D3Dmat_impl;
+    HRESULT ret_value;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
+    ret_value = d3dmaterial_create(&D3Dmat_impl, This);
+
+    *lplpDirect3DMaterial3 = ICOM_INTERFACE(D3Dmat_impl, IDirect3DMaterial3);
+
+    return ret_value;
+}
+
+HRESULT WINAPI
+GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
+					LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
+					IUnknown* pUnkOuter)
+{
+    IDirect3DViewportImpl *D3Dvp_impl;
+    HRESULT ret_value;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpD3DViewport3, pUnkOuter);
+    ret_value = d3dviewport_create(&D3Dvp_impl, This);
+
+    *lplpD3DViewport3 = ICOM_INTERFACE(D3Dvp_impl, IDirect3DViewport3);
+
+    return ret_value;
+}
+
+static HRESULT
+create_device_helper(IDirect3DImpl *This,
+		     REFCLSID iid,
+		     IDirectDrawSurfaceImpl *lpDDS,
+		     void **obj,
+		     int interface) {
+    IDirect3DDeviceImpl *lpd3ddev;
+    HRESULT ret_value;
+
+    ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS);
+    if (FAILED(ret_value)) return ret_value;
+    
+    if (IsEqualGUID( &IID_D3DDEVICE_OpenGL, iid )) {
+	*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice);
+        TRACE(" returning OpenGL D3DDevice %p\n", *obj);
 	return D3D_OK;
     }
+    if (IsEqualGUID( &IID_D3DDEVICE2_OpenGL, iid )) {
+        TRACE(" returning OpenGL D3DDevice2 %p\n", *obj);
+	*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice2);
+	return D3D_OK;
+    }
+    if (IsEqualGUID( &IID_D3DDEVICE3_OpenGL, iid )) {
+        TRACE(" returning OpenGL D3DDevice3 %p\n", *obj);
+	*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice3);
+	return D3D_OK;
+    }
+    if (IsEqualGUID( &IID_D3DDEVICE7_OpenGL, iid )) {
+        TRACE(" returning OpenGL D3DDevice7 %p\n", *obj);
+	*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7);
+	return D3D_OK;
+    }
+    if ((iid == NULL) ||
+	(IsEqualGUID(&IID_IDirect3DHALDevice, iid)) ||
+	(IsEqualGUID(&IID_D3DDEVICE_Default, iid))) {
+        switch (interface) {
+	    case 1:
+		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice);
+	        TRACE(" returning OpenGL D3DDevice %p via default / HAL interface\n", *obj);
+		return D3D_OK;
 
+	    case 2:
+		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice2);
+	        TRACE(" returning OpenGL D3DDevice2 %p via default / HAL interface\n", *obj);
+		return D3D_OK;
+
+	    case 3:
+		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice3);
+	        TRACE(" returning OpenGL D3DDevice3 %p via default / HAL interface\n", *obj);
+		return D3D_OK;
+
+	    case 7:
+		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7);
+	        TRACE(" returning OpenGL D3DDevice7 %p via default / HAL interface\n", *obj);
+		return D3D_OK;
+        }
+    }
+
+    *obj = NULL;
+    ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid));
+    IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7));
     return DDERR_INVALIDPARAMS;
 }
+     
 
-ICOM_VTABLE(IDirect3D2) mesa_d3d2vt =
+HRESULT WINAPI
+GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
+				REFCLSID rclsid,
+				LPDIRECTDRAWSURFACE lpDDS,
+				LPDIRECT3DDEVICE2* lplpD3DDevice2)
 {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    MESA_IDirect3D2Impl_QueryInterface,
-    IDirect3D2Impl_AddRef,
-    MESA_IDirect3D2Impl_Release,
-    MESA_IDirect3D2Impl_EnumDevices,
-    MESA_IDirect3D2Impl_CreateLight,
-    MESA_IDirect3D2Impl_CreateMaterial,
-    MESA_IDirect3D2Impl_CreateViewport,
-    MESA_IDirect3D2Impl_FindDevice,
-    MESA_IDirect3D2Impl_CreateDevice
-};
-
-static HRESULT WINAPI MESA_IDirect3D3Impl_CreateVertexBuffer(
-    LPDIRECT3D3 iface,
-    LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
-    LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
-    DWORD dwFlags,
-    LPUNKNOWN lpUnk)
-{
-  FIXME(":stub\n");
-  return D3D_OK;
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D2, iface);
+    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, lpDDS);
+    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
+    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice2, 2);
 }
 
-static HRESULT WINAPI MESA_IDirect3D3Impl_EnumZBufferFormats(
-    LPDIRECT3D3 iface,
-    REFCLSID riidDevice,
-    LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
-    LPVOID lpContext)
+HRESULT WINAPI
+GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
+				REFCLSID rclsid,
+				LPDIRECTDRAWSURFACE4 lpDDS,
+				LPDIRECT3DDEVICE3* lplpD3DDevice3,
+				LPUNKNOWN lpUnk)
 {
-  FIXME(":stub\n");
-  return DDERR_NOZBUFFERHW; /* Pretend we don't have valid HW */
+    ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface);
+    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
+    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3);
+    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice3, 3);
 }
 
-static HRESULT WINAPI MESA_IDirect3D3Impl_EvictManagedTextures(
-    LPDIRECT3D3 iface)
+static void light_released(IDirect3DImpl *This, GLenum light_num)
 {
-  FIXME(":stub\n");
-  return D3D_OK;
+    IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This;
+    glThis->free_lights |= (light_num - GL_LIGHT0);
 }
 
-
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(mesa_d3d3vt.fun))
+# define XCAST(fun)     (typeof(VTABLE_IDirect3D7.fun))
 #else
-# define XCAST(fun)	(void*)
+# define XCAST(fun)     (void*)
 #endif
 
-ICOM_VTABLE(IDirect3D3) mesa_d3d3vt =
+ICOM_VTABLE(IDirect3D7) VTABLE_IDirect3D7 =
 {
     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    XCAST(QueryInterface)MESA_IDirect3D2Impl_QueryInterface,
-    XCAST(AddRef)IDirect3D2Impl_AddRef,
-    XCAST(Release)MESA_IDirect3D2Impl_Release,
-    XCAST(EnumDevices)MESA_IDirect3D2Impl_EnumDevices,
-    XCAST(CreateLight)MESA_IDirect3D2Impl_CreateLight,
-    XCAST(CreateMaterial)MESA_IDirect3D2Impl_CreateMaterial,
-    XCAST(CreateViewport)MESA_IDirect3D2Impl_CreateViewport,
-    XCAST(FindDevice)MESA_IDirect3D2Impl_FindDevice,
-    XCAST(CreateDevice)MESA_IDirect3D2Impl_CreateDevice,
-    XCAST(CreateVertexBuffer)MESA_IDirect3D3Impl_CreateVertexBuffer,
-    XCAST(EnumZBufferFormats)MESA_IDirect3D3Impl_EnumZBufferFormats,
-    XCAST(EvictManagedTextures)MESA_IDirect3D3Impl_EvictManagedTextures
+    XCAST(QueryInterface) Main_IDirect3DImpl_7_3T_2T_1T_QueryInterface,
+    XCAST(AddRef) Main_IDirect3DImpl_7_3T_2T_1T_AddRef,
+    XCAST(Release) Main_IDirect3DImpl_7_3T_2T_1T_Release,
+    XCAST(EnumDevices) Main_IDirect3DImpl_7_EnumDevices,
+    XCAST(CreateDevice) Main_IDirect3DImpl_7_CreateDevice,
+    XCAST(CreateVertexBuffer) Main_IDirect3DImpl_7_3T_CreateVertexBuffer,
+    XCAST(EnumZBufferFormats) Main_IDirect3DImpl_7_3T_EnumZBufferFormats,
+    XCAST(EvictManagedTextures) Main_IDirect3DImpl_7_3T_EvictManagedTextures,
 };
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
 #undef XCAST
 #endif
 
-HRESULT create_direct3d(LPVOID *obj,IDirectDrawImpl* ddraw) {
-    IDirect3DImpl* d3d;
 
-    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-    d3d->ref = 1;
-    d3d->ddraw = (IDirectDrawImpl *) ddraw;
-    d3d->private = NULL; /* unused for now */
-    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
-    ICOM_VTBL(d3d) = &mesa_d3dvt;
-    *obj = (LPUNKNOWN)d3d;
-    TRACE("  Created IDirect3D interface (%p)\n", *obj);
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3D3.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
 
-    return S_OK;
+ICOM_VTABLE(IDirect3D3) VTABLE_IDirect3D3 =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef,
+    XCAST(Release) Thunk_IDirect3DImpl_3_Release,
+    XCAST(EnumDevices) GL_IDirect3DImpl_3_EnumDevices,
+    XCAST(CreateLight) Main_IDirect3DImpl_3_2T_1T_CreateLight,
+    XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial,
+    XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport,
+    XCAST(FindDevice) Main_IDirect3DImpl_3_2T_FindDevice,
+    XCAST(CreateDevice) GL_IDirect3DImpl_3_CreateDevice,
+    XCAST(CreateVertexBuffer) Thunk_IDirect3DImpl_3_CreateVertexBuffer,
+    XCAST(EnumZBufferFormats) Thunk_IDirect3DImpl_3_EnumZBufferFormats,
+    XCAST(EvictManagedTextures) Thunk_IDirect3DImpl_3_EvictManagedTextures,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3D2.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3D2) VTABLE_IDirect3D2 =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DImpl_2_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DImpl_2_AddRef,
+    XCAST(Release) Thunk_IDirect3DImpl_2_Release,
+    XCAST(EnumDevices) Thunk_IDirect3DImpl_2_EnumDevices,
+    XCAST(CreateLight) Thunk_IDirect3DImpl_2_CreateLight,
+    XCAST(CreateMaterial) Thunk_IDirect3DImpl_2_CreateMaterial,
+    XCAST(CreateViewport) Thunk_IDirect3DImpl_2_CreateViewport,
+    XCAST(FindDevice) Thunk_IDirect3DImpl_2_FindDevice,
+    XCAST(CreateDevice) GL_IDirect3DImpl_2_CreateDevice,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)     (typeof(VTABLE_IDirect3D.fun))
+#else
+# define XCAST(fun)     (void*)
+#endif
+
+ICOM_VTABLE(IDirect3D) VTABLE_IDirect3D =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface) Thunk_IDirect3DImpl_1_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DImpl_1_AddRef,
+    XCAST(Release) Thunk_IDirect3DImpl_1_Release,
+    XCAST(Initialize) Main_IDirect3DImpl_1_Initialize,
+    XCAST(EnumDevices) Thunk_IDirect3DImpl_1_EnumDevices,
+    XCAST(CreateLight) Thunk_IDirect3DImpl_1_CreateLight,
+    XCAST(CreateMaterial) Thunk_IDirect3DImpl_1_CreateMaterial,
+    XCAST(CreateViewport) Thunk_IDirect3DImpl_1_CreateViewport,
+    XCAST(FindDevice) Main_IDirect3DImpl_1_FindDevice,
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+#undef XCAST
+#endif
+
+HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw)
+{
+    IDirect3DImpl *object;
+    IDirect3DGLImpl *globject;
+    
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DGLImpl));
+    if (object == NULL) return DDERR_OUTOFMEMORY;
+
+    object->ref = 1;
+    object->ddraw = ddraw;
+    
+    ICOM_INIT_INTERFACE(object, IDirect3D,  VTABLE_IDirect3D);
+    ICOM_INIT_INTERFACE(object, IDirect3D2, VTABLE_IDirect3D2);
+    ICOM_INIT_INTERFACE(object, IDirect3D3, VTABLE_IDirect3D3);
+    ICOM_INIT_INTERFACE(object, IDirect3D7, VTABLE_IDirect3D7);
+
+    globject = (IDirect3DGLImpl *) object;
+    globject->free_lights = (0x01 << MAX_LIGHTS) - 1; /* There are, in total, 8 lights in OpenGL */
+    globject->light_released = light_released;
+
+    *obj = object;
+
+    TRACE(" creating implementation at %p.\n", *obj);
+    
+    return D3D_OK;
 }
-
-HRESULT create_direct3d2(LPVOID *obj,IDirectDrawImpl* ddraw) {
-    IDirect3D2Impl* d3d;
-
-    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-    d3d->ref = 1;
-    d3d->ddraw = (IDirectDrawImpl *) ddraw;
-    d3d->private = NULL; /* unused for now */
-    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
-    ICOM_VTBL(d3d) = &mesa_d3d2vt;
-    *obj = (LPUNKNOWN)d3d;
-    TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-
-    return S_OK;
-}
-
-HRESULT create_direct3d3(LPVOID *obj,IDirectDrawImpl* ddraw) {
-    IDirect3D3Impl* d3d;
-
-    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-    d3d->ref = 1;
-    d3d->ddraw = (IDirectDrawImpl *) ddraw;
-    d3d->private = NULL; /* unused for now */
-
-    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
-    ICOM_VTBL(d3d) = &mesa_d3d3vt;
-    *obj = (LPUNKNOWN)d3d;
-
-    TRACE("  Creating IDirect3D3 interface (%p)\n", *obj);
-
-    return S_OK;
-}
-
diff --git a/dlls/ddraw/dsurface/dib.c b/dlls/ddraw/dsurface/dib.c
index e2a4f62..6eec516 100644
--- a/dlls/ddraw/dsurface/dib.c
+++ b/dlls/ddraw/dsurface/dib.c
@@ -395,14 +395,31 @@
 	}
     }
 
-    if (xsrc.bottom > sdesc.dwHeight)
-	xsrc.bottom = sdesc.dwHeight;
-    if (xdst.bottom > ddesc.dwHeight)
-	xdst.bottom = ddesc.dwHeight;
+    /* First check for the validity of source / destination rectangles. This was
+       verified using a test application + by MSDN.
+    */
+    if ((src != NULL) &&
+	((xsrc.bottom > sdesc.dwHeight) || (xsrc.bottom < 0) ||
+	 (xsrc.top > sdesc.dwHeight) || (xsrc.top < 0) ||
+	 (xsrc.left > sdesc.dwWidth) || (xsrc.left < 0) ||
+	 (xsrc.right > sdesc.dwWidth) || (xsrc.right < 0) ||
+	 (xsrc.right < xsrc.left) || (xsrc.bottom < xsrc.top))) {
+        WARN("Application gave us bad source rectangle for Blt.\n");
+	return DDERR_INVALIDRECT;
+    }
+    /* For the Destination rect, it can be out of bounds on the condition that a clipper
+       is set for the given surface.
+    */
+    if ((This->clipper == NULL) &&
+	((xdst.bottom > ddesc.dwHeight) || (xdst.bottom < 0) ||
+	 (xdst.top > ddesc.dwHeight) || (xdst.top < 0) ||
+	 (xdst.left > ddesc.dwWidth) || (xdst.left < 0) ||
+	 (xdst.right > ddesc.dwWidth) || (xdst.right < 0) ||
+	 (xdst.right < xdst.left) || (xdst.bottom < xdst.top))) {
+        WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n");
+	return DDERR_INVALIDRECT;
+    }
     
-    if (src) assert((xsrc.bottom-xsrc.top) <= sdesc.dwHeight);
-    assert((xdst.bottom-xdst.top) <= ddesc.dwHeight);
-
     /* Now handle negative values in the rectangles. Warning: only supported for now
        in the 'simple' cases (ie not in any stretching / rotation cases).
 
@@ -428,9 +445,9 @@
         IntersectRect(&temp_rect, &full_rect, &xdst);
         xdst = temp_rect;
     } else {
-        /* This is trickier as any update to one rectangle need to be propagated to the other */
-        int clip_horiz = (xdst.left < 0) || (xdst.right  > (int) ddesc.dwWidth ) || (xsrc.left < 0) || (xsrc.right  > (int) sdesc.dwWidth );
-        int clip_vert  = (xdst.top  < 0) || (xdst.bottom > (int) ddesc.dwHeight) || (xsrc.top  < 0) || (xsrc.bottom > (int) sdesc.dwHeight);
+        /* Only handle clipping on the destination rectangle */
+        int clip_horiz = (xdst.left < 0) || (xdst.right  > (int) ddesc.dwWidth );
+        int clip_vert  = (xdst.top  < 0) || (xdst.bottom > (int) ddesc.dwHeight);
         if (clip_vert || clip_horiz) {
             /* Now check if this is a special case or not... */
             if ((((xdst.bottom - xdst.top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) ||
@@ -441,15 +458,11 @@
             }
 
             if (clip_horiz) {
-              if (xsrc.left < 0) { xdst.left -= xsrc.left; xsrc.left = 0; }
               if (xdst.left < 0) { xsrc.left -= xdst.left; xdst.left = 0; }
-              if (xsrc.right > sdesc.dwWidth) { xdst.right -= (xsrc.right - (int) sdesc.dwWidth); xsrc.right = (int) sdesc.dwWidth; }
               if (xdst.right > ddesc.dwWidth) { xsrc.right -= (xdst.right - (int) ddesc.dwWidth); xdst.right = (int) ddesc.dwWidth; }
             }
             if (clip_vert) {
-                if (xsrc.top < 0) { xdst.top -= xsrc.top; xsrc.top = 0; }
                 if (xdst.top < 0) { xsrc.top -= xdst.top; xdst.top = 0; }
-                if (xsrc.bottom > sdesc.dwHeight) { xdst.bottom -= (xsrc.bottom - (int) sdesc.dwHeight); xsrc.bottom = (int) sdesc.dwHeight; }
                 if (xdst.bottom > ddesc.dwHeight) { xsrc.bottom -= (xdst.bottom - (int) ddesc.dwHeight); xdst.bottom = (int) ddesc.dwHeight; }
             }
             /* And check if after clipping something is still to be done... */
diff --git a/dlls/ddraw/dsurface/main.c b/dlls/ddraw/dsurface/main.c
index 1b1425f..d3a2626 100644
--- a/dlls/ddraw/dsurface/main.c
+++ b/dlls/ddraw/dsurface/main.c
@@ -169,36 +169,52 @@
 	return S_OK;
     }
 #ifdef HAVE_OPENGL
-    else if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) )
+    else if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) ||
+	      IsEqualGUID( &IID_IDirect3DHALDevice, riid) )
     {
-	This->ref++;
-	return is_OpenGL_dx3(riid, This, (IDirect3DDeviceImpl**)ppObj)?S_OK:E_NOINTERFACE;
+        IDirect3DDeviceImpl *d3ddevimpl;
+	HRESULT ret_value;
+
+	ret_value = d3ddevice_create(&d3ddevimpl, NULL, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice);
+	TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj);
+	
+	This->ref++; /* No idea if this is correct.. Need to check using real Windows */
+	return ret_value;
     }
     else if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
     {
-	LPDIRECT3DTEXTURE iface;
-	This->ref++;
-	iface = d3dtexture_create(This);
-	if (iface) {
-	  *ppObj = (LPVOID)iface;
-	  return S_OK;
-	} else
-	  return E_NOINTERFACE;
+        IDirect3DTextureImpl *d3dteximpl;
+	HRESULT ret_value;
+
+	ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture);
+	TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
+	
+	This->ref++; /* No idea if this is correct.. Need to check using real Windows */
+	return ret_value;
     }    
     else if (IsEqualGUID( &IID_IDirect3DTexture2, riid ))
     {
-	LPDIRECT3DTEXTURE2 iface;
-	This->ref++;
-	iface = d3dtexture2_create(This);
-	if (iface) {
-	  *ppObj = (LPVOID)iface;
-	  return S_OK;
-	} else
-	  return E_NOINTERFACE;
+        IDirect3DTextureImpl *d3dteximpl;
+	HRESULT ret_value;
+
+	ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
+	if (FAILED(ret_value)) return ret_value;
+
+	*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture2);
+	TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
+	
+	This->ref++; /* No idea if this is correct.. Need to check using real Windows */
+	return ret_value;
     }    
 #endif
-    else
-	return E_NOINTERFACE;
+
+    return E_NOINTERFACE;
 }
 
 /*** Callbacks */
diff --git a/dlls/ddraw/mesa.c b/dlls/ddraw/mesa.c
index 7fdd9e1..6d1fc60 100644
--- a/dlls/ddraw/mesa.c
+++ b/dlls/ddraw/mesa.c
@@ -30,249 +30,227 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
-#define D3DTPRIVATE(x) mesa_d3dt_private *dtpriv = (mesa_d3dt_private*)(x)->private
-
 void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
 		      DWORD dwRenderState, RenderState *rs)
 {
+    if (TRACE_ON(ddraw))
+        TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
 
-  if (TRACE_ON(ddraw))
-    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
+    /* First, all the stipple patterns */
+    if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
+	(dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
+        ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
+    } else {
+        ENTER_GL();
 
-  /* First, all the stipple patterns */
-  if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
-      (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
-    ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
-  } else {
-    ENTER_GL();
+	/* All others state variables */
+	switch (dwRenderStateType) {
+	    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
+	        IDirect3DTextureImpl *tex = (IDirect3DTextureImpl*) dwRenderState;
+		
+		if (tex == NULL) {
+		    glBindTexture(GL_TEXTURE_2D, 0);
+		    glDisable(GL_TEXTURE_2D);
+		    TRACE("disabling texturing\n");
+		} else {
+		    IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex;
+		    
+		    glEnable(GL_TEXTURE_2D);
+		    /* Default parameters */
+		    glBindTexture(GL_TEXTURE_2D, gl_tex->tex_name);
+		    /* To prevent state change, we could test here what are the parameters
+		       stored in the texture */
+		    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, rs->mag);
+		    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, rs->min);
+		    TRACE("setting OpenGL texture handle : %d\n", gl_tex->tex_name);
+		}
+	    } break;
 
-    /* All others state variables */
-    switch (dwRenderStateType) {
+	    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
+	        if (dwRenderState)
+		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+		else
+		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+	        break;
 
-    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
-      IDirect3DTexture2Impl* tex = (IDirect3DTexture2Impl*) dwRenderState;
+	    case D3DRENDERSTATE_ZENABLE:          /*  7 */
+	        if (dwRenderState)
+		    glEnable(GL_DEPTH_TEST);
+		else
+		    glDisable(GL_DEPTH_TEST);
+	        break;
 
-      if (tex == NULL) {
-	glBindTexture(GL_TEXTURE_2D, 0);
-	glDisable(GL_TEXTURE_2D);
-	TRACE("disabling texturing\n");
-      } else {
-	D3DTPRIVATE(tex);
+	    case D3DRENDERSTATE_FILLMODE:           /*  8 */
+	        switch ((D3DFILLMODE) dwRenderState) {
+		    case D3DFILL_POINT:
+		        glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);        
+			break;
+		    case D3DFILL_WIREFRAME:
+			glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
+			break;
+		    case D3DFILL_SOLID:
+			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
+			break;
+		    default:
+			ERR("Unhandled fill mode !\n");
+		 }
+	         break;
 
-	glEnable(GL_TEXTURE_2D);
-	/* Default parameters */
-	glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
-	/* To prevent state change, we could test here what are the parameters
-	   stored in the texture */
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, rs->mag);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, rs->min);
-	TRACE("setting OpenGL texture handle : %d\n", dtpriv->tex_name);
-      }
-    } break;
+	    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
+	        switch ((D3DSHADEMODE) dwRenderState) {
+		    case D3DSHADE_FLAT:
+		        glShadeModel(GL_FLAT);
+			break;
+		    case D3DSHADE_GOURAUD:
+			glShadeModel(GL_SMOOTH);
+			break;
+		    default:
+			ERR("Unhandled shade mode !\n");
+		}
+	        break;
 
-    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
-      if (dwRenderState)
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
-      else
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
-      break;
+	    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
+	        if (dwRenderState)
+		    glDepthMask(GL_TRUE);
+		else
+		    glDepthMask(GL_FALSE);
+	        break;
 
-    case D3DRENDERSTATE_ZENABLE:          /*  7 */
-      if (dwRenderState)
-	glEnable(GL_DEPTH_TEST);
-      else
-	glDisable(GL_DEPTH_TEST);
-      break;
+	    case D3DRENDERSTATE_TEXTUREMAG:         /* 17 */
+	        switch ((D3DTEXTUREFILTER) dwRenderState) {
+		    case D3DFILTER_NEAREST:
+		        rs->mag = GL_NEAREST;
+			break;
+		    case D3DFILTER_LINEAR:
+			rs->mag = GL_LINEAR;
+			break;
+		    default:
+			ERR("Unhandled texture mag !\n");
+	        }
+	        break;
 
-    case D3DRENDERSTATE_FILLMODE:           /*  8 */
-      switch ((D3DFILLMODE) dwRenderState) {
-      case D3DFILL_POINT:
-        glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);        
-        break;
-      case D3DFILL_WIREFRAME:
-        glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
-        break;
-      case D3DFILL_SOLID:
-        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
-	break;
+	    case D3DRENDERSTATE_TEXTUREMIN:         /* 18 */
+	        switch ((D3DTEXTUREFILTER) dwRenderState) {
+		    case D3DFILTER_NEAREST:
+		        rs->min = GL_NEAREST;
+			break;
+		    case D3DFILTER_LINEAR:
+			rs->mag = GL_LINEAR;
+			break;
+		    default:
+			ERR("Unhandled texture min !\n");
+		}
+	        break;
 
-      default:
-	ERR("Unhandled fill mode !\n");
-      }
-      break;
+	    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
+	        switch ((D3DBLEND) dwRenderState) {
+		    case D3DBLEND_SRCALPHA:
+		          rs->src = GL_SRC_ALPHA;
+			  break;
+		    default:
+			  ERR("Unhandled blend mode !\n");
+		}
+	        glBlendFunc(rs->src, rs->dst);
+	        break;
 
-    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
-      switch ((D3DSHADEMODE) dwRenderState) {
-      case D3DSHADE_FLAT:
-	glShadeModel(GL_FLAT);
-	break;
+	    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
+	        switch ((D3DBLEND) dwRenderState) {
+		    case D3DBLEND_INVSRCALPHA:
+		        rs->dst = GL_ONE_MINUS_SRC_ALPHA;
+			break;
+		    default:
+			ERR("Unhandled blend mode !\n");
+		}
+	        glBlendFunc(rs->src, rs->dst);
+	        break;
 
-      case D3DSHADE_GOURAUD:
-	glShadeModel(GL_SMOOTH);
-	break;
+	    case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
+	        switch ((D3DTEXTUREBLEND) dwRenderState) {
+		    case D3DTBLEND_MODULATE:
+		    case D3DTBLEND_MODULATEALPHA:
+		          glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+			  break;
+		    default:
+			  ERR("Unhandled texture environment !\n");
+		}
+	        break;
 
-      default:
-	ERR("Unhandled shade mode !\n");
-      }
-      break;
+	    case D3DRENDERSTATE_CULLMODE:           /* 22 */
+	        switch ((D3DCULL) dwRenderState) {
+		    case D3DCULL_NONE:
+		         glDisable(GL_CULL_FACE);
+			 break;
+		    case D3DCULL_CW:
+			 glEnable(GL_CULL_FACE);
+			 glFrontFace(GL_CW);
+			 break;
+		    case D3DCULL_CCW:
+			 glEnable(GL_CULL_FACE);
+			 glFrontFace(GL_CCW);
+			 break;
+		    default:
+			 ERR("Unhandled cull mode !\n");
+		}
+	        break;
 
-    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
-      if (dwRenderState)
-	glDepthMask(GL_TRUE);
-      else
-	glDepthMask(GL_FALSE);
-      break;
+	    case D3DRENDERSTATE_ZFUNC:            /* 23 */
+	        switch ((D3DCMPFUNC) dwRenderState) {
+		    case D3DCMP_NEVER:
+		        glDepthFunc(GL_NEVER);
+			break;
+		    case D3DCMP_LESS:
+			glDepthFunc(GL_LESS);
+			break;
+		    case D3DCMP_EQUAL:
+			glDepthFunc(GL_EQUAL);
+			break;
+		    case D3DCMP_LESSEQUAL:
+			glDepthFunc(GL_LEQUAL);
+			break;
+		    case D3DCMP_GREATER:
+			glDepthFunc(GL_GREATER);
+			break;
+		    case D3DCMP_NOTEQUAL:
+			glDepthFunc(GL_NOTEQUAL);
+			break;
+		    case D3DCMP_GREATEREQUAL:
+			glDepthFunc(GL_GEQUAL);
+			break;
+		    case D3DCMP_ALWAYS:
+			glDepthFunc(GL_ALWAYS);
+			break;
+		    default:
+			ERR("Unexpected value\n");
+		}
+	        break;
 
-    case D3DRENDERSTATE_TEXTUREMAG:         /* 17 */
-      switch ((D3DTEXTUREFILTER) dwRenderState) {
-      case D3DFILTER_NEAREST:
-	rs->mag = GL_NEAREST;
-	break;
+	    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
+	        if (dwRenderState)
+		    glEnable(GL_DITHER);
+		else
+		    glDisable(GL_DITHER);
+	        break;
 
-      case D3DFILTER_LINEAR:
-	rs->mag = GL_LINEAR;
-	break;
+	    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
+	        if (dwRenderState)
+		    glEnable(GL_BLEND);
+		else
+		    glDisable(GL_BLEND);
+	        break;
 
-      default:
-	ERR("Unhandled texture mag !\n");
-      }
-      break;
+	    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
+	        if (dwRenderState)
+		    glEnable(GL_BLEND);
+		else
+		    glDisable(GL_BLEND);
+	        break;
 
-    case D3DRENDERSTATE_TEXTUREMIN:         /* 18 */
-      switch ((D3DTEXTUREFILTER) dwRenderState) {
-      case D3DFILTER_NEAREST:
-	rs->min = GL_NEAREST;
-	break;
+	    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
+	        break;
 
-      case D3DFILTER_LINEAR:
-	rs->mag = GL_LINEAR;
-	break;
-
-      default:
-	ERR("Unhandled texture min !\n");
-      }
-      break;
-
-    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
-      switch ((D3DBLEND) dwRenderState) {
-      case D3DBLEND_SRCALPHA:
-	rs->src = GL_SRC_ALPHA;
-	break;
-
-      default:
-	ERR("Unhandled blend mode !\n");
-      }
-
-      glBlendFunc(rs->src, rs->dst);
-      break;
-
-    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
-      switch ((D3DBLEND) dwRenderState) {
-      case D3DBLEND_INVSRCALPHA:
-	rs->dst = GL_ONE_MINUS_SRC_ALPHA;
-	break;
-
-      default:
-	ERR("Unhandled blend mode !\n");
-      }
-
-      glBlendFunc(rs->src, rs->dst);
-      break;
-
-    case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
-      switch ((D3DTEXTUREBLEND) dwRenderState) {
-      case D3DTBLEND_MODULATE:
-      case D3DTBLEND_MODULATEALPHA:
-	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-	break;
-
-      default:
-	ERR("Unhandled texture environment !\n");
-      }
-      break;
-
-    case D3DRENDERSTATE_CULLMODE:           /* 22 */
-      switch ((D3DCULL) dwRenderState) {
-      case D3DCULL_NONE:
-	glDisable(GL_CULL_FACE);
-	break;
-
-      case D3DCULL_CW:
-	glEnable(GL_CULL_FACE);
-	glFrontFace(GL_CW);
-	break;
-
-      case D3DCULL_CCW:
-	glEnable(GL_CULL_FACE);
-	glFrontFace(GL_CCW);
-	break;
-
-      default:
-	ERR("Unhandled cull mode !\n");
-      }
-      break;
-
-    case D3DRENDERSTATE_ZFUNC:            /* 23 */
-      switch ((D3DCMPFUNC) dwRenderState) {
-      case D3DCMP_NEVER:
-	glDepthFunc(GL_NEVER);
-	break;
-      case D3DCMP_LESS:
-	glDepthFunc(GL_LESS);
-	break;
-      case D3DCMP_EQUAL:
-	glDepthFunc(GL_EQUAL);
-	break;
-      case D3DCMP_LESSEQUAL:
-	glDepthFunc(GL_LEQUAL);
-	break;
-      case D3DCMP_GREATER:
-	glDepthFunc(GL_GREATER);
-	break;
-      case D3DCMP_NOTEQUAL:
-	glDepthFunc(GL_NOTEQUAL);
-	break;
-      case D3DCMP_GREATEREQUAL:
-	glDepthFunc(GL_GEQUAL);
-	break;
-      case D3DCMP_ALWAYS:
-	glDepthFunc(GL_ALWAYS);
-	break;
-
-      default:
-	ERR("Unexpected value\n");
-      }
-      break;
-
-    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
-      if (dwRenderState)
-	glEnable(GL_DITHER);
-      else
-	glDisable(GL_DITHER);
-      break;
-
-    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
-      if (dwRenderState)
-	glEnable(GL_BLEND);
-      else
-	glDisable(GL_BLEND);
-      break;
-
-    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
-      if (dwRenderState)
-	glEnable(GL_BLEND);
-      else
-	glDisable(GL_BLEND);
-      break;
-
-    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
-      break;
-
-    default:
-      ERR("Unhandled dwRenderStateType %s !\n", _get_renderstate(dwRenderStateType));
-      break;
+	    default:
+	        ERR("Unhandled dwRenderStateType %s !\n", _get_renderstate(dwRenderStateType));
+	}
+	LEAVE_GL();
     }
-
-    LEAVE_GL();
-  }
 }
diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h
index 6632f84..6b8790b 100644
--- a/dlls/ddraw/mesa_private.h
+++ b/dlls/ddraw/mesa_private.h
@@ -56,30 +56,74 @@
 #define ENTER_GL() wine_tsx11_lock_ptr()
 #define LEAVE_GL() wine_tsx11_unlock_ptr()
 
+extern const GUID IID_D3DDEVICE_OpenGL;
+extern const GUID IID_D3DDEVICE2_OpenGL;
+extern const GUID IID_D3DDEVICE3_OpenGL;
+extern const GUID IID_D3DDEVICE7_OpenGL;
+extern const GUID IID_D3DDEVICE_Default;
 
-/*****************************************************************************
- * IDirect3DLight MESA private structure
- */
-typedef struct mesa_d3dl_private
-{
-    GLenum              light_num;
-} mesa_d3dl_private;
+typedef struct render_state {
+    /* This is used for the device mode */
+    GLenum src, dst;
+    /* This is used for textures */
+    GLenum mag, min;
+} RenderState;
 
-/*****************************************************************************
- * IDirect3DTexture2 MESA private structure
- */
-typedef struct mesa_d3dt_private
-{
-    GLuint                   tex_name;
-} mesa_d3dt_private;
+/* Common functions defined in d3dcommon.c */
+void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
+		      DWORD dwRenderState, RenderState *rs) ;
 
-/*****************************************************************************
- * IDirect3DViewport2 implementation structure
- */
-typedef struct mesa_d3dv_private
+typedef struct IDirect3DGLImpl
 {
-    GLenum                      nextlight;
-} mesa_d3dv_private;
+    struct IDirect3DImpl parent;
+    int free_lights;
+    void (*light_released)(IDirect3DImpl *, GLenum light_num);
+} IDirect3DGLImpl;
+
+typedef struct IDirect3DLightGLImpl
+{
+    struct IDirect3DLightImpl parent;
+    GLenum light_num;
+} IDirect3DLightGLImpl;
+
+typedef struct IDirect3DTextureGLImpl
+{
+    struct IDirect3DTextureImpl parent;
+    GLuint tex_name;
+} IDirect3DTextureGLImpl;
+
+typedef struct IDirect3DDeviceGLImpl
+{
+    struct IDirect3DDeviceImpl parent;
+    
+    GLXContext gl_context;
+
+    /* The current render state */
+    RenderState render_state;
+
+    /* The last type of vertex drawn */
+    D3DVERTEXTYPE vertex_type;
+
+    D3DMATRIX *world_mat;
+    D3DMATRIX *view_mat;
+    D3DMATRIX *proj_mat;
+    
+    Display  *display;
+    Drawable drawable;
+} IDirect3DDeviceGLImpl;
+
+/* All non-static functions 'exported' by various sub-objects */
+extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw);
+extern HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf);
+extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirect3DImpl *d3d, GLenum light_num);
+extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirect3DImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
+extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirect3DImpl *d3d);
+extern HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirect3DImpl *d3d);
+extern HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc);
+extern HRESULT d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface);
+
+/* Used for Direct3D to request the device to enumerate itself */
+extern HRESULT d3device_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD interface_version) ;
 
 /* Matrix copy WITH transposition */
 #define conv_mat2(mat,gl_mat)			\
@@ -116,74 +160,9 @@
     memcpy(gl_mat, (mat), 16 * sizeof(float));      \
 };
 
-typedef struct render_state {
-  /* This is used for the device mode */
-  GLenum src, dst;
-  /* This is used for textures */
-  GLenum mag, min;
-} RenderState;
-
-typedef struct mesa_d3dd_private {
-    GLXContext ctx;
-
-    /* The current render state */
-    RenderState rs;
-
-    /* The last type of vertex drawn */
-    D3DVERTEXTYPE vt;
-
-    D3DMATRIX *world_mat;
-    D3DMATRIX *view_mat;
-    D3DMATRIX *proj_mat;
-    
-    Display  *gdi_display;
-    Drawable drawable;
-} mesa_d3dd_private;
-
-#define _dump_colorvalue(s,v)               \
-    TRACE(" " s " : %f %f %f %f\n",           \
-	    (v).u1.r, (v).u2.g, (v).u3.b, (v).u4.a);
-
-/* Common functions defined in d3dcommon.c */
-void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
-		      DWORD dwRenderState, RenderState *rs) ;
-
-/* All non-static functions 'exported' by various sub-objects */
-extern LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurfaceImpl* surf);
-extern LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurfaceImpl* surf);
-
-extern LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1);
-extern LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2);
-
-extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
-
-extern LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1);
-extern LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2);
-
-extern LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1);
-extern LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2);
-
-extern int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device);
-extern int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
-extern int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
-extern int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d);
-
-extern LPDIRECT3DTEXTURE2 mesa_d3dtexture2_create(IDirectDrawSurfaceImpl*);
-extern LPDIRECT3DTEXTURE mesa_d3dtexture_create(IDirectDrawSurfaceImpl*);
-
-static const GUID WINE_UNUSED IID_D3DDEVICE2_OpenGL = {
-  0x39a0da38,
-  0x7e57,
-  0x11d2,
-  { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
-};
-
-static const GUID WINE_UNUSED IID_D3DDEVICE_OpenGL = {
-  0x31416d44,
-  0x86ae,
-  0x11d2,
-  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
-};
+#define _dump_colorvalue(s,v)                \
+    TRACE(" " s " : %f %f %f %f\n",          \
+    (v).u1.r, (v).u2.g, (v).u3.b, (v).u4.a);
 
 /* This structure contains all the function pointers to OpenGL extensions
    that are used by Wine */
@@ -192,10 +171,6 @@
 			     GLsizei width, GLenum format, GLenum type, const GLvoid *table);
 } Mesa_DeviceCapabilities;
 
-extern ICOM_VTABLE(IDirect3D) mesa_d3dvt;
-extern ICOM_VTABLE(IDirect3D2) mesa_d3d2vt;
-extern ICOM_VTABLE(IDirect3D3) mesa_d3d3vt;
-
 #endif /* HAVE_OPENGL */
 
 #endif /* __GRAPHICS_WINE_MESA_PRIVATE_H */
diff --git a/include/d3d.h b/include/d3d.h
index 8d6d956..5aac6ad 100644
--- a/include/d3d.h
+++ b/include/d3d.h
@@ -281,7 +281,7 @@
 #define IDirect3D3_CreateDevice(p,a,b,c,d)       ICOM_CALL4(CreateDevice,p,a,b,c,d)
 #define IDirect3D3_CreateVertexBuffer(p,a,b,c,d) ICOM_CALL4(CreateVertexBuffer,p,a,b,c,d)
 #define IDirect3D3_EnumZBufferFormats(p,a,b,c)   ICOM_CALL3(EnumZBufferFormats,p,a,b,c)
-#define IDirect3D3_EvictManagedTextures(p)       ICOM_CALL0(EvictManagedTextures,p)
+#define IDirect3D3_EvictManagedTextures(p)       ICOM_CALL (EvictManagedTextures,p)
 
 /*****************************************************************************
  * IDirect3D7 interface
@@ -306,9 +306,9 @@
 /*** IDirect3D3 methods ***/
 #define IDirect3D7_EnumDevices(p,a,b)            ICOM_CALL2(EnumDevices,p,a,b)
 #define IDirect3D7_CreateDevice(p,a,b,c)         ICOM_CALL3(CreateDevice,p,a,b,c)
-#define IDirect3D7_CreateVertexBuffer(p,a,b,c)   ICOM_CALL4(CreateVertexBuffer,p,a,b,c)
+#define IDirect3D7_CreateVertexBuffer(p,a,b,c)   ICOM_CALL3(CreateVertexBuffer,p,a,b,c)
 #define IDirect3D7_EnumZBufferFormats(p,a,b,c)   ICOM_CALL3(EnumZBufferFormats,p,a,b,c)
-#define IDirect3D7_EvictManagedTextures(p)       ICOM_CALL0(EvictManagedTextures,p)
+#define IDirect3D7_EvictManagedTextures(p)       ICOM_CALL (EvictManagedTextures,p)
 
 
 /*****************************************************************************
@@ -396,7 +396,7 @@
 #define IDirect3DMaterial3_METHODS \
     ICOM_METHOD1(HRESULT,SetMaterial, LPD3DMATERIAL,lpMat) \
     ICOM_METHOD1(HRESULT,GetMaterial, LPD3DMATERIAL,lpMat) \
-    ICOM_METHOD2(HRESULT,GetHandle,   LPDIRECT3DDEVICE3,lpDirect3DDevice2, LPD3DMATERIALHANDLE,lpHandle)
+    ICOM_METHOD2(HRESULT,GetHandle,   LPDIRECT3DDEVICE3,lpDirect3DDevice3, LPD3DMATERIALHANDLE,lpHandle)
 #define IDirect3DMaterial3_IMETHODS \
     IUnknown_IMETHODS \
     IDirect3DMaterial3_METHODS
@@ -418,8 +418,8 @@
  */
 #define ICOM_INTERFACE IDirect3DTexture
 #define IDirect3DTexture_METHODS \
-    ICOM_METHOD2(HRESULT,Initialize,     LPDIRECT3DDEVICE,lpDirect3DDevice, LPDIRECTDRAWSURFACE,) \
-    ICOM_METHOD2(HRESULT,GetHandle,      LPDIRECT3DDEVICE,lpDirect3DDevice, LPD3DTEXTUREHANDLE,) \
+    ICOM_METHOD2(HRESULT,Initialize,     LPDIRECT3DDEVICE,lpDirect3DDevice, LPDIRECTDRAWSURFACE,lpDDSurface) \
+    ICOM_METHOD2(HRESULT,GetHandle,      LPDIRECT3DDEVICE,lpDirect3DDevice, LPD3DTEXTUREHANDLE, lpHandle) \
     ICOM_METHOD2(HRESULT,PaletteChanged, DWORD,dwStart, DWORD,dwCount) \
     ICOM_METHOD1(HRESULT,Load,           LPDIRECT3DTEXTURE,lpD3DTexture) \
     ICOM_METHOD (HRESULT,Unload)
@@ -476,7 +476,7 @@
     ICOM_METHOD4(HRESULT,TransformVertices,  DWORD,dwVertexCount, LPD3DTRANSFORMDATA,lpData, DWORD,dwFlags, LPDWORD,lpOffScreen) \
     ICOM_METHOD2(HRESULT,LightElements,      DWORD,dwElementCount, LPD3DLIGHTDATA,lpData) \
     ICOM_METHOD1(HRESULT,SetBackground,      D3DMATERIALHANDLE,hMat) \
-    ICOM_METHOD2(HRESULT,GetBackground,      LPD3DMATERIALHANDLE,, LPBOOL,) \
+    ICOM_METHOD2(HRESULT,GetBackground,      LPD3DMATERIALHANDLE,lphMat, LPBOOL,lpValid) \
     ICOM_METHOD1(HRESULT,SetBackgroundDepth, LPDIRECTDRAWSURFACE,lpDDSurface) \
     ICOM_METHOD2(HRESULT,GetBackgroundDepth, LPDIRECTDRAWSURFACE*,lplpDDSurface, LPBOOL,lpValid) \
     ICOM_METHOD3(HRESULT,Clear,              DWORD,dwCount, LPD3DRECT,lpRects, DWORD,dwFlags) \
@@ -597,7 +597,7 @@
     ICOM_METHOD1(HRESULT,SetExecuteData, LPD3DEXECUTEDATA,lpData) \
     ICOM_METHOD1(HRESULT,GetExecuteData, LPD3DEXECUTEDATA,lpData) \
     ICOM_METHOD4(HRESULT,Validate,       LPDWORD,lpdwOffset, LPD3DVALIDATECALLBACK,lpFunc, LPVOID,lpUserArg, DWORD,dwReserved) \
-    ICOM_METHOD1(HRESULT,Optimize,       DWORD,)
+    ICOM_METHOD1(HRESULT,Optimize,       DWORD,dwDummy)
 #define IDirect3DExecuteBuffer_IMETHODS \
     IUnknown_IMETHODS \
     IDirect3DExecuteBuffer_METHODS
@@ -694,7 +694,7 @@
     ICOM_METHOD1(HRESULT,GetCurrentViewport,   LPDIRECT3DVIEWPORT2*,lplpDirect3DViewport2) \
     ICOM_METHOD2(HRESULT,SetRenderTarget,      LPDIRECTDRAWSURFACE,lpNewRenderTarget, DWORD,dwFlags) \
     ICOM_METHOD1(HRESULT,GetRenderTarget,      LPDIRECTDRAWSURFACE*,lplpRenderTarget) \
-    ICOM_METHOD3(HRESULT,Begin,                D3DPRIMITIVETYPE,, D3DVERTEXTYPE,, DWORD,) \
+    ICOM_METHOD3(HRESULT,Begin,                D3DPRIMITIVETYPE,d3dpt,D3DVERTEXTYPE,dwVertexTypeDesc,DWORD,dwFlags) \
     ICOM_METHOD5(HRESULT,BeginIndexed,         D3DPRIMITIVETYPE,d3dptPrimitiveType, D3DVERTEXTYPE,d3dvtVertexType, LPVOID,lpvVertices, DWORD,dwNumVertices, DWORD,dwFlags) \
     ICOM_METHOD1(HRESULT,Vertex,               LPVOID,lpVertexType) \
     ICOM_METHOD1(HRESULT,Index,                WORD,wVertexIndex) \
@@ -769,8 +769,8 @@
     /*** DrawPrimitive API ***/ \
     ICOM_METHOD1(HRESULT,SetCurrentViewport,   LPDIRECT3DVIEWPORT3,lpDirect3DViewport3) \
     ICOM_METHOD1(HRESULT,GetCurrentViewport,   LPDIRECT3DVIEWPORT3*,lplpDirect3DViewport3) \
-    ICOM_METHOD2(HRESULT,SetRenderTarget,      LPDIRECTDRAWSURFACE,lpNewRenderTarget, DWORD,dwFlags) \
-    ICOM_METHOD1(HRESULT,GetRenderTarget,      LPDIRECTDRAWSURFACE*,lplpRenderTarget) \
+    ICOM_METHOD2(HRESULT,SetRenderTarget,      LPDIRECTDRAWSURFACE4,lpNewRenderTarget, DWORD,dwFlags) \
+    ICOM_METHOD1(HRESULT,GetRenderTarget,      LPDIRECTDRAWSURFACE4*,lplpRenderTarget) \
     ICOM_METHOD3(HRESULT,Begin,                D3DPRIMITIVETYPE,d3dptPrimitiveType,DWORD,dwVertexTypeDesc, DWORD,dwFlags) \
     ICOM_METHOD5(HRESULT,BeginIndexed,         D3DPRIMITIVETYPE,d3dptPrimitiveType,DWORD,d3dvtVertexType, LPVOID,lpvVertices, DWORD,dwNumVertices, DWORD,dwFlags) \
     ICOM_METHOD1(HRESULT,Vertex,               LPVOID,lpVertexType) \
@@ -864,7 +864,7 @@
     ICOM_METHOD2(HRESULT,SetTransform,         D3DTRANSFORMSTATETYPE,dtstTransformStateType, LPD3DMATRIX,lpD3DMatrix) \
     ICOM_METHOD2(HRESULT,GetTransform,         D3DTRANSFORMSTATETYPE,dtstTransformStateType, LPD3DMATRIX,lpD3DMatrix) \
     ICOM_METHOD1(HRESULT,SetViewport,          LPD3DVIEWPORT7,lpData) \
-    ICOM_METHOD2(HRESULT,MultiplyTransform,    D3DTRANSFORMSTATETYPE,,LPD3DMATRIX,) \
+    ICOM_METHOD2(HRESULT,MultiplyTransform,    D3DTRANSFORMSTATETYPE,dtstTransformStateType,LPD3DMATRIX,lpD3DMatrix) \
     ICOM_METHOD1(HRESULT,GetViewport,          LPD3DVIEWPORT7,lpData) \
     ICOM_METHOD1(HRESULT,SetMaterial,          LPD3DMATERIAL7,lpMat) \
     ICOM_METHOD1(HRESULT,GetMaterial,          LPD3DMATERIAL7,lpMat) \
@@ -873,8 +873,8 @@
     ICOM_METHOD2(HRESULT,SetRenderState,       D3DRENDERSTATETYPE,dwRenderStateType, DWORD,dwRenderState) \
     ICOM_METHOD2(HRESULT,GetRenderState,       D3DRENDERSTATETYPE,dwRenderStateType, LPDWORD,lpdwRenderState) \
     ICOM_METHOD (HRESULT,BeginStateBlock) \
-    ICOM_METHOD1(HRESULT,EndStateBlock,        LPDWORD,) \
-    ICOM_METHOD1(HRESULT,PreLoad,              LPDIRECTDRAWSURFACE7,) \
+    ICOM_METHOD1(HRESULT,EndStateBlock,        LPDWORD,lpdwBlockHandle) \
+    ICOM_METHOD1(HRESULT,PreLoad,              LPDIRECTDRAWSURFACE7,lpddsTexture) \
     ICOM_METHOD5(HRESULT,DrawPrimitive,        D3DPRIMITIVETYPE,d3dptPrimitiveType, DWORD,d3dvtVertexType, LPVOID,lpvVertices, DWORD,dwVertexCount, DWORD,dwFlags) \
     ICOM_METHOD7(HRESULT,DrawIndexedPrimitive, D3DPRIMITIVETYPE,d3dptPrimitiveType, DWORD,d3dvtVertexType, LPVOID,lpvVertices, DWORD,dwVertexCount, LPWORD,dwIndices, DWORD,dwIndexCount, DWORD,dwFlags) \
     ICOM_METHOD1(HRESULT,SetClipStatus,        LPD3DCLIPSTATUS,lpD3DClipStatus) \
@@ -882,23 +882,23 @@
     ICOM_METHOD5(HRESULT,DrawPrimitiveStrided, D3DPRIMITIVETYPE,d3dptPrimitiveType,DWORD,dwVertexType,LPD3DDRAWPRIMITIVESTRIDEDDATA,lpD3DDrawPrimStrideData,DWORD,dwVertexCount,DWORD,dwFlags) \
     ICOM_METHOD7(HRESULT,DrawIndexedPrimitiveStrided, D3DPRIMITIVETYPE,d3dptPrimitiveType,DWORD,dwVertexType,LPD3DDRAWPRIMITIVESTRIDEDDATA,lpD3DDrawPrimStrideData,DWORD,dwVertexCount,LPWORD,lpIndex,DWORD,dwIndexCount,DWORD,dwFlags) \
     ICOM_METHOD5(HRESULT,DrawPrimitiveVB,      D3DPRIMITIVETYPE,d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER7,lpD3DVertexBuf,DWORD,dwStartVertex,DWORD,dwNumVertices,DWORD,dwFlags) \
-    ICOM_METHOD7(HRESULT,DrawIndexedPrimitiveVB, D3DPRIMITIVETYPE,d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER7,lpD3DVertexBuf,DWORD,,DWORD,,LPWORD,lpwIndices,DWORD,dwIndexCount,DWORD,dwFlags) \
+    ICOM_METHOD7(HRESULT,DrawIndexedPrimitiveVB, D3DPRIMITIVETYPE,d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER7,lpD3DVertexBuf,DWORD,dwStartVertex,DWORD,dwNumVertices,LPWORD,lpwIndices,DWORD,dwIndexCount,DWORD,dwFlags) \
     ICOM_METHOD5(HRESULT,ComputeSphereVisibility,     LPD3DVECTOR,lpCenters,LPD3DVALUE,lpRadii,DWORD,dwNumSpheres,DWORD,dwFlags,LPDWORD,lpdwReturnValues) \
     ICOM_METHOD2(HRESULT,GetTexture,           DWORD,dwStage,LPDIRECTDRAWSURFACE7*,lpTexture) \
     ICOM_METHOD2(HRESULT,SetTexture,           DWORD,dwStage,LPDIRECTDRAWSURFACE7,lpTexture) \
     ICOM_METHOD3(HRESULT,GetTextureStageState, DWORD,dwStage,D3DTEXTURESTAGESTATETYPE,d3dTexStageStateType,LPDWORD,lpdwState) \
     ICOM_METHOD3(HRESULT,SetTextureStageState, DWORD,dwStage,D3DTEXTURESTAGESTATETYPE,d3dTexStageStateType,DWORD,dwState) \
     ICOM_METHOD1(HRESULT,ValidateDevice,       LPDWORD,lpdwPasses) \
-    ICOM_METHOD1(HRESULT,ApplyStateBlock,      DWORD,) \
-    ICOM_METHOD1(HRESULT,CaptureStateBlock,    DWORD,) \
-    ICOM_METHOD1(HRESULT,DeleteStateBlock,     DWORD,) \
-    ICOM_METHOD2(HRESULT,CreateStateBlock,     D3DSTATEBLOCKTYPE,,LPDWORD,) \
-    ICOM_METHOD5(HRESULT,Load,                 LPDIRECTDRAWSURFACE7,,LPPOINT,,LPDIRECTDRAWSURFACE7,,LPRECT,,DWORD,) \
+    ICOM_METHOD1(HRESULT,ApplyStateBlock,      DWORD,dwBlockHandle) \
+    ICOM_METHOD1(HRESULT,CaptureStateBlock,    DWORD,dwBlockHandle) \
+    ICOM_METHOD1(HRESULT,DeleteStateBlock,     DWORD,dwBlockHandle) \
+    ICOM_METHOD2(HRESULT,CreateStateBlock,     D3DSTATEBLOCKTYPE,d3dsbType,LPDWORD,lpdwBlockHandle) \
+    ICOM_METHOD5(HRESULT,Load,                 LPDIRECTDRAWSURFACE7,lpDestTex,LPPOINT,lpDestPoint,LPDIRECTDRAWSURFACE7,lpSrcTex,LPRECT,lprcSrcRect,DWORD,dwFlags) \
     ICOM_METHOD2(HRESULT,LightEnable,          DWORD,dwLightIndex,BOOL,bEnable) \
-    ICOM_METHOD2(HRESULT,GetLightEnable,       DWORD,,BOOL*,) \
-    ICOM_METHOD2(HRESULT,SetClipPlane,         DWORD,,D3DVALUE*,) \
-    ICOM_METHOD2(HRESULT,GetClipPlane,         DWORD,,D3DVALUE*,) \
-    ICOM_METHOD3(HRESULT,GetInfo,              DWORD,,LPVOID,,DWORD, )
+    ICOM_METHOD2(HRESULT,GetLightEnable,       DWORD,dwLightIndex,BOOL*,pbEnable) \
+    ICOM_METHOD2(HRESULT,SetClipPlane,         DWORD,dwIndex,D3DVALUE*,pPlaneEquation) \
+    ICOM_METHOD2(HRESULT,GetClipPlane,         DWORD,dwIndex,D3DVALUE*,pPlaneEquation) \
+    ICOM_METHOD3(HRESULT,GetInfo,              DWORD,dwDevInfoID,LPVOID,pDevInfoStruct,DWORD,dwSize)
 #define IDirect3DDevice7_IMETHODS \
     IUnknown_IMETHODS \
     IDirect3DDevice7_METHODS
@@ -994,7 +994,7 @@
     ICOM_METHOD7(HRESULT,ProcessVertices,        DWORD,dwVertexOp,DWORD,dwDestIndex,DWORD,dwCount,LPDIRECT3DVERTEXBUFFER7,lpSrcBuffer,DWORD,dwSrcIndex,LPDIRECT3DDEVICE7,lpD3DDevice,DWORD,dwFlags) \
     ICOM_METHOD1(HRESULT,GetVertexBufferDesc,    LPD3DVERTEXBUFFERDESC,lpD3DVertexBufferDesc) \
     ICOM_METHOD2(HRESULT,Optimize,               LPDIRECT3DDEVICE7, lpD3DDevice,DWORD,dwFlags) \
-    ICOM_METHOD7(HRESULT,ProcessVerticesStrided, DWORD,,DWORD,,DWORD,,LPD3DDRAWPRIMITIVESTRIDEDDATA,,DWORD,,LPDIRECT3DDEVICE7,,DWORD,)
+    ICOM_METHOD7(HRESULT,ProcessVerticesStrided, DWORD,dwVertexOp,DWORD,dwDestIndex,DWORD,dwCount,LPD3DDRAWPRIMITIVESTRIDEDDATA,lpStrideData,DWORD,dwVertexTypeDesc,LPDIRECT3DDEVICE7,lpD3DDevice,DWORD,dwFlags)
 #define IDirect3DVertexBuffer7_IMETHODS \
     IUnknown_IMETHODS \
     IDirect3DVertexBuffer7_METHODS