Public Group

# Game running very slow!

This topic is 4493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey, lately I have been doing a lot of work on my game. Today, I go and test it out more, with the main character moving around, a scrolling background, and a little grass scrolling faster then the background, to give a depth effect. Ok...so there are 3 images up on the screen, and the biggest one is only 640X480. When I run the game in windowed mode it seems to work fine...but the grass that is scrolling blinks really fast at random times. I go and run the game fullscreen, and the game is running at no more then 2 FPS it seems like (I am being very serious)! That is a huge problem! I don't understand how that is! So...I have been searching through my code...and I don't see anything that should be slowing it down nearly that much. So, I will show you my code that is in my main file. Language: C++ API: SDL Ghost Boy.cpp
//this is Ghost Boy.cpp
#include "Ghost Boy.h"
#include "Level.h"
#include "Layer.h"
#include "Sprite.h"
#include "Character.h"

//so text can be inside the console
#ifdef main
#undef main
#endif

//now we create all instances
//create instances here

//the test level instance
Level test;
//one of the layers instances
Layer layer1(5);
Character sprite;

//now we start the application with the main function
int main(int argc, char* argv[])
{
//Init SDL using the SDL_Init function
//Init only the video subsystem of SDL
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface* mainScreen;
//now we set up the screen calling SDL_SetVideoMode
//make it fullscreen, use hardware surface for memory, and use double buff
mainScreen=SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);
//now we set the caption of the window
SDL_WM_SetCaption(TITLE, 0);
//now get a snapshot of the current keystate
Uint8* keysheld=SDL_GetKeyState(0);
//create an event
SDL_Event event;
//now that we have used the getkeystate function, just use an array
//to do the keys
//now to make sure it loops
//set done to false because it needs to loop
bool done=false;
/*when the main menu is done
*that function will go here
*
*
*/
//now we start the main game loop
//loop while done is false
cout<<"window is created, now enter game loop"<<endl;
test.CreateLevel("Backgrounds/rainclouds.png", 0);
layer1.CreateLayer("Backgrounds/grass.png", 640, 205, 0, 400);
sprite.Create("Sprites/testchara1.bmp");
sprite.Setup(128, 128, 200, 300-128, 0, 0);
while(!done)
{
//now start the event loop
while(SDL_PollEvent(&event))
{
//if the event is type quit, then done is true
//and we exit the game loop
if(event.type==SDL_QUIT)
{
done=true;
}
//now let check the main character input
sprite.Move(event);
//now we done with event loop
//exit event loop
}
//now we see if the person pressed the "escape" key
if(keysheld[SDLK_ESCAPE])
{
cout<<"escape pressed"<<endl;
done=true;
}
test.DrawLevel();
//now scroll the test level
test.Scroll(1);
layer1.ApplyLayer();
//now scroll the layer
layer1.ScrollLayer();
//now update the sprite
sprite.Update();
//now draw the test sprite
sprite.Draw();
//now flip the main surface every loop
SDL_Flip(mainScreen);
//now exit the main game loop
}
test.FreeLevel();
layer1.FreeLayer();
sprite.Free();
//now we are done, and now quit SDL
cout<<"now we are done, and now quit SDL"<<endl;
//now we quit SDL.
SDL_Quit();
//return 0, so we know no errors occured
return 0;
}

//the ApplySurface function
void ApplySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
SDL_Rect offset;
SDL_Rect* clip=NULL;

offset.x=x;
offset.y=y;

//now blit it
SDL_BlitSurface(source, clip, destination, &offset);
}


If you need to see the rest of the project, then just tell me, I will post the code up here, and maybe y'all can help! System Specs: Dell Dimension 3000 1 gig RAM I have made other 2D games with SDL with AWESOME speed. So...I figure something very bad is wrong with my code! I thank anyone who helps me with this!!! Chad

##### Share on other sites
Do your pngs contain alpha pixels?

SDL, alpha belnding and hardware dont mix well. Try making all your surfaces software surfaces and see if this speeds it up.

This is due to SDL needing to manually do alpha blending, so it needs to read the surface info from the gfx card every time you alpha blit. If all the releveant surfaces are in system memory, it can be much faster

[edit: this probably is the problem. I believe you can only get a hardware surface if you go fullscreen, hence why you only see the problem there...]

##### Share on other sites
What you said sounded right, and thought it would work, but it did not. I changed it to software, and it did not work. Nice try though. I thought it would work!

Anyone else!

Thanks,

PS: Thanks for trying.

also, I have one other thing to try, but all help will be appreciated!

