<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Coding4Fun</title><link>http://blogs.msdn.com/coding4fun/default.aspx</link><description>&lt;div id="menuContainer"&gt;&lt;/div&gt;</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>If it is broken, fix it</title><link>http://blogs.msdn.com/coding4fun/archive/2010/02/05/9959056.aspx</link><pubDate>Fri, 05 Feb 2010 22:49:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9959056</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9959056.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9959056</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9959056</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Ifitisbrokenfixit_D081/1420p-20%5B1%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="1420p-20[1]" border="0" alt="1420p-20[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Ifitisbrokenfixit_D081/1420p-20%5B1%5D_thumb.jpg" width="240" height="160" /&gt;&lt;/a&gt; Our own &lt;a href="http://www.brianpeek.com/blog/archive/2010/01/31/acer-1420p-leaky-handle-driver-fix.aspx"&gt;Brian Peek chats on how he fixed a leaky handle driver for the Acer 1420P (PDC build) laptop&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;Brian used a some free tools to figure out why the one of the tablet’s processes was growing at 10 handles second and what to do about it.&amp;#160; With the &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx"&gt;Process Explorer&lt;/a&gt; tool and &lt;a href="http://www.hex-rays.com/idapro/"&gt;IDA&lt;/a&gt;, he saw CreateFile was being called but never closed.&amp;#160; &lt;/p&gt;  &lt;p&gt;Brian has the source code and application up for download.&amp;#160; &lt;a href="http://www.brianpeek.com/blog/archive/2010/01/31/acer-1420p-leaky-handle-driver-fix.aspx"&gt;He also goes more in depth on the his actual fix in his post on his blog&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9959056" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category></item><item><title>ASP.Net server-side image resizing with WPF</title><link>http://blogs.msdn.com/coding4fun/archive/2010/02/01/9956677.aspx</link><pubDate>Mon, 01 Feb 2010 23:42:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9956677</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9956677.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9956677</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9956677</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/ASP.NetserversideimageresizingwithWPF_DCD1/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/ASP.NetserversideimageresizingwithWPF_DCD1/image_thumb.png" width="230" height="240" /&gt;&lt;/a&gt; &lt;a href="http://weblogs.asp.net/bleroy/archive/2010/01/21/server-side-resizing-with-wpf-now-with-jpg.aspx"&gt;Bertrand Le Roy shows off how to create dynamic images leveraging WPF’s image manipulation classes in an ASP.Net project&lt;/a&gt; instead of GDI+ classes to dramatically reduce creation time.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2009/12/10/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi.aspx"&gt;His prior post on this topic&lt;/a&gt; actually shows how to create them and why it is so fast.&amp;#160; It also shows off different algorithms and their outputs with benchmarks.&amp;#160; Some algorithms may produce great images but if they are slow, in certain cases, they can’t be used.&lt;/p&gt;  &lt;p&gt;Bertrand’s method does work in a Medium Trust environment but be aware of how your processing stuff.&amp;#160; This may not be a solution for you.&lt;/p&gt;  &lt;p&gt;[via &lt;a href="http://channel9.msdn.com/shows/This+Week+On+Channel+9/TWC9-Silverlight-4-Win-7-Driving-Editable-MVC-Routes-F-Missile-Launcher/"&gt;This week on Channel 9&lt;/a&gt;]&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9956677" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/image+manipulation/default.aspx">image manipulation</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/ASP.Net/default.aspx">ASP.Net</category></item><item><title>Making an Ocean with XNA</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/27/9954238.aspx</link><pubDate>Wed, 27 Jan 2010 19:00:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9954238</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9954238.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9954238</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9954238</wfw:comment><description>&lt;p&gt;In this article, Louis Ingenthron will show you how to create a simple endless ocean for an XNA C# game.    &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="157"&gt;           &lt;p&gt;Louis Ingenthron              &lt;br /&gt;&lt;a href="http://fvproductions.org/"&gt;FV Productions&lt;/a&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="481"&gt;           &lt;p&gt;&lt;b&gt;Code It:&lt;/b&gt; &lt;a href="http://xnaocean.codeplex.com/"&gt;http://xnaocean.codeplex.com/&lt;/a&gt; &lt;/p&gt;            &lt;p&gt;&lt;b&gt;Difficulty:&lt;/b&gt; Intermediate               &lt;br /&gt;&lt;b&gt;Time Required:&lt;/b&gt; 1-4 hours               &lt;br /&gt;&lt;b&gt;Cost:&lt;/b&gt; FREE               &lt;br /&gt;&lt;b&gt;Software Needed: &lt;/b&gt;&lt;a href="http://www.microsoft.com/express/download/"&gt;Visual C# Express&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/netframework/default.aspx"&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=80782277-D584-42D2-8024-893FCD9D3E82&amp;amp;displaylang=en"&gt;XNA Game Studio 3.1&lt;/a&gt;               &lt;br /&gt;&lt;b&gt;Hardware:&lt;/b&gt; Windows PC&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;Every game needs boundaries, such as a window separating the player from space or a brick wall. When I first played Splinter Cell: Double Agent's Cozumel Cruise level, I spent a good 5 minutes just looking at the ocean that kept the player in bounds. It was a beautiful sunset with waves moving across the ocean endlessly outward... and it was neat.&lt;/p&gt;  &lt;p&gt;When I was tasked with creating a great ocean for a Caribbean pirate game, I knew it had to look great, like Splinter Cell’s. Too many games, especially indie games, just put a cheap texture or two on a blue quad. But in my opinion, having a great looking boundary like an ocean can really tie your environment together and add a layer of polish.&lt;/p&gt;  &lt;p&gt;Now, just to clarify: we aren't going for the ocean in Crysis here. We want something that looks good and seems to be endless, so most of our work will be in the DirectX 9 Shaders. We will be using C# and XNA to build a project around it (XNA is fantastic for rapid development and tech demos, as well as its full Indie Games Distribution system).&lt;/p&gt;  &lt;h4&gt;Getting Started&lt;/h4&gt;  &lt;p&gt;Let's take a look at the base project. You should be able to compile and run it on the spot. When you get in, you will be able to turn the camera with the mouse and move with WASD (or use the first gamepad with standard FPS controls if you converted to run on Xbox360), but all that’s there is the skybox at an infinite distance away. I won't go into rendering skyboxes in this article because there are &lt;a href="http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2/Skybox.php"&gt;many&lt;/a&gt; &lt;a href="http://www.miszalok.de/C_3D_XNA/C6_Skybox/XNAC6_e.htm"&gt;articles&lt;/a&gt; &lt;a href="http://www.toymaker.info/Games/XNA/html/xna_skybox.html"&gt;about it&lt;/a&gt; &lt;a href="http://www.dotnetkicks.com/xna/Skybox_in_XNA_using_only_Two_Triangles"&gt;already&lt;/a&gt;. But you should be familiar with the concept of Cube Maps, which are basically six square textures representing the six faces of a cube.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image002_thumb.jpg" width="422" height="317" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So, let's get right into the code. We’ll start with a big blue plane. Open up Ocean.cs. You will notice that we already have some code in here. We have some vertices set up in the Load() function and a vertex declaration created (Again, in this article I assume you have a basic understanding of 3D rendering). These vertices will create two triangles that make a very large XZ plane at Y=0. Since our ocean will be processed only in the pixel shader, the plane should be much larger than your far-clip plane set up in your projection matrix. So let's draw the plane. In the Ocean's Draw() function, add these lines:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;Global.Graphics.VertexDeclaration = OceanVD;
Global.Graphics.DrawUserPrimitives&amp;lt;VertexPositionNormalTexture&amp;gt;
    (PrimitiveType.TriangleList, OceanVerts, 0, 2);&lt;/pre&gt;
&lt;style type="text/css"&gt;






.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This code tells the graphics device what kind of vertex we are using, and tells it to draw two consecutive triangles. But XNA uses only Shaders; it doesn’t support fixed function.&lt;/p&gt;

&lt;p&gt;Let's go over to our Solution Explorer. Right click on the Content project in our game project, and click Add -&amp;gt; New Item. Choose the &amp;quot;Effect File&amp;quot; template and name it OceanShader.fx. We are just testing to get the quads on there now, so we won't do much in this effect file yet. I cleaned up the pre-generated comments and changed the pixel shader return value to float4(0,0,1,1) to make it blue instead of red.&lt;/p&gt;

&lt;p&gt;Now, let's go back to Ocean.cs. We need to add a new class variable for the shader. This is encompassed by the Microsoft.Xna.Framework.Graphics.Effect class. We add this to the top of the class:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// the ocean's required content&lt;/span&gt;
&lt;span class="kwrd"&gt;private&lt;/span&gt; Effect oceanEffect; &lt;/pre&gt;

&lt;p&gt;And we actually link that to our FX file in the load function with this:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// load the shader&lt;/span&gt;
oceanEffect = Content.Load&amp;lt;Effect&amp;gt;(&lt;span class="str"&gt;&amp;quot;OceanShader&amp;quot;&lt;/span&gt;); &lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now we just need to set the shader variables in the draw function and tell the shader to begin and end. Our draw function now looks like this:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Draw(GameTime gameTime, Camera cam, 
        TextureCube skyTexture, Matrix proj)
{
    &lt;span class="rem"&gt;// start the shader&lt;/span&gt;
    oceanEffect.Begin();
    oceanEffect.CurrentTechnique.Passes[0].Begin();

    &lt;span class="rem"&gt;// set the transforms&lt;/span&gt;
    oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;World&amp;quot;&lt;/span&gt;].SetValue(Matrix.Identity);
    oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;View&amp;quot;&lt;/span&gt;].SetValue(cam.GetViewMatrix());
    oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;Projection&amp;quot;&lt;/span&gt;].SetValue(proj);

    oceanEffect.CommitChanges();

    &lt;span class="rem"&gt;// draw our geometry&lt;/span&gt;
    Global.Graphics.VertexDeclaration = OceanVD;
    Global.Graphics.DrawUserPrimitives&amp;lt;VertexPositionNormalTexture&amp;gt;
        (PrimitiveType.TriangleList, OceanVerts, 0, 2);

    &lt;span class="rem"&gt;// and we're done!&lt;/span&gt;
    oceanEffect.CurrentTechnique.Passes[0].End();
    oceanEffect.End();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Before we draw, we must first begin an Effect and an EffectPass. Since we only have one pass in our shader, we can just begin the first one. Next, we set the Transform matrices defined in the shader (&lt;a href="http://drunkenhyena.com/cgi-bin/view_cpp_article.pl?chapter=2;article=27"&gt;Read here&lt;/a&gt; for more information on the transform matrices). Then we tell the Effect to CommitChanges(), which basically flushes the parameter changes down the tube to the graphics card so we can draw. Now we see our old code to draw the plane. Finally, we end the EffectPass and the Effect. The program should run now, with a big blue plane where your ocean is.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image004_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image004_thumb.jpg" width="423" height="317" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Skymap Reflections&lt;/h4&gt;

&lt;p&gt;One of the best ways to make water look really neat is to add reflection. Ever seen a snow-covered mountain reflected on the surface of a lake? It’s gorgeous. Let's make our ocean reflect the sky. Go back to the OceanShader.fx file. This is where we will do the majority of our work. We need to give the shader the sky cubemap. Add this parameter to the top of the FX file:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;textureCUBE cubeTex;
samplerCUBE CubeTextureSampler = sampler_state
{
    Texture = &amp;lt;cubeTex&amp;gt;;
    MinFilter = anisotropic;
    MagFilter = anisotropic;
    MipFilter = anisotropic;
    AddressU = wrap;
    AddressV = wrap;
};&lt;/pre&gt;

