<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>FPS locking is easy - not taking 100% CPU is hard</title>
		<link>http://www.allegro.cc/forums/view/589396</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 11 Jan 2007 06:44:30 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>...or at least foreign to Allegro coding standards. Everywhere I look whether it&#39;s this forum or the first few hundred hits on Google, all the sample code for frame locking does a poor job of not using 100% CPU.</p><p>I think we all know the FAQ&#39;s blurb on FPS locking. [url=<a href="http://alleg.sourceforge.net/faq.html#How_can_I_make_my_game_run_at_the_same_speed_on_any_computer_]Not">http://alleg.sourceforge.net/faq.html#How_can_I_make_my_game_run_at_the_same_speed_on_any_computer_]Not</a> a word is meantioned about CPU usage[/url].</p><p>The question is simple - how do I make my simple tile-drawing program not take 100% CPU? rest(0) does nothing. rest(10) or any other static number makes the program run choppily and it still takes close to 70% CPU.</p><p>It&#39;s annoying to see all these FPS threads, I know. I&#39;ve waded through quite a few, but once more to be absolutely sure on the matter, ey?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Wed, 03 Jan 2007 13:21:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You could rest(1) or Sleep(1) (under windows) whenever you are ahead:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>finished<span class="k2">)</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>  <span class="k1">while</span> <span class="k2">(</span>ticks<span class="k2">)</span></td></tr><tr><td class="number">4</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">5</td><td>    <span class="c">/* ... */</span></td></tr><tr><td class="number">6</td><td>    drawgfx <span class="k3">=</span> TRUE<span class="k2">;</span></td></tr><tr><td class="number">7</td><td>    <span class="k3">-</span><span class="k3">-</span>ticks<span class="k2">;</span></td></tr><tr><td class="number">8</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td>  <span class="k1">if</span> <span class="k2">(</span>drawgfx<span class="k2">)</span></td></tr><tr><td class="number">11</td><td>  <span class="k2">{</span> </td></tr><tr><td class="number">12</td><td>    <span class="c">/* ... */</span></td></tr><tr><td class="number">13</td><td>    drawgfx <span class="k3">=</span> FALSE<span class="k2">;</span></td></tr><tr><td class="number">14</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">15</td><td>  <span class="k1">else</span> </td></tr><tr><td class="number">16</td><td>    <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// Sleep(1);</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
Or you could look at variable timing, where you let it run as fast as possible and compensate by using delta values.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Wed, 03 Jan 2007 13:44:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><a href="http://www.allegro.cc/depot/PixelShipsRetro">PixelShips Retro</a> uses far less than 100% CPU resources on every computer I&#39;ve tested it on. Actually, I&#39;ve had one particular system measure it as low as a measly 2%, which couldn&#39;t possibly be right but hey, if that&#39;s what it wanted to believe.</p><p>I switched to using Sleep(1) on Windows over Allegro&#39;s rest(1) because it seems to agree with the OS better.</p><p>If rest(10) is still making your game use 70% CPU, then the problem is two-fold. One, you need to give some CPU time back to the computer. Two, you&#39;re program is already using tons of CPU power just to do its thing.</p><p>Let me guess: You&#39;re running at 800x600 resolution, 24/32 bpp, and are doing a full-redraw of the screen every frame.</p><p>Allegro isn&#39;t accelerated beyond some very simple optimizations, so if you&#39;re only using Allegro to render everything you need to set some boundaries to achieve a more balanced game. Such as 640x480, 16 bpp, etc.</p><p>.<b>EDIT:</b> There is one other thing I nearly forgot to mention. If you are programming on Windows all video memory must be locked before you can draw to it. By default, the only video surface in Allegro is the screen, and it will automatically lock and unlock for you... but that automatic process will wreak havoc if you rely on it for more than one write at a time. Either buffer all drawing to a memory bitmap and then draw that single bitmap to the screen, or call acquire_screen() before rendering everything and release_screen() when done rendering.</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, 03 Jan 2007 14:32:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Kris and Matthew, the Sleep function works wonderfully on Windows :-D.  I&#39;m going to use that for now until I need it to be changed, as I would like some kind of cross-platform capability.  Thanks for the info :-D.  It dropped mine down ~70-80%.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Dalrymple)</author>
		<pubDate>Wed, 03 Jan 2007 15:08:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
