Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Game runs slow on slower computers

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Game runs slow on slower computers
konedima
Member #6,241
September 2005

I know the title sounds obvious, but just read. My game runs fine on my computer (Athlon 64 3000+/1GB RAM/GF7600GT) but not on an old computer I have lying around (an old Celeron 850mhz/256mb/integrated graphics dog). Obviously games shouldn't work as well on that, but my game is just 2d graphics with not too much happening on screen at any one time (during gameplay it's only 7-17 sprites being double buffered), so maybe someone could look over my code and tell me if I've done anything particuarly wrong (since this is my first game in C++/Allegro, I'm not exactly too sure on everything.

My game is War Pong HD, the homepage is http://warpong.sourceforge.net. The source code is available there.

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

Kris Asick
Member #1,424
July 2001

    set_color_depth(32);
    if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN,1024,768,0,0)!=0) {

There's the cause of your slowdowns right there. Switching to 16-bit colour will almost double the framerate. Switching to 8-bit if you can will double it again. (Provided you don't make too many calls to makecol().)

Also, 1024x768 is a very high resolution to be doing non-accelerated doubled-buffered graphics at. It may only be 2D, but if it's the CPU that has to handle the drawing then an over 2 GHz difference in processor speed is going to have a big effect on gameplay.

If you've ever played Mechwarrior II back in the days of DOS you would know that it had a 1024x768 mode. Even on a 600 Mhz computer I once tried that on it only ran at a framerate of about 8.

Without hardware acceleration you need to be careful how much data you're trying to push at any one time. 32-bit colour, 1024x768, and double buffered graphics all together are going to kill the framerate on older computers.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Richard Phipps
Member #1,632
November 2001
avatar

For a non-scrolling pong game use a Dirty Rectangle system for a big speedup and still run at 1024 x 768 in 32 bit colour.

James Stanley
Member #7,275
May 2006
avatar

Quote:

an old Celeron 850mhz/256mb/integrated graphics dog

Dog?
That's better than both my laptops and my brother's laptop put together. Two of my computers are worse, as well...

konedima
Member #6,241
September 2005

Kris: I seem to recall I was having some problems with 16 bit colour, but if I recall, it was a problem I've long since fixed but not changed back.
(And since I'm pedantic, there isn't an over 2Ghz speed difference - my 3000+ runs at 1,8Ghz).

Richard: WTF is dirty rectangle?

James: How many computers do you have?

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

spellcaster
Member #1,493
September 2001
avatar

A dirty rectangle system only updates rects on the screen that have changed since the last update. So, instead of updating the complete screen, you'd only update small parts of it.

--
There are no stupid questions, but there are a lot of inquisitive idiots.

konedima
Member #6,241
September 2005

Most of the screen is actively being changed (what with bullets flying around and such), so dirty rectangle is probably out of the question. Still, could someone please provide either an example or a link to one so I can keep it in mind for the future?

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

james_lohr
Member #1,947
February 2002

Quote:

Most of the screen is actively being changed (what with bullets flying around and such), so dirty rectangle is probably out of the question.

I doubt it. Unless they are extremely large bullets, or there are hundreds of them, you'll still benifit hugely by using dirty rectangles. Suppose you've got 20 bullets each of size 32x32: 32x32*20 / 1024x768 = 3% of the screen.

However there are few things more boring than a game with a static non-scrolling background. :P

konedima
Member #6,241
September 2005

Alright, maybe dirty rectangle would help (most bullets is 10, 8x8, equals an inconprehisibly small percentage). Still, that's not telling me how to do it.

Secondly, what's wrong with a nice static background? I don't want to detract from the main action.

