The Standard Architecture for Universal Comment Extensions or SAUCE as it is more commonly known, is an architecture or protocol for attaching meta data or comments to files. Mainly intended for ANSI art files, SAUCE has always had provisions for many different file types.
In the early 1990s there was a growing popularity in ANSI artwork. The ANSI art groups regularly released the works of their members over a certain period. Some of the bigger groups also included specialised viewers in each ‘artpack’. One of the problems with these artpacks was a lack of standardized way to provide meta data to the art, such as the title of the artwork, the author, the group, ... Some of the specialised viewers provided such information for a specific artpack either by encoding it as part of the executable, or by having some sort of database or list. However every viewer did it their own way. This meant you either had to use the viewer included with the artpack, or had to make do without the extra info. SAUCE was created to address that need. So if you wanted to, you could use your prefered viewer to view the art in a certain artpack, or even store the art files you liked in a separate folder while retaining the meta data.
The goal was simple, but the way to get there certainly was not. Logistically, we wanted as many art groups as possible to support it. Technically, we wanted a system that was easy to implement and – if at all possible – manage to provide this meta data while still being compatible with all the existing software such as ANSI viewers, and Bulletin Board Software.
SAUCE was created in 1994 and it continues to be in use today as a de facto standard within the ANSI art community. However, being created so many years ago, some of the common assumptions made back then are now cause for confusion. This document is a revised edition of the SAUCE specifications; slightly more formal and in a fresh HTML format. This specification is still compatible with the original, some of the legacy confusions are explicitly addressed, and a few new features have been added.
The ‘born from DOS’ nature explains some of the limits of SAUCE. The
Title, Author and Group fields are so short because part of the original design
idea was that the DOS filename, title and author needed to fit on a single line
in text mode while still leaving some space so you could create a decent UI to select
the files in the ANSI viewers. Limitations were also designed around what video
cards could do in text mode.
The specialised viewers in the various ANSI artpacks also explain why it was possible
to add SAUCE to some files even though the file format really does not like it when
you just add a load of extra bytes at the end. The SAUCE-aware viewer could account
for the SAUCE and still render the file properly, even if the applications used
to edit those files regarded the file as corrupt. In such an event, it was easy
enough to remove the SAUCE.
SAUCE is not a perfect solution, but at the time – and with a bit of friendly pressure from the right folks – it managed to fulfill what it was designed to do.
Applied to a file, SAUCE has 4 parts: The original file contents, an End-Of-File or EOF character (Decimal 26, Hex 1A, Ctrl+Z), an optional comment block and the SAUCE record.
The EOF character is an important part of what makes SAUCE work for text files. When processing a text file, the DOS / Windows TYPE command, most BBS terminal software and ANSI-viewers will all stop processing at the end of the file or when a EOF character is encountered with the EOF character itself not being rendered.
Adding SAUCE to a file that does not already contain SAUCE is straightforward. First, you prepare the SAUCE record and optionally the comment block. You open the file you want to add SAUCE to, you append the EOF character, if needed you append the comment block and you append the SAUCE record.
Updating a file that already has SAUCE, can be easy as well if you only want to change some fields in the SAUCE record or change existing comment lines. Things become slightly tricky if you want to add a comment block when there was no comment block before, or if the new comment block has a different number of lines than the old one. The simple solution in such a case is to remove the old SAUCE then add the new SAUCE you want. This involves truncating a file, which depending on the language / library / OS can be a matter of a simple function call, or might involve copying the file contents without the SAUCE to a new file.
Reading SAUCE is equally easy. Read the last 128 bytes of the file into a SAUCE record structure. If the ID is set to "SAUCE", then you can assume you have a file that has SAUCE otherwise it does not. If you need the comment block as well, then once you have the SAUCE record, you can check the Comment field and work your way back to read the comment block.
Below you find some pseudo code to explain this. This code assumes a language that can not handle variable records, so the comment block is read one line at a time. In a language like C or C++ this can be handled with a single read.
Variables: Byte : Count; Long : FileSize; file : F; Code: Open_File(F); | Open the file for read access FileSize = Size_of_file(F); | Determine file size Seek_file (F, FileSize-128); | Seek to start of SAUCE (Eof-128) Read_File (F, SAUCE); | Read the SAUCE record IF SAUCE.ID="SAUCE" THEN | ID bytes match "SAUCE" ? IF SAUCE.Comments>0 THEN | Is there a comment block ? Seek_File(F, FileSize-128-(SAUCE.Comments*64)-5); | Seek to start of Comment block. Read_File(F, CommentID); | Read Comment ID. IF CommentID="COMNT" THEN | Comment ID matches "COMNT" ? FOR Count=1 to SAUCE.Comments | \ Read all comment lines. Read_File(F, CommentLine) | / ENDFOR ELSE Invalid_Comment; | Non fatal, No comment present. ENDIF ENDIF ELSE Invalid_SAUCE; | No valid SAUCE record was found. ENDIF
SAUCE was initially created for supporting only the ANSi and RIP formats. Since those formats are ‘technically’ processed one character at a time, SAUCE almost never interferes with how a program treats the files, reading and processing should stop at the EOF character. Files that are treated in a similar way such as ASCII, PCBoard, Avatar and ANSiMations equally tend to work unaffected even in programs that are not SAUCE aware.
This is not true for all the other types of files SAUCE has DataType / FileType values for however. Adding SAUCE to some of the other types of files may have serious consequences on programs using those files. For this reason I would currently advise against adding SAUCE to such files, unless there is a pressing reason to do so anyway.
If there are any requests for extending SAUCE to support additional file types, such requests will only be honored if the file does not already have its own meta data feature and it can be proven that SAUCE can safely be added from the typical programs editing such files.
A SAUCE record is a structure of 128 bytes having the following layout:
Field name | Type | Size | Description | Required [1] | Revision [2] |
ID | Character [3] | 5 |
SAUCE identification. This should be equal to "SAUCE". |
yes | 00.0 |
Version [6] | Character [3] | 2 |
SAUCE version number, should be "00". |
yes | 00.0 |
Title | Character [3] | 35 | The title of the file. | no | 00.0 |
Author | Character [3] | 20 | The (nick)name or handle of the creator of the file. | no | 00.0 |
Group | Character [3] | 20 | The name of the group or company the creator is employed by. | no | 00.0 |
Date | Character [3] | 8 |
The date the file was created. The format for the date is CCYYMMDD (century, year, month, day). Example: 4 may 2013 would be stored as "20130504". |
no | 00.0 |
FileSize | Unsigned [4] | 4 | The original file size not including the SAUCE information. | no [8] | 00.0 |
DataType | Unsigned [4] | 1 | Type of data. | yes | 00.0 |
FileType | Unsigned [4] | 1 | Type of file. | yes | 00.0 |
TInfo1 [7] | Unsigned [4] | 2 | Type dependant numeric information field 1. | no | 00.0 |
TInfo2 [7] | Unsigned [4] | 2 | Type dependant numeric information field 2. | no | 00.0 |
TInfo3 [7] | Unsigned [4] | 2 | Type dependant numeric information field 3. | no | 00.0 |
TInfo4 [7] | Unsigned [4] | 2 | Type dependant numeric information field 4. | no | 00.0 |
Comments | Unsigned [4] | 1 |
Number of lines in the extra SAUCE comment block. 0 indicates no comment block is present. |
no | 00.0 |
TFlags [7] | Unsigned [4] | 1 | Type dependant flags. | no | 00.1 |
TInfoS [7] | ZString [5] | 22 | Type dependant string information field | no | 00.5 |
A SAUCE comment block is an optional, variable sized structure that holds up to 255 lines of additional information, each line 64 characters wide. There are as many comment lines as is mentioned in the Comments field of the SAUCE record. If the Comments field is set to 0, there should not be a comment block at all. The comment block has the following layout:
Field name | Type | Size | Description | Required [1] | Revision [2] |
ID | Character [3] | 5 |
SAUCE comment block identification. This should be equal to "COMNT". |
yes | 00.0 |
Comment Line 1 | Character [3] | 64 | Line of text. | yes | 00.0 |
... | |||||
Comment Line x | Character [3] | 64 |
Line of text. |
yes | 00.0 |
An Example C or C++ SAUCE record looks like this:
struct SAUCE { char ID[5]; char Version[2]; char Title[35]; char Author[20]; char Group[20]; char Date[8]; unsigned long FileSize; unsigned char DataType; unsigned char FileType; unsigned short TInfo1; unsigned short TInfo2; unsigned short TInfo3; unsigned short TInfo4; unsigned char Comments; unsigned char TFlags; char TInfoS[22]; };
SAUCE currently supports the following values for DataType:
DataType | Name | Description | Revision |
0 | None |
Undefined filetype. You could use this to add SAUCE to a custom or proprietary file, without giving it any particular meaning or interpretation. |
00.0 |
1 | Character |
A character based file. These files are typically interpreted sequentially. Also known as streams. |
00.0 |
2 | Bitmap [1] | Bitmap graphic and animation files. | 00.0 |
3 | Vector | A vector graphic file. | 00.0 |
4 | Audio [2] | An audio file. | 00.0 |
5 | BinaryText |
This is a raw memory copy of a text mode screen. Also known as a .BIN file. This is essentially a collection of character and attribute pairs. |
00.0 |
6 | XBin | An XBin or eXtended BIN file. | 00.2 |
7 | Archive | An archive file. | 00.2 |
8 | Executable | A executable file. | 00.2 |
Each DataType has 1 or more possible values for FileType, and associated with each FileType value there is also an interpretation of the TInfo and Flags fields:
DataType | FileType | Name | Description | TInfo1 [1] | TInfo2 [1] | TInfo3 [1] | TInfo4 [1] | Flags [1] | TInfoS [2] |
None | 0 | - | Undefined filetype. | 0 | 0 | 0 | 0 | 0 | 0 |
Character | 0 | ASCII | Plain ASCII text file with no formatting codes or color codes. | Character width [3] | Number of lines [4] | 0 | 0 | ANSiFlags | FontName |
Character | 1 | ANSi | A file with ANSi coloring codes and cursor positioning. | Character width [3] | Number of lines [4] | 0 | 0 | ANSiFlags | FontName |
Character | 2 | ANSiMation | Like an ANSi file, but it relies on a fixed screen size. | Character width [3] | Character screen height [5] | 0 | 0 | ANSiFlags | FontName |
Character | 3 | RIP script | Remote Imaging Protocol graphics. | Pixel width (640) | Pixel height (350) | Number of colors (16) | 0 | 0 | 0 |
Character | 4 | PCBoard | A file with PCBoard color codes and macros, and ANSi codes. | Character width [3] | Number of lines [4] | 0 | 0 | 0 | 0 |
Character | 5 | Avatar | A file with Avatar color codes, and ANSi codes. | Character width [3] | Number of lines [4] | 0 | 0 | 0 | 0 |
Character | 6 | HTML | HyperText Markup Language | 0 | 0 | 0 | 0 | 0 | 0 |
Character | 7 | Source |
Source code for some programming language. The file extension should determine the programming language. |
0 | 0 | 0 | 0 | 0 | 0 |
Character | 8 | TundraDraw |
A TundraDraw file. Like ANSI, but with a custom palette. |
Character width [3] | Number of lines [4] | 0 | 0 | 0 | 0 |
Bitmap | 0 | GIF | CompuServe Graphics Interchange Format | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 1 | PCX | ZSoft Paintbrush PCX | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 2 | LBM/IFF | DeluxePaint LBM/IFF | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 3 | TGA | Targa Truecolor | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 4 | FLI | Autodesk FLI animation | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 5 | FLC | Autodesk FLC animation | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 6 | BMP | Windows or OS/2 Bitmap | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 7 | GL | Grasp GL Animation | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 8 | DL | DL Animation | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 9 | WPG | Wordperfect Bitmap | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 10 | PNG | Portable Network Graphics | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 11 | JPG/JPeg | JPeg image (any subformat) | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 12 | MPG | MPeg video (any subformat) | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Bitmap | 13 | AVI | Audio Video Interleave (any subformat) | Pixel width | Pixel height | Pixel depth [6] | 0 | 0 | 0 |
Vector | 0 | DXF | CAD Drawing eXchange Format | 0 | 0 | 0 | 0 | 0 | 0 |
Vector | 1 | DWG | AutoCAD Drawing File | 0 | 0 | 0 | 0 | 0 | 0 |
Vector | 2 | WPG | WordPerfect or DrawPerfect vector graphics | 0 | 0 | 0 | 0 | 0 | 0 |
Vector | 3 | 3DS | 3D Studio | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 0 | MOD | 4, 6 or 8 channel MOD (NoiseTracker) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 1 | 669 | Renaissance 8 channel 669 | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 2 | STM | Future Crew 4 channel ScreamTracker | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 3 | S3M | Future Crew variable channel ScreamTracker 3 | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 4 | MTM | Renaissance variable channel MultiTracker | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 5 | FAR | Farandole composer | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 6 | ULT | UltraTracker | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 7 | AMF | DMP/DSMI Advanced Module Format | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 8 | DMF | Delusion Digital Music Format (XTracker) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 9 | OKT | Oktalyser | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 10 | ROL | AdLib ROL file (FM audio) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 11 | CMF | Creative Music File (FM Audio) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 12 | MID | MIDI (Musical Instrument Digital Interface) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 13 | SADT | SAdT composer (FM Audio) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 14 | VOC | Creative Voice File | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 15 | WAV | Waveform Audio File Format | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 16 | SMP8 | Raw, single channel 8bit sample | Sample rate [7] | 0 | 0 | 0 | 0 | 0 |
Audio | 17 | SMP8S | Raw, stereo 8 bit sample | Sample rate [7] | 0 | 0 | 0 | 0 | 0 |
Audio | 18 | SMP16 | Raw, single-channel 16 bit sample | Sample rate [7] | 0 | 0 | 0 | 0 | 0 |
Audio | 19 | SMP16S | Raw, stereo 16 bit sample | Sample rate [7] | 0 | 0 | 0 | 0 | 0 |
Audio | 20 | PATCH8 | 8 Bit patch file | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 21 | PATCH16 | 16 bit patch file | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 22 | XM | FastTracker ][ module | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 23 | HSC | HSC Tracker (FM Audio) | 0 | 0 | 0 | 0 | 0 | 0 |
Audio | 24 | IT | Impulse Tracker | 0 | 0 | 0 | 0 | 0 | 0 |
BinaryText | Variable [8] | - | Binary screen image | 0 | 0 | 0 | 0 | ANSiFlags | FontName |
XBin | 0 | - | eXtended Bin | Character width [3] | Number of lines [4] | 0 | 0 | 0 | 0 |
Archive | 0 | ZIP | PKWare Zip. | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 1 | ARJ | Archive Robert K. Jung | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 2 | LZH | Haruyasu Yoshizaki (Yoshi) | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 3 | ARC | S.E.A. | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 4 | TAR | Unix TAR | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 5 | ZOO | ZOO | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 6 | RAR | RAR | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 7 | UC2 | UC2 | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 8 | PAK | PAK | 0 | 0 | 0 | 0 | 0 | 0 |
Archive | 9 | SQZ | SQZ | 0 | 0 | 0 | 0 | 0 | 0 |
Executable | 0 | - |
Any executable file. .exe, .dll, .bat, ... Executable scripts such as .vbs should be tagged as Source. |
0 | 0 | 0 | 0 | 0 | 0 |
ANSiFlags allow an author of ANSi and similar files to provide a clue to a viewer / editor how to render the image. The 8 bits in the ANSiFlags contain the following information:
0 | 0 | 0 | A | R | L | S | B |
These bits are interpreted as:
The FontName field allows an author of ANSi and similar files to provide a clue to the viewer / editor which font to use to render the image.
Prior to revision 00.5, this field was a filler, so this field will be empty for legacy files. Supplying a font name is not required.
Font name [1] | Font size | Resolution [2] | Aspect ratio [3] | Vertical stretch [6] | Description | |
Display [4] | Pixel [5] | |||||
IBM VGA | 9×16 [7] | 720×400 | 4:3 | 20:27 (1:1.35) | 35% | Standard hardware font on VGA cards for 80×25 text mode (code page 437) |
8×16 | 640×400 | 4:3 | 6:5 (1:1.2) | 20% | Modified stats when using an 8 pixel wide version of "IBM VGA" or code page variant. | |
IBM VGA50 | 9×8 [7] | 720×400 | 4:3 | 20:27 (1:1.35) | 35% | Standard hardware font on VGA cards for condensed 80×50 text mode (code page 437) |
8×8 | 640×400 | 4:3 | 5:6 (1:1.2) | 20% | Modified stats when using an 8 pixel wide version of "IBM VGA50" or code page variant. | |
IBM VGA25G | 8×19 | 640×480 | 4:3 | 1:1 | 0% | Custom font for emulating 80×25 in VGA graphics mode 12 (640×480 16 color) (code page 437). |
IBM EGA | 8×14 | 640×350 | 4:3 | 35:48 (1:1.3714) | 37.14% | Standard hardware font on EGA cards for 80×25 text mode (code page 437) |
IBM EGA43 | 8×8 | 640×350 | 4:3 | 35:48 (1:1.3714) | 37.14% | Standard hardware font on EGA cards for condensed 80×43 text mode (code page 437) |
IBM VGA ### [8] | 9×16 [7] | 720×400 | 4:3 | 20:27 (1:1.35) | 35% | Software installed code page font for VGA 80×25 text mode |
IBM VGA50 ### [8] | 9×8 [7] | 720×400 | 4:3 | 20:27 (1:1.35) | 35% | Software installed code page font for VGA condensed 80×50 text mode |
IBM VGA25G ### [8] | 8×19 | 640×480 | 4:3 | 1:1 | 0% | Custom font for emulating 80×25 in VGA graphics mode 12 (640×480 16 color). |
IBM EGA ### [8] | 8×14 | 640×350 | 4:3 | 35:48 (1:1.3714) | 37.14% | Software installed code page font for EGA 80×25 text mode |
IBM EGA43 ### [8] | 8×8 | 640×350 | 4:3 | 35:48 (1:1.3714) | 37.14% | Software installed code page font for EGA condensed 80×43 text mode |
Amiga Topaz 1 | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Original Amiga Topaz Kickstart 1.x font. (A500, A1000, A2000) |
Amiga Topaz 1+ | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Modified Amiga Topaz Kickstart 1.x font. (A500, A1000, A2000) |
Amiga Topaz 2 | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Original Amiga Topaz Kickstart 2.x font (A600, A1200, A4000) |
Amiga Topaz 2+ | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Modified Amiga Topaz Kickstart 2.x font (A600, A1200, A4000) |
Amiga P0T-NOoDLE | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Original P0T-NOoDLE font. |
Amiga MicroKnight | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Original MicroKnight font. |
Amiga MicroKnight+ | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Modified MicroKnight font. |
Amiga mOsOul | 8×8 [9] | 640×200 | 4:3 | 5:12 (1:2.4) | 140% | Original mOsOul font. |
C64 PETSCII unshifted | 8×8 [10] | 320×200 | 4:3 | 5:6 (1:1.2) | 20% | Original Commodore PETSCII font (PET, VIC-20, C64, CBM-II, Plus/4, C16, C116 and C128) in the unshifted mode. Unshifted mode (graphics) only has uppercase letters and additional graphic characters. This is the normal boot font. |
C64 PETSCII shifted | 8×8 [10] | 320×200 | 4:3 | 5:6 (1:1.2) | 20% | Original PETSCII font in shifted mode. Shifted mode (text) has both uppercase and lowercase letters. This mode is actuated by pressing Shift+Commodore key. |
Atari ATASCII | 8×8 [11] | 320×192 | 4:3 | 4:5 (1:1.25) | 25% | Original ATASCII font (Atari 400, 800, XL, XE) |
Version.Revision | Date | Description |
00.0 | March 1, 1994 | SAUCE is released as part of the monthly ACiD acquisition artpack. |
00.1 | June 30, 1994 | Added the Flags field in the SAUCE record. |
00.2 | July 13, 1996 |
Added support for:
|
00.3 | July 29, 1996 |
Character/Avatar extended to use TInfo1 and TInfo2. Added support for Audio/IT |
00.4 | May 31, 1997 | Technical cleanup |
00.5 | November 12, 2013 |
Complete rewrite of the spec – this document.
|