Pablo
Pablo

Reputation: 1481

SDL fail to load media using files and headers

I just started following Lazy Foo's SDL tutorial. My question regards the code in lesson 02, so I assume this is quite basic. I have to say that I don't have too much C++ experience either!

The code provided by Lazy Foo works fine in my machine (Windows-Code::Blocks). However, as an exercise I tried to move the example's functions to a separate file (with the corresponding header file). I also moved variables into main, so as to avoid globals. The only real change I needed to implement was to include some input variables for my functions, since I would not be relying on globals.

My code compiles, but it fails to upload the image as required. Here you have the code of the simple function:

bool loadMedia(SDL_Surface* gHelloWorld) {
//Loading success flag
bool success = true;

//Load splash image
gHelloWorld = SDL_LoadBMP("hello_world.bmp");
if(gHelloWorld == NULL) {
    printf("Unable to load image %s! SDL Error: %s\n", "hello_world.bmp",
        SDL_GetError());
    success = false;
}

return success;

And this is the bit where I call that function:

    if(!loadMedia(gHelloWorld)) {
        printf( "Failed to load media!\n" );
    } else {
        //Apply the image
        SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

        //Update the surface
        SDL_UpdateWindowSurface( gWindow );

        //Wait two seconds
        SDL_Delay( 2000 );
    }

Using the debugger I noticed gHelloWorld never updates its value, unlike in the original example given by Lazy Foo. Since gHelloWorld is a pointer I believed this should work fine.

What is going on here?

Thank you very much for your help!

Pablo

Upvotes: 2

Views: 772

Answers (1)

Chris
Chris

Reputation: 4231

You need another pointer level to actually modify the variable in the calling function:

bool loadMedia(SDL_Surface** gHelloWorld) {
    ...
    *gHelloWorld = SDL_LoadBMP("hello_world.bmp");
    if(*gHelloWorld == NULL) {
    ...

and call it like this:

SDL_Surface *gHelloWorld;
if(!loadMedia(&gHelloWorld)) {

Explanation: In C, there is little to no behind-the-scenes magic when using pointers. SDL_LoadBMP creates a new SDL_Surface and returns a pointer to that surface. Your function only stored that pointer (i.e. the address) in a local variable, but did not not modify the variable in the calling function. To do that, you need to pass the address of the variable in the calling function using the & operator, and store the value in the pointer at that address, using *.

The code in lazy foo's example worked because gHelloWorld is a global variable there.

Since you are using C++, you could also use reference parameters (which do a little behind-the-scenes magic).

Upvotes: 1

Related Questions