&lt;p&gt;Next, we need to replace the Vertex structures with ones that match the actual vertices. They should look something like this:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;struct&lt;/span&gt; VertexShaderInput
{
    float3 Position            : POSITION0;
    float3 normal              : NORMAL0;
    float2 texCoord            : TEXCOORD0;
};

&lt;span class="kwrd"&gt;struct&lt;/span&gt; VertexShaderOutput
{
    float4 Position            : POSITION0;
    float2 texCoord            : TEXCOORD0;
    float3 worldPos         : TEXCOORD1;
};&lt;/pre&gt;

&lt;p&gt;We’ve now added two variables. The texCoord is pretty simple. We just pass it along (and multiply it). The worldPos is already calculated for us, so we can just assign it. Since it’s an ocean, we can just assume that the normal vector is straight up (why would we have a slanted ocean?). Our vertex shader should look like this:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;VertexShaderOutput output;

float4 worldPosition = mul(float4(input.Position,1), World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
    
output.texCoord = input.texCoord*100;
output.worldPos = worldPosition.xyz;

&lt;span class="kwrd"&gt;return&lt;/span&gt; output;&lt;/pre&gt;

&lt;p&gt;To do reflections, we need one more variable. A reflection off a surface requires a source vector and a surface normal vector. We can create our source vector by subtracting the camera position from the input's world position. To get the camera position, we could extract it from the View Matrix, but that's a pain. Instead, we’ll just add a float3 variable to the top of our FX file like so:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;float3 EyePos; &lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now we update our pixel shader function:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;float3 diffuseColor = float4(0,0,1,1);
float3 normal = float3(0,1,0);
float3 cubeTexCoords = reflect(input.worldPos-EyePos,normal);
float3 cubeTex = texCUBE(CubeTextureSampler,cubeTexCoords).rgb;

&lt;span class="kwrd"&gt;return&lt;/span&gt; float4((cubeTex*0.8)+(diffuseColor*0.2),1); &lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So what is this actually doing? First we set up the diffuseColor, which is the color of the ocean itself, blue, which keeps it from looking like a big mirror. Next we assume the normal is straight up (We'll change this later). Then we need to get the texture coordinates for the skymap. We will reflect the vector from the eye off of the surface normal. Cubemaps take 3-component vectors, and don't even need them to be normalized, so that's all we need there. Then we use those coordinates and actually store the texture lookup's RGB values (what sky has an alpha?). Finally, we combine 80% of the reflected sky color with 20% of the diffuse color. Can we run it now? Well, no. We defined those variables up top, but never set them. Let's go back to the Ocean.cs and add in some more parameter mutators:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;EyePos&amp;quot;&lt;/span&gt;].SetValue(cam.Position);
&lt;span class="rem"&gt;// set the sky texture&lt;/span&gt;
oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;cubeTex&amp;quot;&lt;/span&gt;].SetValue(skyTexture); &lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now we can run it! You should see a big flat body of blue water that reflects the sky. Cool, huh? But it’s not very watery yet, is it?&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image006_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image006" border="0" alt="clip_image006" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image006_thumb.jpg" width="428" height="321" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Normal Mapping&lt;/h3&gt;

&lt;p&gt;Let's add some chop to the surface. Four normal maps are already be included in the Content project, so we just need to add a Texture2D array to our Ocean class and load in these textures. We'll call the texture array OceanNormalMaps:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; Texture2D[] OceanNormalMaps; &lt;/pre&gt;

&lt;p&gt;And load them in the Load() function like this:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// load the normal maps&lt;/span&gt;
OceanNormalMaps = &lt;span class="kwrd"&gt;new&lt;/span&gt; Texture2D[4];
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 4; i++)
    OceanNormalMaps[i] = Content.Load&amp;lt;Texture2D&amp;gt;(&lt;span class="str"&gt;&amp;quot;Ocean&amp;quot;&lt;/span&gt; + (i + 1) + &lt;span class="str"&gt;&amp;quot;_N&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;What are we going to do with these textures? It's simple really: we'll lerp between them. Switch to the FX file and add two new texture registers (we'll only be lerping between two at any given time) and a float for the actual lerping value:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;float&lt;/span&gt; textureLerp;

texture2D normalTex;
sampler2D NormalTextureSampler = sampler_state
{
    Texture = &amp;lt;normalTex&amp;gt;;
    MinFilter = anisotropic;
    MagFilter = anisotropic;
    MipFilter = anisotropic;
    AddressU = wrap;
    AddressV = wrap;
};

texture2D normalTex2;
sampler2D NormalTextureSampler2 = sampler_state
{
    Texture = &amp;lt;normalTex2&amp;gt;;
    MinFilter = anisotropic;
    MagFilter = anisotropic;
    MipFilter = anisotropic;
    AddressU = wrap;
    AddressV = wrap;
};&lt;/pre&gt;

&lt;p&gt;Next, we change our pixel shader code:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;float3 diffuseColor = float4(0,0,1,1);
    
float4 normalTexture1 = tex2D(NormalTextureSampler, input.texCoord);
float4 normalTexture2 = tex2D(NormalTextureSampler2, input.texCoord);
float4 normalTexture = (textureLerp*normalTexture1)+
            ((1-textureLerp)*normalTexture2);
    
float3 normal = ((normalTexture)*2)-1;
normal.xyz = normal.xzy;
normal = normalize(normal);
    
float3 cubeTexCoords = reflect(input.worldPos-EyePos,normal);
    
float3 cubeTex = texCUBE(CubeTextureSampler,cubeTexCoords).rgb;
    
&lt;span class="kwrd"&gt;return&lt;/span&gt; float4((cubeTex*0.8)+(diffuseColor*0.2),1); &lt;/pre&gt;

&lt;p&gt;Alright, let's take a look at this. The first new thing we do is sample the new normal maps and lerp between them with the value declared earlier. Nothing too complex there. But then we need to convert the RGB value into a normal. You'll notice that we take the RGB, multiply by 2 and subtract by one. This simply takes the compressed RGB [0:1] value and converts it to [-1:1] for a full range of normals. The next line re-orders the normal's components. This is because the normal map is traditionally on the XY plane, but our ocean is on the XZ plane—so we swap the Y and Z components. Finally, we normalize our normal. Always normalize your normals! Everything after that is the same as before. Let's go set these variables we defined and get this thing working. Go back to Ocean.cs and add this code to the draw:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// choose and set the ocean textures&lt;/span&gt;
&lt;span class="kwrd"&gt;int&lt;/span&gt; oceanTexIndex = ((&lt;span class="kwrd"&gt;int&lt;/span&gt;)(gameTime.TotalGameTime.TotalSeconds) % 4);
oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;normalTex&amp;quot;&lt;/span&gt;].SetValue(
    OceanNormalMaps[(oceanTexIndex + 1) % 4]);

oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;normalTex2&amp;quot;&lt;/span&gt;].SetValue(
    OceanNormalMaps[(oceanTexIndex) % 4]);

oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;textureLerp&amp;quot;&lt;/span&gt;].SetValue(
    (((((&lt;span class="kwrd"&gt;float&lt;/span&gt;)gameTime.TotalGameTime.TotalSeconds) - 
    (&lt;span class="kwrd"&gt;int&lt;/span&gt;)(gameTime.TotalGameTime.TotalSeconds)) * 2 - 1) * 0.5f) 
    + 0.5f); &lt;/pre&gt;

&lt;p&gt;You can do the math on this if you want, but basically it just cycles through the four textures and sets the lerp value so it’s a continuous shift. After all that, you should have an interesting image when you run the program!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image008_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image008" border="0" alt="clip_image008" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image008_thumb.jpg" width="428" height="321" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Animate and Blend&lt;/h3&gt;

&lt;p&gt;Now we have something that resembles water. But when was the last time you saw water that just moved up and down—especially in the ocean? Let's animate this a bit! The first thing we’ll do is make the texture coordinates scroll based on time. Let's add a time float to the top of the FX file:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;float&lt;/span&gt; time = 0;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Next, let's scroll the texture coordinates in the normal map lookup:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;float4 normalTexture1 = tex2D(NormalTextureSampler, 
    input.texCoord+float2(time,time));
float4 normalTexture2 = tex2D(NormalTextureSampler2, 
    input.texCoord+float2(time,time));&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now, simply set the time parameter in the Ocean.cs's Draw():&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// set the time used for moving waves&lt;/span&gt;
oceanEffect.Parameters[&lt;span class="str"&gt;&amp;quot;time&amp;quot;&lt;/span&gt;].SetValue(
    (&lt;span class="kwrd"&gt;float&lt;/span&gt;)gameTime.TotalGameTime.TotalSeconds * 0.02f);&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Your water should be moving now if you run it.&lt;/p&gt;

&lt;p&gt;There is one more enhancement we can do. What's better than having one moving surface? How about two? It's basically parallax normal mapping. We will change our pixel shader code to look like this:&lt;b&gt; &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;HLSL 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;float3 diffuseColor = float4(0,0,1,1);
    
float4 normalTexture1 = tex2D(NormalTextureSampler, 
    input.texCoord*0.1+float2(time,time));

float4 normalTexture2 = tex2D(NormalTextureSampler2, 
    input.texCoord*0.1+float2(time,time));

float4 normalTexture = (textureLerp*normalTexture1) +
    ((1-textureLerp)*normalTexture2);

float4 normalTexture3 = tex2D(NormalTextureSampler, 
    input.texCoord*2+float2(-time,-time*2));

float4 normalTexture4 = tex2D(NormalTextureSampler2, 
    input.texCoord*2+float2(-time,-time*2));

float4 normalTextureDetail = (textureLerp*normalTexture3) +
    ((1-textureLerp)*normalTexture4);
    
float3 normal = (((0.5*normalTexture) + 
    (0.5*normalTextureDetail))*2) - 1;

normal.xyz = normal.xzy;
normal = normalize(normal);
    
float3 cubeTexCoords = reflect(input.worldPos-EyePos,normal);
    
float3 cubeTex = texCUBE(CubeTextureSampler,cubeTexCoords).rgb;
    
&lt;span class="kwrd"&gt;return&lt;/span&gt; float4((cubeTex*0.8)+(diffuseColor*0.2),1); &lt;/pre&gt;

&lt;p&gt;What we did here is add two separate, lerping texture coordinates together. The 1 and 2 have been scaled by 0.1, making the waves much larger. The 3 and 4 lookups are scaled by 2 so they are much smaller, and move much faster in the opposite direction. This makes it look like the ocean has an overall current and some smaller waves simulating wind. The pixels are then combined before being converted to normals. Go ahead and run it. You should see your nice, new ocean!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image010_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image010" border="0" alt="clip_image010" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MakinganOceanwithXNA_9AD7/clip_image010_thumb.jpg" width="428" height="321" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;And there you have it: a nice, infinite ocean! Since the majority of the work is done in the pixel shader, it will go on to the very end of the depth buffer and tile infinitely. Also, this is best when you are only looking out at it. It becomes somewhat apparent to the user if you are looking at the level on the ocean and only the sky, not the level, reflects properly. You may also notice that the ocean looks a bit cartoony in our example, but the good news is that this is merely an effect of the skybox being done in a soft pastel style. A more realistic skybox means a more realistic ocean.&lt;/p&gt;