...or at least foreign to Allegro coding standards.
</p></div></div><p>
Not at all! Check the source for the test program or the grabber.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
all the sample code for frame locking does a poor job of not using 100% CPU.
</p></div></div><p>
That&#39;s because it&#39;s written to show how to run the same speed on any system, not to show how not to use 100% of teh CPU power. The best way to do that will depend on the game anyway.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
rest(0) does nothing.
</p></div></div><p>
Correction: rest(0) gives up the rest of the timeslice to other processes that need time, allowing them to run. If no other process is running, it will return immediately. In other words, it will never reduce CPU usage.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
rest(10)
</p></div></div><p>
Try rest(1); the result you see will also depend on where you call this. I typically call rest() if the logic does not need updating and the screen has already been drawn (ie, in situations where the game would busy-wait otherwise).</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I switched to using Sleep(1) on Windows over Allegro&#39;s rest(1) because it seems to agree with the OS better.
</p></div></div><p>
Er... rest() calls Sleep() in Windows:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">/* tim_win32_rest:</span></td></tr><tr><td class="number">2</td><td><span class="c"> *  Rests the specified amount of milliseconds.</span></td></tr><tr><td class="number">3</td><td><span class="c"> */</span></td></tr><tr><td class="number">4</td><td><span class="k1">static</span> <span class="k1">void</span> tim_win32_rest<span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a>, AL_METHOD<span class="k2">(</span><span class="k1">void</span>, callback, <span class="k2">(</span><span class="k1">void</span><span class="k2">)</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">5</td><td><span class="k2">{</span></td></tr><tr><td class="number">6</td><td>   <span class="k1">unsigned</span> <span class="k1">int</span> start<span class="k2">;</span></td></tr><tr><td class="number">7</td><td>   <span class="k1">unsigned</span> <span class="k1">int</span> ms <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>&#160;</td></tr><tr><td class="number">9</td><td>   <span class="k1">if</span> <span class="k2">(</span>callback<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">10</td><td>      start <span class="k3">=</span> timeGetTime<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">11</td><td>      <span class="k1">while</span> <span class="k2">(</span>timeGetTime<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> start <span class="k3">&lt;</span> ms<span class="k2">)</span></td></tr><tr><td class="number">12</td><td>         <span class="k2">(</span><span class="k3">*</span>callback<span class="k2">)</span><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">14</td><td>   <span class="k1">else</span> <span class="k2">{</span></td></tr><tr><td class="number">15</td><td>      Sleep<span class="k2">(</span>ms<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
so I have no idea why you think Sleep() works better than rest().
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Wed, 03 Jan 2007 15:17:29 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ideally what you want to have is the ability to change the state of the process to blocking (waiting in some queue... can&#39;t be executed until an event occurs). Then when the timer goes &quot;pop&quot; you want the process to wake up (timer elapsing causes the os to send a signal SIGALRM to wake up the blocked process). Allegro timers use a different thread so your main process will not block.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Under other platforms, they are usually implemented using threads, which run parallel to the main thread. Therefore timer callbacks on such platforms will not block the main thread when called, so you may need to use appropriate synchronisation devices (eg. mutexes, semaphores, etc.) when accessing data that is shared by a callback and the main thread.
</p></div></div><p>

You should be able to get around this by using the timer thread (probably have to be in the nasty callback) to wake up your main thread. Or you can use a different timer system to achieve ideal results. </p><p>A simple way to block your process is to use vsync().
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Goalie Ca)</author>
		<pubDate>Wed, 03 Jan 2007 15:54:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well, you could also take the time one message loop takes and name it dTime<br />if you want to e.g. get a framerate of 75 Hz, one frame is shown 1/75 seconds, so you
</p><div class="source-code snippet"><div class="inner"><pre> <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="k2">(</span><span class="n">1</span><span class="k3">/</span><span class="n">75</span> <span class="k3">-</span> dTime<span class="k2">)</span> <span class="k3">*</span> <span class="n">1000</span><span class="k2">)</span>
</pre></div></div><p>
milliseconds.</p><p>The only problem in this solution is that it can&#39;t handle situations with dTime &gt; 1/75, but I think this should be easily to solve.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (psycho)</author>
		<pubDate>Wed, 03 Jan 2007 18:14:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In my code I usually do essentially what you&#39;re saying albeit with some modular stuff to ensure that I handle integer underflow correctly. Actually nowadays I mostly write my games to run with the vsync and employ a separate fixed rate logic. Assuming vsync is blocking (and at least in OpenGL, it seems to be on all three major platforms), that fixes the CPU time problem.</p><p>However in my emulators that doesn&#39;t make sense since you&#39;re starting from the position of &quot;I must produce exactly 50 frame per second&quot; and so dTime type stuff applies.
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
The only problem in this solution is that it can&#39;t handle situations with dTime &gt; 1/75, but I think this should be easily to solve.
</p></div></div><p>
I do this: if dTime is too large (i.e. you took too long to draw this frame) then do the logic and keep time counting but don&#39;t draw the next one. So on machines that aren&#39;t quite fast enough you get frame skipping and if you can do 2 frames of logic, one drawn, one not, in the time you have to produce 1.5 frames of video then you can still sleep for 0.5 frames and give the other OS systems time to run.</p><p>The only problem comes when you end up perpetually behind, e.g. on systems that aren&#39;t fast enough or are just fast enough to run your program most of the time but some abnormal event (e.g. file access) has but you behind a small portion and you can&#39;t quite seem to catch up. I get around this quite easily. No more than 8 (or some other number I plucked out of thin air) frames are skipped. If the program finds itself trying to skip an 8th frame in a row then it just draws the frame and resets its timing.</p><p>Of course all dependent &quot;real time&quot; systems have to be able to handle the occasional time inconsistency too, but I don&#39;t suppose the average Allegro game has any of those implemented in their own code. I guess AUDIOSTREAMs that rely on the game processing reaching a certain stage before they know what sound to generate are the only example I can think of.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Wed, 03 Jan 2007 18:50:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I tried most the methods in here and none really worked. Granted I did lose CPU usage when I dropped the window size from 640x480 to 256x240, but that&#39;s just annoyingly small. You can&#39;t be serious to tell me that Allegro is THAT slow. I&#39;m just doing a few blits each frame.</p><p>Leverton: Sorry mate, your method just didn&#39;t work.</p><p>Asick: rest(1) didn&#39;t help, and I already am doing acquire_bitmap/release_bitmap [page flipping]</p><p>Dalrymple: Didn&#39;t know quite how I should have done yours. I set up a callback with BPS_TO_TIMER(TARGET_FPS) and then go into a while(!done) { vsync(); }? The callback handling the game of course.. and it just crashed.</p><p>psycho/Harte: Your method seems to have worked the best, however it still took 50% CPU even with 256x240 resolution. Closer, but still not good enough.</p><p>If it turns out that Allegro is just slower than my a bowel movement, I&#39;m going to have to rethink how I teach this blasted seminar. OpenGL for 2D just seems like too much complication than these students need. I just can&#39;t believe that it&#39;s that slow, Asick.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Wed, 03 Jan 2007 22:24:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>post some code; perhaps you are doing something crazy to cause the bad performance.<br />EDIT: Like having a different color depth than your desktop in windowed mode for example.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Wed, 03 Jan 2007 22:27:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include &lt;allegro.h&gt;</span></td></tr><tr><td class="number">2</td><td><span class="p">#include &lt;stdio.h&gt;</span></td></tr><tr><td class="number">3</td><td><span class="p">#include "rect.h"</span></td></tr><tr><td class="number">4</td><td>&#160;</td></tr><tr><td class="number">5</td><td><span class="c">/* *** DEFINES *** */</span></td></tr><tr><td class="number">6</td><td>&#160;</td></tr><tr><td class="number">7</td><td><span class="p">#define TARGET_FPS 60</span></td></tr><tr><td class="number">8</td><td>&#160;</td></tr><tr><td class="number">9</td><td><span class="c">//size of the tiles</span></td></tr><tr><td class="number">10</td><td><span class="p">#define TILE_W 16</span></td></tr><tr><td class="number">11</td><td><span class="p">#define TILE_H 16</span></td></tr><tr><td class="number">12</td><td>&#160;</td></tr><tr><td class="number">13</td><td><span class="c">//max tiles that can fit in the viewport</span></td></tr><tr><td class="number">14</td><td><span class="p">#define TILE_MX (viewport.Width() / TILE_W)</span></td></tr><tr><td class="number">15</td><td><span class="p">#define TILE_MY (viewport.Height() / TILE_H)</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td><span class="c">//map tile and pixel dimensions</span></td></tr><tr><td class="number">18</td><td><span class="p">#define MAP_X 100</span></td></tr><tr><td class="number">19</td><td><span class="p">#define MAP_Y 100</span></td></tr><tr><td class="number">20</td><td><span class="p">#define MAP_PX (MAP_X * TILE_W)</span></td></tr><tr><td class="number">21</td><td><span class="p">#define MAP_PY (MAP_Y * TILE_H)</span></td></tr><tr><td class="number">22</td><td>&#160;</td></tr><tr><td class="number">23</td><td><span class="c">/* *** GLOBALS *** */</span></td></tr><tr><td class="number">24</td><td>&#160;</td></tr><tr><td class="number">25</td><td><a href="http://www.allegro.cc/manual/BITMAP" target="_blank"><span class="a">BITMAP</span></a> <span class="k3">*</span>buffer<span class="k2">;</span></td></tr><tr><td class="number">26</td><td><a href="http://www.allegro.cc/manual/BITMAP" target="_blank"><span class="a">BITMAP</span></a> <span class="k3">*</span>pages<span class="k2">[</span><span class="n">2</span><span class="k2">]</span><span class="k2">;</span></td></tr><tr><td class="number">27</td><td>CRect viewport<span class="k2">;</span></td></tr><tr><td class="number">28</td><td>CRect player<span class="k2">(</span><span class="n">1</span>, <span class="n">1</span>, TILE_W, TILE_H<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">29</td><td><span class="k1">int</span> close_button_pressed <span class="k3">=</span> FALSE<span class="k2">;</span></td></tr><tr><td class="number">30</td><td><span class="k1">int</span> page <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">31</td><td><span class="k1">volatile</span> <span class="k1">int</span> t <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">32</td><td>&#160;</td></tr><tr><td class="number">33</td><td><span class="c">/* *** FUNCTION PROTOTYPES *** */</span></td></tr><tr><td class="number">34</td><td>&#160;</td></tr><tr><td class="number">35</td><td><span class="k1">void</span> init<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">36</td><td><span class="k1">void</span> deinit<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">37</td><td><span class="k1">void</span> input<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">38</td><td><span class="k1">void</span> tick<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">39</td><td><span class="k1">void</span> close_button_handler<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">40</td><td>&#160;</td></tr><tr><td class="number">41</td><td><span class="k1">void</span> input<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">42</td><td> <span class="c">//make sure we're looking at the keys pressed currently</span></td></tr><tr><td class="number">43</td><td> <a href="http://www.allegro.cc/manual/poll_keyboard" target="_blank"><span class="a">poll_keyboard</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">44</td><td>&#160;</td></tr><tr><td class="number">45</td><td> <span class="k1">if</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_UP<span class="k2">]</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">46</td><td>  player.SetTop<span class="k2">(</span>player.top <span class="k3">-</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">47</td><td> <span class="k2">}</span></td></tr><tr><td class="number">48</td><td> <span class="k1">if</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_DOWN<span class="k2">]</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">49</td><td>  player.SetTop<span class="k2">(</span>player.top <span class="k3">+</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">50</td><td> <span class="k2">}</span></td></tr><tr><td class="number">51</td><td> <span class="k1">if</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_LEFT<span class="k2">]</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">52</td><td>  player.SetLeft<span class="k2">(</span>player.left <span class="k3">-</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">53</td><td> <span class="k2">}</span></td></tr><tr><td class="number">54</td><td> <span class="k1">if</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_RIGHT<span class="k2">]</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">55</td><td>  player.SetLeft<span class="k2">(</span>player.left <span class="k3">+</span> <span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">56</td><td> <span class="k2">}</span></td></tr><tr><td class="number">57</td><td><span class="k2">}</span></td></tr><tr><td class="number">58</td><td>&#160;</td></tr><tr><td class="number">59</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">60</td><td> init<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">61</td><td> </td></tr><tr><td class="number">62</td><td> <a href="http://www.allegro.cc/manual/PALETTE" target="_blank"><span class="a">PALETTE</span></a> pal<span class="k2">;</span></td></tr><tr><td class="number">63</td><td> <a href="http://www.allegro.cc/manual/BITMAP" target="_blank"><span class="a">BITMAP</span></a> <span class="k3">*</span>tiles <span class="k3">=</span> <a href="http://www.allegro.cc/manual/load_bitmap" target="_blank"><span class="a">load_bitmap</span></a><span class="k2">(</span><span class="s">"tiles.bmp"</span>, pal<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">64</td><td> <span class="k1">bool</span> draw <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">65</td><td> <span class="k1">int</span> begintime, endtime<span class="k2">;</span></td></tr><tr><td class="number">66</td><td>&#160;</td></tr><tr><td class="number">67</td><td> <span class="c">//create a 2D map full of 4 tiles randomly</span></td></tr><tr><td class="number">68</td><td> <span class="k1">int</span> map<span class="k2">[</span><span class="n">100</span><span class="k2">]</span><span class="k2">[</span><span class="n">100</span><span class="k2">]</span>, x, y, tick<span class="k2">;</span></td></tr><tr><td class="number">69</td><td> <span class="k1">for</span><span class="k2">(</span>y <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> y <span class="k3">&lt;</span> <span class="n">100</span><span class="k2">;</span> y<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">70</td><td>  <span class="k1">for</span><span class="k2">(</span>x <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> x <span class="k3">&lt;</span> <span class="n">100</span><span class="k2">;</span> x<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">71</td><td>   map<span class="k2">[</span>y<span class="k2">]</span><span class="k2">[</span>x<span class="k2">]</span> <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_637.html" target="_blank">rand</a><span class="k2">(</span><span class="k2">)</span> % <span class="n">4</span><span class="k2">;</span> <span class="c">//random number 0-3</span></td></tr><tr><td class="number">72</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">73</td><td> <span class="k2">}</span></td></tr><tr><td class="number">74</td><td>&#160;</td></tr><tr><td class="number">75</td><td> <span class="c">//enter the main loop</span></td></tr><tr><td class="number">76</td><td> <span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_ESC<span class="k2">]</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> <span class="k3">!</span>close_button_pressed<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">77</td><td>  begintime <span class="k3">=</span> t<span class="k2">;</span></td></tr><tr><td class="number">78</td><td>  <span class="c">//catch keypresses to move around our map</span></td></tr><tr><td class="number">79</td><td>  input<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">80</td><td>&#160;</td></tr><tr><td class="number">81</td><td>  <span class="k1">if</span><span class="k2">(</span>draw<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">82</td><td>   buffer <span class="k3">=</span> pages<span class="k2">[</span>page<span class="k2">]</span><span class="k2">;</span></td></tr><tr><td class="number">83</td><td>   <a href="http://www.allegro.cc/manual/acquire_bitmap" target="_blank"><span class="a">acquire_bitmap</span></a><span class="k2">(</span>buffer<span class="k2">)</span><span class="k2">;</span> <span class="c">//used with release_screen() to prevent resource loss</span></td></tr><tr><td class="number">84</td><td>&#160;</td></tr><tr><td class="number">85</td><td>   <span class="c">//center the view around the moving player</span></td></tr><tr><td class="number">86</td><td>   viewport.SetCenter<span class="k2">(</span>player.GetCenter<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">87</td><td>&#160;</td></tr><tr><td class="number">88</td><td>   <span class="c">//Check viewport bounds</span></td></tr><tr><td class="number">89</td><td>   <span class="k1">if</span><span class="k2">(</span>viewport.left <span class="k3">&lt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span> viewport.SetLeft<span class="k2">(</span><span class="n">0</span><span class="k2">)</span><span class="k2">;</span> <span class="k2">}</span></td></tr><tr><td class="number">90</td><td>   <span class="k1">if</span><span class="k2">(</span>viewport.top <span class="k3">&lt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span> viewport.SetTop<span class="k2">(</span><span class="n">0</span><span class="k2">)</span><span class="k2">;</span> <span class="k2">}</span></td></tr><tr><td class="number">91</td><td>   <span class="k1">if</span><span class="k2">(</span>viewport.right <span class="k3">&gt;</span><span class="k3">=</span> MAP_PX<span class="k2">)</span> <span class="k2">{</span> viewport.SetRight<span class="k2">(</span>MAP_PX-1<span class="k2">)</span><span class="k2">;</span> <span class="k2">}</span></td></tr><tr><td class="number">92</td><td>   <span class="k1">if</span><span class="k2">(</span>viewport.bottom <span class="k3">&gt;</span><span class="k3">=</span> MAP_PY<span class="k2">)</span> <span class="k2">{</span> viewport.SetBottom<span class="k2">(</span>MAP_PY-1<span class="k2">)</span><span class="k2">;</span> <span class="k2">}</span></td></tr><tr><td class="number">93</td><td>&#160;</td></tr><tr><td class="number">94</td><td>   <span class="c">//Calculate tile position and the number of pixels to shift</span></td></tr><tr><td class="number">95</td><td>   CPoint camera<span class="k2">(</span>viewport.left <span class="k3">/</span> TILE_W, viewport.top <span class="k3">/</span> TILE_H<span class="k2">)</span>,</td></tr><tr><td class="number">96</td><td>     shift<span class="k2">(</span>viewport.left % TILE_W, viewport.top % TILE_H<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">97</td><td>&#160;</td></tr><tr><td class="number">98</td><td>   <span class="c">//draw our beautiful map</span></td></tr><tr><td class="number">99</td><td>   <span class="k1">for</span><span class="k2">(</span>y <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> y <span class="k3">&lt;</span><span class="k3">=</span> TILE_MY<span class="k2">;</span> y<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">100</td><td>    <span class="k1">for</span><span class="k2">(</span>x <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> x <span class="k3">&lt;</span><span class="k3">=</span> TILE_MX<span class="k2">;</span> x<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">101</td><td>     <a href="http://www.allegro.cc/manual/blit" target="_blank"><span class="a">blit</span></a><span class="k2">(</span>tiles, buffer, map<span class="k2">[</span>camera.y <span class="k3">+</span> y<span class="k2">]</span><span class="k2">[</span>camera.x <span class="k3">+</span> x<span class="k2">]</span> <span class="k3">*</span> TILE_W, <span class="n">0</span>, <span class="k2">(</span>x <span class="k3">*</span> TILE_W<span class="k2">)</span> <span class="k3">-</span> shift.x, <span class="k2">(</span>y <span class="k3">*</span> TILE_H<span class="k2">)</span> <span class="k3">-</span> shift.y, TILE_W, TILE_H<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">102</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">103</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">104</td><td>   <span class="c">//draw our player</span></td></tr><tr><td class="number">105</td><td>   <a href="http://www.allegro.cc/manual/rectfill" target="_blank"><span class="a">rectfill</span></a><span class="k2">(</span>buffer, player.left <span class="k3">-</span> viewport.left, player.top <span class="k3">-</span> viewport.top, player.right <span class="k3">-</span> viewport.left, player.bottom <span class="k3">-</span> viewport.top, <a href="http://www.allegro.cc/manual/makecol" target="_blank"><span class="a">makecol</span></a><span class="k2">(</span><span class="n">200</span>,<span class="n">200</span>,<span class="n">200</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">106</td><td>&#160;</td></tr><tr><td class="number">107</td><td>   <a href="http://www.allegro.cc/manual/release_bitmap" target="_blank"><span class="a">release_bitmap</span></a><span class="k2">(</span>buffer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">108</td><td>   <a href="http://www.allegro.cc/manual/show_video_bitmap" target="_blank"><span class="a">show_video_bitmap</span></a><span class="k2">(</span>buffer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">109</td><td>   page <span class="k3">=</span> <span class="n">1</span> <span class="k3">-</span> page<span class="k2">;</span></td></tr><tr><td class="number">110</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">111</td><td>  endtime <span class="k3">=</span> t <span class="k3">-</span> begintime<span class="k2">;</span></td></tr><tr><td class="number">112</td><td>  <span class="k1">if</span><span class="k2">(</span> endtime <span class="k3">&gt;</span><span class="k3">=</span> <span class="k2">(</span><span class="n">1000</span> <span class="k3">/</span> TARGET_FPS<span class="k2">)</span> <span class="k2">)</span> <span class="k2">{</span> draw <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span> <span class="k2">}</span></td></tr><tr><td class="number">113</td><td>  <span class="k1">else</span> <span class="k2">{</span></td></tr><tr><td class="number">114</td><td>    draw <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span></td></tr><tr><td class="number">115</td><td>    <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span> <span class="k2">(</span><span class="n">1000</span> <span class="k3">/</span> TARGET_FPS<span class="k2">)</span> <span class="k3">-</span> endtime<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">116</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">117</td><td> <span class="k2">}</span></td></tr><tr><td class="number">118</td><td>&#160;</td></tr><tr><td class="number">119</td><td> <a href="http://www.allegro.cc/manual/destroy_bitmap" target="_blank"><span class="a">destroy_bitmap</span></a><span class="k2">(</span>tiles<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">120</td><td>&#160;</td></tr><tr><td class="number">121</td><td> deinit<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">122</td><td> <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">123</td><td><span class="k2">}</span></td></tr><tr><td class="number">124</td><td><a href="http://www.allegro.cc/manual/END_OF_MAIN" target="_blank"><span class="a">END_OF_MAIN</span></a><span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">125</td><td>&#160;</td></tr><tr><td class="number">126</td><td><span class="k1">void</span> tick<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">127</td><td><span class="k2">{</span></td></tr><tr><td class="number">128</td><td> t<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">129</td><td><span class="k2">}</span></td></tr><tr><td class="number">130</td><td><a href="http://www.allegro.cc/manual/END_OF_FUNCTION" target="_blank"><span class="a">END_OF_FUNCTION</span></a><span class="k2">(</span>tick<span class="k2">)</span></td></tr><tr><td class="number">131</td><td>&#160;</td></tr><tr><td class="number">132</td><td><span class="k1">void</span> close_button_handler<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">133</td><td><span class="k2">{</span></td></tr><tr><td class="number">134</td><td> close_button_pressed <span class="k3">=</span> TRUE<span class="k2">;</span></td></tr><tr><td class="number">135</td><td><span class="k2">}</span></td></tr><tr><td class="number">136</td><td><a href="http://www.allegro.cc/manual/END_OF_FUNCTION" target="_blank"><span class="a">END_OF_FUNCTION</span></a><span class="k2">(</span>close_button_handler<span class="k2">)</span></td></tr><tr><td class="number">137</td><td>&#160;</td></tr><tr><td class="number">138</td><td><span class="k1">void</span> init<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">139</td><td> <span class="k1">int</span> depth, res<span class="k2">;</span></td></tr><tr><td class="number">140</td><td> <a href="http://www.allegro.cc/manual/allegro_init" target="_blank"><span class="a">allegro_init</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">141</td><td> depth <span class="k3">=</span> <a href="http://www.allegro.cc/manual/desktop_color_depth" target="_blank"><span class="a">desktop_color_depth</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">142</td><td> <span class="k1">if</span> <span class="k2">(</span>depth <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> depth <span class="k3">=</span> <span class="n">32</span><span class="k2">;</span></td></tr><tr><td class="number">143</td><td> <a href="http://www.allegro.cc/manual/set_color_depth" target="_blank"><span class="a">set_color_depth</span></a><span class="k2">(</span>depth<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">144</td><td> res <span class="k3">=</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_WINDOWED, <span class="n">256</span>, <span class="n">240</span>, <span class="n">0</span>, <span class="n">0</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">145</td><td> <span class="k1">if</span> <span class="k2">(</span>res <span class="k3">!</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">146</td><td>  <a href="http://www.allegro.cc/manual/allegro_message" target="_blank"><span class="a">allegro_message</span></a><span class="k2">(</span><a href="http://www.allegro.cc/manual/allegro_error" target="_blank"><span class="a">allegro_error</span></a><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">147</td><td>  <a href="http://www.delorie.com/djgpp/doc/libc/libc_298.html" target="_blank">exit</a><span class="k2">(</span><span class="k3">-</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">148</td><td> <span class="k2">}</span></td></tr><tr><td class="number">149</td><td>&#160;</td></tr><tr><td class="number">150</td><td> <a href="http://www.allegro.cc/manual/install_timer" target="_blank"><span class="a">install_timer</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">151</td><td> <a href="http://www.allegro.cc/manual/install_keyboard" target="_blank"><span class="a">install_keyboard</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">152</td><td>&#160;</td></tr><tr><td class="number">153</td><td> <a href="http://www.allegro.cc/manual/set_window_title" target="_blank"><span class="a">set_window_title</span></a><span class="k2">(</span><span class="s">"Making Mario - Lesson 2"</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">154</td><td>&#160;</td></tr><tr><td class="number">155</td><td> <span class="c">//create the back buffer</span></td></tr><tr><td class="number">156</td><td> pages<span class="k2">[</span><span class="n">0</span><span class="k2">]</span> <span class="k3">=</span> <a href="http://www.allegro.cc/manual/create_video_bitmap" target="_blank"><span class="a">create_video_bitmap</span></a><span class="k2">(</span><a href="http://www.allegro.cc/manual/SCREEN_W" target="_blank"><span class="a">SCREEN_W</span></a>, <a href="http://www.allegro.cc/manual/SCREEN_H" target="_blank"><span class="a">SCREEN_H</span></a><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">157</td><td> pages<span class="k2">[</span><span class="n">1</span><span class="k2">]</span> <span class="k3">=</span> <a href="http://www.allegro.cc/manual/create_video_bitmap" target="_blank"><span class="a">create_video_bitmap</span></a><span class="k2">(</span><a href="http://www.allegro.cc/manual/SCREEN_W" target="_blank"><span class="a">SCREEN_W</span></a>, <a href="http://www.allegro.cc/manual/SCREEN_H" target="_blank"><span class="a">SCREEN_H</span></a><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">158</td><td>&#160;</td></tr><tr><td class="number">159</td><td> <span class="c">//set viewport to view the entire screen</span></td></tr><tr><td class="number">160</td><td> viewport.SetDimensions<span class="k2">(</span><a href="http://www.allegro.cc/manual/SCREEN_W" target="_blank"><span class="a">SCREEN_W</span></a>, <a href="http://www.allegro.cc/manual/SCREEN_H" target="_blank"><span class="a">SCREEN_H</span></a><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">161</td><td>&#160;</td></tr><tr><td class="number">162</td><td> <span class="c">//make sure the buffer stays within the viewport (VIEWPORT CAN'T BE BIGGER THAN SCREEN)</span></td></tr><tr><td class="number">163</td><td> <a href="http://www.allegro.cc/manual/set_clip_rect" target="_blank"><span class="a">set_clip_rect</span></a><span class="k2">(</span>pages<span class="k2">[</span><span class="n">0</span><span class="k2">]</span>, <span class="n">0</span>, <span class="n">0</span>, viewport.right, viewport.bottom<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">164</td><td> <a href="http://www.allegro.cc/manual/set_clip_rect" target="_blank"><span class="a">set_clip_rect</span></a><span class="k2">(</span>pages<span class="k2">[</span><span class="n">1</span><span class="k2">]</span>, <span class="n">0</span>, <span class="n">0</span>, viewport.right, viewport.bottom<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">165</td><td>&#160;</td></tr><tr><td class="number">166</td><td> <span class="c">//put the player in the center of the screen</span></td></tr><tr><td class="number">167</td><td> player.SetCenter<span class="k2">(</span>viewport.GetCenter<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">168</td><td>&#160;</td></tr><tr><td class="number">169</td><td> <a href="http://www.allegro.cc/manual/set_close_button_callback" target="_blank"><span class="a">set_close_button_callback</span></a><span class="k2">(</span>close_button_handler<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">170</td><td> </td></tr><tr><td class="number">171</td><td> <span class="c">//Do timer initializations</span></td></tr><tr><td class="number">172</td><td> <a href="http://www.allegro.cc/manual/LOCK_VARIABLE" target="_blank"><span class="a">LOCK_VARIABLE</span></a><span class="k2">(</span>t<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">173</td><td> <a href="http://www.allegro.cc/manual/LOCK_FUNCTION" target="_blank"><span class="a">LOCK_FUNCTION</span></a><span class="k2">(</span>increment_t<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">174</td><td> <span class="c">//allow the user to close the app</span></td></tr><tr><td class="number">175</td><td> <a href="http://www.allegro.cc/manual/LOCK_FUNCTION" target="_blank"><span class="a">LOCK_FUNCTION</span></a><span class="k2">(</span>close_button_handler<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">176</td><td> <a href="http://www.allegro.cc/manual/install_int_ex" target="_blank"><span class="a">install_int_ex</span></a><span class="k2">(</span>tick, <span class="n">1</span><span class="k2">)</span><span class="k2">;</span><span class="c">//BPS_TO_TIMER(60)); //lock FPS to 60</span></td></tr><tr><td class="number">177</td><td>&#160;</td></tr><tr><td class="number">178</td><td> <a href="http://www.delorie.com/djgpp/doc/libc/libc_739.html" target="_blank">srand</a><span class="k2">(</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a><span class="k2">(</span>NULL<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span> <span class="c">//randomize to timer</span></td></tr><tr><td class="number">179</td><td><span class="k2">}</span></td></tr><tr><td class="number">180</td><td>&#160;</td></tr><tr><td class="number">181</td><td><span class="k1">void</span> deinit<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">182</td><td> <span class="c">//release the memory used for the back buffer</span></td></tr><tr><td class="number">183</td><td> <a href="http://www.allegro.cc/manual/destroy_bitmap" target="_blank"><span class="a">destroy_bitmap</span></a><span class="k2">(</span>pages<span class="k2">[</span><span class="n">0</span><span class="k2">]</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">184</td><td> <a href="http://www.allegro.cc/manual/destroy_bitmap" target="_blank"><span class="a">destroy_bitmap</span></a><span class="k2">(</span>pages<span class="k2">[</span><span class="n">1</span><span class="k2">]</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">185</td><td> <a href="http://www.allegro.cc/manual/clear_keybuf" target="_blank"><span class="a">clear_keybuf</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">186</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

