/* MoleInvasion - Copyright (C) - Guillaume Chambraud (linuxprocess@free.fr)

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version. */

#define GRAPHICS_C
#include <time.h>
#include "graphics.h"
#include "events.h"

void quit( int code )
{
    close_joystick();
    SDL_Quit();
    exit( code );
}

Uint32 coef_frame_rate(char show_FPS)
{	static Uint32 totalTime=0;
	static Uint32 lastTime=0;
	static int nb_frame=0;
	Uint32 interval,currentTime,before;
	
	before = SDL_GetTicks();

	/* on bloque à 30 FPS soit 33ms/frame en déchargeant le CPU */
	while(SDL_GetTicks()-lastTime< 3)SDL_Delay(21);
	while(SDL_GetTicks()-lastTime<13)SDL_Delay(11);
	while(SDL_GetTicks()-lastTime<23)SDL_Delay(1);
#ifndef WIN32
	while(SDL_GetTicks()-lastTime<33)
	{	struct timespec ts;
		ts.tv_sec=0;
		ts.tv_nsec=50000; /* 50 ms */
		nanosleep(&ts,NULL);
	}
#else
	while(SDL_GetTicks()-lastTime<33);
#endif

	currentTime = SDL_GetTicks();
	interval=currentTime-lastTime;
//	fprintf(stderr,"cur:%u bef:%u lst:%u total:%u inter:%u\n",currentTime,before,lastTime,totalTime,interval);
	lastTime=currentTime;
	nb_frame++;

	totalTime+=interval;
	if(totalTime>1000)
	{	/*fprintf(stderr,"FPS : %f\n",((float)(nb_frame*1000)/(float)interval));*/
		if(show_FPS)printf("FPS : %d\n",nb_frame);
		totalTime=0;
		nb_frame=0;
	}

	return interval;
}

SDL_Surface * IMG_LoadOptCkey(char *filename)
{	Uint32 colorkey;
	SDL_Surface *tmp, *ret;

	tmp=IMG_Load(filename);
	if(!tmp)
	{	fprintf(stderr,"Cannot load : %s\n",filename);
		return NULL;
	}
	colorkey = SDL_MapRGB(tmp->format, 0, 0, 0); 
	SDL_SetColorKey (tmp, SDL_SRCCOLORKEY|SDL_RLEACCEL, colorkey);
	ret=SDL_DisplayFormatAlpha(tmp);
	SDL_FreeSurface(tmp);
	return ret;
}

void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{	int bpp = surface->format->BytesPerPixel;
	Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

	switch(bpp)
	{case 1:*p = pixel; /* donne l'index dans la palette */
		break;
	case 2:	*(Uint16 *)p = pixel;
		break;
	case 3:	if(SDL_BYTEORDER == SDL_BIG_ENDIAN) 
		{	p[0] = (pixel >> 16) & 0xff;
			p[1] = (pixel >> 8) & 0xff;
			p[2] = pixel & 0xff;
		}
		else
		{	p[0] = pixel & 0xff;
			p[1] = (pixel >> 8) & 0xff;
			p[2] = (pixel >> 16) & 0xff;
		}
		break;
	case 4:	*(Uint32 *)p = pixel;
		break;
	}
}
 
Uint32 getPixel(SDL_Surface *surface, int x, int y)
{	int bpp = surface->format->BytesPerPixel;
	Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

	switch(bpp)
	{case 1:return *p; /* donne l'index dans la palette */
	case 2:	return *(Uint16 *)p;
	case 3:	if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
			return p[0] << 16 | p[1] << 8 | p[2];
		else
			return p[0] | p[1] << 8 | p[2] << 16;
	case 4:	return *(Uint32 *)p;
	default:return 0;
	}
}

void imageGetPixel8b(SDL_Surface* image, 
		unsigned int x, unsigned int y,
		unsigned char *r, unsigned char *v ,unsigned char *b)
{
	SDL_Color color;
	
	if( x<0 || x>=image->w || y<0 || y>=image->h )
	{	fprintf(stderr,"Out Of bound %d %d : %d %d\n",image->w,image->h,x,y);
		*r=*v=*b=0;
		return;
	}
	
	assert(image->format->BitsPerPixel == 8);
	
	color=image->format->palette->colors[*((Uint8*)image->pixels+(x+image->pitch*y))];
	*r=color.r;	*v=color.g;	*b=color.b;
}

