Wednesday, January 2, 2008

Designer Jeans?

I was challenged today to make a post about designer jeans, and relate it to programming, which is somewhat daunting.

I ventured into the SB forums and was a bit surprised to see the posts I found there. I guess everyone is not as aware of the absolute volume of work put into this program and its ancillaries, a project reaching almost 100,000 lines of code, and maintained by one man. Daunting to take over, daunting to step into the light of expectation from the current userbase of SB3.

Of course, Joel has done most of the work. As he's mentioned before, the program is, for the most part, done. Portions have been in testing with a beta team, and a good amount of the core development has been checked off.

So what's the delay? Well, for starters, what has been said on the forum is true. I am coming in dark to this all. There is an awful lot to learn, and I've been taking it all in as fast as possible. I am in no way starting over, and the project is not getting abandoned. For those of you who don't use SB, there are several "code trees" at work here. There are internal (module) and external (exe) versions, both of these working on either FSUIPC or SimConnect, and the FSUIPC versions having elements for FS8 and FS9, which continue to be supported. Most of this is done. Let me clarify ahead of time what I mean by "done", and that is: the program elements are working in test situations. This is not the same done as in "If it's done, why not package up what you have and release it while you keep working on new stuff?" done. It's not there, and I don't think Joel or I would want to put that sort of statement of quality on our work anyways.

So what's left is that I'm now writing the module portion for FSX, and progressing along nicely. Once that is done, which includes loading the module at launch, establishing a connection through SimConnect, activating the menu item in the sim and handling the loading of the internal program window when you use said menu item, then there is the matter of testing all of it, which I believe Joel already has a good mechanism in place for, as well as going through the whole codebase and updating everything to the latest version specs, cleaning stuff up, some more testing, some more cleaning, packaging it up and getting it on its merry way.

Really, I would have loved to have had something for Christmas or New Years, but I had to selfishly go and get engaged.

But Joel and I have talked a lot about this and I'm in it for the long-haul. I'm very excited to see where SB and Flight Sim go after this version.

So much for combining this with designer jeans.

Labels: , ,

Wednesday, October 3, 2007

Acceleration, DX10, SP2 Info up

Phil Taylor has updated his blog
with information about what is in and what is out for the DX10 preview. A few items of note:

  • The dx10 codepath is being referred to as a preview. Phil goes into some detail about this, but most importantly, we see a definite shift in protocol towards back-compat with this update. ACES wants to get in all the new features and performance possible, but I'm sure that's hard when they have to spend all their time figuring out why a three year old plane is all messed up in their new, more efficient pipeline. I, for one, agree with this completely.
  • The water is gorgeous. I'm just putting this out there so you guys with Vista and DX10 can be ready for it. I don't have the horsepower to run anything above 2.x low on my system without taking a hit, but after SP2 comes out, running under DX10 will allow me to hit 2.x Max.
  • HDR Bloom - bloom always was a massive fps hit on pretty much everyone's systems. Now it's an accessible feature, and it looks better. You guys notice how they fixed the things that were already in the system instead of pumping out new things to potentially cause more problems? In other words, instead of cloud shadows, we get a better sim. I'm ok with that as well.
  • VC Shadows - you guys are going to love this, if you fly in the vc at all. It adds a great level of immersion. We saw an example of this in the train sim preview vids.

I suppose, given that all we ever got to improve FS9 was a single incremental patch, that ACES has shown a greater attention to community needs by at least 3 times this go around. I think that's important here. This is a sim that keeps getting better, and not just because of the 3rd party guys this time around.

Time to get ready for work, but I have some news coming up soon.

Labels: , , ,

Thursday, May 17, 2007

SP1 is Live - New SDK Features

Talking about being really late on this.

Yes, you all probably know that the SP1 patch for FSX is out and can be found at FSInsider.com. The big news in relation to this blog is that there are tons and tons of features and fixes for SimConnect such as the following:

Facilities API
This was a top-level request from the community for programmatic access to our internal data set for things like airports, navigational aids and waypoints. Full support through both the native and managed interfaces, including new samples and documentation.