Change the resolution back to 640x480 to see what I mean.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Wed, 03 Jan 2007 22:36:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Change the resolution back to 640x480 to see what I mean.
</p></div></div><p>

Your code can&#39;t be compiled without <tt>rect.h</tt>.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (LennyLen)</author>
		<pubDate>Wed, 03 Jan 2007 22:45:55 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>We need the rest of your source if you want us to test it <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>But at a glance, that aquire_bitmap looks wrong. If you need it, put it just before you start your blit&#39;s, and release it just after.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Wed, 03 Jan 2007 22:50:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The problem is likely to be install_int_ex. Allegro&#39;s timers are very bad at anything particularly high resolution (including the every ms tick you want), and will clump together calls to your callback. In practice you often get a better result from using a much lower resolution timer and being more coarse about your rest breaks. Being careful to allow spare time to accumulate before you blow it all on a rest, of course.</p><p>In my &quot;Nuclear War!&quot; for last year&#39;s Christmas hack I used a 200 BPS timer to compensate for a 50 FPS display and tend to see 20-30% CPU usage on machines I&#39;ve tested. Another alternative, if you don&#39;t mind being Windows-only, is to use the Win32 function GetTickCount(), which just returns how many ms it has been since your program started and should work much better than an Allegro timer. SDL provides SDL_GetTicks() to do the same if you want to look into doing the same on non-Windows platforms.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Wed, 03 Jan 2007 23:15:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Post tiles.bmp while you&#39;re at it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Wed, 03 Jan 2007 23:16:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Oh, also note that 1000/60 (i.e. ms / your wanted FPS) isn&#39;t an integer so as you have it, you&#39;ll actually run at 62.5 fps assuming integer divide underflows rather than rounds (which I have to admit I have no idea about).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Wed, 03 Jan 2007 23:20:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><a href="http://ninkazu.the-infidel.net/lesson2.zip">http://ninkazu.the-infidel.net/lesson2.zip</a></p><p>Sorry about the rect.h thing. Bleh.</p><p>::EDIT::<br />And I want cross-platform compatability, so no GetTickCount() for me. I&#39;d like to hold off on SDL or any other lib if possible too.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Wed, 03 Jan 2007 23:24:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
