/* Direct3D Common functions
 * Copyright (c) 1998 Lionel ULMER
 *
 * This file contains all MESA common code
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <stdarg.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wingdi.h"
#include "ddraw.h"
#include "d3d.h"
#include "wine/debug.h"

#include "opengl_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState)
{
    switch (dwRenderState) {
        case D3DCMP_NEVER: return GL_NEVER;
	case D3DCMP_LESS: return GL_LESS;
	case D3DCMP_EQUAL: return GL_EQUAL;
	case D3DCMP_LESSEQUAL: return GL_LEQUAL;
	case D3DCMP_GREATER: return GL_GREATER;
	case D3DCMP_NOTEQUAL: return GL_NOTEQUAL;
	case D3DCMP_GREATEREQUAL: return GL_GEQUAL;
	case D3DCMP_ALWAYS: return GL_ALWAYS;
	default: ERR("Unexpected compare type %d !\n", dwRenderState);
    }
    return GL_ALWAYS;
}

GLenum convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState)
{
    switch (dwRenderState) {
        case D3DSTENCILOP_KEEP: return GL_KEEP;
        case D3DSTENCILOP_ZERO: return GL_ZERO;
        case D3DSTENCILOP_REPLACE: return GL_REPLACE;
        case D3DSTENCILOP_INCRSAT: return GL_INCR;
        case D3DSTENCILOP_DECRSAT: return GL_DECR;
        case D3DSTENCILOP_INVERT: return GL_INVERT;
        case D3DSTENCILOP_INCR: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR;
        case D3DSTENCILOP_DECR: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR;
        default: ERR("Unexpected compare type %d !\n", dwRenderState);      
    }
    return GL_KEEP;
}

GLenum convert_D3D_blendop_to_GL(D3DBLEND dwRenderState)
{
    switch ((D3DBLEND) dwRenderState) {
        case D3DBLEND_ZERO: return GL_ZERO;
        case D3DBLEND_ONE: return GL_ONE;
	case D3DBLEND_SRCALPHA: return GL_SRC_ALPHA;
	case D3DBLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA;
	case D3DBLEND_DESTALPHA: return GL_DST_ALPHA;
	case D3DBLEND_INVDESTALPHA: return GL_ONE_MINUS_DST_ALPHA;
	case D3DBLEND_DESTCOLOR: return GL_DST_COLOR;
	case D3DBLEND_INVDESTCOLOR: return GL_ONE_MINUS_DST_COLOR;
	case D3DBLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE;
	case D3DBLEND_SRCCOLOR: return GL_SRC_COLOR;
	case D3DBLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR;
        default: ERR("Unhandled blend mode %d !\n", dwRenderState); return GL_ZERO;
    }
}

void set_render_state(IDirect3DDeviceImpl* This,
		      D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock)
{
    DWORD dwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
    
    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);

    /* First, all the stipple patterns */
    if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
	(dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
        ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
    } else {
        ENTER_GL();

	/* All others state variables */
	switch (dwRenderStateType) {
	    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
	        IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
		
		IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
					    0, 
					    ICOM_INTERFACE(tex, IDirectDrawSurface7));
	    } break;

	    case D3DRENDERSTATE_ANTIALIAS:        /*  2 */
	        if (dwRenderState)
		    ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n");
	        break;
	      
	    case D3DRENDERSTATE_TEXTUREADDRESSU:  /* 44 */
	    case D3DRENDERSTATE_TEXTUREADDRESSV:  /* 45 */
	    case D3DRENDERSTATE_TEXTUREADDRESS: { /*  3 */
	        D3DTEXTURESTAGESTATETYPE d3dTexStageStateType;

		if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) d3dTexStageStateType = D3DTSS_ADDRESS;
		else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU;
		else d3dTexStageStateType = D3DTSS_ADDRESSV;

		IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
						      0, d3dTexStageStateType,
						      dwRenderState);
	    } break;
	      
	    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
	        if (dwRenderState)
		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
		else
		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
	        break;

	    case D3DRENDERSTATE_WRAPU: /* 5 */
	    case D3DRENDERSTATE_WRAPV: /* 6 */
	    case D3DRENDERSTATE_WRAP0: /* 128 */
	    case D3DRENDERSTATE_WRAP1: /* 129 */
	    case D3DRENDERSTATE_WRAP2: /* 130 */
	    case D3DRENDERSTATE_WRAP3: /* 131 */
	    case D3DRENDERSTATE_WRAP4: /* 132 */
	    case D3DRENDERSTATE_WRAP5: /* 133 */
	    case D3DRENDERSTATE_WRAP6: /* 134 */
	    case D3DRENDERSTATE_WRAP7: /* 135 */
	        if (dwRenderState)
		    ERR("Texture WRAP modes unsupported by OpenGL.. Expect graphical glitches !\n");
	        break;

	    case D3DRENDERSTATE_ZENABLE:          /*  7 */
	        /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be
		   updated either.. No idea about what happens in D3D.
		   
		   Maybe replacing the Z function by ALWAYS would be a better idea. */
	        if (dwRenderState == D3DZB_TRUE) {
		    if (glThis->depth_test == FALSE) {
			glEnable(GL_DEPTH_TEST);
			glThis->depth_test = TRUE;
		    }
		} else if (dwRenderState == D3DZB_FALSE) {
		    if (glThis->depth_test) {
			glDisable(GL_DEPTH_TEST);
			glThis->depth_test = FALSE;
		    }
		} else {
		    if (glThis->depth_test == FALSE) {
			glEnable(GL_DEPTH_TEST);
			glThis->depth_test = TRUE;
		    }
		    WARN(" w-buffering not supported.\n");
		}
	        break;

	    case D3DRENDERSTATE_FILLMODE:           /*  8 */
	        switch ((D3DFILLMODE) dwRenderState) {
		    case D3DFILL_POINT:
		        glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);        
			break;
		    case D3DFILL_WIREFRAME:
			glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
			break;
		    case D3DFILL_SOLID:
			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
			break;
		    default:
			ERR("Unhandled fill mode %ld !\n",dwRenderState);
		 }
	         break;

	    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
	        switch ((D3DSHADEMODE) dwRenderState) {
		    case D3DSHADE_FLAT:
		        glShadeModel(GL_FLAT);
			break;
		    case D3DSHADE_GOURAUD:
			glShadeModel(GL_SMOOTH);
			break;
		    default:
			ERR("Unhandled shade mode %ld !\n",dwRenderState);
		}
	        break;

	    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
	        if ((dwRenderState != FALSE) && (glThis->depth_mask == FALSE))
		    glDepthMask(GL_TRUE);
		else if ((dwRenderState == FALSE) && (glThis->depth_mask != FALSE))
		    glDepthMask(GL_FALSE);
	        glThis->depth_mask = dwRenderState;
	        break;
	      
	    case D3DRENDERSTATE_ALPHATESTENABLE:  /* 15 */
	        if ((dwRenderState != 0) && (glThis->alpha_test == FALSE))
		    glEnable(GL_ALPHA_TEST);
	        else if ((dwRenderState == 0) && (glThis->alpha_test != FALSE))
		    glDisable(GL_ALPHA_TEST);
		glThis->alpha_test = dwRenderState;
	        break;

	    case D3DRENDERSTATE_TEXTUREMAG: {     /* 17 */
	        DWORD tex_mag = 0xFFFFFFFF;

	        switch ((D3DTEXTUREFILTER) dwRenderState) {
		    case D3DFILTER_NEAREST:
		        tex_mag = D3DTFG_POINT;
			break;
		    case D3DFILTER_LINEAR:
		        tex_mag = D3DTFG_LINEAR;
			break;
		    default:
			ERR("Unhandled texture mag %ld !\n",dwRenderState);
	        }

		if (tex_mag != 0xFFFFFFFF) {
		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag);
		}
	    } break;

	    case D3DRENDERSTATE_TEXTUREMIN: {       /* 18 */
	        DWORD tex_min = 0xFFFFFFFF;

	        switch ((D3DTEXTUREFILTER) dwRenderState) {
		    case D3DFILTER_NEAREST:
		        tex_min = D3DTFN_POINT;
			break;
		    case D3DFILTER_LINEAR:
		        tex_min = D3DTFN_LINEAR;
			break;
		    default:
			ERR("Unhandled texture min %ld !\n",dwRenderState);
	        }

		if (tex_min != 0xFFFFFFFF) {
		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min);
		}
	    } break;

	    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
	    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
	        glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1]),
			    convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1]));
	        break;

	    case D3DRENDERSTATE_TEXTUREMAPBLEND: {  /* 21 */
		IDirect3DDevice7 *d3ddev = ICOM_INTERFACE(This, IDirect3DDevice7);
		
	        switch ((D3DTEXTUREBLEND) dwRenderState) {
		    case D3DTBLEND_DECAL:
		        if (glThis->current_tex_env != GL_REPLACE) {
			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
			    glThis->current_tex_env = GL_REPLACE;
			}
			break;
		    case D3DTBLEND_DECALALPHA:
			if (glThis->current_tex_env != GL_REPLACE) {
			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
			    glThis->current_tex_env = GL_DECAL;
			}
			break;
		    case D3DTBLEND_MODULATE:
			if (glThis->current_tex_env != GL_MODULATE) {
			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			    glThis->current_tex_env = GL_MODULATE;
			}
			break;
		    case D3DTBLEND_MODULATEALPHA:
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
			break;
		    default:
		        ERR("Unhandled texture environment %ld !\n",dwRenderState);
		}
	    } break;

	    case D3DRENDERSTATE_CULLMODE:           /* 22 */
	        switch ((D3DCULL) dwRenderState) {
		    case D3DCULL_NONE:
		         if (glThis->cull_face != 0) {
			     glDisable(GL_CULL_FACE);
			     glThis->cull_face = 0;
			 }
			 break;
		    case D3DCULL_CW:
			 if (glThis->cull_face == 0) {
			     glEnable(GL_CULL_FACE);
			     glThis->cull_face = 1;
			 }
			 glFrontFace(GL_CCW);
			 glCullFace(GL_BACK);
			 break;
		    case D3DCULL_CCW:
			 if (glThis->cull_face == 0) {
			     glEnable(GL_CULL_FACE);
			     glThis->cull_face = 1;
			 }
			 glFrontFace(GL_CW);
			 glCullFace(GL_BACK);
			 break;
		    default:
			 ERR("Unhandled cull mode %ld !\n",dwRenderState);
		}
	        break;

	    case D3DRENDERSTATE_ZFUNC:            /* 23 */
	        glDepthFunc(convert_D3D_compare_to_GL(dwRenderState));
	        break;
	      
	    case D3DRENDERSTATE_ALPHAREF:    /* 24 */
	    case D3DRENDERSTATE_ALPHAFUNC: { /* 25 */
		    GLenum func = convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_ALPHAFUNC - 1]);
		    GLclampf ref = (lpStateBlock->render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0;

		    if ((func != glThis->current_alpha_test_func) || (ref != glThis->current_alpha_test_ref)) {
			glAlphaFunc(func, ref);
			glThis->current_alpha_test_func = func;
			glThis->current_alpha_test_ref = ref;
		    }
	        }
	        break;

	    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
	        if (dwRenderState)
		    glEnable(GL_DITHER);
		else
		    glDisable(GL_DITHER);
	        break;

	    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
	        if ((dwRenderState != 0) && (glThis->blending == 0)) {
		    glEnable(GL_BLEND);
		} else if ((dwRenderState == 0) && (glThis->blending != 0)) {
		    glDisable(GL_BLEND);
		}
	        glThis->blending = dwRenderState;

	        /* Hack for some old games ... */
	        if (glThis->parent.version == 1) {
		    lpStateBlock->render_state[D3DRENDERSTATE_COLORKEYENABLE - 1] = dwRenderState;
		}
	        break;
	      
	    case D3DRENDERSTATE_FOGENABLE: /* 28 */
	        /* Nothing to do here. Only the storage matters :-) */
	        break;

	    case D3DRENDERSTATE_SPECULARENABLE: /* 29 */
	        if (dwRenderState)
		    ERR(" Specular Lighting not supported yet.\n");
	        break;
	      
	    case D3DRENDERSTATE_SUBPIXEL:  /* 31 */
	    case D3DRENDERSTATE_SUBPIXELX: /* 32 */
	        /* We do not support this anyway, so why protest :-) */
	        break; 

 	    case D3DRENDERSTATE_STIPPLEDALPHA: /* 33 */
	        if (dwRenderState)
		    ERR(" Stippled Alpha not supported yet.\n");
		break;

	    case D3DRENDERSTATE_FOGCOLOR: { /* 34 */
	        GLfloat color[4];
		color[0] = ((dwRenderState >> 16) & 0xFF)/255.0f;
		color[1] = ((dwRenderState >>  8) & 0xFF)/255.0f;
		color[2] = ((dwRenderState >>  0) & 0xFF)/255.0f;
		color[3] = ((dwRenderState >> 24) & 0xFF)/255.0f;
		glFogfv(GL_FOG_COLOR,color);
		/* Note: glFogiv does not seem to work */
	    } break;

 	    case D3DRENDERSTATE_FOGTABLEMODE:  /* 35 */
 	    case D3DRENDERSTATE_FOGVERTEXMODE: /* 140 */
 	    case D3DRENDERSTATE_FOGSTART:      /* 36 */
	    case D3DRENDERSTATE_FOGEND:        /* 37 */
	        /* Nothing to do here. Only the storage matters :-) */
		break;

	    case D3DRENDERSTATE_FOGDENSITY:    /* 38 */
		glFogi(GL_FOG_DENSITY,*(float*)&dwRenderState);
		break;

	    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
	        /* Nothing done here, only storage matters. */
	        break;

	    case D3DRENDERSTATE_MIPMAPLODBIAS: /* 46 */
	        IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
						      0, D3DTSS_MIPMAPLODBIAS,
						      dwRenderState);
	        break;
	      
	    case D3DRENDERSTATE_ZBIAS: /* 47 */
	        /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
	        if (dwRenderState == 0) {
		    glDisable(GL_POLYGON_OFFSET_FILL);
		    glDisable(GL_POLYGON_OFFSET_LINE);
		    glDisable(GL_POLYGON_OFFSET_POINT);
		} else {
		    glEnable(GL_POLYGON_OFFSET_FILL);
		    glEnable(GL_POLYGON_OFFSET_LINE);
		    glEnable(GL_POLYGON_OFFSET_POINT);
		    glPolygonOffset(1.0, dwRenderState * 1.0);
		}
	        break;
	      
	    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
	        break;

	    case D3DRENDERSTATE_STENCILENABLE:    /* 52 */
	        if ((dwRenderState != 0) && (glThis->stencil_test == 0))
		    glEnable(GL_STENCIL_TEST);
		else if ((dwRenderState == 0) && (glThis->stencil_test != 0))
		    glDisable(GL_STENCIL_TEST);
	        glThis->stencil_test = dwRenderState;
		break;
	    
	    case D3DRENDERSTATE_STENCILFAIL:      /* 53 */
	    case D3DRENDERSTATE_STENCILZFAIL:     /* 54 */
	    case D3DRENDERSTATE_STENCILPASS:      /* 55 */
		glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFAIL - 1]),
			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILZFAIL - 1]),
			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILPASS - 1]));
		break;

	    case D3DRENDERSTATE_STENCILFUNC:      /* 56 */
	    case D3DRENDERSTATE_STENCILREF:       /* 57 */
	    case D3DRENDERSTATE_STENCILMASK:      /* 58 */
		glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFUNC - 1]),
			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILREF - 1],
			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILMASK - 1]);
		break;
	  
	    case D3DRENDERSTATE_STENCILWRITEMASK: /* 59 */
	        glStencilMask(dwRenderState);
	        break;

	    case D3DRENDERSTATE_TEXTUREFACTOR:      /* 60 */
	        /* Only the storage matters... */
	        break;

	    case D3DRENDERSTATE_CLIPPING:          /* 136 */
	    case D3DRENDERSTATE_CLIPPLANEENABLE: { /* 152 */
		    GLint i;
		    DWORD mask, runner;
		    
		    if (dwRenderStateType == D3DRENDERSTATE_CLIPPING) {
			mask = ((dwRenderState) ?
				(This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) : (0x00000000));
		    } else {
			mask = dwRenderState;
		    }
		    for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner = (runner << 1)) {
			if (mask & runner) {
			    GLint enabled;
			    glGetIntegerv(GL_CLIP_PLANE0 + i, &enabled);
			    if (enabled == GL_FALSE) {
			        glEnable(GL_CLIP_PLANE0 + i);
				/* Need to force a transform change so that this clipping plane parameters are sent
				 * properly to GL.
				 */
				glThis->transform_state = GL_TRANSFORM_NONE;
			    }
			} else {
			    glDisable(GL_CLIP_PLANE0 + i);
			}
		    }
		}
	        break;

	    case D3DRENDERSTATE_LIGHTING:    /* 137 */
	        /* Nothing to do, only storage matters... */
	        break;
		
	    case D3DRENDERSTATE_AMBIENT: {            /* 139 */
	        float light[4];

		light[0] = ((dwRenderState >> 16) & 0xFF) / 255.0;
		light[1] = ((dwRenderState >>  8) & 0xFF) / 255.0;
		light[2] = ((dwRenderState >>  0) & 0xFF) / 255.0;
		light[3] = ((dwRenderState >> 24) & 0xFF) / 255.0;
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
	    } break;

	    case D3DRENDERSTATE_COLORVERTEX:          /* 141 */
	          /* Nothing to do here.. Only storage matters */
	          break;
		  
	    case D3DRENDERSTATE_LOCALVIEWER:          /* 142 */
	        if (dwRenderState)
		    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
		else
		    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
		break;

	    case D3DRENDERSTATE_NORMALIZENORMALS:     /* 143 */
	        if (dwRenderState) {
		    glEnable(GL_NORMALIZE);
		    glEnable(GL_RESCALE_NORMAL);
		} else {
		    glDisable(GL_NORMALIZE);
		    glDisable(GL_RESCALE_NORMAL);
		}
		break;

	    case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE:    /* 145 */
	    case D3DRENDERSTATE_SPECULARMATERIALSOURCE:   /* 146 */
	    case D3DRENDERSTATE_AMBIENTMATERIALSOURCE:    /* 147 */
	    case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE:   /* 148 */
	        /* Nothing to do here. Only the storage matters :-) */
		break;

	    default:
	        ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n",
		    _get_renderstate(dwRenderStateType), dwRenderStateType, dwRenderState);
	}
	LEAVE_GL();
    }
}

void store_render_state(IDirect3DDeviceImpl *This,
			D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK *lpStateBlock)
{
    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
    
    /* Some special cases first.. */
    if (dwRenderStateType == D3DRENDERSTATE_SRCBLEND) {
        if (dwRenderState == D3DBLEND_BOTHSRCALPHA) {
	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_SRCALPHA;
	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_INVSRCALPHA;
	    return;
	} else if (dwRenderState == D3DBLEND_BOTHINVSRCALPHA) {
	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_INVSRCALPHA;
	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_SRCALPHA;
	    return;
	}
    } else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) {
        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSU - 1] = dwRenderState;
        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSV - 1] = dwRenderState;
    } else if (dwRenderStateType == D3DRENDERSTATE_WRAPU) {
        if (dwRenderState) 
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_U;
	else
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U;
    } else if (dwRenderStateType == D3DRENDERSTATE_WRAPV) {
        if (dwRenderState) 
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_V;
	else
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V;
    }
    
    /* Default case */
    lpStateBlock->render_state[dwRenderStateType - 1] = dwRenderState;
}

void get_render_state(IDirect3DDeviceImpl *This,
		      D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK *lpStateBlock)
{
    *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
    if (TRACE_ON(ddraw))
        TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
}

void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock)
{
    DWORD i;
    TRACE("(%p,%p)\n", This, lpStateBlock);
    for(i = 0; i < HIGHEST_RENDER_STATE; i++)
	if (lpStateBlock->set_flags.render_state[i])
            set_render_state(This, i + 1, lpStateBlock);
}


