<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/Clint/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/Clint/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/Clint/Posts</link>
    <language>en</language>
    <pubDate>Sat, 18 May 2013 22:28:24 GMT</pubDate>
    <lastBuildDate>Sat, 18 May 2013 22:28:24 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>681</c9:totalResults>
    <c9:pageCount>28</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>MissionControl - A Flexible API for Remote Device Control</title>
      <description><![CDATA[<p>In a race to optimize everything, developers often go to extremes to build software that performs routine tasks. MissionControl is a system that allows users to program a control center that stores interfaces with attached hardware sensors, allowing the users to control any other devices that can be activated via the underlying protocol. For demo purposes, the MissionControl build at this point is compatible with the Phidgets IR hybrid sensor.</p><p>The system has two core components:</p><ul><li>A server application, which is a Win32 console application that handles incoming queries and returns data to the connected clients. This application runs on the desktop machine with the connected sensor. </li><li>The Windows Phone application that sends requests to the target server and can trigger a variety of pre-programmed commands. </li></ul><h1>The Basics</h1><h3>Hardware and Communication Infrastructure</h3><p>One of the most important parts of the project is the signal capture and replication hardware. For the purposes of this project, I decided to use a dual-mode <a href="http://www.phidgets.com/products.php?product_id=1055_0">Phidgets IR sensor</a>. It supports both IR code capture and subsequent replication. From a user’s perspective, this device also eliminates a substantial code-learning overhead as well as the potential error rate. Instead of searching for a device-specific hexadecimal sequence that later has to be transformed in a working IR code, the user simply has to point his remote control at the sensor and press the button that he wants accessible from a mobile device. Given that the capturing software is running on the target machine, once the sensor detects that a code can be repeated within an acceptable precision range, it will be automatically captured and stored, with all required transformations worked out in the backend using the free Phidgets SDK.</p><h3><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0026.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb3.jpg" alt="clip_image002" width="368" height="246" border="0"></a></h3><p>Even though I can, I don’t have to handle the binary code content received through the sensor—the Phidgets .NET libraries carry built-in types that contain all the processed metadata that I will discuss later in this article.</p><p>This sensor is connected through a USB port to a machine that acts as a communication gateway. This server should have port 6169 open for inbound connections.</p><p><strong>NOTE:</strong> <em>The port number can be changed, but you have to keep it consistent between your server and client applications.</em></p><p>The communication between the phone and the computer running the client is performed via a TCP channel—<a href="http://en.wikipedia.org/wiki/Internet_socket">sockets</a> are used to perform the initial connections and serialized data transfer. You can see the generalized data flow between the devices that are involved in the procedure in the graphic below:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0046.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb3.jpg" alt="clip_image004" width="520" height="289" border="0"></a></p><p>The server (desktop client) handles the local storage and release of all incoming IR codes. The mobile client has to know the location of the server—once specified and confirmed, it can send one of the pre-defined commands to it and either query the server for existing command groups (sets) or invoke one of the stored IR codes. When I pass data between devices, I use JSON for the serializable components. The data is also processed before being sent in order to speed-up the process—for example, on the server side the sets are serialized together with the associated codes. Like this:</p><p><pre class="brush: js">
[
{
    &quot;Name&quot;:&quot;batman&quot;,
    &quot;IsList&quot;:false,
    &quot;Commands&quot;:[
    {
        &quot;Name&quot;:&quot;test command&quot;,
        &quot;Code&quot;:{
            &quot;Mask&quot;:{
                &quot;BitSize&quot;:12,
                &quot;CodeData&quot;:&quot;AAA=&quot;
            },
            &quot;BitSize&quot;:12,
            &quot;Encoding&quot;:2,
            &quot;CarrierFrequency&quot;:38000,
            &quot;DutyCycle&quot;:50,
            &quot;Gap&quot;:44761,
            &quot;Header&quot;:[
            2374,
            606
            ],
            &quot;CodeData&quot;:&quot;DJA=&quot;,
            &quot;MinRepeat&quot;:5,
            &quot;One&quot;:[
            1189,
            606
            ],
            &quot;Repeat&quot;:null,
            &quot;Trail&quot;:0,
            &quot;Zero&quot;:[
            582,
            606
            ]
        }
    },
    {
        &quot;Name&quot;:&quot;turn off&quot;,
        &quot;Code&quot;:{
            &quot;Mask&quot;:{
                &quot;BitSize&quot;:12,
                &quot;CodeData&quot;:&quot;AAA=&quot;
            },
            &quot;BitSize&quot;:12,
            &quot;Encoding&quot;:2,
            &quot;CarrierFrequency&quot;:38000,
            &quot;DutyCycle&quot;:50,
            &quot;Gap&quot;:44770,
            &quot;Header&quot;:[
            2360,
            613
            ],
            &quot;CodeData&quot;:&quot;DJA=&quot;,
            &quot;MinRepeat&quot;:5,
            &quot;One&quot;:[
            1169,
            613
            ],
            &quot;Repeat&quot;:null,
            &quot;Trail&quot;:0,
            &quot;Zero&quot;:[
            585,
            613
            ]
        }
    }
    ]
}
]
</pre></p><p>The inherent problem with the JSON data above is the fact that the phone client does not need the information related to the code binary sequence and all the metadata that goes with it. So it is effectively stripped down and reduced to the names of the sets (when a list of sets is requested) and commands (when a list of commands is requested).</p><h3>The Data Model</h3><p>As you saw from the description above, the server organizes individual infrared codes in sets. A single set is a bundle of codes that may or may not be related to each other—ultimately, this is the user’s decision. A good example of using sets is organizing IR commands by rooms, devices or code types. Each set has a unique name on the server, therefore eliminating the possibility of a request conflict.</p><p>Each set stores individual commands built around the <strong>Command</strong> model:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{ 
    public class Command 
    { 
        public Command() 
        { 
        } 
    
    public string Name { get; set; }     
    public SerializableIRCode Code { get; set; } 
    } 
}
</pre></p><p>Despite the obvious <strong>Name</strong> property, you can see that I am using a <strong>SerializableIRCode</strong> instance that is specific to each model. Before going any further, I need to mention that the Phidgets SDK offers the <strong>IRLearnedCode</strong> model to store code contents. I could have used it instead, but there is an issue that prevents me from doing that—there is no public constructor defined for <strong>IRLearnedCode</strong>, therefore there is no way to serialize it, either with the built-in .NET serialization capabilities or JSON.NET, which I am using in the context of the project.</p><p>Instead, I have this:</p><p><pre class="brush: csharp">
using Phidgets; 
namespace Coding4Fun.MissionControl.API.Models 
{     
    public class SerializableIRCode     
    {         
        public SerializableIRCode()         
        { 
            
        } 
        
    IRLearnedCode code;         
    public ToggleMask Mask { get; set; } 
    public int BitSize { get; set; } 
    public Phidgets.IRCodeInfo.IREncoding Encoding { get; set; } 
    public int CarrierFrequency { get; set; } 
    public int DutyCycle { get; set; } 
    public int Gap { get; set; } 
    public int[] Header { get; set; } 
    public byte[] CodeData { get; set; } 
    public int MinRepeat { get; set; } 
    public int[] One { get; set; } 
    public int[] Repeat { get; set; } 
    public int Trail { get; set; } 
    public int[] Zero { get; set; } 
    }     
}
</pre></p><p>It is an almost identical 1:1 copy of the original class, storing both the layout of the IR code and additional information related to its replication mechanism. You can learn more about each property listed in the model above by reading the <a href="http://www.phidgets.com/docs/IR_Remote_Control_Primer">official document on the topic</a>.</p><p><strong>ToggleMask</strong>, the identity bit carrier that helps marking the code as repeated or not, is also implemented through a built-in Phidgets SDK model, and it has the same problem as <strong>IRLearnedCode</strong>. I implemented this model to replace it in the serializable code:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{ 
    public class ToggleMask 
    { 
        public ToggleMask() 
        { 
            
        } 

    public int BitSize { get; set; }         
    public byte[] CodeData { get; set; } 
    } 
}
</pre></p><p>I also needed an easy way to store all sets at once and carry all associated codes in a single instance retrieved from the storage. Here is the <strong>Set</strong> class:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{     
    public class Set 
    { 
        public Set() 
        { 
            Commands = new List&lt;Command&gt;(); 
        } 
        
    public string Name { get; set; } 
    public bool IsList { get; set; } 
    public List&lt;Command&gt; Commands { get; set; } 
    } 
}
</pre></p><p>Notice that there is an <strong>IsList</strong> flag that allows me to specify how to display this specific list on the connecting device. This adds some level of flexibility for situations where the user wants to build a virtual remote for closely-related keys, such as digits. With that in mind, displaying those as a list might be inconvenient, wasting visual space on the client. But if the flag is set to false, the list can be displayed as a pad.</p><p>Also, when the server performs the data exchange, it provides a single “envelope” that allows the connecting device to easily understand what the server is trying to do:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Models 
{     
    public class ServerResponse     
    {     
    public string Identifier { get; set; }     
    public string Marker { get; set; }     
    public string Content { get; set; }     
    } 
}
</pre></p><p>The <strong>Identifier</strong> property carries the server IP address. That way, when a device receives a response, it is able to either accept it, because it knows that a response is requested from a target location, or discard it because the user is no longer using the specific server.</p><p><strong>Marker</strong> carries the command type of the sent command, therefore giving the Windows Phone application a hint as to what to do with the data. The server can send the following commands:</p><ul><li><em>SET_LIST</em> – returns the list of sets that are currently available on the server. </li><li><em>SET_COMMANDS<strong>:</strong>SET_NAME<strong>:</strong>IS_LIST</em> – returns the list of commands that are associated with a given set that is currently stored on the server. </li><li><em>NOTIFICATION</em> – send a simple notification to the client; no further action is required. </li></ul><p>Last but not least, <strong>Content</strong> is used to push the necessary data that is associated with the given <strong>Marker</strong>. It can be either a JSON-based string that lists the sets or commands, or a plain-text message that is used as an alert for the end-user.</p><h1>Server Architecture</h1><p>The server is the only component of this entire system that does all the heavy lifting. It learns commands, stores them and then generates new IR signal requests, as controlled from any of the connected clients. Let’s take a closer look at what happens behind the scenes—to start, I am going to document the network infrastructure.</p><h3>The Network Layer</h3><p>In order to be a reliable system, the server needs to be always ready to accept an incoming connection. For that purpose, it is possible to use the <a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx">TcpListener</a> class—an “always on” receiver that can handle incoming TCP connections. I integrated it in my <strong>CoreStarter</strong> class that is used to start the listener when the application is launched:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API 
{ 
    public class CoreStarter 
    { 
        static TcpListener listener; 
        
        public static void LaunchSocket()     
        {     
            Console.WriteLine(&quot;Starting socket server on port {0}...&quot;, Constants.DEFAULT_PORT); 
            listener = new TcpListener(NetworkHelper.GetLocalIPAddress(), Constants.DEFAULT_PORT); 
            listener.Start(); 
            
            for (int i = 0; i &lt; Constants.MAX_CONCURRENT_CLIENTS; i&#43;&#43;) 
            {     
                Thread socketThread = new Thread(new ThreadStart(ListenForData));     
                socketThread.Start(); 
            } 
        } 
        
        private static void ListenForData() 
        { 
            Console.WriteLine(&quot;Listener thread started.&quot;); 

            while (true) 
            { 
                Socket acceptedSocket = listener.AcceptSocket(); 
                using (MemoryStream coreStream = new MemoryStream()) 
                {     
                    try 
                    { 
                        Console.WriteLine(&quot;Incoming connection: {0}&quot;, acceptedSocket.RemoteEndPoint); 
                        
                        using (Stream sourceStream = new NetworkStream(acceptedSocket)) 
                        {     
                            sourceStream.ReadTimeout = Constants.SOCKET_READ_TIMEOUT; 
                            
                            byte[] buffer = new byte[Constants.DEFAULT_BUFFER_SIZE]; 
                            int i; 
                
                            while ((i = sourceStream.Read(buffer, 0, buffer.Length)) != 0) 
                            { 
                                coreStream.Write(buffer, 0, i); 
                            } 
                        } 
                    } 
                    catch 
                    { 
                        string data = Encoding.ASCII.GetString(coreStream.ToArray()); 
        
                        CommandHelper.InterpretCommand(data, acceptedSocket.RemoteEndPoint.ToString()); 
                    } 
                } 
            } 
        } 
    } 
}
</pre></p><p>When <strong>LaunchSocket</strong> is called, the listener is activated on the current machine. As I mentioned above, the port number can be arbitrarily assigned, but has to be consistent between connecting apps in order for the TCP links to be established. Because I expect that more than one device will be connecting to the service at a time, the listener is set as active across a constant number of threads.</p><p><strong>NOTE:</strong> By default, a there is a maximum limit of 5 simultaneous clients. Although this number can be adjusted, be aware of the requirements of each environment in which a limited number of potential devices can connect. Even though the performance footprint of each thread is minimal, it can have a negative effect if used in unnecessarily large instances.</p><p><strong>ListenForData</strong> is used to read the incoming stream. When an inbound connection is accepted, the data is read with the help of a fixed content buffer. Then a read timeout is specified to prevent situations where the stream was completely read but the application still waits to pull non-existent data. Once the timeout milestone is hit, an exception is thrown, which marks the end of the stream—at this point, the plain text data that was received (remember that both the server and client exchange text data only) is passed to the command interpreter—<strong>CommandHelper</strong>, with a reference to the source of the command.</p><p>The commands from the device are passed as serialized key-value pairs (<a href="http://msdn.microsoft.com/en-us/library/5tbh8a42.aspx">KeyValuePair&lt;T, T&gt;</a>), the key being the command with any possible suffixes, and the value being the contents of the command itself that helps the server identify the specific item in the local storage.</p><p><strong>InterpretCommand</strong>,in this case, does three things sequentially:</p><ol><li>Deserialize the incoming string and create a <strong>KeyValuePair&lt;string,string&gt;</strong> instance. </li><li>Process the command and check whether it is recognizable. </li><li>Send a response to the client, if deemed necessary by the command type. </li></ol><p>The serialization and deserialization is done via <a href="http://james.newtonking.com/projects/json-net.aspx">JSON.NET</a>. You can install this package in your console managed Win32 project and the Windows Phone application project via NuGet:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0056.gif"><img title="clip_image005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image005_thumb3.gif" alt="clip_image005" width="553" height="65" border="0"></a></p><p>The deserialization step is as simple as one line of C# code:</p><p><pre class="brush: csharp">
KeyValuePair&lt;string, string&gt; result = JsonConvert.DeserializeObject&lt;KeyValuePair&lt;string, string&gt;&gt;(rawCommand.Remove(0, rawCommand.IndexOf('{')));
</pre></p><p>The string is sanitized to ensure that only JSON content is being passed to the serializer.</p><p>Because of a relatively limited command set, I can put together the entire interpretation stack like this:</p><p><pre class="brush: csharp">
// Get the initial list of sets on the target server
if (result.Key == Constants.COMMAND_INIT)
{
    SendSets(sourceLocation);
}
// Create a new set on the target server
else if (result.Key.Contains(Constants.COMMAND_CREATE_SET))
{
    CreateSet(result, sourceLocation);
    SendSets(sourceLocation);
}
// Get the commands that are associated with a given set.
else if (result.Key == Constants.COMMAND_GET_COMMANDS)
{
    SendCommands(result.Value, sourceLocation);
}
// The client requested the server to learn a new command.
else if (result.Key.Contains(Constants.COMMAND_LEARN_COMMAND))
{
    LearnCommand(result, sourceLocation);
}
// The client requested one of the commands to be executed on the 
// target server.
else if (result.Key.Contains(Constants.COMMAND_EXECUTE))
{
    ExecuteCommand(result);
}
// The client has requested a set to be deleted from the target server.
else if (result.Key == Constants.COMMAND_DELETE_SET)
{
    DeleteSet(result.Value);
    SendSets(sourceLocation);
}
// The client has requested a set to be deleted from the target server.
else if (result.Key.Contains(Constants.COMMAND_DELETE_COMMAND))
{
    DeleteCommand(result);
    SendCommands(result.Key.Split(new char[] { ':' })[1], sourceLocation);
}
</pre></p><p>All commands are constants, declared in the local helper class:</p><p><pre class="brush: csharp">
public const string COMMAND_INIT = &quot;INIT&quot;; 

public const string COMMAND_CREATE_SET = &quot;CREATE_SET&quot;; 

public const string COMMAND_GET_COMMANDS = &quot;GET_COMMANDS&quot;; 

public const string COMMAND_LEARN_COMMAND = &quot;LEARN_COMMAND&quot;; 

public const string COMMAND_EXECUTE = &quot;EXECUTE&quot;; 

public const string COMMAND_DELETE_SET = &quot;DELETE_SET&quot;;
public const string COMMAND_DELETE_COMMAND = &quot;DELETE_COMMAND&quot;;
</pre></p><p>Notice that these are not the commands that the server sends back, but rather the commands it receives from connecting Windows Phone devices.</p><p>Let’s now take a look at the breakdown for each command.</p><p><strong>SendSets:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Send the list of sets to the client that requested those. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt; 
private static void SendSets(string sourceLocation) 
{ 
    Console.WriteLine(&quot;Received an initial set query from {0}&quot;, sourceLocation);     
    ServerResponse response = new ServerResponse(); 
    response.Marker = &quot;SET_LIST&quot;; 
    response.Content = JsonConvert.SerializeObject(StorageHelper.GetRawSetNames()); 
    response.Identifier = NetworkHelper.GetLocalIPAddress().ToString(); 
    NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response)); 
    Console.WriteLine(&quot;Sent the set list to {0}&quot;, sourceLocation);     
}
</pre></p><p>When this command is received, the server does not have to do much processing. It is only invoked when the client establishes the initiating link and needs to know what possible sets it can get from the target machine. The request is logged in the console and a server response is prepared that contains a serialized list of set names, which is later serialized as well and sent back to the source machine location.</p><p><strong>StorageHelper</strong> and <strong>NetworkHelper</strong> will be documented later in this article.</p><p><strong>CreateSet:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Create a new set and store it on the local server. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;result&quot;&gt;The original deserialized command.&lt;/param&gt; 
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt; 
private static void CreateSet(KeyValuePair&lt;string,string&gt; result, string sourceLocation) 
{ 
    bool isSuccessful = false; 
    string[] data = result.Key.Split(new char[] { ':' }); 
    
    Console.WriteLine(&quot;There is an attempt to create the {0} set from {1}.&quot;, result.Value, sourceLocation); 
    
    if (data[1].ToLower() == &quot;list&quot;) 
        isSuccessful = StorageHelper.AddSet(result.Value); 
    else 
        isSuccessful = StorageHelper.AddSet(result.Value, false); 
    
    if (isSuccessful) 
        Console.WriteLine(&quot;The {0} set was successfully created.&quot;, result.Value); 
    else 
        Console.WriteLine(&quot;Something happened and the {0} set was not created.&quot;, result.Value);     
}
</pre></p><p>When a mobile device attempts to create a new set on the server, it sends a command in the following format:</p><p><strong>CREATE_SET</strong>:<strong>list/pad</strong>, <strong>SET_NAME</strong></p><p>CreateSet will get the type of the set that was created, will check whether a set with the same name already exists and will either create it or ignore the command altogether. No notification is sent to the connecting device, but either the failure or the success of the command is registered in the local console.</p><p><strong>SendCommands:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt;
/// Send a list of commands that are associated with the pushed set.
/// &lt;/summary&gt;
/// &lt;param name=&quot;setName&quot;&gt;The original deserialized command.&lt;/param&gt;
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt;
private static void SendCommands(string setName, string sourceLocation)
{
    Console.WriteLine(&quot;There was a request to get the commands for the {0} set from {1}.&quot;, setName, sourceLocation);
    
    bool isList = StorageHelper.IsSetAList(setName);
    
    ServerResponse response = new ServerResponse();
    response.Marker = string.Format(&quot;SET_COMMANDS:{0}:{1}&quot;, setName, isList);
    response.Identifier = NetworkHelper.GetLocalIPAddress().ToString();
    response.Content = JsonConvert.SerializeObject(StorageHelper.GetRawCommandNames(setName));
    
    NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response));
    
    Console.WriteLine(&quot;Command list for the {0} set were sent to {1}.&quot;, setName, sourceLocation);
}
</pre></p><p>Commands are sent in the same manner as sets—once the set is recognized, the names of the associated commands are retrieved and serialized inside a <strong>ServerResponse</strong> instance and then pushed back to the requesting device.</p><p><strong>LearnCommand:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Learn a new command and store it on the target server. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;result&quot;&gt;The original deserialized command.&lt;/param&gt; 
/// &lt;param name=&quot;sourceLocation&quot;&gt;The location of the requesting client.&lt;/param&gt; 
private static void LearnCommand(KeyValuePair&lt;string,string&gt; result, string sourceLocation) 
{     
    Console.WriteLine(&quot;[!] Server in COMMAND LEARNING MODE! Point the remote towards the sensor and send a command.&quot;); 
    
    string[] data = result.Key.Split(new char[] { ':' });     
    var set = StorageHelper.GetSingleSet(StorageHelper.GetSets(), data[1]); 
    
    if (set != null)     
    {     
        if ((from c in set.Commands where c.Name == result.Value select c).FirstOrDefault() != null) 
        {     
            Console.WriteLine(&quot;Cannot learn command {0} for the following set: {1}. Command already exists.&quot;, data[1], result.Value); 
            
            ServerResponse response = new ServerResponse();     
            response.Marker = &quot;NOTIFICATION&quot;;     
            response.Identifier = NetworkHelper.GetLocalIPAddress().ToString(); 
            response.Content = &quot;We could not save the following command - &quot; &#43; result.Value &#43; &quot;. It already exists in the set.&quot;; 
            
            NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response));     
        } 
        else 
        { 
            if (sensor == null) 
                sensor = new IR(); 
            
            sensor.open(-1); 

            sensor.waitForAttachment(); 
    
            sensor.Learn &#43;= (sender, args) =&gt; 
            { 
                Console.WriteLine(&quot;[!] Server learned the command and is no longer in COMMAND LEARNING MODE.&quot;); 
                IRLearnedCode code = args.LearnedCode; 
                code.CodeInfo.MinRepeat = 5; 
            
                Command command = new Command(); 
                command.Name = result.Value; 
                command.Code = IRCodeWorker.GetSerializableIRCode(code); 
                
                StorageHelper.AddCommand(command, set.Name); 
                
                ServerResponse response = new ServerResponse(); 
                response.Marker = &quot;NOTIFICATION&quot;; 
                response.Identifier = NetworkHelper.GetLocalIPAddress().ToString(); 
                response.Content = &quot;The following command has been stored: &quot; &#43; result.Value; 
                
                NetworkHelper.SendData(sourceLocation, JsonConvert.SerializeObject(response)); 
            }; 
        } 
    } 
}
</pre></p><p>Once a request was received that the server needs to learn a new command, an initial verification is done to make sure that the requested command name and set are not already taken. If neither the command nor the set exist, both will be created.</p><p>After the basic setup is complete, the IR sensor is activated and will be waiting for the command to be learned. The way it works is quite simple – the sensor will remain in learning mode until the point where it recognizes a command without error, being 100% sure that it can be reproduced internally. You will need to point your remote towards the sensor and hold the button you want captured for one or two seconds in order for the command to be learned.</p><p><strong>NOTE:</strong> To ensure that a proper transmission is done, I manually set the minimal repeat value to 5. This is the number of times the sensor will fire the same code towards the target. That is the optimal value for a target device to receive the code if the remote is pointed directly at it without necessarily triggering the same command twice or more.</p><p>After the command is learned, the code is processed and transformed into a serializable instance. The connecting client is then notified about whether the command was learned.</p><p><strong>ExecuteCommand:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Execute one of the commands currently stored on the local server. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;result&quot;&gt;The original deserialized command.&lt;/param&gt; 
private static void ExecuteCommand(KeyValuePair&lt;string,string&gt; result) 
{ 
    string[] data = result.Key.Split(new char[] { ':' }); 

    var set = StorageHelper.GetSingleSet(StorageHelper.GetSets(), data[1]); 
    
    if (set != null) 
    {     
        var command = StorageHelper.GetSingleCommand(StorageHelper.GetCommands(set.Name), result.Value); 

        IRLearnedCode code = IRCodeWorker.GetLearnedCode(command.Code); 
        
        if (sensor == null) 
            sensor = new IR(); 

        sensor.open(-1); 
        sensor.waitForAttachment(); 
        sensor.transmit(code.Code, code.CodeInfo); 
        sensor.close(); 
    } 
}
</pre></p><p>Command execution relies on the hardware sensor. The phone sends a command execution request in the following format:</p><p><strong>EXECUTE</strong>:<strong>SET_NAME</strong>, <strong>COMMAND_NAME</strong></p><p>Once the command is parsed out and found in the local storage, the IR code is transformed back to a model that is recognizable by the Phidgets SDK and transmitted towards the location where the sensor is pointed at the time of the execution.</p><p><strong>DeleteSet:</strong></p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Delete a single set and all the associated commands 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;target&quot;&gt;The name of the set.&lt;/param&gt; 
private static void DeleteSet(string target) 
{ 
    var sets = StorageHelper.GetSets(); 
    var targetSet = StorageHelper.GetSingleSet(sets, target); 
    
    if (targetSet != null) 
    { 
        StorageHelper.RemoveSet(sets, targetSet); 
    } 
}
</pre></p><p>When deleting a set, only the name of the set should be specified. The user will get a warning on the client side that requires a confirmation of the deletion. The server will blindly execute the command.</p><p><strong>DeleteCommand:</strong></p><p><pre class="brush: csharp">
private static void DeleteCommand(KeyValuePair&lt;string, string&gt; result)
{
    var sets = StorageHelper.GetSets();
    string setName = result.Key.Split(new char[] {':'})[1];
    var targetSet = StorageHelper.GetSingleSet(sets, setName);
    var command = (from c in targetSet.Commands where c.Name == result.Value select c).FirstOrDefault();
    
    if (command != null)
    {
        targetSet.Commands.Remove(command);
        StorageHelper.SerializeSets(sets);
    }
}
</pre></p><p>Not only can the user remove entire sets, but he can also target specific commands from a given set. Once a <strong>DELETE_COMMAND</strong> directive is recognized, the set name is parsed out from the original string, that follows the <strong>DELETE_COMMAND:SET_NAME, COMMAND_NAME</strong> format, and a simple LINQ query extracts the command instance, removes it and stores the set content on the local hard drive.</p><p>Notice that for some commands, particularly for set creation, deletion and command deletion, the server will return a list of the remaining items. The contents will be automatically updated on the devices, which will be waiting for that response. This measure was deliberately introduced to minimize the chances of a user triggering a command that was already deleted or trying to query a previously removed set.</p><h3>Transforming Codes</h3><p>You might have noticed that I am using <strong>IRCodeWorker.GetSerializableCodeType</strong> to transform a Phidgets SDK native IR code model into a serializable one. This is a helper function that performs a field copy of the existing object. Because of the differences in the model structure, it has to be done manually:</p><p><pre class="brush: csharp">
public static SerializableIRCode GetSerializableIRCode(IRLearnedCode code) 
{ 
    SerializableIRCode sCode = new SerializableIRCode();     
    sCode.BitSize = code.Code.BitCount;     
    sCode.Encoding = code.CodeInfo.Encoding;     
    sCode.CarrierFrequency = code.CodeInfo.CarrierFrequency;     
    sCode.CodeData = code.Code.Data;     
    sCode.DutyCycle = code.CodeInfo.DutyCycle;     
    sCode.Gap = code.CodeInfo.Gap;     
    sCode.Header = code.CodeInfo.Header;     
    sCode.MinRepeat = 5;     
    sCode.One = code.CodeInfo.One;     
    sCode.Repeat = code.CodeInfo.Repeat;     
    sCode.Trail = code.CodeInfo.Trail;     
    sCode.Zero = code.CodeInfo.Zero;     
    sCode.Mask = new ToggleMask()     
    {         
        BitSize = code.CodeInfo.ToggleMask.BitCount,         
        CodeData = code.CodeInfo.ToggleMask.Data         
    }; 
    
    return sCode;     
}
</pre></p><p>The reverse process is easier because I can pass each of the existing properties to the <strong>IRCodeInfo</strong> constructor. The only difference is the fact that I need to use Reflection to create an instance of <strong>IRLearnedCode</strong> because there is no public constructor defined and a dynamic object has to be created:</p><p><pre class="brush: csharp">
internal static IRLearnedCode GetLearnedCode(SerializableIRCode serializableIRCode) 
{ 
    IRCode code = new IRCode(serializableIRCode.CodeData, serializableIRCode.BitSize);     
    IRCodeInfo info = new IRCodeInfo(serializableIRCode.Encoding, serializableIRCode.BitSize, serializableIRCode.Header,     
    serializableIRCode.Zero, serializableIRCode.One, serializableIRCode.Trail, serializableIRCode.Gap, serializableIRCode.Repeat, 
serializableIRCode.MinRepeat, serializableIRCode.Mask.CodeData, IRCodeInfo.IRCodeLength.Constant,
serializableIRCode.CarrierFrequency, serializableIRCode.DutyCycle); 
    
    object[] parameters = new object[] { code, info }; 
    
    BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; 
    object instantType = Activator.CreateInstance(typeof(IRLearnedCode), flags, null, parameters, null); 

    return (IRLearnedCode)instantType; 
}
</pre></p><h3>Command and Set Management</h3><p>Looking back at the code that I put together for the command interpreter, there is one class that does all local content manipulation—<strong>StorageHelper</strong>. This is a simple class that performs LINQ queries on set as well as command collections, and makes sure that all the changes are preserved in the <strong>sets.xml</strong> file in the application folder that is used as the only storage place for all the content that is being manipulated by the server.</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API.Helpers 
{ 
    public class StorageHelper 
    { 
        
        /// &lt;summary&gt; 
        /// Lists all available sets that are currently stored on the server.         
        /// &lt;/summary&gt; 
        /// &lt;returns&gt;List of sets on the machine.&lt;/returns&gt;         
        internal static List&lt;Set&gt; GetSets()         
        {             
            List&lt;Set&gt; sets = null; 
            
            string rawContent = GetRawSets();             
            sets = JsonConvert.DeserializeObject&lt;List&lt;Set&gt;&gt;(rawContent); 
            
            return sets;             
        } 
        
        /// &lt;summary&gt;         
        /// Returns the list of commands that are associated with the given set.         
        /// &lt;/summary&gt;         
        /// &lt;param name=&quot;setName&quot;&gt;The name of the target set.&lt;/param&gt;         
        /// &lt;returns&gt;List of commands associated with the given set.&lt;/returns&gt;         
        internal static List&lt;Command&gt; GetCommands(string setName)         
        {             
            List&lt;Command&gt; commandList = null; 
            
            var sets = GetSets(); 
            
            Set singleSet = null;             
            if (sets != null)             
                singleSet = (from c in sets where c.Name == setName select c).FirstOrDefault(); 
            
            if (singleSet != null)         
            {         
                commandList = singleSet.Commands;     
            } 
            
            return commandList; 
        } 
        
        /// &lt;summary&gt;     
        /// Gets the list of names for the commands in the requested set. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;setName&quot;&gt;The name of the target set.&lt;/param&gt; 
        /// &lt;returns&gt;List of commands associated with the given set.&lt;/returns&gt; 
        internal static List&lt;string&gt; GetRawCommandNames(string setName) 
        { 
            List&lt;Command&gt; commandList = GetCommands(setName); 
            
            List&lt;string&gt; stringSet = null; 
            
            if (commandList != null) 
            {     
                stringSet = commandList.Select(x =&gt; x.Name).ToList();     
            } 
            
            return stringSet;     
        } 
        
        /// &lt;summary&gt; 
        /// Get the list of names for all sets on the local server. 
        /// &lt;/summary&gt; 
        /// &lt;returns&gt;List of sets on the machine.&lt;/returns&gt; 
        internal static List&lt;string&gt; GetRawSetNames() 
        {     
            List&lt;Set&gt; sets = GetSets(); 
            
            List&lt;string&gt; stringSet = null; 
    
            if (sets != null) 
            {     
                stringSet = sets.Select(x =&gt; x.Name).ToList();     
            } 
            
            return stringSet; 
        } 
        
        /// &lt;summary&gt; 
        /// Get the raw string contents of sets.xml. Should only be used in the 
        /// context of this class. 
        /// &lt;/summary&gt; 
        /// &lt;returns&gt;JSON string representing stored sets and commands.&lt;/returns&gt; 
        internal static string GetRawSets() 
        { 
            string sets = string.Empty; 
            
            if (File.Exists(&quot;sets&quot;)) 
            { 
                using (StreamReader reader = new StreamReader(File.OpenRead(&quot;sets&quot;))) 
                { 
                    sets = reader.ReadToEnd(); 
                } 
            } 
            else 
            { 
                FileStream stream = File.Create(&quot;sets.xml&quot;); 
                
                stream.Close();     
            } 
            
            return sets; 
        } 
        
        /// &lt;summary&gt; 
        /// Check whether a set is marked with a IsList flag. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;setName&quot;&gt;The name of the target set.&lt;/param&gt; 
        /// &lt;returns&gt;TRUE - set is a list. FALSE - set is not a list.&lt;/returns&gt; 
        internal static bool IsSetAList(string setName) 
        { 
            bool isList = true; 
            var sets = GetSets(); 
            Set set = null; 

            if (sets != null) 
                set = (from c in sets where c.Name == setName select c).FirstOrDefault(); 
            
            if (set != null) 
                isList = set.IsList; 
            
            return isList;     
        } 
        
        /// &lt;summary&gt; 
        /// Serialize the set collection to sets.xml 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;sets&quot;&gt;Collection to be serialized.&lt;/param&gt; 
        /// &lt;returns&gt;true if sets are serialized.&lt;/returns&gt; 
        private static bool SerializeSets(List&lt;Set&gt; sets) 
        { 
            try 
            { 
                using (StreamWriter writer = new StreamWriter(&quot;sets.xml&quot;, false)) 
                {     
                    string data = JsonConvert.SerializeObject(sets); 
            
                    writer.Write(data); 
                } 
                
                return true; 
            } 
            catch 
            {     
                return false;     
            } 
        } 
        
        /// &lt;summary&gt; 
        /// Add a new set to the existing global set collection. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;name&quot;&gt;Set name.&lt;/param&gt; 
        /// &lt;returns&gt;true if successfully added set.&lt;/returns&gt; 
        internal static bool AddSet(string name, bool isList = true) 
        { 
            var sets = GetSets(); 

            if (sets == null) 
                sets = new List&lt;Set&gt;(); 
            
            var singleSet = GetSingleSet(sets, name); 

            if (singleSet == null) 
                sets.Add(new Set { Name = name, IsList = isList }); 
            
            if (SerializeSets(sets)) 
                return true; 
            else 
                return false; 
        } 
        
        /// &lt;summary&gt; 
        /// Retrieves a single set from a collection that has a specific name. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;sets&quot;&gt;The source collection from which to extract the set.&lt;/param&gt; 
        /// &lt;param name=&quot;name&quot;&gt;The name of the set to get.&lt;/param&gt; 
        /// &lt;returns&gt;An instance of the found set, if any.&lt;/returns&gt; 
        internal static Set GetSingleSet(List&lt;Set&gt; sets, string name) 
        { 
            if (sets != null) 
                return (from c in sets where c.Name == name select c).FirstOrDefault(); 
            else 
                return null; 
        } 
        
        /// &lt;summary&gt; 
        /// Add a IR command to an existing set. If the set is not found, it will be created. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;command&quot;&gt;The command instance to be added.&lt;/param&gt; 
        /// &lt;param name=&quot;targetSet&quot;&gt;The name of the target set.&lt;/param&gt; 
        /// &lt;returns&gt;true if the command was successfully added.&lt;/returns&gt; 
        internal static bool AddCommand(Command command, string targetSet) 
        { 
            var sets = GetSets(); 
            
            if (sets == null) 
                sets = new List&lt;Set&gt;(); 
            
            var singleSet = GetSingleSet(sets, targetSet); 
            
            if (singleSet == null) 
                singleSet = new Set { Name = targetSet }; 
            
            var singleCommand = (from c in singleSet.Commands where c.Name == command.Name select c).FirstOrDefault(); 
            
            if (singleCommand == null) 
            { 
                singleSet.Commands.Add(command); 
                
                if (SerializeSets(sets)) 
                    return true; 
                else 
                    return false; 
            } 
            else 
                return false; 
        } 
        
        /// &lt;summary&gt; 
        /// Retrieve a single command instance from one of the sets on the local server. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;commands&quot;&gt;Original list of commands.&lt;/param&gt; 
        /// &lt;param name=&quot;name&quot;&gt;Name of the command to be retrieved.&lt;/param&gt; 
        /// &lt;returns&gt;An instance of the command, if found. NULL if not.&lt;/returns&gt; 
        internal static Command GetSingleCommand(List&lt;Command&gt; commands, string name) 
        { 
            if (commands != null) 
                return (from c in commands where c.Name == name select c).FirstOrDefault(); 
            else 
                return null; 
        } 
        
        /// &lt;summary&gt; 
        /// Remove a set from a local machine. 
        /// &lt;/summary&gt; 
        /// &lt;param name=&quot;sets&quot;&gt;Original list of sets.&lt;/param&gt; 
        /// &lt;param name=&quot;targetSet&quot;&gt;Name of the set to remove.&lt;/param&gt; 
        internal static void RemoveSet(List&lt;Set&gt; sets, Set targetSet) 
        { 
            sets.Remove(targetSet); 
            
            SerializeSets(sets); 
        } 
    } 
}
</pre></p><h2>Sending Data Back to the Client</h2><p><strong>SendData</strong> in the <strong>NetworkHelper</strong> class handles all outbound connections. Here is its structure:</p><p><pre class="brush: csharp">
/// &lt;summary&gt; 
/// Send data to the target network machine. 
/// &lt;/summary&gt; 
/// &lt;param name=&quot;destination&quot;&gt;The target machine IP.&lt;/param&gt; 
/// &lt;param name=&quot;data&quot;&gt;Data to be sent, in string format.&lt;/param&gt; 
/// &lt;param name=&quot;sanitizeIp&quot;&gt;Determines whether to remove the port from the given IP string.&lt;/param&gt; 
public static void SendData(string destination, string data, bool sanitizeIp = true) 
{ 
    using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
    {     
        string completeIp = string.Empty; 
        
        if (sanitizeIp)     
            completeIp = destination.Remove(destination.IndexOf(&quot;:&quot;), destination.Length - destination.IndexOf(&quot;:&quot;)); 
        
        client.Connect(completeIp, 6169); 
        client.Send(Encoding.UTF8.GetBytes(data));     
    }     
}
</pre></p><p>A new stream socket is created in order to connect to the target machine over the TCP pipe. If IP sanitization is enabled, the port is stripped from the address in order to pass a valid IP. A <strong>Socket</strong> instance cannot directly handle IPs of the format:</p><p><strong><em>255.255.255.0:PORT_NUMBER</em></strong></p><p>Later, in a synchronous manner, a connection is established and the data is sent.</p><p>At this point, you can see that the barebones service offers a flexible way to manage content. It can be accessed by any application type as long as the server can be accessed and the application can send commands in the pre-defined format and the content requested is actually located on the target server. This allows for high levels of extensibility and interoperability, as the server usage is not limited to a single platform. If I decide to create a Windows Store application that would allow me to control my TV, I simply need to add socket connection layer that will send plain strings to the machine where the IR sensor is connected.</p><p>Similarly, if some functionality needs to be added, it is possible to do so without ever touching the client applications. A modification in the endpoint will be reflected with no direct effect on all connection applications as long as all handled returned and requested values are preserved. The only additional requirement is that if the client applications want to take advantage of newly introduced capabilities, they need to have an updated command transmission layer for the new command types.</p><p>In <strong>Program.cs</strong>, I simply need to start the server through the <strong>CoreStarter</strong> class:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.API 
{ 
    class Program     
    {         
        static void Main(string[] args)         
        {             
            Console.WriteLine(&quot;Coding4Fun MissionControl Server&quot;);             
            CoreStarter.LaunchSocket();             
        }         
    }     
}
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0076.jpg"><img title="clip_image007" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image007_thumb3.jpg" alt="clip_image007" width="527" height="267" border="0"></a></p><h1>Mobile client overview</h1><p>The mobile client does not have the capability to send commands directly to the IR sensor. Instead, it connects to a remote machine that has the IR sensor plugged in and attempts to invoke a command from the list returned by the service. A single mobile client can support control over multiple servers.</p><p><strong>NOTE:</strong> Make sure that at the time of working with the Windows Phone client, the server is actually running on your local machine. To make it easier to test, also open port 6169 for incoming connections in Windows Firewall.</p><p>When building a Windows Phone application, make sure you have the <a href="http://developer.windowsphone.com/en-us/downloadsdk">proper version of the SDK installed</a>, as well as a <a href="http://en.wikipedia.org/wiki/Second_Level_Address_Translation">SLAT-compatible</a> machine if you plan on testing the application in the emulator.</p><h2>Networking Infrastructure</h2><p>The Windows Phone application also relies on a network infrastructure somewhat similar to that of the server. There is a TCP listener that is created when the application is started:</p><p><pre class="brush: csharp">
// Code to execute when the application is launching (eg, from Start) 
// This code will not execute when the application is reactivated 
private void Application_Launching(object sender, LaunchingEventArgs e) 
{ 
    ServiceSerializer.DeserializeServices(); 
    
    listener.OnClientConnected &#43;= listener_OnClientConnected; 
    listener.Start(6169); 
}
</pre></p><p>Here, listener is an instance of <strong>TcpSocketListener</strong>—a custom class designed to handle incoming network connections:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{ 
    public class TcpSocketListener : SocketConnectorBase     
    {     
        StreamSocketListener coreSocket; 
        
        public async void Start(int port)     
        {     
            coreSocket = new StreamSocketListener();         
            coreSocket.ConnectionReceived &#43;= coreSocket_ConnectionReceived; 
            
            try     
            {         
                await coreSocket.BindServiceNameAsync(port.ToString());         
            }     
            catch (Exception ex) 
            {     
                Debug.WriteLine(ex.Message); 
                
                coreSocket.Dispose();     
                coreSocket = null; 
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = false, DeviceID = string.Empty }); 
            } 
        } 
        
        async void coreSocket_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) 
        { 
            Debug.WriteLine(&quot;Connection received!&quot;); 
            
            DataReader reader = new DataReader(args.Socket.InputStream); 
            
            try 
            { 
                while (true) 
                { 
                    StringBuilder builder = new StringBuilder(); 
        
                    uint actualLength = 1; 

                    while (actualLength &gt; 0) 
                    {     
                        actualLength = await reader.LoadAsync(256); 
                        builder.Append(reader.ReadString(actualLength)); 
                    } 
                    
                    OnConnectionCompleted(new ConnectionEventArgs 
                    { 
                        Socket = args.Socket, 
                        IsSuccessful = true, 
                        DeviceID = args.Socket.Information.RemoteHostName.DisplayName, 
                        Token = builder.ToString() 
                    }); 
                    break; 
                } 
            } 
            catch (Exception exception) 
            { 
                Debug.WriteLine(exception.Message); 
                
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = false }); 
            } 
        } 
    } 
}
</pre></p><p>A <strong>StreamSocketListener</strong> is used for the connection core. When a connection is received, a continuous loop reads the entire contents of the incoming stream. <strong>OnConnectionCompleted</strong> is declared in the base class—<strong>SocketConnectorBase</strong>.</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{ 
    public class SocketConnectorBase 
    { 
        public event EventHandler&lt;ConnectionEventArgs&gt; OnClientConnected; 
        public virtual void OnConnectionCompleted(ConnectionEventArgs connectionArgs) 
        { 
            if (OnClientConnected != null) 
            { 
                OnClientConnected(this, connectionArgs); 
            } 
        } 
        
        public event EventHandler&lt;bool&gt; OnSendCompletedEvent; 
        public virtual void OnSendCompleted(bool succeeded) 
        { 
            if (OnSendCompletedEvent != null) 
            { 
                OnSendCompletedEvent(this, succeeded); 
            } 
        } 
    } 
    
    public class ConnectionEventArgs : EventArgs 
    { 
        public StreamSocket Socket { get; set; }     
        public string DeviceID { get; set; }     
        public string Token { get; set; }     
        public bool IsSuccessful { get; set; }     
    } 
}
</pre></p><p><strong>ConnectionEventArgs</strong> here is used to identify the content that is passed to the client. <strong>DeviceID</strong> gives access to the source IP, <strong>IsSuccessful</strong> tells the developer whether the established connection is active and the <strong>Token</strong> carries the raw string if any was received.</p><p>Sending data is simplified to the maximum with the help of the <strong>SocketClient</strong> class, which relies on a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.sockets.streamsocket.aspx">StreamSocket</a> instance that handles outbound connections and writing to the output stream:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{ 
    public class SocketClient : SocketConnectorBase 
    {     
        StreamSocket _socket; 
        
        public SocketClient() 
        {     
            _socket = new StreamSocket();     
        } 
        
        public SocketClient(StreamSocket socket) 
        {     
            _socket = socket;     
        } 
        
        public async void Connect(string hostName, int portNumber) 
        { 
            try 
            { 
                await _socket.ConnectAsync(new HostName(hostName), portNumber.ToString(), SocketProtectionLevel.PlainSocket); 
            
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = true }); 
            } 
            catch (Exception ex) 
            {     
                Debug.WriteLine(ex.Message); 
                
                OnConnectionCompleted(new ConnectionEventArgs { IsSuccessful = false });     
            } 
        } 
        
        public async void Send(string dataToSend) 
        { 
            try 
            {     
                using (DataWriter writer = new DataWriter(_socket.OutputStream)) 
                { 
                    // Write the length of the binary data that is being 
                    // sent to the client. 
                    writer.WriteUInt32((UInt32)dataToSend.Length); 
                    
                    writer.WriteString(dataToSend); 
        
                    // Send the actual data. 
                    await writer.StoreAsync(); 
                    
                    writer.DetachStream(); 
                    
                    OnSendCompleted(true); 
                } 
            } 
            catch 
            { 
                _socket.Dispose();     
                _socket = null;     
                OnSendCompleted(false);     
            }     
        }     
    }     
}
</pre></p><p>As with the listener class, <strong>SocketClient</strong> supports <strong>OnConnectionCompleted</strong> to notify the application that the connection attempt completed.</p><p>Back in <strong>App.xaml.cs</strong>, the data from the incoming connection captured by the <strong>TcpSocketListener</strong> instance is passed to the <strong>ResponseHelper</strong> class:</p><p><pre class="brush: csharp">
void listener_OnClientConnected(object sender, ConnectionEventArgs e) 
{ 
    ResponseHelper.HandleIncomingResponse(e.Token); 
}
</pre></p><p>This class reads the possible three commands sent by the server and interprets them, creating internal collections from the raw data if the current server IP matches the one obtained in the <strong>ServerResponse</strong> (the same model in the desktop application):</p><p><pre class="brush: csharp">
using Coding4Fun.MissionControl.WP.Models;
using Coding4Fun.MissionControl.WP.ViewModels;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;

