Below the surface

This week, I worked on implementing a few Lingo commands that required some significant backend work, but not much in the rendering code where I have spent so much of my time. I mentioned that I had worked on a custom cursor implementation, and I spent the first part of the week fixing bugs there. Now cursor bitmaps like the starfish on the island are properly displayed at the proper position, whereas after my initial work just a black box showed.

Early in the week, I fixed a subtle rendering bug that had plagued Spaceship Warlock for a while. You’ve seen how the Stambulian policemen in Warlock were bright green; well, this was about the same as the keying colour that the MacGUI was using for border transparency. Once I spotted this, the fix was easy – and also prevented a redundant surface copy. (Yay for performance improvements!) Here you can see how the erroneously applied transparency actually gave a nice look to an otherwise bland wall in Stambul:

I also finished the implementation of custom colour palettes. For a long while the opening to Chop Suey looked all psychedelic. It turns out that a recent refactoring swapped around the order of palette loading so ScummVM was given the wrong palette to use. My partial fix for this revealed that our recently-added target Majestic used a castmember palette, which had been loaded before – albeit improperly. So over the weekend I expanded our Director palette manager to support custom palettes alongside the half-dozen default Mac ones. This also brought along basic support for the puppetPalette command, which controls the palette from Lingo. Now, Chop Suey and Majestic are looking quite handsome:

This project came later in the week, however. I first implemented sound fading, which more intense than I first knew. Since multiple movies can be running at once, my knee-jerk blocking fade loop didn’t work out. Instead, I needed to integrate the sound fade with the existing score stepping methods. I’m amused that that this was one of my largest commits for the week. (Thankfully, though, transitions do seem to block in the original – that would be a pain to refactor.)

Finally, I scratched my head for a while on an issue that @sev has since begun looking into. An interesting Director target is Macromedia’s own guided tour, which takes you “behind the scenes” at their studios to introduce new features of Director. Our renderer implicitly assumed that bitmap sprites had the same dimensions as the underlying castmembers, unless the dimensions had been modified from Lingo. Well, our smartly-dressed friend from the guided tour dismissed that theory:

What’s on the left is the original sprite (plus arms), and on right is the original castmember. ScummVM draws them both the same size. I would never have noticed, except that the sprite for his moving mouth appears all out of place when he isn’t the right size. Director does indeed have an option to scale individual sprites in the score, and we were reading this information in for bitmaps… but when I tried to use it there were puzzling discrepancies in the dimensions we expected and what the file clearly said. I still haven’t figured out why.

It’s been a good week over all, with interesting tasks both in and outside GSoC. You’ve perhaps seen on my bio that I like playing music. One of my friends recruited me to play piano for her upcoming violin competition, so when I need a break from coding I spend a few hours with the interesting sonorities of the great American composer Samuel Barber. And, at university on the weekends, I am working on using machine learning to control dielectric elastomers – smart materials that show much promise for soft robotics.

Lots of chop suey

Hey there!

My big showcase for the week’s work is a few scenes from the kids’ game Chop Suey, one of our primary Director 4 test cases:


Just a few weeks ago, Chop Suey ran at an almost unplayable crawl in ScummVM. Part of this was its reliance on Matte inks, for which I implemented a simple surface caching scheme and shaved about 20% off our buildbot’s target test time for Spaceship Warlock. This also made Chop Suey run much faster, though it still consumed CPU

Last week I called Chop Suey a Lingo-heavy game, and I was referring to how much it controls animation via puppets and the updateStage command. Because, as you saw, its cursors are bitmaps and certainly do not fit in the standard 16×16 Macintosh cursor box, Chop Suey introduces its own mouse update code and calls for the stage to be updated several dozen times each frame. Most of the inefficiencies were here.

I spent the early part of the week in much trial-and-error, working out the pieces of the renderer that were most inefficient under such repeated application. The idea is to do a little bit of work up front – checking flags and so forth – so the expense of redrawing a region of the screen is saved. (As I have realized, even when working on Chop Suey, very subtle bugs can arise from forgetting to check a rendering flag.) Even at usual framerates without much Lingo that doesn’t matter very much, but Lingo-heavy games like Chop Suey have shown dramatic improvement.

