Skip to main content
GameDev.net gamedev.net
🔒 Locked

SDL window locking up [SOLVED]

Started by Itzmattu Mar 28, 2009 at 6:50 PM 8 replies 6k views
Original Post
Itzmattu
Itzmattu
So I've been trying to get an object oriented version of SDL (version 1.2.13) code up and working for the past few days. This is eventually going to be the graphics engine for a real-time parlor game. Currently, all my code compiles and follows the same logical steps that any other code I've written does. In fact, it even shows a window that is the correct size and with the correct image (when I give it one). The problem is that as soon as SDL draws to the screen once, it locks up and the window freezes. It cannot be closed, moved, and stays as a static image. The most annoying part of this all is that I get no compile errors and that when I run it in debug mode within Visual Studio 2008 and set some breakpoints before each SDL_Flip() routine, it appears to be updating fine in the code, but the window continues to lock up. I have no clue what's going on and I'm hoping someone here has tried the same and overcome this problem. A ZIP of the project files and a VS 2008 SLN file can be found here. The source files are also stored there separately if that is what you're interested in. I'll include the files in the post as well if you prefer to look at them that way.

/*!
*
* \file   Graphics.h
*
* \author Matt Fielding & Zori Babroudi
*
* \par    email: ---
*
* \date   3/27/2009
*
* Header file for Graphics.cpp.
*
*/

#ifndef _GRAPHICS_H_
#define _GRAPHICS_H_

#include "SDL.h"
#include <string>

/*!
* \class Graphics Graphics.h
* \brief This is the main class for the Graphics engine.
*
* The Graphics class sets up SDL, the window, and has methods to draw
* the screen.
*/

namespace UMLGDG {

class Graphics
{
public:
	// Graphics constructor.
	Graphics();

	// Graphics destructor.
	~Graphics();

	// Getters for private variables.
	int getScreenWidth() const;
	int getScreenHeight() const;
	int getScreenBPP() const;
	int getFPS() const;
	std::string getConfigFile() const;

	// Method to draw all current objects to the screen.
	void draw();


protected:
	// No protected members needed.

private:
	// Config file for Graphics.
	static const std::string CONFIG_FILE;

	// Important variables used to setup window.
	int SCREEN_WIDTH;
	int SCREEN_HEIGHT;
	int SCREEN_BPP;
	int FRAMES_PER_SECOND;

	// SDL_Surface used as main surface for window.
	SDL_Surface *screen;

	// Method to parse config file and save values.
	bool configParse();

	// Method to apply a surface to another surface (usually the screen).
	void apply_surface( int x, int y, SDL_Surface *source, SDL_Surface *destination );

}; // End Graphics class.

} // End UMLGDG namespace.

#endif





/*!
*
* \file   Graphics.cpp
*
* \author Matt Fielding & Zori Babroudi
*
* \par    email: ---
*
* \date   3/27/2009
*
* This file implements the Graphics class.
*
* The job of the Graphics class is to setup the window using SDL, and
* draw whatever data is currently on the screen when called to do so.
*
*/

#include "Graphics.h"
#include "graphics_util.h"
#include "SDL.h"
#include <string>
#include <map>
#include <fstream>
#include <iostream>
#include <sstream>

const std::string UMLGDG::Graphics::CONFIG_FILE = "graphics.conf";

UMLGDG::Graphics::Graphics()
{
	configParse();
	SDL_Init( SDL_INIT_EVERYTHING );
	SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
	SDL_WM_SetCaption( "G.R.I.D.", NULL );
}

