Logo Pending


AGI versus SCI – A Comparison

AGI, which Sierra used up until around the release of King’s Quest IV – The Perils of Rosella, was a strictly linear scripting language with a fairly simple bytecode. Much simpler than SCI’s object-oriented virtual machine. But how do they compare?

Inspired by this one particular book that’s ostensibly about SCI but contains only AGI snippets from what I’ve seen, here’s the first playable room in King’s Quest IV, and how it’s initialized. I’ve left out a bunch of stuff for clarity. Because it’s so simple, AGI bytecode is pretty easy to decompile:

if (justEntered)
{
  set.horizon(84);

  if (!nightTime) { v152 = 1; }
  else { v152 = 101; }
  load.pic(v152);
  draw.pic(v152);
  discard.pic(v152);

  //Place Ego according to the previous room
  if (lastRoom == 1) { position(ego, 141, 82); }
  if (lastRoom == 2) { position(ego, 107, 82); }
  if (lastRoom == 9) { position(ego, 96, 82); }
  if (lastRoom == 10) { position(ego, 80, 82); }
  if ((lastRoom == 11 || lastRoom == 15)) { position(ego, 70, 82); }
  if ((lastRoom == 12 || lastRoom == 14)) { position(ego, 60, 82); }

  //Add some waves in the water.
  animate.obj(o3);
  load.view(55);
  set.view(o3, 55);
  set.loop(o3, 4);
  set.priority(o3, 5);
  ignore.objs(o3);
  cycle.time(o3, 3);
  position(o3, 64, 152);
  draw(o3);

  draw(ego);
  show.pic();
}

Hmm. Compare that to its SCI equivalent. SCI bytecode is much harder to decompile. You can disassemble it, but until SCI Companion came out it wasn’t possible to decompile it. Still here we are:

(instance Room1 of Room
  (properties
    picture 1
    north 25
    south 7
    west 31
    east 2
    horizon 100
  )
	
  (method (init)
    (if gNightTime (= picture 101))
    (super init:)
    (self setRegions: 503 501 504 506)
    (wave1
      isExtra: 1
      view: 665
      loop: 0
      cel: 0
      posn: 203 76
      setPri: 0
      ignoreActors:
      cycleSpeed: 3
      init:
    )
    ; Other waves left out for clarity
    (waves add: wave1 wave2 wave3)
    (wave1 setScript: waveActions)

    ; This part is simplified significantly.
    (switch gPreviousRoom
      (south (gEgo posn: 225 188))
      (north (gEgo x: 225 y: (+ horizon 1)))
      (0 (gEgo x: 220 y: 135))
      (east (gEgo x: 318)) ; Y stays the same.
    )
    (gEgo init:)
  )
)

You might notice that there’s no equivalent to draw.pic and discard.pic and such. The Room class handles that by itself the moment Room1 calls (super init:).

[ , , ] Leave a Comment

Going in-depth on SCI map files

One thing that stood out to me when I look at my collection of Sierra SCI games is that basically all the 16-color and early 256-color games (that is, SCI0, SCI01, SCI1) have multiple resource volumes, but the SCI11 games do not. Not because a lot of them came on CD either, the diskette versions, once installed, had a single resource volume too.

Why do you suppose that is? Why do the diskettes for SCI11 games contain a single resource.000 file that’s been split across them all for the install script to merge back together on the hard drive?

Because the map format doesn’t allow it.

The resource.map file specifies which resources can be found on which disks. For SCI0, it’s a list of six-byte entries. The first two encode the type (upper five bits) and number (the lower 11 bits), the next four have the volume number (upper six) and absolute offset in the volume (the rest). If a resource appears on multiple disks, it’s listed once for every appearance. In SCI01, there are only four bits for the volume number, trading amount for space.

In the later versions, the map file starts off with a list of offsets for each type listed in the map. With this list and a contract that the map entries are sorted by type, the interpreter can look up a given type of resource much faster. Since we already know that this part of the list only contains resources of a given type, we can use the full 16 bit range for the numbers. In SCI1, the next four bytes are just like in SCI01. In SCI11 however there’s only three, and there’s no volume number. Then in SCI2 it’s a straight-up plain 32 bit offset value.

The trick with SCI11 having only a 24 bit range for its offsets is that the value is shifted. They must be aligned on a two byte boundary so that the offset range is effectively doubled again.

As a practical example, let’s look at The Dating Pool. If I open its resource.map in my favorite hex editor and try to look up the second view, it’d go like this.

