<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kometbomb &#187; Programming</title>
	<atom:link href="http://kometbomb.net/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://kometbomb.net</link>
	<description>Programming and stuff.</description>
	<lastBuildDate>Thu, 27 Oct 2011 15:43:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Android NDK and SDL_RWops</title>
		<link>http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/</link>
		<comments>http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 14:48:53 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Android NDK]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Native]]></category>
		<category><![CDATA[SDL]]></category>
		<category><![CDATA[Source code]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=804</guid>
		<description><![CDATA[Note: There&#8217;s now a patch for SDL that makes the same possible on older Androids as well. The Android NDK makes it possible to use SDL to code Android apps. The aliens.c example bundled with the Android SDL port is fine and dandy except it reads data from /sdcard/data and it has to be pushed [...]]]></description>
			<content:encoded><![CDATA[<p><b>Note:</b> There&#8217;s now <a href="http://bugzilla.libsdl.org/show_bug.cgi?id=1261">a patch for SDL</a> that makes the same possible on older Androids as well.</p>
<p>The Android NDK makes it possible to use SDL to code Android apps. The aliens.c example bundled with the Android SDL port is fine and dandy except it reads data from /sdcard/data and it has to be pushed manually on the device. A nicer approach is to use the standard SDL way to load data from weird sources: with the SDL_RWops struct. We can use the Android AssetManager object to read data from the APK file (the assets directory in the project), Android 2.3 comes with <kbd>&lt;android/asset_manager.h&gt;</kbd> that has the needed helper NDK stuff.</p>
<p>Now, the SDL example is for Android 1.5 (or 1.6, I forget) which means it doesn&#8217;t use NativeActivity but instead rolls its own Java wrapper. That means we don&#8217;t have simple access to the asset manager &#8212; NativeActivity makes this easy because it calls the native code with all the useful stuff ready in a <kbd>struct android_app</kbd> &#8212; so we have to look it up ourselves. </p>
<p>In short:</p>
<ol>
<li>
<p>Get access to AAssetManager</p>
<ol>
<li>
<p>Using NativeActivity, it&#8217;s in struct android_app passed to android_main()</p>
</li>
<li>
<p>If struct android_app is not available (as in the SDL example), store JNI environment in a global variable in the SDL startup code and use it in your code to get AssetManager</p>
</li>
</ol>
</li>
<li>
<p>Use AAsset_RWFromAsset() defined below to get an SDL_RWops to a file inside the assets directory</p>
</li>
</ol>
<p>We have to modify the SDL startup method defined in the library source code:</p>
<h3 id="toc-sdl_android_main-cpp-line-19-ish">SDL_android_main.cpp (line 19-ish)</h3>
<pre><code>JNIEnv *g_env;

extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj)
{
    // Store the environment for later use.
    g_env = env;

    /* This interface could expand with ABI negotiation, calbacks, etc. */
    SDL_Android_Init(env, cls);

    /* Run the application code! */
    int status;
    char *argv[2];
    argv[0] = strdup("SDL_app");
    argv[1] = NULL;
    status = SDL_main(1, argv);

    /* We exit here for consistency with other platforms. */
    exit(status);
}</code></pre>
<h3 id="toc-main-c">main.c</h3>
<p>Note: <kbd>fatal()</kbd> is a macro that invokes the Android logging interfaces, much like the LOGE() macro.</p>
<pre><code>#include "android_rwops.h"
#include &lt;android/asset_manager_jni.h&gt;
#include &lt;jni.h&gt;

// g_env is set in SDL_android_main.cpp
extern JNIEnv *g_env;

// This function retrieves a static member of SDLActivity called mAssetMgr
// which is initialized in the onCreate() method like so:
// ...
//   mAssetMgr = getAssets();
// ...
// You can also call the getAssets() method from the native code.

AAssetManager * get_asset_manager()
{
	jclass sdlClass = (*g_env)-&gt;FindClass(g_env, "org/libsdl/app/SDLActivity");

	if (sdlClass == 0)
	{
		fatal("org/libsdl/app/SDLActivity not found.");
		return NULL;
	}

	jfieldID assman = (*g_env)-&gt;GetStaticFieldID(g_env, sdlClass,
                          "mAssetMgr", "Landroid/content/res/AssetManager;");

	if (assman == 0)
	{
		fatal("Could not find mAssetMgr.");
		return NULL;
	}

	jobject assets = (*g_env)-&gt;GetStaticObjectField(g_env, sdlClass, assman);

	if (assets == 0)
	{
		fatal("Could not get mAssetMgr.");
		return NULL;
	}

	return AAssetManager_fromJava(g_env, assets);
}

int main(int argc, char **argv)
{
  AAssetManager *assets = get_asset_manager();

  // You should check the return value, here we assume logo.png is found
  SDL_RWops *rw = AAsset_RWFromAsset(assets, "image.bmp");

  // Do whatever you want with the rwops
  GfxSurface *i = SDL_LoadBMP_RW(rw, 1);

  ...
}
</code></pre>
<h3 id="toc-android_rwops-h">android_rwops.h</h3>
<pre><code>#pragma once

#ifdef _cplusplus
extern "C" {
#endif

#include "SDL_rwops.h"
#include &lt;android/asset_manager.h&gt;

SDL_RWops * AAsset_RWFromAsset(AAssetManager *mgr, const char *filename);

#ifdef _cplusplus
}
#endif</code></pre>
<h3 id="toc-android_rwops-c">android_rwops.c</h3>
<pre><code>#include "android_rwops.h"

static SDLCALL long aa_rw_seek(struct SDL_RWops * ops, long offset, int whence)
{
	return AAsset_seek((AAsset*)ops-&gt;hidden.unknown.data1, offset, whence);
}

static SDLCALL size_t aa_rw_read(struct SDL_RWops * ops, void *ptr, size_t size, size_t maxnum)
{
	return AAsset_read((AAsset*)ops-&gt;hidden.unknown.data1, ptr, maxnum * size) / size;
}

static SDLCALL int aa_rw_close(struct SDL_RWops * ops)
{
	AAsset_close((AAsset*)ops-&gt;hidden.unknown.data1);
	SDL_FreeRW(ops);

	return 0;
}

SDL_RWops * AAsset_RWFromAsset(AAssetManager *mgr, const char *filename)
{
	AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_RANDOM);

	if (!asset)
		return NULL;

	SDL_RWops *ops = SDL_AllocRW();

	if (!ops)
	{
		AAsset_close(asset);
		return NULL;
	}

	ops-&gt;hidden.unknown.data1 = asset;
	ops-&gt;read = aa_rw_read;
	ops-&gt;write = NULL;
	ops-&gt;seek = aa_rw_seek;
	ops-&gt;close = aa_rw_close;

	return ops;
}</code></pre>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2009/09/22/introducing-my-latest-projects/" title="Introducing My Latest Projects">Introducing My Latest Projects</a></li><li><a href="http://kometbomb.net/2010/02/28/libconfig/" title="An Alternative to XML">An Alternative to XML</a></li><li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/" title="Creating a Simple GUI from Scratch">Creating a Simple GUI from Scratch</a></li><li><a href="http://kometbomb.net/2008/03/21/a-tiny-xml-parser/" title="A Tiny XML Parser">A Tiny XML Parser</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lossless Audio Compression</title>
		<link>http://kometbomb.net/2011/01/02/lossless-audio-compression/</link>
		<comments>http://kometbomb.net/2011/01/02/lossless-audio-compression/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 20:38:17 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[audio compression]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[klystrack]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=767</guid>
		<description><![CDATA[Here's an audio compression scheme I came up for <a href="http://code.google.com/p/klystrack/">my tracker project</a>. ]]></description>
			<content:encoded><![CDATA[<p><!--adsense_square-->
<div class="toc">
<ol>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-introduction">Introduction</a></li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-the-algorithm">The algorithm</a>
<ol>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-delta-encoding">Delta encoding</a></li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-gray-encoding">Gray encoding</a></li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-reordering-data-in-bit-planes">Reordering data in bit planes</a></li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-run-length-encoding">Run-length encoding</a></li>
</ol>
</li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-improvements">Improvements</a></li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-compression-results">Compression results</a></li>
<li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/#toc-source-code">Source code</a></li>
</ol>
</div>
<h2 id="toc-introduction">Introduction</h2>
<p>Here&#8217;s an audio compression scheme I came up for <a href="http://code.google.com/p/klystrack/">my tracker project</a>. Generally, I wanted an algorithm that meets these three conditions:</p>
<ul>
<li>Has to compress mono audio losslessly</li>
<li>Has to be simple, should be just one source code file or 500 lines of C code at most</li>
<li>Should compress 8-bit audio that&#8217;s upscaled to 16-bits to near 8 bits per sample</li>
</ul>
<p>The lossless requirement is obvious and the simplicity gives the benefit of not having to rely on external libraries (e.g. when using something like RAR compression) and not being overkill. The audio data is not huge in any case so the compression ratio doesn&#8217;t have to be exceptional. The last requirement is the most important: in klystrack, it is possible to load raw 8-bit audio files, usually originally from the Amiga computer. The native audio format in klystrack is 16-bit, however, so when saving the audio data there always are 8 redundant bits and the file will generally be twice as large as the original file. Also, since the software deals with low-fidelity aesthetics (chiptunes), the audio data might be even lower quality than 8-bit.</p>
<p>While there&#8217;s the option of detecting the bit fidelity and only saving the most significant bits, I thought it should be quite simple to devise an algorithm that automatically detects and leaves the redundant bits out while still doing some compression for even 16-bit audio data.</p>
<p><!--adsense_inside_post--></p>
<h2 id="toc-the-algorithm">The algorithm</h2>
<p>In short, the algorithm does this:</p>
<ol>
<li>
<p><a href="http://en.wikipedia.org/wiki/Delta_encoding">Delta code</a> input data</p>
</li>
<li>
<p><a href="http://en.wikipedia.org/wiki/Gray_code">Gray code</a> the data from above</p>
</li>
<li>
<p>Reorder the data from above in <a href="http://en.wikipedia.org/wiki/Bit_plane">bit planes</a>. I.e. first output the least significant bit of all samples, then the next bit for all samples and so forth</p>
</li>
<li>
<p><a href="http://en.wikipedia.org/wiki/Run-length_encoding">Run-length encode</a> the above data exploiting the fact you only need to store the distance between bit flips</p>
</li>
</ol>
<h3 id="toc-delta-encoding">Delta encoding</h3>
<p>By delta encoding the audio data, we can exploit the fact audio data very often changes just a little between samples and so the generated delta values (the amount of change) need fewer bits to be expressed. However, you can&#8217;t store 16-bit data with e.g. 8-bit delta values since it is not assured the change is always small enough to be stored in 8 bits, requiring the use of 16-bit delta values in the worst case. </p>
<h3 id="toc-gray-encoding">Gray encoding</h3>
<p>Using gray codes we can minimize the amount of bit flipping that happens (e.g. when a value changes between 7 and 8, where the bits change from <kbd>0111</kbd> to <kbd>1000</kbd> &#8212; three bits flip even if the value changes by one) to one bit flip between any two neighboring values. In practice, this doesn&#8217;t always result in better compression and sometimes it even can hurt the compression ratio.</p>
<h3 id="toc-reordering-data-in-bit-planes">Reordering data in bit planes</h3>
<p>This step is the key to good compression in our case. Between two neighboring delta values, it&#8217;s common that most of the bits are the same and it&#8217;s common for one bit to stay completely static for the whole data. So, we take the bits from all samples and sort them so that all significant bits come before the lesser bits. The result is long runs of bits, usually in the most significant bits.</p>
<p><!--adsense_inside_post--></p>
<h3 id="toc-run-length-encoding">Run-length encoding</h3>
<p>Finally, we take the encoded and reordered data and store the bits using RLE. While RLE usually stores the repeated data and the number of repetitions, we can exploit the fact the data is always zero or one, always changing between runs &#8212; only the starting state of the bit needs to be stored. <a href="http://en.wikipedia.org/wiki/Elias_gamma_coding">Elias gamma coding</a> is used to store the run-lengths since in most cases the run length is in the range of a few bits (for completely empty bit planes we can use special flags that tell they&#8217;re all zero or one) and tend to fall in 1-4 bits. With gamma coding it&#8217;s possible to store the number 1 by using one bit, the number two takes three bits. </p>
<p>Also, for some bit planes a raw dump of bits with no compression should be used if compression would result in much longer data than the original. There are also two special codes for the bit planes, in cases where all bits are zero or one (common if the audio data is quiet, i.e. uses only a subrange of the 16-bit resolution) or if the data is offset by a constant.</p>
<p>Depending on implementation the total overhead is around two bits per bit plane (i.e. 32 bits or two bytes for 16-bit audio data), not including the header data describing the compressed data (data length, uncompressed length). Since there&#8217;s the possibility of a raw dump of bits, in the worst case (none of the bit planes compress at all), the data size grows only by two bytes. A completely quiet (all zero bits) data will take only two bytes for any length. </p>
<h2 id="toc-improvements">Improvements</h2>
<p>My implementation only compresses the whole audio data as one big chunk but this can be easily improved to compress in chunks. This should improve the compression when there are parts where the audio is quiet and most of the bits will be zero.</p>
<p>Stereo audio can be compressed by compressing two chunks of data, one for both channels. The other channel should be delta coded compared to the other channel since in stereo audio the two channels often heavily correlate.</p>
<p>Since the Gray coding may even hurt compression, there should be the option to disable the coding for chunks. This can be simply by brute force, comparing which combination of options produces the shortest compressed data.</p>
<h2 id="toc-compression-results">Compression results</h2>
<p>The following contains example compression results. The Option column tells different configurations where the input data is delta coded and/or Gray coded.  This shows how different preprocessing steps work better for different kinds of input data.</p>
<p><em>Legend: 0 = no coding before compression, 1 = delta coding, 2 = Gray coding, 3 = delta and Gray coding.</em></p>
<style type="text/css">tr.best { background-color: #cfc; } table.maintable table td {text-align:right;}  table.maintable table tr.heading { background-color: #ddd; } table.maintable > tr > td { padding-right: 40px; }</style>
<table class="maintable">
<tr>
<td>
<table>
<tr class="heading">
<th>Options</th>
<th>Ratio</th>
</tr>
<tr>
<th colspan="2">Sine wave (loud)</th>
</tr>
<tr>
<td>0</td>
<td>73.1 %</td>
</tr>
<tr>
<td>1</td>
<td>29.6 %</td>
</tr>
<tr>
<td>2</td>
<td>67.9 %</td>
</tr>
<tr class="best">
<td>3</td>
<td>22.6 %</td>
</tr>
<tr>
<th colspan="2">White noise (loud)</th>
</tr>
<tr>
<td>0</td>
<td>100.0 %</td>
</tr>
<tr>
<td>1</td>
<td>100.0 %</td>
</tr>
<tr class="best">
<td>2</td>
<td>99.8 %</td>
</tr>
<tr>
<td>3</td>
<td>100.0 %</td>
</tr>
<tr>
<th colspan="2">Complex wave</th>
</tr>
<tr>
<td>0</td>
<td>75.3 %</td>
</tr>
<tr>
<td>1</td>
<td>38.2 %</td>
</tr>
<tr>
<td>2</td>
<td>69.6 %</td>
</tr>
<tr class="best">
<td>3</td>
<td>30.0 %</td>
</tr>
</table>
</td>
<td>
<table>
<tr class="heading">
<th>Options</th>
<th>Ratio</th>
</tr>
<tr>
<th colspan="2">Sine wave and noise</th>
</tr>
<tr>
<td>0</td>
<td>84.7 %</td>
</tr>
<tr>
<td>1</td>
<td>100.0 %</td>
</tr>
<tr class="best">
<td>2</td>
<td>80.9 %</td>
</tr>
<tr class="best">
<td>3</td>
<td>80.9 %</td>
</tr>
<tr>
<th colspan="2">White noise (quiet)</th>
</tr>
<tr class="best">
<td>0</td>
<td>50.0 %</td>
</tr>
<tr>
<td>1</td>
<td>100.0 %</td>
</tr>
<tr class="best">
<td>2</td>
<td>50.0 %</td>
</tr>
<tr>
<td>3</td>
<td>55.9 %</td>
</tr>
<tr>
<th colspan="2">Complex wave (saturated)</th>
</tr>
<tr>
<td>0</td>
<td>38.9 %</td>
</tr>
<tr>
<td>1</td>
<td>21.9 %</td>
</tr>
<tr>
<td>2</td>
<td>37.2 %</td>
</tr>
<tr class="best">
<td>3</td>
<td>17.7 %</td>
</tr>
</table>
</td>
</tr>
</table>
<h2 id="toc-source-code">Source code</h2>
<pre class="brush: cpp; title: ; notranslate">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;math.h&gt;

typedef unsigned char Uint8;
typedef short int Sint16;
typedef unsigned short int Uint16;
typedef int Sint32;
typedef unsigned int Uint32;

/* bitpack() bit plane codes */
enum
{
	BITPACK_STATIC0,
	BITPACK_STATIC1,
	BITPACK_LITERAL,
	BITPACK_RLE
};

/* bitstream writer helpers*/
typedef struct
{
	Uint8 *buffer;
	Uint32 byte, size_byte; 	// Read/write position counters (byte component)
	Uint8 bit, size_bit;		// Read/write position counters (bit component)
} BitPtr;

#define BIT_BLOCK_SIZE 1024 // Bitstream buffer allocation increment size

void bit_init(BitPtr *p, Uint8 *buffer, Uint32 size_bytes, Uint8 size_bits)
{
	memset(p, 0, sizeof(*p));
	p-&gt;buffer = buffer;
	p-&gt;size_byte = size_bytes;
	p-&gt;size_bit = size_bits;
}

void bit_deinit(BitPtr *p)
{
	free(p-&gt;buffer);
	memset(p, 0, sizeof(*p));
}

void bit_rewind(BitPtr *p)
{
	p-&gt;bit = p-&gt;byte = 0;
}

void bit_seek(BitPtr *p, Uint32 byte, Uint8 bit)
{
	p-&gt;byte = byte;
	p-&gt;bit = bit;
}

void bit_w(BitPtr *p, int bit)
{
	if (p-&gt;bit == 0 &amp;&amp; !(p-&gt;byte &amp; (BIT_BLOCK_SIZE - 1)))
	{
		// If write position modulo BIT_BLOCK_SIZE is zero, allocate a larger buffer
		p-&gt;buffer = realloc(p-&gt;buffer, p-&gt;byte + BIT_BLOCK_SIZE);
	}

	if (bit)
		p-&gt;buffer[p-&gt;byte] |= 1 &lt;&lt; p-&gt;bit;
	else
		p-&gt;buffer[p-&gt;byte] &amp;= ~(1 &lt;&lt; p-&gt;bit);

	++p-&gt;bit;

	if (p-&gt;bit == 8)
	{
		p-&gt;bit = 0;
		++p-&gt;byte;
	}

	p-&gt;size_byte = p-&gt;byte;
	p-&gt;size_bit = p-&gt;bit;
}

int bit_r(BitPtr *p)
{
	if (p-&gt;size_byte &lt;= p-&gt;byte &amp;&amp; p-&gt;size_bit &lt;= p-&gt;bit)
		return -1;

	int bit = (p-&gt;buffer[p-&gt;byte] &amp; (1 &lt;&lt; p-&gt;bit)) != 0;

	++p-&gt;bit;

	if (p-&gt;bit == 8)
	{
		p-&gt;bit = 0;
		++p-&gt;byte;
	}

	return bit;
}

/* Write Elias gamma coded value (has to be nonzero) */
void bit_wgamma(BitPtr *p, Uint32 value)
{
	int l = log2(value);

	for (int a=0; a &lt; l; a++)
		bit_w(p, 0); //put 0s to indicate how many bits will follow

	bit_w(p, 1);      //mark the end of the 0s

	for (int a=l-1; a &gt;= 0; a--) //Write the bits as plain binary
	{
		bit_w(p, value &amp; 1 &lt;&lt; a);
	}

}

/* Read Elias gamma coded value, zero return value signals read error */
Uint32 bit_rgamma(BitPtr *p)
{
	int numberBits = 0;
	int bit;
	while (!(bit = bit_r(p)))
		numberBits++; //keep on reading until we fetch a one...

	if (bit &lt; 0) return 0;

	Uint32 current = 0;
	for (int a=numberBits-1; a &gt;= 0; a--) //Read numberBits bits
	{
		if ((bit = bit_r(p)))
			current |= 1 &lt;&lt; a;

		if (bit &lt; 0) return 0;
	}
	current |= 1 &lt;&lt; numberBits; //last bit isn't encoded!

	return current;
}

/* Read bits bits */
Sint32 bit_rbits(BitPtr *p, Uint8 bits)
{
	Sint32 rval = 0;

	for (int i = 0 ; i &lt; bits ; ++i)
	{
		int bit = bit_r(p);

		if (bit &lt; 0) return -1;

		rval |= bit &lt;&lt; i;
	}

	return rval;
}

/* Write bits bits of v */
void bit_wbits(BitPtr *p, Uint32 v, Uint8 bits)
{
	for (int i = 0 ; i &lt; bits ; ++i)
	{
		bit_w(p, v &amp; (1 &lt;&lt; i));
	}
}

/* Gray and delta encoding helpers */
static inline Uint16 gray(Uint16 v)
{
	return v ^ (v &gt;&gt; 1);
}

static inline Uint16 degray(Uint16 v)
{
	v ^= (v&gt;&gt;8);
    v ^= (v&gt;&gt;4);
	v ^= (v&gt;&gt;2);
	v ^= (v&gt;&gt;1);
	return v;
}

static void delta_encode(Sint16 *buffer, const int n)
{
	Sint32 delta = 0;
	Sint32 original;
	for (int i = 0; i &lt; n; ++i)
	{
		original = buffer[i];
		Sint32 x = original - delta;
		buffer[i] = gray(x + 32768); // Gray code can not be negative
		delta = original;
	}
}

static void delta_decode(Sint16 *buffer, const int n)
{
	Sint32 delta = 0;
	for (int i = 0; i &lt; n; ++i)
	{
		Sint32 v = degray(buffer[i]);
		buffer[i] = (v - 32768) + delta;
		delta = buffer[i];
	}
}

/* Compress 16-bit signed data into bitstream, return compressed data size in packed_size (in bits) */
Uint8 * bitpack(const Sint16 *_buffer, const int n, Uint32 *packed_size)
{
	BitPtr bp;
	bit_init(&amp;bp, NULL, 0, 0);

	Sint16 *buffer = malloc(sizeof(Sint16) * n);
	memcpy(buffer, _buffer, sizeof(Sint16) * n);

	delta_encode(buffer, n);

	for (int plane = 0 ; plane &lt; sizeof(*buffer) * 8 ; ++plane)
	{
		const Sint16 mask = 1 &lt;&lt; plane;
		int bit = mask &amp; *buffer;

		int type = BITPACK_STATIC0 | (bit != 0);

		for (int i = 0 ; i &lt; n ; ++i)
			if ((buffer[i] &amp; mask) != bit)
			{
				// Was not all zeros or all ones, needs to compress
				type = BITPACK_RLE;
				break;
			}

		Uint32 p_byte = bp.byte;
		Uint32 p_bit = bp.bit;

again:

		bit_wbits(&amp;bp, type, 2);

		switch (type)
		{
			case BITPACK_LITERAL:
				for (int i = 0 ; i &lt; n ; ++i)
					bit_w(&amp;bp, buffer[i] &amp; mask);
				break;

			case BITPACK_STATIC0:
			case BITPACK_STATIC1:
				// No data needed, bit plane is all zeros or all ones
				break;

			case BITPACK_RLE:
			{
				// Write starting bit state
				bit_w(&amp;bp, bit);

				Uint32 ctr = 0;

				for (int i = 0 ; i &lt; n ; ++i)
				{
					if (((buffer[i] &amp; mask) == bit))
						++ctr;

					if ((buffer[i] &amp; mask) != bit)
					{
						bit_wgamma(&amp;bp, ctr);

						ctr = 1;

						// Flip the bit (no neighboring bits are the same state)
						bit ^= mask;
					}
				}

				if (ctr != 0) bit_wgamma(&amp;bp, ctr);

				if ((bp.byte * 8 + bp.bit) - (p_byte * 8 + p_bit) &gt; n + 2)
				{
					// RLE gave longer data than the original, dump data instead
					bit_seek(&amp;bp, p_byte, p_bit);
					type = BITPACK_LITERAL;
					goto again;
				}

			}
			break;
		}

	}

	free(buffer);

	*packed_size = bp.byte * 8 + bp.bit;

	return bp.buffer;
}

/* Decompress compressed bitstream into 16-bit signed data, decompress at most packed_size bits
	unpacked_size tells the function the data length (important)
 */
Sint16 * bitunpack(const Uint8 *packed_data, const Uint32 packed_size, Uint32 unpacked_size)
{
	BitPtr bp;
	bit_init(&amp;bp, (Uint8*)packed_data, packed_size / 8, packed_size &amp; 7);

	Sint16 *buffer = calloc(unpacked_size, sizeof(Sint16));

	for (int plane = 0 ; plane &lt; sizeof(*buffer) * 8 ; ++plane)
	{
		const Sint16 mask = 1 &lt;&lt; plane;

		Sint32 type = bit_rbits(&amp;bp, 2);

		if (type &lt; 0) goto read_error;

		switch (type)
		{
			case BITPACK_LITERAL:
				for (int i = 0 ; i &lt; unpacked_size ; ++i)
				{
					int bit = bit_r(&amp;bp);
					if (bit &lt; 0) goto read_error;
					if (bit) buffer[i] |= mask;
				}
				break;

			case BITPACK_STATIC0:
				// Data bits are zero by default, no action needed
				break;

			case BITPACK_STATIC1:
				// Fill bit plane with set/unset bit
				for (int i = 0 ; i &lt; unpacked_size ; ++i)
					buffer[i] |= mask;
				break;

			case BITPACK_RLE:
			{
				// Read the starting bit status
				int bit = bit_r(&amp;bp);

				if (bit &lt; 0) goto read_error;

				if (bit) bit = mask; else bit = 0;

				buffer[0] |= bit;

				for (int i = 0 ; i &lt; unpacked_size ; )
				{
					Uint32 ctr = bit_rgamma(&amp;bp);

					if (ctr == 0) goto read_error;

					for (; i &lt; unpacked_size &amp;&amp; ctr ; ++i, --ctr)
						buffer[i] |= bit;

					if (ctr) goto read_error;

					// Flip the bit (neighboring bits are always different)
					bit ^= mask;
				}
			}
			break;
		}
	}

	delta_decode(buffer, unpacked_size);

	if (0)
	{
read_error:
		free(buffer);
		return NULL;
	}

	return buffer;
}

/* Generate test data, 0 is a sine wave and 1 generates noise */
void getdata(Sint16 *buffer, const int n, int t)
{
	switch (t)
	{
		case 0:
			for (int i = 0 ; i &lt; n ; ++i)
			{
				buffer[i] = (((int)(sin((float)i / 1000 * 3.141 * 2) * 20000)));
			}

			break;

		case 1:
			for (int i = 0 ; i &lt; n ; ++i)
				buffer[i] = (rand() * 4);

			break;
	}
}

int main(int argc, char **argv)
{
	const int n = 100000;

	Sint16 *b = malloc(sizeof(Sint16) * n);
	Uint32 packed_size;

	getdata(b, n, 0);

	Uint8 * data = bitpack(b, n, &amp;packed_size);
	Sint16 * udata = bitunpack(data, packed_size, n);

	if (udata == NULL || memcmp(b, udata, sizeof(Sint16) * n) != 0)
	{
		printf(&quot;Upack failed\n&quot;);
	}
	else
	{
		printf(&quot;Compression ratio %.1f %%\n&quot;, (float)100 * packed_size / (n * sizeof(Sint16) * 8));

	}

	free(data);
	free(udata);
	free(b);

	return 0;
}
</pre>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/" title="Android NDK and SDL_RWops">Android NDK and SDL_RWops</a></li><li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/" title="Plenty of Room, Part II">Plenty of Room, Part II</a></li><li><a href="http://kometbomb.net/2011/10/11/chiptune-drums/" title="Chiptune Drums">Chiptune Drums</a></li><li><a href="http://kometbomb.net/2010/02/28/libconfig/" title="An Alternative to XML">An Alternative to XML</a></li><li><a href="http://kometbomb.net/2009/09/22/introducing-my-latest-projects/" title="Introducing My Latest Projects">Introducing My Latest Projects</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2011/01/02/lossless-audio-compression/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>An Alternative to XML</title>
		<link>http://kometbomb.net/2010/02/28/libconfig/</link>
		<comments>http://kometbomb.net/2010/02/28/libconfig/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 15:42:06 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Webfinds]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=701</guid>
		<description><![CDATA[XML can be overkill or simply cumbersome to edit manually for example when used in configuration files. Or, it may simply be unavailable for the preferred platform. Here's a great alternative.]]></description>
			<content:encoded><![CDATA[<p>My new weapon of choice. <strong><a href="http://www.hyperrealm.com/libconfig/">libconfig</a></strong> is a configuration file parser that supports arrays, named and typed members, selection by path (e.g. <tt>cfg.users.[3].name</tt>) and more. That is, it has basically all the useful (as in 80% of cases) features of XML and none of the bad. There&#8217;s a minimal but well defined structure that will work for most situations and that can be used to enforce e.g. all array items having to be of the same type. There&#8217;s no overkill markup so it&#8217;s easy to read and write by humans. The library can also write the settings tree into a text file.</p>
<p>The configuration files look like this:</p>
<pre class="brush: plain; title: ; notranslate">screen = { width = 300; height = 200; }
users = ( { name = &quot;Torgo&quot;; items = [ &quot;Item 1&quot;, &quot;Item 2&quot; ]; } );</pre>
<p>And in C you would do something like this:</p>
<pre class="brush: cpp; title: ; notranslate">int screen_height = 100;
const char *name;
config_init(&amp;cfg);
config_read_file(&amp;cfg, &quot;config&quot;);
if (!config_lookup_int(&amp;cfg, &quot;screen.height&quot;, &amp;screen_height))
  puts(&quot;Using default screen height&quot;);
if (config_lookup_string(&amp;cfg, &quot;users.[0].name&quot;, &amp;name))
  puts(name);
config_destroy(&amp;cfg);</pre>
<p>You can also iterate the setting tree without the path for easier array or tree traversal. In all, I would say it involves less work compared to any XML library, especially in C. I like to think it&#8217;s a good example of software designed by the same guy who also uses it and not by some external committee.</p>
<ul>
<li><a href="http://www.hyperrealm.com/libconfig/">Homepage</a></li>
<li><a href="http://www.hyperrealm.com/libconfig/test.cfg.txt">An example config file</a></li>
</ul>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2008/03/21/a-tiny-xml-parser/" title="A Tiny XML Parser">A Tiny XML Parser</a></li><li><a href="http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/" title="Android NDK and SDL_RWops">Android NDK and SDL_RWops</a></li><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2009/09/22/introducing-my-latest-projects/" title="Introducing My Latest Projects">Introducing My Latest Projects</a></li><li><a href="http://kometbomb.net/2008/02/24/google-chart-api-is-pretty-cool/" title="Google Chart API is pretty cool">Google Chart API is pretty cool</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2010/02/28/libconfig/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating a Simple GUI from Scratch</title>
		<link>http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/</link>
		<comments>http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 14:27:20 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[SDL]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=695</guid>
		<description><![CDATA[More often than not, the biggest obstacle for a programmer is adding a GUI to a otherwisely ready application. This probably is because you generally can create a program that inputs and outputs text with a few lines of code in any language. ]]></description>
			<content:encoded><![CDATA[<div class="toc">
<ol>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-introduction">Introduction</a></li>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-how-to-do-it">How to do it</a></li>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-solutions-to-common-problems">Solutions to common problems</a></li>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-faq">FAQ</a>
<ol>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-i-absolutely-need-a-separate-window">I absolutely need a separate window</a></li>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-is-this-reusable">Is this reusable?</a></li>
</ol>
</li>
<li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/#toc-conclusion">Conclusion</a></li>
</ol>
</div>
<h3 id="toc-introduction">Introduction</h3>
<p>More often than not, the biggest obstacle for a programmer is adding a GUI to a otherwisely ready application. This probably is because you generally can create a program that inputs and outputs text with a few lines of code in any language. However, if you don&#8217;t count <tt>MessageBox()</tt> and other similar helper APIs that are available in most windowing systems and that are as simple to use as <tt>gets()</tt> and <tt>printf()</tt>, it&#8217;s a unnecessarily big step to change a command line program into a program that outputs the exact same text but with complex command line arguments replaced by a few buttons and a window with the outputted text.</p>
<p>However, if you are developing a program that already draws something on the screen, it&#8217;s really easy to add simple mouse interactivity. This is especially true if you are using SDL (even if it&#8217;s <em>extremely</em> bare bones in these things!) and already use <tt>SDL_rect</tt> (your standard rectangle) to draw things. You can simply change the draw routine so that it takes one more argument which would be the <tt>SDL_event</tt> struct you&#8217;re already using to check for a quit message and so on. Then for every object you are drawing on screen, check if the event if a mouse button down event and that the coordinates are inside the rectangle that will be drawn. This eliminates completely the need for having to plan a separate system that interprets the mouse events. It&#8217;s sort of piggybacking on the existing code with minimal changes to the existing code.</p>
<p>Now, you might already think that is way too simplistic and lazy but think again. Not many programs need a more complex GUI with multiple movable windows and so on. If you really do need that, then be my guest and create a exhaustive windowing system or take the time to learn an existing system. But it is still overhead and you have to do comparatively a lot of work before any real results. At least I hate that kind of mental overhead. And while this whole idea of combining the drawing and the event processing sounds like a bit of a hack, it really isn&#8217;t a &#8220;hack&#8221; as in patching something you will probably have to replace with a better solution later. It&#8217;s just a different way of doing almost the same thing. With <em>less overhead</em>.</p>
<p>I have used this approach in <a href="http://code.google.com/p/klystrack/">my latest project</a> and from direct experience I know it is possible to create scrollbars, scrolling text fields, text input fields, message boxes and pretty much anything I have needed. And it&#8217;s not too much code either even if you have to create absolutely everything from nothing. In other words I do not feel limited or burdened.</p>
<h3 id="toc-how-to-do-it">How to do it</h3>
<p>As explained above, you most likely are drawing to a specific region on the screen for every object you need to check for mouse clicks. It is not necessary to have any kind of array where those regions are. You need to make sure that for every mouse click event runs the draw loop once and that the mouse click event gets passed to the draw routine. Then check if the coordinates are inside the draw region. </p>
<p>This is where the part starts that it admittedly gets a bit hacky: if a button is pressed, the event that the button triggers will be run in the middle of the draw loop (unless you somehow buffer the events). In most cases this doesn&#8217;t matter at all but it could be that what is on the screen is not exactly how it really is; you might have two selected items for a duration of one frame and so on. For the most part this doesn&#8217;t matter since you are getting results with very little overhead.</p>
<p>Consider this example.</p>
<pre class="brush: cpp; title: ; notranslate">void draw_stuff()
{
  SDL_Rect position = {10, 10, 40, 40};

  SDL_BlitRect(button_gfx, NULL, screen, &amp;position);
}

void draw_stuff_and_check_events(SDL_Event *event)
{
  SDL_Rect position = {10, 10, 40, 40};

  if (event-&gt;type == SDL_MOUSEBUTTONDOWN
   &amp;&amp; event-&gt;button.x &gt;= position.x
   &amp;&amp; event-&gt;button.y &gt;= position.y
   &amp;&amp; event-&gt;button.x &lt; position.x + position.w
   &amp;&amp; event-&gt;button.y &lt; position.y + position.h)
     button_event();

  SDL_BlitRect(button_gfx, NULL, screen, &amp;position);
}

void event_loop()
{
  SDL_Event event;

  while (SDL_PollEvent(&amp;event))
  {
    if (event.type == SDL_QUIT) break;

    draw_stuff(&amp;event);
  }
}</pre>
<p>From the above example, the benefits of this approach are obvious. The event checking can simply be injected anywhere in the code as long as you have the event and a region. </p>
<h3 id="toc-solutions-to-common-problems">Solutions to common problems</h3>
<p>One downside in this is that if you draw multiple overlapping regions, the region drawn last will be the one that is visible on the screen but the click is handled by the first region. Our event checking sees the regions from the other side of the screen. In such cases you can first iterate the regions in reverse order checking the event and then draw them in the correct order. An example in the mentioned project is the menu, submenus often overlap the parent menu; I solved that by first going through the menus in the order the user sees them and then drawing them back to front.</p>
<p>Dragging items is easy: simply check for mouse motion events and if the button is held down and the mouse is moved, just adjust the position of the matching region. You do not need any special &#8220;drag starts now&#8221; and &#8220;drag ends now, update objects&#8221; phases. However, this simplistic method is subject to the previous issue if you move a region over one that seems to be under it. You can also simply record the clicked object when the mouse button is pressed and make the motion events match only the selected region.</p>
<h3 id="toc-faq">FAQ</h3>
<h4 id="toc-i-absolutely-need-a-separate-window">I absolutely need a separate window</h4>
<p>This is possible as long as the window can be modal (like a message or open file dialog that takes over from the window behind it). You simply jump to another event loop until the new window is closed, much like it&#8217;s done in the Windows API with <tt>GetOpenFileName()</tt> or the <tt>MessageBox()</tt> mentioned earlier. Then it&#8217;s just a matter of drawing the new window and checking for the events normally. </p>
<h4 id="toc-is-this-reusable">Is this reusable?</h4>
<p>Of course. You could create a small library that has basic functionality and helper functions. <a href="http://code.google.com/p/klystron/source/browse/#svn/trunk/src/gui">A practical example can be seen here</a>.</p>
<p>Even if you can use the event checking straight in the source code, you can still define the regions in an array and link to relevant event handlers. </p>
<h3 id="toc-conclusion">Conclusion</h3>
<p>Combining the drawing and the event processing code can save time in the short term. Many common GUI elements are perfectly possible to replicate. The idea described above should be considered if a project needs mouse interaction and external libraries are not available, the conversion of existing code seems expensive or the learning curve is too steep compared to the future benefits. Nonetheless, in borderline cases, it can be well worth prototyping due to the minimal overhead and developing considerations.</p>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/" title="Android NDK and SDL_RWops">Android NDK and SDL_RWops</a></li><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2010/02/28/libconfig/" title="An Alternative to XML">An Alternative to XML</a></li><li><a href="http://kometbomb.net/2009/09/22/introducing-my-latest-projects/" title="Introducing My Latest Projects">Introducing My Latest Projects</a></li><li><a href="http://kometbomb.net/2009/07/19/opengl-static-arrays-and-glmaterialfv/" title="OpenGL, Static Arrays and glMaterialfv">OpenGL, Static Arrays and glMaterialfv</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plenty of Room, Part II</title>
		<link>http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/</link>
		<comments>http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 16:47:17 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[256B]]></category>
		<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Demoscene]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=128</guid>
		<description><![CDATA[As stated earlier, tiny intros written in assembly language fascinate me. I have written a few in x86 assembly language, here's one of them. I have tried to make the inner workings of the program as accessible -- or, at least as thought-provoking -- as possible even if assembly wasn't their weapon of choice. ]]></description>
			<content:encoded><![CDATA[<p style="border:1px #eee solid;padding:2px;background-color:#f8f8f8;font-size:11px">This is the second part of the epic (<del datetime="2009-11-09T13:46:36+00:00">two</del> three-part) series of articles about tiny intros, <a href="http://kometbomb.net/2007/10/22/theres-plenty-of-room-at-the-bottom/">the previous part was an essay about 256-byte intros in general</a>.</p>
<p><em><strong>Ed. note:</strong> Since this article seems to take forever to finish, here&#8217;s the first half of it. The (hopefully) final part will detail more of the specifics.</em></p>
<p><img src="http://kometbomb.net/wp-content/uploads/2009/11/rubba.png" alt="rubba" title="rubba" width="320" height="199" class="alignright size-full wp-image-649 iradius8" /> As stated earlier, tiny intros written in assembly language fascinate me. I have written a few in x86 assembly language, here&#8217;s one of them. I have tried to make the inner workings of the program as accessible &#8212; or, at least as thought-provoking &#8212; as possible even if assembly wasn&#8217;t their weapon of choice. </p>
<p>I&#8217;ve included the original DOS intro (you can use <a href="http://dosbox.sourceforge.net/">DOSBox</a> to run it, it should also work on Windows XP) and a Win32 port of it, written in C while trying to keep the original structure intact. I&#8217;ll also try to explain the general idea of the effect in pseudocode where syntax can be an obstacle. The archive <a href='http://kometbomb.net/wp-content/uploads/2009/11/rubba_c.zip'>rubba_c.zip</a> contains the source code, <kbd>rubba_b.exe</kbd> which is the compiled Win32 executable and <kbd>RUBBA.COM</kbd> which is the 16-bit MS-DOS executable. To compile the C program, you need the <a href="http://sourceforge.net/projects/tinyptc/">TinyPTC library</a> (like SDL but even more bare-bones).</p>
<p>I won&#8217;t go into details about x86 assembly language, I suggest anyone interested first reads an introduction and <a href="http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/index.html">learns some of the basics</a>. However, I&#8217;ll try to make the code look interesting, explain some weird or obfuscated code and probably show some basic size optimization tricks.</p>
<div class="toc">
<ol>
<li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/#toc-the-effect">The Effect</a></li>
<li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/#toc-the-code">The Code</a>
<ol>
<li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/#toc-initialization">Initialization</a></li>
<li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/#toc-the-main-loop">The Main Loop</a>
<ol>
<li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/#toc-self-modifying-code">Self Modifying Code</a></li>
</ol>
</li>
</ol>
</li>
</ol>
</div>
<h3 id="toc-the-effect">The Effect</h3>
<p>The intro, called <b>rubba_b</b>, shows one effect: a twisting bar drawn using primitive light-shaded texture mapping. The color palette and the texture are generated run-time. The texturing is done using linear interpolation and no vector math is used even if the bar looks like it is rotated. The lighting is an extremely simple approximation of the light source being exactly where the camera is located. That is, the length of the textured line directly determines the light. </p>
<p>If looked from above, the bar will be a tower of squares. If one of the squares is rotated around the center, the corners will move in a circular pattern. So, the X coordinate will be equal to <tt>cos(corner_number*(360 degrees/4)+square_rotation)</tt>, the Z coordinate (why Z? Because it goes towards the screen) is equal to the sine but it can be discarded because we will not need it for perspective calculation. Remember, we&#8217;re short on bytes.</p>
<p>We then modulate the bar rotation for each square in the tower. If the amount of rotation changes when moving up or down the tower, the bar will twist. If the rotation stays the same for each square, the bar will rotate uniformly and look uninteresting.</p>
<p>The textured horizontal line is drawn from each corner to the next corner, from left to right. If the line would be drawn from right to left, we know it isn&#8217;t facing towards the camera, another line facing the camera will be drawn over it and we simply skip the line. The color value fetched from the texture is multiplied by the line length which makes short lines darker.</p>
<p>Still with me?</p>
<h3 id="toc-the-code">The Code</h3>
<h4 id="toc-initialization">Initialization</h4>
<p>First things first. We need to set the video mode before we continue. In the Win32 version we simply open a TinyPTC window, in the original version we need to tell BIOS to go in a nice 320x200x8 video mode (the <em>de facto</em> video mode back in the day).</p>
<table>
<tr>
<td><strong>C</strong></td>
<td><strong>asm</strong></td>
</tr>
<tr>
<td>
<pre><code>ptc_open("rubba_b",320,200)</code></pre>
</td>
<td>
<pre><code>mov al,13h
int 10h</code></pre>
</td>
</tr>
</table>
<p>In the above code, the Win32 part is self-explanatory. The assembly bit probably needs some clarification: we put  the number <strong>13h</strong> (hex) in the 8-bit register <strong>al</strong> and we request for interrupt <strong>10h</strong>. This is the BIOS video interrupt and since register <strong>ax</strong> (which consists of <strong>al</strong> &#8211; &#8220;low&#8221; &#8211; and <strong>ah</strong> &#8211; &#8220;high&#8221;) equals to <strong>0013h</strong> (when the program starts, <strong>ax</strong> is always zeroed), BIOS will call the routine for changing the video mode (<strong>ah</strong>=<strong>00h</strong>) to <strong>13h</strong>. </p>
<p>If above sounds complicated, don&#8217;t worry. It&#8217;s just a matter of memorization &#8211; similar to how you would memorize the function name for changing the video mode.</p>
<p>The next thing we need is some space for the texture, the sine table and the double buffer. In the Win32 version this is obvious, we just add a few arrays (although since TinyPTC only supports 32-bit video modes, we will also have an array for the palette). Again, in the assembly version we won&#8217;t use any fancy way to reserve memory to save some precious bytes: we simply decide certain areas of the memory will be used for whatever we want. The benefits of no memory protection and single tasking. ;)</p>
<table>
<tr>
<td><strong>C</strong></td>
<td><strong>asm</strong></td>
</tr>
<tr>
<td>
<pre><code>short int sinetab[SINETAB];
unsigned char palette[256*4];
unsigned char texture[256*256];
unsigned char screen[320*200];</code></pre>
</td>
<td>
<pre><code>mov dh,80h
mov gs,dx
mov dh,70h
mov es,dx
mov dh,60h
mov fs,dx</code></pre>
</td>
</tr>
</table>
<p>The assembly version basically sets the register <strong>dx</strong> to <strong>60xxh-80xxh</strong> (we set only the high byte, i.e. <strong>dh</strong> to save bytes, thus the low byte of <strong>dx</strong> is undefined &#8211; it won&#8217;t matter) and puts the value into various segment registers (<strong>es-gs</strong>). </p>
<p>This makes it so that if we use the different segment registers, we can access each of the three 64 kilobyte segments as a 64 kilobyte array. E.g. the sine is in <strong>gs</strong>, thus <tt>mov ax,[gs:2]</tt> would move the second word in the sine table in <strong>ax</strong>. In C, the equivalent would be <tt>short int value=sinetab[1]</tt> (note how the C compiler knows the fact that a word is 2 bytes but in assembly you have to take care of that yourself &#8211; all memory accesses are always by the exact location, not the array element!).</p>
<p>All this is because in 16-bit memory accessing you can see only 64 kilobytes at one time. You can&#8217;t have a 128 KB array, nor can you have two 64 K arrays in the same segment. It&#8217;s something comparable to having a flashlight and a big sheet of paper in a dark room; you can move the light to show different areas but you will never see more than what there is in the spotlight.</p>
<p>The next two parts calculate the sine table (back in the day you simply could not do trigonometric stuff real-time, even in hardware &#8212; although in the intro it&#8217;s there just for show) and set the palette. This is pretty straight-forward stuff across the two versions. The only difference is that in the Windows version we have to remember the palette has 8-bit color components and the original has 6-bit components (0..255 ~ 0..63). And of course, the Windows version simply puts the values in a palette look-up table (because 32-bit video mode doesn&#8217;t use a palette) and the original actually sets the video mode colors.</p>
<p>I won&#8217;t reiterate the source code for the sine table and palette change here, I think you should be able to figure it out by comparing the source code. But in theory, here&#8217;s how to change a color: first, write the color index in port <strong>3C8h</strong>, then write the three color components in port <strong>3C9h</strong> (hint: <strong>dx</strong> first contains <strong>3C8h</strong> and it&#8217;s incremented to <strong>3C9h</strong> to save bytes). </p>
<p>The sine routine increases the angle (<b>st0</b> the topmost register on the FPU) by <strong>2*PI/32768</strong> (a full circle is 2*PI, the sine table has 32768 elements). You probably should check some FPU tutorial, arithmetic on the 8087 is pretty interesting due to the stack-based architecture. For example, you first push in two numbers and then do an add, which (in most cases) pops out the two values and pushes in the result.</p>
<p>The texture generation bit is interesting. It also was annoying to port to C thanks to the fact you have to emulate how some instructions work &#8211; there are no accurate analogies in the C standard. A big thanks goes to <strong>baze</strong> whose code I originally cannibalized for this (I think). To be honest the conversion doesn&#8217;t work 100 % accurately but does still produce a nice texture.</p>
<p>The algorithm uses addition, bitwise operations and other simple things to achieve complexity thanks to how processors do arithmetics. Mainly, the results from an earlier calculation is carried over to the next calculation &#8212; when an addition or a subtraction overflows, i.e. the result is too large or too small to fit in a register, the processor lets the result wrap over but sets the <strong>carry flag</strong>. </p>
<p>This is quite similar to how you would carry numbers when calculating with a pen and a paper. The flag affects the results unpredictably because it&#8217;s used across quite different operations; usually you would just use to to add big numbers together as in the pen and paper example. </p>
<h4 id="toc-the-main-loop">The Main Loop</h4>
<p>Here is the meat of the code. The C version has many variables that are named after registers in order to see the connection with the original code. Sometimes, as with the 8-bit registers, some code doesn&#8217;t work exactly as in the original because you can&#8217;t do things similarly in C. E.g. you can&#8217;t have two variables that also are a part of one big register similarly how <strong>al</strong> and <strong>ah</strong> form <strong>ax</strong> (well, you can with pointers or unions but that is besides the point, kind of).</p>
<h5 id="toc-self-modifying-code">Self Modifying Code</h5>
<p>I use self modifying code (SMC) in a few places because it produces faster and also much simpler code. For example, if you have a variable that is changed in a few places but used by one instruction only (and the instruction performs arithmetic or otherwise accepts a constant parameter), it&#8217;s much faster to store the variable where the constant for the instruction would be. That way you don&#8217;t have to read the variable in a register and then use the register to do something.</p>
<p>E.g. Let&#8217;s multiply <strong>cx</strong> by the variable <strong>foo</strong>:</p>
<table>
<tr>
<td><strong>Original</strong></td>
<td><strong>SMC</strong></td>
</tr>
<tr>
<td>
<pre><code>  push ax ; save ax
  mov ax,[foo] ; move variable foo in ax
  imul cx,ax ; multiply cx by ax
  pop ax  ; restore ax
  ...
  mov ax,123   ; set foo ...
  mov [foo],ax ; ... to 123
  ...
foo: dw 0</code>
</pre>
</td>
<td>
<pre><code>  imul cx,123
foo equ $-2
  ...
  mov ax,123   ; set foo ...
  mov [foo],ax ; ... to 123</code></pre>
</td>
</tr>
</table>
<p>We can exploit the fact <strong>imul</strong> (signed multiplication) accepts constant multipliers. If you looked at the code with a hex editor, you&#8217;d see 123 next to the opcode. You can change the constant run-time and you do that exactly like you would change a variable: if you just define <b>foo</b> as the address where the constant is (the above code defines it as the last two bytes (i.e. word) of the previous instruction: in NASM, <strong>$</strong> is the current location and <strong>$-2</strong> equals the address of the previous word).</p>
<p><strong><em>To be concluded&#8230;</em></strong></p>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2009/09/08/you-can-stop-programming-now/" title="You Can Stop Programming Now">You Can Stop Programming Now</a></li><li><a href="http://kometbomb.net/2007/10/22/theres-plenty-of-room-at-the-bottom/" title="There&#8217;s Plenty of Room at the Bottom">There&#8217;s Plenty of Room at the Bottom</a></li><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2007/09/04/image-retargeting/" title="Image retargeting">Image retargeting</a></li><li><a href="http://kometbomb.net/2007/07/17/nanopond-screensaver/" title="Nanopond Screensaver">Nanopond Screensaver</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing My Latest Projects</title>
		<link>http://kometbomb.net/2009/09/22/introducing-my-latest-projects/</link>
		<comments>http://kometbomb.net/2009/09/22/introducing-my-latest-projects/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 22:34:30 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Nonsense]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Game programming]]></category>
		<category><![CDATA[Retro gaming]]></category>
		<category><![CDATA[SDL]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[Video games]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=611</guid>
		<description><![CDATA[<em>... Or, How to Procrastinate Productively.</em> <a href="http://kometbomb.net/wp-content/uploads/2009/09/klystrack3.png"><img src="http://kometbomb.net/wp-content/uploads/2009/09/klystrack3-250x187.png" alt="klystrack3" title="klystrack3" width="192" height="144" class="alignright size-thumbnail wp-image-628" style="width:192px;height:144px" /></a>

I decided to make one of my current projects open source and post them on Google Code just for fun. The project is a toolchain that I'm using to remake <em>Thrust</em>. In reality, I decided to divide the project into two separate projects: <a href="http://code.google.com/p/klystron/">the actual game engine</a> and related tools, and <a href="http://code.google.com/p/klystrack/">a music editor</a> that uses the engine. ]]></description>
			<content:encoded><![CDATA[<p><em>&#8230; Or, How to Procrastinate Productively.</em></p>
<p><a href="http://kometbomb.net/wp-content/uploads/2009/09/klystrack3.png"><img src="http://kometbomb.net/wp-content/uploads/2009/09/klystrack3-250x187.png" alt="klystrack3" title="klystrack3" width="250" height="187" class="alignright size-thumbnail wp-image-628" /></a></p>
<p>I decided to make one of my current projects open source and post them on Google Code just for fun. The project is a tool chain that I&#8217;m using to remake <em>Thrust</em>. In reality, I decided to divide the project into two separate projects: <a href="http://code.google.com/p/klystron/">the actual game engine</a> (called <em>klystron</em>) and related tools, and <a href="http://code.google.com/p/klystrack/">a music editor</a> that uses the engine. </p>
<p>Here are two videos I made a while ago that demonstrate the engine. The first is the music editor (called <em>klystrack</em>) &#8212; it&#8217;s much less ugly at the moment but the sound synthesis is the same, and that&#8217;s what matters:</p>
<p class="aligncenter" style="text-align:center"><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/mJewnkOW42I&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0xe1600f&#038;color2=0xfebd01"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/mJewnkOW42I&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0xe1600f&#038;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<p>The sound engine (&#8220;Cyd&#8221;) is basically a very simple software synthesizer with capabilities comparable to the SID or any 8-bit machine from the 80s. The editor is a fairly standard tracker, much like <a href="http://en.wikipedia.org/wiki/GoatTracker">GoatTracker</a>.</p>
<p>The graphics half of the engine is basically a wrapper around a quite fast collision detection system (pixel-accurate, or it wouldn&#8217;t be much good for a thrustlike) built on <a href="http://www.libsdl.org">SDL</a>. It also does background collisions and drawing as well. As you may have guessed, the whole point is to provide a limited but still helpful set of routines that are useful for creating 2D games not unlike what video games were in 1991.</p>
<p>And, here&#8217;s a proof I&#8217;m actually working on the actual game (the sound effects are created in real time by the sound engine):</p>
<p class="aligncenter" style="text-align:center"><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/Yt1LtVSv5gw&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0xe1600f&#038;color2=0xfebd01"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Yt1LtVSv5gw&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0xe1600f&#038;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
<p>A note on <a href="http://code.google.com/">Google Code</a>: it&#8217;s rather nice. It provides the standard open source development stuff like source control an such but I really like how clean and hassle-free it is. Adding a project takes a minute and after that it&#8217;s simply coding and some quick documentation on the project wiki. The project wiki is good example of how simple but elegant the system is: the wiki pages actually exists inside the source control as files, just like your source code. </p>
<p>Go check Google Code out and while you&#8217;re at it, contribute on my projects. :)</p>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/" title="Android NDK and SDL_RWops">Android NDK and SDL_RWops</a></li><li><a href="http://kometbomb.net/2010/12/27/review-ninja-senki/" title="Review: Ninja Senki">Review: Ninja Senki</a></li><li><a href="http://kometbomb.net/2008/07/23/collision-detection-with-occlusion-queries-redux/" title="Collision Detection with Occlusion Queries Redux">Collision Detection with Occlusion Queries Redux</a></li><li><a href="http://kometbomb.net/2008/06/18/thrustlikes/" title="Thrustlikes">Thrustlikes</a></li><li><a href="http://kometbomb.net/2008/04/10/rom-check-fail/" title="ROM CHECK FAIL">ROM CHECK FAIL</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2009/09/22/introducing-my-latest-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You Can Stop Programming Now</title>
		<link>http://kometbomb.net/2009/09/08/you-can-stop-programming-now/</link>
		<comments>http://kometbomb.net/2009/09/08/you-can-stop-programming-now/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 10:36:26 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[256B]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Demoscene]]></category>
		<category><![CDATA[Raytracing]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=585</guid>
		<description><![CDATA[I'll be deleting all my own source code since perfection has finally been achieved and there is no need for programmers anymore.]]></description>
			<content:encoded><![CDATA[<p class="aligncenter" style="text-align:center"><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/3vzcMdkvPPg&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0xe1600f&#038;color2=0xfebd01"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/3vzcMdkvPPg&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0xe1600f&#038;color2=0xfebd01" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
<p>The above is <em>puls</em>, a <a href="http://kometbomb.net/2007/10/22/theres-plenty-of-room-at-the-bottom/">256-byte intro</a> by <a href="http://rrrola.wz.cz/">?r?ola</a>. It&#8217;s basically a raytracer with screen space ambient occlusion (which makes it so much realistic and cooler). While <a href="http://www.pouet.net/prod.php?which=3397"><em>tube</em></a> &#8212; which I think was the best 256-byte intro until now (when design and code are judged together) &#8212; also did raytracing of a cylinders, and after that many other intros did similar tracing of more complex surfaces, <em>puls</em> simply crushes all of them with objects that are formed by multiple plane surfaces (e.g. a cube would be a combination of six intersecting planes), a very nice color palette and that delicious ambient occlusion. </p>
<blockquote cite="http://pouet.net/prod.php?which=53816&#038;howmanycomments=25&#038;page=9"><p>Thinking it out in C and sketching it out in asm took about a week, byte crunching took another one&#8230; that&#8217;s like forty hours of full focus and eighty of playing.</p>
</blockquote>
<p>It&#8217;s also really, really slow which is the only minus especially because you can&#8217;t run 16-bit executables on Windows 7, so you have to use <a href="http://www.dosbox.com/">DOSBox</a> to watch it (or, use a <a href="http://www.kolumbus.fi/xtmb/goatsefloppy/#custom">boot floppy</a> to run it or something). <ins datetime="2009-09-08T14:09:45+00:00">There&#8217;s now a Windows port including a screensaver, <a href="http://pouet.net/prod.php?which=53816">see the Pouet.net page for more</a></ins>. A big thank you to nordak5 who was kind enough to upload a video on Youtube.</p>
<p>?r?ola has also included source code with <a href="http://rrrola.wz.cz/downloads.html">the binary that you can find over here</a>. That said, I&#8217;ll be deleting all my own source code since perfection has finally been achieved and there is no need for programmers anymore.</p>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/" title="Plenty of Room, Part II">Plenty of Room, Part II</a></li><li><a href="http://kometbomb.net/2007/10/22/theres-plenty-of-room-at-the-bottom/" title="There&#8217;s Plenty of Room at the Bottom">There&#8217;s Plenty of Room at the Bottom</a></li><li><a href="http://kometbomb.net/2009/09/22/introducing-my-latest-projects/" title="Introducing My Latest Projects">Introducing My Latest Projects</a></li><li><a href="http://kometbomb.net/2008/03/28/playstation-3-vs-atari-vcs/" title="Playstation 3 vs. Atari VCS">Playstation 3 vs. Atari VCS</a></li><li><a href="http://kometbomb.net/2008/03/25/some-cool-demoscene-stuff/" title="Some Cool Demoscene Stuff">Some Cool Demoscene Stuff</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2009/09/08/you-can-stop-programming-now/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Retargeting Images Using Parallax</title>
		<link>http://kometbomb.net/2009/09/02/retargeting-images-paralla/</link>
		<comments>http://kometbomb.net/2009/09/02/retargeting-images-paralla/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 10:10:41 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Image retargeting]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=553</guid>
		<description><![CDATA[I came up with a neat way to retarget images using a mesh that is transformed by rotating and doing an ortographic (non-perspective) projection. This is generally quite interesting since it can be done using a mesh and simple transformations and so can be done almost completely on the GPU. Even using a mesh can [...]]]></description>
			<content:encoded><![CDATA[<p><!--adsense_square--></p>
<p>I came up with a neat way to <a href="http://www.youtube.com/watch?v=qadw0BRKeMk">retarget images</a> using a mesh that is transformed by rotating and doing an ortographic (non-perspective) projection. This is generally quite interesting since it can be done using a mesh and simple transformations and so can be done almost completely on the GPU. Even using a mesh can be avoided if one uses a height map à la <a href="http://en.wikipedia.org/wiki/Parallax_mapping">parallax mapping</a> to alter the texture coordinates so just one quad needs to be drawn (with a suitable fragment shader, of course).</p>
<p>The idea is simply to have areas of images at a slope depending of how much the areas should be resized when retargeting. The slope angle depends of from what angle the source image is viewed to get the retargeting effect since the idea is to eliminate the viewing angle using the slope. </p>
<p>Here&#8217;s a more detailed explanation:</p>
<ol>
<li>
<p>Create an energy map of the source image, areas of interest have high energy</p>
</li>
<li>
<p>Traverse the energy map horizontally accumulating the energy value of the current pixel and the accumulated sum from the previous pixel</p>
</li>
<li>
<p>Repeat the previous step vertically using the accumulated map from the previous step. The accumulated energy map now &#8220;grows&#8221; from the upper left corner to the lower right corner. You may need a lot of precision for the map</p>
</li>
<li>
<p>Create a mesh with the x and y coordinates of each vertex encoding the coordinates of the source image (and thus also the texture coordinates) and the z coordinate encoding the accumulated energy. The idea is to have all areas of interest at a steep slope and other areas with little or no slope</p>
</li>
<li>
<p>Draw the mesh with ortographic projection, using depth testing and textured with the source image</p>
</li>
<li>
<p>Rotate the mesh around the Y axis to retarget image horizontally and around the X axis to retarget image vertically</p>
</li>
</ol>
<p>Here is a one-dimensional example (sorry for the awful images):</p>
<div id="attachment_554" class="wp-caption aligncenter" style="width: 339px"><a href="http://kometbomb.net/wp-content/uploads/2009/09/red-dots.png"><img src="http://kometbomb.net/wp-content/uploads/2009/09/red-dots.png" alt="Source image" title="red-dots" width="329" height="79" class="size-full wp-image-554" /></a><p class="wp-caption-text">Source image</p></div>
<p>The red dots represent areas of interest, such as sharp edges that we don&#8217;t want to resize as much as we want to resize the areas between the details. We then elevate our line for every red dot:</p>
<div id="attachment_554" class="wp-caption aligncenter" style="width: 339px"><a href="http://kometbomb.net/wp-content/uploads/2009/09/red-dots1.png"><img src="http://kometbomb.net/wp-content/uploads/2009/09/red-dots1.png" alt="red-dots" title="red-dots" width="302" height="132" class="aligncenter size-full wp-image-555" /></a><p class="wp-caption-text">Elevated mesh</p></div>
<p>Imagine the above example as something you would do for every row and column of a two-dimensional image. Now, when the viewer views the mesh (which is drawn without perspective) he or she sees the original image:</p>
<div id="attachment_554" class="wp-caption aligncenter" style="width: 339px"><a href="http://kometbomb.net/wp-content/uploads/2009/09/red-dots3.png"><img src="http://kometbomb.net/wp-content/uploads/2009/09/red-dots3.png" alt="red-dots3" title="red-dots3" width="328" height="336" class="aligncenter size-full wp-image-556" /></a><p class="wp-caption-text">Viewing the mesh from zero angle</p></div>
<p>However, if the viewing angle is changed, the red dots don&#8217;t move in relation to each other as much as the areas that are not elevated when they are projected on the view plane. Consider the below example:</p>
<div id="attachment_554" class="wp-caption aligncenter" style="width: 339px"><a href="http://kometbomb.net/wp-content/uploads/2009/09/red-dots31.png"><img src="http://kometbomb.net/wp-content/uploads/2009/09/red-dots31.png" alt="red-dots3" title="red-dots3" width="300" height="203" class="aligncenter size-full wp-image-557" /></a><p class="wp-caption-text">Viewing the mesh from an angle (gray line is the projected mesh)</p></div>
<p>Note how the unelevated line segments will seem shorter from the viewer&#8217;s perspective while the distance between the red dots is closer to the original distance. The blue dots in the above image show how areas that have little energy and so are not on a slope, thus will be move more compared to the red dots.</p>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2007/09/04/image-retargeting/" title="Image retargeting">Image retargeting</a></li><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2009/11/09/plenty-of-room-part-ii/" title="Plenty of Room, Part II">Plenty of Room, Part II</a></li><li><a href="http://kometbomb.net/2008/07/23/collision-detection-with-occlusion-queries-redux/" title="Collision Detection with Occlusion Queries Redux">Collision Detection with Occlusion Queries Redux</a></li><li><a href="http://kometbomb.net/2008/02/20/lets-make-a-planet/" title="Let&#8217;s make a planet">Let&#8217;s make a planet</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2009/09/02/retargeting-images-paralla/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenGL, Static Arrays and glMaterialfv</title>
		<link>http://kometbomb.net/2009/07/19/opengl-static-arrays-and-glmaterialfv/</link>
		<comments>http://kometbomb.net/2009/07/19/opengl-static-arrays-and-glmaterialfv/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 20:09:27 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=505</guid>
		<description><![CDATA[I stumbled upon weird behavior of OpenGL: I was setting material properties with <tt>glMaterialfv</tt> and for some reason this did not change the parameters if done multiple times in succession. I.e. when I drew two versions of the same object on the screen side by side with different material parameters, they both looked the same.]]></description>
			<content:encoded><![CDATA[<p>I stumbled upon weird behavior of OpenGL (OGL 1.4, Catalyst 8.612, GCC if that matters): I was setting material properties with <tt><a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">glMaterialfv</a></tt> and for some reason this did not change the parameters if done multiple times in succession. I.e. when I drew two versions of the same object on the screen side by side with different material parameters, they both looked the same.</p>
<p>The reason seems to be I was using a static array to store the parameters like this:</p>
<pre><code>void set_params(const Color&amp; diffuse)
{
  static float d[4] = {diffuse.r, diffuse.g, diffuse.b, diffuse.a};
  glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
}</code></pre>
<p>The only explanation I can think of is OpenGL doesn&#8217;t copy or use the values before <tt>glMaterialfv</tt> returns but instead reads them later, at which time there could be different values in the array (because it&#8217;s declared static) set for some other object being drawn. But that doesn&#8217;t explain why it can read the array (which AFAIK will be located on stack) later because the address to the then-valid location on the stack most likely won&#8217;t point to the parameters. Maybe the driver assumes anything that&#8217;s not on the stack can be used later and stuff located on stack will be copied. Who knows?</p>
<p>In any case, not declaring the array as static fixed the problem.</p>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/" title="Android NDK and SDL_RWops">Android NDK and SDL_RWops</a></li><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2010/02/28/libconfig/" title="An Alternative to XML">An Alternative to XML</a></li><li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/" title="Creating a Simple GUI from Scratch">Creating a Simple GUI from Scratch</a></li><li><a href="http://kometbomb.net/2008/08/19/out-of-memory/" title="Out of Memory?">Out of Memory?</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2009/07/19/opengl-static-arrays-and-glmaterialfv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Out of Memory?</title>
		<link>http://kometbomb.net/2008/08/19/out-of-memory/</link>
		<comments>http://kometbomb.net/2008/08/19/out-of-memory/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 20:07:34 +0000</pubDate>
		<dc:creator>kometbomb</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Memory]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://kometbomb.net/?p=375</guid>
		<description><![CDATA[It&#8217;s a common practice not to check what malloc() or new returns, since in an ideal world you will never run out of memory and so allocating memory will never fail. With a reasonably sized page file that is mostly true. When using a page file, this wouldn&#8217;t be a problem since if there is [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a common practice not to check what <tt>malloc()</tt> or <tt>new</tt> returns, since in an ideal world you will never run out of memory and so allocating memory will never fail. With a reasonably sized <a href="http://en.wikipedia.org/wiki/Paging" title="Paging" rel="wikipedia" class="zem_slink">page file</a> that is mostly true. When using a page file, this wouldn&#8217;t be a problem since if there is free space on the drive the page file is located, <a href="http://en.wikipedia.org/wiki/Virtual_memory" title="Virtual memory" rel="wikipedia" class="zem_slink">virtual memory</a> space can be temporarily enlarged (and a message pops up mentioning that) and the application that tried to allocate memory got what it asked.</p>
<p>However, since I upgraded to the maximum amount of memory Windows XP supports, and switched memory paging completely off, I&#8217;ve noticed some programs will silently fail when the system runs out of memory. And this isn&#8217;t that uncommon since I develop software and the crap programmer I am, silly mistakes are and always will be made that cause huge memory usage (and there&#8217;s also the rest of the software running on the computer). I have noticed at least Firefox simply disappears, while some software die with an error message.</p>
<p>For a game this wouldn&#8217;t be an issue (or a web browser even) but there are tons of programs downloading stuff or just hanging there that you&#8217;ll never notice missing. But it&#8217;s annoying to notice everything isn&#8217;t as you left it. </p>
<p>So, in case you haven&#8217;t thought of allocation failing, you probably should do something about it. When there&#8217;s no free memory left, even a <tt>malloc(sizeof(char))</tt> will invariably fail. A lazy way out would be wrapping the allocation with something that checks if the allocation succeeded and if not, displaying a message box will halt the program until the user does something (kills the offending app reserving all that memory or frees some disk space for the page file) and then clicks &#8220;Retry&#8221; and then the wrapper simply tries to allocate again. In C++, the <tt>new</tt> operator can be overloaded.</p>
<p>Just my 2 cents (Euro).</p>
<h3 id="toc-example-code">Example code</h3>
<h4 id="toc-c">C</h4>
<pre><code>void * my_alloc(size_t bytes)
{
  if (NULL == (ptr = malloc(bytes)))
  {
    // malloc failed, do something about it!
  }
  return ptr;
}</code></pre>
<h4 id="toc-c1">C++</h4>
<p>This uses the function from above C code.</p>
<pre><code>void * operator new(size_t bytes)
{
  return my_malloc(bytes);
}</code></pre>
<div style="margin-top: 10px; height: 15px;" class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/91884b1b-4ef2-46ee-8343-cc6bb32f1031/" title="Zemified by Zemanta"><img style="border: medium none ; float: right;" class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=91884b1b-4ef2-46ee-8343-cc6bb32f1031" alt="Reblog this post [with Zemanta]" /></a></div>
<h3  class="related_post_title">You might also like...</h3><ul class="related_post"><li><a href="http://kometbomb.net/2011/07/25/android-ndk-and-sdl_rwops/" title="Android NDK and SDL_RWops">Android NDK and SDL_RWops</a></li><li><a href="http://kometbomb.net/2011/01/02/lossless-audio-compression/" title="Lossless Audio Compression">Lossless Audio Compression</a></li><li><a href="http://kometbomb.net/2010/02/28/libconfig/" title="An Alternative to XML">An Alternative to XML</a></li><li><a href="http://kometbomb.net/2009/12/31/creating-a-simple-gui-from-scratch/" title="Creating a Simple GUI from Scratch">Creating a Simple GUI from Scratch</a></li><li><a href="http://kometbomb.net/2009/07/19/opengl-static-arrays-and-glmaterialfv/" title="OpenGL, Static Arrays and glMaterialfv">OpenGL, Static Arrays and glMaterialfv</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://kometbomb.net/2008/08/19/out-of-memory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

