Porting FC64 to Android via Adobe AIR

| No Comments | No TrackBacks
A long, long time ago on an Internet far, far away, Claus Wahlers and I collaborated to create FC64, a low level Commodore 64 emulator written in ActionScript 3.  I remember first talking about FC64 at FITC, and I first blogged about it back in May of 2006.

FC64 is a side project of ours that, like the cobbler's kids who never get shoes, never seems to get the attention it deserves.  The TODO list hasn't been chipped away at in a long time, and there are still some glaring omissions (the most obvious being sound emulation).  There's a nagging decimal mode bug in the CPU that still needs to be fixed.  The code has been lost, found, moved around a few places, survived a hard drive failure, but eventually made it's way to http://github.com/claus/fc64 where it's been dormant for, well... a long time.

However, all of that changed this weekend when my Nexus One arrived.

So far I've been doing all of my Android development with the native Java SDK testing on a Motorola Droid, but the Nexus One gave me a chance to install Android 2.2 and the AIR runtime.  This provided me an opportunity to take a deep, hands-on dive with with the AIR for Android beta.

Naturally, the very first thing I did with it was to try and get FC64 running on the device.  I tweeted about it quickly on Saturday and included a very poor screenshot, and Scott Janousek picked up on it and relayed the news around on the his weblog.  I was a little embarrassed that not only did I have a typo in the tweet that was going around (as an aside, Twitter as a stream-of-thought medium for me tends to be much more raw than an article/post/entry), but that the screenshot was such poor quality.  It literally was the very first build though, and I was excited to at least get that far.

Since then I've had the chance to bring FC64 to a point where I would officially call it "working" on Android 2.2 via AIR.  Here are a few screenshots that illustrate the current progress of version 0.0.1 (click images for larger versions):

These two images show FC64 loaded in portrait mode using the native on-screen keyboard to enter commands. This shows the result of running a simple POKE command.

FC64 in landscape mode playing a game.
Here we have a game running in landscape mode with the virtual keyboard hidden.

For the most part it was straightforward and easy to port our 4-year-old ActionScript project to Android via AIR.  Here is the short list of things that needed to be done:

  • Installing the AIR runtime on my Nexus One
  • Creation of a separate AIR project in FlashBuilder with a device-specific main runner class
  • Addition of code to handle screen orientation changes
  • Refactoring of code to handle keyboard input
  • Added support for trackball support to act as a joystick
  • Creation of a build script to compile, package, and install the application on my phone
Everything else worked out of the box without modification.  I did make a few minor changes to the base code in order to improve performance just a little.  For example, we were originally dispatching a lot of events for tracking frames per second, but new Event() at short intervals has a lot of overhead on mobile and was slowing down the emulation.  This will probably be refactored again into a conditional compilation directive.

I also took some time to wire up the Nexus One trackball so that it can be used as a joystick.  In Galaga, for example, scrolling the trackpad will move your ship left and right, and pressing the button down will fire.  It's a nice addition and fun for games.

There is still a lot that needs to be done, both for the Android application and for FC64 in general, but I was pleasantly surprised at how quickly I was able to get an initial port of the code base running on my device.

A short Android-specific TODO list for FC64:

  • Load ROMs from SD card.  Currently I've hard-coded the public domain game Galaga into the application.  Pressing the Android "back" button will load the ROM and start it automatically, or, if the ROM has already been loaded, it will reset the CPU.
  • Further optimizations such as using Joa's TDSI and Memory class to improve performance (both for mobile and in general).
  • Update the visual display.  Currently we're scaling the renderer to match the width or height, but it degrades the C64 text.  We might remove the scale and just center the renderer for a crisper display.
  • Proper key mapping.  This wasn't so apparent on the desktop version, but the virtual keyboard on mobile doesn't allow you to press "shift + 2" which is required for entering the " symbol (the original C64 keyboard had " as shift + 2) so BASIC commands are hard to enter.
I plan on pushing the source for this into my GitHub repository at http://github.com/darronschall/fc64 in the next day or so, and I'll propagate the changes upstream to the master repository.

I had a great time presenting at Flash Camp Philadelphia 2009.  My session was Using FlexUnit 4.  I covered the new features of FlexUnit 4 and dove into a lot of examples, from getting started with writing test cases to integrating FlexUnit test results into your Continuous Integration server via an ANT build process.

You can find the slides (exported with additional notes that I've since added for context) here: FlexUnit4.pdf

The example code to complement the slides is here: FlexUnit4Examples.zip  - Note, at the time of the presentation, these examples were compiled against the FlexUnit 4 "beta 2" drop.

Thank you to everyone who attended my session.  The questions at the end were great, and I enjoyed the interaction. Be sure to check out the FlexUnit 4 forums if you need additional support!

Mate vs. Swiz

| No Comments | No TrackBacks
Last week I gave an online presentation to a user group of Flash Platform developers in Boston.  The presentation was focused around the Mate and Swiz Flex frameworks.  Having experience using both, I wanted to highlight how the frameworks compare side-by-side.

I've exported my presentation slides into a PDF file (with the presenter notes view enabled).  You can download the slides here: http://www.darronschall.com/presentations/2009/10/08/Mate vs Swiz.pdf

The main theme of the presentation was that both frameworks are MVC frameworks for Flex.  No matter what framework you choose you should end up with similar architecture at a high level.  The key differences are really in the implementation details (and they're not as different as you might think).

The last slide offers some food for thought.  Which framework should you choose?  There is no easy answer.  This is largely a matter of personal preference, opinion, and style.  I've used both in applications and been happy with the results.  Some teams prefer Mate, some teams prefer Swiz.  One is not necessarily better than the other, they're just... different.  

As always, your mileage may vary.

A common design pattern used in Flex applications is leveraging mock delegates in the business layer.  Mock delegates and delegates share the same client/server interface, but the mock versions can be used as stand-ins for the real delegates when a connection to the server cannot be established or perhaps when the server method has not been built or is not integrated yet.

For example, if an application needs to log a user in it might make a call to LoginDelegate::login and pass along the user's credentials.  The server might respond with the detailed user information if the credentials are valid, or it might throw an error or return null of they are not.

Since a login screen is typically the first screen in an application, client-side development is generally dependent on the server's ability to log a user in consistently.  What happens when this isn't the case?  This is where mock delegates shine.  They free client-side developers from server-side dependencies and enable development to proceed even if the server or the remote method is unavailable.

Mate has Mock Services (pdf)  to enable easy mock delegate creation.  With Swiz you build mock delegates that leverage TestUtil.mockResult.  If you google for MockRemoteObject there are other implementations to be found out there, such as this one.

Once mock delegates have been created, populating them with fake data to return usually involves creating some code to generate random data. Something like this...

public function getUserList():ArrayCollection
    var users:Array = new Array();
    var user:User;
    // Generate 10 fake users
    for ( var i:int = 1; i <= 10; i++ )
        user = new User();
        user.id = i;
        user.firstName = "First " + i;
        user.lastName = "Last" + i;
        // More here... Math.random(), lorem ipsum generation, etc.        

        users.push( user );

    return new ArrayCollection( users );

There are more sophisticated tools you can use to generate mock data (this StackOverflow question is probably a good place to start looking), but the general idea of creating fake values and stuffing them into objects still applies.

Fortunately, this process can sometimes be made easier with ServiceCapture (or possibly Charles or another tool, but I'm a ServiceCapture user).

ServiceCapture is a developer tool that captures HTTP traffic on a computer. It enables the introspection of data being sent between the client and server tiers, and includes support for decoding AMF. It also has the ability to save responses received from the server.

That last line is important. With ServiceCapture, it is possible to locally save the response from a server (even AMF responses). These responses can then be used in the mock service layer to accurately simulate real responses in mock scenarios.

Naturally, this technique only works when the remote method is available to capture results from. If client and server development are happening in parallel and the server has not exposed any methods yet, the technique of using a server response as a base for a mock response does not apply. However, when server methods are available to test against, saving responses is both beneficial (since mock data behaves like real data will during development), and time saving (because scripting mock data becomes just a few lines of code).

Here are the steps to take in order to leverage a saved server response in a mock server method:

  1. With ServiceCapture open, make the appropriate call to the remote method from the client application. ServiceCapture will show the request as a line item in it's grid view.
  2. After the result comes back from the server, right-click on the call and select "Save Response" from the context menu.
  3. In the Save dialog, save the response to your local computer. A good practice here is to use the method name and parameters followed by an extension such as ".data" for AMF responses to indicate that the response is binary. For example, if the method is getUserDetails and takes a userId:int parameter, the saved response might be named getUserDetails_13.data.
  4. Place the saved .data file in the appropriate folder location in the project directory, e.g. Project/mock/[projectPackagePath]/services/data (where mock is defined as an additional source folder in the project properties).
  5. In the MockDelegate class, embed the .data file and read in the contents at runtime. Return the contents to the user as the mock result. An example:
     * This particular example would be used as a mockGenerator for a MockRemoteObject
     * in Mate.
    public class MyServiceMock
    	[Embed( source="data/getUserList.data", mimeType="application/octet-stream" )]
    	private var getUserListData:Class;
    	public function getUserList():ArrayCollection
    		var response:ByteArrayAsset = ByteArrayAsset( new getUserListData() );
    		response.objectEncoding = ObjectEncoding.AMF3;
    		response.position = 30
    		var ackMessage:AcknowledgeMessage = response.readObject();
    		var collection:ArrayCollection = ArrayCollection( ackMessage.body );
    		// At this point, collection is an ArrayCollection of User instances.  If
    		// we wanted to, we could change some properties here to "mock" more data, but 
    		// just returning the collection is exactly the same as what we would get from
    		// the real service.
    		return collection;

You'll notice that there's some special sauce in the code example above. The server response is created as a ByteArrayAsset, and then the position is moved to position 30 before reading the AcknowledgeMessage instance from it. The actual data being returned is contained in the message's body property.

The position of 30 is not consistent in every scenario and varies based on the server's response, but it usually works. I used a hex editor to determine the location to use to start reading this particular AMF remoting envelope's body response.

A better approach would be to create a small library to pull the response data out automatically. That said, however, this approach can still be a big time saver when it comes to generating mock data. Not only is it faster to create the mock data, but the data itself is a direct copy of real data for the system which gives the application a better feel during development and testing.

In summary, mock delegates enable parallel client/server development, simplify integration, and enable offline development.  By using a tool such as ServiceCapture, you can quickly and easily generate data in your mock services that exactly matches the data returned by the server.

Flash Camp Atlanta 2009

| No Comments | No TrackBacks

Where has this year gone? It's already August, which means Flash Camp Atlanta 2009 is right around the corner. If you're looking for a quick way to gain some insight into the Flash Platform and learn some new tricks, Flash Camp is a great one-day conference with a talented speaker lineup.

The speaker lineup includes a keynote from Greg Wilson of Adobe, with sessions presented by David Tucker, Jesse Warden, Carl Smith, Leif Wells, Douglas Knudsen, Ben Stucki, and Christian Saylor. All of the sessions share a common theme: "Enabling the Convergence of Art & Science With The Flash Platform."

The full-day event is happening on Friday August 28th at the GeorgiaWorld Congress Center in downtown Atlanta. If you haven't signed up yet, this is a great opportunity to get together with fellow professionals and learn a thing or two about the craft. It's a little too late for the early bird pricing, but the tickets are still reasonably priced for a one-day conference packed with content.

For some additional information, here's what a few other people have to say around the blogosphere: Doug Knudsen, Russell Brown, and David Tucker.

Disclaimer: I'm employed by Universal Mind, an elite group of technologists who excel at solving the difficult challenges of building an optimizing rich internet applications, and also the primary sponsor of Flash Camp Atlanta 2009.

DelegateInvoker for the Mate Flex Framework

| No Comments | No TrackBacks

I've been using the Mate Flex Framework a lot in recent history.   I think it's a solid framework that does a lot of things right and it's very lightweight and easy to use.  If you haven't used it yet, it's at least worth looking into.

That said, I was recently confronted with a situation in which the current service invokers were insufficient.  By service invokers, I mean specifically the RemoteObjectInvoker, HTTPServiceInvoker, and WebServiceInvoker classes.  Let me explain.

When you use the Web Service code generation tools from FlexBuilder Gumbo MAX Preview, you end up with a service class that wraps a web service and provides a well defined public interface.  Each method in the class returns an AsyncToken that allows you to add a responder to be notified of success/failure when the remote method call comes back.  The generated code looks something like this:

public class MyService extends WebServiceWrapper
    public function myRemoteMethod(param1:String, param2:int) : AsyncToken
        var operation:AbstractOperation = _serviceControl.getOperation("myRemoteMethod");
        var token:AsyncToken = operation.send(param1, param2);
        return token;

If you've used Cairngorm before, this code should look very familiar.  It's the same type of code that you would normally see in the Delegate layer.

How do we use this type of delegate class in Mate?  My first approach was to try and use a WebServiceInvoker, but the delegate class is not a WebService.  My second approach was to try and leverage AsyncMethodInvoker, but that had a few other problems.  The biggest was that the success/failure listeners respond to the class itself and not the token returned by the method.  Additionally, the AsyncMethodInvoker doesn't integrate with the UnhandledFaultEvent approach to application-wide service fault handling.

So, I decided the best approach was to create a new kind of invoker, DelegateInvoker, specifically to handle calling these types of delegate classes. Usage is essentially the same as the other Mate service invokers:

<DelegateInvoker instance="{ services.myService }" method="myRemoteMethod"
	arguments="{ [ 'param1', 12 ] }"

If no faultHandlers are defined, then an UnhandledFaultEvent is generated. This allows the DelegateInvoker to integrate with the application-wide service fault handler.

The DelegateInvoker can be used with any method that returns an AsyncToken. Behind the scenes, the DelegateInvoker attaches a responder to the AsyncToken returned by the method. The responder listens for success/failure and triggers the inner handlers when the method call returns. If the method does not return an AsyncToken to attach a responder to a runtime error is logged.

I've spoken with Nahuel about getting this new DelegateInvoker class incorporated into the Mate core. He will be adding it into the Mate in_development branch. It should be available for download in the next day or so, and I'll update this entry when the class is posted.

The DelegateInvoker class is available as of revision 93 in Mate's SVN. It's currently in the in_development branch, but will eventually be moved to the trunk in a future release.

Flex 2.0.1 SDK is dying

| No Comments | No TrackBacks
If you have a project that still uses the Flex 2.0.1 hotfix 3 SDK, now is a good time to consider upgrading.  When the new version of FlexBuilder is released (presumably in the second half of 2009), you will no longer be able to build your Flex 2.0.1 projects using FlexBuilder.

When you try to build a project with the Flex 2.0.1 SDK using the FlexBuilder Gumbo MAX Preview build, you'll encounter an error indicating that the flex-compiler-oem.jar is missing from the classpath.  I've logged this as the following issue: https://bugs.adobe.com/jira/browse/FB-15688.  The issue was resolved as Not a Bug with the comment Flex Builder 4 will not support Flex SDK 2.

I'll repeat that.  On a separate line.  In Bold.  Pay attention.

FlexBuilder 4 will not support Flex SDK 2.

Of course, ANT scripts and command-line compiles will continue to work.  However, losing IDE support should be a pretty compelling reason to look into the upgrade process.

Flex 3.0 was released February 25, 2008.  Since release the SDK has been updated to Flex 3.1 on August 15 and Flex 3.2 on October 29.

To learn more about the Flex SDK and download new versions, visit http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK.

For those of you looking to upgrade from Flex 2 to Flex 3, check out the compatibility issues in the Flex 3 release notes.

And now, I leave you with Monty Python's "Bring Out Your Dead".  Flex 2.0.1, you'll be stone dead in a moment.

AS3 JSON library now a little less strict

| No Comments | No TrackBacks
I've just checked in revision 83 of as3corelib that adds a strict flag to the AS3 JSON library.  In the past the library would generate an error if the JSON string was deemed invalid according to the syntax rules.  Now, based on the strict flag setting, the parser does a better job at allowing "valid" input even if the input doesn't match the JSON spec.

I've actually had this code completed since MAX 2008.  I wrote it on my flight from San Fransisco to Harrisburg, but haven't had the time to get it ready for check-in until now.

Here is the commit message:

  • Added throwing error if entire string cannot be consumed (when there are remaining characters left in the input stream)
  • Added "strict" flag to decoding process.  Default is true for backwards compatibility.  When false, relaxes input format rules.  Fixes #34, Fixes #41, Fixes #71:
    • Allows for hex specification for numbers, ex: { "myNum": 0xFFCC33 }
    • Allows for NaN to be parsed as a number, ex: { "myNum": NaN }
    • Allows for trailing commas in arrays, ex: [1,2,]
    • Allows for trailing commas in objects, ex: { "p1":true, "p2":false, }
    • Does not throw error if there were characters left in the input string
  • Added tests for strict flag
  • Added tests to better exercise comments
  • Updated tests to use proper assert types
  • Some minor cosmetic code cleanup
Usage is exactly the same as before, with the additional option of specifying the strict flag as part of the JSON.decode( string, strict ) call.  Example:

// Set strict mode to false to allow for trailing commas to not throw an error
var o:Array = JSON.decode( "[0,1,]", false ) as Array;
assertEquals( 0, o[0] );
assertEquals( 1, o[1] );

// Same usage as before, strict mode will throw a runtime error if the string is not valid
var a:Array = JSON.decode( "[0,1,]" ) as Array;

I still need to address #35 to allow for unquoted keys in objects to be parsed in non-strict mode.  This is a bit more complicated of a change because it changes how the tokenizer recognizes what is in the input stream.  It's coming though!

Note that a new .swc file was not yet posted.  If you want to experiment with these changes, you'll have to pull the latest from source.  I'll work with Mike to get the download .swc updated soon.

Hello World 2.0

| No Comments | No TrackBacks
It's been about a year since I've last posted something.  Pardon the dust...  it's not that I haven't had anything to say, it's more that I just haven't had the time to say it.

In fact, I've neglected my weblog so much that I had to upgrade through not just one but two major versions of MovableType.  It was interesting upgrading from 2.6 to 3.35 to 4.21 then finally to the latest 4.23.  The upgrade from 2.6 to 3.35 was smooth, but 3.35 to 4.21 was an epic fail.

Years and years ago when I first created my weblog I chose Berkeley DB as my database option.  I would've chosen MySQL but at the time either my host didn't support it or MT didn't support it, I don't really remember.  Today, it turns out that Brekeley DB is no longer supported in modern versions of MT.

I lost basically everything during the 3.35 to 4.21 upgrade when my database became unreadable.  I had some backups that I was able to use to import all of my old entries and comments without too much issue, but I wasn't able to recover the site design.  I had customized the default MT templates to leverage my ColdFusion custom tag templating system that I createad for my website, but the MT templates have radically changed over the years.  Also, the CSS and page structure were too structurally different and I wasn't able to quickly/easily modify the default MT template to work with my past site design.  I'm not a huge fan of the default design I'm using now so I'm still working on getting my old site design back (but I expect that it's going to take quite a bit time).

Not only that, but I also lost my code coloring plugin.  In the past I've used MTCodeBeautifier but this no longer works with the MT4.  I've started using SyntaxHighlighter which is a completely JavaScript-based solution and should be future-proof, however, I haven't been through all of my old entries to convert them.  I'm still working on that, too...

Anyway, what I have been up to lately?

Well... I've been up to my elbows in Flex development.  It's been a great year and I've worked on some really interesting and challenging projects.  Perhaps the biggest news, though, is that my employment situation has changed.

I'm now officially employed by Universal Mind as a Principal Architect (and have been since the summer).  It feels great to be part of such an elite and passionate team.  I'm really excited about what the future holds for both myself and the company, and I'm especially happy to see the immense positive reaction that SpatialKey has been getting.

Now that I'm back up and running, in the future I hope to get through the backlog of weblog ideas that I've been meaning to post for... well... over a year now.  I'm just as busy as always but now that I actually have modern weblog software that can do things like schedule entry posting dates, it should be easier for me to stay on top of things.

Stay tuned...

Oh, one final note, my RSS feed link has changed to http://feedproxy.google.com/darronschall.  The old rdf link is no longer being updated.

Creating Default, Cancelable Event Handlers

| 4 Comments | No TrackBacks

Events play a key role in Flex-based RIAs so it's important to have a solid understanding of them when building applications. Today I'm going to show you how to create a default event handler that performs an operation, and what steps are needed to cancel that default behavior to prevent it from happening.

A default event handler is a method of a component that handles the same event it dispatches and performs some default action. This happens a lot in component development. A component can dispatch an event, but also act on that event with some default behavior. You don't have to explicitly listen for the event because the default action happens automatically within the component itself.

For example, let's think about a "closeable" tab navigator. When you click on the "x" to close a tab, a "closeTab" event might be dispatched to signal that a tab is intended to be closed. The tab navigator itself listens for the "closeTab" event and provides a default behavior of removing the tab that was intended to be closed.

But what if you want to present the user with a confirm dialog first before the tab gets removed? In this situation, you don't want the default behavior to occur because the tab will be removed before the user has a chance to respond to the confirm dialog. So, you need a way to prevent the tab from being removed by the component.

There are 4 things associated with creating default event handlers and allowing them to be canceled. They are:

Rather than elaborating on these pieces with a few paragraphs of text, I think a code sample illustrates this best. Here's a sample component that has an "alarm" event with a default behavior of just showing an Alert dialog to let you know the default behavior has happened:


import flash.events.Event;

import mx.controls.Alert;
import mx.core.EventPriority;
import mx.core.UIComponent;	

[Event( name="alarm", type="flash.events.Event" )]

public class MyComponent extends UIComponent

	public function MyComponent()
		// Assign a default event listener for the "alarm" event.  The key here
		// is the event priority of DEFAULT_HANDLER.  This is a low priority and 
		// allows normal listeners to execute first, giving them a chance to call
		// event.preventDefault() to cancel the event's default behavior
		addEventListener( "alarm", handleAlarm, false, EventPriority.DEFAULT_HANDLER, true );
	 * Silly method here just to have the component dispatch an event that it
	 * has a default behavior for.
	public function triggerAlarm():void
		// Create a new event of type alarm.  The key here is the third
		// parameter which signals that the event is allowed to be canceled
		// via event.preventDefault();
		dispatchEvent( new Event( "alarm", false, true ) ); 
	 * The default behavior for handling the "alarm" event
	protected function handleAlarm( event:Event ):void
		// Check to see whether or not the event had it's default behavior prevented
		// by another event listener
		if ( !event.isDefaultPrevented() )
			// The event has NOT been canceled, so continue with
			// the default behavior
			Alert.show( "handleAlarm default handler executed from MyComponent" );
} // end class
} // end package

Here's a sample Flex application using this component. I add a listener for the "alarm" event, and if the user wants to cancel the default event behavior I call event.preventDefault() in my alarm listener:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*">
			protected function handleAlarm( event:Event ):void
				// Just for example purposes, we have a flag in the UI to indicate
				// if we want to prevent the default event handler from executing
				// or not...
				if ( preventToggle.selected )
					trace( "Default behavior is prevented" );
					trace( "We didn't prevent the default behavior, so we'll see the alert from MyComponent." );
	<mx:Button label="Trigger Event" click="myComp.triggerAlarm();" />
	<mx:CheckBox id="preventToggle" label="Prevent default behavior?" selected="true" />
	<local:MyComponent id="myComp" alarm="handleAlarm( event );" />

So, there you have it! There's not much to it really, but it's a pretty useful technique. I'd actually like to see this covered a bit more in the Events portion of the livedocs site. Creating cancelable default event behaviors is a key part of Flex component development. Having a solid understanding of events will go a long way when it comes to building Flex applications.


Recent Comments

  • darron: You can download the project by following the instructions on read more
  • jim: I'm researching card engines at the moment and this project read more
  • Mike Keesey: I'll second what the last poster said, except that I've read more
  • Josh Dura: Great article Darron. Thanks! I'm just starting to learn AS3 read more
  • darron: You would need to wrap the default behavior in a read more
  • Ben Clinkinbeard: I bet you're not surprised to see me here. :) read more
  • darron: Thanks for the comment Luke - I didn't know about read more
  • Luke Bayes: Hey Darron, There is one major difference between the open read more
  • Mike Keesey: Nice! I like it. (I mean, I don't like it read more
  • Ryan Taylor: Good thoughts, Darron. I've certainly used the pattern in a read more

Recent Assets

  • galaga_color_landscape.png
  • poke_portrait_keyboard_after.png
  • poke_portrait_keyboard_before.png