<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Game runs slow on slower computers</title>
		<link>http://www.allegro.cc/forums/view/591498</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 24 May 2007 12:00:13 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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&#39;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&#39;s only 7-17 sprites being double buffered), so maybe someone could look over my code and tell me if I&#39;ve done anything particuarly wrong (since this is my first game in C++/Allegro, I&#39;m not exactly too sure on everything.</p><p>My game is War Pong HD, the homepage is <a href="http://warpong.sourceforge.net">http://warpong.sourceforge.net</a>. The source code is available there.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Mon, 21 May 2007 17:24:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code snippet"><div class="inner"><pre>    <a href="http://www.allegro.cc/manual/set_color_depth" target="_blank"><span class="a">set_color_depth</span></a><span class="k2">(</span><span class="n">32</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k1">if</span> <span class="k2">(</span><a href="http://www.allegro.cc/manual/set_gfx_mode" target="_blank"><span class="a">set_gfx_mode</span></a><span class="k2">(</span>GFX_AUTODETECT_FULLSCREEN,<span class="n">1024</span>,<span class="n">768</span>,<span class="n">0</span>,<span class="n">0</span><span class="k2">)</span><span class="k3">!</span><span class="k3">=</span><span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
</pre></div></div><p>

There&#39;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&#39;t make too many calls to makecol().)</p><p>Also, 1024x768 is a very high resolution to be doing non-accelerated doubled-buffered graphics at. It may only be 2D, but if it&#39;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.</p><p>If you&#39;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.</p><p>Without hardware acceleration you need to be careful how much data you&#39;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.</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Mon, 21 May 2007 18:10:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Richard Phipps)</author>
		<pubDate>Mon, 21 May 2007 18:27:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
an old Celeron 850mhz/256mb/integrated graphics dog
</p></div></div><p>

Dog?<br />That&#39;s better than both my laptops and my brother&#39;s laptop put together. Two of my computers are worse, as well...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (James Stanley)</author>
		<pubDate>Mon, 21 May 2007 20:28:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Kris: I seem to recall I was having some problems with 16 bit colour, but if I recall, it was a problem I&#39;ve long since fixed but not changed back.<br />(And since I&#39;m pedantic, there isn&#39;t an over 2Ghz speed difference - my 3000+ runs at 1,8Ghz).</p><p>Richard: WTF is dirty rectangle?</p><p>James: How many computers do you have?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Tue, 22 May 2007 12:11:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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&#39;d only update small parts of it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Tue, 22 May 2007 12:15:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Tue, 22 May 2007 16:18:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Most of the screen is actively being changed (what with bullets flying around and such), so dirty rectangle is probably out of the question.
</p></div></div><p>

I doubt it. Unless they are extremely large bullets, or there are hundreds of them, you&#39;ll still benifit hugely by using dirty rectangles.  Suppose you&#39;ve got 20 bullets each of size 32x32:  32x32*20 / 1024x768  =  3% of the screen.</p><p>However there are few things more boring than a game with a static non-scrolling background. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (james_lohr)</author>
		<pubDate>Tue, 22 May 2007 16:28:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Alright, maybe dirty rectangle would help (most bullets is 10, 8x8, equals an inconprehisibly small percentage). Still, that&#39;s not telling me how to do it.</p><p>Secondly, what&#39;s wrong with a nice static background? I don&#39;t want to detract from the main action.</p><p>Also I was able to fix my 16 bit graphics issue (which I mentioned at the top of the thread and extensively in <a href="http://www.allegro.cc/forums/thread/589766">http://www.allegro.cc/forums/thread/589766</a> - read that if you don&#39;t know what I&#39;m talking about). To put it bluntly, it wasn&#39;t displaying my 16 bit bitmaps at 16 bit colour, but if either of them was another bit depth it would work. I&#39;m now using PNGs, and when I set it 16 bit colour, it wasn&#39;t displaying my nice PNGs (which surprised me, because they&#39;re 24 bit). It&#39;s fixed though: the problem was my double buffering. I was using:<span class="source-code">buffer <span class="k3">=</span> <a href="http://www.allegro.cc/manual/create_bitmap" target="_blank"><span class="a">create_bitmap</span></a><span class="k2">(</span><span class="n">1024</span>,<span class="n">768</span><span class="k2">)</span><span class="k2">;</span></span> which didn&#39;t work. I change it to:<span class="source-code">buffer <span class="k3">=</span> <a href="http://www.allegro.cc/manual/create_bitmap_ex" target="_blank"><span class="a">create_bitmap_ex</span></a><span class="k2">(</span><span class="n">16</span>,<span class="n">1024</span>,<span class="n">768</span><span class="k2">)</span><span class="k2">;</span></span> and it magically works.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Tue, 22 May 2007 16:59:30 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
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&#39;m sure you&#39;ll find plenty of info..
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Richard Phipps)</author>
		<pubDate>Tue, 22 May 2007 17:26:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Another, but not so popular method would be to actually think about the concept. Then you could show us how you&#39;d implement it and we might be able to learn something from you.<br />Also, an idea you explore for yourself will always teach you more than if we just explain it to you.</p><p>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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Tue, 22 May 2007 19:23:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Of course, optimizing these areas (merging to reduce overdraw / function calls) etc is non-trivial, but also not really vital (profile!)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Tue, 22 May 2007 20:26:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Dog?<br />That&#39;s better than both my laptops and my brother&#39;s laptop put together. Two of my computers are worse, as well...
</p></div></div><p>

