Monday, July 23, 2012

Definitive Guide to Using Hyperdeck Shuttle II with Mac OSX

It took quite some experimentation and I was about to give up on this, but it looks I cracked it. I can now record compressed video with the BlackMagic Hyperdeck Shuttle II and use the video file with Mac OSX. I was already able to use the uncompressed video files from the device, but those are just too freaking huge to comfortably work with on a macbook air.

STEP1:
Make sure you are using the latest drivers and firmware as posted on the support page of Blackmagic design. I used the 3.0.2 version.

STEP2:
Set the device to record compressed files into a quicktime container.

STEP3:
Don't try to record output from your iPhone... I tried, and it did not work. My iPad2 and iPad3 HDMI signals were accepted just fine. You will need an adapter from Apple to hookup an iPad to a Hyperdeck Shuttle II.

STEP4:
BlackMagic wants you to install the DNxHD codecs from Avid's website. Frankly: don't bother. You can try, but they did not work for me. I would either get a black screen video with some audio (iPhone recording) or worse, I would have a crashing quicktime player (iPad recording). The crash I am seeing is this one:

Thread 3 Crashed:: Dispatch queue: com.apple.coremedia.playbackboss
0   com.apple.audio.toolbox.AudioToolbox 0x00007fff841595a7 _AT_AudioUnitUninitialize + 55
1   com.apple.audio.toolbox.AudioToolbox 0x00007fff841ed819 MixerChannel::Uninitialize() + 27
2   com.apple.audio.toolbox.AudioToolbox 0x00007fff841ede5e SubmixGraph::ConnectToDestination(bool, CAStreamBasicDescription const&, CAAudioChannelLayout*) + 184
3   com.apple.audio.toolbox.AudioToolbox 0x00007fff841e7120 MasterMixer::ConnectSubgraph(SubmixGraph*) + 686
4   com.apple.audio.toolbox.AudioToolbox 0x00007fff841e7415 SubmixGraph::ConnectInputChannel(bool, MixerChannel*, bool) + 657
5   com.apple.audio.toolbox.AudioToolbox 0x00007fff841e7826 AQMEDevice::AddRunningClient(AQIONodeClient&, bool) + 262
6   com.apple.audio.toolbox.AudioToolbox 0x00007fff841cbaf5 AudioQueueObject::StartRunning(AQIONode*) + 51
7   com.apple.audio.toolbox.AudioToolbox 0x00007fff841c47e3 AudioQueueObject::_Start(XAudioTimeStamp const&) + 637
8   com.apple.audio.toolbox.AudioToolbox 0x00007fff841c494a AudioQueueObject::Start(XAudioTimeStamp const&) + 18
9   com.apple.audio.toolbox.AudioToolbox 0x00007fff841dd8cb AQServer_Start + 64
10  com.apple.audio.toolbox.AudioToolbox 0x00007fff841e0e88 AudioQueueStart + 183
11  com.apple.MediaToolbox         0x00007fff877497d8 FigAudioQueueStart + 551
12  com.apple.MediaToolbox         0x00007fff877a33b3 0x7fff87728000 + 504755
13  com.apple.MediaToolbox         0x00007fff8779ae4e 0x7fff87728000 + 470606
14  com.apple.MediaToolbox         0x00007fff8779e2e0 0x7fff87728000 + 484064
15  com.apple.MediaToolbox         0x00007fff8779e508 0x7fff87728000 + 484616
16  com.apple.MediaToolbox         0x00007fff8779e75a 0x7fff87728000 + 485210
17  libdispatch.dylib              0x00007fff8dd77a86 _dispatch_call_block_and_release + 18
18  libdispatch.dylib              0x00007fff8dd792d6 _dispatch_queue_drain + 264
19  libdispatch.dylib              0x00007fff8dd79132 _dispatch_queue_invoke + 54
20  libdispatch.dylib              0x00007fff8dd7892c _dispatch_worker_thread2 + 198
21  libsystem_c.dylib              0x00007fff8825b3da _pthread_wqthread + 316
22  libsystem_c.dylib              0x00007fff8825cb85 start_wqthread + 13

STEP5:
FFMPEG to the rescue! Instead of trying to get DNxHD and Quicktime to play nice together, Open Source will save us, hooray! Note that some companies charge 500 euros for video conversion software, but ffmpeg will do the trick. You need to make sure you have a very recent version, as DNxHD support was only recently added. Get the ffmpeg binary from the ffmpegmac.net site.

STEP6:
Convert the DNxHD file to something more useful using the following command line:

$ ffmpeg -i Capture0002.mov -an output.mp4
Note that this invokation strips the audio, if you want to keep it, you will have to consult the ffmpeg manual on how to do that. The ffmpeg tool recognizes the iPad2 stream with the following properties:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Capture0002.mov':
  Metadata:
    creation_time   : 2012-07-23 22:12:33
  Duration: 00:00:13.38, start: 0.000000, bitrate: 238657 kb/s
    Stream #0:0(eng): Video: dnxhd (AVdn / 0x6E645641), yuv422p10le, 1280x720, 220200 kb/s, 60 fps, 60 tbr, 6k tbn, 6k tbc
    Metadata:
      creation_time   : 2012-07-23 22:12:33
      handler_name    : Apple Alias Data Handler
    Stream #0:1(eng): Audio: pcm_s24le (lpcm / 0x6D63706C), 48000 Hz, 16 channels, s32, 18432 kb/s
    Metadata:
      creation_time   : 2012-07-23 22:12:33
      handler_name    : Apple Alias Data Handler

Friday, July 13, 2012

Beware of automatically downscaled retina images


The iOS development environment facilitates image content loading for retina and non-retina devices with a clever naming scheme. If an iOS app is running on a retina device, and is instructed to load an image named foo.png, it will actually attempt to load the foo@2x.png file if it exists. By providing both foo.png and foo@2x.png images, both classes of devices are supported.

This convenience offered by UIKit goes one step further: if you do not provide the regular resolution version foo.png but only the retina version foo@2x.png then non-retina devices will load the high res version and automatically downscale a factor 2 so that it can be used. If you are tempted by just providing retina versions of your images, and skip the regular versions, like I was, you are selling your app short. It turns out that UIKit does a horrible job at downscaling, and the image will look considerably worse than a version that you pre-scaled yourself.

To illustrate the effect, see below how the original is downscaled by UIKit, and how it is downsampled by my authoring tool inkscape. A big difference, I would say.

The bottom line: if you care for your iPad2 and iPhone3GS Users, don't skimp on images. Provide both the foo.png and the foo@2x.png files.


The retina version of the graphic, viewed at 1:1 zoom.


The image automatically downscaled by UIKit from the retina version, viewed at 2:1 zoom.


The image, exported at non-retina resolution by inkscape, viewed at 2:1 zoom.

Monday, June 25, 2012

Bram's upcoming indie game

I've been working on my next indie game. It uses a voxel art style, and like the little crane that could, it features a top notch physics simulation. Here are some screenshots of the game. Note: the new project has not been named yet.


On the farm.


Visiting the queen.


At the picnic.

Monday, May 21, 2012

De Nederlandsche taal, het redden niet waard?

Zittend in mijn badkuip overpeinsde ik de betekenis van het woordje weer. Dit woordje heeft een verscheidenheid aan betekenissen, geillustreerd met de zin:

Wegens het stormachtige weer moest de brandweer vandaag weer uitrukken.

Dan doen de oosterburen het toch een stuk preciezer in de Duitse taal. Met mijn VWO Duits (en Google) maak ik er het volgende van:

Wegen des stürmischen Wetters musste die Feuerwehr heute wieder ausrücken.

Waarom is de Nederlandse taal zo slordig? Mijn vermoeden is dat deze termen niet altijd op één hoop werden gegooid, getuige het oud Nederlandsche woord onweder en de term wederom. Door de eeuwen heen zijn de termen gedegenereerd tot één enkel woord. Door al die jaren heen hebben de Nederlanders het niet zou nauw genomen met hun taal, dus waarom zouden we dat in de 21e eeuw wel moeten doen? Van mij mogen dus de colleges aan de Nederlandse universiteiten best in het Engels, Duits of zelfs Kantonees (toekomstgericht!) worden gegeven. Het redden van de taal hadden we 500 jaar eerder maar moeten doen, nu is het denk ik de redding niet waard.

Thursday, May 17, 2012

Building a brand

I had this printed at Make Vancouver, so I can build my brand. I will be wearing this during Apple's World Wide Developer Conference, so I can get some exposure for the fine game that is 'the little crane that could'. It is a full colour digital print. I was considering a silk screen print, but that requires reducing the number of colours. I am still toying with the idea of getting an embroidered jacket to go with it.

Tuesday, March 27, 2012

Making good progress on the World Editor

I am making good progress on the world editor for the little crane that could. I am creating a stand alone companion app for the game with which you can build your own levels. The levels are stored in iCloud, so that you can play them on any iOS device you own. You can also send your designs to friends via email. Here is a screen shot of the game menu that shows a user created level in the list.

The world editor and the game are both supporting the retina display of the new iPad. Man, oh man, that 2048x1536 resolution sure looks marvellous, and is ideally suited for level editing.

Tuesday, February 21, 2012

Skycrane

My game the little crane that could is still going strong, so I keep releasing updates for it. Lately, it has been very popular in Japan, not sure why. A lot of Japanese downloads, but the conversion rate in Japanese market is pretty low. Anyway, the next update will feature something special: a Skycrane.

Just like I did for the crane on wheels, I am taking the high road: a proper full blown physics simulation. This means that the forces of lift actually work on the rotor blades, where force leads to acceleration leads to velocity leads to movement. Also, the force that spins the main rotor causes the body of the helicopter to counter rotate, so I apply an anti-torque force with the tail rotor. Note that the tail rotor is not yet visualized in the image. Also missing are wheel struts and some sort of winch with hook that will enable the player to grab objects.

After implementing this elaborate and accurate simulation, I found out that controlling the helicopter was neigh impossible. It was simply too hard to steer due to oscillations and spiralling out of control. That is why I added two PID controllers that sit between the cyclic controller (joystick) and the control surfaces. They translate the player's intent into steering signals, 180 times per second. With PID control you can fix overshoots, oscillations and steady state errors by carefully tuning the proportional, integral and derivative constants. Now the Skycrane flies like a dream: it has nice, yet realistic handling characteristics.

Monday, January 2, 2012

Walk in the park

Because mommy had a day off today, we were able to make a little walk in the park with Annelies this morning. Annelies enjoyed it very much, and loved playing with doggies and getting attention from the women. Nobody can resist her when she puts on her best smile and start giggling. Annelies is excited about her grandparents visit at the end of this month. We all look forward to seeing them again.

Sunday, January 1, 2012

A 1000 soldiers

My explorations of Android Development are starting to find shape. Here is a screenshot from my tablet device showing a lot of the little buggers on the march. Now I have to find a good gameplay mechanic to make directing a small army fun for the player. In my younger years (early 90s) I used to play xbattle on the University's Sun workstations. That was a lot of fun, so it would be an excellent starting point. And I think that a touch interface is a much better fit for an xbattle game than a mouse interface is, so that should give me an edge. The performance is pretty good on the Acer Iconia, despite the modest Tegra2 specifications that don't even include Neon SIMD support.

Saturday, December 17, 2011

Android Explorations


Today I bought an Android powered tablet, the Acer Iconia 7" tablet. As my friends keep telling me, I should start doing Android development, so that I can port the little crane that could to Android devices. Apart from the horrible colours and contrast of the display, I am satisfied with the device so far. Graphics performance seems way behind what an iPad2 can do though, so graphics optimizations are going to be important. Here are some things I learned about Android programming so far:

  • You need to install an SDK and an NDK.
  • As of recently, you can do native development in C without writing a single line of Java code. To do this, see the NativeActivity sample from the NDK.
  • You can do development from the command line without IDE's.
  • Instead of make, you need to use a combination of ndk-build and ant.
  • GLESv1_CM is the OpenGL ES1 library to use. CM stands for COMMON and means that it uses floating point, not fixed point.
  • Doing 'ant debug' and 'ant installd' is often not enough, as I need to do a clean before building. Are the dependencies not set up properly in the sample projects?
  • The emulator cannot do OpenGL ES2, only ES1. When doing ES1 it is super slow, even on a modern mac.
  • The equivalent of GLX for Android is called EGL
  • Android NDK by default targets the ARMV6 devices, which means software floating point emulation. This is very slow.
  • To target ARMV7 with hardware floating point (VFP), add this to jni/Application.mk: APP_ABI := armeabi-v7a
  • To see verbose output of the build process, use ndk-build V=1
  • Loading assets from native code is a painful experience. So instead I convert images to C source code, and build as a shared object. Then I use dlopen() to get to the data.
  • To debug simply run ndk-gdb --start from the project dir.
  • You can set java compiler flags on the ant command line like this: ant "-Djava.compilerargs=-Xlint:unchecked -Xlint:deprecation" debug
  • You can make screenshots with the ddms utility. Select the device and press ⌘S to grab the screen.
  • To incorporate a third party framework, all you have to do is copy the .jar file into your projects ./lib/ directory, and the build system will automagically find and use it.
  • If you want to install certain resource types without compression, then you need to edit your SDK. Change the tools/ant/build.xml file by adding a < nocompress extension="foo" /> to the aapt section.
  • Don't get confused by -msoft-float and -mhard-float, they do not toggle the hardware floating point unit. Instead they influence the convention for passing function arguments. So using -mhard-float will only get a modest speed bump, at the cost of decreased ABI compatibility.
  • in jni/Application.mk you need to keep APP_PLATFORM set to android-20 or lower. At android-21, downward compatibility breaks, and on a pre-android L device, your app will crash with a 'failed: dlopen failed: cannot locate symbol "rand" referenced by...' error.
I am using The Android NDK Beginner's Guide as reference, as well as a guide by IIvan Vučica. That last one is pretty ambitious: it sets up the development environment so that you can do Objective C for Android. However, I decided to keep it simple, and do my project in C.
There is an excellent GDC presentation from Lars Bishop of nVidia on android development.
For future reference, you need to set up some environment variables. This is what I use in my .bashrc file:
export ANDROID_NDK_ROOT=$HOME/android-ndk-r9d
export ANDROID_SDK_ROOT=$HOME/android-sdk-linux
export NDK_MODULE_PATH=$HOME/apps:$HOME/src
PATH=$PATH:$ANDROID_NDK_ROOT:$ANDROID_SDK_ROOT

Friday, December 16, 2011

First Art

Annelies made her first art today at day care. Well art, not sure if you can call it art, but she did paint a picture. Some bold use of colour! The teacher misspelled her name though.

Thursday, December 15, 2011

Nieuwe Nederlanders / New Dutchies

En met deze handdruk is Amy een Nederlandse geworden. Haar man is Nederlands, haar dochter is Nederlands, maar dankzij Amy's Nederlandse moeder is Amy nu genaturaliseerd door de deputy consul in Vancouver.

And with this handshake, Amy became a Dutch citizen. Her husband is Dutch, her daughter is dutch, but thanks to Amy's Dutch mother, Amy could be naturalized by the deputy consul in Vancouver.

Tuesday, December 6, 2011

Don't bother buying Infinity Blade II

So, after all that hype, I decided it was time to find out what Infinity Blade II was all about. I've heard things attributed to it as 'best looking game on iOS' and such, so as a game developer myself I wanted to see it. So I pay the $6.99, got my fancy noise cancelling headphones for the optimal experience, and then..... NOTHING! The game crashes during the title credits. Tried a few times, a 100% crash. I stopped ALL backgrounded apps on my iPad2, and tried again... Crash.

