/* 
 * Project: SDL
 * Demo Code
 * This demo simply inits the library.
 *
 * Joseph M. Robertson, jmr, jmrobert5@home.com
 *
 * Copyright(c) 2001, Joseph M. Robertson.
 * This code protected by the GNU Public License.
 * See the LICENSE file or http://www.gnu.org for details.
 */

/*
 * build code
 * gcc -c init.c -I/usr/include/SDL
 * gcc -o init init.o -lSDL -lpthread
 */

#include "SDL.h"   /* All SDL App's need this */
#include <stdio.h>

void drawpixel(void);

/* new */
SDL_Surface *screen;
SDL_Event event;

int main() {
   
     printf("Initializing SDL.\n");
   
     /* Initialize defaults, Video and Audio */
     if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
	  printf("Could not initialize SDL: %s.\n", SDL_GetError());
	  exit(-1);
     }     
     printf("SDL initialized.\n");

     /* new
      * set the vid mode 
      * Have a preference for 8-bit, but accept any depth */
     screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
     if ( screen == NULL ) {
	  fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
		  SDL_GetError());
	  exit(1);
     }
     printf("Set 640x480 at %d bits-per-pixel mode\n",
	    screen->format->BitsPerPixel);
     
     /* new */
     drawpixel();

     while (1) {
     /* Poll for events. SDL_PollEvent() returns 0 when there are no  */
     /* more events on the event queue, our while loop will exit when */
     /* that occurs.                                                  */
     while( SDL_PollEvent( &event ) ){
	  /* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
	  switch( event.type ){
	  case SDL_KEYDOWN:
	       printf( "Key press detected\n" );
	       
	       printf("Quitting SDL.\n");
	       /* Shutdown all subsystems */
	       SDL_Quit();
	       printf("Quitting....\n");     
	       exit(0);

	       break;       
	  case SDL_KEYUP:
	       printf( "Key release detected\n" );
	       break;       
	  default:
	       break;
	  }
     }

     }
    
}

/* new
 * Return the pixel value at (x, y)
 * NOTE: The surface must be locked before calling this!
 */
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
     int bpp = surface->format->BytesPerPixel;
     /* Here p is the address to the pixel we want to retrieve */
     Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;     
     switch(bpp) {
     case 1:
	  return *p;     
     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;       /* shouldn't happen, but avoids warnings */
     }
}


/*
 * Set the pixel at (x, y) to the given value
 * NOTE: The surface must be locked before calling this!
 */
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
     int bpp = surface->format->BytesPerPixel;
     /* Here p is the address to the pixel we want to set */
     Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;     
     switch(bpp) {
     case 1:
	  *p = pixel;
	  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;
     }
}

void drawpixel(){
     /* Code to set a yellow pixel at the center of the screen */     
     int x, y;
     Uint32 yellow;     
     /* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00)
      * Note:  If the display is palettized, you must set the palette first.
      */
     yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);     
     x = screen->w / 2;
     y = screen->h / 2; 
    
     /* Lock the screen for direct access to the pixels */
     if ( SDL_MUSTLOCK(screen) ) {
	  if ( SDL_LockSurface(screen) < 0 ) {
	       fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
	       return;
	  }
     }     
    
     putpixel(screen, x, y, yellow);     

     if ( SDL_MUSTLOCK(screen) ) {
	  SDL_UnlockSurface(screen);
     }
     /* Update just the part of the display that we've changed */
     SDL_UpdateRect(screen, x, y, 1, 1);     

     return;

}

