The Holy Grail - Wine 0.9 - thanks to all

Christian Costa titan.costa at wanadoo.fr
Sun Oct 30 08:26:02 CST 2005


H. Verbeet wrote:

>On 10/30/05, Christian Costa <titan.costa at wanadoo.fr> wrote:
>  
>
>>IIRC, a patch fixing this problem was commited about 2 or 3 months ago.
>>    
>>
>This one? http://cvs.winehq.org/patch.py?id=18002
>
>It doesn't touch CreateLight. The crash happens because of this check
>in GL_IDirect3DImpl_3_2T_1T_CreateLight:
>
>    if (fl == MAX_LIGHTS) {
>        return DDERR_INVALIDPARAMS; /* No way to say 'max lights reached' ... */
>    }
>
>The application is sloppy for not checking the result of course, but
>on Windows the call never fails, at least not for creating more lights
>than the hardware supports.
>
Could you try this patch ?

-------------- next part --------------
? dlls/ddraw/.d3d_private.h.swp
? dlls/ddraw/.device_opengl.c.swp
? dlls/ddraw/.direct3d_opengl.c.swo
? dlls/ddraw/.direct3d_opengl.c.swp
? dlls/ddraw/.light.c.swp
? dlls/ddraw/.opengl_private.h.swp
? dlls/ddraw/device_opengl.c.fog
? dlls/ddraw/device_opengl.c.work
? dlls/ddraw/lights.diff
? dlls/ddraw/t.txt
Index: dlls/ddraw/direct3d_opengl.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/direct3d_opengl.c,v
retrieving revision 1.2
diff -u -r1.2 direct3d_opengl.c
--- dlls/ddraw/direct3d_opengl.c	26 Jul 2005 20:10:51 -0000	1.2
+++ dlls/ddraw/direct3d_opengl.c	30 Oct 2005 12:10:01 -0000
@@ -98,23 +98,31 @@
 {
     ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
     IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This->d3d_private;
-    int fl;
+    DWORD light_index;
     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);
+    for (light_index = 0; light_index < glThis->max_lights; light_index++) {
+        if (!glThis->used_lights[light_index])
 	    break;
-	}
     }
-    if (fl == MAX_LIGHTS) {
-        return DDERR_INVALIDPARAMS; /* No way to say 'max lights reached' ... */
+    if (light_index == glThis->max_lights) {
+	int new_max_lights = glThis->max_lights ? 2 * glThis->max_lights : 1;
+	BOOL *new_used_lights = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_max_lights * sizeof(BOOL));
+	if (!new_used_lights)
+	    return E_OUTOFMEMORY;
+	CopyMemory(new_used_lights, glThis->used_lights, glThis->max_lights);
+	HeapFree(GetProcessHeap(), 0, glThis->used_lights);
+	glThis->max_lights = new_max_lights;
+	glThis->used_lights = new_used_lights;
     }
-    ret_value = d3dlight_create(&d3dlimpl, This, GL_LIGHT0 + fl);
+    ret_value = d3dlight_create(&d3dlimpl, This, light_index);
     *lplpDirect3DLight = ICOM_INTERFACE(d3dlimpl, IDirect3DLight);
 
+    if (ret_value == D3D_OK)
+	glThis->used_lights[light_index] = TRUE;
+
     return ret_value;
 }
 
@@ -306,10 +314,10 @@
     return res;
 }
 
-static void light_released(IDirectDrawImpl *This, GLenum light_num)
+static void light_released(IDirectDrawImpl *This, DWORD light_index)
 {
     IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This->d3d_private;
-    glThis->free_lights |= (light_num - GL_LIGHT0);
+    glThis->used_lights[light_index] = FALSE;
 }
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
@@ -453,7 +461,6 @@
     ICOM_INIT_INTERFACE(This, IDirect3D3, VTABLE_IDirect3D3);
     ICOM_INIT_INTERFACE(This, IDirect3D7, VTABLE_IDirect3D7);
 
-    globject->free_lights = (0x01 << MAX_LIGHTS) - 1; /* There are, in total, 8 lights in OpenGL */
     globject->light_released = light_released;
 
     This->d3d_private = globject;
