GoodEngine/HO (File Format): Difference between revisions

no edit summary
(Created page with "'''HO archives''' are container files used by Heavy Iron Studios in their 7 Havok games. They are used to store assets, which are the resources and objects used to create levels, characters and menus for the games. ==Blocks== ===HEL/HEB=== 0x800 HO header {| class="wikitable" |- ! Offset !! Type !! Variable !! Description |- | 0x00 || int/string || '''cMagic''' || "'''HEL'''" or "'''HEB'''" |- | 0x04 || int || '''verPackFile''' || |- | 0x08 || int || '''verWMlSchema''...")
 
No edit summary
 
(16 intermediate revisions by 2 users not shown)
Line 1:
'''HO archives''' are container files used by Heavy Iron Studios in their 7 Good Engine/Havok games. They are used to store assets, which are the resources and objects used to create levels, characters and menus for the games.
 
==Blocks=Endian===
HO archives are stored as [https://en.wikipedia.org/wiki/Endianness big endian] in all console versions of each game. Family Guy PC archives are stored as [https://en.wikipedia.org/wiki/Endianness little endian].
===HEL/HEB===
0x800 HO header
 
==Format==
===Header===
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || int/stringchar[4] || '''cMagic''' || "'''HEL'''" or "'''HEB'''"
|-
| 0x04 || int || '''verPackFile''' ||
Line 17 ⟶ 18:
| 0x0C || int || '''geBuildNum''' ||
|-
| 0x10 || long || '''timeValue''' || Number of seconds since 00:00, Jan 1 1970 UTC, with a timezone offset of UTC-7:00 (Pacific Time).
| 0x10 || int || '''pad''' || padding
|-
| 0x18 || char[0x18] || '''timeString''' || <code>Www Mmm dd hh:mm:ss yyyy</code>
| 0x14 || int || '''timeValue''' || Number of seconds since 00:00, Jan 1 1970 UTC, with a timezone offset of UTC-7:00 (Pacific Time)
|-
| 0x180x40 || stringint || [FormatInfo] '''timeStringsectorSize''' || <code>Www MmmAlways dd0x800 hh:mm:ss(2048 yyyy</code>bytes).
|-
| 0x400x44 || int || [MasterTable] '''sectorSizestartSector''' || Always 1 (if '''sectorSize''' is 0x800).
|-
| 0x440x48 || int || [MasterTable] '''startSectortableSize''' || Size of [[#MasterTable|MAST]].
|-
| 0x480x4C || intbyte[0x3B4] || '''tableSizereserved''' || ''null''
|-
| 0x4C0x400 || intWideString || '''pad01platform''' || padding
|-
| 0x400 || string || '''platform''' ||
* WII
* PS3
* XENON (Xbox360)
* PC?
|-
| 0x43C || stringWideString || '''user''' || always "'''hvir_autobuild'''"
|-
| 0x47C || stringWideString || '''target''' ||
* Rats = Ratatouille
* WALE = Wall-E
* Up = Up
* SB09 = SpongeBob's Truth or Square
* UFCT = UFC Personal Trainer
* FIVE = Harley Pasternak's Hollywood Workout
* FGUY = Family Guy: BTTM
* FGUY = Family Guy: Back to the Multiverse
* FIVE = Hollywood Workout
|-
| 0x4BC || stringWideString || '''creator''' || always "'''GoodEditor:PackView.GEPlugin'''"
|-
| 0x4FC || stringWideString || '''comment''' || ''null''
|-
| 0x5FC || stringWideString || '''hash''' ||
|-
| 0x63C || int || '''libVersion''' || Always 1.
|-
| 0x640 || intbyte[0x1C0] || '''pad02reserved''' || padding''null''
|}
 
===MasterTable===
====TableHeader====
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || char[4] || '''tableTypeTag''' || '''MAST'''
|-
| 0x04 || int || '''entryCount''' || Amount of [[#MasterEntry|master entries]], always 1.
|-
| 0x08 || int || '''tableFlags''' || ''null''
|-
| 0x0C || int || '''firstString''' || Offset to [[#StringTable|StringTable]], relative to start of this header.
|-
| 0x10 || int || '''stringTableSize''' || Size of [[#StringTable|StringTable]], relative to end of [[#MasterEntry|MasterEntry]].
|-
| 0x14 || int || '''firstMetaRec''' || ''0xFFFFFFFF''
|-
| 0x18 || int || '''metaDataSize''' || ''null''
|-
| 0x1C || byte[4] || '''reserved''' || ''null''
|}
 
====MasterEntry====
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || int || '''sectionType''' || '''SECT/TCES'''
|-
| 0x04 || ushort || '''packLangID''' || ''null''
|-
| 0x06 || ubyte || '''parcelType''' || ''null''
|-
| 0x07 || byte || '''pad''' || ''0x33''
|-
| 0x08 || int || '''userKey''' || ''null''
|-
| 0x0C || uint || '''nameHash''' || Lowercase BKDR hash of domain string.
|-
| 0x10 || int || '''namePtr''' || Offset to domain string, relative to start of [[#MasterTable|MAST]].
|-
| 0x14 || uint || '''fromNameHash''' || ''null''
|-
| 0x18 || int || '''fromNamePtr''' || ''0xFFFFFFFF''
|-
| 0x1C || int || '''startSector''' || Multiply this by [[#Header|'''sectorSize''']] to get the absolute offset. Start of [[#SectionTable|SectionTable]].
|-
| 0x20 || int || '''sizeOnDisk''' || Size of [[#SectionTable|SECT]].
|-
| 0x24 || int || '''sizeInMem''' || Size of [[#SectionTable|SECT]].
|-
| 0x28 || int || '''memoryAlignment''' || ''0xFFFFFFFF''
|-
| 0x2C || int || '''attributeFlags''' || ''null''
|-
| 0x30 || int || '''externName''' || ''0xFFFFFFFF''
|-
| 0x34 || int || '''metaBlockCount''' || ''null''
|-
| 0x38 || int || '''metaRecord''' || ''0xFFFFFFFF''
|-
| 0x3C || byte[4] || '''reserved''' || ''null''
|}
 
=====StringTable=====
Unknown
 
===SectionTable===
====TableHeader====
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || char[4] || '''tableTypeTag''' || '''SECT'''
|-
| 0x04 || int || '''entryCount''' || Amount of [[#SectionEntry|section entries]].
|-
| 0x08 || int || '''tableFlags''' || ''null''
|-
| 0x0C || int || '''firstString''' || Offset to domain string, relative to start of this header.
|-
| 0x10 || int || '''stringTableSize''' || Size of domain string.
|-
| 0x14 || int || '''firstMetaRec''' || Offset to [[#MetaSection|MetaSection]], relative to start of this header.
|-
| 0x18 || int || '''metaDataSize''' || Size of PSL/PSLD entries in [[#MetaSection|MetaSection]] (without child blocks).
|-
| 0x1C || byte[4] || '''reserved''' || ''null''
|}
 
====SectionEntry====
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || int || '''sectionType''' ||
* '''P''' = Parcel
* '''PD/DP''' = ParcelDebug
* '''PTEX/XETP''' = ParcelTexture
* '''PFST/TSFP''' = ParcelMemFast '''(Not present in Ratatouille)'''
|-
| 0x04 || ushort || '''packLangID''' ||
'''Values are in big-endian'''<br>First byte is region code, second byte is language code<br>E.g., 0x0409 = English US, 0x0009 = English Neutral
* 0x0000 = Neutral Neutral
* 0x0401 = Arabic SaudiArabia
* 0x0804 = Chinese China
* 0x0C04 = Chinese HongKong
* 0x0404 = Chinese Taiwan
* 0x1004 = Chinese Singapore
* 0x0405 = Czech Republic
* 0x0406 = Danish Denmark
* 0x0413 = Dutch Netherlands
* 0x0409 = English US
* 0x0809 = English UK
* 0x0C09 = English Australia
* 0x1009 = English Canada
* 0x040B = Finnish Finland
* 0x040C = French France
* 0x0407 = German Germany
* 0x0807 = German Swiss
* 0x0408 = Greek Greece
* 0x0410 = Italian Italy
* 0x0411 = Japanese Japan
* 0x0412 = Korean Korea
* 0x0814 = Norwegian Nynorsk
* 0x0415 = Polish Poland
* 0x0816 = Portuguese Portugal
* 0x0416 = Portuguese Brazilian
* 0x0419 = Russian Federation
* 0x041B = Slovak Slovak
* 0x080A = Spanish Mexican
* 0x0C0A = Spanish Spain
* 0x041D = Swedish Sweden
* 0x0422 = Ukrainian Ukraine
|-
| 0x06 || ubyte || '''parcelType''' ||
* 0 = UNDEFINED
* 1 = EXCLUSIVE
* 2 = SHARED
* 3 = FROMDOMAIN
|-
| 0x07 || byte || '''pad''' || ''0x33''
|-
| 0x08 || int || '''userKey''' || ''null''
|-
| 0x0C || uint || '''nameHash''' || Lowercase BKDR hash of domain string.
|-
| 0x10 || int || '''namePtr''' || Offset to domain string, relative to start of [[#SectionTable|SECT]].
|-
| 0x14 || uint || '''fromNameHash''' || Lowercase BKDR hash of domain string from original parcel (if '''parcelType''' is 3).
|-
| 0x18 || int || '''fromNamePtr''' || ''0xFFFFFFFF''
|-
| 0x1C || int || '''startSector''' || Multiply this by [[#Header|'''sectorSize''']] to get the absolute offset. Start of section.
|-
| 0x20 || int || '''sizeOnDisk''' || Size of section.
|-
| 0x24 || int || '''sizeInMem''' || Size of section.
|-
| 0x28 || int || '''memoryAlignment''' || Memory alignment of ParcelData assets in section.
|-
| 0x2C || int || '''attributeFlags''' || ''null''
|-
| 0x30 || int || '''externName''' || ''0xFFFFFFFF''
|-
| 0x34 || int || '''metaBlockCount''' || Amount of [[#ParcelSliceMeta|PSL]]/[[#ParcelSliceDebugMeta|PSLD]] entries, always 1.
|-
| 0x38 || int || '''metaRecord''' || Offset to [[#ParcelSliceMeta|PSL]] (P, PTEX, PFST) or [[#ParcelSliceDebugMeta|PSLD]] (PD) entry, relative to start of [[#SectionTable|SECT]].
|-
| 0x3C || byte[4] || '''reserved''' || ''null''
|}
 
===MetaSection===
====ParcelSliceMeta====
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
! colspan="4" | MetaParcelSlicesHeader
|-
| 0x00 || char[4] || '''metatype''' || '''PSL'''
|-
| 0x04 || int || '''metasize''' || Size of PSL.
|-
| 0x08 || int || '''numSlices''' || Amount of slice entries.
|-
| 0x0C || int || '''reserved''' || ''null''
|-
! colspan="4" | MetaParcelSlicesEntry
|-
| 0x00 || int || '''sliceType''' ||
* 0 = [[#ParcelTOC|ParcelTOC]]
* 1 = ParcelData
* 2 = Padding (0x33)
|-
| 0x04 || int || '''sliceStart''' || Offset to slice, relative to start of [[#SectionEntry|'''startSector''']].
|-
| 0x08 || int || '''sliceSize''' || Size of slice in [[#SectionEntry|SectionEntry]].
|-
| 0x0C || int || '''sliceAlign''' ||
|}
 
=====ParcelTOC=====
{| class="wikitable
|-
! Offset !! Type !! Variable !! Description
|-
! colspan="4" | TOCHeader
|-
| 0x00 || int || '''elementCount''' || Amount of TOC entries.
|-
| 0x04 || int || '''brickDataOffset''' ||
|-
| 0x08 || int[6] || ''' reserved''' || ''0x74747474''
|-
! colspan="4" | TOCEntry
|-
| 0x00 || int || '''elementSize''' || Size of asset (with 0x33 padding bytes).
|-
| 0x04 || int || '''elementOffset''' || Offset to asset, relative to start of [[#SectionEntry|'''startSector''']].
|-
| 0x08 || int || '''blobSize''' || Size of asset (without 0x33 padding bytes).
|-
| 0x0C || int || '''blobAlign''' ||
|-
| 0x10 || [[AssetID]] || '''uidSelf''' || AssetID of corresponding asset.
|-
| 0x18 || int || '''wmlTypeID''' || AssetType of corresponding asset.
|-
| 0x1C || short || '''subType''' || Not present in Ratatouille/Wall-E
|-
| 0x1E || short || '''blobFlags''' || int32 in Ratatouille/Wall-E
|}
 
====ParcelSliceDebugMeta====
{| class="wikitable
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || string || '''magic''' || '''PSLD'''
|-
| 0x04 || int || '''size''' || Size of PSLD.
|-
| 0x08 || int || '''count'''|| Amount of [[#PSLD Entry|'''entrySize''']] and [[#PSLD Entry|'''NameTableEntry''']].
|-
| 0x0C || int || '''offset''' || Offset to [[#PSLD Entry|'''NameTableEntry''']], relative to start of [[#SectionEntry|'''startSector''']].
|-
| 0x10 || byte[16] || Unknown ||
|}
 
=====PSLD Entry=====
{| class="wikitable"
|-
! Offset !! Type !! Variable !! Description
|-
| 0x00 || int[count] || '''entrySize''' || Length in bytes of the entries below.
|-
! colspan="4" | NameTableEntry
|-
| 0x00 || [[AssetID]] || '''assetid''' || AssetID of corresponding asset.
|-
| 0x08 || int || '''offset'''? || Relative offset to assetname?
|-
| 0x0C || int || Unknown ||
|-
| 0x10 || int || Unknown || ''0xFFFFFFFF''
|-
| 0x14 || int[3] || Unknown || ''null''
|-
| 0x20 || char[] || '''assetname''' || Null-terminated name of corresponding asset.
|-
| colspan="4 | Padding - 0x33 bytes until this entry reaches '''<entrySize>''' in length.
|}
 
 
[[Category:File Format]] [[Category:GoodEngine]]
2,079

edits