- APPENDIX C -
Files ending in '.GEM' are graphic metafiles created by GDOS.
They are usually used to represent vector graphics but may also
be used to store links to bitmap images and textual information.
Two primary versions of GEM files exist. Version 1 files
are guaranteed not to contain bezier curves whereas version 3
files may. Version 3.xx files are also commonly referred to as
GEM/3 files.
GEM metafiles begin with a header as follows:
NATIVE FILE FORMATS
The .GEM File Format
The Metafile Header
| Contents |
---|---|
| Magic number (0xFFFF). |
| Header length in WORDs. |
| Version number (major * 100 + minor). |
| NDC Flag as follows: Value Meaning 0 (0, 0) in lower-left corner (NDC)
2 (0, 0) in upper-left corner (RC) |
| Minimum X extent. |
| Minimum Y extent. |
| Maximum X extent. |
| Maximum Y extent. |
| Page width in tenths of millimeters. |
| Page height in tenths of millimeters. |
| Lower Left X value of coordinate system. |
| Lower Left Y value of coordinate system. |
| Upper Right X value of coordinate system. |
| Upper Right Y value of coordinate system. |
| Other information may appear in the header following which is currently undefined. Use WORD #1 to skip any unknown information. |
The definition of WORDs 4-13 is defined by the creator
of the file using three metafile commands. WORDs 4-7 are
set with the v_meta_extents() function. WORDs 8-9
are defined with the vm_pagesize() function. WORDs
10-13 are defined with vm_coords(). If the creator fails
to specify defaults for any of these values, the appropriate values
will be set to 0 in the header. If zeros appear for WORDs
10-13, the default NDC coordinate system should be assumed.
Following the header will appear a list of records of varying
length which, when translated, can be 'played back' on the destination
VDI device. Each record is formatted as follows:
Metafile Records
| Meaning |
---|---|
| Opcode of VDI function. |
| Number of PTSIN elements. |
| Number of INTIN elements. |
| Function sub-ID. |
| PTSIN elements. |
| INTIN elements. |
The list of records is terminated with an opcode of 0xFFFF (this record is written when a v_clswk() call is made by the creator).
When playing back GEM files, the application must translate
all coordinates from the metafile coordinate system to that of
the destination device. In addition, text metrics should be appropriately
converted. If an unknown opcode is discovered it should be played
after any elements of the PTSIN array are translated (making
the assumption that they should be).
GEM metafiles support the use of special sub-opcodes for
implementing reserved and user-defined functions. GEM metafile
translators should ignore sub-opcodes they don't understand. Each
sub-opcode can be identified with the primary opcode of 5, function
ID of 99 and the first (required) member of INTIN being
the sub-opcode ID. The currently defined sub-opcodes are as follows:
Metafile Sub-Opcodes
| Meaning |
---|---|
| Start Group. |
| End Group. |
| Set No Line Style. |
| Set Attribute Shadow On. |
| Set Attribute Shadow Off. |
| Start Draw Area Type Primitive. |
| End Draw Area Type Primitive. |
None of the pre-defined sub-opcodes use additional INTIN or PTSIN elements though user-defined sub-opcodes may.
Opcodes from 0-100 are reserved for use by Atari. Sub-opcodes from 101-65535 are available for use by developers but should be registered with Atari to avoid possible conflicts.
The IMG file format was designed to support raster images with a varying number of planes. In practice, almost all IMG files currently available are simple black and white single plane images because the original file format did not specify a method of storing palette information with the file. To fill this need, several unofficial extensions to the format were put into use (some of which were incorrectly implemented by applications supporting them). The color extension which will be discussed here to cover color images is the 'XIMG' format.
Image headers consist of at least 8 WORDs as follows:
| Meaning |
---|---|
| Image file version (Usually 0x0001). |
| Header length in WORDs. |
| Number of planes. |
| Pattern definition length. |
| Source device pixel width (in microns). |
| Source device pixel height (in microns). |
| Scan line width (in pixels). |
| Number of scan lines. |
Some IMG files will have additional header information which should
be skipped or interpreted as discussed below.
If WORD #2 is set to 1, then the image data consists of
one plane (i.e. monochrome) and any extra header information should
be ignored.
If WORD #2 is set to 16 or 24 then the image data consists
of that many planes of high color or true color data and any extra
header information should be ignored. In a high color image, planes
appear in the order RRRRR GGGGGG BBBBB. In a true-color image,
planes appear in the order RRRRRRRR GGGGGGGG BBBBBBBB.
If WORD #2 is set to 2, 4, or 8, the image consists of
palette based color image data. If no extra header information
is given then the creator did not specify palette data for this
image. If extra header WORDs appears they may be useful
in determining the color palette. The two primary extensions to
the IMG format are 'XIMG' and 'STTT'. 'STTT' will not be discussed
here as it does not serve well as a machine or device independent
format. The 'XIMG' header extension is as follows:
Interpreting Extra Palette Information
| Meaning |
---|---|
| ASCII 'XIMG' |
| Color format (Almost always 0 - RGB). |
| RGB WORD triplets. Three WORDs appear for each pen. There are (2 ^ numplanes) pens. Each word contains a value from 0 to 1000 for direct passage to vs_color(). |
Each scanline contains data in VDI device independent format
which must be converted using the VDI call vr_trnfm().
Each scanline is padded to the nearest byte. Every plane for each
scanline should appear prior to the beginning of data for the
next scanline. This allows interpreters to decompress and transform
the image data a scanline at a time to conserve on time and memory.
A sample ordering for a four-plane image is listed below:
Image Data Format
|
|
|
|
|
|
|
|
|
| Contents |
---|---|
| 0x00 |
| 0x00 |
| 0xFF |
| Replication Count |
Immediately following the vertical replication count is the encoded scanline data. This runlength encoding can by looking for three separate flag BYTEs. A 0x80 BYTE indicates the beginning of a bit-string item. A bit-string item is formatted as follows:
| Contents |
---|---|
| 0x80 |
| Byte count 'n'. |
| 'n' BYTEs of unencoded data. |
A pattern-run item begins with a BYTE of 0x00. It specifies a fixed number of times that the pattern which follows it should be repeated. It is formatted as follows:
| Contents |
---|---|
| 0x00 |
| Length of run. |
| Pattern bytes (length of pattern is determined by header WORD #3). |
Finally, a solid-run item begins with any other BYTE code. If the high order bit is set then this indicates a run of black pixels, otherwise it indicates a run of white pixels. The lower 7 bits of the byte indicates the length of the run in bytes. For example a BYTE code of 0x83 indicates a run of 24 black pixels (3 bytes).
Filenames ending with the extension '.FNT' represent bitmap font
files. These files may be utilized by loading them through any
version of GDOS. FNT files are composed of a file header,
font data, a character offset table, and (optionally) a horizontal
offset table.
Font files begin with a header 88 BYTEs long. WORD
and LONG format entries in the header must be byte-swapped
as they appear in Intel ('Little Endian') format. The font header
is formatted as follows:
The FNT Header
| Contents | Related VDI Call |
---|---|---|
| Face ID (must be unique). | vqt_name() |
| Face size (in points). | vst_point() |
| Face name. | vqt_name() |
| Lowest character index in face (usually 32 for disk-loaded fonts). | vqt_fontinfo() |
| Highest character index in face. | vqt_fontinfo() |
| Top line distance expressed as a positive offset from baseline. | vqt_fontinfo() |
| Ascent line distance expressed as a positive offset from baseline. | vqt_fontinfo() |
| Half line distance expressed as a positive offset from baseline. | vqt_fontinfo() |
| Descent line distance expressed as a positive offset from baseline. | vqt_fontinfo() |
| Bottom line distance expressed as a positive offset from baseline. | vqt_fontinfo() |
| Width of the widest character. | N/A |
| Width of the widest character cell. | vqt_fontinfo() |
| Left offset. | vqt_fontinfo() |
| Right offset. | vqt_fontinfo() |
| Thickening size (in pixels). | vqt_fontinfo() |
| Underline size (in pixels). | vqt_fontinfo() |
| Lightening mask (used to eliminate pixels, usually 0x5555). | N/A |
| Skewing mask (rotated to determine when to perform additional rotation on a character when skewing, usually 0x5555). | N/A |
| Font flags as follows: Bit Meaning (if Set)
0 Contains System Font 1 Horizontal Offset Tables should be used. 2 Font data need not be byte-swapped. 3 Font is mono-spaced. | N/A |
| Offset from start of file to horizontal offset table. | vqt_width() |
| Offset from start of file to character offset table. | vqt_width() |
| Offset from start of file to font data. | N/A |
| Form width (in bytes). | N/A |
| Form height (in scanlines). | N/A |
| Pointer to the next font (set by GDOS after loading). | N/A |
The binary font data is arranged on a single raster form. The raster's height is the same as the font's height. The raster's width is the sum of the character width's padded to end on a WORD boundary.
There is no padding between characters. Each character may overlap BYTE boundaries. Only the last character in a font is padded to make the width of the form end on an even WORD boundary.
If bit #2 of the font flags header item is cleared, each WORD
in the font data must be byte-swapped.
The Character Offset Table is an array of WORDs which specifies
the distance (in pixels) from the previous character to the next.
The first entry is the distance from the start of the raster form
to the left side of the first character. One succeeding entry
follows for each character in the font yielding (number of characters
+ 1) entries in the table. Each entry must be byte-swapped as
it appears in Intel ('Little Endian') format.
The Horizontal Offset Table is an optional array of positive or
negative WORD values which when added to the values in
the character offset table yield the true spacing information
for each character. One entry appears in the table for each character.
This table is not often used.
Resource files contain application specific data which is generally
loaded at run-time. RSC files contain OBJECT trees (see
the discussion of the OBJECT structure in Chapter 6:
AES ), strings, and images.
Two resource file formats are currently supported. TOS
versions less than 4.0 support the original RSC format while TOS
4.0 and greater will now support the older format and a new extensible
format. The original format will be discussed first followed by
an explanation of the changes incurred by the newer format.
Resource files begin with an 18 WORD header as follows:
Character Offset Table
Horizontal Offset Table
The .RSC File Format
The RSC Header
| Field Name | Contents |
---|---|---|
| rsh_vrsn | Contains the version number of the resource file. This value is 0x0000 or 0x0001 in old format RSC files and has the third bit set (i.e. 0x0004) in the new file format. |
| rsh_object | Contains an offset from the beginning of the file to the OBJECT structures. |
| rsh_tedinfo | Contains an offset from the beginning of the file to the TEDINFO structures. |
| rsh_iconblk | Contains an offset from the beginning of the file to the ICONBLK structures. |
| rsh_bitblk | Contains an offset from the beginning of the file to the BITBLK structures. |
| rsh_frstr | Contains an offset from the beginning of the file to the string pointer table. |
| rsh_string | Contains an offset from the beginning of the file to the string data. |
| rsh_imdata | Contains an offset from the beginning of the file to the image data. |
| rsh_frimg | Contains an offset from the beginning of the file to the image pointer table. |
| rsh_trindex | Contains an offset from the beginning of the file to the tree pointer table. |
| rsh_nobs | Number of OBJECTs in the file. |
| rsh_ntree | Number of object trees in the file. |
| rsh_nted | Number of TEDINFOs in the file. |
| rsh_nib | Number of ICONBLKs in the file. |
| rsh_nbb | Number of BITBLKs in the file. |
| rsh_nstring | Number of free strings in the file. |
| rsh_nimages | Number of free images in the file. |
| rsh_rssize | Size of the resource file (in bytes). Note that this is the size of the old format resource file. If the newer format file is being used then this value can be used as an offset to the extension array. |
Many of the header entries represent offsets from the beginning
of the file. These offsets are expressed as positive unsigned
WORDs making the standard file a maximum size of 64k bytes.
Each RSC file may contain a number of object trees. rsh_object
contains an offset from the beginning of the file to the object
trees (stored consecutively). The LONG array pointed to
by rsh_trindex can be used to separate the object trees
in the list. There are rsh_ntree LONGs in this array.
Each array entry can be used as an array index to a different
object tree. After being loaded in memory by rsrc_load(),
the members at rsh_trindex are filled in with the absolute
pointers to their respective trees.
Each individual OBJECT is stored differently on disk then
in memory. In the file, pointers to TEDINFOs, BITBLKs,
and ICONBLKs are stored as absolute indexes into the arrays
of these members stored in the file. Therefore a G_TEXT
OBJECT whose ob_spec field would normally point
a TEDINFO in memory would contain the value 0 if that TEDINFO
were the first TEDINFO contained in the file.
String pointers are represented on disk by their absolute offset
from the beginning of the file. Image pointers in BITBLK
and ICONBLK structures are likewise pointed to through
absolute file offsets, not indexes.
rsh_frstr points to a table of LONGs which each
specify an offset from the start of the RSC file to a free string.
rsh_frimg points to a table of LONGs which each
specify an offset from the start of the file to a BITBLK
structure.
Beginning with AES 3.30, the resource file format was altered
to allow for new OBJECT types. The only OBJECT which
currently takes advantage of this format is G_CICON. G_CICONs
can only be stored in files of the new format. The new format
can be identified by the third bit of rsh_vrsn being set.
Immediately following the old resource data (using rsh_rssize
as an offset) an extension array is added. The first entry in
this array is a LONG containing the true size of the RSC
file. Notice that values such as these are now stored as LONGs
to allow the size of RSC files to exceed 64k. Due to the method
in which some older resource elements were stored many components
of RSC files will still be constrained to 64k.
Following the file size is a LONG word for each extension
present followed by a 0L which terminates the array. Currently
only one extension exists (CICONBLK) and it always
occupies the first extension slot. As additional extensions are
added, a value of -1L for any entry will indicate that there are
no resource elements of that type in the file. For example an
extension array that does contain CICONBLKs would look
like this.
Object Trees
Free Strings and Images
AES 3.30 Resource Format
The Extension Array
|
|
|
|
The G_CICON object type adds the ability to display color icons from the AES. The ob_spec of the object indexes a CICONBLK structure stored in the extension area. Each CICONBLK must contain a monochrome icon and a color icon for as many different resolutions as desired. When drawn, the AES will pick the icon that is the closest match for the current screen display. If there is no color icon present which the AES is able to convert, the monochrome icon is displayed.
The cicon_offset pointer gives an offset from the beginning of the resource file to a file segment which contains the CICON data. This segment contains a CICONBLK pointer table followed by the actual CICONBLKs.
The CICONBLK pointer table is simply a longword 0L for each CICONBLK present in the file. These pointers are filled in by the AES when loaded. The list is terminated by a -1L.
Immediately following the pointer table is one of the following variable length structures for each CICONBLK:
ICONBLK monoicon; /* This is the standard monochrome resource. */ LONG n_cicons; /* Number of CICONs of different resolutions. */ WORD mono_data[x]; /* Monochrome bitmap data. */ WORD mono_mask[x]; /* Monochrome bitmap mask. */ CHAR icon_text[12]; /* Icon text (maximum of 12 characters). */ /* for each resolution supported (n_cicons) include the following structure */ WORD num_planes; /* Number of planes this icon was intended for */ LONG col_data; /* Placeholder (calculated upon loading). */ LONG col_mask; /* Placeholder (calculated upon loading). */ LONG sel_data; /* Placeholder (must be non-zero if 'selected' data exists */ LONG sel_mask; /* Placeholder (calculated upon loadind). */ LONG next_res; /* 1L = more icons follow */ WORD color_data[n]; /* n WORDs of image data (n is num_planes*WORDs in mono icon).*/ WORD color_mask[n]; /* n WORDs of image mask. */ WORD select_data[n]; /* Only present if sel_data is non-zero. */ WORD select_mask[n]; /* Only present if sel_data is non-zero. */
All color image data is stored in VDI device independent format on disk and is automatically converted by vr_trnfm() upon rsrc_load().