For all DLLs with defined DllMain and which do not require
[wine] / dlls / ddraw / d3dviewport.c
index 2a03617..6262a6b 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "config.h"
 #include "windef.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
+#include "objbase.h"
 #include "ddraw.h"
 #include "d3d.h"
 #include "wine/debug.h"
 
 #include "d3d_private.h"
-#include "mesa_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
 static void activate(IDirect3DViewportImpl* This) {
     IDirect3DLightImpl* light;
-
+    D3DVIEWPORT7 vp;
+    
     /* Activate all the lights associated with this context */
     light = This->lights;
 
@@ -41,6 +43,26 @@ static void activate(IDirect3DViewportImpl* This) {
         light->activate(light);
        light = light->next;
     }
+
+    /* And copy the values in the structure used by the device */
+    if (This->use_vp2) {
+        vp.dwX = This->viewports.vp2.dwX;
+       vp.dwY = This->viewports.vp2.dwY;
+       vp.dwHeight = This->viewports.vp2.dwHeight;
+       vp.dwWidth = This->viewports.vp2.dwWidth;
+       vp.dvMinZ = This->viewports.vp2.dvMinZ;
+       vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
+    } else {
+        vp.dwX = This->viewports.vp1.dwX;
+       vp.dwY = This->viewports.vp1.dwY;
+       vp.dwHeight = This->viewports.vp1.dwHeight;
+       vp.dwWidth = This->viewports.vp1.dwWidth;
+       vp.dvMinZ = This->viewports.vp1.dvMinZ;
+       vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
+    }
+    
+    /* And also set the viewport */
+    IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
 }
 
 
@@ -99,7 +121,7 @@ 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);
+    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
     return ++(This->ref);
 }
 
@@ -107,7 +129,7 @@ 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);
+    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
     if (!--(This->ref)) {
         HeapFree(GetProcessHeap(), 0, This);
        return 0;
@@ -163,6 +185,13 @@ Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
     This->use_vp2 = 0;
     memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
     memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
+
+    /* Tests on two games shows that these values are never used properly so overide
+       them with proper ones :-)
+    */
+    This->viewports.vp1.dvMinZ = 0.0;
+    This->viewports.vp1.dvMaxZ = 1.0;
+    
     return DD_OK;
 }
 
@@ -193,7 +222,15 @@ 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);
+    TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
+    
+    This->background = (IDirect3DMaterialImpl *) hMat;
+    TRACE(" setting background color : %f %f %f %f\n",
+         This->background->mat.u.diffuse.u1.r,
+         This->background->mat.u.diffuse.u2.g,
+         This->background->mat.u.diffuse.u3.b,
+         This->background->mat.u.diffuse.u4.a);
+
     return DD_OK;
 }
 
@@ -233,8 +270,27 @@ Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
                                        DWORD dwFlags)
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags);
-    return DD_OK;
+    DWORD color = 0x00000000;
+    
+    TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
+    if (This->active_device == NULL) {
+        ERR(" Trying to clear a viewport not attached to a device !\n");
+       return D3DERR_VIEWPORTHASNODEVICE;
+    }
+    if (dwFlags & D3DCLEAR_TARGET) {
+        if (This->background == NULL) {
+           ERR(" Trying to clear the color buffer without background material !\n");
+       } else {
+           color = 
+             ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
+             ((int) ((This->background->mat.u.diffuse.u2.g) * 255) <<  8) |
+             ((int) ((This->background->mat.u.diffuse.u3.b) * 255) <<  0) |
+             ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
+       }
+    }
+    return This->active_device->clear(This->active_device, dwCount, lpRects, 
+                                     dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
+                                     color, 1.0, 0x00000000);
 }
 
 HRESULT WINAPI
@@ -243,13 +299,30 @@ Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
 {
     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
+    DWORD i = 0;
+    DWORD map = This->map_lights;
     
     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
     
+    if (This->num_lights >= 8)
+        return DDERR_INVALIDPARAMS;
+
+    /* Find a light number and update both light and viewports objects accordingly */
+    while(map&1) {
+        map>>=1;
+       i++;
+    }
+    lpDirect3DLightImpl->dwLightIndex = i;
+    This->num_lights++;
+    This->map_lights |= 1<<i;
+
     /* Add the light in the 'linked' chain */
     lpDirect3DLightImpl->next = This->lights;
     This->lights = lpDirect3DLightImpl;
 
+    /* Attach the light to the viewport */
+    lpDirect3DLightImpl->active_viewport = This;
+    
     /* If active, activate the light */
     if (This->active_device != NULL) {
         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
@@ -273,6 +346,10 @@ Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
            lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
            if (prev_light == NULL) This->lights = cur_light->next;
            else prev_light->next = cur_light->next;
+           /* Detach the light to the viewport */
+           cur_light->active_viewport = NULL;
+           This->num_lights--;
+           This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
            return DD_OK;
        }
        prev_light = cur_light;
@@ -362,106 +439,12 @@ Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
                                     DWORD dwStencil)
 {
     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
-GL_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
-                                       DWORD dwCount,
-                                       LPD3DRECT lpRects,
-                                       DWORD dwFlags)
-{
-    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
-    GLboolean ztest;
-    
-    TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
-
-    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
-GL_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
-                                    DWORD dwCount,
-                                    LPD3DRECT lpRects,
-                                    DWORD dwFlags,
-                                    DWORD dwColor,
-                                    D3DVALUE dvZ,
-                                    DWORD dwStencil)
-{
-    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);
-
-    if (dwCount != 1) {
-        WARN("  Warning, this function only for now clears the whole screen...\n");
-    }
-
-    /* Clears the screen */
-    ENTER_GL();
-    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;
-    }
-    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\n", dwColor);
+    if (This->active_device == NULL) {
+        ERR(" Trying to clear a viewport not attached to a device !\n");
+       return D3DERR_VIEWPORTHASNODEVICE;
     }
-    
-    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;
+    return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
 }
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
@@ -485,7 +468,7 @@ ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
     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(Clear) Main_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,
@@ -493,7 +476,7 @@ ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
     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,
+    XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2,
 };
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
@@ -503,7 +486,7 @@ ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
 
 
 
-HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirect3DImpl *d3d)
+HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
 {
     IDirect3DViewportImpl *object;
 
@@ -516,6 +499,8 @@ HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirect3DImpl *d3d)
     object->use_vp2 = 0xFF;
     object->next = NULL;
     object->lights = NULL;
+    object->num_lights = 0;
+    object->map_lights = 0;
     
     ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);