int hasAnyAlpha(SDL_Surface *image)
{	unsigned int x,y;
	Uint32 pixel,temp;
	Uint8 alpha;
	SDL_PixelFormat *fmt;

	fmt=image->format;

	if(!fmt->Amask)return 0;

	if(SDL_MUSTLOCK(image))
		SDL_LockSurface(image);
	
	for (y=0;y<image->h;y++)
		for (x=0;x<image->w;x++)
		{	pixel=getPixel(image, x, y);
			/* Get Alpha component */
			temp=pixel&fmt->Amask; /* Isolate alpha component */
			temp=temp>>fmt->Ashift;/* Shift it down */
			temp=temp<<fmt->Aloss; /* Expand to a full 8-bit number */
			alpha=(Uint8)temp;
			
			if(alpha!=255)
			{//	fprintf(stderr,"found alpha pixel (%u,%u)=%hhu ",x,y,alpha);
				if(SDL_MUSTLOCK(image))
					SDL_UnlockSurface(image);
				return 1;
			}
		}

	if(SDL_MUSTLOCK(image))
		SDL_UnlockSurface(image);
	
	return 0;
}

SDL_Surface * IMG_LoadOptAlpha(char *filename)
{	SDL_Surface *tmp, *ret;

	tmp=IMG_Load(filename);
	if(!tmp)
	{	fprintf(stderr,"Cannot load : %s\n",filename);
		return NULL;
	}

	if(hasAnyAlpha(tmp))
	{	SDL_SetAlpha (tmp, SDL_SRCALPHA | SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
		ret=SDL_DisplayFormatAlpha(tmp);
//		fprintf(stderr,"%s has alpha\n",filename);
	}
	else
	{	ret=SDL_DisplayFormat(tmp);
//		fprintf(stderr,"%s has no alpha\n",filename);
	}

	SDL_FreeSurface(tmp);

	return ret;
}

char GFX_loadCompleteSprite(struct gsi * csp, char * sp_name,int spwall_id,char * spwall_gfx_dir,char *sp_map,char mode)
{	char buff[512];
	SDL_Surface* 	tmpgfx;
	struct stat fstatb;
	int cpt;

	assert(csp);
	memset(csp,0,sizeof(struct gsi));

	/* en fonction du mode, on ne chargera que ce qui est necessaire */

	/* la map */
	sprintf(buff,"%s/%.200s",GFX_DIR,sp_map);
	tmpgfx=IMG_Load(buff);
	if(!tmpgfx)
	{	fprintf(stderr,"Cannot load %s\n",buff);
		quit(1);
	}
	csp->map=tmpgfx;
			
	/* la optmap */
	if(mode != FAKE_MODE)
	{	sprintf(buff,"%s/%.200s",GFX_DIR,sp_map);
		tmpgfx=IMG_LoadOptCkey(buff);
	}
	else
		tmpgfx=(void*)1;
	if(!tmpgfx)
	{	fprintf(stderr,"Cannot load %s\n",buff);
		quit(1);
	}
	if(g_opengl)
	{	csp->OGLoptmap = OGLloadSurface(tmpgfx);
		SDL_FreeSurface(tmpgfx);
	}
	else
		csp->optmap=tmpgfx;

/*	for(cpt=0;cpt<sizeof(csp->imgs)/sizeof(csp->imgs[0]);cpt++)
		csp->imgs[cpt]=NULL;
*/				
	/* les images */
	if(!sp_name)
	{	/* cas wall */
		csp->type=SINGLE;
		csp->imgs_cnt=1;
		tmpgfx=NULL;
		if(mode == EDITOR_MODE)
		{	sprintf(buff,"%s/%s/wall-%.2d-editor.png",GFX_DIR,spwall_gfx_dir,spwall_id);
			tmpgfx=IMG_LoadOptAlpha(buff);
		}
		else if(mode == FAKE_MODE)
		{	tmpgfx=(void*)1;
		}
		if(!tmpgfx)
		{	sprintf(buff,"%s/%s/wall-%.2d.png",GFX_DIR,spwall_gfx_dir,spwall_id);
			tmpgfx=IMG_LoadOptAlpha(buff);
		}
		if(!tmpgfx)
		{	fprintf(stderr,"Cannot load %s\n",buff);
			quit(1);
		}
		csp->imgs[0]=tmpgfx;
	}
	
	else if(strstr(sp_name,".png"))
	{	/* cas image static */
		csp->type=SINGLE;
		csp->imgs_cnt=1;
		tmpgfx=NULL;
		if(mode == EDITOR_MODE)
		{	char* ptr;
			sprintf(buff,"%s/%.40s",GFX_DIR,sp_name);
			ptr=strstr(buff,".png");
			sprintf(ptr,"-editor.png");
			tmpgfx=IMG_LoadOptAlpha(buff);
		}
		else if(mode == FAKE_MODE)
		{	tmpgfx=(void*)1;
		}
		if(!tmpgfx)
		{	sprintf(buff,"%s/%.40s",GFX_DIR,sp_name);
			tmpgfx=IMG_LoadOptAlpha(buff);
		}
		if(!tmpgfx)
		{	fprintf(stderr,"Cannot load %s\n",buff);
			quit(1);
		}
		csp->imgs[0]=tmpgfx;
	}

	else
	{	/* cas image animee */
		if( mode == GAME_MODE )
		{	/* recherche de "sprite1.png" ou "sprite-gche-jump.png" */
			sprintf(buff,"%s/%s/%s",GFX_DIR,sp_name,"sprite1.png");
			if(stat(buff,&fstatb) == 0)
			{	/* image de type LIST */
				csp->type=LIST;
				
				for(cpt=0;cpt<sizeof(csp->imgs)/sizeof(csp->imgs[0]);cpt++)
				{	sprintf(buff,"%s/%s/sprite%d.png",GFX_DIR,sp_name,cpt+1);
					if(stat(buff,&fstatb) != 0)
						break;
					tmpgfx=IMG_LoadOptAlpha(buff);
					if(!tmpgfx)
					{	fprintf(stderr,"Cannot load %s\n",buff);
						quit(1);
					}
					csp->imgs[cpt]=tmpgfx;
				}
				csp->imgs_cnt=cpt;
			}
			else
			{	sprintf(buff,"%s/%s/%s",GFX_DIR,sp_name,"sprite-gche-jump.png");
				if(stat(buff,&fstatb) == 0)
				{	/* image de type FULL */
					csp->type=FULL;
					sprintf(buff,"%s/%.20s/sprite-drte-stop.png",GFX_DIR,sp_name);csp->imgs[DRTE_STOP]=IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av1.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV1] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av2.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV2] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av3.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV3] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av4.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV4] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-jump.png",GFX_DIR,sp_name);csp->imgs[DRTE_JUMP]=IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-fall.png",GFX_DIR,sp_name);csp->imgs[DRTE_FALL]=IMG_LoadOptAlpha(buff);
	
					sprintf(buff,"%s/%.20s/sprite-gche-stop.png",GFX_DIR,sp_name);csp->imgs[GCHE_STOP]=IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av1.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV1] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av2.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV2] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av3.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV3] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av4.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV4] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-jump.png",GFX_DIR,sp_name);csp->imgs[GCHE_JUMP]=IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-fall.png",GFX_DIR,sp_name);csp->imgs[GCHE_FALL]=IMG_LoadOptAlpha(buff);
	
					csp->imgs_cnt=14;
					for(cpt=0;cpt<csp->imgs_cnt;cpt++)
						if (!csp->imgs[cpt])
						{	fprintf(stderr,"Sprite %s imcomplet !\n",sp_name);
							quit(1);
						}
				}
				else
				{	/* image de type SIMPLE */
					csp->type=SIMPLE;
					sprintf(buff,"%s/%.20s/sprite-drte-av1.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV1] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av2.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV2] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av3.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV3] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-drte-av4.png",GFX_DIR,sp_name); csp->imgs[DRTE_AV4] =IMG_LoadOptAlpha(buff);
	
					sprintf(buff,"%s/%.20s/sprite-gche-av1.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV1] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av2.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV2] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av3.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV3] =IMG_LoadOptAlpha(buff);
					sprintf(buff,"%s/%.20s/sprite-gche-av4.png",GFX_DIR,sp_name); csp->imgs[GCHE_AV4] =IMG_LoadOptAlpha(buff);
	
					csp->imgs_cnt=8;
					for(cpt=0;cpt<4;cpt++)
						if (!csp->imgs[cpt])
						{	fprintf(stderr,"Sprite %s imcomplet !\n",sp_name);
							quit(1);
						}
					for(cpt=7;cpt<11;cpt++)
						if (!csp->imgs[cpt])
						{	fprintf(stderr,"Sprite %s imcomplet !\n",sp_name);
							quit(1);
						}
				}
			}
		}
		else if (mode == EDITOR_MODE )
		{	csp->type=SINGLE;
			csp->imgs_cnt=1;
			tmpgfx=NULL;

			sprintf(buff,"%s/%.20s/editor.png",GFX_DIR,sp_name);
			tmpgfx=IMG_LoadOptAlpha(buff);
			if(!tmpgfx)
			{	sprintf(buff,"%s/%.20s/sprite1.png",GFX_DIR,sp_name);
				tmpgfx=IMG_LoadOptAlpha(buff);
			}
			if(!tmpgfx)
			{	sprintf(buff,"%s/%.20s/sprite-gche-av1.png",GFX_DIR,sp_name);
				tmpgfx=IMG_LoadOptAlpha(buff);
			}
			if(!tmpgfx)
			{	fprintf(stderr,"Cannot load any editor img\n");
				quit(1);
			}
			csp->imgs[0]=tmpgfx;
		}
		else if (mode == FAKE_MODE )
		{	csp->type=SINGLE;
			csp->imgs_cnt=1;
			tmpgfx=(void*)1;
			csp->imgs[0]=tmpgfx;
		}
		else
		{	fprintf(stderr,"Mode %d unknonw !\n",mode);
			quit(1);
		}
	}

	if (mode != FAKE_MODE )
	for(cpt=0;cpt<sizeof(csp->imgs)/sizeof(csp->imgs[0]);cpt++)
	{	if(csp->imgs[cpt])
		{	csp->imgW[cpt] = csp->imgs[cpt]->w;
			csp->imgH[cpt] = csp->imgs[cpt]->h;
			if(g_opengl)
			{	csp->OGLtexture[cpt] = OGLloadSurface(csp->imgs[cpt]);
				SDL_FreeSurface(csp->imgs[cpt]);
				csp->imgs[cpt]=NULL;
			}
		}
	}
		
	return 0;
}

