All, With this patch, DungeonSiege is now starting to work and displays stuff. It now gives me a lot of warnings about stuff not implemented (yeah :-) ). There is still one *huge* problem : basically, it gives us completely bogus lock rectangles at the first time it locks the front buffer to display the mouse cursor... This means that for the game to work, you need an ugly hack that 'sanitizes' the Lock rectangles (available on request :-) ). Lionel Changelog: - added RGB 32 surface locking (seems to work fine without resorting to Alpha hacks) -- Lionel Ulmer - http://www.bbrox.org/
--- dlls/ddraw_CVS/d3ddevice/mesa.c Sat May 17 17:02:36 2003 +++ dlls/ddraw/d3ddevice/mesa.c Sat May 17 23:16:14 2003 @@ -2578,6 +2578,7 @@ ((is_front == FALSE) && (gl_d3d_dev->state != SURFACE_MEMORY))) { /* If the surface is already in memory, no need to do anything here... */ GLenum buffer_type; + GLenum buffer_color; GLenum prev_read; RECT loc_rect; int y; @@ -2601,8 +2602,21 @@ /* Application wants to lock the back buffer */ glReadBuffer(GL_BACK); - if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) { + if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) && + (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) && + (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) && + (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F) && + (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) { buffer_type = GL_UNSIGNED_SHORT_5_6_5; + buffer_color = GL_RGB; + } else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) && + (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && + (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && + (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) && + (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) { + buffer_type = GL_UNSIGNED_BYTE; + buffer_color = GL_BGRA; + glPixelStorei(GL_PACK_SWAP_BYTES, TRUE); } else { ERR(" unsupported pixel format at device locking.\n"); LEAVE_GL(); @@ -2627,17 +2641,33 @@ y--) { glReadPixels(loc_rect.left, y, loc_rect.right - loc_rect.left, 1, - GL_RGB, buffer_type, dst); + buffer_color, buffer_type, dst); dst += This->surface_desc.u1.lPitch; } glReadBuffer(prev_read); - + glPixelStorei(GL_PACK_SWAP_BYTES, FALSE); + if (is_front) gl_d3d_dev->front_state = SURFACE_MEMORY; else gl_d3d_dev->state = SURFACE_MEMORY; +#if 0 + /* I keep this code here as it's very useful to debug :-) */ + { + static int flush_count = 0; + char buf[128]; + FILE *f; + + if ((++flush_count % 50) == 0) { + sprintf(buf, "lock_%06d.pnm", flush_count); + f = fopen(buf, "wb"); + DDRAW_dump_surface_to_disk(This, f); + } + } +#endif + LEAVE_GL(); } } @@ -2645,26 +2675,28 @@ #define UNLOCK_TEX_SIZE 256 static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect) { - GLenum buffer_type; + GLenum buffer_type, buffer_color; RECT loc_rect; IDirectDrawSurfaceImpl *surf = d3d_dev->surface; IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - GLint depth_test, alpha_test, cull_face, lighting, min_tex, max_tex, tex_env; + GLint depth_test, alpha_test, cull_face, lighting, min_tex, max_tex, tex_env, blend, stencil_test; GLuint initial_texture; GLint tex_state; int x, y; - + loc_rect.top = 0; loc_rect.left = 0; loc_rect.bottom = surf->surface_desc.dwHeight; loc_rect.right = surf->surface_desc.dwWidth; - TRACE(" flushing memory back to the frame-buffer.\n"); + TRACE(" flushing memory back to the frame-buffer (%ld,%ld) x (%ld,%ld).\n", loc_rect.top, loc_rect.left, loc_rect.right, loc_rect.bottom); glGetIntegerv(GL_DEPTH_TEST, &depth_test); glGetIntegerv(GL_ALPHA_TEST, &alpha_test); + glGetIntegerv(GL_STENCIL_TEST, &stencil_test); glGetIntegerv(GL_CULL_FACE, &cull_face); glGetIntegerv(GL_LIGHTING, &lighting); + glGetIntegerv(GL_BLEND, &blend); glGetIntegerv(GL_TEXTURE_BINDING_2D, &initial_texture); glGetIntegerv(GL_TEXTURE_2D, &tex_state); glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &max_tex); @@ -2672,10 +2704,23 @@ glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env); /* TODO: scissor test if ever we use it ! */ - if (surf->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) { + if ((surf->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) && + (surf->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) && + (surf->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) && + (surf->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F) && + (surf->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) { buffer_type = GL_UNSIGNED_SHORT_5_6_5; + buffer_color = GL_RGB; + } else if ((surf->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) && + (surf->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && + (surf->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && + (surf->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) && + (surf->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) { + buffer_type = GL_UNSIGNED_BYTE; + buffer_color = GL_BGRA; + glPixelStorei(GL_UNPACK_SWAP_BYTES, TRUE); } else { - WARN(" unsupported pixel format.\n"); + ERR(" unsupported pixel format at frame buffer flush.\n"); return; } @@ -2703,9 +2748,11 @@ glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); glDisable(GL_ALPHA_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - + for (x = loc_rect.left; x < loc_rect.right; x += UNLOCK_TEX_SIZE) { for (y = loc_rect.top; y < loc_rect.bottom; y += UNLOCK_TEX_SIZE) { /* First, upload the texture... */ @@ -2715,7 +2762,7 @@ 0, 0, 0, w, h, - GL_RGB, + buffer_color, buffer_type, ((char *) surf->surface_desc.lpSurface) + (x * GET_BPP(surf->surface_desc)) + (y * surf->surface_desc.u1.lPitch)); glBegin(GL_QUADS); @@ -2737,14 +2784,32 @@ if (depth_test != 0) glEnable(GL_DEPTH_TEST); if (lighting != 0) glEnable(GL_LIGHTING); if (alpha_test != 0) glEnable(GL_ALPHA_TEST); + if (stencil_test != 0) glEnable(GL_STENCIL_TEST); if (cull_face != 0) glEnable(GL_CULL_FACE); + if (blend != 0) glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, initial_texture); if (tex_state == 0) glDisable(GL_TEXTURE_2D); glDisable(GL_SCISSOR_TEST); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SWAP_BYTES, FALSE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_tex); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_env); + +#if 0 + /* I keep this code here as it's very useful to debug :-) */ + { + static int flush_count = 0; + char buf[128]; + FILE *f; + + if ((++flush_count % 50) == 0) { + sprintf(buf, "flush_%06d.pnm", flush_count); + f = fopen(buf, "wb"); + DDRAW_dump_surface_to_disk(surf, f); + } + } +#endif } static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)