Logo Pending


Police Quest’s flashing siren lights

The flashing siren lights in the title screens for Police Quest 1 and 3 are sort of interesting, because they are not quite a simple matter of calling (Palette palANIMATE) once or twice. In fact it’s called eight times each frame! Here’s the final result:

And here’s the Script at the heart of it:

(instance cycleColors of Script
  (method (changeState newState)
    ; Fun fact: the switch isn't actually needed.
    ; Not in this use-case.
    (switch (= state newState)
      (0
        (Palette palANIMATE 208 213  1) ;blue in the middle
        (Palette palANIMATE 213 218  1)
        (Palette palANIMATE 218 223  1)
        (Palette palANIMATE 223 228  1) ;blue on the side
        ; Note that we're switching from 1 to -1 now.
        (Palette palANIMATE 229 234 -1) ;red in the middle
        (Palette palANIMATE 234 239 -1)
        (Palette palANIMATE 239 244 -1)
        (Palette palANIMATE 244 249 -1) ;red on the side
 
        ; Almost immediately do it all over again
        (= cycles 10000)
        (= state -1)
      )
    )
  )
)

The palette here has a very particular setup. The lowest colors, #208 to #249, are set up like this:

Each of the eight siren colors in the image has its own four-step palette, individually rotated! It looks kinda like this:

If that one black entry wasn’t in the way between blue and red, it’d line up better, but what can you do?

What’s particularly funny about this is of course that no SCI interpreter with fewer than 256 colors implements this feature.

The cycleColors script is still there and is still invoked. Just like with the chronostream animation in Space Quest 4.

[ , , ] Leave a Comment

Save early, delete when you need

There’s one interesting tidbit missing here, which is how deletion (SCI1 and later) is implemented. Namely by manipulating the .DIR file in the script, and not – as any sane person would do – with a kernel call.

So wrote Iskovlun in a comment some time back. Let’s see exactly how insane it really is.

; First we open up the directory file.
; Confusing, I know, to call it a directory file. Perhaps
; "catalog" would be better considering a directory is
; already something else. And in SCI32, they did!
((= fd (File new:))
  name: (DeviceInfo diMAKESAVEDIRNAME @str (gGame name?))
  open: fCREATE
)
 
; The format of a save game directory is pretty straight-
; forward -- a word for the index, then the name, terminated
; with an $0A, repeat until done, end with $FFFF.
 
; (File write:) requires a pointer to the data it is to write,
; so we need to put values into variables, rather than just
; passing them immediately. Well, unless you have SCI11+ with
; the extra file kernel calls I nabbed from SCI32 and a matching
; File class, in which case you could just do (File writeByte:
; $0A) if you were so inclined!
(= ret $0A0A)
 
; Now we write the number and name of each saved game, EXCEPT
; for the one that was selected for deletion.
(for ((= i 0)) (< i numGames) ((++ i))
  (if (!= i selected)
    (fd write: @[nums i] 2)
    (fd writeString: @[names (* i COMMENTBUFF)])
    (fd write: @ret 1)
  )
)
 
; Now we write the terminating $FFFF to finish the catalog
; I mean directory off.
(= ret -1)
(fd
  write: @ret 2
  close:
  dispose:
)
 
; Now that that's done, we can safely delete the actual
; save game file.
(DeviceInfo diMAKESAVEFILENAME (gGame name?) [nums selected])
(FileIO fiUNLINK @str)

I almost feel like doing the so-called sane thing and adding a DeleteGame kernel call to SCI11+.

[ ] Leave a Comment

VGA Versus VESA – A Followup

Back in the days, if you wanted square pixels in your games you had to either switch to 640×480 with only 16 colors or use Mode X, which offered 320×240 with all 256 colors but both of these stored their pixel data in those funky non-packed or non-linear formats.

Sure. Sure. With Mode X you could write a whole bunch of pixels at once. It’s a trade-off, and one that I’d rather not have to make. Give me linear frame buffers or give me death!

But what if there was a third option? Turns out on DOSBox’s approximation of the S3, mode 151h offers 320×240 pixels in 256 colors! Besides the need to switch memory windows to access the bottom 36-something lines, that’s as friendly to work with as anything! And if, unlike me, you write DOS games in 32 bits, even that shouldn’t be a problem!

