<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Perfect Game Loop (A5 edition)</title>
		<link>http://www.allegro.cc/forums/view/598066</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 29 Oct 2008 16:57:29 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>So, since I recently decided to start playing around with A5, I again decided to tackle the problem of the perfect game loop for fixed timestep timing system (the only deterministic system there is).</p><p>I&#39;ve came up with two approaches, which roughly operate to give the same resulting logic per second and frame per second rates.</p><p>This first approach uses A5 events and timers in a very hacky fashion. I don&#39;t really like it, although it takes the fewest number of lines, and perhaps is easier to understand. Basically, we use a timer only event queue to control our logic updates, and at the same time rest when possible.</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">int</span> refresh_rate <span class="k3">=</span> <span class="n">60</span><span class="k2">;</span></td></tr><tr><td class="number">2</td><td><span class="k1">float</span> max_logic_time <span class="k3">=</span> <span class="n">0</span>.<span class="n">5f</span> <span class="k3">/</span> refresh_rate<span class="k2">;</span></td></tr><tr><td class="number">3</td><td>ALLEGRO_EVENT timer_dummy<span class="k2">;</span></td></tr><tr><td class="number">4</td><td>&#160;</td></tr><tr><td class="number">5</td><td>ALLEGRO_TIMER <span class="k3">*</span>timer <span class="k3">=</span> al_install_timer<span class="k2">(</span>ALLEGRO_BPS_TO_SECS<span class="k2">(</span>refresh_rate<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td>al_start_timer<span class="k2">(</span>timer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>ALLEGRO_EVENT_QUEUE <span class="k3">*</span>timer_queue <span class="k3">=</span> al_create_event_queue<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>al_register_event_source<span class="k2">(</span>timer_queue, <span class="k2">(</span>ALLEGRO_EVENT_SOURCE<span class="k3">*</span><span class="k2">)</span>timer<span class="k2">)</span><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">bool</span> done <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">11</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<span class="k2">)</span></td></tr><tr><td class="number">12</td><td><span class="k2">{</span>  </td></tr><tr><td class="number">13</td><td>  al_wait_for_event<span class="k2">(</span>timer_queue, <span class="k3">&amp;</span>timer_dummy<span class="k2">)</span><span class="k2">;</span><span class="c">//rest at least the fixed time step</span></td></tr><tr><td class="number">14</td><td>  <span class="k1">double</span> start_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>  <span class="k1">do</span></td></tr><tr><td class="number">16</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">17</td><td>    DoLogic<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">18</td><td>    </td></tr><tr><td class="number">19</td><td>    <span class="k1">if</span><span class="k2">(</span>al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> start_time <span class="k3">&gt;</span> max_logic_time<span class="k2">)</span><span class="c">//break if we are taking too long</span></td></tr><tr><td class="number">20</td><td>      <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">21</td><td>  <span class="k2">}</span> <span class="k1">while</span><span class="k2">(</span>al_get_next_event<span class="k2">(</span>timer_queue, <span class="k3">&amp;</span>timer_dummy<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>&#160;</td></tr><tr><td class="number">23</td><td>  al_flush_event_queue<span class="k2">(</span>timer_queue<span class="k2">)</span><span class="k2">;</span><span class="c">//remove excess overflow</span></td></tr><tr><td class="number">24</td><td>  </td></tr><tr><td class="number">25</td><td>  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">26</td><td>  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">27</td><td>  </td></tr><tr><td class="number">28</td><td>  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">29</td><td>  </td></tr><tr><td class="number">30</td><td>  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">31</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