UMLGDG::Graphics::~Graphics()
{
	// Quit SDL
	SDL_Quit();
}
bool UMLGDG::Graphics::configParse()
{

	std::string temp;
	std::map<std::string, int> varMap;

	std::ifstream infile;
	infile.open(CONFIG_FILE.c_str(), std::fstream::in);

	if(!infile)
	{
		return false;
	}

	while (!infile.eof())
	{
		std::string var;
		int val;
		getline(infile, temp);
		std::istringstream buffer(temp); 
		buffer >> var >> val;
		varMap[var] = val;
	}

	infile.close();

	if (varMap.size() != 3)
	{	
		return false;
	}

	SCREEN_HEIGHT = varMap["SCREEN_HEIGHT"];
	SCREEN_WIDTH = varMap["SCREEN_WIDTH"];
	SCREEN_BPP = varMap["SCREEN_BPP"];

	return true;

} // End configParse() definition.

void UMLGDG::Graphics::apply_surface( int x, int y, SDL_Surface *source, SDL_Surface *destination )
{
	// Make a temporary SDL_Rect to hold a rectangle.
	SDL_Rect offset;

	// Give the offsets to the rectangle.
	offset.x = x;
	offset.y = y;

	// Blit the surface
	SDL_BlitSurface( source, NULL, destination, &offset );
}

void UMLGDG::Graphics::draw()
{
	return;
}





#include "SDL.h"
#include "Graphics.h"

int main(int argc, char *argv[])
{
	UMLGDG::Graphics *gfxEngine = new UMLGDG::Graphics();

	bool quit = false;

	while( quot == false )
	{
		gfxEngine->draw();
	}

	return 0;
}




I appreciate any input anyone has on this problem. Thanks for taking your time to help me out! Matt Fielding [Edited by - Itzmattu on March 29, 2009 7:40:50 PM]
CmpDev
CmpDev
Where is your window loop and why is the draw method just returning?
void UMLGDG::Graphics::draw(){	return;}
Itzmattu
Itzmattu
The main function is where the loop is with

while( quit == false )	{		gfxEngine->draw();	}


and yes it is quit == false, the code I put up above was just a typo and not in the running code. I changed it back to the loop after trying to call draw() directly outside of the loop with some delays.

As far as it just returning, that's basically just so it creates the window and displays it. The fact that nothing is being applied to the buffer just makes it draw a black background. I've basically just stripped the code down to its bare minimum to make it easy to debug and look through for everyone here. I've done tests with images being blitted to screen, and then SDL_Flip()'ing which had the same results as this code, so my assumption is that the problem lies somewhere here. I will add the code to the examples though and retest just to see what happens and repost it here.

Matt Fielding
Ariste
Ariste
Maybe I'm missing something, but where do you call your apply_surface() function?

What I'm seeing is you initializing SDL through the Graphics constructor, which sets up the screen, but you never actually draw anything to it. Calling your draw() function doesn't do anything at all, since the function just returns. Where do you blit your stuff to the screen?

Also - the screen's probably freezing because your while (quit == false) loop is infinite. There's nothing to set quit equal to false. You're just calling your draw() function over and over again.
Jack Sotac
Jack Sotac
Have you tried pumping SDL's event queue?
while(1){   while ( SDL_PollEvent(&event) ) {      ..Handle events   }    Draw();}
0xa0000000
Itzmattu
Itzmattu
Quote:
Original post by Ariste
Maybe I'm missing something, but where do you call your apply_surface() function?


In the code above no where. I had code previously that was applying surfaces but the same result still occurred.

Quote:
Original post by Ariste
Also - the screen's probably freezing because your while (quit == false) loop is infinite. There's nothing to set quit equal to false. You're just calling your draw() function over and over again.


That doesn't make any sense to me on a technical level. If the loop is infinite it should just keep drawing the screen forever until I force quit the program via the OS. I've never had any problems with programs similar in the past.

Quote:
Original post by Jack Sotac
Have you tried pumping SDL's event queue?


I'll try that as soon as I either revert to my old code or get this current bug fixed.

