packet writing software all Results


Sponsored Links:



I was my understanding that Vista includes packet writing software.
Does it?

If so, are products such as INCD or DRag 2 Disc necessary in Vista?




O.K., so I buy and install a CD-DVD creator, then, when I
run the Backup Utility or the Files and Setting Transfer
Wizard, (BTW, which is the best one to use?), the
computer will allow me to use a CR-RW. I won't get a "!"
box from the Backup utility that says, "The backup file
name could not be used. "F:Backup.bkf" Please ensure it
is a valid path, and that you have sufficient access.",
or a box from the Files and Settings Transfer Wizard that
says, "The disk is corrupted, or there is no disk in the
drive. Please insert a valid disk." Right?
I tell you, I'd really like to find the people who writes
these programs and beat their heads into the ground for
making them so impossible to use. Ha Ha. Please assure
me that this will work before I go out and spend money
that I shouldn't have to if these programs worked the way
they ought to. And yes, my F (CD) drive should be a
valid path, yes, I do have administrator access which
should be "sufficient access", no, the disk is not
corrupted, and, yes, there is a valid disk in the
drive!!!!!!

BTW, I can't thank you enough for all your help. Thank
you!

----------------------------------------
Subject: Confussed Using Backup Utility
From: "Richard Urban"
Sent: 8/22/2004
11:41:06 PM

I haven't used the Microsoft backup utility for about 2
years now. When I was
using it I was able to backup to CD's. The trick is, you
need 3rd party
software (such as Roxio CD-DVD Creator) that installs
packet writing
software along with the main program. This allows your
computer to write to
the CD's as if they were a hard drive.

