Monday, July 18, 2011

Super Monaco GP Inspired HTML 5 Canvas Demo

Quite a while ago I ported a short 2D racing engine demo I'd done in Flash to Javascript using the HTML 5 canvas object.

While at IOMO I worked on several racing games include Pursuit Squad, Chase HQ and Colin Mcrae Rally 05, FPR Superbikes and Le-mans 2004. By the end I could code a racing game in my sleep (and had too in some cases) ;-)

Anyway, I've put the demo up on my website, link below. It's in no way optimised and for a real game you'd almost certainly use DOM objects for the sprites but, I was surprised how quick it was to port. Basically only a few hours - the major issue was converting a few of the integer calculations to work correctly with rounded floats.

I've only really tried it in Safari on my mac, but it did run on my iPhone classique, although pretty slowly. It nicely heats up my Macbook Pro, so can be used to warm your freezing hands in the current beautiful British summer - if nothing else!

Maybe one day we'll actually make a game out of it at Megadev.

Thursday, April 29, 2010

iRacing USB Racing Dashboard

I've had a broken leg for a while so I've been finding more and more elaborate ways to waste my spare time...

One such way was to increase my iRacing safety racing so I can graduate out of the rookie class and drive some fun cars. For anyone who hasn't driven iRacing I would highly recommend it, its the closest thing to a real racing I've found.

I've had a Microchip PIC18F4550 microcontroller lying around for a while which was destined for my motion seat controller. So I dug it out and thought I'd see how easy it was to create a simple led dashboard similar to those in current F1 cars, from the minimum of parts on some breadboard.

It doesn't look pretty, but I was really surprised how easy it was to build a functioning USB device. All in all it took about a day spread out over the weekend. I was lucky to find the wiki of Simon Inns. His article on building a USB pic device was great.

First step was to get the PIC working and hooked up to my PICKit 2 programmer. This was straight forward. It's important to use the power smoothing capacitor otherwise you get programming errors.

After I sorted that I was able to read and program the chips flash memory without trouble. However it had no inputs or outputs so wasn't particularly fascinating!

USB Interface
The PIC18F4550 contains a fully working USB interface. In order to run USB the PIC has particular clock speed requirements - using a 20mHz clock crystal and a couple of small capacitors gave an external clock source compatible with USBs requirements.

I had to build a small adapter to fit the USB plug onto the breadboard. This was a bit of strip board with some pins soldered into it.

In order to test the USB you need to download the Microchip USB framework which is contained in the Microchip Application Libraries. This gives you a fully working USB stack for the device and some PC source code to communicate with it in a variety of examples that are ready to go using MPLAB and the M18 C Compiler.

It took quite a while to get the PC and PIC talking over USB due to a short between the socket case and the adapter board. Once that was solved I was able to program the device with the USB Bootloader.

The bootloader allows you to program the device via USB, so now the PICKit 2 is consigned to my desk drawer. All thats needed is to short a pin when you turn the device on (or add a switch ;-) and the device will enter the bootloader, otherwise it runs your code.

Both the USB stack and boot loader have a configuration file that needs altering for your specific configuration (as you could have switches and leds on any port on the PIC). Choosing the config for the PICDEM2 usb board was approximate to my configuration, I modified this to suit my needs.

The Display
The displays are 7 segment led displays and the rpm indicator is 15 superbright 3mm leds.
7 control lines connect the anodes of each segment to the PICs PORTB output.
PORTA is used as an open collector output to ground the cathode to the relevant display. To do this the output is set to zero, and the TRISA register bit to 0 when the output should current sink (led on) and 1 when it should drain (led off).

The same control scheme is used for the LEDs, arranged into 3 banks of 5.

The firmware I wrote for the PIC multiplexes the output for all the displays, activating the required segments of each display (or led bank) one at a time - switching between them faster than the eye can see to make a solid display.

iRacing Telemetry
Hacking together a quick console app to control the Dash from iRacing was relatively simple too. I took the code from the Microchip USB PC sample (removed it's dependancy on .NET - a case of changing it to use CStrings and the correct Setup API func prototypes) and integrated in into the iRacing sample app to send the rpm and gear to the dash.

Here's the result:

Wednesday, December 30, 2009

Invocation - Destroy thy-self!

I've been working over the past few days to tidy up some code I've done in one of our new iPhone games.
The tools that come with iPhone SDK for profiling and debugging are pretty good for a C based environment. However every now and again you come across a bug that reminds you this is a native language.

Although the retain/release concept is very simple it often produces confusing bugs relating to premature deallocation of objects. The reason being that the errors thrown up can easily be somewhere down the line as a result of a future memory access/alloc/free failing on the FREED object. Because these errors can occur elsewhere in the code (often seemingly at random locations) - these kind of problems can be *very* tricky to debug.

This particular issue was quite interesting:

One of my UI controls is a Button that accepts an onclick action from script. This onclick action is simply parsed as a selector that belongs to the current screen. It's used to script menus etc. simply and bind them to simple methods of the current screen.

-(void)setOnClick:(id) reciever Selector:(SEL) selector
[ clickInvocation release ];
clickInvocation = nil;

onClickReciever = reciever;
onClickSelector = selector;

if( onClickReciever != nil )
NSMethodSignature *sig = [ [ reciever class ]
instanceMethodSignatureForSelector:selector ];
clickInvocation = [ NSInvocation
invocationWithMethodSignature:sig ];
[ clickInvocation setTarget: onClickReciever ];
[ clickInvocation setSelector: onClickSelector ];

// If the selector takes an extra argument it's th
// event source.
if( [ sig numberOfArguments ] > 2 )
[ clickInvocation setArgument:&self atIndex:2];

[ clickInvocation retainArguments ];
[ clickInvocation retain ];

if( clickInvocation != nil )
[ clickInvocation invoke ];

You can see form the short code excerpt that when the onclick string is set, it simply creates an NSInvocation which the Button can invoke each time it gets clicked.

This has worked flawlessly until I started doing some profiling in Instruments yesterday.... I noticed that going between 2 menus in rapid succession, after a few times would crash... with seemingly random errors in malloc_error_break or EXC_BAD_ACCESS in many different parts of code.

Finding The Cause

I could see it was something to do with clearing the menus, and after exhaustively profiling the retain/release cycles of my XML parsing and UI code I started to think it must be threading. This was a no-go because all the touch events and drawing happen from the same NSRunLoop - and hence same thread.

Chasing the cause of the seemingly random errors in the debugger led me all over my XML parsing, drawing code and even to main(int argc, char *argv[]) - I was starting to wonder what was going on!

Finally I decided to try to reproduce the problem from a test harness without any touch input. Displaying the menus quickly in succession proved no problems, but as soon as I start to poke the Button's touch events to do it the problems re-occured.

Delving deeper; I started to poke the button's onclick internals until finally I realised what was going on...

At Last!

For Button's, often the selector set on onclick is one which shows a different menu. This means that selector is responsible for removing the current menu from the screen, which in turn will release all of the menus contents, releasing the Button which has just been pressed.

You'd assume that is not a problem, but obviously it is for the NSInvocation - when it gets deallocated before it has returned!


The fix is obviously to retain the NSInvocation before you call invoke and release afterward in the Buttons onclick method.
It is odd that you can deallocate an object that is part of the current call stack, but understandable I suppose on the grounds that the runtime doesn't want to incur the overhead of retaining each object on the stack.

In any case that's several hours of my life that I won't get back ;-) Now back to the original profiling task!

Tuesday, October 20, 2009

Motion Racing Seat Update

It's been a while since my last post because I'm so busy...(yeah yeah I know everyone says that :-) ).

We're working on an exciting new iPhone game at Megadev which is starting to look great.
That coupled with me trying to sort out the business plan, pitch and tech demo for my new startup idea is taking pretty much all my time outside of the day job.

Anyway, this weekend I did find a few hours to work on my Motion Racing Seat again. After many months ticking over in the background I've finally got the whole thing bolted together properly including sturdy wheel and pedal mounts.

Having the pedals and wheel mounted securely makes a big difference to the feeling of immersion. I've made the horizontal width of the frame quite small deliberately to mimic what it is like for me inside a single seat cockpit. IIt feels great now and I even end up bracing myself with my knee's against the frame as I enter fast corners (exactly what I used to do in my Formula Ford!).

Apart from the frame, I also took some time to finish off the motion algorithms. After a lot of debugging they're finally silky smooth. They are a simple implementation off fairly standard motion cuing algorithms used in larger simulators:

    High-pass filtered g-force is scaled and applied directly to the platform angle.
    This is where you feel the onset of acceleration in any direction. It's especially effective longitudinally (fore/aft) and is scaled to be larger laterally (sideways) to compensate.
    This filtering smooths out the hard edge of the motion (where the seat stops moving abruptly), this reduces false motion cues that damage the overall effect.

    Low-pass filtered g-force is scaled and applied to the platform in the washout.
    This is where the larger sustained platform tilt comes from, it is applied slowly so you don't notice the motion application.
    What you do hopefully feel is the gravity coupling effect and physical sensations of pressure caused by the seat angle.

    Finally there is a low-pass output smoothing.
    In many games (especially Rfactor) the output is quite harsh over bumps in the track - unrealistically so and detracts from the g-force sensation (The 2 amp DC motors also driving the platform give serious kick, the smoothing helps take away the pain induced from a 1st gear-shift in an F1 car)!

Other than my own motion software, the seat could also be compatible with the open source X-Simulator software with a few minor tweaks - although my motion software is much simpler to use (all automatic).

So while It's not the best motion sim out there, the great thing is that it's produced from mostly off the shelf components, doesn't need any special tools to put together and is very cheap (comparatively). Power comes from a single laptop sized power supply (but 24v at 4 amps), so there is a lot of power but it's not hugely dangerous either.

I'm kicking around the idea of putting the plans on the net and possibly selling the few difficult to source components as a kit with the motion software. I would assume there are some pretty massive legal obligations to fulfil there for safety and public liability insurance? so maybe that will never happen - but you never know.

After watching Jenson Button win the F1 World Championship this Sunday (good lad!) I took the sim for a spin around Interlagos, Brazil in RFactor and it was really great and much more immersive than before by an order of magnitude.

A few things left to tidy up though... the lower frame is a bit to0 small so the sim is not quite as stable as it should be and the motor controller needs the wiring tidied up with the whole lot mounting under the seat somewhere.

Shouldn't be too hard to finish it off... hope I can find the time soon.

Monday, July 20, 2009

Silicon Valley Trip

So I've finally decided to bite the bullet and organise myself a trip to Silicon Valley.

It should be a good break from everyday work and what better place to concentrate building up some of my own startup ideas into something more solid.

One idea in particular I'm quite excited about.

Anyway... I'm trying to find a hotel in San Fransisco so I can look around in the evenings with day trips into the heart of the 'valley.

Still building up a list of places, but my first thoughts are in my Trip Google Map.

A lot more research to do but should be very inspiring!

Monday, May 04, 2009

Reinventing The Leaderboard

I've been working a lot recently on the iPhone/iTouch version of Megadev's Knightfall it's coming along well so expect some teaser videos to be released soon.

As mentioned previously we've had Time4Cat developed to a reasonable level for a while but I've been waiting to establish an overall strategy before we finish it off as I'd like to make sure our games cross-promote themselves properly.

Getting a game written and released for iPhone can be done in a pretty short time (Bomboozle is proof of that!) but realistically most games now require some server side "App Services" such as Highscore Leaderboards, Adverts, and Downloadable Content to deliver what consumers expect. 

For advertising, we had some mild success with AdMob but I think the adverts look amaturish and there's not enough creative control (a tiny poorly resized icon and a snippet of text).

With leaderboards there's a lot of noise about OpenFeint recently but I don't feel like it offers the kind of integration that we want and at the moment I'm not sure what the terms will be once it's not free anymore.

So with a case of not invented here syndrome I've decide we can do better so I'm going to roll our own Mega App Services platform for casual games.  This will culminate in a re-release of Bomboozle 1.2 including leaderboards, cross promotion of apps with a high degree of customisation (and a great user experience) and other tbd online functionality.

The same platform will then be used to release Time4Cat which we will be a free title in the lead up to the Knightfall release.  All of the new releases will use the latest version of our Objective-C/OpenGL development library which includes some pretty special stuff for handling gestures and XML->Object mapping (Obj-c has some great features in this area).  I'm in the process of sorting out my own website where I'll start posting technical articles on the development of all the apps for anyone interested.

Quite a lot of work ahead but hopefully the 1.2 release of Bomboozle wont be too far off, stay tuned for more updates...

Thursday, April 02, 2009

I had a brainwave yesterday which has resulted in an idea I'm exploring that would involve me creating a service that would produce some iPhone apps via a web console.

No point in me saying yet what those binaries would be, or what they would be for ;-) as I'm unclear on whether the iPhone dev agreements would quash the requirements.

I'm posting here because it may be of general interest to people when/if I do find out... and also because some of you may know already! ;-) The key points are below:

  • Produce an iPhone app from externally provided content.
    Will Apple approve an app if the content was not yours and you are publishing on behalf of someone.

    I assume so as this is what publisher's do, therefore I would be acting as a publisher.

  • Sign development apps with someone else's certificate.
    Need some way to allow app stakeholders to test the apps, if they had there own certs then great.

    Obviously unsigned for the simulator is one option.

    Ad-hoc distribution setup is another option, but it has the draw back of being a manual process (unless someone has automation hooks into itunes connect?) and limited in numbers.

  • Would Apple dis-approve in general?
    Difficult to go into full detail here but the said apps would all be completely unique and creative they would just have aspects that weren't created directly in x-code and obj-c.

I'll be delving in to the Developer and App Store agreements and for anyone out there: Answers on a postcard please...

--- Update ---
Looks like Adobe got there first and added an iPhone compiler to the next version of Flash.
Oh well - great minds and all that ;-)

I was proposing to just compile code written for our Flash game framework into the associated iPhone version. Adobe's solution is better compiling the Action script directly and using LLVM to optimise and translate the code to ARM machine code. Will be interesting to see what the porting implications for app developers are due to the hardware constraints on the iPhone, memory foot print will be a big one I suspect as most flash apps are pretty hungry.