#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <SDL.h>
#define GP2X_PRODUCTION_BUILD
#define LOCK(s)   {if(SDL_MUSTLOCK(s))(void)SDL_LockSurface(s);}
#define UNLOCK(s) {if(SDL_MUSTLOCK(s))(void)SDL_UnlockSurface(s);}
void DrawScene(SDL_Surface *scene);
void PutPixel(SDL_Surface *surface, Uint16 x, Uint16 y, Uint8 r, Uint8 g
 , Uint8 b);
/* SDL Demo program:
 */
int main()
{
		SDL_Surface *screen_ptr = NULL;
		SDL_Joystick *joystick_ptr = NULL;
		SDL_Event event;
		Uint32 col;
		int done = 0;
		/* Initialize SDL:
		 */
		if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
				fprintf(stderr, "Couldn't initialize SDL: %s\n"
				 , SDL_GetError());
				return 1;
		}
		if ( (screen_ptr=SDL_SetVideoMode(320, 240, 8, SDL_SWSURFACE) )
		 == NULL) {
				fprintf(stderr, "Couldn't set video mode: %s\n"
				 , SDL_GetError());
				return 1;
		}
		if ( (joystick_ptr=SDL_JoystickOpen(0) ) == NULL) {
				fprintf(stderr, "Couldn't open the joystick: %s\n"
				 , SDL_GetError());
				return 1;
		}
		/* Hide cursor:
		 */
		SDL_ShowCursor(SDL_DISABLE);
		/* Initialize screen:
		 */
		col = SDL_MapRGB(screen_ptr->format, 0xff, 0x00, 0xff);
		SDL_FillRect(screen_ptr, NULL, col);
		SDL_UpdateRect(screen_ptr, 0,0,0,0);
		/* Draw nice scene:
		 */
		DrawScene(screen_ptr);
		SDL_UpdateRect(screen_ptr, 0,0,0,0);
		/* Wait for keypress or term:
		 */
		while (!done)
		{
				SDL_WaitEvent(&event);
				switch (event.type)
				{
						case SDL_JOYBUTTONDOWN:
						case SDL_QUIT:
								done=1;
								break;
				}
				/* Be nice:
				 */
				SDL_Delay(10);
		}
		/* Close SDL:
		 */
		SDL_Quit();
		/* Return to GP2x menu:
		 */
#ifdef GP2X_PRODUCTION_BUILD
		chdir("/usr/gp2x");
		execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
#endif
		/* Otherwise quit for PC:
		 */
		return 0;
}
/* Fancy background:
 */
void DrawScene(SDL_Surface *scene)
{
		int x,y;
		LOCK(scene);
		for(x=0; x< scene->w; x++)
				for(y=0; y< scene->h; y++)
						PutPixel(scene, x, y,
								(( (255.0 / scene->w) * (x + 0.0) ) / 16) * 16,
								(( (255.0 / scene->h) * (y + 0.0) ) / 16) * 16,
								0
								);
		UNLOCK(scene);
}
/* The mandatory putpixel routine from www.libsdl.org:
 */
void PutPixel(SDL_Surface *surface, Uint16 x, Uint16 y, Uint8 r, Uint8 g
			  , Uint8 b){
		Uint32 color = SDL_MapRGB(surface->format, r, g, b);
		switch (surface->format->BytesPerPixel){
		case 1: /* 8-bpp */
		{
		Uint8 *bufp;
		bufp = (Uint8 *)surface->pixels + y*surface->pitch + x;
		*bufp = color;
		}
		break;
	case 2: // Probably 15-bpp or 16-bpp
	  {
		Uint16 *bufp;
		bufp = (Uint16 *)surface->pixels + y*surface->pitch/2 + x;
		*bufp = color;
	  }
	  break;
	case 3: // Slow 24-bpp mode, usually not used
	  {
		Uint8 *bufp;
		bufp = (Uint8 *)surface->pixels + y*surface->pitch + x * 3;
		if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
		{
		  bufp[0] = color;
		  bufp[1] = color >> 8;
		  bufp[2] = color >> 16;
		} else {
		  bufp[2] = color;
		  bufp[1] = color >> 8;
		  bufp[0] = color >> 16;
		}
	  }
	  break;
	case 4: // Probably 32-bpp
	  {
		Uint32 *bufp;
		bufp = (Uint32 *)surface->pixels + y*surface->pitch/4 + x;
		*bufp = color;
	  }
	  break;
  }
}