[D3D 72] Various stuff to get Monkey4 working in D3D mode

Lionel Ulmer lionel.ulmer at free.fr
Thu Jan 2 05:57:02 CST 2003


Changelog
 - hack for one case of the ProcessVertices case
 - some changes in the execute buffer to reuse the new Matrix code
 - always reinitialize the enumeration structures in case some games
   modify them
 - added support for the (unused) Reserved1 field in the FVF formats
 - fix 32 bit texturing and added more checks
 - remove some useless and annoying fixme


PS: I updated the d3d_status.html page (http://www.bbrox.org/d3d_status.html)

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3ddevice/main.c	2003-01-01 15:26:58.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3ddevice/main.c	2003-01-02 09:29:18.000000000 +0100
@@ -724,7 +724,7 @@
                                    DWORD dwSize)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize);
+    TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize);
 
     if (TRACE_ON(ddraw)) {
         TRACE(" info requested : ");
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3ddevice/mesa.c	2003-01-01 15:26:58.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3ddevice/mesa.c	2003-01-02 10:31:51.000000000 +0100
@@ -52,22 +52,22 @@
 					 const GLvoid *table);
 #endif
 
-static const float id_mat[16] = {
+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
 };
 
-static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
-				     D3DPRIMITIVETYPE d3dptPrimitiveType,
-				     DWORD d3dvtVertexType,
-				     LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-				     DWORD dwStartVertex,
-				     DWORD dwVertexCount,
-				     LPWORD dwIndices,
-				     DWORD dwIndexCount,
-				     DWORD dwFlags) ;
+static void draw_primitive_strided(IDirect3DDeviceImpl *This,
+				   D3DPRIMITIVETYPE d3dptPrimitiveType,
+				   DWORD d3dvtVertexType,
+				   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+				   DWORD dwStartVertex,
+				   DWORD dwVertexCount,
+				   LPWORD dwIndices,
+				   DWORD dwIndexCount,
+				   DWORD dwFlags) ;
 
 /* retrieve the X display to use on a given DC */
 inline static Display *get_display( HDC hdc )
@@ -271,22 +271,25 @@
 
 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
 {
-    D3DDEVICEDESC d1, d2;
+    D3DDEVICEDESC dref, d1, d2;
     HRESULT ret_value;
     
-    fill_opengl_caps(&d1);
-    d2 = d1;
+    fill_opengl_caps(&dref);
 
     TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
+    d1 = dref;
+    d2 = dref;
     ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
     if (ret_value != D3DENUMRET_OK)
         return ret_value;
 
     TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
+    d1 = dref;
+    d2 = dref;
     ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
     if (ret_value != D3DENUMRET_OK)
         return ret_value;
-    
+
     return D3DENUMRET_OK;
 }
 
@@ -410,23 +413,23 @@
     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");
+    TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (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;
+    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 GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n");
+    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 =        0x00007C00;
-    pformat->u3.dwGBitMask =        0x000003E0;
-    pformat->u4.dwBBitMask =        0x0000001F;
-    pformat->u5.dwRGBAlphaBitMask = 0x00008000;
+    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;
 
@@ -450,16 +453,6 @@
     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_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;
@@ -705,7 +698,7 @@
 	    strided.normal.dwStride = sizeof(D3DVERTEX);
 	    strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
 	    strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
-	    draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
+	    draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
 	} break;
 
         case D3DVT_LVERTEX: {
@@ -717,7 +710,7 @@
 	    strided.specular.dwStride = sizeof(D3DLVERTEX);
 	    strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
 	    strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
-	    draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
+	    draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
 	} break;
 
         case D3DVT_TLVERTEX: {
@@ -729,7 +722,7 @@
 	    strided.specular.dwStride = sizeof(D3DTLVERTEX);
 	    strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
 	    strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
-	    draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
+	    draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
 	} break;
 
         default:
@@ -912,15 +905,15 @@
     if (tex_index == 0) glTexCoord2fv(coords);
 }
 
