Tuesday, December 5, 2006

Retro Gaming

Current-gen games look better and are far more complex compared to older, especially console, games, but arent necessarily any more fun! I'm certainly not the first person to think and blog this, but its actually true...
Recently I went to LAN event and came back with a SNES emulator and a few ROMS, just for kicks. I played StarFox and Street Fighter and then loaded up Zelda 3. Zelda fans probably know where I'm going with this one...

I've never played a Zelda game before. There, I said it. I call myself a gamer but have never played Zelda. So I figured I would give it a go and see what all the fuss was about.

An hour later I was still playing and having a great time! The graphics are actually pretty good with rain effects and different environments. The story unfolds just quickly enough to keep you interested.

It can be frustrating at times though. If youre not careful, it can seem like you have looked everywhere for the secret entrance or key and just cant find it. I admit I resorted to a walkthrough for the very first task! (Although that was because I didn't know Link (the character) could push obstacles around...!)

Its the attention to detail which may be what sets this game apart, even today. Walking outside into the rain, you hear the rain, walking back inside it stops. Sounds like such a simple thing but it feels really cool in a game this old.

Everyone talks about the Zelda music, and it really sticks in your head. Its the kind of music you find yourself humming to yourself the next morning on the way to work.

Really recommend you check this game out, I'm not an RPG fan at all but I loved it. I used the free ZSNES emulator and had no stability or performance problems. (Although I am running a E6600 Core 2 Duo & 7900GT) Im sure the ROM can be found somewhere on the internet...

Thursday, November 30, 2006

Update GUI controls in multi-threaded WinForm apps in .NET 2.0

.NET 2.0 by default doesn't allow code running in a separate thread to update controls created by the main GUI thread. So if you create a new thread, that thread cannot call Textbox1.Text = "Hello World" for example.

There are two ways around this - set the CheckForIllegalCrossThreadCalls flag to false. This will allow .NET 1.1 controls to work as they did under the 1.1 framework.

The proper way to do it (according to Microsoft) is to create a method to do the control update, then call that method (on the main thread) through a delegate.

Its always easiest to see some code example. In this example, I am hiding/showing the main form from a worker thread.

At the top of my form class I have the following:
delegate void SetFormVisibleCallBack(bool visible);


The actual method to set the Visible flag is:

private void SetFormVisible(bool visible)
{
if (this.InvokeRequired) /*returns true if we are calling the method from a worker thread.*/
{
SetFormVisibleCallBack visCB = new SetFormVisibleCallBack(SetFormVisible);
this.Invoke(visCB, new object[] { visible });
}
else
{
this.Visible = visible;
}
}

If called from a worker thread, SetFormVisible Invoke()'s the main thread to call the SetFormVisible method again. When it does so, this.InvokeRequired will be false, allowing the Visible property to be directly set.

Now, to set the form's Visible property from the main thread or a worker thread, simply call:
this.SetFormVisible(false);


There is an Microsoft Help article on this, but its unnecessarily hard to follow.

Wednesday, November 29, 2006

Sound Detection using C#

I few weeks ago I needed to detect sound through a microphone. What I wanted to do was turn on a computer screen when a sound was heard (talking, clapping etc). After a long google session, all I turned up were several expensive sound detection systems and a piece of VB6 code which sets up the soundcard for sampling using the Win32 API.

Instead of porting all the API code to C#, and having an 'interesting' history with VB6 (who doesn't), I hacked the VB6 code into a dll. This library now provides a list of available recording devices, listens to the microphone and raises an event when the volume is greater than a given threshold. And best of all its easily accessible from .NET code.

Internally, it
  • Grabs a buffer of 8-bit samples from the soundcard. 8-bit means each sample value is 0-256, with 127 being silence.
  • Loops through the buffer, and if there is a value greater than the threshold, raise an event

Get the Detector library (+ source + sample C# application)
Feel free to use it in your own projects. Enjoy!

Monday, November 27, 2006

Hello World!

Welcome to my new blog! It will probably cover a whole lot of different topics, from software development to philosophical musings...