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).