The first few bytes are 80 2B 00 81 EE 00 82 BB 01. We know the format, so this means that views (type 80) start at offset 002B and background pictures (81) start at offset 00EE, which means the views end there. Skipping ahead to the given offset, we see this: 00 00 00 00 00 05 00 02 26 00. Obviously the first resource (view 0) is at offset zero. Splitting this up into handy chunks, 0000 000000 0005 002602, we see that view 5 (which is the second one in the game data) is at offset 2602 << 1 = 4C04. Open up resource.000 and go there, and the first thing we see is confirmation: 80 05 00 36 44 36 44 00 00. View number 5, 4436 bytes in size both unpacked and packed, no compression, followed by the actual view data. Then there’s a single null byte for padding, and view 10 begins.

[ ] Leave a Comment

Animation Shop

December 23rd last year, I was working on some example material for my seqmaker tool, a converter/player that turns image sequences into SEQ files that SCI11 can play. The DOS versions of King’s Quest 6 and Gabriel Knight 1 used them extensively. At first I wanted to use a GIF sequence from Prince of Persia, the original one, because it has very few colors (32) and the only animated elements in that sequence are the Prince and a touchplate.

The only tool I had available to me to manipulate the GIF was ffmpeg. It wasn’t very helpful as after I’d made the SEQ file and watched it in examine mode, which blanks out everything outside of the changed region, I found that there was very subtle dithering.

One would expect, when the Prince starts to turn around, that he’d be the only thing stored, much like this:

“No. Fuck you and the horse you dithered in on.”

This is simply not acceptable!

To think I’d already spent too long manually undithering the solid black background! So in the end I went with the first shot from Hotel Mario instead. Worked out great.

Now, years ago I used to have a program called Jasc Animation Shop. By the creators of Paint Shop Pro, which I use to this day. The old 8.0 version from Jasc, before Corel bent it over. Importantly, Animation Shop was meant for GIFs, but also supported AVI and could import from sequences. Even more importantlier, it could export to GIF with full quality control. Or at least full enough to ensure it wouldn’t add dither noise. Today I found a copy and tried the thing again for a laugh.

Beautiful.

[ ] Leave a Comment

What even is an adventure game?

That’s a question SCI doesn’t even bother asking.

Weird, I know, considering it’s an adventure game engine.

Or is it? Turns out it’s really not. The “adventure game” part is almost entirely a matter of scripts.

In SCI proper, there is no concept of a player, of a room, of basically anything concrete. The engine only cares about a few data types like List, for which it provides function calls to use them, that the Cast list’s contents are View objects in a duck-typing sense, and that this list is global variable #5. Also, script zero export zero is the starting point. From there, you’re mostly on your own.

A room in SCI is just a particular kind of object that sets up the things you can find inside, handles room-specific inputs, and… that’s basically it. The SCI engine doesn’t even know the difference between an abstract View (some possibly-animated non-background element), an atmospheric effect, an NPC, or the player character. Note that all of those things are still View, in a class-inheritance sense.

The biggest blow to the idea that SCI is an adventure game engine has to be the board games though. Between Jones in the Fast Lane and the Hoyle series, I don’t think anyone could claim otherwise for long.

Contrast that with a certain other engine or two.

[ ] Leave a Comment

On fonts

SCI, being rooted in MS-DOS and from a time before Unicode (fun fact, the first draft proposal dates back to 1988, when King’s Quest 4 came out as the first SCI game), SCI uses an 8-bit string format. That is, each character in a string is one byte, and that’s all it can be. Making strings one of very few standard data types in SCI that aren’t 16-bits and requiring a dedicated kernel call to manipulate (as seen in KQ4 Copy Protection) but that’s not the point here.

American releases of SCI games would normally have font resources ranging only up to 128 characters, with the Sierra logo at 0x01 and ~ at 0x7E. Only caring about newlines, all other characters are considered printable. European releases would include usually not 256 but 226 characters, up to ß at 0xE1, basically copying code page 437 but leaving out the graphical elements among others. This means, of course, that a Russian translation of such a game would require another custom font copying code page 866 instead.

And then there’s the whole thing where SCI Companion uses the Win-1252 code page (it’s not exactly a Unicode application) which makes translated games look pretty wild:

Ich glaube Dir gern, daá Du das tun m”chtest!

That doesn’t look quite right. That’s supposed to be “Ich glaube Dir gern, daß Du das tun möchtest!” And indeed, comparing things between DOS-437 and Win-1252, we see that á and ß are both encoded in the same byte value.

That’s the kind of bullshit Unicode was made for, isn’t it?

Continue reading “On fonts”

[ , ] Leave a Comment

Musings on iMuse

