Benny Posted June 23, 2003 Share Posted June 23, 2003 I think it'd be nice to have more documentation for SCUMM (and indeed GRIME) especially at the moment while Lucashacks is down. The ScummVM Source is all well and good but not everyone can read C++ or understand it, plus its always nice to have things laid out seperately. More documentation will help us get/make some nice new tools too. Here's the idea, in this thread you post various stuff, layout of blocks, image formats or whatever anything really and I'll post them all up neat in another sticky that I'll add to as more stuff is documented. It would be really good if those who can understand C++ could document from the ScummVM Source some of the stuff that hasnt been documented before like costumes etc.. Anyway its an idea, what do you all think? Link to comment Share on other sites More sharing options...
Benny Posted June 23, 2003 Author Share Posted June 23, 2003 This is outdated, I have a newer version of the specs than this, I havent finished it yet, if you need it just ask My documentation of Index Files, the lfl stuff may be wrong: IndexFiles ---------- 00.lfl/000.lfl Used in V3/4 .000 Used in V5/6 .LA0 Used in V7/8 Conventions: ------------ All little endian unless stated Chunk - a named part of the file, ie RNAM Chunk sizes begin from the start of the chunk ie they include the 8 bytes for the chunk header and size *=repeat until *=no of items, then move onto the next * eg for DROO, read Room No until you've read in (No of items) then do the same for offsets #=do then move onto the next #item and loop until=no of objects eg for RNAM, read Room No, them Room Name, then loop Chunks ------ RNAM Room Names In V5+ MAXS Maximum Values In V5+ DROO Directory of Rooms In V5+ DRSC Direcory of Room Scripts In V8 DSCR Directory of Scripts In V5+ DSOU Directory of Sounds In V5+ DCOS Directory of Costumes In V5+ DCHR Directory of Charsets In V5+ DOBJ Directory of Objects In V5+ AARY List of Arrays In V6+ ANAM Animation Names? In V7 RM Room Names In V3/4 0R Directory Of Rooms In V3/4 0S Directory Of Scripts? In V3/4 0N Directory Of Sounds? In V3/4 0C Directory Of Costumes? In V3/4 0O Directory Of Objects? In V3/4 Scumm V5 -------- Files are xor'ed with 0x69 RNAM ---- Block Name (4 bytes) Block Size (4 bytes BE) #Room No (1 byte) #Room Name (9 bytes) XOR'ed with FF Blank (00) byte (1 byte) Marks end of chunk MAXS ---- Block Name (4 bytes) Block Size (4 bytes BE) Variables (2 bytes) Unknown (2 bytes) Bit Variables (2 bytes) Local Objects (2 bytes) Unknown (2 bytes) Character Sets (2 bytes) Unknown (2 bytes) Unknown (2 bytes) Inventory Objects (2 bytes) DROO ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) DSCR ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) DSOU ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) DCOS ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) DCHR ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) DOBJ ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes) *Owner of Object (1 byte) ScummV6 ------- Files are xor'ed with 0x69 RNAM ---- Blank Byte(00) (1 byte) MAXS ---- Block Name (4 bytes) Block Size (4 bytes BE) Variables (2 bytes) Unknown (2 bytes) Bit Variables (2 bytes) Local Objects (2 bytes) Arrays (2 bytes) Unknown (2 bytes) Verbs (2 bytes) Floating Objects (2 bytes) Inventory Objects (2 bytes) Rooms (2 bytes) Scripts (2 bytes) Sounds (2 bytes) Character Sets (2 bytes) Costumes (2 bytes) Global Objects (2 bytes) DROO DSCR DSOU DCOS DCHR DOBJ ---- All as in V5 AARY ---- Block Name (4 bytes) Block Size (4 bytes BE) #Stop (2 bytes) Stops if 0x0000 #A (2 bytes) #B (2 bytes) #C (2 bytes) num=AARY no (itinerate through in loop) if c=1 then AARY=(num, 1, a, b) else AARY=(num, 1, a, b) If stop=0 you dont seek past the 6 bytes of A,B,C you just start the loop again. ScummV7 ------ Files aren't xor'ed RNAM ---- As in V6 MAXS ---- Block Name (4 bytes) Block Size (4 bytes BE) Variables (2 bytes) Bit Variables (2 bytes) Unknown (2 bytes) Global Objects (2 bytes) Local Objects (2 bytes) New Names (2 bytes) Verbs (2 bytes) Floating Objects (2 bytes) Inventory Objects (2 bytes) Arrays (2 bytes) Rooms (2 bytes) Scripts (2 bytes) Sounds (2 bytes) Character Sets (2 bytes) Costumes (2 bytes) DROO DSCR DSOU DCOS DCHR DOBJ AARY ---- All as in V5 ANAM ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (2 bytes #Name (8 bytes) #Blank (00) byte (1 byte) Blank (FF) byte (1 byte) Marks end of chunk ScummV8 ------- Files aren't xor'ed RNAM ---- As in V6 MAXS ---- Block Name (4 bytes) Block Size (4 bytes BE) Variables (4 bytes) Bit Variables (4 bytes) Unknown (4 bytes) Scripts (4 bytes) Sounds (4 bytes) Character Sets (4 bytes) Costumes (4 bytes) Rooms (4 bytes) Unknown (4 bytes) Global Objects (4 bytes) Unknown (4 bytes) Local Objects (4 bytes) New Names (4 bytes) Floating Objects (4 bytes) Inventory Objects (4 bytes) Arrays (4 bytes) Verbs (4 bytes) DROO ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes) DRSC ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes) DSCR ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes) DSOU ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes) DCOS ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes) DCHR ---- Block Name (4 bytes) Block Size (4 bytes BE) No of items (4 bytes) *Room Number (1 byte) *Offset (2 bytes) DOBJ AARY ---- All as in V5 Scumm V3/4 ---------- File's aren't xor'ed Block Size does not include the 4 block size bytes RN ---- Block Size (4 bytes) Block Name (2 bytes) #Room No (1 byte) #Room Name (9 bytes) XOR'ed with FF Blank (00) byte (1 byte) Marks end of chunk 0R ---- Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) 0S ---- Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) ON ---- Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) 0C ---- Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) *Room Number (1 byte) *Offset (4 bytes) 0O ---- Block Size (4 bytes) Block Name (2 bytes) No of items (2 bytes) *Owner of Object (1 byte) [/Code] Link to comment Share on other sites More sharing options...
Ray Jones Posted June 24, 2003 Share Posted June 24, 2003 i'd like some kind of documentation for scummvm .. Link to comment Share on other sites More sharing options...
Ray Jones Posted June 27, 2003 Share Posted June 27, 2003 ive found some scumm-documentation at this loco... Link to comment Share on other sites More sharing options...
Benny Posted June 27, 2003 Author Share Posted June 27, 2003 Yeah, its still very incomplete though and abandoned if I remember rightly, I think its now part of the scummvm page. Link to comment Share on other sites More sharing options...
Ender Posted July 2, 2003 Share Posted July 2, 2003 Originally posted by bgbennyboy Yeah, its still very incomplete though and abandoned if I remember rightly, I think its now part of the scummvm page. Yeah, we were planning to finish it... Sometime. Maybe. Link to comment Share on other sites More sharing options...
Benny Posted July 2, 2003 Author Share Posted July 2, 2003 Post stuff here in the meantime then! People will be thinking that this is a poorly disguised attempt by me to get someone to document costumes... Link to comment Share on other sites More sharing options...
Ender Posted July 2, 2003 Share Posted July 2, 2003 Originally posted by bgbennyboy Post stuff here in the meantime then! People will be thinking that this is a poorly disguised attempt by me to get someone to document costumes... After ScummVM 0.5.0, I am planning to get a group together to work on documenting codecs and the like. But I'm too busy gearing up for 0.5.0 so far Link to comment Share on other sites More sharing options...
checkmate Posted July 3, 2003 Share Posted July 3, 2003 AKOS: The Costume Format From Hell WARNING: I do not guarantee all the information in this document is correct. I'm mainly interpreting from the ScummVM source code. If you have a correction to make, please do so! ANOTHER WARNING: I won't be covering the AKSQ and AKCH stuff here. I tried, but the ScummVM code is messy, to say the least. Maybe one of its developers could document the sequence and animation stuff? YET ANOTHER WARNING: This stuff may confuse you. I apologize for the inconvenience. ONE MORE WARNING: Codec 16 still confuses me. I can't cover it. Sorry. AKOS is an actor costume format. A costume is a set of graphics and animation which visualizes an actor (which is a good thing, otherwise Guybrush would be invisible). AKOSes are found in SCUMM versions 7 and 8, including Full Throttle, The Dig, and Curse of Monkey Island. Older SCUMM engines used the original "COST" costume format, but AKOS replaced it because it provided new stuff like larger images, better compression, and color effects like shadows. Technical Stuff Please make sure you understand how a palettized computer display works before you try to conquer the AKOS format. You should probably know about SCUMM's actor palette system before reading on, so here you go: Each actor contains its own special palette table. Whenever the AKOS renderer draws a pixel, that pixel's value (from the AKOS data) is translated into the actual pixel (to be drawn to the screen) using this palette table. For instance, if it has to draw "1", it will look in the first entry of the palette table for the pixel it should write to the display. Why does it do this? Well, it really helps when the SCUMM engine needs to apply a color effect to the costume (also called a "remap"). Here's how it would make a costume slightly bluer, for example. For each entry in the actor's palette: A) Compute the result color (which is slightly bluer) using the RGBS block as a reference (more on that below). B) Search the hardware palette for a color which most closely matches the color it's looking for. C) If that color is still not accurate enough, find an unused entry to change instead. D) Remap the actor's palette table entry to the entry found in the hardware palette. So, hopefully you can see the palette system's purpose. The Chunks An AKOS is based on the IFF format, and begins with the following header: Name ("AKOS") (4 bytes) Size (big endian) (4 bytes) This is followed by a series of IFF chunks, described below: AKHD: The AKOS Header, containing some important information about the costume. AKPL: The AKOS Palette, containing the initial palette table for the actor. This block may be empty in some costumes! RGBS: RGB Values, used by the SCUMM engine as a reference when applying a color effect to a costume. Contains the actual colors used in the costume. This block isn't used in some costumes! AKOF: AKOS Offsets. This is used to find frame data in the AKCI and AKCD blocks. AKCI: AKOS Costume Information. This contains the width, height, and position of each frame. AKCD: AKOS Costume Data. The most important block! Contains the compressed costume frames. AKHD Name ("AKHD") (4 bytes) Size (big endian) (4 bytes) Unknown (2 bytes) Flags (1 byte) Unknown (1 byte) Number of Animations (2 bytes) Number of Frames (2 bytes) Codec (2 bytes) As you can see, a couple fields haven't been identified yet. However, the ScummVM source code labels "Number of Frames" as unknown, but I've figured it out. There are only two known flags in the Flags field: Bit 0: If set, the renderer will need to mirror frames for the actor to face certain directions. Bit 1: If set, the actor can face 8 directions, rather than 4. There are three codecs: Codec 1, Codec 5, and Codec 16. The codec specifies the type of compression used to compress the frames in the costume. Codec 1 is the same codec used in the old "COST" format, Codec 5 uses BOMP compression, and Codec 16 uses a bit stream encoding technique. I'll describe the codecs later. AKPL and RGBS The AKPL stores the actor's palette table and looks like this: Name ("AKPL") (4 bytes) Size (big endian) (4 bytes) Palette Table Entries (1 byte, continues to end of block) The RGBS stores the actor's colors, and looks like this: Name ("RGBS") (4 bytes) Size (big endian) (4 bytes) [until end of block:] Red (1 byte) Green (1 byte) Blue (1 byte) AKOF This block is used to find frame data in the AKCI and AKCD blocks. Name ("AKOF") (4 bytes) Size (big endian) (4 bytes) [Repeating until end of block:] AKCD Offset (4 bytes) AKCI Offset (2 bytes) AKCI This block contains information about each frame. Name ("AKCI") (4 bytes) Size (big endian) (4 bytes) [Repeating until end of block:] Width (2 bytes) Height (2 bytes) Relative X Position (2 bytes) Relative Y Position (2 bytes) X Movement (2 bytes) Y Movement (2 bytes) When the renderer wants to draw at an X, Y position, it will need to compute the actual position to render on the screen with the "Relative" fields. This lets the costume identify its position with the offset of, say, Guybrush's feet rather than the top left of the frame. AKCD Name ("AKCD") (4 bytes) Size (big endian) (4 bytes) Data (X bytes, until end of block) The all-important AKCD block! It contains the compressed frame data itself. Let's take a look at the codecs: Codec 1 This is the same codec as used in the old "COST" format. It works like this: Byte Identification: If NumColors = 32 then 5 bits for color, 3 bits for repeat. Else if NumColors = 64 then 6 bits for color, 2 bits for repeat. Else 4 bits for color, 4 bits for repeat. For each byte in data: If repeat = 0 then repeat = next byte. For repeat value: Plot color at pixel. Advance row. If row > height then Back to original row. Advance column. If column > width then Done! Codec 5 This is just BOMP disguised as an AKOS codec. It works like this: For each row: Code = next byte. Repeat = (code >> 1) + 1. If first bit in code is set then Color = next byte. For repeat value: Plot color at pixel. Advance column. Else For repeat value: Plot next byte at pixel. Advance column. If column > width then next row! Codec 16 This is the tricky one. It's a bit stream encoded thing that baffled the ScummVM developers for a while. Then one of them disassembled it and said, "This shouldn't be too hard," and implemented it. What the heck? I need somebody to explain it to me, really. AkosView isn't dead! The next version will run in a window (using a magical thing called a DIBSection) and have improvements to its AKOS decoder. What I need is a way to extract AKOSes from SCUMM resource files so you don't have to use Scumm Revisited, preferably without going through the index file. Any help on this? Link to comment Share on other sites More sharing options...
Benny Posted July 3, 2003 Author Share Posted July 3, 2003 Nice one Nolan. I dont like bitstream stuff either, I tried to make an image/object viewer last week and I completely messed up the bitstream reading. I ended up about 10 bytes behind where I should have been every time¬ As for extracting AKOS' from resource files, you could just take the brute force approach. Repeat until>EOF Read 4 bytes to a BlockName var If BlockName=LECF or LOFF or ROOM then - seek 4 bytes, past the block size Else begin Read 4 bytes BE to a blocksize var if Blockname=AKOS then begin A dumpfile procedure here. Something like: Seek -8 bytes so you are at the start of the block Dump blocksize bytes to a file Seek +8 bytes so the fileposition is back where it was for the loop end Seek BlockSize-8 end This is simple to do in Delphi, I assume its just as easy in C++ Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.