And I want cross-platform compatability, so no GetTickCount() for me.
</p></div></div><p>
You need to check ALLEGRO_VRAM_SINGLE_SURFACE in that case, and if it is defined, allocate a virtual screen large enough to accomodate multiple pages.</p><p>With that change, I tested your program, in 640x480. I never saw more than 5% CPU usage. Tested on an AMD64-3200 running Linux with the plain X11 driver (ie, no hardware acceleration whatsoever).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Thu, 04 Jan 2007 00:00:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well I&#39;m not sure how the single page functionality is supposed to work. How are you supposed to draw to it and how are you supposed to blit the backbuffer? Is there a standard or what&#39;s the deal?</p><p>Strange that it got 5%... I don&#39;t have nearly as good a processor, but Centrino 2ghz should be able to draw that much with no problems. Geh, I really don&#39;t want to have to do this in OpenGL. That would require me to learn that crap before I have to learn it in my graphics class next semester :/</p><p>Should I even be worrying about CPU? It&#39;s nice to have something you can play wirelessly in class without having just 30 minutes of battery life, but that&#39;s really not what these lessons are about.</p><p>I suppose I haven&#39;t stated my goals - I&#39;m creating a series of lessons and exercises to informally teach students at my university how to make a simple game like Super Mario Bros. So looking at this &quot;lesson 2&quot; I&#39;m still wondering where I should go for lesson 3. I&#39;m thinking about introducing collision detection, jumping physics and organizing the code into a more structured MVC pattern. I just hope that&#39;s not too much for one lesson. Maybe I&#39;ll take out the jumping physics and just add a simple frame-based animation structure.</p><p>What do you guys think? I&#39;m open to suggestion (just don&#39;t bicker about source control and programming language like they did on the last forum I asked this).</p><p>::EDIT::<br />Just to see how this current timing is fairing, I boosted the resolution to 640x480 again and only saw a jump of a couple percentage points of CPU. There has to be a way to get it down. The drawing should not be an issue, just when and how long to rest..</p><p>::EDIT 2::<br />I tried with the tick at every 5ms instead of 1ms and I&#39;m getting pretty stable framerates at 60 fps, which is about the same as the 1ms. Still getting the same CPU usage though. Here&#39;s the updated relevant code</p><div class="source-code snippet"><div class="inner"><pre>    endtime <span class="k3">=</span> t <span class="k3">-</span> begintime<span class="k2">;</span>
    <span class="k1">if</span><span class="k2">(</span> endtime <span class="k3">&gt;</span><span class="k3">=</span> <span class="k2">(</span><span class="n">200</span> <span class="k3">/</span> TARGET_FPS<span class="k2">)</span> <span class="k2">)</span> <span class="k2">{</span> draw <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span> <span class="k2">}</span>
    <span class="k1">else</span> <span class="k2">{</span>
      draw <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
      <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span> <span class="k2">(</span><span class="k2">(</span><span class="n">200</span> <span class="k3">/</span> TARGET_FPS<span class="k2">)</span> <span class="k3">-</span> endtime<span class="k2">)</span> <span class="k3">*</span> <span class="n">5</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k2">}</span>
</pre></div></div><p>
begintime = t before the logic and rendering.<br />I realized my timer wasn&#39;t called with the right value (5 instead of MSEC_TO_TIMER(5)) so that&#39;s fixed too.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Thu, 04 Jan 2007 00:48:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><b>Evert:</b> I know about rest() calling Sleep(), but that doesn&#39;t negate that there was a marked performance increase when I switched from rest() and Allegro timers to directly calling Sleep() and using the Windows high-performance timers. (Which Allegro should theoretically also be using after checking the same file that routine was in.) I can&#39;t explain it but there must be a reason why because the difference is there.</p><p><b>Ninkazu:</b> First of all, when you do page flipping you should not be doing <i>any</i> game logic while you&#39;ve got a video page locked. The <u>only</u> thing you should be doing between calls to the acquire and release commands are drawing commands. The longer you lock a page of video memory for the longer everything running on your computer has to wait for that process to finish before memory handling can go back to normal.</p><p>The second thing is that if your desktop is set to 32-bit colour your code is defaulting to it as well. 32-bit colour is twice slower to draw in memory than 16-bit, and has to be done entirely by the CPU. The speed of your computer will make a huge difference. When it comes down to the graphics card however, there are a number of factors that come into play for how quickly the CPU can transmit data to video bitmaps. You may have a particular combination that doesn&#39;t like 32-bit colour so much, further slowing down the draw operation.</p><p>Force your program into 8-bit or 16-bit, depending on how you want to go about it, then see if that helps. There are almost no reasons to need 32-bit over 16-bit in a non-accelerated program.</p><p><s>Lastly, your calculations for your rest periods are completely out of whack.

To understand this and modify your code properly, consider that 1000 / 60 = 16.666666667, while endtime will almost never be anything but 0 or 1 unless your framerate drops below 60. Thus all of your calculations using endtime must be completely off.</s> Scratch that, the timing code is ok.</p><p>But your calls to rest() should be simple. One thing you could do is reset your timer to go at a rate of 60 ticks a second, then time your game logic to the timer. Then, call rest(1) in a loop until another timer tick has passed, then process it. It&#39;s one way to go about doing it.</p><p>Two other last things. Try updating your graphics drivers and switching to full-screen instead of Windowed. It could be that your graphics card does not handle Windowed drawing very well.</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, 04 Jan 2007 01:21:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Fullscreen 640x480 16-bit still runs at around 45-55%.<br />I think the code I uploaded didn&#39;t have the acquire moved, but the code I&#39;ve been testing on does, so that&#39;s taken care of too.</p><p>Can you post an example of the logic and rest loop? It sounds like the first bit of code posted in this thread, which I tried at no help (100% CPU)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Thu, 04 Jan 2007 01:53:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You still haven&#39;t mentioned what kind of <s>CPU and</s> graphics card you have. 55% might be as good as you can hope for depending on the complexity of what you&#39;re doing.</p><p>Here is some mock-up code to demonstrate a fixed-time game loop along with the ability to drop frames if the framerate dies.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">volatile</span> <span class="k1">int</span> tick<span class="k2">;</span></td></tr><tr><td class="number">2</td><td>&#160;</td></tr><tr><td class="number">3</td><td><span class="k1">void</span> tick_timer <span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">4</td><td><span class="k2">{</span></td></tr><tr><td class="number">5</td><td>  tick<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td><span class="k2">}</span></td></tr><tr><td class="number">7</td><td><a href="http://www.allegro.cc/manual/END_OF_FUNCTION" target="_blank"><span class="a">END_OF_FUNCTION</span></a><span class="k2">(</span>tick_timer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>&#160;</td></tr><tr><td class="number">9</td><td><span class="k1">void</span> main <span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">10</td><td><span class="k2">{</span></td></tr><tr><td class="number">11</td><td>  <span class="k1">int</span> quit_loop <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">12</td><td>  <span class="k1">int</span> draw_frame <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td>  <span class="c">// Initialize Everything</span></td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>  <a href="http://www.allegro.cc/manual/LOCK_VARIABLE" target="_blank"><span class="a">LOCK_VARIABLE</span></a><span class="k2">(</span>tick<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>  <a href="http://www.allegro.cc/manual/LOCK_FUNCTION" target="_blank"><span class="a">LOCK_FUNCTION</span></a><span class="k2">(</span>tick_timer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>&#160;</td></tr><tr><td class="number">19</td><td>  <a href="http://www.allegro.cc/manual/install_timer" target="_blank"><span class="a">install_timer</span></a><span class="k2">(</span>tick_timer,BPS_TO_TIMER<span class="k2">(</span><span class="n">60</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">20</td><td>&#160;</td></tr><tr><td class="number">21</td><td>  <span class="c">// Game Loop Follows:</span></td></tr><tr><td class="number">22</td><td>&#160;</td></tr><tr><td class="number">23</td><td>  <span class="k1">do</span> <span class="k2">{</span></td></tr><tr><td class="number">24</td><td>    <span class="k1">while</span> <span class="k2">(</span>tick <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">25</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">26</td><td>      <span class="c">// Game Logic goes here</span></td></tr><tr><td class="number">27</td><td>&#160;</td></tr><tr><td class="number">28</td><td>      draw_frame <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">29</td><td>      tick--<span class="k2">;</span></td></tr><tr><td class="number">30</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">31</td><td>    <span class="k1">if</span> <span class="k2">(</span>draw_frame<span class="k2">)</span></td></tr><tr><td class="number">32</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">33</td><td>      <span class="c">// Lock video memory (if page flipping) and</span></td></tr><tr><td class="number">34</td><td>      <span class="c">// draw the screen.</span></td></tr><tr><td class="number">35</td><td>&#160;</td></tr><tr><td class="number">36</td><td>      draw_frame <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">37</td><td>      <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="n">0</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// Give at least something back to Windows.</span></td></tr><tr><td class="number">38</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">39</td><td>    <span class="k1">else</span></td></tr><tr><td class="number">40</td><td>      <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// Or Sleep(1) if you're in Windows</span></td></tr><tr><td class="number">41</td><td>  <span class="k2">}</span> <span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>quit_loop<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">42</td><td>&#160;</td></tr><tr><td class="number">43</td><td>  <span class="c">// Uninit Everything</span></td></tr><tr><td class="number">44</td><td><span class="k2">}</span></td></tr><tr><td class="number">45</td><td><a href="http://www.allegro.cc/manual/END_OF_MAIN" target="_blank"><span class="a">END_OF_MAIN</span></a><span class="k2">(</span><span class="k2">)</span></td></tr></tbody></table></div></div><p>

That&#39;s so ugly to me... I&#39;m too used to real-time anymore. In either case, that&#39;s the way I would aim for what you&#39;re trying to do.</p><p>One other thing to consider is that 60 is a tough framerate to maintain depending on how complex your game is. You might want to try aiming for 30 instead. (In fact, if you implement frame dropping as I have above, you may see things go at 30 instead of 60!)</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, 04 Jan 2007 02:06:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I must have been doing something wrong the first time I tried that method. I tried it this time with a 30 fps target at fullscreen 640x480x16 and hovered around 20%.</p><p>Cool. Thanks for the help.<br />[ATI Radeon X300 256mb... it&#39;s sad, my laptop is my gaming computer... I need to upgrade this summer when I&#39;m working at NVIDIA]
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ninkazu)</author>
		<pubDate>Thu, 04 Jan 2007 02:17:11 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Evert said:</div><div class="quote"><p>