One of the things I think LucasArts got Sierra beat in with regards to their old point-and-click adventure games has to be the music. I don’t mean that the music itself is better, but the underlying technology.

In SCI, a given music track can have cue points and a loop. These cue points can increase or set a value visible to the game engine, and let the game time things accordingly. Notable examples off the top of my head include the singalong text and images in Freddy Pharkas Frontier Pharmacist, the selection highlight following the beat in Quest For Glory, the singalong in Leisure Suit Larry 6… yeah.

But that’s just one way. The song can nudge the game, and that’s about it. A harmless bit of Mickey Mousing at best.

iMuse, on the other hand? The DirectMusic of its day. Remember DirectMusic? Me neither. Anyway, an iMuse song (near as I understand it) has queued triggers and a sense of beat, allowing the game to say “hey, switch to the cartographer’s version of Woodtick” and the song would wait for the current beat to finish, play a little flourish, and seamlessly transition into a different song. You could cancel them too, if you were fast enough. And let’s not get into the most triumphant example I’ve heard so far, X-Wing/Tie Fighter.

I figure if you give an SCI track beat markers, preload a fill riff, and have a script listen for requests, you might be able to approximate the basics. If you’re playing variations of the same song that only differ in instruments, you might be able to mute specific tracks, or send raw “Program Change” messages if you’re really adventurous…

But yeah. That’s why you can have proper MIDI dumps of SCI games, but you can’t quite hack it with most SCUMM games.

[ , , , ] Leave a Comment

Palette Cycling in Space Quest 4

It’s a followup.

Here’s Roger falling through the chronostream in the introduction:

And here’s the EGA release’s take on that shot:

I immediately thought, of course, the EGA release wouldn’t support palette cycling effects. That’s the official EGA release, with an ega320.drvnot the later ones with ega640.drv. Totally different.

But what if I were to make SQ4 VGA use ega640.drv? What would happen? Would the background remain static?

Keeping the answer under the fold for all you epileptic viewers out there.

Continue reading “Palette Cycling in Space Quest 4”

[ , , ] Leave a Comment

Palette Cycling in Larry 5

I distinctly recalled just before posting this that one particular room in Leisure Suit Larry 5 – Passionate Patti does Pittsburgh a Little Undercover Work had a palette cycling effect that bit into the 64 global colors of the palette. So I enabled the debug handler, loaded up ScummVM, and Alt-T’d my way over to room 700.

…It looks perfectly right. That’s not right.

Now, you’ll notice the Fast Forward icon isn’t grayed out. That’s what you get when you cheat, but that’s hardly relevant here.

Had I remembered wrong? Was this the wrong screen? No, surely my memory isn’t that bad? Besides, old adventure games are relevant to my interests. I don’t tend to forget things about those.

But then again, this is ScummVM. What does DOSBox have to say?

Thank you, DOSBox. I figure it must be because ScummVM draws it all in truecolor mode, manually applying the effect to the background, as opposed to the original actually changing the VGA color palette.

(Any political implications are entirely in the reader’s head.)

[ , , , ] Leave a Comment

Evolution of a Title Screen

From day one, the title screen for The Dating Pool has been rendered, with one short intermission. Looking back at my development archives, I felt I should show the unseen. So in the inimitable words of Verka Serduchka… Let’s begin!

The original title screen was a closeup of the main character’s little black book, in what was then planned to be her bedroom. Between the default textures and the book’s cover being edited in post, I honestly can’t remember why I replaced it… but it’s not exactly evocative of a “dating pool”, or any kind of pool, really.

Ah, the original demo release’s title screen. This is actually slightly newer than it should be at this point, with the wine and glass added, but who’s keeping track? Maybe me at best, but I hardly did. Anyway, I’m not gonna hunt down a copy without the wine only to post this version a little later.

At one point I figured the 3D renders could serve as the basis for pixel art redraws. I put hours into this image, only to not use it at all. Honestly, I can’t quite remember why I gave up on that idea. But before the demo was in a playable state, I’d reverted to the render and added the wine. Perhaps it was just to not increase the workload even more, or maybe it was because it didn’t actually help solve some issues with global palettes that I’d hoped it would. Oh well, what’s a few wasted hours when you have this much free time to waste to begin with?

And that brings us to the title screen as it is now. The Itch demo has a slightly earlier version of this screen that’s a bit shinier in silly places, but otherwise it’s the same.

(2018 note: the above paragraph was later outdated by an updated demo release.)

I wonder if should put some animation in this. The old screen had the flickering candles… Anyone?

[ , , ] Leave a Comment