Modeless Dialog API
Ability to utilize an ATC-like XUI menu to allow modeless interaction with a SimConnect client. This was the last remaining feature of SimConnect required to meet the needs of FSUIPC interaction without binary offset manipulation. Supports both native and managed interfaces, and includes ability to manipulate a subset of the text format. Documentation and samples are also provided.


These two additions to the package integrate seamlessly with your code and add a wealth of information. Right off the bat, the modeless dialog lets you send feedback or collect user input via ATC/ATIS menus in the sim. I've done some work with the new APIs during beta testing, and I think they are fantastic.


Important to note that the SP1A patch on the site requires the original SDK (or a patched to SP1) version from the Deluxe edition of FSX.

Labels: ,

Friday, May 4, 2007

SP1 Beta 4

In case you aren't watching other blogs:
http://blogs.msdn.com/ptaylor/archive/2007/05/04/fsx-sp1-beta4-posted.aspx

Beta 4 of FSX SP1 has gone up, and testing has begun on it. I'm hoping that we are real close now.

There are some great new things happening with SimConnect that hopefully I'll get into soon.

Labels:

Thursday, December 7, 2006

A Ten-Thousand Foot View of SimConnect - Part 3

By this point, we have a basic operation that connects to SimConnect at the click of a button...and does nothing. So it's about time we start looking at the framework of how to actually interact with FSX.

You may have read, heard or gotten involved in the conversations about multithreading, hyperthreading, fibers, etc., but all you really need to know about the whole concept is the message queue. As we said before, your SimConnect program (like other Windows applications) is Event Driven. This means that the program acts on events sent to it from the system. Say for instance, you click on our "Connect" button. The operating system registers that mouse click, and sends a message to the program. The program gets the message, containing the click event, and fires off our function in response. A lot of this is transparent, because it is built into Windows and the .NET framework, but we have the ability to expose some of the functionality and expand upon it, which is exactly what we plan to do. In SimConnect, events and data are sent to our program via system messages.

For an in-depth look at the Windows System Message system, check out this page:
Messages and Message Queues

The core of our application's message system is the "Windows Procedures" or WinProc. It is a function that receives system messages and figures out what to do with them. We want to have our program handle the SimConnect messages when they come down the pipe, so we use an ability in programming to "override" the default function. This just means that we are taking an already defined function and creating our own version of it. In the case of the WinProc, it will look something like this:

protected override void DefWndProc(ref Message m)
{
  if (m.Msg == WM_USER_SIMCONNECT)
  {
    if (simconnect != null)
    {
      simconnect.ReceiveMessage();
    }
  }
  else
  {
    base.DefWndProc(ref m);
  }
}

As you can see, we are defining the function called DefWndProc, or Default Windows Procedures. "Protected" refers to the accessibility of the function in a way, meaning who can access or alter it. We have already talked about override, that tells us that we are making our own version of an existing function, and void is the return type. Functions can return a value, such as if you have a function that adds two integers together, the return value could be the sum. When you see void, it means that there is no return value.


Looking closer at the meat of the function, we discover our old friend WM_USER_SIMCONNECT. You will recall that we defined this constant variable back at the beginning and sent him along with our connection function. This variable identifies the system messages coming from FSX. When we connect to SimConnect, we pass along this identifier, and whenever FSX sends a message back to us, it has that same value attached to it. So by looking for that value, we know that it has come from SimConnect. Then, the function continues: "if the simconnect object is not null (meaning we have connected to FSX already), then run the method simconnect.ReceiveMessage( )". This is the function within the SimConnect framework that processes the messages sent to us and figures out what we want to do with them. If it's not a message from FSX, process it as normal. Basically, there's no reason why we would ever need to change this. We can just stick it in our Form1 class under the button click function and know that it will do what we want.


So now we are ready to handle messages from SimConnect. The first one we want to look for is the message telling us that our add-on has successfully connected to FSX. The messages contain data structures, which are just variables grouped together into a consolidated object. Think of them like classes, but without the functions. All we need to know about them is that they are little bundles of data wrapped into one object. The SIMCONNECT_RECV_OPEN data structure contains a whole slew of information about the connection, the version of SimConnect, all of that lovely nonsense. Right now, we don't need any of that, we just need to know what happens, and when.


