Thread: SDL questions

  1. #1
    Registered User Cpro's Avatar
    Join Date
    Oct 2006
    Posts
    149

    SDL questions

    I was following a tutorial and I created this simple program that displays some graphics. I have a question about it.

    Here is the code :
    Code:
    #include "SDL/SDL.h"
    #include "SDL/SDL_image.h"
    #include "SDL/SDL_ttf.h"
    #include <string>
    using namespace std;
    
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    const int SCREEN_BPP = 32;
    
    SDL_Surface *background = NULL;
    SDL_Surface *board = NULL;
    SDL_Surface *circle = NULL;
    SDL_Surface *x = NULL;
    SDL_Surface *title = NULL;
    SDL_Surface *screen = NULL;
    
    SDL_Surface *arrowKey = NULL;
    
    SDL_Surface *upMessage = NULL;
    SDL_Surface *downMessage = NULL;
    SDL_Surface *leftMessage = NULL;
    SDL_Surface *rightMessage = NULL;
    
    SDL_Event event;
    
    TTF_Font *font = NULL;
    SDL_Color textColor = {255, 255, 255};
    
    
    SDL_Surface *load_image(string filename)
    {
    	//Temporary storage for the image that's loaded.
    	SDL_Surface *loadedImage = NULL;
    
    	//The optimized image that will be used.
    	SDL_Surface *optimizedImage = NULL;
    
    	//Load the image.
    	loadedImage = IMG_Load(filename.c_str());
    
    	//If image loaded
    	if(loadedImage != NULL)
    	{
    		//Create an optimized image.
    		optimizedImage = SDL_DisplayFormat(loadedImage);
    
    		//Free the old image.
    		SDL_FreeSurface(loadedImage);
    
    		/*
    		if(optimizedImage != NULL)
    		{
    			//Map the color key
    			Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0xFF, 0xFF, 0xFF);
    
    			//Set all pixels of that color to be transparent.
    			SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
    		}	
    		*/		
    	}
    	return optimizedImage;
    }
    void ApplySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination)
    {
    	//Make a temporary rectange to hold the offsets.
    	SDL_Rect offset;
    
    	//Give the offsets to the rectangle.
    	offset.x = x;
    	offset.y = y;
    
    	//Blit the surface.
    	SDL_BlitSurface(source, NULL, destination, &offset);
    }
    bool init()
    {
    	//Initialize all SDL subsystems.
    	if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
    	{
    		return false;
    	}
    
    	//Set up screen.
    	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
    
    	//If there was an error.
    	if(screen == NULL)
    	{
    		return 1;
    	}
    
    	//Initialize SDL_ttf
    	if(TTF_Init() == -1 )
    	{
    		return false;
    	}
    
    	//Set caption.
    	SDL_WM_SetCaption("Event Test", NULL);
    
    	//If everything initialized fine.
    	return true;
    }
    bool load_files()
    {
    	//Load the images.
    	background = load_image("blueBackground.png");
    	board = load_image("tBoard.png");
    	x = load_image("xMark.png");
    	circle = load_image("oMark.png");
    
    	//Open the font.
    	font = TTF_OpenFont("arial.ttf", 24);
    	
    	if(font == NULL)
    	{
    		return false;
    	}	
    	
    	//If there was an error.
    	if(background == NULL)
    	{
    		return false;
    	}
    
    	//If everything loaded fine.
    	return true;
    }
    void clean_up()
    {
    	//Free the surfaces.
    	SDL_FreeSurface(background);
    	SDL_FreeSurface(board);
    	SDL_FreeSurface(x);
    	SDL_FreeSurface(circle);
    	
    	//Quit SDL.
    	SDL_Quit();
    }
    int main(int argc, char *args[])
    {
    	//Make sure program waits for a quit.
    	bool quit = false;
    
    	//Initialize.
    	if(init() == false)
    	{
    		return 1;
    	}
    
    	//Load the files.
    	if(load_files() == false)
    	{
    		return 1;
    	}
    
    	//Render text.
    	title = TTF_RenderText_Solid(font, "This is the Title.", textColor);
    
    	upMessage = TTF_RenderText_Solid(font, "The up button was pressed.", textColor);
    	downMessage = TTF_RenderText_Solid(font, "The down button was pressed." , textColor);
    	leftMessage = TTF_RenderText_Solid(font, "The left button was pressed." , textColor);
    	rightMessage = TTF_RenderText_Solid(font, "The right button was pressed." , textColor);
    
    	if(title == NULL)
    	{
    		return 1;
    	}	
    
    	ApplySurface(0,0,background, screen);
    	ApplySurface(500,25,title,screen);
    
    	//Update screen.
    	if(SDL_Flip(screen) == -1)
    	{
    		return 1;
    	}
    
    	while(quit == false)
    	{
    		//While there is an event to handle.
    		while(SDL_PollEvent(&event)) 
    		{
    			//If a key was pressed.
    			if(event.type == SDL_KEYDOWN)
    			{
    				switch(event.key.keysym.sym)
    				{
    					case SDLK_UP: arrowKey = upMessage;
    						break;
    					case SDLK_DOWN: arrowKey = downMessage;
    						break;
    					case SDLK_LEFT: arrowKey = leftMessage;
    						break;
    					case SDLK_RIGHT: arrowKey = rightMessage;
    						break;
    				}
    			}
    			//If the user has Xed out of the window.
    			else if(event.type == SDL_QUIT)
    			{
    				//Quit the program.
    				quit = true;
    			}
    		}
    		//If a message needs to be displayed.
    		if(arrowKey != NULL)
    		{
    			ApplySurface(0,0,background, screen);
    			ApplySurface((SCREEN_WIDTH - arrowKey->w)/2, (SCREEN_HEIGHT - arrowKey->h)/2, arrowKey, screen);
    
    			arrowKey = NULL;
    		}
    
    		if(SDL_Flip(screen) == -1)
    		{
    			return 1;
    		}
    	}
    
    	clean_up();
    
    	return 0;
    }
    The title is displayed when the program is first started. Then, when I press a key, a new message is displayed. It appears as if the new message, along with a new copy of the background, are being placed over the title and original background. So, each time a key is pressed, a new copy of the background and message are applied. Is this the correct way to do this? It seems after a long time, this would be very inefficient. I was thinking whenever I would want to display a new background or message, that I would replace the old with the new. But, i'm not sure how I would do this here.

    Any help would be appreciated.
    Thanks.

    PS: i just started SDL a few days ago.
    IDE - Visual Studio 2005
    Windows XP Pro

  2. #2
    Registered User
    Join Date
    Aug 2008
    Posts
    2
    The short answer is you have to clear the screen surface between button presses to attain the desired effect.

    There are a few ways of doing it, the most straight forward way is to use
    Code:
    int SDL_FillRect  (SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
    To fill the the screen's rectangle ( if you don't have one make one or use the surfaces rectangle ).
    Last edited by outlaw2k5; 08-09-2008 at 12:31 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A very long list of questions... maybe to long...
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-16-2007, 05:36 AM
  2. Problems compiling this SDL app
    By Rider in forum C++ Programming
    Replies: 3
    Last Post: 03-27-2007, 12:22 PM
  3. SDL questions.
    By antex in forum Game Programming
    Replies: 3
    Last Post: 10-30-2005, 12:08 AM
  4. SDL and Windows
    By nickname_changed in forum Windows Programming
    Replies: 14
    Last Post: 10-24-2003, 12:19 AM
  5. sdl in c++
    By Klinerr1 in forum C++ Programming
    Replies: 8
    Last Post: 07-07-2002, 07:46 AM