User Tools

Site Tools


yoshis_story

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
yoshis_story [2019/09/26 22:51]
shygoo [Objects]
yoshis_story [2019/10/04 17:09]
shygoo split yoshi's story
Line 1: Line 1:
 ====== Yoshi'​s Story Hacking ====== ====== Yoshi'​s Story Hacking ======
 +~~NOTOC~~
 ---- ----
-===== ROM "​bank-offset"​ addressing ===== 
  
-Yoshi'​s Story uses 32-bit "​bank-offsets"​ to point to resources in ROM. The bank table is located at 0x000A79D4 in ROM (0x800A6DD4 in RAM) as an array of bank base addresses. There are 16 available slots for bank addresses, but only bank numbers 0x00, 0x03, and 0x04 seem to be used by the game.+<WRAP group> 
 +<WRAP half column>​ 
 +==== Hacking Notes ==== 
 +  * [[yoshis_story:​file_system]] 
 +  * [[yoshis_story:​level_data]] 
 +  * [[yoshis_story:​object_data]] 
 +  * [[yoshis_story:​object_ids]] 
 +  * [[yoshis_story:​data_diagram]] 
 +  * [[yoshis_story:​smsr00_compression]] 
 +  * [[yoshis_story:​overlay_files]] 
 +</​WRAP>​
  