The second approach takes more lines, but it does not use A5 timers or events, making it a little more elegant in that sense. It&#39;s operation is a little more complicated, but I am sure you all will be able to figure it out. Another advantage of this method is that it maps a little more closely to the abortive delta timing method, making it a little more tractable.</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">int</span> refresh_rate <span class="k3">=</span> <span class="n">60</span><span class="k2">;</span></td></tr><tr><td class="number">2</td><td><span class="k1">double</span> fixed_dt <span class="k3">=</span> <span class="n">1</span>.<span class="n">0f</span> <span class="k3">/</span> refresh_rate<span class="k2">;</span></td></tr><tr><td class="number">3</td><td><span class="k1">double</span> old_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k1">double</span> game_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="k1">bool</span> done <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<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>  <span class="k1">double</span> dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span></td></tr><tr><td class="number">10</td><td>  al_rest<span class="k2">(</span>fixed_dt <span class="k3">-</span> dt<span class="k2">)</span><span class="k2">;</span> <span class="c">//rest at least fixed_dt</span></td></tr><tr><td class="number">11</td><td>  dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span></td></tr><tr><td class="number">12</td><td>  old_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>  </td></tr><tr><td class="number">14</td><td>  <span class="k1">if</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time <span class="k3">&gt;</span> dt<span class="k2">)</span><span class="c">//eliminate excess overflow</span></td></tr><tr><td class="number">15</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">16</td><td>    game_time <span class="k3">+</span><span class="k3">=</span> fixed_dt <span class="k3">*</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time<span class="k2">)</span> <span class="k3">/</span> fixed_dt<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">18</td><td>  </td></tr><tr><td class="number">19</td><td>  <span class="k1">double</span> start_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">20</td><td>  <span class="k1">while</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time <span class="k3">&gt;</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">21</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">22</td><td>    game_time <span class="k3">+</span><span class="k3">=</span> fixed_dt<span class="k2">;</span></td></tr><tr><td class="number">23</td><td>    </td></tr><tr><td class="number">24</td><td>    DoLogic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>    </td></tr><tr><td class="number">26</td><td>    <span class="k1">if</span><span class="k2">(</span>al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> start_time <span class="k3">&gt;</span> fixed_dt <span class="k3">*</span> <span class="n">0</span>.<span class="n">5</span><span class="k2">)</span><span class="c">//break if we start taking too long</span></td></tr><tr><td class="number">27</td><td>      <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">28</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">29</td><td>  </td></tr><tr><td class="number">30</td><td>  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">31</td><td>  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">32</td><td>  </td></tr><tr><td class="number">33</td><td>  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">34</td><td>  </td></tr><tr><td class="number">35</td><td>  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">36</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