Get the software and start burning your backups (-:

--
Regards:

Richard Urban

aka Crusty (-: Old B@stard :-)
----------------------------------------
"Robin" wrote in message
...
I want to thank you for replying to my posts so
quickly and with such accurate information. I was
able to download and install the Backup utility
without any problem.

However, I am still very confused.

It makes no sense to me to simply store a copy to
another location on my hard drive. If my
computer crashes, I'll still lose everything. And I
have no idea how to store it to a tape or another
hard drive. Why is the easiest and most
convenient, obvious, sensible method of using CD's not
allowed!? And why does the Files and Settings
Transfer Wizard have the same limitation? And what is
the difference? Both do essentially the same
thing. As you can see, I'm not very computer
literate.

I just need a simple, easy to understand method of
backing up my files and settings (everything) on CD's.
Or, tell me how to store the info on a tape. BTW, would
that be a standard cassette tape?




First of all, it looks like you can disregard my last posting about an IRQ 11 conflict. It seems that the three of the Iomega techs who told me that the device wasn't being detected correctly under the Unversial Serial Bus device category were all wrong, and my CDRW WAS being detected correctly (as a Iomega USB Storage Adapter (TPP) ) after all.

Here's the situation. I'm using a Dell Inspiron 3800 laptop (PIII/600mhz, 128mb RAM, 250-300mb of available hard disk space & Windows '98SE) with an Iomega external USB CDRW drive. When the Hotburn software is installed, and the "Drag n' Burn" option (which is the "UDF Packet Writing Software") is checked (for installation), my internal CD freezes up for about 5-10 minutes before I can access it. This occurrs on bootup, as well as every time I change the disc. Note that my internal CD is NOT a CDRW, but just a regular CD reader. What, if I may ask, is it about the "Drag n' Burn" (which, by the way, allows for doing multisession CD burns) that is not allowing my own internal CD to access a disk.

The actual symptom is that EVERYTHING is frozen, because while the CD was trying to access the disc I inserted, I couldn't do anything else--until the internal CD finally managed to access the disc again.

Incidentally, the Iomega CDRW never seemed to hang on me, even when I changed the disc. It looks like the CDRW is getting all of the resources it needs (and, perhaps, some that it "doesn't need AND shouldn't have")

Does anyone have any ideas?

Thank you for your time,
Steve Weber




This problem, incidentally, does NOT occur when I have Hotburn installed in the Windows 2000 system at the office.

Here's the situation. I'm using a Dell Inspiron 3800 laptop (PIII/600mhz, 128mb RAM, 250-300mb of available hard disk space & Windows '98SE) with an Iomega external USB CDRW drive. When the Hotburn software for the drive is installed, and the "Drag n' Burn" option (which is the "UDF Packet Writing Software") is checked (for installation), my internal CD freezes up for about 5-10 minutes before I can access it. This occurrs on bootup, as well as every time I change the disc. Note that my internal CD is NOT a CDRW, but just a regular CD reader. What, if I may ask, is it about the "Drag n' Burn" (which, by the way, allows for doing multisession CD burns) that is not allowing my own internal CD to access a disk.

The actual symptom is that EVERYTHING is frozen, because while the CD was trying to access the disc I inserted, I couldn't do anything else--until the internal CD finally managed to access the disc again.

Incidentally, the Iomega CDRW never seemed to hang on me, even when I changed the disc. It looks like the CDRW is getting all of the Windows '98 resources it needs (and, perhaps, some that it "doesn't need AND shouldn't have")

Does anyone have any ideas?

Thank you for your time,
Steve Weber




Can anyone tell me how to uninstall the existing Roxio-sourced CD-writing software supplied as part of Win XP Pro? (It's not mentioned in "Add and remove programs") I then want to install Nero 5.5 with InCD to enable direct drag-and-drop copying to CDRW disks (using packet writing), without all the Roxio fuss and read-only format. Alternatively, does anyone know of any good alternative software enabling this simple drag-and-drop copying to CDRW?

Grateful for any help




An acquaintance of mine told me once (long forgotten) about a little utility that would remove the "Read Only" attribute from files copied to a CD R/RW so that you could either read them or copy (use) them on another PC other than your own. Does anyone know of any freeware applications that would do this?

Here's my particular situation. I have burned all my downloaded programs to a CD RW using Nero on my XP machine and also copied them from the CD RW to a CD R. But when I put either of these disks in the CD ROM of my Win 98SE machine, in Windows Explorer the contents of that disk aren't displayed..... i.e., blank. I know about Nero's "EasyWriteReader.exe" that you can install on another PC that doesn't have Nero installed that would allow that PC to access files on a CD that were written with UDF packet writing software, i.e, Nero in this case, or like the CD R that was copied from the CD RW. But to take advantage of this, you would have to put this utility on a floppy and install it first before being able to use the data on the CD RW. I am hoping that a utility that would remove the "Read Only" attribute from the files on the CD RW and the CD R would work just as well???

Jeff




Introduction

In early January, we were tasked with creating a unique, interactive experience for the SXSW Interactive launch party with Frog Design. We bounced around many ideas, and finally settled on a project that Rick suggested during our first meeting: boxing robots controlled via Kinect.
The theme of the opening party was Retro Gaming, so we figured creating a life size version of a classic tabletop boxing game mashed up with a "Real Steel"-inspired Kinect experience would be a perfect fit. Most importantly, since this was going to be the first big project of the new Coding4Fun team, we wanted to push ourselves to create an experience that needed each of us to bring our unique blend of hardware, software, and interaction magic to the table under an aggressively tight deadline.
Hardware

The BoxingBots had to be fit a few requirements:

They had to be funThey had to survive for 4 hours, the length of the SXSW opening partyEach robot had to punch for 90 seconds at a time, the length of a roundThey had to be life-sizeThey had to be Kinect-drivableThey had to be built, shipped, and reassembled for SXSW
Creating a robot that could be beaten up for 4 hours and still work proved to be an interesting problem. After doing some research on different configurations and styles, it was decided we should leverage a prior project to get a jump start to meet the deadline. We repurposed sections of our Kinect drivable lounge chair, Jellybean! This was an advantage because it contained many known items, such as the motors, motor controllers, and chassis material. Additionally, it was strong and fast, it was modular, and the code to drive it was already written.
Jellybean would only get us part of the way there, however. We also had to do some retrofitting to get it to work for our new project. The footprint of the base needed to shrink from 32x50 inches to 32x35 inches, while still allowing space to contain all of the original batteries, wheels, motors, motor controllers, switches, voltage adapters. We also had to change how the motors were mounted with this new layout, as well as provide for a way to easily "hot swap" the batteries out during the event. Finally, we had to mount an upper body section that looked somewhat human, complete with a head and punching arms.

Experimenting with possible layouts
The upper body had its own challenges, as it had to support a ton of equipment, including:

Punching armsPopping headPneumatic valvesAir manifoldAir Tank(s)LaptopPhidget interface boardPhidget relay boardsPhidget LED boardXbox wireless controller PC transmitter / receiverChest plateLEDsSensors to detect a punch

Brian and Rick put together one of the upper frames
Punching and Air Tanks

We had to solve the problem of getting each robot to punch hard enough to register a hit on the opponent bot while not breaking the opponent bot (or itself). Bots also had to withstand a bit of side load in case the arms got tangled or took a side blow. Pneumatic actuators provided us with a lot of flexibility over hydraulics or an electrical solution since they are fast, come in tons of variations, won't break when met with resistance, and can fine tuned with a few onsite adjustments.
To provide power to the actuators, the robots had two 2.5 gallon tanks pressurized to 150psi, with the actuators punching at ~70psi. We could punch for about five 90-second rounds before needing to re-pressurize the tanks. Pressurizing the onboard tanks was taken care of by a pair of off-the-shelf DeWalt air compressors.

The Head

It wouldn’t be a polished game if the head didn’t pop up on the losing bot, so we added another pneumatic actuator to raise and lower the head, and some extra red and blue LEDs. This pneumatic is housed in the chest of the robot and is triggered only when the game has ended.
To create the head, we first prototyped a concept with cardboard and duct tape. A rotated welding mask just happened to provide the shape we were going for on the crown, and we crafted each custom jaw with a laser cutter. We considered using a mold and vacuum forming to create something a bit more custom, but had to scrap the idea due to time constraints.

Sensors

Our initial implementation for detecting punches failed due to far too many false positives. We thought using IR distance sensors would be a good solution since we could detect a “close” punch and tell the other robot to retract the arm before real contact. The test looked promising, but in practice, when the opposite sensors were close, we saw a lot of noise in the data. The backup and currently implemented solution was to install simple push switches in the chest and detect when those are clicked by the chest plate pressing against them.

Power

Different items required different voltages. The motors and pneumatic valves required 24V, the LEDs required 12V and the USB hub required 5V. We used Castle Pro BEC converters to step down the voltages. These devices are typically used in RC airplanes and helicopters.
Shipping

So how does someone ship two 700lb robots from Seattle to Austin? We did it in 8 crates. . The key thing to note is that the tops and bottoms of each robot were separated. Any wire that connected the two parts had to be able to be disconnected in some form. This affected the serial cords and the power cords (5V, 12V, 24V).
Software

The software and architecture went through a variety of iterations during development. The final architecture used 3 laptops, 2 desktops, an access point, and a router. It's important to note that the laptops of Robot 1 and Robot 2 are physically mounted on the backs of each Robot body, communicating through WiFi to the Admin console. The entire setup looks like the following diagram:

Admin Console

The heart of the infrastructure is the Admin Console. Originally, this was also intended to be a scoreboard to show audience members the current stats of the match, but as we got further into the project, we realized this wouldn't be necessary. The robots are where the action is, and people's eyes focus there. Additionally, the robots themselves display their current health status via LEDs, so duplicating this information isn't useful. However, the admin side of this app remains.
Sockets

The admin console is the master controller for the game state and utilizes socket communication between it, the robots, and the user consoles. A generic socket handler was written to span each computer in the setup. The SocketListener object allows for incoming connections to be received, while the SocketClient allows clients to connect to those SocketListeners. These are generic objects, which must specify objects of type GamePacket to send and receive:

public class SocketListener where TSend : GamePacket where TReceive : GamePacket, new()

GamePacket is a base class from which specific packets inherit:

public abstract class GamePacket{ public byte[] ToByteArray() { MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); try { WritePacket(bw); } catch(IOException ex) { Debug.WriteLine("Error writing packet: " + ex); } return ms.ToArray(); } public void FromBinaryReader(BinaryReader br) { try { ReadPacket(br); } catch(IOException ex) { Debug.WriteLine("Error reading packet: " + ex); } } public abstract void WritePacket(BinaryWriter bw); public abstract void ReadPacket(BinaryReader br);}For example, in communication between the robots and the admin console, GameStatePacket and MovementDescriptorPacket are sent and received. Each GamePacket must implement its own ReadPacket and WritePacket methods to serialize itself for sending across the socket.
Packets are sent between machines every "frame". We need the absolute latest game state, robot movement, etc. at all times to ensure the game is functional and responsive.

As is quite obvious, absolutely no effort was put into making the console "pretty". This is never seen by the end users and just needs to be functional. Once the robot software and the user consoles are started, the admin console initiates connections to each of those four machines. Each machine runs the SocketListener side of the socket code, while the Admin console creates four SocketClient objects to connect to each those. Once connected, the admin has control of the game and can start, stop, pause, and reset a match by sending the appropriate packets to everyone that is connected.
Robot

The robot UI is also never intended to be seen by an end user, and therefore contains only diagnostic information.

Each robot has a wireless Xbox 360 controller connected to it so it can be manually controlled. The UI above reflects the positions of the controller sticks and buttons. During a match, it's possible for a bot to get outside of our "safe zone". One bot might be pushing the other, or the user may be moving the bot toward the edge of the ring. To counter this, the player's coach can either temporarily move the bot, turning off Kinect input, or force the game into "referee mode" which pauses the entire match and turns off Kinect control on both sides. In either case, the robots can be driven with the controllers and reset to safe positions. Once both coaches signal that the robots are reset, the admin can then resume the match.
Controlling Hardware

Phidget hardware controlled our LEDs, relays, and sensors. Getting data out of a Phidget along with actions, such as opening and closing a relay, is shockingly easy as they have pretty straightforward C# APIs and samples, which is why they typically are our go-to product for projects like this.
Below are some code snippets for the LEDs, relays, and sensor.
LEDs – from LedController.cs
This is the code that actually updates the health LEDs in the robot's chest. The LEDs were put on the board in a certain order to allow this style of iteration. We had a small issue of running out of one color of LEDs so we used some super bright ones and had to reduce the power levels to the non-super bright LEDs to prevent possible damage:

private void UpdateLedsNonSuperBright(int amount, int offset, int brightness){ for (var i = offset; i < amount + offset; i++) { _phidgetLed.leds[i] = brightness / 2; }}private void UpdateLedsSuperBright(int amount, int offset, int brightness){ for (var i = offset; i < amount + offset; i++) { _phidgetLed.leds[i] = brightness; }}
Sensor data – from SensorController.cs
This code snippet shows how we obtain the digital and analog inputs from the Phidget 8/8/8 interface board:

public SensorController(InterfaceKit phidgetInterfaceKit) : base(phidgetInterfaceKit){ PhidgetInterfaceKit.ratiometric = true;}public int PollAnalogInput(int index){ return PhidgetInterfaceKit.sensors[index].Value;}public bool PollDigitalInput(int index){ return PhidgetInterfaceKit.inputs[index];}
Relays – from RelayController.cs
Electrical relays fire our pneumatic valves. These control the head popping and the arms punching. For our application, we wanted the ability to reset the relay automatically. When the relay is opened, an event is triggered and we create an actively polled thread to validate whether we should close the relay. The reason why we actively poll is someone could be quickly toggling the relay. We wouldn't want to close it on accident. The polling and logic does result in a possible delay or early trigger for closing the relay, but for the BoxingBots the difference of 10ms for a relay closing is acceptable:

public void Open(int index, int autoCloseDelay){ UseRelay(index, true, autoCloseDelay);}public void Close(int index){ UseRelay(index, false, 0);}private void UseRelay(int index, bool openRelay, int autoCloseDelay){ AlterTimeDelay(index, autoCloseDelay); PhidgetInterfaceKit.outputs[index] = openRelay;}void _relayController_OutputChange(object sender, OutputChangeEventArgs e){ // closed if (!e.Value) return; ThreadPool.QueueUserWorkItem(state => { if (_timeDelays.ContainsKey(e.Index)) { while (_timeDelays[e.Index] > 0) { Thread.Sleep(ThreadTick); _timeDelays[e.Index] -= ThreadTick; } } Close(e.Index); });}public int GetTimeDelay(int index){ if (!_timeDelays.ContainsKey(index)) return 0; return _timeDelays[index];}public void AlterTimeDelay(int index, int autoCloseDelay){ _timeDelays[index] = autoCloseDelay;}
User Console

Since the theme of the party was Retro Gaming, we wanted to go for an early 80's Sci-fi style interface, complete with starscape background and solar flares! We wanted to create actual interactive elements, though, to maintain the green phosphor look of early monochrome monitors. Unlike traditional video games, however, the screens are designed not as the primary focus of attention, but rather to help calibrate the player before the round and provide secondary display data during the match. The player should primarily stay focused on the boxer during the match, so the interface is designed to sit under the players view line and serve as more of a dashboard during each match.
However, during calibration before each round, it is important to have the player understand how their core body will be used to drive the Robot base during each round. To do this, we needed to track an average of the joints that make up each fighter's body core. We handled the process by creating a list of core joints and a variable that normalizes the metric distances returned from the Kinect sensor into a human-acceptable range of motion:

private static List coreJoints = newList( newJointType[] { JointType.AnkleLeft, JointType.AnkleRight, JointType.ShoulderCenter, JointType.HipCenter });private const double RangeNormalizer = .22;private const double NoiseClip = .05;And then during each skeleton calculation called by the game loop, we average the core positions to determine the averages of the players as they relate to their playable ring boundary:

public staticMovementDescriptorPacket AnalyzeSkeleton(Skeleton skeleton){ // ... CoreAverageDelta.X = 0.0; CoreAverageDelta.Z = 0.0; foreach (JointType jt in CoreJoints) { CoreAverageDelta.X += skeleton.Joints[jt].Position.X - RingCenter.X; CoreAverageDelta.Z += skeleton.Joints[jt].Position.Z - RingCenter.Z; } CoreAverageDelta.X /= CoreJoints.Count * RangeNormalizer; CoreAverageDelta.Z /= CoreJoints.Count * RangeNormalizer; // ... if (CoreAverageDelta.Z > NoiseClip || CoreAverageDelta.Z < -NoiseClip) { packet.Move = -CoreAverageDelta.Z; } if (CoreAverageDelta.X > NoiseClip || CoreAverageDelta.X < -NoiseClip) { packet.Strafe = CoreAverageDelta.X; }}In this way, we filter out insignificant data noise and allow the player's average core body to serve as a joystick for driving the robot around. Allowing them to lean at any angle, the move and strafe values are accordingly set to allow for a full 360 degrees of movement freedom, while at the same time not allowing any one joint to unevenly influence their direction of motion.
Another snippet of code that may be of interest is the WPF3D rendering we used to visualize the skeleton. Since the Kinect returns joint data based off of a center point, it is relatively easy to wire up a working 3D model in WPF3D off of the skeleton data, and we do this in the ringAvatar.xaml control.
In the XAML, we simply need a basic Viewport3D with camera, lights, and an empty ModelVisual3D container to hold or squares. The empty container looks like this:

In the code, we created a generic WPF3DModel that inherits from UIElement3D and is used to store the basic positioning properties of each square. In the constructor of the object, though, we can pass a reference key to a XAML file that defines the 3D mesh to use:

public WPF3DModel(string resourceKey){ this.Visual3DModel = Application.Current.Resources[resourceKey] as Model3DGroup;}This is a handy trick when you need to do a fast WPF3D demo and require a certain level of flexibility. To create a 3D cube for each joint when ringAvatar is initialized, we simply do this:

private readonly List _models = new List();private void CreateViewportModels(){ for (int i = 0; i < 20; i++) { WPF3DModel model = new WPF3DModel("mesh_cube"); viewportModelsContainer2.Children.Add(model); // ... _models.Add(model); } // ...}And then each time we need to redraw the skeleton, we loop through the skeleton data and set the cube position like so:

if (SkeletonProcessor.RawSkeleton.TrackingState == SkeletonTrackingState.Tracked){ int i = 0; foreach (Joint joint in SkeletonProcessor.RawSkeleton.Joints) { if (joint.TrackingState == JointTrackingState.Tracked) { _models[i].Translate( joint.Position.X * 8.0, joint.Position.Y * 10.0, joint.Position.Z * -10.0); i++; } } // ...}There are a few other areas in the User Console that you may want to further dig into, including the weighting for handling a punch as well dynamically generating arcs based on the position of the fist to the shoulder. However, for this experience, the User Console serves as a secondary display to support the playing experience and gives both the player and audience a visual anchor for the game.
Making a 700lb Tank Drive like a First Person Shooter

The character in a first person shooter (FPS) video game has an X position, a Y position, and a rotation vector. On an Xbox controller, the left stick controls the X,Y position. Y is the throttle (forward and backward), X is the strafing amount (left and right), and the right thumb stick moves the camera to change what you're looking at (rotation). When all three are combined, the character can do things such as run around someone while looking at them.
In the prior project, we had existing code that worked for controlling all 4 motors at the same time, working much like a tank does, so we only had throttle (forward and back) and strafing (left and right). Accordingly, we can move the motors in all directions, but there are still scenarios in which the wheels fight one another and the base won't move. By moving to a FPS style, we eliminate the ability to move the wheels in an non-productive way and actually make it a lot easier to drive.
Note that Clint had some wiring "quirks" with polarity and which motor was left VS right, he had to correct in these quirks in software :

public Speed CalculateSpeed(double throttleVector, double strafeVector, double rotationAngle){ rotationAngle = VerifyLegalValues(rotationAngle); rotationAngle = AdjustValueForDeadzone(rotationAngle, AllowedRotationAngle, _negatedAllowedRotationAngle); // flipped wiring, easy fix is here throttleVector *= -1; rotationAngle *= -1; // miss wired, had to flip throttle and straff for calc return CalculateSpeed(strafeVector + rotationAngle, throttleVector, strafeVector - rotationAngle, throttleVector);}protected Speed CalculateSpeed(double leftSideThrottle, double leftSideVectorMultiplier, double rightSideThrottle, double rightSideVectorMultiplier) { /* code from Jellybean */ }Conclusion

The Boxing Bots project was one of the biggest things we have built to date. It was also one of our most successful projects. Though it was a rainy, cold day and night in Austin when the bots were revealed, and we had to move locations several times during setup to ensure the bots and computers wouldn't be fried by the rain, they ran flawlessly for the entire event and contestants seemed to have a lot of fun driving them.

More...




The HP Printer Display Hack is a simple background application that periodically checks the current price of a selected stock and sends it to the display of HP (and compatible) laser printers.
Introduction

This app is based on an old hack from back to at least 1997 that uses the HP Job control language to change the text on the LCD status display. Some background on this hack can be found here: http://www.irongeek.com/i.php?page=s...rinterhacking. There are various versions of the hack code out there, and typically they all work the same way: you specify the address of the printer and the message to send, open a TCP connection to the printer over port 9100, and then send a command to update the display.
This app is a variation of that hack. It’s a tray application that periodically checks the stock price for a company and then sends a formatted message of the stock symbol and price to a specified printer.
To get the current stock price, we retrieve the data from Yahoo! through finance.yahoo.com. The data comes back in CSV format. To save a step in parsing the CSV columns, we use YQL, the Yahoo! Query Language. Yahoo! created YQL to provide a SQL-like API for querying data from various online web services. YQL! can return XML or JSON data, and we’ll take the XML and use LINQ to parse the data.

How to Use the App

The first time you run the app, the main form will appear and you'll be able to enter in the stock symbol and the IP address of your printer. Click the “Get Printer” button to view a dialog listing the available printers connected on port 9100.
There are two checkboxes. The first one is labeled “Start with Windows”. When this setting is saved, the following code is executed to tell Windows whether to start the app when user logs in:

C#

private void StartWithWindows(bool start) { using (RegistryKey hkcu = Registry.CurrentUser) { using (RegistryKey runKey = hkcu.OpenSubKey(@"SoftwareMicrosoftWindowsCurrentVersionRun", true)) { if (runKey == null) return; if (start) runKey.SetValue(wpfapp.Properties.Resources.Code4FunStockPrinter, Assembly.GetEntryAssembly().Location); else { if (runKey.GetValue(wpfapp.Properties.Resources.Code4FunStockPrinter) != null) runKey.DeleteValue(wpfapp.Properties.Resources.Code4FunStockPrinter); } } } }
VB

Private Sub StartWithWindows(ByVal start As Boolean) Using hkcu As RegistryKey = Registry.CurrentUser Using runKey As RegistryKey = hkcu.OpenSubKey("SoftwareMicrosoftWindowsCurrentVersionRun", True) If runKey Is Nothing Then Return End If If start Then runKey.SetValue(My.Resources.Code4FunStockPrinter, System.Reflection.Assembly.GetEntryAssembly().Location) Else If runKey.GetValue(My.Resources.Code4FunStockPrinter) IsNot Nothing Then runKey.DeleteValue(My.Resources.Code4FunStockPrinter) End If End If End Using End UsingEnd SubThe enabled checkbox is used so that you can pause the sending of the stock price to the printer without having to exit the app. When you press the “Start” button, you are prompted to save any changed settings and the app hides the main form, leaving just the system tray icon. While the app is running, it will check the stock price every 5 minutes. If the price has changed, it tells the printer to display the stock symbol and price on the display.
A DispatcherTimer object is used to determine when to check the stock price. It’s created when the main form is created and will only execute the update code when the settings have been defined and enabled.
If an unexpected error occurs, the DispatcherUnhandledException event handler will log the error to a file and alert the user:

C#

void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { // stop the timer _mainWindow.StopPrinterHacking(); // display the error _mainWindow.LogText("Sending the stock prince to the printer was halted due to this error:" + e.Exception.ToString()); // display the form ShowMainForm(); // Log the error to a file and notify the user Exception theException = e.Exception; string theErrorPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "PrinterDisplayHackError.txt"; using (System.IO.TextWriter theTextWriter = new System.IO.StreamWriter(theErrorPath, true)) { DateTime theNow = DateTime.Now; theTextWriter.WriteLine(String.Format("The error time: {0} {1}", theNow.ToShortDateString(), theNow.ToShortTimeString())); while (theException != null) { theTextWriter.WriteLine("Exception: " + theException.ToString()); theException = theException.InnerException; } } MessageBox.Show("An unexpected error occurred. A stack trace can be found at:n" + theErrorPath); e.Handled = true; }
VB

Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As System.Windows.Threading.DispatcherUnhandledExceptionEventArgs) ' stop the timer _mainWindow.StopPrinterHacking() ' display the error _mainWindow.LogText("Sending the stock prince to the printer was halted due to this error:" & e.Exception.ToString()) ' display the form ShowMainForm() ' Log the error to a file and notify the user Dim theException As Exception = e.Exception Dim theErrorPath As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) & "PrinterDisplayHackError.txt" Using theTextWriter As System.IO.TextWriter = New System.IO.StreamWriter(theErrorPath, True) Dim theNow As Date = Date.Now theTextWriter.WriteLine(String.Format("The error time: {0} {1}", theNow.ToShortDateString(), theNow.ToShortTimeString())) Do While theException IsNot Nothing theTextWriter.WriteLine("Exception: " & theException.ToString()) theException = theException.InnerException Loop End Using MessageBox.Show("An unexpected error occurred. A stack trace can be found at:" & vbLf & theErrorPath) e.Handled = TrueEnd Sub
The User Interface

The application currently looks like this:

Pressing the “Get Printer” button opens a dialog that looks like this:

The UI was designed with WPF and uses the basic edit controls as well as a theme from the WPF Themes project on CodePlex. On the main form, the stock symbol, printer IP address, and the check boxes using data bindings to bind each control to a custom setting are defined in the PrinterHackSettings class.
The settings are defined in a class descended from ApplicationSettingsBase. The .NET runtime will read and write the settings based on the rules defined here.
The big RichTextBog in the center of the form is used to display the last 10 stock price updates. The app keeps a queue of the stock price updates, and when the queue is updated it’s sent to the RichTextBox with the following code:

C#

public void UpdateLog(RichTextBox rtb) { int i = 0; TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd); textRange.Text = string.Empty; foreach (var lg in logs) { i++; TextRange tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd) { Text = String.Format("{0} : ", lg.LogTime.ToString("hh:mm:ss")) }; tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DarkRed); tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd) { Text = lg.LogMessage + Environment.NewLine }; tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black); } if (i > 10) logs.Dequeue(); rtb.ScrollToEnd(); }
VB

Public Sub UpdateLog(ByVal rtb As RichTextBox) Dim i As Integer = 0 For Each lg As LogEntry In logs i += 1 Dim tr As New TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd) With {.Text = String.Format("{0} : ", lg.LogTime.ToString("hh:mm:ss"))} tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red) tr = New TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd) With {.Text = lg.LogMessage & Environment.NewLine} tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.White) Next lg If i > 10 Then logs.Dequeue() End If rtb.ScrollToEnd()End Sub

