<?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>Cale Dunlap &#187; Development Journal</title>
	<atom:link href="http://www.caledunlap.com/category/development-journal/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.caledunlap.com</link>
	<description>Programmer and hobbyist game developer</description>
	<lastBuildDate>Fri, 20 Aug 2010 08:13:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Its been a while</title>
		<link>http://www.caledunlap.com/2010/08/its-been-a-while/</link>
		<comments>http://www.caledunlap.com/2010/08/its-been-a-while/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 08:13:23 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[gesture recognition]]></category>
		<category><![CDATA[mocap]]></category>
		<category><![CDATA[quaternion]]></category>
		<category><![CDATA[simulator]]></category>

		<guid isPermaLink="false">http://www.caledunlap.com/?p=596</guid>
		<description><![CDATA[Other than the title of]]></description>
			<content:encoded><![CDATA[<p>Other than the title of a crappy Staind song&#8230; it has been a while indeed. My WP install has been pretty horked for the last few months so I haven&#8217;t bothered updating. I&#8217;ll take this opportunity (now that I&#8217;ve reinstalled WP completely and restored from backup) to fill anybody reading in on what I&#8217;ve been doing over the last ~6 months.</p>
<p>To sum it up&#8230; I have been working my rocks off. Incase you haven&#8217;t read my LinkedIn profile, I&#8217;m working as a serious game software developer at a research company that primarily focuses on US Army dismounted infantry simulators. We have a demo coming up in September so we&#8217;re all pretty strapped for time while trying to make this demo as clean and bug-free as possible.</p>
<p>One of the more interesting aspects of my work lately has been using motion capture equipment to retrieve realtime data about the anatomical positions of bones and joins throughout the body in order to get a computer (NPC, non-player character) to recognize what the user is actually doing with their body. In essence this is gesture recognition. Much like speech recognition, it is the process of looking for patterns inside of a set of input data. This input data however is not a sound-wave. It is a huge sequence of 3D vectors and Quaternions (for the bone positions and orientations) and a long sequence of values between 0 and 1 for the fingers.</p>
<p>The finger data is captured using a glove that has potentiometers (variable resistors for the layperson) that react to the closing and opening of each finger along with the abduction between each digit on the hand (thats the webbing between your fingers). The rest of the body is measured using accelerometers, g-force sensors, and compasses placed in key locations on the human body. As the body moves it creates various changes in this data which is translated into 3-dimensional vectors for position and 4-dimensional vectors (Quaternions) for orientation.</p>
<p>This data is then sent through a processor (the software I&#8217;m working on) which looks for patterns in the data and attempts to match these patterns with pre-recorded &#8220;template&#8221; gestures. The match with the highest confidence level wins out and ultimately becomes what is deemed recognized by the NPC.</p>
<p>This recognition is then tied to key events in the training software such as directing your squad of NPCs to clear a building, freeze, follow (in various formations), or commence firing among many others. The other purpose for recognizing when a gesture has been made by the user is for locomotion through the virtual world. This means the user of the system can walk around in the virtual world, fully immersed in the equipment, and not move outside of a 6ftx6ft square on the floor. Its pretty remarkable what we&#8217;ve been able to accomplish with this.</p>
<p>It still has some distance to go before it is production ready, but these early tests look very promising. It has been quite a task to figure out this problem. In the process we have all learned how complex the human body really is and what we as humans take for granted in terms of how we move and act. The human body and brain is a very remarkable feat of biological engineering.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2010/08/its-been-a-while/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A few handy Javascript Methods</title>
		<link>http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/</link>
		<comments>http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 17:30:24 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://caledunlap.com/2009/11/a-few-handy-javascript-methods/</guid>
		<description><![CDATA[So I’ve been doing a]]></description>
			<content:encoded><![CDATA[<p>So I’ve been doing a LOT of Javascript programming in the last few days and I ran into a few limitations of the language or constructs within the language. For example, certain versions of IE do not support the Array.indexOf() method. Another problem I ran into is that the Javascript language does not contain a method for performing deep copies on objects. So after some Googling I found a few ways around the aforementioned problems. The first one (indexOf) is as follows:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:26771b21-04fc-42a4-8226-2a6c06ce403e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap">Array.prototype.findObject = (<br /> &#160;&#160;&#160;&#160;!Array.indexOf ? <span style="color:#0000ff">function</span> (o) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">var</span> l = <span style="color:#0000ff">this</span>.length + 1;<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">while</span> (l&#8211;) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>[l - 1] === o) <span style="color:#0000ff">return</span> l &#8211; 1;<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> -1;<br /> &#160;&#160;&#160;&#160;} : <span style="color:#0000ff">function</span> (o) { <span style="color:#0000ff">return</span> (<span style="color:#0000ff">this</span>.indexOf(o) !== -1); }<br /> );</div>
</p></div>
</p></div>
<p>The above code will add the ‘findObject’ method to your Array objects. Then you can use that instead of indexOf() and be guaranteed that it will work regardless if the browser supports indexOf or not.</p>
<p>The second one (deep copying) can be circumvented by creating a helper method which will perform the copy for you: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5f811a2f-8dd1-4896-a377-da22dd65ef42" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">var</span> ObjectHandler = {<br /> &#160;&#160;&#160;&#160;<span style="color:#006400">//public method</span><br /> &#160;&#160;&#160;&#160;getCloneOfObject: <span style="color:#0000ff">function</span>(oldObject) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">var</span> tempClone = {};</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (<span style="color:#0000ff">typeof</span>(oldObject) == <span style="color:#800000">&quot;object&quot;</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">for</span> (prop <span style="color:#0000ff">in</span> oldObject)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#006400">// for array use private method getCloneOfArray</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> ((<span style="color:#0000ff">typeof</span>(oldObject[prop]) == <span style="color:#800000">&quot;object&quot;</span>) &amp;&amp;<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(oldObject[prop]).__isArray)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone[prop] = <span style="color:#0000ff">this</span>.getCloneOfArray(oldObject[prop]);<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#006400">// for object make recursive call to getCloneOfObject</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">else</span> <span style="color:#0000ff">if</span> (<span style="color:#0000ff">typeof</span>(oldObject[prop]) == <span style="color:#800000">&quot;object&quot;</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone[prop] = <span style="color:#0000ff">this</span>.getCloneOfObject(oldObject[prop]);<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#006400">// normal (non-object type) members</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone[prop] = oldObject[prop];</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> tempClone;<br /> &#160;&#160;&#160;&#160;},</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#006400">//private method (to copy array of objects) &#8211; getCloneOfObject will use this internally</span><br /> &#160;&#160;&#160;&#160;getCloneOfArray: <span style="color:#0000ff">function</span>(oldArray) {<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">var</span> tempClone = [];</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">for</span> (<span style="color:#0000ff">var</span> arrIndex = 0; arrIndex &lt;= oldArray.length; arrIndex++)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">if</span> (<span style="color:#0000ff">typeof</span>(oldArray[arrIndex]) == <span style="color:#800000">&quot;object&quot;</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone.push(<span style="color:#0000ff">this</span>.getCloneOfObject(oldArray[arrIndex]));<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;tempClone.push(oldArray[arrIndex]);</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff">return</span> tempClone;<br /> &#160;&#160;&#160;&#160;}<br /> };</div>
</p></div>
</p></div>
</p>
</p>
<p>Just thought I’d share those with everyone. Credit for the majority of the deep copy code goes to <a href="http://blog.pramatiservices.com/deep-copy-in-javascript/">http://blog.pramatiservices.com/deep-copy-in-javascript/</a> and credit for the findObject code goes to someone other than me, but I didn’t bookmark the link so I can’t find it again. Sorry <img src='http://www.caledunlap.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/11/a-few-handy-javascript-methods/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FIX: When you undock some windows or change the window layout in the Visual Studio 2008 Service Pack 1 IDE, the IDE crashes</title>
		<link>http://www.caledunlap.com/2009/10/fix-when-you-undock-some-windows-or-change-the-window-layout-in-the-visual-studio-2008-service-pack-1-ide-the-ide-crashes/</link>
		<comments>http://www.caledunlap.com/2009/10/fix-when-you-undock-some-windows-or-change-the-window-layout-in-the-visual-studio-2008-service-pack-1-ide-the-ide-crashes/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 22:16:11 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>

		<guid isPermaLink="false">http://caledunlap.com/?p=545</guid>
		<description><![CDATA[FIX: When you undock some]]></description>
			<content:encoded><![CDATA[<p><a href="http://support.microsoft.com/kb/960075">FIX: When you undock some windows or change the window layout in the Visual Studio 2008 Service Pack 1 IDE, the IDE crashes</a>.</p>
<p>I just thought I re-post this incase anybody stumbled upon my blog before they landed on the Microsoft page that had the fix for IDE crashes. I experienced this only one time when I was moving/undocking windows.</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/10/fix-when-you-undock-some-windows-or-change-the-window-layout-in-the-visual-studio-2008-service-pack-1-ide-the-ide-crashes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Templatize Tool</title>
		<link>http://www.caledunlap.com/2009/07/templatize-tool/</link>
		<comments>http://www.caledunlap.com/2009/07/templatize-tool/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 06:52:31 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[templatizer]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=345</guid>
		<description><![CDATA[I recently wrote up a]]></description>
			<content:encoded><![CDATA[<p>I recently wrote up a template engine tool called Templatize. It started as a tool for my girlfriend so she could quickly generate HTML pages from CSV rows for use on eBay, but then quickly grew into a more robust template tool.</p>
<p>Basically it takes a set of input data, containing multiple entities (rows), each with multiple properties (columns), formatted from some type of delimited text file. Then it takes in a master template file and spits out multiple &#8220;data-injected&#8221; versions of that template.</p>
<p>View the full page <a href="http://caledunlap.com/blog/c/templatize/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/07/templatize-tool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CTask-Lite on GitHub</title>
		<link>http://www.caledunlap.com/2009/07/ctask-lite-on-github/</link>
		<comments>http://www.caledunlap.com/2009/07/ctask-lite-on-github/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 23:49:07 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[ctask]]></category>
		<category><![CDATA[ctask-lite]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=295</guid>
		<description><![CDATA[Alright, I&#8217;ve finally put my]]></description>
			<content:encoded><![CDATA[<p>Alright, I&#8217;ve finally put my open-source project website woes to rest. I successfully published the first version of CTask-Lite out on GitHub. It can be found here: <a href="http://github.com/cdunlap/ctask-lite">http://github.com/cdunlap/ctask-lite</a></p>
<p>CTask-Lite is an easy to install, configure, theme, and use task management system. It is aimed at tiny teams working on &#8216;open&#8217; projects. What I mean by open is that they don&#8217;t care who sees what (because there is no user/role management capability in it).</p>
<p>The Wiki for CTask-Lite is here:  <a style="text-decoration: none;" href="http://wiki.github.com/cdunlap/ctask-lite">http://wiki.github.com/cdunlap/ctask-lite</a></p>
<p>Spread the word! Download it, use it, mangle it, hack it, fork it, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/07/ctask-lite-on-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why is open source project hosting annoying and not playing nice with me?</title>
		<link>http://www.caledunlap.com/2009/07/why-is-open-source-project-hosting-annoying-and-not-playing-nice-with-me/</link>
		<comments>http://www.caledunlap.com/2009/07/why-is-open-source-project-hosting-annoying-and-not-playing-nice-with-me/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 04:00:14 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[Rants]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=292</guid>
		<description><![CDATA[I wrote a neat little]]></description>
			<content:encoded><![CDATA[<p>I wrote a neat little web-based task system in PHP, jQuery, and SQLite last night and wanted a place to put it so I could give it to the world (and maintain my source code).</p>
<p>I checked out Google code, where I have placed several projects of mine. I successfully created a project, but when I&#8217;d try to check in the code, the SVN server wasn&#8217;t available. At the same time, I&#8217;d try to click the &#8220;Source&#8221; tab on the project that I just created and I&#8217;d get an HTTP 500 from Google (which is incredibly rare). So I marked that project for deletion from Google Code.</p>
<p>Then I went over to Source Forge. Source Forge is having issues. I couldn&#8217;t get their site to load at the time that I tried, again, HTTP 500 errors. Though I did get an email from them a few days ago saying they were going to be pushing a new UI to their site soon. The email said the service interruptions were only going to be for a few minutes at the most. Lets just say it was more than a few minutes, so I scrapped that idea.</p>
<p>Then I remembered a guy at work recommended GitHub. I&#8217;m really new to Git and so far I don&#8217;t like it. I find it more difficult to use than SVN&#8211;though it is faster by far. So I get the code put up on GitHub just fine, but now I can&#8217;t edit the repository details in the admin area. Every time I try to change the project website or description it responds with &#8220;Name is already taken&#8221;. Ok, minor annoyance. Ignoring that, I went over to the downloads area to upload my ZIP containing the final v1.0 build of the project. It gets 100% done and then I get a HTTP 500 from GitHub. I try to go back to the project page but now I&#8217;m getting a HTTP 500 error anytime I try to do anything with my project. Not all of GitHub&#8230; <strong>my</strong> project page. I seem to be the only one affected by this.</p>
<p>So, I&#8217;m a bit frustrated at the moment. I guess I&#8217;ll start working on one of my closed-source projects and call it a night.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/07/why-is-open-source-project-hosting-annoying-and-not-playing-nice-with-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>1 little 2 little 3 little endians&#8230; er wait, is it 3 little 2 little 1 little endians?</title>
		<link>http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/</link>
		<comments>http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 17:50:42 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[confusion]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=286</guid>
		<description><![CDATA[Well, it depends on what]]></description>
			<content:encoded><![CDATA[<p>Well, it depends on what encoding you&#8217;re using.</p>
<p>Lately I&#8217;ve been in &#8220;endian-ness&#8221; hell on a project I&#8217;m working on. Well, not really a &#8220;hell&#8221;, more of a hurdle that can easily be overcome. A friend of mine recently asked me the difference between the two binary encoding strategies and when I went to explain it to him (via cell phone txt messaging) I quickly realized that I will run up both our bills pretty quickly by doing so. So here&#8217;s the quick rundown, and an example as it applies to the project I am working on.</p>
<p>Big Endian means that value is stored &#8220;from left to right&#8221;. The most significant values (bytes) are stored in memory with the lowest address first. This is probably what many people are familiar with, especially those in the networking field.  Here&#8217;s an example of data stored as Big Endian:</p>
<p>Take for instance the 2-byte value 1325, equivalent to a short or unsigned short. Stored in Big Endian encoding, the value would look like this in binary: 00000101 00101101. Makes sense right?</p>
<p>Now here is the same 2-byte value, 1325, in Little Endian encoding: 00101101 00000101. The bytes are flipped and thus to make any sense of it, you must read the last set of bits first.</p>
<p>So for simplicity&#8217;s sake, Big Endian values are stored like so:</p>
<pre>&lt;byte1&gt; &lt;byte2&gt; &lt;byte3&gt; &lt;byte4&gt; ... &lt;byten&gt;</pre>
<p>Little Endian values are stored like so:</p>
<pre>&lt;byten&gt; ... &lt;byte4&gt; &lt;byte3&gt; &lt;byte2&gt; &lt;byte1&gt;</pre>
<p>Network devices use Big Endian, it is considered the network standard, or &#8220;network encoding&#8221;. Endian-ness varies from CPU to CPU depending on its architecture. <strong>Power</strong> Macs use Big Endian, network devices use Big Endian. Intel PC&#8217;s (and <strong>Intel</strong> Macs) use Little Endian. What does that mean? Well, it means that if a program running on a <strong>Power</strong> Mac sends data to a PC, the PC may not understand it correctly without some type of encoding change taking place.</p>
<p>In my situation, I&#8217;m reading a series of values off of the network, all coming in via a byte stream. So the client will send the following packet for example:</p>
<p>4 bytes, 2 bytes, 1 byte, &#8230; and some others but I won&#8217;t get into them</p>
<p>So when I read the first four bytes off the network (which uses Big Endian encoding, remember?) I must flip the entire set of 4 bytes before my Little Endian PC can understand it.  Same goes for the next 2 bytes. The single byte obviously doesn&#8217;t need to be flipped with anything, it stands alone. So an incoming set of data may look like:</p>
<pre>0x1A 0x2B 0x3C 0x4D 0x2A 0x2B 0xAD</pre>
<p>Now I must flip each set of values byte by byte (but not invert the entire thing; this is a packet, containing multiple values).</p>
<p>In Little Endian, the same set of data reads:</p>
<pre>0x4D 0x3C 0x2B 0x1A 0x2B 0x2A 0xAD</pre>
<p>Confused yet? You&#8217;ll figure it out. Here&#8217;s some reading that should help: <a href="http://en.wikipedia.org/wiki/Endianness">http://en.wikipedia.org/wiki/Endianness</a>. It even gets into the origins of the word, which is pretty interesting. Here&#8217;s a little tool that may help you understand the pattern: <a href="http://dlnova.com/reverseendian.htm">http://dlnova.com/reverseendian.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/06/1-little-2-little-3-little-endians-er-wait-is-it-3-little-2-little-1-littl-endians/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KnowIT RC2.1 Released</title>
		<link>http://www.caledunlap.com/2009/05/knowit-rc21-released/</link>
		<comments>http://www.caledunlap.com/2009/05/knowit-rc21-released/#comments</comments>
		<pubDate>Mon, 18 May 2009 14:02:37 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[knowit]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=265</guid>
		<description><![CDATA[I&#8217;ve completed the modifications and]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve completed the modifications and package builds for KnowIT releast candidate 2.1. They are available from the <a href="http://knowitaig.googlecode.com/" target="_blank">KnowIT Google Code site</a>. Dare I say, this is one of the best peices of software I have written in a long time. And the best part is, its open source!</p>
<p>Check out the <a href="http://code.google.com/p/knowitaig/wiki/Screenshots" target="_blank">Screenshots</a>.</p>
<p>KnowIT works with Windows ONLY. There is currently not a Linux/UNIX scanner available for KnowIT, and the database back-end is a Microsoft product (MSSQL 2005). However, I did add ODBC support this time around, so it may work on other database types as well. If anybody gets it to work on MySQL or Oracle, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/05/knowit-rc21-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VGL Math &#8211; 2D/3D Video Game Math Library</title>
		<link>http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/</link>
		<comments>http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 10:05:25 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[vgl]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=231</guid>
		<description><![CDATA[I decided to get bold]]></description>
			<content:encoded><![CDATA[<p>I decided to get bold and start another open source project. This time it is related to the math involved in developing 2D and 3D video games. The project is hosted at <a href="http://code.google.com/p/vglmath" target="_blank">http://code.google.com/p/vglmath</a>. I decided to deem it a &#8220;VGL community project&#8221;; VGL being the company I founded a few months ago.</p>
<p>I&#8217;m looking for any pointers, contributors, or experts to make improvements or recommendations to the code. So please check it out. If you&#8217;re interested in contributing, please send me an email at cale@caledunlap.com so I can add your Google account to the members list.</p>
<p>And if you haven&#8217;t already, check out <a href="http://www.venomgamelabs.com" target="_blank">http://www.venomgamelabs.com</a>!</p>
<p>Now for your entertainment for the evening:<br />
<a href="http://www.youtube.com/watch?v=FRgYtp3HfvY"><span class="youtube">
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/FRgYtp3HfvY&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/FRgYtp3HfvY&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=FRgYtp3HfvY">www.youtube.com/watch?v=FRgYtp3HfvY</a></p></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/03/vgl-math-2d3d-video-game-math-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross-Tabulation (Pivot Tables) with MySQL</title>
		<link>http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/</link>
		<comments>http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 10:09:14 +0000</pubDate>
		<dc:creator>Cale</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development Journal]]></category>
		<category><![CDATA[confusion]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pivot tables]]></category>
		<category><![CDATA[tabulation]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://caledunlap.com/blog/?p=191</guid>
		<description><![CDATA[I don&#8217;t really have any]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t really have any sections on my website related to MySQL, so I figured I&#8217;d just throw together a quick post about something I found incredibly helpful. I&#8217;m sure others will find it nice too.</p>
<p>So in my years being trained on data architecture and database design, I learned to &quot;normalize, normalize, normalize&quot;. Unfortunately, normalization doesn&#8217;t lend itself to very simple statistical calculations&#8211;such as those used to generate graphs or a statistical scorecard.</p>
<p>In the case of Angel, I&#8217;ve normalized the hell out of the data. Now it comes down to needing to report on that data. At first, my reporting attempts were terrible&#8211;tons of nested loops, many queries, etc. Well, when I spoke to a colleague of mine at work, he said that if I was running on an SAS Mainframe, the work would already be done for me using a function called &quot;PROC TABULATE&quot;. He sort of dated himself by saying that.</p>
<p>Then I broke the news to him: I&#8217;m not using SAS, or any other mainframe technology. He replied by suggesting I look into some sort of MySQL equivalent to that function. So I started hunting. I came across this very nice article: <a href="http://dev.mysql.com/tech-resources/articles/wizard/print_version.html" target="_blank">http://dev.mysql.com/tech-resources/articles/wizard/print_version.html</a></p>
<p>That article shows, very effectively, how to create a nice &quot;statistical&quot; report using cross-tabulation techniques with normalized source data. The queries are sort of monstrous if you have a large number of fields to report on, but at that point, you&#8217;d be using code to generate the parameters for the SELECT statement.</p>
<p>Here&#8217;s my example:</p>
<p>My source data looks like the following&#8211;please note that some results are truncated because the result set would be WAY too large for a blog:</p>
<p> <code>
<pre>mysql&gt; select uid, Email from players;
+-----+--------------------------+
| uid | Email                    |
+-----+--------------------------+
|  10 | brian@venomgamelabs.com  |
|   4 | cale@caledunlap.com      |
|   1 | cale@venomgamelabs.com   |
|   9 | daniel@venomgamelabs.com |
|  11 | dave@venomgamelabs.com   |
|   5 | jane@venomgamelabs.com   |
|   8 | janes@venomgamelabs.com  |
|  12 | jill@venomgamelabs.com   |
|   6 | john@venomgamelabs.com   |
|   7 | johns@venomgamelabs.com  |
+-----+--------------------------+
mysql&gt; select * from gamedata LIMIT 10;
+----------+---------+------+
| playerid | fieldid | data |
+----------+---------+------+
|        1 |       3 | 60   |
|        1 |       4 | 1    |
|        1 |       5 | 1    |
|        1 |       6 | 286  |
|        1 |       7 | 1    |
|        1 |       8 | 13   |
|        1 |       9 | 1    |
|        1 |      10 | 1    |
|        1 |      11 | 261  |
|        1 |      12 | 13   |
+----------+---------+------+

mysql&gt; select FieldID, FriendlyName, GameID, FieldTypeID FROM gamefields;
+---------+---------------------------------+--------+-------------+
| FieldID | FriendlyName                    | GameID | FieldTypeID |
+---------+---------------------------------+--------+-------------+
|       1 | Play Time                       |      1 |           2 |
|       2 | Last Character                  |      1 |           1 |
|       3 | Total Eggs                      |      4 |           2 |
|       4 | Total Playtime                  |      4 |           2 |
|       5 | Total King Of The Hill Captures |      4 |           2 |
|       6 | Total Kills                     |      4 |           2 |
|       7 | Total Deaths                    |      4 |           2 |
|       8 | Engineer Playtime               |      4 |           2 |
|      10 | Mongo Playtime                  |      4 |           2 |
|      11 | Grunt Playtime                  |      4 |           2 |
|      12 | Gladiator Playtime              |      4 |           2 |
|      13 | Total Powerup Uses              |      4 |           2 |
|      14 | Total Powerups Received         |      4 |           2 |
+---------+---------------------------------+--------+-------------+
mysql&gt; select typeid, typename from field_types;
+--------+------------------+
| typeid | typename         |
+--------+------------------+
|      1 | Text             |
|      2 | Numeric          |
|      3 | Game Coordinates |
|      4 | Boolean          |
|      5 | Physical Address |
|      6 | IP Address       |
+--------+------------------+</pre>
<p></code></p>
<p>What I want to know from that data is how many players have field values within specific ranges&#8211;to generate some input data for a chart output. The code I&#8217;m using does the following math (from a separate query):</p>
<ol>
<li>Find the minimum value out of all of the player data for each field (SQL Query) </li>
<li>Find the maximum value out of all of the player data for each field (Same SQL query) </li>
<li>Get a &quot;standard deviation&quot; between the number <code>$StandardDeviation = floor( ($High - $Low)/NUM_DEVIATION_RANGES );</code> </li>
<li>Begins a SQL query and assembles a list of parameters to select (based on the deviation ranges) <code>
<pre>for $i = 0 to NUM_DEVIATION_RANGES
$Min = $Low + ($StandardDeviation * $i)
$Max = ($Min + $StandardDeviation) – 1;
$Query .= “SUM( IF( CAST(gamedata.Data AS UNSIGNED) &gt;= $Min AND CAST(gamedata.Data AS UNSIGNED) &lt;= $Max, 1, 0) ) AS ‘$Min-$Max’,”;
end for</pre>
<p>    </code></li>
<li>Runs the query, obtains a single result per field and feeds it to the chart to render a per-field graphical analysis chart. </li>
</ol>
<p>The output of the query from step 4 is as follows:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0d8710e5-306b-41bd-9c98-3e3cec81dfee" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">SELECT</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 60 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 87<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;60-87&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 88 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 115<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;88-115&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 116 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 143<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;116-143&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 144 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 171<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;144-171&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 172 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 199<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;172-199&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 200 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 227<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;200-227&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 228 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 255<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;228-255&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 256 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 283<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;256-283&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 284 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 311<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;284-311&#39;</span><span style="color:#808080">,</span><br />
&#160;&#160;&#160;&#160;<span style="color:#ff00ff">SUM</span><span style="color:#808080">(</span> <span style="color:#0000ff">IF</span><span style="color:#808080">(</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&gt;=</span> 312 <span style="color:#808080">AND</span> <span style="color:#ff00ff">CAST</span><span style="color:#808080">(</span>gamedata<span style="color:#808080">.</span>Data <span style="color:#0000ff">AS</span> UNSIGNED<span style="color:#808080">)</span> <span style="color:#808080">&lt;=</span> 339<span style="color:#808080">,</span>1<span style="color:#808080">,</span>0<span style="color:#808080">)</span> <span style="color:#808080">)</span> <span style="color:#0000ff">AS</span> <span style="color:#ff0000">&#39;312-339&#39;</span><br />
<span style="color:#0000ff">FROM</span> gamedata<span style="color:#808080">,</span> gamefields<span style="color:#808080">,</span> field_types<br />
<span style="color:#0000ff">WHERE</span> gamedata<span style="color:#808080">.</span>fieldid <span style="color:#808080">=</span> gamefields<span style="color:#808080">.</span>FieldID<br />
&#160;&#160;&#160;&#160;<span style="color:#808080">AND</span> gamefields<span style="color:#808080">.</span>FieldTypeID <span style="color:#808080">=</span> field_types<span style="color:#808080">.</span>typeid<br />
&#160;&#160;&#160;&#160;<span style="color:#808080">AND</span> field_types<span style="color:#808080">.</span>typename <span style="color:#808080">=</span> <span style="color:#ff0000">&#39;Numeric&#39;</span><br />
&#160;&#160;&#160;&#160;<span style="color:#808080">AND</span> gamefields<span style="color:#808080">.</span>FriendlyName <span style="color:#808080">=</span> <span style="color:#ff0000">&#39;Total Eggs&#39;</span></div>
</div>
</div>
<p>Now that query runs once per number of fields requested. The above query was just a single query for a single field. Note how the code generated the SELECT statement parameters (min and max) and set them as the column header in the result?</p>
<p>The result of that query looks like this:</p>
<p><code></p>
<pre>+-------+--------+---------+---------+---------+---------+---------+---------+---------+---------+
| 60-87 | 88-115 | 116-143 | 144-171 | 172-199 | 200-227 | 228-255 | 256-283 | 284-311 | 312-339 |
+-------+--------+---------+---------+---------+---------+---------+---------+---------+---------+
|     2	|      0 |	 2 |	   0 |	     1 |      0	 |	2  |	   0 |	     1 |       0 |
+-------+--------+---------+---------+---------+---------+---------+---------+---------+---------+</pre>
<p></code></p>
<p>So the output is exactly what I need for my chart. The result fields represent the X axis of the chart, and the result values represent the Y axis of the chart, all from a single query against normalized data using cross-tabulation.</p>
<p>I urge you to click on the link I mentioned near the top of the article if you want to learn how to do this. My example is fairly specific to my situation. That article showed me exactly what I needed to do, but I needed to apply it to my data and my reports.&#160; You&#8217;ll notice that I&#8217;ve used CAST&#8217;s in my query. The reason being that in order to accept any type of data, I&#8217;ve used the &#8216;TEXT&#8217; type on my game data fields&#8211;that&#8217;s why I also have a type table and a type ID in the field types. I then query what types of fields is numeric, and only perform my calculations against them.</p>
<p>Doing cross-tabluation/pivot tables isn&#8217;t too bad once you know what you&#8217;re doing. I had a tough time wrapping my head around it, but after a few hours of tinkering, I finally got what I was looking for. Another thing to note is that I&#8217;m summing up 1&#8242;s and 0&#8242;s, basically a tally. If you want to sum up your real data, don&#8217;t use 1&#8242;s and 0&#8242;s; use your actual data field.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caledunlap.com/2009/02/cross-tabulation-pivot-tables-with-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
