Some help with sdl

I’m just beginning working with SDL and C++, and I’ve been following some of
the tutorials I found on the libsdl.org web. After finishing them, I decided to
create a class, Engine, to use the basic functions of SDL.

However, when I did this, I no longer can use or see results. When the
functions were on the same cpp file, they work ok. But when I started making
them a class, doing the h file, and a separate cpp for the implementations, now
the only thing I can see is a black windows and then it retorns to windows.

This is the code I use:

Engine.h:

#ifndef ENGINE_H
#define ENGINE_H

//------------- INCLUDES -----------------------

//Initialises the SDL API
#include <SDL/SDL.h>

//------------ !INCLUDES ------------------------

class Engine {
private:

public:
//Initialises the Engine
Engine(); //constructor
~Engine(); //destructor

//Sets the mode for the Game
void Set_Video_Mode(SDL_Surface * screen, int SCREEN_WIDTH, int SCREEN_HEIGHT,
int SCREEN_BPP);

// Draws a Pixel on the Screen. Useful?
void DrawPixel(SDL_Surface * screen,int x, int y,
Uint8 R, Uint8 G, Uint8 B);

//Locks the Screen. Needs to be used before DrawPixel
void Slock(SDL_Surface * screen);

//Unlocks the Screen. After using DrawPixel
void Sulock(SDL_Surface * screen);

//Draws an Image somewhere on the main screen
void DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y);

//Draws a part of an image somewhere on the screen
void DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y,int w, int
h, int x2, int y2);

};

#endif

Engine.cpp:

//------------- INCLUDES -----------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “engine.h”

//------------ !INCLUDES ------------------------

//------------ DECLARATIONS ---------------------

//----------- !DECLARATIONS ---------------------

//---------- FUNCTIONS PROTOTYPES ---------------

//---------- !FUNCTIONS PROTOTYPES --------------

//---------- GLOBAL DECLARATIONS ----------------//

//---------- !GLOBAL DECLARATIONS ---------------//

//>>>>>>>>>> MAIN FUNCTIONS <<<<<<<<<<<<<<<<<<<<<//

//We initialize the engine. Just video for now.
Engine::Engine() {
if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
//If an error occurs (SDL_Init < 0 ) we show the error on a file and exit.
printf(“Unable to init SDL: %s\n”, SDL_GetError());
exit(1);
}
//Whenever we exit, this closes the Engine
atexit(SDL_Quit);
}

//Destructor
Engine::~Engine(){}

//Here we start the main screen. The resolution is the 2 first parameters
//800x600 is which almost an standard ('cause many work with 1024 now…)
void Engine::Set_Video_Mode(SDL_Surface * screen, int SCREEN_WIDTH, int
SCREEN_HEIGHT, int SCREEN_BPP) {
screen = SDL_SetVideoMode
(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREE
N);

//If this is null, then a problem arises. Again, we exit and write the error.
if ( screen == NULL )
{
printf(“Unable to set video: %s\n”,SDL_GetError());
exit(1);
}

}

//Draws an Image somewhere on the main screen
void Engine::DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
SDL_Flip(screen);
}

//Draws a part of an image somewhere on the screen
void Engine::DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y,int
w, int h, int x2, int y2)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.x = x2;
dest2.y = y2;
dest2.w = w;
dest2.h = h;
SDL_BlitSurface(img, &dest2, screen, &dest);
SDL_Flip(screen);
}

//Locks the Screen. Needs to be used before DrawPixel
void Engine::Slock(SDL_Surface * screen)
{
if ( SDL_MUSTLOCK(screen) )
{
if ( SDL_LockSurface(screen) < 0 )
{
return;
}
}
}

//Unlocks the Screen. After using DrawPixel
void Engine::Sulock(SDL_Surface * screen)
{
if ( SDL_MUSTLOCK(screen) )
{
SDL_UnlockSurface(screen);
}
}

// Draws a Pixel on the Screen. Useful?
// Just requires where, coordinates and color
void Engine::DrawPixel(SDL_Surface * screen, int x, int y,Uint8 R, Uint8 G,
Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
switch (screen->format->BytesPerPixel)
{
case 1: // Assuming 8-bpp
{
Uint8 *bufp;
bufp = (Uint8 )screen->pixels + yscreen->pitch + x;
*bufp = color;
}
break;
case 2: // Probably 15-bpp or 16-bpp
{
Uint16 *bufp;
bufp = (Uint16 )screen->pixels + yscreen->pitch/2 + x;
*bufp = color;
}
break;
case 3: // Slow 24-bpp mode, usually not used
{
Uint8 *bufp;
bufp = (Uint8 )screen->pixels + yscreen->pitch + x * 3;
if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
{
bufp[0] = color;
bufp[1] = color >> 8;
bufp[2] = color >> 16;
} else {
bufp[2] = color;
bufp[1] = color >> 8;
bufp[0] = color >> 16;
}
}
break;
case 4: // Probably 32-bpp
{
Uint32 *bufp;
bufp = (Uint32 )screen->pixels + yscreen->pitch/4 + x;
*bufp = color;
}
break;
}
}

//>>>>>>>>>> !MAIN FUNCTIONS <<<<<<<<<<<<<<<<<<<<//

And here is the code where I use the class:

//------------- INCLUDES -----------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “engine.h”
//------------ !INCLUDES ------------------------

//------------ DECLARATIONS ---------------------

//----------- !DECLARATIONS ---------------------

//---------- FUNCTIONS PROTOTYPES ---------------

//---------- !FUNCTIONS PROTOTYPES --------------

//---------- GLOBAL DECLARATIONS ----------------//

//This will paint a background
SDL_Surface *back;

//This will take the box image from a file
SDL_Surface *image;

//Main Screen, where you watch all
SDL_Surface *screen;

Engine engine;

//This are the starting positions of the box
int iXpos=0,iYpos=0;

int SCREEN_HEIGHT(480);
int SCREEN_WIDTH(640);

//---------- !GLOBAL DECLARATIONS ---------------//

//Draws an image filling the screen
void DrawBG()
{
engine.DrawIMG(screen,back, 0, 0);
}

//Draws a scene
void DrawScene()
{

engine.DrawIMG(screen,back, iXpos-8, iYpos-8, 144, 144, iXpos-8, iYpos-8);
engine.DrawIMG(screen,back, 0, 0, 144, 144, iXpos, iYpos);
engine.DrawIMG(screen,back, 144, 144, 144, 144, iXpos, iYpos);
engine.DrawIMG(screen,image, iXpos, iYpos);

SDL_Flip(screen);
}

//Load the images from a file and sets them to Surfaces
int InitImages()
{
//Both graphics must be on the same folder.
back = SDL_LoadBMP(“bg.bmp”);
image = SDL_LoadBMP(“image.bmp”);
return 0;
}

//>>>>>>>>>> MAIN GAME CODE <<<<<<<<<<<<<<<<<<<<<//

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

//We start the Engine
engine.Set_Video_Mode(screen,SCREEN_WIDTH,SCREEN_HEIGHT,32);

//Now that everything is ok, we initialize the images…
InitImages();

DrawBG();

SDL_Flip(screen);

DrawBG();
SDL_Flip(screen);

//To move the character, we use the variable keys
Uint8* uKeys;

//Here we’ll check all the events that occur on the game
while(1)
{
SDL_Event event;

 while ( SDL_PollEvent(&event) )
 {
   if ( event.type == SDL_QUIT )  {  return 0;  }

   if ( event.type == SDL_KEYDOWN ) 
   {
     if ( event.key.keysym.sym == SDLK_ESCAPE ) { return 0; }
   }
 }
 uKeys = SDL_GetKeyState(NULL);
 if ( uKeys[SDLK_UP] ) { if (iYpos > 0) {iYpos -= 4;} }
 if ( uKeys[SDLK_DOWN] ) { if((iYpos+image->h)<screen->h){iYpos += 4; }}
 if ( uKeys[SDLK_LEFT] ) { if (iXpos > 0){iXpos -= 4; }}
 if ( uKeys[SDLK_RIGHT] ) {if ((iXpos+image->w<screen->w)) {iXpos += 4; }}

 DrawScene();  

 SDL_Flip(screen);

}

return 0;
}

