Earlier I posted some details of what I've been working on for a few days, a portable system that allows me to code once and deploy to applet, android and more complicatedly - iPhone. The first two are reasonably easy to get to, they're both Java and both support the majority of the SDK. They have different rendering methods (if you want to use their 2D APIs) so that needed to be abstracted, but that was basically it.

However, when it came to the iPhone the code needs to be in ObjC (or C++/C), so the Java will have to be converted - for me it has to be automatic. What's more somehow the Java code needs to have access to the iPhone SDK methods. Sounds like quite a tall order? Step in XMLVM, it's a tool that provides for both of the tasks above (along with a great deal of other stuff).

First, XMLVM gives you Java to ObjC conversion. More explicitly it converts from Java byte code to an intermediate XML form and then passes that through an XSL sheet to produce whatever language the sheet is designed for. In this case there's an XSL to produce ObjC. However, the current version of the sheet is just a start on the task - it's missing a bunch of byte codes. As I've gone along with the process I've been adding one's I've needed, only four or five. A typical mapping looks like this:

<xsl:template match="jvm:ishr">
  <xsl:text>    _op2.i = _stack[--_sp].i;
    _op1.i = _stack[--_sp].i;
    _stack[_sp++].i = _op1.i >> _op2.i;
</xsl:template>

The conversion process has mostly already been provided by the great XMLVM authors. The bit that really takes the time is the ability to make use of iPhone SDKs in Java, this has a long way to go. XMLVM looks a bit like this in that regard:

So your game code sits up there in the Java space. To be able to build it against the the iPhone SDKs there has to be a Java version of those APIs implemented. Those are provided as part of the XMLVM compatibility library. Whats more is that these libraries arn't just empty API/prototypes for the methods you need, but rather are implemented in terms of Java 2D. This means that once you've built your game using these APIs you can actually run it on the Java side and test the basic logic before you even get to the ObjC problems. My game for instance looked like this after I'd built against the Java libraries:

It looks sort of like iPhone right? XMLVM provides some internal classes that emulate the iPhone. Be warned however, this isn't the real iPhone emulator by any means. It's just a Java shell that let's you test. The code will only be able to run on the real emulator once the ObjC has been produced and built.

The ObjC version of the compatibility library provides a the API functions to the converted Java code. So, once the Java game code has been translated as described above it can be built against the ObjC compatibility library to produce the final iPhone application. The nice thing here is that once you're at that stage there's no difference between your ObjC application and any other hand coded one - which means no legal qualms, no jail breaking, no problems.

There's a problem of course, this ObjC library has to provide access to every iPhone SDK method/function you want and so far there arn't many implemented. For us Java types implementing the Java version of each API function is reasonably easy, however then you get the joy of dropping into ObjC and writing the equivalent function there. It's probably clearer with an example. Take the getClip() method on the CGContext API, in Java it looks like this:

public CGRect getClip() {
    Rectangle clip = graphicsContext.getClipBounds();
    
    return new CGRect(clip.x, clip.y, clip.width, clip.height);
}

Easy right? Just take the Graphics2D clipping bounds and convert it to a suitable type. However, the ObjC version is just a bit more dirty:

- (org_xmlvm_iphone_CGRect*)getClip;
{
	CGRect rect = CGContextGetClipBoundingBox(context);
	org_xmlvm_iphone_CGRect* retVal = 
          [[[org_xmlvm_iphone_CGRect alloc] init] autorelease];
	retVal->origin->x = rect.origin.x;
	retVal->origin->y = rect.origin.y;
	retVal->size->width = rect.size.width;
	retVal->size->height = rect.size.height;
	
	return retVal;
}

It's not that bad, a bit ugly and a bit cumbersome. The problem is finding these methods, while the documentation isn't bad it's having a clue where to start. This is probably my lack of iPhone experience though - I don't have any at all. Essentially all it does it map the method to a CGContext C API call and return the result.

Once the ObjC API is implemented it's just a matter of take the generated ObjC and the ObjC library, build them on OSX using the iPhone SDK and out comes your application. Of course there will be problems, and debugging applications on the iPhone isn't much fun. I've mostly relied on running the application from the command line and getting stdout. Here's my game running on the real iPhone Emulator:

There are some limitations that I've come across, I guess some will be overcome with time and patience, but they're probably worth mentioning:

  • System.arraycopy isn't implemented and I couldn't see an easy way to do it. Shouldn't hurt most people but I use it now and again
  • No field names can be duplicated in child/parent class. All members end up public so can't compile with the same name
  • Array references are never null - so you can't use a null check on int[] for instance

So that's XMLVM. It's big and it's clever and it gives us a way onto the the iPhone platform. If I could get hold of the developer's I'd contribute the stuff I've added back (it's available below). If we could only get this set up as a community based project I'm sure we'd soon have most of the byte codes mapped and the majority of the Java API and iPhone SDK made available in the compatibility library!

For now it's hopefully enough to say thank you to the XMLVM developers. It's a really great piece of technology and I hope it carries on soon.

Updates to XMLVM including a new build

I"d seen xmlvm and had

I"d seen xmlvm and had decided to stick with Objective-C. Bit of a learning curve but had at first thought no harm in learning a new language for a new platform.

Seeing a footy game up and running without a line of Obj-C has got me resolved to give this a try. No point throwing 10 years java experience out the window now, is there.

Hello Kevin, I couldnt

Hello Kevin,

I couldnt manage xmlvm run successfully. It is built successfully but converted iphone applications of the demo applications are missing. I just followed the manual on xmlvm.org.

As far as I see, you could manage to convert a 3d game. I couldnt convert a simple "helloWorld" application. I always get the "input processess couldnt be created" error. I asked through the mailing list, but I couldnt get a satisfactory answer.

Can you tell me how you did it? On which platform? What steps you took? In fact, if you could create a guide for converting android applications to iphone using xmlvm, I'd be very appreciated.

Regards,
Ahmet.