//Ces routines proviennent de WinGraph.h (par moi)
int LARG_BUF=1280, HAUT_BUF=1024;
int LARG=1280, HAUT=1024;
int CLIP_X0=0, CLIP_Y0=0, CLIP_X1=LARG, CLIP_Y1=HAUT;
#define ASSERT(condition)	if (!(condition))	  MessageBox(GetFocus(),"Une erreur s'est produite car la condition suivante est fausse: "#condition,"Erreur interne",MB_ICONERROR);
unsigned char *Bits2=NULL;
unsigned char *Bits3=NULL;
unsigned char *Bits4=NULL;
BITMAPINFOHEADER BIH;

typedef unsigned char * SPRITE;

//Clippe un sprite
#define ClipSprite			{										\
							if (!Bits || !sprite)	return;						\
							if (y0<0)	{							\
								sprite+=l*(0-y0)*3;					\
								h-=0-y0;							\
								y0=0;								\
							}										\
							if (x0<0)	{							\
								l+=0+x0;							\
								a=-x0;								\
								sprite+=-x0*3;						\
								x0=0;								\
							}										\
							y0+=CLIP_Y0;							\
							x0+=CLIP_X0;							\
							if (y0+h>=CLIP_Y1)	{					\
								h+=CLIP_Y1-(y0+h);					\
							}										\
							if (x0+l>=CLIP_X1)	{					\
								a=-(CLIP_X1-(x0+l));				\
								l-=a;								\
							}										\
							a*=3;									\
							if (h<0)	return;						\
							}

//Clippe un sprite 8 bits
#define ClipSprite8			{										\
							if (!Bits || !sprite)	return;			\
							if (y0<0)	{							\
								sprite+=l*(0-y0);					\
								h-=0-y0;							\
								y0=0;								\
							}										\
							if (x0<0)	{							\
								l+=0+x0;							\
								a=-x0;								\
								sprite+=-x0;						\
								x0=0;								\
							}										\
							y0+=CLIP_Y0;							\
							x0+=CLIP_X0;							\
							if (y0+h>=CLIP_Y1)	{					\
								h+=CLIP_Y1-(y0+h);					\
							}										\
							if (x0+l>=CLIP_X1)	{					\
								a=-(CLIP_X1-(x0+l));				\
								l-=a;								\
							}										\
							if (h<0)	return;						\
							}

//Clippe un rectangle (sans blague!)
#define ClipRect			{										\
							if (!Bits)	return;						\
							if (y0<0)	{							\
								h-=0-y0;							\
								y0=0;								\
							}										\
							if (x0<0)	{							\
								l+=0+x0;							\
								x0=0;								\
							}										\
							y0+=CLIP_Y0;							\
							x0+=CLIP_X0;							\
							if (y0+h>=CLIP_Y1)	{					\
								h+=CLIP_Y1-(y0+h);					\
							}										\
							if (x0+l>=CLIP_X1)	{					\
								l+=CLIP_X1-(x0+l);					\
							}										\
							if (h<0)	return;						\
							}


//Crée une DIB de taille "cx" et "cy" pour pouvoir y dessiner en l'utilisant comme un
//bloc de mémoire de "ibitcount" bits par pixel. La sélectionne dans "hdc" et la stocke
//dans "hbm". Le pointeur sur les bits de cette bitmap sera écrit dans "bits".
int CreeDIB(HDC hdc, int cx, int cy, int ibitcount, HBITMAP *hbm, void **bits) 
{
   // Create a BITMAPINFOHEADER structure to describe the DIB.
   int iSize = sizeof(BITMAPINFOHEADER);

   ASSERT((ibitcount == 8) || (ibitcount == 16) || (ibitcount == 24) || (ibitcount == 32)) ;
   ASSERT(cx > 0);
   ASSERT(cy > 0);
   memset(&BIH, 0, iSize);

   // Fill in the header info. 
   BIH.biSize = iSize;
   BIH.biWidth = cx;
   BIH.biHeight = cy;
   BIH.biPlanes = 1;
   BIH.biBitCount = ibitcount;
   BIH.biCompression = BI_RGB;

   // Create a new device context.

   // Create the DIB section.
   *hbm = CreateDIBSection(hdc,
               (BITMAPINFO*) &BIH,
                             DIB_PAL_COLORS,
                             (void**)bits,
                             NULL,
                             0);

/*    ASSERT(*hbm);
    ASSERT(*bits);*/

    // Select the new bitmap into the buffer DC.
    if (*hbm && *bits)
    {
        SelectObject(hdc,*hbm);
		return 1;
    }
	else	{
		return 0;
	}
}