Index: dlls/ddraw/light.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/light.c,v
retrieving revision 1.2
diff -u -r1.2 light.c
--- dlls/ddraw/light.c	26 Jul 2005 20:10:51 -0000	1.2
+++ dlls/ddraw/light.c	30 Oct 2005 12:10:01 -0000
@@ -158,39 +158,43 @@
 
 static void update(IDirect3DLightImpl* This) {
     IDirect3DDeviceImpl* device;
-    if (!This->active_viewport||!This->active_viewport->active_device)
+    if (!This->active_viewport || !This->active_viewport->active_device)
         return;
     device =  This->active_viewport->active_device;
-    IDirect3DDevice7_SetLight(ICOM_INTERFACE(device,IDirect3DDevice7),This->dwLightIndex,&(This->light7));
+    IDirect3DDevice7_SetLight(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, &(This->light7));
 }
 
 static void activate(IDirect3DLightImpl* This) {
     IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This;
+    IDirect3DDeviceImpl* device;
+    if (!This->active_viewport || !This->active_viewport->active_device)
+        return;
+    device =  This->active_viewport->active_device;
 
     TRACE("(%p)\n", This);
     
-    ENTER_GL();
     update(This);
     /* If was not active, activate it */
     if ((glThis->parent.light.dwFlags & D3DLIGHT_ACTIVE) == 0) {
-        glEnable(glThis->light_num);
+        IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), glThis->light_index, TRUE);
 	glThis->parent.light.dwFlags |= D3DLIGHT_ACTIVE;
     }
-    LEAVE_GL();
 }
 
 static void desactivate(IDirect3DLightImpl* This) {
     IDirect3DLightGLImpl *glThis = (IDirect3DLightGLImpl *) This;
-    
+    IDirect3DDeviceImpl* device;
+    if (!This->active_viewport || !This->active_viewport->active_device)
+        return;
+    device =  This->active_viewport->active_device;
+
     TRACE("(%p)\n", This);
     
-    ENTER_GL();
     /* If was not active, activate it */
     if ((glThis->parent.light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
-        glDisable(glThis->light_num);
+        IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), glThis->light_index, FALSE);
 	glThis->parent.light.dwFlags &= ~D3DLIGHT_ACTIVE;
     }
-    LEAVE_GL();
 }
 
 ULONG WINAPI
@@ -203,7 +207,7 @@
     TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
 
     if (!ref) {
-        ((IDirect3DGLImpl *) This->d3d->d3d_private)->light_released(This->d3d, glThis->light_num);
+        ((IDirect3DGLImpl *) This->d3d->d3d_private)->light_released(This->d3d, glThis->light_index);
         HeapFree(GetProcessHeap(), 0, This);
 	return 0;
     }
@@ -233,7 +237,7 @@
 
 
 
-HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d, GLenum light_num)
+HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d, DWORD light_index)
 {
     IDirect3DLightImpl *object;
     IDirect3DLightGLImpl *gl_object;
@@ -249,7 +253,7 @@
     object->desactivate = desactivate;
     object->update = update;
     object->active_viewport = NULL;
-    gl_object->light_num = light_num;
+    gl_object->light_index = light_index;
     
     ICOM_INIT_INTERFACE(object, IDirect3DLight, VTABLE_IDirect3DLight);
 
Index: dlls/ddraw/opengl_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/opengl_private.h,v
retrieving revision 1.2
diff -u -r1.2 opengl_private.h
--- dlls/ddraw/opengl_private.h	12 Jun 2005 10:43:11 -0000	1.2
+++ dlls/ddraw/opengl_private.h	30 Oct 2005 12:10:02 -0000
@@ -48,14 +48,15 @@
 /* This structure is used for the 'd3d_private' field of the IDirectDraw structure */
 typedef struct IDirect3DGLImpl
 {
-    DWORD free_lights;
-    void (*light_released)(IDirectDrawImpl *, GLenum light_num);
+    BOOL *used_lights;
+    int max_lights;
+    void (*light_released)(IDirectDrawImpl *, DWORD light_index);
 } IDirect3DGLImpl;
 
 typedef struct IDirect3DLightGLImpl
 {
     struct IDirect3DLightImpl parent;
-    GLenum light_num;
+    DWORD light_index;
 } IDirect3DLightGLImpl;
 
 /* This structure is used for the 'private' field of the IDirectDrawSurfaceImpl structure */
@@ -185,7 +186,7 @@
 /* All non-static functions 'exported' by various sub-objects */
 extern HRESULT direct3d_create(IDirectDrawImpl *This);
 extern HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf);
-extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d, GLenum light_num);
+extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d, DWORD light_index);
 extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirectDrawImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
 extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d);
 extern HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d);


More information about the wine-devel mailing list