I've noticed this weird trend where the bigger the studio/publisher, the more crashes I see. Why do these big studios get away with publishing crap, and still rank among the top grossing titles? I noticed it with EA's SimCity Deluxe for iPad. The names don't get any bigger than that: EA, Sim City. Yet, they are unable to create a stable experience without crashing. My advice to the consumers here: forget about that big studio crap, and buy indie games. You will typically get email support from the author directly, and there is someone who actually cares about you. Don't let EA and Chair Entertainment get away with this: just stop buying from them.

And you don't have to take my word for it, there are plenty of crash reports from users. In case someone at Chair entertainment decides to do something about it, here is the log of a run where there is not a single other app running in the background:


Dec 6 18:35:18 unknown kernel[0] : launchd[11064] Builtin profile: container (sandbox)
Dec 6 18:35:18 unknown kernel[0] : launchd[11064] Container: /private/var/mobile/Applications/6CD18407-B4A9-4692-AA34-D07EBAF21381 [69] (sandbox)
Dec 6 18:35:18 unknown SwordGame[11064] : Installing signal handler
Dec 6 18:35:19 unknown SwordGame[11064] : Unknown movie state 0
Dec 6 18:35:19 unknown kernel[0] : virtual void AppleCLCD::mieEnable(bool), enable: 1
Dec 6 18:35:20 unknown SwordGame[11064] : This device is [iPad2,1], enum value 5
Dec 6 18:35:20 unknown sandboxd[11065] : SwordGame(11064) deny file-write-data /private/var/mobile/Library/Mobile Documents/8XJ6WJ8Z84~com~chairentertainment~IB2
Dec 6 18:35:21 unknown kernel[0] : launchd[11067] Builtin profile: gamed (sandbox)
Dec 6 18:35:22 unknown gamed[11067] : 18:35:22.436090 com.apple.AVConference: GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.221:4398";
"gk-commnat-cohort" = "17.173.254.223:16386";
"gk-commnat-main0" = "17.173.254.222:16384";
"gk-commnat-main1" = "17.173.254.222:16385";
}
Dec 6 18:35:23 unknown SwordGame[11064] : 18:35:23.312345 com.apple.AVConference: GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.221:4398";
"gk-commnat-cohort" = "17.173.254.223:16386";
"gk-commnat-main0" = "17.173.254.222:16384";
"gk-commnat-main1" = "17.173.254.222:16385";
}
Dec 6 18:35:23 unknown kernel[0] : virtual void AppleCLCD::mieEnable(bool), enable: 0
Dec 6 18:35:23 unknown SwordGame[11064] : Initialize!
Dec 6 18:35:23 unknown SwordGame[11064] : FBDelegate: !
Dec 6 18:35:23 unknown SwordGame[11064] : SetAppID to 152777738124418 / (null) / (null)!
Dec 6 18:35:23 unknown SwordGame[11064] : FBDelegate.FB: !
Dec 6 18:35:24 unknown SwordGame[11064] : GLView: 1357870
Dec 6 18:35:24 unknown SwordGame[11064] : GLView: (EAGLView: 0x1357870; frame = (0 0; 1024 768); layer = )
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.25000
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.150000
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.750000
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.2500000
Dec 6 18:35:27 unknown wifid[27] : WiFi:[344918127.366272]: Client itunesstored is background application
Dec 6 18:35:27 unknown librariand[11053] : item update observer error: Connection invalid
Dec 6 18:35:28 unknown SwordGame[11064] : Reading int value for key CurrentSlot369d86c1e1a21755d7f29b7aa7ac2065436e116d
Dec 6 18:35:30 unknown MobileMail[11062] : Received memory warning.
Dec 6 18:35:30 unknown SwordGame[11064] : Received memory warning.
Dec 6 18:35:31 unknown SpringBoard[15] : Received memory warning.
Dec 6 18:35:31 unknown syncdefaultsd[11058] : received memory warning
Dec 6 18:35:32 unknown SwordGame[11064] : Reading int value for key LocalSaves_dvb54c8b744f649484cfcae3478da0ec06
Dec 6 18:35:36 unknown com.apple.launchd[1] : (com.apple.gamed) Exited: Killed: 9
Dec 6 18:35:36 unknown com.apple.launchd[1] : (UIKitApplication:com.apple.mobilemail[0x45a2]) Exited: Killed: 9
Dec 6 18:35:36 unknown com.apple.launchd[1] : (UIKitApplication:com.apple.mobilephone[0x6ebe]) Exited: Killed: 9
Dec 6 18:35:36 unknown com.apple.launchd[1] : (UIKitApplication:com.chairentertainment.IB2[0x11fc]) Exited: Killed: 9
Dec 6 18:35:36 unknown UserEventAgent[12] : jetsam: kernel termination snapshot being created
Dec 6 18:35:36 unknown SpringBoard[15] : Application 'Mail' exited abnormally with signal 9: Killed: 9
Dec 6 18:35:36 unknown mediaserverd[43] : 18:35:36.366 AudioSessionSetClientPlayState(11064): cannot get ClientInfo
Dec 6 18:35:36 unknown mediaserverd[43] : 18:35:36.532 AudioQueue: Error 'ini?' from AudioSessionSetClientPlayState(11064)
Dec 6 18:35:36 unknown kernel[0] : launchd[11070] Builtin profile: MobileMail (sandbox)
Dec 6 18:35:36 unknown SpringBoard[15] : Application 'FaceTime' exited abnormally with signal 9: Killed: 9
Dec 6 18:35:36 unknown SpringBoard[15] : Application 'InfinityBlade2' exited abnormally with signal 9: Killed: 9
Dec 6 18:35:37 unknown ReportCrash[11069] : Saved crashreport to /Library/Logs/CrashReporter/LowMemory-2011-12-06-183537.plist using uid: 0 gid: 0, synthetic_euid: 0 egid: 0
Dec 6 18:35:38 unknown librariand[11053] : client connection is invalid: Connection invalid