void ZoneEcran(int x0,int y0,int x1,int y1)		{
	CLIP_X0=x0, CLIP_Y0=y0, CLIP_X1=x1, CLIP_Y1=y1;
}

void ColoreCadre(register unsigned char *Bits, int x0, int y0, int l, int h, int couleur);

void GetRealXY(int *xdst, int *ydst)			{
	int x,y;
	x=*xdst, y=*ydst;
	//ATTENTION: /3 car 24 bits!
	if (DIMENSION_MAX!=0 && (unsigned)(x*y)>=DIMENSION_MAX/3)			{
		bRedimDIBOverflow = x*y*3;
		double dRapport;
		dRapport = x/y;
		x = (int)(sqrt((float)(DIMENSION_MAX/3))*sqrt(dRapport));
		y = (int)(sqrt((float)(DIMENSION_MAX/3))/sqrt(dRapport));
	}
	*xdst=x, *ydst=y;
}

void RedimDIB(int x,int y, int useMaxSize)		{
	int ancX=LARG, ancY=HAUT;
	HBITMAP hbm3=hbm2;
	unsigned char *BitsTemp;

	bRedimDIBOverflow = FALSE;
	if (!useMaxSize)
		GetRealXY(&x, &y);
//	if (x>DIMENSION_MAX)		x=DIMENSION_MAX;
//	if (y>DIMENSION_MAX)		y=DIMENSION_MAX;

	if (LARG==x && HAUT==y)
		return;
	LARG=x;
	HAUT=y;
	if (LARG%4==0)
		LARG_BUF=LARG;
	else
		LARG_BUF=LARG+(4-LARG%4);
	HAUT_BUF=HAUT;
	//Crée une bitmap utilisable par mon système graphique (graphlib)
	if (CreeDIB(hdcImage2,LARG_BUF,HAUT_BUF,24,&hbm2,(void**)&BitsTemp))		{
//		HAUT_BUF+=1;
		//Ouvre une "fenêtre" graphique (pas Window!) pour y dessiner
		ZoneEcran(0,0,LARG,HAUT);
		DeleteObject(hbm3);
		Bits2=BitsTemp;
	}
	else	{
		if (ancX<x || ancY<y)
			bRedimDIBOverflow = x*y*3;
		LARG=ancX;
		HAUT=ancY;
		if (LARG%4==0)
			LARG_BUF=LARG;
		else
			LARG_BUF=LARG+(4-LARG%4);
		HAUT_BUF=HAUT;
		hbm2=hbm3;
	}
	ColoreCadre(Bits2,0,0,LARG,HAUT,cFond);
}