So yeah... comments/suggestions? I think the second one can be improved by hiding some of its functionality behind functions, for one.<br /> <br /> <br /><b>EDIT:</b></p><p>Notably, if you promise that your DoLogic() will never ever ever ever take longer than the fixed time step to complete, you can simplify the versions as follows:</p><p>A5 Timer/Event:
</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">int</span> refresh_rate <span class="k3">=</span> <span class="n">60</span><span class="k2">;</span></td></tr><tr><td class="number">2</td><td>ALLEGRO_EVENT timer_dummy<span class="k2">;</span></td></tr><tr><td class="number">3</td><td>&#160;</td></tr><tr><td class="number">4</td><td>ALLEGRO_TIMER <span class="k3">*</span>timer <span class="k3">=</span> al_install_timer<span class="k2">(</span>ALLEGRO_BPS_TO_SECS<span class="k2">(</span>refresh_rate<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">5</td><td>al_start_timer<span class="k2">(</span>timer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td>ALLEGRO_EVENT_QUEUE <span class="k3">*</span>timer_queue <span class="k3">=</span> al_create_event_queue<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>al_register_event_source<span class="k2">(</span>timer_queue, <span class="k2">(</span>ALLEGRO_EVENT_SOURCE<span class="k3">*</span><span class="k2">)</span>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">bool</span> done <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<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>  al_wait_for_event<span class="k2">(</span>timer_queue, <span class="k3">&amp;</span>timer_dummy<span class="k2">)</span><span class="k2">;</span><span class="c">//rest at least the fixed time step</span></td></tr><tr><td class="number">13</td><td>  <span class="k1">do</span></td></tr><tr><td class="number">14</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">15</td><td>    DoLogic<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">16</td><td>  <span class="k2">}</span> <span class="k1">while</span><span class="k2">(</span>al_get_next_event<span class="k2">(</span>timer_queue, <span class="k3">&amp;</span>timer_dummy<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>  </td></tr><tr><td class="number">18</td><td>  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td>  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">20</td><td>  </td></tr><tr><td class="number">21</td><td>  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>  </td></tr><tr><td class="number">23</td><td>  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr></tbody></table></div></div><p>

A5 cur_time:</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">int</span> refresh_rate <span class="k3">=</span> <span class="n">60</span><span class="k2">;</span></td></tr><tr><td class="number">2</td><td><span class="k1">double</span> fixed_dt <span class="k3">=</span> <span class="n">1</span>.<span class="n">0f</span> <span class="k3">/</span> refresh_rate<span class="k2">;</span></td></tr><tr><td class="number">3</td><td><span class="k1">double</span> old_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k1">double</span> game_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="k1">bool</span> done <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<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>  <span class="k1">double</span> dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span></td></tr><tr><td class="number">10</td><td>  al_rest<span class="k2">(</span>fixed_dt <span class="k3">-</span> dt<span class="k2">)</span><span class="k2">;</span> <span class="c">//rest at least fixed_dt</span></td></tr><tr><td class="number">11</td><td>  dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span></td></tr><tr><td class="number">12</td><td>  old_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>  </td></tr><tr><td class="number">14</td><td>  <span class="k1">while</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time <span class="k3">&gt;</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">15</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">16</td><td>    game_time <span class="k3">+</span><span class="k3">=</span> fixed_dt<span class="k2">;</span></td></tr><tr><td class="number">17</td><td>    </td></tr><tr><td class="number">18</td><td>    DoLogic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">20</td><td>  </td></tr><tr><td class="number">21</td><td>  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">23</td><td>  </td></tr><tr><td class="number">24</td><td>  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>  </td></tr><tr><td class="number">26</td><td>  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">27</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Fri, 24 Oct 2008 12:48:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
... for fixed timestep timing system (the only deterministic system there is).
</p></div></div><p>
Don&#39;t tell Newton!</p><p>My only useful comment: if al_rest can at any point rest a little too short (e.g. if it resnts to within ±2ms) then following:
</p><div class="source-code snippet"><div class="inner"><pre>al_rest<span class="k2">(</span>fixed_dt <span class="k3">-</span> dt<span class="k2">)</span><span class="k2">;</span> <span class="c">//rest at least fixed_dt</span>
  dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span>
</pre></div></div><p>
dt may be less than fixed_dt. Is that what you want? If al_rest has a stated accuracy then you should round down to th enearest multiple of that and then add one more multiple, if it doesn&#39;t then I guess there&#39;s little you can do.</p><p>Re:
</p><div class="source-code snippet"><div class="inner"><pre>  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span>
  
  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  
  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Would it not be more sensible to do:
</p><div class="source-code snippet"><div class="inner"><pre>  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span>
  
  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  
  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
Vsyncing before your draw and then flipping after whatever portion of a frame it takes you to draw is likely to lead to tearing.</p><p>Other than that, I&#39;ve yet to fully digest the code. And it&#39;s slightly past work o&#39;clock.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Fri, 24 Oct 2008 13:47:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Aha, thanks for the vsync tip. It doesn&#39;t really work at all for me, so I couldn&#39;t tell the difference between different locations for it. Your reasoning makes sense though.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Is that what you want? If al_rest has a stated accuracy then you should round down to th enearest multiple of that and then add one more multiple, if it doesn&#39;t then I guess there&#39;s little you can do.
</p></div></div><p>

The idea is that we rest until the time passed since we last measured time is at least fixed_dt. dt is usually smaller than fixed_dt, so we usually rest for some period of time.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Fri, 24 Oct 2008 22:16:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><span class="source-code">al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span></span> I believe that should be in DrawStuff();</p><p>Maybe this was with AllegroGL (and by extension, OpenLayer) only (and I haven&#39;t looked at Allegro5&#39;s docs yet), but doesn&#39;t calling al_flip_display(); imply al_wait_for_vsync(); on platforms that support vsync?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (MiquelFire)</author>
		<pubDate>Fri, 24 Oct 2008 22:51:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>No, it doesn&#39;t.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Fri, 24 Oct 2008 22:58:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
doesn&#39;t calling al_flip_display(); imply al_wait_for_vsync(); on platforms that support vsync?
</p></div></div><p>
It probably should (or at least be a parameter).</p><p>It&#39;s not clear to me that al_wait_for_vsync() is useful by itself.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Fri, 24 Oct 2008 23:29:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>How would it make any difference? The user calls al_wait_for_vsync then al_flip_display.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Sat, 25 Oct 2008 00:07:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What happens if al_flip_display() waits for vsync anyway (eg: an OpenGL backend)? Do we wait for vsync twice? If we ignore al_wait_for_vsync() on those platforms, apps lose the ability to time things using vsync (which is still useful for many reasons).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Sat, 25 Oct 2008 00:49:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The opengl backend doesn&#39;t wait for vsync AFAIK unless you call al_wait_for_vsync yourself.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Sat, 25 Oct 2008 02:30:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yes it does. At the end of the day, it calls wglSwapBuffers(), which is allowed to (and most of the time does) wait for vsync, by default.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Sat, 25 Oct 2008 03:15:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>We should remove al_wait_for_vsync and make it a display flag.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Sat, 25 Oct 2008 04:27:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
We should remove al_wait_for_vsync and make it a display flag.
</p></div></div><p>I was thinking the same thing. And a HINT at that. We can&#39;t guarantee its enabled or disabled since the user can force the issue in the driver settings.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sat, 25 Oct 2008 04:33:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Okay, I looked around some other forums, and Bullet source code, and it seems that this is the optimal solution. I probably will put it up on the wiki eventually...</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">int</span> refresh_rate <span class="k3">=</span> <span class="n">60</span><span class="k2">;</span></td></tr><tr><td class="number">2</td><td><span class="k1">double</span> fixed_dt <span class="k3">=</span> <span class="n">1</span>.<span class="n">0f</span> <span class="k3">/</span> refresh_rate<span class="k2">;</span></td></tr><tr><td class="number">3</td><td><span class="k1">double</span> old_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k1">double</span> game_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="k1">bool</span> done <span class="k3">=</span> <span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>done<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>  <span class="c">/*</span></td></tr><tr><td class="number">10</td><td><span class="c">  Standard rester:</span></td></tr><tr><td class="number">11</td><td><span class="c">  Forces the drawing to take at least one fixed_dt interval, reducing CPU usage</span></td></tr><tr><td class="number">12</td><td><span class="c">  in lighweight programs.</span></td></tr><tr><td class="number">13</td><td><span class="c">  */</span></td></tr><tr><td class="number">14</td><td>  <span class="k1">double</span> dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span></td></tr><tr><td class="number">15</td><td>  al_rest<span class="k2">(</span>fixed_dt <span class="k3">-</span> dt<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>  dt <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> old_time<span class="k2">;</span></td></tr><tr><td class="number">17</td><td>  old_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>  </td></tr><tr><td class="number">19</td><td>  <span class="c">/*</span></td></tr><tr><td class="number">20</td><td><span class="c">  Time overflow eliminator:</span></td></tr><tr><td class="number">21</td><td><span class="c">  Makes sure that when game time gets too far behind,</span></td></tr><tr><td class="number">22</td><td><span class="c">  the logic while loop does not enter a period of</span></td></tr><tr><td class="number">23</td><td><span class="c">  hyperactivity. Note that this may need to be eliminated</span></td></tr><tr><td class="number">24</td><td><span class="c">  for networked games, where game_time should be synchronized</span></td></tr><tr><td class="number">25</td><td><span class="c">  across machines. </span></td></tr><tr><td class="number">26</td><td><span class="c">  */</span></td></tr><tr><td class="number">27</td><td>  <span class="k1">if</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time <span class="k3">&gt;</span> dt<span class="k2">)</span></td></tr><tr><td class="number">28</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">29</td><td>    game_time <span class="k3">+</span><span class="k3">=</span> fixed_dt <span class="k3">*</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time<span class="k2">)</span> <span class="k3">/</span> fixed_dt<span class="k2">)</span><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>  </td></tr><tr><td class="number">32</td><td>  <span class="k1">double</span> start_time <span class="k3">=</span> al_current_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">33</td><td>  <span class="k1">while</span><span class="k2">(</span>old_time <span class="k3">-</span> game_time <span class="k3">&gt;</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">34</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">35</td><td>    game_time <span class="k3">+</span><span class="k3">=</span> fixed_dt<span class="k2">;</span></td></tr><tr><td class="number">36</td><td>    </td></tr><tr><td class="number">37</td><td>    DoLogic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">38</td><td>    </td></tr><tr><td class="number">39</td><td>    <span class="c">/*</span></td></tr><tr><td class="number">40</td><td><span class="c">    Logic time limiter:</span></td></tr><tr><td class="number">41</td><td><span class="c">    It ensures that the logic does not spiral out of control when it starts</span></td></tr><tr><td class="number">42</td><td><span class="c">    taking too long to complete. This measures the time for all of the logic</span></td></tr><tr><td class="number">43</td><td><span class="c">    steps, not just one. I find that this leads to a smoother operation than</span></td></tr><tr><td class="number">44</td><td><span class="c">    when limiting each step individually. This favours FPS over LPS.</span></td></tr><tr><td class="number">45</td><td><span class="c">    */</span>    </td></tr><tr><td class="number">46</td><td>    <span class="k1">if</span><span class="k2">(</span>al_current_time<span class="k2">(</span><span class="k2">)</span> <span class="k3">-</span> start_time <span class="k3">&gt;</span> fixed_dt<span class="k2">)</span></td></tr><tr><td class="number">47</td><td>      <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">48</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">49</td><td>&#160;</td></tr><tr><td class="number">50</td><td>  <span class="c">/*</span></td></tr><tr><td class="number">51</td><td><span class="c">  Various drawing operations go here</span></td></tr><tr><td class="number">52</td><td><span class="c">  */</span></td></tr><tr><td class="number">53</td><td>  al_clear<span class="k2">(</span>black<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>  </td></tr><tr><td class="number">55</td><td>  DrawStuff<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">56</td><td>&#160;</td></tr><tr><td class="number">57</td><td>  al_wait_for_vsync<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>  al_flip_display<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">59</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Wed, 29 Oct 2008 15:39:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Sorry, this is absolutely more my day job editor instincts coming out than my programmer instincts, but maybe chuck an extra comment in above &#39;double start_time = al_current_time();&#39; to the effect that the main logic call loop follows, so that it&#39;s more obvious to newbies where the section of code that &quot;may need to be eliminated for networked games&quot; ends?</p><p>My unnecessary, tedious pedantry also makes me comment again on:
</p><div class="quote_container"><div class="title">SiegeLord said:</div><div class="quote"><p>
fixed timestep timing system (the only deterministic system there is).
</p></div></div><p>
To the effect that my argument for disagreeing with your assertion is that real life isn&#39;t run on a fixed timestep system and you cannot build a deterministic system from a non-deterministic system.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Wed, 29 Oct 2008 16:45:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Sorry, this is absolutely more my day job editor instincts coming out than my programmer instincts, but maybe chuck an extra comment in above &#39;double start_time = al_current_time();&#39; to the effect that the main logic call loop follows, so that it&#39;s more obvious to newbies where the section of code that &quot;may need to be eliminated for networked games&quot; ends?
</p></div></div><p>
Ah, good point. I&#39;ll be more blatant about it, and why that actually works in the actual article.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
To the effect that my argument for disagreeing with your assertion is that real life isn&#39;t run on a fixed timestep system and you cannot build a deterministic system from a non-deterministic system.
</p></div></div><p>

What I mean by deterministic is that, given identical starting conditions, when you run a game it will run identically in every case. This is impossible (pretty much) to do with a variable time step, especially one dependent on framerate. There are other benefits to using fixed step timing of course, but that&#39;s irrelevant in this case.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Wed, 29 Oct 2008 16:57:29 +0000</pubDate>
	</item>
</rss>
