SDL Doesn't display image, but everything seems fine

Well here’s the thing, there is a tutorial series posted on libSDL that is made by LazyFoo.
After a while of messing with SDL my friend asked me to make him a simple platformer.
just to give him a quick result, I one of LazyFoo’s tutorials and started to modify it and just put it in classes and stuff.
Why I tell you this? because it worked. the tutorial with the same files, worked.
but since I started putting it into classes, it all broke, It’s my second week I think of trying to fix all the mistakes I do (I am kind of a newbie).
Now after a long frustrating weekend, I decided to turn to this forum for help:

My images, the ones I mentioned before, just won’t show. I went trough the code a dozen of times and a few tens of times with the debugger, and couldn’t find where I am wrong. also, as I mentioned before, the images did display when the code was without the classes, so “file is missing” is not the problem.

There is not much code, but I broke it down to what I see important, tell me if you need the rest:

Main.cpp:
Code:
//The headers
#include “SDL.h”
#include “SDL_image.h”
#include
#include “timer.h”
#include “graphic.h”
#include “dot.h”
#include “main.h”

//The surfaces
Graphic screen;
Graphic background;
Dot dot;

//The event structure
SDL_Event event;

bool init()
{
if(SDL_Init(SDL_INIT_EVERYTHING) == -1) return false;
screen.image = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
if(screen.image == NULL) return false;
SDL_WM_SetCaption(“Move the Dot”, NULL);
return true;
}

int main( int argc, char* args[] )
{
bool quit = false;
Dot myDot;
Timer fps;
if(!init()) return 1;

//Load the files
if((background.load_image("bg.png") == NULL) && (dot.load_image("dot.bmp") == NULL)) return 2;

//While the user hasn't quit
while(quit == false)
{
    fps.start();
    while(SDL_PollEvent(&event))
    {
		myDot.handle_input(event);
        if(event.type == SDL_QUIT) quit = true;
    }
    myDot.move();
    myDot.set_camera();
    background.apply_surface(0, 0, screen.image, &camera);
    myDot.show(screen.image);

    if(SDL_Flip(screen.image)) return 3;

    //Cap the frame rate
    if(fps.get_ticks() < 1000 / FRAMES_PER_SECOND)
    {
        SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
    }
}
SDL_Quit();
return 0;

}

main.h:

Code:
#ifndef CHK_MAIN
#define CHK_MAIN

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The frame rate
const int FRAMES_PER_SECOND = 20;

//The dot dimensions
const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 45;

//The dimensions of the level
const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;

//The camera
static SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
#endif

graphic.h:

Code:
#ifndef CHK_GRAPHIC
#define CHK_GRAPHIC

#include
class Graphic
{
public:
SDL_Surface* image;
void kill()
{SDL_FreeSurface(image);};
bool load_image(const char* filename);
void apply_surface(int x, int y, SDL_Surface* image, SDL_Rect* clip = NULL);
};
#endif

graphic.cpp:

Code:
#include “SDL.h”
#include “SDL_image.h”
#include “graphic.h”

bool Graphic::load_image(const char* filename)
{
image = IMG_Load(filename); //The image that’s loaded
if(image == NULL) return(false);
image = SDL_DisplayFormat(image);
SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 0, 0xFF, 0xFF));
if(image == NULL) return(false);
return(true);
}

void Graphic::apply_surface(int x, int y, SDL_Surface* image, SDL_Rect* clip)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;

SDL_BlitSurface(image, clip, image, &offset);

}

dot.h:

Code:
#ifndef CHK_DOT
#define CHK_DOT

#include “SDL.h”
#include “graphic.h”

class Dot: public Graphic
{
private:
int x, y; //The X and Y offsets of the dot
int xVel, yVel; //The velocity of the dot
public:
Dot(); //Initializes the variables
void handle_input(SDL_Event &event); //Takes key presses and adjusts the dot’s velocity
void move(); //Moves the dot
void show(SDL_Surface* surface_screen); //Shows the dot on the screen
void set_camera(); //Sets the camera over the dot
};
#endif

dot.cpp:

Code:
#include “dot.h”
#include “main.h”

Dot::Dot()
{
x = 0; //Initialize the offsets
y = 0;
xVel = 0; //Initialize the velocity
yVel = 0;
}

void Dot::handle_input(SDL_Event &event)
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel -= DOT_HEIGHT / 2; break;
case SDLK_DOWN: yVel += DOT_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= DOT_WIDTH / 2; break;
case SDLK_RIGHT: xVel += DOT_WIDTH / 2; break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel += DOT_HEIGHT / 2; break;
case SDLK_DOWN: yVel -= DOT_HEIGHT / 2; break;
case SDLK_LEFT: xVel += DOT_WIDTH / 2; break;
case SDLK_RIGHT: xVel -= DOT_WIDTH / 2; break;
}
}
}