Too bad whatever VirtualBox exposes on my system doesn’t include one of those — it has no 320×240 at all.

As a bonus for sticking with me for this tomfoolery, here’s DOSBox running a test of mine.

[ ] 2 Comments on VGA Versus VESA – A Followup

VGA Versus VESA

We’re all familiar here with the classic 320×200 pixels, 256 color screen mode popularized by the VGA video card, colloquially known as Mode 13h. Most old DOS games from before a particular point in time used it. But what if you want or need bigger? Or more colors? Enter the Super VGA cards with their extended VESA modes.

These VESA modes number 100h and higher, but which exactly are available and what their specs are depends on your exact hardware. As such you can’t rightly assume a certain mode is available and will be that particular resolution and color depth. What you’re supposed to do is ask the system what VESA video modes are available, walk the list to see if you find the one you need, and note its number.

All I have is a copy of DOSBox and a copy of VirtualBox, and of vesachk.exe, available here if you want to try it out yourself. This application gives you that list. Now, the two systems yield vastly different results, mirroring differences in video hardware. DOSBox for example emulates some form of S3 card.

I’ve noticed that when an SCI32 game is made for low-res it runs in plain ol’ Mode 13h, but if it’s meant for higher it’ll use Mode 101h. That’s one of the few in the list that DOSBox and VBox agree on — it has 640×480 resolution at 8 bits per pixel, packed, starting at 0xA0000000.

On the one hand, a regular old 16-bit DOS application wouldn’t be able to address all 307,200 pixels at once the way you can in mode 13h. On the other, a 32-bit application would have direct access to the full linear frame buffer no matter its size. A 16-bit application would need trickery to reach any pixel beyond a certain point, setting the window registers to basically shift the next part of video memory into that same 64 kb block.

This is why SCI32, when switching to mode 13h, just does so:

void Vga::Set320x200()
{
	union REGS reg;
 
	reg.w.ax = 0x0013;
	int386(0x10, &reg, &reg);
	SetVideoMode(1);	// clear all video memory
	SetVideoMode(0);	// back to Normal Mode 13
	lenx = 320;
	leny = 200;
}

But when it switches to mode 101h, it jumps through several hoops. First it checks if VESA is supported at all, then it switches to mode 101h, and then it does some more checks to see if things are as they should be, bailing out if they’re not.

And that’s all good.

But what if you were to find a VESA video mode that was 320×200 with 256 colors? Is there such a thing? A redundancy with mode 13h? As a matter of fact, there is! On the S3 emulated by DOSBox, it’s VESA mode 150h, and once you switch to it things work exactly the same as in mode 13h, except the memory access timing or whatever is different.

; VGA mode 13
mov ah, 0x00
mov al, 0x13
int 0x10
 
; VESA mode 150h
mov ax, 4F02h
mov bx, 150h
int 10h

But on whatever VBox has to offer, which is a vastly longer list with about a hundred more modes, this could be 146h, 346h, 546h, or 746h. And that’s why you really should ask the system about it!

But SCI32 basically assumes 101h is what it needs to be and presumably the folks at Sierra tested a bunch of contemporary cards and found this to be true.

Fun fact: SCI16 has all its video driver code in files like VGA320.DRV, but SCI32’s VGA.DRV is practically empty. It’s technically a valid SCI driver file but it’s basically just a header. Same with its VESA.DRV. All their code is in the interpreter itself, much like the mouse driver. It’s only there so the installer can offer it and the interpreter can determine which was chosen. And even then, the interpreter for later high-res only games like Gabriel Knight 2 will happily ignore all that.

[ , ] Leave a Comment

Go home, Twitter

This is seriously something that happened earlier today on Twitter. I asked what to blog about, since my last post here was in May, and I could see I got a reply, but not what that reply was.

There was no “unavailable” placeholder or anything, no “potentially offensive” click barrier, just a non-zero counter. Logging out, switching to private mode, no difference. Then @Purrpleneko1 replied, I went to their profile to check their replies, and found what was being hidden from me: a perfectly good suggestion that unfortunately fell outside of my interests and expertise — I’m more into software than hardware. Why was this being hidden from me? I could see their other replies just fine!

So yeah. Go home, Twitter. You’re drunk on algorithms.

*sips cuppasoup*

[ , ] Leave a Comment