&lt;p&gt;I'm looking forward to seeing how people use this effect! If you use it, please &lt;a href="mailto:louisingenthron@fvproductions.org"&gt;send me an email&lt;/a&gt; with a screenshot.&lt;/p&gt;

&lt;h3&gt;About The Author&lt;/h3&gt;

&lt;p&gt;Louis Ingenthron is a Game Developer in Orlando, FL. He works on commercial Console and PC titles, but runs his own Indie Games company, &lt;a href="http://fvproductions.org/"&gt;FV Productions&lt;/a&gt;, on the side. He is best known for his open source XNA rhythm game Unsigned and specializes in real-time Graphics programming. He has been working with XNA since the 2.0 Beta and with .NET C# for just as long. He is also familiar with several other development languages, such as C, C++, and Java. Occasionally, he can even be found doing web development and Flash. Louis also writes for MSDN's Coding4Fun website, contributing articles on a monthly basis.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9954238" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/gaming/default.aspx">gaming</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/HSL/default.aspx">HSL</category></item><item><title>Missile Launchers with F#</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/25/9953075.aspx</link><pubDate>Mon, 25 Jan 2010 17:48:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9953075</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9953075.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9953075</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9953075</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MissileLauncherswithF_8A08/hasKitty_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="hasKitty" border="0" alt="hasKitty" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/MissileLauncherswithF_8A08/hasKitty_thumb.jpg" width="240" height="180" /&gt;&lt;/a&gt; Chris Smith had a talk at the CodeMash conference in January 2010 titled “Being an Evil Genius with F# and .NET”.&amp;#160; Chris created a post about his talk and doing &lt;a href="http://blogs.msdn.com/chrsmith/archive/2010/01/24/being-an-evil-genius-with-f-and-net.aspx"&gt;Computer Vision, Speech Recognition, and shooting missiles at people all with F#!&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;Here is a bit of his speech recognition code using the System.Speech.dll:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;let recognizerEvent = getWordRecognizer()

&lt;span class="rem"&gt;// Main handler - convert spoken text into RL commands&lt;/span&gt;
let handleWord spokenText =
    printfn &lt;span class="str"&gt;&amp;quot;Recognized Word: %s&amp;quot;&lt;/span&gt; spokenText
    let action = 
        match spokenText with
        | &lt;span class="str"&gt;&amp;quot;up&amp;quot;&lt;/span&gt;  &lt;span class="rem"&gt;// Has a hard time recognizing this :(&lt;/span&gt;
        | &lt;span class="str"&gt;&amp;quot;north&amp;quot;&lt;/span&gt; -&amp;gt; MoveUp(20)
        | &lt;span class="str"&gt;&amp;quot;down&amp;quot;&lt;/span&gt;  -&amp;gt; MoveDown(20)
        | &lt;span class="str"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;  -&amp;gt; MoveLeft(20)
        | &lt;span class="str"&gt;&amp;quot;right&amp;quot;&lt;/span&gt; -&amp;gt; MoveRight(20)

        | &lt;span class="str"&gt;&amp;quot;fire&amp;quot;&lt;/span&gt;  -&amp;gt; Fire

        | _ -&amp;gt; NoOp
        
    performAction rocketLauncher action |&amp;gt; ignore

&lt;span class="rem"&gt;// Exit handler - specifically look for exit/quit&lt;/span&gt;
let terminateLoop = &lt;span class="kwrd"&gt;ref&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;
let terminateLoopHandler = function | &lt;span class="str"&gt;&amp;quot;exit&amp;quot;&lt;/span&gt; 
                                    | &lt;span class="str"&gt;&amp;quot;quit&amp;quot;&lt;/span&gt; -&amp;gt; terminateLoop := &lt;span class="kwrd"&gt;true&lt;/span&gt;
                                    | _      -&amp;gt; ()

&lt;span class="rem"&gt;// Hook up event handlers&lt;/span&gt;
recognizerEvent.Add(handleWord)
recognizerEvent.Add(terminateLoopHandler)

&lt;span class="kwrd"&gt;while&lt;/span&gt; terminateLoop.Value = &lt;span class="kwrd"&gt;false&lt;/span&gt; &lt;span class="kwrd"&gt;do&lt;/span&gt;
    System.Threading.Thread.Yield() |&amp;gt; ignore
