<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Game Loops</title>
		<link>http://www.allegro.cc/forums/view/590871</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 10 Apr 2007 16:21:39 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In the past I&#39;ve been making simple games with a simple game loop where I handle input, do logic calculations, draw, and then cleanup. However, on my current, large 2d project, I realized that this method no longer applies well in the &quot;larger games&quot; arena. This method, when used, kills the game&#39;s FPS. So far the current rate is 25, and I haven&#39;t implemented all the features yet. Now some of you would argue that 25fps is fine for 2d games, however, I haven&#39;t implemented much of the game yet.. So I was wondering if you guys have any suggestions for optimizing this simple loop method or have a better method altogether...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (wegstar)</author>
		<pubDate>Thu, 05 Apr 2007 10:03:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;re doing something wrong with the drawing if you only get 25 FPS. A typical game loop looks like this:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<span class="k2">)</span> <span class="k2">{</span>
   <span class="k1">while</span> <span class="k2">(</span>timer_ticker <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
      process_one_frame_of_logic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      <span class="k3">-</span><span class="k3">-</span>timer_ticker<span class="k2">;</span>
   <span class="k2">}</span>

   <span class="k1">if</span> <span class="k2">(</span>need_to_redraw<span class="k2">)</span> <span class="k2">{</span>
      draw_one_frame_to_the_backbuffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      blit_buffer_to_screen<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>

Any major deviation from this is likely to be wrong.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (miran)</author>
		<pubDate>Thu, 05 Apr 2007 10:08:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>wegstar, could you provide a sample of what your code&#39;s loop currently looks like?
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span>
<span class="k2">{</span>
  ...
  <span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>exit_game<span class="k2">)</span>
  <span class="k2">{</span>
    get_userinput<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    update_animations<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    move_npcs<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    move_player<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    play_sound<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    blit_to_screen<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k2">}</span>
  <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

This is a generic loop you might see in different peoples&#39; code.  Are you saying that this is where all of your FPS slowdown is coming from?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (TeamTerradactyl)</author>
		<pubDate>Thu, 05 Apr 2007 10:12:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Now some of you would argue that 25fps is fine for 2d games
</p></div></div><p>

NO! it should not run at less than 60fps.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I realized that this method no longer applies well in the &quot;larger games&quot; arena
</p></div></div><p>

OOP is the only way to write complex games IMHO.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Paul whoknows)</author>
		<pubDate>Thu, 05 Apr 2007 10:13:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Or if you want to ruthlessly abuse the CPU: (This is so you can see how fast your CPU maxes out).
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<span class="k2">)</span> <span class="k2">{</span>
   <span class="k1">while</span> <span class="k2">(</span>timer_ticker <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
      process_one_frame_of_logic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      <span class="k3">-</span><span class="k3">-</span>timer_ticker<span class="k2">;</span>
   <span class="k2">}</span>

   <span class="k1">while</span> <span class="k2">(</span>timer_ticker <span class="k3">&lt;</span><span class="k3">=</span><span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
      draw_one_frame_to_the_backbuffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      blit_buffer_to_screen<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
      fps<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span> <span class="c">//&lt;--- For kicks you know.</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Hard Rock)</author>
		<pubDate>Thu, 05 Apr 2007 10:15:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>My code roughly translates to this:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span>
<span class="k2">{</span>
  ...
  <span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>exit_game<span class="k2">)</span>
  <span class="k2">{</span>
    get_userinput<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    update_world<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    update_player<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    update_npcs<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <span class="c">// loop through a global list of npcs and run their update funcs</span>
    <span class="c">//draw some extra things here</span>
    blit_to_screen<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k2">}</span>
  <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
When I removed a portion of the code where I did drawing in a for loop, I had a 5 fps increase...
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">for</span><span class="k2">(</span><span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> <span class="k1">int</span><span class="k2">(</span>player.bullets<span class="k2">)</span><span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span><span class="k2">{</span>
     blit_bullets_to_buffer<span class="k2">(</span>x<span class="k3">*</span>i, y<span class="k2">)</span><span class="k2">;</span> <span class="c">// (x position, y position)</span>
<span class="k2">}</span>
</pre></div></div><p>
But normally, doing simple logic calculations involving setting variables shouldn&#39;t cause too much latency..correct?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (wegstar)</author>
		<pubDate>Thu, 05 Apr 2007 10:16:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Are you loading and unloading and data inside the loop? If so, then don&#39;t. Are you doing any drawing in the logic code? Don&#39;t do that either. How do you measure the framerate? Why aren&#39;t you using timers?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (miran)</author>
		<pubDate>Thu, 05 Apr 2007 10:49:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Okay, as requested, here is a bad summary of Game Coding Complete&#39;s architecture.</p><p>You have three separate systems, that communicate via a message system that is controlled by the <b>Game Application Layer</b>.</p><ul><li><p> <b>Game Application Layer</b></p></li><li><p> <b>Game Logic Layer</b></p></li><li><p> <b>Game View*</b></p></li></ul><p>
<sub>*Game View is actually a list of Game View interface objects that can be local players, AI agents, or networked players.</sub></p><p>Example of message system:<br />&quot;A&quot; Button is pressed on keyboard</p><p>Human View checks for button presses, translates button press to game message &quot;Apply Emergency Brake&quot; and sends it</p><p>Game Logic receives message and changes the state of the player&#39;s car, sending a message back to the Human View: &quot;Car State: E-Brake On&quot;</p><p>Human View responds to the message by maybe changing the visual representation of the car to have its tires lay down rubber or something</p><p><b>---Game Application Layer---</b><br />Connection and disconnection of devices like keyboards and mice<br />Files<br />RAM<br />Timing<br />Language DLLs<br />Threads<br />Network connection<br />Core libraries<br />The main loop (<tt>AppLayer-&gt;Run();</tt>)<br />Init &amp; Shutdown</p><p><b>---Game Logic Layer---</b><br /><i>**you may have different implementations of the Game Logic that you swap in and out depending on whether the player is in server or client mode, single player or multiplayer, whatever**</i><br />Game State &amp; Data Structures<br />Physics<br />Events*<br />Process Manager**<br />Command Interpreter***</p><p><i>*Send messages such as &quot;time bomb created&quot; so Game View can play a ticking sound and make a visual representation of it and so AI agents can run from it, etc

**Processes are anything that needs to run every loop; this is essentially your Update() function (they are esentially threads, but in a cooperative multitasking environment rather than this mutex locking, time-wasting jazz)

***Takes the messages from the Game View and does something with them inside the Game Logic, like applying the E-Brake and then sending a message back to the Game View so it knows to lay down the rubber trails</i></p><p><b>---Game View (Human)---</b><br />Game display<br />^- the scene<br />^- GUI<br />^- FLIC anims<br />Audio<br />^- sfx<br />^- music<br />^- speech<br />Input interpreter*<br />Process Manager** (yet again!)<br />Options</p><p><i>*Should be obvious what this does...
**For button animations, little graphical tricks, anything that needs to have the equivalent of an Update() function</i></p><p><b>---Game View (AI agent)---</b><br />Stimulus interpreter<br />Decision system<br />Process Manager<br />Options</p><p><i>Rather self-explanatory</i></p><p>In addition, you may have a &quot;Remote Game View&quot; derived class that gets messages from a server game logic instead of a local game logic. If you need me to explain that in detail, ask me to.</p><p>That&#39;s the basic setup, here&#39;s the execution of it.</p><div class="source-code snippet"><div class="inner"><pre><span class="c">//entry point for the file</span>
GameAppLayer g_app<span class="k2">;</span>

<span class="k1">int</span> main<span class="k2">(</span><span class="k1">int</span> argc, <span class="k1">char</span> <span class="k3">*</span>argv<span class="k2">[</span><span class="k2">]</span><span class="k2">)</span>
<span class="k2">{</span>
    <span class="k1">if</span> <span class="k2">(</span>g_app.Init<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span>
    <span class="k2">{</span>
        g_app.Run<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k2">}</span>
    g_app.Deinit<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k1">return</span> g_app.GetExitCode<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

</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">//GameAppLayer.cpp</span></td></tr><tr><td class="number">2</td><td><span class="c">//This is actually a bit hackish because I just quickly adapted it from DirectX,</span></td></tr><tr><td class="number">3</td><td><span class="c">//but the basic setup ought to be the same</span></td></tr><tr><td class="number">4</td><td><span class="k1">void</span> GameAppLayer::Run<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">while</span> <span class="k2">(</span>m_bIsRunning<span class="k2">)</span></td></tr><tr><td class="number">7</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">8</td><td>        <span class="k1">while</span> <span class="k2">(</span>m_LogicTime <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">9</td><td>        <span class="k2">{</span></td></tr><tr><td class="number">10</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></td></tr><tr><td class="number">11</td><td>        <span class="k2">}</span></td></tr><tr><td class="number">12</td><td>        <span class="k1">float</span> renderTime <span class="k3">=</span> <span class="n">0</span>.<span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>        <span class="k1">while</span> <span class="k2">(</span>m_LogicTime <span class="k3">&gt;</span> <span class="n">0</span><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>            Update<span class="k2">(</span>m_TotalTime, m_LogicTime<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td>            <span class="c">//done this way in case TimerHandler() is called during Update()</span></td></tr><tr><td class="number">18</td><td>            m_LogicTime <span class="k3">-</span><span class="k3">=</span> m_TimerResolution<span class="k2">;</span></td></tr><tr><td class="number">19</td><td>            renderTime <span class="k3">+</span><span class="k3">=</span> m_TimerResolution<span class="k2">;</span></td></tr><tr><td class="number">20</td><td>        <span class="k2">}</span></td></tr><tr><td class="number">21</td><td>        Render<span class="k2">(</span>m_TotalTime, renderTime<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">23</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

There&#39;s a ton more to this architecture, but I&#39;m not about to type up 900 pages.<br /><img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" /></p><p>Edit: Corrected.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Thu, 05 Apr 2007 11:06:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>There&#39;s probably a few things to comment about the above, but I&#39;ll keep it to one thing.</p><p>The above is basically a model-view-controller architecture, except that the controller and view are combined. One suggestion might be that splitting the view and controller could give some benefits. In the above, the &quot;human view&quot; I assume is responsible for all rendering (graphics and sound), but it also processes input. If the input processing is split from the view, you can have different implementations of the controller. This may be useful for demo playback, or for spectating in an online game (where the input comes from a remote player).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gillius)</author>
		<pubDate>Thu, 05 Apr 2007 18:28:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Beyond the common mistakes, such as loading data while in your game loop, allocating and deallocating memory frequently, adding/removing items from vectors or using large linked lists, there are a few things you need to watch out for when coding with Allegro:</p><p>1. If you&#39;re doing more than one blit to video bitmaps per frame, including the screen, you have to lock that bitmap first before you draw to it using the acquire commands, then unlock with the release commands. (Doesn&#39;t apply for blitting video bitmaps to video bitmaps.) If you don&#39;t, locks are engaged and disengaged for every draw you make to a video bitmap, causing an enormous amount of slowdown. If you only ever draw to the screen or a video bitmap once every frame then there&#39;s nothing to worry about.</p><p>2. If you&#39;re working in 8-bit colour, be careful when you call the palette setting commands as some of them request a vsync() operation first, thus if you call those commands more than once in a frame you&#39;ll kill your framerate. (And you should thus never call more than one palette command which will vsync() per frame and you should always call it right before blitting to the screen.) Also, palette altering and page flipping don&#39;t mix harmoniously as <i>both</i> of them request a vsync() operation.</p><p>3. Since Allegro does not take advantage of hardware acceleration (excepting video to video blits) 32-bit colour will run nearly twice as slow as 16-bit colour. If you&#39;re working in 32-bit, trying scaling down to 16-bit.</p><p>4. If you run your program in a window, try not to run a 16-bit application with a 32-bit desktop or vice versa as you&#39;ll get some additional slowdown. (The amount of which will vary depending on how good your video card is.) 15-bit and 24-bit are very strange to work with anymore and you should avoid them. 8-bit should run fine in a window at any bit-depth desktop.</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, 05 Apr 2007 20:10:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
One suggestion might be that splitting the view and controller could give some benefits. In the above, the &quot;human view&quot; I assume is responsible for all rendering (graphics and sound), but it also processes input. If the input processing is split from the view, you can have different implementations of the controller.
</p></div></div><p>

Controllers ought to be abstracted so the game view can&#39;t even tell what kind of controller the player is using. That allows for the different implementations.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
This may be useful for demo playback, or for spectating in an online game (where the input comes from a remote player).
</p></div></div><p>

The architecture already allows this, since input from remote players goes through the same channels as local players. Demo playback is essentially a dummy AI agent that sends messages from a game record file. As for spectating, you would just have to disallow input for the spectator and use the regular client game logic.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Thu, 05 Apr 2007 20:47:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The only problem with Kibiz0r&#39;s main I see is that init usually allocates some memory such as creating buffers, ...</p><p>This way you can still call deinit to free any allocated memory.</p><p>Here is my typical app. main creates a buffer, loads a datafile, ...<br />I don&#39;t want to worry about freeing them in init if the something fails.
</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">// app.h</span></td></tr><tr><td class="number">2</td><td><span class="k1">class</span> App</td></tr><tr><td class="number">3</td><td><span class="k2">{</span></td></tr><tr><td class="number">4</td><td>public:</td></tr><tr><td class="number">5</td><td>    App<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td>    ~App<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>    <span class="k1">static</span> <span class="k1">int</span> main<span class="k2">(</span> <span class="k1">int</span> argc, <span class="k1">char</span> <span class="k3">*</span><span class="k3">*</span>argv <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>private:</td></tr><tr><td class="number">10</td><td>    <span class="k1">int</span> init<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">11</td><td>    <span class="k1">void</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_519.html" target="_blank">kill</a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">12</td><td>    <span class="k1">void</span> loop<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>    <span class="k1">void</span> draw<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>    <span class="k1">void</span> logic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>    <span class="k1">static</span> <span class="k1">void</span> callback<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>&#160;</td></tr><tr><td class="number">18</td><td>    <span class="k1">static</span> <span class="k1">bool</span> cbPressed<span class="k2">;</span></td></tr><tr><td class="number">19</td><td>    <span class="k1">static</span> <span class="k1">bool</span> shutDown<span class="k2">;</span></td></tr><tr><td class="number">20</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">21</td><td>&#160;</td></tr><tr><td class="number">22</td><td><span class="c">// app.cpp</span></td></tr><tr><td class="number">23</td><td><span class="p">#include "alleg.h"</span></td></tr><tr><td class="number">24</td><td><span class="p">#include "globals.h"</span></td></tr><tr><td class="number">25</td><td><span class="p">#include "defines.h"</span></td></tr><tr><td class="number">26</td><td><span class="p">#include "app.h"</span></td></tr><tr><td class="number">27</td><td><span class="p">#include "timer.h"</span></td></tr><tr><td class="number">28</td><td><span class="p">#include "log.h"</span></td></tr><tr><td class="number">29</td><td><span class="p">#include "gfx.h"</span></td></tr><tr><td class="number">30</td><td><span class="p">#include "input.h"</span></td></tr><tr><td class="number">31</td><td>&#160;</td></tr><tr><td class="number">32</td><td><span class="k1">bool</span> App::cbPressed <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">33</td><td><span class="k1">bool</span> App::shutDown <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">34</td><td>&#160;</td></tr><tr><td class="number">35</td><td><span class="k1">int</span> main<span class="k2">(</span> <span class="k1">int</span> argc, <span class="k1">char</span> <span class="k3">*</span><span class="k3">*</span>argv <span class="k2">)</span></td></tr><tr><td class="number">36</td><td><span class="k2">{</span></td></tr><tr><td class="number">37</td><td>    <span class="k1">return</span> App::main<span class="k2">(</span> argc, argv <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">38</td><td><span class="k2">}</span></td></tr><tr><td class="number">39</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">40</td><td>&#160;</td></tr><tr><td class="number">41</td><td>App::App<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">42</td><td><span class="k2">{</span></td></tr><tr><td class="number">43</td><td><span class="k2">}</span></td></tr><tr><td class="number">44</td><td>&#160;</td></tr><tr><td class="number">45</td><td>App::~App<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">46</td><td><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>&#160;</td></tr><tr><td class="number">49</td><td><span class="k1">int</span> App::main<span class="k2">(</span> <span class="k1">int</span> argc, <span class="k1">char</span> <span class="k3">*</span><span class="k3">*</span>argv <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>    App app<span class="k2">;</span></td></tr><tr><td class="number">52</td><td>&#160;</td></tr><tr><td class="number">53</td><td>    log.open<span class="k2">(</span> logFilename <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>&#160;</td></tr><tr><td class="number">55</td><td>    <span class="k1">if</span> <span class="k2">(</span> app.init<span class="k2">(</span><span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> <span class="n">0</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>        app.loop<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">59</td><td>&#160;</td></tr><tr><td class="number">60</td><td>    app.kill<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">61</td><td>&#160;</td></tr><tr><td class="number">62</td><td>    log.close<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">63</td><td>&#160;</td></tr><tr><td class="number">64</td><td>    <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">65</td><td><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="k1">int</span> App::init<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">68</td><td><span class="k2">{</span></td></tr><tr><td class="number">69</td><td>    <span class="k1">char</span> fullPath<span class="k2">[</span> <span class="n">1024</span> <span class="k2">]</span> <span class="k3">=</span> <span class="s">""</span><span class="k2">;</span></td></tr><tr><td class="number">70</td><td>    <span class="k1">char</span> workingDirectory<span class="k2">[</span> <span class="n">1024</span> <span class="k2">]</span> <span class="k3">=</span> <span class="s">""</span><span class="k2">;</span></td></tr><tr><td class="number">71</td><td>&#160;</td></tr><tr><td class="number">72</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Game startup begun"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">73</td><td>&#160;</td></tr><tr><td class="number">74</td><td>    <span class="k1">if</span> <span class="k2">(</span> <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="k3">&lt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">75</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">76</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Allegro Library could not be initialized"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">77</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">78</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">79</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Allegro Library initialized"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<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="p">#ifndef _DEBUG</span></td></tr><tr><td class="number">82</td><td>    <a href="http://www.allegro.cc/manual/get_executable_name" target="_blank"><span class="a">get_executable_name</span></a><span class="k2">(</span> fullPath,</td></tr><tr><td class="number">83</td><td>                         <span class="k1">sizeof</span><span class="k2">(</span> fullPath <span class="k2">)</span> <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">84</td><td>&#160;</td></tr><tr><td class="number">85</td><td>    <a href="http://www.allegro.cc/manual/replace_filename" target="_blank"><span class="a">replace_filename</span></a><span class="k2">(</span> workingDirectory,</td></tr><tr><td class="number">86</td><td>                      fullPath,</td></tr><tr><td class="number">87</td><td>                      <span class="s">""</span>,</td></tr><tr><td class="number">88</td><td>                      <span class="k1">sizeof</span><span class="k2">(</span> workingDirectory <span class="k2">)</span> <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">89</td><td>&#160;</td></tr><tr><td class="number">90</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_92.html" target="_blank">chdir</a><span class="k2">(</span> workingDirectory <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">91</td><td><span class="p">#endif</span></td></tr><tr><td class="number">92</td><td>&#160;</td></tr><tr><td class="number">93</td><td>&#160;</td></tr><tr><td class="number">94</td><td>    <a href="http://www.allegro.cc/manual/set_config_file" target="_blank"><span class="a">set_config_file</span></a><span class="k2">(</span> cfgFilename <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">95</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> gameTitle <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">96</td><td>    <a href="http://www.allegro.cc/manual/set_display_switch_mode" target="_blank"><span class="a">set_display_switch_mode</span></a><span class="k2">(</span> SWITCH_BACKGROUND <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">97</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> App::callback <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">98</td><td>&#160;</td></tr><tr><td class="number">99</td><td>    <span class="k1">if</span> <span class="k2">(</span> Gfx::setMode<span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">100</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">101</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</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="k1">else</span></td></tr><tr><td class="number">104</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">105</td><td>        <a href="http://www.allegro.cc/manual/clear_bitmap" target="_blank"><span class="a">clear_bitmap</span></a><span class="k2">(</span> <a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a> <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">106</td><td>        <a href="http://www.allegro.cc/manual/textout_ex" target="_blank"><span class="a">textout_ex</span></a><span class="k2">(</span> <a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>, <a href="http://www.allegro.cc/manual/font" target="_blank"><span class="a">font</span></a>, <span class="s">"Loading ..."</span>, <span class="n">8</span>, <span class="n">8</span>, <a href="http://www.allegro.cc/manual/makecol" target="_blank"><span class="a">makecol</span></a><span class="k2">(</span> <span class="n">255</span>, <span class="n">255</span>, <span class="n">255</span> <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">107</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">108</td><td>&#160;</td></tr><tr><td class="number">109</td><td>&#160;</td></tr><tr><td class="number">110</td><td>    <span class="k1">if</span> <span class="k2">(</span> <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="k3">&lt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">111</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">112</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Keyboard could not be installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">113</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">114</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">115</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Keyboard installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">116</td><td>&#160;</td></tr><tr><td class="number">117</td><td>    <span class="k1">if</span> <span class="k2">(</span> <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="k3">&lt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">118</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">119</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Timer could not be installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">120</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">121</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">122</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Timer installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">123</td><td>&#160;</td></tr><tr><td class="number">124</td><td>    <span class="k1">if</span> <span class="k2">(</span> Timer::install<span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">125</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">126</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Timers could not be installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">127</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">4</span><span class="k2">;</span></td></tr><tr><td class="number">128</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">129</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Timers installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">130</td><td>&#160;</td></tr><tr><td class="number">131</td><td>    <span class="k1">if</span> <span class="k2">(</span> <a href="http://www.allegro.cc/manual/install_mouse" target="_blank"><span class="a">install_mouse</span></a><span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">132</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">133</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Mouse could not be installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">134</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><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.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Mouse installed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<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">if</span> <span class="k2">(</span> <span class="k3">!</span><span class="k2">(</span> Global::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> bufferWidth, bufferHeight <span class="k2">)</span> <span class="k2">)</span> <span class="k2">)</span></td></tr><tr><td class="number">139</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">140</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Double buffer could not be created"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">141</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">142</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">143</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Double buffer created"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">144</td><td>    <a href="http://www.allegro.cc/manual/clear_bitmap" target="_blank"><span class="a">clear_bitmap</span></a><span class="k2">(</span> Global::buffer <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">145</td><td>&#160;</td></tr><tr><td class="number">146</td><td>    <span class="k1">if</span> <span class="k2">(</span> <span class="k3">!</span><span class="k2">(</span> Global::datafile <span class="k3">=</span> <a href="http://www.allegro.cc/manual/load_datafile" target="_blank"><span class="a">load_datafile</span></a><span class="k2">(</span> datFilename <span class="k2">)</span> <span class="k2">)</span> <span class="k2">)</span></td></tr><tr><td class="number">147</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">148</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Datafile '"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> datFilename <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"' could not be loaded"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">149</td><td>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">150</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">151</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Datafile '"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> datFilename <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"' loaded"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">152</td><td>&#160;</td></tr><tr><td class="number">153</td><td>    input.enable<span class="k2">(</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>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_739.html" target="_blank">srand</a><span class="k2">(</span> <span class="k2">(</span><span class="k1">int</span><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></td></tr><tr><td class="number">156</td><td>&#160;</td></tr><tr><td class="number">157</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Game startup complete"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<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="k1">return</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">160</td><td><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="k1">void</span> App::kill<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">163</td><td><span class="k2">{</span></td></tr><tr><td class="number">164</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl <span class="k3">&lt;</span><span class="k3">&lt;</span> endl <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Game shutdown begun"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<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="k1">if</span> <span class="k2">(</span> Global::datafile <span class="k2">)</span></td></tr><tr><td class="number">167</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">168</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Datafile unloaded"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">169</td><td>        <a href="http://www.allegro.cc/manual/unload_datafile" target="_blank"><span class="a">unload_datafile</span></a><span class="k2">(</span> Global::datafile <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">170</td><td>        Global::datafile <span class="k3">=</span> NULL<span class="k2">;</span></td></tr><tr><td class="number">171</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">172</td><td>&#160;</td></tr><tr><td class="number">173</td><td>    <span class="k1">if</span> <span class="k2">(</span> Global::buffer <span class="k2">)</span></td></tr><tr><td class="number">174</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">175</td><td>        <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Double buffer destroyed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">176</td><td>        <a href="http://www.allegro.cc/manual/destroy_bitmap" target="_blank"><span class="a">destroy_bitmap</span></a><span class="k2">(</span> Global::buffer <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">177</td><td>        Global::buffer <span class="k3">=</span> NULL<span class="k2">;</span></td></tr><tr><td class="number">178</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">179</td><td>&#160;</td></tr><tr><td class="number">180</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Text mode set"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">181</td><td>    <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_TEXT, <span class="n">0</span>, <span class="n">0</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">182</td><td>&#160;</td></tr><tr><td class="number">183</td><td>    <a href="http://www.allegro.cc/manual/allegro_exit" target="_blank"><span class="a">allegro_exit</span></a><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.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Allegro Library uninitialized"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">185</td><td>&#160;</td></tr><tr><td class="number">186</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Game shutdown complete"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">187</td><td><span class="k2">}</span></td></tr><tr><td class="number">188</td><td>&#160;</td></tr><tr><td class="number">189</td><td><span class="k1">void</span> App::loop<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">190</td><td><span class="k2">{</span></td></tr><tr><td class="number">191</td><td>    <span class="k1">while</span> <span class="k2">(</span> <span class="k3">!</span>App::shutDown <span class="k2">)</span></td></tr><tr><td class="number">192</td><td>    <span class="k2">{</span>       </td></tr><tr><td class="number">193</td><td>        this-&gt;draw<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">194</td><td>&#160;</td></tr><tr><td class="number">195</td><td>        <span class="k1">while</span> <span class="k2">(</span> Timer::logicTimer <span class="k3">&gt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">196</td><td>        <span class="k2">{</span></td></tr><tr><td class="number">197</td><td>            Timer::logicTimer--<span class="k2">;</span></td></tr><tr><td class="number">198</td><td>            this-&gt;logic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">199</td><td>        <span class="k2">}</span></td></tr><tr><td class="number">200</td><td>&#160;</td></tr><tr><td class="number">201</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_ESC <span class="k2">]</span> <span class="k3">|</span><span class="k3">|</span></td></tr><tr><td class="number">202</td><td>            App::cbPressed <span class="k2">)</span></td></tr><tr><td class="number">203</td><td>        <span class="k2">{</span></td></tr><tr><td class="number">204</td><td>            App::shutDown <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span></td></tr><tr><td class="number">205</td><td>        <span class="k2">}</span></td></tr><tr><td class="number">206</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">207</td><td><span class="k2">}</span></td></tr><tr><td class="number">208</td><td>&#160;</td></tr><tr><td class="number">209</td><td><span class="k1">void</span> App::draw<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">210</td><td><span class="k2">{</span></td></tr><tr><td class="number">211</td><td>    <a href="http://www.allegro.cc/manual/clear_bitmap" target="_blank"><span class="a">clear_bitmap</span></a><span class="k2">(</span> Global::buffer <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">212</td><td>&#160;</td></tr><tr><td class="number">213</td><td>    Gfx::flip<span class="k2">(</span> Global::buffer <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">214</td><td><span class="k2">}</span></td></tr><tr><td class="number">215</td><td>&#160;</td></tr><tr><td class="number">216</td><td><span class="k1">void</span> App::logic<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">217</td><td><span class="k2">{</span></td></tr><tr><td class="number">218</td><td><span class="k2">}</span></td></tr><tr><td class="number">219</td><td>&#160;</td></tr><tr><td class="number">220</td><td><span class="k1">void</span> App::callback<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">221</td><td><span class="k2">{</span></td></tr><tr><td class="number">222</td><td>    <a href="http://www.delorie.com/djgpp/doc/libc/libc_542.html" target="_blank">log</a> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"Close button pressed"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> endl<span class="k2">;</span></td></tr><tr><td class="number">223</td><td>    App::cbPressed <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span></td></tr><tr><td class="number">224</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>


His run loop I don&#39;t like. What&#39;s up with the rest()? </p><p>Use Miran&#39;s. Do all logic, this might include multiple sets of logic. <br />Then draw the updated graphics once.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DanielH)</author>
		<pubDate>Thu, 05 Apr 2007 22:31:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you do it Miran&#39;s way, don&#39;t use a message system, because it will process all messages that have been queued up in multiple logic frames inside the equivalent of one logic frame.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
What&#39;s up with the rest()?
</p></div></div><p>

I was <i>told</i> that rest(0) yields to other processes. We ought to not use the CPU as long as logic doesn&#39;t need to be updated, yeah?</p><p>Edit: Your code looks eerily similar to mine, it gave me chills, heh. Your loop, though... it will draw the current frame <i>again</i> if logic time == 0.</p><p>Edit 2:
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
The only problem with Kibiz0r&#39;s main I see is that init usually allocates some memory such as creating buffers, ...</p><p>This way you can still call deinit to free any allocated memory.
</p></div></div><p>

Yeah, it&#39;s in the book that way, I don&#39;t know why I noobed it up. <img src="http://www.allegro.cc/forums/smileys/cry.gif" alt=":&#39;(" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Thu, 05 Apr 2007 22:40:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
4. If you run your program in a window, try not to run a 16-bit application with a 32-bit desktop or vice versa as you&#39;ll get some additional slowdown. (The amount of which will vary depending on how good your video card is.) 15-bit and 24-bit are very strange to work with anymore and you should avoid them. 8-bit should run fine in a window at any bit-depth desktop.
</p></div></div><p>
15-bit IS 16-bit, it just uses a different color format (RGB-555 vs. RGB-565). It ignores one of the bits, but it&#39;s still there, and you could safely use it for storage if you wanted - just like 32-bit ignores a full byte. 24-bit is strange to work with if you need direct access to pixel data, otherwise it&#39;s exactly the same as 32-bit. And since some GFX cards prefer 24-bit over 32-bit (yes, some still do), I&#39;d support it anyway, if only for the final display (leaving all sprites at 16 / 32). 15 &lt;-&gt; 16 and 24 &lt;-&gt; 32 conversions are relatively cheap.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Fri, 06 Apr 2007 12:49:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Controllers ought to be abstracted so the game view can&#39;t even tell what kind of controller the player is using. That allows for the different implementations.
</p></div></div><p>
But it also makes it a bit more difficult to make a good control scheme if you have to work on an abstracted layer with no assumptions about the control method (eg. using a keyboard will work differently than using a joystick, which will work differently than a gamepad, etc). Sure th ey can be abstracted to properly work on them all, but then the controls can&#39;t be as tailored to the control type the player is using, which can make things feel clunky.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I was told that rest(0) yields to other processes. We ought to not use the CPU as long as logic doesn&#39;t need to be updated, yeah?
</p></div></div><p>
rest(0) only yields the CPU, but returns ASAP. rest(1) will give away the CPU for at least 1 millisecond and return ASAP after that. The former will reduce CPU usage, while rest(0) takes full CPU usage.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kitty Cat)</author>
		<pubDate>Fri, 06 Apr 2007 13:01:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I prefer the semaphore mechanism myself.<br />Literally the same thing as the tick variable but goes to sleep in the main loop if the value is 0. It will wake up when the value goes back up above 0.</p><p>There are various portable libraries, and standard OS implementations.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Goalie Ca)</author>
		<pubDate>Sat, 07 Apr 2007 03:25:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This is good stuff i think i am having the same problem. i do music and sound effects in the logic loop how much of a slow down are we talking about.<br />and for 32bit thingy are you talking about changing the graphics mode to 16 or the sprites?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (piccolo)</author>
		<pubDate>Sat, 07 Apr 2007 04:59:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
But it also makes it a bit more difficult to make a good control scheme if you have to work on an abstracted layer with no assumptions about the control method (eg. using a keyboard will work differently than using a joystick, which will work differently than a gamepad, etc). Sure th ey can be abstracted to properly work on them all, but then the controls can&#39;t be as tailored to the control type the player is using, which can make things feel clunky.
</p></div></div><p>

What I meant to say was that the &quot;Input Interpreter&quot; ought to serve the same function and <i>send</i> the same messages regardless of the control scheme, but can have completely different ways of going about it, depending on what kind of input we&#39;re talking about.</p><p>For example, Up on a d-pad might only result in a message like <tt>Accelerate 100%</tt>, whereas on an analog stick, it could send anything from <tt>Accelerate 1%</tt> to <tt>Accelerate 100%</tt>.</p><p>As for clunkiness arising from supporting multiple methods of input... It&#39;s a problem that exists no matter what setup you use, really. As game designers, we try to set it up so that it feels right to us, but another player might have a completely different idea of what feels right. But that&#39;s the strength of this architecture: you can specialize the way input is interpreted for each device without changing the way the game itself is played.</p><p>I do have a question, though: Should dead zones be applied in the application layer, or the game view?<br />It alters the input itself, not how it is interpreted as a game command... yet, the amount of dead zone may have to do with personalized options, which are associated with the game view and really shouldn&#39;t be within a stone&#39;s throw of the application layer.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Tue, 10 Apr 2007 16:21:39 +0000</pubDate>
	</item>
</rss>
