// MIO0 decompression code by HyperHacker (adapted from SF64Toolkit) public static bool DecompressMIO0(byte[] data, out byte[] outputData) { MIO0Header Header; byte MapByte = 0x80, CurMapByte, Length; ushort SData, Dist; uint NumBytesOutput = 0; uint MapLoc = 0; // current compression map position uint CompLoc = 0; // current compressed data position uint RawLoc = 0; // current raw data position uint OutLoc = 0; // current output position outputData = null; int i; Header.ID = ByteHelper.ReadUInt(data, 0); Header.OutputSize = ByteHelper.ReadUInt(data, 4); Header.CompLoc = ByteHelper.ReadUInt(data, 8); Header.RawLoc = ByteHelper.ReadUInt(data, 12); // "MIO0" if (Header.ID != 0x4D494F30) { return(false); } byte[] MIO0Buffer = new byte[Header.OutputSize]; MapLoc = 0x10; CompLoc = Header.CompLoc; RawLoc = Header.RawLoc; CurMapByte = data[MapLoc]; while (NumBytesOutput < Header.OutputSize) { // raw if ((CurMapByte & MapByte) != 0x0) { MIO0Buffer[OutLoc] = data[RawLoc]; // copy a byte to output. OutLoc++; RawLoc++; NumBytesOutput++; } // compressed else { SData = ByteHelper.ReadUShort(data, CompLoc); // get compressed data Length = (byte)((SData >> 12) + 3); Dist = (ushort)((SData & 0xFFF) + 1); // sanity check: can't copy from before first byte if (((int)OutLoc - Dist) < 0) { return(false); } // copy from output for (i = 0; i < Length; i++) { MIO0Buffer[OutLoc] = MIO0Buffer[OutLoc - Dist]; OutLoc++; NumBytesOutput++; if (NumBytesOutput >= Header.OutputSize) { break; } } CompLoc += 2; } MapByte >>= 1; // next map bit // if we did them all, get the next map byte if (MapByte == 0x0) { MapByte = 0x80; MapLoc++; CurMapByte = data[MapLoc]; // sanity check: map pointer should never reach this int Check = (int)CompLoc; if (RawLoc < CompLoc) { Check = (int)RawLoc; } if (MapLoc > Check) { return(false); } } } outputData = MIO0Buffer; return(true); }