()&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Chris happily provided the source code as well, &lt;a href="http://blogs.msdn.com/chrsmith/attachment/9952779.ashx"&gt;RocketLauncher_v1.0.zip&lt;/a&gt;.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9953075" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Speech+Recognition/default.aspx">Speech Recognition</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/f_2300_/default.aspx">f#</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Computer+Vision/default.aspx">Computer Vision</category></item><item><title>Creating torn images</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/20/9951019.aspx</link><pubDate>Wed, 20 Jan 2010 19:28:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9951019</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9951019.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9951019</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9951019</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Creatingtornimages_A141/tornphotodemo5%5B1%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="tornphotodemo5[1]" border="0" alt="tornphotodemo5[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Creatingtornimages_A141/tornphotodemo5%5B1%5D_thumb.jpg" width="240" height="165" /&gt;&lt;/a&gt; Adam Kinney did a pretty neat port of a flash application that &lt;a href="http://adamkinney.wordpress.com/2010/01/09/image-blitting-in-silverlight-with-writeablebitmapex/"&gt;creates an effect that gives an image like it was torn and crumpled up in Silverlight using the WriteableBitmapEx.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Blitting is the act of blending multiple images together.&amp;#160; More about the &lt;a href="http://en.wikipedia.org/wiki/Bit_blit"&gt;BLIT operation can be found at Wikipedia&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Adam used the Blit method with different blend modes to achieve the effect from the standard image.&amp;#160; With masking, alpha blending, and the multiply mode combined with a few masks and textures, he was able start with a standard image and give it that “pulled out of my pocket” effect.&lt;/p&gt;  &lt;p&gt;The WriteableBitmapEx team over at &lt;a title="http://writeablebitmapex.codeplex.com/" href="http://writeablebitmapex.codeplex.com/"&gt;http://writeablebitmapex.codeplex.com/&lt;/a&gt; really did a great job with their library too!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9951019" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/media/default.aspx">media</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/image+manipulation/default.aspx">image manipulation</category></item><item><title>Wi-Fi Warthogs</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/18/9950111.aspx</link><pubDate>Tue, 19 Jan 2010 01:55:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9950111</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9950111.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9950111</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9950111</wfw:comment><description>&lt;p&gt;If you were at PDC09, you might have played “WI-FI Warthogs”, a computer robotics Laser Tag Game that uses the Xbox 360 controller to remotely control Power Wheels vehicles. In this article, I’ll tell you how to build your very own WI-FI Warthogs game, from start to finish.    &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="181"&gt;           &lt;p&gt;&lt;strong&gt;Tim Higgins&lt;/strong&gt;               &lt;br /&gt;&lt;a href="http://www.waterhobo.com/blogengine.net/"&gt;Waterhobo.com&lt;/a&gt;               &lt;br /&gt;&lt;/p&gt;            &lt;h3&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="clip_image002" border="0" alt="clip_image002" align="left" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image002_thumb.jpg" width="159" height="168" /&gt;&lt;/a&gt;&lt;/h3&gt;         &lt;/td&gt;          &lt;td valign="top" width="457"&gt;           &lt;p&gt;&lt;b&gt;Source Code:&lt;/b&gt; &lt;a href="http://wifiwarthogs.codeplex.com/SourceControl/list/changesets"&gt;Download&lt;/a&gt;&lt;/p&gt;            &lt;p&gt;&lt;b&gt;Difficulty:&lt;/b&gt; Intermediate               &lt;br /&gt;&lt;b&gt;Time Required:&lt;/b&gt; 50 to 100 hours               &lt;br /&gt;&lt;b&gt;Cost:&lt;/b&gt; $350+              &lt;br /&gt;&lt;b&gt;Software:&lt;/b&gt; &lt;a href="http://www.codeproject.com/KB/game/XNA_360_Controller_Input.aspx"&gt;XNA to 360 example&lt;/a&gt;, &lt;a href="http://www.phidgets.com/programming_resources.php"&gt;Phidgets Libraries&lt;/a&gt;, &lt;a href="http://www.microsoft.com/express/download/"&gt;Visual C# Express&lt;/a&gt;              &lt;br /&gt;&lt;b&gt;Hardware:&lt;/b&gt; 1 motorized vehicle (Power Wheel), Netbook/Laptop, &lt;a href="http://www.trossenrobotics.com/"&gt;Phidgets devices &lt;/a&gt;, &lt;a href="http://www.bestbuy.com/site/olspage.jsp?skuId=8221471&amp;amp;type=product&amp;amp;id=1166839533325"&gt;Xbox 360 controller with PC receiver&lt;/a&gt; &lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;h3&gt;Getting Started&lt;/h3&gt;  &lt;p&gt;I’ll start with the Hardware and then move on to the main application and engines that run the robotics.&lt;/p&gt;  &lt;p&gt;To get started, all you need are the parts and software listed above, and some basic DIY skills. I found my parts at many different places, one of the best of which was &lt;a href="http://www.trossenrobotics.com"&gt;Trossen Robotics&lt;/a&gt; (which also has a great forum site). I found automotive relays and wiring harnesses at &lt;a href="http://www.allelectronics.com"&gt;All Electronics&lt;/a&gt; website, cheap Power Wheels ($15) at garage sales, and additional parts at the local junk yard. &lt;/p&gt;  &lt;p&gt;If your Power Wheels car is in need of repairs, check out the &lt;a href="http://www.modifiedpowerwheels.com"&gt;Modified Power Wheels&lt;/a&gt; website for more info.&lt;/p&gt;  &lt;p&gt;The video below shows pictures I started taking on the first day—they continue all the way through the prototyping life cycle. &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px auto; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:3701b7bf-df0f-4caa-8624-4950d4411637" class="wlWriterEditableSmartContent"&gt;&lt;div id="7d17a4f8-d8dc-486d-93c6-f6695b00eb56" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=pvhLJexOwaY&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" target="_new"&gt;&lt;img src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/video07d9f3dcd7e4.jpg" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('7d17a4f8-d8dc-486d-93c6-f6695b00eb56'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/pvhLJexOwaY&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;&amp;amp;hl=en\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/pvhLJexOwaY&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;  &lt;h3&gt;Hardware&lt;/h3&gt;  &lt;h4&gt;Modifying the Cars&lt;/h4&gt;  &lt;p&gt;To modify the car, I removed all the existing controls from my Power Wheels Barbie Jeeps and wired their rear motors together. (Keep in mind that in order for the car to go forward or in reverse, the wires on ONE of the motors has to be reversed. Otherwise, when you connect the two red wires together and the two blue ones together and give it power, one wheel will spin forward while the other one spins backwards.)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image004_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image004_thumb.jpg" width="455" height="606" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Next, I attached the motors to a set of automotive relays, forming a DPDT switch. This was in turn connected to a Phidgets four relay board. Two of the Phidgets relays will control the transmission.&lt;/p&gt;  &lt;p&gt;For the steering, I used the tracks from an electric car seat to move the tires from right to left. Any 12 volt electric car seat should work—you can get them at an auto salvage yard, usually at a reasonable price. You could also use an old cordless drill, as seen &lt;a href="http://www.waterhobo.com/blogengine.net/post/2009/12/10/WiFi-Warthogs-Alternate-Steering.aspx"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Note that you’ll have to modify your car for the steering unit. To do this, I fitted a 2x4 into the front section of the car. On the board, I screwed in the seat track, giving it something solid to sit on.&lt;/p&gt;  &lt;p&gt;The wiring for the steering motor was the same as the transmission, except I needed to add limiting switches to keep the tires from going too far left or right. I tied these to the automotive relays. Then, I wired the relays for steering to the Phidgets 4 relay board. (See wiring diagram. Or, for more on automotive relay, see &lt;a href="http://www.waterhobo.com/hobofiles/autorelay.doc"&gt;here&lt;/a&gt;.)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image006_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image006" border="0" alt="clip_image006" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image006_thumb.jpg" width="422" height="317" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I had two different versions of the jeeps and my process was a little different each time, so you might have a little trial and error to find the right fit for the car.&lt;/p&gt;  &lt;p&gt;The plastic and drywall screws work great to hold everything in place but you might have a few extra screw holes when you’re finished. I call that “character”. &lt;/p&gt;  &lt;p&gt;Also, relays and motors can cause EMI noise. For ways to control it, read &lt;a href="http://www.phidgets.com/documentation/Tutorials/Addressing_EMI_Issues_Tutorial.pdf"&gt;this&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image008_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image008" border="0" alt="clip_image008" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image008_thumb.jpg" width="500" height="344" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can now drive the car forward, reverse, left and right. To test this, try running the Phidgets test program or use my code. For a Phidgets test, right click on the Phidgets item in the tray on your computer. Then, select the 004 device and right click to bring up a screen that lets you manually control the device.&lt;/p&gt;  &lt;p&gt;Remember to NEVER turn on both relays to transmission or steering at same time, or you will blow your motors, Phidgets and possibly the USB port to your computer. You can turn on one from steering and one from transmission—just turn them off before you switch to the other relays. My program does all of this for you. (The Phidgets driver also does all this for you, but beware: it gives you total control, so you can turn all relays on at once. As mentioned, this would cause bad things to happen.)&lt;/p&gt;  &lt;h4&gt;Adding a Gun Turret &lt;/h4&gt;  &lt;p&gt;To control the gun, we’ll use three more Phidgets devices: the 888 interface IO board, the voltage board, and dual relay daughter boards. The voltage board will tell the 888 board when it sees a voltage spike, which happens when one gun hits another. The dual relay board acts like a simple switch; it fires the gun and allows it to reload ammo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/gunwire%5B1%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="gunwire[1]" border="0" alt="gunwire[1]" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/gunwire%5B1%5D_thumb.jpg" width="500" height="375" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To aim the gun and move it from right to left, we’ll use the Phidgets servo controller. As a cheaper option, you could replace the laser tag guns with just about anything else. (In a prior version, for example, I used only a relay and was able to shoot water from a windshield washer pump by using the relay as a switch and turning the power to the pump on and off.) We now have our hardware in place. &lt;/p&gt;  &lt;p&gt;The gun is mounted in a holster that can be turned by the servo. I used the “lazy Susan” concept, the same as what most people have in their houses. I made a wooden box that the gun fits in and mounted it on a ball bearing swivel. The servo is mounted directly below it, and everything is control from the Xbox controller (you can buy them from &lt;a href="http://Sparkfun.com"&gt;Sparkfun.com&lt;/a&gt;). It’s now time to control the car with the computer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image012_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image012" border="0" alt="clip_image012" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WiFiWarthogs_FBFE/clip_image012_thumb.jpg" width="409" height="307" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Computers&lt;/h4&gt;  &lt;p&gt;I used Asus EeePCs models 904 and 1000HE, but any computer with XP or newer installed on it will work. You can pick up a used Netbook (a great and cheap option for robotics) from EBay for little to nothing—I recently bought one that had a 32GB SSD and the 1.6 GHz Atom processor for $250. If possible, get one with a shock-resistant SSD drive. The ones we used at PDC all had standard hard drives and worked fine, but you have to watch for hard hits, which can damage the hard drives.&lt;/p&gt;  &lt;h4&gt;Controller Application&lt;/h4&gt;  &lt;p&gt;First, I have to give credit Joel Ivory Johnson, whose article and &lt;a href="http://www.codeproject.com/KB/game/XNA_360_Controller_Input.aspx"&gt;sample&lt;/a&gt; will make understanding the controller code much easier. His sample is also great for testing functionality and making sure the drivers are working properly for the Xbox 360 controller.&lt;/p&gt;  &lt;p&gt;The main controller app is a simple program: an action happens (a button pushed, joystick moved, etc). Then, a call is made to the proper method. Finally, the method fires off a message to its queue and goes back to waiting for the next action (fire and forget). I created two methods: “Drivecar” and “GunControl”. The names pretty much tell you what’s going to happen.&lt;/p&gt;  &lt;p&gt;In addition to the two main functions, there are two timer events. One controls the main loop; the other allows feedback to be given back to the main program. The feedback can come from any of the engines, or from the scoreboard. I use the feedback timer to supply the players’ vibrations to their controllers when they get hit. I also use it for beginning and ending a game.&lt;/p&gt;  &lt;p&gt;I used Microsoft message queue to send messages from the application to the different engines.&lt;/p&gt;  &lt;p&gt;So to summarize: I have feedback, 888 IO interface, servo, and relay interface queues that are installed on each Netbook. The queues operate on their own; we’ll discuss them more below.&lt;/p&gt;  &lt;p&gt;I have 3 cars and 3 computers (you could use more or less). I can bring on more cars or switch the computers around to different cars. I do this by using the DNS name of the computer and syncing it up with a configuration file. The engines will pull all their configuration data in from this file. Below is an example of one of the nodes, along with the code I use to read the node:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Car&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;carnumber&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;TimCar2&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;carnumber&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;relaycar&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;FormatName:DIRECT=OS:timcar2\private$\relaycar&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;relaycar&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;servocar&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;FormatName:DIRECT=OS:timcar2\private$\servocar&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;servocar&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;interface888&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;FormatName:DIRECT=OS:timcar2\private$\interface888&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;interface888&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;feedback&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;FormatName:DIRECT=OS:timcar2\private$\feedback&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;feedback&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ok2reload&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Y&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ok2reload&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;relayserialnum&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;8694&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;relayserialnum&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;serialnum888&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;30448&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;serialnum888&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;servoserialnum&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;88630&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;servoserialnum&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;scorecard&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;FormatName:DIRECT=OS:timcar3\private$\scorecard&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;scorecard&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;scorecardnolimit&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;False&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;scorecardnolimit&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;scorecardnolimittime&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;1800&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;scorecardnolimittime&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Car&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Each node (Car) has a “Carnumber” that’s equal to the DNS name of the computer. The other information you see is the location of the private queues, the serial numbers of the different Phidgets devices, and some additional configuration data on how the game operates. The file is in XML format and the values are read in with the following code:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;ProjectUtils.Utilities x = &lt;span class="kwrd"&gt;new&lt;/span&gt; ProjectUtils.Utilities();

whatcar = System.Net.Dns.GetHostName();
scorecard = x.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;scorecard&amp;quot;&lt;/span&gt;);
relaycar1 = x.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;relaycar&amp;quot;&lt;/span&gt;);
servocar1 = x.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;servocar&amp;quot;&lt;/span&gt;);
interface888car1 = x.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;interface888&amp;quot;&lt;/span&gt;);
feedbackque1 = x.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;feedback&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Another function of the controller program is to determine how many players (1 or 2) are attached to this receiver. If there are two players, player 1 will be the driver and player 2 will be the gunner. If there is only one player, he will need to press the “A” button to switch back and forth between the different modes of play, since it’s not safe to drive and shoot at the same time. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.gamePadState1.IsConnected == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
{
    player1active = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    numberOfPlayers++;

    &lt;span class="rem"&gt;//what if only one player let them choose if they want to be in driver or&lt;/span&gt;
    &lt;span class="rem"&gt;// gunner mode&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.gamePadState2.IsConnected == &lt;span class="kwrd"&gt;false&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;this&lt;/span&gt;.gamePadState1.Buttons.Equals(&lt;span class="kwrd"&gt;this&lt;/span&gt;.previousState1.Buttons))
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.gamePadState1.Buttons.A == Input.ButtonState.Pressed)
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (player1Driver == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
                {
                    player1Driver = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
                    lbT1Player1.Text = &lt;span class="str"&gt;&amp;quot;Gunner&amp;quot;&lt;/span&gt;;
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                    player1Driver = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
                    lbT1Player1.Text = &lt;span class="str"&gt;&amp;quot;Driver&amp;quot;&lt;/span&gt;;
                }
            }

        }
    }

}
&lt;span class="kwrd"&gt;else&lt;/span&gt;
{
    lbT1Player1.Text = &lt;span class="str"&gt;&amp;quot;Not Connected&amp;quot;&lt;/span&gt;;
    player1active = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
}

&lt;span class="kwrd"&gt;if&lt;/span&gt; (player1active == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (player1Driver == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
    {
        lbT1Player1.Text = &lt;span class="str"&gt;&amp;quot;Driver&amp;quot;&lt;/span&gt;;
        DriveCar(gamePadState1, previousState1, 1);
        PlayRadio(gamePadState1, previousState1, 1);
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        lbT1Player1.Text = &lt;span class="str"&gt;&amp;quot;Gunner&amp;quot;&lt;/span&gt;;
        GunControl(gamePadState1, previousState1, 2);
    }
}

&lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.gamePadState2.IsConnected == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
{
    player2active = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    numberOfPlayers++;
    GunControl(gamePadState2, previousState2, 2);
    lbT1Player2.Text = &lt;span class="str"&gt;&amp;quot;Connected&amp;quot;&lt;/span&gt;;
}
&lt;span class="kwrd"&gt;else&lt;/span&gt;
{
    lbT1Player2.Text = &lt;span class="str"&gt;&amp;quot;Not Connected&amp;quot;&lt;/span&gt;;
    player2active = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;In XNA programming for the Xbox controller, there are previous and current states. For the most part I care only about the current state of the controller, but I do use the previous state to see if the button or joystick has moved between the last loop and the current loop. The loops happen every 100 milliseconds for the main loop (10 times a second, 1000 milliseconds = 1 second).&lt;/p&gt;

&lt;p&gt;Below is the code for the “DriveCar” function. As you can see, it’s pretty straightforward—I simply pass in the previous and current states of the game controller. For steering, I interrogate the state of the right joystick. If it’s a different value than the last time we were here, I send a message to the “InterfaceIO” (004 Phidgets interface board) message queue, passing the current state value of the joystick. The drive engine will take the value and determine the action. The transmission is handled the same way, except that we check the left joystick.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DriveCar(GamePadState gameController, GamePadState prevState, &lt;span class="kwrd"&gt;int&lt;/span&gt; player)
{
    &lt;span class="rem"&gt;//either player 1 or 2 will send their current GamePadState&lt;/span&gt;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; xStickCurrent;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; xStickPrev;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; yStickCurrent;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; yStickPrev;
    &lt;span class="kwrd"&gt;string&lt;/span&gt; steerPos = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (allstop == &lt;span class="kwrd"&gt;false&lt;/span&gt;)
    {
        &lt;span class="rem"&gt;//Steering&lt;/span&gt;
        xStickCurrent = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)((gameController.ThumbSticks.Right.X + 1.0f) * 100.0f / 2.0f);
        xStickPrev = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)((prevState.ThumbSticks.Right.X + 1.0f) * 100.0f / 2.0f);

        steerPos = xStickCurrent.ToString();

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (xStickCurrent != xStickPrev)
        {
            queueCount++;
            &lt;span class="rem"&gt;//6 = servo number , steerPos = joystick position&lt;/span&gt;
            listBox1.Items.Add(&lt;span class="str"&gt;&amp;quot;steering&amp;quot;&lt;/span&gt; + steerPos);
            qM.SendMsgNoTransaction(3, &lt;span class="str"&gt;&amp;quot;3&amp;quot;&lt;/span&gt; + steerPos, relaycar1);
            xStickPrev = xStickCurrent;
        }

        &lt;span class="rem"&gt;//Transmission&lt;/span&gt;
        &lt;span class="rem"&gt;//0-49(backward) 51- 100(forward) 50 = Neutral&lt;/span&gt;

        yStickCurrent = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)((gameController.ThumbSticks.Left.Y + 1.0f) * 100.0f / 2.0f);
        yStickPrev = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)((prevState.ThumbSticks.Left.Y + 1.0f) * 100.0f / 2.0f);

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (yStickCurrent != yStickPrev)
        {
            queueCount++;
            listBox1.Items.Add(&lt;span class="str"&gt;&amp;quot;transmission &amp;quot;&lt;/span&gt; + yStickCurrent.ToString());
            qM.SendMsgNoTransaction(3, &lt;span class="str"&gt;&amp;quot;4&amp;quot;&lt;/span&gt; + yStickCurrent.ToString(), relaycar1);
            yStickPrev = yStickCurrent;
        }
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        &lt;span class="rem"&gt;//we are in all stop do not allow any sends to car...&lt;/span&gt;
        &lt;span class="rem"&gt;//if we have not sent all stop to relay engine do it..&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (sentallstop == &lt;span class="kwrd"&gt;false&lt;/span&gt;)
        {
            sentallstop = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            &lt;span class="rem"&gt;//tell transmission to go to neutral&lt;/span&gt;
            qM.SendMsgNoTransaction(3, &lt;span class="str"&gt;&amp;quot;450&amp;quot;&lt;/span&gt;, relaycar1);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Each of the queue engines (feedback, drivetrain, 888interface) is set up pretty much the same way. The “Main” function sets up the Phidgets device it will control. It then goes into an endless loop until you cancel the program. In the loop, it checks the Message queue for any new messages and calls the proper function based on the content of the message. Then, it gives the processor back to the computer via the do events call while it waits for the next message. &lt;/p&gt;

&lt;p&gt;Below is the “Main” function from the drivetrain queue engine. It sets itself up based on the configuration file and creates the events that the Phidgets devices require. The code then enters its loop and waits for messages to process.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
{
    whatcar = System.Net.Dns.GetHostName();
    relaycar = projectUtils.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;relaycar&amp;quot;&lt;/span&gt;);
    ioboardserialnum = projectUtils.ReadXMLFile4CarElementValue(&lt;span class="str"&gt;&amp;quot;c:\\deploy\\carconfig.xml&amp;quot;&lt;/span&gt;, whatcar, &lt;span class="str"&gt;&amp;quot;relayserialnum&amp;quot;&lt;/span&gt;);

    &lt;span class="rem"&gt;//write to the console what is happening, useful for debugging&lt;/span&gt;
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Configured Car number - &amp;quot;&lt;/span&gt; + whatcar + &lt;span class="str"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;);
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Configured Relay serial number - &amp;quot;&lt;/span&gt; + ioboardserialnum + &lt;span class="str"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;);

    &lt;span class="rem"&gt;//Wiring up the Phidgets devices with their events&lt;/span&gt;
    ifKit = &lt;span class="kwrd"&gt;new&lt;/span&gt; InterfaceKit();

    ifKit.Attach += &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachEventHandler(ifKit_Attach);
    ifKit.Detach += &lt;span class="kwrd"&gt;new&lt;/span&gt; DetachEventHandler(ifKit_Detach);
    ifKit.Error += &lt;span class="kwrd"&gt;new&lt;/span&gt; ErrorEventHandler(ifKit_Error);

    ifKit.InputChange += &lt;span class="kwrd"&gt;new&lt;/span&gt; InputChangeEventHandler(ifKit_InputChange);
    ifKit.OutputChange += &lt;span class="kwrd"&gt;new&lt;/span&gt; OutputChangeEventHandler(ifKit_OutputChange);
    ifKit.SensorChange += &lt;span class="kwrd"&gt;new&lt;/span&gt; SensorChangeEventHandler(ifKit_SensorChange);

    ifKit.open(&lt;span class="kwrd"&gt;int&lt;/span&gt;.Parse(ioboardserialnum));

    &lt;span class="kwrd"&gt;while&lt;/span&gt; (&lt;span class="kwrd"&gt;true&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;try&lt;/span&gt;
        {
            &lt;span class="rem"&gt;// get the message from the message queue &lt;/span&gt;
            o = qM.PullMsg(relaycar);

            &lt;span class="rem"&gt;//body will have for servo 1 to 7 rest of string is position to move too.&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (o != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; o.QueMsgBody != &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
            {
                mycount++;
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;process body and count &amp;quot;&lt;/span&gt; + o.QueMsgBody + &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt; + mycount.ToString() + &lt;span class="str"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;);
                inputDeviceNum = Int32.Parse(o.QueMsgBody.Substring(0, 1));
                msgMainBody = &lt;span class="kwrd"&gt;int&lt;/span&gt;.Parse(o.QueMsgBody.Substring(1));

                &lt;span class="kwrd"&gt;switch&lt;/span&gt; (inputDeviceNum)
                {
                    &lt;span class="kwrd"&gt;case&lt;/span&gt; 3:
                        steering(msgMainBody);
                        &lt;span class="kwrd"&gt;break&lt;/span&gt;;
                    &lt;span class="kwrd"&gt;case&lt;/span&gt; 4:
                        transmission(msgMainBody);
                        &lt;span class="kwrd"&gt;break&lt;/span&gt;;
                }
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;null or 0 length queue message&amp;quot;&lt;/span&gt; + &lt;span class="str"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;);
            }

            Application.DoEvents();
            Thread.Sleep(100);
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
        {
            projectUtils.WriteEventToApplicationLog(&lt;span class="str"&gt;&amp;quot;PhidgetsIO&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Main -&amp;gt; &amp;quot;&lt;/span&gt; + ex.ToString());
        }
    }
}&lt;/pre&gt;