Er... rest() calls Sleep() in Windows:
</p></div></div><p>
Well then why when I ctrl alt delete does my game crash when I call rest, but when I call sleep it works flawlessly?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Dalrymple)</author>
		<pubDate>Fri, 05 Jan 2007 08:17:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Well then why when I ctrl alt delete does my game crash when I call rest, but when I call sleep it works flawlessly?
</p></div></div><p>

That&#39;s how you recognize you have made a big memory overwrite: when making irrelevent changes DOES change the result.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Fri, 05 Jan 2007 08:38:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Also, sleep != Sleep. One is a libc function, the other is a win32 function.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Fri, 05 Jan 2007 09:24:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Well then why when I ctrl alt delete does my game crash when I call rest, but when I call sleep it works flawlessly?
</p></div></div><p>
You screwed up somewhere? Just look at the source I posted above; if you don&#39;t have a callback, rest() calls Sleep() directly.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Fri, 05 Jan 2007 15:44:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Doesn&#39;t crash after ctrl alt delete
</p><div class="source-code snippet"><div class="inner"><pre>     <span class="k1">while</span><span class="k2">(</span><span class="k3">!</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_ESC<span class="k2">]</span><span class="k2">)</span>
     <span class="k2">{</span>
          FpsCounter::NewFrameStarted<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
          deltaTime <span class="k3">=</span> FpsCounter::GetDeltaTime<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>

          firstmap.Draw<span class="k2">(</span><span class="n">0</span>, <span class="n">0</span>, <span class="n">1</span><span class="k2">)</span><span class="k2">;</span>

          Canvas::Refresh<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
          
          Sleep<span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
     <span class="k2">}</span>
</pre></div></div><p>
Crashes after ctrl alt delete
</p><div class="source-code snippet"><div class="inner"><pre>     <span class="k1">while</span><span class="k2">(</span><span class="k3">!</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_ESC<span class="k2">]</span><span class="k2">)</span>
     <span class="k2">{</span>
          FpsCounter::NewFrameStarted<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
          deltaTime <span class="k3">=</span> FpsCounter::GetDeltaTime<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>

          firstmap.Draw<span class="k2">(</span><span class="n">0</span>, <span class="n">0</span>, <span class="n">1</span><span class="k2">)</span><span class="k2">;</span>

          Canvas::Refresh<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
          
          <a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
     <span class="k2">}</span>
</pre></div></div><p>
edit:<br />nm<br />rest(0); crashes.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Dalrymple)</author>
		<pubDate>Sun, 07 Jan 2007 10:27:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;ll need to post your entire project to determine what&#39;s wrong. rest(1) under windows ends up calling Sleep(1) after two or three regular function calls.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Sun, 07 Jan 2007 10:41:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><a href="http://www.allegro.cc/forums/thread/589424">http://www.allegro.cc/forums/thread/589424</a></p><p>It&#39;s attached to that thread.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Dalrymple)</author>
		<pubDate>Sun, 07 Jan 2007 11:16:11 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Matthew Dalrymple said:</div><div class="quote"><p>

Well then why when I ctrl alt delete does my game crash when I call rest, but when I call sleep it works flawlessly?
</p></div></div><p>
What version of Allegro are you using? In the Windows version of 4.2.0, there&#39;s a bug that causes the program to crash when CTRL+ALT+DEL is pressed. This has been fixed in 4.2.1</p><p>AE.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Andrei Ellman)</author>
		<pubDate>Thu, 11 Jan 2007 06:44:30 +0000</pubDate>
	</item>
</rss>