//>>>>>>>>>> !MAIN GAME CODE <<<<<<<<<<<<<<<<<<<<//

//------------ END OF FILE -----------------------

I really need help for this, 'cause I’m working on creating my second rpg
engine, and I’d like to use SDL in this.

You can help me writing to my email: @Alvaro_Pereyra or
meriadoc2k2 at hotmail.com

Thanks in advance.

This is a lot of code to read. Try to reproduce your problem with less
code. Or make some tests during coding, and not once you have writen
1000 lines.

Julien

I think it might be related to the fact that you aren’t
calling SDL_UpdateRects().

Another thing, why are you calling SDL_Flip() so
many times? It will slow down your code to change
buffers with that frequency.

Cheers,
Paulo Pinto

Alvaro Pereyra wrote:>I’m just beginning working with SDL and C++, and I’ve been following some of

the tutorials I found on the libsdl.org web. After finishing them, I decided to
create a class, Engine, to use the basic functions of SDL.

However, when I did this, I no longer can use or see results. When the
functions were on the same cpp file, they work ok. But when I started making
them a class, doing the h file, and a separate cpp for the implementations, now
the only thing I can see is a black windows and then it retorns to windows.

This is the code I use:

Engine.h:

#ifndef ENGINE_H
#define ENGINE_H

//------------- INCLUDES -----------------------

//Initialises the SDL API
#include <SDL/SDL.h>

//------------ !INCLUDES ------------------------

class Engine {
private:

public:
//Initialises the Engine
Engine(); //constructor
~Engine(); //destructor

//Sets the mode for the Game
void Set_Video_Mode(SDL_Surface * screen, int SCREEN_WIDTH, int SCREEN_HEIGHT,
int SCREEN_BPP);

// Draws a Pixel on the Screen. Useful?
void DrawPixel(SDL_Surface * screen,int x, int y,
Uint8 R, Uint8 G, Uint8 B);

//Locks the Screen. Needs to be used before DrawPixel
void Slock(SDL_Surface * screen);

//Unlocks the Screen. After using DrawPixel
void Sulock(SDL_Surface * screen);

//Draws an Image somewhere on the main screen
void DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y);

//Draws a part of an image somewhere on the screen
void DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y,int w, int
h, int x2, int y2);

};

#endif

Engine.cpp:

//------------- INCLUDES -----------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “engine.h”

//------------ !INCLUDES ------------------------

//------------ DECLARATIONS ---------------------

//----------- !DECLARATIONS ---------------------

//---------- FUNCTIONS PROTOTYPES ---------------

//---------- !FUNCTIONS PROTOTYPES --------------

//---------- GLOBAL DECLARATIONS ----------------//

//---------- !GLOBAL DECLARATIONS ---------------//

//>>>>>>>>>> MAIN FUNCTIONS <<<<<<<<<<<<<<<<<<<<<//

//We initialize the engine. Just video for now.
Engine::Engine() {
if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
//If an error occurs (SDL_Init < 0 ) we show the error on a file and exit.
printf(“Unable to init SDL: %s\n”, SDL_GetError());
exit(1);
}
//Whenever we exit, this closes the Engine
atexit(SDL_Quit);
}

//Destructor
Engine::~Engine(){}

//Here we start the main screen. The resolution is the 2 first parameters
//800x600 is which almost an standard ('cause many work with 1024 now…)
void Engine::Set_Video_Mode(SDL_Surface * screen, int SCREEN_WIDTH, int
SCREEN_HEIGHT, int SCREEN_BPP) {
screen = SDL_SetVideoMode
(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREE
N);

//If this is null, then a problem arises. Again, we exit and write the error.
if ( screen == NULL )
{
printf(“Unable to set video: %s\n”,SDL_GetError());
exit(1);
}

}

//Draws an Image somewhere on the main screen
void Engine::DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
SDL_Flip(screen);
}

//Draws a part of an image somewhere on the screen
void Engine::DrawIMG(SDL_Surface * screen, SDL_Surface *img, int x, int y,int
w, int h, int x2, int y2)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.x = x2;
dest2.y = y2;
dest2.w = w;
dest2.h = h;
SDL_BlitSurface(img, &dest2, screen, &dest);
SDL_Flip(screen);
}