Also I was able to fix my 16 bit graphics issue (which I mentioned at the top of the thread and extensively in http://www.allegro.cc/forums/thread/589766 - read that if you don't know what I'm talking about). To put it bluntly, it wasn't displaying my 16 bit bitmaps at 16 bit colour, but if either of them was another bit depth it would work. I'm now using PNGs, and when I set it 16 bit colour, it wasn't displaying my nice PNGs (which surprised me, because they're 24 bit). It's fixed though: the problem was my double buffering. I was using:buffer = create_bitmap(1024,768); which didn't work. I change it to:buffer = create_bitmap_ex(16,1024,768); and it magically works.

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

Richard Phipps
Member #1,632
November 2001
avatar

There are different types of Dirty Rectangle Systems, the Allegro demo uses one as an option too. I think I even posted a simple one on this forums some years ago. Do a search on these forums and I'm sure you'll find plenty of info..

spellcaster
Member #1,493
September 2001
avatar

Another, but not so popular method would be to actually think about the concept. Then you could show us how you'd implement it and we might be able to learn something from you.
Also, an idea you explore for yourself will always teach you more than if we just explain it to you.

A DRS is really pretty simple. Keep a list of all areas that need to be updated and update only these areas instead of the whole screen.

--
There are no stupid questions, but there are a lot of inquisitive idiots.

Jonatan Hedborg
Member #4,886
July 2004
avatar

Of course, optimizing these areas (merging to reduce overdraw / function calls) etc is non-trivial, but also not really vital (profile!)

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

BAF
Member #2,981
December 2002
avatar

Quote:

Dog?
That's better than both my laptops and my brother's laptop put together. Two of my computers are worse, as well...

That just means your laptop, your brothers laptop, and two of your computers suck then. :P

Kris Asick
Member #1,424
July 2001

The simplest way to implement dirty rectangles for your game would probably be:

1. Eliminate the buffer. Do all drawing directly to the screen. (This will mean that all drawing to the screen has to be done at once between an acquire_screen() and release_screen() pair unless you store everything into video bitmaps. (Which would be faster but has an added complication of having to restore all video bitmaps if there's a task switch.))

2. All sprites must store their previous positions from the last frame. This is because you only ever redraw sprites which have moved. (Or animated.)

3. You never clear the screen. You simply clear any area you're about to draw to. (IE: If you're about to draw a paddle in a new position, you blit the section of the background the paddle was previously over to the screen, then blit the new position of the paddle immediately afterwards.)

For instance, for drawing any sprite you would have the following mock code:

blit(bg_bitmap,screen,sprite.prev_x,sprite.prev_y,sprite.prev_x,sprite.prev_y,sprite.h,sprite.w);
draw_sprite(screen,sprite.bitmap,sprite.x,sprite.y);

You could probably convert that into a special function to make such drawing simpler.

The buffer is the big performance hit with the screen resolution and colour depth you're using. Eliminating it eliminates not one but TWO full-screen blits every frame. That's a lot of CPU power you're getting back!

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

konedima
Member #6,241
September 2005

The problem with not double buffering is that the graphics flicker horribly, and double buffering is the best way I know of to fix it. At least I looking through my code I found an unnecessary clear running on the buffer (unnecessary because I draw the background each frame anyway).

Also, I'm just not following you on the dirty rectangles code you put there. Could you please simplify it a bit?

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

spellcaster
Member #1,493
September 2001
avatar

Ok, we simplify.

You have double buffer
double buffer good.
blitting all of buffer every frame not good
blitting only needed part of buffer good

keeping list of changed regions helps
blitting only changed regions will make game fast
fast good

Nah, but seriously: All you do is instead of blitting the complete buffer, you only blit changed parts of the buffer. Since this will be even faster than blitting the complete buffer, you get all benefits without drawbacks.

If you don't want to keep a list, try this (it's not quite as good, but should be easy to implement):

Your screen is 1024x768
Divide that into quads of 128x128

Whenever you draw something mark the quad you're drawing in as "dirty".
When you blit the buffer, only blit the "dirty" quads.
If more than "n" quads are dirty, blit the whole screen.

This way you can keep a simple array to keep track of the dirty parts.

Another option:
If the only things moving are:
The paddles, the ball and the shots, you can blit the paddle columns, the area surrounding the ball and parts of the line of each shot.
The area you need to blit can be easily found by the speed of the shot / ball and it's current position.
Then you don't even need to mark the area as dirty, you can simply calculate what#s dirty.

--
There are no stupid questions, but there are a lot of inquisitive idiots.

BAF
Member #2,981
December 2002
avatar

Quote:

Eliminating it eliminates not one but TWO full-screen blits every frame.

How does it remove two full-screen blits?

spellcaster
Member #1,493
September 2001
avatar

Because both the backbuffer and the screen will only be updated as needed.
Right now he creates the backbuffer every frame (by blitting the bg image, then the sprites) and blits the result to screen.

with the DRS he'll be updating only what's needed.

--
There are no stupid questions, but there are a lot of inquisitive idiots.

BAF
Member #2,981
December 2002
avatar

Blitting the buffer to the screen is only one full-screen blit though.

konedima
Member #6,241
September 2005

For some reason your explanation made me blissfully more aware. I just fear that it could get complicated with the logo and scores (just use ifs to determine if a part I need to redraw lies in one of those areas, right?). Anyway, I did figure out how to dirty rectangle the paddles (as long as it's acceptable practice that it redraws the whole column, not just around where the paddle actually is).

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

Jonatan Hedborg
Member #4,886
July 2004
avatar

Does it make the gameplay acceptable?
If that is the case, then that's all you need to do. Otherwise, you may want to optimize it further.
All you really need to do is to redraw the parts that move; keep a record of previous position and current position of all bullets, paddles and ball(s). Redraw those areas (and anything else that changes, the score or something maybe?).

First "clear" all the areas that objects were at last frame by blitting the background image over them, then draw the objects at their current positions.

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

konedima
Member #6,241
September 2005

I don't need to track the previous positions of the objects (at least, I don't think I need to). Everything except the ball moves at a constant rate (and the ball has variables to track its speed), so I can just calculate the previous position.

War Pong HD! Every time you don't download it, a kitten of hope dies in my heart. Please, save the imaginary kittens.
http://warpong.sourceforge.net

Kris Asick
Member #1,424
July 2001

Quote:

I don't need to track the previous positions of the objects (at least, I don't think I need to). Everything except the ball moves at a constant rate (and the ball has variables to track its speed), so I can just calculate the previous position.

Something you're going to learn about programming: The more memory you use, the faster things go.

IE: When given the choice between making new variables to track something and calculating it every frame, make the new variables to save yourself the CPU time of recalculating. ;)

The reason for tracking previous coordinates with the method I described is because you only want to redraw things that have moved since the last frame. If it doesn't move, you don't redraw it, because that's what makes it flicker without a buffer.

The method I've described is actually used in a lot of much older games. Back before the 386 processor was invented redrawing the entire screen each frame could take forever. (This is why side scrollers weren't common, or would only scroll fixed amounts when reaching the edge of the screen.) Plus, it would take a lot of memory to store a buffer, and without extended memory every byte made a difference!

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

spellcaster
Member #1,493
September 2001
avatar

Quote:

Blitting the buffer to the screen is only one full-screen blit though.

Yep. And blitting the fullscreen bgImage to the backbuffer is the 2nd. (Well, actually it's the first, and bliting the backbuffer is the 2nd).

--
There are no stupid questions, but there are a lot of inquisitive idiots.

Richard Phipps
Member #1,632
November 2001
avatar

From my experience, if you use a Dirty Rectangle System for a breakout game you can have smooth 60 fps action at 1280 x 960 in 32 bit colour on a PII 300mhz PC.

 1   2 


Go to: