inicio mail me! sindicaci;ón

New iPhone Puzzle Game: VidSplit

Just thought i’d let all you devoted readers know, i just released my second iPhone app on iTunes, vidsplit.

vidsplit

vidsplit is a simple picture puzzle game with an added twist: instead of a picture, you have to piece together a full-motion video. With a grand total of two difficulty settings and 3 puzzles, it should keep pretty much any puzzle enthusiast entertained for hours.

On the technical side of things, vidsplit is basically a really souped up fork of anim8gif. Instead of animated gifs however, i’m using far higher quality PVR compressed videos.

Why PVR? Well, it really is the only thing you can use to get smooth video playback, apart from the hardware mpeg decoding chips which sadly aren’t accessible using the SDK. All other methods and texture formats are far too slow to get any acceptable playback speed.

For the curious, you might also be interested to know the video frames are basically 256×256 pixels in size, stretched to the dimensions of the screen. Any bigger and the video files would balloon in size. Any smaller and the video would look like complete mush, so it’s pretty much an acceptable sweet spot in terms of quality.

The decoder is pretty simple. Every frame, a PVR texture is read from the video file (basically concatenated PVR textures) and uploaded as an OpenGLES texture. Ad-infimum. It really couldn’t be any simpler than that!

As for the actual graphical interface, i’m using a custom solution based on my kitten game engine.

To conclude

So what are you waiting for, why not buy it from itunes? :)

Playing Animated GIFs on the iPhone

Following on from my Animated images on the iPhone post, i thought i’d take things a step further.

To re-cap, i pretty much summarised the available options for playing back simple animations on the iphone in this nice table:

Method Problem
Use UIImageView It doesn’t scale
Re-draw a UIView every frame Far too slow
Use GLES Beyond the scope of the last article, but not this one!
Transform a clipped UIView each frame We did that last time

To take things further, OpenGLES needs to be used. Specifically, you need to upload and draw a texture for every frame of your animation.

Now while this sounds like a great idea, there is a slight problem: uploading textures on the iPhone is hideously slow. Excluding the requirements of a video decoder, you only have enough time per frame to be able to playback a small stop motion video in RGB format.

All is not lost though. The iPhone supports two rather interesting texture formats: GL_COMPRESSED_RGB_PVRTC_* which is the native format, and GL_PALETTE* which is, as the name implies is a texture with a palette.

The fastest format to upload is PVR, but unfortunately there aren’t many native video codecs or animation formats about that decode to PVR format. Which leaves us with the palette format, which is just about fast enough to playback something more substantial…

Now which animation format uses a palette and is widely supported? Animated gif!

So to cut a long story short, i ended up writing a fairly elaborate library to decode and playback animated gifs on the iPhone, all in realtime.

Provided the gif is not gigantic (since the bigger the gif, the slower the decode + upload), it’s actually quite useable.

anim8gif

In fact, as a proof of concept i ended up writing an app using this library to playback animated gifs from any website in fullscreen (similar to the youtube app). Feel free to check it out – anim8gif.

The code

The code for this gif animation library, glgif, is located on github. As always, feel free to fork!

Double Entry Accounting with Invoicing in Rails

You may remember a little post i made ages ago about Double Entry Accounting in Rails, in which i went over what one needed in order to make a simple double entry accounting system within the confines of the Ruby on Rails web development framework.

After a few requests by readers, i have decided to write the sequel. Double Entry Accounting with Invoicing in Rails.

To recap…

Last time i identified the following core tables you needed in your database:

  • Account (has many Postings)
  • Asset Type (e.g. £, $, monkeys)
  • Batch (has many Journals, links them into a group of transactions – though not really needed)
  • Journal (has many Postings, links them into a transaction)
  • Posting (associates with Account, Journal, and Asset Type)

Though i failed to elaborate on what you really needed to store in these tables. In truth, it can be as complicated or as simple as you’d like. No need for Batches? Then don’t include them.

As long as you at least store amounts in Posting’s, and practice the art of double entry accounting, you should be fine.

The next major point of note was how does one calculate the balances in the accounts? Well it turned out the solution was rather simple:

credit_amount = postings.sum(:value, :conditions => "amount < 0")
debit_amount = postings.sum(:value, :conditions => "amount > 0")

Coupled in with the balances were the amounts in the Postings, which had to be flipped depending on the type of account they resided in:

def real_amount
return [:asset, :expense].include?(self.account.account_type) ? self.value : -self.value
end

def real_amount=(val)
self.value = [:asset, :expense].include?(self.account.account_type) ? val : -val
end

In simpler terms: if an account is an asset or expense account, a positive value = a positive amount. Otherwise, a positive value = a negative amount. Vice versa.

So how do we factor invoicing into this?

There are two ways in which invoicing can be linked into a double entry accounting system:

  1. Link the payment of each invoice to transactions in the system
  2. Link the amount owed by each client for each invoice to transactions in the system

Realistically though, #1 is a fairly stupid idea as in the real world, clients don’t always pay on time. Or with the correct amount or order. Not only that, they can also pay off multiple invoices at once!

Which brings us to #2 – linking the amount owed by each client for each invoice into the system.

How do we do this? Well to summarise:

  • Have a revenue account which tracks how much you make.
  • Have a checking account which tracks what is in the bank.
  • Make an asset account for each client.
  • When you make out an invoice, record a transaction which transfers the total amount of the invoice from your revenue account into the client account.
  • Link any transaction(s) generated by the invoice to the invoice (so you can revert them later if required)
  • When the client pays, record a transaction which transfers the paid amount from the client account into your checking account.

Which might look like this in the system:

Account Debit Credit
Checking Accounts
Bank 100 0
Invoice Accounts
Microsoft 50 0
Apple 50 0
Revenue Accounts
Revenue 0 200

So…

  • For tax purposes, your revenue account will at least sum up to the total amount in all of your invoices.
  • If the client’s account has a positive balance, they owe you money for any one of your invoices.
  • If the client’s account has a negative balance, they’ve obviously overpaid you. So go party!!

… which more or less concludes this article. Happy accounting!

Animated images on the iPhone – sans memory leaks!

For those of you who have developed on the iPhone, you may have cringed at the prospect of having an animated image in your app, due to the flaky operation of the UIImageView which is the de-facto method of making a simple image animation.

For small images and animations, UIImageView works well. However, when you get to bigger and longer animations, it simply doesn’t scale. You might be fooled by the simulator, but on the real device your images will load very slowly before succumbing to the limited memory available.

Fortunately, there are other methods in which to playback and animated image. The first and perhaps the best method would be to implement everything in GLES. The second, which will be described here might be easier if you don’t want to setup GLES, considering it uses standard UIKit.

To start with

The Challenge

Here’s the theory: UIImageView sucks, so we need another method in which to animate images.

Method Problem
Use UIImageView It doesn’t scale
Re-draw a UIView every frame Far too slow
Use GLES Beyond the scope of this article
Transform a clipped UIView each frame None, perfect!

As you can see, there are only two realistic methods in which to animate our image: either use GLES, or transform a view around the screen.

Since i don’t want to be messing around with GLES right now, i’ll tackle the UIView, or flip-book approach.

Illustration of Concept

A flip-book can be made either by putting an image in a UIScrollView and scrolling through it, or by making a custom clipped UIView with the image inserted as a subview.

(The latter approach which i prefer as it is a bit cleaner)

The code put simply

To start off with, your master view needs to be set to clip its subviews on init. i.e.:

self.clipsToBounds = YES;

And the subview, which should be a UIView which basically needs to draw a big image containing all the frames, needs to have user interaction disabled. i.e.:


// MYAnimationViewSlide code