char displaySurfaceSDL( SDL_Surface* surface, SDL_Surface* screen, Sint16 x, Sint16 y)
{	SDL_Rect dest;

	if(!surface)
		return 1;

	dest.x = x;
	dest.y = screen->h - surface->h - y;
	SDL_BlitSurface(surface, NULL, screen, &dest);
	return 0;
}


/* *************************************************** */

void My_Flip()
{
	if(g_opengl)
	{	SDL_GL_SwapBuffers();
		glLoadIdentity();
		glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
		glOrtho(0,800,600,0,0,1);
	}
	else
		SDL_Flip(g_SDL_screen);
}
/*#include <GL/glu.h>*/

char displaySurfaceOGL(OGL_Surface texture, Sint16 x, Sint16 y, Sint16 heigth)
{
	glPushMatrix();
	glTranslatef((GLfloat)x,(GLfloat)(600-heigth-y),0);
	glBindTexture(GL_TEXTURE_2D, texture.texture);
	glBegin(GL_QUADS);
	glTexCoord2f(0, 0);	glVertex2i(0,         texture.h);
	glTexCoord2f(1, 0);	glVertex2i(texture.w, texture.h);
	glTexCoord2f(1, 1);	glVertex2i(texture.w, 0);
	glTexCoord2f(0, 1);	glVertex2i(0,         0);
	glEnd();
	glPopMatrix();
	return 0;
}

