« February 2006 | Main | April 2006 »

March 23, 2006

Chips Ahoy!

Intel chips, that is. I've been working on many things these past few weeks. The "day" job has been Civ4 with scattered showers of a Civ3 patch. We're making great headway on Civ4 - I believe the worst is behind us now. The game is rendering a good 80-90% of everything correctly, and it's playable for a pretty good stretch. I've been working on a crashing bug that's been slowing down progress, but I have a workaround now that'll prevent the crash, although it's not something I'd want to ship in the game by any stretch.

Civ3 is being patched to fix a few crashes and problems with third-party scenarios. It's also being built as a universal binary so it'll be native on the new Intel Macs. That part was relatively easy. The hard part is that network games now seem to go out of sync if there are PPC and Intel clients in the same game. Hopefully I'll have that licked soon - this patch is starting to drag. When you fire up the CodeWarrior Remote Debugger, it gives you a window with a quote at the top: "double your debugging, double your fun!" This quote is equally applicable to networking problems, let me tell you.

For kicks, I've been working on universal binaries of Jedi Academy and Jedi Knight 2. Those are mostly done now. They ran afoul of some bugs in Apple's OpenAL implementation on dual-processor Macs which made them highly unstable, but lucky me - Apple posted a fix for these exact issues a few days back to the Creative CVS. So I'm cautiously optimistic that all I need to do now is grab those latest OpenAL fixes, build it and it'll be ready for testing and release.

We've run into a few Xcode issues that have caused us some interesting times. First is build size. We use precompiled headers to speed up build time, and it helps dramatically. Civ4 is roughly 1500 source files and takes a good 15 minutes to build on the Core Duo chip. The downside to using precompiled headers is that it bloats the .o files. So at the end of the build, we have roughly 1500 .o files that range in size between 3.5 and 6 megs. This in turn gives the linker fits - we can't currently build a universal binary in Xcode for the debug builds as some of the subtarget libraries spew a vm_allocate failure error trying to allocate 1.6 gigs. Thatsa spicy meatball! Still, we're able to build either PPC or x86 and debug those. This bulk also tends to affect the debugger. Breaking into the debugger in Civ4 takes - on the Core Duo - almost 2 minutes. At first I thought it was simply hung or broken but as I was asking one of my colleagues about it, the debugger eventually sprang to life. Luckily some of our smaller projects (like Civ3) don't suffer from this, athough I still have to watch my disk space. I inadvertently chewed up 12 gigs the other day (and filled my hard drive in the process) doing a build of Civ3 Complete followed by a build of Play the World - each takes up around 6 gigs of intermediate space.

We still maintain our PowerPC builds in CodeWarrior, so this helps quite a bit. When we run into problems debugging in CodeWarrior or Xcode, we just switch to the other. Usually one of them is up to the task. Ah, the life of a Mac developer!

March 16, 2006

Release the hounds!

Life with the puppies these past few months has kept us busy, to say the least. We've got it down to a pretty good rhythm now. The puppies (mostly) go into their cages after excursions outside to do their business, although they are far more reluctant to go in their cages after playtime.

We've been letting them out for more and longer times, which has definitely caused some stress for the cats - 4 animals indoors at the same time is, by any measure, a bit much. We're still not sure how that happened.

When the puppies are loose, they have a keen interest in only one thing: each other. They can be briefly distracted only by the call of nature or the smell of cat puke (or cat poop).

Beth mentioned that they're like those 2 brothers in an early episode of Queer Eye. If you've ever seen the show, it's the two brothers who share a house and also a love for dropping to the floor and wrestling on a moment's notice. The puppies will be walking along, and a split second later be at each other on the ground, then back up again.

Beth's cat, Bagheera, has shown a streak of bravery that we never knew existed. He frequently wants to defend us from the puppies, and will go so far as to seek out and slap them on occasion. Luckily for everyone, the puppies are absolutely terrified of the cats. Hopefully it'll stay that way.

Barney has learned how to jump on and off of the sofas and our bed. Kermit is a little slower - he can jump off the sofa, but hasn't learned how to jump up. He will slowly claw his way onto it though, which amuses us to no end since by the time he's up, Barney has usually jumped over him to get off, thus effectively negating his great struggle.

Kermit's collar has become frayed along the loose extra strap part from constant battle with Barney. The loose part of the strap usually dangles below his chin, and because it's 100% frayed, it now looks like he's wearing a stylish black cravat.

March 13, 2006

I'm your ice cream man, stop me when I'm passing by

One of my hobbies is collecting 3.75" Star Wars action figures. I've got a fairly comprehensive collection and I try to keep up with the latest developments. It can be exhausting at times because demand has a tendency to outstrip supply, as is common with most collectibles.

Anyway, Hasbro is running a poll for people to vote for an upcoming figure. They're going to release the final list of 25 shortly, but one of the candidates is the Ice Cream Maker Guy. He even has a name - Willrow Hood. If he makes it, he could steal the title of "most improbable character to be made into a figure" from Jek Porkins - the fat X-Wing pilot from the first Star Wars movie. Hasbro even pimped Porkins in an ad campaign.