//Colle une image (très vieille fonction écrite par moi à l'époque ou je supportais encore
//l'anglais :|
int PasteImage(const char *fichier, int *dx, int *dy, int donotdelete)	{
	char tempname[MAX_PATH];
	strcpy(tempname, fichier);
	_strlwr(tempname);
	if (!bGdiPlusEnabled || !strcmp(tempname+strlen(tempname)-4, ".bmp"))			{
		//Sans GDI+
		hbmConv = (HBITMAP) LoadImage(NULL, fichier, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
		if (!hbmConv)	{
			return 0;
		}
		GetObject(hbmConv, sizeof(bmConv), &bmConv);
		*dx=bmConv.bmWidth;
		*dy=bmConv.bmHeight;

		hdcConv = CreateCompatibleDC(hdcImage2);
		
		SelectObject(hdcConv, hbmConv);
		RedimDIB(*dx,*dy,TRUE);
	}
	else		{
		//Avec GDI+
		hdcConv = CreateCompatibleDC(hdcImage2);
		if (!GDIPLUS_DrawImage(fichier, dx, dy))		{
			DeleteDC(hdcConv);
			return 0;
		}
	}

	if (!donotdelete || (modeConversion==0 || bTil32Bits))		{
		StretchBlt(hdcImage2, 0, 0, *dx, *dy, hdcConv, 0, 0, *dx, *dy, SRCCOPY);
		DeleteDC(hdcConv);
		DeleteObject(hbmConv);
	}
	return 1;
}


//Dessine un pixel.
__inline void DessPix(register unsigned char *Bits, register int x,register int y,register int c)		{
	register unsigned char *ptr;
	x+=CLIP_X0;
	y+=CLIP_Y0;
	if (x<0 || y<0 || x>=CLIP_X1 || y>=CLIP_Y1)
		return;
	ptr=Bits+LARG_BUF*3*(HAUT_BUF-y)-3*(LARG_BUF-x);
	if ((c&0x0000ff)==0xfe)
		return;
	*(ptr++)=(unsigned char)((c&0x00ff0000)>>16);
	*(ptr++)=(unsigned char)((c&0x0000ff00)>>8);
	*(ptr++)=(unsigned char)(c&0x000000ff);
}

//Lit un pixel et stocke les valeurs r,v,b de celui-ci dans les paramètre correspondants.
__inline void LitPixRVB(register unsigned char *Bits, register int x,register int y, register unsigned char *r, register unsigned char *v, register unsigned char *b)		{
	register unsigned char *ptr;
	x+=CLIP_X0;
	y+=CLIP_Y0;
	if (x<0 || y<0 || x>=CLIP_X1 || y>=CLIP_Y1)
		return;
	ptr=Bits+LARG_BUF*3*(HAUT_BUF-y)-3*(LARG_BUF-x);
	*b=*(ptr++);
	*v=*(ptr++);
	*r=*(ptr++);
}


//Colore un cadre sans transparence
void ColoreCadre(register unsigned char *Bits, int x0, int y0, int l, int h, int couleur)	{
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr;
	register int x, y;
	register unsigned char rouge=couleur&0x000000ff, vert=(couleur&0x0000ff00)>>8, bleu=(couleur&0x00ff0000)>>16;

	ClipRect;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			*(ptr++)=bleu;
			*(ptr++)=vert;
			*(ptr++)=rouge;
		}
	}
}

//Crée une couleur RVB en évitant les dépassements
__inline int RVB(register int r, register int v, register int b)		{
	if (r<0)		r=0;
	if (r>255)		r=255;
	if (v<0)		v=0;
	if (v>255)		v=255;
	if (b<0)		b=0;
	if (b>255)		b=255;
	return RGB(r,v,b);
}

void SpritePalSansMasque_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			pal=(unsigned char*)sprite;
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
			sprite++;
		}
		sprite+=a;
	}

}

void SpritePalSansMasque(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		SpritePalSansMasque_32(Bits, x0, y0, l, h, sprite, palette);
		return;
	}
	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			pal=palette+3*(*sprite++);
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
		}
		sprite+=a;
	}
}


void SpritePalMiroirSansMasque_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=(unsigned char*)sprite;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				sprite++;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=(unsigned char*)sprite;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				sprite++;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=(unsigned char*)sprite;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				sprite++;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=(unsigned char*)sprite;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				sprite++;
			}
			sprite+=a;
		}
	}
}

void SpritePalMiroirSansMasque(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		SpritePalMiroirSansMasque_32(Bits, x0, y0, l, h, sprite, palette, MH, MV, couleurs);
		return;
	}
	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=palette+3*((*sprite++)&couleurs);
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=palette+3*((*sprite++)&couleurs);
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=palette+3*((*sprite++)&couleurs);
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=palette+3*((*sprite++)&couleurs);
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
}


void TransSpritePalMiroirSansMasque_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal, nv=255-niveau;

	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=(unsigned char*)sprite;
				sprite++;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=(unsigned char*)sprite;
				sprite++;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=(unsigned char*)sprite;
				sprite++;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=(unsigned char*)sprite;
				sprite++;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
}