-static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
-				     D3DPRIMITIVETYPE d3dptPrimitiveType,
-				     DWORD d3dvtVertexType,
-				     LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
-				     DWORD dwStartVertex,
-				     DWORD dwVertexCount,
-				     LPWORD dwIndices,
-				     DWORD dwIndexCount,
-				     DWORD dwFlags)
+static void draw_primitive_strided(IDirect3DDeviceImpl *This,
+				   D3DPRIMITIVETYPE d3dptPrimitiveType,
+				   DWORD d3dvtVertexType,
+				   LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
+				   DWORD dwStartVertex,
+				   DWORD dwVertexCount,
+				   LPWORD dwIndices,
+				   DWORD dwIndexCount,
+				   DWORD dwFlags)
 {
     IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
     if (TRACE_ON(ddraw)) {
@@ -1098,53 +1091,6 @@
     TRACE("End\n");    
 }
 
-static void draw_primitive_7(IDirect3DDeviceImpl *This,
-			     D3DPRIMITIVETYPE d3dptPrimitiveType,
-			     DWORD d3dvtVertexType,
-			     LPVOID lpvVertices,
-			     DWORD dwStartVertex,
-			     DWORD dwVertexCount,
-			     LPWORD dwIndices,
-			     DWORD dwIndexCount,
-			     DWORD dwFlags)
-{
-    D3DDRAWPRIMITIVESTRIDEDDATA strided;
-    int current_offset = 0;
-    int tex_index;
-    
-    if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
-        strided.position.lpvData = lpvVertices;
-        current_offset += 3 * sizeof(D3DVALUE);
-    } else {
-        strided.position.lpvData  = lpvVertices;
-        current_offset += 4 * sizeof(D3DVALUE);
-    }
-    if (d3dvtVertexType & D3DFVF_NORMAL) { 
-        strided.normal.lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += 3 * sizeof(D3DVALUE);
-    }
-    if (d3dvtVertexType & D3DFVF_DIFFUSE) { 
-        strided.diffuse.lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += sizeof(DWORD);
-    }
-    if (d3dvtVertexType & D3DFVF_SPECULAR) {
-        strided.specular.lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += sizeof(DWORD);
-    }
-    for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
-        strided.textureCoords[tex_index].lpvData  = ((char *) lpvVertices) + current_offset;
-        current_offset += 2 * sizeof(D3DVALUE);
-    }
-    strided.position.dwStride = current_offset;
-    strided.normal.dwStride   = current_offset;
-    strided.diffuse.dwStride  = current_offset;
-    strided.specular.dwStride = current_offset;
-    for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
-        strided.textureCoords[tex_index].dwStride  = current_offset;
-    
-    draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwStartVertex, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
-}
-
 HRESULT WINAPI
 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
 					  D3DPRIMITIVETYPE d3dptPrimitiveType,
@@ -1154,13 +1100,15 @@
 					  DWORD dwFlags)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    D3DDRAWPRIMITIVESTRIDEDDATA strided;
 
     TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
     if (TRACE_ON(ddraw)) {
         TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
     }
 
-    draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
+    convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
+    draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
     
     return DD_OK;
 }
@@ -1176,13 +1124,15 @@
 						 DWORD dwFlags)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+    D3DDRAWPRIMITIVESTRIDEDDATA strided;
 
     TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
     if (TRACE_ON(ddraw)) {
         TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
     }
 
-    draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
+    convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
+    draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
     
     return DD_OK;
 }
@@ -1201,7 +1151,7 @@
     if (TRACE_ON(ddraw)) {
         TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
     }
-    draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
+    draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
 
     return DD_OK;
 }
@@ -1223,7 +1173,7 @@
         TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
     }
 
-    draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
+    draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
 
     return DD_OK;
 }
@@ -1238,13 +1188,28 @@
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
     IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
+    D3DDRAWPRIMITIVESTRIDEDDATA strided;
 
     TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
     if (TRACE_ON(ddraw)) {
         TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
     }
 
-    draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
+    if (vb_impl->processed == TRUE) {
+        IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
+	IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
+
+	glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
+	This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
+			   &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
+
+	convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
+	draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
+
+    } else {
+        convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
+	draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
+    }
 
     return DD_OK;
 }
@@ -1261,13 +1226,28 @@
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
     IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
+    D3DDRAWPRIMITIVESTRIDEDDATA strided;
     
     TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
     if (TRACE_ON(ddraw)) {
         TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
     }
 