"What current bug?" you may ask. Well, I was adding in an actual surface to get drawn, and on this journey I ran into yet another strange problem. Now I'm getting a memory access violation when SDL_BlitSurface is called in my apply_surface() method of the Graphics class. I've retraced all my variables to make sure they are accessible via these methods (they are because not only are they methods of the class, but the variables are public) as well as the correct files are being loaded (the file path is correct).

The newest version of code is supplied below. I'm not sure what the heck it is I'm doing wrong, but time and time again since about last week I have the most random issues with getting this very basic code to work in an OO environment, when normally this type of thing is no problem for me. Hopefully the event queue will solve the problem. We'll see.

/* main.cpp */#include "SDL.h"#include "Graphics.h"#include "graphics_util.h"int main(int argc, char *argv[]){	UMLGDG::Graphics *gfxEngine = new UMLGDG::Graphics();	bool quit = false;	SDL_Event event;	while( quit == false )	{		if( gfxEngine->ErrorCode != UMLGDG::GFX_ERROR_NONE )		{			return 1;		}		gfxEngine->draw();	}	return 0;}



/*!** \file   Graphics.h** \author Matt Fielding & Zori Babroudi** \par    email: ---** \date   3/27/2009** Header file for Graphics.cpp.**/#ifndef _GRAPHICS_H_#define _GRAPHICS_H_#include "SDL.h"#include "graphics_util.h"#include <string>/*!* \class Graphics Graphics.h* \brief This is the main class for the Graphics engine.** The Graphics class sets up SDL, the window, and has methods to draw* the screen.*/namespace UMLGDG {class Graphics{public:	// Graphics constructor.	Graphics();	// Graphics destructor.	~Graphics();	// Getters for private variables.	int getScreenWidth() const;	int getScreenHeight() const;	int getScreenBPP() const;	int getFPS() const;	std::string getConfigFile() const;	// Method to draw all current objects to the screen.	void draw();	// Error code holder.	UMLGDG::GraphicsError ErrorCode;	// SDL_Surface used as main surface for window.	SDL_Surface *screen;	// SDL_Surface used as background image.	SDL_Surface *background;protected:	// No protected members needed.private:	// Config file for Graphics.	static const std::string CONFIG_FILE;	// Important variables used to setup window.	int SCREEN_WIDTH;	int SCREEN_HEIGHT;	int SCREEN_BPP;	int FRAMES_PER_SECOND;	// Method to parse config file and save values.	bool configParse();	// Method to apply a surface to another surface (usually the screen).	void apply_surface( int x, int y, SDL_Surface *source, SDL_Surface *destination );}; // End Graphics class.} // End UMLGDG namespace.#endif



/*!** \file   Graphics.cpp** \author Matt Fielding & Zori Babroudi** \par    email: ---** \date   3/27/2009** This file implements the Graphics class.** The job of the Graphics class is to setup the window using SDL, and* draw whatever data is currently on the screen when called to do so.**/#include <string>#include <map>#include <fstream>#include <iostream>#include <sstream>#include "SDL.h"#include "Graphics.h"#include "graphics_util.h"const std::string UMLGDG::Graphics::CONFIG_FILE = "graphics.conf";UMLGDG::Graphics::Graphics(){	configParse();	SDL_Init( SDL_INIT_EVERYTHING );	SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );	SDL_WM_SetCaption( "G.R.I.D.", NULL );	background = load_image( "images/background.png" );	ErrorCode = GFX_ERROR_NONE;	FRAMES_PER_SECOND = 60;}UMLGDG::Graphics::~Graphics(){	// Quit SDL	SDL_Quit();}bool UMLGDG::Graphics::configParse(){	std::string temp;	std::map<std::string, int> varMap;	std::ifstream infile;	infile.open(CONFIG_FILE.c_str(), std::fstream::in);	if(!infile)	{		return false;	}	while (!infile.eof())	{		std::string var;		int val;		getline(infile, temp);		std::istringstream buffer(temp); 		buffer >> var >> val;		varMap[var] = val;	}	infile.close();	if (varMap.size() != 3)	{			return false;	}	SCREEN_HEIGHT = varMap["SCREEN_HEIGHT"];	SCREEN_WIDTH = varMap["SCREEN_WIDTH"];	SCREEN_BPP = varMap["SCREEN_BPP"];	return true;} // End configParse() definition.void UMLGDG::Graphics::apply_surface( int x, int y, SDL_Surface *source, SDL_Surface *destination ){	// Make a temporary SDL_Rect to hold a rectangle.	SDL_Rect offset;	// Give the offsets to the rectangle.	offset.x = x;	offset.y = y;	// Blit the surface	SDL_BlitSurface( source, NULL, destination, &offset );	return;}void UMLGDG::Graphics::draw(){	apply_surface( 0, 0, this->background, this->screen );	if( SDL_Flip( screen ) == -1 )	{		ErrorCode = GFX_ERROR_SDL;	}	return;}