void TransSpritePalMiroirSansMasque(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal, nv=255-niveau;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		TransSpritePalMiroirSansMasque_32(Bits, x0, y0, l, h, sprite, palette, MH, MV, couleurs, niveau);
		return;
	}
	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=palette+3*((*sprite++)&couleurs);
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=palette+3*((*sprite++)&couleurs);
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				pal=palette+3*((*sprite++)&couleurs);
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				pal=palette+3*((*sprite++)&couleurs);
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
}


void SpritePalMiroir_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
}


void SpritePalMiroir(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		SpritePalMiroir_32(Bits, x0, y0, l, h, sprite, palette, MH, MV, couleurs);
		return;
	}
	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
				*ptr=*pal++;
				ptr++;
			}
			sprite+=a;
		}
	}
}



void TransSpritePalMiroir_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal, nv=255-niveau;

	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (!(*sprite&0xff000000))		{
					pal=(unsigned char*)sprite;
					sprite++;
				}
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}

}


void TransSpritePalMiroir(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, int MH, int MV, int couleurs, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal, nv=255-niveau;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		TransSpritePalMiroir_32(Bits, x0, y0, l, h, sprite, palette, MH, MV, couleurs, niveau);
		return;
	}
	ClipSprite8;

	if (!MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && !MV)		{
		for (y=y0;y<y0+h;y++)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (!MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			for (x=0;x<l;x++)	{
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}
	else if (MH && MV)		{
		for (y=y0+h-1;y>=y0;y--)	{
			ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
			ptr+=3*l+3;
			for (x=0;x<l;x++)	{
				ptr-=6;
				if (*sprite)
					pal=palette+3*((*sprite++)&couleurs);
				else	{
					sprite++;
					ptr+=3;
					continue;
				}
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
				*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			}
			sprite+=a;
		}
	}

}


void SpritePal_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			if (!(*sprite&0xff000000))		{
				pal=(unsigned char*)sprite;
				sprite++;
			}
			else	{
				sprite++;
				ptr+=3;
				continue;
			}
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
		}
		sprite+=a;
	}

}


void SpritePal(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, *pal;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		SpritePal_32(Bits, x0, y0, l, h, sprite, palette);
		return;
	}
	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			if (*sprite)
				pal=palette+3*(*sprite++);
			else	{
				sprite++;
				ptr+=3;
				continue;
			}
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
			*ptr=*pal++;
			ptr++;
		}
		sprite+=a;
	}

}

void TransCadre(register unsigned char *Bits, int x0, int y0, int l, int h, int couleur, register unsigned char niveau)	{
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr;
	int x, y;
	unsigned char rouge=couleur&0x000000ff, vert=(couleur&0x0000ff00)>>8, bleu=(couleur&0x00ff0000)>>16;
	int nv=niveau-255, factb=bleu*niveau, factv=vert*niveau, factr=rouge*niveau;

	ClipRect;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			*ptr=(factb-nv*(*ptr))>>8;
			ptr++;
			*ptr=(factv-nv*(*ptr))>>8;
			ptr++;
			*ptr=(factr-nv*(*ptr))>>8;
			ptr++;
		}
	}
}

void TransSprite(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, nv=255-niveau, *pal;

	ClipSprite;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			if (*sprite==0xfe)		{
				sprite+=3;
				ptr+=3;
				continue;
			}
			pal = (unsigned char*)sprite;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			sprite++;
		}
		sprite+=a;
	}

}

void TransSpritePalSansMasque_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, nv=255-niveau, *pal;

	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			pal=(unsigned char*)sprite;
			sprite++;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
		}
		sprite+=a;
	}
}

void TransSpritePalSansMasque(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, nv=255-niveau, *pal;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		TransSpritePalSansMasque_32(Bits, x0, y0, l, h, sprite, palette, niveau);
		return;
	}
	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			pal=palette+3*(*sprite++);
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
		}
		sprite+=a;
	}
}

void TransSpritePal_32(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, nv=255-niveau, *pal;

	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			if (!(*sprite&0xff000000))		{
				pal=(unsigned char*)sprite;
				sprite++;
			}
			else	{
				sprite++;
				ptr+=3;
				continue;
			}
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
		}
		sprite+=a;
	}

}