March 08, 2006

printf this!

As I sit here waiting for another build to complete, I thought I'd share some tales from the front-line of Win32 game porting. Today's brutal example: printf and friends.

As every C programmer knows, printf (and its relatives, sprintf, fprint, wprintf, etc) are used to spew formatted text to various places. It's really common and you see it all the time as it's a core part of the standard library.

What may not be apparent is that it's a portability nightmare, at least when coming from apps built with Visual Studio. This point has been hammered home over and over while working on Civ4. How can such a basic staple of the language be unportable, I hear you ask? Let me count the ways.

1. The most common problem we hit has to do with wchar string formatting. Visual Studio takes a sharp left turn from the standard here, but in a subtle way. For the non-unicode printf family, you'd typically use the %s token to insert a regular char string, and the %ls or %S formatting tokens to insert a wchar string into the output.

Things get weird when you use the wchar variants, like wprintf. The standard states that, essentially, wprintf takes the same formatting tokens as the printf case: %s for char strings, %ls or %S for wchar strings. Visual Studio, however, does the exact opposite. in wprintf, it uses %s to represent wchar strings, and %S to represent regular char strings. Worse, they've added the notion of %hs to also represent regular char strings in a wprintf statement.

2. The second oddity has to do with 64-bit values. The standard states that something like %lld is the proper token to use for a long-long integer type (i.e. 64 bits). Visual Studio is not down with that though - it uses %I64.

3. The third oddity has to do with NULL string pointers. If you try to print the value of a string, and the pointer itself is NULL, standard-compliant libraries output nothing. On Visual Studio, it outputs "(null)". You wouldn't think this is important, but believe it or not, some games have relied on this behavior. Jedi Knight 2 and Jedi Academy have relied on this to detect the "dual-handed" lightsaber case. The games print a string containing the name of the lightsaber you're using for both hands of your player, send it across the net, and on the receiving end, use the detection of the "(null)" string to determine if the player has two lightsabers or not. This led to interesting bugs where you'd start a game and have a spare lightsaber sticking out of you or other odd behavior.

March 07, 2006

More Q&A from the comments

I don't mind answering questions from the comments, so here's a new batch.

Are you trying to rewrite those pesky libraries you mentioned? Or are you going to do it game-specific (not portable code)?

The biggest stickler is the sound library, so we're substituting it with OpenAL. I think this is a win-win situation. We recently hired a few guys from the now-defunct Mac division at Metrowerks, and one of them (Isaac Wankerl) is digging into this as a sort of trial-by-fire into Mac game porting.

Have you considered writing your own game? What genre would it be? Would you do it cross-platform?

I haven't had time to even think about this. If I did it, it'd be Mac-only unless there was absolutely crazy money to be had by moving it to another platform.

Will you put in any new features into civ4? ones that won't be in the PC version.

At the moment, it doesn't look like it. OpenAL is going in, so depending on how you look at it, that could be construed as a new feature.

Sorry to keep posting, but do you ever work on MAME anymore?

Yes. I started (and mostly finished) a rewrite of the NES GPU in January for MESS, but I need to plug it into MAME (since it's shared code) and get it working there. As for MacMAME, I update it in my spare time. I've been waiting to do a new release when I get time to make it universal, but I may just punt on that and do a PPC-only release since that's easy.

Will Civ4 for mac play on the new intel mac mini?

I honestly don't know. My hunch is that it will push any 3D card pretty hard, and the 3D chip in the new Mini is weak in all the areas that Civ4 needs (hardware TCL, vertex shaders and lots of VRAM). We'll have to wait until one arrives at Aspyr World Headquarters and Civ4 gets closer to release. With that said, I would not buy a Mac mini with the sole expectation of playing Civ4 (or really any modern 3D games) - that way lies sorrow.

Swizzled

The past week, I've been working on a patch for Civ 3 to fix bugs that were reported on the released version. The patch is in testing now and will probably be ready in a few weeks, depending on how the QA process goes.

I was able to fix pretty much all of the reported crashing bugs as well as compatibility issues with play-by-e-mail (PBEM) games and some third-party mods (like Rye's of Civilization). I had to break network compatibility with the current Mac version as a side effect of that. The PBEM games can occasionally contain embedded network data chunks, so Mac users participating in a game that has PC players would typically crash or act oddly when this data was encountered.

Byte-swapping the network data was something I was going to have to do eventually for the Universal Binary builds, so this gave me the perfect excuse to get that done. It ended up being more of a chore than I would have liked though. Byte-swapping the data in Civ3 was a relative breeze compared to sorting out the byte-swapping issues in our DirectPlay8 peer-to-peer code. As it turns out, our DP8 code had to stay in big-endian format or older Mac versions would crash when an updated game advertised itself on the network. This led me down a headache-inducing path whereby I had to swizzle the bytes for our DirectPlay8 stuff so that it stayed in big-endian, and swizzle the bytes in the Civ3 data payloads so that it stayed little-endian. I never thought I'd have to write code to byte-swap Unicode character streams, but now I have.

In the end, I can say unequivocally that I don't care for network code. :-)