//Locks the Screen. Needs to be used before DrawPixel
void Engine::Slock(SDL_Surface * screen)
{
if ( SDL_MUSTLOCK(screen) )
{
if ( SDL_LockSurface(screen) < 0 )
{
return;
}
}
}

//Unlocks the Screen. After using DrawPixel
void Engine::Sulock(SDL_Surface * screen)
{
if ( SDL_MUSTLOCK(screen) )
{
SDL_UnlockSurface(screen);
}
}

// Draws a Pixel on the Screen. Useful?
// Just requires where, coordinates and color
void Engine::DrawPixel(SDL_Surface * screen, int x, int y,Uint8 R, Uint8 G,
Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
switch (screen->format->BytesPerPixel)
{
case 1: // Assuming 8-bpp
{
Uint8 *bufp;
bufp = (Uint8 )screen->pixels + yscreen->pitch + x;
*bufp = color;
}
break;
case 2: // Probably 15-bpp or 16-bpp
{
Uint16 *bufp;
bufp = (Uint16 )screen->pixels + yscreen->pitch/2 + x;
*bufp = color;
}
break;
case 3: // Slow 24-bpp mode, usually not used
{
Uint8 *bufp;
bufp = (Uint8 )screen->pixels + yscreen->pitch + x * 3;
if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
{
bufp[0] = color;
bufp[1] = color >> 8;
bufp[2] = color >> 16;
} else {
bufp[2] = color;
bufp[1] = color >> 8;
bufp[0] = color >> 16;
}
}
break;
case 4: // Probably 32-bpp
{
Uint32 *bufp;
bufp = (Uint32 )screen->pixels + yscreen->pitch/4 + x;
*bufp = color;
}
break;
}
}

//>>>>>>>>>> !MAIN FUNCTIONS <<<<<<<<<<<<<<<<<<<<//

And here is the code where I use the class:

//------------- INCLUDES -----------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “engine.h”
//------------ !INCLUDES ------------------------

//------------ DECLARATIONS ---------------------

//----------- !DECLARATIONS ---------------------

//---------- FUNCTIONS PROTOTYPES ---------------

//---------- !FUNCTIONS PROTOTYPES --------------

//---------- GLOBAL DECLARATIONS ----------------//

//This will paint a background
SDL_Surface *back;

//This will take the box image from a file
SDL_Surface *image;

//Main Screen, where you watch all
SDL_Surface *screen;

Engine engine;

//This are the starting positions of the box
int iXpos=0,iYpos=0;

int SCREEN_HEIGHT(480);
int SCREEN_WIDTH(640);

//---------- !GLOBAL DECLARATIONS ---------------//

//Draws an image filling the screen
void DrawBG()
{
engine.DrawIMG(screen,back, 0, 0);
}

//Draws a scene
void DrawScene()
{

engine.DrawIMG(screen,back, iXpos-8, iYpos-8, 144, 144, iXpos-8, iYpos-8);
engine.DrawIMG(screen,back, 0, 0, 144, 144, iXpos, iYpos);
engine.DrawIMG(screen,back, 144, 144, 144, 144, iXpos, iYpos);
engine.DrawIMG(screen,image, iXpos, iYpos);

SDL_Flip(screen);
}

//Load the images from a file and sets them to Surfaces
int InitImages()
{
//Both graphics must be on the same folder.
back = SDL_LoadBMP(“bg.bmp”);
image = SDL_LoadBMP(“image.bmp”);
return 0;
}

//>>>>>>>>>> MAIN GAME CODE <<<<<<<<<<<<<<<<<<<<<//

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

//We start the Engine
engine.Set_Video_Mode(screen,SCREEN_WIDTH,SCREEN_HEIGHT,32);

//Now that everything is ok, we initialize the images…
InitImages();

DrawBG();

SDL_Flip(screen);

DrawBG();
SDL_Flip(screen);

//To move the character, we use the variable keys
Uint8* uKeys;

//Here we’ll check all the events that occur on the game
while(1)
{
SDL_Event event;

while ( SDL_PollEvent(&event) )
{
  if ( event.type == SDL_QUIT )  {  return 0;  }

  if ( event.type == SDL_KEYDOWN ) 
  {
    if ( event.key.keysym.sym == SDLK_ESCAPE ) { return 0; }
  }
}
uKeys = SDL_GetKeyState(NULL);
if ( uKeys[SDLK_UP] ) { if (iYpos > 0) {iYpos -= 4;} }
if ( uKeys[SDLK_DOWN] ) { if((iYpos+image->h)<screen->h){iYpos += 4; }}
if ( uKeys[SDLK_LEFT] ) { if (iXpos > 0){iXpos -= 4; }}
if ( uKeys[SDLK_RIGHT] ) {if ((iXpos+image->w<screen->w)) {iXpos += 4; }}

DrawScene();  

SDL_Flip(screen);

}

return 0;
}

//>>>>>>>>>> !MAIN GAME CODE <<<<<<<<<<<<<<<<<<<<//

//------------ END OF FILE -----------------------

I really need help for this, 'cause I’m working on creating my second rpg
engine, and I’d like to use SDL in this.

You can help me writing to my email: alvaro at epic-worlds.com or
meriadoc2k2 at hotmail.com

Thanks in advance.


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

I’m just beginning working with SDL and C++, and I’ve been following some
of the tutorials I found on the libsdl.org web. After finishing them, I
decided to create a class, Engine, to use the basic functions of SDL.

However, when I did this, I no longer can use or see results. When the
functions were on the same cpp file, they work ok. But when I started
making them a class, doing the h file, and a separate cpp for the
implementations, now the only thing I can see is a black windows and then
it retorns to windows.

This is the code I use:

<snip!>

I really need help for this, 'cause I’m working on creating my second rpg
engine, and I’d like to use SDL in this.

You can help me writing to my email: alvaro at epic-worlds.com or
meriadoc2k2 at hotmail.com

Thanks in advance.

A few problems.

void Engine::Set_Video_Mode(SDL_Surface *screen, int SCREEN_WIDTH, int
SCREEN_HEIGHT, int SCREEN_BPP);

Stylistically, you shouldn’t be using SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP
as variable names. Uppercase indicates a macro. Unless you have a very good
reason (backwards compatability, say) this will confuse others.

More importantly, you are trying to ‘return’ the value of ‘screen’ for use in
other parts of the program. Why not actually return it instead of void?

SDL_Surface *Engine::Set_Video_Mode( int width, int height, int bpp )
{
int flags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN;

return SDL_SetVideoMode(width, height, bpp, flags); 

}

Call like this:

screen = engine.Set_Video_Mode(SCREEN_WIDTH, SCREEN_HEIGHT, 32);

You could put your test here if you want, but doing an exit() will prove to be
a bit drastic in the long term!

Alternatively, you could fix the definition of the function:

void Engine::Set_Video_Mode(SDL_Surface **screen, int SCREEN_WIDTH, int
SCREEN_HEIGHT, int SCREEN_BPP)
{
int flags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN;

*screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, flags);
if ( *screen == NULL )
{
printf(“Unable to set video: %s\n”,SDL_GetError());
exit(1);
}
}

Notice the extra '*'s, and call it like this:

engine.Set_Video_Mode( &screen, SCREEN_WIDTH, SCREEN_HEIGHT, 32);

I think of this as passing a pointer to place you want the function to write
the result into.

Of course, all this is just hiding the OO design flaw. Why isn’t ‘screen’ part
of the engine class?

class Engine {
private:
SDL_Surface *m_screen;
public:
Engine();
~Engine();
public:
int Set_Video_Mode(int width, int height, int bpp);
void Flip();

};

Engine::Engine() : m_screen(0)
{

}

int Engine::Set_Video_Mode( int width, int height, int bpp )
{
int flags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN;

m_screen = SDL_SetVideoMode(width, height, bpp, flags);
return m_screen != NULL;

}

void Engine::Flip()
{
SDL_Flip(m_screen);
}

void Engine::DrawIMG(SDL_Surface *img, int x, int y,
int w, int h, int x2, int y2)
{

}

Suddenly all those functions with screen as a first parameter become a bit
clearer,

Good luck,
cheers,
John Popplewell.On Tuesday 02 March 2004 8:29 pm, Alvaro Pereyra wrote:


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl