Building Blorbs for Infocom's V6 games

I’m exploring the idea of producing Blorbs with the EGA and CGA versions of the graphics. One big question is this: How were the contents of the Rect chunks determined?

1 Like

As best I can tell, Rects are stored in the picture file along with the normal graphics; when parsing the “directory” at the top of the file, if the “address” field is all zeroes for a particular entry, that image is a Rect. Its width and height are taken from that directory entry.

I’m familiar with what the Rect chunks and their contents, but not how their contents were determined. Using the old ztools package, I can easily extract GIF format image files from the Infocom files, which can easily be turned into PNG files, but nothing comes out of it corresponding to the no-data rectangle images.

Ah, I see. Do you happen to have an EGA or CGA graphics file on hand (or know where I can find them)? I think I understand the old Infocom format well enough to write a script that extracts Rects, but it’ll be easier if I have something to test with. (And the IF Archive only seems to have the MCGA versions.)

Basically, after the header in each Infocom graphics file is a “directory” that lists the width, height, flags, resource number, colormap, and data pointer for each picture. If the data pointer is non-zero, it’s an offset into the file where that picture’s data is stored (as a raw array of bytes). If it’s zero, that “picture” is actually a rectangle. The ZTools converter currently skips over rectangles when it’s converting the graphics, but it could just as easily be made to print out the rectangle’s width and height instead—much more easily, honestly, since it wouldn’t have to do any of the color calculations or image compression.

I got a few. Let me PM you a link…

I have them all, also PMed a link.

The pix2gif program from the old Ztools package will convert the MCGA and EGA graphics files, but has weird problems with the CGA ones, leaving the GIFs truncated. The program itself says that it handles MCGA and EGA, but makes no mention of CGA. Did someone document the internals of these files anywhere?

Many thanks, both of you! My little Python script is attached: zimg.zip (729 bytes). The code is a mess, but it works, and it’s only 37 lines long; give it a graphics file and it’ll list off the directory in a human-readable format.

To my understanding, all three files use the same format, and indeed their directories are very similar except for image dimensions and flags.

The flags themselves, annoyingly, aren’t documented anywhere that I can find. The lowest bit (0x0001) seems to indicate that there’s transparency; the highest four bits (0xF000) indicate which index means transparent. But the CG1 file also sets the fourth bit (0x0008) on all its images, and I can’t find any documentation on what this bit is supposed to mean.

My guess, based on how pix2gif mangles CG1 files, is that it changes the meaning of the color palette. Perhaps it means “this image is monochrome”? Do we know which systems actually used the CG1 file?

IBM PC with the CGA graphics board used the CG1 files.

That’s good to know!

I’m getting out of my depth here, but the images in the CG1 file seem to use only two colors (0x02 and 0x03) plus transparency (0x00), and they never specify a palette that these colors should be drawn from. The largest images are 640x200, and according to Wikipedia, CGA supports “640×200 in 2 colors. Pixel aspect ratio of 1:2.4”.

In other words, it seems like these images truly are monochrome. There might be some way to set the foreground color, since CGA allows for that, but I can’t find any real signs of that in the image file.

As an experiment, here’s what the first image in the file looks like if my hypothesis is right:
titlecard

Which looks quite reasonable to me!

(Just to add: I got that image by patching pix2gif.c, adding the following before line 214:

if(directory->image_flags & 0x08){
	colourmap[2][0] = 255; colourmap[2][1] = 255; colourmap[2][2] = 255;
	colourmap[3][0] = 0; colourmap[3][1] = 0; colourmap[3][2] = 0;
}

and then scaling the result by (1.0, 2.4).)

Yeah, that title screen looks about right to me, except my quick run in DOSBox renders it in light gray.

I’ve uploaded the EGA and CGA graphics files to the IF Archive. I also created a Git repository for ztools at https://gitlab.com/DavidGriffith/ztools, to which I will apply Draconis’s patch.

1 Like

I’ve updated pix2gif.c to generate Rect (rectangle) and APal (adaptive palette) chunk contents. Working on generating the resolution chunk and figuring out how to correctly extract CGA images.

3 Likes

Next step: does anyone understand how to determine if an image extracted from an Infocom image file is scalable? I can’t seem to figure out where Kevin Bracey is these days.

I don’t think the Infocom images have any idea of ‘scalability’. All the images in the Infocom game blorb files have the same scaling information, which I think means ‘By default print at actual size, but you can scale it infinitely in either direction’.

So, I’ll just have pix2gif.c emit a resolution chunk that okays infinite scaling for everything. What remains now is correctly processing CGA files.

Well, creating a resolution chunk (pix2gif.c updated to do this) that okays infinite scrolling for everything doesn’t result in a Reso chunk identical to what Kevin Bracey created. The one I get is 0x2B68 bytes long – significantly shorter than Kevin’s, which is 0x371C bytes long. At 0x2700, they begin to differ.

The length of a resolution chunk is ‘num*28+24’ where ‘num’ is the number of image resolutions in the chunk. Kevin Bracey’s Reso chunk has 107 more image resolutions than yours. A quick review of ZorkZero.blb reveals there are 107 Rect images, which you’re presumably not handling correctly.

1 Like

I don’t see where I’m missing the rectangles because I do a push into the resolution stack each time around the loop.

It looks to me like your code for processing Rect images has a return statement in it, and the code for adding an image to the resolution chunk comes after that.