This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
mission_impossible [2019/06/03 14:37] shygoo note about offsets |
mission_impossible [2019/06/17 01:10] shygoo link rom map & sool engine pages |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Mission Impossible ====== | + | ====== Mission Impossible Hacking ====== |
- | Scratch page for ROM of the Month | + | **June 2019 [[rom_of_the_month]]** |
+ | This page is under construction! Feel free to add notes and links in whatever way you see fit - we'll polish everything towards the end of the month. | ||
+ | ---- | ||
+ | ===== Tools ===== | ||
+ | * [[https://github.com/hack64-net/rotm/releases/tag/miextract|miextract]] - Basic command-line ROM decompressor | ||
+ | |||
+ | ---- | ||
+ | ===== See Also ===== | ||
+ | * [[mission_impossible:rom_map]] | ||
+ | * [[mission_impossible:sool_engine]] | ||
+ | * [[https://hack64.net/Thread-RotM-June-2019-Mission-Impossible|Mission Impossible discussion thread]] | ||
+ | * [[https://hackmd.io/-WVc2PjoSkS06XMpV55bsw?edit|n64split config]] | ||
+ | |||
+ | ---- | ||
===== SDK Functions ===== | ===== SDK Functions ===== | ||
<code> | <code> | ||
Line 160: | Line 173: | ||
</code> | </code> | ||
+ | ---- | ||
===== "Burp" Headers ===== | ===== "Burp" Headers ===== | ||
Burp headers describe a series of compressed or uncompressed data blocks in ROM. | Burp headers describe a series of compressed or uncompressed data blocks in ROM. | ||
<code> | <code> | ||
- | typedef struct | + | struct BurpBlock |
{ | { | ||
- | uint32_t dstSize; | + | u32 dstSize; |
- | uint32_t srcSize; | + | u32 srcSize; |
- | uint32_t unk08; // seems unused | + | u32 unk08; |
- | uint32_t offset; // relative to start of BurpHeader | + | u32 offset; // relative to start of BurpHeader |
- | uint32_t unk10; // 0x00000000 when dst and src are the same size, otherwise 0x04000000 | + | u8 unk10[4]; // 00000000 when dst and src are the same size, otherwise 04000000 |
- | } BurpBlock; | + | }; |
- | typedef struct | + | struct BurpHeader |
{ | { | ||
- | char signature[4]; // "Burp" | + | char signature[4]; // "Burp" |
- | uint32_t numBlocks; | + | u32 numBlocks; |
- | BurpBlock blocks[]; | + | struct BurpBlock blocks[]; |
- | } BurpHeader; | + | }; |
</code> | </code> | ||
Map of all burp headers: https://pastebin.com/raw/QT8gVWun | Map of all burp headers: https://pastebin.com/raw/QT8gVWun | ||
+ | |||
+ | ---- | ||
+ | ===== Level Objects ===== | ||
+ | <code> | ||
+ | struct Object { | ||
+ | /*0x00*/ void *unk00; | ||
+ | /*0x04*/ void *unk04; | ||
+ | /*0x08*/ u32 unk08; | ||
+ | /*0x0C*/ u32 unk0C; | ||
+ | /*0x10*/ u8 unk10[2]; | ||
+ | /*0x12*/ u16 unk12; // unioned with two u8's | ||
+ | /*0x14*/ u16 unk14; | ||
+ | /*0x16*/ u16 unk16; | ||
+ | /*0x18*/ vec3f position; | ||
+ | /*0x24*/ u8 unk24[0x0E]; | ||
+ | /*0x32*/ u16 unk16; | ||
+ | /*0x34*/ u8 unk34[0x0C]; | ||
+ | /*0x40*/ vec3f rotation; | ||
+ | /*0x4C*/ s32 timer; // copied from gFrameCount | ||
+ | /*0x50*/ u8 unk50[2]; // player: FFFF | ||
+ | /*0x52*/ u16 unk52; // some flags? unsetting bit 5 makes object invisible | ||
+ | /*0x54*/ s32 unk54; // maybe an animation counter, but locking it seems to have no effect | ||
+ | /*0x58*/ u8 unk58[4]; // 003d0900 for player object | ||
+ | /*0x5C*/ s32 unk5C; | ||
+ | /*0x60*/ struct Object *unk60; | ||
+ | /*0x64*/ u8 unk64[4]; | ||
+ | /*0x68*/ s16 unk68; // 0x0004 for player object | ||
+ | /*0x68*/ s16 unk6A; // 0x0005 for player object | ||
+ | /*0x6C*/ s32 unk6C; | ||
+ | /*0x70*/ u8 unk70[8]; | ||
+ | /*0x78*/ u16 unk78; | ||
+ | /*0x7A*/ u16 unk7A; | ||
+ | /*0x7C*/ u8 unk7C[4]; // 00058800 for player object | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | /*80086190*/ struct Object *gLevelObjects; | ||
+ | /*80093840*/ s16 gNumLevelObjects; | ||
+ | </code> | ||
+ | |||
+ | Below is the header struct for level object placement data. When a level is loaded, one of these structs is decompressed from ROM along with ObjectPosRot and ObjectPosArray structs that follow. All pointer members of this struct are initially offsets relative to the beginning of the struct, but the game converts them to virtual addresses in-place. | ||
+ | <code> | ||
+ | struct ObjectPlacements | ||
+ | { | ||
+ | /*0x00*/ s32 numPlacements0; | ||
+ | /*0x04*/ struct ObjectPosRot *placements0; | ||
+ | /*0x08*/ s32 numPlacements1; | ||
+ | /*0x0C*/ struct ObjectPosRot *placements1; | ||
+ | /*0x10*/ s32 numPlacements2; | ||
+ | /*0x14*/ struct ObjectPosRot *placements2; // unconfirmed type | ||
+ | /*0x18*/ s32 numPlacements3; | ||
+ | /*0x1C*/ struct ObjectPosArray *placements3[]; | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | struct ObjectPosRot | ||
+ | { | ||
+ | /*0x00*/ u8 unk00[2]; | ||
+ | /*0x02*/ vec3s position; | ||
+ | /*0x08*/ vec3s rotation; | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | struct ObjectPosArray | ||
+ | { | ||
+ | /*0x00*/ s32 numPositions; | ||
+ | /*0x04*/ vec3s positions[]; | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | /*0x800A98CC*/ struct ObjectPlacements *gObjectPlacements; | ||
+ | </code> | ||
+ | |||
+ | Breakdown of object placement data for the first mission: https://pastebin.com/raw/657rL7jD |