19/02/2007, 10:42 PM
Note, I'm assuming you already have basic hex editing knowledge...
This is the file structure, as far as I know, of decrypted (FW2.60 and lower) RCOs.
Many thanks go to Z33 at MaxConsole for providing much information on this. His thread can be found here.
NOTES:
Anyways, there's 3 basic sections of the RCO.
Contents
RCO Header
Table Section (begins at 0xA4)
If the table area is compressed (FW2.60), there are 3 DWords before the compressed data:
For FW2.71+, the table seems to be packed in parts, rather than the whole table section packed together.
Now, back to the uncompressed header.
Each table entry seems to have a 40 byte header, followed by the entry data. (note, the "main entry" refers to the first one - which "contains" all the other entries)
Table entry headers
Table entry data
This varies, depending on the type:
Entry Pointer sections
These immediately follow the above tables. They just contain absolute offsets to the various subentries above. These sections are described by the values from 0x50 to 0x80, and follow the same order.
However, these seem to be out of order, and have "null" entries. Don't understand why, lol
Text/"native:/" Tables
The "text tables" (offset is given at 0x40 and 0x48) are just ASCII text separated by null characters. Each string is aligned to a 4 byte boundary (thus extra padding may be used).
Data Area
Basically, where all the data is stored...
Resources are aligned to 4 byte boundaries (thus padding may be used to achieve this).
Deflated resources have the 2 byte signature, 0xDA78. "Encrypted" resources have the 2 byte signature, 0xD905.
Alright, that's all I really know about the RCO format - Z33 has some more info in his documentation (can be found here).
Hope this guide helped someone
This is the file structure, as far as I know, of decrypted (FW2.60 and lower) RCOs.
Many thanks go to Z33 at MaxConsole for providing much information on this. His thread can be found here.
NOTES:
- I tend to refer to "encrypted" - RCOs aren't really encrypted, but just compressed in an unknown way. I use this word for convenience purposes :P
- Everything is aligned to a 4 byte boundary, so basically all values are DWords. There are one or two which are just Words however. Thus, padding is used to achieve this 4 byte boundary at times
- Lengths don't include padding (obviously)
- For text entries, they are always separated by at least one null character
Anyways, there's 3 basic sections of the RCO.
Contents
RCO Header
Offset | Type/Size | Purpose |
0x00 | DWord | RCO Signature, always is 0x46525000 (.PRF) |
0x04 | DWord | Appears to be a switch of some kind:
|
0x08 | DWord | Unknown - always seems to be 0x00 |
0x0C | DWord | Seems to change when different compressed headers are used:
|
For the following sections, 0xFFFFFF means the section doesn't exist | ||
0x10 | DWord | Offset of the "information"? table - always is 0xA4 |
0x14 | DWord | Unknown. Always seems to be 0xFFFFFF |
0x18 | DWord | Offset of the text table |
0x1C | DWord | Offset of the sound (VAG) table |
0x20 | DWord | Offset of the model (OMG) table |
0x24 | DWord | Offset of the image (MIG) table |
0x28 | DWord | Unknown. Always seems to be 0xFFFFFF |
0x2C | DWord | Unknown. Always seems to be 0xFFFFFF |
0x30 | DWord | Offset of the "page" table |
0x34 | DWord | Offset of the "anim" table |
0x40 | DWord | Offset of the label table |
0x44 | DWord | Length of the label table |
0x48 | DWord | Offset of the "native:/" table |
0x4C | DWord | Length of the "native:/" table |
0x50 | DWord | Offset of the text pointer table. |
0x54 | DWord | Length of the text pointer table. |
0x58 | DWord | Offset of the image (MIG) pointer table. |
0x5C | DWord | Length of the image (MIG) pointer table. |
0x60 | DWord | Offset of the model (OMG) pointer table. |
0x64 | DWord | Length of the model (OMG) pointer table. |
0x68 | DWord | Offset of the sound (VAG) pointer table. |
0x6C | DWord | Length of the sound (VAG) pointer table. |
0x70 | DWord | Offset of the "page" pointer table. |
0x74 | DWord | Length of the "page" pointer table. |
0x78 | DWord | Offset of the "anim" pointer table. |
0x7C | DWord | Length of the "anim" pointer table. |
0x38 | DWord | (note the offset) Offset and length to some text. If this text doesn't exist, this value is the same as the value at 0x40, and length is 0x00. |
0x80 | DWord | Offset of the image (MIG) data section |
0x84 | DWord | Length of the image (MIG) data section |
0x88 | DWord | Offset of the sound (VAG) data section |
0x8C | DWord | Length of the sound (VAG) data section |
0x90 | DWord | Offset of the model (OMG) data section |
0x94 | DWord | Length of the model (OMG) data section |
0x98 | DWord | End marker??? Always seems to be 0xFFFFFF |
0x9C | DWord | End marker??? Always seems to be 0xFFFFFF |
0xA0 | DWord | End marker??? Always seems to be 0xFFFFFF |
Table Section (begins at 0xA4)
If the table area is compressed (FW2.60), there are 3 DWords before the compressed data:
Offset | Type/Size | Purpose |
0x00 | DWord | Packed size of all the table sections |
0x04 | DWord | Unpacked size of all the table sections |
0x08 | DWord | "Something about the unpacked size of the next file after the packed header..." -Z33 |
For FW2.71+, the table seems to be packed in parts, rather than the whole table section packed together.
Now, back to the uncompressed header.
Each table entry seems to have a 40 byte header, followed by the entry data. (note, the "main entry" refers to the first one - which "contains" all the other entries)
Table entry headers
Offset | Type/Size | Purpose |
0x00 | Byte | ID of the current entry??? The main entry, seems to have a value of 1. Some subentries seem to use this as the "depth" of the current entry. |
0x01 | Byte | Type of the entry. Here's a few:
|
0x02 | Word | Unknown - always seem to be 0x0000 |
0x04 | DWord | Offset to the label (relative to the label table). 0xFFFFFFFF means the label doesn't exist for this entry |
0x08 | DWord | Size of entry header? (always 0x28) |
0x0C | DWord | Offset of current entry to first entry (of same depth)? |
0x10 | DWord | Number of subentries in this one |
0x14 | DWord | Size of the entry |
0x18 | DWord | Offset to the next entry? |
0x1C | DWord | Current entry offset from the main table (which is always 0xA4) |
0x20 | DWord | Unknown - always seem to be 0x00000000 |
0x24 | DWord | Unknown - always seem to be 0x00000000 |
For entry headers longer than this, the rest is unknown |
Table entry data
This varies, depending on the type:
0x03 (text)
This starts off with 2 bytes, before the actual text indexes.
After this, is the actual text indexes (each is 12 bytes long):
Offset | Type/Size | Purpose |
0x00 | DWord | Language ID:
|
0x04 | DWord | Number of text indexes in current entry |
Offset | Type/Size | Purpose |
0x00 | DWord | Offset to label, relative of the label table |
0x04 | DWord | Length of the text |
0x08 | DWord | Offset of the text, relative to the text data start address |
0x04 (image)
Offset | Type/Size | Purpose |
0x00 | Word | File type ID (0x05 = MIG) |
0x02 | Word | Compression flag? 0x00 = uncompressed, 0x01 = zlib deflated |
0x04 | DWord | Packed size of data without padding |
0x08 | DWord | Offset of data relative to the beginning of the image data section |
0x0C | DWord | Size of unpacked data |
0x05 (object)
Offset | Type/Size | Purpose |
0x00 | Word | File type ID? (0x00 = OMG) |
0x02 | Word | Compression flag? 0x00 = uncompressed, 0x01 = zlib deflated |
0x04 | DWord | Packed size of data without padding |
0x08 | DWord | Offset of data relative to the beginning of the image data section |
0x0C | DWord | Size of unpacked data |
0x06 (sound)
Offset | Type/Size | Purpose |
0x00 | Word | File type ID? (0x01 = VAG) |
0x02 | Word | Number of channels, either 0x01 or 0x02 |
0x04 | DWord | Size of data (if there's two channels, then this is the size of both) |
0x08 | DWord | Offset of the sound data to the beginning of the sound data section |
0x0C | DWord | Size of left channel VAG |
0x10 | DWord | Offset of left channel VAG to the beginning of the sound data section |
Note, the following values don't exist for single channel VAGs | ||
0x14 | DWord | Size of right channel VAG |
0x18 | DWord | Offset of right channel VAG to the beginning of the sound data section |
0x08 (page)
In this section, the entry ID (from the table entry header described above) is rather important in determining what the page entry does, and the type of values under it.
A few common common characteristics first though:
Many entries have a "position description" at the beginning. This consists of 13 consecutive float values:
For the position values, 0 = centre of screen. For the colour channels, 0 = no colour, 1 = full colour (for example, the colour red (FF0000FF in hex colour code) would be R:1, G:0, B:0, A:1)
Another common thing are "objects". These consist of two DWords, the first is a type descriptor, the second refers points to the object. Below is a list of the types of objects known:
Now onto each type of entry. The following table shows the types of values (in order) under each particular type of page entry. (note, RCO Editor will stick a "8" at the front, thus 0x802 instead of 0x02)
A few common common characteristics first though:
Many entries have a "position description" at the beginning. This consists of 13 consecutive float values:
# | Purpose |
1 | Position X |
2 | Position Y |
3 | Object Scale |
4 | Colour Channel (Red) |
5 | Colour Channel (Green) |
6 | Colour Channel (Blue) |
7 | Colour Channel (Alpha) |
8 | Dimension - Width |
9 | Dimension - Height |
10 | Unknown |
11 | Stretch X |
12 | Stretch Y |
13 | Element Scale |
Another common thing are "objects". These consist of two DWords, the first is a type descriptor, the second refers points to the object. Below is a list of the types of objects known:
Type | Pointer |
0x400 (event) | Points to a native:/ entry relative to the "native" table. |
0x401 (text) | The text entry #. For example, 0 = the first text entry. |
0x402 (image) | Absolute pointer to the image table entry. |
0x403 (model) | Absolute pointer to model table entry. |
0x407 (page?) | Same as 0x409??? |
0x408 (anim) | Absolute pointer to anim table entry. |
0x409 (page) | Absolute pointer to page table entry. |
0xFFFF (blank) | This value should always be 0xFFFFFFFF |
Now onto each type of entry. The following table shows the types of values (in order) under each particular type of page entry. (note, RCO Editor will stick a "8" at the front, thus 0x802 instead of 0x02)
Type | Data |
0x01 (page) | * note that this is always a top level page entry 0x111 (dunno what this does) <object (event)> <object (event)> <object (event)> <object (event)> |
0x02 (plane) | * this entry seems to describe an image <position description> <DWord> <object (event)> <object (image)> <DWord> |
0x03 (button) | * this entry seems to be used for "buttons" or small images <position description> <DWord> <object (event)> <object (image)> <object (image)> <object (image)> <object> <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> <DWord> |
0x04 (xmenu? [XmbMenu?]) | <position description> <?> <object (event)> <DWord> * number of sub menus? <object (event)> <object (event)> <object (event)> <object (event)> <object> |
0x05 (list [XmbMainList?]) | * this entry seems to only appear for XMB main menu icons <?> <object (image)> <object> |
0x06 (xlist [XmbList]) | <position description> <DWord> <object (event)> <DWord> * seems to be number of items under this xlist <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> <object (event)> |
0x07 | <position description> <DWord> <object (event)> <Float> <?> <object> <object> <object> |
0x08 (scroll?) | * A scrollbar??? Only seems to appear under lists <position description> <DWord> <object> <Float> <Float> <?> <object> <object> <object> <object> <object> |
0x09 (mlist [MenuList]) | * seems to describe those context menus, for example, selecting a language in the System Settings <position description> <DWord> <object (event)> <DWord> <?> <DWord> <Float> <Float> <object> <object (event)> <object> <object> <object> <object (event)> <object> <object> <object> <object (event)> <object> |
0x0A (item [MenuItem]) | * Item under MenuList <object (text)> <object (text)> <object> |
0x0B | * This type doesn't seem to exist :P |
0x0C (item_xlist [XmbListItem]) | <object (image)> <object (text)> <object> |
0x0D (text) | <position description> <DWord> <object> <object (text)> <object> <DWord> <DWord> <Float> <Float> <Float> <Float> <Float> <Float> <Float> <?> <?> <?> <?> <Float> <Float> <Float> <?> <Float> <Float> <Float> <Float> <?> <?> <?> <Float> <Float> <Float> <Float> <DWord> |
0x0E (model) | <position description> <?> <object (event)> <object (model)> |
0x0F | <position description> <DWord> <object (event)> <?> <DWord> <object> <object> <object (event)> <object (event)> <object (event)> <object> <object> <object> <object> <object> |
0x10 | <object> |
0x11 (item_spin) | * seems to be some item which often changes - eg the seconds counter when listening to music <position description> <DWord> <object (event)> <DWord> <DWord> <DWord> <DWord> <DWord> <Float> <object> <object> <object (event)> <object (event)> <object> <object> <object> <object> <object (page)> <object (page)> |
0x12 (group) | * used to group page resources together? <position description> <DWord> <object> |
0x13 (list?) | <position description> <DWord> <object> <DWord> <?> <Float> <object> <object> <object> <object> <object> <object> <object (event)> <object> |
0x14 (litem?) | <object (text)> <object> <object> |
0x15 (edit?) | * An edit field? <position description> <DWord> <object (event)> <?> <?> <?> <?> <object> <object> <object (event)> <object> <object> <object> <object (event)> <object (event)> <object (page)> <object (page)> <object> |
0x16 (clock) | * O_o, a clock :P <position description> <DWord> <object (event)> <DWord> <Float> <object (text)> <object (text)> <object> <object> <object (event)> <object (event)> <object> <object> <object (event)> <object (event)> <object> <object> <object (event)> |
0x17 (ilist [InfoList]) | <position description> <DWord> <object (event)> <Float> <object> <object> <object (event)> <object> |
0x18 (item [InfoItem]) | * A piece of "information" <object (text)> * Default text to display <object (text)> * Error/alternative text to display |
0x19 (icon?) | <position description> <?> <object (event)> <object (image)> <object (image)> <object> |
0x09 (anim)
Note that the following information has not been tested yet - it's actually just my idea on how it works :P
The structure of anim resources are similar to that of page resources. There's no multiple-depth subentries, and subentries don't have a label.
It seems that each subentry describes a "command". The PSP, when the animation sequence is fired, will start executing each command in order in parallel, until a DELAY (0x07) command is reached.
Most of these commands involve modifying some attribute of a page resource - for these, the first bit of data is the <object (page)> to modify, then the next item would be the time (in ms) it takes to perform the animation (for example, if a set position command is given, with time=100, then the PSP will take 0.1 seconds to animate the page moving to the specified position). Times are floats (so decimals accepted).
Note that anim resources will borrow the <object> concept from page resources.
Here's the list of IDs: (note, RCO Editor will stick a "9" at the front, thus 0x902 instead of 0x02)
The structure of anim resources are similar to that of page resources. There's no multiple-depth subentries, and subentries don't have a label.
It seems that each subentry describes a "command". The PSP, when the animation sequence is fired, will start executing each command in order in parallel, until a DELAY (0x07) command is reached.
Most of these commands involve modifying some attribute of a page resource - for these, the first bit of data is the <object (page)> to modify, then the next item would be the time (in ms) it takes to perform the animation (for example, if a set position command is given, with time=100, then the PSP will take 0.1 seconds to animate the page moving to the specified position). Times are floats (so decimals accepted).
Note that anim resources will borrow the <object> concept from page resources.
Here's the list of IDs: (note, RCO Editor will stick a "9" at the front, thus 0x902 instead of 0x02)
ID | Description | Data |
0x01 | Parent | * No data |
0x02 | Set pos. | <object (page)> Time <?> Target X Target Y <?> |
0x03 | Set colour | <object (page)> Time <?> New Red value New Green value New Blue value New Alpha value |
0x05 | Set scale? | <object (page)> Time <?> New Object Scale? New X Scale? New Y Scale? |
0x06 | Set alpha | <object (page)> Time <?> New Alpha value |
0x07 | Delay | Time |
0x08 | Fire event | <object (event)> |
0x09 | Some switch??? | 0xFFFFFFFF |
0x0B | ??? | <object (page)> <?> <?> <Float> <?> <?> <Float> |
Entry Pointer sections
These immediately follow the above tables. They just contain absolute offsets to the various subentries above. These sections are described by the values from 0x50 to 0x80, and follow the same order.
However, these seem to be out of order, and have "null" entries. Don't understand why, lol
Text/"native:/" Tables
The "text tables" (offset is given at 0x40 and 0x48) are just ASCII text separated by null characters. Each string is aligned to a 4 byte boundary (thus extra padding may be used).
Data Area
Basically, where all the data is stored...
Resources are aligned to 4 byte boundaries (thus padding may be used to achieve this).
Deflated resources have the 2 byte signature, 0xDA78. "Encrypted" resources have the 2 byte signature, 0xD905.
Alright, that's all I really know about the RCO format - Z33 has some more info in his documentation (can be found here).
Hope this guide helped someone