&lt;p&gt;This snippet of code is the “transmission” function, which allows the car to move forward, in reverse or stop. This is where I determine what action I need to do based on the joystick’s position. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; transmission(&lt;span class="kwrd"&gt;int&lt;/span&gt; myPos)
{
    &lt;span class="kwrd"&gt;try&lt;/span&gt;
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (myPos &amp;lt; 20)
        {
            myMsg = &lt;span class="str"&gt;&amp;quot;Moving transmission to =&amp;gt; Reverse&amp;quot;&lt;/span&gt;;
            currentSteerPos = &lt;span class="str"&gt;&amp;quot;R&amp;quot;&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (myPos &amp;gt; 80)
        {
            myMsg = &lt;span class="str"&gt;&amp;quot;Moving transmission in Forward&amp;quot;&lt;/span&gt;;
            currentSteerPos = &lt;span class="str"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;;
        }
        &lt;span class="rem"&gt;// giving most range from the joystick to stop the car, being safe&lt;/span&gt;
        &lt;span class="kwrd"&gt;else&lt;/span&gt;
        {
            myMsg = &lt;span class="str"&gt;&amp;quot;Moving Transmission to =&amp;gt;  Neutral&amp;quot;&lt;/span&gt;;
            currentSteerPos = &lt;span class="str"&gt;&amp;quot;N&amp;quot;&lt;/span&gt;;
        }

        Console.WriteLine(myMsg + &lt;span class="str"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;);
        &lt;span class="rem"&gt;//first stop motor, then wait  and finally do new command.&lt;/span&gt;
       &lt;span class="rem"&gt;// we stop only long enough for the electricity to stop energising the relay&lt;/span&gt;
        &lt;span class="rem"&gt;//since we are turning both relays to off (false) that is the same as Neutral so we&lt;/span&gt;
        &lt;span class="rem"&gt;//do not need to check for it.&lt;/span&gt;

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (ifKit.Attached == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
        {
            &lt;span class="rem"&gt;//set relay 3 to not be engerized, relays start with 0 base count&lt;/span&gt;
            ifKit.outputs[2] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            Thread.Sleep(20);
        }

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (ifKit.Attached == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
        {
            &lt;span class="rem"&gt;//set relay 3 to not be engerized, relays start with 0 base count&lt;/span&gt;
            ifKit.outputs[3] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            Thread.Sleep(20);
        }

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (currentSteerPos == &lt;span class="str"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (ifKit.Attached == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
            {
                &lt;span class="rem"&gt;// turn on relays to power motors forward&lt;/span&gt;
                ifKit.outputs[2] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (currentSteerPos == &lt;span class="str"&gt;&amp;quot;R&amp;quot;&lt;/span&gt;)
        {
            &lt;span class="rem"&gt;// turn on relays to power motors reverse&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (ifKit.Attached == &lt;span class="kwrd"&gt;true&lt;/span&gt;)
            {
                ifKit.outputs[3] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
        }
    }
    &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
    {
        projectUtils.WriteEventToApplicationLog(&lt;span class="str"&gt;&amp;quot;PhidgesIO&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Transmission -&amp;gt; &amp;quot;&lt;/span&gt; + ex.ToString());
    }
}&lt;/pre&gt;

&lt;h3&gt;Notes&lt;/h3&gt;

&lt;p&gt;First, remember to always turn off relays before changing direction, so you never have both relays running at the same time. &lt;/p&gt;

&lt;p&gt;Also, there is more code in the “main” function (instead of in a timer routine) because of performance issues. When I created a timer and added all the code to the event, the processor showed like it was redlined at 100%. When I put the “do events” in the timer event everything worked fine, but it still looked like the process was redlined. However, when I moved everything into the “Main “ function and added a “do events”, everything worked fine and the processor dropped to about 8% usage—even with all of the engines running and the main program processing the Xbox controller commands.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This was a fun project that gave me a better understanding of robotics and C# functionality. Like I said in the beginning, there are many things you could do to make it better and even faster—I simply gave you a starting point. Questions to ponder: Why console apps and not Windows services? Why MSMQ and not WFC? &lt;/p&gt;

&lt;p&gt;If you have any questions or thoughts, feel free to ask them here or over at my &lt;a href="http://www.waterhobo.com/blogengine.net/"&gt;blog&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;About The Author&lt;/h3&gt;

&lt;p&gt;Tim is an IT Director in the Enterprise Architect Group for &lt;a href="http://www.maritz.com"&gt;Maritz&lt;/a&gt;, a sales and marketing services company. He has developed many systems in numerous languages over the years and is currently working with C#. In his off time he enjoys coming up with off the wall ideas and then seeing if he can make them happen. Tim’s blog is finally getting started and can be seen at &lt;a href="http://www.waterhobo.com/blogengine.net/"&gt;Waterhobo.com&lt;/a&gt; where he tries to explain them; he can be emailed at &lt;a href="mailto:tbh726@gmail.com"&gt;tbh726@gmail.com&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9950111" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx">hardware</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/PDC/default.aspx">PDC</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Phidgets/default.aspx">Phidgets</category></item><item><title>Want Windows 7 Sensors that are Arduino powered?</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/15/9949045.aspx</link><pubDate>Fri, 15 Jan 2010 18:06:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9949045</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9949045.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9949045</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9949045</wfw:comment><description>&lt;p&gt;&lt;a href="http://milesburton.com/wiki/index.php?title=Dallas_Temperature_Control_Library"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="TCL310_On_AtMega8[1]" border="0" alt="TCL310_On_AtMega8[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WantWindows7SensorsthatareArduinopowered_8E24/TCL310_On_AtMega8%5B1%5D_3.jpg" width="240" height="180" /&gt;&lt;/a&gt;Am I the only one warming up their soldering iron?&amp;#160;&amp;#160; I posted a bit ago on being able to do a &lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/12/10/9934884.aspx"&gt;Windows 7 sensor with a parallax board&lt;/a&gt;, but Brian Jepson (&lt;a href="http://twitter.com/bjepson"&gt;@bjepson&lt;/a&gt;) of &lt;a href="http://www.makezine.com/"&gt;MAKE&lt;/a&gt; and O’Reilly helped port that driver into a more generic driver that works with Arduino!&lt;/p&gt;  &lt;p&gt;Right now there is one Arduino sketch in there from &lt;a href="http://twitter.com/skobalczyk"&gt;@skobalczyk&lt;/a&gt;; but they plan to add more soon.&lt;/p&gt;  &lt;p&gt;Head over to &lt;a href="http://win7sensorserial.codeplex.com"&gt;http://win7sensorserial.codeplex.com&lt;/a&gt; to get the driver and how to do more!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9949045" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx">hardware</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Windows+7/default.aspx">Windows 7</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Sensors/default.aspx">Sensors</category></item><item><title>Scanner access with WIA via WPF</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/15/9945958.aspx</link><pubDate>Fri, 15 Jan 2010 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9945958</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9945958.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9945958</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9945958</wfw:comment><description>&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image_7[1]" border="0" alt="image_7[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/ScanneraccesswithWIAviaWPF_D619/image_7%5B1%5D_3.png" width="227" height="240" /&gt;Pete Brown has created an &lt;a href="http://community.irritatedvowel.com/blogs/pete_browns_blog/archive/2010/01/08/Scanning-images-in-WPF-via-WIA.aspx"&gt;example of accessing a scanner with WIA via WPF&lt;/a&gt;.&amp;#160; In the past we’ve chatted about &lt;a href="http://blogs.msdn.com/coding4fun/archive/2007/09/25/5121856.aspx"&gt;going paperless with WIA&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/10/31/912546.aspx"&gt;accessing a camera with it&lt;/a&gt; too, but Pete talks about how WIA the guts of it works and how to get&amp;#160; an application to leverage it.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;To find out more about WIA on top of Pete’s example, head over to MSDN’s section on it.&amp;#160; &lt;a title="http://msdn.microsoft.com/en-us/library/ms630368(VS.85).aspx" href="http://msdn.microsoft.com/en-us/library/ms630368(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms630368(VS.85).aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9945958" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx">hardware</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WIA/default.aspx">WIA</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Scanner/default.aspx">Scanner</category></item><item><title>SSH that conversation</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/13/9945873.aspx</link><pubDate>Wed, 13 Jan 2010 19:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9945873</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9945873.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9945873</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9945873</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/SSHthatconversation_A074/loose-lips-sink-ships%5B1%5D_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="loose-lips-sink-ships[1]" border="0" alt="loose-lips-sink-ships[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/SSHthatconversation_A074/loose-lips-sink-ships%5B1%5D_thumb.jpg" width="180" height="240" /&gt;&lt;/a&gt; Tamir Gal has a Secure Shell (SSH) library for .Net.&amp;#160; What is SSH you ask?&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Secure_Shell"&gt;SSH&lt;/a&gt; is a &lt;a href="http://en.wikipedia.org/wiki/Network_protocol"&gt;network protocol&lt;/a&gt; that allows data to be exchanged using a &lt;a href="http://en.wikipedia.org/wiki/Secure_channel"&gt;secure channel&lt;/a&gt; between two networked devices&lt;/p&gt;  &lt;p&gt;SharpSSH allows you to read/write data and transfer files over SSH channels using an API similar to &lt;a href="http://sharpssh.cvs.sourceforge.net/viewvc/sharpssh/SharpSSH/Examples/jsch_samples/"&gt;JSch's API&lt;/a&gt;. In addition, it provides some additional &lt;a href="http://sharpssh.cvs.sourceforge.net/viewvc/sharpssh/SharpSSH/Examples/sharpssh_samples/"&gt;wrapper classes&lt;/a&gt; which offer even simpler abstraction for SSH communication. &lt;/p&gt;  &lt;p&gt;SharpSSH is hosted on sourceforge, please check out its &lt;a href="http://www.tamirgal.com/blog/admin/Pages/project%20page"&gt;project page&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9945873" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Protocol/default.aspx">Protocol</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/SSH/default.aspx">SSH</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Internet/default.aspx">Internet</category></item><item><title>Windows 7: Federated Search</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/11/9942117.aspx</link><pubDate>Mon, 11 Jan 2010 21:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9942117</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9942117.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9942117</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9942117</wfw:comment><description>&lt;p&gt;In this article, you'll learn how to use federated search in Windows 7 to easily locate items from various public and private sources directly from Windows Explorer.&lt;/p&gt; &lt;table border="0" cellspacing="0" cellpadding="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="282"&gt; &lt;p&gt;Arian T. Kulp &lt;br&gt;&lt;a title="http://www.ariankulp.com" href="http://www.ariankulp.com/"&gt;http://www.ariankulp.com&lt;/a&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign="top" width="356"&gt; &lt;p&gt;&lt;b&gt;Code It:&lt;/b&gt; &lt;a href="http://c4fosdxgen.codeplex.com/"&gt;Download&lt;/a&gt;&lt;strong&gt; &lt;br&gt;Try It:&lt;/strong&gt; n/a&lt;br&gt;&lt;strong&gt;Difficulty:&lt;/strong&gt; Intermediate &lt;br&gt;&lt;b&gt;Time Required:&lt;/b&gt; 3 hours &lt;br&gt;&lt;b&gt;Cost:&lt;/b&gt; Free! &lt;br&gt;&lt;b&gt;Software Needed:&lt;/b&gt; &lt;a href="http://www.microsoft.com/express/"&gt;Visual Studio 2008&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;In this article, I've created a class file to encapsulate a federated search provider.&amp;nbsp; This lets you use the new federated search feature of Windows 7.&amp;nbsp; Here, you'll learn about:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Federated search  &lt;li&gt;Serializing a class as an XML object  &lt;li&gt;Creating a simple Silverlight project to expose it&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;What is Federated Search?&lt;/h3&gt; &lt;p&gt;Windows 7 now lets you search web sites from Windows Explorer. This isn't a hugely-publicized feature, and it's not really accessible to developers (as far as I know), but it's useful for anyone.&amp;nbsp; &lt;p&gt;Windows 7 federated search is built on the OpenSearch specification developed by Amazon A9.&amp;nbsp; The search itself takes place by making a simple HTTP GET request for a given search term specified in a URL (http://example?search=TEST).&amp;nbsp; The response is the web site's results, formatted as RSS or ATOM.&amp;nbsp; Any site that offers search can choose to also make the results available in one of these supported formats.&amp;nbsp; Applications like SharePoint, Exchange Server and even Sticky Notes included with Vista and Windows 7 offer this ability.  &lt;p&gt;OpenSearch reduces the bandwidth needed for a typical search response and allows developers to create interesting applications with the results.&amp;nbsp; Of course, one of these applications is the ability to display results directly in Windows Explorer, including the ability to sort by columns, copy and paste, and use the common search field.&amp;nbsp; Some custom providers even support full integration with the Windows shell, such as drag-and-drop for copying entities or viewing additional properties (think Outlook, SharePoint, or images).  &lt;p&gt;In order for Windows to add an OpenSearch provider, you need to provide a definition file in OSDX format.&amp;nbsp; This format specifies human-readable descriptive information, along with necessary URL's and other parameters.  &lt;p&gt;&lt;/p&gt; &lt;h3&gt;Generating OpenSearch Definition Files&lt;/h3&gt; &lt;p&gt;The purpose of this project is to create OpenSearch definition files-that is, the OSDX files.&amp;nbsp; These files are associated with Windows Explorer and add themselves to the Searches folder: &lt;i&gt;C:\Users\{USER}\Searches&lt;/i&gt;.  &lt;p&gt;This code does not actually perform any searches or integrate with Windows; it's not a proxy and it doesn't scrape web pages. In fact, it doesn't do anything except create the OSDX files to add to your system.&amp;nbsp; &lt;p&gt;To create an OSDX file, you need to provide a URL to invoke and a name for the provider.&amp;nbsp; A minimal file looks like this:&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="UTF-8"&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OpenSearchDescription&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://a9.com/-/spec/opensearch/1.1/"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ShortName&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Bing&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ShortName&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Description&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Get Relevant Results &lt;span class="attr"&gt;&amp;amp;amp;&lt;/span&gt; Decide Faster. Bing Gets The Job Done!&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Description&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Url&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="application/rss+xml"&lt;/span&gt; &lt;span class="attr"&gt;template&lt;/span&gt;&lt;span class="kwrd"&gt;="http://www.bing.com/search?q={searchTerms}&amp;amp;amp;go=&amp;amp;amp;form=QBLH&amp;amp;amp;qs=n&amp;amp;amp;format=rss"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OpenSearchDescription&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Once you find the right URL, use "{searchTerms}" to replace the term.&amp;nbsp; There are also escape expressions for starting index ("{startIndex}"), result counts per page ("{count}"), and more.&amp;nbsp; Note that Windows Explorer is very picky about using a provider file.&amp;nbsp; If there is anything malformed in the XML (be sure to escape ampersands in URL's!) or if you are missing an Atom or RSS URL, then it will fail with no useful information:&lt;/p&gt;
&lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Search Connector error" border="0" alt="Search Connector error" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WorkingwithOpenSearch_107C5/image_5.png" width="370" height="195"&gt; &lt;/p&gt;
&lt;p&gt;To make this easier, I created a class, OpenSearchDefinition, with the right properties.&amp;nbsp; The class and properties are marked up with XML attributes so it can be written out as well-formatted XML without any string concatenation.&lt;/p&gt;
&lt;p&gt;It can be difficult to find sites that offer RSS search results, but fortunately there's another way.&amp;nbsp; Bing searches the internet and can be scoped to a given site's content.&amp;nbsp; Even better: you can request search results in RSS.&amp;nbsp; Google provides RSS search results too, but you need to pre-configure your searches.&amp;nbsp; Bing allows you to do this on-the-fly, as a parameter for any search.&lt;/p&gt;
&lt;h3&gt;Creating the Front-End&lt;/h3&gt;
&lt;p&gt;The OpenSearchDefinition class file does all of the work, and could be reused, but doesn't have a broad usage story.&amp;nbsp; I created a Silverlight front-end to demonstrate one way of using it.&amp;nbsp; An ASP.NET Web Form sits on the back-end and serves up the OSDX file based on URL parameters.&amp;nbsp; The Silverlight application just provides a convenient way to enter those parameters.&lt;/p&gt;
&lt;p&gt;The first tab is a way to create a provider for any site by using Bing.&amp;nbsp; Remember that if you scope the search using the &lt;strong&gt;site&lt;/strong&gt; parameter, Bing will return search results for only one site - effectively a site-level search.&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WorkingwithOpenSearch_107C5/image_9.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WorkingwithOpenSearch_107C5/image_thumb_2.png" width="391" height="291"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The second tab is for building up an OSDX file using any site's RSS search URL.&amp;nbsp; You can enter a custom name, description, and search URL.&amp;nbsp; This is the best method for adding new search providers.&amp;nbsp; &lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WorkingwithOpenSearch_107C5/image_7.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/WorkingwithOpenSearch_107C5/image_thumb_1.png" width="391" height="291"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p align="left"&gt;Though Bing can be used to search most sites, you won't be able to take advantage of all features a site has to offer.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Currently, very few site owners seem interested in offering syndicated search results-this may be because they're concerned about ads not being seen.&amp;nbsp; But of course, if I perform a search and view the results, I'll likely end up on the site and see the ads anyway!&amp;nbsp; So if you run a popular site and have a search feature (don't they all?) consider offering that little RSS/ATOM link next to results. 
&lt;p&gt;From the consumption point of view, it's really easy to create a search provider definition using the OSDX format.&amp;nbsp; You could do it by hand, but this tool simplifies the process and shows off Silverlight, XML serialization, and a few other nifty features as a bonus! 
&lt;p&gt;The OpenSearchDefinition class file is ready to reuse.&amp;nbsp; As with all Coding 4 Fun code, you can do whatever you want with it. Let me know if you find other uses for it! 
&lt;p&gt;Download the free Visual C# 2008 Express Edition so you can play with the code, or download the ASP.NET web site and give it a try.&amp;nbsp; &lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Additional Information&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a title="http://www.neowin.net/news/main/09/01/06/windows-7-federated-search" href="http://www.neowin.net/news/main/09/01/06/windows-7-federated-search"&gt;http://www.neowin.net/news/main/09/01/06/windows-7-federated-search&lt;/a&gt; 
&lt;li&gt;&lt;a title="http://www.msdev.com/Directory/Description.aspx?EventId=1199" href="http://www.msdev.com/Directory/Description.aspx?EventId=1199"&gt;http://www.msdev.com/Directory/Description.aspx?EventId=1199&lt;/a&gt; 
&lt;li&gt;&lt;a title="http://www.sevenforums.com/tutorials/742-windows-7-search-federation-providers.html" href="http://www.sevenforums.com/tutorials/742-windows-7-search-federation-providers.html"&gt;http://www.sevenforums.com/tutorials/742-windows-7-search-federation-providers.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Arian Kulp is a software developer living in Western Oregon.&amp;nbsp; He creates samples, screencasts, demos, labs, and articles, he speaks at programming events, and he enjoys spending time with his family.&amp;nbsp; Check out his &lt;a href="http://www.ariankulp.com" target="_blank"&gt;homepage&lt;/a&gt; to contact him or learn more.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9942117" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/windows/default.aspx">windows</category></item><item><title>Video ambient lighting effects</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/08/9945861.aspx</link><pubDate>Fri, 08 Jan 2010 19:12:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9945861</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9945861.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9945861</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9945861</wfw:comment><description>&lt;p&gt;&lt;a href="http://fun3md.blogspot.com/2009/12/overview-of-my-setup.html"&gt;Fun3 MD created a DIY version with an Arduino&lt;/a&gt; of the &lt;a href="http://www.microsofttranslator.com/BV.aspx?ref=Internal&amp;amp;a=http%3a%2f%2fwww.vdr-wiki.de%2fwiki%2findex.php%2fAtmo-plugin"&gt;AtmoLight&lt;/a&gt;, which is a clone of the Philip Amblight system.&amp;#160; Awesome job of leveraging a pre-existing technology instead of re-inventing the wheel.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:9534d779-09f3-487d-a911-6f15d8d26a23" class="wlWriterEditableSmartContent"&gt;&lt;div id="193e7b7a-5cd9-40d2-badc-511024f789ef" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=i4JnrAwullI&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0" target="_new"&gt;&lt;img src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Videoambientlightingeffects_9D9D/video3e08c3c3474a.jpg" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('193e7b7a-5cd9-40d2-badc-511024f789ef'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/i4JnrAwullI&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0&amp;amp;hl=en\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/i4JnrAwullI&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9945861" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/media/default.aspx">media</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx">hardware</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Just+Neat/default.aspx">Just Neat</category></item><item><title>RGB in, HLS out</title><link>http://blogs.msdn.com/coding4fun/archive/2010/01/04/9943689.aspx</link><pubDate>Tue, 05 Jan 2010 02:03:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9943689</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9943689.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9943689</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9943689</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/RGBinHLSout_FDD8/temp0%5B1%5D_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="temp0[1]" border="0" alt="temp0[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/RGBinHLSout_FDD8/temp0%5B1%5D_thumb.png" width="240" height="170" /&gt;&lt;/a&gt; David Veeneman wrote a neat little console application that will &lt;a href="http://www.codeproject.com/KB/WPF/WpfColorConversions.aspx"&gt;convert RGB colors to HLS&lt;/a&gt; (Hue-Luminance-Saturation) or HSB (Hue-Saturation-Brightness) over at Code Project.&lt;/p&gt;  &lt;p&gt;One of the neat things David also did was show off using IValueConverter as well to do some of the conversion for you.&lt;/p&gt;  &lt;p&gt;David did use an MSDN article as reference, if you want to see the sample, head over to &lt;a title="http://msdn.microsoft.com/en-us/library/ms771620.aspx" href="http://msdn.microsoft.com/en-us/library/ms771620.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms771620.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9943689" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category></item><item><title>Creating An Application With Full Plug-in Support</title><link>http://blogs.msdn.com/coding4fun/archive/2009/12/28/9941747.aspx</link><pubDate>Mon, 28 Dec 2009 22:43:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9941747</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9941747.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9941747</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9941747</wfw:comment><description>&lt;p&gt;In this article, you’ll learn how to create an application with full plug-in support.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="157"&gt;         &lt;p&gt;Arian T. Kulp           &lt;br /&gt;&lt;a href="http://www.ariankulp.com"&gt;www.ariankulp.com&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="481"&gt;         &lt;p&gt;&lt;b&gt;Project site:&lt;/b&gt; &lt;a title="http://utilrunner.codeplex.com/" href="http://utilrunner.codeplex.com/"&gt;http://utilrunner.codeplex.com/&lt;/a&gt;&lt;b&gt;             &lt;br /&gt;Code It: &lt;/b&gt;&amp;#160;&lt;a href="http://utilrunner.codeplex.com/Release/ProjectReleases.aspx"&gt;Downloads&lt;/a&gt;            &lt;br /&gt;&lt;strong&gt;Run It:&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;&lt;a href="http://utilrunner.codeplex.com/Release/ProjectReleases.aspx"&gt;Downloads&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;b&gt;Difficulty:&lt;/b&gt; Intermediate            &lt;br /&gt;&lt;b&gt;Time Required:&lt;/b&gt; 3 hours            &lt;br /&gt;&lt;b&gt;Cost:&lt;/b&gt; Free!            &lt;br /&gt;&lt;b&gt;Software Needed:&lt;/b&gt; &lt;a href="http://www.microsoft.com/express/download/"&gt;Visual C# 2008 Express Edition or higher&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;   &lt;p&gt;&lt;a href="http://www.microsoft.com/express/download/"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/p&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;It’s been a number of months since I released the &lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/04/14/9535026.aspx"&gt;first version of my Utility Runner application&lt;/a&gt;.&amp;#160; Utility Runner makes it possible to run system utilities with as little overhead as possible: Instead of lots of tray icons, numerous EXE’s, and the associated memory and startup time overhead, this application manages multiple utilities from one place.&lt;/p&gt;  &lt;p&gt;To open this solution, you’ll need Visual Studio 2008 Express Edition (Visual C# or Visual Basic), at least.&amp;#160; If you don’t have it yet, you should get it!&lt;/p&gt;  &lt;h3&gt;Working with MEF&lt;/h3&gt;  &lt;p&gt;Little has changed functionally from the last version of the application, beyond some refactoring that’s taken place since the new version of MEF was released.&amp;#160; For one thing, the attribute for marking an export is no longer sealed, so you can now create a subclassed attribute that encompasses the export name and any other metadata included with it.&amp;#160; Consumers can simply use your new custom attribute for a stronger-typed experience.&amp;#160; In my case, I created a WpfServiceMetadata class.&amp;#160; Read on for more information.&lt;/p&gt;  &lt;h3&gt;Managing Addins&lt;/h3&gt;  &lt;p&gt;My big challenge was figuring out how to implement an addin manager to support multiple utility addins, like in Firefox.&amp;#160; MEF lets you easily mark what classes are addins and where they should fit into your overall code, but I wanted to take it further.&amp;#160; I decided that my goals were:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The ability to load an addin through the UI&lt;/li&gt;    &lt;li&gt;The ability to disable/enable addins&lt;/li&gt;    &lt;li&gt;The ability to remove an addin&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are a number of ways to achieve these goals.&amp;#160; Mine isn’t the ideal way, but it works pretty well nonetheless.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Loading Addins&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Loading addins is mostly handled by the MEF Framework itself, but there is some manual work involved as well.&amp;#160; I decided that instead of scanning a folder for DLL’s like in the first version, I’d take things a step further:&amp;#160; I came up with a simple packaging format to contain the addin and its associated files.&lt;/p&gt;    &lt;p&gt;The packaging format is simply a Zip file renamed with the .util extension.&amp;#160; The file contains at least the DLL of the addin itself, but might also include associated libraries, images, sounds, or other resources.&amp;#160; I toyed with creating a manifest file to help supply addin information that didn’t require class loading, but I kept it simple for now.&lt;/p&gt;    &lt;p&gt;Before loading DLL’s with addins, the &lt;b&gt;AddinManager &lt;/b&gt;class will scan the addins folder for .util files and unzip them to same-named folders.&amp;#160; Each of these folders gets added to the list of folders in which MEF searches.&amp;#160; The original file then gets deleted.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Adding an addin&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;An application that uses addins needs a way for users to add new ones.&amp;#160; The easiest method would be to have the user just drag new .util files into the Addins folder, but this isn’t very user-friendly.&amp;#160; I wanted to make it easy for a user to click something in the application to install an addin.&lt;/p&gt;    &lt;p&gt;If the user clicks the &lt;b&gt;Add New Addin From File &lt;/b&gt;button, they use a file browse button to locate the file.&amp;#160; The application then copies that file to the Addins folder and notifies the user that it will be loaded on next startup.&amp;#160; It would be great to load the addin immediately, and MEF supports that, but I decided to skip dynamic addin control for simplicity.&lt;/p&gt;    &lt;p&gt;Instead of going through the dialog when loading an addin, it would be nice to support double-clicking. To do this, an association needs to be made from the .util extension to the executable.&amp;#160; If you launch the executable with a file argument and it’s the right format, it will automatically copy it to the Addins folder.&amp;#160; If an instance is already running, the new instance will just exit.&amp;#160; Similarly, if you launch the executable when another instance is running, the existing instance will show itself and the new instance will exit.&lt;/p&gt;    &lt;p&gt;It’s important to note that standard users don’t have write access to the &lt;i&gt;Program Files &lt;/i&gt;folder.&amp;#160; For this reason, addins need to be stored in the user’s local profile folder.&amp;#160; System-level addins can be stored in the &lt;i&gt;ProgramData &lt;/i&gt;folder.&amp;#160; Addins could be in the user’s roaming profile folder, but I haven’t thought through all of that yet.&amp;#160; (For example, if a user logs into different machines, an addin might not run on each system due to different hardware configurations.)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Disabling an addin&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Disabling an addin should be a simple matter of renaming the addin folder.&amp;#160; You can’t do this at runtime though, since the DLL’s are locked and loaded.&amp;#160; As an alternative, I create a file (zero-length) with the same name and add the .disable extension to it.&amp;#160; I check for this upon startup and before loading, and can handle it properly.&lt;/p&gt;    &lt;p&gt;Enabling and removing addins are handled similarly, using .enable and .delete extensions on the zero-length files.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;Creating Addins&lt;/h3&gt;  &lt;p&gt;To create an addin, you need to 1) implement the &lt;b&gt;IWpfService &lt;/b&gt;interface, and 2) add the &lt;b&gt;WpfServiceMetadata &lt;/b&gt;attribute with a name for your addin.&amp;#160; From there, be sure to implement all the methods in the interface.&amp;#160; The &lt;b&gt;Start &lt;/b&gt;method is called at initialization (you shouldn’t take much time in the constructor), and &lt;b&gt;Stop &lt;/b&gt;is called at the end, for cleanup.&amp;#160; Any time you want to update the &lt;b&gt;Status&lt;/b&gt;, be sure to raise the &lt;b&gt;StatusChanged &lt;/b&gt;event.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;[WpfServiceMetadata(&lt;span class="str"&gt;&amp;quot;SampleAddin&amp;quot;&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SampleAddinImpl : IWpfService
{
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The final thing you’ll need to do is copy your addin DLL to a folder with your addin name, plus the .util extension (Yes, an extension on the folder name.&amp;#160; I do this in Visual Studio with a post-build event.&amp;#160; If you debug the application, it looks for an Addins folder under the current directory.&amp;#160; When started normally (such as when installed) it uses the local user profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/CreatingAnApplicationWithFullPluginSuppo_CF07/clip_image001_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/CreatingAnApplicationWithFullPluginSuppo_CF07/clip_image001_thumb.png" width="400" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you’re ready to distribute the addin, compress the DLL and any supporting files into the top-level of a ZIP file, then rename the .zip extension to .util.&amp;#160; You can load this from the Addins page of the app settings, or manually move it to the &lt;i&gt;MefUtilRuner\Addins&lt;/i&gt; folder in your local profile folder (&lt;i&gt;c:\users\{USERNAME}\AppData&lt;/i&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/CreatingAnApplicationWithFullPluginSuppo_CF07/clip_image002_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/CreatingAnApplicationWithFullPluginSuppo_CF07/clip_image002_thumb.png" width="457" height="283" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;TimedQueue&lt;/h3&gt;

&lt;p&gt;Message boxes, balloon help, status bars—these are all great ways to display a message to the user, but they all only show one string at a time.&amp;#160; If you call it again before the reader has the chance to see it, it’s just gone.&amp;#160; There are some nice message managers that make it easy to manage stacking alerts, but I decided to stick with the built-in balloon help provider, and just manage how often I send changes.&amp;#160; It’s basically a buffered balloon provider that will only show messages every x number of seconds, regardless of how many attempts the application makes.&amp;#160; To use it, simply add items to the collection.&amp;#160; An event is raised whenever an item is available.&amp;#160; If an item has exceeded the maximum time-to-live threshold, the users of the collection never see it.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Repeat while there are items (one pulse may occur with several items ready)&lt;/span&gt;
&lt;span class="kwrd"&gt;while&lt;/span&gt; (item != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
{
    &lt;span class="rem"&gt;// If this is an old item, no event is raised.  This could happen if&lt;/span&gt;
    &lt;span class="rem"&gt;// a process goes into a loop and dumps a large number in a very short&lt;/span&gt;
    &lt;span class="rem"&gt;// amount of time.  &lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (DateTime.Now.Subtract(item.TimeStamp).TotalMilliseconds &amp;lt; _maxTTL)
    {
        RaiseEvent(item.Item);
        Thread.Sleep(_interval);
    }

    item = &lt;span class="kwrd"&gt;default&lt;/span&gt;(ItemWrapper&amp;lt;T&amp;gt;);

    &lt;span class="kwrd"&gt;lock&lt;/span&gt; (_lock)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt;( _items.Count &amp;gt; 0 )
            item = _items.Dequeue();
    }
}&lt;/pre&gt;

&lt;p&gt;The main window creates an instance of the TimedQueue class.&amp;#160; Every time an addin wants to display a message, it’s added to the collection.&amp;#160; When &lt;b&gt;ItemAvailableEvent&lt;/b&gt; fires, it’s dispatched to the UI thread to be displayed.&amp;#160; Dispatching prevents cross-threading issues between the background &lt;b&gt;TimedQueue &lt;/b&gt;thread and the UI thread.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; statuses_ItemAvailableEvent(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender,
    ItemAvailableEventArgs&amp;lt;StatusMessage&amp;gt; e)
{
    Dispatcher.BeginInvoke((ThreadStart)&lt;span class="kwrd"&gt;delegate&lt;/span&gt;() {
        StatusUpdatedHandler(e.Item); }
        , DispatcherPriority.Background);
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Though this instance is being used for status messages, you can also use &lt;b&gt;TimedQueue &lt;/b&gt;for other purposes, when you are willing to lose old messages.&amp;#160; One example would be to throttle user input, such as a game that doesn’t want constant firing or jumping as fast as the user clicks a button.&lt;/p&gt;

&lt;h3&gt;Next Steps&lt;/h3&gt;

&lt;p&gt;There are a number of things that would be nice to have in this application.&amp;#160; It would be good to allow utilities to extend the context menu to enable or disable something, or at least to jump straight to their configuration page.&lt;/p&gt;

&lt;p&gt;Using ClickOnce to deploy utilities would also be nice since it’s so clean for the user, but there is a cost:&amp;#160; ClickOnce is very strict about how applications can interact with the system.&amp;#160; They are always per-user, and they live in “secret” folders.&amp;#160; Developers can’t read or write to the hard drive except to protected storage (similar to the iPhone I suppose).&amp;#160; I’m not sure if they are restricted in other ways, but it could cause a hardship.&lt;/p&gt;

&lt;p&gt;It would also be nice if addins could be added at runtime.&amp;#160; This is a fairly simple case, but I didn’t get to it yet.&amp;#160; Furthermore, if you add, you might expect to enable/disable/remove at runtime too.&amp;#160; Unfortunately, disabling and removing aren’t really possible.&amp;#160; Sure, I could call &lt;b&gt;Stop&lt;/b&gt; on a utility and remove it from the UI (and not call &lt;b&gt;Start &lt;/b&gt;on it next time), but that’s not really disabled since it could still be running until the next restart.&amp;#160; I couldn’t force it to die unless I used separate application domains, which I’m loath to do.&lt;/p&gt;

&lt;p&gt;Finally, I’d really like to get an “app store” type of repository going.&amp;#160; I imagine being able to publish utilities like Sidebar Gadgets or Windows Live Writer Plugins so users can browse, read information, and click-and-install.&amp;#160; That could be a really great way to make the idea take off. &lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;There are definitely some rough edges at this point, but it’s getting there.&amp;#160; The source code is fully available and I’d be willing to give commit access to anyone interested in moving things forward.&amp;#160; Just drop me a line!&lt;/p&gt;

&lt;h3&gt;About Arian&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.ariankulp.com"&gt;Arian Kulp&lt;/a&gt; is a software developer living in Western Oregon.&amp;#160; He creates samples, screencasts, demos, labs, and articles; speaks at programming events; and enjoys spending time with his family.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9941747" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/UtilRunner/default.aspx">UtilRunner</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Trace.Writing in your web applications</title><link>http://blogs.msdn.com/coding4fun/archive/2009/12/25/9941111.aspx</link><pubDate>Fri, 25 Dec 2009 08:45:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9941111</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9941111.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9941111</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9941111</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Trace.Writinginyourwebapplications_26D4/tracing_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="tracing" border="0" alt="tracing" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Trace.Writinginyourwebapplications_26D4/tracing_thumb.jpg" width="500" height="256" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We’ve talked in the past about debugging your application but if you can’t attach a debugger to your website, &lt;a href="http://blogs.msdn.com/webdevelopertips/archive/2009/12/18/tip-100-did-you-know-how-to-view-asp-net-trace-information.aspx"&gt;why not use the ASP.Net Tracing&lt;/a&gt;?&amp;#160; This acts very much like a &lt;strong&gt;Debug.WriteLine&lt;/strong&gt; in a Windows application but instead you do &lt;strong&gt;Trace.Write&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Since this does have some memory ramifications, you’ll have to add in a line to your web.config file under the &lt;strong&gt;System.Web&lt;/strong&gt; section.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="rem"&gt;&amp;lt;!-- Add me! --&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;trace&lt;/span&gt; &lt;span class="attr"&gt;enabled&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;mostRecent&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;pageOutput&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;requestLimit&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;20&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Then you just go to your trace.axd file.&amp;#160; So in an example where your application is in “WebSite1” and on your local development box, &lt;a href="http://localhost/WebSite1/trace.axd"&gt;http://localhost/WebSite1/trace.axd&lt;/a&gt; would be where to get this information&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9941111" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/debugging/default.aspx">debugging</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/ASP.Net/default.aspx">ASP.Net</category></item><item><title>IronRuby sketch up</title><link>http://blogs.msdn.com/coding4fun/archive/2009/12/16/9937778.aspx</link><pubDate>Wed, 16 Dec 2009 18:20:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9937778</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9937778.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9937778</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9937778</wfw:comment><description>&lt;p&gt;&lt;a href="http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html"&gt;Jimmy Schementi posted about his talk at RubyConf 2009&lt;/a&gt; and talked about embedding IronRuby in another program.&amp;#160; His goals were:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;2D rendering surface with simple primitive shapes &lt;/li&gt;    &lt;li&gt;Simple animation support – callbacks for each frame and each object on the canvas &lt;/li&gt;    &lt;li&gt;User-loadable “macros” for drawing and animating&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;His outcome looks amazing!&amp;#160; It is worth noting Jimmy is using Visual Studio 2010 beta 2 for the demo here.&amp;#160; His blog states he hasn’t tried it in Visual Studio 2008.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:7be7f167-1ea1-4505-9525-9cfe595696eb" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;object width="400" height="280"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8185302&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=8185302&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="280"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9937778" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/IronRuby/default.aspx">IronRuby</category></item></channel></rss>