/* Texture management code.

    - upload_surface_to_tex_memory_init initialize the code and computes the GL formats 
      according to the surface description.

    - upload_surface_to_tex_memory does the real upload. If one buffer is split over
      multiple textures, this can be called multiple times after the '_init' call. 'rect'
      can be NULL if the whole buffer needs to be upload.

    - upload_surface_to_tex_memory_release does the clean-up.

   These functions are called in the following cases :
    - texture management (ie to upload a D3D texture to GL when it changes).
    - flush of the 'in-memory' frame buffer to the GL frame buffer using the texture
      engine.
    - use of the texture engine to simulate Blits to the 3D Device.
*/
typedef enum {
    NO_CONVERSION,
    CONVERT_PALETTED,
    CONVERT_CK_565,
    CONVERT_CK_5551,
    CONVERT_CK_4444,
    CONVERT_CK_4444_ARGB,
    CONVERT_CK_1555,
    CONVERT_555,
    CONVERT_CK_RGB24,
    CONVERT_CK_8888,
    CONVERT_CK_8888_ARGB,
    CONVERT_RGB32_888
} CONVERT_TYPES;

/* Note : we suppose that all the code calling this is protected by the GL lock... Otherwise bad things
   may happen :-) */
static GLenum current_format;
static GLenum current_pixel_format;
static CONVERT_TYPES convert_type;
static IDirectDrawSurfaceImpl *current_surface;
static GLuint current_level;
static DWORD current_tex_width;
static DWORD current_tex_height;
static GLuint current_alignement_constraints;
static int current_storage_width;

HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLuint level, GLenum *current_internal_format,
					  BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck, DWORD tex_width, DWORD tex_height)
{
    const DDPIXELFORMAT * const src_pf = &(surf_ptr->surface_desc.u4.ddpfPixelFormat);
    BOOL error = FALSE;
    BOOL colorkey_active = need_alpha_ck && (surf_ptr->surface_desc.dwFlags & DDSD_CKSRCBLT);
    GLenum internal_format = GL_LUMINANCE; /* A bogus value to be sure to have a nice Mesa warning :-) */
    BYTE bpp = GET_BPP(surf_ptr->surface_desc);
    BOOL sub_texture = TRUE;

    current_surface = surf_ptr;
    current_level = level;

    if (src_pf->dwFlags & DDPF_FOURCC) {
	GLenum retVal;
	int size = surf_ptr->surface_desc.u1.dwLinearSize;
	int width = surf_ptr->surface_desc.dwWidth;
	int height = surf_ptr->surface_desc.dwHeight;
	LPVOID buffer = surf_ptr->surface_desc.lpSurface;

	switch (src_pf->dwFourCC) {
	    case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
	    case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
	    case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
	    default:
		FIXME("FourCC Not supported\n");
		return DD_OK;
	}

	if (GL_extensions.s3tc_compressed_texture) {
	    GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width, height, 0, size, buffer);
	} else
	    ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");

	return DD_OK;
    }

    /* First, do some sanity checks ... */
    if ((surf_ptr->surface_desc.u1.lPitch % bpp) != 0) {
	FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n");
    } else {
	/* In that case, no need to have any alignement constraints... */
	if (current_alignement_constraints != 1) {
	    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	    current_alignement_constraints = 1;
	}
    }

    /* Note: we only check width here as you cannot have width non-zero while height is set to zero */
    if (tex_width == 0) {
	sub_texture = FALSE;
	
	tex_width = surf_ptr->surface_desc.dwWidth;
	tex_height = surf_ptr->surface_desc.dwHeight;
    }

    current_tex_width = tex_width;
    current_tex_height = tex_height;

    if (src_pf->dwFlags & DDPF_PALETTEINDEXED8) {
	/* ****************
	   Paletted Texture
	   **************** */
	current_format = GL_RGBA;
	internal_format = GL_RGBA;
	current_pixel_format = GL_UNSIGNED_BYTE;
	convert_type = CONVERT_PALETTED;
    } else if (src_pf->dwFlags & DDPF_RGB) {
	/* ************
	   RGB Textures
	   ************ */
	if (src_pf->u1.dwRGBBitCount == 8) {
	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x00)) {
		error = TRUE;
	    } else {
		if ((src_pf->u2.dwRBitMask == 0xE0) &&
		    (src_pf->u3.dwGBitMask == 0x1C) &&
		    (src_pf->u4.dwBBitMask == 0x03)) {
		    /* **********************
		       GL_UNSIGNED_BYTE_3_3_2
		       ********************** */
		    if (colorkey_active) {
			/* This texture format will never be used.. So do not care about color keying
			   up until the point in time it will be needed :-) */
			FIXME(" ColorKeying not supported in the RGB 332 format !\n");
		    }
		    current_format = GL_RGB;
		    internal_format = GL_RGB;
		    current_pixel_format = GL_UNSIGNED_BYTE_3_3_2;
		    convert_type = NO_CONVERSION;
		} else {
		    error = TRUE;
		}
	    }
	} else if (src_pf->u1.dwRGBBitCount == 16) {
	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x0000)) {
		if ((src_pf->u2.dwRBitMask ==        0xF800) &&
		    (src_pf->u3.dwGBitMask ==        0x07C0) &&
		    (src_pf->u4.dwBBitMask ==        0x003E) &&
		    (src_pf->u5.dwRGBAlphaBitMask == 0x0001)) {
		    current_format = GL_RGBA;
		    internal_format = GL_RGBA;
		    current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
		    if (colorkey_active) {
			convert_type = CONVERT_CK_5551;
		    } else {
			convert_type = NO_CONVERSION;
		    }
		} else if ((src_pf->u2.dwRBitMask ==        0xF000) &&
			   (src_pf->u3.dwGBitMask ==        0x0F00) &&
			   (src_pf->u4.dwBBitMask ==        0x00F0) &&
			   (src_pf->u5.dwRGBAlphaBitMask == 0x000F)) {
		    current_format = GL_RGBA;
		    internal_format = GL_RGBA;
		    current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
		    if (colorkey_active) {
			convert_type = CONVERT_CK_4444;
		    } else {
			convert_type = NO_CONVERSION;
		    }
		} else if ((src_pf->u2.dwRBitMask ==        0x0F00) &&
			   (src_pf->u3.dwGBitMask ==        0x00F0) &&
			   (src_pf->u4.dwBBitMask ==        0x000F) &&
			   (src_pf->u5.dwRGBAlphaBitMask == 0xF000)) {
		    if (colorkey_active) {
			convert_type = CONVERT_CK_4444_ARGB;
			current_format = GL_RGBA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
		    } else {
			convert_type = NO_CONVERSION;
			current_format = GL_BGRA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV;
		    }
		} else if ((src_pf->u2.dwRBitMask ==        0x7C00) &&
			   (src_pf->u3.dwGBitMask ==        0x03E0) &&
			   (src_pf->u4.dwBBitMask ==        0x001F) &&
			   (src_pf->u5.dwRGBAlphaBitMask == 0x8000)) {
		    if (colorkey_active) {
			convert_type = CONVERT_CK_1555;
			current_format = GL_RGBA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
		    } else {
			convert_type = NO_CONVERSION;
			current_format = GL_BGRA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV;
		    }
		} else {
		    error = TRUE;
		}
	    } else {
		if ((src_pf->u2.dwRBitMask == 0xF800) &&
		    (src_pf->u3.dwGBitMask == 0x07E0) &&
		    (src_pf->u4.dwBBitMask == 0x001F)) {
		    if (colorkey_active) {
			convert_type = CONVERT_CK_565;
			current_format = GL_RGBA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
		    } else {
			convert_type = NO_CONVERSION;
			current_format = GL_RGB;
			internal_format = GL_RGB;
			current_pixel_format = GL_UNSIGNED_SHORT_5_6_5;
		    }
		} else if ((src_pf->u2.dwRBitMask == 0x7C00) &&
			   (src_pf->u3.dwGBitMask == 0x03E0) &&
			   (src_pf->u4.dwBBitMask == 0x001F)) {
		    convert_type = CONVERT_555;
		    current_format = GL_RGBA;
		    internal_format = GL_RGBA;
		    current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
		} else {
		    error = TRUE;
		}
	    }
	} else if (src_pf->u1.dwRGBBitCount == 24) {
	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x000000)) {
		error = TRUE;
	    } else {
		if ((src_pf->u2.dwRBitMask == 0xFF0000) &&
		    (src_pf->u3.dwGBitMask == 0x00FF00) &&
		    (src_pf->u4.dwBBitMask == 0x0000FF)) {
		    if (colorkey_active) {
			convert_type = CONVERT_CK_RGB24;
			current_format = GL_RGBA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
		    } else {
			convert_type = NO_CONVERSION;
			current_format = GL_BGR;
			internal_format = GL_RGB;
			current_pixel_format = GL_UNSIGNED_BYTE;
		    }
		} else {
		    error = TRUE;
		}
	    }
	} else if (src_pf->u1.dwRGBBitCount == 32) {
	    if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x00000000)) {
		if ((src_pf->u2.dwRBitMask ==        0xFF000000) &&
		    (src_pf->u3.dwGBitMask ==        0x00FF0000) &&
		    (src_pf->u4.dwBBitMask ==        0x0000FF00) &&
		    (src_pf->u5.dwRGBAlphaBitMask == 0x000000FF)) {
		    if (colorkey_active) {
			convert_type = CONVERT_CK_8888;
		    } else {
			convert_type = NO_CONVERSION;
		    }
		    current_format = GL_RGBA;
		    internal_format = GL_RGBA;
		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
		} else if ((src_pf->u2.dwRBitMask ==        0x00FF0000) &&
			   (src_pf->u3.dwGBitMask ==        0x0000FF00) &&
			   (src_pf->u4.dwBBitMask ==        0x000000FF) &&
			   (src_pf->u5.dwRGBAlphaBitMask == 0xFF000000)) {
		    if (colorkey_active) {
			convert_type = CONVERT_CK_8888_ARGB;
			current_format = GL_RGBA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
		    } else {
			convert_type = NO_CONVERSION;
			current_format = GL_BGRA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
		    }
		} else {
		    error = TRUE;
		}
	    } else {
		if ((src_pf->u2.dwRBitMask == 0x00FF0000) &&
		    (src_pf->u3.dwGBitMask == 0x0000FF00) &&
		    (src_pf->u4.dwBBitMask == 0x000000FF)) {
		    if (need_alpha_ck) {
			convert_type = CONVERT_RGB32_888;
			current_format = GL_RGBA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
		    } else {
			convert_type = NO_CONVERSION;
			current_format = GL_BGRA;
			internal_format = GL_RGBA;
			current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
		    }
		} else {
		    error = TRUE;
		}
	    }
	} else {
	    error = TRUE;
	}
    } else {
	error = TRUE;
    } 

    if (error) {
	ERR("Unsupported pixel format for textures : \n");
	if (ERR_ON(ddraw)) {
	    DDRAW_dump_pixelformat(src_pf);
	}
	return DDERR_INVALIDPIXELFORMAT;
    } else {
	if ((need_to_alloc) ||
	    (internal_format != *current_internal_format)) {
	    glTexImage2D(GL_TEXTURE_2D, level, internal_format,
			 tex_width, tex_height, 0,
			 current_format, current_pixel_format, NULL);
	    *current_internal_format = internal_format;
	}
    }

    if (sub_texture && (convert_type == NO_CONVERSION)) {
	current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp;
    } else {
	if (surf_ptr->surface_desc.u1.lPitch == (surf_ptr->surface_desc.dwWidth * bpp)) {
	    current_storage_width = 0;
	} else {
	    current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp;
	}	
    }
    glPixelStorei(GL_UNPACK_ROW_LENGTH, current_storage_width);

    TRACE(" initialized texture upload for level %d with conversion %d.\n", current_level, convert_type);
    
    return DD_OK;
}

HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, void **temp_buffer)
{
    const DDSURFACEDESC * const src_d = (DDSURFACEDESC *)&(current_surface->surface_desc);
    void *surf_buffer = NULL;
    RECT lrect;
    DWORD width, height;
    BYTE bpp = GET_BPP(current_surface->surface_desc);
    int line_increase;
    
    if (rect == NULL) {
	lrect.top = 0;
	lrect.left = 0;
	lrect.bottom = current_tex_height;
	lrect.right = current_tex_width;
	rect = &lrect;
    }

    width = rect->right - rect->left;
    height = rect->bottom - rect->top;

    if (current_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
	GLint retVal;
	int size = current_surface->surface_desc.u1.dwLinearSize;
	int width_ = current_surface->surface_desc.dwWidth;
	int height_ = current_surface->surface_desc.dwHeight;
	LPVOID buffer = current_surface->surface_desc.lpSurface;

	switch (current_surface->surface_desc.u4.ddpfPixelFormat.dwFourCC) {
	    case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
	    case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
	    case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
	    default:
		FIXME("Not supported\n");
		return DD_OK;
	}

	if (GL_extensions.s3tc_compressed_texture) {
	    /* GL_extensions.glCompressedTexSubImage2D(GL_TEXTURE_2D, current_level, xoffset, yoffset, width, height, retVal, (unsigned char*)temp_buffer); */
	    GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width_, height_, 0, size, buffer);
	} else
	    ERR("Trying to upload S3TC texture whereas the device does not have support for it\n");

	return DD_OK;
    }
    
    /* Used when converting stuff */
    line_increase = src_d->u1.lPitch - (width * bpp);

    switch (convert_type) {
        case CONVERT_PALETTED: {
	    IDirectDrawPaletteImpl* pal = current_surface->palette;
	    BYTE table[256][4];
	    unsigned int i;
	    unsigned int x, y;
	    BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (pal == NULL) {
		/* Upload a black texture. The real one will be uploaded on palette change */
		WARN("Palettized texture Loading with a NULL palette !\n");
		memset(table, 0, 256 * 4);
	    } else {
		/* Get the surface's palette */
		for (i = 0; i < 256; i++) {
		    table[i][0] = pal->palents[i].peRed;
		    table[i][1] = pal->palents[i].peGreen;
		    table[i][2] = pal->palents[i].peBlue;
		    if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
			(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
			(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			/* We should maybe here put a more 'neutral' color than the standard bright purple
			   one often used by application to prevent the nice purple borders when bi-linear
			   filtering is on */
			table[i][3] = 0x00;
		    else
			table[i][3] = 0xFF;
		}
	    }
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
					 current_tex_width * current_tex_height * sizeof(DWORD));
	    dst = (BYTE *) *temp_buffer;

	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    BYTE color = *src++;
		    *dst++ = table[color][0];
		    *dst++ = table[color][1];
		    *dst++ = table[color][2];
		    *dst++ = table[color][3];
		}
		src += line_increase;
	    }
	} break;

        case CONVERT_CK_565: {
	    /* Converting the 565 format in 5551 packed to emulate color-keying.
	       
	       Note : in all these conversion, it would be best to average the averaging
	              pixels to get the color of the pixel that will be color-keyed to
		      prevent 'color bleeding'. This will be done later on if ever it is
		      too visible.
		      
	       Note2: when using color-keying + alpha, are the alpha bits part of the
	              color-space or not ?
	    */
	    unsigned int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= 0x0001;
		    dst++;
		}
		src = (WORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_CK_5551: {
	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
	    unsigned int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = color & 0xFFFE;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= color & 0x0001;
		    dst++;
		}
		src = (WORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_CK_4444: {
	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
	    unsigned int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = color & 0xFFF0;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= color & 0x000F;
		    dst++;
		}
		src = (WORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_CK_4444_ARGB: {
	    /* Move the four Alpha bits... */
	    unsigned int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = (color & 0x0FFF) << 4;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= (color & 0xF000) >> 12;
		    dst++;
		}
		src = (WORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_CK_1555: {
	    unsigned int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = (color & 0x7FFF) << 1;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= (color & 0x8000) >> 15;
		    dst++;
		}
		src = (WORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_555: {
	    /* Converting the 0555 format in 5551 packed */
	    unsigned int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			WORD color = *src++;
			*dst = (color & 0x7FFF) << 1;
			if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			    *dst |= 0x0001;
			dst++;
		    }
		    src = (WORD *) (((BYTE *) src) + line_increase);
		}
	    } else {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			WORD color = *src++;
			*dst++ = ((color & 0x7FFF) << 1) | 0x0001;
		    }
		    src = (WORD *) (((BYTE *) src) + line_increase);
		}
	    }
	    
	} break;
	
        case CONVERT_CK_RGB24: {
	    /* This is a pain :-) */
	    unsigned int x, y;
	    BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
	    DWORD *dst;

	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));
	    dst = (DWORD *) *temp_buffer;

	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    DWORD color = *((DWORD *) src) & 0x00FFFFFF;
		    src += 3;
		    *dst = color << 8;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= 0xFF;
		    dst++;
		}
		src += line_increase;
	    }
	} break;

        case CONVERT_CK_8888: {
	    /* Just use the alpha component to handle color-keying... */
	    unsigned int x, y;
	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));	    
	    dst = (DWORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    DWORD color = *src++;
		    *dst = color & 0xFFFFFF00;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= color & 0x000000FF;
		    dst++;
		}
		src = (DWORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_CK_8888_ARGB: {
	    unsigned int x, y;
	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));	    
	    dst = (DWORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    DWORD color = *src++;
		    *dst = (color & 0x00FFFFFF) << 8;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= (color & 0xFF000000) >> 24;
		    dst++;
		}
		src = (DWORD *) (((BYTE *) src) + line_increase);
	    }
	} break;
	
        case CONVERT_RGB32_888: {
	    /* Just add an alpha component and handle color-keying... */
	    unsigned int x, y;
	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));	    
	    dst = (DWORD *) *temp_buffer;
	    
	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			DWORD color = *src++;
			*dst = color << 8;
			if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			    *dst |= 0xFF;
			dst++;
		    }
		    src = (DWORD *) (((BYTE *) src) + line_increase);
		}
	    } else {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			*dst++ = (*src++ << 8) | 0xFF;
		    }
		    src = (DWORD *) (((BYTE *) src) + line_increase);
		}
	    }
	} break;

        case NO_CONVERSION:
	    /* Nothing to do here as the name suggests... Just set-up the buffer correctly */
	    surf_buffer = (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
	    break;
    }

    if (convert_type != NO_CONVERSION) {
	/* When doing conversion, the storage is always of width 'width' as there will never
	   be any Pitch issue... For now :-)
	*/
	surf_buffer = *temp_buffer;
	if (width != current_storage_width) {
	    glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
	    current_storage_width = width;
	}
    }
    
    glTexSubImage2D(GL_TEXTURE_2D,
		    current_level,
		    xoffset, yoffset,
		    width, height,
		    current_format,
		    current_pixel_format,
		    surf_buffer);

    return DD_OK;
}

HRESULT upload_surface_to_tex_memory_release(void)
{
    current_surface = NULL;

    return DD_OK;
}
