- added more texture formats using OpenGL's packed pixel formats

diff --git a/graphics/d3ddevices.c b/graphics/d3ddevices.c
index e6cf395..5d15b2c 100644
--- a/graphics/d3ddevices.c
+++ b/graphics/d3ddevices.c
@@ -16,6 +16,12 @@
 
 #include "d3d_private.h"
 
+/* Define this variable if you have an unpatched Mesa 3.0 (patches are available
+   on Mesa's home page) or version 3.1b.
+
+   Version 3.2b should correct this bug */
+#undef HAVE_BUGGY_MESAGL
+
 #ifdef HAVE_MESAGL
 
 static GUID IID_D3DDEVICE2_OpenGL = {
@@ -81,11 +87,11 @@
 
 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
 {
-  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_TRANSFORMCAPS | D3DDD_TRICAPS;
+    | 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 |
@@ -102,6 +108,7 @@
   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 :-) ) */
@@ -342,17 +349,17 @@
   pformat->dwSize = sizeof(DDPIXELFORMAT);
   pformat->dwFourCC = 0;
   
-  TRACE(ddraw, "Enumerating GL_RGBA (32)\n");
+  TRACE(ddraw, "Enumerating GL_RGBA unpacked (32)\n");
   pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
   pformat->x.dwRGBBitCount = 32;
-  pformat->y.dwRBitMask =  0x00FF0000;
-  pformat->z.dwGBitMask =  0x0000FF00;
-  pformat->xx.dwBBitMask = 0x000000FF;
-  pformat->xy.dwRGBAlphaBitMask = 0xFF000000;
+  pformat->y.dwRBitMask =         0xFF000000;
+  pformat->z.dwGBitMask =         0x00FF0000;
+  pformat->xx.dwBBitMask =        0x0000FF00;
+  pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
   if (cb(&sdesc, context) == 0)
     return DD_OK;
 
-  TRACE(ddraw, "Enumerating GL_RGB (24)\n");
+  TRACE(ddraw, "Enumerating GL_RGB unpacked (24)\n");
   pformat->dwFlags = DDPF_RGB;
   pformat->x.dwRGBBitCount = 24;
   pformat->y.dwRBitMask =  0x00FF0000;
@@ -362,7 +369,10 @@
   if (cb(&sdesc, context) == 0)
     return DD_OK;
 
-  TRACE(ddraw, "Enumerating GL_RGB (16)\n");
+#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(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
   pformat->dwFlags = DDPF_RGB;
   pformat->x.dwRGBBitCount = 16;
   pformat->y.dwRBitMask =  0x0000F800;
@@ -372,6 +382,37 @@
   if (cb(&sdesc, context) == 0)
     return DD_OK;
 
+  TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
+  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+  pformat->x.dwRGBBitCount = 16;
+  pformat->y.dwRBitMask =         0x0000F800;
+  pformat->z.dwGBitMask =         0x000007C0;
+  pformat->xx.dwBBitMask =        0x0000003E;
+  pformat->xy.dwRGBAlphaBitMask = 0x00000001;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
+  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+  pformat->x.dwRGBBitCount = 16;
+  pformat->y.dwRBitMask =         0x0000F000;
+  pformat->z.dwGBitMask =         0x00000F00;
+  pformat->xx.dwBBitMask =        0x000000F0;
+  pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
+  pformat->dwFlags = DDPF_RGB;
+  pformat->x.dwRGBBitCount = 8;
+  pformat->y.dwRBitMask =         0x0000F800;
+  pformat->z.dwGBitMask =         0x000007C0;
+  pformat->xx.dwBBitMask =        0x0000003E;
+  pformat->xy.dwRGBAlphaBitMask = 0x00000001;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+#endif
+  
   TRACE(ddraw, "Enumerating Paletted (8)\n");
   pformat->dwFlags = DDPF_PALETTEINDEXED8;
   pformat->x.dwRGBBitCount = 8;
@@ -400,7 +441,7 @@
 
 static HRESULT WINAPI IDirect3DDevice2_BeginScene(LPDIRECT3DDEVICE2 this)
 {
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
+  /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; */
   
   FIXME(ddraw, "(%p)->(): stub\n", this);
   
@@ -1331,6 +1372,7 @@
   TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, d3dMatHandle, lpD3DMatrix);
 
   dump_mat(lpD3DMatrix);
+  
   *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
   
   return DD_OK;
@@ -1362,7 +1404,7 @@
 
 static HRESULT WINAPI IDirect3DDevice_BeginScene(LPDIRECT3DDEVICE this)
 {
-  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
+  /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; */
   
   FIXME(ddraw, "(%p)->(): stub\n", this);
   
@@ -1406,6 +1448,7 @@
       unsigned char g =  *lsrc++;
       unsigned char b =  *lsrc++;
       lsrc++; /* Alpha */
+
       *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
       
       dest++;
diff --git a/graphics/d3dtexture.c b/graphics/d3dtexture.c
index 0344c9c..76ed9ed 100644
--- a/graphics/d3dtexture.c
+++ b/graphics/d3dtexture.c
@@ -18,6 +18,11 @@
 
 #ifdef HAVE_MESAGL
 
+/* Define this if you want to save to a file all the textures used by a game
+   (can be funny to see how they managed to cram all the pictures in
+   texture memory) */
+#undef TEXTURE_SNOOP
+
 static IDirect3DTexture2_VTable texture2_vtable;
 static IDirect3DTexture_VTable texture_vtable;
 
@@ -106,6 +111,14 @@
 
   *lpHandle = (DWORD) this;
   
+  /* Now, bind a new texture */
+  lpD3DDevice->set_context(lpD3DDevice);
+  this->D3Ddevice = (void *) lpD3DDevice;
+  if (this->tex_name == 0)
+    glGenTextures(1, &(this->tex_name));
+
+  TRACE(ddraw, "OpenGL texture handle is : %d\n", this->tex_name);
+  
   return D3D_OK;
 }
 