-    draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
+    if (vb_impl->processed == TRUE) {
+        IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
+	IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
+
+	glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
+	This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
+			   &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
+
+	convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
+	draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
+
+    } else {
+        convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
+	draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
+    }
 
     return DD_OK;
 }
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3d_private.h	2003-01-01 15:26:58.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3d_private.h	2003-01-02 08:55:26.000000000 +0100
@@ -226,6 +226,8 @@
     D3DVERTEXBUFFERDESC desc;
     LPVOID *vertices;
     DWORD vertex_buffer_size;
+
+    BOOLEAN processed;
 };
 
 /* Various dump and helper functions */
@@ -237,6 +239,11 @@
 extern void dump_D3DMATRIX(D3DMATRIX *mat);
 extern void dump_D3DVECTOR(D3DVECTOR *lpVec);
 extern void dump_flexible_vertex(DWORD d3dvtVertexType);
-extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements);
+extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
+extern void convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided);
+extern void dump_D3DVOP(DWORD dwVertexOp);
+extern void dump_D3DPV(DWORD dwFlags);
+
+extern const float id_mat[16];
 
 #endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dcommon.c	2003-01-01 15:26:58.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dcommon.c	2003-01-02 08:57:56.000000000 +0100
@@ -230,23 +230,20 @@
 }
 
 
-DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
+DWORD get_flexible_vertex_size(DWORD d3dvtVertexType)
 {
     DWORD size = 0;
-    DWORD elts = 0;
     
-    if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
-    if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
-    if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
+    if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE);
+    if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD);
+    if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD);
+    if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD);
     switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
-        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
-        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
+        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
+        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
 	default: TRACE(" matrix weighting not handled yet...\n");
     }
     size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
-    elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
-
-    if (elements) *elements = elts;
 
     return size;
 }
@@ -290,3 +287,64 @@
     }
     DPRINTF("\n");
 }
+
+void
+convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided)
+{
+    int current_offset = 0;
+    int tex_index;
+    
+    if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
+        strided->position.lpvData = lpvVertices;
+        current_offset += 3 * sizeof(D3DVALUE);
+    } else {
+        strided->position.lpvData  = lpvVertices;
+        current_offset += 4 * sizeof(D3DVALUE);
+    }
+    if (d3dvtVertexType & D3DFVF_RESERVED1) {
+        current_offset += sizeof(DWORD);
+    }
+    if (d3dvtVertexType & D3DFVF_NORMAL) { 
+        strided->normal.lpvData  = ((char *) lpvVertices) + current_offset;
+        current_offset += 3 * sizeof(D3DVALUE);
+    }
+    if (d3dvtVertexType & D3DFVF_DIFFUSE) { 
+        strided->diffuse.lpvData  = ((char *) lpvVertices) + current_offset;
+        current_offset += sizeof(DWORD);
+    }
+    if (d3dvtVertexType & D3DFVF_SPECULAR) {
+        strided->specular.lpvData  = ((char *) lpvVertices) + current_offset;
+        current_offset += sizeof(DWORD);
+    }
+    for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
+        strided->textureCoords[tex_index].lpvData  = ((char *) lpvVertices) + current_offset;
+        current_offset += 2 * sizeof(D3DVALUE);
+    }
+    strided->position.dwStride = current_offset;
+    strided->normal.dwStride   = current_offset;
+    strided->diffuse.dwStride  = current_offset;
+    strided->specular.dwStride = current_offset;
+    for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
+        strided->textureCoords[tex_index].dwStride  = current_offset;   
+}
+
+void
+dump_D3DVOP(DWORD dwVertexOp)
+{
+    static const flag_info flags[] =
+    {
+        FE(D3DVOP_LIGHT),
+	FE(D3DVOP_CLIP),
+	FE(D3DVOP_EXTENTS),
+	FE(D3DVOP_TRANSFORM)
+    };
+    DDRAW_dump_flags(dwVertexOp, flags, sizeof(flags)/sizeof(flags[0]));
+}
+
+void
+dump_D3DPV(DWORD dwFlags)
+{
+    if (dwFlags == D3DPV_DONOTCOPYDATA) DPRINTF("D3DPV_DONOTCOPYDATA\n");
+    else if (dwFlags != 0) DPRINTF("Unknown !!!\n");
+    else DPRINTF("\n");
+}
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dexecutebuffer.c	2003-01-01 15:26:58.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dexecutebuffer.c	2003-01-01 16:35:49.000000000 +0100
@@ -238,43 +238,34 @@
 		        /* 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", lpDevice->proj_mat);
-			dump_D3DMATRIX(lpDevice->proj_mat);
-			TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
-			dump_D3DMATRIX(lpDevice->view_mat);
-
-			/* 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 *) lpDevice->proj_mat);
-			glMultMatrixf((float *) lpDevice->view_mat);
+			if (TRACE_ON(ddraw)) {
+			    TRACE("  Projection Matrix : (%p)\n", lpDevice->proj_mat);
+			    dump_D3DMATRIX(lpDevice->proj_mat);
+			    TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
+			    dump_D3DMATRIX(lpDevice->view_mat);
+			}
+
+			/* Using the identity matrix as the world matrix as the world transformation was
+			   already done. */
+			lpDevice->set_matrices(lpDevice, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
+					       (D3DMATRIX *) id_mat, lpDevice->view_mat, lpDevice->proj_mat);
 			break;
 
 		    case D3DVT_LVERTEX:
 			/* No lighting */
 			glDisable(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", lpDevice->proj_mat);
-			dump_D3DMATRIX(lpDevice->proj_mat);
-			TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
-			dump_D3DMATRIX(lpDevice->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 *) lpDevice->proj_mat);
-			glMultMatrixf((float *) lpDevice->view_mat);
+			if (TRACE_ON(ddraw)) {
+			    TRACE("  Projection Matrix : (%p)\n", lpDevice->proj_mat);
+			    dump_D3DMATRIX(lpDevice->proj_mat);
+			    TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
+			    dump_D3DMATRIX(lpDevice->view_mat);
+			}
+
+			/* Using the identity matrix as the world matrix as the world transformation was
+			   already done. */
+			lpDevice->set_matrices(lpDevice, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
+					       (D3DMATRIX *) id_mat, lpDevice->view_mat, lpDevice->proj_mat);
 			break;
 
 		    case D3DVT_TLVERTEX: {
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dtexture.c	2002-12-27 17:40:23.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dtexture.c	2003-01-02 10:41:29.000000000 +0100
@@ -237,22 +237,40 @@
 	       RGB Textures
 	       ************ */
         if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+	    if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) &&
+		(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) &&
+		(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) {
 	        /* **********************
 		   GL_UNSIGNED_BYTE_3_3_2
 		   ********************** */
-	    format = GL_RGB;
-	    pixel_format = GL_UNSIGNED_BYTE_3_3_2;
+	        format = GL_RGB;
+		pixel_format = GL_UNSIGNED_BYTE_3_3_2;
+	    } else {
+	        error = TRUE;
+	    }
 	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
-  	    if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
+	    if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF800) &&
+		(src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x07E0) &&
+		(src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
+		(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
 	        format = GL_RGB;
 		pixel_format = GL_UNSIGNED_SHORT_5_6_5;
-	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
+	    } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF800) &&
+		       (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x07C0) &&
+		       (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x003E) &&
+		       (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) {
 	        format = GL_RGBA;
 		pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
+	    } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF000) &&
+		       (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0F00) &&
+		       (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x00F0) &&
+		       (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) {
 	        format = GL_RGBA;
 		pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;	      
-	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000F000) {
+	    } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x0F00) &&
+		       (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x00F0) &&
+		       (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000F) &&
+		       (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) {
 	        /* Move the four Alpha bits... */
 		DWORD i;
 		WORD *src = (WORD *) src_d->lpSurface, *dst;
@@ -268,7 +286,10 @@
 
 	        format = GL_RGBA;
 		pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; 		
-	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
+	    } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x7C00) &&
+		       (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x03E0) &&
+		       (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
+		       (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) {
 	        /* Converting the 1555 format in 5551 packed */
 		DWORD i;
 		WORD *src = (WORD *) src_d->lpSurface, *dst;
@@ -284,21 +305,47 @@
 	        format = GL_RGBA;
 		pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
 	    } else {
-	        ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
 		error = TRUE;
 	    }
 	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
-	    format = GL_RGB;
-	    pixel_format = GL_UNSIGNED_BYTE;
+	    if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
+		(src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
+		(src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
+		(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
+	        format = GL_BGR;
+		pixel_format = GL_UNSIGNED_BYTE;
+	    } else {
+	        error = TRUE;
+	    }
 	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
-	    format = GL_RGBA;
-	    pixel_format = GL_UNSIGNED_BYTE;
+	    if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xFF000000) &&
+		(src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x00FF0000) &&
+		(src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x0000FF00) &&
+		(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) {
+	        format = GL_RGBA;
+		pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+	    } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
+		       (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
+		       (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
+		       (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
+	        /* Just add an alpha component... */
+		DWORD i;
+		DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+		
+		surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+		dst = (DWORD *) surface;
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    *dst++ = (*src++ << 8) | 0xFF;
+		}
+	        format = GL_RGBA;
+		pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+	    } else {
+		error = TRUE;
+	    }
 	} else {
-	    ERR("Unhandled texture format (bad RGB count)\n");
 	    error = TRUE;
 	}
     } else {
-        ERR("Unhandled texture format (neither RGB nor INDEX)\n");
 	error = TRUE;
     } 
 
@@ -321,6 +368,11 @@
 			    pixel_format,
 			    surface == NULL ? src_d->lpSurface : surface);
 	if (surface) HeapFree(GetProcessHeap(), 0, surface);