namespace Coding4Fun.MissionControl.WP.Misc
{
        public class ResponseHelper
        {
                public static void HandleIncomingResponse(string rawResponse)
                {
                        if (rawResponse != null)
                        {
                                ServerResponse response = JsonConvert.DeserializeObject&lt;ServerResponse&gt;(rawResponse);
                
                                if (response.Marker == Constants.COMMAND_SERVER_NOTIFICATION)
                                {
                                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                                        {
                                                MessageBox.Show(response.Content, &quot;Server Response&quot;, MessageBoxButton.OK);
                                        });
                                }
                                else
                                {
                                        if (CommonViewModel.Instance.IsWaiting)
                                        {
                                                if (response.Identifier == CommonViewModel.Instance.CurrentServer.Location)
                                                {
                                                        // returns the list of sets that are associated with the current server.
                                                        if (response.Marker == Constants.COMMAND_SERVER_SET_LIST)
                                                        {
                                
                                                                List&lt;string&gt; items = JsonConvert.DeserializeObject&lt;List&lt;string&gt;&gt;(response.Content);
                                
                                                                if (items != null)
                                                                {
                                                                        List&lt;Group&lt;string&gt;&gt; groupedItems = Group&lt;string&gt;.CreateGroups(items,
                                                                        CultureInfo.CurrentCulture, (string s) =&gt; { return s[0].ToString(); }, true);
                                                                        SetsPageViewModel.Instance.Sets = groupedItems;
                                                                }
                                                                else
                                                                {
                                                                        SetsPageViewModel.Instance.Sets = new List&lt;Group&lt;string&gt;&gt;();
                                                                }
                                
                                                                Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                                                                    {
                                                                            CommonViewModel.Instance.IsWaiting = false;
                                    
                                                                            if (!App.RootFrame.CurrentSource.ToString().Contains(&quot;SetsPage&quot;))
                                                                            {
                                                                                    App.RootFrame.Navigate(new Uri(&quot;/Views/SetsPage.xaml&quot;, UriKind.Relative));
                                                                            }
                                                                    });
                                
                                                        }
                                                        // returns the list of commands associated with a given set.
                                                        else if (response.Marker.Contains(Constants.COMMAND_SERVER_SET_COMMANDS))
                                                        {
                                                            string[] data = response.Marker.Split(new char[] { ':' });
                                                                if (data[1] == CommonViewModel.Instance.CurrentSet)
                                                                {
                                                                        bool isList = false;
                                                                        bool.TryParse(data[2].ToLower(), out isList);
                                    
                                                                        if (isList)
                                                                        {
                                                                                CommonViewModel.Instance.CurrentSetType = &quot;list&quot;;
                                                                        }
                                                                        else
                                                                        {
                                                                                CommonViewModel.Instance.CurrentSetType = &quot;pad&quot;;
                                                                        }
                                    
                                                                        CommandsPageViewModel.Instance.Commands = new System.Collections.ObjectModel.ObservableCollection&lt;string&gt;(JsonConvert.DeserializeObject&lt;List&lt;string&gt;&gt;(response.Content));
                                    
                                                                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                                                                            {
                                                                                    CommonViewModel.Instance.IsWaiting = false;
                                                                                    App.RootFrame.Navigate(new Uri(&quot;/Views/CommandsPage.xaml&quot;, UriKind.Relative));
                                                                            });
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
}
</pre></p><p>If the response comes from a server that is different than the one that is currently active, the data is discarded as the user no longer needs it. Also, for specific commands, the mobile application will be on standby, waiting for a response (unless the user decides to cancel the request) – the <strong>IsWaiting</strong> flag is an application-wide indicator that a pending server action is in the queue.</p><p>Same as with the server, the commands in the Windows Phone application are represented through pre-defined constants:</p><p><pre class="brush: csharp">
public const string COMMAND_SERVER_SET_LIST = &quot;SET_LIST&quot;; 

public const string COMMAND_SERVER_SET_COMMANDS = &quot;SET_COMMANDS&quot;; 

public const string COMMAND_SERVER_NOTIFICATION = &quot;NOTIFICATION&quot;;
</pre></p><p>Let’s now take a closer look at how it is handled internally to build the visual layer.</p><h4>Handling the Data</h4><p>The first thing users will see when the application is launched is the list of registered servers:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0003%5B4%5D.png"><img title="wp_ss_20130507_0003" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0003_thumb%5B2%5D.png" alt="wp_ss_20130507_0003" width="288" height="480" border="0"></a></p><p>This is <strong>ServiceListPage.xaml</strong>. The list of servers that were added is retrieved from the isolated storage on application startup, with the help of the standard serialization routine implemented in the <a href="https://coding4fun.codeplex.com/">Coding4Fun Toolkit</a>—specifically, its storage subset (you can get it <a href="http://nuget.org/packages/Coding4Fun.Toolkit.Storage/">via NuGet</a>):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image0116.jpg"><img title="clip_image011" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image011_thumb3.jpg" alt="clip_image011" width="535" height="61" border="0"></a></p><p>The one-liner that initializes the internal server collection is as follows:</p><p><pre class="brush: csharp">
MainPageViewModel.Instance.Servers = Serialize.Open&lt;ObservableCollection&lt;Server&gt;&gt;(Constants.SERVERS_FILE);
</pre></p><p>&nbsp;</p><p>Here, the <strong>SERVERS_FILE</strong> constant is equal to <strong>servers.xml</strong>. It is a good idea to use constants for file names in order to be able to later modify the location through a single change instead of digging through the many source files in a solution to find references to the old location.</p><p>The user can define an unlimited number of servers, as long as he can access those. There is no restriction on the location of the server itself—it can work with the desktop in your room just as well as with a PC on the other end of the world (yes, this was tested).</p><p>When adding a new server, the user is redirected to <strong>AddServicePage.xaml</strong>, where he can fill in connection details, as well as the location of an image that would help him identify that specific item in the general list:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130423_0005%5B4%5D.png"><img title="wp_ss_20130423_0005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130423_0005_thumb%5B2%5D.png" alt="wp_ss_20130423_0005" width="288" height="480" border="0"></a></p><p>Once data entry is complete, it is validated internally to make sure that the server is not already registered with the same name and location. If the validation step passes, the server is added to the list of local access points and the user is returned back to the server selection page:</p><p><pre class="brush: csharp">
private void AttemptAddService()
{
        if (!string.IsNullOrWhiteSpace(txtName.Text) &amp;&amp; !string.IsNullOrWhiteSpace(txtLocation.Text))
        {
                Server server = new Server
                    {
                            Name = txtName.Text,
                            Location = txtLocation.Text,
                            ImageURL = !string.IsNullOrWhiteSpace(txtAvatar.Text) ? txtAvatar.Text : string.Empty
                    };
        
                if (!CollectionHelper.CheckServerExists(server))
                {
                        MainPageViewModel.Instance.Servers.Add(server);
            
                        Serialize.Save(Constants.SERVERS_FILE, MainPageViewModel.Instance.Servers);
                        NavigationService.GoBack();
                }
                else
                {
                        Alert.Send(&quot;The service with this name or location is already registered.&quot;);
                }
        }
        else
        {
                Alert.Send(&quot;The service needs a name and a location.&quot;);
        }
}
</pre></p><p>When a server selection is made by the user, it is necessary to show <strong>SetsPage.xaml</strong>. However, it is necessary to also check whether the server is active or not prior to the actual navigation. With the help of internal bindings, I am doing it through a <strong>RelayCommand</strong>:</p><p><pre class="brush: csharp">
public RelayCommand SelectServerCommand { get; private set; }
private async void SelectServer(object server)
{
        CommonViewModel.Instance.IsWaiting = true;
        CommonViewModel.Instance.CurrentServer = (Server)server;
    
        bool result = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location, 
        Constants.COMMAND_SERVER_HELLO, string.Empty);
        if (!result)
        {
                Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                CommonViewModel.Instance.CurrentServer = null;
        
                CommonViewModel.Instance.IsWaiting = false;
        }
}
</pre></p><p>&nbsp;</p><p><strong>COMMAND_SERVER_HELLO</strong> represents the initial handshake command that I mentioned earlier—it requests the list of sets on the target server. To streamline command processing, <strong>CommandClient</strong> is used and wraps around the <strong>SocketClient</strong> class, giving me the possibility to call <strong>SendCommand</strong> with the command metadata without having to explicitly handle socket interactions in my views:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Network 
{     
    public class CommandClient     
    {     
        private SocketClient client; 
        
        public Task&lt;bool&gt; SendCommand(string key, string value, Action&lt;bool&gt; onCompleted = null) 
        {     
            var taskCompletionSource = new TaskCompletionSource&lt;bool&gt;(); 
            
            client = new SocketClient();     
            client.OnClientConnected &#43;= (s, args) =&gt;     
            {     
                if (args.IsSuccessful)     
                {     
                    string data = JsonConvert.SerializeObject(new KeyValuePair&lt;string, string&gt;(key, value));     
                    client.Send(data);     
                } 
            
                taskCompletionSource.SetResult(args.IsSuccessful); 
                client = null; 
            }; 
            
            client.Connect(Binder.Instance.CurrentService.Location, 6169); 
            return taskCompletionSource.Task;     
        } 
    } 
}
</pre></p><p>From here on, <strong>ResponseHelper</strong> is once again involved, grouping all the data alphabetically—remember this call:</p><p><pre class="brush: csharp">
// returns the list of sets that are associated with the current server. 
if (response.Marker == Constants.COMMAND_SERVER_SET_LIST) 
{     
    List&lt;string&gt; items = JsonConvert.DeserializeObject&lt;List&lt;string&gt;&gt;(response.Content);     
    if (items != null) 
    {     
        List&lt;Group&lt;string&gt;&gt; groupedItems = Group&lt;string&gt;.CreateGroups(items,     
    CultureInfo.CurrentCulture, (string s) =&gt; { return s[0].ToString(); }, true);     
        Binder.Instance.Sets = groupedItems;     
    } 
    else 
    {     
        Binder.Instance.Sets = new List&lt;Group&lt;string&gt;&gt;();     
    } 
}
</pre></p><p>&nbsp;</p><p>The grouped collection is later bound to a <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj244365(v=vs.105).aspx">LongListSelector</a> instance:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0001%5B4%5D.png"><img title="wp_ss_20130507_0001" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0001_thumb%5B2%5D.png" alt="wp_ss_20130507_0001" width="288" height="480" border="0"></a></p><p>For each handshake call to the server, the set collection will be re-initialized, in case the server was updated by another device while the user was not taking any actions.</p><p>Adding a set takes the user to <strong>AddSetPage.xaml</strong>, where the user input is once again validated and the appropriate command sent to the currently selected server:</p><p><pre class="brush: csharp">
private async void AttemptAddSet()
{
        if (!string.IsNullOrWhiteSpace(txtName.Text))
        {
                this.Focus();
        
                bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location, 
                    string.Format(Constants.COMMAND_CREATE_SET, ((ListPickerItem)lstType.SelectedItem).Content.ToString()), txtName.Text);
                if (!commandSent)
                {
                        Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                }
                else
                {
                        CommonViewModel.Instance.IsWaiting = true;
                        NavigationService.GoBack();
                }
        }
        else
        {
                Alert.Send(Constants.MESSAGE_NO_NAME_FAIL);
        }
}
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130430_0002%5B4%5D-1.png"><img title="wp_ss_20130430_0002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130430_0002_thumb%5B2%5D-1.png" alt="wp_ss_20130430_0002" width="288" height="480" border="0"></a></p><p>The end-user is also able to specify whether the new set is a list or a pad. Since the server does not explicitly define the type of a set beyond marking whether it’s a list, it is possible to have an arbitrary type here.</p><p>To give you an idea of what it looks like in the current release of MissionControl, here is the pad representation of a set of commands:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0002%5B13%5D.png"><img title="wp_ss_20130507_0002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0002_thumb%5B11%5D.png" alt="wp_ss_20130507_0002" width="288" height="480" border="0"></a></p><p>It is a convenient way to display buttons for typical actions, such as channel switching through digits. Since we can safely assume many of those will be tapped sequentially, a list would be inconvenient to scroll through.</p><p>On the other hand, some remote control commands work well with a list because no sequences are invoked most of the time:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0004%5B4%5D.png"><img title="wp_ss_20130507_0004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0004_thumb%5B2%5D.png" alt="wp_ss_20130507_0004" width="288" height="480" border="0"></a></p><p>If the pad is not desired, it can easily be swapped with another design and internal template - the appearance is swapped dynamically and is not hard-bound to a string value.</p><p>Once a set is selected, a connection attempt is made to the current server in order to check whether there is still a communication channel available with the resource that fetched the initial list of commands. If a connection is established, the server will also return a set of commands that are available in the set at the time of the request.</p><p><pre class="brush: csharp">
private async void AttemptLoadCommands()
{
        bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location,
            Constants.COMMAND_GET_COMMANDS, CommonViewModel.Instance.CurrentSet);
        if (!commandSent)
        {
                Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                CommonViewModel.Instance.IsWaiting = false;
        }
}
</pre></p><p>You’ve probably already noticed that both for commands and sets, the initial routine verifies the connection to the server. The server might go dark after the set list is loaded, therefore rendering any attempt to process other commands impossible. To avoid scenarios in which the user is waiting for a response from a server that doesn’t run, the user is notified before being redirected to the subsequent view, if the connection fails. That way unnecessary navigation passes are out of the picture.</p><p>If the user selects a command from one of the lists demonstrated above, an <strong>EXECUTE</strong> directive is issued via the <strong>CommandClient</strong> class:</p><p><pre class="brush: csharp">
private async void lstCommands_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (lstCommands.SelectedItem != null)
    { 
        string selectedItem = lstCommands.SelectedItem.ToString(); 
        
        CommandClient commandClient = new CommandClient(); 
        bool commandSent = await commandClient.SendCommand(string.Format(Constants.COMMAND_EXECUTE, 
        
        Binder.Instance.CurrentSet), selectedItem); 
    
        if (!commandSent) 
        {     
            Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);     
        } 
        
        lstCommands.SelectedItem = null; 
    } 
}
</pre></p><p>Once the server receives the command, it will send it to the target without additional notifications being released to the connecting client.</p><p>When it comes to learning a new remote control code in <strong>LearnCodePage.xaml</strong>, the procedure is exactly the same as with any other part of the server communication process — a <strong>LEARN_CODE</strong> command is sent to the server with the associated set and new command name, and the server will wait for incoming IR input, leaving the connecting device free (no waiting lock is issued):</p><p><pre class="brush: csharp">
private async void AttemptLearnCode()
{
        if (!string.IsNullOrWhiteSpace(txtName.Text))
        {
                CommonViewModel.Instance.IsWaiting = true;
                this.Focus();
        
                bool commandSent = await CommonViewModel.Instance.CommandClient.SendCommand(CommonViewModel.Instance.CurrentServer.Location,
                    string.Format(Constants.COMMAND_LEARN_NEW, CommonViewModel.Instance.CurrentSet), txtName.Text);
                if (!commandSent)
                {
                        Alert.Send(Constants.MESSAGE_SERVER_CONNECT_FAIL);
                }
                else
                {
                        Alert.Send(Constants.MESSAGE_COMMAND_LEARN_WAIT);
                        NavigationService.GoBack();
                }
        
                CommonViewModel.Instance.IsWaiting = false;
        }
        else
        {
                Alert.Send(Constants.MESSAGE_NO_NAME_FAIL);
        }
}
</pre></p><p>Once the server learns a new command — if, and only if, the user still works in the context of the same server — an alert will be displayed, telling the user whether the command was successfully learned.</p><p>For convenience purposes, I also implemented a quick launch panel, where frequently-used commands can be placed. Whenever a user wants to add something here, he will tap-and-hold on an existing command in any of the sets that are available for any given server, and select the &quot;add to quick launch&quot; option. Once completed, the stored commands will be available on the main page, even when the user is not directly connected to the server that carries the command:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0005%5B4%5D.png"><img title="wp_ss_20130507_0005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/wp_ss_20130507_0005_thumb%5B2%5D.png" alt="wp_ss_20130507_0005" width="288" height="480" border="0"></a></p><p>Because this interaction layer is placed outside the boundaries of a single server or set, I needed to create a special data model to store the quick commands and the related connection information, that would let me call the server even when it is not the currently selected one:</p><p><pre class="brush: csharp">
namespace Coding4Fun.MissionControl.WP.Models
{
        public class Favorite
        {
            public string CommandName { get; set; }
            public string ParentSet { get; set; }
            public string ServerLocation { get; set; }
        }
}
</pre></p><p>Same as with the list of servers, the list of favorites is deserialized on application startup:</p><p><pre class="brush: csharp">
MainPageViewModel.Instance.Favorites = Serialize.Open&lt;ObservableCollection&lt;Favorite&gt;&gt;(Constants.FAVORITES_FILE);
</pre></p><p>&nbsp;</p><p>Logically, we would also need to have a way to eliminate trailing commands for servers or sets that have been removed, since those can no longer be invoked or might have a different meaning on servers that were added and have the same IP as the previous owner. This is easily done with a simple LINQ expression that is passed to <strong>RemoveTrailingFavorites </strong>in the <strong>CollectionHelper </strong>class:</p><p><pre class="brush: csharp">
internal static void RemoveTrailingFavorites(Func&lt;Favorite,bool&gt; predicate)
{
        var favorites = MainPageViewModel.Instance.Favorites.Where(predicate).ToList();
    
        if (favorites.Count() &gt; 0)
        {
                foreach (var favorite in favorites)
                {
                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                            {
                                    MainPageViewModel.Instance.Favorites.Remove(favorite);
                            });
                }
        
                Serialize.Save(Constants.FAVORITES_FILE, MainPageViewModel.Instance.Favorites);
        }
}
</pre></p><p>A typical usage scenario is reflected in the server removal snippet:</p><p><pre class="brush: csharp">
public static bool RemoveServer(Server server)
{
        try
        {
                RemoveTrailingFavorites(x=&gt; x.ServerLocation == server.Location);
        
                MainPageViewModel.Instance.Servers.Remove(server);
        
                Serialize.Save(Constants.SERVERS_FILE, MainPageViewModel.Instance.Servers);
        
                return true;
        }
        catch
        {
                return false;
        }
}
</pre></p><p>Because an <a href="http://msdn.microsoft.com/en-us/library/ms668604(v=vs.95).aspx" target="_blank">ObservableCollection&lt;T&gt;</a> is used for both the list of servers and quick launch commands, the view will be instantly updated to reflect the changes.</p><h1>Improvements to the project</h1><p>This specific project relies on a hybrid IR transmitter and receiver, which is not exactly cheap. As a step forward for this project, it can be adapted to use a central microcontroller that acts as a server (e.g. <a href="http://www.netduino.com/" target="_blank">Netduino</a>) and a series of IR emitters (instead of using a composite receiver/emitter) connected to it. Reduced cost for the IR infrastructure is key, as not every single component needs the capability to learn IR commands. You can have a single command capturing endpoint and multiple transmitters. This will also eliminate the need for a desktop client, since the server on the microcontroller can be built to be accessible via a web-browser.</p><p>Another important aspect not covered in this article is security. With the current workflow, anyone who has direct access to the server IP is able to do anything he wants with the data handled by the server. I am basing my writing on the assumption that you are testing the application on a secure local network and that the the odds of something like this happening are close to zero. However, for other environments where tampering with a server might be unacceptable, consider implementing a layer of security between the server and the client.</p><h2>Conclusion</h2><p>With affordable microcontrollers and sensors, home and office automation can be a nice bonus resulting from little investment. This article covers the implementation of a proof-of-concept server and application that can be easily extended and adapted to a variety of environments and devices.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:b029d939c55f459c9663a1b70159bff4">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control</comments>
      <itunes:summary>In a race to optimize everything, developers often go to extremes to build software that performs routine tasks. MissionControl is a system that allows users to program a control center that stores interfaces with attached hardware sensors, allowing the users to control any other devices that can be activated via the underlying protocol. For demo purposes, the MissionControl build at this point is compatible with the Phidgets IR hybrid sensor. The system has two core components: A server application, which is a Win32 console application that handles incoming queries and returns data to the connected clients. This application runs on the desktop machine with the connected sensor. The Windows Phone application that sends requests to the target server and can trigger a variety of pre-programmed commands. The BasicsHardware and Communication InfrastructureOne of the most important parts of the project is the signal capture and replication hardware. For the purposes of this project, I decided to use a dual-mode Phidgets IR sensor. It supports both IR code capture and subsequent replication. From a user’s perspective, this device also eliminates a substantial code-learning overhead as well as the potential error rate. Instead of searching for a device-specific hexadecimal sequence that later has to be transformed in a working IR code, the user simply has to point his remote control at the sensor and press the button that he wants accessible from a mobile device. Given that the capturing software is running on the target machine, once the sensor detects that a code can be repeated within an acceptable precision range, it will be automatically captured and stored, with all required transformations worked out in the backend using the free Phidgets SDK. Even though I can, I don’t have to handle the binary code content received through the sensor—the Phidgets .NET libraries carry built-in types that contain all the processed metadata that I will discuss later in this article. </itunes:summary>
      <itunes:duration>229</itunes:duration>
      <link>http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control</link>
      <pubDate>Mon, 13 May 2013 15:12:48 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_512.jpg" height="288" width="512"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_960.jpg" height="540" width="960"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl.mp3" expression="full" duration="229" fileSize="3674107" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl.mp4" expression="full" duration="229" fileSize="22113376" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl.webm" expression="full" duration="229" fileSize="16308048" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl.wma" expression="full" duration="229" fileSize="1867511" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl.wmv" expression="full" duration="229" fileSize="15574259" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_high.mp4" expression="full" duration="229" fileSize="48262843" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_mid.mp4" expression="full" duration="229" fileSize="33783291" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl_Source.wmv" expression="full" duration="229" fileSize="135746099" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/330a/ce7e23b2-7e59-47e3-ba68-af17f8ab330a/MissionControl.wmv" length="15574259" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/MissionControl-A-Flexible-API-for-Remote-Device-Control/RSS</wfw:commentRss>
      <category>Networking</category>
      <category>Windows</category>
      <category>Windows  Phone</category>
    </item>
  <item>
      <title>TWC9: Next XBOX Announcement, AzureConf, Code Digger, Princess Leia and more</title>
      <description><![CDATA[<p>This week on Channel 9, Dan and Clint discuss the week's top developer news, including;</p><ul><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=0m33s">[00:33]</a> <a href="http://www.xbox.com" target="_blank">XBox Event May 21, 10AM PDT</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=1m10s">[01:10]</a> <a href="http://channel9.msdn.com/Events/windowsazure/Windows-AzureConf-2013">Windows AzureConf 2013</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=2m07s">[02:07]</a> <a href="http://blogs.msdn.com/b/nikolait/archive/2013/04/23/introducing-code-digger-an-extension-for-vs2012.aspx">Introducing: Code Digger, an extension for VS2012</a> (Nikolai Tillmann ) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=3m06s">[03:06]</a> <a href="http://blogs.msdn.com/b/typescript/">TypeScript</a> <a href="http://blogs.msdn.com/b/typescript/archive/2013/04/22/announcing-0-9-early-previews.aspx">Announcing 0.9 early previews</a> (Jonathan Turner) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=4m25s">[04:25]</a> <a href="http://www.infoq.com/news/2013/04/node-socketio-servicebus">Microsoft Offers Module to Scale Out Real-time Node.js Applications</a> (Richard Seroter, Glenn Block) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=5m27s">[05:27]</a> <a href="http://blogs.msdn.com/b/eternalcoding/archive/2013/04/24/using-visual-studio-s-javascript-memory-analysis-tool-to-find-memory-leaks-on-your-windows-8-javascript-app.aspx">Using Visual Studio’s Javascript Memory Analysis tool to find memory leaks on your Windows 8 Javascript app</a> (David Catuhe) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=7m11s">[07:11]</a> <a href="http://channel9.msdn.com/Blogs/Charles/Miguel-de-Icaza-Mono-Open-Source-Visual-Studio-and-Xamarin">Miguel de Icaza: Mono, Open Source, Visual Studio, and Xamarin</a> (Charles, Miguel de Icaza) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=7m58s">[07:58]</a> <a href="http://wootstudio.ca/win8platstarter">Build your next great game for Windows 8</a>, <a title="http://opengameart.org/" href="http://opengameart.org/">OpenGameArt.org</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=9m25s">[09:25]</a> <a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Introducing-Creative-Coding-and-ProcessingJS-With-Windows">Channel 9 Highlight: Introducing Creative Coding and ProcessingJS With Windows</a> (Clint Rutkas, Matthias Shapiro, Rick Barraza ) </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Dan's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=11m52s">[11:52]</a> <a href="http://blogs.msdn.com/b/uk_faculty_connection/archive/2013/04/21/the-power-of-3d-interaction.aspx">The power of 3D interaction</a> (Lee Stott), <a href="http://drdave.co.uk/page/projects">http://drdave.co.uk/page/projects</a> (Dr Dave Brown) </li><li>Clint's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013#time=12m33s">[12:33]</a> <a href="http://www.polygon.com/2013/4/22/4252934/pizza-hut-for-xbox-360-app-kinect">Pizza Hut launching Xbox 360 app that lets console owners order pizza from Xbox Live</a> (Alexa Ray Corriea) </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7a3e074e43934f94b1c8a1ab017d43c0">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013</comments>
      <itunes:summary>This week on Channel 9, Dan and Clint discuss the week&#39;s top developer news, including; [00:33] XBox Event May 21, 10AM PDT [01:10] Windows AzureConf 2013 [02:07] Introducing: Code Digger, an extension for VS2012 (Nikolai Tillmann ) [03:06] TypeScript Announcing 0.9 early previews (Jonathan Turner) [04:25] Microsoft Offers Module to Scale Out Real-time Node.js Applications (Richard Seroter, Glenn Block) [05:27] Using Visual Studio’s Javascript Memory Analysis tool to find memory leaks on your Windows 8 Javascript app (David Catuhe) [07:11] Miguel de Icaza: Mono, Open Source, Visual Studio, and Xamarin (Charles, Miguel de Icaza) [07:58] Build your next great game for Windows 8, OpenGameArt.org [09:25] Channel 9 Highlight: Introducing Creative Coding and ProcessingJS With Windows (Clint Rutkas, Matthias Shapiro, Rick Barraza ) Picks of the Week! Dan&#39;s Pick of the Week:[11:52] The power of 3D interaction (Lee Stott), http://drdave.co.uk/page/projects (Dr Dave Brown) Clint&#39;s Pick of the Week:[12:33] Pizza Hut launching Xbox 360 app that lets console owners order pizza from Xbox Live (Alexa Ray Corriea) </itunes:summary>
      <itunes:duration>827</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013</link>
      <pubDate>Mon, 29 Apr 2013 16:09:52 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/b26ffdcf-5e68-4cc2-aae4-2d3f58b6bdbb.png" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/ecb59145-7678-4f58-816c-c6ea07a3e97e.png" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/2c343551-d42c-42bf-a273-297b4fb9b16a.png" height="288" width="512"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/f948d192-8866-4dca-8c57-d686b2562b30.png" height="540" width="960"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.mp3" expression="full" duration="827" fileSize="13245544" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.mp4" expression="full" duration="827" fileSize="78529969" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.webm" expression="full" duration="827" fileSize="56543982" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.wma" expression="full" duration="827" fileSize="6700947" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.wmv" expression="full" duration="827" fileSize="55073231" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426_high.mp4" expression="full" duration="827" fileSize="172225071" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426_mid.mp4" expression="full" duration="827" fileSize="120319783" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426_Source.wmv" expression="full" duration="827" fileSize="110638355" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.ism/manifest" expression="full" duration="827" fileSize="6036" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/dbe2/906ee4d7-afe1-457b-89dd-6447988bdbe2/TWC920130426.wmv" length="55073231" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Dan Fernandez, Greg Duncan</dc:creator>
      <itunes:author>Clint Rutkas, Dan Fernandez, Greg Duncan</itunes:author>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-26-2013/RSS</wfw:commentRss>
      <category>JavaScript</category>
      <category>Mono</category>
      <category>Visual Studio extensibility</category>
      <category>Windows Azure</category>
      <category>Xbox</category>
      <category>Game Development</category>
      <category>Windows 8</category>
      <category>Visual Studio 2012</category>
      <category>TypeScript</category>
    </item>
  <item>
      <title>Introducing Creative Coding and ProcessingJS With Windows</title>
      <description><![CDATA[<p>Welcome to Creative Coding with ProcessingJS for Windows! In this series, our goal is to introduce people to the basics of using code to unleash their creative mind and give them the tools to create beautiful things with code. To this end, we've created some great tools and projects.</p><p><a href="http://processingjs.codeplex.com/"><img src="http://files.channel9.msdn.com/thumbnail/eef3492b-29c1-4619-94dd-900bb3ecd825.png" alt=""></a><a href="http://apps.microsoft.com/windows/app/processing-for-windows/27e8a073-f881-45fc-b887-ef739ed7095a"><img src="http://files.channel9.msdn.com/thumbnail/ab28038f-dca1-4275-84e6-d48b37033176.png" alt=""></a><a href="http://www.windowsphone.com/s?appid=734ea3b3-d4db-46c3-b46c-45131fb748af"><img src="http://files.channel9.msdn.com/thumbnail/1130b603-a2e8-46d0-9c81-9e124b9e2b5d.png" alt=""></a></p><p><strong><a href="http://processingjs.codeplex.com/">ProcessingJS Sketchbooks on Codeplex </a></strong>- Open source starter projects for writing full screen apps using ProcessingJS. We've included a ProcessingJS implementation&nbsp;for Windows 8&nbsp;in&nbsp;both&nbsp;C# and JavaScript and another for Windows Phone. ProcessingJS Template for Windows Phone - Want to write a Windows Phone app in ProcessingJS? Install this template and start as many ProcessingJS Windows Phone projects as you want.</p><p><strong>Creative Coding video series</strong> - a creative coding lesson plan taught by Rick Barraza and Matthias Shapiro (links below).</p><p><a href="http://apps.microsoft.com/windows/app/processing-for-windows/27e8a073-f881-45fc-b887-ef739ed7095a"><strong>ProcessingJS for Windows</strong></a> - a micro-IDE in the Windows Store that allows users to write, view and export ProcessingJS sketches.</p><p><a href="http://www.windowsphone.com/s?appid=734ea3b3-d4db-46c3-b46c-45131fb748af"><strong>ProcessingJS Reader for Windows Phone</strong></a> - view your ProcessingJS sketches on your Windows Phone. Share sketches by emailing them or sharing them via NFC. Available in the Windows Phone Marketplace.</p><p>As an introduction to the series, we'll break it down into three parts before walking through all the tools we're releasing to help you create your own unique visuals.</p><p><strong>Creative Coding</strong></p><p>Have you ever looked at some beautiful programmatic animation, visualization, or interaction and wondered how it was done (or wished you could do that yourself)? This is the drive behind the Creative Coding series.</p><p>We've put together a set of 10 videos that will walk you through some of the essential skills and techniques necessary to create responsive and beautiful interactive visuals. The videos build upon one another so watch them in order to get the most out of the series.</p><p><strong>Topics covered</strong></p><ul><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Setting-up-your-Windows-8-environment">Getting Started in ProcessingJS </a>- programming a bouncing ball </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Particles-Classes-and-Color">Simple Particles</a>&nbsp; - random motion </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Jelly-Blobs-Easing-and-Elastic">Jelly Blobs</a> - easing and elastic motion </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Drawing-with-Emitters">Simple Emitter</a> - animation queues and life cycles </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Trigonometry-for-Designers-Dont-Panic">Fibonacci Flowers</a> - trigonometry in design </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Grids-Direction-and-Rotation">Direction and Rotation</a> - tangents and rotation </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Text-Pens-and-Multi-Touch">Mouse, Pen, Fingers</a> - multi touch interactions </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Simple-Collision-Detection-and-Response">Collision and Bounce</a> - programming angled collisions </li><li><a href="http://channel9.msdn.com/Series/Sketchbooktutorial/Loading-Images-and-Generative-Art">Working with Images</a> - loading graphics and recursion </li><li><a href="http://media.ch9.ms/ch9/761e/9c114521-c571-4dc2-bff2-ecb20d59761e/PJSphoneIntro.mp4">ProcessingJS and Windows Phone </a>- getting your sketch on your Windows Phone </li></ul><p><strong>With ProcessingJS</strong></p><p>For our coding environment, we wanted to use a technology that would make our projects as accessible as possible. We ultimately decided to use ProcessingJS, which is a web-compatible implementation of the Processing visual programming language. ProcessingJS is a simple but powerful library for visual programming that uses the HTML5 canvas as the drawing board for data visualizations, digital art, interactive animations and even games.</p><p>ProcessingJS sketches can get people started with a single line of code. For example:</p><p><pre class="brush: text">ellipse(100,100, 20, 20);</pre></p><p>is a valid ProcessingJS sketch that draws a 20 pixel diameter ellipse at&nbsp;the (100,100)&nbsp;x,y coordinate on a default sketch canvas.</p><p>But we can also write sketches that use a draw loop to create iterative visuals. Or we could write event based sketches that update or react base on interactive events (like mouse or touch).&nbsp;By combining these programming and visual elements, we can create some beautiful sketches by just layering these simple concepts. This makes ProcessingJS perfect as platform for learning creative coding.</p><p><a href="http://processingjs.org/reference/">ProcessingJS Reference</a></p><p><a href="https://github.com/processing-js/processing-js/">ProcessingJS Source Github</a></p><p><strong>For Windows (and Windows Phone)</strong></p><p>These projects and apps are designed to take advantage of the Windows and Windows Phone platforms. Because of this, we've made a few updates to the ProcessingJS library. In the Windows Store app, the entire application is written in HTML5, so integrating a JavaScript library to that was no problem at all for most ProcessingJS sketches. But when it came time to implement multi-touch interactions, we found that we needed to add support for pointer events to ProcessingJS.</p><p>Pointer events are what Internet Explorer 10 uses to detect any pointer interaction, which covers mouse, stylus and touch interaction. It is currently (as of March 21, 2013) a W3C working draft an intended to become&nbsp;the W3C recommendations for touch interaction standards.&nbsp;But the nicest thing about (at least for this project) is that IE10 in on both Windows 8 and Windows Phone 8 so we can take the same pointer-enabled ProcessingJS library, do nothing to it and know that our sketches will work in Windows Phone.</p><p>And we've designed for this. If you're building a ProcessingJS sketch in the Windows Store app, you can export it as a file and simply attach it in an email and you or your friends can launch that sketch in directly from the email app in your Windows Phone (Windows Phone 8 is required). This way you can create and share apps across Windows 8 and Windows Phone 8 using apps freely available in the Stores.</p><p>If you want to move beyond that and use ProcessingJS to create full Windows 8 and Windows Phone 8 apps, go to our ProcessingJS Codeplex and download the projects and templates there. Using these projects and templates, you can build full-screen ProcessingJS apps for both platforms. We even have a Windows Phone 8 template that you can install and just have a ProcessingJS enabled project ready to go anytime.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:fc041e0496624412ab80a187016bb695">]]></description>
      <comments>http://channel9.msdn.com/Series/Sketchbooktutorial/Introducing-Creative-Coding-and-ProcessingJS-With-Windows</comments>
      <itunes:summary>Welcome to Creative Coding with ProcessingJS for Windows! In this series, our goal is to introduce people to the basics of using code to unleash their creative mind and give them the tools to create beautiful things with code. To this end, we&#39;ve created some great tools and projects.  ProcessingJS Sketchbooks on Codeplex - Open source starter projects for writing full screen apps using ProcessingJS. We&#39;ve included a ProcessingJS implementation&amp;nbsp;for Windows 8&amp;nbsp;in&amp;nbsp;both&amp;nbsp;C# and JavaScript and another for Windows Phone. ProcessingJS Template for Windows Phone - Want to write a Windows Phone app in ProcessingJS? Install this template and start as many ProcessingJS Windows Phone projects as you want. Creative Coding video series - a creative coding lesson plan taught by Rick Barraza and Matthias Shapiro (links below). ProcessingJS for Windows - a micro-IDE in the Windows Store that allows users to write, view and export ProcessingJS sketches. ProcessingJS Reader for Windows Phone - view your ProcessingJS sketches on your Windows Phone. Share sketches by emailing them or sharing them via NFC. Available in the Windows Phone Marketplace. As an introduction to the series, we&#39;ll break it down into three parts before walking through all the tools we&#39;re releasing to help you create your own unique visuals. Creative Coding Have you ever looked at some beautiful programmatic animation, visualization, or interaction and wondered how it was done (or wished you could do that yourself)? This is the drive behind the Creative Coding series. We&#39;ve put together a set of 10 videos that will walk you through some of the essential skills and techniques necessary to create responsive and beautiful interactive visuals. The videos build upon one another so watch them in order to get the most out of the series. Topics covered Getting Started in ProcessingJS - programming a bouncing ball Simple Particles&amp;nbsp; - random motion Jelly Blobs - easing and elastic motion Simple Emitter</itunes:summary>
      <link>http://channel9.msdn.com/Series/Sketchbooktutorial/Introducing-Creative-Coding-and-ProcessingJS-With-Windows</link>
      <pubDate>Wed, 24 Apr 2013 17:58:39 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/Sketchbooktutorial/Introducing-Creative-Coding-and-ProcessingJS-With-Windows</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/1e0188a4-c210-4fb1-b514-1ec2f7d4991b.jpg" height="63" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/c809d5d8-1f39-4dc3-8423-6cc67d8f56b9.jpg" height="139" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/4d09840d-af61-4d85-a151-11b99e99e4e5.jpg" height="288" width="512"></media:thumbnail>      
      <dc:creator>Clint Rutkas, Matthias Shapiro, Rick Barraza</dc:creator>
      <itunes:author>Clint Rutkas, Matthias Shapiro, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/Sketchbooktutorial/Introducing-Creative-Coding-and-ProcessingJS-With-Windows/RSS</wfw:commentRss>
    </item>
  <item>
      <title>TWC9: VS 2012.3 CTP1, Windows Azure IaaS, ALM VM&#39;s, NFC, UX resources and Kitties!</title>
      <description><![CDATA[<p>This week on Channel 9, Peter and Clint discuss the week's top developer news, including;</p><ul><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=0m32s">[00:32]</a> <a href="http://www.microsoft.com/en-us/download/details.aspx?id=38426&amp;WT.mc_id=rss_alldownloads_all">Visual Studio 2012 Update 3 CTP 1</a>, <a href="http://support.microsoft.com/kb/2835600">Description of Visual Studio 2012 Update 3 CTP 1</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=1m06s">[01:06]</a> <a href="http://weblogs.asp.net/scottgu/archive/2013/04/16/windows-azure-general-availability-of-infrastructure-as-a-service-iaas.aspx">Windows Azure: General Availability of Infrastructure as a Service (IaaS)</a> (Scott Guthrie) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=1m58s">[01:58]</a> <a href="http://blogs.msdn.com/b/bclteam/archive/2013/04/17/microsoft-bcl-async-is-now-stable.aspx">Microsoft.Bcl.Async is Now Stable</a> (Immo Landwerth) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=2m35s">[02:35]</a> <a href="http://www.richard-banks.org/2013/04/whats-visual-studios-code-map-all-about.html">What’s Visual Studio’s Code Map All About?</a> (Richard Banks) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=3m43s">[03:43]</a> <a href="http://blogs.msdn.com/b/briankel/archive/2013/04/17/list-of-all-visual-studio-alm-virtual-machines.aspx">List of all Visual Studio ALM Virtual Machines</a> (<a href="http://aka.ms/ALMVMs">http://aka.ms/ALMVMs</a>), <a href="http://blogs.msdn.com/b/briankel/archive/2013/04/17/visual-studio-2012-update-2-alm-virtual-machine-and-hands-on-labs-demo-scripts-now-available.aspx">Visual Studio 2012 Update 2 ALM Virtual Machine and Hands-on-Labs / Demo Scripts Now Available</a> (Brian Keller) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=4m19s">[04:19]</a> <a href="http://blogs.msdn.com/b/windowsappdev/archive/2013/04/18/develop-a-cutting-edge-app-with-nfc.aspx">Develop a cutting edge app with NFC</a> (Priya Dandawate) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=5m15s">[05:15]</a> <a href="http://blogs.msdn.com/b/uk_faculty_connection/archive/2013/04/17/ux-ui-design-the-benefits-of-building-prototype-even-if-you-have-only-initial-sketches-of-your-prototype.aspx">UX/UI Design the benefits of building prototype, even if you have only initial sketches of your prototype.</a> (Lee Stott ) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=6m47s">[06:47]</a> <a href="http://blogs.msdn.com/b/uk_faculty_connection/archive/2013/04/17/where-can-i-get-some-tips-and-guidance-design-resources.aspx">Where can I get some tips and guidance design resources?</a> (Lee Stott) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=7m25s">[07:25]</a> <a href="http://codefoster.com/post/2013/04/15/appart">App Art</a> (Jeremy Foster) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=8m16s">[08:16]</a> <a href="http://blogs.msdn.com/b/officeapps/archive/2013/04/18/developer-must-have-125-apps-for-office-and-sharepoint-code-samples.aspx">Developer Must-Have: 125&#43; Apps for Office and SharePoint Code Samples</a> (Ricardo Loo ) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=8m58s">[08:58]</a> <a href="http://blogs.msdn.com/b/astrojonathans_hack-a-day_blog/archive/2013/04/16/worldwide-telescope-sharpens-it-s-visuals-with-sharpdx.aspx">WorldWide Telescope Sharpens it's Visuals with SharpDX</a> (Jonathan Fay) </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Peter's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=10m43s">[10:43]</a> <a href="http://www.i-programmer.info/news/105-artificial-intelligence/5760-kitty-radar-cat-detector.html">Kitty Radar Cat Detector</a> (Lucy Black), <a href="http://harthur.github.io/kittydar/">http://harthur.github.io/kittydar/</a> (Heather Arthur) </li><li>Clint's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013#time=12m15s">[12:15]</a> <a href="http://majornelson.com/2013/04/11/xbox-360-achievement-unlocked-as-a-visual/">Xbox 360 “Achievement Unlocked” sound as a visual </a>(Major Nelson) </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:620b8db1d64d4198876aa1a5016e4a49">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013</comments>
      <itunes:summary>This week on Channel 9, Peter and Clint discuss the week&#39;s top developer news, including; [00:32] Visual Studio 2012 Update 3 CTP 1, Description of Visual Studio 2012 Update 3 CTP 1 [01:06] Windows Azure: General Availability of Infrastructure as a Service (IaaS) (Scott Guthrie) [01:58] Microsoft.Bcl.Async is Now Stable (Immo Landwerth) [02:35] What’s Visual Studio’s Code Map All About? (Richard Banks) [03:43] List of all Visual Studio ALM Virtual Machines (http://aka.ms/ALMVMs), Visual Studio 2012 Update 2 ALM Virtual Machine and Hands-on-Labs / Demo Scripts Now Available (Brian Keller) [04:19] Develop a cutting edge app with NFC (Priya Dandawate) [05:15] UX/UI Design the benefits of building prototype, even if you have only initial sketches of your prototype. (Lee Stott ) [06:47] Where can I get some tips and guidance design resources? (Lee Stott) [07:25] App Art (Jeremy Foster) [08:16] Developer Must-Have: 125&amp;#43; Apps for Office and SharePoint Code Samples (Ricardo Loo ) [08:58] WorldWide Telescope Sharpens it&#39;s Visuals with SharpDX (Jonathan Fay) Picks of the Week! Peter&#39;s Pick of the Week:[10:43] Kitty Radar Cat Detector (Lucy Black), http://harthur.github.io/kittydar/ (Heather Arthur) Clint&#39;s Pick of the Week:[12:15] Xbox 360 “Achievement Unlocked” sound as a visual (Major Nelson) </itunes:summary>
      <itunes:duration>811</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013</link>
      <pubDate>Fri, 19 Apr 2013 23:41:30 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_512.jpg" height="288" width="512"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_960.jpg" height="540" width="960"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.mp3" expression="full" duration="811" fileSize="12989336" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.mp4" expression="full" duration="811" fileSize="76183031" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.webm" expression="full" duration="811" fileSize="30324175" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.wma" expression="full" duration="811" fileSize="6571775" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.wmv" expression="full" duration="811" fileSize="57326087" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_high.mp4" expression="full" duration="811" fileSize="166855097" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_mid.mp4" expression="full" duration="811" fileSize="116664309" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9_Source.wmv" expression="full" duration="811" fileSize="166153663" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.ism/manifest" expression="full" duration="811" fileSize="6036" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/0875/8c823fad-02fe-4618-aec0-fbf1a1b30875/20130419TWC9.wmv" length="57326087" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Greg Duncan, Peter Dwersteg</dc:creator>
      <itunes:author>Clint Rutkas, Greg Duncan, Peter Dwersteg</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-April-19-2013/RSS</wfw:commentRss>
      <category>ALM</category>
      <category>Design</category>
      <category>Design Tools</category>
      <category>JavaScript</category>
      <category>Team Foundation Server</category>
      <category>UX</category>
      <category>Virtual Machines</category>
      <category>Xbox 360</category>
    </item>
  <item>
      <title>Philips Hue Lighting Controller</title>
      <description><![CDATA[<h3><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-9.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-10.jpg" alt="clip_image002" width="605" height="341" border="0"></a></h3><p>So Philips recently introduced their Hue Connected Bulbs: an easy-to-use set of LED light bulbs and Wi-Fi connected bridge which allows you to dynamically change the color of your home lighting using their iOS or Android app. What’s particularly cool is that the bridge has a web API which you can access to set the colors of each bulb with your own app.</p><p>We at <a href="http://untitlednet.com">untitled network</a> developed our own Philips Hue app called Oni: light Control, which is&nbsp;currently available on the <a href="http://www.windowsphone.com/en-us/store/app/oni-light-control/c8199c0b-3976-4a3b-9275-2d3a803f68ab">Windows Phone Store</a>. In addition to allowing you to set the color of your home lighting with defined “Moods”, the app also allows you to do the same using your phone’s built in voice commands or inexpensive NFC stickers. Here’s a demo of the Oni: Light Control in action:</p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/bJUqLPvlJS0&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/bJUqLPvlJS0&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p><p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/n00gZqQj5wk&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/n00gZqQj5wk&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p><p>I’m going to show you how you can develop your own app using the color picker from the Coding4Fun Toolkit for Windows Phone and the Json.Net library from Newtonsoft. These libraries can be found on NuGet, but you’ll obviously need the Philips Hue Connected Bulbs kit to test things out.</p><p><strong>Getting Started:</strong></p><p>The Philips Hue API uses a restful JSON interface you can access using any http client. Documentation on all of the supported methods by the Philips Hue bridge can be found at <a href="http://blog.ef.net/2012/11/02/philips-hue-api.html">http://blog.ef.net/2012/11/02/philips-hue-api.html</a>.</p><p>To get started, you’ll need authorized access to your bridge’s API. Once the bridge has successfully established a network connection with your router, discover its internal IP address via the URL: <a href="http://www.meethue.com/api/nupnp">http://www.meethue.com/api/nupnp</a></p><p>You should get a response similar to:</p><p><pre class="brush: csharp">[{&quot;id&quot;:&quot;ffss00fffe123456&quot;,&quot;internalipaddress&quot;:&quot;192.168.1.100&quot;,&quot;macaddress&quot;:&quot;0aa:bb:cc:dd:00:11&quot;}]
</pre></p><p>Note the internalipaddress value and use the IP to access the bridge’s API directly the with the URL <a href="http://192.168.1.100/api">http://192.168.1.100/api</a></p><p>Now, since we haven’t registered a user for authorization, attempting to access the hub will return an error from the bridge:</p><p><pre class="brush: csharp">
[{&quot;error&quot;:{&quot;type&quot;:1,&quot;address&quot;:&quot;/&quot;,&quot;description&quot;:&quot;unauthorized user&quot;}}]
</pre></p><p>To register a new user, we’ll first POST the username we wish to use.</p><p><pre class="brush: csharp">
var client = new WebClient();
 
//our uri to perform registration
var uri = new Uri(string.Format(&quot;http://{0}/api&quot;, HostnameTextBox.Text));
 
//create our registration object, along with username and description
var reg = new
{
    username = UsernameTextBox.Text,
    devicetype = &quot;Coding4Fun Hue Light Project&quot;
};
 
var jsonObj = JsonConvert.SerializeObject(reg);
 
 
//decide what to do with the response we get back from the bridge
client.UploadStringCompleted &#43;= (o, args) =] Dispatcher.BeginInvoke(() =]
{
    try
    {
        ResponseTextBox.Text = args.Result;
    }
    catch (Exception ex)
    {
        ResponseTextBox.Text = ex.Message;
    }
});
 
//Invoke a POST to the bridge
client.UploadStringAsync(uri, jsonObj);
</pre></p><p>Note the response we get back from our hub will be</p><p><pre class="brush: csharp">
[{&quot;error&quot;:{&quot;type&quot;:101,&quot;address&quot;:&quot;&quot;,&quot;description&quot;:&quot;link button not pressed&quot;}}]
</pre></p><p>This is because bridge requires you to first push the link button before new registrations can be made. After pushing the button and invoking the registration function again, you should receive the following result from the bridge:</p><p><pre class="brush: csharp">
[{&quot;success&quot;:{&quot;username&quot;:&quot;coding4fun&quot;}}]
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/settingScreen%5B2%5D.png"><img title="settingScreen" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/settingScreen_thumb.png" alt="settingScreen" width="288" height="480" border="0"></a></p><p><strong>Setting the Bulb Color:</strong></p><p>We should now be able to access all methods on the bridge. You can get all of the configuration details, including all of the bulbs and their statuses with the same base url: <a href="http://192.168.1.100/api/coding4fun">http://192.168.1.100/api/coding4fun</a></p><p>Now comes the fun part. There are three color modes in which you can use to set the color of your bulbs:</p><ul><li><strong>hue &amp; sat:</strong> ‘hue’ is a color range between 0-65535 which represent 182.04*degrees, ‘sat’ is saturation with a range of 0-254 </li><li><strong>xy:</strong> are coordinates in the CIE 1931 space </li><li><strong>ct:</strong> is a color temperature expressed in mireds from 154 to 500, coolest to warmest respectfully </li></ul><p><em>Source: </em><a href="http://rsmck.co.uk/hue"><em>http://rsmck.co.uk/hue</em></a></p><p>We’ll be setting the colors of our bulbs using hue &amp; saturation parameters. Luckily, the Coding4Fun Toolkit for Windows Phone has three awesome color picker controls and some useful color extensions which makes setting the bulb colors a breeze. We start by building our state object – a list of parameters we want our bulb to be set to. Then we use the PUT verb to set the light with the following URL: http://{BRIGE-IPADDRESS}/api/coding4fun/lights/1/state</p><p>The “1” in the url is the 1-based index of the bulb you want to set.</p><p><pre class="brush: csharp">
//Get the HSV Value from the currently selected color
var hsv = LightColorSlider.Color.GetHSV();
 
//build our State object
var state = new
{
    on = true,
    hue = (int)(hsv.Hue * 182.04), //we convert the hue value into degrees by multiplying the value by 182.04
    sat = (int)(hsv.Saturation * 254)
};
 
//convert it to json:
var jsonObj = JsonConvert.SerializeObject(state);
 
//set the api url to set the state
var uri = new Uri(string.Format(&quot;http://{0}/api/{1}/lights/{2}/state&quot;, HostnameTextBox.Text, UsernameTextBox.Text, LightIndexTextBox.Text));
 
var client = new WebClient();
 
//decide what to do with the response we get back from the bridge
client.UploadStringCompleted &#43;= (o, args) =&gt; Dispatcher.BeginInvoke(() =&gt;
{
    try
    {
        ResponseTextBox.Text = args.Result;
    }
    catch (Exception ex)
    {
        ResponseTextBox.Text = ex.Message;
    }
     
});
 
//Invoke the PUT method to set the state of the bulb
client.UploadStringAsync(uri, &quot;PUT&quot;, jsonObj);
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/colorScreen%5B2%5D.png"><img title="colorScreen" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/colorScreen_thumb.png" alt="colorScreen" width="288" height="480" border="0"></a></p><p>That’s it! Be sure to check out all of the other functions the (other functions the Hue API supports) at <a href="http://developers.meethue.com/index.html">http://developers.meethue.com/index.html</a></p><p><strong>Bio</strong>:<br><a href="http://channel9.msdn.com/Niners/unt1tled">Jarem Archer</a> is a self-taught Software Developer and UX Designer. He’s part of a small team at <a href="http://untitlednet.com">untitled network</a> who have a passion for video games, digital motion, entertainment and gadgets. Follow him on Twitter at <a href="http://twitter.com/unt1tled">http://twitter.com/unt1tled</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:5f2b34e566b542fb8fefa1860129d903">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller</comments>
      <itunes:summary>So Philips recently introduced their Hue Connected Bulbs: an easy-to-use set of LED light bulbs and Wi-Fi connected bridge which allows you to dynamically change the color of your home lighting using their iOS or Android app. What’s particularly cool is that the bridge has a web API which you can access to set the colors of each bulb with your own app. We at untitled network developed our own Philips Hue app called Oni: light Control, which is&amp;nbsp;currently available on the Windows Phone Store. In addition to allowing you to set the color of your home lighting with defined “Moods”, the app also allows you to do the same using your phone’s built in voice commands or inexpensive NFC stickers. Here’s a demo of the Oni: Light Control in action:   I’m going to show you how you can develop your own app using the color picker from the Coding4Fun Toolkit for Windows Phone and the Json.Net library from Newtonsoft. These libraries can be found on NuGet, but you’ll obviously need the Philips Hue Connected Bulbs kit to test things out. Getting Started: The Philips Hue API uses a restful JSON interface you can access using any http client. Documentation on all of the supported methods by the Philips Hue bridge can be found at http://blog.ef.net/2012/11/02/philips-hue-api.html. To get started, you’ll need authorized access to your bridge’s API. Once the bridge has successfully established a network connection with your router, discover its internal IP address via the URL: http://www.meethue.com/api/nupnp You should get a response similar to: [{&amp;quot;id&amp;quot;:&amp;quot;ffss00fffe123456&amp;quot;,&amp;quot;internalipaddress&amp;quot;:&amp;quot;192.168.1.100&amp;quot;,&amp;quot;macaddress&amp;quot;:&amp;quot;0aa:bb:cc:dd:00:11&amp;quot;}]
 Note the internalipaddress value and use the IP to access the bridge’s API directly the with the URL http://192.168.1.100/api Now, since we haven’t registered a user for authorization, attempting to access the hub will return an error from the bridge: 
[{&amp;quot;error&amp;quot;:{&amp;quot;type</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller</link>
      <pubDate>Mon, 08 Apr 2013 15:17:51 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/93227cad-f0ec-4cb0-90b2-576862b90f5e.JPG" height="100" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/9407e40d-9ebd-479e-ace3-78d19024604d.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/b8395754-2668-4cc8-9b04-06434dd68dbb.jpg" height="288" width="512"></media:thumbnail>      
      <dc:creator>Clint Rutkas, Jarem Archer</dc:creator>
      <itunes:author>Clint Rutkas, Jarem Archer</itunes:author>
      <slash:comments>13</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Philips-Hue-Lighting-Controller/RSS</wfw:commentRss>
      <category>C#</category>
      <category>Hardware</category>
      <category>Windows Phone</category>
    </item>
  <item>
      <title>TWC9: Build 2013, Brew, Backbone, Git, YUI and more</title>
      <description><![CDATA[<p>This week on Channel 9, Brian and Clint discuss the week's top developer news, including;</p><ul><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=0m31s">[00:31]</a> <a href="http://www.buildwindows.com/">Build 2013</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=1m04s">[01:04]</a> <a href="http://wpf.2000things.com/2013/03/27/785-using-the-visual-profiler-tool/">#785 – Using the Visual Profiler Tool</a>, <a href="http://wpf.2000things.com/2013/03/25/783-downloading-and-installing-the-wpf-performance-suite/">#783 – Downloading and Installing the WPF Performance Suite</a> (Sean Sexton), <a href="http://msdn.microsoft.com/en-us/library/aa969767.aspx">WPF Performance Suite</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=1m45s">[01:45]</a> <a href="http://blog.shellscape.org/blog/2013/03/18/brew-1.0-has-arrived/">Brew 1.0 has arrived!</a> [Found Via: <a href="http://blog.cwa.me.uk/2013/03/22/the-morning-brew-1321/">The Morning Brew #1321</a>] </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=2m23s">[02:23]</a> <a href="http://ashkenas.com/backbonejs-1.0/">Backbone 1.0</a> (Jeremy Ashkenas) [Found Via: <a href="http://blog.cwa.me.uk/2013/03/22/the-morning-brew-1321/">The Morning Brew #1321</a>] </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=2m50s">[02:50]</a> <a href="http://refcardz.dzone.com/refcardz/git-patterns-and-anti-patterns">Git Patterns and Anti-Patterns</a> (Luca Milanesio) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=4m03s">[04:03]</a> <a href="http://blogs.msdn.com/b/vcblog/archive/2013/03/26/developing-an-app-with-the-visual-studio-3d-starter-kit-part-1-of-3.aspx">Developing an app with the Visual Studio 3D Starter Kit, part 1 of 3</a> (Roberto Sonnino) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=4m51s">[04:51]</a> <a href="http://code.msdn.microsoft.com/windowsapps/GDC-2013-Windows-Developer-8dd7abdf">GDC 2013 Windows Developer Content Direct3D Game Templates</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=5m29s">[05:29]</a> <a href="http://blogs.windows.com/windows_phone/b/wpdev/archive/2013/03/27/new-middleware-makes-porting-games-to-windows-phone-easy.aspx">New middleware makes porting games to Windows Phone easy</a> (Todd Brix) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=6m06s">[06:06]</a> <a href="http://www.dzone.com/articles/test-non-standard-scenarios">Windows Phone Apps - Watch Your Code for Hidden Activity</a> (Den Delimarsky) </li><li>Channel 9 Highlight:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=7m08s">[07:08]</a> <a href="http://channel9.msdn.com/posts/Title-Build-Windows-8-Apps-with-YUI">Build Windows 8 Apps with YUI</a> (Jeff Burtoft) </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Brian's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=7m40s">[07:40]</a> <a href="http://www.404techsupport.com/2013/03/arena-xlsm-an-rpg-built-using-excel/">Arena.Xlsm, an RPG built using Excel</a>, <a href="http://carywalkin.wordpress.com/2013/03/17/arena-xlsm-released/">carywalkin.wordpress.com</a>, <a href="http://carywalkin.wordpress.com/2013/03/27/arena-xlsm-version-1-1-preview/">Version 1.1</a>, <a href="http://arenaxlsm.wikia.com/">Arena.Xlsm wiki</a> </li><li>Clint's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013#time=8m11s">[08:11]</a> <a href="http://channel9.msdn.com/coding4fun/articles/Dynamic-Lockscreen-Changer-for-Windows-Phone-8-Built-With-ASPNET-MVC-and-Azure-Mobile-Services">Dynamic Lockscreen Changer for Windows Phone 8, Built With ASP.NET MVC and Azure Mobile Services</a> (Clint Rutkas, Den Delimarsky) </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c4fd57bca9a64142b182a18f0161a5a5">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013</comments>
      <itunes:summary>This week on Channel 9, Brian and Clint discuss the week&#39;s top developer news, including; [00:31] Build 2013 [01:04] #785 – Using the Visual Profiler Tool, #783 – Downloading and Installing the WPF Performance Suite (Sean Sexton), WPF Performance Suite [01:45] Brew 1.0 has arrived! [Found Via: The Morning Brew #1321] [02:23] Backbone 1.0 (Jeremy Ashkenas) [Found Via: The Morning Brew #1321] [02:50] Git Patterns and Anti-Patterns (Luca Milanesio) [04:03] Developing an app with the Visual Studio 3D Starter Kit, part 1 of 3 (Roberto Sonnino) [04:51] GDC 2013 Windows Developer Content Direct3D Game Templates [05:29] New middleware makes porting games to Windows Phone easy (Todd Brix) [06:06] Windows Phone Apps - Watch Your Code for Hidden Activity (Den Delimarsky) Channel 9 Highlight:[07:08] Build Windows 8 Apps with YUI (Jeff Burtoft) Picks of the Week! Brian&#39;s Pick of the Week:[07:40] Arena.Xlsm, an RPG built using Excel, carywalkin.wordpress.com, Version 1.1, Arena.Xlsm wiki Clint&#39;s Pick of the Week:[08:11] Dynamic Lockscreen Changer for Windows Phone 8, Built With ASP.NET MVC and Azure Mobile Services (Clint Rutkas, Den Delimarsky) </itunes:summary>
      <itunes:duration>585</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013</link>
      <pubDate>Sat, 30 Mar 2013 00:40:39 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.mp3" expression="full" duration="585" fileSize="9372315" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.mp4" expression="full" duration="585" fileSize="56551308" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.webm" expression="full" duration="585" fileSize="20965213" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.wma" expression="full" duration="585" fileSize="4742339" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.wmv" expression="full" duration="585" fileSize="33617939" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9_high.mp4" expression="full" duration="585" fileSize="123616381" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9_mid.mp4" expression="full" duration="585" fileSize="86526837" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9_Source.wmv" expression="full" duration="585" fileSize="134187967" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.ism/manifest" expression="full" duration="585" fileSize="6036" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/e4cb/f9cef35c-7371-4fb2-8191-245e460de4cb/20130329TWC9.wmv" length="33617939" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Keller, Clint Rutkas, Greg Duncan</dc:creator>
      <itunes:author>Brian Keller, Clint Rutkas, Greg Duncan</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-29-2013/RSS</wfw:commentRss>
      <category>ALM</category>
      <category>ASP.NET MVC</category>
      <category>DirectX</category>
      <category>JavaScript</category>
      <category>Visual Studio</category>
      <category>Windows Phone</category>
      <category>WPF</category>
      <category>Game Development</category>
      <category>GDC</category>
      <category>Web Development</category>
      <category>Build</category>
      <category>Windows 8</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Dynamic Lockscreen Changer for Windows Phone 8, Built With ASP.NET MVC and Azure Mobile Services</title>
      <description><![CDATA[<p>With the release of Windows Phone 8, <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206968%28v=vs.105%29.aspx">a few new developer API</a> endpoints were made available that allow third-party applications to change the device lockscreen image. In this article, I am establishing the infrastructure and building a mobile application that provides the ability to choose from a number of dynamic image sets, from which images can be selected and then cycled as lockscreen wallpapers.</p><h1>What do you need</h1><p>You will need to download and install <a href="http://www.asp.net/mvc/mvc3">ASP.NET MVC3</a> to work on the web frontend and <a href="http://dev.windowsphone.com/en-us/downloadsdk">Windows Phone 8 SDK</a> to work on the mobile applications. An <a href="http://www.windowsazure.com/en-us/develop/mobile/">Azure Mobile Services</a> account will be necessary, and of course don’t forget to download and install the <a href="http://www.windowsazure.com/en-us/develop/mobile/developer-tools/">Azure Mobile Services client libraries</a>. All three components are available at no additional charge.</p><p><strong>NOTE:</strong> <em>Without the Azure Mobile Services SDK installed on the development machine, the compilation process will fail for the Windows Phone application.</em></p><h1>Setting up The Data Store</h1><p>First we need to establish the general design of the application and organize the workflow. The application will provide two ways to assign the dynamic lockscreen:</p><ul><li>With the help of custom image sets that are provided by the service; </li><li>With the help of self-created image sets, aggregated from images provided by the service but ultimately managed by the end-user. </li></ul><p>Let’s talk about the general data model. Every image belongs to a certain category and to keep track of each we need a table with two columns—category ID and category name. We also need another core table containing the image references themselves, with the following columns: image URL, descriptive name, and the category ID to which it belongs. The overall structure looks like this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001%5B7%5D.png"><img title="clip_image001" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001_thumb%5B4%5D.png" alt="clip_image001" width="321" height="141" border="0"></a></p><p>Now to the Windows Azure Management Portal and creating a new Mobile Service.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image003%5B5%5D.jpg"><img title="clip_image003" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image003_thumb%5B2%5D.jpg" alt="clip_image003" width="560" height="387" border="0"></a></p><p>Once created, you need to specify database information, just like you would with a standard SQL Server database:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image005%5B6%5D.jpg"><img title="clip_image005" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image005_thumb%5B3%5D.jpg" alt="clip_image005" width="564" height="368" border="0"></a></p><p>As the database is being created, you can easily integrate it with SQL Server Management Studio. You will need the server address, which may be obtained in the Azure Management Portal. To login, use the credentials that you set when creating the core database.</p><p>Create the two tables mentioned above, with the following column configuration:</p><p><strong>Categories</strong></p><ul><li>ID - <strong>int</strong> </li><li>Name – <strong>varchar(100)</strong> </li></ul><p><strong>Images</strong></p><ul><li>ID – <strong>int</strong> </li><li>URL – <strong>varchar(500)</strong> </li><li>Name – <strong>varchar(100)</strong> </li><li>CategoryID – <strong>int</strong> </li></ul><p>You can create these tables either in the SQL Server Management Studio or through the Azure Management Portal. However, you will need the Management Studio to create the column structure, as the Azure Management Portal does not offer this functionality right now.</p><p>By default, the <strong>id</strong> column will be created automatically. To add the Name column to the Categories table, run this query:</p><p><pre class="brush: sql">
ALTER TABLE c4flockscreen.Categories
ADD Name VARCHAR(100)
</pre></p><p>To add the missing columns to the Images table, simply execute this query:</p><p><pre class="brush: sql">
ALTER TABLE c4flockscreen.Images
ADD URL VARCHAR(500),
Name VARCHAR(100),
CategoryID INT
</pre></p><p>Now that the database is ready, we’ll proceed to working on the web layer, which will effectively be the administrative portal for the service.</p><h1>Creating the Web Portal</h1><p>There should be a way to easily manage images and constantly expand the collection of possible lockscreen wallpapers. One way to do this is create a basic management portal that can carry basic CRUD operations.</p><p>Start by creating an empty project:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image007%5B5%5D.jpg"><img title="clip_image007" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image007_thumb%5B2%5D.jpg" alt="clip_image007" width="321" height="291" border="0"></a></p><p>If you are not yet aware of the Model-View-Controller (MVC) development pattern, <a href="http://msdn.microsoft.com/en-us/library/ff649643.aspx">here is a good read</a> explaining the fundamentals.</p><p>Create a new controller in the <strong>Controllers</strong> folder, named <strong>HomeController</strong>. This will be the only controller created in this project. For now, add an <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.actionresult%28v=vs.108%29.aspx">ActionResult</a>-based function that will return the main view:</p><p><pre class="brush: csharp">
using System.Web.Mvc;

namespace Coding4Fun.Lockscreen.Web.Controllers
{
    public class HomeController : Controller    
    {    
        public ActionResult MainView()    
        {    
            return View();    
        }
    }
}
</pre></p><p>Having the controller without the proper views is pointless, so create a new view in <strong>Views/Home</strong> and name it <strong>MainView</strong>. For now, do not focus on the visual layout of the page, but rather on the functional aspect of the web frontend. If you run the application now, you will most likely get a 404 response. That is because the associated home view is by default not found. Open <strong>App_Start/RouteConfig.cs</strong> and make sure that the default view is set to <strong>MainView</strong> instead of <strong>Index</strong>.</p><p><pre class="brush: csharp">
routes.MapRoute(
name: &quot;Default&quot;,
url: &quot;{controller}/{action}/{id}&quot;,
defaults: new { controller = &quot;Home&quot;, action = &quot;MainView&quot;, id = UrlParameter.Optional }
);
</pre></p><p>The core is created and now if running the web application you will see a basic HTML page:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image009%5B5%5D.jpg"><img title="clip_image009" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image009_thumb%5B2%5D.jpg" alt="clip_image009" width="508" height="345" border="0"></a></p><p>We now need to handle data from the Azure Mobile Services database. Out-of-the-box, there is no ASP.NET SDK available, but the database can be easily <a href="http://msdn.microsoft.com/en-us/library/windowsazure/jj710108.aspx">accessed through a REST API</a>. But before that, we need to define the data models for the Categories and Images table. Begin by creating two classes in the Models folder:</p><p><strong>Category.cs:</strong></p><p><pre class="brush: csharp">
public class Category
{
public int? id { get; set; }
public string Name { get; set; }
}
</pre></p><p><strong>Image.cs:</strong></p><p><pre class="brush: csharp">
public class Image
{
public int? id { get; set; }    
public string URL { get; set; }
public string Name { get; set; }
public int CategoryID { get; set; }
}
</pre></p><p>Each of the properties is tied to the associated column in the database we created earlier. Notice that the ID values are nullable. This is introduced because the index will by default be automatically assigned. When new instances of Category or Image are created, I will not explicitly set the <strong>id</strong> property, so keeping it null instead of at a potential default value of 0 will ensure that it is properly set on the backend.</p><p>Let’s now create the connectivity engine that will allow us to query the content of the data store. For this purpose, I created a <strong>DataStore</strong> folder and a <strong>DataEngine</strong> class inside it. We will need a unique API key for each of our requests, so open the Azure Management Portal and obtain it from there:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B5%5D.png"><img title="clip_image010" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010_thumb%5B2%5D.png" alt="clip_image010" width="749" height="333" border="0"></a></p><p>In order to keep consistency between projects, and to be able to re-use the same Azure Mobile Services API key and core URL, I created an <strong>AuthConstants</strong> class in the context of the <strong>Coding4Fun.Lockscreen.Core</strong> project. It carries three static fields:</p><p><pre class="brush: csharp">
public static class AuthConstants
{
    public static string AmsApiKey = &quot;YOUR_KEY_HERE&quot;;    
    public const string AmsUrl = &quot;https://c4flockscreen.azure-mobile.net/&quot;;
    public const string AmsTableUrl = AmsUrl &#43; &quot;tables/&quot;;
}
</pre></p><p>Back in the ASP.NET project, the query operations are carried with the help of <a href="http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.aspx">HttpClient</a> initialized in the class constructor, which also includes the key used to authenticate the requests via the X-ZUMO-APPLICATION header:</p><p><pre class="brush: csharp">
private HttpClient client;

public DataEngine()
{    
    client = new HttpClient();    
    client.DefaultRequestHeaders.Add(&quot;X-ZUMO-APPLICATION&quot;, KEY);
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(&quot;application/json&quot;));    
}
</pre></p><p>This is the basic data harness. I also implemented two core methods in order to get all existing categories:</p><p><pre class="brush: csharp">
public IEnumerable&lt;Category&gt; GetAllCategories()
{
    var result = client.GetStringAsync(string.Concat(CORE_URL,&quot;Categories&quot;)).Result;
    IEnumerable&lt;Category&gt; categories = JsonConvert.DeserializeObject&lt;IEnumerable&lt;Category&gt;&gt;(result);
    return categories;    
}
</pre></p><p>And images:</p><p><pre class="brush: csharp">
public IEnumerable&lt;Image&gt; GetAllImages()
{
    var result = client.GetStringAsync(string.Concat(CORE_URL, &quot;Images&quot;)).Result;
    IEnumerable&lt;Image&gt; images = JsonConvert.DeserializeObject&lt;IEnumerable&lt;Image&gt;&gt;(result);
    return images;    
}
</pre></p><p>For each of these, a basic request is made with the table name appended to the base URL (represented by the <strong>CORE_URL</strong> constant). Since <a href="http://www.hanselman.com/blog/VisualStudio2012RCIsReleasedTheBigWebRollup.aspx">JSON.NET is now bundled with ASP.NET</a>, I am able to easily deserialize the returned JSON data array to an <strong>IEnumerable&lt;Type&gt;</strong>. There is one problem, however, with the <strong>GetAllImages</strong> approach. It implies that even if I want to use LINQ to query the existing image collection, I have to first download the entire set locally.</p><p>Fortunately, the Azure Mobile Services REST API provides an endpoint with filtering, and that’s what I am using in <strong>GetCategoryById</strong> and <strong>GetImagesByCategoryId</strong>:</p><p><pre class="brush: csharp">
public Category GetCategoryById(int id)
{    
    string composite = string.Concat(CORE_URL, &quot;Categories?$filter=(id%20eq%20&quot;, id.ToString(), &quot;)&quot;);    
    var result = client.GetStringAsync(composite).Result;
    IEnumerable&lt;Category&gt; categories = JsonConvert.DeserializeObject&lt;IEnumerable&lt;Category&gt;&gt;(result);
    return categories.FirstOrDefault();
}

public IEnumerable&lt;Image&gt; GetImagesByCategoryId(int id)
{    
    string composite = string.Concat(CORE_URL, &quot;Images?$filter=(CategoryID%20eq%20&quot;, id.ToString(), &quot;)&quot;);    
    var result = client.GetStringAsync(composite).Result;
    IEnumerable&lt;Image&gt; images = JsonConvert.DeserializeObject&lt;IEnumerable&lt;Image&gt;&gt;(result);
    return images();
}
</pre></p><p>Notice the <strong>?$filter=</strong> parameter, in which the conditional is URL encoded and is wrapped in parentheses. For the category query, I am checking the <strong>id </strong>value, and for the image I’m checking <strong>CategoryID</strong>.</p><p>In the <strong>Views/Home</strong> folder, create a new view and name it Images. It will be used to list existing images that are associated with one of the selected categories. You also need to adjust the controller code to handle the incoming data:</p><p><pre class="brush: csharp">
using Coding4Fun.Lockscreen.Web.DataStore;
using System.Web.Mvc;

namespace Coding4Fun.Lockscreen.Web.Controllers
{    
    public class HomeController : Controller    
    {    
        DataEngine engine;    
        public HomeController()
        {    
            engine = new DataEngine();    
        }
        
        public ActionResult MainView()
        {    
            var categories = engine.GetAllCategories();    
            return View(categories);
        }
        
        public ActionResult Images(int categoryId)
        {    
            var images = engine.GetImagesByCategoryId(categoryId);    
            if (images != null)
            {    
                return View(images);    
            }
            
            return View(&quot;MainView&quot;);
        }
    }
}
</pre></p><p>For the main view, I am getting the list of categories and passing them as the bound model. For the Images view, the category ID is passed as an argument that will later enable the engine to return a list of all images that have <strong>CategoryID</strong> set to that value. In case the returned list is not null, the view is shown. Otherwise, the main view is the terminal point.</p><p>In its current state, I’ll be able to use the frontend to list existing categories and images, but not to add, remove, or update items. Adding a category and an image is a matter of modifying an <strong>HttpClient</strong> request, with the help of <a href="http://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage.aspx">HttpRequestMessage</a>. For example, here is how I can add a category through my DataEngine class:</p><p><pre class="brush: csharp">
public HttpStatusCode AddCategory(Category category)
{    
    var serializedObject = JsonConvert.SerializeObject(category, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
    var request = new HttpRequestMessage(HttpMethod.Post, string.Concat(CORE_URL, &quot;Categories&quot;));
    request.Content = new StringContent(serializedObject, Encoding.UTF8, &quot;application/json&quot;);
    var response = client.SendAsync(request).Result;
    return response.StatusCode;
}
</pre></p><p>JSON.NET capabilities are used to serialize the object that needs to be inserted. The POST request is executed against the standard table URL, with the UTF8 encoded JSON string. Since the client is already carrying the basic authentication header, all that needs to be done is calling the <a href="http://msdn.microsoft.com/en-us/library/hh138176.aspx">SendAsync</a> function.</p><p>Updating a category follows the same approach, though a <a href="http://tools.ietf.org/html/rfc5789">PATCH method</a> is used for the request and the URL contains the index of the category that needs to be updated:</p><p><pre class="brush: csharp">
public HttpStatusCode UpdateCategory(Category category)
{    
    var request = new HttpRequestMessage(new HttpMethod(&quot;PATCH&quot;), string.Concat(CORE_URL, &quot;Categories&quot;, &quot;/&quot;, category.id));    
    var serializedObject = JsonConvert.SerializeObject(category);
    request.Content = new StringContent(serializedObject, Encoding.UTF8, &quot;application/json&quot;);
    var response = client.SendAsync(request).Result;
    return response.StatusCode;
}
</pre></p><p>To delete a category from the data store, one simply needs to pass a parameter to it that identifies the index of the category that needs to be removed:</p><p><pre class="brush: csharp">
public HttpStatusCode DeleteCategoryFromId(int categoryId)
{    
    var request = new HttpRequestMessage(HttpMethod.Delete, string.Concat(CORE_URL, &quot;Categories&quot;, &quot;/&quot;, categoryId));    
    var response = client.SendAsync(request).Result;
    return response.StatusCode;
}
</pre></p><p>For images, the same methods can be used, with the <strong>Images</strong> table passed as the name for the target in the composite URL. Let’s now get back to working on some of the views. A static category list is not fun, so let’s create a way to add new categories. Right click on the <strong>Views/Home</strong> folder and select <strong>Add View</strong>:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B5%5D-1.jpg"><img title="clip_image012" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012_thumb%5B2%5D-1.jpg" alt="clip_image012" width="342" height="338" border="0"></a></p><p>A great thing about the view creation process in Visual Studio is the fact that you are able to use a basic scaffold template for a strongly-typed view. In this case, I am associating it with a <strong>Category</strong> class and using the <strong>Create</strong> template. I now need to modify the controller code to process requests to AddCategory. I need to handle two types of requests, GET and POST, because the view will be displayed to both add an item and submit an item:</p><p><pre class="brush: csharp">
public ActionResult AddCategory()
{    
    return View();    
}

[HttpPost]
public ActionResult AddCategory(Category category)
{    
    if (ModelState.IsValid)    
    {    
        engine.AddCategory(category);    
        return RedirectToAction(&quot;MainView&quot;);    
    }
    
    return View();
}
</pre></p><p>For a GET request, I am simply returning the view. For a POST view, I am adding the category that was defined by the bound model through the local <strong>DataEngine</strong> instance, after which the user is redirected to the main view. But we also need to add an ActionResult for the MainView to obtain the list of items that are currently in the Categories table:</p><p><pre class="brush: csharp">
public ActionResult MainView()
{    
    var categories = engine.GetAllCategories();    
    return View(categories);
}
</pre></p><p>The <strong>DataEngine</strong> instance will return all categories in an <strong>IEnumerable&lt;Category&gt;</strong> form that are passed as the model for the main view. The layout of MainView.cshtml can be as simple as a table:</p><p><pre class="brush: csharp">
@{    
    ViewBag.Title = &quot;Coding4Fun Dynamic Lockscreen&quot;;    
}

&lt;h2&gt;Coding4Fun Dynamic Lockscreen - Categories&lt;/h2&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;b&gt;ID&lt;/b&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;b&gt;Category Name&lt;/b&gt;
&lt;/td&gt;
&lt;/tr&gt;

@foreach (var p in Model)
{    
    &lt;tr&gt;    
    &lt;td&gt;
    @p.id
    &lt;/td&gt;
    &lt;td&gt;
    @p.Name
    &lt;/td&gt;
    &lt;td&gt;
@Html.ActionLink(&quot;Images&quot;, &quot;Images&quot;, new { categoryId = p.id })
    &lt;/td&gt;
    &lt;td&gt;
@Html.ActionLink(&quot;Edit&quot;, &quot;EditCategory&quot;, new { categoryId = p.id })
    &lt;/td&gt;
    &lt;td&gt;
@Html.ActionLink(&quot;Delete&quot;, &quot;DeleteCategory&quot;, new { categoryId = p.id })
    &lt;/td&gt;
    &lt;/tr&gt;
}

&lt;/table&gt;

@Html.ActionLink(&quot;Add Category&quot;, &quot;AddCategory&quot;)
</pre></p><p>The <strong>ActionLink</strong> helper allows me to invoke a view and, if necessary, pass specific parameters to it (e.g., when I need to identify the category that needs to be deleted or edited). Some of the views listed here are not yet created, but I can easily use placeholder names in any case.</p><p>The ultimate result for the main page will look like this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013%5B5%5D.png"><img title="clip_image013" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013_thumb%5B2%5D.png" alt="clip_image013" width="610" height="400" border="0"></a></p><p>Notice that you are also able to add new categories now by clicking on the Add Category link on the bottom. This will redirect you to the <strong>AddCategory</strong> view that we created:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B5%5D.png"><img title="clip_image014" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014_thumb%5B2%5D.png" alt="clip_image014" width="610" height="400" border="0"></a></p><p>Let’s see how to implement the category editing in the web frontend. First of all, create a new view in <strong>Views/Home</strong> and name it <strong>EditCategory</strong>. Use the <strong>Edit</strong> scaffold template. Like <strong>AddCategory</strong>, <strong>EditCategory</strong> needs to be handled in two separate ways for GET and POST requests in the controller:</p><p><pre class="brush: csharp">
public ActionResult EditCategory(int categoryId)
{    
    Category category;    
    category = engine.GetCategoryById(categoryId);
    if (category != null)
       return View(category);
    return View(&quot;MainView&quot;);
}

[HttpPost]
public ActionResult EditCategory(Category category)
{    
    if (ModelState.IsValid)    
    {    
        engine.UpdateCategory(category);    
        return RedirectToAction(&quot;MainView&quot;);
    }
    
    return View();
}
</pre></p><p>For a <strong>GET</strong> request, we need to identify the category that needs to be added by its index, so we are using a <strong>categoryId</strong> argument passed to the view, which is later used by the <strong>DataEngine</strong> instance to retrieve the category from the data store. For a POST action, the implementation for <strong>UpdateCategory</strong> from above is used, where a PATCH request is run with the serialized object bound to the view.</p><p>For the Delete action, no additional view is necessary but the controller still needs a handler, so we can use a snippet like this:</p><p><pre class="brush: csharp">
public ActionResult DeleteCategory(int categoryId)
{    
    engine.DeleteCategoryFromId(categoryId);    
    return RedirectToAction(&quot;MainView&quot;);
}
</pre></p><p>You can use the same approach to add, delete, and edit items in the list of images. For adding images, however, you might want to pass the category identifier. When images are listed after the category has been selected, it is necessary to provide a way to identify the category to which new entities should be added. To do this, we can. in the main controller. pass the category index to the view when the Images action is being triggered:</p><p><pre class="brush: csharp">
public ActionResult Images(int categoryId)
{    
    var images = engine.GetImagesByCategoryId(categoryId);    
    if (images != null)
    {    
        ViewData[&quot;CID&quot;] = categoryId;    
        return View(images);
    }
    
    return View(&quot;MainView&quot;);
}
</pre></p><p>Afterwards, the <strong>categoryId</strong> value can be obtained by using the <strong>CID</strong> key for <strong>ViewData</strong> inside the view itself.</p><h4>Let’s now take a look at how images are represented for each category. I created a custom view to list all the images associated with the Images category. If you look above at the controller code, you will notice that I am passing the category ID, through which the image set query is executed, and the returned collection is set as the bound model:</h4><p><pre class="brush: csharp">
public ActionResult Images(int categoryId)
{    
    var images = engine.GetImagesByCategoryId(categoryId);    
    if (images != null)
    {    
        ViewData[&quot;CID&quot;] = categoryId;    
        return View(images);
    }
    
    return View(&quot;MainView&quot;);
}
</pre></p><p>When an image needs to be added, call the <strong>AddImage</strong> view. In <strong>HomeController.cs</strong>, it carries implementations for both GET and POST requests:</p><p><pre class="brush: csharp">
public ActionResult AddImage(int categoryId)
{    
    Image image = new Image();    
    image.CategoryID = categoryId;
    return View(image);    
}

[HttpPost]
public ActionResult AddImage(HttpPostedFileBase file, Image image)
{    
    if (file != null &amp;&amp; file.ContentLength &gt; 0)    
    {    
        var fileName = Path.GetFileName(file.FileName);    
        var path = Path.Combine(Server.MapPath(&quot;~/Uploads&quot;), image.CategoryID.ToString(), fileName);
        string dirPath = Path.GetDirectoryName(path);
        
        if (!Directory.Exists(dirPath))
            Directory.CreateDirectory(dirPath);
        
        file.SaveAs(path);

        string applicationUrl = string.Format(&quot;{0}://{1}{2}&quot;,        
            HttpContext.Request.Url.Scheme,
            HttpContext.Request.ServerVariables[&quot;HTTP_HOST&quot;],
            (HttpContext.Request.ApplicationPath.Equals(&quot;/&quot;)) ? string.Empty : HttpContext.Request.ApplicationPath
        );
        
        image.URL = Path.Combine(applicationUrl, &quot;Uploads&quot;, image.CategoryID.ToString(), fileName);
    }
    
    if (ModelState.IsValid &amp;&amp; image.URL != null)
    {    
        engine.AddImage(image);    
        return RedirectToAction(&quot;Images&quot;, new { categoryID = image.CategoryID });
    }
    
    return View();
}
</pre></p><p>When a GET request is executed against the <strong>AddImage</strong> endpoint, I pass the category ID as the flag, signaling which category the image should be included in. When a POST request is executed, it can go two ways—either the user is passing an existing link to a hosted image or the user is uploading his own image to the local server. When an upload is inbound, <a href="http://msdn.microsoft.com/en-us/library/system.web.httppostedfilebase.aspx">HttpPostedFileBase</a> carries the content that needs to be pushed to the server.</p><p>The upload component on the view itself is done by creating a form with a file input:</p><p><pre class="brush: csharp">
&lt;h2&gt;Or you could upload your own file: &lt;/h2&gt;

@if (Model != null)
{    
    using (Html.BeginForm(&quot;AddImage&quot;, &quot;Home&quot;, FormMethod.Post, new { enctype = &quot;multipart/form-data&quot;, image = Model }))
    {    
        @Html.HiddenFor(model =&gt; model.CategoryID);    
        &lt;input type=&quot;file&quot; name=&quot;file&quot; /&gt;
        &lt;input type=&quot;submit&quot; value=&quot;OK&quot; /&gt;
    }
}
</pre></p><p>If there is no file selected, the system assumes that the user just decided to add an existing URL.</p><p>It’s important to mention that the upload workflow relies on the availability of the Upload folder. It is created by default when the project is deployed to the server, but you also need to make sure that the ASP.NET user on the machine where IIS is located has the appropriate write permission for the folder.</p><h1>The Windows Phone 8 Application Foundation</h1><p>Create a new Windows Phone 8 application and add a reference to <a href="http://weblogs.asp.net/scottgu/archive/2012/08/28/announcing-windows-azure-mobile-services.aspx">Windows Azure Mobile Services Managed Client</a>. It should be available in the Extensions section if you installed the Windows Azure Mobile Services SDK as I mentioned at the beginning of the article:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016%5B5%5D.jpg"><img title="clip_image016" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016_thumb%5B2%5D.jpg" alt="clip_image016" width="516" height="355" border="0"></a></p><p>In <strong>App.xaml.cs</strong> you need to create an instance of <a href="http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.windowsazure.mobileservices.mobileserviceclient.aspx">MobileServiceClient</a> that will be used as the central connection point to the database. Notice that I am using the predefined AMS and API KEY string constants:</p><p><pre class="brush: csharp">
public static MobileServiceClient MobileService =
new MobileServiceClient(AuthConstants.AmsUrl, AuthConstants.AmsApiKey);
</pre></p><p>The mobile application should also carry the data models for both the categories and images. That said, we can reorganize those a bit for a more convenient data binding layout. To ensure that we can reuse the classes from different application components, I am once again using the <strong>Coding4Fun.Lockscreen.Core</strong> project.</p><p>Create a new folder called <strong>Models</strong> and add a new class called <strong>Category</strong>:</p><p><pre class="brush: csharp">
using System.Collections.ObjectModel;

namespace Coding4Fun.Lockscreen.Core.Models
{    
    public class Category    
    {    
        public Category()    
        {    
            Images = new ObservableCollection&lt;Image&gt;();    
        }
    
        public int? id { get; set; }    
        public string Name { get; set; }

        public ObservableCollection&lt;Image&gt; Images { get; set; }
        
        public override string ToString()        
        {    
            return Name;    
        }
    }
}
</pre></p><p>We are still relying on a <a href="http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx">nullable index value</a>, but now there is an <a href="http://msdn.microsoft.com/en-us/library/ms668604%28v=vs.95%29.aspx">ObservableCollection</a> for images. The reason for using this specific collection type is because with an <strong>ObservableCollection</strong>, binding updates are performed automatically when new items are added or removed, therefore cutting the need to implement the notification mechanism.</p><p>The ToString function is overridden to simplify data extraction on binding. When a collection with categories will be hooked to a list, for example, I don’t have to create a converter or a property link.</p><p>For the <strong>Image</strong> model, create a new class called <strong>Image</strong> in the same <strong>Models</strong> folder:</p><p><pre class="brush: csharp">
namespace Coding4Fun.Lockscreen.Core.Models
{    
    public class Image    
    {    
        public int? id { get; set; }
        public string URL { get; set; }
        public string Name { get; set; }
        public int CategoryID { get; set; }    
    }
}
</pre></p><h1>Application Workflow &amp; Storage</h1><p>Let’s talk about how image categories will be handled in the application. On application startup, the database is queried for the available categories and each of them is listed on the home screen. If the user taps on one of the categories, the database is queried for the images that are associated with the category index.</p><p>However, the user should also be able to create his own custom categories that will only be available in-app. Those categories can carry images from multiple other categories, if necessary, with the default reference set to the internal storage.</p><p>Since we are working with local storage, let’s create a helper class called <strong>LocalStorageHelper</strong> in the <strong>Coding4Fun.Lockscreen.Core</strong> project in the <strong>Storage</strong> folder. This class will carry basic read and write functions, allowing us to store data internally:</p><p><pre class="brush: csharp">
public static class LocalStorageHelper
{    
    public async static void WriteData(string folderName, string fileName, byte[] content)    
    {    
        IStorageFolder rootFolder = ApplicationData.Current.LocalFolder;
        
        if (folderName != string.Empty)    
        {    
            rootFolder = await rootFolder.CreateFolderAsync(folderName,    
            CreationCollisionOption.OpenIfExists);    
        }
        
        IStorageFile file = await rootFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        using (var s = await file.OpenStreamForWriteAsync())
        {    
            s.Write(content, 0, content.Length);    
        }
    }
    
    public static async void ClearFolder(string folderName)
    {    
        var folder = await ApplicationData.Current.LocalFolder.GetFolderAsync(folderName);    
        if (folder != null)
        {    
            foreach (IStorageFile file in await folder.GetFilesAsync())    
            {    
                await file.DeleteAsync();    
            }
        }
    }
    
    public static async Task&lt;string&gt; ReadData(string fileName)
    {    
        byte[] data;    
        StorageFolder folder = ApplicationData.Current.LocalFolder;
        StorageFile file = await folder.GetFileAsync(fileName);
        using (Stream s = await file.OpenStreamForReadAsync())
        {        
            data = new byte[s.Length];    
            await s.ReadAsync(data, 0, (int)s.Length);
        }
        
        return Encoding.UTF8.GetString(data, 0, data.Length);
    }    
}
</pre></p><p>Notice that I am using the newly-introduced <a href="http://msdn.microsoft.com/library/windows/apps/BR227230">StorageFolder</a>/<a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.storagefile.aspx">StorageFile</a> capabilities. If you worked with Windows Store application development, you are probably already familiar with them. <strong>Application.Current.LocalFolder</strong> gives me direct access to the local directory. which can be modified from within the application itself. It works in a manner similar to <strong>IsolatedStorageFile</strong> in Windows Phone 7, but with more flexibility when it comes to creating new folders and files and well doing file sweeps.</p><p>As I mentioned above, there will be internal data stored as XML. For this purpose, I need a class that carries serialization and deserialization routines, and I can simplify this task by using the <a href="http://coding4fun.codeplex.com/">Coding4Fun Toolkit</a> <strong>Serialize.Save&lt;T&gt;</strong> and <strong>Serialize.Open&lt;T&gt;</strong> capabilities. Calls to these functions allow flexible serialization, where by default the static class is not aware of the serialization type, but is instead able to dynamically infer it from the incoming data. Once the byte layout is obtained for the content, I use the <strong>LocalStorageHelper</strong> class to write it to a file.</p><p>As there are multiple UI items that need to be bound to collections and object instances, I have a <strong>CentralBindingPoint</strong> class in my main project that is my main view model (it implements <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged%28v=vs.95%29.aspx">INotifyPropertyChanged</a>). It implements the singleton pattern, so that the main instance is created on initialization and is subsequently re-used as necessary:</p><p><pre class="brush: csharp">
using Coding4Fun.Lockscreen.Core.Models;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Coding4Fun.Lockscreen.Mobile
{    
    public class CentralBindingPoint : INotifyPropertyChanged    
    {    
        static CentralBindingPoint instance = null;    
        static readonly object padlock = new object();
        
        public CentralBindingPoint()
        {    
            Categories = new ObservableCollection&lt;Category&gt;();    
            CustomCategories = new ObservableCollection&lt;Category&gt;();    
        }
        
        public static CentralBindingPoint Instance
        {    
            get    
            {    
                lock (padlock)    
                {    
                    if (instance == null)    
                    {    
                        instance = new CentralBindingPoint();    
                    }
                
                    return instance;        
                }
            }
        }
        
        private ObservableCollection&lt;Category&gt; _categories;
        public ObservableCollection&lt;Category&gt; Categories
        {    
            get    
            {    
                return _categories;    
            }
            set
            {    
                if (_categories != value)        
                {    
                    _categories = value;    
                    NotifyPropertyChanged(&quot;Categories&quot;);
                }
            }
        }
        
        private ObservableCollection&lt;Category&gt; _customCategories;
        public ObservableCollection&lt;Category&gt; CustomCategories
        {    
            get    
            {    
                return _customCategories;    
            }
            set
            {    
                if (_customCategories != value)    
                {    
                    _customCategories = value;    
                    NotifyPropertyChanged(&quot;CustomCategories&quot;);
                }        
            }
        }
    
        private Category _currentCategory;    
        public Category CurrentCategory
        {    
            get    
            {        
                return _currentCategory;    
            }
            set
            {    
                if (_currentCategory != value)    
                {    
                    _currentCategory = value;    
                    NotifyPropertyChanged(&quot;CurrentCategory&quot;);
                }
            }
        }
        
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {    
            if (PropertyChanged != null)    
            {    
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(    
                () =&gt;
                {    
                    PropertyChanged(this, new PropertyChangedEventArgs(info));    
                });
            }
        }
    }
}
</pre></p><p>On the main page, I create a <a href="http://msdn.microsoft.com/en-US/library/windowsphone/develop/microsoft.phone.controls.pivot%28v=vs.105%29.aspx">Pivot-based layout</a> to have an easy way to transition between the web collections (categories) and the local ones:</p><p><img src="http://www.codeplex.com/Download?ProjectName=lockscreen&amp;DownloadId=631917" alt="" width="288" height="480" border="0"></p><p>For each of the collection types, there is a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox%28v=vs.95%29.aspx">ListBox</a> with a custom <a href="http://msdn.microsoft.com/en-us/library/system.windows.datatemplate%28v=VS.95%29.aspx">DataTemplate</a> assigned for each item. The items are obtained from the <strong>Categories</strong> collection for web sets and the <strong>CustomCategories</strong> collection for local sets, both in the <strong>CentralBindingPoint</strong> view model.</p><p>The categories are loaded with the help of the <strong>DataEngine</strong> class that I added in the Data folder in the main application project. It is a wrapper for the Azure Mobile Services data operations, allowing me to aggregate the list of categories and images, given that I know the category index:</p><p><pre class="brush: csharp">
public class DataEngine
{    
    async public Task&lt;List&lt;Category&gt;&gt; GetCategoryList()    
    {    
        IMobileServiceTable&lt;Category&gt; table = App.MobileService.GetTable&lt;Category&gt;();    
        List&lt;Category&gt; data = await table.ToListAsync();
        
        return data;
    }
    
    async public Task&lt;List&lt;Image&gt;&gt; GetImagesByCategoryId(int categoryId)
    {    
        IMobileServiceTable&lt;Image&gt; table = App.MobileService.GetTable&lt;Image&gt;();    
        List&lt;Image&gt; data = await table.Where(x =&gt; x.CategoryID == categoryId).ToListAsync();
        
        return data;
    }
}
</pre></p><p>When the main page loads, I use the local <strong>DataEngine</strong> instance to call <strong>GetCategoryList</strong> and obtain a List&lt;Category&gt; collection that is subsequently transformed into an <strong>ObservableCollection</strong> through one of the default constructors:</p><p><pre class="brush: csharp">
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{    
    CentralBindingPoint.Instance.Categories = new ObservableCollection&lt;Category&gt;(await dataEngine.GetCategoryList());    
}
</pre></p><p>When a category is selected in the web sets list, I assign the selected item as the current category and navigate to the <strong>ImageSetPage.xaml</strong> page that will display the associated images:</p><p><pre class="brush: csharp">
async void ListBox_SelectionChanged_1(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{    
    var box = (ListBox)sender;
    
    if (box.SelectedItem != null)    
    {    
        Category selectedCategory = (Category)box.SelectedItem;    
        selectedCategory.Images = new ObservableCollection&lt;Coding4Fun.Lockscreen.Core.Models.Image&gt;
        (await dataEngine.GetImagesByCategoryId((int)selectedCategory.id));
        
        CentralBindingPoint.Instance.CurrentCategory = selectedCategory;
        NavigationService.Navigate(new Uri(&quot;/ImageSetPage.xaml&quot;, UriKind.Relative));
    }
}
</pre></p><p>Notice that the images are not loaded at the same time as the categories; rather, they’re loaded only when a category has been selected, hence the <strong>GetImagesByCategoryId</strong> call on selection.</p><p>For a custom set, the procedure is pretty much the same, the only difference being the fact that image references are already present since those were deserialized from the local storage:</p><p><pre class="brush: csharp">
private void lstCustomSets_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{    
    var box = (ListBox)sender;
    
    if (box.SelectedItem != null)    
    {    
        Category selectedCategory = (Category)box.SelectedItem;    
        CentralBindingPoint.Instance.CurrentCategory = selectedCategory;
        NavigationService.Navigate(new Uri(&quot;/ImageSetPage.xaml&quot;, UriKind.Relative));
    }
}
</pre></p><p>In <strong>ImageSetPage.xaml</strong> I use a <strong>ListBox</strong> with a <strong>WrapPanel</strong> in the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemspaneltemplate.aspx">ItemsPanelTemplate</a>, which ensures that I can have only two images in a row and any additions will be wrapped, with a fixed row length. You can get that control from the <a href="http://phone.codeplex.com/">WPToolkit</a> (formerly known as Silverlight Toolkit for Windows Phone, <a href="https://nuget.org/packages/WPtoolkit">available on NuGet</a>).</p><p><img src="http://www.codeplex.com/Download?ProjectName=lockscreen&amp;DownloadId=631916" alt="" width="288" height="480"></p><p>Here is the basic XAML layout:</p><p><pre class="brush: xml">
&lt;ListBox 
    SelectionMode=&quot;Single&quot;
    Margin=&quot;24&quot;
    x:Name=&quot;lstImages&quot; SelectionChanged=&quot;lstImages_SelectionChanged_1&quot;
    ItemsSource=&quot;{Binding Path=Instance.CurrentCategory.Images,
    Source={StaticResource CentralBindingPoint}}&quot;
    ItemTemplate=&quot;{StaticResource ListItemTemplate}&quot;&gt;
    &lt;ListBox.ItemsPanel&gt;
        &lt;ItemsPanelTemplate&gt;
            &lt;toolkit:WrapPanel ItemWidth=&quot;216&quot; ItemHeight=&quot;260&quot;/&gt;
        &lt;/ItemsPanelTemplate&gt;
    &lt;/ListBox.ItemsPanel&gt;
&lt;/ListBox&gt;
</pre></p><p>Now that we have a basic skeleton for the incoming data, let’s see how it can be transformed into a live lockscreen, on which wallpapers can be cycled. In the <strong>ImageSetPage.xaml</strong> page I have a button in the application bar that allows me to set the current category as the source for the switching wallpapers.</p><p>Currently, each <strong>Image</strong> instance carries an image URL and the images can be located anywhere outside the application. This can cause problems with the wallpaper setting process, however, since the API only allows local images to be set as background. This means that I need to download each image to the local application folder:</p><p><pre class="brush: csharp">
private async void btnSetStack_Click_1(object sender, EventArgs e)
{    
    var isProvider = Windows.Phone.System.UserProfile.LockScreenManager.IsProvidedByCurrentApplication;
    
    if (!isProvider)    
    {    
        var op = await Windows.Phone.System.UserProfile.LockScreenManager.RequestAccessAsync();    
        isProvider = op == Windows.Phone.System.UserProfile.LockScreenRequestResult.Granted;
    }
    
    if (isProvider)
    {    
        downloadableItems = new List&lt;string&gt;();    
        fileItems = new List&lt;string&gt;();

        foreach (var image in CentralBindingPoint.Instance.CurrentCategory.Images)        
        {    
            downloadableItems.Add(image.URL);    
            fileItems.Add(Path.GetFileName(image.URL));    
        }
        
        SerializationHelper.SerializeToFile(fileItems, &quot;imagestack.xml&quot;);
        LocalStorageHelper.ClearFolder(&quot;CurrentSet&quot;);
        DownloadImages();
        grdDownloading.Visibility = System.Windows.Visibility.Visible;
    }
}
</pre></p><p>First of all, I need to make sure that the application can set a lockscreen background and is registered in the OS as a provider. The application needs to state its intent to be able to access the wallpaper by adding this snippet to the <strong>WMAppManifest.xml</strong>, right after the <strong>Tokens</strong> node:</p><p><pre class="brush: xml">
&lt;Extensions&gt;
      &lt;Extension ExtensionName=&quot;LockScreen_Background&quot; ConsumerID=&quot;{111DFF24-AA15-4A96-8006-2BFF8122084F}&quot; TaskID=&quot;_default&quot; /&gt;
&lt;/Extensions&gt;
</pre></p><p><strong>downloadableItems</strong> is a collection that represents the download queue. <strong>fileItems</strong> contains the local file names for each image that is about to be downloaded and will be serialized and used in the background agent to iterate through the category files. Whenever the download process is started, an overlay becomes visible to notify the user that the image acquisition process is in progress.</p><p>Also, notice the fact that I am calling <strong>LocalStorageHelper.ClearFolder</strong>, passing the name of the folder as the first argument. I do not want to keep images for sets that are not active, therefore when a new set is selected, the currently stored images are deleted from the <strong>CurrentSet</strong> folder and replaced by the ones that are about to be downloaded. The implementation of the <strong>ClearFolder</strong> function looks like this:</p><p><pre class="brush: csharp">
public static void ClearFolder(string folderName
{    
    if (store.DirectoryExists(folderName))    
    {    
        foreach (string file in store.GetFileNames(folderName &#43; &quot;\\*.*&quot;))    
        {    
            store.DeleteFile(folderName &#43; &quot;\\&quot; &#43; file);    
        }
    }
}
</pre></p><p>Once the file names are stored in <strong>imagestack.xml</strong>, the image contents are downloaded via <strong>DownloadImages</strong>:</p><p><pre class="brush: csharp">
void DownloadImages()
{    
    WebClient client = new WebClient();    
    string fileName = Path.GetFileName(downloadableItems.First());
    client.OpenReadAsync(new Uri(downloadableItems.First()));
    client.OpenReadCompleted &#43;= (sender, args) =&gt;
    {    
        Debug.WriteLine(&quot;Downloaded &quot; &#43; fileName);    
        LocalStorageHelper.WriteData(&quot;CurrentSet&quot;, fileName, StreamToByteArray(args.Result));
        downloadableItems.Remove(downloadableItems.First());
        if (downloadableItems.Count != 0)
            DownloadImages();
        else
        {    
            grdDownloading.Visibility = System.Windows.Visibility.Collapsed;    
            LocalStorageHelper.CycleThroughImages();
            
            //ScheduledActionService.LaunchForTest(&quot;LockscreenChanger&quot;, TimeSpan.FromSeconds(5));
        }
    };
}
</pre></p><p>Here you can see that I am making a call to <strong>LocalStorageHelper.CycleThroughImages</strong>—a function that reads the file that contains the current set and picks the first image, assigning it to be the current wallpaper and then pushing it to the back of the list, making the succeeding image the next in line for the wallpaper:</p><p><pre class="brush: csharp">
public static void CycleThroughImages()
{    
    List&lt;string&gt; images = Coding4Fun.Phone.Storage.Serialize.Open&lt;List&lt;string&gt;&gt;(&quot;imagestack.xml&quot;);    
    if (images != null)
    {    
        string tempImage = images.First();    
        Uri currentImageUri = new Uri(&quot;ms-appdata:///Local/CurrentSet/&quot; &#43; tempImage, UriKind.Absolute);
        Windows.Phone.System.UserProfile.LockScreen.SetImageUri(currentImageUri);
        images.Remove(tempImage);
        images.Add(tempImage);
        Coding4Fun.Phone.Storage.Serialize.Save&lt;List&lt;string&gt;&gt;(&quot;imagestack.xml&quot;, images);
    }
}
</pre></p><p>You might be wondering why I’m not using <a href="http://msdn.microsoft.com/en-us/library/7977ey2c.aspx">Queue&lt;T&gt;</a> for this. After all, <strong>Enqueue</strong> and <strong>Dequeue</strong> would make things a bit easier. The problem is that a Queue instance cannot be directly serialized without being transformed to a flat list. Therefore, I am sticking to minimal resource processing by manipulating a <strong>List&lt;T&gt;</strong> instance instead.</p><p>The recursive image download method runs until the download queue is emptied, after which the overlay is hidden.</p><h1>Background Agent</h1><p>At this point, we have the images locally stored and listed in an XML file. If the user accepted the system prompt, the application has also been registered as a lockscreen background provider, but there is not yet a single piece of code that would actually set the wallpaper cycle. For that, create a new Background Agent project in your solution. I named mine <strong>Coding4Fun.Lockscreen.Agent</strong>.</p><p>The <strong>OnInvoke</strong> function in <strong>ScheduledAgent.cs</strong> is executed at 30-minute intervals. This is a time limit defined by the <a href="http://msdn.microsoft.com/en-US/library/windowsphone/develop/microsoft.phone.scheduler.periodictask%28v=vs.105%29.aspx">PeriodicTask</a> background agent type that we’ll be using here. You need to add the following snippet to it:</p><p><pre class="brush: csharp">
protected override void OnInvoke(ScheduledTask task)
{    
    var isProvider = Windows.Phone.System.UserProfile.LockScreenManager.IsProvidedByCurrentApplication;    
    if (isProvider)
    {    
        LocalStorageHelper.CycleThroughImages();    
    }
    NotifyComplete();
}
</pre></p><p>As with the download snippet, I am ensuring that before I attempt to change the wallpaper the application is a registered provider. Otherwise, an exception will be thrown and the background agent will crash. The bad thing about periodic tasks crashing is the fact that once two consecutive crashes occur, the task is removed from the task queue and the backgrounds will not be changed.</p><p>If the application is a provider, call <strong>CycleThroughImages</strong> to set the new background and push the old one to the end of the list. To make sure that a different image is selected each time, the original deserialized list is modified, where the first image now becomes last, switching the stack up, after which it is serialized back into <strong>imagestack.xml</strong>.</p><p>The background agent needs to be registered in the <strong>WMAppManifest.xml</strong>. Inside the Tasks node, add an ExtendedTask:</p><p><pre class="brush: csharp">
&lt;ExtendedTask Name=&quot;LockscreenChangerTask&quot;&gt;
    &lt;BackgroundServiceAgent Specifier=&quot;ScheduledTaskAgent&quot;
        Name=&quot;LockscreenChanger&quot;
        Source=&quot;Coding4Fun.Lockscreen.Agent&quot;
        Type=&quot;Coding4Fun.Lockscreen.Agent.ScheduledAgent&quot; /&gt;
&lt;/ExtendedTask&gt;
</pre></p><p>Also, when the application starts, you need to ensure that the task is registered, and register it if it isn’t yet. Use the Application_Launching event handler for this task:</p><p><pre class="brush: csharp">
private void Application_Launching(object sender, LaunchingEventArgs e)
{    
    string taskName = &quot;LockscreenChanger&quot;;    
    var oldTask = ScheduledActionService.Find(taskName) as PeriodicTask;

    if (oldTask != null)
    {    
        ScheduledActionService.Remove(taskName);    
    }
    
    PeriodicTask task = new PeriodicTask(taskName);
    task.Description = &quot;Change lockscreen wallpaper.&quot;;
    
    ScheduledActionService.Add(task);    
    LoadCustomCategories();    
}
</pre></p><p>Here, <strong>LoadCustomCategories</strong> will deserialize the existing custom categories, so that those can be shown in the main page after the application starts:</p><p><pre class="brush: csharp">
private async void LoadCustomCategories()
{    
    try    
    {    
        CentralBindingPoint.Instance.CustomCategories =    
        (ObservableCollection&lt;Category&gt;)await SerializationHelper.DeserializeFromFile(
        typeof(ObservableCollection&lt;Category&gt;), &quot;customcat.xml&quot;);
    }
    catch
    {    
        Debug.WriteLine(&quot;No customcat.xml - no registered custom categories.&quot;);    
    }
}
</pre></p><p>Now the backgrounds will automatically change based on the web sets that you will activate every 30 minutes.</p><h1>Working with Custom Categories</h1><p>Let’s create some custom sets. To manage user input, I leverage the <strong>CustomMessageBox</strong> control available in the <a href="http://phone.codeplex.com/">Windows Phone Toolkit</a>. It has enough flexibility to let me choose between adding a <strong>TextBox</strong> control, to have the user create the new category or use a <strong>ListPicker</strong> to show the available custom categories in a consistent UI layout.</p><p>When the user decides to create a new category, he taps the plus button in the application bar on the main page:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image022%5B5%5D.png"><img title="clip_image022" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image022_thumb%5B2%5D.png" alt="clip_image022" width="262" height="437" border="0"></a></p><p>The implementation for the call is simple:</p><p><pre class="brush: csharp">
private void btnSetStack_Click_1(object sender, EventArgs e)
{    
    TextBox textBox = new TextBox();    
    CustomMessageBox box = new CustomMessageBox()
    {    
        Caption = &quot;Add Custom Category&quot;,    
        Message = &quot;Enter a unique name for the new category.&quot;,
        LeftButtonContent = &quot;ok&quot;,
        RightButtonContent = &quot;cancel&quot;,
        Content = textBox
    };
    
    box.Dismissed &#43;= (s, boxEventArgs) =&gt;
    {    
        if (boxEventArgs.Result == CustomMessageBoxResult.LeftButton)    
        {    
                    if (!string.IsNullOrWhiteSpace(textBox.Text))    
                    {    
                        var categoryCheck = (from c in CentralBindingPoint.Instance.CustomCategories    
                        where
                        c.Name == textBox.Text
                        select c).FirstOrDefault();
                        
                        if (categoryCheck == null)
                        {    
                            Category category = new Category() { Name = textBox.Text };
                            CentralBindingPoint.Instance.CustomCategories.Add(category);
                            Coding4Fun.Toolkit.Storage.Serialize.Save&lt;ObservableCollection&lt;Category&gt;&gt;(
                            &quot;customcat.xml&quot;, CentralBindingPoint.Instance.CustomCategories);
                        }
                        else
                        {    
                            MessageBox.Show(&quot;Add Custom Category&quot;,    
                            &quot;This category name was already taken!&quot;,
                            MessageBoxButton.OK);
                        }
                    }
        }        
    };
    
    box.Show();    
}
</pre></p><p>When the message box is dismissed, I check which button is pressed to take the appropriate course of action. Let’s assume that the user decided to add the new category—we need to check and make sure that there isn’t already a category with the same name in the existing collection. If there isn’t one, a new <strong>Category</strong> instance is created, added to the collection in the main view model, and serialized to <strong>customcat.xml</strong>.</p><p>The user also needs to be able to add images from any category to another custom category. To do this, I decided to give the user the option to carry across the image name and URL when he taps on an image in the <strong>ImageSetPage.xaml</strong>.</p><p>Remember, if there are no current custom categories registered, the user should be informed that he should create some first, so the alternative route for the dialog with custom category name selection should be a message box alert:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image024%5B5%5D.png"><img title="clip_image024" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image024_thumb%5B2%5D.png" alt="clip_image024" width="264" height="440" border="0"></a></p><p>Here is the snippet that does this:</p><p><pre class="brush: csharp">
private void lstImages_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{    
    if (CentralBindingPoint.Instance.CustomCategories.Count &gt; 0)    
    {    
        if (lstImages.SelectedItem != null)    
        {    
            ListPicker picker = new ListPicker()    
            {    
                Header = &quot;Custom category name:&quot;,    
                ItemsSource = CentralBindingPoint.Instance.CustomCategories,
                Margin = new Thickness(12, 42, 24, 18)
            };
            
            CustomMessageBox messageBox = new CustomMessageBox()
            {    
                Caption = &quot;Add To Custom Category&quot;,    
                Message = &quot;Select a registered custom category to add this image to.&quot;,
                Content = picker,
                LeftButtonContent = &quot;ok&quot;,
                RightButtonContent = &quot;cancel&quot;
            };
            
            messageBox.Dismissing &#43;= (s, boxEventArgs) =&gt;
            {    
                if (picker.ListPickerMode == ListPickerMode.Expanded)    
                {    
                    boxEventArgs.Cancel = true;    
                }
            };
            
            messageBox.Dismissed &#43;= (s2, e2) =&gt;
            {    
                switch (e2.Result)    
                {    
                    case CustomMessageBoxResult.LeftButton:    
                    {    
                        if (picker.SelectedItem != null)    
                        {    
                            Category category = (from c in CentralBindingPoint.Instance.CustomCategories    
                            where c.Name == picker.SelectedItem.ToString()
                            select c).FirstOrDefault();
                            
                            if (category != null)
                            {    
                                category.Images.Add((Coding4Fun.Lockscreen.Core.Models.Image)lstImages.SelectedItem);    
                                Coding4Fun.Toolkit.Storage.Serialize.Save&lt;ObservableCollection&lt;Category&gt;&gt;(
                                &quot;customcat.xml&quot;, CentralBindingPoint.Instance.CustomCategories);
                            }
                            
                            lstImages.SelectedItem = null;
                            lstImages.IsEnabled = true;
                        }
                        break;
                    }
            
                    case CustomMessageBoxResult.RightButton:        
                    case CustomMessageBoxResult.None:
                    {    
                        lstImages.SelectedItem = null;                    
                        break;
                    }
                }
            };
            
            messageBox.Show();
        }
    }
    else
    {    
        MessageBox.Show(&quot;Add To Custom Category&quot;,    
        &quot;Tapping on an image will prompt you to add it to a custom category&quot; &#43; Environment.NewLine &#43;
        &quot;Seems like you don't have any custom categories yet.&quot;, MessageBoxButton.OK);    
    }
}
</pre></p><p>Once the category is selected from the list, the image is added to the Images collection in the <strong>Category</strong> instance, and the category list is serialized to preserve the changes. There are no restrictions as to which categories can fetch images to other categories—we can even select images from custom categories and include them in other categories. The image can be added multiple times to the same category as well.</p><h1>Conclusion</h1><p>With Azure Mobile Services and a managed SDK available for Windows Phone, as well as an open REST API, it is fairly easy to build connected applications on multiple platforms at once without major logic and code base modifications.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1d735d263cfc4453ba06a1870057ac0e">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Dynamic-Lockscreen-Changer-for-Windows-Phone-8-Built-With-ASPNET-MVC-and-Azure-Mobile-Services</comments>
      <itunes:summary>With the release of Windows Phone 8, a few new developer API endpoints were made available that allow third-party applications to change the device lockscreen image. In this article, I am establishing the infrastructure and building a mobile application that provides the ability to choose from a number of dynamic image sets, from which images can be selected and then cycled as lockscreen wallpapers. What do you needYou will need to download and install ASP.NET MVC3 to work on the web frontend and Windows Phone 8 SDK to work on the mobile applications. An Azure Mobile Services account will be necessary, and of course don’t forget to download and install the Azure Mobile Services client libraries. All three components are available at no additional charge. NOTE: Without the Azure Mobile Services SDK installed on the development machine, the compilation process will fail for the Windows Phone application. Setting up The Data StoreFirst we need to establish the general design of the application and organize the workflow. The application will provide two ways to assign the dynamic lockscreen: With the help of custom image sets that are provided by the service; With the help of self-created image sets, aggregated from images provided by the service but ultimately managed by the end-user. Let’s talk about the general data model. Every image belongs to a certain category and to keep track of each we need a table with two columns—category ID and category name. We also need another core table containing the image references themselves, with the following columns: image URL, descriptive name, and the category ID to which it belongs. The overall structure looks like this:  Now to the Windows Azure Management Portal and creating a new Mobile Service.  Once created, you need to specify database information, just like you would with a standard SQL Server database:  As the database is being created, you can easily integrate it with SQL Server Management Studio. You will need the se</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Dynamic-Lockscreen-Changer-for-Windows-Phone-8-Built-With-ASPNET-MVC-and-Azure-Mobile-Services</link>
      <pubDate>Mon, 25 Mar 2013 15:39:25 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Dynamic-Lockscreen-Changer-for-Windows-Phone-8-Built-With-ASPNET-MVC-and-Azure-Mobile-Services</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/6e006890-17a7-490b-84ab-dc762acb6541.png" height="100" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/ac86e266-3378-4993-b73b-0e3d002b3ca5.png" height="220" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/f6acb002-27be-41d5-8f4d-97ca7e170e80.png" height="284" width="512"></media:thumbnail>      
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Dynamic-Lockscreen-Changer-for-Windows-Phone-8-Built-With-ASPNET-MVC-and-Azure-Mobile-Services/RSS</wfw:commentRss>
      <category>Azure</category>
      <category>MVC</category>
      <category>Windows Phone</category>
      <category>Windows Azure Mobile Services</category>
    </item>
  <item>
      <title>TWC9: Kinect for Windows SDK v1.7, SignalR eBook, Meteor and more</title>
      <description><![CDATA[<p>This week on Channel 9, Dan and Clint discuss the week's top developer news, including;</p><ul><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=0m26s">[00:26]</a> <a href="http://blogs.msdn.com/b/kinectforwindows/">The latest Kinect for Windows [v1.7] SDK is here</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=1m38s">[01:38]</a> <a href="http://weblogs.asp.net/scottgu/archive/2013/03/18/windows-azure-new-hadoop-service-html5-js-cors-phonegap-mercurial-and-dropbox-support.aspx">Windows Azure: New Hadoop service &#43; HTML5/JS (CORS), PhoneGap, Mercurial and Dropbox support</a> (Scott Guthrie), <a href="http://channel9.msdn.com/Series/Windows-Azure-Mobile-Services/Getting-Started-with-the-Mobile-Services-HTML-Client">Getting Started with the Mobile Services HTML Client</a> (Nick Harris) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=2m43s">[02:43]</a> <a href="http://www.campusmvp.net/signalr-ebook/">SignalR eBook </a>(campusMVP.Net, Jose M Aguilar) [Found via: <a href="http://blog.cwa.me.uk/2013/03/15/the-morning-brew-1316/">The Morning Brew #1316</a>] </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=3m34s">[03:34]</a> <a href="http://visualstudiomagazine.com/articles/2013/03/01/pattern-recognition-with-perceptrons.aspx">Modeling Neuron Behavior in C#</a> (James McCaffrey) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=4m59s">[04:59]</a> <a href="http://blog.aviary.com/aviary-launches-windows-8-sdk-with-6-partners/">Aviary Launches Windows 8 SDK with 6 Partners</a> </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=6m00s">[06:00]</a> <a href="http://dx.codeplex.com/">dx.h - A modern C&#43;&#43; library for DirectX programming</a> (Kenny Kerrca) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=6m52s">[06:52]</a> <a href="http://stephenwalther.com/archive/2013/03/18/an-introduction-to-meteor.aspx">An Introduction to Meteor</a> (Stephen Walther) </li><li><a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=7m54s">[07:54]</a><strong>&nbsp;</strong><a href="http://blogs.msdn.com/b/ukmsdn/archive/2013/03/19/from-a-side-project-to-windows-8-store-featured-app-the-interference-story.aspx">From a side project to Windows 8 Store featured app - the Interference story</a> (Sara Allison) </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Dan's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=8m55s">[08:55]</a> <a href="http://lifehacker.com/5991385/treat-your-kids-like-a-team-of-agile-software-developers-and-lower-your-family-stress">Treat Your Kids Like a Team of Agile Software Developers and Lower Your Family Stress</a> (Whitson Gordon) </li><li>Clint's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013#time=10m50s">[10:50]</a> <a href="http://www.imaginecup.com/IC13/Competition/Kodu#?fbid=9G8pi-J5C80">Kodu Challenge</a> (Jennifer Ritzinger) </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:e1af67c4d9da467bb865a18901081bbb">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013</comments>
      <itunes:summary>This week on Channel 9, Dan and Clint discuss the week&#39;s top developer news, including; [00:26] The latest Kinect for Windows [v1.7] SDK is here [01:38] Windows Azure: New Hadoop service &amp;#43; HTML5/JS (CORS), PhoneGap, Mercurial and Dropbox support (Scott Guthrie), Getting Started with the Mobile Services HTML Client (Nick Harris) [02:43] SignalR eBook (campusMVP.Net, Jose M Aguilar) [Found via: The Morning Brew #1316] [03:34] Modeling Neuron Behavior in C# (James McCaffrey) [04:59] Aviary Launches Windows 8 SDK with 6 Partners [06:00] dx.h - A modern C&amp;#43;&amp;#43; library for DirectX programming (Kenny Kerrca) [06:52] An Introduction to Meteor (Stephen Walther) [07:54]&amp;nbsp;From a side project to Windows 8 Store featured app - the Interference story (Sara Allison) Picks of the Week! Dan&#39;s Pick of the Week:[08:55] Treat Your Kids Like a Team of Agile Software Developers and Lower Your Family Stress (Whitson Gordon) Clint&#39;s Pick of the Week:[10:50] Kodu Challenge (Jennifer Ritzinger) </itunes:summary>
      <itunes:duration>752</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013</link>
      <pubDate>Sat, 23 Mar 2013 23:40:14 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.mp3" expression="full" duration="752" fileSize="12043500" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.mp4" expression="full" duration="752" fileSize="71926377" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.webm" expression="full" duration="752" fileSize="27559937" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.wma" expression="full" duration="752" fileSize="6091135" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.wmv" expression="full" duration="752" fileSize="49580837" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013_high.mp4" expression="full" duration="752" fileSize="157586527" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013_mid.mp4" expression="full" duration="752" fileSize="110037971" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013_Source.wmv" expression="full" duration="752" fileSize="142696886" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.ism/manifest" expression="full" duration="752" fileSize="6046" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/d2c8/1a4dada0-3001-45f6-9a1c-3f815939d2c8/TWC9Mar222013.wmv" length="49580837" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Dan Fernandez, Greg Duncan</dc:creator>
      <itunes:author>Clint Rutkas, Dan Fernandez, Greg Duncan</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-22-2013/RSS</wfw:commentRss>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX 11</category>
      <category>Kinect</category>
      <category>Kodu</category>
      <category>Windows Azure</category>
      <category>Signal</category>
      <category>Kinect SDK</category>
    </item>
  <item>
      <title>Channel 9 turns 9!</title>
      <description><![CDATA[<p><span>From our humble beginnings as a website built with alpha quality forum technologies that we stitched together with creative code and a lot of love, and our videos were made by a few dudes roaming the halls of Microsoft with a cheap camcorder – look at us now. Channel 9 streams live events to 100,000s of people around the world, we have a state of the art recording studio, we do C9 Live at events around the world bringing you directly into the conversation with Microsoft folks in real time. Today, much of our content is created from folks around the company. Channel 9 is THE place to watch MS events on demand and to learn about our technologies from the people who make them – people are the lifeblood of software and technology. Channel 9 is people! <br><br>Today marks 9 years of 9. It's a very special day. We are especially humbled and honored to still be around given the change rate of the web. We thank all past, present and future Niners for the excellent conversations, arguments, debates, entertainment, and camaraderie. &nbsp;9 Years of 9. That rolls so nicely off the tongue.&nbsp; Here's to 9 more.</span></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:5982f907684740249cfea182000a5272">]]></description>
      <comments>http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9</comments>
      <itunes:summary>From our humble beginnings as a website built with alpha quality forum technologies that we stitched together with creative code and a lot of love, and our videos were made by a few dudes roaming the halls of Microsoft with a cheap camcorder – look at us now. Channel 9 streams live events to 100,000s of people around the world, we have a state of the art recording studio, we do C9 Live at events around the world bringing you directly into the conversation with Microsoft folks in real time. Today, much of our content is created from folks around the company. Channel 9 is THE place to watch MS events on demand and to learn about our technologies from the people who make them – people are the lifeblood of software and technology. Channel 9 is people! Today marks 9 years of 9. It&#39;s a very special day. We are especially humbled and honored to still be around given the change rate of the web. We thank all past, present and future Niners for the excellent conversations, arguments, debates, entertainment, and camaraderie. &amp;nbsp;9 Years of 9. That rolls so nicely off the tongue.&amp;nbsp; Here&#39;s to 9 more. </itunes:summary>
      <itunes:duration>562</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9</link>
      <pubDate>Fri, 15 Mar 2013 13:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.mp3" expression="full" duration="562" fileSize="9007482" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.mp4" expression="full" duration="562" fileSize="52588716" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.webm" expression="full" duration="562" fileSize="21935504" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.wma" expression="full" duration="562" fileSize="4559095" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.wmv" expression="full" duration="562" fileSize="62278697" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_high.mp4" expression="full" duration="562" fileSize="114186491" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_mid.mp4" expression="full" duration="562" fileSize="79671024" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_Source.wmv" expression="full" duration="562" fileSize="313490493" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.ism/manifest" expression="full" duration="562" fileSize="8462" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.wmv" length="62278697" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Charles, Clint Rutkas, Dan Fernandez, Duncan Mackenzie, Jeff Sandquist, Larry Larsen, Laura Foy, Golnaz, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Charles, Clint Rutkas, Dan Fernandez, Duncan Mackenzie, Jeff Sandquist, Larry Larsen, Laura Foy, Golnaz, Rick Barraza</itunes:author>
      <slash:comments>48</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Flying the AR.Drone 2.0 with Windows Store Applications</title>
      <description><![CDATA[<h4>The AR.Drone 2.0</h4><p>The Parrot AR.Drone 2.0 is an awesome device packed with cool features. The drone contains two cameras, one pointed forward that streams live video, and one pointed downwards (for all your surveillance needs). Its got four powerful engines that make it fast and maneuverable. The drone’s firmware keeps it stable and level while stationary or performing maneuvers, handling a huge burden for the user. It’s a fun device to write code for, and even more fun to pilot when you’re done!</p><p>There’s a few projects that have created AR.Drone APIs that can be used for Windows 8 Desktop Apps. However, I wanted to fly my drone from a Windows Store App, so I decided to build my own API compatible with WinRT. The result is covered in this series of posts. Thanks to Nisha Singh (<a title="http://blogs.msdn.com/b/nishasingh/" href="http://blogs.msdn.com/b/nishasingh/">http://blogs.msdn.com/b/nishasingh/</a>) and everyone else who helped me out with this project!</p><p>In the first post, I’ll go over how the API handles communicating with and controlling the drone, and then demonstrate how to use the API to make a simple control App.</p><p>&nbsp;</p><h4>API Information and Terms</h4><p>The API consists of 5 files:</p><ul><li>DroneConnection.cs: functionality to connect to, and disconnect from, the drone. </li><li>DroneControl.cs: contains the control loop. </li><li>DroneMovement.cs: contains methods that construct and return fully-formatted commands. </li><li>InputProcessing.cs: determines the next command to issue to the drone. </li><li>InputState.cs: used to pass information between the UI and back-end. </li><li><p>The terms the API code uses to refer to axes of movement are as follows:</p></li><li>DroneStrafeX: left-right. </li><li>DroneStrafeY: forward-backward. </li><li>DroneRotateX: yaw, or rotation. </li><li>DroneAscendY: up-down. </li><li><p>&nbsp;</p><h4>Communicating with the Drone</h4><p>The AR.Drone 2.0 communicates with other devices through its own wireless network. Sending the drone instructions is as simple as connecting your computer to the drone’s network, opening a UDP connection to the drone (I.P. 192.168.1.1, Port 5556), and then sending commands over this connection. The code to connect to the drone is contained inside DroneConnection.cs:</p><pre class="brush: csharp">
// Initialize the connection to the drone
public static async Task ConnectToDrone()
{
      
         ...
      
         // Set up the UDP connection
         string remotePort = &quot;5556&quot;;
         HostName droneIP = new HostName(&quot;192.168.1.1&quot;);
      
         udpSocket = new DatagramSocket();
         await udpSocket.BindServiceNameAsync(remotePort);
         await udpSocket.ConnectAsync(droneIP, remotePort);
         udpWriter = new DataWriter(udpSocket.OutputStream);
      
         ...
      
}
</pre> <div id="codeSnippetWrapper">&nbsp;</div><p>Once a connection has been established, we can begin to send the drone messages:</p><p><pre class="brush: csharp">
// Send a command to the drone
public static async Task SendDroneCommand(string command)
{
         udpWriter.WriteString(command);
         await udpWriter.StoreAsync();
}
</pre></p><p>This networking code is discussed more in-depth here: <a title="http://blogs.msdn.com/b/trycatchfinally/archive/2012/09/06/welcome.aspx" href="http://blogs.msdn.com/b/trycatchfinally/archive/2012/09/06/welcome.aspx">Try, Catch, Finally... - UDP and Windows 8 Apps</a></p><p>The drone needs to continuously receive commands for it to remain responsive. If the drone doesn’t receive any commands for two seconds, it assumes the connection has been lost, and it will ignore any further commands. If this happens, you need to close and re-establish the connection before you can continue to pilot the drone. DroneConnection.cs contains methods that allow you to do this.</p><p>&nbsp;</p><h4>Commanding the Drone</h4><p>You can command the drone by sending it strings called AT commands. There are seven different categories of AT commands, but only two are required to fly the drone, and are the only ones included in the API:</p></li><li>AT*REF – Used for basic behavior such as takeoff/landing, and emergency stop/reset. </li><li>AT*PCMD – Used to fly the drone once airborne. This controls pitch, yaw, roll, and altitude. </li><li><p>AT commands have very specific formatting, and consist of four parts. An improperly formatted command will be ignored by the drone. The different sections of an AT*PCMD command are highlighted below:</p><p>&nbsp;</p><p>AT*PCMD=23,1,0,0,0,0\r\n</p><p>&nbsp;</p><p>Header: The type of the AT command</p><p>Sequence Number: The sequence number is used by the drone to keep track of which commands it needs to execute. The drone will not execute any commands with a sequence number lower than the highest sequence number it has received so far. The first command sent should always have a sequence number of 1, and each command sent subsequently should increment this number by 1. The sequence number can be manually reset by sending a command with the number 1.</p><p>Payload: This carries the command arguments. Its format and content vary from command to command. In the AT*PCMD command, the first value is a flag indicating whether the drone should do nothing (low) or move according to the other arguments (high). The next four values denote roll, pitch, vertical speed, and angular speed respectively. These values are floats ranging from [-1, 1], where (0, 1] represents movement speed in one direction, and [-1, 0) represents the other. A 0 causes the drone to remain stationary along that axis, a 1 or –1 is maximum movement speed in their respective directions, and each value between is a fraction of the maximum possible speed. For example, in the pitch argument, a .75 would cause the drone to move backward at 3/4 maximum speed, while a –.5 would make it move forward at 1/2 the possible speed. However, the drone doesn’t respond to values in the [-1, 1] range. The actual value that needs to be inserted into the AT command is the signed integer value represented by the bytes the float is actually stored in. This conversion is done for you in the FloatConversion method in DroneMovement.cs.</p><p>Carriage Character: A newline character. Use the one specific to your environment.</p><p>DroneMovement.cs has a set of methods to generate AT*REF and AT*PCMD commands, all of which take the current sequence number as an argument, and return a ready-to-send AT command. Some methods take additional arguments to control the movement speed. An example of one of these methods is:</p><pre class="brush: csharp">
// Strafe drone forward or backward at velocity in range [-1,1]
public static string GetDroneStrafeForwardBackward(uint sequenceNumber, double velocity)
{
         // Convert the ratio into a value the drone understands
         int value = FloatConversion(velocity);
         return CreateATPCMDCommand(sequenceNumber, &quot;0,&quot; &#43; value &#43; &quot;,0,0&quot;); 
}
  
// Return a full ATPCMD command
private static string CreateATPCMDCommand(uint sequenceNumber, string command)
{
         return &quot;AT*PCMD=&quot; &#43; sequenceNumber &#43; &quot;,1,&quot; &#43; command &#43; Environment.NewLine;
}
</pre> <p><strong>Control Infrastructure</strong></p><p>The drone is controlled with an continuous loop that sends a command to the drone every 30 ms. Each cycle, the loop determines the next command, sends the command to the drone, and then increments the sequence number. The method is asynchronous and awaits the call to System.Threading.Tasks.Task.Delay() so that it doesn’t block the UI between cycles.</p><p><pre class="brush: csharp">
public static async void ControlLoop()
{
         while (true)
         {
          
                 ...
          
                 // Get and send the next command
                 string commandToSend = InputProcessing.NextCommand(sequenceNumber);
                 await DroneConnection.SendDroneCommand(commandToSend);
          
                 sequenceNumber&#43;&#43;;
          
                 await System.Threading.Tasks.Task.Delay(30);
         }
}
</pre></p><p>You need to implement the InputProcessing.NextCommand() method to return an AT command based on criteria of your own choosing. The API includes the class InputState.cs that you can use to pass information between your UI and the control infrastructure. The example App contains an example of this.</p><h4>Example App</h4><p>I’ve included a simple example App to demonstrate how to use the API. The App allows you to connect to the drone and make it take off, land, and rotate. It also illustrates how to pass input information between the UI and the control infrastructure using InputState instances. In the App, FlyingPage contains the method GetState() that returns an instance of InputState. GetState() looks at the input the App is receiving, then creates and returns an instance of InputState containing that information.</p><pre class="brush: csharp">
// returns the current state of the input controls
public static InputState GetState()
{
         // slider value is in the range [-1,1]
         return new InputState(0, 0, 0, sliderValue, isFlying);
}
</pre> <p>InputProcessing.NextCommand() calls GetState, and then interprets the state to decide on the next command to send:</p><pre class="brush: csharp">
// returns the next command that should be executed
public static string NextCommand(uint sequenceNumber)
{
         InputState state = MainPage.GetState();
      
         // Determine if the drone needs to take off or land
         if (state.startFlying &amp;&amp; !isFlying)
         {
                 isFlying = !isFlying;
                 return DroneMovement.GetDroneTakeoff(sequenceNumber);
         }
         else if (!state.startFlying &amp;&amp; isFlying)
         {
                 isFlying = !isFlying;
                 return DroneMovement.GetDroneLand(sequenceNumber);
         }
      
         
         // Check if the drone needs to rotate
         if (state.rotateX != 0)
         {
                 return DroneMovement.GetDroneRotate(sequenceNumber, state.rotateX);
         }
      
         // Otherwise have the drone do nothing.
         return DroneMovement.NullCommand(sequenceNumber);
}
</pre> <p>The command decision is made in order of importance. Takeoff and landing commands are the most important, followed by movement commands. If there is no other command to send, NextCommand() returns a null command so that the drone will continue hovering and listening to the connection.</p><p>Once NextCommand() has been implemented, all the App needs to do is connect to the drone and initiate the control loop by calling DroneConnection.ConnectToDrone(), followed by calling DroneControl.ControlLoop(). In the example App, this is done in the handler for the connect button. Once the control loop is running, the drone is ready to fly!</p><h4>Get Flying</h4><p>The API should give you everything you need to get started writing drone Apps for Windows Store. In part 2, I’ll discuss a more complete App I’ve written to pilot the drone. There’s still so much drone functionality to be exposed, so get coding and get flying!</p></li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:47d1ec89174242a29500a10b0130e4bf">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Flying-the-ARDrone-20-with-Windows-Store-Applications</comments>
      <itunes:summary>The AR.Drone 2.0The Parrot AR.Drone 2.0 is an awesome device packed with cool features. The drone contains two cameras, one pointed forward that streams live video, and one pointed downwards (for all your surveillance needs). Its got four powerful engines that make it fast and maneuverable. The drone’s firmware keeps it stable and level while stationary or performing maneuvers, handling a huge burden for the user. It’s a fun device to write code for, and even more fun to pilot when you’re done! There’s a few projects that have created AR.Drone APIs that can be used for Windows 8 Desktop Apps. However, I wanted to fly my drone from a Windows Store App, so I decided to build my own API compatible with WinRT. The result is covered in this series of posts. Thanks to Nisha Singh (http://blogs.msdn.com/b/nishasingh/) and everyone else who helped me out with this project! In the first post, I’ll go over how the API handles communicating with and controlling the drone, and then demonstrate how to use the API to make a simple control App. &amp;nbsp; API Information and TermsThe API consists of 5 files: DroneConnection.cs: functionality to connect to, and disconnect from, the drone. DroneControl.cs: contains the control loop. DroneMovement.cs: contains methods that construct and return fully-formatted commands. InputProcessing.cs: determines the next command to issue to the drone. InputState.cs: used to pass information between the UI and back-end. The terms the API code uses to refer to axes of movement are as follows: DroneStrafeX: left-right. DroneStrafeY: forward-backward. DroneRotateX: yaw, or rotation. DroneAscendY: up-down. &amp;nbsp; Communicating with the DroneThe AR.Drone 2.0 communicates with other devices through its own wireless network. Sending the drone instructions is as simple as connecting your computer to the drone’s network, opening a UDP connection to the drone (I.P. 192.168.1.1, Port 5556), and then sending commands over this connection. The code to connect to t</itunes:summary>
      <itunes:duration>38</itunes:duration>
      <link>http://channel9.msdn.com/coding4fun/articles/Flying-the-ARDrone-20-with-Windows-Store-Applications</link>
      <pubDate>Wed, 30 Jan 2013 20:44:13 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Flying-the-ARDrone-20-with-Windows-Store-Applications</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.mp3" expression="full" duration="38" fileSize="613368" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.mp4" expression="full" duration="38" fileSize="3549735" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.webm" expression="full" duration="38" fileSize="1414464" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.wma" expression="full" duration="38" fileSize="317447" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.wmv" expression="full" duration="38" fileSize="2360171" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone_high.mp4" expression="full" duration="38" fileSize="7740622" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone_mid.mp4" expression="full" duration="38" fileSize="5386511" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone_Source.wmv" expression="full" duration="38" fileSize="13005298" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.ism/manifest" expression="full" duration="38" fileSize="7674" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/106e/0b67c1ce-dbb3-40f2-8595-a22760b0106e/20121116arDrone.wmv" length="2360171" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Peter Dwersteg</dc:creator>
      <itunes:author>Clint Rutkas, Peter Dwersteg</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Flying-the-ARDrone-20-with-Windows-Store-Applications/RSS</wfw:commentRss>
      <category>C#</category>
      <category>Hardware</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>TWC9: Fall Fury, Azure push, Windows Phone 7.8 SDK, CHEEVOS! </title>
      <description><![CDATA[<p>This week on Channel 9, Dan and Clint discuss the week's top developer news, including;</p><ul><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=34s">[0:34]</a>&nbsp;<a href="http://weblogs.asp.net/scottgu/archive/2013/01/22/announcing-release-of-windows-azure-media-services.aspx">Announcing Release of Windows Azure Media Services</a> (Scott Guthrie) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=1m42s">[1:42]</a>&nbsp;<a href="http://weblogs.asp.net/scottgu/archive/2013/01/22/broadcast-push-notifications-to-millions-of-mobile-devices-using-windows-azure-notification-hubs.aspx">Broadcast push notifications to millions of mobile devices using Windows Azure Notification Hubs</a> (Scott Guthrie) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=2m33s">[2:33]</a>&nbsp;<a href="http://blogs.windows.com/windows_phone/b/wpdev/archive/2013/01/22/now-available-windows-phone-sdk-update-for-7-8.aspx">Now Available: Windows Phone SDK Update for 7.8</a> (Cliff Simpkins ) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=3m25s">[3:25]</a>&nbsp;<a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction">Fall Fury: Part 1 - Introduction</a> (Den Delimarsky, Brian Peek, Clint Rutkas, Dan Fernandez, Rick Barraza ) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=5m16s">[5:16]</a>&nbsp;<a href="http://worldwidecode.wordpress.com/2013/01/19/tile-design-guidelines-for-windows-phone-8/">Tile design guidelines for Windows Phone 8</a> (Shubhan Chemburkar) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=6m8s">[6:08]</a>&nbsp;<a href="http://blogs.msdn.com/b/windowsappdev/archive/2013/01/21/building-the-bing-apps-for-windows-8.aspx">Building the Bing apps for Windows 8</a> (Jigar Thakkar) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=7m18s">[7:18]</a>&nbsp;<a href="http://www.codeproject.com/Articles/533151/Building-HTML5-Games-for-the-Atari-Arcade">Building HTML5 Games for the Atari Arcade</a> </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=8m36s">[8:36]</a>&nbsp;<a href="http://blogs.msdn.com/b/webdev/archive/2013/01/23/introducing-svcperf-an-end-to-end-trace-analysis-tool-for-wcf.aspx">Introducing SvcPerf - An End-to-End trace Analysis tool for WCF</a> (Sajay Antony), <a href="http://svcperf.codeplex.com/">http://svcperf.codeplex.com/</a> </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=9m36s">[9:36]</a>&nbsp;<a href="http://research.microsoft.com/apps/pubs/default.aspx?id=180138">CODEMINE: Building a Software Analytics Platform for Collecting and Analyzing Engineering Process Data at Microsoft</a> (Jacek Czerwonka, Nachi Nagappan, and Wolfram Schulte) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=10m40s">[10:40]</a>&nbsp;<a href="http://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-13-Visual-Studio-3D-Starter-Kit-Meet-Roberto-Sonnino" target="_blank">GoingNative 13: Visual Studio 3D Starter Kit, Meet Roberto Sonnino</a> </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Clint's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=11m43s">[11:43]</a>&nbsp;<a href="http://conversations.nokia.com/2013/01/18/everything-you-need-to-know-about-the-lumia-820-and-3d-printing/">Everything you need to know about the Lumia 820 and 3D printing</a> (Joel Willans) </li><li>Dan's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-January-25-2013#time=13m">[13:00]</a> <a href="http://channel9.msdn.com/Forums/Coffeehouse/Visual-Studio-Achievements-theyre-not-Xbox-live-right?page=1" target="_blank">Visual Studio ​Achievement​s; they're not Xbox live right? (Cheevos!)</a> </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:97e9b2fb00424aac953ba150016dd600">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-January-25-2013</comments>
      <itunes:summary>This week on Channel 9, Dan and Clint discuss the week&#39;s top developer news, including; [0:34]&amp;nbsp;Announcing Release of Windows Azure Media Services (Scott Guthrie) [1:42]&amp;nbsp;Broadcast push notifications to millions of mobile devices using Windows Azure Notification Hubs (Scott Guthrie) [2:33]&amp;nbsp;Now Available: Windows Phone SDK Update for 7.8 (Cliff Simpkins ) [3:25]&amp;nbsp;Fall Fury: Part 1 - Introduction (Den Delimarsky, Brian Peek, Clint Rutkas, Dan Fernandez, Rick Barraza ) [5:16]&amp;nbsp;Tile design guidelines for Windows Phone 8 (Shubhan Chemburkar) [6:08]&amp;nbsp;Building the Bing apps for Windows 8 (Jigar Thakkar) [7:18]&amp;nbsp;Building HTML5 Games for the Atari Arcade [8:36]&amp;nbsp;Introducing SvcPerf - An End-to-End trace Analysis tool for WCF (Sajay Antony), http://svcperf.codeplex.com/ [9:36]&amp;nbsp;CODEMINE: Building a Software Analytics Platform for Collecting and Analyzing Engineering Process Data at Microsoft (Jacek Czerwonka, Nachi Nagappan, and Wolfram Schulte) [10:40]&amp;nbsp;GoingNative 13: Visual Studio 3D Starter Kit, Meet Roberto Sonnino Picks of the Week! Clint&#39;s Pick of the Week:[11:43]&amp;nbsp;Everything you need to know about the Lumia 820 and 3D printing (Joel Willans) Dan&#39;s Pick of the Week:[13:00] Visual Studio ​Achievement​s; they&#39;re not Xbox live right? (Cheevos!) </itunes:summary>
      <itunes:duration>864</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-January-25-2013</link>
      <pubDate>Fri, 25 Jan 2013 18:58:49 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-January-25-2013</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.mp3" expression="full" duration="864" fileSize="13830269" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.mp4" expression="full" duration="864" fileSize="82622182" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.webm" expression="full" duration="864" fileSize="33033362" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.wma" expression="full" duration="864" fileSize="6995339" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.wmv" expression="full" duration="864" fileSize="52754765" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125_high.mp4" expression="full" duration="864" fileSize="180372448" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125_mid.mp4" expression="full" duration="864" fileSize="126644743" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125_Source.wmv" expression="full" duration="864" fileSize="170550063" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.ism/manifest" expression="full" duration="864" fileSize="6036" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/30ad/6aa4f0fa-3790-46ba-af54-4a27273930ad/TWC920130125.wmv" length="52754765" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Dan Fernandez, Greg Duncan</dc:creator>
      <itunes:author>Clint Rutkas, Dan Fernandez, Greg Duncan</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-January-25-2013/RSS</wfw:commentRss>
      <category>3D</category>
      <category>DirectX</category>
      <category>HTML5</category>
      <category>Microsoft Research</category>
      <category>Push Notifcation</category>
      <category>WCF</category>
      <category>Windows Azure</category>
      <category>Windows  Phone</category>
      <category>Game Development</category>
      <category>Windows 8</category>
      <category>Windows Phone 8</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 12 - Project Conclusion</title>
      <description><![CDATA[<p>In this video, Den Delimarsky summarizes his experiences building FallFury, highlighting the lessons he learned as a software developer on the Coding4Fun team at Microsoft.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:036f886aee27434695d7a13f01829948">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion</comments>
      <itunes:summary>In this video, Den Delimarsky summarizes his experiences building FallFury, highlighting the lessons he learned as a software developer on the Coding4Fun team at Microsoft. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1133</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion</link>
      <pubDate>Wed, 23 Jan 2013 23:59:14 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.mp3" expression="full" duration="1133" fileSize="18137909" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.mp4" expression="full" duration="1133" fileSize="76441843" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.webm" expression="full" duration="1133" fileSize="35449275" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.wma" expression="full" duration="1133" fileSize="9179247" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.wmv" expression="full" duration="1133" fileSize="38880107" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_high.mp4" expression="full" duration="1133" fileSize="242090737" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_mid.mp4" expression="full" duration="1133" fileSize="148041231" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_Source.wmv" expression="full" duration="1133" fileSize="103772286" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.ism/manifest" expression="full" duration="1133" fileSize="8462" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12.wmv" length="38880107" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 11 - Hardware Testing</title>
      <description><![CDATA[<p>Because of the large Windows 8 user base, FallFury was tested on different hardware with different input layouts. This video covers the basic setup necessary for remote debugging and performance tuning when connected to a test device, such as the Microsoft Surface.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ee8b551e56084ee0bb6ca13f018281f6">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing</comments>
      <itunes:summary>Because of the large Windows 8 user base, FallFury was tested on different hardware with different input layouts. This video covers the basic setup necessary for remote debugging and performance tuning when connected to a test device, such as the Microsoft Surface. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>707</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing</link>
      <pubDate>Wed, 23 Jan 2013 23:59:10 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.mp3" expression="full" duration="707" fileSize="11315411" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.mp4" expression="full" duration="707" fileSize="54068940" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.webm" expression="full" duration="707" fileSize="24968296" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.wma" expression="full" duration="707" fileSize="5730655" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.wmv" expression="full" duration="707" fileSize="25814015" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_high.mp4" expression="full" duration="707" fileSize="160833339" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_mid.mp4" expression="full" duration="707" fileSize="97822943" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_Source.wmv" expression="full" duration="707" fileSize="83625730" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.ism/manifest" expression="full" duration="707" fileSize="8462" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11.wmv" length="25814015" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 10 - Charms</title>
      <description><![CDATA[<p>Windows 8 offers a unified way to interact with other applications, as well as with the app's own settings, through charms. This video introduces you to the concept of Windows 8 charms and covers the implementation of a Settings and Share charm integration mechanism in FallFury.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3dc6c00618ff4b8f8a29a13f01827298">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-10-Charms</comments>
      <itunes:summary>Windows 8 offers a unified way to interact with other applications, as well as with the app&#39;s own settings, through charms. This video introduces you to the concept of Windows 8 charms and covers the implementation of a Settings and Share charm integration mechanism in FallFury. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>984</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-10-Charms</link>
      <pubDate>Wed, 23 Jan 2013 23:58:52 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-10-Charms</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.mp3" expression="full" duration="984" fileSize="15757889" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.mp4" expression="full" duration="984" fileSize="89965283" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.webm" expression="full" duration="984" fileSize="36936001" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.wma" expression="full" duration="984" fileSize="7977647" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.wmv" expression="full" duration="984" fileSize="38335397" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_high.mp4" expression="full" duration="984" fileSize="206460652" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_mid.mp4" expression="full" duration="984" fileSize="142233883" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_Source.wmv" expression="full" duration="984" fileSize="140555392" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.ism/manifest" expression="full" duration="984" fileSize="8462" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10.wmv" length="38335397" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-10-Charms/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 9 - Particle System</title>
      <description><![CDATA[<p>This video covers the creation of a particle system that is able to generate a texture-based particle layout in different parts of the visible screen, with different geometric and displacement conditions.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3ae96e77a6d04c32911da13f018260ce">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System</comments>
      <itunes:summary>This video covers the creation of a particle system that is able to generate a texture-based particle layout in different parts of the visible screen, with different geometric and displacement conditions. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1030</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System</link>
      <pubDate>Wed, 23 Jan 2013 23:58:49 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.mp3" expression="full" duration="1030" fileSize="16485982" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.mp4" expression="full" duration="1030" fileSize="74535124" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.webm" expression="full" duration="1030" fileSize="35469767" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.wma" expression="full" duration="1030" fileSize="8347139" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.wmv" expression="full" duration="1030" fileSize="36459209" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_high.mp4" expression="full" duration="1030" fileSize="239960640" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_mid.mp4" expression="full" duration="1030" fileSize="137966226" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_Source.wmv" expression="full" duration="1030" fileSize="121307668" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.ism/manifest" expression="full" duration="1030" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9.wmv" length="36459209" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 8 - Element Interaction</title>
      <description><![CDATA[<p>In FallFury, elements such as obstacle, buttons, and characters collide and react to each other's actions depending on specific game conditions. This video describes the basics of collision detection and object interaction in the game.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7b77f68e4c52401cab16a13f01814ff1">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction</comments>
      <itunes:summary>In FallFury, elements such as obstacle, buttons, and characters collide and react to each other&#39;s actions depending on specific game conditions. This video describes the basics of collision detection and object interaction in the game. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1114</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction</link>
      <pubDate>Wed, 23 Jan 2013 23:58:45 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8.mp3" expression="full" duration="1114" fileSize="17825963" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8.mp4" expression="full" duration="1114" fileSize="82202538" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8.webm" expression="full" duration="1114" fileSize="38496918" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8.wma" expression="full" duration="1114" fileSize="9020035" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8.wmv" expression="full" duration="1114" fileSize="39854075" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_high.mp4" expression="full" duration="1114" fileSize="234154759" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_mid.mp4" expression="full" duration="1114" fileSize="150556867" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_Source.wmv" expression="full" duration="1114" fileSize="135964166" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8.wmv" length="39854075" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 7 - Animations</title>
      <description><![CDATA[<p>This video covers the creation of basic animations in FallFury with the help of the core game update loop and additional timers capable of switching object states.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ed4e9837e67b44dfa086a13f018139c5">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-7-Animations</comments>
      <itunes:summary>This video covers the creation of basic animations in FallFury with the help of the core game update loop and additional timers capable of switching object states. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1964</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-7-Animations</link>
      <pubDate>Wed, 23 Jan 2013 23:58:40 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-7-Animations</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.mp3" expression="full" duration="1964" fileSize="31438884" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.mp4" expression="full" duration="1964" fileSize="173074091" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.webm" expression="full" duration="1964" fileSize="68874981" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.wma" expression="full" duration="1964" fileSize="15902199" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.wmv" expression="full" duration="1964" fileSize="75918365" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_high.mp4" expression="full" duration="1964" fileSize="406073930" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_mid.mp4" expression="full" duration="1964" fileSize="280558876" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_Source.wmv" expression="full" duration="1964" fileSize="273569272" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.ism/manifest" expression="full" duration="1964" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7.wmv" length="75918365" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-7-Animations/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 6 - Rendering Level Elements</title>
      <description><![CDATA[<p>Levels rely on multiple elements aggregated directly from the associated XML file. In this video, Den explains how such elements are processed and rendered internally.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:fe1e30f7d2394306b861a13f018115d7">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements</comments>
      <itunes:summary>Levels rely on multiple elements aggregated directly from the associated XML file. In this video, Den explains how such elements are processed and rendered internally. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>873</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements</link>
      <pubDate>Wed, 23 Jan 2013 23:58:37 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.mp3" expression="full" duration="873" fileSize="13984260" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.mp4" expression="full" duration="873" fileSize="66154814" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.webm" expression="full" duration="873" fileSize="31056101" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.wma" expression="full" duration="873" fileSize="7079451" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.wmv" expression="full" duration="873" fileSize="31761131" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_high.mp4" expression="full" duration="873" fileSize="187261821" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_mid.mp4" expression="full" duration="873" fileSize="121925346" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_Source.wmv" expression="full" duration="873" fileSize="127674726" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.ism/manifest" expression="full" duration="873" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6.wmv" length="31761131" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 5 - Creating Levels</title>
      <description><![CDATA[<p>FallFury supports dynamic level creation and rendering and is not tied to the level content that is shipped with the default build. This video covers the level XML building process and in-game testing.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:2d230ac00fcf4370b13aa13f0180f46f">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels</comments>
      <itunes:summary>FallFury supports dynamic level creation and rendering and is not tied to the level content that is shipped with the default build. This video covers the level XML building process and in-game testing. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1693</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels</link>
      <pubDate>Wed, 23 Jan 2013 23:58:33 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.mp3" expression="full" duration="1693" fileSize="27103399" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.mp4" expression="full" duration="1693" fileSize="157603835" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.webm" expression="full" duration="1693" fileSize="61751368" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.wma" expression="full" duration="1693" fileSize="13712283" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.wmv" expression="full" duration="1693" fileSize="64185851" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_high.mp4" expression="full" duration="1693" fileSize="351067777" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_mid.mp4" expression="full" duration="1693" fileSize="253154672" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_Source.wmv" expression="full" duration="1693" fileSize="226911646" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.ism/manifest" expression="full" duration="1693" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5.wmv" length="64185851" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 4 - XAML Interop</title>
      <description><![CDATA[<p>In this video, Den Delimarsky shows how the DirectX and XAML hybrid applications available in Visual Studio 2012 were implemented in FallFury and discusses what should be considered when working on an app that leverages these capabilities.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:484c9e8941544956a986a13f017d7190">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop</comments>
      <itunes:summary>In this video, Den Delimarsky shows how the DirectX and XAML hybrid applications available in Visual Studio 2012 were implemented in FallFury and discusses what should be considered when working on an app that leverages these capabilities. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1034</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop</link>
      <pubDate>Wed, 23 Jan 2013 23:58:29 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.mp3" expression="full" duration="1034" fileSize="16551598" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.mp4" expression="full" duration="1034" fileSize="92209073" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.webm" expression="full" duration="1034" fileSize="37150672" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.wma" expression="full" duration="1034" fileSize="8374175" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.wmv" expression="full" duration="1034" fileSize="38192273" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_high.mp4" expression="full" duration="1034" fileSize="221254547" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_mid.mp4" expression="full" duration="1034" fileSize="159353109" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_Source.wmv" expression="full" duration="1034" fileSize="282571692" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.ism/manifest" expression="full" duration="1034" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4.wmv" length="38192273" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 3 - Basic Rendering and Movement </title>
      <description><![CDATA[<p>This video covers the basics of character movement through a variety of controls, such as the accelerometer, keyboard, and mouse. The fundamentals of object rendering through a DirectX implementation of SpriteBatch are also covered.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:459cd33f3ba0435bb7aca13f017f02a5">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement</comments>
      <itunes:summary>This video covers the basics of character movement through a variety of controls, such as the accelerometer, keyboard, and mouse. The fundamentals of object rendering through a DirectX implementation of SpriteBatch are also covered. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1510</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement</link>
      <pubDate>Wed, 23 Jan 2013 23:58:26 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.mp3" expression="full" duration="1510" fileSize="24165578" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.mp4" expression="full" duration="1510" fileSize="122322646" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.webm" expression="full" duration="1510" fileSize="53095080" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.wma" expression="full" duration="1510" fileSize="12225303" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.wmv" expression="full" duration="1510" fileSize="55214777" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_high.mp4" expression="full" duration="1510" fileSize="320068921" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_mid.mp4" expression="full" duration="1510" fileSize="222847275" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_Source.wmv" expression="full" duration="1510" fileSize="203982548" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.ism/manifest" expression="full" duration="1510" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3.wmv" length="55214777" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 2 - Shaders</title>
      <description><![CDATA[<p>Shaders are the core part of many modern video games. This video covers the fundamentals of the High Level Shader Language as well as its application in creating vertex and pixel shaders for a Windows Store DirectX &amp; XAML hybrid project.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:9ebb176e64b64148a84fa13f017d8cb4">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-2-Shaders</comments>
      <itunes:summary>Shaders are the core part of many modern video games. This video covers the fundamentals of the High Level Shader Language as well as its application in creating vertex and pixel shaders for a Windows Store DirectX &amp;amp; XAML hybrid project. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1437</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-2-Shaders</link>
      <pubDate>Wed, 23 Jan 2013 23:58:23 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-2-Shaders</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.mp3" expression="full" duration="1437" fileSize="22997360" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.mp4" expression="full" duration="1437" fileSize="101812905" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.webm" expression="full" duration="1437" fileSize="47741682" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.wma" expression="full" duration="1437" fileSize="11633515" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.wmv" expression="full" duration="1437" fileSize="50821979" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_high.mp4" expression="full" duration="1437" fileSize="319500869" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_mid.mp4" expression="full" duration="1437" fileSize="187767219" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_Source.wmv" expression="full" duration="1437" fileSize="154526110" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.ism/manifest" expression="full" duration="1437" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2.wmv" length="50821979" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-2-Shaders/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Part 1 - Introduction</title>
      <description><![CDATA[<p>In this video, Den Delimarsky introduces the FallFury project, describing the basic core and organization as well as the technologies used to create the game.</p><p>Check out the article for this video at <a href="http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction</a></p><p>For the source code, head over to <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:8ccb87d7121f45e093b5a14a01336fc9">]]></description>
      <comments>http://channel9.msdn.com/Series/FallFury/Part-1-Introduction</comments>
      <itunes:summary>In this video, Den Delimarsky introduces the FallFury project, describing the basic core and organization as well as the technologies used to create the game. Check out the article for this video at http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction For the source code, head over to http://fallfury.codeplex.com </itunes:summary>
      <itunes:duration>1128</itunes:duration>
      <link>http://channel9.msdn.com/Series/FallFury/Part-1-Introduction</link>
      <pubDate>Wed, 23 Jan 2013 23:58:20 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/FallFury/Part-1-Introduction</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_512.jpg" height="289" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.mp3" expression="full" duration="1128" fileSize="18051654" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.mp4" expression="full" duration="1128" fileSize="110659455" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.webm" expression="full" duration="1128" fileSize="37583295" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.wma" expression="full" duration="1128" fileSize="9131183" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.wmv" expression="full" duration="1128" fileSize="45597095" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_high.mp4" expression="full" duration="1128" fileSize="245887608" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_mid.mp4" expression="full" duration="1128" fileSize="172098106" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_Source.wmv" expression="full" duration="1128" fileSize="227481511" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.ism/manifest" expression="full" duration="1128" fileSize="8446" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1.wmv" length="45597095" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Clint Rutkas, Den Delimarsky</dc:creator>
      <itunes:author>Clint Rutkas, Den Delimarsky</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/FallFury/Part-1-Introduction/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 12 - Conclusions</title>
      <description><![CDATA[<h3>Project Conclusions</h3><p>Developing FallFury was a fun and educational activity. Besides the fact that I got to work with an amazing team of people who were willing to assist me with the testing and development, I learned some important points about the development process as a whole and have outlined them in this article.&nbsp; Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion">http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Go Outside Your Comfort Zone</h4><p>This past summer, I decided to tackle a new challenge—game development. Never before had I built a game from the ground up. Moreover, as I could already find my way around C# code, I decided that I wanted to make C&#43;&#43; the language of choice, and so worked with DirectX instead of XNA. Additionally, the project needed to be constructed with Windows 8 as the target platform and I’d have to rely on the WinRT stack.</p><p>The concepts were new to me, but I figured that learning about a new platform and a new language would be more interesting than sticking to my comfort zone. Through FallFury I extended my knowledge about pointers, trigonometry, how DirectX handles a lot of the graphics legwork, and how to write HLSL shaders.</p><p>It was a challenging but very rewarding experience.</p><h4>Communicate</h4><p>The most important part of any project is communication. There are always people who know more than you in one field or another, so don't hesitate to reach out to other developers and ask questions. Your code is not perfect, so talk about best practices used in production and how you can improve on what you already have—communication should not be limited to your team, floor, or even building.</p><p>One bonus of my experience at Microsoft was discovering that a lot of developers, when not in a meeting or in the middle of an important assignment, are more than happy to help a fellow employee with a piece of advice or some code review.</p><h4>Plan the Small Details</h4><p>Before you even touch the keyboard to write your first line of code, outline the components of your application and have a general idea of how you’ll implement those components as well as how they’ll interact with each other. It is tempting to start coding and then add or modify features, but doing so will create more problems than it will solve.</p><h4>Build Small Prototypes</h4><p>FallFury is a complex project composed out of blocks such as:</p><ul><li>XML level/metadata reader and writer </li><li>The Share and Settings charm components </li><li>SpriteBatch sub-system </li><li>Level renderer </li><li>Screen sub-system </li><li>Menu interaction sub-system </li></ul><p>Each block is responsible for its own set of tasks and each can be individually tested with either mocked data or a loose connection to the existing codebase. The necessity for small prototypes comes from individual requirements tied to the platform and possible integration scenarios. For example, when I began development, I created a non-hybrid DirectX project, which meant that if I needed to introduce XAML integration, I had to rewrite small parts of my swap chain preparation stack as well as work with a lot of XAML content in the code-behind. The Settings charm integration heavily relied on XAML, and I would have had to write the popup and control-related code in C#.</p><p>Obviously, that was not an option, so I created a hybrid project instead and ported most of my code into the new solution. Lesson learned here: prototype—and prototype early—in order to make sure that what you plan to implement will be implemented in an efficient manner.</p><h4>Test Often, Test with Other People</h4><p>When working on an application, it is important to understand the needs and expectations of your target audience, and a big part of this is making sure that the application provides a way for the user to easily learn about an action without a helper booklet. The menu system is a good example of this in FallFury. As I was designing the buttons on my screens, I tried to implement the approach used in games such as Dance Central—the user simply slides the button-panel and it takes him to the screen that was linked to that specific button. However, as I was testing the application with the local development crowd, I noticed a pattern—people were attempting to simply tap the button instead of sliding it. To avoid this confusion, I added a pulsating arrow on the right side of the button in order to highlight the fact that the button should be displaced in order to be activated.</p><p>The XML level loading system is another example of how secondary testing improved FallFury. Initial element positioning relied on a given level length, as well as on a ration-based placement. For example, if I wanted to put a button in the middle of the screen, I could position it with a value, such as .5. The level loader would then translate this value relative to the screen size. Rick Barraza was creating some test levels when he notified me about a big flaw—as the level extended, some elements were mis-positioned by a large margin compared to the original intended location. This was because when a level length was reset, the ratio was applied on a larger/smaller value, and some elements would therefore overlap. Ultimately, I rewrote the level structure to rely on pixel values, and designed the level-length to calculate automatically based on the included elements and their size.</p><h4>Test on Different Hardware</h4><p>FallFury started with portable hardware in mind. Its original design targeted Windows 8 tablet devices, though it was later decided that the project should support desktop machines as well. That automatically added thousands of possible hardware combinations on which the game might potentially run. Here are just some of the test machines we got to use:</p><ul><li>Samsung Series 7 Slate </li><li>ARM Developer Tablet (Microsoft Surface) </li><li><a href="http://www.asus.com/Eee/Eee_Pad/Eee_Slate_EP121/">ASUS EP121 Slate</a> </li></ul><p>Each of these machines came with its own specific conditions that had to be accommodated. While Samsung Series 7 Slate featured an accelerometer, at the time of development the ASUS EP121 tablet did not have Windows 8 drivers for its sensor. When I sideloaded the game, I noticed that I could no longer control the character the way I wanted to. Also, though FallFury has keyboard controls, I had to develop controls for machines without keyboards. This is why I came up with the concept of touch-based, on-screen controls.</p><p>Moving on to the ARM device, first and foremost I noticed that my shader configurations were not compatible with the platform capabilities. All my testing was done on a machine that supported DirectX Feature Level 10, which was not the case for a low-power ARM machine that supports DirectX Feature Level 9.1. I had to work with some MSDN samples to find a way to properly modify the required shaders so they would work on Windows RT. ARM devices are built with battery life in mind. Therefore, their capabilities are reduced compared to those of a full-sized Windows tablet. This had an impact on the general game performance—some parts of the game, such as particle rendering, were working fine on a desktop machine, but were quite laggy on the ARM tablet. Knowing the possible source of the problem, I had to optimize the particle storage and rendering stack to ensure they didn’t affect the user experience on Windows RT hardware.</p><h4>There Is Never Enough Time - Learn To Cut</h4><p>When I started planning FallFury, I worked up a huge list of features. As the deadline approached, however, I noticed that I somewhat underestimated the allocated project time—a lot of time was spent on testing and eliminating bugs in existing features. That was the point at which I had to cut my feature set.</p><p>When designing the feature list for your app, make sure that you have a clear vision of which features get the priority and which can be cut if necessary. For example, FallFury was originally planned to be a multiplayer game. Although it was tempting to start working on it as such from the very beginning, I knew that it wasn’t a core feature and that it wouldn’t necessarily affect the general play experience on release day. Ultimately, multiplayer capability was dropped from initial development along with a number of other not-immediately-integral features.</p><h4>Expect the Unexpected</h4><p>When allocating time for the project, anticipate situations that might derail the process and cause a delay in the planned delivery date. It is easy to estimate that creating an accelerometer-based motion system will take you a day or two, but you also need to allow for the potential possibility of your code not working as expected, hardware accidents, natural disasters, etc. Doing so will help you focus on the right features at the right time while diminishing the risk of missing the deadline.</p><h4>Platform Samples Are the Best Documentation - Learn to Read Others’ Code</h4><p>While building the core of FallFury, I leveraged multiple features that hadn’t yet become mainstream among Windows developers. Therefore, the documentation was scarce and in some instances the only help I could get was internal. Luckily, Microsoft bundled hundreds of samples that demonstrate what the new platform can do. A lot of the development approaches gained during my internship were learned from looking at the official, publicly released sample code. The lesson here: if it's not on MSDN or blogs, check the official developer samples. For example, I used the <a href="http://code.msdn.microsoft.com/windowsapps/Direct3D-sprite-sample-97ae6262">DirectX sprite drawing sample</a> to see how to build a proper sprite rendering mechanism with behavior similar to the one available in XNA.</p><h4>Atomic Commits</h4><p>When I started, source control wasn’t new to me, but there were proper usage practices that I didn’t apply before the internship. One of them is atomic commits, which I learned from <a href="https://twitter.com/ClintRutkas">Clint Rutkas</a>.</p><p>With every new addition to the application, chances are something might go wrong. It could be a faulty third-party assembly, a misplaced class, or a broken reference that brings down the entire solution. If the commits include longer time intervals, for example, you will ultimately have to roll back to a build without a lot of the new functionality. Using atomic commits, however, you’ll be able to avoid unnecessary, redundant work in the case that something goes wrong during development.</p><h4>A Non-standard Approach Is Not Necessarily a Bad Approach</h4><p>For loading high scores, I needed the UI layout to display the registered items. To do so, I had could either use data binding or write a simple routine that would generate XAML items on the fly in the code-behind. Data binding is a pretty common practice among XAML developers, so my initial thought was to use that, but I would have had to create a C&#43;&#43; binding harness in addition to the existing data retrieval code. The second approach was much cleaner because it didn’t require me to rewrite or add much code. The lesson here: pick the best approach for the job and don’t blindly follow programming trends.</p><h4>Focus on the User Experience</h4><p>At the end of the day, the user doesn’t care whether you wrote the application in native DirectX or XNA, whether you applied the MVVM pattern, or whether you have easily readable code. The user cares about having a great time while playing the game, regardless of its backbone. It’s your goal as a developer to deliver that user experience and ensure that the user feels comfortable with the product. This means that the development cycle goes beyond simply writing code. In FallFury, levels are dynamic, which means the source code doesn’t necessarily need to be modified in order to create a different playable experience. But that experience matters in any case, and level design is a huge part of FallFury’s final product. Users need to be immersed in the game world, so levels must be planned in such as way that the user returns to the game and doesn’t abandon it after a couple of lost rounds.</p><h4>Conclusion</h4><p>FallFury was my first major project that I wrote almost entirely in C&#43;&#43;, targeting the newly released Windows 8 operating system. Although the development process was challenging, it was proven to be a great educational experience that taught me about the approaches and practices that are used internally at Microsoft.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:cf5ded925e574af79c1fa14d01624d0b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</comments>
      <itunes:summary>Project ConclusionsDeveloping FallFury was a fun and educational activity. Besides the fact that I got to work with an amazing team of people who were willing to assist me with the testing and development, I learned some important points about the development process as a whole and have outlined them in this article.&amp;nbsp; Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Go Outside Your Comfort ZoneThis past summer, I decided to tackle a new challenge—game development. Never before had I built a game from the ground up. Moreover, as I could already find my way around C# code, I decided that I wanted to make C&amp;#43;&amp;#43; the language of choice, and so worked with DirectX instead of XNA. Additionally, the project needed to be constructed with Windows 8 as the target platform and I’d have to rely on the WinRT stack. The concepts were new to me, but I figured that learning about a new platform and a new language would be more interesting than sticking to my comfort zone. Through FallFury I extended my knowledge about pointers, trigonometry, how DirectX handles a lot of the graphics legwork, and how to write HLSL shaders. It was a challenging but very rewarding experience. CommunicateThe most important part of any project is communication. There are always people who know more than you in one field or another, so don&#39;t hesitate to reach out to other developers and ask questions. Your code is not perfect, so talk about best practices used in production and how you can improve on what you already have—communication should not be limited to your team, floor, or even building. One bonus of my experience at Microsoft was discovering that a lot of developers, when not in a meeting or in the middle of an important assignment, are more than happy to help a fellow employee with a piece of advice or some code </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</link>
      <pubDate>Wed, 23 Jan 2013 23:57:48 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 11 - Hardware Testing &amp; Debugging</title>
      <description><![CDATA[<h3>Hardware Testing &amp; Debugging</h3><p>As previously mentioned, FallFury runs on multiple types of hardware as long as that hardware supports Windows 8. This article describes the project’s general testing and debugging process, including setting the debug configurations and remote debugging.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing">http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Remote Debug</h4><p>When working on an application that targets different machines, it’s probably out of the question to install Visual Studio on each instance and move the solution from one source to another in order to run it and diagnose potential problems. Here is where <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30674">Remote Tools for Visual Studio 2012</a> come into play. Microsoft offers you three separate builds—tools for x86 systems, x64 systems, and ARM systems—also known as Surface RT.</p><p>Once the tools are running on the machine you want to debug, you have two choices. You can either install the remote debugger as a service, allowing it to constantly run in the background, or you can use the debugger on a per-launch basis. From a developer perspective, the choice doesn’t affect how your application is executed on the remote machine. From a security perspective, however, you need to be sure that you properly configure it so that no unwanted apps are remotely deployed.</p><p>Now you can start the Remote Debugger Configuration Wizard:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-8.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-9.jpg" alt="clip_image002" width="372" height="312" border="0"></a> <a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-6.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-7.jpg" alt="clip_image004" width="333" height="312" border="0"></a></p><p>This works on both the initial start-up and also any subsequent launch as a way to easily and quickly set the necessary remote debugger settings. Specifically, it is useful to configure the machine’s network settings, allowing cross-domain communications for debugging purposes.</p><p>Once the wizard is completed, launch the Remote Debugger Monitor. Notice that it lists your machine name and the port on which it’s running. This is necessary for configuring the project to send the package to a remote machine instead of the local one:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D-4.jpg"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb-5.jpg" alt="clip_image006" width="501" height="167" border="0"></a></p><p>The configuration depends on the network settings on both the local machine and the subnet as a whole. For example, in some cases, and especially on domain-joined machines, remote debugging is better done with the authentication disabled. Windows Authentication is used by default.</p><p>Since FallFury is a C&#43;&#43; project, the configuration for a remote session is different than, say, that of a C# Windows Store application. To configure the session, right click on the project in <strong>Solution Explorer</strong> and open the <strong>Debugging</strong> section. Make sure that Remote Machine is selected as the type of debugger to launch:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B3%5D-5.jpg"><img title="clip_image008" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008_thumb-6.jpg" alt="clip_image008" width="640" height="142" border="0"></a></p><p>Next, specify the machine name as well as whether the current session will require authentication:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B3%5D-3.jpg"><img title="clip_image010" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010_thumb-4.jpg" alt="clip_image010" width="640" height="196" border="0"></a></p><p>If you cannot specify the machine name, use the direct IPv4 address of that computer, minus the port <a>(unless you’ve explicitly set it to a port other than 4016, which is the assumed default).</a> Once the source machine connects to the remote one, you will see Visual Studio performing the deployment:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B3%5D-5.jpg"><img title="clip_image012" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012_thumb-5.jpg" alt="clip_image012" width="640" height="108" border="0"></a></p><h4>Configurations</h4><p>As a matter of convenience, it is always good to have different debug configurations that will define how your projects are built, especially if the project targets multiple platforms (such as ARM and x86). Visual Studio provides a <a href="http://msdn.microsoft.com/en-us/library/kwybya3w%28v=vs.80%29.aspx">Configuration Manager</a> that can be accessed from the debug target dropdown:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013%5B3%5D.png"><img title="clip_image013" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013_thumb.png" alt="clip_image013" width="300" height="199" border="0"></a></p><p>FallFury includes two separate projects—the game core, and the C#-based XML reader. Both need to be explicitly associated with separate target platforms in order to be correctly debugged. For that, profiles were created for both local and remote sessions:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B3%5D.png"><img title="clip_image014" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014_thumb.png" alt="clip_image014" width="640" height="186" border="0"></a></p><p>As with standard Debug/Release configurations, the ones shown above determine whether the project will carry debug symbols and support debugging commands. It is important to mention that as you switch configurations, you must be careful how you configure the graphic shaders. For each shader in the container folder, explicitly set the HLSL shader type and model. Otherwise the application deployment will fail:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016%5B3%5D-3.jpg"><img title="clip_image016" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016_thumb-4.jpg" alt="clip_image016" width="640" height="144" border="0"></a></p><h4>Remote Profiling</h4><p>Last but not least, when working with different hardware configurations it might be useful to perform application profiling or performance review. Fortunately, Visual Studio also provides this capability through the <a href="http://msdn.microsoft.com/en-us/library/hh977161.aspx"><strong>vsperf</strong></a> tool, which is already integrated in the IDE if you are using Visual Studio 2012 Professional or above.</p><p>To initiate a profiling session on a remote device, the Remote Debugger Monitor must be active. Make sure that the <strong>Remote Machine</strong> debug target is selected, and go to <strong>Analyze &gt; Start Performance Analysis</strong>:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image017%5B3%5D.png"><img title="clip_image017" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image017_thumb.png" alt="clip_image017" width="404" height="83" border="0"></a></p><p>On the remote machine, allow the <strong>vsperf</strong> process to run with administrative privileges. Once the profiling session completes and the data is analyzed, you can review the same performance indicators as you would when having a standard application run the profiler on the local machine:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image019%5B3%5D.jpg"><img title="clip_image019" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image019_thumb.jpg" alt="clip_image019" width="640" height="312" border="0"></a></p><h4>Conclusion</h4><p>Testing hardware outside the boundaries of a desktop machine is often a necessity, especially if the application relies on specific sensors, such as NFC, touch, or accelerometer. The remote debugging process is fairly streamlined and intuitive, with developing a proper network configuration allowing communication between machines requiring the most significant amount of effort. If you have problems getting the debugger to work, <a href="http://msdn.microsoft.com/en-us/library/bt727f1t.aspx">consult this article on MSDN</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/Clint/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:4e4e6ed2c2cc4a98946aa14d0161797b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</comments>
      <itunes:summary>Hardware Testing &amp;amp; DebuggingAs previously mentioned, FallFury runs on multiple types of hardware as long as that hardware supports Windows 8. This article describes the project’s general testing and debugging process, including setting the debug configurations and remote debugging. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Remote DebugWhen working on an application that targets different machines, it’s probably out of the question to install Visual Studio on each instance and move the solution from one source to another in order to run it and diagnose potential problems. Here is where Remote Tools for Visual Studio 2012 come into play. Microsoft offers you three separate builds—tools for x86 systems, x64 systems, and ARM systems—also known as Surface RT. Once the tools are running on the machine you want to debug, you have two choices. You can either install the remote debugger as a service, allowing it to constantly run in the background, or you can use the debugger on a per-launch basis. From a developer perspective, the choice doesn’t affect how your application is executed on the remote machine. From a security perspective, however, you need to be sure that you properly configure it so that no unwanted apps are remotely deployed. Now you can start the Remote Debugger Configuration Wizard:   This works on both the initial start-up and also any subsequent launch as a way to easily and quickly set the necessary remote debugger settings. Specifically, it is useful to configure the machine’s network settings, allowing cross-domain communications for debugging purposes. Once the wizard is completed, launch the Remote Debugger Monitor. Notice that it lists your machine name and the port on which it’s running. This is necessary for configuring the project to send the package to a remote ma</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</link>
      <pubDate>Wed, 23 Jan 2013 23:57:44 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>    
</channel>
</rss>