MHPF Format - CookiePLMonster/TDUModTools GitHub Wiki
MHPF (Melbourne House Pack File)
Generic container format used to store files in filesystem-like structure.
Present in Test Drive Unlimited PS2/PSP with a .PCK
extension.
Format specification
- One sector is 2048 bytes.
- Format can be both little endian or big endian. Endianness is specified by the magic string in the header. No games are known to use the big endian format, but TDU's MHPF parser proves they existed.
Header
char[4] - 'MHPF' (for little endian archives) or 'FPHM' (for big endian archives)
uint16 - version (1)
uint16 - version (2)
uint32 - total archive size (in bytes)
uint32 - total number of resources
uint32 - hash prime (for resource path hashes), default 31
uint32 - absolute offset to the Resource Table (in bytes)
uint32 - size of the Resource Table (in bytes)
uint32 - absolute offset to the Files Data (in bytes)
uint32 - size of the Files Data (in bytes)
uint32 - absolute offset to the File Name Offsets Table (in bytes)
uint32 - size of the File Name Offsets Table (in bytes)
uint32 - absolute offset to the File Names Data (in bytes)
uint32 - size of the File Names Data (in bytes)
Resource Table
- Section offset must be sector-aligned. Section size has no alignment requirements.
- Entries must be ordered by the hash value, in ascending order.
For every resource:
uint32 - hash of the file path
uint32 - absolute offset to the file data (in bytes)
uint32 - size of the file data (in bytes)
Paths are hashed with the following algorithm:
def pathHash(path, prime):
result = 0
separator = True
for c in path:
if c == '/' or c == '\\':
if separator:
continue
c = '/'
separator = True
else:
separator = False
result = (result * prime) + ord(chr(c).lower())
return result & 0xffffffff
Files Data
- Every file must be sector-aligned, therefore the section offset must be sector-aligned. Files must be padded to the sector size, therefore the section size must be sector-aligned.
- Files are ordered manually to optimize loading speeds. Their ordering does not have to match the order of entries in the Resource Table.
- File data is not compressed or encrypted in any way.
For every resource:
byte[] - raw file data
File Name Offsets Table
- Sector has no offset or size alignment requirements.
- All offsets are relative to the start of the File Names Data.
- Entries are ordered accordingly to the ordering of entries in the Resource Table.
For every resource:
uint32 - offset to the file name (relative)
File Names Data
- Sector has no offset or size alignment requirements.
- Entries do not have to follow a specific order.
For every resource:
char[] - null terminated file path
Other resources
- 010 Editor MHPF template by Nenkai