Luckily, ACES likes us, and has put that functionality into the SimConnect wrapper. After we have our connection to SimConnect, and therefore, our simconnect object is defined, we can start adding stuff to it. The first thing is event handlers. This doesn't require a whole lot of explanation. It's just a statement of what function to run when a certain event is received.


NOTE: You may have noticed already that Visual C# Express has an "autocomplete" function. This is incredibly useful (although sometimes it gets in your way when you are coding quickly), in that it automates certain procedures based on what you are probably trying to do. In the case of these event handlers, they will allow you to press the tab key to enter the default values, and will even create the new function for you, like what happened with our button click function.


Speaking of our button click function, here it is as it stands right now:


        private void button_Connect_Click(object sender, EventArgs e)
        {
            try
            {
                simconnect = new SimConnect("SimConnect Tutorial", this.Handle, WM_USER_SIMCONNECT, null, 0);
                textBox_Connect.Text = "Connected to FSX";
            }
            catch (COMException ex)
            {
                textBox_Connect.Text = "Unable to Connect";
            }
        }

Right after our the line that sets the textbox text to "Connected to FSX" but before the } (curly bracket), we are going to enter this line:

simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(simconnect_OnRecvOpen);



As soon as you type "simconnect.", a drop down box will appear with all of the properties and methods of this object, as I mentioned above. You can type in "OnRecvOpen" or find it on the list. So far, we've only used the equal sign by itself (=), but here we use plus sign equal sign (+=). This adds a value to a definition, as opposed to just assigning a value. In this case, it is adding something new to the function that processes when the "Open" message is received (which happens when SimConnect is connected). Immediately after typing "+=", you should be presented with an option to press tab to enter the default value, and then to press tab again to create the new function automagically. That's the method I followed here. As you can see, we are adding a new event handler to the OnRecvOpen event, that fires off the function "simconnect_OnRecvOpen". In this function, we define what we want to do when FSX has told us that we are connected.


Everyone with me still? Just in case more clarification is needed, I mapped it out in another of the "Worst Flowcharts Ever" (click for full-size)



As you can see, SimConnect sends messages (events) into the message queue, which the OS sends to our program. The DefWndProc passes them along to the simconnect object, which sees that there is an event handler for this event. On top of that, we have added our own event handler to the mix, and in that we do whatever we need to do.


If you tabbed through the creation of our event handler line, you will notice that it added the function "simconnect_OnRecvOpen" to the code. There's an exception in there right now, telling us that we haven't done anything with it yet. We want to remove that. In it's place, just cut and paste the following line from our button click function:

textBox_Connect.Text = "Connected to FSX";


Because, really, we don't really want to tell the user that we are connected until we are sure that we are connected. This waits until we receive notification from SimConnect that the connection is made, then changes the status. Make sure you remove that line from it's original position as well. If you want to be fancy, you can leave it in, but change the text to "Connecting..." or something like that. In most cases, it won't be up very long anyways.


We're going to add another event handler right under our first one. This time, it's to catch the event that SimConnect sends out if the user quits out of FSX. The handler is OnRecvQuit, and the line looks like this:

simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(simconnect_OnRecvQuit);


If we use tab and autocomplete again, it will create another function called simconnect_OnRecvQuit. We're just going to add a line in there to tell the user that we have been disconnected.


        void simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
        {
            textBox_Connect.Text = "Disconnected";
        }


Now, run the program (once again, click the green arrow or use the menu option Debug -> Start Debugging. The shortcut key is F5) without FSX running. If we press the connect button, we should get a message telling us "Unable to Connect". Load FSX, start a flight, and press connect again. Now it should report that we are connected. Leave the program running, and exit out of FSX. Now we are informed that SimConnect has disconnected.


And then we get an exception.


Go back up to the debug menu and select "Stop Debugging". VC# will take you back to the basic code view. What went wrong? Well, we don't have SimConnect running anymore, but we still have the simconnect object waiting for messages. So we need to get rid of the simconnect object within our program. Luckily, again, they give us a simple way to do this, called the Dispose method. Add these two lines of code to dispose of the simconnect object and set it back to null where we started:


        void simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
        {
            textBox_Connect.Text = "Disconnected";
            simconnect.Dispose();
            simconnect = null;
        }


