Finger info for

 Work officially begins. Time to get this building under gcc again. Since
 we changed up the source tree layout, the Makefiles from UE2 are basically
 useless. Rather than rewrite them, I'm going to spend some time exploring
 SCons, which came highly recommended by TTimo, the Doom3/linux guy. First
 Unreal steals their colored lighting, then their build system!  :)
 Obviously, there's a lot to be done at this point, but best to start now
 so I'm not scrambling to port a whole engine when UE3 games get closer to
 shipping. Updates as I have them.

Spider-Man 2:
 Gone gold, baby.

 Now open source!

Shrek 2:
 Now shipping!

 For those that weren't at WWDC, Apple gave out preview discs of MacOS X Tiger.
 One of the things Tiger installs by default? OpenAL.framework. No kidding.
 That's basically awesome. It's Apple's version, which is open-sourced and
 residing in's CVS repository.

 Likely I'll move my implementation over to Linux and stop further Mac
 development, so that there is a clear technology path on the Mac. I'll
 devote further Mac development and debugging to the Apple implementation.
 After all, it was partially a stop-gap solution (remember when ut2003 took
 25% of the CPU mixing audio? It was a needed fix, no doubt!), and partially
 a technology proof-of-concept to show Apple what works well in terms of game
 development. No doubt it has served me well.

 In the short term,  I'll have to decide what we ship on the disc with
 Unreal-based games. For ut2004, my implementation is the only one with
 ALC_EXT_capture support for VoIP...this could be added to the other
 implementation, but hasn't been as of yet. My version is apparently a
 little faster, but it's stereo only (but the subversion repository doesn't
 crash on M-Audio 5.1 and 7.1 cards anymore), so Apple's tech is probably
 more attractive for further development by default.

 All of the missing functionality in Apple's implementation could be fixed
 with some elbow grease, which I'm sure will show up one way or another in
 the near future. Overall, this is a very good step forward, and I applaud
 Apple for giving game developers something they really need.

 Latest CVS builds and runs on Solaris/x86 (and presumably Solaris/sparc, too).
 I get a lot of questions about MacOS X: the game _does_ run on OSX, there
 just isn't a nice installer or anything at the moment, so you have to
 compile it yourself. When there's time, I'll put together a shareware-based
 installer, and, if I can find a copy, one that works with the Mac retail disc.

 (Yes, this is still being worked on.)

Unreal Tournament 2003:
 There's an exploit in the ut2003 network code, so here's a new build.


 The Linux one has about a million changes over the stock 2225, since it's got
 all the MacOSX work on top of it. Consider it beta. The Mac version has one
 or two fixes, so it's worth updating.

Unreal Tournament 2004:
 If Mac retail installer crashes on you, use this:

 Linux (x86 and amd64) official 3236 patch (new build with load times fixed):

 MacOS X (un?)official 3236 patch (YES, this is newer than 3229):

Call of Duty:
 1.4 is out, now with PunkBuster support:

 This is a 1.4 server with an exploit closed. Admins should all upgrade:

