Table of Contents

TimeSplitters 2 Pak

Pak files for all versions all alike. The GameCube version doesn't use big-endian.

Header 4 bytes 2nd tells you the variant.

Variant 0x34

bool flip = false;
long lOffsetTail = GT.ReadUInt32(fs, 4, flip);
long lTailSize = GT.ReadUInt32(fs, 4, flip);
long lReserved = GT.ReadUInt32(fs, 4, flip);
 
fs.Position = lOffsetTail;
long lNumResources = lTailSize / 60;
for (int i = 0; i < lNumResources; i++) {
	long last = fs.Position;
 
	string sString = GT.ReadASCIItoNull(fs, fs.Position, flip);
 
	fs.Position = last + 48;
 
	long lOffsetFile = GT.ReadUInt32(fs, 4, flip);
	long lFileSize = GT.ReadUInt32(fs, 4, flip);
	byte[] bFReserved = GT.ReadBytes(fs, 4, false);
 
	pack.Add(new Pack(sString, lOffsetFile, lFileSize));
}

Variant 0x38

bool flip = false;
long lOffsetTail = GT.ReadUInt32(fs, 4, flip);
long lNumResources = GT.ReadUInt32(fs, 4, flip);
long lOffsetStringTable = GT.ReadUInt32(fs, 4, flip);
long lOffsetStringSize = GT.ReadUInt32(fs, 4, flip);
 
string hoho = GT.ReadASCII(fs, 12, flip);
 
fs.Position = lOffsetTail;
for (int i = 0; i < lNumResources; i++) {
	long lOffsetFileName = GT.ReadUInt32(fs, 4, flip);
	long lFileSize = GT.ReadUInt32(fs, 4, flip);
	long lOffsetFile = GT.ReadUInt32(fs, 4, flip);
 
	long lStart = lOffsetStringTable + lOffsetFileName;
	string sString = GT.ReadASCIItoNull(fs, lStart, flip);
 
	pack.Add(new Pack(sString, lOffsetFile, lFileSize));
}