<?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>ChaosEngineer.com</title>
	<atom:link href="http://chaosengineer.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://chaosengineer.com</link>
	<description>Harnessing the power of chaos using opensource.</description>
	<lastBuildDate>Sun, 11 Jul 2010 03:21:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Coulomb&#8217;s Law Simulation</title>
		<link>http://chaosengineer.com/?p=128</link>
		<comments>http://chaosengineer.com/?p=128#comments</comments>
		<pubDate>Thu, 18 Mar 2010 22:58:45 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=128</guid>
		<description><![CDATA[I created a gravitational simulation a while back, and it was pretty cool. I was recently reading an article about how similar Coulomb's Law is to Newton's Law of Universal Gravitation. I thought I would visit the world of physical simulations again, this time using my strange attractor engine to simulate charges in an electric [...]]]></description>
			<content:encoded><![CDATA[<p>I created a gravitational simulation a while back, and it was pretty cool. I was recently reading an article about how similar <a href="http://en.wikipedia.org/wiki/Coulomb's_law">Coulomb's Law</a> is to <a href="http://en.wikipedia.org/wiki/Newton's_law_of_universal_gravitation">Newton's Law of Universal Gravitation</a>. I thought I would visit the world of physical simulations again, this time using my strange attractor engine to simulate charges in an electric field.</p>
<p>Obviously the first step is to create charges that contribute to an electric field. The simple solution is to turn the points on the attractor into electric charges, lets say electrons. We now have a collection of charges creating an electric field. The next step is to implement Coulomb's Law.</p>
<p>The scalar form of Coulomb's Law states that <strong>f = k * ( (q0 * q1) / (r * r) )</strong>, where <strong>k</strong> is the Coulomb constant, <strong>q0</strong> is the charge of particle 1, <strong>q1</strong> is the charge of particle 2, and <strong>r</strong> is the distance between the particles.</p>
<p>There are a couple things to note about this equation. Most importantly is how the sign of the charge on each particle effects the sign of the force magnitude itself. Two charges of like sign result in a positive force, and two charges of opposing sign result in a negative force. Also, this equation simply gives the magnitude of the force, there is no direction associated with it.</p>
<p>To get a resultant force vector is quite simple. We take the vector formed by the two particles, and reduce it to unit length. We then multiply this unit length vector by the scalar magnitude of the force as determined by Coulomb's law.</p>
<p>To create a "field", we have to find the cumulative force felt on a charge from all sources. So to put it in programmer language, for each individual particle we iterate through all the charged particles in range, accumulating the force vector for each to create a resultant overall force vector. It can be said that this resultant force vector represents the field at that given point.</p>
<p>Obviously we can then resolve this force into acceleration knowing the particle's mass. Maintaining a velocity vector for each particle, we can use this acceleration to create a realtime simulation of the particle's motion through the field. As the position of these particles change, the field changes, creating a feedback system. Any lover of chaos knows we have established the prime requisite for a complex system. Hopefully we can stir some emergence from this system.</p>
<p>Applying these rules to a simple collection of electrons isn't very interesting. The cloud of electrons just explodes outward, and continues on to infinity (assuming no dampening). We need to add some positive charges to the mix, and shake it about. For the interest of science, let us create atomic nuclei with a charge much greater than that of a single electron.</p>
<p>Throwing a couple of randomly positioned positively charged nuclei into the simulation does indeed spice things up. Now we get quite interesting swirling clusters of electrons, some maintaining orbits strongly resembling electrons in the common depiction of the atom.</p>
<p>Sometimes an electron will approach a nucleus on just the right vector and get very very close to it's true position. This causes the denominator of the Coulomb's Law equation to approach zero, and the magnitude of the force to skyrocket. This results in the electron being flung off into space at high speeds. I wanted to address this problem, as it didn't jive with the aesthetics I hoped for.</p>
<p>I remember watching an episode of Fringe not too long ago, where two people were discussing the collision of two dimensions. One of the individuals dropped a reference to the <a href="http://en.wikipedia.org/wiki/Pauli_exclusion_principle">Pauli Exclusion Principle</a>, and then smashed two snowglobes together for effect. This principle explains much about the structure of atoms, and applies here because of what it says about electrons orbiting the atomic nucleus. Exercising some artistic liberties with the interpretation of this principle, I made our nuclei exert an exponentially increasing opposing force on electrons that approached too closely. If you wanted to add some scientific rigor, it would be elementary to make definitions on the characteristics of each nucleus, and apply a different force gradient to approaching electrons based on how many were already in orbit. You could easily create electron shells where the outermost (valence) shell could contain electrons that could easily be pulled off by passing nuclei, just like in chemical reactions!</p>
<p>I didn't go so far as to create multiple shells (yet), but the initial results are promising. The electrons around the nucleus form self-organizing spheres, as they seek the lowest energy by spacing themselves evenly across the surface. When multiple nuclei are interacting, its neat to see how the charge density changes and the electrons pack themselves more densely on the sides of the sphere facing nearby nuclei. </p>
<p>I'm looking forward to modulating the charge of nuclei based on realtime audio FFT data.</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/eiwFaMGUcDQ&hl=en_US&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/eiwFaMGUcDQ&hl=en_US&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=128</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NDS WiFi Programming with devkitARM &#8212; Part 4</title>
		<link>http://chaosengineer.com/?p=115</link>
		<comments>http://chaosengineer.com/?p=115#comments</comments>
		<pubDate>Thu, 25 Feb 2010 14:31:36 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[NintendoDS]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[sensors]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=115</guid>
		<description><![CDATA[We've established the important parts of the PC application, the NdsInterfaceHost, and now comes time to actually delve into the DS programming aspects w/ devkitARM and dswifi. We will here lay out the design of the NintendoDS application, the NdsInterfaceClient. Many of the network and socket concepts we covered during Part 3 of this article [...]]]></description>
			<content:encoded><![CDATA[<p>We've established the important parts of the PC application, the <em>NdsInterfaceHost</em>, and now comes time to actually delve into the DS programming aspects w/ devkitARM and dswifi. We will here lay out the design of the NintendoDS application, the <em>NdsInterfaceClient</em>. Many of the network and socket concepts we covered during Part 3 of this article will carry over into the DS code. I will try not to cover the same ground. Also note that it is entirely possible to use C++ and iostream type code with devkitARM. I chose to use standard C because it is less verbose, and for the DS platform, it just seems more appropriate to use less abstraction. </p>
<p>The NDS application exhibits much code that is ancillary to the main purpose of the project. Being a platform that is rarely developed for, there is only a small community focusing on NintendoDS development. I figure that any code that exploits the features of the DS or establishes a framework that can be extended and used for new purposes is a good contribution to the community. I won't cover this ancillary code, but be sure to download the project and examine the extra bits like the chat server that will let you telnet into your DS.</p>
<p>The basis of the NdsInterfaceClient is simple. On start, it displays some information about the DS it is running on, and then prompts the user to press B to get a list of wireless access points (APs). The code then calls Wifi_ScanMode(), and enters a loop that constantly polls the number of APs, collects information about each, and displays this information on the screen. The Wifi_ScanMode() call actually tells the dswifi library to poll and maintain an internal list of available APs. You can then query the length of this internal list using Wifi_GetNumAp(), and then get specifics using Wifi_GetAPData(...), passing the index of a particular AP.</p>
<p>For the AP list, I reused some code written by <a href="http://www.akkit.org">Stephen Stair</a> (the author of the dswifi library). I added some ANSI color for readability, and changed the format for AP data so it offered more info, particularly letting the user know if an AP was WAP protected (and thus unusable by dswifi). One of devkitPro's first feats was to implement a console on the DS. The state of this implementation today is quite elite. The console supports <a href="http://en.wikipedia.org/wiki/ANSI_escape_code">ANSI escape sequences</a>, which allow coloring text and arbitrarily relocating the cursor position. One could create an ASCII game using the console and escape sequences alone. The chat server code shows how to use escape sequences to create a "window" in the console.</p>
<p>Once an AP is selected from the list, the code will determine if the user needs to enter an encryption key. If so, a keyboard appears, and allows the entry of an encryption key. The user can enter either a 40b or 104b encryption key. Based on the length of the entry, the code determines if it is 64 or 128-bit WEP encryption, and attempts a connection to the AP. This is one of the least documented basic steps for using dswifi, and on top of that, there are some curiosities worth mentioning.</p>
<p>WAP encryption is unsupported by the NDS and NDS Lite. Support for WAP was added to the DSi, but it isn't likely we'll see it supported by the dswifi library any time soon, if ever. We are limited to using WEP-secured APs. There are two levels of supported WEP encryption, 64-bit and 128-bit. Here is where a curiosity appears. Both 64b and 128b WEP encryption use a 24b <em>Initialization Vector</em>, which is not included in the length of the encryption key you enter. So the actual length of the entered encryption keys for 64b and 128b WEP encryption are 40b and 104b, respectively. It is fine to refer to these encryption levels as either bit length including the IV, or bit length excluding the IV.  Strangely, the dswifi library does both, and defines the following two values: WEPMODE_40BIT and WEPMODE_128BIT.  It should be obvious which is which. </p>
<p>So, with the keyboard displayed a user can enter the ASCII representation of a 40b or 104b hex key, which is either a 10 or 26 character long string, respectively. We then need to convert this ASCII representation of a hex value into a 5 or 13 byte actual hex value. To accomplish this, we look at each character in the string and convert it from it's ASCII value to it's hex value. We then pack two of these hex values into a single byte (unsigned char), and append each byte onto our encryption key. Once we have 5 or 13 of these bytes, we pass them to the Wifi_ConnectAP(...) function, and wait for the connection to succeed or fail. This is accomplished by polling Wifi_AssocStatus(), waiting for it to return ASSOCSTATUS_ASSOCIATED, or ASSOCSTATUS_CANNOTCONNECT.</p>
<p>Once we successfully connect to a wireless access point, our DS will be assigned an IP address (we assume the use of DHCP). Now connected to the network, we can then start using functions like gethostbyname(...) to look up DNS entries, or connect(...) to make socket connections to remote hosts. Things are finally getting interesting. To provide a user interface to a variety of functions, we print a simple menu, with each DS button bound to a different function, and wait for a keypress:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>status == ASSOCSTATUS_ASSOCIATED<span style="color: #FFFFFF;">&#41;</span> <span style="color: #b92dc7;">while</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#41;</span>
<span style="color: #FFFFFF;">&#123;</span>
	u32 ip = Wifi_GetIP<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	consoleClear<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;ip: [%i.%i.%i.%i]<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span>, <span style="color: #FFFFFF;">&#40;</span>ip <span style="color: #FFFFFF;">&#41;</span> &amp; 0xFF, <span style="color: #FFFFFF;">&#40;</span>ip &gt;&gt; <span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#41;</span> &amp; 0xFF, <span style="color: #FFFFFF;">&#40;</span>ip &gt;&gt; <span style="color: #0064dd;">16</span><span style="color: #FFFFFF;">&#41;</span> &amp; 0xFF, <span style="color: #FFFFFF;">&#40;</span>ip &gt;&gt; <span style="color: #0064dd;">24</span><span style="color: #FFFFFF;">&#41;</span> &amp; 0xFF<span style="color: #FFFFFF;">&#41;</span>;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;--------------------------------<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Press Y to nslookup host name<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Press X to connect to interface<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Press A to listen on socket<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Press B to break<span style="color: #666666; font-weight: bold;">\n</span><span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	keypressed = <span style="color: #0064dd;">0</span>;
	<span style="color: #b92dc7;">while</span><span style="color: #FFFFFF;">&#40;</span>!<span style="color: #FFFFFF;">&#40;</span>keypressed &amp; <span style="color: #FFFFFF;">&#40;</span>KEY_Y | KEY_X | KEY_A | KEY_B | KEY_L<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		scanKeys<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
		keypressed = keysDown<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #FFFFFF;">&#125;</span>
&nbsp;
	<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>keypressed &amp; KEY_Y<span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		<span style="color: #e53434;">//execute gethostbyname(...)</span>
	<span style="color: #FFFFFF;">&#125;</span>
&nbsp;
	<span style="color: #e53434;">//etc...</span>
<span style="color: #FFFFFF;">&#125;</span>
&nbsp;</pre>
<p>Now the code governing the interaction with the Host interface is very similar to the code in the NdsHostInterface application. We synchronously send a register signal, receive the signal port (and data port) back with the register acknowledgement signal from the Host interface. We then use this signal port to construct a listener, and this data port to pipe input data to the Host.  This is the main loop of the NdsInterfaceClient:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">while</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#41;</span>
<span style="color: #FFFFFF;">&#123;</span>
	tvTimeout.<span style="color: #00eeff;">tv_sec</span> = <span style="color: #0064dd;">0</span>;
	tvTimeout.<span style="color: #00eeff;">tv_usec</span> = <span style="color: #0064dd;">1000</span>; <span style="color: #e53434;">// This will throttle the data xfer rate just a tad...</span>
	<span style="color: #e53434;">// I've found that anything less than 1000 microseconds will make select return immediately</span>
	<span style="color: #e53434;">// when called on the DS platform</span>
&nbsp;
	FD_ZERO<span style="color: #FFFFFF;">&#40;</span>&amp;fdsRead<span style="color: #FFFFFF;">&#41;</span>;
	FD_SET<span style="color: #FFFFFF;">&#40;</span>sktServer, &amp;fdsRead<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	retval = select<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1</span>, &amp;fdsRead, <span style="color: #b92dc7;">NULL</span>, <span style="color: #b92dc7;">NULL</span>, &amp;tvTimeout<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #b92dc7;">if</span> <span style="color: #FFFFFF;">&#40;</span>retval == <span style="color: #0064dd;">-1</span><span style="color: #FFFFFF;">&#41;</span>
		iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;select() error<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #b92dc7;">else</span> <span style="color: #b92dc7;">if</span> <span style="color: #FFFFFF;">&#40;</span>retval<span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
&nbsp;
		<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#40;</span>sktClient = accept<span style="color: #FFFFFF;">&#40;</span>sktServer, <span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">struct</span> sockaddr *<span style="color: #FFFFFF;">&#41;</span>&amp;adrSignalClient, &amp;iClientSize<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span> &lt; <span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#41;</span>
		<span style="color: #FFFFFF;">&#123;</span>
			iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Failed to accept client connection.<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
			<span style="color: #b92dc7;">continue</span>;
		<span style="color: #FFFFFF;">&#125;</span>
		iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Client connected: %s<span style="color: #666666; font-weight: bold;">\n</span>&quot;</span>, inet_ntoa<span style="color: #FFFFFF;">&#40;</span>adrSignalClient.<span style="color: #00eeff;">sin_addr</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
		InterfaceSignalHandler<span style="color: #FFFFFF;">&#40;</span>sktClient<span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #FFFFFF;">&#125;</span>
&nbsp;
	<span style="color: #e53434;">// If there are no signals from the host, and pen is down, send input data on UDP port.</span>
	<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>keysHeld<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span> &amp; KEY_TOUCH<span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		touchRead<span style="color: #FFFFFF;">&#40;</span>&amp;touchXY<span style="color: #FFFFFF;">&#41;</span>;
		pos = 0x00000000;
		pos = <span style="color: #FFFFFF;">&#40;</span>touchXY.<span style="color: #00eeff;">px</span> | <span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">int</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#40;</span>touchXY.<span style="color: #00eeff;">py</span><span style="color: #FFFFFF;">&#41;</span> &lt;&lt; <span style="color: #0064dd;">16</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
		iprintf<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;Sending 0x%x&quot;</span>, pos<span style="color: #FFFFFF;">&#41;</span>;
		sendto<span style="color: #FFFFFF;">&#40;</span>sktData, &amp;pos, <span style="color: #0064dd;">4</span>, <span style="color: #0064dd;">0</span>, &amp;adrData, <span style="color: #93249e;">sizeof</span><span style="color: #FFFFFF;">&#40;</span>adrData<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #FFFFFF;">&#125;</span>
&nbsp;
	scanKeys<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>keysDown<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span> &amp; KEY_B<span style="color: #FFFFFF;">&#41;</span>
		<span style="color: #b92dc7;">break</span>;
<span style="color: #FFFFFF;">&#125;</span>
&nbsp;
<span style="color: #e53434;">// Broke out of main loop, so unregister from Host and shutdown...</span>
&nbsp;</pre>
<p>That is really the jist of the NdsInterfaceClient. Obviously check out the source code to see how to appropriately construct sockets. In my last article in this series, I'll provide links to the complete source code for both applications. I might take the time to make the NdsInterfaceHost compile on Windows as well as Linux and OSX, but no promises. I'd rather leave the standard Berkeley sockets implementation alone, and let you port it to winsock yourself... or even better let you install a REAL operating system, and run it there. =)</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=115</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NDS WiFi Programming with devkitARM — Part 3</title>
		<link>http://chaosengineer.com/?p=98</link>
		<comments>http://chaosengineer.com/?p=98#comments</comments>
		<pubDate>Thu, 18 Feb 2010 20:16:46 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[NintendoDS]]></category>
		<category><![CDATA[sockets]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[dswifi]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=98</guid>
		<description><![CDATA[Finally, after half a year... part 3. 
I don't want to go any further without laying out some terminology to use. This project will consist of two parts, an application running on a PC, which I will refer to as the "Interface Host", and an application running on a NintendoDS, which I will refer to [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, after half a year... part 3. </p>
<p>I don't want to go any further without laying out some terminology to use. This project will consist of two parts, an application running on a PC, which I will refer to as the "Interface Host", and an application running on a NintendoDS, which I will refer to as the "Interface Client".</p>
<p>The host application as you may know will be rendering a cube using SDL and OpenGL. It will have a socket listener that will allow the NintendoDS to connect and negotiate terms by which it will send input data to the PC. I wanted to make the project simple but at the same time built with a framework that can be easily extended to do even more interesting things like pipe audio from the DS to the PC or something of the like. In order to do this, we'll define a simple protocol.</p>
<p>The protocol is quite simple. The Host machine will have a TCP listener that will allow Clients to connect and register. Once registered, a Client opens it's own TCP listener that will allow the Host to send commands to it. These listeners are used for <em>signaling</em>, or sending commands back and forth. I will use the terms <em>signal</em> and <em>command</em> interchangeably. After establishing signal listeners on both ends, there is a channel by which communication between the applications is simple. They can use this channel to negotiate terms for a transfer of DS touchpad data, for example. </p>
<p>By having an array of agreed-upon values that correspond to specific signals, and expected data to follow those signals, the applications have the foundation of a protocol. There may be more to the protocol as well, such as an expected order of operations. Again with a focus on simplicity, let us outline a protocol:<br />
<div id="attachment_99" class="wp-caption alignleft" style="width: 360px"><img src="http://chaosengineer.com/wp-content/uploads/2010/02/NdsInterface_protocol.png" alt="Nds Interface Protocol" title="NdsInterface_protocol" width="350" height="458" class="size-full wp-image-99" /><p class="wp-caption-text">Nds Interface Protocol</p></div></p>
<p>The idea here is that the machines first negotiate with one another, eventually establishing a method to transfer data from the client to the host. All negotiation occurs over TCP, but the actual data transfer will occur over UDP on an agreed-upon port. I won't go into details of TCP vs UDP. There are articles on the net written by people far more qualified than me if you are curious. The basic reasoning is that we need the negotiation to be reliable, but we can tolerate a missing data transfer. Although in theory a series of UDP packets sent over a network can arrive at the destination in any order, I have never seen this happen in practice. Perhaps because all my practice has been over a LAN... maybe things over a WAN would be different. Regardless... UDP works great in practice and provides the benefits of being simpler and carrying less overhead. UDP is generally used for realtime streaming applications where a lost transfer doesn't break the overall functionality of the system. This is exactly the situation for our input data.</p>
<p>The host machine opens a listener on a port the client knows to look for. The client connects to the host machine on this port, and sends the <em>Register</em> signal. The host responds on the same socket with the <em>RegisterAck</em> signal. This acknowledgement signal is followed by a 32-bit integer telling the client what port to open as it's own signal listener. The host then knows how to communicate with it's newly registered "node". After constructing it's own signal listener, the machines can have any number of conversations initiated by either end. Each conversation will typically occur over the same socket connection, and consist of a signal followed an acknowledgement signal  w/ a data payload. A simple beowulf cluster could be implemented using this design. Typically deployed over a non-homogenous array of machines, a beowulf host might send a signal to query each node's capability and the node might respond with the time it required to crunch some numbers using it's potentially unique hardware specifications.</p>
<p>The first applications I wrote that implemented this signaling design used multiple threads. The main thread was the signal listener, and when it got incoming connections, it would accept them and then pass the connected socket to a newly spawned thread that would handle the signal from the client. At the time, I thought this was an elite implementation, and without a doubt the best way to accomplish things. I then got myself into situations where I wanted to construct a signal listener either in a project I didn't want to implement threads or on a platform that doesn't support them. Enter the select() system call.</p>
<p>Multiplexing in a single thread, now THAT is elite. Using select(), you can easily monitor a listening socket for new connections while still handling signals from new sockets and even sending data every frame. The innermost loop of our Interface Client application on the DS will do exactly this. It will be managing the signal listener, handling any new signals and sending touchpad coordinates over the established data socket.</p>
<p>Here is what this synchronous code would look like inside an application's main loop, here being part of the Interface Host's main loop:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">while</span><span style="color: #FFFFFF;">&#40;</span>!g_bDone<span style="color: #FFFFFF;">&#41;</span> <span style="color: #e53434;">// Pseudo main loop</span>
<span style="color: #FFFFFF;">&#123;</span>
	<span style="color: #e53434;">// Check listener for new signals. This is done in a time-sensitive manner</span>
	<span style="color: #e53434;">//using select to return immediately if there is no data/connections present.</span>
	tvTimeout.<span style="color: #00eeff;">tv_sec</span> = <span style="color: #0064dd;">0</span>;
	tvTimeout.<span style="color: #00eeff;">tv_usec</span> = <span style="color: #0064dd;">0</span>;
&nbsp;
	FD_ZERO<span style="color: #FFFFFF;">&#40;</span>&amp;fdsRead<span style="color: #FFFFFF;">&#41;</span>;
	FD_SET<span style="color: #FFFFFF;">&#40;</span>sktHost, &amp;fdsRead<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	retval = select<span style="color: #FFFFFF;">&#40;</span>FD_SETSIZE, &amp;fdsRead, <span style="color: #b92dc7;">NULL</span>, <span style="color: #b92dc7;">NULL</span>, &amp;tvTimeout<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #b92dc7;">if</span> <span style="color: #FFFFFF;">&#40;</span>retval == <span style="color: #0064dd;">-1</span><span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		<span style="color: #93249e;">cerr</span> &lt;&lt; __FILE__ &lt;&lt; <span style="color: #666666;">'@'</span> &lt;&lt; __LINE__ &lt;&lt; <span style="color: #666666;">&quot; : select() error waiting on accept.&quot;</span> &lt;&lt; endl;
	<span style="color: #FFFFFF;">&#125;</span>
	<span style="color: #b92dc7;">else</span> <span style="color: #b92dc7;">if</span> <span style="color: #FFFFFF;">&#40;</span>retval<span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		<span style="color: #93249e;">cout</span> &lt;&lt; <span style="color: #666666;">&quot;Incoming connection...&quot;</span> &lt;&lt; endl;
&nbsp;
		<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#40;</span>sktClient = accept<span style="color: #FFFFFF;">&#40;</span>sktHost, <span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">struct</span> sockaddr*<span style="color: #FFFFFF;">&#41;</span>&amp;adrInterfaceClient, <span style="color: #FFFFFF;">&#40;</span>socklen_t*<span style="color: #FFFFFF;">&#41;</span>&amp;iClientSize<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span> &lt; <span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#41;</span>
		<span style="color: #FFFFFF;">&#123;</span>
			<span style="color: #93249e;">cerr</span> &lt;&lt; __FILE__ &lt;&lt; <span style="color: #666666;">'@'</span> &lt;&lt; __LINE__ &lt;&lt; <span style="color: #666666;">&quot; : Failed to accept client connection.&quot;</span> &lt;&lt; endl;
		<span style="color: #FFFFFF;">&#125;</span>
		<span style="color: #b92dc7;">else</span>
		<span style="color: #FFFFFF;">&#123;</span>
			<span style="color: #93249e;">strcpy</span><span style="color: #FFFFFF;">&#40;</span>g_szConnectedClientName, inet_ntoa<span style="color: #FFFFFF;">&#40;</span>adrInterfaceClient.<span style="color: #00eeff;">sin_addr</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
			<span style="color: #93249e;">cout</span> &lt;&lt; <span style="color: #666666;">&quot;Client connected: &quot;</span> &lt;&lt; g_szConnectedClientName &lt;&lt; endl;
&nbsp;
			InterfaceClientSignalHandler<span style="color: #FFFFFF;">&#40;</span>sktClient<span style="color: #FFFFFF;">&#41;</span>;
		<span style="color: #FFFFFF;">&#125;</span>
	<span style="color: #FFFFFF;">&#125;</span>
&nbsp;
	<span style="color: #e53434;">// Do whatever else here... render objects, process input, etc.</span>
<span style="color: #FFFFFF;">&#125;</span>
&nbsp;</pre>
<p>The next article -- part 4 -- will detail the NintendoDS implementation using the dswifi library, and I'll probably write a 5th article just to wrap it all up.</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=98</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unforgotten</title>
		<link>http://chaosengineer.com/?p=91</link>
		<comments>http://chaosengineer.com/?p=91#comments</comments>
		<pubDate>Mon, 15 Feb 2010 10:14:33 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[OSX]]></category>
		<category><![CDATA[gaming]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=91</guid>
		<description><![CDATA[I almost forgot I started a blog!
About six months ago I got a MacBook Pro, so I spent a long while just updating my applications to run on OSX, and also exploring Core Foundation. I've made some neat stuff that I'll share with you guys, as soon as I get out this NDS WiFi programming [...]]]></description>
			<content:encoded><![CDATA[<p>I almost forgot I started a blog!</p>
<p>About six months ago I got a MacBook Pro, so I spent a long while just updating my applications to run on OSX, and also exploring Core Foundation. I've made some neat stuff that I'll share with you guys, as soon as I get out this NDS WiFi programming project that I've been promising for nearly a year. =P</p>
<p>Around the same time I got my new Mac, I also found Dragon Age: Origins. Installing this game created a time anomaly centered around my computer. I played enough DA:O that the heat generated by my video card has likely contributed greatly to global warming, and melted a few iceburgs. The deaths of many penguins was worth the glory of turning back a blight.</p>
<p>After DA:O (like 6 characters and playthroughs later), I got wrapped up in the whole Bioware strategic RPG thing. I played through the entire Baldur's Gate series with all expansions, then the Neverwinter Nights series with all expansions, and I just finished Mass Effect. SOO... needless to say, I've been distracted.</p>
<p>I haven't forgotten about you however, and I will soon piece together the final bits of the NDS WiFi project, and make a post to bring it all together, I promise. =)</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=91</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DERAILED &#8212; Platform independent dynamic linking</title>
		<link>http://chaosengineer.com/?p=86</link>
		<comments>http://chaosengineer.com/?p=86#comments</comments>
		<pubDate>Sun, 09 Aug 2009 05:19:49 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[multiplatform]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[random]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=86</guid>
		<description><![CDATA[Ooops, I definitely got sidetracked more mucking around with my platform independent rendering engine. Instead of just holding out on the NDS wifi article in silence for any longer, I thought I would chime in and let you know I haven't forgot about you and show you what I've been up to.
My platform independent rendering [...]]]></description>
			<content:encoded><![CDATA[<p>Ooops, I definitely got sidetracked more mucking around with my platform independent rendering engine. Instead of just holding out on the NDS wifi article in silence for any longer, I thought I would chime in and let you know I haven't forgot about you and show you what I've been up to.</p>
<p>My platform independent rendering engine is based on a pure virtual renderer base class that is filled with an instance of a derived class by a dynamically linked code module. Along with the pure virtual renderer class, there are a few pure virtual resource classes as well, the actual instantiation of which are performed by the renderer class. Trying to maintain platform independence, the singleton (factory / manager) class that returns this renderer instance has some interesting code I thought I would share. </p>
<p>It is possible to have a project directory (even though a bit messy) that will compile in both Microsoft Visual Studio and in GCC without having to change a lick of code. Thats child's play for a simple project, but its still possible even for a project that contains a main executable and several other dynamic libraries. </p>
<p>So first off, since we are dynamically linking, we are definitely going to have function pointers returned by dlsym(...) or GetProcAddress(...). The actual DLL/SO modules export only three functions--one to create the instance, one to destroy it, and one to return the version. So we have the typedefs for these as so:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">typedef</span> <span style="color: #b92dc7;">int</span> <span style="color: #FFFFFF;">&#40;</span>*fpCreateRendererInterface<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#40;</span>CRenderer **pInterface<span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #b92dc7;">typedef</span> <span style="color: #b92dc7;">int</span> <span style="color: #FFFFFF;">&#40;</span>*fpDestroyRendererInterface<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#40;</span>CRenderer **pInterface<span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #b92dc7;">typedef</span> <span style="color: #b92dc7;">int</span> <span style="color: #FFFFFF;">&#40;</span>*fpQueryRendererVersion<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">void</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;</pre>
<p>Second off, this is platform independent, so obviously we will need to be using some fancy pre-processor conditionals (PPCs) to detect the platform / compiler. Now in certain instances we only want to know what the compiler is, because the actual platform doesn't matter, but in other cases we want to know the actual platform as well because the same compiler is used on multiple platforms (GCC is used in Linux and also Mac). First for the compiler, we can detect Visual C++ by checking to see if <strong>_MSC_VER</strong> is defined, and we can detect GCC by checking to see if <strong>__GNUC__</strong> is defined. For the platform, we can detect Windows by checking if <strong>WIN32</strong> is defined (yes, even 64-bit Windows defines this), we can detect Linux by checking if <strong>__linux__</strong> is defined, and we can detect OSX by checking if <strong>__MACH__</strong> and <strong>__APPLE__</strong> are defined.</p>
<p>We can then use these PPCs to create code that is savagely flexible. In this singleton class, I have a static void pointer to the library (Windows' HMODULE is just a void*, don't let them trick you) called m_hLibrary. Lets see how we could dynamically link either a .so file in Linux or a .dll file in Windows and place the returned handle in the same variable... here is the code for the "SGL" (SDL GL) renderer type which can be used in either Linux or Windows, taking into account if the code is in release or debug mode:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">case</span> rstSGL:
	<span style="color: #93249e;">Log</span>::<span style="color: #00eeff;">Entry</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">-1</span>,__FILE__,__LINE__,<span style="color: #666666;">&quot;Creating SGL rendering interface...&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#if defined(__GNUC__)</span>
&nbsp;
<span style="color: #339900;">#if defined(NDEBUG)</span>
	<span style="color: #93249e;">Log</span>::<span style="color: #00eeff;">Entry</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">-1</span>,__FILE__,__LINE__,<span style="color: #666666;">&quot;__GNUC__ defined... opening release library&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	m_hLibrary = dlopen<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;./libRendererSGL.so&quot;</span>,RTLD_NOW<span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#else</span>
	<span style="color: #93249e;">Log</span>::<span style="color: #00eeff;">Entry</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">-1</span>,__FILE__,__LINE__,<span style="color: #666666;">&quot;__GNUC__ defined... opening debug library&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	m_hLibrary = dlopen<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;../RendererSGL/bin/Debug/libRendererSGL.so&quot;</span>,RTLD_NOW<span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#endif</span>
	<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>!m_hLibrary<span style="color: #FFFFFF;">&#41;</span>
		<span style="color: #93249e;">Log</span>::<span style="color: #00eeff;">Entry</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">2</span>,__FILE__,__LINE__,<span style="color: #666666;">&quot;Error loading shared library. dlerror() = %s&quot;</span>,dlerror<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#elif defined(_MSC_VER)</span>
<span style="color: #339900;">#if defined(NDEBUG)</span>
	m_hLibrary = LoadLibraryExA<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;RendererSGL.dll&quot;</span>,<span style="color: #b92dc7;">NULL</span>,<span style="color: #b92dc7;">NULL</span><span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#else</span>
	m_hLibrary = LoadLibraryExA<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;../RendererSGL/bin/Debug/RendererSGL.dll&quot;</span>,<span style="color: #b92dc7;">NULL</span>,<span style="color: #b92dc7;">NULL</span><span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#endif</span>
<span style="color: #339900;">#endif</span>
	<span style="color: #b92dc7;">break</span>;
&nbsp;</pre>
<p>Please note that NDEBUG is not defined by GCC even when using -O2, so you need to set your release target to define this manually (-D NDEBUG). I find it strange because it is supposedly a standard...</p>
<p>Also note that when linking using dlopen(...), we specify RTLD_NOW to force resolution of all symbols in the dynamic library. If we used RTLD_LAZY, we could exclude a lot of code from our library, and let it resolve symbols later (i.e. from the main executable). Unfortunately this works great on Linux but seemingly has no analogy in Windows, and in order to keep the projects symmetrical across platforms, we use RTLD_NOW to behave appropriately.</p>
<p>So lets look at whats going on here... its a bit over complicated, but I thought I would provide some extra good ideas for you guys. If using GCC, we use dlopen(...) to get the handle to the .so file, and if using VC++, we use LoadLibraryExA(...) to get the handle to the .dll file. If <strong>NDEBUG</strong> is defined, we link to the release version of the dynamic library (actually look in the current directory or system path as if it were a proper deployment), otherwise we link to the debug version of the library to simplify development.</p>
<p>Oh snap! So we now have linked to a dynamic library regardless of what platform we are running on! This is kickass, so where to now? We need to get pointers to the functions in the library we are going to use. The function that does this in Linux is dlsym(...), and in windows is GetProcAddress(...). Here is what this would look like in a platform independent form:</p>
<pre class="cpp">&nbsp;
<span style="color: #339900;">#if defined(__GNUC__)</span>
	fpCreateRendererInterface IntCreate=<span style="color: #FFFFFF;">&#40;</span>fpCreateRendererInterface<span style="color: #FFFFFF;">&#41;</span>dlsym<span style="color: #FFFFFF;">&#40;</span>m_hLibrary,<span style="color: #666666;">&quot;CreateInterface&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#elif defined(_MSC_VER)</span>
	fpCreateRendererInterface IntCreate=<span style="color: #FFFFFF;">&#40;</span>fpCreateRendererInterface<span style="color: #FFFFFF;">&#41;</span>GetProcAddress<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#40;</span>HMODULE<span style="color: #FFFFFF;">&#41;</span>m_hLibrary,<span style="color: #666666;">&quot;CreateInterface&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
<span style="color: #339900;">#endif</span>
&nbsp;</pre>
<p>Damn, its that easy? Indeed it is. We now have a function pointer to a procedure in a dynamically linked library regardless of if it came from a .so file in Linux or a .dll file in Windows. Obviously once armed with the function pointer, the remaining code is the same regardless of platform. We just use IntCreate(...) like it were a normal function. In this case we pass a pointer to a pointer to the pure virtual renderer base class, and inside the dynamic library, we assign the pointer to an instance of a derived class:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">extern</span> <span style="color: #666666;">&quot;C&quot;</span>
<span style="color: #FFFFFF;">&#123;</span>
	<span style="color: #b92dc7;">int</span> CreateInterface<span style="color: #FFFFFF;">&#40;</span>CRenderer **pInterface<span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>*pInterface<span style="color: #FFFFFF;">&#41;</span>
			<span style="color: #b92dc7;">return</span> <span style="color: #0064dd;">-1</span>;
&nbsp;
		*pInterface = <span style="color: #93249e;">new</span> CRendererSGL<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
		<span style="color: #b92dc7;">return</span> <span style="color: #0064dd;">0</span>;
	<span style="color: #FFFFFF;">&#125;</span>
...
&nbsp;</pre>
<p>This is really quite powerful, and since the only actual call to an exported function is when creating the derived class instance, the performance hit while using the derived class is only from the vftable. More importantly this lets us do something ultra simple in our main code to get a reference to an abstract renderer interface that doesn't require knowledge of the nitty-gritty of either D3D or OpenGL:</p>
<pre class="cpp">&nbsp;
	<span style="color: #93249e;">Log</span>::<span style="color: #00eeff;">Entry</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">0</span>,__FILE__,__LINE__,<span style="color: #666666;">&quot;Creating rendering device...&quot;</span><span style="color: #FFFFFF;">&#41;</span>;
	Graphics::<span style="color: #00eeff;">CreateInterface</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	CRenderer *renderer = Graphics::<span style="color: #00eeff;">GetInterface</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	renderer-&gt;Initialize<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>g_bSafeDevice<span style="color: #FFFFFF;">&#41;</span>
		renderer-&gt;CreateDeviceSafe<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #b92dc7;">else</span>
		renderer-&gt;CreateDevice<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">800</span>, <span style="color: #0064dd;">600</span>, <span style="color: #0064dd;">32</span>, g_bWindowed<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;</pre>
<p>Yeah, I know. That code is delicious. Its even more tasty when you have a CMesh that contains instances of pure virtual CResourceVtxBuff and CResourceIdxBuff created by the derived CRenderer class in the dynamic library, and CModel that contains a number of CMesh instances as well as a number of CMaterial instances that contain instances of pure virtual CResourceTexture also created by the derived CRenderer class in the dynamic library. So to create a model and render it, you would have to do something like the following:</p>
<pre class="cpp">&nbsp;
	<span style="color: #e53434;">// example of loading a mesh</span>
	mshOut = <span style="color: #93249e;">new</span> CMesh<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	iStride=mshOut-&gt;GetVtxStride<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	mshOut-&gt;SetVtxCount<span style="color: #FFFFFF;">&#40;</span>iVertexCount<span style="color: #FFFFFF;">&#41;</span>;
	mshOut-&gt;SetFaceCount<span style="color: #FFFFFF;">&#40;</span>iFaceCount<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	m_pRenderer-&gt;CreateMeshBuffers<span style="color: #FFFFFF;">&#40;</span>iStride*iVertexCount,<span style="color: #93249e;">sizeof</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">int</span><span style="color: #FFFFFF;">&#41;</span>*<span style="color: #0064dd;">3</span>*iFaceCount,mshOut<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">// if pRenderer is D3D, this lock would be like IDirect3DVertexBuffer9-&gt;Lock(...),</span>
	<span style="color: #e53434;">//while in OpenGL it would be like glMapBufferARB(...). Transparent at this point.</span>
	VtxData=<span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">unsigned</span> <span style="color: #b92dc7;">char</span>*<span style="color: #FFFFFF;">&#41;</span>mshOut-&gt;GetVtxPtr<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>-&gt;LockWrite<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">0</span>,<span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">// Write vertex buffer to VtxData here...</span>
&nbsp;
	mshOut-&gt;GetVtxPtr<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>-&gt;Unlock<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	IdxData=<span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">unsigned</span> <span style="color: #b92dc7;">char</span>*<span style="color: #FFFFFF;">&#41;</span>mshOut-&gt;GetIdxPtr<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>-&gt;LockWrite<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">0</span>,<span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">// write index buffer to IdxData here..</span>
&nbsp;
	mshOut-&gt;GetIdxPtr<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>-&gt;Unlock<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">// example of loading a material</span>
	mtlOut=<span style="color: #93249e;">new</span> CMaterial<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
	mtlOut-&gt;SetDiffuse<span style="color: #FFFFFF;">&#40;</span>FloatToLongColor<span style="color: #FFFFFF;">&#40;</span>v3fDiffuse.<span style="color: #00eeff;">x</span>, v3fDiffuse.<span style="color: #00eeff;">y</span>, v3fDiffuse.<span style="color: #00eeff;">z</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
	mtlOut-&gt;SetAmbient<span style="color: #FFFFFF;">&#40;</span>FloatToLongColor<span style="color: #FFFFFF;">&#40;</span>v3fAmbient.<span style="color: #00eeff;">x</span>, v3fAmbient.<span style="color: #00eeff;">y</span>, v3fAmbient.<span style="color: #00eeff;">z</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
	mtlOut-&gt;SetSpecular<span style="color: #FFFFFF;">&#40;</span>FloatToLongColor<span style="color: #FFFFFF;">&#40;</span>v3fSpecular.<span style="color: #00eeff;">x</span>, v3fSpecular.<span style="color: #00eeff;">y</span>, v3fSpecular.<span style="color: #00eeff;">z</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
	mtlOut-&gt;SetMaterialName<span style="color: #FFFFFF;">&#40;</span>sMaterialName<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	mtlOut-&gt;SetTexture<span style="color: #FFFFFF;">&#40;</span>m_pRenderer-&gt;CreateTexture<span style="color: #FFFFFF;">&#40;</span>&amp;imgTexture<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">// and you add them to a model which contains std::vectors of meshes and materials...</span>
&nbsp;
	iMaterialIdxList<span style="color: #FFFFFF;">&#91;</span>j<span style="color: #FFFFFF;">&#93;</span> = mdlOut-&gt;AddMaterial<span style="color: #FFFFFF;">&#40;</span>mtlOut<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">//...</span>
&nbsp;
	mdlOut-&gt;AddMesh<span style="color: #FFFFFF;">&#40;</span>mshOut,iMaterialIdxList<span style="color: #FFFFFF;">&#91;</span>iMaterialRef<span style="color: #FFFFFF;">&#93;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #e53434;">// and eventually render!</span>
&nbsp;
	iMeshCount = mdlCurr-&gt;GetMeshCount<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
	<span style="color: #b92dc7;">for</span><span style="color: #FFFFFF;">&#40;</span>j=<span style="color: #0064dd;">0</span>;j&lt;iMeshCount;j++<span style="color: #FFFFFF;">&#41;</span>
	<span style="color: #FFFFFF;">&#123;</span>
		pRenderer-&gt;SetWorld<span style="color: #FFFFFF;">&#40;</span>&amp;matWorld<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
		k = mdlCurr-&gt;GetMeshMaterialIdx<span style="color: #FFFFFF;">&#40;</span>j<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
		pRenderer-&gt;SetTexture<span style="color: #FFFFFF;">&#40;</span>mdlCurr-&gt;GetMaterial<span style="color: #FFFFFF;">&#40;</span>k<span style="color: #FFFFFF;">&#41;</span>-&gt;GetTexture<span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
		pRenderer-&gt;Render<span style="color: #FFFFFF;">&#40;</span>mdlCurr-&gt;GetMesh<span style="color: #FFFFFF;">&#40;</span>j<span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #FFFFFF;">&#125;</span>
&nbsp;</pre>
<p>Anyway, I guess this isn't all that useful, and maybe I'm just showing off at this point. It does exhibit some good ideas, and show how glorious abstraction can be though. Regardless, I got distracted again. The NDS Wifi example continues. I will post in the next few days to describe the protocol used and give a little primer on sockets. Keep your eyes peeled.</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=86</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NDS WiFi Programming with devkitARM &#8212; Part 2</title>
		<link>http://chaosengineer.com/?p=76</link>
		<comments>http://chaosengineer.com/?p=76#comments</comments>
		<pubDate>Sat, 27 Jun 2009 00:10:43 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[dswifi]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=76</guid>
		<description><![CDATA[So the idea I had to display the potential for socket programming on the NDS was to simply pipe the input data from the NDS over the network to a remote host. To make this appealing from beyond just a technical standpoint, I figured the remote host should be running some sort of visualization that [...]]]></description>
			<content:encoded><![CDATA[<p>So the idea I had to display the potential for socket programming on the NDS was to simply pipe the input data from the NDS over the network to a remote host. To make this appealing from beyond just a technical standpoint, I figured the remote host should be running some sort of visualization that the user could interact with remotely by using the NDS touchscreen. Making an OpenGL application with a 3D cube the user could spin using the touchscreen would work nicely. Lets figure out how to do that from an OpenGL perspective.</p>
<p><img src="http://chaosengineer.com/wp-content/uploads/2009/06/crossproduct1.png" alt="Candidate for Crossproduct" title="crossproduct1" width="188" height="190" class="size-full wp-image-82" />We want to rotate the cube along an axis perpendicular to the mouse motion vector. This will give the impression that the cube is spinning as a direct result of the motion, as if you had quickly ran your hand along it. So we first need to construct a vector that is perpendicular to the motion, and lies in the plane of the screen. Lets assume we have a default OpenGL view setup, where we are looking along the negative z-axis, and the screen lies in the xy-plane. Thus, we want a vector that is perpendicular to the mouse motion and lies in the xy-plane.</p>
<p>Anyone with some math background may immediately recognize the cross-product as a candidate to construct the perpendicular vector. Indeed, if we create a vector from the relative mouse motion (conveniently in our environment the mouse motion is on the xy-plane, so the screen coordinates align nicely), then take the cross-product of this vector with the z-axis, the result is a vector that is perpendicular to the mouse motion and lies in the xy-plane.</p>
<pre class="cpp">&nbsp;
&nbsp;
<span style="color: #e53434;">//iRelX and iRelY is the relative mouse motion</span>
&nbsp;
<span style="color: #b92dc7;">float</span> fTheta;
<span style="color: #b92dc7;">float</span> vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>;
<span style="color: #b92dc7;">float</span> fCrossMag;
&nbsp;
<span style="color: #e53434;">// Assign theta to the magnitude of the mouse motion vector</span>
<span style="color: #e53434;">// This is rather arbitrary</span>
fTheta = <span style="color: #FFFFFF;">&#40;</span>iRelX*iRelX + iRelY*iRelY<span style="color: #FFFFFF;">&#41;</span>/<span style="color: #0064dd;">16.0</span>;
&nbsp;
<span style="color: #e53434; font-style: italic;">/*
vCrossX = v1y*v2z - v1z*v2y
vCrossY = v1z*v2x - v1x*v2z
vCrossZ = v1x*v2y - v1y*v2x
*/</span>
&nbsp;
<span style="color: #e53434;">// Perform cross-product.</span>
<span style="color: #e53434;">// Here v1 is the mouse motion vector and v2 is the z-axis.</span>
<span style="color: #e53434;">// This gives us a vector that is perpendicular to</span>
<span style="color: #e53434;">//the mouse motion and lies in the xy-plane.</span>
vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> = iRelY*<span style="color: #0064dd;">1.0</span> - <span style="color: #0064dd;">0.0</span>*<span style="color: #0064dd;">0.0</span>;
vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>*<span style="color: #0064dd;">0.0</span> - -iRelX*<span style="color: #0064dd;">1.0</span>;
vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> = -iRelX*<span style="color: #0064dd;">0.0</span> - iRelY*<span style="color: #0064dd;">0.0</span>;
&nbsp;
<span style="color: #e53434;">// Normalize this vector for use as axis in rotation matrix</span>
fCrossMag = <span style="color: #93249e;">sqrt</span><span style="color: #FFFFFF;">&#40;</span>vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>*vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> + vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>*vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> + vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span>*vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span><span style="color: #FFFFFF;">&#41;</span>;
vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> = vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> / fCrossMag;
vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> = vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> / fCrossMag;
vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> = vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> / fCrossMag;
&nbsp;</pre>
<p>Great. So now we can just take this vector and use it when calling glRotatef(...) in order to transform the modelview matrix, right? Well, not quite. We CAN do this, but if you've played around with glRotatef(...) to manipulate objects in your scene via the modelview matrix, you may have noticed that when you rotate an object on one axis, it actually transforms the other two axes. This basically means that using glRotatef(...) or any other matrix transform in this manner is actually operating in the model's local coordinate system. If we tried to rotate our cube around our constructed axis using glRotatef(...), it would work as expected initially but then subsequent rotations would rotate around the already transformed axis. We don't want this, we want to operate on a fixed coordinate system, what is often referred to as the <em>world</em> coordinate system.</p>
<p>This issue arises because matrix operations post-multiply on the matrix stack in OpenGL. If we could pre-multiply the operations, we would be good, but unfortunately there is no way to tell OpenGL to pre-multiply instead, so we really have to do this operation manually. In order to accomplish this, we need to maintain our own modelview matrix accumulation, and each frame multiply our rotation matrix by this accumulation matrix to get the new modelview transform. Note that if we used glRotatef(...), it would multiply the accumulation matrix by the rotation matrix. Matrix multiplication isn't commutative, and in our situation it makes all the difference in the world. </p>
<p>So we need to get our hands dirty with a little linear algebra. First we need to define a few 4x4 matrices that we can hand to OpenGL:</p>
<pre class="cpp">&nbsp;
<span style="color: #e53434;">// OpenGL likes this format for a 4x4 matrix</span>
<span style="color: #e53434;">//as declared in the Redbook</span>
<span style="color: #b92dc7;">float</span> matWorld<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">16</span><span style="color: #FFFFFF;">&#93;</span>;
<span style="color: #b92dc7;">float</span> matWorldAccum<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">16</span><span style="color: #FFFFFF;">&#93;</span>;
<span style="color: #b92dc7;">float</span> matBuff<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">16</span><span style="color: #FFFFFF;">&#93;</span>;
&nbsp;</pre>
<p>Also define a function that can construct a rotation matrix when rotating around an arbitrary axis:</p>
<pre class="cpp">&nbsp;
<span style="color: #e53434;">// Theta is in radians</span>
<span style="color: #b92dc7;">void</span> MatrixRotation<span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">float</span> *matRot, <span style="color: #b92dc7;">float</span> fTheta, <span style="color: #b92dc7;">float</span> fAxisX, <span style="color: #b92dc7;">float</span> fAxisY, <span style="color: #b92dc7;">float</span> fAxisZ<span style="color: #FFFFFF;">&#41;</span>
<span style="color: #FFFFFF;">&#123;</span>
	<span style="color: #b92dc7;">float</span> fCosTheta, fSinTheta;
&nbsp;
	<span style="color: #e53434;">// m0   m4   m8   m12</span>
	<span style="color: #e53434;">// m1   m5   m9   m13</span>
	<span style="color: #e53434;">// m2   m6   m10  m14</span>
	<span style="color: #e53434;">// m3   m7   m11  m15</span>
	fCosTheta = <span style="color: #93249e;">cos</span><span style="color: #FFFFFF;">&#40;</span>fTheta<span style="color: #FFFFFF;">&#41;</span>;
	fSinTheta = <span style="color: #93249e;">sin</span><span style="color: #FFFFFF;">&#40;</span>fTheta<span style="color: #FFFFFF;">&#41;</span>;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> = fAxisX*fAxisX+<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fAxisX*fAxisX<span style="color: #FFFFFF;">&#41;</span>*fCosTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span> = fAxisX*fAxisY*<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fCosTheta<span style="color: #FFFFFF;">&#41;</span>-fAxisZ*fSinTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span> = fAxisX*fAxisZ*<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fCosTheta<span style="color: #FFFFFF;">&#41;</span>+fAxisY*fSinTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>; <span style="color: #e53434;">// m12,m13,m14 can be used for translation</span>
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> = fAxisX*fAxisY*<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fCosTheta<span style="color: #FFFFFF;">&#41;</span>+fAxisZ*fSinTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span> = fAxisY*fAxisY+<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fAxisY*fAxisY<span style="color: #FFFFFF;">&#41;</span>*fCosTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span> = fAxisY*fAxisZ*<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fCosTheta<span style="color: #FFFFFF;">&#41;</span>-fAxisX*fSinTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> = fAxisX*fAxisZ*<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fCosTheta<span style="color: #FFFFFF;">&#41;</span>-fAxisY*fSinTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span> = fAxisY*fAxisZ*<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fCosTheta<span style="color: #FFFFFF;">&#41;</span>+fAxisX*fSinTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span> = fAxisZ*fAxisZ+<span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">1.0</span>-fAxisZ*fAxisZ<span style="color: #FFFFFF;">&#41;</span>*fCosTheta;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">0.0</span>;
	matRot<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #0064dd;">1.0</span>;
&nbsp;
<span style="color: #FFFFFF;">&#125;</span>
&nbsp;</pre>
<p>Now we need to be able to multiply our rotation matrix by the accumulated modelview transformation matrix:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">void</span> MatrixMultiply<span style="color: #FFFFFF;">&#40;</span><span style="color: #b92dc7;">float</span> *matDest, <span style="color: #b92dc7;">const</span> <span style="color: #b92dc7;">float</span> *matA, <span style="color: #b92dc7;">const</span> <span style="color: #b92dc7;">float</span> *matB<span style="color: #FFFFFF;">&#41;</span>
<span style="color: #FFFFFF;">&#123;</span>
	<span style="color: #e53434;">// m0   m4   m8   m12</span>
	<span style="color: #e53434;">// m1   m5   m9   m13</span>
	<span style="color: #e53434;">// m2   m6   m10  m14</span>
	<span style="color: #e53434;">// m3   m7   m11  m15</span>
&nbsp;
	<span style="color: #e53434;">// Inner product of each row with each column</span>
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>;
&nbsp;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>;
&nbsp;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>;
&nbsp;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">4</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">5</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">6</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">9</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">10</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>;
	matDest<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>=matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">3</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">12</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">7</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">13</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">11</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">14</span><span style="color: #FFFFFF;">&#93;</span> + matA<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>*matB<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">15</span><span style="color: #FFFFFF;">&#93;</span>;
&nbsp;
<span style="color: #FFFFFF;">&#125;</span>
&nbsp;</pre>
<p>Great, so we are now equipped to construct and maintain our own modelview matrix! This means we no longer have to ask OpenGL for transformations. We can do them ourselves, and just hand the transformation matrix to OpenGL for rendering the current scene.</p>
<pre class="cpp">&nbsp;
<span style="color: #e53434;">// Now we contruct a matrix to rotate around this axis</span>
MatrixRotation<span style="color: #FFFFFF;">&#40;</span>matWorld, fTheta*PI/<span style="color: #0064dd;">180.0</span>, vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">0</span><span style="color: #FFFFFF;">&#93;</span>, vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">1</span><span style="color: #FFFFFF;">&#93;</span>, vCross<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">2</span><span style="color: #FFFFFF;">&#93;</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
<span style="color: #e53434;">// Notice this is matWorld * matWorldAccum, instead of</span>
<span style="color: #e53434;">//matWorldAccum * matWorld, as it would be if we just used</span>
<span style="color: #e53434;">//glMultMatrix with the constructed matWorld rotation matrix</span>
MatrixMultiply<span style="color: #FFFFFF;">&#40;</span>matBuff, matWorld, matWorldAccum<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
<span style="color: #e53434;">// Assign the world matrix accumulation to the modelview matrix</span>
glMatrixMode<span style="color: #FFFFFF;">&#40;</span>GL_MODELVIEW<span style="color: #FFFFFF;">&#41;</span>;
glLoadMatrixf<span style="color: #FFFFFF;">&#40;</span>matBuff<span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
<span style="color: #e53434;">// Update accumulated matrix</span>
<span style="color: #b92dc7;">for</span><span style="color: #FFFFFF;">&#40;</span>i=<span style="color: #0064dd;">0</span>; i&lt;<span style="color: #0064dd;">16</span>; i++<span style="color: #FFFFFF;">&#41;</span>
	matWorldAccum<span style="color: #FFFFFF;">&#91;</span>i<span style="color: #FFFFFF;">&#93;</span> = matBuff<span style="color: #FFFFFF;">&#91;</span>i<span style="color: #FFFFFF;">&#93;</span>;
&nbsp;</pre>
<p>Fun stuff, eh? I always feel empowered by doing more things in my client code instead of processing data in a black box. Next part of the article we will get into the NDS and socket programming. I know you are holding your breath. =)</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=76</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Newline neutrality with ifstream</title>
		<link>http://chaosengineer.com/?p=47</link>
		<comments>http://chaosengineer.com/?p=47#comments</comments>
		<pubDate>Thu, 25 Jun 2009 17:30:09 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[endline]]></category>
		<category><![CDATA[multiplatform]]></category>
		<category><![CDATA[newline]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=47</guid>
		<description><![CDATA[I recently got distracted and started porting my old game engine to use a new platform independent rendering interface I devised. I'm pretty psyched about the rendering system, it fully encapsulates a graphics sdk and all it's associated resources (vertex and index buffers, textures, etc). Deriving from the pure virtual renderer and resource base classes, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got distracted and started porting my old game engine to use a new platform independent rendering interface I devised. I'm pretty psyched about the rendering system, it fully encapsulates a graphics sdk and all it's associated resources (vertex and index buffers, textures, etc). Deriving from the pure virtual renderer and resource base classes, I can write a new renderer class that targets a specific platform/SDK, plug it in, and just have it work without modifying a single line of code.</p>
<p>Part of this old game engine was a resource management class that could load 3D Studio MAX ASCII exported scenes/objects. These files are .ASE files, which is a versatile and simple format that has a surprisingly wide usage by various game engines. ASE files can be used when building Doom3 and Quake3 / Quake4 levels, since the format boasts native support in ID and Loki software's <a href="http://en.wikipedia.org/wiki/GtkRadiant">GtkRadiant</a> design tool, so it is a generally accepted format for storing game content. The ASE format specification itself is quite versatile, and can contain material specifications, verticies, faces (vertex indexes), vertex colors, texture coordinates, and even animations with full interpolation parameters just to name a few. Being ASCII, it is rather easy to parse and modify.</p>
<p>In the ASE format, each <strong>line</strong> of the file serves a single purpose. It is either an opening or closing tag for a field, or an element in a field. It made sense then when I first wrote the import code to parse the file on a line-by-line basis using ifstream::getline(...). This worked great in Windows, and I had no issues with my implementation. Flash forward to now when I am rewriting this code to work in Linux, but using files created in Windows. I never thought the disparities of a 'newline' between platforms would ever cause such a problem.</p>
<p>The ifstream::getline function was specifically designed to get a single line from a file <strong>without</strong> including the newline or delimiting character(s). The newline character ('\n') is the delimiting character by default, as it serves its purpose most of the time. ifstream::getline(...) reads in all characters up to the delimiter, then extracts and discards the delimiter. The problem arises when considering the definition of a newline on different platforms.</p>
<p>In Windows, the newline for iostream operations is a carriage-return,line-feed combo. It is actually two characters with ASCII decimal values 13, 10 (0x0D, 0xOA in hex), often referred to as a CRLF combo. In Linux, a newline is simply a line-feed (dec 10, hex 0x0A). So when performing ifstream::getline(...) in Linux, what you are doing is reading a line up to the delimiter--newline by default--and if your file was created in Windows only the last half of the CRLF combo is discarded, while the first half is read in as the last character in your string variable. This makes any literal comparisons made against this string variable fail in Linux while working fine in Windows.</p>
<p>I thought for sure there was some elegant way to overcome this and attain platform independent file parsing without forcing a complete rewrite of the import code. This turned out to not be the case. The ifstream::getline function is handy, but by doing you the favor of automatically extracting and discarding the delimiter, it somewhat cripples it's versatility. My impetus was two fold. Obviously first I wanted to be able to read these ASE files with 0x0D,0x0A line delimiters into Linux without having the 0x0D on the end of my read lines. This would be simple enough, but I wanted also code that would work regardless of platform combinations. This meant reading Windows files in Linux, Linux files in Windows, Windows files in Windows and Linux files in Linux.</p>
<p>So this added a bit of complexity to the requirements. First off, it would be impossible to use ifstream::getline(...) because it would extract and discard different characters from the file stream depending on platform. When reading a Linux file in Windows, it would keep reading from the stream, looking for a CRLF combo, and would likely read the entire file without finding one. When reading a Windows file in Linux as I found out, it would read the line including 0x0D, then stop at and discard the 0x0A. If it didn't consider reading Linux files in Windows, the following implementation was elegant, and worked in all other situations:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">char</span> szLineBuff<span style="color: #FFFFFF;">&#91;</span><span style="color: #0064dd;">256</span><span style="color: #FFFFFF;">&#93;</span>;
ifstream fsIn<span style="color: #FFFFFF;">&#40;</span><span style="color: #666666;">&quot;test.ase&quot;</span>, ios::<span style="color: #00eeff;">in</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;
<span style="color: #e53434;">// Note that failbit would be set if this</span>
<span style="color: #e53434;">//failed to extract any chracters before</span>
<span style="color: #e53434;">//the delimiter, and the loop would end.</span>
<span style="color: #b92dc7;">while</span><span style="color: #FFFFFF;">&#40;</span>fsIn.<span style="color: #00eeff;">get</span><span style="color: #FFFFFF;">&#40;</span>szLineBuff, <span style="color: #0064dd;">128</span>, <span style="color: #666666;">'<span style="color: #666666; font-weight: bold;">\n</span>'</span><span style="color: #FFFFFF;">&#41;</span>.<span style="color: #00eeff;">good</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #FFFFFF;">&#41;</span><span style="color: #FFFFFF;">&#41;</span>
<span style="color: #FFFFFF;">&#123;</span>
	<span style="color: #e53434;">// This extracts 2 characters in</span>
	<span style="color: #e53434;">//windows, just 1 in Linux.</span>
	fsIn.<span style="color: #00eeff;">ignore</span><span style="color: #FFFFFF;">&#40;</span><span style="color: #0064dd;">2</span>,<span style="color: #666666;">'<span style="color: #666666; font-weight: bold;">\x</span>0A'</span><span style="color: #FFFFFF;">&#41;</span>;
	<span style="color: #e53434;">// Cleans Windows line in Linux</span>
	<span style="color: #b92dc7;">if</span><span style="color: #FFFFFF;">&#40;</span>szLineBuff<span style="color: #FFFFFF;">&#91;</span><span style="color: #93249e;">strlen</span><span style="color: #FFFFFF;">&#40;</span>szLineBuff<span style="color: #FFFFFF;">&#41;</span><span style="color: #0064dd;">-1</span><span style="color: #FFFFFF;">&#93;</span> == <span style="color: #666666;">'<span style="color: #666666; font-weight: bold;">\x</span>0D'</span><span style="color: #FFFFFF;">&#41;</span>
		szLineBuff<span style="color: #FFFFFF;">&#91;</span><span style="color: #93249e;">strlen</span><span style="color: #FFFFFF;">&#40;</span>szLineBuff<span style="color: #FFFFFF;">&#41;</span><span style="color: #0064dd;">-1</span><span style="color: #FFFFFF;">&#93;</span> = <span style="color: #666666;">'<span style="color: #666666; font-weight: bold;">\0</span>'</span>;
&nbsp;
	<span style="color: #e53434;">// Process szLineBuff...</span>
&nbsp;
<span style="color: #FFFFFF;">&#125;</span>
&nbsp;</pre>
<p>Now I recognize that opening the file in binary mode (ios::binary) would make the '\n' be interpreted as simply '\x0A' on both Windows and Linux. My problem with this is that the file <em>isn't</em> binary. I'm stubborn and think this ASCII text file should be read in text mode, and that there should be a simple way to interpret newlines from any platform on any other platform. There must be a simple and elegant solution out there somewhere...</p>
<p>I'll be honest and say I stopped there, as my code worked for 3/4 of the scenarios I laid out. I have yet to find a Linux native source of ASE files, so the last scenario (Linux files on Windows) hasn't become important for me yet. If anyone has a better solution for this, or knows one that would work in all scenarios while still being somewhat elegant, I'd love to hear about it. </p>
<p>Also, I know I promised a follow-up on the NDS WiFi programming. I only got a little distracted, the example applications are nearly finished. You'll definitely like it when it comes.</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=47</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NDS WiFi programming with devkitARM</title>
		<link>http://chaosengineer.com/?p=31</link>
		<comments>http://chaosengineer.com/?p=31#comments</comments>
		<pubDate>Sat, 06 Jun 2009 06:15:15 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[HID]]></category>
		<category><![CDATA[NintendoDS]]></category>
		<category><![CDATA[sensors]]></category>
		<category><![CDATA[sockets]]></category>
		<category><![CDATA[chaos]]></category>
		<category><![CDATA[devkitpro]]></category>
		<category><![CDATA[dswifi]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=31</guid>
		<description><![CDATA[I have a grand plan to make a beowulf cluster dedicated to computing, interfacing and manipulating chaotic systems. I have a protocol devised that would allow multiple applications running on an arbitrary number of computers in a network pool hardware resources for this task. Each application (node) would have it's own capabilities, and could be [...]]]></description>
			<content:encoded><![CDATA[<p>I have a grand plan to make a beowulf cluster dedicated to computing, interfacing and manipulating chaotic systems. I have a protocol devised that would allow multiple applications running on an arbitrary number of computers in a network pool hardware resources for this task. Each application (node) would have it's own capabilities, and could be used to collect sensory data, provide a human interface, or just to crunch numbers. I could easily have a management node that would maintain a list of other nodes and their abilities, and query them as needed. I recently had a great idea to use a NintendoDS as both an interface (via the touchscreen), and a sensory device (collecting audio samples with the buit-in microphone).</p>
<p>So I did a bunch of NDS programming a few years back using the <a href="http://www.devkitpro.org">devkitPro toolchain</a>, specifically devkitARM. They were at release r20 then, and dswifi had just made it on the scene. For those who don't know, dswifi is a library written by <a href="http://www.akkit.org">Stephen Stair</a> that allows NintendoDS homebrew developers using devkitARM to use the wifi features of the NDS. You can connect to wireless access points, and from there you have network access and a standard Berkley sockets interface, so you can pretty much accomplish anything you set your mind to. I just downloaded the latest version of devkitARM, which is now r26. I was quite pleased with the progress the toolchain had made during my absence, and especially pleased to see dswifi so well integrated. Things pretty much went downhill from there.</p>
<p><strong>NOTE: 09.06.16 - The rest of this post is for historical information only. After I isolated the bug in dswifi that was the root of my problems, I notified the maintainers of devkitPro who committed a fix. There are now new releases of libnds, dswifi and default arm 7 available that correctly handle the DS' MAC address. Please see the addendum at the end of this article for more information. Do not downgrade your devkitPro install if you are having problems. Instead get the very latest versions of all libraries, and you should be good.</p>
<p></strong></p>
<p>There were no examples provided with the nds-examples package that showed how to connect to WEP secured Access Point (AP). The only examples provided were for either using the WFC information stored in the NDS firmware, or for connecting to an unsecured AP. They did have code to enumerate APs and to provide a keyboard interface that I happily integrated. Prior to even testing the included examples I poured a couple hours into writing a code base using the most involved methods possible (swapping out all the simple 0 argument init functions with the 8 argument equivalents) to establish a console and collect and display a list of APs. Selecting an AP from this list that was secured would then provide a prompt to specify either 40-bit or 104-bit encryption. The user could then type in the 10 or 26 character string using a tiny little keyboard on the DS touchscreen. This string was then encoded to a byte array and passed to the Wifi_ConnectAP(...) function provided by dswifi.</p>
<div id="attachment_41" class="wp-caption aligncenter" style="width: 460px"><img class="size-full wp-image-41" title="dstelnet00_2" src="http://chaosengineer.com/wp-content/uploads/2009/06/dstelnet00_2.png" alt="Wifi AP list and a tiny keyboard" width="450" height="438" /><p class="wp-caption-text">Wifi AP list and a tiny keyboard</p></div>
<p>I then spent three times as long troubleshooting. It took a while for me to remember that I have MAC address filtering enabled on my router (*bonk self*). I loaded up a wifi enabled game, pulled the MAC address of my DS from Nintendo's WFC interface, and put it on my router's Access Control List. I rubbed my hands in greedy anticipation, and loaded up my homebrew app once again. No joy ensued. I still could not connect to my AP.</p>
<p>At this point, I decided to try something simple just to verify the functionality of dswifi (yes, I'm backasswards when it comes to programming), so I loaded up one of the basic dswifi examples. Strangely, it did not work either. I knew it wasn't my DS or router anymore, because I would connect with a proper DS game that was wifi enabled. I didn't see anyone else complaining in the devkitPro forums, but r26 was *just* released and the forums over there aren't exactly teeming with DS programmers. I thought maybe the devkitPro toolchain for x64 Linux might have been the culprit, so I tried in Windows XP as well. Still no joy.</p>
<p>Operating under the assumption that dswifi worked at SOME point in devkitPro, I decided it was time to start digging backwards through the releases, and testing the functionality as I went with the most simple example possible... one that loaded the AP information from the WFC info stored in the DS and automatically tried to connect. This simple example did indeed work back in devkitPro r25 (2009.02.20). I then increased my resolution to try and find *exactly* where dswifi broke in devkitPro.</p>
<p><strong>&lt;SNIP&gt;<br />
Several paragraphs removed at the request of the devkitPro maintainers.</strong><br />
This section basically highlighted my procedures to somewhat subvert the available devkitPro library distributions to create a tool chain that pre-dated issues with the DS MAC address handling. As noted above, the bug I isolated has been fixed in the latest devkitPro library distributions, so this information is no longer pertinent. I found out that in my setup, the simple WFC autoconnect example worked fine when built with dswifi 0.3.7, but refused to work in dswifi 0.3.8. So I configured a motley devkitPro toolchain with different versions of specific libraries in order to get dswifi working for me.<br />
<strong>&lt;/SNIP&gt;</strong></p>
<div id="attachment_36" class="wp-caption aligncenter" style="width: 460px"><img class="size-full wp-image-36" title="dstelnet01" src="http://chaosengineer.com/wp-content/uploads/2009/06/dstelnet01.png" alt="Telnetting into my NintendoDS Echo Server." width="450" height="359" /><p class="wp-caption-text">Telnetting into my NintendoDS Echo Server.</p></div>
<p>I now have code running on my DS that allows me to connect to my WEP secured AP, and from there get a socket connection to my workstation. Its pretty blasted awesome to be able to telnet into your DS and see what you type into your computer appear on the screen. Its several magnitudes more awesome to use the DS touchscreen and keys to remotely manipulate a 3D chaotic system in realtime. Add the ability to pipe recorded audio data from the DS microphone over the network and into that system where the fourier-tranformed signal is then used to modulate said system, and you might as well be dividing by zero.</p>
<p><strong>UPDATE 2009.06.07</strong>:</p>
<p>After butting heads with the maintainers of devkitPro on the forum (they deleted a few of my posts because they don't like people telling users to downgrade or linking to obsolete libraries -- support headaches) who said the examples worked fine in r26, I pulled the source code for dswifi 0.3.7 and 0.3.8 than ran diff against the versions, excluding the svn nonsense:</p>
<pre class="text">diff -urNp -x '*svn*'  dswifi-src-0.3.7 dswifi-src-0.3.8 &gt; dswifi.patch</pre>
<p>Thanks to diff and a little persistence reading through the patch file, I found exactly where my problem was originating.</p>
<p>Remember how I said I had MAC address filtering enabled on my router? Well recent changes to dswifi did indeed break the example, for me at least... the MAC address bytes were being read from the firmware but written to a main data structure incorrectly:</p>
<pre class="cpp">&nbsp;
<span style="color: #b92dc7;">for</span><span style="color: #FFFFFF;">&#40;</span>i=<span style="color: #0064dd;">0</span>;i&lt;<span style="color: #0064dd;">3</span>;i++<span style="color: #FFFFFF;">&#41;</span>
	WifiData-&gt;MacAddr<span style="color: #FFFFFF;">&#91;</span>i<span style="color: #FFFFFF;">&#93;</span>= ReadFlashByte<span style="color: #FFFFFF;">&#40;</span>0x36+i<span style="color: #FFFFFF;">&#41;</span> + <span style="color: #FFFFFF;">&#40;</span>ReadFlashByte<span style="color: #FFFFFF;">&#40;</span>0x36+i<span style="color: #0064dd;">+1</span><span style="color: #FFFFFF;">&#41;</span>&lt;&lt;<span style="color: #0064dd;">8</span><span style="color: #FFFFFF;">&#41;</span>;
&nbsp;</pre>
<p>This loop doesn't write the data to MacAddr as intended. After the loop, MacAddr is filled with the bytes from the following firmware addresses : 0x36, 0x37, 0x37, 0x38, 0x38, 0x39. The intention is obviously to write the bytes from 0x36, 0x37, 0x38, 0x39, 0x40, 0x41. Simple mistake, simple solution. I notified the maintainers, so when you download devkitPro r27, you can thank me when connecting to APs with MAC address filtering. =)</p>
<p><strong>ADDENDUM 2009.06.16</strong>:</p>
<p>A fix for the MAC address bug in dswifi was submitted to the devkitPro svn on June 11th. The maintainers built new distributions of three libraries the same day. So if you get the following versions of libnds, dswifi and default arm7, your DS' MAC will be properly presented to access points:</p>
<p>libnds 1.3.5<br />
dswifi 0.3.9<br />
default arm7 0.5.4</p>
<p>Way to go, devkitPro.</p>
<p>You can see the full discourse on the forums <a href="http://forums.devkitpro.org/viewtopic.php?f=23&t=1372&start=0">here.</a></p>
<p>With this issue now past tense, I'll work on posting a PART 2 of this article with some actually useful programming information.</p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=31</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A History of Hatred</title>
		<link>http://chaosengineer.com/?p=15</link>
		<comments>http://chaosengineer.com/?p=15#comments</comments>
		<pubDate>Thu, 21 May 2009 22:07:39 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[gaming]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=15</guid>
		<description><![CDATA[Over the past couple years I have completely migrated out of Microsoft Windows except for those circumstances where I am forced to use it (read: 'work'). I have thus been spending my time discovering the amazing power of Linux and of the opensource community. OpenGL has proved to be quite a good friend. I am [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past couple years I have completely migrated out of Microsoft Windows except for those circumstances where I am forced to use it (read: 'work'). I have thus been spending my time discovering the amazing power of Linux and of the opensource community. OpenGL has proved to be quite a good friend. I am constantly enheartened by it's prowess. VBOs, PBOs, FBOs... OpenGL is far from a substandard graphics API (as I used to believe) and can push polygons with the best of them. SDL has also been by my side, cutting a path through the uglier bits of interfacing with X11, providing clean input methods, and making my projects easily run on both Windows and Linux.</p>
<p>I used to be a Microsoft fan boy. I loved DirectX, and spent nearly every waking hour using it while crafting a game engine. I can remember working with Direct3D 6 and tearing my hair out trying to decide between immediate and retained mode. What an ugly API it was too, but I still used it over OpenGL because I had the feeling it was more powerful. DirectX 8 came out and all of a sudden everything was sleek and seemed to fit into place so well, and boy, was I ever excited over DirectX 9.</p>
<div id="attachment_16" class="wp-caption alignleft" style="width: 308px"><img class="size-full wp-image-16" title="tux" src="http://chaosengineer.com/wp-content/uploads/2009/05/tux.jpg" alt="Tux Plotting" width="298" height="288" /><p class="wp-caption-text">Tux Plotting</p></div>
<p>So what happened? At what point did I decide that Microsoft was evil and didn't deserve my time? The feeling culminated slowly. Microsoft pulled one stunt after another, betraying the trust consumers had placed in them. They were constantly using their market share and financial prowess to inhibit innovation and force the consumer's hand to benefit only themselves. It soon became apparent to me that they knew almost no bounds. They would commit horrible atrocities and get away with it because they are Microsoft.</p>
<p>I had been following the development of Bungee's Halo eagerly for some time. This was going to best PC game ever. One day, the Halo website just disappeared. Nobody knew what happened. Microsoft had recently announced they were entering the console market. It soon became obvious what was going on. Halo was to be a launch title for Microsoft's Xbox. They had acquired Bungee. I held my breath and patiently waited for the PC release of Halo. Bungee wouldn't turn it's back on the PC market, would they?</p>
<p>When it finally came, the PC port of Halo was substandard. I played the demo and never got the full version, maybe because Blood Gulch was enough for me, or maybe it was the flaws I saw. The networking code was seemingly never designed to operate with the high latencies found on the WAN. It was possible to accomplish... Unreal Tournament's cubic interpolation allowed the server to accurately render players and detect hits based on their projected locations. When playing the PC port of Halo, I found myself having to perform this interpolation myself, aiming ahead of players a certain distance based on the amount of latency I had with the server. Don't get me wrong, I got damn good at this and could still drop mofos from the far side of Blood Gulch with a pistol while both at full tilt, but I still felt betrayed and forgotten by Bungee with their new guiding hand. And man, oh man, when Halo 2 was released on the PC under Microsoft's new "Games for Windows" (AKA: Games that _only_ run on MS's craptacular new Vista OS) platform, there aren't words to describe how furious I was. Bungee's output was again used to push Microsoft's own agenda, this time trying to wrangle people into buying the new Vista OS, which was almost universally hated. Halo and Bungee aside, there are plenty of other reasons to despise Microsoft...</p>
<p>I had always been a tables layout HTML kind of guy. Who wasn't? When CSS starting making its way into the mainstream and new standards for positioning web page elements were devised, I resisted change for quite some time. Tables were so handy. I didn't need these new fancy DIVs and all this new positioning mojumbo. I could do all that with nested tables using colspan, rowspan, and the ever-useful CENTER tag. Needless to say, the CSS revolution didn't move me. I was still happily making webpages without a single style attribute. I tell you this just so you know I'm not a standards whore who expounds upon and proudly touts every little tidbit thrown out by the W3C.</p>
<p>One day while meandering about on the interwebs and mourning the fact VRML never caught on, I stumbled across a new standard that made me salivate. Scalable Vector Graphics had become a web standard. The W3 Consortium said so! This was blasted glorious! It was only a matter of time before webpages based on SVG would become standard, and we could present content on interactive SMIL animated geometry! SVG had presented epic new parameters to the web.</p>
<p>I quickly downloaded Opera with it's high level of SVG and SMIL compliance, and set to work creating an exemplary SVG based webpage. Previous experience with geometry and transformation pipelines from game engine design lent itself well here. I learned all sorts of new things with Javascript, stuff I had never before even thought of doing. I was dynamically modifying SVG transform attributes, adding and removing JS event handlers, and generally having a ball. I made a tasty little SVG "module" that would allow you to specify an array of images and it would create a task bar much akin to the Mac OS X dock. As your mouse cursor approached one of the "tasks" the image associated with it would grow larger( transform="scale(4.3*glory, 5.2*splendor)" ), nudging it's neighboring task icons to either side. You could even grab the dock itself and drag it to some other location on the screen without changing it's functionality. Obviously the possibilities for content interaction and presentation were limitless. Web design had never been so fun or rewarding.</p>
<p>So after the initial reveling was over, it was time to realize the benefits of the SVG standard, and deploy some content. Internet Explorer 7 was about to be released, I thought for sure it would come with some support for SVG, considering Firefox was already providing some support, and Opera was rocking near full compliance. Well, IE 7 came out without a lick of SVG support. Surely they would wise up, get with the program and provide support in a service pack? Wrong. Hell, IE 8 *just* came out and Microsoft is still pretending like SVG doesn't exist. Not even a hint of support for SVG. Why you ask? Why would Microsoft totally ignore such a great standard that offers so much promise for the web? Two words. Silver. Light. Yes, Silverlight and XAML. Microsoft basically rips off the SVG standard to define XAML, then turns it's back and pretends like SVG doesn't exist, again in order to promote it's own agenda. For some reason as I write this, I am reminded of Death of a Salesman: "You cannot eat the orange and throw the peel away. A web standard is not a piece of fruit!". Microsoft ate the fruit of W3C's labors, threw the rind away, and walked off.</p>
<p>This transgression by Microsoft is magnitudes more serious than the Bungee / Halo fiasco. This makes that seem completely insignificant. This is Microsoft using it's market share to try and KILL a standard. With the majority of end users using Microsoft's browser, they can pretend that SVG doesn't exist, and thus make the majority of the world not realize it exists. No one will push forward with SVG, because the world's most popular browser... Microsoft Internet Explorer stubbornly refuses to support it. The world is being denied an open web standard that can provide interactive and dynamic content on level with Adobe's Flash, but is natively supported in browsers. Can you imagine the community driven image gallery projects like Gallery, CopperMine and 4Images but based on SVG that would exist if Microsoft had supported SVG six years ago when they should have? I don't think you can. Hell, I'll make a prototype just to hint at what you are missing (as long as you aren't using IE).</p>
<p>At first it was denial... I continued to search the web for news that Microsoft wasn't being that obstinate, and actually had plans to support SVG in IE at some point. I hunted through the forums waiting for some Microsoft engineer to say in a forum somewhere that yes, of course SVG support was on the IE development roadmap. Time dragged on, and eventually I couldn't deny the facts anymore... Microsoft was doing this... HOW COULD THEY?!? AAARRGGHHH!!! The anger was the worst because I had little outlet for it. My friends didn't seem to understand the fury that drove my diatribes about how evil Microsoft was. I hoped that maybe... maybe if they didn't feel threatened by SVG they would relent and offer support for it. I cried a little. Tears fell from my ocular devices, shed for all the potential glory of SVG that would never be realized. I became sullen and discarded web development for years. My webpage lied in repose. It was during this time of depression that I rediscovered Linux.</p>
<div id="attachment_21" class="wp-caption alignright" style="width: 266px"><img class="size-full wp-image-21" title="05-11-07_2059_sm" src="http://chaosengineer.com/wp-content/uploads/2009/05/05-11-07_2059_sm.jpg" alt="Frankenstein Milkcrate Machine" width="256" height="341" /><p class="wp-caption-text">Frankenstein Milkcrate Machine</p></div>
<p>I had used Linux before, but never considered it's real potential. I always used it when telnetting to shells, and back in 1996 I built a Frankenstein computer assembled from the corpses of other machines. I installed RedHat Linux (v2 I think) and used it to make a CGI application for the ISP I worked for. It was pretty neat, and I liked the feeling of being totally lost in a new operating system, but at that time I still had much to learn about windows, and only considered Linux as a second-rate OS. Back on the real timeline, I got myself a copy of Gentoo and again installed it in a Frankenstein computer, this time one that was assembled in a milk crate (real classy, eh?). For some reason this time around, my feelings for Linux were much different.</p>
<p>This change in feeling can be likely attributed to two things. One, I felt I had pretty much learned everything that wasn't hyper esoteric about Windows. I knew XP inside and out, I knew Windows server, all about Active Directory, Group Policy Objects, terminal services, etc. I had also used a crap ton of C/C++ Microsoft APIs most people had never heard of like the TS API and the GP API. Two, I had started to hate Microsoft and finding out that from within Linux I could emulate the fast majority of Windows applications uisng WINE and even emulate DOS using DOSBox gave me a great feeling of control and satisfaction. Furthermore, Linux was aimed at people like me.</p>
<p>People who wanted the freedom to customize EVERYTHING if they wanted. People who wanted the source code for all the applications they use just in case they wanted to modify how they operated slightly. People who wanted to work using formats that were standardized and open. People who didn't like being told how to use their computers. People who saw new computer technology and standards not as either a threat or a chance to capitalize, but as a road to innovation where they could potentially improve the quality of digital life for computer users. It is these people who embrace Linux and opensource, and feel oppressed when working with Microsoft Windows.</p>
<p>After this recent excursion into Linux, I approached the operating system as a replacement for Windows, not just a diversion from. This meant I needed to be able to do everything I typically did within Windows without inconvenience. After years of using nothing but Gentoo, Debian and of course Ubuntu, I can honestly say that I have found absolutely nothing I cannot accomplish in Linux with similar or improved efficiency, except perhaps playing TES: Oblivion.</p>
<p>I can take the lack of support for new PC games. Oblivion was a time vortex anyway... I stopped playing it on Windows before I really got into it. I knew otherwise I would sink countless hours into the void. It seemed a game that you could continue playing forever. My father actually proved this wrong though... he played Oblivion into the ground. He only stopped after he got 100% chameleon so nobody could see or hurt him. At that point he resorted to just hanging out on the front porch of his house in Anvil watching the people go by. Apparently this lost its appeal pretty soon.</p>
<p>Back to the point though, I try not to spend too much time playing games anymore. I started playing text MUDs back in like 1996. I hardly ever left the house anymore. My friends were pissed because I wouldn't join in the D&amp;D campaigns we constantly ran. My parents were pissed because the phone line was CONSTANTLY in use and nobody could call without getting a busy signal. I was only pissed when Creeping Death, Age of Legends or Carrion Fields went down. Diku/Merc/ROM was the stuff dreams were made of. I would often have dreams about being on the text mud. My dreams actually consisted of text on a screen. It was absurd.</p>
<p>When the first graphical MUDs started appearing, I was ALL over that. I was playing the first real graphical MUD, Meridian59 back when it was only the town of Tos. A single large room. I beta tested and played the hell out of pretty much every significant (and some insignificant) MMORPG that came out. Beta tested for Meridian59, Ultima Online, Asheron's Call, Star Wars Galaxies, and finally Ever Quest. For some reason after Ever Quest, I abandoned MMORPGs. I haven't touched one since the EQ beta. I just decided to not sink my time into games like I used to. MMORPGs were becoming the ultimate distraction... to the point of absurdity. People were living richer lives in virtual worlds than they granted themselves IRL. I digress. Perhaps I'll pontificate about it at a later time.</p>
<p>For all my haughty talk, I still like a good distraction once in a while just as much as the next guy. Fortunately there are a scad of options for digital entertainment in Linux. Many of the best games for Linux are found under emulators. I play PSone games using ePSXe, n64 games using Mupen64Plus, SNES games with zSNES, GBA games with VisualBoy Advance, DOS games with DOSBox, and Windows games with WINE. There are plenty of options for gaming input devices in Linux. Any device that is HID compliant will likely run without problems. There are devices that will let you plug PS/PS2, NES, SNES, and n64 controllers right into your computer and use them with your emulators. There aren't any good n64 adapters on the market since the Adaptoid went out of production, but I'm planning to take the time to make a microcontroller circuit for connecting them. Maybe I'll share.</p>
<p>With no shortage of solutions for the biggest complaint about Linux (no games), I don't have any immediate shortcomings I can describe. Maybe its my rose-colored glasses. Maybe its the huge array of upsides clouding my judgement.</p>
<div id="attachment_25" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-25" title="screenshot" src="http://chaosengineer.com/wp-content/uploads/2009/05/screenshot-300x187.png" alt="Tasty Desktop" width="300" height="187" /><p class="wp-caption-text">Tasty Desktop</p></div>
<p>Linux can be crafted to be as flashy or as spartan as the user likes. You can choose between a number of window managers (Gnome, KDE, XFCE, Enlightenment). You can have screen widgets. You can customize every single icon. You can install custom docking managers like Avant Window Navigator or Kiba Dock. You can go all out and install Compiz (previously Beryl) to give yourself wobbly, burning, alpha blended, motion blurred, dynamically zooming windows that exist across 4 desktops on the surface of a transparent 3D cube that you can rotate under a custom sky dome. There is no question that the Linux desktop environment is far superior in scope, functionality and configurability when compared to Windows.<br />
<div id="attachment_60" class="wp-caption aligncenter" style="width: 460px"><img src="http://chaosengineer.com/wp-content/uploads/2009/05/screenshot-stubart.png" alt="Oldschool Tasty Desktop" title="screenshot-oldschool" width="450" height="338" class="size-full wp-image-60" /><p class="wp-caption-text">Oldschool Tasty Desktop</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=15</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chaotic Background</title>
		<link>http://chaosengineer.com/?p=9</link>
		<comments>http://chaosengineer.com/?p=9#comments</comments>
		<pubDate>Thu, 21 May 2009 21:02:11 +0000</pubDate>
		<dc:creator>Chaos Engineer</dc:creator>
				<category><![CDATA[fractals]]></category>
		<category><![CDATA[strange attractors]]></category>
		<category><![CDATA[chaos]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://chaosengineer.com/?p=9</guid>
		<description><![CDATA[I started my foray into chaos over four years ago now, at the end of 2004. I stumbled across a book by Clifford Pickover and Elahe Khorasani in the local library. It was about chaos, fractals and computer graphics.At the time I was working on a game engine in Direct3D, so I quickly created a [...]]]></description>
			<content:encoded><![CDATA[<p>I started my foray into chaos over four years ago now, at the end of 2004. I stumbled across a book by <a href="http://sprott.physics.wisc.edu/pickover/home.htm">Clifford Pickover</a> and Elahe Khorasani in the local library. It was about chaos, fractals and computer graphics. <div id="attachment_5" class="wp-caption alignright" style="width: 310px"><img src="http://chaosengineer.com/wp-content/uploads/2009/05/first-300x300.png" alt="First Julia" title="first" width="300" height="300" class="size-medium wp-image-5" /><p class="wp-caption-text">First Julia</p></div> At the time I was working on a game engine in Direct3D, so I quickly created a templated complex number library and set to work visualising some systems. Nothing worked at first, I was just getting pure black images as a result. Then... I thought I saw something. I increased the contrast of an image, and sure enough there was *something* hiding there in the darkness. I tweaked and adjusted my code some more. Finally, this Julia set materialised out of the void.</p>
<p>It may look meager, and by all counts really *is*, but at the time when those chaotic curls first appeared on my screen as a result of a some complex math, I was floored. I carefully adjusted the boundaries and sampling frequency of the system, and effectively zoomed in. <div id="attachment_6" class="wp-caption alignleft" style="width: 310px"><img src="http://chaosengineer.com/wp-content/uploads/2009/05/first_zoom-300x300.png" alt="First Julia Zoom" title="first_zoom" width="300" height="300" class="size-medium wp-image-6" /><p class="wp-caption-text">First Julia Zoom</p></div> The tiny crevices in the curls opened up and spewed forth more detail. Where would it end? I spent hours rewriting this recursive routine and recompiling in order to change parameters of this Julia set rendering, and soon realised that I needed a better way to interface with these complex systems.</p>
<p>I adapted my rendering engine and created a Fractal Playground, where I could explore and play in the infinite number of fractal landscapes out there. I was limited only by the speed of my processor and the precision of 64-bit floating point maths. To me, exploring these fractal landscapes was as exciting as going on vacation to some new place. Rewriting the governing equation, defining new complex math operations, adding and modifying terms... it was like a grab bag of free vacations. I never knew where I would end up next. Some of these places were drab and repetitive, while others astounded me as soon as I stepped off the tarmac. The ones that I really remember are the ones that were drab on the outside, but with a little digging revealed themselves as fractal geodes... containing an unrivalled inner beauty encased within a plain shroud. <div id="attachment_10" class="wp-caption alignright" style="width: 310px"><img src="http://chaosengineer.com/wp-content/uploads/2009/05/buried_treasure-300x240.png" alt="Buried Treasure" title="buried_treasure" width="300" height="240" class="size-medium wp-image-10" /><p class="wp-caption-text">Buried Treasure</p></div>This image which is aptly named 'Buried Treasure' I found about 10E30 deep into a fractal landscape that seemed totally composed of white noise. I followed just a hint of a crevice in the noise down to this treasure. There were no real discernible features until this image appeared. Quite beautiful as well... it looks like the fancy sort of wood carving you would see on antique furniture.</p>
<p>I moved on from the typical convergence digrams where the color of a sample was defined by the number of iterations required to push it's magnitude past a threshold value. It was possible as well to track the actual orbit of a sample in complex space as you iterated it. Instead of just looking at the magnitude of a sample as it was iterated, I started plotting the values on the complex plane. <div id="attachment_11" class="wp-caption alignleft" style="width: 310px"><img src="http://chaosengineer.com/wp-content/uploads/2009/05/encapsulating_sine-300x240.jpg" alt="Encapsulating Sine" title="encapsulating_sine" width="300" height="240" class="size-medium wp-image-11" /><p class="wp-caption-text">Encapsulating Sine</p></div> I referred to these as vector diagrams. The first time I plotted the orbits, as with many things, it didn't seem to work or make sense. There was far too much going on to understand the nuances. I needed a reference, and to start with a limited set of points. I first drew a convergence map, and then plotted the orbit of each sample on every 16th row or something. The results were intriguing. I soon found that plotting orbits in an aesthetically pleasing and efficient manner was quite difficult. Many wild and very strange images resulted from my experiments with this temperamental routine.</p>
<p>There was much more to be done however. This playground was fine for exploring, and giving brief reports on these landscapes, but it vastly lacked "production" features. The images I saved were limited in size to my screen resolution. The playground had a fullscreen mode, and I resorted to using the windows PrntScrn functionality to copy the full screen images to the clipboard and saving them off that way. I knew it was possible to create fractal images of arbitrary resolution... sometimes I hard coded a routine to dump a huge image of a system. It was a clunky way of accomplishing things, and many times while exploring I wished for the ability to do this dynamically. I also needed a better way to interface with the complex systems. Bringing up a dialog box and tabbing through controls, or even clicking on menu items was an annoyance while exploring. Fullscreen mode and modifying parameters (besides the zoom and pan) were mutually exclusive.</p>
<p>I was a bit daunted at first at the notion of entirely reworking the playground. My main code module (the one that contained the Windows entry point) had like a hundred global variables and was just under ten thousand lines long. In my state of fractal fervor, every new feature on the playground, every little test and modification was implemented as a kludge. I only cared about immediate results, and had cast maintainability to the wind. I built an empire out of bubblegum and bailing twine.</p>
<p>I rewrote the core routines, and this time built them out of brick instead of sticks and mud. I encapsulated everything, and made the multitude of non-exclusive boolean options for the system into a bitfield. There was now a single "state" variable where each individual bit represented a switch I could flip for a given option. One of the biggest and most effective changes was implementing a physically-based camera that existed in complex space. Physically-based, meaning the camera had momentum and friction, and moving it was all based on applying forces. When zooming/panning the weight of the camera would carry it for a bit even after releasing the controls. Note that this pre-dated the weighted interface of the iPhone by quite some time, and this idea was purely my own.</p>
<p>Now with the interface exclusive from the OS, I had a platform for fractal exploration that I never needed to bring out of fullscreen mode. With input and update routines built much like a game engine, I could define esoteric keypresses to my heart's desire, and the only change would be in the class's UpdateInput method. As I thought of new options, I defined a new bit in the bitfield and added accessors. It was simple to add routines for dumping the current scene to a huge detailed image, or saving each frame to make videos from. Now THIS was the kind of vehicle I needed for traversing the world of complex geometry.</p>
<p>Around this time I was an active member of the electronica scene in my area. I talked with some of the people setting up shows and got myself an invite to be a VJ for an upcoming event. I secured myself a projector and hauled my behemoth number cruncher (thanks, Stu!) to the venue. I had myself a little electroluminescent keyboard that worked perfect for manipulating the system in the darkness of the drum & bass arena. People were definitely impressed. One dude recognized the Mandelbrot set and was amazed to see it in such a dynamic light. That was probably the biggest compliment of the night. Everyone thought the convolving text routine where I feed text into a vector diagram and let the system swirl it around was mighty badass. All in all, it was quite a success.</p>
<p>Bolstered by the positive feedback from my first VJ gig, I was determined to expand the capabilities of this new application. Around this time I started experimenting with strange attractors. I used vector vector maps in the original fractal playground to build a "hit map" where computed locations of sample orbits were added to two-dimensional array that far exceeded the depth of a typical image. After subsampling the complex field and running thousands of iterations, I ran some statistical routines to get an idea of the spread of this data. I managed to clamp this data into a range acceptable by images, and interpolated the data into this clamped region to get some visual output. The results reminded me of images of strange attractors I had seen before. I didn't really know what a strange attractor was, but I figured they must be scads easier to work with than these complex vector diagrams.</p>
<p>I created a new application (again using parts from my game engine) for visualizing and manipulating strange attractors. These strange attractors proved to be quite varied and appealing. I especially enjoyed the way they moved when modulating the parameters over time. I produced hundreds of high resolution images and a few videos of these systems, all which were received well. I needed to get this new form of chaos integrated into my VJ software so I could switch between the systems on the fly. It was around this time that I migrated out of Windows and into linux, so this application would be the first to be resurrected in OpenGL.<br />
<div id="attachment_12" class="wp-caption aligncenter" style="width: 310px"><img src="http://chaosengineer.com/wp-content/uploads/2009/05/20060918011120-300x225.jpg" alt="Iconic Engineered Attractor" title="20060918011120" width="300" height="225" class="size-medium wp-image-12" /><p class="wp-caption-text">Iconic Engineered Attractor</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://chaosengineer.com/?feed=rss2&amp;p=9</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