I also implemented another feature that is notable in Chop Suey by its absence. I said that Chop Suey does its own cursor handling. Well, the window manager was still drawing a regular cursor atop the bitmap, which looked pretty ugly. Near the end of the week, though, I added a flexible cursor class for the three cursor types Director can use: built-in cursors, cast (bitmap) cursors, and resource cursors. The last type is important for Majestic: Alien Encounter, but I haven’t seen custom cursors used much elsewhere. It was fun to implement, though. As a nice byproduct in Chop Suey, the default cursor is now properly turned off.

Oh, and I also spent most of a day trying to discover why some textboxes in Spaceship Warlock weren’t rendering properly, along with some other nettling MacGUI issues. The issue actually lay in the cast loading code, which I hadn’t touched much, but it’s always satisfying to squash a bug and learn more about the codebase in the process – even if your “fix” breaks other stuff. 🙂

Rendering my progress

Hey there!

After last week’s post, I nearly finished with the last major piece of the ink types – applying foreground and background colours on the fly. We had some idea of when this colour-application process took effect, but deducing the rules and working out the patterns took a while. I have gained a new appreciation for the power of bitwise operations through this process. My next step will be extending all this logic to other colour depths, but I probably won’t get to that this week.

It’s getting late now and I can’t find the test movie I had made to demonstrate this work. I’ll look at it tomorrow and post a video demonstration of my work then.

There is still some optimization that must be done, including eliminating my reliance upon the window manager’s slow colour finder and implementing some sort of colour caching. (The inked operations are often not applied directly to the colour value; it must first be split into its components and then recombined in the palette space.)

I also performed some fine-tuning on the data structures used for rendering, to ensure that our pixel-based callback is quite fast. Lots more refactoring went into that. Finally, last week I implemented some obscure features, like the constraint and stretch of sprite. The latter allows a sprite to be arbitrary scaled to another bounding box, and implementing that feature largely finished my goal of having self-contained blitting routines for our engine.

Many of the tasks currently in my Trello channel are concerns with MacGUI elements that don’t impact most real games. These bugs will still take some work, but as I am working on those I also want to get the graphics in Chop Suey (and other Lingo-heavy titles) running smoothly and efficiently. Today I chased bugs and inefficiencies in the rendering pipeline. This is a hefty task, as Chop Suey often uses about 70-75% of my system’s CPU when it is running in ScummVM. With the discoveries I made today, however, taking the slack out of the renderer should be eminently doable.

That was fast!

Another week has gone by quite quickly. After taking some time off for Independence Day here in the US, I can’t believe that another Monday has passed. Last week I talked about a major update to our renderer, and I finished that pretty early last week. There was some major refactoring involved, but my work – splitting out our renderer into a Stage class and moving to traditional dirty-rects handling – worked well with some of the major refactoring that djsrv had been wanting to do for a while. Going into this week, our engine’s code is far more modular (thanks primarily to djsrv), and the graphics are looking good. All this we showed off to John Henry Thompson last Thursday.

First, I finished implementing the puppetTransition command, which allows you to call transitions from Lingo. As part of this, I reworked the transitions pipeline to support only drawing a transition on the changed area of the screen. This took a lot more work (and many paper sketches) more than I was expecting, as some of the transition algorithms had interesting behaviour when I tried to clip them.

I also did some more work on the ink types, including making an efficient interface for the ink types that use implicit mattes or masks. Over the weekend I worked on what was for a long time a big irritation of mine – sprites with scripts did not highlight (or, in Director parlance, hilite) on click. When I tried to work on this before, I found that simply testing for a script on the sprite was far too broad; there were many erroneous inversions. It turns out that for bitmaps there was a special flag, and for shapes (as far as I could discern) only one ink type where this effect showed. I hadn’t looked much at the Director file format before, but I found where that flag was and also uncovered some other unknown fields in bitmap casts (primarily palette information). Working there led me to some nice condensing of our sprite code, which I pushed this morning. That’s one more step to making The Apartment realistic!

Overall, though, last week felt like mostly under-the-hood changes and small optimizations to individual movies. Right now I’m working on the graphics code for efficiently setting the foreground and background colour of puppeted bitmap sprites, and rendering this on-the-fly.