<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>fixing crashes, file sizes and array sizes.</title>
		<link>http://www.allegro.cc/forums/view/606675</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sat, 12 Mar 2011 23:46:33 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi again. I&#39;m approaching the end of my project. Before I try to figure out how to build a release version for it I&#39;m attempting to fix all the scenarios that can cause the program to crash.</p><p>Most of these issues come from array sizes not matching files.</p><p>Currently if I load a map file that doesn&#39;t match the dimensions of my current vector&lt;map&gt; it will fail.</p><p>This is one of the solutions I&#39;ve tried:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>
<span class="number">  2</span>file <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_fopen"><span class="a">al_fopen</span></a><span class="k2">(</span>a.c_str<span class="k2">(</span><span class="k2">)</span>, <span class="s">"r"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  3</span>
<span class="number">  4</span>  <span class="k1">if</span> <span class="k2">(</span><a href="http://www.allegro.cc/manual/al_fsize"><span class="a">al_fsize</span></a><span class="k2">(</span>file<span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> <span class="k2">(</span>map.getWidth<span class="k2">(</span><span class="k2">)</span><span class="k3">*</span>map.getHeight<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">)</span>
<span class="number">  5</span>  <span class="k2">{</span>
<span class="number">  6</span>    std::cout <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"success!"</span><span class="k2">;</span>
<span class="number">  7</span>
<span class="number">  8</span>    <span class="k1">for</span> <span class="k2">(</span><span class="k1">int</span> h <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> h<span class="k3">&lt;</span>map.getHeight<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> h<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
<span class="number">  9</span>    <span class="k2">{</span>
<span class="number"> 10</span>      <span class="k1">for</span> <span class="k2">(</span><span class="k1">int</span> w <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> w<span class="k3">&lt;</span>map.getWidth<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> w<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
<span class="number"> 11</span>      <span class="k2">{</span>
<span class="number"> 12</span>        map.map<span class="k2">[</span>h<span class="k3">*</span>map.getWidth<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>w<span class="k2">]</span>.setId<span class="k2">(</span><a href="http://www.allegro.cc/manual/al_fread32le"><span class="a">al_fread32le</span></a><span class="k2">(</span>file<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>        map.map<span class="k2">[</span>h<span class="k3">*</span>map.getWidth<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>w<span class="k2">]</span>.setBmp<span class="k2">(</span>pallet.pallet<span class="k2">[</span>map.map<span class="k2">[</span>h<span class="k3">*</span>map.getWidth<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>w<span class="k2">]</span>.getId<span class="k2">(</span><span class="k2">)</span><span class="k2">]</span>.getBmp<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 14</span>      <span class="k2">}</span>
<span class="number"> 15</span>    <span class="k2">}</span>
<span class="number"> 16</span>
<span class="number"> 17</span>    <a href="http://www.allegro.cc/manual/al_fclose"><span class="a">al_fclose</span></a><span class="k2">(</span>file<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 18</span>  <span class="k2">}</span>
<span class="number"> 19</span>  <span class="k1">else</span>
<span class="number"> 20</span>  <span class="k2">{</span>
<span class="number"> 21</span>    <a href="http://www.allegro.cc/manual/al_fclose"><span class="a">al_fclose</span></a><span class="k2">(</span>file<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 22</span>    std::cout <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"File size does not match map size!\n"</span><span class="k2">;</span>
<span class="number"> 23</span>  <span class="k2">}</span>
</div></div><p>

al_fsize(file) Does not equal the number of elements in my array. The manual isn&#39;t very clear on this, but I was assuming the al_fsize() gets the amount of data blocks in my file.</p><p>Now, the next thing I&#39;m considering (if there is no way to get do this with the previous method).</p><p>When I save the map file, write the map&#39;s width, and height in the first 2 blocks of the file. Then create a map that size before loading. My issue with doing this is:</p><p>If someone wanted to use my map editor files in their own program, they&#39;d have to know about thoes first two blocks of data.</p><p>I guess the question is.</p><p>Can I get by without adding array sizes to the files?</p><p>Is adding this extra data to the files a more practical solution for me and people that are potentually using them?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jason perkins)</author>
		<pubDate>Sat, 12 Mar 2011 11:33:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Every call to writing a 32-bit integer increases the file size by 4 bytes. So your file size will be w * h * 4 (assuming you write one integer per cell). I&#39;m not sure where you are storing the dimensions right now, but a file size of 16 &quot;blocks&quot; (i.e., one block = 4 bytes in this example) could be 4x4 or 8x2 or 16x1, etc. That is, you cannot deduce the width and height by only the total size.</p><p>Regardless of that, I would generally store the dimensions at the beginning.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Sat, 12 Mar 2011 11:37:58 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks alot, That&#39;s definately enough for me to get this working. I guess If someone where to use it. I&#39;d include a readme to tell them exactly how the files are made and how to access the information. So the first two blocks identifying the width/height wouldn&#39;t be much of an issue.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jason perkins)</author>
		<pubDate>Sat, 12 Mar 2011 11:46:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I like to have a header for the map file that contains as much info as possible about the file.  </p><p>I store the data it will write in a <span class="source-code"><span class="k1">struct</span></span> like this one:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">typedef</span> <span class="k1">struct</span> <span class="k2">{</span>

    <span class="k1">char</span> ident<span class="k2">[</span><span class="n">4</span><span class="k2">]</span><span class="k2">;</span>
    <span class="k1">uint32_t</span> width<span class="k2">;</span>
    <span class="k1">uint32_t</span> height<span class="k2">;</span>
    <span class="k1">uint32_t</span> num_tiles<span class="k2">;</span>
    <span class="k1">uint32_t</span> bytes_per_tile<span class="k2">;</span>
    <span class="k1">uint32_t</span> tile_data_length<span class="k2">;</span>
    <span class="k1">uint32_t</span> tile_data_offset<span class="k2">;</span>


<span class="k2">}</span> mapfile_header<span class="k2">;</span>
</pre></div></div><p>

<span class="source-code">ident</span> is a unique string (in this case, TMAP), that can be used to identify that a file being read is of the correct type.  <span class="source-code">width</span> and <span class="source-code">height</span> are pretty self-explanatory.  The number of tiles doesn&#39;t really need to be stored, since it can be easily calculated from the width and height, but I like to store it anyway.  To increase the flexibility of the format, I store the number of bytes per tile.  If a map has simple needs, a single char per tile may do, for complicated maps with layers, and many different tiles, each record could take up several bytes. <span class="source-code">tile_data_length</span> will be equal to <span class="source-code">num_tiles</span> * <span class="source-code">bytes_per_tile</span> but I again store it for use later.  <span class="source-code">tile_data_offset</span> stores the location in the file where the tile data starts.  This means we can add any amount of extra comments or data between the header and the tile data if we want to later.</p><p>You can check the sizes as you load it like this (test map using one byte per tile):</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">int</span> load_map<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>
<span class="number">  3</span>    <span class="k1">int</span> x, y<span class="k2">;</span>
<span class="number">  4</span>    <a href="http://www.allegro.cc/manual/PACKFILE"><span class="a">PACKFILE</span></a> <span class="k3">*</span>in <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_fopen"><span class="a">pack_fopen</span></a><span class="k2">(</span><span class="s">"test.map"</span>, F_READ<span class="k2">)</span><span class="k2">;</span>
<span class="number">  5</span>    <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>in<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  6</span>
<span class="number">  7</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Error opening map file!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number">  9</span>
<span class="number"> 10</span>    <span class="k2">}</span>
<span class="number"> 11</span>
<span class="number"> 12</span>    <a href="http://www.allegro.cc/manual/pack_fread"><span class="a">pack_fread</span></a><span class="k2">(</span>header.ident, <span class="n">4</span>, in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>    <span class="k1">if</span> <span class="k2">(</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_768.html" target="_blank">strncmp</a><span class="k2">(</span>header.ident, <span class="s">"TMAP"</span>, <span class="n">4</span><span class="k2">)</span> <span class="k3">!</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 14</span>
<span class="number"> 15</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Inalid file!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 16</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number"> 17</span>
<span class="number"> 18</span>    <span class="k2">}</span>
<span class="number"> 19</span>    header.width <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl"><span class="a">pack_igetl</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 20</span>    <span class="k1">if</span> <span class="k2">(</span>header.width <span class="k3">!</span><span class="k3">=</span> map.getWidth<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span>
<span class="number"> 21</span>
<span class="number"> 22</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Map width in header does not match!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 23</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number"> 24</span>
<span class="number"> 25</span>    <span class="k2">}</span>
<span class="number"> 26</span>    header.height <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl"><span class="a">pack_igetl</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 27</span>    <span class="k1">if</span> <span class="k2">(</span>header.height <span class="k3">!</span><span class="k3">=</span> map.getHeight<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span>
<span class="number"> 28</span>
<span class="number"> 29</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Map height in header does not match!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 30</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number"> 31</span>
<span class="number"> 32</span>    <span class="k2">}</span>
<span class="number"> 33</span>    header.num_tiles <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl"><span class="a">pack_igetl</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 34</span>    <span class="k1">if</span> <span class="k2">(</span>header.num_tiles <span class="k3">!</span><span class="k3">=</span> map.getWidth<span class="k2">(</span><span class="k2">)</span> <span class="k3">*</span> map.getHeight<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span>
<span class="number"> 35</span>
<span class="number"> 36</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Map size in header does not match!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 37</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number"> 38</span>
<span class="number"> 39</span>    <span class="k2">}</span>
<span class="number"> 40</span>    header.bytes_per_tile <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl"><span class="a">pack_igetl</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 41</span>    <span class="k1">if</span> <span class="k2">(</span>header.bytes_per_tile <span class="k3">!</span><span class="k3">=</span> <span class="k1">sizeof</span><span class="k2">(</span><span class="k1">uint8_t</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 42</span>
<span class="number"> 43</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Tile size in header does not match!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 44</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number"> 45</span>
<span class="number"> 46</span>    <span class="k2">}</span>
<span class="number"> 47</span>    header.tile_data_length <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl"><span class="a">pack_igetl</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 48</span>    <span class="k1">if</span> <span class="k2">(</span>header.tile_data_length <span class="k3">!</span><span class="k3">=</span> <span class="k1">sizeof</span><span class="k2">(</span><span class="k1">uint8_t</span><span class="k2">)</span> <span class="k3">*</span> map.getWidth<span class="k2">(</span><span class="k2">)</span> <span class="k3">*</span> map.getHeight<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 49</span>
<span class="number"> 50</span>        <a href="http://www.allegro.cc/manual/allegro_message"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"Tile data size in header does not match!"</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 51</span>        <span class="k1">return</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span>
<span class="number"> 52</span>
<span class="number"> 53</span>    <span class="k2">}</span>
<span class="number"> 54</span>    header.tile_data_offset <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl"><span class="a">pack_igetl</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 55</span>
<span class="number"> 56</span>    <span class="k1">for</span> <span class="k2">(</span>y <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> y <span class="k3">&lt;</span> TILES_H<span class="k2">;</span> y<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 57</span>
<span class="number"> 58</span>        <span class="k1">for</span> <span class="k2">(</span>x <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> x <span class="k3">&lt;</span> TILES_W<span class="k2">;</span> x<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 59</span>
<span class="number"> 60</span>            tilemap<span class="k2">[</span>x<span class="k2">]</span><span class="k2">[</span>y<span class="k2">]</span> <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_getc"><span class="a">pack_getc</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 61</span>
<span class="number"> 62</span>
<span class="number"> 63</span>        <span class="k2">}</span>
<span class="number"> 64</span>
<span class="number"> 65</span>    <span class="k2">}</span>
<span class="number"> 66</span>
<span class="number"> 67</span>    <a href="http://www.allegro.cc/manual/pack_fclose"><span class="a">pack_fclose</span></a><span class="k2">(</span>in<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 68</span>    <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 69</span>
<span class="number"> 70</span><span class="k2">}</span>
</div></div><p>

edit: you&#39;d need to convert that from A4 to A5, but that is pretty trivial.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (LennyLen)</author>
		<pubDate>Sat, 12 Mar 2011 19:30:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks Lenny, That looks very useful. Right now though the program isn&#39;t going to know in advance what sizes of files to expect. It&#39;s just for loading any file that was created by the same program. That looks like a solid system though. And once I start making maps I intend to use I&#39;ll probly come back and snag this code. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>I could have just mis-understood something, but it seems to me like that sort of system is used after you&#39;ve made a file, to make certain you&#39;re loading the correct data from it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jason perkins)</author>
		<pubDate>Sat, 12 Mar 2011 19:58:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Something else I always add to my map header is a version number.  So if you modify your map data in the future, you can update the version number so that old maps that were made using the old structure aren&#39;t loaded.  You could also easily create a converter to convert your maps from the old version to the new one (something I done a couple times with my Deluxe Pacman game).  So basically I had the header + version number as the first two pieces of data.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Neil Roy)</author>
		<pubDate>Sat, 12 Mar 2011 23:46:33 +0000</pubDate>
	</item>
</rss>
