Dali Clock 2.31
I finally got the iPhone/iPad port working.
It was ridiculously difficult, because I refused to fork the MacOS X code base: the desktop and the phone are both supposedly within spitting distance of being the same operating system, so it should be a small matter of ifdefs to have the same app compile as a desktop application and an iPhone application, right?
Oh ho ho ho.
I think it's safe to say that MacOS is more source-code-compatible with NextStep than the iPhone is with MacOS. It's full of all kinds of idiocy like this -- Here's how it goes on the desktop:
- NSColor fg = [NSColor colorWithCalibratedHue:h saturation:s brightness:v alpha:a];
[fg getRed:&r green:&g blue:&b alpha:&a];
[fg getHue:&h saturation:&s brightness:&v alpha:&a];
But on the phone:
- UIColor fg = [UIColor colorWithHue:h saturation:s brightness:v alpha:a];
const CGFloat *rgba = CGColorGetComponents ([fg CGColor]);
// Oh, you wanted to get HSV? Sorry, write your own.
It's just full of nonsense like that. Do you think someone looked at the old code and said, "You know what, to make this code be efficient enough to run on the iPhone, we're going to have to rename all the classes, and also make sure that the new classes have an arbitrarily different API and use arbitrarily different arguments in their methods that do exactly the same thing that the old library did! It's the only way to make this platform succeed."
No, they got some intern who was completely unfamiliar with the old library to just write a new one from scratch without looking at what already existed.
It's 2010, and we're still innovating on how you pass color components around. Seriously?
You can work around some of this nonsense with #defines, but the APIs are randomly disjoint in a bunch of ways too, so that trick only goes so far. If you have a program that manipulates colors a lot, you can imagine the world of #ifdeffy hurt you are in.
Preferences are the usual flying circus as well. I finally almost understood bindings, and had a vague notion of when you should use NSUserDefaultsController versus NSUserDefaults, and now guess what the iPhone doesn't have? Bindings. Or NSUserDefaultsController. But it does have NSUserDefaults. I can't explain.
I basically gave up on trying to have any kind of compatible version of either Cocoa or Quartz imaging that worked on both platforms at the same time -- my intermediate attempts were a loony maze of #ifdefs due to arbitrary API wankery like the above, scathing examples of which I have mercifully forgotten -- so finally I said "Fuck it, the iPhone runs OpenGL, right? I'll just rewrite the display layer in GL and throw away all this bullshit Quartz code." (Let's keep in mind here the insanely complicated thing I'm doing in this program: I have a bitmap. I want to put it on the screen, fast, using two whole colors. And the colors change some times. This should be fucking trivial, right? Oh, ho ho ho.)
So I rewrote it in OpenGL, just dumping my bitmap into a luminance texture, and this is where some of you are laughing at me already, because I didn't know that the iPhone actually runs OpenGLES! Which has, of course, even less to do with OpenGL than iPhones have to do with Macs.
I expected the usual crazy ifdef-dance around creating the OpenGL context and requesting color buffers and whatnot, since OpenGL never specified any of that crap in a cross-platform way to begin with, but what I didn't expect -- and I'm still kind of slack-jawed at this -- is that OpenGLES removed glBegin() and glVertex().
No, really, it really did.
That's like, the defining characteristic of OpenGL. So OpenGLES is just a slight variant of OpenGL, in the way that unicycle is a slight variant of a city bus. If you can handle one, the other should be pretty much the same, right?
Again, what the hell -- I can almost understand wanting to get rid of display lists for efficiency reasons in an embedded API (I don't like it, because my screen savers tend to use display lists a lot, but I can sort-of understand it), but given that you could totally implement glBegin() and glVertex() in terms of glDrawArrays() why the hell did they take them out! Gaah!
Anyway, where was I?
Oh, yeah. So Dali Clock works on the iPhone and iPad now, I think. I can't actually run it on my phone, because I haven't gotten over my righteous indignation at the idea that I'm supposed to tithe $100 to Captain Steve before I'm allowed to test out the program I wrote on the phone that I bought. I imagine I could manage it if I jailbroke my phone first, but the last time I did that it destabilized it a lot and I had to re-install.
So if one of you who has supplicated at the App Store troth would like to build it from source and let me know if it runs on your actual device, that'd be cool.
Oh, PS, I just noticed that since I rewrote it in OpenGL, it's now too slow to get a decent frame rate when running full screen on an 860MHz PPC G4. I mean, that machine is only 53× faster than a 16MHz Palm Pilot, and only 107× faster than an 8MHz Mac128k.
This is why I sell beer.