/* 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 "mesa_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->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;
		break;
	}

	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;
		break;
	}

	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;
}