Displaying a notification trace icon

WPF does not provide any functionality for running an app with just an icon in the notification area of the taskbar. We need to tap into some WinForms functionality. Add a reference to the System.Windows.Form namespace to the project. In the App.xaml file, add an event handler to the Startup event. Visual Studio will wire up an Application.Startup event in the code behind file. We can use that event to add a WinForms.NotifyIcon and wireup a context menu to it:

C#

private void Application_Startup(object sender, StartupEventArgs e) { _notifyIcon = new WinForms.NotifyIcon(); _notifyIcon.DoubleClick += notifyIcon_DoubleClick; _notifyIcon.Icon = wpfapp.Properties.Resources.Icon; _notifyIcon.Visible = true; WinForms.MenuItem[] items = new[] { new WinForms.MenuItem("&Settings", Settings_Click) { DefaultItem = true } , new WinForms.MenuItem("-"), new WinForms.MenuItem("&Exit", Exit_Click) }; _notifyIcon.ContextMenu = new WinForms.ContextMenu(items); _mainWindow = new MainWindow(); if (!_mainWindow.SettingsAreValid()) _mainWindow.Show(); else _mainWindow.StartPrinterHacking(); }
VB

Private Sub Application_Startup(ByVal sender As Object, ByVal e As StartupEventArgs) _notifyIcon = New System.Windows.Forms.NotifyIcon() AddHandler _notifyIcon.DoubleClick, AddressOf notifyIcon_DoubleClick _notifyIcon.Icon = My.Resources.Icon _notifyIcon.Visible = True Dim items() As System.Windows.Forms.MenuItem = {New System.Windows.Forms.MenuItem("&Settings", AddressOf Settings_Click) With {.DefaultItem = True}, New System.Windows.Forms.MenuItem("-"), New System.Windows.Forms.MenuItem("&Exit", AddressOf Exit_Click)} _notifyIcon.ContextMenu = New System.Windows.Forms.ContextMenu(items) _mainWindow = New MainWindow() If Not _mainWindow.SettingsAreValid() Then _mainWindow.Show() Else _mainWindow.StartPrinterHacking() End IfEnd Sub
Getting the Stock Information

From the Yahoo Financial site, you get can download a CSV file for any specified stock. Here's a web site that documents the format needed to get the right fields: http://www.gummy-stuff.org/Yahoo-data.htm. We want to return the stock symbol and the last traded price. That works out to be “s” and “l1”, respectively.
If you open the following URL with a browser, a file named quotes.csv will be returned:
http://download.finance.yahoo.com/d/...v?s=MSFT&f=sl1
You should get a file like this:

The first field is the stock symbol and the second is the last recorded price. You could just read that data and parse out the fields, but we can get the data in more readable format.
Yahoo! has a tool called the YQL Console that will you let you interactively query against Yahoo! and other web service providers. While it's overkill to use on a two column CSV file, it can be used to tie together data from multiple services.
To use our MSFT stock query with YQL, we format the query like this:

select * from csv where url='http://download.finance.yahoo.com/d/quotes.csv?s=MSFT&f=sl1' and columns='symbol,price'You can see this query loaded into the YQL Console here.

When you click the “TEST” button, the YQL query is executed and the results displayed in the lower panel. By default, the results are in XML, but you can also get the data back in JSON format.
Our result set has been transformed into the following XML:

MSFT
30.54
This XML document can be easily parsed in the application code. The URL listed below “THE REST QUERY” on the YQL page is the YQL query encoded so that it can be sent as a GET request. For this YQL query, we use the following URL:
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3Fs%3DMSFT%26f%3Dsl1'%20and%20columns%3D'symbol%2Cprice'
This is the URL that our application uses to get the stock price. Notice the MSFT in bold face—we replace that hard coded stock symbol with a format item and just use String.Format() to generate the URL at run time.
To get the stock price from our code, we can wrap this with the following method:

C#

public string GetPriceFromYahoo(string tickerSymbol) { string price = string.Empty; string url = string.Format("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3Fs%3D{0}%26f%3Dsl1'%20and%20columns%3D'symbol%2Cprice'", tickerSymbol); try { Uri uri = new Uri(url); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri); HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); XDocument doc = XDocument.Load(resp.GetResponseStream()); resp.Close(); var ticker = from query in doc.Descendants("query") from results in query.Descendants("results") from row in query.Descendants("row") select new { price = row.Element("price").Value }; price = ticker.First().price; } catch (Exception ex) { price = "Exception retrieving symbol: " + ex.Message; } return price; }
VB

Public Function GetPriceFromYahoo(ByVal tickerSymbol As String) As String Dim price As String Dim url As String = String.Format("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3Fs%3D{0}%26f%3Dsl1'%20and%20columns%3D'symbol%2Cprice'", tickerSymbol) Try Dim uri As New Uri(url) Dim req As HttpWebRequest = CType(WebRequest.Create(uri), HttpWebRequest) Dim resp As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse) Dim doc As XDocument = XDocument.Load(resp.GetResponseStream()) resp.Close() Dim ticker = From query In doc.Descendants("query") , results In query.Descendants("results") , row In query.Descendants("row") _ Let xElement = row.Element("price") _ Where xElement IsNot Nothing _ Select New With {Key .price = xElement.Value} price = ticker.First().price Catch ex As Exception price = "Exception retrieving symbol: " & ex.Message End Try Return priceEnd Function
While this code makes the readying of a two column CSV file more complicated than it needs to be, it makes it easier to adapt this code to read the results for multiple stock symbols and/or additional fields.
Getting the List of Printers

We are targeting a specific type of printer: those that use the HP PJL command set. Since we talk to these printers over port 9100, we only need to list the printers that listen on that port. We can use Windows Management Instrumentation (WMI) to list the printer TCP/IP addresses that are using port 9100. The WMI class Win32_TCPIPPrinterPort can be used for that purpose, and we’ll use the following WMI query:
Select Name, HostAddress from Win32_TCPIPPrinterPort where PortNumber = 9100
This returns the list of port names and addresses on your computer that are being used over port 9100. Take that list and store it in a dictionary for a quick lookup:

C#

static public Dictionary GetPrinterPorts(){ var ports = new Dictionary(); ObjectQuery oquery = new ObjectQuery("Select Name, HostAddress from Win32_TCPIPPrinterPort where PortNumber = 9100"); ManagementObjectSearcher mosearcher = new ManagementObjectSearcher(oquery); using (var searcher = new ManagementObjectSearcher(oquery)) { var objectCollection = searcher.Get(); foreach (ManagementObject managementObjectCollection in objectCollection) { var portAddress = IPAddress.Parse(managementObjectCollection.GetPropertyValue("HostAddress").ToString()); ports.Add(managementObjectCollection.GetPropertyValue("Name").ToString(), portAddress); } } return ports; }
VB

Public Shared Function GetPrinterPorts() As Dictionary(Of String, IPAddress) Dim ports = New Dictionary(Of String, IPAddress)() Dim oquery As New ObjectQuery("Select Name, HostAddress from Win32_TCPIPPrinterPort where PortNumber = 9100") Dim mosearcher As New ManagementObjectSearcher(oquery) Using searcher = New ManagementObjectSearcher(oquery) Dim objectCollection = searcher.Get() For Each managementObjectCollection As ManagementObject In objectCollection Dim portAddress = IPAddress.Parse(managementObjectCollection.GetPropertyValue("HostAddress").ToString()) ports.Add(managementObjectCollection.GetPropertyValue("Name").ToString(), portAddress) Next managementObjectCollection End Using Return portsEnd Function
Next, we get the list of printers that this computer knows about. We could do that through WMI, but I decided to stay closer to the .NET Framework and use the LocalPrintServer class. The GetPrintQueues method returns a collection of print queues of the type PrintQueueCollection. We can then iterate through the PrintQueueCollection and look for all printers that have a port name that matches the names returned by the WMI query. That gives code that looks like this:

C#

public class LocalPrinter { public string Name { get; set; } public string PortName { get; set; } public IPAddress Address { get; set; } } static public List GetPrinters() { Dictionary ports = GetPrinterPorts(); EnumeratedPrintQueueTypes[] enumerationFlags = { EnumeratedPrintQueueTypes.Local }; LocalPrintServer printServer = new LocalPrintServer(); PrintQueueCollection printQueuesOnLocalServer = printServer.GetPrintQueues(enumerationFlags); return (from printer in printQueuesOnLocalServer where ports.ContainsKey(printer.QueuePort.Name) select new LocalPrinter() { Name = printer.Name, PortName = printer.QueuePort.Name, Address = ports[printer.QueuePort.Name] }).ToList(); }
VB

Public Class LocalPrinter Public Property Name() As String Public Property PortName() As String Public Property Address() As IPAddressEnd ClassPublic Shared Function GetPrinters() As List(Of LocalPrinter) Dim ports As Dictionary(Of String, IPAddress) = GetPrinterPorts() Dim enumerationFlags() As EnumeratedPrintQueueTypes = { EnumeratedPrintQueueTypes.Local } Dim printServer As New LocalPrintServer() Dim printQueuesOnLocalServer As PrintQueueCollection = printServer.GetPrintQueues(enumerationFlags) Return ( _ From printer In printQueuesOnLocalServer _ Where ports.ContainsKey(printer.QueuePort.Name) _ Select New LocalPrinter() With {.Name = printer.Name, .PortName = printer.QueuePort.Name, .Address = ports(printer.QueuePort.Name)}).ToList()End Function

Sending the Stock Price to the Printer

The way to send a message to a HP display is via a PJL command. PJL stands for Printer Job Language. Not all PJL commands are recognized by every HP printer, but if you have an HP laser printer with a display, the command should work. This should work for any printer that is compatible with HP’s PJL command set. For the common PJL commands, HP has an online document here.
We will be using the “Ready message display” PJL command. All PJL commands will start and end with a sequence of bytes called the “Universal Exit Language” or UEL. This sequence tells the printer that it’s about to receive a PJL command. The UEL is defined as
%-12345X
The format of the packet sent to the printer is be "UEL PJL command UEL". The Ready message display format is
@PJL RDYMSG DISPLAY=”message”[]
To send the command that has the printer display “Hello World”, you would send the following sequence:
%-12345X@PJL RDYMSG DISPLAY=”Hello World”[]%-12345X[]
We wrap this up in a class called SendToPrinter and the good stuff gets executed in the Send method, as listed below:

C#

public class SendToPrinter { public string host { get; set; } public int Send(string message) { IPAddress addr = null; IPEndPoint endPoint = null; try { addr = Dns.GetHostAddresses(host)[0]; endPoint = new IPEndPoint(addr, 9100); } catch (Exception e) { return 1; } Socket sock = null; String head = "u001B%-12345X@PJL RDYMSG DISPLAY = ""; String tail = ""rnu001B%-12345Xrn"; ASCIIEncoding encoding = new ASCIIEncoding(); try { sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); sock.Connect(endPoint); sock.Send(encoding.GetBytes(head)); sock.Send(encoding.GetBytes(message)); sock.Send(encoding.GetBytes(tail)); sock.Close(); } catch (Exception e) { return 1; } int bytes = (head + message + tail).Length; return 0; } }
VB

