DatabasePackedFile
Archive format used many Maxis developed games, includingr The Sims 2 and SimCity 4.
Contents |
Format
Most Sims 2 Data is as you probably know stored in various types of archive files that all have the same internal format such as package, cache, etc. This format is proprietary to Maxis and has been used in the SimCity 4, and The Sims Online as well as this one.
Entries may be compressed with RefPack compression depending on their entry data.
Overview
This is the general structure of DatabasePackedFile packages:
Header (96 bytes)
File 1 File 2 ... File n Index Entry 1 (20 bytes) Index Entry 2 ... Index Entry n
Header first, individual files following with no filenames and a small file header area at the beginning of each followed by an index of all the files in the archive. Note that files may appear after the index table in files that are updated.
Header
Name | Version | Type/Size | Info |
---|---|---|---|
Magic | char[4] | DBPF | |
Major Version | u32 |
| |
Minor Version | u32 | ||
unknown | 2.0 | u32 | |
unknown | 2.0 | u32 | |
unknown | 2.0 | u32 | Should always be zero in DBPF 2.0. |
Date Created | 1.0 | u32 | |
Date Modified | 1.0 | u32 | |
Index major version | < 2.0 | u32 | Always 7 in The Sims 2, Sim City 4. If this is used in 2.0, then it is 0 for SPORE. |
Index entry count | u32 | Number of entries in the Index table. | |
Offset of first Index entry | < 2.0 | u32 | |
Index size | u32 | Size of the Index table in bytes. | |
Hole entry count | < 2.0 | u32 | |
Hole offset | < 2.0 | u32 | |
Hole size | < 2.0 | u32 | |
Index minor version | < 2.0? | u32 | Version 1.1+ in The Sims 2 only. In DBPF 2.0, it has a value of 3, unknown if used. |
Index offset | 2.0 | u32 | Offset to Index table in DBPF 2.0. |
unknown | 2.0 | u32 | |
reserved | char[24] |
Index Table
There are 2 known formats of indexes in the game. The format version is found in the file header.
DBPF 1.x, Index table 7.0
(20 bytes, some DBPF 1.1 entries use this format)
- DWORD
- Type ID (see InternalFormats)
- DWORD
- Group ID
- DWORD
- Instance ID
- DWORD
- Location of the file in the archive
- DOWRD
- Size of the file
DBPF 1.x, Index table 7.1
(24 bytes)
- DWORD
- Type ID (see InternalFormats)
- DWORD
- Group ID
- DWORD
- Instance ID
- DWORD
- Second Instance ID
- DWORD
- Location of the file in the archive
- DOWRD
- Size of the file
Hole Table
DBPF 1.x
A Hole record contains the location and size of all holes in a DBPF file.
- repeating
- DWORD
- Hole Location
- DWORD
- Hole size
Holes are created when the game deletes something from a DBPF. The holes themselves are simply junk data of the appropriate length to fill the hole.
File
Bulk of DBPF packages. Each file is either uncompressed or compressed. To check if a file is compressed you first need to read the DIR resource, if it exists. (See the corresponding entry for a description). If no DIR entry exists, then no files within the package are compressed.
Compression
When reading a DBPF file, the first thing you should do is check to see if any chunks inside are compressed. This is done via the DIR resource.
For example code and a description of the mechanics, see DBPF Compression.
Directory Files
These are used for compression lists. See E86B1EEF
Header
Only if the file is compressed
- DWORD
- Compressed Size of file
- WORD
- Compression ID (0x10FB) QFS Compression. (See packages for compression information)
- 3 bytes
- Uncompressed Size of file
Body
Raw data of the files. See InternalFormats for a list.
Pseudocode
To read files inside a .package file you need to perform the following steps, in order
- Read the DBPF header
- Read the Index tables
- Check for a DIR record
- Check for the file you want to extract
- Is this file compressed? If so, uncompress it
- Read the file data and process accordingly
For an example PHP class for reading DBPF files, see DBPF/Source Code