@@ -138,6 +151,7 @@
   /* Now, bind a new texture */
   lpD3DDevice2->set_context(lpD3DDevice2);
   this->D3Ddevice = (void *) lpD3DDevice2;
+  if (this->tex_name == 0)
   glGenTextures(1, &(this->tex_name));
 
   TRACE(ddraw, "OpenGL texture handle is : %d\n", this->tex_name);
@@ -155,14 +169,17 @@
   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 */
 static HRESULT WINAPI IDirect3DTexture2_Load(LPDIRECT3DTEXTURE2 this,
 					     LPDIRECT3DTEXTURE2 lpD3DTexture2)
 {
   DDSURFACEDESC	*src_d, *dst_d;
   TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DTexture2);
 
-  /* Hack ? */
   TRACE(ddraw, "Copied to surface %p, surface %p\n", this->surface, lpD3DTexture2->surface);
+
+  /* Suppress the ALLOCONLOAD flag */
   this->surface->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
 
   /* Copy one surface on the other */
@@ -187,9 +204,16 @@
     /* 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 (this->tex_name == 0)
+      glGenTextures(1, &(this->tex_name));
     glBindTexture(GL_TEXTURE_2D, this->tex_name);
 
     if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+      /* ****************
+	 Paletted Texture
+	 **************** */
       LPDIRECTDRAWPALETTE pal = this->surface->s.palette;
       BYTE table[256][4];
       int i;
@@ -212,8 +236,7 @@
 	table[i][3] = 0xFF;
       }
       
-#if 0
-      /* If you want to see how the game manages its textures :-) */
+#ifdef TEXTURE_SNOOP
       {
 	FILE *f;
 	char buf[32];
@@ -249,8 +272,117 @@
 		   GL_COLOR_INDEX,      /* texture format */
 		   GL_UNSIGNED_BYTE,    /* texture type */
 		   src_d->y.lpSurface); /* the texture */
+    } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
+      /* ************
+	 RGB Textures
+	 ************ */
+      if (src_d->ddpfPixelFormat.x.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->y.lpSurface);
+      } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 16) {
+	if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) {
+#ifdef TEXTURE_SNOOP
+	  {
+	    FILE *f;
+	    char buf[32];
+	    int x, y;
+	    
+	    sprintf(buf, "%d.pnm", this->tex_name);
+	    f = fopen(buf, "wb");
+	    fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight);
+	    for (y = 0; y < src_d->dwHeight; y++) {
+	      for (x = 0; x < src_d->dwWidth; x++) {
+		unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];
+		fputc((c & 0xF800) >> 8, f);
+		fputc((c & 0x07E0) >> 3, f);
+		fputc((c & 0x001F) << 3, f);
+	      }
+	    }
+	    fclose(f);
+	  }
+#endif
+	  glTexImage2D(GL_TEXTURE_2D,
+		       0,
+		       GL_RGB,
+		       src_d->dwWidth, src_d->dwHeight,
+		       0,
+		       GL_RGB,
+		       GL_UNSIGNED_SHORT_5_6_5,
+		       src_d->y.lpSurface);
+	} else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) {
+#ifdef TEXTURE_SNOOP
+	  {
+	    FILE *f;
+	    char buf[32];
+	    int x, y;
+	    
+	    sprintf(buf, "%d.pnm", this->tex_name);
+	    f = fopen(buf, "wb");
+	    fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight);
+	    for (y = 0; y < src_d->dwHeight; y++) {
+	      for (x = 0; x < src_d->dwWidth; x++) {
+		unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];
+		fputc((c & 0xF800) >> 8, f);
+		fputc((c & 0x07C0) >> 3, f);
+		fputc((c & 0x003E) << 2, f);
+	      }
+	    }
+	    fclose(f);
+	  }
+#endif
+	  
+	  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->y.lpSurface);
+	} else if (src_d->ddpfPixelFormat.xy.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->y.lpSurface);
+	} else {
+	  ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
+	}
+      } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 24) {
+	glTexImage2D(GL_TEXTURE_2D,
+		     0,
+		     GL_RGB,
+		     src_d->dwWidth, src_d->dwHeight,
+		     0,
+		     GL_RGB,
+		     GL_UNSIGNED_BYTE,
+		     src_d->y.lpSurface);
+      } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 32) {
+	glTexImage2D(GL_TEXTURE_2D,
+		     0,
+		     GL_RGBA,
+		     src_d->dwWidth, src_d->dwHeight,
+		     0,
+		     GL_RGBA,
+		     GL_UNSIGNED_BYTE,
+		     src_d->y.lpSurface);
+      } else {
+	ERR(ddraw, "Unhandled texture format (bad RGB count)\n");
+      }
     } else {
-      ERR(ddraw, "Unhandled texture format\n");
+      ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n");
     }
 
     glBindTexture(GL_TEXTURE_2D, current_texture);