- (void)setImage:(UIImage*)aValue {
  [image release];
  image = [aValue retain];

  // Resize to fit
  CGSize sz = image.size;
  self.frame = CGRectMake(0, 0, sz.width, sz.height);

  [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
  // ...
  // Just draw the image!
  [image drawAtPoint:CGPointMake(0, 0)];

  // No more need for the image
  [image release];
  image = nil;
  // ...
}

// in init...
  self.userInteractionEnabled = NO;

Then all you need to do is move your slide around in your view by setting the .transform property, i.e.:


// MYAnimationView code

// slide size == child view size
CGSize slideSz = slide.bounds.size;
// frame size == root view size
CGSize viewSz = self.bounds.size;

// Calculate x,y position for the frame
// (assuming your frames are packed in a block rather than a strip)
int framesPerRow = floor(slideSz.width / viewSz.width);
int x = currentFrame % framesPerRow;
int y = currentFrame / framesPerRow;

slide.transform = CGAffineTransformMakeTranslation(-viewSz.width*x,
                                                   -viewSz.height*y);

While tied to an NSTimer:


// MYAnimationView code

advanceTime = (1.0 / 25.0);
animTimer = [NSTimer scheduledTimerWithTimeInterval:advanceTime
                     target:self
                     selector:@selector(animateTimer:)
                     userInfo:nil repeats:YES];

// ...

- (void)animateTimer:(NSTimer*)timer
{
  NSTimeInterval timeInterval=timer.timeInterval;
  NSTimeInterval currentTime=[NSDate timeIntervalSinceReferenceDate];

  if (lastTime != 0) {
    double delta = (currentTime - lastTime) / timeInterval;

    // advance by at least 1 frame, at most frames in delta
    if (delta < 1)
      self.currentFrame += 1;
    else
      self.currentFrame += (int)delta;
  }

  lastTime = currentTime;
}

It's as simple as that!

(unless your slides exceed 1024x1024, in which case you need to use more than one slide. i'll let you figure that one out)

The Code

For those of you who are interested in the code for this flip-book, i have pasted a gist on github. As always, feel free to fork!

And in case you want an example image, here's a set of frames for a 50 frame, 96x66 animation.

anim

Making a Real Calendar in Rails

For a while now, i have been looking at the various calendar helpers on Github. One thing stands out over all of them: they all suck.

bad_calendar

Why? well, they all implement the same basic concept – that is, they make a table containing rows for each week, and cells for each day, yielding in case the user wants to display anything other than a day number in the cell.

This is fine if all you want to do is display single-day events, but if you want to go to the next level and display multiple “all day” events it is practically impossible as the events are constrained in their table cell. Instead, another approach is needed.

good_calendar

The approach? Well, put simply the events are placed in a row below each set of day cells. Events which span more than 1 row are repeated, and a layout algorithm handles vertical placement.

Now rather than writing a whole post describing in agonising detail how to implement this approach, i thought i’d post a gist on github describing how to do it. Read it here. Any improvements? Feel free to fork. Comments? feel free to post below!

 

Surviving a Game Development Job Interview

The recent demise downfall of Free Radical brought back some fond memories of when i was trying to get a real programmer job in the Game Development industry. Sad to say, i didn’t make it – but then again after second thoughts, i kind of figured it wasn’t the best career path for me anyway.

Still, i learnt quite a lot about what is expected from a game development job interview. And i thought i’d list my top 3 points here, which are general enough to apply to any game development profession:

1) Bring a laptop to show off how good you are

This is perhaps the most important point. You cannot rely on thumb drives, cd’s, or the internet.

There is a high probability that your demos will not load properly on your interviewers systems. So be sure to show them on one that you know does work – yours.

In addition, the very fact that your demos are on your own hardware gives that extra inclination that you made them yourself.

2) Brush up on common knowledge pertaining to your profession.

Chances are that you will be given some form of test, either on paper or through meticulous quizzing. The aim of this is to weed out clueless candidates. Make sure you are not clueless.

3) Have something to say, questions to ask.

If you find that the interviewer is talking more than you are, then chances are they are more interested in themselves rather than who they should be interested in – you.

Have something well-formed to talk about. Don’t let the interviewer get carried away talking about some obscure technical concept.

The focus should be on you.

So after waffling on with the usual interview talk, your interviewer will usually ask “Any more questions?“. At this point, if you answer “No” then chances are you will fail the interview.

Why? Well, remember that there are two parties being interviewed. You and your interviewer. They are giving the reins over to you, in a sense.

So now is your last chance to stand out from the crowd (if you haven’t done so already). If you do not take it, then there will be little to distinguish yourself from the rest of the candidates.

To conclude

Anyone else have any more suggestions? Feel free to comment below!

Open Question: What should i write about?

Really, i don’t know what i should be writing about.

Over the past couple of years, i have written a handful of posts on this blog, most of which have been written on-the-fly and without any long-term considerations taken into account.

As a result the blog lacks consistency, leaving the reader with little clue what to expect. And much worse, it leaves me wondering what the hell to write about.

Looking at the analytics, the top 5 content is:

  • “Running your own iPhone applications without paying the developer fee”
  • The front page
  • “Flash plays SCUMM, take two”
  • “C to ActionScript via Adobe Alchemy”
  • “The Horror of Native GNUCash on Mac OS X”

So maybe i should write about developing iPhone applications? After all, it would nicely tie in with what i am doing now… writing an iPhone application. Then again…