Public Function Send(ByVal message As String) As Integer Dim endPoint As IPEndPoint = Nothing Try Dim addr As IPAddress = Dns.GetHostAddresses(Host)(0) endPoint = New IPEndPoint(addr, 9100) Catch Return 1 End Try Dim startPJLSequence As String = ChrW(&H1B).ToString() & "%-12345X@PJL RDYMSG DISPLAY = """ Dim endPJLSequence As String = """" & vbCrLf & ChrW(&H1B).ToString() & "%-12345X" & vbCrLf Dim encoding As New ASCIIEncoding() Try Dim sock As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP) sock.Connect(endPoint) sock.Send(encoding.GetBytes(startPJLSequence)) sock.Send(encoding.GetBytes(message)) sock.Send(encoding.GetBytes(endPJLSequence)) sock.Close() Catch Return 1 End Try Return 0End Function
The Installer

The installer for this app was written with WiX, Windows Installer XML. WiX is an open source project created by Rob Mensching that lets you build Windows Installer .msi and .msm files from XML source code. I used the release candidate of WiX 3.6, but any recent version should work. Of course, you don’t need an installer if you build the app yourself.
Setting InstalScope to “perUser” designates this package as being a per-user install. Adding the property “WixAppFolder” and set to “WixPerUserFolder” tells WiX to install this app under %LOCALAPPDATA% instead of under %ProgramFiles%. This eliminates the need for the installer to request elevated rights and the UAC prompt:

Because we are not touching any system settings, I eliminated the creation of a system restore point at the start of the installation process. This greatly speeds up the installation of the app, and is handled by adding a property named MSIFASTINSTALL with the value of “1”:

I modified the UI sequence to skip over the end user license agreement. There is nothing to license here and no one reads EULAs anyways. To do this, I needed to download the WiX source code and extract a file named WixUI_Mondo.wxs. I added it to the installer project and renamed it to WixUI_MondoNoLicense.wxs. I also added a checkbox to the exit dialog to allow the user to launch the app after it been installed:

WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed
When you build the installer, it generates two ICE91 warning messages. An ICE91 warning occurs when you install a file or shortcut into a per-user only folder. Since we have explicitly set the InstallScope to “perUser”, we can safely ignore these two warnings. If you hate warning messages, you can use the tool settings for the installer project to suppress ICE91 validation checks:

Conclusion

I have had various versions of this app running in my office for over a year. It’s been set to show our current stock price on the main printer in the development department. It’s fun to watch people walk near the printer just to check out the current stock price.
If you want to try this out, the download link for the source code and installer is at the top of the article!
About The Author

I am a senior R&D engineer for Tyler Technologies, working on our next generation of school bus routing software. I also am the leader of the Tech Valley .NET Users Group (TVUG). You can follow me at @anotherlab and check out my blog at anotherlab.rajapet.net. I would list my G+ address, but I don’t use it. I started out with a VIC-20 and been slowly moving up the CPU food chain ever since.
I would like to thank Brian Peek on the Coding4Fun team for his encouragement and suggestions and for letting me steal large chunks of the UI code from his TweeVo project .

More...




C9 Netduino Shield Series - Using Arduino Shield with Netduino - Part I

Photo courtesy of John Boxall
Introduction

When the Arduino Duemilanove microcontroller appeared in 2005, it featured a set of female pin headers exposing most of the pins of the ATmega168 for easy hacking and for connecting accessory boards known as 'Shields'. The purpose of a shield is to provide new plug-and-play functionality to the host microcontroller, such as circuit prototyping, motion control, sensor integration, network and radio communication, or gaming interfaces, without worrying too much about the hardware implementation details. Seven years after the birth of the original Arduino, new shields keep coming out and are being cataloged on http://shieldlist.org/, a testament to the versatility of the design. It is also simple to build a DIY shield when nothing out there will meet your needs or when you want to understand how the shield concept works from the ground up.
In their infinite wisdom, Secret Labs, the makers of the Netduino, adopted the same Arduino form factor and header pin out to let .NET Micro Framework users tap into the vast array of Arduino shields on the market. Yet, there's always one hurdle that needs to be overcome: in order to give access to their hardware functions easily, many Arduino shields provide sample sketches (a.k.a. C/C++ Wiring programs) and libraries also written in C/C++ designed to be used within the Arduino IDE. Unfortunately, Arduino sketches and libraries aren't compatible with the Visual Studio environment and the .NET runtime: they need to be adapted in order to make use of the shield's hardware.
The goal of this series of articles is to attempt to demystify what an Arduino shield is. To do this, we'll start by building one from scratch. Then, we'll present a generic approach for selecting Netduino-compatible Arduino shields and adapting Arduino code to interface with the .NET Micro Framework.
Selecting Arduino shields for use with Netduino / Plus

Arduino shields using hardware components interfaced over protocols such as SPI, I2C, 1-Wire or serially over a UART are generally good candidates for a Netduino adaptation because the .NET Micro Framework supports these protocols natively and can do bulk I/O transfers, yielding good performance.
However, if a shield requires bit-banging data on GPIOs (i.e. communicating data serially, such as SPI, I2C, RS-232, in software by toggling GPIO lines individually instead of using dedicated hardware interfaces) or has very low I/O latency requirements, it may not be practical or even possible to use the shield on a Netduino / Plus.
The reason for this is simple: the Arduino runs native code and can access hardware registers directly with a latency orders of magnitude lower than what the .NET Micro Framework can achieve on a Netduino / Plus where toggling GPIOs means going through multiple framework layers while running interpreted code. The maximum raw I/O toggling frequency on a Netduino / Plus clocked at 48 MHz was measured around ~8.4KHz which is slow compared to the few MHz achievable on an Arduino clocked at 16 MHz.
Fortunately, there are possible workarounds and strategies

Whenever an Arduino library bit-bangs SPI data on GPIOs, regardless of the pins used to do it, it can be replaced by using the standard SPI interface on the Netduino / Plus.The Netduino / Plus has significantly more RAM available than the Arduino and can transfer larger SPI data buffer in a single shot, dramatically reducing I/O latency. For instance, driving a display shield would greatly benefit from this method where a frame is cached in RAM on the Netduino / Plus then sent in one shot over SPI to the hardware display driver.
The bottom line is that it is always a good idea to review how the Arduino code interfaces with a given shield before proceeding with a purchase or starting a conversion project. This review process is also facilitated by http://shieldlist.org which shows which pins are being used to drive a shield. For example, the Adafruit Industries Logger Shield uses hardware SPI (pins D10-D13) for the SD card and I2C (pins A4-A5) for the DS1307 real time clock, making it a perfect adaptation candidate for the Netduino / Plus as we'll see in our next article.

It's also very important to know what features are available on the .NET Micro Framework running on the Netduino / Plus: some things come standard with the .NET Micro Framework which normally require add-ons libraries on the Arduino such as file system and networking support.
Finally, it is wise to search code repositories such as CodePlex, BitBucket and GitHub for hardware drivers and libraries before undertaking writing one in C# from scratch based on component datasheets. This extends to the Netduino and the TinyCLR community forums where many people have posted drivers in discussion threads.
Building a shield from scratch to meet specific requirements

Recently, we were asked if it was possible to connect our Touch Display module designed for a Netduino Go! to a Netduino / Plus. By doing a bit of research and seeing how the driver for the Touch Module works, this can be done by building a simple custom shield composed of a few parts connecting the Netduino pin headers to a Netduino Go! socket breakout board like so:

High-Level Software Interface

To frame the rest of this article, the communication interface with the shield is done using SPI and a GPIO used for synchronization. The communication protocol details are wrapped in the Nwazet.Go.Display.Imaging.VirtualCanvas class which needs to be initialized with the SPI and GPIO parameters matching the pin out of the shield:

var canvas = new VirtualCanvas(TouchEventHandler, WidgetClickedHandler);canvas.Initialize( displaySpi: SPI.SPI_module.SPI1, displayChipSelect: Pins.GPIO_PIN_D9, displayGPIO: Pins.GPIO_PIN_D8, speedKHz: 5000);From that point on, all interactions with the shield are done through Draw* methods followed by a call to the Execute() method which handles sending and receiving SPI data packets. The VirtualCanvas class also provides methods for creating widgets such as buttons, receiving touch screen events and setting the screen orientation.
For example, the following code snippet draws and updates a progress bar and uses one of the proportional fonts built into the display:

public static void Main() { var canvas = new VirtualCanvas(); canvas.Initialize( displaySpi: SPI.SPI_module.SPI1, displayChipSelect: Pins.GPIO_PIN_D9, displayGPIO: Pins.GPIO_PIN_D8, speedKHz: 5000); var fontInfo = new DejaVuSans9().GetFontInfo(); canvas.DrawFill(0xFFFF); canvas.DrawString(5, 144, (ushort)BasicColor.Black, fontInfo.ID, "Progress"); for (var progress = 1; progress




For //build/ 2012, we wanted to showcase what Windows 8 can offer developers. There are a lot of projects showing off great things like contracts and Live Tiles, but we wanted to show off some of the lesser known features. This project focuses on one of those: stereoscopic 3D with DirectX 11.1.
Prior to DirectX 11.1, stereoscopic 3D required specific hardware and a custom API written for that hardware. With DX11.1, stereoscopic 3D has been "democratized." Any GPU that supports DirectX 11.1 can be connected to any device which supports stereoscopic 3D, be it a projector, an LCD TV, or anything else. Plug it in and DirectX does the rest.
From the software side of things, any DX11.1 application can determine if the connected display supports stereoscopic 3D, and choose to render itself separately for the player's left and right eye.
To showcase this feature, we decided to build a very simple game that would give the illusion of depth, but be easy to explain and play. What's easier than Pong? So, we built the world's most over-engineered game of 3D Pong named Maelstrom.

Software

Each player setup consists of two applications: the DirectX 11.1 game written in C++, and the touch-screen controller written in C#/XAML. Both are Windows Store applications. Since this is a two player game, there are two instances of each application running, one per player. All for applications are networked together using StreamSockets from the Windows Runtime. The two controllers and player two's DirectX game connect to player one's DirectX game, which acts as the "master". Controller input is sent here, and, once the ball and paddle positions are calculated, the data is drawn for player one and sent to player two which draws the world from the other player's perspective.

Direct3D Application

Getting Started with stereoscopic DirectX11, C++, and XAML

If you have never worked with DirectX before, it can be a little overwhelming at first. And even if you have worked with it some in the past, targeting the new Windows 8 ecosystem, along with C++ and XAML have added some additional changes in how you may have designed your solution previously.
Fortunately, the Windows Dev Center for Windows Store Apps has some great samples to get you started, and we took full advantage of them to get to speed. For a great, simple example of how to leverage the new stereoscopic feature in Direct3D 11.1, we started with Direct3D Stereoscopic Sample which shows the basic adjustments to the Render loop for toggling your virtual cameras. However, to see a great example of a simple game structure that also leverages stereoscopic rendering where available, the tutorial found at Walkthrough: a simple Windows Store game with DirectX is invaluable. Further in this article, we will dive deeper into the specifics of stereoscopic rendering in our game.
One thing to note, if you follow the link in the above Walkthrough to the original project, it will take you to a C++ only implementation of the game. Now, of course, all the DirectX game objects such as the paddle, puck and walls are all rendered using D3D. However, for HUD (Heads up Display) elements, this C++ only sample also uses DirectX exclusively. If you are coming from a managed code background, this will definitely seem like unnecessary overhead. That is because this C++ only sample was created after last year's BUILD conference in 2011 and C++ and DirectX still did not play well with XAML.
However, a few months later, the ability to nest DirectX content in a XAML project became available for true hybrid style solutions (see the article DirectX and XAML interop - Windows Store apps using C++ and DirectX for more information). After this feature was added, the simple Shooter Game referenced above had its HUD logic rewritten in XAML and posted up to Dev Center as XAML DirectX 3D shooting game sample, which shows both stereoscopic support, a simple Game Engine structure in C++ and XAML integration. At this point, we had all the starter code we needed to start writing our own game.
Game Engine

We modified the base sample to accommodate our needs. We created specific GameObjects, such as Paddle, Puck, etc. to add the behaviors we needed. We also added an Update and Render method to the base GameObject so that, for every frame, we could do any calculations required, and then draw the object to the screen. This is very similar to how XNA sets up its game engine.
Game Constants

Because we were tweaking a variety of values like colors, sizes, camera locations, etc., we created a GameConstants.h header file which contains nothing but these types of values in a single location. This made it very easy for us to quickly try out various tweaks and see the results on the next run. Using namespaces helped keep the code a bit more manageable here as well. Here’s a quick snippet of that file:

namespace GameConstants{ // bounds of the arena static const DirectX::XMFLOAT3 MinBound = DirectX::XMFLOAT3( 0.0f, 0.0f, 0.0f); static const DirectX::XMFLOAT3 MaxBound = DirectX::XMFLOAT3(19.0f, 10.0f, 90.0f); // game camera "look at" points static const DirectX::XMFLOAT3 LookAtP1 = DirectX::XMFLOAT3(9.5f, 5.0f, 90.0f); static const DirectX::XMFLOAT3 LookAtP2 = DirectX::XMFLOAT3(9.5f, 5.0f, 0.0f); // Waiting Room camera positions static const DirectX::XMFLOAT3 WaitingEyeP1 = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MaxBound.z - 12.0f); static const DirectX::XMFLOAT3 WaitingEyeP2 = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MinBound.z + 12.0f); static const DirectX::XMFLOAT3 WaitingEyeMjpegStation = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MinBound.z + 9.6f); // game camera eye position static const DirectX::XMFLOAT3 EyeP1 = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MinBound.z - 6.0f); static const DirectX::XMFLOAT3 EyeP2 = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MaxBound.z + 6.0f); static const float Paddle2Position = MaxBound.z - 5.0f; namespace PaddlePower { // power level to light paddle at maximum color static const float Max = 9.0f; // max paddle power color...each component will be multiplied by power factor static const DirectX::XMFLOAT4 Color = DirectX::XMFLOAT4(0.2f, 0.4f, 0.7f, 0.5f); // factor to multiply mesh percentage based on power static const float MeshPercent = 1.2f; }; // time to cycle powerups namespace Powerup { namespace Split { static const float Time = 10.0f; static const float NumTiles = 4; static const DirectX::XMFLOAT4 TileColor = DirectX::XMFLOAT4(0.1f, 0.4f, 1.0f, 1.0f); static const float TileFadeUp = 0.20f; static const float TileDuration = 2.10f; static const float TileFadeDown = 0.20f; static const float TileMeshPercent = 2.0f; static const float TileDiffusePercent = 2.0f; }; };}Stereoscopic 3D

Direct3D must be initialized properly to support stereoscopic displays. When the swap chains are created, an additional render target is required, such that one render target is for the left eye, and one render target is for the right eye. Direct3D will let you know if a stereoscopic display is available, so you can create the swap chain and render targets appropriately.
With those in place, it’s simply a matter of rendering your scene twice, once per eye…that is, once per render target.
For our game this was very simple. Our in-game camera contains two projection matrices, one representing the view from the left eye, and one from the right eye. These are calculated when the projection parameters are set.

void Camera::SetProjParams( _In_ float fieldOfView, _In_ float aspectRatio, _In_ float nearPlane, _In_ float farPlane ){ // Set attributes for the projection matrix. m_fieldOfView = fieldOfView; m_aspectRatio = aspectRatio; m_nearPlane = nearPlane; m_farPlane = farPlane; XMStoreFloat4x4( &m_projectionMatrix, XMMatrixPerspectiveFovLH( m_fieldOfView, m_aspectRatio, m_nearPlane, m_farPlane ) ); STEREO_PARAMETERS* stereoParams = nullptr; // Update the projection matrix. XMStoreFloat4x4( &m_projectionMatrixLeft, MatrixStereoProjectionFovLH( stereoParams, STEREO_CHANNEL::LEFT, m_fieldOfView, m_aspectRatio, m_nearPlane, m_farPlane, STEREO_MODE::NORMAL ) ); XMStoreFloat4x4( &m_projectionMatrixRight, MatrixStereoProjectionFovLH( stereoParams, STEREO_CHANNEL::RIGHT, m_fieldOfView, m_aspectRatio, m_nearPlane, m_farPlane, STEREO_MODE::NORMAL ) );}Depending on which eye we are rendering, we grab the appropriate projection matrix and pass it down to the vertex shader, so the final scene is rendered offset for the proper eye.
Collision Detection

If you are just starting to move into 3D modeling and programming, one of the trickier aspects of your game can be collision detection and response. Maelstrom uses primitives for all of the game elements, so our collision code was able to be a bit more straightforward compared to complex mesh collisions, but understanding a few core math concepts is still critical to grasp what the code is doing.
Fortunately, DirectX provides us with an DirectX Math Library that is able to do the serious heavy lifting, so the main complexity comes from framing the problem and learning how to apply the library.
For example, In our situation we had up to three very fast moving spheres and needed to check for wall collisions and then handle to appropriate bounce, since some of the walls would also be angled. In a 2D game, a collision detection between a sphere and an axis line is very easy. If the distance between a circle and the line is less than or equal to the radius of the sphere, they are touching. On every frame, you move your circle based on its velocity and do your collision test again. But even here, your solution may not be that easy for two reasons.
First, what if the line is angled and not lying flat on the X or Y axis? You have to find the point on the line based on the line's angle that is closest to the sphere to do your distance calculations. And if you then want it to bounce, you have to rotate the velocity of the circle by the line's angle, calculate your bounce, and then rotate back. And that's just rotated walls in 2D. When you move up to 3D, you have to take into account the surface normal (which way the 3D plane is facing) in your calculations.
The second complexity that we needed to account for and which pops up in either 2D or 3D collision detection is travel between frames. In other words, if your ball is travelling very fast, it may have completely travelled through your collision boundary in between frames and you wouldn't notice it if you are only doing a distance / overlap check as outlined above. In our case, the pucks had the ability of travelling very fast with a speed boost, so we needed a more robust solution. Therefore, instead of implementing a simple sphere plane intersection test, we needed to create a line of motion that represented where the ball ended on the previous frame and where it currently is after it's new velocity is added to it's position. That line then needs to first be tested to see if it crosses a WallTile. If it does cross, then we know an collision has occurred between frames. We then solve for the time (t) between frames the Sphere would have first made contact to know the exact point of impact and calculate the appropriate "bounce off" direction.
The final code for a puck (or moving sphere) and wallTile collision test looks like this:

bool GameEngine::CheckWallCollision(Puck^ puck){ bool isIntersect = false; bool wallCollision = false; for(unsigned int i = 0; i < m_environmentCollisionWalls.size(); i++) { WallTile^ wall = m_environmentCollisionWalls[i]; float radius = puck->Radius(); float signedRadius = puck->Radius(); float contactTime = 0.0f; XMVECTOR contactPlanePoint = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f); XMVECTOR contactPuckPosition = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f); bool intersectsPlane = false; // Determine the velocity of this tick by subtracting the previous position from the proposed current position. // in the previous update() cycle, puck->Position() = puck->OldPosition() + ( puck->velocity * timerDelta ). // Therefore, this calculated velocity for the current frame movement differs from the stored velocity // since the stored velocity is independent of each game tick's timerDelta. XMVECTOR puckVectorVelocity = puck->VectorPosition() - puck->OldVectorPosition(); float D = XMVectorGetX( XMVector3Dot( wall->VectorNormal(), wall->VectorPosition() ) ); // Determine the distance of the puck to the plane of the wall. float dist = XMVectorGetX( XMVector3Dot(wall->VectorNormal(), puck->OldVectorPosition() )) - D; signedRadius = dist > 0 ? radius : -radius; // if the distance of the puck to the plane is already less than the radius, the oldPosition() was intersecting already if ( fabs(dist) < radius ) { // The sphere is touching the plane. intersectsPlane = true; contactTime = 0.0f; contactPuckPosition = puck->OldVectorPosition(); contactPlanePoint = puck->OldVectorPosition() + wall->VectorNormal()*XMVectorSet(signedRadius,signedRadius,signedRadius,1.0f); } else { // See if the time it would take to cross the plane from the oldPosition() with the current velocity falls within this game tick. // puckVelocityNormal is the amount of force from the velocity exerted directly toward the plane. float puckVelocityNormal = XMVectorGetX(XMVector3Dot(wall->VectorNormal(), puckVectorVelocity )); // if the puckvVelocityNormal times the distance is less than zero, a plane intersection will occur if ( puckVelocityNormal * dist < 0.0f ) { // determine the contactTime, taking into account the shell of the sphere ( position() + radius ) // is what will make contact, not the position alone. contactTime = (signedRadius - dist) / puckVelocityNormal; // if the contact time is bewteen zero and one, the intersection has occured bewteen oldPosition() and position() if ( contactTime > 0.0f && contactTime < 1.0f ) { intersectsPlane = true; // this is the position of the puck when its shell makes contact on the plane contactPuckPosition = puck->OldVectorPosition() + XMVectorScale(puckVectorVelocity, contactTime); // this is the position on the plane where the shell touches. contactPlanePoint = contactPuckPosition - XMVectorScale(wall->VectorNormal(), signedRadius); } } } // If the puck has contacted the wall plane, determine if the point of contact falls within the wall boundary for true contact. if (intersectsPlane) { float Kr = 1.0f; // Kr is the coefficient of restitution. At 1.0, we have a totally elastic bounce with no dampening. At Kr = 0.0, the ball would stop at the wall. // Make sure the puck velocity and wall normal are facing each other float impact = XMVectorGetX ( XMVector3Dot ( wall->VectorNormal(), puck->VectorVelocity()) ); if (impact < 0.0f) { wallCollision = true; //// bounce the vector off the plane XMVECTOR VectorNormal = XMVector3Dot(wall->VectorNormal(), puck->VectorVelocity())*wall->VectorNormal(); XMVECTOR VectorTangent = puck->VectorVelocity() - VectorNormal; puck->Velocity(VectorTangent - (XMVectorScale(VectorNormal, Kr))); puck->Position(contactPuckPosition); int segment = (int)(puck->Position().z / GameConstants::WallSegmentDepth); segment = max(min(segment, GameConstants::NumWallSegments-1), 0); auto tiles = m_wallTiles[segment]; WallTile^ tile = tiles[i]; if(tile->GetPowerup() == Powerup::Split) SplitPucks(); break; } } } return wallCollision;}Drawing Maelstrom

To draw the game, we wanted to use some advanced techniques. We decided to go with a light pre-pass deferred rendering pipeline with normal mapping. That’s a lot of jargon but it isn’t all that complicated once you know what the jargon means, so let’s break it down.
When you draw something in 3D, there are three things that come together to determine the final color of each pixel on the screen: meshes, materials, and lights. A mesh is a collection of triangles that make up a game object (such as a wall tile in Maelstrom). On its own, a mesh is just a bunch of dots and lines. A material makes a mesh look like something. It could be as simple as a solid color but usually it’s a texture and sometimes it’s more (the wall tiles in Maelstrom use both a texture and a normal map to define their material properties). Lastly, lights transform materials by determining how bright they should appear and what sort of tint, if any, they should have. Without lights you would either have complete darkness or you would have flat lighting (where everything has a uniform brightness and adding a tint color would uniformly tint everything on the screen).
Forward Rendering vs. Deferred Rendering vs. Light Pre-Pass Rendering

The simplest approach to drawing 3D graphics is something called forward rendering. With forward rendering, drawing consists of rendering the mesh and calculating its material and all the lights that affect the material all at the same time. The more lights you add, the more complicated your shaders become since you have to determine whether each light affects the material and if so how much. (Ok, so there’s also multi-pass forward rendering, but that has its own problems – more passes mean longer render times and thus a lower frame rate – and we wanted to keep the descriptions simple).
In the last 5 years, many games started using a technique called deferred rendering. In classic deferred rendering, there are two rendering passes. The first pass renders the positions, normals, and material values of all the meshes in the scene to something called a G-Buffer (two or more render targets); nothing is actually drawn to the screen in this first pass. The second pass uses the data from the G-Buffer (which tells us everything we need to know about the geometry that appears at each screen pixel) and combines it with the lights to create the final image that you see. By doing this, we decouple geometry and lighting. This makes it possible to add more lights to the scene with a much smaller performance impact than in forward rendering since we don’t need to create a really complex pixel shader to handle all the lights (single-pass forward rendering) or draw the geometry over and over again for each light (multi-pass forward rendering).
There are drawbacks to classic deferred rendering though. Even a minimal G-Buffer takes up quite a bit of memory and the more different types of materials you want to support, the larger the G-Buffer will need to be. Wolfgang Engel, an XNA/DirectX MVP, came up with a variation on deferred rendering which he called Light Pre-Pass Rendering. This is a three pass technique. We once again use a G-Buffer, but in this case it is smaller than the classic deferred rendering G-Buffer and can even be squeezed down to a single render target which makes it viable for graphics hardware which does not support drawing to multiple render targets at the same time.
The G-Buffer is created in the first pass by rendering all the scene geometry. It only needs to store normals and the geometry’s world position. We stored the world position of the geometry at that screen position in one render target and its normal at that screen position in second render target for simplicity.
The next pass draws the lights to a light accumulation buffer. The buffer starts out entirely dark and each light that is rendered adds brightness (and tint, if any) to the light buffer. These lighting calculations take into account the normal and world position of the geometry that is at each screen position, drawing the values from the G-Buffer, such that each light only affects the pixels it is supposed to have an impact on. In Maelstrom we ended up only using point lights (spheres of light that fade out as you get further from the light’s position), but you can use any kind of light you can imagine (spot lights and directional lights are the two other common light types). Adding more lights has a very low impact on rendering time and this kind of lighting tends to be much easier for the designer to work with since there’s no need for him or her to understand HLSL or even any complicated C++ in order to add, remove, reposition, or otherwise change any lights.
The final pass draws the geometry a second time. This time, though, all the lighting calculations are done so all we do here is just render the meshes with their appropriate materials, adjust the color values and intensities from the material based on the light buffer value, and we’re done. Each rendering style (forward, deferred, and light pre-pass) has its own benefits and drawbacks, but in this case light pre-pass was a good solution and choosing it let us show how a state-of-the-art graphics technique works.
Normal Mapping

We also incorporated normal mapping. Normal mapping makes us of a special texture (a normal map) in addition to the regular texture that a material has. Normals are values used in lighting calculations to determine how much a particular light should affect a particular pixel. If you wanted to draw a brick wall, you would typically create two triangles that lined up to form a rectangle and you would apply a texture of a brick wall to them as their material. The end result of that doesn’t look very convincing though since unlike a real brick wall there are no grooves in the mortared area between each brick since our brick and mortar is just a flat texture applied to flat triangles. We could fix this by changing from two triangles to a fully modeled mesh with actual grooves, but that would add thousands of extra vertices which would lower the frame rate.
So instead we use a normal map, which fakes it. One of the reasons that the two triangles + a brick wall texture approach doesn’t look right is because the lighting doesn’t behave correctly when compared to a real brick wall (or to a fully modeled mesh of a real brick wall). The normals point straight out perpendicular from the face of the rectangle whereas if we had the fully modeled mesh with actual grooves, the surface normals would only point straight out on the bricks themselves and they would curve along the mortared areas such that the lighting calculations would end up giving us the right levels of light and dark depending on the location and direction of the light. That’s where a normal map comes in. The normal map (which you can generate using a plugin for Adobe Photoshop or GIMP or by modeling a real brick wall in 3DSMax, Maya, or Blender which you then “bake” a normal map from) allows us to get the same lighting effect as we would with a fully modeled mesh while still keeping the simple two triangle + a brick wall texture approach that gives us really good performance for our game. There are limits to the effectiveness of normal mapping (you can’t use it to fake anything too deep and it doesn’t hold up as well if the camera can get really close to the object) but in Maelstrom it allowed us to keep the walls as simple triangles (like the two triangles + a brick wall texture example above) while making it seem like there were geometric grooves in the wall. Here’s a before and after screenshot using normal mapping:

Post-Processing Effects

We also used several post-processing effects. The first was the bloom effect. Bloom is an effect that analyzes a rendered image, identifies parts that are above a certain brightness threshold, and makes those areas brighter and adds a peripheral glow to them as well, giving it a look and feel that is similar to a neon sign or to the light cycles in the movie Tron. Here’s the same shot as above with the addition of bloom:

We also made use of two different damage effects. Whenever the player took damage, we had a reddish tinge around the edge of the screen. This was simply a full screen overlay texture that is actually white but is tinted red by the shader. It is alpha-blended over the final rendered scene and fades out over the course of a couple of seconds. Rather than fading out linearly, we use a power curve which helps to sell the effect as being more complicated than it really is.
Lastly we added in some damage particles. The particles themselves were created using a geometry shader. The vertex shader took in a series of points in world space and passed these points along to the geometry shader. The geometry shader expanded these points into two triangles by generating the missing vertices and applying the world-view-projection transformation matrix to transform the positions from world coordinates to homogeneous coordinates so that they can then be rasterized correctly by D3D and the resulting pixels passed along to the pixel shader. Once again we used a simple texture with alpha blending to simulate much more complicated geometry than we were actually drawing. In this case we also made use of a texture atlas (an image made up of smaller images) which, in conjunction with the randomizer we used to generate the initial vertices for the particles, allowed us to have several different particle textures. Like with the power curve for the damage texture, the texture atlas allowed us to make the particles seem more complex than they really were. It also let us show off the use of a geometry shader, a feature that was added in DirectX 10 and requires DirectX 10 or higher hardware.
Audio

All audio was done using the XAudio2 API. Thankfully, we were able to get a huge head start by using some of the code from the sample project we started from. The audio engine sets up the very basics of XAudio2, and then wraps that with a simpler API for the rest of the application to call.
We don’t have many sound effects, so we on startup, we load all sounds effects and music cues into a std::map, keyed on a SoundCue enum. Sounds are loaded using the Media Foundation classes, and the resulting byte data of the sound (and some format information) are stored in our SoundEffect class.

void AudioEngine::Initialize(){ m_audio = ref new Audio(); m_audio->CreateDeviceIndependentResources(); m_mediaReader = ref new MediaReader(); // Impacts m_soundMap[SoundCue::BallLaunch] = LoadSound("SoundsImpactsBallLaunch.wav"); m_soundMap[SoundCue::Buzz] = LoadSound("SoundsImpactsBuzz.wav"); m_soundMap[SoundCue::Impact1] = LoadSound("SoundsImpactsImpact1.wav"); m_soundMap[SoundCue::Impact2] = LoadSound("SoundsImpactsImpact2.wav");...}SoundEffect^ AudioEngine::LoadSound(String^ filename){ Array^ soundData = m_mediaReader->LoadMedia(filename); auto soundEffect = ref new SoundEffect(); soundEffect->Initialize(m_audio->SoundEffectEngine(), m_mediaReader->GetOutputWaveFormatEx(), soundData); return soundEffect;}When the game needs to play a sound, it simply calls the PlaySound method, passing in the cue to play, and the volume to play it at. PlaySound keys into the sound map, getting the associated SoundEffect, and plays it.

void AudioEngine::PlaySound(SoundCue cue, float volume, bool loop){ m_soundMap[cue]->Play(volume, loop);}MJPEG Cameras

To achieve the effect of seeing the opponent in stereoscopic 3D, we strapped two Axis M1014 network cameras side-by-side. Using Brian’s MJPEG Decoder library, with a special port to Windows Runtime (available soon), individual JPEG frames were pulled off each camera, and then applied to a texture at the back of the arena. The image from the left camera is drawn when DirectX renders the player’s left eye, and the frame from the right camera is drawn when DirectX renders the right eye. This is a cheap and simple way to pull off live stereoscopic 3D.

void MjpegCamera::Update(GameEngine^ engine){ if(m_decoderLeft != nullptr) UpdateTexture(m_decoderLeft->CurrentFrame, &textureLeft); if(m_decoderRight != nullptr) UpdateTexture(m_decoderRight->CurrentFrame, &textureRight); Face::Update(engine);}void MjpegCamera::Render(_In_ ID3D11DeviceContext *context, _In_ ID3D11Buffer *primitiveConstantBuffer, _In_ bool isFirstPass, int eye){ if(eye == 1 && textureRight != nullptr) m_material->SetTexture(textureRight.Get()); else if(textureLeft != nullptr) m_material->SetTexture(textureLeft.Get()); GameObject::Render(context, primitiveConstantBuffer, isFirstPass);}With the distance between the cameras being about the distance of human eyes (called the intra-axial distance), the effect works pretty well!

Tablet/Controller

The Tablet controller is the touch screen that lets the player control their 3D paddle in the Game Console app. For this part of the game system, there wasn't a reason to dive deep into DirectX and C++ since the controller is neither stereoscopic or visually intense, so we kept things simple with C#.
Since the controller would also serve as our attract screen in the podium to entice potential players, we wanted to have the wait screen do something eye-catching. However, if you are moving from C# in WPF to C# and XAML in WinRT and are used to taking advantage of some of the more common "memory hoggish UX hacks" from WPF, you'll quickly find them absent in WinRT! For example, we no longer have OpacityMask, non-rectangular clipping paths or the ability to render a UIElement to a Bitmap. Our bag of UX tricks may be in need of an overhaul. However, what we do get in C# / XAML for WinRT is Z rotation, which is something we've had in Silverlight but I personally have been begging for in WPF for a long time.
Therefore, the opening animation in the controller is a procedurally generated effect that rotates PNG "blades" in 3D space, creating a very compelling effect. Here is how it works. The Blade user control is a simple canvas that displays one of a few possible blade images. The Canvas has a RenderTransform to control the scale and rotation and a PlaneProjection which allows us to rotate the blade graphic in X, Y and Z space.

Each Blade is added dynamically to the Controller when the Tablet application first loads, stored in a List to have it's Update() method called during the CompositionTarget.Rendering() loop.

protected override void OnNavigatedTo(NavigationEventArgs e){ canvas_blades.Children.Clear(); _blades.Clear(); for (int i = 0; i < NumBlades; i++) { Blade b = new Blade { X = 950.0, Y = 530.0 }; int id = _rand.Next(0, 5); b.SetBlade(id); b.Speed = .1 + id * .1; SeedBlade(b); _blades.Add(b); canvas_blades.Children.Add(b); }}void CompositionTarget_Rendering(object sender, object e){ if(_inGame) { paddle.Update(); } else if(_isClosing) { foreach (Blade b in _blades) b.UpdateExit(); } else { foreach (Blade b in _blades) b.Update(); }}Since each Blade has been assigned an individual speed and angle of rotation along all three axis, they have a very straightforward Update function. The reason we keep the rotation values between -180 and 180 during the spinning loop is to make it easier to spin them out zero when we need them to eventually leave the screen.

public void Update(){ _rotX += Speed; _rotZ += Speed; _rotY += Speed; if (_rotX > 180) _rotX -= 360.0; if (_rotX < -180) _rotX += 360.0; if (_rotY > 180) _rotY -= 360.0; if (_rotY < -180) _rotY += 360.0; if (_rotZ > 180) _rotZ -= 360.0; if (_rotZ < -180) _rotZ += 360.0; projection.RotationX = _rotX; projection.RotationY = _rotY; projection.RotationZ = _rotZ;}public void UpdateExit(){ _rotX *= .98; _rotZ *= .98; _rotY += (90.0 - _rotY) * .1; projection.RotationX = _rotX; projection.RotationY = _rotY; projection.RotationZ = _rotZ;}Network

To continue the experiment of blending C# and C++ code, the network communication layer was written in C# as a Windows Runtime component. Two classes are key to the system: SocketClient and SocketListener. Player one’s game console starts a SocketListener to listen for incoming connections from each game controller, as well as player two’s game console. Each of those use a SocketClient object to make the connection.
In either case, once the connection is made, the client and the listener sit and wait for data to be transmitted. Data must be sent as an object which implements our IGamePacket interface. This contains two important methods: FromDataReaderAsync and WritePacket. These methods serialize and deserialze the byte data to/from an IGameState packet of whatever type is specified in the PacketType property.

namespace Coding4Fun.Maelstrom.Communication{ public enum PacketType { UserInputPacket = 0, GameStatePacket } public interface IGamePacket { PacketType Type { get; } IAsyncAction FromDataReaderAsync(DataReader reader); void WritePacket(DataWriter writer); }}The controllers write UserInputPackets to the game console, consisting of X,Y positions of the paddle, as well as whether the player has tapped the screen to begin.

public sealed class UserInputPacket : IGamePacket{ public PacketType Type { get { return PacketType.UserInputPacket; } } public UserInputCommand Command { get; set; } public Point3 Position { get; set; }}Player one’s game console writes a GameStatePacket to player' two’s game console, which consists of the positions of each paddle, each ball, the score, and which tiles are lit for the ball splitter power up. Player two’s Update and Render methods use this data to draw the screen appropriately.
Hardware

The hardware layer of this project is responsible for two big parts. One is a rumble effect that fires every time the player is hit, and the other is a lighting effect that changes depending on the game state.
As all good programmers do, we reused code from another project. We leveraged the proven web server from Project Detroit for our Netduino, but with a few changes. Here, we had static class “modules” which knew how to talk to the physical hardware, and “controllers” which handled items like a player scoring, game state animations, and taking damage. Because the modules are static classes, we can have them referenced in multiple classes without issue.
NETMF Web Server

When a request comes in, we perform the requested operation, and then return a new line character to verify we got the request. If you don’t return any data, some clients will actually fire a second request which then can cause some odd behaviors. The flow is as follows:

Parse the URLGet the target controllerExecute the appropriate action

private static void WebServerRequestReceived(Request request){ var start = DateTime.Now; Logger.WriteLine("Start: " + request.Url + " at " + DateTime.Now); try { var data = UrlHelper.ParseUrl(request.Url); var targetController = GetController(data); if (targetController != null) { targetController.ExecuteAction(data); } } catch (Exception ex0) { Logger.WriteLine(ex0.ToString()); } request.SendResponse(NewLine); Logger.WriteLine("End: " + request.Url + " at " + DateTime.Now + " took: " + (DateTime.Now - start).Milliseconds);}public static IController GetController(UrlData data){ if (data.IsDamage) return Damage; if (data.IsScore) return Score; if (data.IsGameState) return GameState; // can assume invalid return null;}Making It Shake

We used a Sparkfun MP3 trigger board, a subwoofer amplifier, and bass rumble plates to create this effect. The MP3 board requires power, and two jumpers to cause the MP3 to play. It has an audio jack that then gets plugged into the amplifier which powers the rumble plates.
From here, we just needed to wire a ground to the MP3 player’s ground pin, and the target pin on the MP3 player to a digital IO pin on the Netduino. In the code, we declare it as an OutputPort and give it an initial state of true. When we get a request, we toggle the pin on a separate thread.

private static readonly OutputPort StopMusic = new OutputPort(Pins.GPIO_PIN_D0, true);private static readonly OutputPort Track1 = new OutputPort(Pins.GPIO_PIN_D1, true);// .. more pinspublic static void PlayTrack(int track){ switch (track) { case 1: TogglePin(Track1); break; // ... more cases default: // stop all, invalid choice TogglePin(StopMusic); break; }}public static void Stop(){ TogglePin(StopMusic);}private static void TogglePin(OutputPort port){ var t = new Thread(() => { port.Write(false); Thread.Sleep(50); port.Write(true); }); t.Start();}Lighting Up the Room

For lighting, we used some RGB Lighting strips. The strips can change a single color and use a PWM signal to do this. This is different than the lighting we used in Project Detroit which allowed us to individually control each LED and used SPI to communicate. We purchased an RGB amplifier to allow a PWM signal to power a 12 volt strip. We purchased ours from US LED Supply and the exact product was RGB Amplifier 4A/Ch for interfacing with a Micro-Controller (PWM/TTL Input).
We alter the Duty Cycle to shift the brightness of the LEDs and do this on a separate thread. Below is a stripped down version of the lighting hardware class.

public static class RgbStripLighting{ private static readonly PWM RedPwm = new PWM(Pins.GPIO_PIN_D5); private static readonly PWM GreenPwm = new PWM(Pins.GPIO_PIN_D6); private static readonly PWM BluePwm = new PWM(Pins.GPIO_PIN_D9); private const int ThreadSleep = 50; private const int MaxValue = 100; const int PulsePurpleIncrement = 2; const int PulsePurpleThreadSleep = 100; private static Thread _animationThread; private static bool _killThread; #region game state animations public static void PlayGameIdle() { AbortAnimationThread(); _animationThread = new Thread(PulsePurple); _animationThread.Start(); } #endregion private static void PulsePurple() { while (!_killThread) { for (var i = 0; i = 0; i -= PulsePurpleIncrement) { SetPwmRgb(i, 0, i); } Thread.Sleep(PulsePurpleThreadSleep); } } private static void AbortAnimationThread() { _killThread = true; try { if(_animationThread != null) _animationThread.Abort(); } catch (Exception ex0) { Debug.Print(ex0.ToString()); Debug.Print("Thread still alive: "); Debug.Print("Killed Thread"); } _killThread = false; } private static void SetPwmRgb(int red, int green, int blue) { // typically, 0 == off and 100 is on // things flipped however for the lighting so building this in. red = MaxValue - red; green = MaxValue - green; blue = MaxValue - blue; red = CheckBound(red, MaxValue); green = CheckBound(green, MaxValue); blue = CheckBound(blue, MaxValue); RedPwm.SetDutyCycle((uint) red); GreenPwm.SetDutyCycle((uint) green); BluePwm.SetDutyCycle((uint) blue); Thread.Sleep(ThreadSleep); } public static int CheckBound(int value, int max) { return CheckBound(value, 0, max); } public static int CheckBound(int value, int min, int max) { if (value = max) value = max; return value; }}Conclusion

We built this experience over the course of around 4 to 5 weeks. It was our first DirectX application in a very long time, and our first C++ application in a very long time. However, we were able to pick up the new platform and language changes fairly easily and create a simple, yet fun game in that time period.
Attributions

Music track - "FatLoad- The Bullet(no master)" by FreaK NeoSSound effects + music edition - David WallimannDirectX shaders - Michael McLaughlin

More...




I've been getting the following blue screen stop error in=20
Windows XP, but only while burning a DVD, or shortly=20
after burning a DVD:

IRQL_NOT_LESS_OR_EQUAL STOP: 0x0000000A (0x82844FF0,=20
0x00000002, 0x00000001, 0x8050D819)

PAGE_FAULT_IN_NONPAGED_AREA STOP: 0x00000050 (0xFDEFFDD7,=20
0x00000001, 0x80515FF4, 0x00000000)

and a few other variations.

This has been a problem with my last DVD Burner, as well=20
as my current one, so I know it's not a matter of=20
defective hardware. The drive is independantly the=20
master on the secondary chain, and I used the cable that=20
came with the drive. I've tested my RAM, and no errors=20
have been found. I reinstalled Windows XP, still to no=20
avail. I don't recall my DVD drive ever having this=20
error under windows 98 SE, but since that OS crashes so=20
frequently anyway, maybe I just never noticed it. My=20
motherboard, a FIC AZ11EA (VIA KT133A + 686B Chipset) has=20
been updated with the most recent Award BIOS available on=20
the fic website. I have an AMD Duron 1.00 GHz processor,=20
which for some reason always comes up under diagnostics=20
as a 1.33 GHz. I have 512 Megs of ram and a 160 GB hard=20
drive with 35 Gigs free.

I'm absolutely stumped. Can anyone suggest any solutions?

Here's what Nero Info Tool has gathered about my system:

Nero InfoTool 2.21

Drive Information
------------------
Drive : VOM-12E48X =20
Type : DVD=B1R/RW Recorder
Firmware Version : 1008
Buffer Size : 2 MB
Date : ?
Serial Number
Vendor Specific : =01

Drive Letter : D:
Location : 1:0
Mechanism : Tray
Read Speed : 6.0 X
Write Speed : 1.0 X

Read CD Text : Yes
Return C2 Pointers : Yes
Read CD-R : Yes
Read CD-RW : Yes
Read DVD-ROM : Yes
Read DVD-RAM : No
Read DVD-R : Yes
Read DVD-RW : Yes
Read DVD+R : Yes
Read DVD+RW : Yes
Read DVD+R DL : No
Read Digital Audio : Yes
Read CD+G : No
Read VideoCD : Yes

Write CD-R : Yes
Write CD-RW : Yes
Write DVD-R : Yes
Write DVD-RW : Yes
Write DVD+R : Yes
Write DVD+RW : Yes
Write DVD+R DL : No
Write DVD-RAM : No
Buffer Underrun=20
Protection =20
=20
=20
=20
: Yes
Mount Rainier : No
Modes : Packet, TAO, DAO, SAO, RAW=20
SAO, RAW DAO, RAW SAO 16, RAW SAO 96, RAW DAO 16, RAW DAO=20
96

Region Protection Control : RPC II
Region : None
Changes User : 5
Changes Vendor : 4

Disc Information (D:)
-------------------
Type : DVD+RW
Capacity : 510:01.29 (1052 MB)
Tracks : 1
Sessions : 1

File System : ISO9660, Joliet
Title : Test
Date : 25 July 2004
Publisher : n/a
Application : Nero Burning ROM

Interface Information
---------------------
Adapter 1
---------
Description : Primary IDE Channel

Driver
Description : System32DRIVERSatapi.sys
Company : Microsoft Corporation
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Description : IDE/ATAPI Port Driver

Attached Devices
Description : Master: ST3160023A
Type : Disk Drive
DMA : On

Adapter 2
---------
Description : Secondary IDE Channel

Driver
Description : System32DRIVERSatapi.sys
Company : Microsoft Corporation
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Description : IDE/ATAPI Port Driver

Attached Devices
Description : Master: VOM-12E48X
Type : CD-Rom Drive
DMA : On
Autorun : On

Software Information
--------------------
Operating System : Windows XP Home Edition (5.01.2600=20
Service Pack 1)
DirectX : DirectX 9.0b

Description : Nero Burning ROM
Version : 6, 3, 1, 17
Company : Ahead Software AG
Version Check : Ok

Description : Nero StartSmart
Version : 1, 0, 1, 22
Company : Ahead Software AG

Description : NeroVision Express
Version : 2,1,2,16
Company : Ahead Software AG

Description : Nero ShowTime
Version : 1, 5, 0, 31
Company : Ahead software AG

Description : Nero Recode 2
Version : 2, 0, 0, 18
Company : Ahead Software AG

Description : Cover Designer
Version : 2, 3, 0, 8
Company : Ahead Software AG

Description : Nero BackItUp Application
Version : 1, 2, 0, 18
Company : Ahead Software AG

Description : PowerDVD
Version : 3.0.0904=20
Company : CyberLink Corp.

Description : Sonic MyDVD
Version : 4.0
Company : Sonic Solutions

Hardware Information
--------------------
CPU : AMD Duron 1333 MHz
Bus Speed : 133 MHz
Motherboard : First AZ11EA/AZ11E
System : System Product Name
BIOS : Award 6.00 PG
Memory : 512 MB (60ns)
Sound : SB Live! Audio [B800]
Video : ALL-IN-WONDER RADEON 7500

Driver Information
------------------
Driver : Abiosdsk
Description : n/a
Version : n/a
Company : n/a

Driver : abp480n5
Description : n/a
Version : n/a
Company : n/a

Driver : ACPI
Description : ACPI Driver for NT
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : ACPIEC
Description : ACPI Embedded Controller Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : adpu160m
Description : n/a
Version : n/a
Company : n/a

Driver : aec
Description : Microsoft Acoustic Echo Canceller
Version : 5.1.2601.1095 built by: xpsp1
Company : Microsoft Corporation

Driver : Aha154x
Description : n/a
Version : n/a
Company : n/a

Driver : aic78u2
Description : n/a
Version : n/a
Company : n/a

Driver : aic78xx
Description : n/a
Version : n/a
Company : n/a

Driver : AliIde
Description : n/a
Version : n/a
Company : n/a

Driver : AmdK7
Description : Processor Device Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : amsint
Description : n/a
Version : n/a
Company : n/a

Driver : Arp1394
Description : IP/1394 Arp Client
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : asc
Description : n/a
Version : n/a
Company : n/a

Driver : asc3350p
Description : n/a
Version : n/a
Company : n/a

Driver : asc3550
Description : n/a
Version : n/a
Company : n/a

Driver : AsyncMac
Description : MS Remote Access serial network=20
driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : atapi
Description : IDE/ATAPI Port Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Atdisk
Description : n/a
Version : n/a
Company : n/a

Driver : ATI Remote Wonder II
Description : n/a
Version : n/a
Company : n/a

Driver : ati2mtag
Description : ATI Radeon Miniport Driver
Version : 6.14.10.6430
Company : ATI Technologies Inc.

Driver : atinrvxx
Description : ATI WDM Rage Theater MiniDriver RT2
Version : 6.14.10.6227
Company : ATI Technologies Inc.

Driver : ATITUNEP
Description : n/a
Version : n/a
Company : n/a

Driver : ativraxx
Description : n/a
Version : n/a
Company : n/a

Driver : ATIXSAudio
Description : n/a
Version : n/a
Company : n/a

Driver : Atmarpc
Description : IP/ATM Arp Client
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : audstub
Description : AudStub Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : AvgCore
Description : n/a
Version : n/a
Company : n/a

Driver : AvgFsh
Description : n/a
Version : n/a
Company : n/a

Driver : Bridge
Description : MAC Bridge Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : BridgeMP
Description : n/a
Version : n/a
Company : n/a

Driver : cbidf2k
Description : CardBus/PCMCIA IDE Miniport Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : CCDECODE
Description : WDM Closed Caption VBI Codec
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : cd20xrnt
Description : n/a
Version : n/a
Company : n/a

Driver : Cdaudio
Description : CD-ROM Audio Filter Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : Cdfs
Description : CD-ROM File System Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Cdrom
Description : SCSI CD-ROM Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Changer
Description : n/a
Version : n/a
Company : n/a

Driver : CINEMSUP
Description : SW CineMaster Support
Version : 1.0.01.0010
Company : Ravisent Technologies, Inc.

Driver : CmdIde
Description : n/a
Version : n/a
Company : n/a

Driver : Cpqarray
Description : n/a
Version : n/a
Company : n/a

Driver : ctac32k
Description : Creative AC3 SW Decoder Device=20
Driver (WDM)
Version : 5.12.01.0245-1.31.0050
Company : Creative Technology Ltd

Driver : ctaud2k
Description : Creative WDM Audio Device Driver
Version : 5.12.01.0252-1.31.0120
Company : Creative Technology Ltd

Driver : ctljystk
Description : Creative Joyport Enabler
Version : 5.1.2501.0 built by: WinDDK
Company : Creative Technology Ltd.

Driver : ctprxy2k
Description : Creative Proxy Device Driver (WDM)
Version : 5.12.01.0244-1.31.0040
Company : Creative Technology Ltd

Driver : ctsfm2k
Description : SoundFont(R) Manager (WDM)
Version : 5.12.01.0140-0.75.1490 (beta-release)
Company : Creative Technology Ltd

Driver : dac960nt
Description : n/a
Version : n/a
Company : n/a

Driver : Disk
Description : PnP Disk Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : dmboot
Description : NT Disk Manager Startup Driver
Version : 2600.0.503.0
Company : Microsoft Corp., Veritas Software

Driver : dmio
Description : NT Disk Manager I/O Driver
Version : 2600.0.503.0
Company : Microsoft Corp., Veritas Software

Driver : dmload
Description : NT Disk Manager Startup Driver
Version : 2600.0.503.0
Company : Microsoft Corp., Veritas Software.

Driver : DMusic
Description : Microsoft Kernel DLS Synthesizer
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : dpti2o
Description : n/a
Version : n/a
Company : n/a

Driver : drmkaud
Description : Microsoft Kernel DRM Audio=20
Descrambler Filter
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : emupia
Description : n/a
Version : n/a
Company : n/a

Driver : Fastfat
Description : Fast FAT File System Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Fdc
Description : Floppy Disk Controller Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : Flpydisk
Description : Floppy Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Ftdisk
Description : FT Disk Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : gameenum
Description : Game Port Enumerator
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : GEARAspiWDM
Description : CDRom Class Filter Driver
Version : 2.034
Company : GEAR Software Inc.

Driver : gel90xne
Description : n/a
Version : n/a
Company : n/a

Driver : Gpc
Description : n/a
Version : n/a
Company : n/a

Driver : ha10kx2k
Description : Creative EMU10KX HAL (WDM)
Version : 5.12.01.0250-1.31.0090
Company : Creative Technology Ltd

Driver : hidusb
Description : USB Miniport Driver for Input Devices
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : hpn
Description : n/a
Version : n/a
Company : n/a

Driver : hpusbfd
Description : USB Scanner Filter Driver.
Version : 1.00
Company : Hewlett-Packard Co.

Driver : i2omgmt
Description : n/a
Version : n/a
Company : n/a

Driver : i2omp
Description : n/a
Version : n/a
Company : n/a

Driver : i8042prt
Description : i8042 Port Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Imapi
Description : IMAPI Kernel Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : ini910u
Description : n/a
Version : n/a
Company : n/a

Driver : IntelIde
Description : n/a
Version : n/a
Company : n/a

Driver : io.sys
Description : n/a
Version : n/a
Company : n/a

Driver : IpFilterDriver
Description : n/a
Version : n/a
Company : n/a

Driver : IpInIp
Description : IP in IP Encapsulation Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : IpNat
Description : IP Network Address Translator
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : IPSec
Description : IPSec Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : IRENUM
Description : Infra-Red Bus Enumerator
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : isapnp
Description : PNP ISA Bus Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : kmixer
Description : Kernel Mode Audio Mixer
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : lbrtfdc
Description : n/a
Version : n/a
Company : n/a

Driver : Modem
Description : Modem Device Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : mouhid
Description : HID Mouse Filter Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : mraid35x
Description : n/a
Version : n/a
Company : n/a

Driver : MRxDAV
Description : Windows NT WebDav Minirdr
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : MSKSSRV
Description : MS KS Server
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : MSPCLOCK
Description : MS Proxy Clock
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : MSPQM
Description : MS Proxy Quality Manager
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : MSTEE
Description : WDM Tee/Communication Transform=20
Filter=20
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : MVDCODEC
Description : n/a
Version : n/a
Company : n/a

Driver : NABTSFEC
Description : WDM NABTS/FEC VBI Codec
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : NdisIP
Description : Microsoft IP Driver
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : NdisTapi
Description : NDIS 3.0 connection wrapper driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : Ndisuio
Description : NDIS User mode I/O Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : NdisWan
Description : MS PPP Framing Driver (Strong=20
Encryption)
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : NIC1394
Description : IEEE1394 Ndis Miniport and Call=20
Manager
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : NPDriver
Description : Norton Protection Driver
Version : 16.00.0.22
Company : Symantec Corporation

Driver : Npfs
Description : NPFS Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : Ntfs
Description : NT File System Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : NwlnkFlt
Description : NWLINK2 Traffic Filter Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : NwlnkFwd
Description : NWLINK2 Forwarder Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : ohci1394
Description : 1394 OpenHCI Port Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : ossrv
Description : n/a
Version : n/a
Company : n/a

Driver : Parport
Description : Parallel Port Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : PartMgr
Description : Partition Manager
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : ParVdm
Description : VDM Parallel Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : PCDCODEC
Description : n/a
Version : n/a
Company : n/a

Driver : PCI
Description : NT Plug and Play PCI Enumerator
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : PCIDump
Description : n/a
Version : n/a
Company : n/a

Driver : PCIIde
Description : n/a
Version : n/a
Company : n/a

Driver : Pcmcia
Description : PCMCIA Bus Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : PDCOMP
Description : n/a
Version : n/a
Company : n/a

Driver : PDFRAME
Description : n/a
Version : n/a
Company : n/a

Driver : PDRELI
Description : n/a
Version : n/a
Company : n/a

Driver : PDRFRAME
Description : n/a
Version : n/a
Company : n/a

Driver : perc2
Description : n/a
Version : n/a
Company : n/a

Driver : perc2hib
Description : n/a
Version : n/a
Company : n/a

Driver : pfc
Description : Padus(R) ASPI Shell
Version : 2, 5, 0, 201
Company : Padus, Inc.

Driver : PfModNT
Description : n/a
Version : n/a
Company : n/a

Driver : PptpMiniport
Description : n/a
Version : n/a
Company : n/a

Driver : PSched
Description : MS QoS Packet Scheduler
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Ptilink
Description : Parallel Technologies DirectParallel=20
IO Library
Version : 1.10 (XPClient.010817-1148)
Company : Parallel Technologies, Inc.

Driver : ql1080
Description : n/a
Version : n/a
Company : n/a

Driver : Ql10wnt
Description : n/a
Version : n/a
Company : n/a

Driver : ql12160
Description : n/a
Version : n/a
Company : n/a

Driver : ql1240
Description : n/a
Version : n/a
Company : n/a

Driver : ql1280
Description : n/a
Version : n/a
Company : n/a

Driver : Rasl2tp
Description : RAS L2TP mini-port/call-manager=20
driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : RasPppoe
Description : RAS PPPoE mini-port/call-manager=20
driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : Raspti
Description : PTI DirectParallel(R) mini-port/call-
manager driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : Rdbss
Description : Redirected Drive Buffering SubSystem=20
Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : RDPCDD
Description : RDP Miniport
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : RDPWD
Description : RDP Terminal Stack Driver (US/Canada=20
Only, Not for Export)
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : redbook
Description : Redbook Audio Filter Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : sbp2port
Description : SBP-2 Protocol Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Secdrv
Description : n/a
Version : n/a
Company : n/a

Driver : serenum
Description : Serial Port Enumerator
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : Serial
Description : Serial Device Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Sfloppy
Description : SCSI Floppy Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Simbad
Description : n/a
Version : n/a
Company : n/a

Driver : SLIP
Description : Microsoft Slip Deframing Filter=20
Minidriver
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : sonydcam
Description : 1394 Desktop Camera Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Sparrow
Description : n/a
Version : n/a
Company : n/a

Driver : splitter
Description : Microsoft Kernel Audio Splitter
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : sr
Description : System Restore Filesystem Filter=20
Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Srv
Description : Server driver
Version : 5.1.2600.1193 (xpsp2.030327-2018)
Company : Microsoft Corporation

Driver : streamip
Description : Microsoft IP Driver
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : swenum
Description : Plug and Play Software Device=20
Enumerator
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : swmidi
Description : Microsoft GS Wavetable Synthesizer
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : symc810
Description : n/a
Version : n/a
Company : n/a

Driver : symc8xx
Description : n/a
Version : n/a
Company : n/a

Driver : SymEvent
Description : Symantec Event Library
Version : 11.3.0.17
Company : Symantec Corporation

Driver : sym_hi
Description : n/a
Version : n/a
Company : n/a

Driver : sym_u3
Description : n/a
Version : n/a
Company : n/a

Driver : sysaudio
Description : System Audio WDM Filter
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : Tcpip
Description : TCP/IP Protocol Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : TDPIPE
Description : Named Pipe Transport Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : TDTCP
Description : TCP Transport Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : Teefer
Description : Teefer Driver
Version : 1.60.1101
Company : Sygate Technologies, Inc.

Driver : TermDD
Description : Terminal Server Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : TosIde
Description : n/a
Version : n/a
Company : n/a

Driver : Udfs
Description : UDF File System Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : ultra
Description : n/a
Version : n/a
Company : n/a

Driver : Update
Description : Update Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : USBFVNETR
Description : n/a
Version : n/a
Company : n/a

Driver : usbhub
Description : Default Hub Driver for USB
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : usbscan
Description : USB Scanner Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : USBSTOR
Description : USB Mass Storage Class Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : usbuhci
Description : UHCI USB Miniport Driver
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : VgaSave
Description : n/a
Version : n/a
Company : n/a

Driver : viaagp
Description : VIA NT AGP Filter
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : viaagp1
Description : VIA NT AGP Filter
Version : 5.1.0.3442 built by: VIA
Company : VIA Technologies, Inc.

Driver : ViaIde
Description : Generic PCI IDE Bus Driver
Version : 1.00.01.00
Company : Microsoft Corporation

Driver : VIAudio
Description : n/a
Version : n/a
Company : n/a

Driver : VolSnap
Description : Volume Shadow Copy Driver
Version : 5.1.2600.0 (XPClient.010817-1148)
Company : Microsoft Corporation

Driver : Wanarp
Description : MS Remote Access and Routing ARP=20
Driver
Version : 5.1.2600.0 (xpclient.010817-1148)
Company : Microsoft Corporation

Driver : WDICA
Description : n/a
Version : n/a
Company : n/a

Driver : wdmaud
Description : MMSYSTEM Wave/Midi API mapper
Version : 5.1.2600.1106 (xpsp1.020828-1920)
Company : Microsoft Corporation

Driver : wg3n
Description : wgxn
Version : 1.2.1222.0
Company : Sygate Technologies, Inc.

Driver : wpsdrvnt
Description : wpsdrvnt
Version : 1, 0, 0, 17
Company : Sygate Technologies, Inc.

Driver : WSTCODEC
Description : WDM WST Codec Driver
Version : 5.3.0000000.900 built by: DIRECTX
Company : Microsoft Corporation

Driver : X10UIF
Description : X10 USB Control Interface
Version : 2.0.0.36
Company : X10 Wireless Technology, Inc.

Driver : zntport
Description : n/a
Version : n/a
Company : n/a

Driver : msvcrt.dll
Version : 7.0.2600.1106 (xpsp1.020828-1920)

Driver : msvcirt.dll
Version : 7.0.2600.0 (xpclient.010817-1148)

Driver : mfc42.dll
Version : 6.00.8665.0

Driver : msvcp60.dll
Version : 6.00.8972.0

Driver : msvcr70.dll
Version : 7.00.9466.0

Driver : ole32.dll
Version : 5.1.2600.1362 (xpsp2.040109-1800)

Driver : olepro32.dll
Version : 5.0.5014

Driver : oledlg.dll
Version : 1.0 (XPClient.010817-1148)

Driver : advapi32.dll
Version : 5.1.2600.1106 (xpsp1.020828-1920)

Driver : comctl32.dll
Version : 5.82 (xpsp1.020828-1920)

Driver : setupapi.dll
Version : 5.1.2600.1106 (xpsp1.020828-1920)

Lower Filters
-------------
Driver : Pfc
Description : Padus(R) ASPI Shell
Version : 2, 5, 0, 201
Company : Padus, Inc.

Upper Filters
-------------
Driver : GEARAspiWDM
Description : CDRom Class Filter Driver
Version : 2.034
Company : GEAR Software Inc.

Video Codecs
------------
Cinepak Codec by Radius : 1.10.0.6
Intel 4|2|0 Video V2.50 : 4.4.3400
Intel Indeo(R) Video R3.2
Intel Indeo(R) Video R3.2
Intel IYUV codec : 5.1.2600.0=20
(XPClient.010817-1148)
Microsoft RLE :=20
5.1.2600.1106 (xpsp1.020828-1920)
Microsoft Video 1 : 5.1.2600.0=20
(xpclient.010817-1148)
Microsoft YUV :=20
5.3.0000000.900 built by: DIRECTX
Microsoft YUV :=20
5.3.0000000.900 built by: DIRECTX
Microsoft H.263 Video Codec : 4.4.3400
Microsoft H.261 Video Codec : 4.4.3400
ATI YUV12 Format Codec
Indeo=AE video 5.11 :=20
R.5.11.15.2.55
Intel Indeo=AE Video Raw R1.2
ATI YUV12 Format Codec
XviD MPEG-4 Codec : n/a
DivX=AE 5.1.1 Codec : 5.1.1.1031

Audio Codecs
------------
Microsoft IMA ADPCM CODEC : 4.00.0.0
Microsoft ADPCM CODEC : 4.00.0.0
Microsoft CCITT G.711 A-Law and u-Law CODEC : 4.00.0.0
Microsoft GSM 6.10 Audio CODEC : 4.00.0.0
DSP Group TrueSpeech(TM) Software CODEC : 1.00.0.0
Microsoft G.723.1 CODEC : 1.02.0.1
Windows Media Audio : 4.02.0.0
Sipro Lab Telecom ACELP.net audio codec : 3.02.0.0
Fraunhofer IIS MPEG Layer-3 Codec=20
(advanced) =20
=20
=20
=20
: 1.09.1.49
Creative MP3 CODEC : 1.00.0.0
Indeo=AE audio software : 2.05.0.50
Ulead DV Audio CODEC : 1.00.0.0
Microsoft PCM Converter : 5.00.0.0

ASPI Information
----------------
System ASPI : ASPI is not installed

Nero ASPI : ASPI is installed and working properly

WNASPI32.DLL : 2.0.1.59 160016 bytes December 16,=20
2003

Installed OS Patches
--------------------
(Q810090) USB=20
Update =20
=20
: No
(Q329112) Multi-Border DVD with More Than 4 GB of Data=20
Not Readable Past First=20
Border =20
: Yes
(Q812415) Problems with Multiple ATA=20
devices =20
: No
(Q322359) Intelide.sys Is Not Used on Computers with ICH4=20
or=20
ICH5 =20
: No
(Q320174) IMAPI Update - CDs recorded have missing files=20
or=20
errors =20
: Yes
(Q311542) Devices May not power up properly when resuming=20
from=20
standby =20
: Yes
(Q327086) Data Added to Removable Media During=20
Hibernation May Be Lost When You Resume Windows=20
XP : =20
Yes
(Q308374) Ricoh 1394 Controller May Not Work with Windows=20
XP =20
: Yes
(Q314634) Windows XP Does Not Detect Your New USB=20
Device =20
: Yes
(Q822603) USB 1.1 and USB 2.0=20
update =20
=20
: No
(Q323507) Your IEEE 1394 or USB CD-ROM or DVD-ROM Drive=20
May Not Be Recognized in Windows=20
XP =20
: No
(Q815834) 'Code 28' Error Message and a Yellow=20
Exclamation Mark Next to a USB Device in Device Manager=20
After Your Computer Resumes from=20
Hibernation =20
=20
=20
=20
: No
(Q316575) Problems When You Swap a CD-ROM During=20
Hibernation in Windows=20
XP =20
: No
(Q811789) Surprise Removal of 1394 Device Can Cause=20
Bluescreen=20
Error =20
: No
(Q323322) Cannot Use Sony VAIO PCG-C1MRX Internal Camera=20
with Windows Messenger After You Apply=20
Q316397 : No
(Q811789) Surprise Removal of 1394 Device Can Cause=20
Bluescreen=20
Error =20
: No




I have a new CD-RW Drive (CyberDrive CW078D) that I have installed on a Dell8200 running WinXP. I am having lots of problems getting the software to recognize and write to CD-RW disks. This drive replaced an older HP CR-RW drive. I had the Roxio Easy CD 5.1 installed, but it was having problems reading the CD-RW disks. The new drive came with Nero Burning Rom 5.5, so I removed Easy CD and put Nero on, and got the latest update from the Ahead Web Site. Both Nero and InCD (the packet writer) were updated. I still have problems recognizing formatted CD-RW disks. These disks were all formatted with Roxio Easy CD. Does anyone know if there are format incompatibilities between Easy CD and Nero? I have tried reformatting the disks using Nero, but that does not seem to work either - the format runs, but the resulting disk is marked read only. My guess now is that this CD-RW hardware is not supported by the Nero InCD packet writer. What a mess! I may end up taking all the software off, and seeing what happens with the base XP software. Any advice for things to consider and/or to try? This technology sure seems to me as very fragile. I had lots of problems with the original Easy CD 5.0, and Roxio supprt has been pathetic. I basically want to be able to move files between my home PC and work PC (running Win2K and Easy CD 4).




PROBLEM: Windows 7 SP1, fresh installation -- enters sleep mode, on awakening mapped drives are lost. Only happens on desktop PC's (Dell Vostro 1100s)

SETUP: Small LAN setup in a "Workgroup": (5) Desktops, (5) Laptops, (2) iPads, (5) iPhones, (1) Drobo FS 'beyond RAID' RAID-type NAS w/ 3-2TB HDDs, (1) Canon laser printer, (1) Linksys 2400 switch in a wiring closet, and (1) Linksys E4200 router directly connected on one side to an SMC Comcast Business Cable modem and on the other side to the LAN. This is all on Cat 5. WiFi is good at 300Mbps, LAN & NICs are all matched at 100Mbps. Existing NICs & modem all top out at Fast ethernet (100 Mbps) but the Drobo, switch & router can do Gigabit. Router provides hardware firewall, Windows systems all run stock software firewall, and MSE.

BACKGROUND: I've recently begun upgrading our SOHO LAN to Windows 7 Home Premium 32 bit. I bought a 3-seat package and have thus far installed 2-seats on desktops. The other 3 desktops are on XP-SP3. Three of the laptops are Win 7 64b, the other two are XP-SP3. The i-stuff is on i-blah. All data is stored on the Drobo NAS. User files are obviosly on the individual devices. Prior to installing the two seats on the desktops, all systems were reliably mapped and reconnected every time, all the time, to the NAS, including the 3-laptops running Win 7 64b. The new Windows 7 SP1 installs are running the default "Balanced Power" setting. The other devices continue to function reliably and as-expected, properly mapping. The NAS is hot-swap capable and off-site backup is to iDrive cloud service.

Upon doing clean installs on the 2-Dells (not upgrades - full, formatted, clean installs) and setting up everything I mapped the usual folder on the NAS (G) to the desktops as (G) and ticked 'Reconnect at logon'. I soon noticed that when Windows 7 enters sleep, it disconnects the mapped drives and upon waking does not reconnect the mapped drives.

I checked online assuming this must be a known-fixed issue by now, 2012. Yes, I found out it was known since at least 2009, but I haven't found a real fix.

MS has a Mr. Fixit that automates writing an entry in the registry parameters for LanmanServer changing the autodisconnect time.They also refer to a manual fix that adds a KeepConn value in the LanmanWorkstation parameters, andtwo command line efforts: one for net use which tells the system to reconnect the map and is fine if 'G' is connected on shut down or reboot, andanother for net config which has to be written under admin priviledges and is fine to keep the mapped connection from disconnecting which the machine is awake.I've also tried adjusting the NIC power management settings.
The NIC was set to: [x] Allow computer to turn off / [x] Allow computer to wake / [x] Only allow a magic packet to wake.At first I tried changing them to disallow the computer from turning off the NIC, thenAllow / Allow / don't require a magic packet.

This seems to keep the box from losing the map haphazardly while it's awake, but all bets are off if it goes to sleep.

There are a variety of reasons why this is an issue and the sleep cycle is wanted for several reasons as well -- so just skipping sleep mode or instructing users to re-map drives every time they logon won't fly.