Warning: This site is under construction, most links will be broken.

Open formats: ZGP: game package file format

Last modified on Sun, 30th Nov 2008 at 14:58 GMT by zipplet

1. ZGP game package file format, 1.2
------------------------------------

Copyright (c) Michael Nixon (Zipplet) 2004 - 2008.

web: http://www.zipplet.co.uk/, http://www.zipplet.org/
email: zipplet@zipplet.co.uk

1a. Changes since 1.1
---------------------

- Added the GZip and BZ2 compression algorithyms (not currently supported by official tools)

Note: Support for archive signing will be coming soon in a future spec.

Changes since 1.0
-----------------

- Changed the deflate compression ID to $0008
- Removed references to zlib - the standard is called deflate.

2. Introduction
---------------

ZGP is a resource archive file format - multiple resources are stored inside a
single ZGP archive and accessed by the game without unpacking the archive.
Games will take up less disk space (because cluster losses due to lots of
small files will not be an issue) and install quicker.

Byte order is little endian, so if the specification states that $ABCD will be
written, it will be written as $CDAB.

3. Basic file structure
-----------------------

+-------------+----------------------------------------------------------------+
| Location    |  Description                                                   |
+-------------+----------------------------------------------------------------+
| Beginning   | Archive header - identifies archive as ZGP                     |
+-------------+----------------------------------------------------------------+
|             | Data                                                           |
+-------------+----------------------------------------------------------------+
|             | File allocation table                                          |
+-------------+----------------------------------------------------------------+
| EOF-6       | Pointer to file allocation table                               |
+-------------+----------------------------------------------------------------+
| EOF-2       | $5A, $47, $50 ("ZGP")                                          |
+-------------+----------------------------------------------------------------+

4. Identifying and mounting a ZGP archive
-----------------------------------------

The loader should first look at the archive header. If the archive header
identifies the file as a valid ZGP archive and the version is supported, the
loader should then read the pointer to the file allocation table, and maybe
cache entries from the file allocation table. The 3 bytes just after the FAT
are for the purpose of detecting a truncated ZGP.

The ZGP unit for the diraccess library performs these checks but also parses
the entire FAT on load and does sanity checks on the FAT also. This is
recommended to prevent a crash during a game due to a bad ZGP.

5. Archive header
-----------------

All types shown are types used in the Delphi programming language.

+-------------+-------------+--------------------------------------------------+
| Bytes       | Type        | Description                                      |
+-------------+-------------+--------------------------------------------------+
| 256         | shortstring | "ZGP: game package"                              |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Major version                                    |
+-------------+-------------+--------------------------------------------------+

The major version is currently "1". Loaders should check both the shortstring
and the major version, and refuse to load a ZGP with a shortstring that does not
match the one in this document, or a ZGP with a major version that is greater
than the version the loader was designed for.

6. Pointer to file allocation table
-----------------------------------

This is simply a 32-bit integer, which points to the beginning of the FAT.
The offset is 0 based. The maximum size of a ZGP archive is 4GB.

7. File allocation table
------------------------

All types shown are types used in the Delphi programming language.

+-------------+-------------+--------------------------------------------------+
| Bytes       | Type        | Description                                      |
+-------------+-------------+--------------------------------------------------+
| 3           | byte*3      | $46, $41, $54 ("FAT")                            |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Number of entries in the table                   |
+-------------+-------------+--------------------------------------------------+
|             | fatrecord*n | FAT records                                      |
+-------------+-------------+--------------------------------------------------+

8. FAT record format
--------------------

+-------------+-------------+--------------------------------------------------+
| Bytes       | Type        | Description                                      |
+-------------+-------------+--------------------------------------------------+
| 256         | shortstring | File name and path                               |
|             |             | - Leading / is not present                       |
|             |             | - / is the directory seperator for compatibility |
|             |             |   with the diraccess library                     |
|             |             | - Path can include directory names               |
|             |             | Example: "graphics/mario/left1.fbm"              |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Unix timestamp of file modification time         |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Offset to start of data in ZGP archive (0 based) |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Size of compressed data in ZGP archive           |
|             |             | - if this resource is not compressed, this field |
|             |             |   will be equal to the size of uncompressed data |
|             |             |   field. This field must always be set even for  |
|             |             |   uncompressed resources!                        |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Size of uncompressed data                        |
|             |             | - this is the size of the resource once it is    |
|             |             |   uncompressed.                                  |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Compression method                               |
|             |             | - There is a list of compression methods later in|
|             |             |   this document.                                 |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Version of decompressor required to decompress   |
|             |             | - a decompressor should not attempt to decompress|
|             |             |   a newer version than it was designed for.      |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Resource version                                 |
|             |             | - this is application specific, the application  |
|             |             |   may use this field for anything it wants.      |
+-------------+-------------+--------------------------------------------------+
| 4           | integer     | Extra information                                |
|             |             | - this is application specific, the application  |
|             |             |   may use this field for anything it wants.      |
+-------------+-------------+--------------------------------------------------+

9. Compression methods and versions
-----------------------------------

+------------+-----------------+-----------------------------------------------+
| Identifier | Current version | Name                                          |
+------------+-----------------+-----------------------------------------------+
| $0000      | $0000           | Raw uncompressed data                         |
+------------+-----------------+-----------------------------------------------+
| $0008      | $0100           | Deflate                                       |
+------------+-----------------+-----------------------------------------------+
| $0100      | $0000           | GZ                                            |
+------------+-----------------+-----------------------------------------------+
| $0200      | $0000           | BZ2                                           |
+------------+-----------------+-----------------------------------------------+