One of these days

4am, woken up by Madame Stefanie, my human alarm clock (no she doesn’t go off … pervert…)

5am, arrival at airport Graz

9:30am, arrival in Zürich

9:45-15:00 What happens at Google, stays at Google! EOT…

3:15pm, lol, i was in your base! now i get drunk! (7 Franken for 0.33liters of beer? really zürich? taxi driver told me i got screwed)

23:39Back in the parking lot of Graz airport. I’ve been away for how long??? wtf!

Google == Willy Wonkers Chocolate Factory – Chocolate + more of the crazy :p

Thanks to Viola and Aleksandra for making this happen. It was an awesome (and exhausting) day.

Libgdx multitouch & emulator woes

Today i implemented multitouch support. It was in there for quite a while already, i just didn’t implement the backend. The Input interface has a few new methods.

Note that Input.supportsMultitouch() is a hint at best. For Android version 1.5 and 1.6 this will always report false as there’s no multitouch API support there. For Android 2.0 it will also return false even if there’s multitouch support by the device. A big thank you to the guy who forgot to add PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH to API version 5 (==2.0 the one were multitouch was introduced) and 6 (2.0.1 the bug fix update…). As this is not available in the 2.0 and 2.0.1 APIs i can’t query for multitouch support. I simply assume there is and handle all events accordingly. Everything works as expected on 2.1 and 2.2. Given that 2.0 is dying already it shouldn’t be that much of a problem. Note: this does not mean that multitouch won’t work on 2.0/2.0.1. It will if available, you just don’t now whether it’s there or not by calling Input.supportsMultitouch().

I wrote a very simple test that shows you how to use this stuff. Each finger gets an id, the first finger always has id 0, all subsequent fingers have 1, 2 and so on. If fingers with id 1 and 2 stay on the screen and finger with id 0 is lifted the other two keep their id. If a new finger is put on the screen it will receive the first free id, in this case 0. I especially like how that is totally not documented in the MotionEvent reference or anywhere else. I guess multitouch is a minor feature anyways.

Which brings me to the next item of todays list. Some people reported that all the tests, the hello world app and gdx invaders crash on the emulator. I also got some logcats that told me that the new BufferUtils.copy() method is the culprit. If you remember the earlier post about bulk putting float arrays to direct buffers: It’s slow. So i wrote a simple JNI method which speeds this up tremendously. It worked flawlessly on all devices i have (Samsung Galaxy Leo, HTC Hero, Motorola Droid, Nexus One) as well as on the desktop. The emulator just crashes with a sigseg at address deadd00d, which seems to be Androids variant of deadbeef…

It took me 3 hours to figure out what’s wrong. Here’s the C code that crashed:

Here’s the code that doesn’t crash the emulator:

Yes, it’s a matter of order. It seems that on the emulator you have to call GetPrimitiveArrayCritical before GetDirectBufferAddress. I might be ignorant but i think it shouldn’t really matter. This believe was reinforced by the fact that the code worked on all other platforms and devices, just not on the emulator. I’ll look up all the info i can on the two methods and see whether it’s my fault. If not than i’ll file my first ever Android bug…

From the JNI documentation of GetPrimitiveArrayCritical: “After calling GetPrimitiveArrayCritical, the native code should not run for an extended period of time before it calls ReleasePrimitiveArrayCritical. We must treat the code inside this pair of functions as running in a “critical region.” Inside a critical region, native code must not call other JNI functions, or any system call that may cause the current thread to block and wait for another Java thread. (For example, the current thread must not call read on a stream being written by another Java thread.)”. So, it doesn’t exactly seem like a restriction to me. It only excludes method that might block the current thread. Dunno whether it’s a bug in Dalvik or specified behaviour. The fun part is that it only crashes on the emulator.

How to find out whether multi-touch is supported on Android…

Edit: wall of text sorry.
Correction: Android devices are indeed required to have a touch screen per CDD
Update: finished reading the 2.2 CDD. Section 8.5 Touchscreen input: “SHOULD support fully independently tracked points, if the touchscreen supports multiple pointers.”. So i gather it’s not a MUST. Oh well…

So, for nearly a year now i’ve been very disappointed with how multi-touch works on Android. Or rather does not work on most devices. This is nothing we can blame on Google. Some hardware manufacturers (HTC, Motorola to name the most prominent ones) don’t like bundling proper multi-touch screens with your 500$ phones. Why? I have no freaking idea, i imagine the cost of a proper touch pad wouldn’t be that much higher and i’d even be willing to throw out a few extra bugs to have proper multi-touch.

There’s two types of multi-touch functionality on Android. Let’s call them gesture multi-touch and real multi-touch. Gesture multi-touch is the only thing available on phones like the Nexus One. It features a “self capacitive” touch pad suited for gestures like pinch zoom but not suited for keeping track of multiple finger positions. Check the link to find out more. Real multi-touch on the other hand allows both, gesture detection as well as keeping track of multiple individual fingers.

Now, i could live with that fact if only there was a way for me as a programmer to know what’s actually supported by the phone my app is running on. Last time i checked (and i checked long and hard) there was no such thing. That was when API version 6 came out.

I wanted to implement multi-touch support for libgdx today and checked again. And, oh my fsm, i found something in the PackageManager class. Namely the following constants to be used with PackageManager.hasSystemFeature():

  • PackageManager.FEATURE_TOUCHSCREEN, The device’s display has a touch screen.
  • PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH, The device’s touch screen supports multitouch sufficient for basic two-finger gesture detection.
  • PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT, The device’s touch screen is capable of tracking two or more fingers fully independently.
  • For games we want PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT for obvious reasons. The N1 will return false. I have to test with the Motorola Droid, but it should also return false. Its screen is also severly broken.

    Seeing this i was happy at first. Then i realized that PackageManager.FEATURE_TOUCHSCREEN is actually pretty scary. There will be Android devices without a touch screen? I thought that was a minimum requirement? Maybe the documentation is just not extensive enough though and it serves as a valid but ultimately useless counterpart to PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH. If that’s not the case than i’m really afraid of the future. I assume that all the game UIs out there are touch driven, those would brake immediatly. Of course you could check at startup whether the device has a touchscreen at all. But…

    Those 3 constants are API Level 7 and 8, that is 2.1 and 2.2. Now, a lot of devices have received an update to 2.1 already, even my trusty HTC Hero. But i’d assume that only very low-budget devices would not have a touch screen. I’d further assume that those wouldn’t sport 2.1 or 2.2 either than. As a developer i’d have no chance of detecting the missing touch screen then.

    Why those constants weren’t there from at least 2.0 onwards is a riddle to me. Better late than never though, at least things are moving forward.

    In order to access the market with a new device each manufacturer has to pass the Android compatibility program. This program is executed by Google itself which sets the minimum software and hardware requirements a device has to fulfill for a specific version in order to be allowed to access the market. Additionally the software and hardware stack have to pass the compatibility test suite as a final test. Real multi-touch support from day 1 would have been the bestest thing since sliced bread for Android in my opinion. I can live with a software renderer for OpenGL, even one that does only affine texture mapping. But having this mess of multi-touch support is just sad.

    I still love Android and think Google is doing a fine job! It’s everyone’s fault!