Missions of the Reliant

Those who have been using Macs for at least 14 years may or may not remember a space game for old Macs that went by the name “Missions of the Reliant”.

It was a really fun little game with a few missions in it, changable crew members in your ship, powerups for your ship, a nice big galaxy to hang around in, systems that took damage and could be repaired… if you’re thinking Rescue!, don’t, Missions was much better.

Anyway, like all the old Mac games, it’s long since nonfunctional on modern machines. But I wasn’t willing to settle for that, so I pulled up my e-mail and wrote a letter to Michael Rubin, the original author of Missions, asking if I might get the source code and take a crack at porting it to OS X.

His enthusiasm was beyond anything I could have hoped for. I’m very grateful to him for the opportunity he’s given me to bring a classic back to the Mac. I’ll be posting updates here regularly about my progress on the port.

Progress Report 1

Well, I’ve got the code, and I’ve looked it over. Ah, the old glory days of Pascal, inline A-traps, GWorlds, manual event handling… The Mac Toolbox did almost nothing for you; it was a true low-level interface to the OS, something I feel we’ve gotten away from in these days of Cocoa. Sure, OS X has the POSIX interfaces, but they’re a whole different world. Anyway, the code is a real trip back to olden times, and I love every minute of it.

First step was to create the Xcode project. That took about three hours.

Wait, what? Three hours? Well, once you figure setting up the project settings, the target settings, tweaking the things Xcode’s templates don’t get quite right, editing the pregenerated files to not have broken line breaks and incorrect heading comments, and writing the entire Info.plist for the application, that’s a lot of work! I had to look up Info.plist keys, UTI listings, sweep the original source code for the proper value of NSHumanReadableCopyright, and ask a question or two about semantics in the #macdev IRC channel.

Next step, I figure, is to sweep up all the original visual resources – strings, pictures, icons – and reorganize them out of old-style rsrc files into a modern application’s Resources folder. Yes, I’m aware you can still use resource files in OS X, but I feel if you’re going to do something, you might as well do it right!

After that, I have to take a little time out to brush up on my OpenGL 2D, it’s been awhile since I used it and I never did use it for anything this complex. Binding several dozens of textures to represent all the various sprites should be a fascinating undertaking.

I’m enjoying the hell out of myself *grin*. Thanks again, Michael!

Pointless optimization

So I was looking at the macro used to calculate 16-bit parity in pure C without branching:

#define parity(v)   ({ \
        uint16_t pv = (v); \
        pv ^= (uint16_t)(pv < < 8); \
        pv ^= (uint16_t)(pv << 4); \
        pv ^= (uint16_t)(pv << 2); \
        pv ^= (uint16_t)(pv << 1); \
        (uint16_t)(pv & 0x0001); \
    })

It uses GCC’s handy compound statement syntax, but otherwise it’s plain old C. Let’s look at the 64-bit ASM this compiles to at -Os: Continue reading

Clang: one savvy code analyzer!

Given this code:

- (void)calculateData:(int32_t)n intoLeftBuffer:(int16_t *)lbuf rightBuffer:(int16_t *)rbuf
{
    static uint64_t            (*calculateInternalCall)(id, SEL) = NULL;

    if (!calculateInternalCall)
        calculateInternalCall = (uint64_t (*)(id, SEL))[self methodForSelector:@selector(calculateInternal)];
    
    uint64_t    leftEnableMask = self.isEnabled && lbuf ?
                          ((-(is0Enabled & leftEnabled[0])) & 0xFFFF000000000000) |
                          ((-(is1Enabled & leftEnabled[1])) & 0x0000FFFF00000000) |
                          ((-(is2Enabled & leftEnabled[2])) & 0x00000000FFFF0000) |
                          ((-(is3Enabled & leftEnabled[3])) & 0x000000000000FFFF)
                      : 0,
                rightEnableMask = self.isEnabled && rbuf ?
                          ((-(is0Enabled & rightEnabled[0])) & 0xFFFF000000000000) |
                          ((-(is1Enabled & rightEnabled[1])) & 0x0000FFFF00000000) |
                          ((-(is2Enabled & rightEnabled[2])) & 0x00000000FFFF0000) |
                          ((-(is3Enabled & rightEnabled[3])) & 0x000000000000FFFF)
                : 0;

    for (int32_t i = 0; i &lt; n; ++i)
    {
        uint64_t     data = calculateInternalCall(self, @selector(calculateInternal)),
                     lv = data & leftEnableMask, rv = data & rightEnableMask;
        int16_t      *l = (int16_t *)&lv, *r = (int16_t *)&rv;
        lbuf[i] += l[0] + l[1] + l[2] + l[3];
        rbuf[i] += r[0] + r[1] + r[2] + r[3];
    }
}

Where are the two NULL dereferences Clang claims to have found?

Continue reading

Feeling stupid when writing code

We all make mistakes when coding, and some of them are quite deeply foolish. But this particular snafu I just made takes the cake, in my opinion (dumbed-down code):

// Written as a static inline C function for max
// speed; this is called in a very tight loop, usually
// at something like 40,000 times per second.
static inline uint8_t _readByte(NSUIntger *cursor,
                                const char *bytes,
                                NSUInteger maxlen)
{ return (*cursor < maxlen) ? bytes[*cursor++] : 0x66; }
// Macro for readability, known to be called only from the one function
#define readByte() _readByte(&cursor, buffer, bufferlen)
// Macro to skip so many bytes
#define skipBytes(n) do { \
    __typeof__(n) nn = (n); \
    for (uint8_t i = 0; i < nn; ++i) \
        readByte(); \
    } while (0)
- (void)processBuffer
{
    // assume the declarations of n, cursor, buffer, bufferlen
    // ...
    n = readByte();
    // ...
    else if (n > 0x29)
        skipBytes((uint8_t[16]){0,0,0,1,1,2,0,0,0,0,2,2,3,3,4,4})(n & 0xF0) >> 4);
}

See it? (Hint: Look at the implementation of skipBytes().)

Continue reading