void TransSpritePal(register unsigned char *Bits, int x0, int y0, int l, int h, register unsigned long *sprite, unsigned char *palette, register unsigned char niveau)		{
	int x, y, a=0;
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr, nv=255-niveau, *pal;

	//Pas la bonne foncion qui est appelée?
	if (bTil32Bits)		{
		TransSpritePal_32(Bits, x0, y0, l, h, sprite, palette, niveau);
		return;
	}
	ClipSprite8;

	for (y=y0;y<y0+h;y++)	{
		ptr=bits-LARG_BUF*3*y-3*(LARG_BUF-x0);
		for (x=0;x<l;x++)	{
			if (*sprite)
				pal=palette+3*(*sprite++);
			else	{
				sprite++;
				ptr+=3;
				continue;
			}
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
			*(ptr++)=((*ptr)*nv+niveau*(*pal++))>>8;
		}
		sprite+=a;
	}

}

/*
	FxRect

	Dessine un rectangle avec la possibilité d'appliquer les effets suivants:
	-FX_OPAQUE, FX_ADD, FX_SOUS, FX_MASQUE, FX_TRANS, FX_XOR
*/

void TransRect(register unsigned char *Bits, int x0, int y0, int l, int h, int couleur, register int niveau)		{
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr;
	register int x, y;
	register unsigned char rouge=couleur&0x000000ff, vert=(couleur&0x0000ff00)>>8, bleu=(couleur&0x00ff0000)>>16;
	int yBase=y0+CLIP_Y0, xBase=x0+CLIP_X0, lBase=l, hBase=h;
	int nv=niveau-255, factb=bleu*niveau, factv=vert*niveau, factr=rouge*niveau;

	ClipRect;

	for (y=0;y<hBase;y+=hBase-1)		{
		if (yBase+y>=CLIP_Y0 && yBase+y<CLIP_Y1)		{
			ptr=bits-LARG_BUF*3*(yBase+y)+3*x0+3;
			for (x=2;x<l;x++)	{
				*ptr=(factb-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factv-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factr-nv*(*ptr))>>8;
				ptr++;
			}
		}
		if (hBase<=1)	break;
	}
	for (x=0;x<lBase;x+=lBase-1)		{
		if (xBase+x>=CLIP_X0 && xBase+x<CLIP_X1)		{
			ptr=bits-LARG_BUF*3*y0+3*(xBase+x);
			for (y=0;y<h;y++)	{
				*ptr=(factb-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factv-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factr-nv*(*ptr))>>8;
				ptr++;
				ptr-=LARG_BUF*3+3;
			}
		}
		if (lBase<=1)	break;
	}
}


void TransRectFond(register unsigned char *Bits, int x0, int y0, int l, int h, int couleur, register int niveau)		{
	register unsigned char *bits=Bits+LARG_BUF*3*HAUT_BUF, *ptr;
	register int x, y;
	register unsigned char rouge=couleur&0x000000ff, vert=(couleur&0x0000ff00)>>8, bleu=(couleur&0x00ff0000)>>16;
	int yBase=y0+CLIP_Y0, xBase=x0+CLIP_X0, lBase=l, hBase=h;
	int nv=niveau-255, factb=bleu*niveau, factv=vert*niveau, factr=rouge*niveau;

	ClipRect;

	for (y=hBase-1;y<hBase;y+=hBase-1)		{
		if (yBase+y>=CLIP_Y0 && yBase+y<CLIP_Y1)		{
			ptr=bits-LARG_BUF*3*(yBase+y)+3*x0;
			for (x=1;x<l;x++)	{
				*ptr=(factb-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factv-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factr-nv*(*ptr))>>8;
				ptr++;
			}
		}
		if (hBase<=1)	break;
	}
	for (x=lBase-1;x<lBase;x+=lBase-1)		{
		if (xBase+x>=CLIP_X0 && xBase+x<CLIP_X1)		{
			ptr=bits-LARG_BUF*3*y0+3*(xBase+x);
			for (y=0;y<h;y++)	{
				*ptr=(factb-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factv-nv*(*ptr))>>8;
				ptr++;
				*ptr=(factr-nv*(*ptr))>>8;
				ptr++;
				ptr-=LARG_BUF*3+3;
			}
		}
		if (lBase<=1)	break;
	}
}