+    } else if (error == TRUE) {
+	if (ERR_ON(ddraw)) {
+	    ERR("Unsupported pixel format for textures : \n");
+	    DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat);
+	}
     }
 
     glBindTexture(GL_TEXTURE_2D, current_texture);
--- /home/ulmer/Wine/wine_base//dlls/ddraw/mesa_private.h	2003-01-01 15:26:58.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/mesa_private.h	2003-01-01 20:02:25.000000000 +0100
@@ -137,6 +137,15 @@
     Drawable drawable;
 } IDirect3DDeviceGLImpl;
 
+/* This is for the OpenGL additions... */
+typedef struct {
+    struct IDirect3DVertexBufferImpl parent;
+
+    DWORD dwVertexTypeDesc;
+    D3DMATRIX world_mat, view_mat, proj_mat;
+    LPVOID vertices;
+} IDirect3DVertexBufferGLImpl;
+
 /* All non-static functions 'exported' by various sub-objects */
 extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw);
 extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf);
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dvertexbuffer.c	2002-12-31 18:56:34.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dvertexbuffer.c	2003-01-02 09:52:17.000000000 +0100
@@ -99,6 +99,10 @@
 	DDRAW_dump_lockflag(dwFlags);
     }
     
+    if (This->processed == TRUE) {
+        WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
+    }
+
     if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
 
     if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
@@ -263,6 +267,197 @@
                                                       lpD3DVertexBufferDesc);
 }
 
