Avoid structures or arrays of size 0.
[wine] / dlls / ddraw / d3dtexture.c
1 /* Direct3D Texture
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the implementation of interface Direct3DTexture2.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winerror.h"
27 #include "wine/obj_base.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "wine/debug.h"
31
32 #include "mesa_private.h"
33
34 #define D3DDPRIVATE(x) mesa_d3dd_private*odev=(mesa_d3dd_private*)(x)->private
35 #define D3DTPRIVATE(x) mesa_d3dt_private*dtpriv=(mesa_d3dt_private*)(x)->private
36
37 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
38
39 /* Define this if you want to save to a file all the textures used by a game
40    (can be funny to see how they managed to cram all the pictures in
41    texture memory) */
42 #undef TEXTURE_SNOOP
43
44 #ifdef TEXTURE_SNOOP
45 #include <stdio.h>
46
47 #define SNOOP_PALETTED()                                                                        \
48       {                                                                                         \
49         FILE *f;                                                                                \
50         char buf[32];                                                                           \
51         int x, y;                                                                               \
52                                                                                                 \
53         sprintf(buf, "%ld.pnm", dtpriv->tex_name);                                                      \
54         f = fopen(buf, "wb");                                                                   \
55         fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);                      \
56         for (y = 0; y < src_d->dwHeight; y++) {                                                 \
57           for (x = 0; x < src_d->dwWidth; x++) {                                                \
58             unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x];   \
59             fputc(table[c][0], f);                                                              \
60             fputc(table[c][1], f);                                                              \
61             fputc(table[c][2], f);                                                              \
62           }                                                                                     \
63         }                                                                                       \
64         fclose(f);                                                                              \
65       }
66
67 #define SNOOP_5650()                                                                                    \
68           {                                                                                             \
69             FILE *f;                                                                                    \
70             char buf[32];                                                                               \
71             int x, y;                                                                                   \
72                                                                                                         \
73             sprintf(buf, "%ld.pnm", dtpriv->tex_name);                                                  \
74             f = fopen(buf, "wb");                                                                       \
75             fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);                          \
76             for (y = 0; y < src_d->dwHeight; y++) {                                                     \
77               for (x = 0; x < src_d->dwWidth; x++) {                                                    \
78                 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];     \
79                 fputc((c & 0xF800) >> 8, f);                                                            \
80                 fputc((c & 0x07E0) >> 3, f);                                                            \
81                 fputc((c & 0x001F) << 3, f);                                                            \
82               }                                                                                         \
83             }                                                                                           \
84             fclose(f);                                                                                  \
85           }
86
87 #define SNOOP_5551()                                                                                    \
88           {                                                                                             \
89             FILE *f;                                                                                    \
90             char buf[32];                                                                               \
91             int x, y;                                                                                   \
92                                                                                                         \
93             sprintf(buf, "%ld.pnm", dtpriv->tex_name);                                                  \
94             f = fopen(buf, "wb");                                                                       \
95             fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);                          \
96             for (y = 0; y < src_d->dwHeight; y++) {                                                     \
97               for (x = 0; x < src_d->dwWidth; x++) {                                                    \
98                 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];     \
99                 fputc((c & 0xF800) >> 8, f);                                                            \
100                 fputc((c & 0x07C0) >> 3, f);                                                            \
101                 fputc((c & 0x003E) << 2, f);                                                            \
102               }                                                                                         \
103             }                                                                                           \
104             fclose(f);                                                                                  \
105           }
106 #else
107 #define SNOOP_PALETTED()
108 #define SNOOP_5650()
109 #define SNOOP_5551()
110 #endif
111
112 extern ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable;
113 extern ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable;
114
115 /*******************************************************************************
116  *                              Texture2 Creation functions
117  */
118 LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurfaceImpl* surf)
119 {
120   IDirect3DTexture2Impl* tex;
121
122   tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
123   tex->ref = 1;
124   ICOM_VTBL(tex) = &mesa_texture2_vtable;
125   tex->surface = surf;
126
127   tex->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dt_private));
128
129   return (LPDIRECT3DTEXTURE2)tex;
130 }
131
132 /*******************************************************************************
133  *                              Texture Creation functions
134  */
135 LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurfaceImpl* surf)
136 {
137   IDirect3DTexture2Impl* tex;
138
139   tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
140   tex->ref = 1;
141   ICOM_VTBL(tex) = (ICOM_VTABLE(IDirect3DTexture2)*)&mesa_texture_vtable;
142   tex->surface = surf;
143
144   tex->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dt_private));
145
146   return (LPDIRECT3DTEXTURE)tex;
147 }
148
149 /*******************************************************************************
150  *                         IDirectSurface callback methods
151  */
152 HRESULT WINAPI  SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
153 {
154   DDSURFACEDESC *tex_d;
155   D3DTPRIVATE(texture);
156   int bpp;
157   GLuint current_texture;
158
159   TRACE("(%p) : colorkey callback\n", texture);
160
161   /* Get the texture description */
162   tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc);
163   bpp = (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
164          1 /* 8 bit of palette index */:
165          tex_d->ddpfPixelFormat.u1.dwRGBBitCount / 8 /* RGB bits for each colors */ );
166
167   /* Now, save the current texture */
168   ENTER_GL();
169   glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
170
171   /* If the GetHandle was not done yet, it's an error */
172   if (dtpriv->tex_name == 0) {
173     ERR("Unloaded texture !\n");
174     LEAVE_GL();
175     return DD_OK;
176   }
177   glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
178
179   if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
180     FIXME("Todo Paletted\n");
181   } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
182     if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
183       FIXME("Todo 3_3_2_0\n");
184     } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
185       if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
186         /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
187         unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(),
188                                                             HEAP_ZERO_MEMORY,
189                                                             tex_d->dwWidth * tex_d->dwHeight * bpp);
190         unsigned short *src = (unsigned short *) tex_d->lpSurface;
191         int x, y;
192
193         for (y = 0; y < tex_d->dwHeight; y++) {
194           for (x = 0; x < tex_d->dwWidth; x++) {
195             unsigned short cpixel = src[x + y * tex_d->dwWidth];
196
197             if ((dwFlags & DDCKEY_SRCBLT) &&
198                 (cpixel >= ckey->dwColorSpaceLowValue) &&
199                 (cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */
200               dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000;
201             else                                         /* Alpha bit is set => this pixel will be seen */
202               dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001;
203           }
204         }
205
206         glTexImage2D(GL_TEXTURE_2D,
207                      0,
208                      GL_RGBA,
209                      tex_d->dwWidth, tex_d->dwHeight,
210                      0,
211                      GL_RGBA,
212                      GL_UNSIGNED_SHORT_5_5_5_1,
213                      dest);
214
215         /* Frees the temporary surface */
216         HeapFree(GetProcessHeap(),0,dest);
217       } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
218         FIXME("Todo 5_5_5_1\n");
219       } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
220         FIXME("Todo 4_4_4_4\n");
221       } else {
222         ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
223       }
224     } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
225       FIXME("Todo 8_8_8_0\n");
226     } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
227       FIXME("Todo 8_8_8_8\n");
228     } else {
229       ERR("Unhandled texture format (bad RGB count)\n");
230     }
231   } else {
232     ERR("Unhandled texture format (neither RGB nor INDEX)\n");
233   }
234   LEAVE_GL();
235
236   return DD_OK;
237 }
238
239 /*******************************************************************************
240  *                              IDirect3DTexture2 methods
241  */
242
243 HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface,
244                                                         REFIID riid,
245                                                         LPVOID* ppvObj)
246 {
247   ICOM_THIS(IDirect3DTexture2Impl,iface);
248
249   FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
250
251   return S_OK;
252 }
253
254
255
256 ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface)
257 {
258   ICOM_THIS(IDirect3DTexture2Impl,iface);
259   TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
260
261   return ++(This->ref);
262 }
263
264
265
266 ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface)
267 {
268   ICOM_THIS(IDirect3DTexture2Impl,iface);
269   D3DTPRIVATE(This);
270   FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
271
272   if (!--(This->ref)) {
273     /* Delete texture from OpenGL */
274     ENTER_GL();
275     glDeleteTextures(1, &(dtpriv->tex_name));
276     LEAVE_GL();
277
278     /* Release surface */
279     IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->surface);
280
281     HeapFree(GetProcessHeap(),0,This);
282     return 0;
283   }
284
285   return This->ref;
286 }
287
288 /*** IDirect3DTexture methods ***/
289 HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
290                                                  LPDIRECT3DDEVICE lpD3DDevice,
291                                                  LPD3DTEXTUREHANDLE lpHandle)
292 {
293     ICOM_THIS(IDirect3DTexture2Impl,iface);
294     D3DTPRIVATE(This);
295     IDirect3DDeviceImpl* ilpD3DDevice=(IDirect3DDeviceImpl*)lpD3DDevice;
296     FIXME("(%p)->(%p,%p): stub\n", This, ilpD3DDevice, lpHandle);
297
298     *lpHandle = (D3DTEXTUREHANDLE) This;
299
300     /* Now, bind a new texture */
301     ENTER_GL();
302     ilpD3DDevice->set_context(ilpD3DDevice);
303     This->D3Ddevice = (void *) ilpD3DDevice;
304     if (dtpriv->tex_name == 0)
305         glGenTextures(1, &(dtpriv->tex_name));
306     LEAVE_GL();
307
308     TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);
309
310     return D3D_OK;
311 }
312
313 HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
314                                                   LPDIRECT3DDEVICE lpD3DDevice,
315                                                   LPDIRECTDRAWSURFACE lpSurface)
316 {
317   ICOM_THIS(IDirect3DTexture2Impl,iface);
318   TRACE("(%p)->(%p,%p)\n", This, lpD3DDevice, lpSurface);
319
320   return DDERR_ALREADYINITIALIZED;
321 }
322
323 HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface)
324 {
325   ICOM_THIS(IDirect3DTexture2Impl,iface);
326   FIXME("(%p)->(): stub\n", This);
327
328   return D3D_OK;
329 }
330
331 /*** IDirect3DTexture2 methods ***/
332 HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface,
333                                                   LPDIRECT3DDEVICE2 lpD3DDevice2,
334                                                   LPD3DTEXTUREHANDLE lpHandle)
335 {
336     ICOM_THIS(IDirect3DTexture2Impl,iface);
337     D3DTPRIVATE(This);
338     IDirect3DDevice2Impl* ilpD3DDevice2=(IDirect3DDevice2Impl*)lpD3DDevice2;
339     TRACE("(%p)->(%p,%p)\n", This, ilpD3DDevice2, lpHandle);
340
341     /* For 32 bits OSes, handles = pointers */
342     *lpHandle = (D3DTEXTUREHANDLE) This;
343
344     /* Now, bind a new texture */
345     ENTER_GL();
346     ilpD3DDevice2->set_context(ilpD3DDevice2);
347     This->D3Ddevice = (void *) ilpD3DDevice2;
348     if (dtpriv->tex_name == 0)
349         glGenTextures(1, &(dtpriv->tex_name));
350     LEAVE_GL();
351
352     TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);
353
354     return D3D_OK;
355 }
356
357 /* Common methods */
358 HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(
359     LPDIRECT3DTEXTURE2 iface, DWORD dwStart, DWORD dwCount
360 ) {
361   ICOM_THIS(IDirect3DTexture2Impl,iface);
362   FIXME("(%p)->(%8ld,%8ld): stub\n", This, dwStart, dwCount);
363
364   return D3D_OK;
365 }
366
367 /* NOTE : if you experience crashes in this function, you must have a buggy
368           version of Mesa. See the file d3dtexture.c for a cure */
369 HRESULT WINAPI IDirect3DTexture2Impl_Load(
370     LPDIRECT3DTEXTURE2 iface, LPDIRECT3DTEXTURE2 lpD3DTexture2
371 ) {
372   ICOM_THIS(IDirect3DTexture2Impl,iface);
373   D3DTPRIVATE(This);
374   IDirect3DTexture2Impl* ilpD3DTexture2=(IDirect3DTexture2Impl*)lpD3DTexture2;
375   DDSURFACEDESC *src_d, *dst_d;
376   static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
377                                     GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
378 #if 0
379   static BOOL color_table_queried = FALSE;
380 #endif
381
382   TRACE("(%p)->(%p)\n", This, ilpD3DTexture2);
383   TRACE("Copied surface %p to surface %p\n", ilpD3DTexture2->surface, This->surface);
384
385   /* Suppress the ALLOCONLOAD flag */
386   This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
387
388   /* Copy one surface on the other */
389   dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc);
390   src_d = (DDSURFACEDESC *)&(ilpD3DTexture2->surface->surface_desc);
391
392   /* Install the callbacks to the destination surface */
393   This->surface->texture = This;
394   This->surface->SetColorKey_cb = SetColorKey_cb;
395
396   if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
397     /* Should also check for same pixel format, lPitch, ... */
398     ERR("Error in surface sizes\n");
399     return D3DERR_TEXTURE_LOAD_FAILED;
400   } else {
401     /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
402     /* I should put a macro for the calculus of bpp */
403     int bpp = (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
404                1 /* 8 bit of palette index */:
405                src_d->ddpfPixelFormat.u1.dwRGBBitCount / 8 /* RGB bits for each colors */ );
406     GLuint current_texture;
407
408     /* Copy the main memry texture into the surface that corresponds to the OpenGL
409        texture object. */
410     memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->dwWidth * src_d->dwHeight * bpp);
411
412     ENTER_GL();
413
414     /* Now, load the texture */
415     /* d3dd->set_context(d3dd); We need to set the context somehow.... */
416     glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
417
418     /* If the GetHandle was not done, get the texture name here */
419     if (dtpriv->tex_name == 0)
420       glGenTextures(1, &(dtpriv->tex_name));
421     glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
422
423     if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
424       /* ****************
425          Paletted Texture
426          **************** */
427       IDirectDrawPaletteImpl* pal = This->surface->palette;
428       BYTE table[256][4];
429       int i;
430
431 #if 0
432       if (color_table_queried == FALSE) {
433         ptr_ColorTableEXT =
434           ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
435       }
436 #endif
437
438       if (pal == NULL) {
439         ERR("Palettized texture Loading with a NULL palette !\n");
440         LEAVE_GL();
441         return D3DERR_TEXTURE_LOAD_FAILED;
442       }
443
444       /* Get the surface's palette */
445       for (i = 0; i < 256; i++) {
446         table[i][0] = pal->palents[i].peRed;
447         table[i][1] = pal->palents[i].peGreen;
448         table[i][2] = pal->palents[i].peBlue;
449         if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
450             (i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
451             (i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
452           table[i][3] = 0x00;
453         else
454         table[i][3] = 0xFF;
455       }
456
457       /* Texture snooping */
458       SNOOP_PALETTED();
459
460       if (ptr_ColorTableEXT != NULL) {
461         /* use Paletted Texture Extension */
462         ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
463                           GL_RGBA,          /* internal format */
464                           256,              /* table size */
465                           GL_RGBA,          /* table format */
466                           GL_UNSIGNED_BYTE, /* table type */
467                           table);           /* the color table */
468
469         glTexImage2D(GL_TEXTURE_2D,       /* target */
470                      0,                   /* level */
471                      GL_COLOR_INDEX8_EXT, /* internal format */
472                      src_d->dwWidth, src_d->dwHeight, /* width, height */
473                      0,                   /* border */
474                      GL_COLOR_INDEX,      /* texture format */
475                      GL_UNSIGNED_BYTE,    /* texture type */
476                      src_d->lpSurface); /* the texture */
477       } else {
478         DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
479         DWORD i;
480         BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
481
482         for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
483           BYTE color = *src++;
484           *dst++ = table[color][0];
485           *dst++ = table[color][1];
486           *dst++ = table[color][2];
487           *dst++ = table[color][3];
488         }
489
490         glTexImage2D(GL_TEXTURE_2D,
491                      0,
492                      GL_RGBA,
493                      src_d->dwWidth, src_d->dwHeight,
494                      0,
495                      GL_RGBA,
496                      GL_UNSIGNED_BYTE,
497                      surface);
498
499         HeapFree(GetProcessHeap(), 0, surface);
500       }
501     } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
502       /* ************
503          RGB Textures
504          ************ */
505       if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
506         /* **********************
507            GL_UNSIGNED_BYTE_3_3_2
508            ********************** */
509         glTexImage2D(GL_TEXTURE_2D,
510                      0,
511                      GL_RGB,
512                      src_d->dwWidth, src_d->dwHeight,
513                      0,
514                      GL_RGB,
515                      GL_UNSIGNED_BYTE_3_3_2,
516                      src_d->lpSurface);
517       } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
518         if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
519
520           /* Texture snooping */
521           SNOOP_5650();
522
523           glTexImage2D(GL_TEXTURE_2D,
524                        0,
525                        GL_RGB,
526                        src_d->dwWidth, src_d->dwHeight,
527                        0,
528                        GL_RGB,
529                        GL_UNSIGNED_SHORT_5_6_5,
530                        src_d->lpSurface);
531         } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
532           /* Texture snooping */
533           SNOOP_5551();
534
535           glTexImage2D(GL_TEXTURE_2D,
536                        0,
537                        GL_RGBA,
538                        src_d->dwWidth, src_d->dwHeight,
539                        0,
540                        GL_RGBA,
541                        GL_UNSIGNED_SHORT_5_5_5_1,
542                        src_d->lpSurface);
543         } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
544           glTexImage2D(GL_TEXTURE_2D,
545                        0,
546                        GL_RGBA,
547                        src_d->dwWidth, src_d->dwHeight,
548                        0,
549                        GL_RGBA,
550                        GL_UNSIGNED_SHORT_4_4_4_4,
551                        src_d->lpSurface);
552         } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
553           /* Converting the 1555 format in 5551 packed */
554           WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
555           DWORD i;
556           WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
557
558           for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
559             *dst++ = (((*src & 0x8000) >> 15) |
560                       ((*src & 0x7FFF) <<  1));
561             src++;
562           }
563
564           glTexImage2D(GL_TEXTURE_2D,
565                        0,
566                        GL_RGBA,
567                        src_d->dwWidth, src_d->dwHeight,
568                        0,
569                        GL_RGBA,
570                        GL_UNSIGNED_SHORT_5_5_5_1,
571                        surface);
572
573           HeapFree(GetProcessHeap(), 0, surface);
574         } else {
575           ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
576         }
577       } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
578         glTexImage2D(GL_TEXTURE_2D,
579                      0,
580                      GL_RGB,
581                      src_d->dwWidth, src_d->dwHeight,
582                      0,
583                      GL_RGB,
584                      GL_UNSIGNED_BYTE,
585                      src_d->lpSurface);
586       } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
587         glTexImage2D(GL_TEXTURE_2D,
588                      0,
589                      GL_RGBA,
590                      src_d->dwWidth, src_d->dwHeight,
591                      0,
592                      GL_RGBA,
593                      GL_UNSIGNED_BYTE,
594                      src_d->lpSurface);
595       } else {
596         ERR("Unhandled texture format (bad RGB count)\n");
597       }
598     } else {
599       ERR("Unhandled texture format (neither RGB nor INDEX)\n");
600     }
601
602     glBindTexture(GL_TEXTURE_2D, current_texture);
603
604     LEAVE_GL();
605   }
606
607   return D3D_OK;
608 }
609
610
611 /*******************************************************************************
612  *                              IDirect3DTexture2 VTable
613  */
614 ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable =
615 {
616   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
617   /*** IUnknown methods ***/
618   IDirect3DTexture2Impl_QueryInterface,
619   IDirect3DTexture2Impl_AddRef,
620   IDirect3DTexture2Impl_Release,
621   /*** IDirect3DTexture methods ***/
622   IDirect3DTexture2Impl_GetHandle,
623   IDirect3DTexture2Impl_PaletteChanged,
624   IDirect3DTexture2Impl_Load
625 };
626
627 /*******************************************************************************
628  *                              IDirect3DTexture VTable
629  */
630 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
631 # define XCAST(fun)     (typeof(mesa_texture_vtable.fun))
632 #else
633 # define XCAST(fun)     (void*)
634 #endif
635
636 ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable =
637 {
638   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
639   /*** IUnknown methods ***/
640   XCAST(QueryInterface)IDirect3DTexture2Impl_QueryInterface,
641   XCAST(AddRef)IDirect3DTexture2Impl_AddRef,
642   XCAST(Release)IDirect3DTexture2Impl_Release,
643   /*** IDirect3DTexture methods ***/
644   IDirect3DTextureImpl_Initialize,
645   IDirect3DTextureImpl_GetHandle,
646   XCAST(PaletteChanged)IDirect3DTexture2Impl_PaletteChanged,
647   XCAST(Load)IDirect3DTexture2Impl_Load,
648   IDirect3DTextureImpl_Unload
649 };
650
651 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
652 #undef XCAST
653 #endif