-^Bank #^ROM address^ +<WRAP half column> 
-|0x00|0x00001060| +==== Hacking Tools ==== 
-|0x01|0x00000000| +  * [[https://​github.com/​shygoo/​ys-project/​blob/​master/​webtools/​viewer.htm|Level Viewer]]
-|0x02|0x00000000| +
-|0x03|0x00526EC0| +
-|0x04|0x00B47A10| +
-|0x05|0x00000000| +
-|0x06|0x00000000| +
-|0x07|0x00000000| +
-|0x08|0x00000000| +
-|0x09|0x00000000| +
-|0x0A|0x00000000| +
-|0x0B|0x00000000| +
-|0x0C|0x00000000| +
-|0x0D|0x00000000| +
-|0x0E|0x00000000| +
-|0x0F|0x00000000|+
  
-Bank-offsets are 32 bits, containing a 4-bit bank number and a 24-bit offset: +==== ROM Hacks ==== 
-<​code>​---- bbbb oooooooooooooooooooooooo</​code>​ +  * [[https://youtu.be/QvdDvmQRhN8?​t=19|SMB 1-1 Custom level]] 
- +</WRAP
-^Bitfield^Description^ +</WRAP>
-|-|unused bits| +
-|b|4-bit bank number| +
-|o|24-bit offset| +
- +
-So a bank-offset to ROM address conversion formula could look something like this: +
-<code C> +
-u32 boToAddress(u32 bankOffset) +
-+
-    u8  bankNum ​(bankOffset >> 24) & 0x0F; +
-    u32 offset ​bankOffset & 0x00FFFFFF;​ +
-    u32 romAddress ​gRomBanks[bankNum] + offset; +
-    return romAddress;​ +
-+
-</​code>​ +
- +
----- +
-===== Levels ===== +
-The main level list is at 0x000A84A0 in ROM as an array of 177 "​LevelEntry"​ structs. +
- +
-==== LevelEntry struct ​==== +
-This struct simply points to a LevelInfo struct. +
-<code C> +
-struct LevelEntry +
-+
-    /*00*/ u32 unk00; +
-    /*04*/ u32 boLevelInfo;​ // bank-offset of LevelInfo struct +
-}; +
-</​code>​ +
- +
-==== LevelInfo struct ==== +
-This struct contains a pointer to an ObjectPlacementListInfo struct. The rest of the data hasn't been studied yet. +
-<code C> +
-struct LevelInfo +
-+
-    /*00*/ u8    unk00[8]; +
-    /*08*/ f32   ​unk08;​ +
-    /*0C*/ u8    unk0C[24];​ +
-    /*24*/ void *unk24; +
-    /*28*/ u8    unk28[4]; +
-    /*2C*/ f32   ​unk2C;​ +
-    /*30*/ f32   ​unk30;​ +
-    /*34*/ u8    unk34[4]; +
-    /*38*/ f32   ​unk38;​ +
-    /*3C*/ f32   ​unk3C;​ +
-    /*40*/ u8    unk40[4]; +
-    /*44*/ f32   ​unk44;​ +
-    /*48*/ f32   ​unk48;​ +
-    /*4C*/ f32   ​unk4C;​ +
-    /*50*/ u8    unk50[4]; +
-    /*54*/ f32   ​unk54;​ +
-    /*58*/ u8    unk58[4]; +
-    /*5C*/ u32   ​boObjectPlacementListInfoPtr;​ // bank-offset of bank-offset of ObjectPlacementListInfo +
-    /*60*/ u16   ​unk60[0x98]; ​                 // seems to be a list of objectId'​s to preload? terminated by 0xFFFF? unknown size +
-    /*F8*/ u8    unkF8[28];​ +
-}; +
-</​code>​ +
- +
-==== ObjectPlacementListInfo struct ==== +
-This struct simply references an array of ObjectPlacement structs. +
-<code C> +
-struct ObjectPlacementListInfo +
-+
-    /*00*/ u16 numObjects; ​        // number of ObjectPlacement structs in the array +
-    /*02*/ u16 unk02; ​             // probably padding +
-    /*04*/ u32 boObjectPlacements;​ // bank-offset of ObjectPlacement array +
-}; +
-</​code>​ +
- +
-==== ObjectPlacement struct ==== +
-This struct contains the object ID, tag(?), and position of an object to be placed in a level. +
-<code C> +
-struct ObjectPlacement +
-+
-    u16 objectId; // object ID +
-    u16 layer; ​   // seems to be the drawing layer, collision is active on layer 0x0001 +
-    f32 x;        // x coordinate in level +
-    f32 y;        // y coordinate in level +
-}; +
-</​code>​ +
- +
----- +
-===== Objects ===== +
-The object lookup table is at 0x000A1C90 in ROM as an array of 1582 ObjectEntry structs. +
- +
-[[yoshis_story:​object_ids]] +
-==== ObjectEntry struct ==== +
-<code C> +
-struct ObjectEntry +
-+
-    /*00*/ u16 objectId; ​ // unique identifier +
-    /*02*/ u16 unk02; ​    // probably padding +
-    /*04*/ u32 boObjectDefA;​ // bank-offset of ObjectDefA struct +
-    /*08*/ u32 boObjectDefB;​ // bank-offset of ObjectDefB struct +
-}; +
-</​code>​ +
- +
-==== ObjectDefA_00 struct ==== +
-This structure defines the properties of an object. +
- +
-<code C> +
-struct ObjectDefA_00 +
-+
-    /*00*/ u16     ​type; ​                // structure type (0x0001) +
-           ​u8 ​     _pad02[2]; +
-    /*04*/ CodeInfo codeInfo; +
-    /*18*/ u16   ​objectId; ​            // unique identifier +
-    /*1A*/ u16   ​unk1A;​ +
-    /*1C*/ u32   ​tileDimensionsSize; ​  // sizeof(TileDimensions) +
-    /*20*/ u32   ​boTileDimensions; ​    // bank-offset of TileDimensions struct +
-    /*24*/ u32   ​tileDataInfoSize; ​    // sizeof(BlockInfo) +
-    /*28*/ u32   ​boTileDataInfo; ​      // bank-offset of BlockInfo struct for the tiles' 8bit color-index data +
-    /*2C*/ u32   ​tilePaletteInfoSize; ​ // sizeof(BlockInfo) +
-    /*30*/ u32   ​boTilePaletteInfo; ​   /* bank-offset of BlockInfo struct for the tiles' palette data +
-                                          palette data is a 0x200 byte array of rgba5551 (u16) colors */ +
-    /*34*/ u32   ​tileMapInfoSize; ​     // sizeof(BlockInfo) +
-    /*38*/ u32   ​boTileMapInfo; ​       /* bank-offset of BlockInfo struct for the tile map +
-                                          the tile map is a u16 array tile indeces */ +
-    /*3C*/ u32   ​unkData1InfoSize; ​    // sizeof(BlockInfo) +
-    /*40*/ u32   ​boUnkData1; ​          // bank-offset of BlockInfo struct for ?? +
-    /*44*/ u32   ​unkData2InfoSize; ​    // sizeof(BlockInfo) +
-    /*48*/ u32   ​boUnkData2; ​          // bank-offset of BlockInfo struct for ?? +
-    /*4C*/ u32   ​collisionMapInfoSize;​ // sizeof(BlockInfo) +
-    /*50*/ u32   ​boCollisionMapInfo; ​  /* bank-offset of BlockInfo struct for collision data +
-                                          the collision map is a u16 array, parallel to the tile map array */ +
-    /*54*/ u8    unk54[16];            // unknown data +
-}; +
-</​code>​ +
- +
-==== ObjectDefA_01 struct ==== +
-This structure defines the properties of the Yoshi player object. +
- +
-<code C> +
-struct ObjectDefA_01 ​  // only used for yoshi +
-+
-    /*0x00*/ u16 type;   // structure type (0x0001) +
-    /*0x04*/ u8  unk04; +
-    /*0x08*/ u32 unk08; +
-    /*0x18*/ u16 unk18; +
-    /*0x1C*/ u8  unk1C; +
-    /*0x1D*/ u8  unk1D; +
-    /*0x20*/ u32 boUnk20; +
-    /*0x24*/ u32 boUnk24; +
-    /*0x28*/ u32 boUnk28; +
-    /*0x2C*/ u32 unk2C; +
-    /*0x30*/ u32 boUnk30; +
-    /*0x34*/ u32 unk34; +
-    /*0x38*/ u32 unk38; +
-    /*0x3C*/ u32 unk3C; +
-    /*0x40*/ u32 boUnk40; +
-}; +
-</​code>​ +
- +
-==== ObjectDefA_02 struct ==== +
- +
-<code C> +
-struct ObjectDefA_02 +
-+
-    /*00*/ u16 type;      // structure type (0x0002) +
-           u8 _pad02[2];​ +
-           ​CodeInfo codeInfo; +
-}; +
-</​code>​ +
- +
-==== ObjectDefB struct ==== +
-<code C> +
-struct ObjectDefB +
-+
-    // todo +
-}; +
-</​code>​ +
- +
-==== TileDimensions struct ==== +
-<code C> +
-struct TileDimensions +
-+
-    /*0x00*/ u16 unk00; ​     // ?? related to width +
-    /*0x02*/ u16 unk02; ​     // ?? related to height +
-    /*0x04*/ u16 tileWidth; ​ // width of an individual tile +
-    /*0x06*/ u16 tileHeight; // height of an individual tile +
-    /*0x08*/ u16 mapWidth; ​  // width of the whole map (num tiles X * tileWidth) +
-    /*0x0A*/ u16 mapHeight ​  // height of the whole map (num tiles Y * tileHeight) +
-}; +
-</​code>​ +
- +
-==== BlockInfo struct ==== +
-This structure references a block of data in ROM. The block of data may either be raw or SMSR00 compressed depending on the size and sizeEnc fields.  +
-<code C> +
-struct BlockInfo +
-+
-    /*0x00*/ u32 size;    // decoded block size +
-    /*0x04*/ u32 sizeEnc; // encoded block size +
-    /*0x08*/ u32 boData; ​ /* bank-offset of the data (may be a CMPR or raw) +
-                             if the data is raw, both size and sizeEnc will be the same value */ +
-}; +
-</​code>​ +
- +
-==== CodeInfo struct ==== +
-This struct references code that an object should use. It can either reference an overlay file or a single function already in memory. +
-<code C> +
-struct CodeInfo +
-+
-    u8 useOverlay; ​         // 1 = use overlay, 0 = use nativeFunc +
-    u8 _pad[3]; ​            // padding +
-    union { +
-        void *nativeFunc; ​  // pointer to native function +
-        struct +
-        { +
-            u32 romStart; ​      // overlay rom start address +
-            u32 romEnd; ​        // overlay rom end address +
-            void *fakeMemStart;​ // fake ram start address  +
-            void *fakeMemEnd; ​  // fake ram end address +
-        } overlay; +
-    }; +
-}; +
-</​code>​ +
- +
----- +
-===== Level/​Object Data Diagram ===== +
-Here is a diagram of this game's pointer spaghetti. +
- +
-{{https://hack64.net/docs/​yosh.png}} +
- +
----- +
-===== Overlays ===== +
-Yoshi'​s Story uses overlays to save memory. The structure for overlay files is as follows: +
- +
-<code C> +
-u8  text[textSize] +
-u8  data[dataSize] +
-u8  rodata[rodataSize] +
-meta { +
-    u32 textSize +
-    u32 dataSize +
-    u32 rodataSize +
-    u32 bssSize +
-    u32 numRelocations +
-    u32 relocations[numRelocations] +
-    u32 metaSize +
-+
-</​code>​ +
- +
-  * The position of the meta section is calculated by subtracting metaSize from the total size of the overlay file. +
-  * The .bss section is allocated immediately after the overlay file in memory. +
- +
-Relocation bitfields:​ +
-<​code>​ss -- rrrr oooooooooooooooooooooooo</​code>​ +
- +
-^Bitfield^Description^ +
-|s|Section (0 = invalid?, ​= .text, 2 = .data, 3 = .rodata)| +
-|-|Unused?| +
-|r|Relocation type (4 = R_MIPS_26, 5 = R_MIPS_HI16,​ 6 = R_MIPS_LO16)| +
-|o|Offset| +
- +
-The dynamic linker routine is located at 0x80081430 in RAM. +
-<code C>​func_80081430(void *overlay_block,​ void *meta_section);</​code>​ +
- +
-The game keeps track of active overlays using an array of the following struct at 0x800DA840 in RAM. +
-<code C> +
-struct OverlayEntry +
-+
-    /*00*/ void *location; ​    // actual location in memory +
-    /*04*/ u16   ​objectId; ​    // id of the object that this overlay belongs to +
-           ​u8 ​   _pad[2]+
-    /*08*/ void *fakeMemStart;​ // fake start address +
-    /*0C*/ void *fakeMemEnd; ​  // fake end address +
-}; +
-</​code>​ +
- +
----- +
-===== Compression ===== +
-Yoshi'​s Story uses an LZ77-type compression format called SMSR00 which is very similar to SM64's MIO0 format. Each SMSR00 block in ROM is preceded by a 16-byte '​CMPR'​ header which contains the size of the encoded block and the size of the block when it's decoded. +
- +
-==== CMPRHeader struct ==== +
-<code C> +
-struct CMPRHeader +
-+
-    /*00*/ char cmprSignature[4]; // '​CMPR'​ +
-    /*04*/ u32  sizeEnc; ​         // size of encoded data +
-    /*08*/ u32  size;             // size of decoded data +
-    /*0C*/ u32  unused; ​          // probably padding +
-}; +
-</code> +
- +
-==== SMSRHeader struct ==== +
-<code C> +
-struct SMSRHeader +
-+
-    ​/*00*/ char smsrSignature[6];​ // '​SMSR00'​ +
-    /*06*/ u8   ​unused[2]; ​       // padding +
-    /*08*/ u32  outputSize; ​      // size of decoded data +
-    /*0C*/ u32  dataOffset; ​      // offset of the data section in the smsr00 block +
-}; +
-</code> +
- +
-==== Decoder implementations ==== +
-  * C: https://​raw.githubusercontent.com/​shygoo/​ys-project/​master/​tools/​src/​smsr00.c +
-  * JS: https://​github.com/​shygoo/​ys-project/​blob/​master/​webtools/​smsr00.js +
- +
----- +
-===== References ===== +
-  * https://​github.com/​shygoo/​ys-project+
yoshis_story.txt · Last modified: 2019/10/04 17:09 by shygoo