Try it again and everything should work as expected.


Now we have a good framework for the program, have the connection and some events running, but we also want to think about what the user might want to do. For our last step tonight, we are going to expand our button click function to turn the connect button into a disconnect button when we connect.


This is going to take a few lines of code throughout our program. First, in our simconnect_OnRecvOpen function, we want to change the text of the button to "Disconnect". When the program connects to FSX, this will just change what the button says. Right after the textbox line, add the following line of code:

button_Connect.Text = "Disconnect";


Same deal with the simconnect_OnRecvQuit function:

button_Connect.Text = "Connect";


So now, when the program connects or disconnects, the button changes. Now to implement the functionality, we use a if - then - else loop. This is called a "conditional". If this is true, do this, else do this. I'll paste the new button click code and then explain it.


        private void button_Connect_Click(object sender, EventArgs e)
        {
            if (simconnect == null)
            {
                try
                {
                    simconnect = new SimConnect("SimConnect Tutorial", this.Handle, WM_USER_SIMCONNECT, null, 0);
                    textBox_Connect.Text = "Connecting...";
 
                    simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(simconnect_OnRecvOpen);
                    simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(simconnect_OnRecvQuit);
                }
                catch (COMException ex)
                {
                    textBox_Connect.Text = "Unable to Connect";
                }
            }
            else
            {
                textBox_Connect.Text = "Disconnected";
                button_Connect.Text = "Connect";
                simconnect.Dispose();
                simconnect = null;
            }
        }


If our simconnect object equals (== compares two values, as opposed to = which just sets a value) null, meaning that we do not yet have a connected simconnect object, then run through our connection procedure. ELSE, if it does not equals null, meaning that we are connected, then do the same thing as if FSX just quit. Set our text to show that there is no connection and dispose of the SimConnect object.


Try it out. Run your program and FSX and you should find yourself able to connect and disconnect as many times as you want, both by using the button and by closing FSX.


By now, hopefully a lot of the theory behind this is understood. I've tried to put a lot of detail into a very small bit of actual operation so that those who aren't familiar with the procedures of programming or C# or even just SimConnect will be able to ride along smoothly down the line.


As of now, we have a program that is able to connect and disconnect from SimConnect, can detect and handle events sent from FSX, and has the beginnings of a useable interface. Not bad for a few lessons, I think. Now that we have a framework for events, we are going to use that ability to send and listen to events, so that we can control the toggling of landing gear from outside the program, and then to detect when the gear are up or down.


Could this happen tomorrow? Maybe. I'll certainly try my best to get it done by the end of the day (Friday).


And finally, here is the full code as I have it right now for Form1.cs:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.FlightSimulator.SimConnect;
using System.Runtime.InteropServices;
 
namespace SimConnect_Tutorial
{
    public partial class Form1 : Form
    {
        SimConnect simconnect;
        const int WM_USER_SIMCONNECT = 0x0402;
 
        public Form1()
        { 
            InitializeComponent();
        }
 
        private void button_Connect_Click(object sender, EventArgs e)
        {
            if (simconnect == null)
            {
                try
                {
                    simconnect = new SimConnect("SimConnect Tutorial", this.Handle, WM_USER_SIMCONNECT, null, 0);
                    textBox_Connect.Text = "Connecting...";
 
                    simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(simconnect_OnRecvOpen);
                    simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(simconnect_OnRecvQuit);
                }
                catch (COMException ex)
                {
                    textBox_Connect.Text = "Unable to Connect";
                }
            }
            else
            {
                textBox_Connect.Text = "Disconnected";
                button_Connect.Text = "Connect";
                simconnect.Dispose();
                simconnect = null;
            }
        }
 
        void simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
        {
            textBox_Connect.Text = "Disconnected";
            button_Connect.Text = "Connect";
            simconnect.Dispose();
            simconnect = null;
        }
 
        void simconnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data)
        {
            textBox_Connect.Text = "Connected to FSX";
            button_Connect.Text = "Disconnect";
        }
 
        protected override void DefWndProc(ref Message m)
        {
            if (m.Msg == WM_USER_SIMCONNECT)
            {
                if (simconnect != null)
                {
                    simconnect.ReceiveMessage();
                }
            }
            else
            {
                base.DefWndProc(ref m);
            }
        }
    }
}

Labels: , ,

Friday, December 1, 2006

Engine Fires and Oil Leakage

Over at the Avsim SimConnect Forum, Endre brought up the question of getting engine fires and oil leaks to occur with SimConnect. He said that neither worked properly, so I set out to put together a program to show how it would indeed work as it should.

Problem is, it didn't.

I haven't tried this solution in C++, so it may just be an issue with the managed wrapper. But I think it's more likely that something doesn't work or we aren't implementing it right.

First off, the variables:

ENG ON FIRE:index On fire state
GENERAL ENG OIL LEAKED
PERCENT:index
Percent of max oil
capacity leaked


As you can see, ENG ON FIRE is a simple on/off switch for the failure (so it seems) and our oil var is just a percentage of how much oil has been lost. However, our second variable is read-only.

The ever-brilliant Pete Dowson ( http://www.schiratti.com/dowson.html ) has told us that most of the time in that case, we have to find an event that mirrors the effect. So far, I haven't found an event for either of these. Maybe someone has and can point me in the right direction. Because without an event and with the variable non-settable, we won't be able to do anything with it.

So the code is as follows (just for the engine part of things)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

// Include Simconnect and Interop References
// Remember to reference the SDK .DLL in the project
using Microsoft.FlightSimulator.SimConnect;
using System.Runtime.InteropServices;

namespace Engine_Fire
{
// Standard Windows Form, see the designer for placement
public partial class Form1 : Form
{
// SimConnect Object
SimConnect simconnect;

// User-defined win32 event
const int WM_USER_SIMCONNECT = 0x0402;

// Data definitions
enum DEFINITIONS
{
EngineData,
}

// Requests
enum DATA_REQUESTS
{
SET_ENGINE_FIRE,
}

// Our engine data struct.
// Standard marshalling message
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct EngineData
{
public bool engine1fire;
public bool engine2fire;
};

// Our initializer
// To-do: Initialize Simconnect object,
// Set up data definitions,
// Add struct to marshaller
public Form1()
{
InitializeComponent();

// Initialize SimConnect (this is straight from the SDK, just changed the app name)
simconnect = null;
try
{
simconnect = new SimConnect("Engine Fire Demo", this.Handle, WM_USER_SIMCONNECT, null, 0);
}
catch (COMException ex)
{
// A connection to the SimConnect server could not be established
// Normally you would handle the exception here
}

// Set up data definitions
simconnect.AddToDataDefinition(DEFINITIONS.EngineData, "Eng On Fire:0", "bool", SIMCONNECT_DATATYPE.FLOAT32, 0.0f, SimConnect.SIMCONNECT_UNUSED);
simconnect.AddToDataDefinition(DEFINITIONS.EngineData, "Eng On Fire:1", "bool", SIMCONNECT_DATATYPE.FLOAT32, 0.0f, SimConnect.SIMCONNECT_UNUSED);

// Add struct to marshaller
simconnect.RegisterDataDefineStruct(DEFINITIONS.EngineData);

}

// Default System Message Handler
protected override void DefWndProc(ref Message m)
{
if (m.Msg == WM_USER_SIMCONNECT)
{
if (simconnect != null)
{
simconnect.ReceiveMessage();
}
}
else
{
base.DefWndProc(ref m);
}
}

private void button1_Click(object sender, EventArgs e)
{
EngineData sendEngFire = new EngineData();

sendEngFire.engine1fire = true;
sendEngFire.engine2fire = true;
simconnect.SetDataOnSimObject(DEFINITIONS.EngineData, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, sendEngFire);
}
}
}


The key is the button1_Click function. I slapped a button my form and all it's doing is sending a message to FSX to set the ENG ON FIRE vars for engines 1 and 2 to "True". So I fire up FSX, run the code, press the button,

and nothing. No response. I check the console window, and the data certainly is being sent.

Just to make sure something wasn't backwards, I ran a test to pull the variables instead of setting them, and in normal flight, they are set to false, even after trying to set them to "true" with my program.

Here's a shot "in the thick of it" (click for larger version)



Even after sending the variables, they still come back as false.

My assumption right now is that I'm doing it wrong, and I'm certainly open to suggestions.

Labels: , , , , ,

SimConnect Debug Console

For those of you getting started with the SimConnect SDK, there is a message console that allows you to see pretty verbose output about what's happening with your program.

To get it running, copy the SimConnect.ini file from the SDK directory, located under Core Utilities Kit/SimConnect SDK/config and paste it into your My Documents/Flight Simulator X Files directory.

The file looks like this and turns on the console by default:

[SimConnect]
level=verbose
console=1
;RedirectStdOutToConsole=1
;OutputDebugString=1
;file=c:\simconnect%03u.log
;file_next_index=0
;file_max_index=9

For programs where you are doing a lot of data transfer or waiting on events, the log feature can be helpful as well. The SimConnect section of the SDK docs tells you in detail what each line does, but it should be pretty self explanatory.

Labels: ,

Wednesday, November 29, 2006

Little Signs of Life

Things are coming along nicely with the PFD so far.

Currently, I am pulling the bank and pitch angle.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct Struct1
{
public float bankangle;
public float pitchangle;
};

simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Plane Bank Degrees", "radians", SIMCONNECT_DATATYPE.FLOAT32, 0.0f, SimConnect.SIMCONNECT_UNUSED);
simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Plane Pitch Degrees", "radians", SIMCONNECT_DATATYPE.FLOAT32, 0.0f, SimConnect.SIMCONNECT_UNUSED);


After that, it's all pretty simple.

I've got three layers of texture, although, technically, it could be two. The first the large brown horizon, on top of that is a "glass ball" texture (using alpha to make it partially transparent) that includes the center marks, and the top black mask layer that frames it all.

Then it's just a matter of moving and rotating the horizon based on the angles that simconnect is sending me. The program runs at 60fps, and I've got FSX at 20fps, so I send really only get an update once every 3 frames on the client side, but it still looks smooth enough.

The core of the Update function is this:

RotationAngle = 0;

KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))
{
Exit();
}
else
{
rotpasstrans = (float)hWindow.rotpass;
RotationAngle = rotpasstrans;

float switchPitch = (float)hWindow.pitchpass * -600.0f;
horizonPos.Y = (Window.ClientBounds.Width / 2.0f)+ switchPitch;
}