##### Share on other sites
Can you post the code that applies to level, layer, and character? Your problem might reside there.

##### Share on other sites
If you can, run a profiler. The bottleneck should jump out from that.

##### Share on other sites
Why did a double-buffered window flicker?

##### Share on other sites
Quote:
 Original post by LukewarmWhy did a double-buffered window flicker?

I had the same question on my mind!

Also,
I would be using a profiler, but I don't know of a free one, and I use Dev-CPP. I don't think one comes with Dev-CPP. Or...does one? I guess I will google it, and see what it brings up.

Also, here is the code for the Character, Level, Layer, and Sprite Class(The Character class inherits from the Character class).

Level.cpp
//this will be Level.cpp//first we need to include Level.h#include "Level.h"//we will start with the ConstructorLevel::Level(){     levelbackground=NULL;     leveltitle=NULL;     keysheld=SDL_GetKeyState(0);}//now we will move to the DeconstructorLevel::~Level(){     cout<<"The Deconstructor has been called"<<endl;}//now weill create the levelsvoid Level::CreateLevel(string filename, int maxEnemies){     levelbackground=IMG_Load(filename.c_str());     if(!levelbackground)     {          cout<<"ERROR: Could not load "<<filename<<endl;          levelbackground=NULL;     }     cout<<"we have loaded the background";     cout<<"This is where all the enemies will be loaded up"<<endl;}//Now we will draw the levelvoid Level::DrawLevel(){     levelbackgroundSource.x=0;     levelbackgroundSource.y=1;     levelbackgroundSource.w=640;     levelbackgroundSource.h=480;     ApplySurface(bgX, bgY, levelbackground, SDL_GetVideoSurface());}//now we will create the level titlevoid Level::CreateLevelTitle(string filename){    /* leveltitle=IMG_Load(filename.c_str());     if(!leveltitle)     {          cout<<"ERROR: Could not load "<<filename<<endl;          leveltitle=NULL;     }*/     cout<<"we are in the create level title function"<<endl;}//now we will draw the level titlevoid Level::DrawLevelTtile(){     cout<<"we are in the draw level title function"<<endl;}//now we will scroll the levelvoid Level::Scroll(int speed){ 	//scroll the background 	bgX-=speed; 	if(bgX<= -levelbackground->w) 	{          bgX=0;     }     ApplySurface(bgX+levelbackground->w, bgY, levelbackground, SDL_GetVideoSurface());}//now we will free the levelvoid Level::FreeLevel(){     SDL_FreeSurface(levelbackground);}//now we will free the level title void Level::FreeLevelTitle(){    // SDL_FreeSurface(leveltitle);    cout<<"Inside free level title function"<<endl;}

The functions about the leveltitle, those are the functions for when I need to get the level titled drawn. Right now, this early in the stage I do not need it to happen.

Layer.cpp
//this will be layer.cpp#include "Layer.h"//now lets startLayer::Layer(){     speed=7;     layer=NULL;}//now the overloaded oneLayer::Layer(int scrollingSpeed){     speed=scrollingSpeed;     layer=NULL;}//now the deconstructorLayer::~Layer(){}//now create the layervoid Layer::CreateLayer(string filename, Sint16 sourceW, Sint16 sourceH, int destX,		                    int destY){     layerSource.x=0;     layerSource.y=1;     layerSource.w=sourceW;     layerSource.h=sourceH;          bgX=destX;     bgY=destY;          //now load the layer image into memory     layer=IMG_Load(filename.c_str());     if(!layer)     {          cout<<"ERROR: Could not load "<<filename<<endl;          layer=NULL;     }}//now draw the layervoid Layer::ApplyLayer(){ 	ApplySurface(bgX, bgY, layer, SDL_GetVideoSurface());}//now scroll the layer//this is what makes the depth effectvoid Layer::ScrollLayer(){ 	//scroll the layer 	bgX-=speed; 	if(bgX<= -layer->w) 	{          bgX=0;     }     ApplySurface(bgX+layer->w, bgY, layer, SDL_GetVideoSurface());}//now free the layervoid Layer::FreeLayer(){     if(layer)     {          SDL_FreeSurface(layer);     }     layer=NULL;}

