Packages - Gemini-Loboto3/DC2-Mod-SDK GitHub Wiki
Most data in the game files is stored inside containers that behave like archives, containing several types of information. Every package has a header of 2048 bytes that stores information about the sub-files contained inside. The game uses the following structure to determine what each package can store:
// standard entry in packed headers
typedef struct tagDc2GenericEntry
{
u32 type; // check generic entry type enumation
u32 size; // real size to read
u32 reserve[6]; // round entry to 32 bytes
} DC2_ENTRY_GENERIC;
Each of these entries is exactly 32 bytes for Dino Crisis 2, while it was 16 bytes for the first Dino Crisis. In most cases the entry data can by type-cast to several types which match and never exceed 16 bytes (the reason to expand to 32 bytes is unknown, probably a planned feature for complexity). In order to obtain the count of these entries, the game checks for type == 'dumm' - whenever that string is found or we reach the max amount that can store in 2048 bytes (64 entries), extraction is halted.
These are the types available to the game, depending on the architecture on which it runs:
// dino crisis 2 psx entries
enum GEntryType
{
GET_DATA, // 0 plain data
GET_TEXTURE, // 1 stripped TIM pixel
GET_PALETTE, // 2 stripped TIM clut
GET_SNDH, // 3 VAG header 'Gian'
GET_SNDB, // 4 VAG body
GET_SNDE, // 5 tracker music
GET_UNK, // 6 unknown usage
GET_LZSS0, // 7 compressed data
GET_LZSS1 // 8 compressed texture
};
// dino crisis 2 pc entries
enum GEntryTypePC
{
GPC_DATA, // 0 plain data
GPC_TEXTURE, // 1 swizzled texture
GPC_PALETTE, // 2 color information
GPC_SOUND, // 3 info+riff samples (replaces SNDH+SNDB)
GPC_MP3, // 4 music
GPC_LZSS0, // 5 compressed data
GPC_LZSS1, // 6 compressed texture
GPC_FONT, // 7 used for the 28x28 font inside CORE.DAT
GPC_LZSS2, // 8 large masks in DBS files
};
So depending on what enumeration Id a sub-file has, we can have a multitude of type that we can cast to, in order to obtain more information on how to handle chunks correctly.
// literal or compressed data
typedef struct tagDc2EntryLzs
{
u32 type;
u32 size;
u32 ptr; // destination in ram
} DC2_ENTRY_LZS;
// for TEXTURE (compressed or not) and PALETTE types
typedef struct tagDc2EntryGfx
{
u32 type;
u32 size;
u16 x, y; // framebuffer coordinates
u16 w, h; // framebuffer size
} DC2_ENTRY_GFX;
// for PC exclusive music
typedef struct tagDc2EntryMp3
{
u32 type;
u32 size;
u32 id; // bgm id
u32 loop; // 1 = loop, 0 = non looping
} DC2_ENTRY_MP3;
In order to seek correctly between the various sub-files inside a package, the game rounds the size value of each chunk to 2048 bytes (the size of a data sector on PlayStation, which was also kept on PC).