SDL: Graphics not loading while in a header?

Started by
5 comments, last by DestX 15 years, 4 months ago
I just tried moving a class I wrote in a main function onto a header file(It worked in the main) which includes using of SDL for graphic management. This is the code I use to load the sprite from "Hero.cpp", having all the variables defined in "Hero.cpp" and in the main program code file, passed as arguments of the function(The SDL_Surfaces):
void Hero::printSpriteset(SDL_Surface *screen, SDL_Surface *head, SDL_Surface *body, SDL_Surface *legR,
		SDL_Surface *handR, SDL_Surface *legL, SDL_Surface *handL){
	SDL_Rect source1;
		source1.x = 0;
		source1.y = 0;
		source1.w = 16;
		source1.h = 16;

	SDL_Rect destination1;
		destination1.x = (heroX+((headW-bodyW)/2)+1);
		destination1.y = (heroY+headH-2);
		destination1.w = 16;
		destination1.h = 16;

	SDL_BlitSurface(body, &source1, screen, &destination1);
...
}
This is repeated for 6 sprites but I cut it down as they're all similiar. The heroX, headW, etc. variables are members of this class so they didn't need forwarding, as far as I know. And the surfaces for the sprites have been filled in a different function in the same class. An extract from the function:
else if(weightM || weightF){
				head = IMG_Load("HeadLV10Weight.png");
				body = IMG_Load("BodyLV10WeightAll.png");
				legR = IMG_Load("LegLV10WeightAllR.png");
				handR = IMG_Load("HandLV10WeightAllR.png");
				legL = IMG_Load("LegLV10WeightAllL.png");
				handL = IMG_Load("HandLV10WeightAllL.png");
				handW = 4; handH = 6; headW = 11; headH = 9; bodyW = 7; bodyH = 6; legW = 6; legH = 5;
			}
So as you can see, it should, and did until I moved it onto a header file, load fine. It compiles fine and all with no errors and the variables inside the class that's in the header work fine as well(Monitoring through the console box), the only problem is that when it comes to printing the graphics, it just ignores it and the sprites aren't shown even though the program goes on. Any help you can offer? Thanks in advance.
Advertisement
Are you 100% sure that the IMG_Load() statements are executing?

How is the caller of printSpriteset getting these variables, if they are loaded inside some member function of Hero?
Quote:Original post by rip-off
Are you 100% sure that the IMG_Load() statements are executing?

How is the caller of printSpriteset getting these variables, if they are loaded inside some member function of Hero?


No, I didn't check that...

After your post I did go and add a cout line to print to the console the value of one of Surfaces I IMG_Load() to, and it shows a bunch of 0's, I suppose that means it's empty, so that's probably the problem. These surfaces aren't inside the class either, you might be on to something.

As for the second question, the function is called upon from the main code page in which the variables were declared.

Do you mean that if I load the values to the Surfaces inside a class member function they won't realize they were changed in the main code?

If so, how do I pass it onto them without using return, so I won't have to break the function into 6. Or rather, is there a way to declare SDL_Surfaces as class members? When I tried earlier it gave me an error saying "Class member variables can only be static const integers" or something like that, is there a way to bypass that?


Btw, off-topic but, I've been away from these boards for a while, can you remind me how to wrap my code in that scrolling box? What was the []command for it again? ^^'

*Edit:
Just tried again and it let me put the SDL_Surfaces as class members now, no idea why. Though the same problem persists, it still shows 0000000000 as value for the Surface and still loads nothing even though it now uses a member of itself for the function.
Yes, parameters are passed by value. This means that changes made inside a function to the parameters are not visible in the calling function.

Simple example:
void addone(int x){   ++x;}int main(){   int var = 13;   addone(var);   // var still equal to 13 here}


More complex example, closer to what you were doing:
void set_null(int *p){    p = 0;}int main(){    int x;    int *p = &x;    set_null(p);    // p still holds the address of x}


You could have them as class members. This way you must allocate storage for them, and they must be explicitly initialised by some function (because you cannot call IMG_Load() before initialising SDL and SDL_Image):
// header file hero.hclass Hero{public:    static void loadImages();    static void freeImages();private:    static SDL_Surface *head, *body, *legR, *handR, *legL, *handL;};// source file hero.cpp#include "hero.h"SDL_Surface *Hero::head = 0;SDL_Surface *Hero::body = 0;SDL_Surface *Hero::legR = 0;SDL_Surface *Hero::handR = 0;SDL_Surface *Hero::legL = 0;SDL_Surface *Hero::handL = 0;void Hero::loadImages(){     // this function needs error checking     head = IMG_Load("HeadLV10Weight.png");     body = IMG_Load("BodyLV10WeightAll.png");     legR = IMG_Load("LegLV10WeightAllR.png");     handR = IMG_Load("HandLV10WeightAllR.png");     legL = IMG_Load("LegLV10WeightAllL.png");     handL = IMG_Load("HandLV10WeightAllL.png");}void Hero::freeImages(){     // lots of calls to SDL_FreeSurface() =)}


There are other ways to achieve the same thing, but this is relatively simple.
I must've edited too late.
I already tried moving these to be class members, and did pretty much exactly what you suggested now, the only difference being that I initialized the surfaces inside the class' constructor and as "head = 0; body = 0;" etc, instead of SDL_Surface *Hero::head = 0;. Is that supposed to make a difference?

*Edit: I tried adding to the console monitoring this:
Quote:int i = 0, ii = 0;
if(IMG_Load("HeadLV1.png") == NULL) ii = 1;
hero.head = IMG_Load("HeadLV1.png");
if(head.head == NULL) i = 1;
std::cout << head << " " << ii << " " << i << std::endl;


result is:
000000000 0 0

so the IMG_Load() does work, and the Surface realizes it got the picture inside it, yet it's not displayed... why?

[Edited by - DestX on December 20, 2008 12:03:54 PM]
If they are class members (declared static), then initialising them in the constructor is dangerous. What happens when another instance of the class is constructed?

If they aren't class members, then that way is fine. Just be aware that every Hero instance is going to load the same artwork, which means you are going to have lots of copies of those images in memory.

Quote:
int i = 0, ii = 0;
if(IMG_Load("HeadLV1.png") == NULL) ii = 1;
hero.head = IMG_Load("HeadLV1.png");
if(head.head == NULL) i = 1;
std::cout << head << " " << ii << " " << i << std::endl;


This is confusing code, I suspect it isn't the actual code you have written. In particular the "head.head" part makes me suspicious. Where is "hero" declared? What about "head". Can you post the actual code?
Nono, I just wrote it here instead of copying from VS.
It's supposed to be hero.head, not head.head =S
Hero hero; is declared a bit back in the code.
And no, this isn't the actual code, I just made it so I can get outputs of the process to the console window for a bit simpler and faster way of debugging.

Anyway, the new problem I created by putting them in the class was that I forgot to remove the original ones from the main code and change the ones in the calling to the function from head to hero.head. So they DID exist, yet were empty and therefore both didn't alert me and didn't display anything.

Thanks alot for your help, really saved me.

And btw, I am aware of it creating these sprites for every instance of Hero, when I first wrote the class I wasn't finished with my algorithms yet and didn't know exactly what I was going to do, but I was bored and had enough material to start work on this class with, so I called it Hero, but in actuallity, it's going to be the template for every character sprite in the game, and later on I'll add a function that realizes which one is the player and sets control to them. A more accurate name would be Character for the class, but I suppose it doesn't really matter that much and can be changed easily.

Well, thanks again for your help.

This topic is closed to new replies.

Advertisement