+#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
+
+static HRESULT
+process_vertices_strided(IDirect3DVertexBufferImpl *This,
+			 DWORD dwVertexOp,
+			 DWORD dwDestIndex,
+			 DWORD dwCount,
+			 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
+			 DWORD dwVertexTypeDesc,
+			 IDirect3DDeviceImpl *device_impl,
+			 DWORD dwFlags)
+{
+    IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
+    DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
+    char *dest_ptr;
+    int i;
+
+    This->processed = TRUE;
+
+    /* For the moment, the trick is to save the transform and lighting state at process
+       time to restore them at drawing time.
+       
+       The BIG problem with this method is nothing prevents D3D to do dirty tricks like
+       processing two different sets of vertices with two different rendering parameters
+       and then to display them using the same DrawPrimitive call.
+
+       It would be nice to check for such code here (but well, even this is not trivial
+       to do).
+
+       This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
+       in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
+       implementing this mostly useless (IMHO) API.
+    */
+    glThis->dwVertexTypeDesc = dwVertexTypeDesc;
+
+    if (dwVertexTypeDesc & D3DFVF_NORMAL) {
+        WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
+    }
+
+    if (glThis->vertices == NULL) {
+        glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
+    }
+    dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
+    
+    memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
+    memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
+    memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
+
+    for (i = 0; i < dwCount; i++) {
+        int tex_index;
+
+	if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
+	    D3DVALUE *position =
+	      (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
+	    copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
+	} else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
+	    D3DVALUE *position =
+	      (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
+	    copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
+	}
+	if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
+	    dest_ptr += sizeof(DWORD);
+	}
+	if (dwVertexTypeDesc & D3DFVF_NORMAL) { 
+	    D3DVALUE *normal = 
+	      (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);	    
+	    copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
+	}
+	if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
+	    DWORD *color_d = 
+	      (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
+	    copy_and_next(dest_ptr, color_d, sizeof(DWORD));
+	}
+	if (dwVertexTypeDesc & D3DFVF_SPECULAR) { 
+	    DWORD *color_s = 
+	      (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
+	    copy_and_next(dest_ptr, color_s, sizeof(DWORD));
+	}
+	for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
+	    D3DVALUE *tex_coord =
+	      (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + 
+			    i * lpStrideData->textureCoords[tex_index].dwStride);
+	    copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
+	}
+
+	if (TRACE_ON(ddraw)) {
+	    if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
+	        D3DVALUE *position =
+		  (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
+		TRACE(" %f %f %f", position[0], position[1], position[2]);
+	    } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
+	        D3DVALUE *position =
+		  (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
+		TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
+	    }
+	    if (dwVertexTypeDesc & D3DFVF_NORMAL) { 
+	        D3DVALUE *normal = 
+		  (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);	    
+		DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
+	    }
+	    if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
+	        DWORD *color_d = 
+		  (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
+		DPRINTF(" / %02lx %02lx %02lx %02lx",
+			(*color_d >> 16) & 0xFF,
+			(*color_d >>  8) & 0xFF,
+			(*color_d >>  0) & 0xFF,
+			(*color_d >> 24) & 0xFF);
+	    }
+	    if (dwVertexTypeDesc & D3DFVF_SPECULAR) { 
+	        DWORD *color_s = 
+		  (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
+		DPRINTF(" / %02lx %02lx %02lx %02lx",
+			(*color_s >> 16) & 0xFF,
+			(*color_s >>  8) & 0xFF,
+			(*color_s >>  0) & 0xFF,
+			(*color_s >> 24) & 0xFF);
+	    }
+	    for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
+	        D3DVALUE *tex_coord =
+		  (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + 
+				i * lpStrideData->textureCoords[tex_index].dwStride);
+		DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
+	    }
+	    DPRINTF("\n");
+	}
+    }
+
+    return DD_OK;
+}
+
+#undef copy_and_next
+
+HRESULT WINAPI
+GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
+						  DWORD dwVertexOp,
+						  DWORD dwDestIndex,
+						  DWORD dwCount,
+						  LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
+						  DWORD dwSrcIndex,
+						  LPDIRECT3DDEVICE7 lpD3DDevice,
+						  DWORD dwFlags)
+{
+    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
+    IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
+    IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
+    D3DDRAWPRIMITIVESTRIDEDDATA strided;
+    DWORD size;
+
+    TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);    
+
+    if (TRACE_ON(ddraw)) {
+        DPRINTF(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
+	DPRINTF(" - flags             : "); dump_D3DPV(dwFlags);
+    }
+
+    if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
+
+    size = get_flexible_vertex_size(src_impl->desc.dwFVF);
+    convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided);
+
+    return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
+}
+
+HRESULT WINAPI
+GL_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);
+    IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
+
+    TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
+    if (TRACE_ON(ddraw)) {
+        DPRINTF(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
+	DPRINTF(" - flags             : "); dump_D3DPV(dwFlags);
+	DPRINTF(" - vertex format     : "); dump_flexible_vertex(dwVertexTypeDesc);
+    }
+
+    if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
+
+    return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
+}
+
+
+
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
 # define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
 #else
@@ -277,10 +472,10 @@
     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_1T_ProcessVertices,
+    XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
     XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
     XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
-    XCAST(ProcessVerticesStrided) Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
+    XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
 };
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
@@ -321,13 +516,13 @@
 	FE(D3DVBCAPS_WRITEONLY)
     };
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferImpl));
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
     if (object == NULL) return DDERR_OUTOFMEMORY;
 
     object->ref = 1;
     object->d3d = d3d;
     object->desc = *lpD3DVertBufDesc;
-    object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF, NULL) * lpD3DVertBufDesc->dwNumVertices;
+    object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
     object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
     
     ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer,  VTABLE_IDirect3DVertexBuffer);


More information about the wine-patches mailing list