void Dot::move()
{
//Move the dot left or right
x += xVel;

//If the dot went too far to the left or right
if( ( x < 0 ) || ( x + DOT_WIDTH > LEVEL_WIDTH ) )
{
    //move back
    x -= xVel;
}

//Move the dot up or down
y += yVel;

//If the dot went too far up or down
if( ( y < 0 ) || ( y + DOT_HEIGHT > LEVEL_HEIGHT ) )
{
    //move back
    y -= yVel;
}

}

void Dot::show(SDL_Surface* surface_screen)
{
//Show the dot
apply_surface(x - camera.x, y - camera.y, surface_screen);
}

void Dot::set_camera()
{
//Center the camera over the dot
camera.x = ( x + DOT_WIDTH / 2 ) - SCREEN_WIDTH / 2;
camera.y = ( y + DOT_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;

//Keep the camera in bounds.
if( camera.x < 0 )
{
    camera.x = 0;
}
if( camera.y < 0 )
{
    camera.y = 0;
}
if( camera.x > LEVEL_WIDTH - camera.w )
{
    camera.x = LEVEL_WIDTH - camera.w;
}
if( camera.y > LEVEL_HEIGHT - camera.h )
{
    camera.y = LEVEL_HEIGHT - camera.h;
}

}------------------------
Step into my world… Now find a parachute, as it’s going to be a loooooong fall.

Hi,

In Graphic::apply_surface(), you pass the “image” local parameter as both
arguments to SDL_BlitSurface(). I imagine the “source” parameter was
intended to be Graphic::image. One solution is to use this->image, another
is to rename the parameter to avoid shadowing the member variable (
http://en.wikipedia.org/wiki/Variable_shadowing)

This problem is unrelated to SDL, it is a regular C++ problem. It just
happens to manifest through SDL. If you have a general programming question,
there are general programming sites, forums and mailing lists you should
use. An example is www.gamedev.net, of which the LazyFoo tutorial writers
was an active member.

Regards,
– Brian.On 24 September 2011 23:48, heptanitrocube wrote:

**
Well here’s the thing, there is a tutorial series posted on libSDL that is
made by LazyFoo.
After a while of messing with SDL my friend asked me to make him a simple
platformer.
just to give him a quick result, I one of LazyFoo’s tutorials and started
to modify it and just put it in classes and stuff.
Why I tell you this? because it worked. the tutorial with the same files,
worked.
but since I started putting it into classes, it all broke, It’s my second
week I think of trying to fix all the mistakes I do (I am kind of a newbie).
Now after a long frustrating weekend, I decided to turn to this forum for
help:

heptanitrocube wrote:

Main.cpp:

Code:


bool init()
{
if(SDL_Init(SDL_INIT_EVERYTHING) == -1) return false;
screen.image = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
if(screen.image == NULL) return false;
SDL_WM_SetCaption(“Move the Dot”, NULL);
return true;
}

The one thing I would check for. In your Init, you aren’t passing the flag SDL_DOUBLEBUF, so SDL_Flip shouldn’t actually do anything. You’d have to use SDL_UpdateRect. I didn’t see where the “draw to the screen” code was. Since everything else works, I’d ensure you are using the right function to refresh the screen.

Check it out and let us know what you find out.

  • Micah

Hi,

For non double-buffered surfaces, SDL_Flip() is the same as calling
SDL_UpdateRect for the entire size of the screen.

– BrianOn 5 October 2011 16:57, MBrening <micah.brening at gmail.com> wrote:

**

The one thing I would check for. In your Init, you aren’t passing the flag
SDL_DOUBLEBUF, so SDL_Flip shouldn’t actually do anything. You’d have to use
SDL_UpdateRect. I didn’t see where the “draw to the screen” code was. Since
everything else works, I’d ensure you are using the right function to
refresh the screen.

Check it out and let us know what you find out.

  • Micah

Brian Barrett wrote:

Hi,

For non double-buffered surfaces, SDL_Flip() is the same as calling SDL_UpdateRect for the entire size of the screen.

– Brian

Really? Oops! I wasn’t aware of that. That’s good to know.

Den 25. sep. 2011 00:48, skrev heptanitrocube:

//Load the files
if((background.load_image(“bg.png”) == NULL) &&
(dot.load_image(“dot.bmp”) == NULL)) return 2;

There’s a bug here. “dot.bmp” is only loaded if “bg.png” fails to load,
because the if-condition short-circuits (the first condition is false,
so it’s all false, and the second load_image is never called). Change
the ‘&&’ to ‘||’ to fix this.

(Also, load_image returns a bool, not a pointer)

You’re also blitting images to themselves, but Brian Barrett covered that.

-g