What about making a nice page instead. Does this really have to be a blog? Perhaps i could have a single page blended with cuppalicious content! Then again…

Perhaps i should write more about silly programming projects. Forget about SCUMM, why not compile VIM or Emacs for Adobe Flash? Or taking it to the extreme, what about compiling the Linux kernel to run in Flash? 

Or maybe i should rant. Everybody loves a good internet rant!

All i know is the current iteration of this blog is no more. It is just plain unworkable.

So what next?

I’d really like to keep the general development theme, but invigorate it with something a bit more interesting. The only problem is… i’m not sure what that “interesting” element should be.

Any ideas? I’d love to have some input on this.

C to ActionScript via Adobe Alchemy

Recently Adobe’s Alchemy was released to the public for testing. It claims to be a tool which can “compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2)”.

In English, that means you can take C and C++ applications and run them in Flash 10.

Since i am always interested in the next big thing, i though i’d check it out by porting something interesting over. Previously i managed to rewrite a SCUMM interpreter from C to HaXe for Flash 9.
So naturally, to form a good comparison i decided to compile this interpreter using Adobe’s Alchemy instead.

What went right

Well, i managed to get it ported, using a front-end written in AS3, and the back-end compiled to a swc via Alchemy. Above you can see a screen shot of the version written in C (the haXe version for comparison here). Compared to the haXe implementation, the C version is much more feature complete.

It should also be noted that it took me only 2 days to get the Adobe Alchemy version to work properly, vs several weeks to get the HaXe version barely functional.

What went wrong

While Adobe Alchemy is cool, it was a nightmare to work with. For starters, compiling in C++ was broken (as the new operator didn’t work), so i could only compile programs written in C. This obviously meant no ScummVM port, which would have been far more featureful.

It also meant that i had to put up with the full quirkiness of the horrible Alchemy API. For example, this grabs the current time:

static unsigned sdl_scvm_get_time(scvm_backend_sdl_t* be) {
  AS3_Val ns;
  AS3_Val func;
  AS3_Val ares;
  AS3_Val und = AS3_Undefined();
  AS3_Val params = AS3_Array("");
  int res;

  ns = AS3_String("flash.utils");
  func = AS3_NSGetS(ns, "getTimer");
  ares = AS3_Call(func, und, params);
  res = AS3_IntValue(ares);

  AS3_Release(ares);
  AS3_Release(ns);
  AS3_Release(func);
  AS3_Release(und);
  AS3_Release(params);

  return res;
}

Ok, maybe i am exaggerating a bit here, but it seems that almost every function requires an AS3_Val, which you need to release. And it gets really annoying when you have to keep remembering to explicitly release everything you use. Hasn’t anyone at Adobe heard of autorelease pools?

Another thing is i could not find a proper way of debugging the C code. I had to resort to printing out values and trying to decipher the cryptic error messages which don’t really help me figure out the real problem.

Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
        at ()[45593.achacks.as:3340]
        at ()[45593.achacks.as:3902]
        at ScummTest/initEngine()
        at ScummTest$/process_loadQueue()
        at ScummTest$/swfLoaded()
        at flash.events::EventDispatcher/dispatchEventFunction()
        at flash.events::EventDispatcher/dispatchEvent()
        at flash.net::URLLoader/onComplete()

It would also have helped if there was proper documentation. True, there were a few examples, and you can figure out a few things from looking at the headers, but source code is not documentation.

And finally, even if you ignore the failings of the API and documentation, you still have to contend with the slow performance. In my example, the SCUMM interpreter was notably slower than its natively compiled counterpart, especially when it printed all of its debugging statements to the trace log. And even when it wasn’t printing anything out, it still took a long time doing seemingly nothing.

To conclude

To be fair, Adobe Alchemy is still “pre-release” software, so i have no doubt it will improve over the coming months.

In addition Adobe specifically mention that “Alchemy is primarily intended to be used with C/C++ libraries that have few operating system dependencies” and “is not intended for general development of SWF applications using C/C++”.

So i don’t think i will be making a habit of porting C/C++ applications to Flash using Alchemy.

Ok, libraries perhaps. But applications?

I really think it is better to write as much as you can in ActionScript or HaXe. It isn’t like in .NET where you can access objects and classes in the runtime via a transparent interface. You have to explicitly use the AS3 interface in order to manipulate native ActionScript objects.