Sprite.cpp
//first let's include the Sprite.h header file#include "Sprite.h"//we will start with the constructorSprite::Sprite():			  xVel(0),			  yVel(0){}//now it is time for the deconstructorSprite::~Sprite(){     surface=NULL;}//now it is time for the craete functionvoid Sprite::Create(string filename){ 	surface=IMG_Load(filename.c_str()); 	if(!surface) 	{          fprintf(stderr, "ERROR: Could not load the sprite");     }     SDL_SetColorKey(surface, SDL_SRCCOLORKEY|SDL_RLEACCEL,                   SDL_MapRGB(SDL_GetVideoSurface()->format, 255, 255, 255));}//now it is time to set everything upvoid Sprite::Setup(Sint16 sw, Sint16 sh, Sint16 x, Sint16 y, int xvel, int yvel){ 	//set the source     sourceRect.w=sw;     sourceRect.h=sh;          //set the destination     destRect.x=x;     destRect.y=y;          //set the velocity     xVel=xvel;     yVel=yvel;}//now it is time to draw the spritevoid Sprite::Draw(){ 	SDL_BlitSurface(surface, &sourceRect, SDL_GetVideoSurface(), &destRect);}//now  it is time to free the spritevoid Sprite::Free(){ 	SDL_FreeSurface(surface);}

Character.cpp
//this will be where Character.cpp will be//first let's include the Character.h header file#include "Character.h"//lets start with the constructorCharacter::Character(){}//time to do the deconstructorCharacter::~Character(){}//time to move the charactervoid Character::Move(SDL_Event& event){ 	if(event.type==SDL_KEYDOWN) 	{          switch(event.key.keysym.sym)          {               case SDLK_w: yVel-=sourceRect.h/10; break;               case SDLK_s: yVel+=sourceRect.h/10; break;               case SDLK_a: xVel-=sourceRect.w/10; break;               case SDLK_d: xVel+=sourceRect.w/10; break;		}     }    else if(event.type==SDL_KEYUP)     {          switch(event.key.keysym.sym)          {               case SDLK_w: yVel+=sourceRect.h/10; break;               case SDLK_s: yVel-=sourceRect.h/10; break;               case SDLK_a: xVel+=sourceRect.w/10; break;               case SDLK_d: xVel-=sourceRect.w/10; break;		}     }}//time to update the charactervoid Character::Update(){ 	destRect.x+=xVel; 	destRect.y+=yVel;}/**more will go here later, as later on in the game we figure out exactly how*the main character will be.*/

As you can see, I did not include the .h's for them. If you need them, then just tell me. I will include them also.

Also...please be nice if I made a really stupid mistake. lol. I am here to learn, so you can tell me some needed stuff to know, but we all make stupid mistakes...so please be kind of nice. hehe.

I thank all of y'all for helping me!!! It is time for me to start goolging profilers.

Thanks,

##### Share on other sites
AMD has a free profiler but does it work on Intel chips? This is why I only develop on AMD machines ;-) Better Dev support IMO.

##### Share on other sites
Thanks AP, I will check out AMD's profiler. I am downloading the 30 day trial of Intel's VTune as we speak though right now. I will check out AMD's though, to see if I can use it with my Intel Pentium 4.

EDIT: I just checked out AMD's Profiler, and from what I read it seems like it does only work on AMD hardware. Oh well, I will just continue downloading Intels VTune. I will also appreciate any help if anyone can help me!

##### Share on other sites
Quote:
 void Sprite::Create(string filename){ surface=IMG_Load(filename.c_str()); if(!surface) { fprintf(stderr, "ERROR: Could not load the sprite"); } SDL_SetColorKey(surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(SDL_GetVideoSurface()->format, 255, 255, 255));}

Have you tried converting your surfaces to the display format to see if that heps? Otherwise SDL has to do conversions everytime it blits and with large surfaces like the ones you are using that could definitely be a bottleneck especially if the surfaces are being loaded in hardware -> converted in software -> uploaded back to hardware each frame.

void Sprite::Create(string filename){    SDL_Surface *temp = IMG_Load(filename.c_str());    if(!temp)    {        fprintf(stderr, "ERROR: Could not load the sprite");    }        surface = SDL_Displayformat( temp );    SDL_FreeSurface( temp );    temp = NULL;    SDL_SetColorKey(surface, SDL_SRCCOLORKEY|SDL_RLEACCEL,                   SDL_MapRGB(surface->format, 255, 255, 255));}

I also changed the SDL_MapRGB part a bit. You always want to pass the format of the surface you are working on and you are working on the sprite surface, not the screen surface.

See if that helps out.

1. 1
Rutin
36
2. 2
3. 3
4. 4
5. 5

• 12
• 14
• 9
• 9
• 14
• ### Forum Statistics

• Total Topics
633345
• Total Posts
3011440
• ### Who's Online (See full list)

There are no registered users currently online

×