/* graphics_util.h */#ifndef _GRAPHICS_UTIL_H_#define _GRAPHICS_UTIL_H_#include <string>#include "SDL.h"#include "SDL_image.h"namespace UMLGDG {typedef enum {	GFX_ERROR_NONE,	GFX_ERROR_CONFIG,	GFX_ERROR_SDL,	GFX_ERROR_SURFACE,	GFX_ERROR_INPUT,	GFX_ERROR_UNDEF} GraphicsError;SDL_Surface* load_image( std::string filename );} // End UMLGDG namespace.#endif



/* graphics_util.cpp */#include "SDL.h"#include "SDL_image.h"#include "graphics_util.h"#include <string>SDL_Surface* UMLGDG::load_image( std::string filename ){	// The image that's loaded.	SDL_Surface *loadedImage = NULL;	// The optimized image that will be used.	SDL_Surface *optimizedImage = NULL;	// Load the image using IMG_Load	loadedImage = IMG_Load( filename.c_str() );	// If the image loaded...	if( loadedImage != NULL )	{		// ...create an optimized image.		optimizedImage = SDL_DisplayFormat( loadedImage );		// Free the old image.		SDL_FreeSurface( loadedImage );	}	// Return the optimized image.	return optimizedImage;}


Thanks once again for all your replies and any further help.

Matt Fielding
scarypajamas
scarypajamas
http://lazyfoo.net/SDL_tutorials/

Check out the link. Lazy foo's tutorials are the best on the net for SDL. Taught me everything I need to know.
Itzmattu
Itzmattu
Quote:
Original post by scarypajamas
http://lazyfoo.net/SDL_tutorials/

Check out the link. Lazy foo's tutorials are the best on the net for SDL. Taught me everything I need to know.


I've done every single lazyfoo tutorial, and this code is actually based off of that.

The problem is, his tutorials aren't object oriented for the main SDL code. I'm trying to make mine OO, so the tutorials really don't do much for me regarding my problem.
Itzmattu
Itzmattu
Well, the problem is finally solved and I have a working graphics engine.

The last problem I was having had to do with my call to SDL_SetVideoMode(). I was calling it but I wasn't setting it equal to screen. I totally overlooked that you have to store it somewhere and thought it just saved the info in the SDL system. That fixed the bugs I was having with SDL_BlitSurface().

As far as the screen locking up, Jack Sotac was correct that it was I wasn't SDL_PollEvent()'ing. Thank you Jack. I'll forever remember now that the event queue will stick up your game if you don't check it each iteration. :P

Hopefully someone else learns from my mistakes. Oh, and don't code when you're tired. :P
archaos90
archaos90
Quote:

Hopefully someone else learns from my mistakes. Oh, and don't code when you're tired. :P


Hehe, funny enough, I always solve all bugs I encounter when coding during the day at night when I'm extremely tired. I also find it easier to think. It's like drinking alcohol while coding: http://xkcd.com/323/, it might be the same phenomenon.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.