Still, i look forward to see what becomes of Alchemy.

What’s New in Rucksack

A while ago, i posted a little piece about my Backpack-inspired organisation tool, Rucksack. At the time, i only just got the basics working, and it was nowhere near “production ready”.

Now, it still isn’t really “production ready”, but it has drastically improved these past few months. In August, it started out looking like:

And now it looks like this:

Which to say the least, is a big improvement.

But “What’s new?“, you may ask. Well apart from the new grey spaced out look…

  • You can now see a general overview of recent activity
  • You can now upload files
  • You can send emails to to pages
  • Basic reminders have been implemented with email functionality
  • Journals and Status (think Twitter) have been implemented
  • Fed-up of the default page width? You can now resize Pages!
  • Pages can now be shared to the public
  • Client-side interface re-written in jQuery
  • Bug fixes and stability improvements

So safe to say, a lot of improvements. But still, a long way to go before it is truly useful for every day organisation.

As always, Rucksack is open source and can be checked out on github.

Converting RubyCocoa Projects to MacRuby

After trying out MacRuby, the port of which directly runs on Objective C, i decided to try and convert some of my existing RubyCocoa projects over in order to take advantage of the speed boost and the simplified interface.

While the process was relatively straightforward, i have decided to reproduce it here so anyone else in my predicament can get their applications up and running in RubyCocoa with the minimum of fuss.

Preamble

Firstly, open up the Project Info box by double clicking on your project in the tree.

Your project needs to use the 10.5 sdk, since that is the only version which MacRuby supports. If you are planning on targeting 10.4, then MacRuby is not for you.

In addition you need to make sure you enable the Garbage Collection for Objective C, otherwise the MacRuby framework won’t link. In case you have forgotten where this option is, go to the build tab, select “All Configurations” for the configuration, then look for “Objective-C Garbage Collection“.

I selected “Supported“, though you can use “Required” as well.

Spot the difference

While a MacRuby project is similar to a RubyCocoa one, there are a few differences. Obviously, they use different frameworks, the initialization in ruby is slightly different, and of course there are a few big differences in the interface.

1) main.m

RubyCocoa

#import <Cocoa/Cocoa.h>
#import <RubyCocoa/RBRuntime.h>

int main(int argc, const char *argv[])
{
    return RBApplicationMain("rb_main.rb", argc, argv);
}

MacRuby

#import <MacRuby/MacRuby.h>

int main(int argc, char *argv[])
{
    return macruby_main("rb_main.rb", argc, argv);
}

2) rb_main.rb

RubyCocoa

require 'osx/cocoa'

def rb_main_init
  path = OSX::NSBundle.mainBundle.resourcePath.fileSystemRepresentation
  rbfiles = Dir.entries(path).select {|x| /\.rb\z/ =~ x}
  rbfiles -= [ File.basename(__FILE__) ]
  rbfiles.each do |path|
    require( File.basename(path) )
  end
end

if $0 == __FILE__ then
  rb_main_init
  OSX.NSApplicationMain(0, nil)
end

MacRuby

framework 'Cocoa'

# Loading all the Ruby project files.
dir_path = NSBundle.mainBundle.resourcePath.fileSystemRepresentation
Dir.entries(dir_path).each do |path|
  if path != File.basename(__FILE__) and path[-3..-1] == '.rb'
    require(path)
  end
end

# Starting the Cocoa main loop.
NSApplicationMain(0, nil)

3) Framework link

RubyCocoa

Located in /System/Library/Frameworks/RubyCocoa.framework

MacRuby

Located in /Library/Frameworks/MacRuby.framework

4) Generally speaking

Ignore the OSX module, use framework instead of require for frameworks, and don’t use ib_outlet or ib_action.

RubyCocoa

require 'osx/cocoa'

class MyClass < OSX::NSObject
  ib_outlet :myOutlet
  ib_action :myAction do |sender|
  end
end

MacRuby

framework 'Cocoa'

class MyClass < NSObject
  attr_writer :myOutlet
  def myAction(sender)
  end
end

In addition, since MacRuby is based on Ruby 1.9 (as opposed to 1.8.x) it would be a good idea to check for incompatibilities in your code which arise from changes in Ruby 1.9.

Celebrate

With any luck, provided you have followed the above and managed to convert all of your RubyCocoa code over, your app should now run with MacRuby!

Next entries »