It's a bit messy, but it does the work.

Here's a screenshot of the PFD in action, chirping along (2048x800)



As you can see, it can use some polish and tuning, but for the most part, it's working perfectly. The next step is going to be sizing everything down a bit to make room for more stuff, and then adding the angle of attack registration lines, bank indicator at the top of the artificial horizon, and then the fun stuff: Heading indicator, and the speed and altitude tape.

I have an idea on how to do that, but it most certainly will not be as easy as I think it will.


I want to throw out a huge show of support for ZiggyWare for their wonderfully easy to use XNAFont tutorial. Although you don't see it there, I have been using it for debug purposes.

They have some great stuff going on over there, so I suggest checking out the tutorials if you want to get started from the ground floor on XNA programming.

More to come tomorrow, when I attempt to break everything.

Labels: , ,

Tuesday, November 28, 2006

In The Beginning

I've done the livejournal thingy before, and MySpace and all that nonsense, but now I am moving into different avenues of my life and I finally have some stuff to blog about.

A little introduction, my name is Brian, 26, from Northern Virginia, and among other things, I'm the moderator of the SimConnect forum at avsim.com, the leading Flight Simulator enthusiast website. I'm also a developer who will be creating add-on programs for FSX (Flight Simulator X) and I wanted to chronicle that journey.

In addition to that, because my time isn't used up enough, I've been venturing into the world of game programming with the new Microsoft XNA framework. Although I'm not completely new to the world of game logic, this is a new level for me, so I'm going to struggle along and do a lot of things wrong.

The upside? You guys get to watch.

Labels: , , ,