Sdl blitting problem

Started by
3 comments, last by silverphyre673 18 years, 7 months ago
In a function I do this:

// DEBUG
			SDL_Surface* img = SDL_LoadBMP( ("Sprites\\" + filename + "_" + sAnimation + ".bmp").c_str() );	// load animation sourceimage
			Sdl->DrawImg( img, 0, 0);	// then draw it (just for now as debug)
The DrawImg is a part of my sdlwrapper and looks like this:

void SdlWrapper::DrawImg(SDL_Surface* img, int x, int y) {	// draws the image at those coordinates on the screen
	SDL_Rect dest;
	dest.x = x;
	dest.y = y;
	SDL_BlitSurface(img, NULL, screen, &dest);
}
Screen is just a SDL_Surface* screen. And after this I do SDL_Flip(screen); But in the DrawImg function, on the line where I blit to the screen, I get Unhandled Exception and Access Violation.

First-chance exception at 0x0041b8ea in TileSystem.exe: 0xC0000005: Access violation reading location 0xcccccce0.
Unhandled exception at 0x0041b8ea in TileSystem.exe: 0xC0000005: Access violation reading location 0xcccccce0.
The thread 'Win32 Thread' (0xaf0) has exited with code -1073741819 (0xc0000005).
Do I somehow blit in the wrong way? I think I used that DrawImg function a few days ago and it worked fine, and I havent changed it since. Anyone knows what could be the problem?
Advertisement
I would need to see the rest of the function that loads and blits the image. My best guess right now is that you aren't calling SDL_FreeSurface() on "img". This causes a (probably large) memory leak every time you call the function. A better option would be to load and free the SDL_Surface once per game/level/whatever, so you don't have to allocate memory, load the image, and free the image every frame. This would cause huge slowdowns in a real game.

I'm not sure what DrawImage will do if it tries to blit a surface that failed to load - if your loading function cannot find the file, it doesn't look like it has anything to handle that. That may be another problem.
my siteGenius is 1% inspiration and 99% perspiration
Is screen properly initialized?
It seems the systems tries to read from 0xCCCCCCE0. The value 0xCCCCCCCC is one of the special values the C-runtime sets a variable to.
Hmm... No Im not calling SDL_FreeSurface(). Why and when should i do that? I dont remember Ive read it in any tutorial...

However the function is supposed to load a bitmap in which several small images are. Four small images, each on 16x16 pixels so the total bmp size is 64x16 pixels. The functions purpose is then to "Clip Blit" the images into a vector of frames. The vector is a part of a std::map which holds all the animations. Hehe hard to explain this. :P

This holds all the animations:
	// call it with the animation name and you get a vector with all its frames	map <string, vector<Frame> > Animation;


The Frame structure looks like this:
struct Frame {	SDL_Surface* image;		// the actual image in the frame	int displayTime;		// for how long should the image be displayed before we go on to the next?};


The functions then looks like this:
bool Sprite::LoadAnimations(string filename) {	// *** LOCAL VARIABLES *****************************************	stringstream str;					// for the log to write in	SDL_Surface* SourceFile;			// the sourcefile which in all the frames are		stringstream DataFile;				// the txt file with all the numbers	int SpriteSize = 0;					// the size of the sprite;	int Frames = 0;						// how many frames in the animation	string sAnimation = "UNDEFINED";	// the name of the sprite	SDL_Rect source;						// we have this so we now which area in the image sourcefile to take the image from							// **************************************************************	str << "Sprite:\tLoading sprite " << filename << " ... ";		DataFile << "Sprites\\" << filename << ".txt";	ifstream file(DataFile.str().c_str());		// the txt with all the data	file >> SpriteSize;	// we need to know how big each frame is	str << "Size: " << SpriteSize << " px";	while(1) {		if(file.eof())				// have we read all the data yet?			break;				// read in the data		file >> sAnimation;		file >> Frames;		// load the bmp in which the animation is held		SourceFile = SDL_LoadBMP( ("Sprites\\" + filename + "_" + sAnimation + ".bmp").c_str() );	// attempt to load the texture		if(SourceFile == NULL) {	// NULL, no image is there			str << "\n\tFAILED: unable to open bmp file";			Log::Write(str.str());			return false;		} // the image was loaded successfully, go on		// setting transparency		SDL_SetColorKey(SourceFile, SDL_SRCCOLORKEY, SDL_MapRGB(SourceFile->format, 255, 0, 255));		str << "\n\tAnimation: " << sAnimation;		Animation[sAnimation].resize(Frames);	// we want this many frames		for(int frame = 0; frame < Frames; frame++) {	// copy all the images			source.x = SpriteSize * frame;			source.y = SpriteSize;			source.h = SpriteSize;			source.w = SpriteSize;			// the source area is now sorted out			SDL_BlitSurface(SourceFile, &source, Animation[sAnimation][frame].image, NULL);	// copy it			file >> Animation[sAnimation][frame].displayTime;	// store the wait time			str << "\n\t" << frame << "\t" << Animation[sAnimation][frame].displayTime;			// and go on to the next fram;			// DEBUG			SDL_Surface* img = SDL_LoadBMP( ("Sprites\\" + filename + "_" + sAnimation + ".bmp").c_str() );	// load animation sourceimage			Sdl->DrawImg( img, 0, 0);	// then draw it (just for now as debug)		}			}	str << "\tSuccess";	Log::Write(str.str());	return true;}


The function reads the data from a .txt file, which holds the data like how many pixels the sprite is in size, how many frames it has, its name, and how many milliseconds it should display each frame. The file for my ninja sprite looks like this:

16running4 500 500 500 500


Any ideas?

Oh, I see what you're doing. I thought you were blitting the animation to the screen during the loading procedure, and loading it up every time you wanted to blit =) Whew. Anyways, SDL_FreeSurface() is basically like the C++ delete keyword that you use to free the memory used for an SDL_Surface. You need to call it when you are cleaning up your program, like when you are done with a particular animation. Most likely, this call will go in its destructor.

In the end, I'm going to guess that you are trying to read from or write to some bad memory, or something like that. Check that you aren't trying to delete any NULL pointers or something like that. You'll probably have to step through a bit more of your code with the debugger. For your sake, I hope you aren't using dev-cpp, because its debugger is currently a heap of steaming feces. And I still use it. Masochism++.
my siteGenius is 1% inspiration and 99% perspiration

This topic is closed to new replies.

Advertisement