SDL blit troubles

Started by
12 comments, last by Last Hylian 14 years, 7 months ago
Alright, so, yeah, just trying my hand at SDL, and I know how to Blit surfaces, but I'm trying to right a functions to streamline it all. For some reason though, the image isn't showing up, so, if someone would like to enlighten me, that'd be great. main.cpp

#include "sdl.h"
#include "main_functions.h"

int main(int argc, char* argv[])
{
	main_functions mainfunct;

	mainfunct.execute();

	return 0;
}
main_functions.h

#ifndef MAIN_FUNCTIONS_H_
#define MAIN_FUNCTIONS_H_
#include "sdl.h"
#include "graphic_functions.h"

class main_functions
{
private:
	bool running;
	SDL_Event Event;
public:
	SDL_Surface* screen;
public:
	main_functions();
	void execute();
	bool start();
	void check_event(SDL_Event Event);
	void draw();
	void clean_up();
};

#endif
main_functions.cpp

#include "main_functions.h"

main_functions::main_functions()
{
	running = true;
	screen = NULL;
}

bool main_functions::start()
{
	if((SDL_Init(SDL_INIT_EVERYTHING)) < 0)
	{
		return false;
	}
	if((screen = SDL_SetVideoMode(600,400,16, SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
	{
		return false;
	}

	return true;
}

void main_functions::check_event(SDL_Event Event)
{
	graphic_functions graphfunct;
	if(SDL_PollEvent(&Event))
	{
		if(Event.type == SDL_KEYDOWN)
		{
		switch(Event.key.keysym.sym)
			{
			case SDLK_UP: graphfunct.subtracty();break;
			case SDLK_DOWN: graphfunct.addy();break;
			case SDLK_LEFT: graphfunct.subtractx(); break;
			case SDLK_RIGHT: graphfunct.addx();break;
			}
		}
		else if(Event.type == SDL_QUIT)
		{
			running = false;
		}
	}
}

void main_functions::draw()
{
	graphic_functions graphfunct;

	graphfunct.prepare_image("avy.bmp");
	graphfunct.draw_sprite(graphfunct.avy,graphfunct.getx(),graphfunct.gety());
}

void main_functions::clean_up()
{
	SDL_FreeSurface(screen);
}

execute.cpp

#include "main_functions.h"

void main_functions::execute()
{
	start();
	while(running)
	{
		check_event(Event);
		draw();
		SDL_Flip(SDL_GetVideoSurface());
	}
	clean_up();
}
graphic_functions.h

#ifndef GRAPHIC_FUNCTIONS_H_
#define GRAPHIC_FUNCTIONS_H_
#include "sdl.h"
#include "main_functions.h"

class graphic_functions
{
private:
	int playerx;
	int playery;
public:
	//surfaces for optimization
	SDL_Surface* original_image;
	SDL_Surface* optimized_image;

	//actual game graphics
	SDL_Surface* avy;

	graphic_functions();
	void load_image(char* file);
	void prepare_image(char* file);
	void draw_sprite(SDL_Surface* sprite, int x, int y);
	void moveplayer(SDL_Event Event);
	int getx();
	int gety();
	void addx();
	void subtractx();
	void addy();
	void subtracty();
};

#endif
graphic_functions.cpp

#include "graphic_functions.h"

graphic_functions::graphic_functions()
{
	SDL_Surface* original_image = NULL;
	SDL_Surface* optimized_image = NULL;
	SDL_Surface* avy = NULL;
	playerx = 1;
	playery = 1;
}

void graphic_functions::load_image(char* file)
{
	original_image = SDL_LoadBMP(file);
}

void graphic_functions::prepare_image(char* file)
{
	load_image(file);
	optimized_image = SDL_DisplayFormat(original_image);
	avy = optimized_image;
}

void graphic_functions::draw_sprite(SDL_Surface* sprite, int x, int y)
{
	main_functions mainfunct;

	SDL_Rect rect;
	rect.x = x;
	rect.y = y;
	SDL_BlitSurface(sprite,NULL,SDL_GetVideoSurface(),&rect);
}

int graphic_functions::getx()
{
	return playerx;
}

int graphic_functions::gety()
{
	return playery;
}

void graphic_functions::addx()
{
	playerx++;
}

void graphic_functions::addy()
{
	playery++;
}

void graphic_functions::subtractx()
{
	playerx--;
}

void graphic_functions::subtracty()
{
	playery--;
}


So, anybody know what's up? [Edited by - Last Hylian on September 10, 2009 8:12:57 PM]
Advertisement
You need to call SDL_Flip whenever you want to update the screen.
Ah, crap I knew that, ok thanks.

EDIT: Ok, I added it and updated original post, but it's still not working. Did I put it in the right place?
Hm, after taking a closer look at your code (should have noticed this earlier, sorry :s ), it seems you're declaring another main_functions instance in graphic_functions::draw_sprite -- but its SDL_Surface* screen pointer won't be the same as the one used everywhere else (in fact it'll be NULL)
You should probably structure your code a bit differently, but a quick workaround for now would be to use SDL_GetVideoSurface() to get a pointer to the screen rather than trying to access the one held by mainfunct
Alright, all fixed, any advice as to where I place the screen surface?
You have scope issues it looks like.

Another thing is that every time you are calling yr draw() method, you are reloading the image into a surface (see yr prepare_image() method). This is not good since every time you are drawing the image you are reloading it from file!

Also, use

[*source][*/source] tags when posting code.
Just remove the *'s in the tags. Quote this post to see how or read FAQ.

[Edited by - signal_ on September 9, 2009 10:39:12 PM]
Alright, I'll fix those tags in the original post. Ok, and, sorry, but I have one more question. I figured better to ask it here than start a new thread. Again, I'm quite new to this, so I'm there are a few I'm trying a few basic things and, though it's not returning any errors, it's just not working. Because of that, I really have nothing I can do but ask for help. I'll update the original post. Now I'm working on being able to move the image I just blitted around the screen, I think my logic is sound, but apparently it isn't adequate. I didn't get this from a tutorial, I came up with this method on my own, so I figured I'd probably have to iron out a few posts. Check the original post and see if you see any faults in the code or in the logic behind the code, please. Thanks.
Similar problem -- you're declaring new instances of graphic_functions in both main_functions::check_event and in main_functions::draw. Not only are those not the same instance (so the x and y won't be the same between function calls), but you're declaring them on the stack (i.e. without using new), so they're local to the functions and get deallocated when they go out of scope.
Again, you should probably structure your code a bit differently -- for instance, you can have an instance of graphic_functions be a member of main_functions.

As for your movement logic, it's mostly okay, but notice that you only change the value of x and y when the user presses a key -- if the user holds a key down, the sprite will only move a single pixel. A basic (but helpful) motion tutorial can be found here.
By having an instance of graphic_functions be a member of main_functions, you mean that I should declare that instance along with the functions of the main_function class, right? Because, I'm trying that and seem to be getting an error, so, before I went into the process of trying to fix the error, I wanted to make sure that's what you were advising I do.
Yes, that's what I meant, but it was just one (probably bad, even) possible suggestion -- how you go about structuring your code is up to you (e.g. you could make playerx and playery static and keep the rest as is, or you could move them out graphic_functions entirely since they probably don't really belong there, or you could come up with a completely new class hierarchy, or whatever)
It's not an SDL problem, so you have really any number of ways to deal with that

This topic is closed to new replies.

Advertisement