Hover City at night

Hover Biker version 1.0 was just uploaded to Apple for review. Hopefully they get to it before dec 22, at which time they will stop processing submissions for a week. It would be really nice to have my game available on the app store before Christmas. I've put in a night-time level in the game, which brings the number of levels to 6 free levels, 7 premium levels and 1 tutorial level. I keep wondering how well it will do on the app store. I am hoping to replicate Little Crane's success, but as a worst case scenario, I can't see it do any worse than Panzer Class, which does not sell spectacularly, but still brings in money. But the good news is that every iPad sold by Apple this month is a new potential customer.

Wednesday, November 30, 2011

Gameplay Video

Here is a video that shows the gameplay in my new game Hover Biker. I shot it with a webcam pointed at my monitor fed with an HDMI signal of the iPad2 in mirroring mode. So the quality is not that great. I would have liked to record it with a BlackMagic Hyperdeck Shuttle, but BlackMagic is not responding to inquiries about iPad2 compatibility of their product. Too bad, iOS devs could be a large customer base for them. Feel free to critique, suggest or discuss it, over at the Hover Biker thread at the Touch Arcade forums.

The music is again by the highly talented Johan Stolk who composed the score, and played all the instruments as well. Please note how I timed the first long draw on his guitar with the moment that the robot pushes the right throttle lever. I can't stop watching that.

Keep an eye out on App Battleground where there may appear a review of my game, which is now available at the app store.


Thursday, November 24, 2011

Teaser shots from my new game

Hot off the press... some teaser shots of my new game that is currently under development: Hover Biker. In many ways it will be a better game than the little crane that could. Better graphics, more action, and more mass appeal. What has not changed is a first-rate unsurpassed physics simulation at the root of the game.

This time around, I purchased professional 3D artwork for the city environment. Unlike my own art (which we call programmer art in my industry) it has textures applied. The game will feature a very rich city environment that is completely accessible for the player. This is the opposite of a 'game on rails', if your hover bike can reach it, you are free to visit every nook and cranny of the city.

I will release the game with plenty of challenging levels, but just high speed hovering and pulling stunts with the hover bike is a treat in itself. The game should be in the app store for iPad and iPhone this Christmas. I have a feeling that this game could do very well, and is capable of making some big waves on the app store. There is potential to equal or surpass little crane's success.