Star Fox 64
- MIO0 Compression
- All data here is v1.0
Pretty much all here was documented by xdaniel.
Functions
Native Functions
/* 0x8009CD90 */
extern void sf64_print_string(int x, int y, float x_scale, float y_scale, char *str);
OS and Graphic Functions
0x8001ffc0,osContInit 0x800201b8,__osContGetInitData 0x80020288,__osPackRequestData 0x80020380,osContStartReadData 0x80020444,osContGetReadData 0x800205e0,osRecvMesg 0x80020720,osSendMesg 0x80020870,osContStartQuery 0x800208f4,osContGetQuery 0x80020f40,guPerspectiveF 0x80021170,guPerspective 0x800211d0,guLookAtF 0x80021488,guLookAt 0x80021500,guOrthoF 0x80021654,guOrtho 0x800216c0,osInvalICache 0x80021740,osInvalDCache 0x800217f0,osPiStartDma 0x80021900,osViBlack 0x80021970,osWritebackDCacheAll 0x800219a0,osViSwapBuffer 0x800219f0,osViRepeatLine 0x80021ac0,osViSetMode 0x80021b30,osViSetSpecialFeatures 0x80021cf0,osCreateMesgQueue 0x80021d20,osSetEventMesg 0x80021d90,osViSetEvent 0x80021e00,osSpTaskYielded 0x80021e80,osSpTaskYield 0x80022190,osDpSetStatus 0x800221a0,osCreateThread 0x800222f0,osStartThread 0x80022440,osCreateViManager 0x80022930,osSetThreadPri 0x80022ca0,osGetTime 0x80022d30,__sinf/fsin/sinf 0x80022ef0,__cosf/fcos/cosf 0x80023060,sqrtf 0x80023070,osSetTimer 0x80023150,osEepromRead 0x80023450,osEepromWrite 0x8002370c,__osEepStatus 0x80023930,__ull_rshift 0x8002395c,__ull_rem 0x80023998,__ull_div 0x800239d4,__ll_lshift 0x80023a00,__ll_rem 0x80023a3c,__ll_div 0x80023a98,__ll_mul 0x80023ac8,__ull_divremi 0x80023b28,__ll_mod 0x80023bc4,__ll_rshift 0x80023bf0,osEepromProbe 0x80023c60,memcpy 0x80023c8c,strlen 0x80023cb4,strchr 0x800249c0,osSetTime 0x80024a00,osAiSetFrequency 0x80024c50,osEPiStartDma 0x80024d30,osAiGetLength 0x80024d40,osAiSetNextBuffer 0x80024df0,osGetCount 0x80024e00,__osSiRawStartDma 0x80024f70,__osDisableInt 0x80024f90,__osRestoreInt 0x80024fb0,__osDequeueThread 0x80025900,osPfsIsPlug 0x80025aa0,__osPfsRequestData 0x80025b9c,__osPfsGetInitData 0x80025c70,__osContAddressCrc 0x80025d20,__osContDataCrc 0x80026500,guMtxF2L 0x80026600,guMtxIdentF 0x80026688,guMtxIdent 0x800266b8,guMtxL2F 0x80026770,osJamMesg 0x800268c0,osPiGetCmdQueue 0x80026a30,__osSpGetStatus 0x80026a40,__osSpSetStatus 0x80026a50,bcopy/_bcopy 0x80026d60,osVirtualToPhysical 0x80026de0,osWritebackDCache 0x80026e60,__osSpSetPc 0x80026ea0,__osSpRawStartDma 0x80026f30,__osSpDeviceBusy 0x80027360,osGetThreadPri 0x80027390,__osViSwapContext 0x800278b0,osPiRawStartDma 0x80028050,__osSetSR 0x80028060,__osGetSR 0x80028070,__osSetFpcCsr 0x80028080,__osSiRawReadIo 0x80028080,__osSpRawReadIo 0x800280d0,__osSiRawWriteIo 0x800280d0,__osSpRawWriteIo 0x80028120,osMapTLBRdb 0x80028180,osPiRawReadIo 0x800281e0,bzero/_bzero/blkclr/_blkclr 0x80028280,_Litob 0x80028520,_Ldtob 0x80028fe0,__osAiDeviceBusy 0x80029010,__osSiDeviceBusy 0x800c3850,osViModeNtscLan1 0x800c38f0,osViModeMpalLan1 0x800c4fb0,__libm_qnan_f 0x800c5020,__osRcpImTable
DMA Table
As for the DMA table, it's similar to the Zelda's, but not identical. Starting at 0x0D9A90 in the ROM, you've got a table with the following layout:
[Virtual start offset (4 bytes)] [Physical start offset (4 bytes)] [Physical end offset (4 bytes)] [Compression flag (4 bytes)]
So, for example 008DD590 008A2E60 008A5700 00000001 means that the file is accessed from offset 0x008DD590 by the game, physically resides between 0x008A2E60 and 0x008A5700 in the ROM and is MIO0 compressed.
Level Data
To my knowledge, each level has one file inside the game's "file system" that contains all of its data, besides sound-related things - textures, models, level layout. Thus, one way to find a specific level's file is to check each file for textures that belong to the level you want to find.
Level Header
The level setup data or level header is a block of 0x44 (68) bytes that sets such things as the BGM, fog properties and more. It's always located directly before the actual level layout data in each file. Pointers to each setup data block can be found inside the second file in the file system, at offset 0xCE158, or at offset 0xCF1A8 in the regular ROM. This pointer table is ordered by level IDs, which is the same as the Level Select Gameshark code, so ex. Corneria's pointer is at 0xCE158/0xCF1A8, while the Training stage's is at 0xCE180/0xCF1D0.
Using the Training stage's data as an example here, which has its setup data at 0x6A60 inside its file, the following level properties are known: (absolute offsets used)
- 0x6A6B: BGM - 1 byte, defines which BGM is used on the stage, ex. 0x3F for Training
- 0x6A6F: Fog color (R) - 1 byte, red color component for fog
- 0x6A73: Fog color (G) - 1 byte, green color component for fog
- 0x6A77: Fog color (B) - 1 byte, blue color component for fog
- 0x6A7A: Fog near value - 2 bytes, ex. 0x03E4 (= 996)
- 0x6A7E: Fog far value - 2 bytes, ex. 0x03E8 (= 1000)
- (Note: Valid ranges for fog near/far values are not known, I've seen graphical glitches and crashes while experimenting with those!)
The byte at offset 0x6A63 seems to be related to the level type (ground, space, water), and the single bytes at offsets 0x6A8F to 0x6AA3 are lighting color RGB components.
Level Layout
As mentioned before, the level layout data always follows the 0x44 bytes of level setup data. Each level appears to be fully made of objects, besides the level's ground plane, which are placed using this data. Each entry in the level layout is 0x14 (20) bytes long.
The syntax seems to be as follows, again using the Training stage as an example, where it starts at offset 0x6AA4:
- 0x6AA4: Ascending in-level position - 4 bytes, ex. 0x42C80000, this must NOT descend, otherwise no further objects will be loaded(!?)
- 0x6AA8: X coordinate - 2 bytes, ex. 0xF448
- 0x6AAA: Y coordinate - 2 bytes, ex. 0xFB50
- 0x6AAC: Z coordinate - 2 bytes, ex. 0xFF38
- 0x6AAE: X rotation - 2 bytes, ex. 0x0000
- 0x6AB0: Y rotation - 2 bytes, ex. 0x0000
- 0x6AB2: Z rotation - 2 bytes, ex. 0x0000
- 0x6AB4: Object type - 2 bytes, ex. 0x0085
- 0x6AB6: Unknown - 2 bytes, appear to be always 0000
The initial in-level position appears to always be 0x42C80000 and it is unknown how exactly it works. Also, coordinates appear to be somehow relative to the current in-level position.
Here is a short and incomplete list of object types, as tested in the Training level. Not all objects are available in all levels, and it is currently unknown if additional object models can be loaded per level.
- 0x0085: Building/Tower
- 0x0142: Item: Laser power-up
- 0x0143: Checkpoint
- 0x0144: Item: Silver ring
- 0x0145: Item: Silver star
- 0x0146: Gate initiating rotation
- 0x0147: Item: Bomb
- 0x0148: Training fox-guy putting you into all-range mode
- 0x014E: Invisible training mode fly-through ring?
- 0x014F: Item: Arwing (1up?)
- 0x0150: Item: Golden ring
- 0x0151: Item: Wing repair
- 0x0152: Training mode fly-through ring
- 0x03E8+: ROB64's training mode speech
- 0x0410: Enemy: Ground-based cannon
- 0x0411: Enemy: Stationary floating enemy (needs high Z coordinate to appear in level, around 0x0650+)
- 0x0412: Enemy: Winged enemy, stationary (needs high Z coordinate)
- 0x0413: Enemy: Winged enemy, moving (need high Z coordinate)
- 0x0414: Enemy: Other stationary floating enemy
- 0x0415: Item: Wing repair (being dropped?)
- 0x0442: Moving wall
- 0xFFFF: Data end marker
Tools
SF64ToolKit
Star Fox 64 toolkit. This tool allows you to decompress/split DMA information, renders level data, etc (usage).
NewSF64Toolkit
Forked from xdaniel's project: https://github.com/mib-f8sm9c/NewSF64Toolkit
(I don't know anyone who's used it. Just know it at least works.)