That just means your laptop, your brothers laptop, and two of your computers suck then. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Tue, 22 May 2007 20:56:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The simplest way to implement dirty rectangles for your game would probably be:</p><p>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&#39;s a task switch.))</p><p>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.)</p><p>3. You never clear the screen. You simply clear any area you&#39;re about to draw to. (IE: If you&#39;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.)</p><p>For instance, for drawing any sprite you would have the following mock code:</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/blit" target="_blank"><span class="a">blit</span></a><span class="k2">(</span>bg_bitmap,<a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>,sprite.prev_x,sprite.prev_y,sprite.prev_x,sprite.prev_y,sprite.h,sprite.w<span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/draw_sprite" target="_blank"><span class="a">draw_sprite</span></a><span class="k2">(</span><a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>,sprite.bitmap,sprite.x,sprite.y<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

You could probably convert that into a special function to make such drawing simpler.</p><p>The buffer is the big performance hit with the screen resolution and colour depth you&#39;re using. Eliminating it eliminates not one but TWO full-screen blits every frame. That&#39;s a lot of CPU power you&#39;re getting back!</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Wed, 23 May 2007 10:55:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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).</p><p>Also, I&#39;m just not following you on the dirty rectangles code you put there. Could you please simplify it a bit?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Wed, 23 May 2007 17:15:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ok, we simplify.</p><p>You have double buffer<br />double buffer good.<br />blitting all of buffer every frame not good<br />blitting only needed part of buffer good</p><p>keeping list of changed regions helps<br />blitting only changed regions will make game fast<br />fast good</p><p>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.</p><p>If you don&#39;t want to keep a list, try this (it&#39;s not quite as good, but should be easy to implement):</p><p>Your screen is 1024x768<br />Divide that into quads of 128x128</p><p>Whenever you draw something mark the quad you&#39;re drawing in as &quot;dirty&quot;.<br />When you blit the buffer, only blit the &quot;dirty&quot; quads.<br />If more than &quot;n&quot; quads are dirty, blit the whole screen.</p><p>This way you can keep a simple array to keep track of the dirty parts.</p><p>Another option:<br />If the only things moving are:<br />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.<br />The area you need to blit can be easily found by the speed of the shot / ball and it&#39;s current position.<br />Then you don&#39;t even need to mark the area as dirty, you can simply calculate what#s dirty.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Wed, 23 May 2007 17:29:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Eliminating it eliminates not one but TWO full-screen blits every frame.
</p></div></div><p>

How does it remove two full-screen blits?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Wed, 23 May 2007 17:41:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Because both the backbuffer and the screen will only be updated as needed.<br />Right now he creates the backbuffer every frame (by blitting the bg image, then the sprites) and blits the result to screen.</p><p>with the DRS he&#39;ll be updating only what&#39;s needed.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Wed, 23 May 2007 17:45:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Blitting the buffer to the screen is only one full-screen blit though.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (BAF)</author>
		<pubDate>Wed, 23 May 2007 17:59:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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&#39;s acceptable practice that it redraws the whole column, not just around where the paddle actually is).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Wed, 23 May 2007 18:00:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Does it make the gameplay acceptable?<br />If that is the case, then that&#39;s all you need to do. Otherwise, you may want to optimize it further.<br />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?).</p><p>First &quot;clear&quot; all the areas that objects were at last frame by blitting the background image over them, then draw the objects at their current positions.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Wed, 23 May 2007 18:05:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I don&#39;t need to track the previous positions of the objects (at least, I don&#39;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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Wed, 23 May 2007 18:13:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I don&#39;t need to track the previous positions of the objects (at least, I don&#39;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.
</p></div></div><p>

Something you&#39;re going to learn about programming: The more memory you use, the faster things go.</p><p>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. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p>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&#39;t move, you don&#39;t redraw it, because that&#39;s what makes it flicker without a buffer.</p><p>The method I&#39;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&#39;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!</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Wed, 23 May 2007 21:35:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Blitting the buffer to the screen is only one full-screen blit though.
</p></div></div><p>
Yep. And blitting the fullscreen bgImage to the backbuffer is the 2nd. (Well, actually it&#39;s the first, and bliting the backbuffer is the 2nd).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (spellcaster)</author>
		<pubDate>Thu, 24 May 2007 00:27:11 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
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.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Richard Phipps)</author>
		<pubDate>Thu, 24 May 2007 02:10:53 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Fair enough, so answer me this: since I know that everything except the paddles will move (bacground image doesn&#39;t count), it&#39;s safe to draw over where they were. But what&#39;s better for the paddles: using ifs to compare its previous position and seeing if they have moved, or just drawing within its movement range?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (konedima)</author>
		<pubDate>Thu, 24 May 2007 09:02:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you use the dirty rectangle system I suggested, you must never redraw something which hasn&#39;t moved or it is sure to flicker. Also remembering never to erase an object without immediately redrawing it.</p><p>If you use the other dirty rectangle system suggested, where you keep a buffer but only copy changed parts to the screen, you have to blit the combined areas of where the object was and where it has moved to, so you should still track previous coordinates anyways and save yourself the extra calculations.</p><p>The best way to store previous coordinates is at the start of processing any movement for an object, simply store the current coordinates into the previous ones, then update the current ones. Then, at the end of processing movement, if the current and previous coordinates are still identical, the object hasn&#39;t moved and doesn&#39;t need to be redrawn.</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Thu, 24 May 2007 12:00:13 +0000</pubDate>
	</item>
</rss>