unsigned int nextPowerOf2(unsigned int v)
{	unsigned int res=1;
	while(res<v)
		res<<=1;
	
	return res;
}

char isPowerOf2(unsigned int v)
{	while(v)
	{	if(v&1)
		{	v>>=1;
			if(v)
				return 0;
		}
		else
			v>>=1;
	}
	return 1;
}

/* This is a procedure that's been floating around in various forms to take
 an SDL_Surface and load it into video ram. */
OGL_Surface OGLloadSurface(SDL_Surface *sdlimage)
{	OGL_Surface retSurf;
	GLuint texture;
	void *raw;
	int w, h, i, j, bpp;
	Uint8 *srcPixel, *dstPixel;
	Uint32 truePixel;
	GLenum errorCode;

/* While it is feasable to load paletized (1 BPP) images, we won't
bother with that since I doubt we'll prefer one over a truecolor texture. */
bpp = sdlimage->format->BytesPerPixel;
assert(bpp >= 2 && bpp <= 4);

w = nextPowerOf2(sdlimage->w);
h = nextPowerOf2(sdlimage->h);

raw = (void *)malloc(w * h * 4);
dstPixel = (Uint8 *)raw;

if(SDL_MUSTLOCK(sdlimage))
	SDL_LockSurface(sdlimage);

/* Loop through the image, converting SDL's byte order to RGBA byte order. */
for (i = h - 1; i >= 0; i--) {
	for (j = 0; j < w; j++) {
		if (i >= sdlimage->h || j >= sdlimage->w) {
			/* Use transparency if we go off the source image. */
			memset(dstPixel, 0, 4);
		} else {
			srcPixel = (Uint8 *)sdlimage->pixels + i * sdlimage->pitch + j * bpp;
			switch (bpp) {
			case 2:
				truePixel = *(Uint16 *)srcPixel;
				break;
			case 3:
				if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
					truePixel = srcPixel[0] << 16 | srcPixel[1] << 8 | srcPixel[2];
				} else {
					truePixel= srcPixel[0] | srcPixel[1] << 8 | srcPixel[2] << 16;
				}
				break;
			case 4:
				truePixel = *(Uint32 *)srcPixel;
				break;
			}

			/* This is the function does the dirty work to fill dstPixel with a 32-bit RGBA value.*/
			SDL_GetRGBA(truePixel, sdlimage->format, &(dstPixel[0]), &(dstPixel[1]), & (dstPixel[2]), &(dstPixel[3]));
		}
		dstPixel += 4;
	}
}

if(SDL_MUSTLOCK(sdlimage))
	SDL_UnlockSurface(sdlimage);

while (glGetError()) { ; } /* eat any gl errors before we cause some of our own */

/* glGenTextures allocates textures. The first parameter is how many
 and the second is an array to store the texture names in. */
glGenTextures(1, &texture);

/* Check if there were any errors. */
errorCode = glGetError();
if (errorCode != 0) {
	/* glDeleteTextures is the opposite of glGenTextures */
	glDeleteTextures(1, &texture);
	free(raw);

	if (errorCode == GL_OUT_OF_MEMORY) {
		fprintf(stderr,"Out of texture memory.\n");
	} else {
		fprintf(stderr,"Generic GL error occured during glGenTextures.\n");
	}
	exit(0);
}

/* glBindTexture is used to bind a texture to a texture context,
 in this case GL_TEXTURE_2D, the 2d texture. */
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D (GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *)raw);

/* cleanup */
free(raw);

errorCode = glGetError();
if (errorCode != 0) {
	glDeleteTextures(1, &texture);

	if (errorCode == GL_OUT_OF_MEMORY) {
		fprintf(stderr,"Out of texture memory.\n");
	} else {
		fprintf(stderr,"Generic GL error occured during gluBuild2DMipmaps.\n");
	}
}

	retSurf.texture=texture;
	retSurf.w=w;
	retSurf.h=h;
	return retSurf;
}

SDL_Surface * BlitImages(char ** images_names,int *posXs,int *posYs, int nb)
{	unsigned int i,wmax,hmax,wtot;
	SDL_Surface **tmp, *ret, *ret2;
	SDL_Rect pos;

	tmp=(SDL_Surface **)malloc(sizeof(SDL_Surface *)*nb);
	wmax=hmax=0;
	for(i=0;i<nb;i++)
	{	tmp[i]=IMG_LoadOptAlpha(images_names[i]);
		assert(tmp[i]);
		wtot=tmp[i]->w+posXs[i];
		if(wtot > wmax)
			wmax=wtot;
		if(tmp[i]->h+posYs[i] > hmax)
			hmax=tmp[i]->h+posYs[i];
	}
	ret=SDL_CreateRGBSurface(SDL_HWSURFACE,wmax,hmax,
		g_SDL_screen->format->BitsPerPixel,
		g_SDL_screen->format->Rmask, g_SDL_screen->format->Gmask,
		g_SDL_screen->format->Bmask, g_SDL_screen->format->Amask);
	assert(ret);
	SDL_FillRect(ret, NULL,SDL_MapRGB(ret->format, 0, 0, 0));
	for(i=0;i<nb;i++)
	{	pos.y=posYs[i];
		for( pos.x = posXs[i] ; pos.x < ret->w ; pos.x += tmp[i]->w+posXs[i] )
			SDL_BlitSurface(tmp[i],NULL,ret,&pos);
		SDL_FreeSurface(tmp[i]);
	}
	free(tmp);
	ret2=SDL_DisplayFormat(ret); /* no alpha here */
	SDL_FreeSurface(ret);
	return ret2;
}