Postal 2 Share the Pain:
 Linux demo:
 Linux retail: In beta testing (apply at
 Mac retail: In beta testing (no more applications, please!)

America's Army:
 2.1.0 is out for Linux and Mac:

Other stuff:
 Mac::Glue is the best thing since sliced bread.

 I have about 20 gigabytes of MP3s on my Linux box, and I want to put them
 in an iTunes library on the Mac. The music is stored like this:


 So I copy this over to the Mac, try to use iTunes's "Add to Library" option.
 It renames all the files, strips off the track number, and sorts them
 alphabetically by track name, which is dumb. I turn off the "copy to library"
 preference (since I don't really want the music copied/moved anyhow), and
 it still can't handle this.

 Plus, I'd like a playlist for each album, which is out of the question.

 iTunes is pretty controllable via AppleScript, which I don't want to take the
 time to learn. The basics of the interface are simple enough:

   tell "iTunes" to add filename

 etc, but i didn't want to spend time figuring out how to get file listings
 and iterate over them in AppleScript. Enter pudge's excellent Mac::Glue
 perl module, which basically uses Reflection to make an AppleScript interface
 into a Perl one. Pretty sweet.

 So here's my code. It counts on your mp3s being in a certain structure, but
 it'll add them to the main library, create a playlist named album_name, add
 the mp3s to that, and then correct the playlist name once iTunes has access
 to the id3tags. It also sets the "track number", which organizes the tracks
 correctly (not by this moronic alphabetical-by-track-name method)...they are
 sorted correctly in both the playlists and the main library view.

 None of these albums have associated artwork, but the creative could automate
 the pulling down of this from Amazon or iTMS at a later date. There
 apparently already are AppleScripts for this.

 Whole process took about 40 minutes to import 20.31GB (5269 mp3 files). This
 would take longer if iTunes was commanded to copy the files, but we were
 mostly just building a playlist database. Both Perl and iTunes spent a lot
 of time idle, which I guess was waiting on disk i/o.

 Let's see if IcculusFinger throws up on Perl code...

#!/usr/bin/perl -w
# You need Mac::Glue for this to work. To download and install it, run this,
#  as root, from the Terminal:
#     perl -MCPAN -e 'install Mac::Glue'
# And say "yes" to anything it asks you about adding stuff to the queue.
#   Then run this:
#     perl -w ./ /where/i/keep/my/mp3s
# Written by Ryan C. Gordon (

use warnings;
use strict;
use Mac::Glue;
use Mac::Errors '$MacError';

my $mp3lib = shift;
die("\n\nUSAGE: $0 <mp3dir>\n\n") if not defined $mp3lib;

sub check_error {
    return if not $^E;
    print(" - AppleScript error: $MacError\n");
    exit 1;

print(" + Starting converter...\n");

opendir(DIRH, $mp3lib) or die(" - opendir('$mp3lib') failed: $!\n");
my @artists = readdir(DIRH);

my $itunes = new Mac::Glue 'iTunes';
print(" + activating iTunes...\n");
$itunes->activate();  # load iTunes if needed.

my $d = '';
foreach (@artists) {
    next if $_ eq '.DS_Store';  # some Mac thing.
    next if $_ eq '.';
    next if $_ eq '..';
    my $fullartist = "$mp3lib/$_";
    print(" - '$fullartist' is not a directory!\n"), next if not -d $fullartist;
    my $artist = $_;
    print(" + Artist: $artist\n");
    $d = "$mp3lib/$artist";
    opendir(DIRH, "$d") or die(" - opendir('$d') failed: $!\n");
    my @albums = readdir(DIRH);
    foreach (@albums) {
        next if $_ eq '.DS_Store';
        next if $_ eq '.';
        next if $_ eq '..';
        my $fullalbum = "$mp3lib/$artist/$_";
        print(" - '$fullalbum' is not a directory!\n"), next if not -d $fullalbum;
        my $album = $_;
        print(" +   Album: $album\n");
        $d = "$mp3lib/$artist/$album";
        opendir(DIRH, "$d") or die(" - opendir('$d') failed: $!\n");
        my @files = readdir(DIRH);
        my @tracks;
        foreach (@files) { next if not /.mp3\Z/i; push @tracks, $_; }
        next if (scalar(@tracks) == 0);
        @tracks = sort @tracks;
        my $playlist = $itunes->make(new => 'user playlist', with_properties =>
            name => $album,
            shared => 1,
            smart => 0,
            visible => 1,
            shuffle => 0,
            song_repeat => 'off'

        my $tracknum = 1;
        my $renamed = 0;
        foreach (@tracks) {
            my $trackname = $_;
            my $trackfile = "$mp3lib/$artist/$album/$_";
            print(" +     Track: $trackname ($tracknum)\n");
            my $track = $itunes->add($trackfile, to => $playlist);

            # Rename playlist from the album's dirname (the_album_name) to
            #  whatever is in the first id3tag we see (The Album Name), since
            #  it's more likely to be right.
            if (not $renamed) {
                my $realalbum = $track->prop('album')->get();
                if ((defined $realalbum) and (not $realalbum =~ /\A\s*\Z/)) {
                    $playlist->prop('name')->set(to => $realalbum);
                    $renamed = 1;

            # set track number; this causes it to be sorted correctly in
            #  the primary library view...
            $track->prop('track number')->set(to => $tracknum);



exit 0;

# end of ...


When this .plan was written: 2004-08-07 21:42:18
.plan archives for this user are here (RSS here).
Powered by IcculusFinger v2.1.24
Stick it in the camel and go.