Aeon Emulator Blog

October 22, 2009

Regarding WPF

Filed under: Aeon, WPF — Greg Divis @ 7:58 pm

When I was starting to add VGA emulation to Aeon, I had to decide how the graphics would be presented in a window. I wanted to do the whole thing in C#, so that gave me three obvious choices: Windows Forms, WPF, or XNA. Of the three, I was most familiar with the Windows Forms API, but one of the main reasons I started working on this was to learn, so I really wanted to give either WPF or XNA a shot. Also, WPF and XNA both use significant Direct3D hardware acceleration, which would be nice in something like Aeon. The XNA framework is really designed for making games – sure, games are pretty much the only type of program I run in Aeon, but I pictured the emulator as more of a regular Windows application. This left WPF – it’s very powerful, very efficient, and very hard to learn.

I really have no desire to ramble about what I like and dislike about WPF, so now that I’ve established why I’m using it for Aeon, I’ll talk a little bit about how I’m using it. Nearly all of the interaction between the emulator and the user is enabled by a WPF control called EmulatorDisplay. As far as XAML goes, it’s pretty simple:

<ContentControl x:Class=”Aeon.Presentation.EmulatorDisplay”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;
    xmlns:local=”clr-namespace:Aeon.Presentation”
    MinWidth=”160″ MinHeight=”100″ Background=”Transparent” Focusable=”True”>
    <ContentControl.Resources>
        <Pen x:Key=”blackPen” Brush=”Black” Thickness=”1″ />
        <DrawingImage x:Key=”defaultArrow”>
            <DrawingImage.Drawing>
                <GeometryDrawing Brush=”White” Geometry=”{x:Static Member=local:Geometries.Arrow}” Pen=”{StaticResource blackPen}” />
            </DrawingImage.Drawing>
        </DrawingImage>
    </ContentControl.Resources>
    <Viewbox Name=”outerViewbox”>
        <Canvas Name=”displayArea”>
            <Image Name=”displayImage” Stretch=”None” MouseDown=”displayImage_MouseDown” MouseUp=”displayImage_MouseUp” MouseMove=”displayImage_MouseMove” />
            <Rectangle Name=”cursorRectangle” Width=”8″ Height=”2″ Fill=”Gray” Visibility=”Collapsed” />
            <Image Name=”mouseImage” Source=”{StaticResource defaultArrow}” Visibility=”Collapsed” />
        </Canvas>
    </Viewbox>
</ContentControl>

This file is pretty short; unusually for a WPF control, most of this one is in procedural code. The displayImage control is used to display the emulated video output, and also to capture input events from the user. Its Source property is set to an instance of a System.Windows.Interop.InteropBitmap in code based on the current video mode. Generating 32-bit pixel data from the various emulated video modes is a topic worthy of its own post, and I’ll cover that later – suffice it to say that the displayImage control hosts the final result.

The cursorRectangle instance is the text-mode keyboard cursor. Right now its size and color are hardcoded, and it’s moved around in code to match the current state of the cursor in the emulator. Similarly, the mouseImage control is used to display the mouse cursor normally provided by a DOS mouse driver. Many games drew their own mouse cursors and didn’t use this, so it’s normally invisible. Technically, the shape of the cursor can be set in DOS by a call to the mouse driver, but right now I just have it locked to the arrow shape defined in the control’s resource dictionary.

The displayArea Canvas is used in code to position the cursor and mouse images in pixel units.

Finally, all of this stuff is wrapped inside a Viewbox. The viewbox provides the nice, smooth scaling of the emulated window and also transforms incoming mouse position coordinates from mouse events.

That’s it. Those are all of the WPF elements used to compose the emulated display area.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: