Beispiel #1
0
        private void packPNK(FileStream data, BinaryReader input, loadedBCH bch)
        {
            uint veryBase = (uint)data.Position;

            input.ReadUInt32();



            uint[] sectionsCnt = new uint[5];

            for (int i = 0; i < 5; i++)
            {
                sectionsCnt[i] = input.ReadUInt32(); //Count for each section on the file (total 5)
            }
            uint baseAddr = (uint)data.Position;

            for (int sect = 0; sect < 5; sect++)
            {
                uint count = sectionsCnt[sect];

                for (int i = 0; i < count; i++)
                {
                    data.Seek(baseAddr + i * 4, SeekOrigin.Begin);
                    data.Seek(input.ReadUInt32() + veryBase, SeekOrigin.Begin);

                    byte   nameStrLen  = input.ReadByte();
                    string name        = IOUtils.readStringWithLength(input, nameStrLen);
                    uint   descAddress = input.ReadUInt32() + veryBase;

                    data.Seek(descAddress, SeekOrigin.Begin);

                    if (sect == 1)
                    {
                        bch.mips[0].textures.Add(loadPKM(data, input));
                    }
                }
                baseAddr += count * 4;
            }
        }
        private bool open(string fileName)
        {
            using (FileStream data = new FileStream(fileName, FileMode.Open))
            {
                BinaryReader input = new BinaryReader(data);

                string magic = IOUtils.readString(input, 0);
                if (magic != "BCH") return false;
                currentFile = fileName;
                data.Seek(4, SeekOrigin.Current);
                byte backwardCompatibility = input.ReadByte();
                byte forwardCompatibility = input.ReadByte();
                ushort version = input.ReadUInt16();

                uint mainHeaderOffset = input.ReadUInt32();
                uint stringTableOffset = input.ReadUInt32();
                uint gpuCommandsOffset = input.ReadUInt32();
                uint dataOffset = input.ReadUInt32();
                uint dataExtendedOffset = backwardCompatibility > 0x20 ? input.ReadUInt32() : 0;
                uint relocationTableOffset = input.ReadUInt32();

                uint mainHeaderLength = input.ReadUInt32();
                uint stringTableLength = input.ReadUInt32();
                uint gpuCommandsLength = input.ReadUInt32();
                uint dataLength = input.ReadUInt32();
                uint dataExtendedLength = backwardCompatibility > 0x20 ? input.ReadUInt32() : 0;
                uint relocationTableLength = input.ReadUInt32();

                data.Seek(mainHeaderOffset, SeekOrigin.Begin);
                uint modelsPointerTableOffset = input.ReadUInt32() + mainHeaderOffset;
                uint modelsPointerTableEntries = input.ReadUInt32();

                data.Seek(mainHeaderOffset + 0x24, SeekOrigin.Begin);
                uint texturesPointerTableOffset = input.ReadUInt32() + mainHeaderOffset;
                uint texturesPointerTableEntries = input.ReadUInt32();

                bch = new loadedBCH();

                //Textures
                for (int index = 0; index < texturesPointerTableEntries; index++)
                {
                    data.Seek(texturesPointerTableOffset + (index * 4), SeekOrigin.Begin);
                    data.Seek(input.ReadUInt32() + mainHeaderOffset, SeekOrigin.Begin);

                    loadedTexture tex;
                    tex.modified = false;
                    tex.gpuCommandsOffset = input.ReadUInt32() + gpuCommandsOffset;
                    tex.gpuCommandsWordCount = input.ReadUInt32();
                    data.Seek(0x14, SeekOrigin.Current);
                    uint textureNameOffset = input.ReadUInt32();
                    string textureName = IOUtils.readString(input, textureNameOffset + stringTableOffset);

                    data.Seek(tex.gpuCommandsOffset, SeekOrigin.Begin);
                    PICACommandReader textureCommands = new PICACommandReader(data, tex.gpuCommandsWordCount);

                    tex.offset = textureCommands.getTexUnit0Address() + dataOffset;
                    RenderBase.OTextureFormat fmt = textureCommands.getTexUnit0Format();
                    Size textureSize = textureCommands.getTexUnit0Size();
                    switch (fmt)
                    {
                        case RenderBase.OTextureFormat.rgba8: tex.length = (textureSize.Width * textureSize.Height) * 4; break;
                        case RenderBase.OTextureFormat.rgb8: tex.length = (textureSize.Width * textureSize.Height) * 3; break;
                        case RenderBase.OTextureFormat.rgba5551: tex.length = (textureSize.Width * textureSize.Height) * 2; break;
                        case RenderBase.OTextureFormat.rgb565: tex.length = (textureSize.Width * textureSize.Height) * 2; break;
                        case RenderBase.OTextureFormat.rgba4: tex.length = (textureSize.Width * textureSize.Height) * 2; break;
                        case RenderBase.OTextureFormat.la8: tex.length = (textureSize.Width * textureSize.Height) * 2; break;
                        case RenderBase.OTextureFormat.hilo8: tex.length = (textureSize.Width * textureSize.Height) * 2; break;
                        case RenderBase.OTextureFormat.l8: tex.length = textureSize.Width * textureSize.Height; break;
                        case RenderBase.OTextureFormat.a8: tex.length = textureSize.Width * textureSize.Height; break;
                        case RenderBase.OTextureFormat.la4: tex.length = textureSize.Width * textureSize.Height; break;
                        case RenderBase.OTextureFormat.l4: tex.length = (textureSize.Width * textureSize.Height) >> 1; break;
                        case RenderBase.OTextureFormat.a4: tex.length = (textureSize.Width * textureSize.Height) >> 1; break;
                        case RenderBase.OTextureFormat.etc1: tex.length = (textureSize.Width * textureSize.Height) >> 1; break;
                        case RenderBase.OTextureFormat.etc1a4: tex.length = textureSize.Width * textureSize.Height; break;
                        default: throw new Exception("OBCHTextureReplacer: Invalid texture format on BCH!");
                    }

                    while ((tex.length & 0x7f) > 0) tex.length++;

                    data.Seek(tex.offset, SeekOrigin.Begin);
                    byte[] buffer = new byte[textureSize.Width * textureSize.Height * 4];
                    input.Read(buffer, 0, buffer.Length);
                    Bitmap texture = TextureCodec.decode(
                        buffer,
                        textureSize.Width,
                        textureSize.Height,
                        fmt);

                    tex.texture = new RenderBase.OTexture(texture, textureName);

                    bch.textures.Add(tex);
                }

                //Materials
                for (int mdlIndex = 0; mdlIndex < modelsPointerTableEntries; mdlIndex++)
                {
                    data.Seek(modelsPointerTableOffset + (mdlIndex * 4), SeekOrigin.Begin);
                    data.Seek(input.ReadUInt32() + mainHeaderOffset, SeekOrigin.Begin);
                    data.Seek(0x34, SeekOrigin.Current);

                    uint materialsTableOffset = input.ReadUInt32() + mainHeaderOffset;
                    uint materialsTableEntries = input.ReadUInt32();

                    for (int index = 0; index < materialsTableEntries; index++)
                    {
                        if (backwardCompatibility < 0x21)
                            data.Seek(materialsTableOffset + (index * 0x58), SeekOrigin.Begin);
                        else
                            data.Seek(materialsTableOffset + (index * 0x2c), SeekOrigin.Begin);

                        loadedMaterial mat;

                        data.Seek(0x10, SeekOrigin.Current);
                        mat.gpuCommandsOffset = input.ReadUInt32() + gpuCommandsOffset;
                        mat.gpuCommandsWordCount = input.ReadUInt32();

                        if (backwardCompatibility < 0x21)
                            data.Seek(0x30, SeekOrigin.Current);
                        else
                            data.Seek(4, SeekOrigin.Current);

                        uint texture0Offset = input.ReadUInt32() + stringTableOffset;
                        uint texture1Offset = input.ReadUInt32() + stringTableOffset;
                        uint texture2Offset = input.ReadUInt32() + stringTableOffset;

                        mat.texture0 = IOUtils.readString(input, texture0Offset);
                        mat.texture1 = IOUtils.readString(input, texture1Offset);
                        mat.texture2 = IOUtils.readString(input, texture2Offset);

                        bch.materials.Add(mat);
                    }
                }

                bch.mainHeaderOffset = mainHeaderOffset;
                bch.gpuCommandsOffset = gpuCommandsOffset;
                bch.dataOffset = dataOffset;
                bch.relocationTableOffset = relocationTableOffset;
                bch.relocationTableLength = relocationTableLength;
            }

            updateTexturesList();
            return true;
        }
Beispiel #3
0
        private bool open(string fileName)
        {
            using (FileStream data = new FileStream(fileName, FileMode.Open))
            {
                BinaryReader input = new BinaryReader(data);

                if (peek(input) == 0x00010000)
                {
                    currentFile = fileName;
                    bch         = new loadedBCH();
                    bch.isBCH   = false;
                    bch.mips.Add(new MIPlayer());
                    packPNK(data, input, bch);
                }
                if (peek(input) == 0x15041213)
                {
                    currentFile = fileName;
                    bch         = new loadedBCH();
                    bch.isBCH   = false;
                    bch.mips.Add(new MIPlayer());
                    bch.mips[0].textures.Add(loadPKM(data, input));
                }
                string magic2b = getMagic(input, 2);
                if (magic2b == "PC" || magic2b == "CM")
                {
                    bch         = new loadedBCH();
                    bch.isBCH   = false;
                    currentFile = fileName;
                    data.Seek(2, SeekOrigin.Current);
                    ushort numEntrys = input.ReadUInt16();
                    for (int i = 0; i < (int)numEntrys; i++)
                    {
                        data.Seek(4 + (i * 4), SeekOrigin.Begin);
                        uint offset = input.ReadUInt32();
                        uint end    = input.ReadUInt32();
                        uint lenth  = end - offset;
                        long rtn    = data.Position;
                        data.Seek(offset, SeekOrigin.Begin);
                        if (magic2b == "CM" & i == 0)
                        {
                            packPNK(data, input, bch);
                        }
                        if (lenth > 4)
                        {
                            if (magic2b == "PC")
                            {
                                if (peek(input) == 0x15041213)
                                {
                                    bch.mips[0].textures.Add(loadPKM(data, input));
                                }
                            }
                        }
                    }
                }
                string magic = IOUtils.readString(input, 0);
                if (magic == "BCH")
                {
                    currentFile = fileName;
                    data.Seek(4, SeekOrigin.Current);
                    byte   backwardCompatibility = input.ReadByte();
                    byte   forwardCompatibility  = input.ReadByte();
                    ushort version = input.ReadUInt16();

                    uint mainHeaderOffset      = input.ReadUInt32();
                    uint stringTableOffset     = input.ReadUInt32();
                    uint gpuCommandsOffset     = input.ReadUInt32();
                    uint dataOffset            = input.ReadUInt32();
                    uint dataExtendedOffset    = backwardCompatibility > 0x20 ? input.ReadUInt32() : 0;
                    uint relocationTableOffset = input.ReadUInt32();

                    uint mainHeaderLength      = input.ReadUInt32();
                    uint stringTableLength     = input.ReadUInt32();
                    uint gpuCommandsLength     = input.ReadUInt32();
                    uint dataLength            = input.ReadUInt32();
                    uint dataExtendedLength    = backwardCompatibility > 0x20 ? input.ReadUInt32() : 0;
                    uint relocationTableLength = input.ReadUInt32();

                    data.Seek(mainHeaderOffset, SeekOrigin.Begin);
                    uint modelsPointerTableOffset  = input.ReadUInt32() + mainHeaderOffset;
                    uint modelsPointerTableEntries = input.ReadUInt32();

                    data.Seek(mainHeaderOffset + 0x24, SeekOrigin.Begin);
                    uint texturesPointerTableOffset  = input.ReadUInt32() + mainHeaderOffset;
                    uint texturesPointerTableEntries = input.ReadUInt32();

                    bch       = new loadedBCH();
                    bch.isBCH = true;
                    for (int i = 0; i < 6; i++)
                    {
                        bch.mips.Add(new MIPlayer());
                    }
                    MipSelect.Enabled = true;

                    //Textures
                    for (int index = 0; index < texturesPointerTableEntries; index++)
                    {
                        data.Seek(texturesPointerTableOffset + (index * 4), SeekOrigin.Begin);
                        data.Seek(input.ReadUInt32() + mainHeaderOffset, SeekOrigin.Begin);

                        loadedTexture tex;
                        tex.modified             = false;
                        tex.gpuCommandsOffset    = input.ReadUInt32() + gpuCommandsOffset;
                        tex.gpuCommandsWordCount = input.ReadUInt32();
                        data.Seek(0x14, SeekOrigin.Current);
                        uint   textureNameOffset = input.ReadUInt32();
                        string textureName       = IOUtils.readString(input, textureNameOffset + stringTableOffset);

                        data.Seek(tex.gpuCommandsOffset, SeekOrigin.Begin);
                        PICACommandReader textureCommands = new PICACommandReader(data, tex.gpuCommandsWordCount);

                        tex.offset = textureCommands.getTexUnit0Address() + dataOffset;
                        RenderBase.OTextureFormat fmt = textureCommands.getTexUnit0Format();
                        Size textureSize = textureCommands.getTexUnit0Size();
                        tex.type = fmt;

                        int OGW = textureSize.Width;
                        int OGH = textureSize.Height;
                        for (int i = 0; i < 6; i++)
                        {
                            textureSize.Width  = OGW / Convert.ToInt32(Math.Pow(2, i));
                            textureSize.Height = OGH / Convert.ToInt32(Math.Pow(2, i));
                            tex.length         = returnSize(fmt, textureSize.Width, textureSize.Height);

                            if (textureSize.Height >= 8 & textureSize.Width >= 8)
                            {
                                data.Seek(tex.offset, SeekOrigin.Begin);
                                byte[] buffer = new byte[tex.length];

                                //data.Seek(tex.length + returnSize(fmt, textureSize.Width / 2, textureSize.Height / 2), SeekOrigin.Current);
                                tex.offset = (uint)data.Position;
                                input.Read(buffer, 0, tex.length);
                                Bitmap texture = TextureCodec.decode(
                                    buffer,
                                    textureSize.Width,
                                    textureSize.Height,
                                    fmt);

                                tex.texture = new RenderBase.OTexture(texture, textureName);

                                bch.mips[i].textures.Add(tex);
                                tex.offset = (uint)data.Position;
                            }
                        }
                    }

                    bch.mainHeaderOffset      = mainHeaderOffset;
                    bch.gpuCommandsOffset     = gpuCommandsOffset;
                    bch.dataOffset            = dataOffset;
                    bch.relocationTableOffset = relocationTableOffset;
                    bch.relocationTableLength = relocationTableLength;
                }
                else if (magic == "CTPK\u0001")
                {
                    currentFile = fileName;
                    data.Seek(4, SeekOrigin.Current);
                    ushort ver                  = input.ReadUInt16();
                    ushort numTexture           = input.ReadUInt16();
                    uint   TextureSectionOffset = input.ReadUInt32();
                    uint   TextureSectionSize   = input.ReadUInt32();
                    uint   HashSectionOffset    = input.ReadUInt32();
                    uint   TextureInfoSection   = input.ReadUInt32();

                    bch       = new loadedBCH();
                    bch.isBCH = false;
                    bch.mips.Add(new MIPlayer());
                    for (int i = 0; i < numTexture; i++)
                    {
                        data.Seek(0x20 * (i + 1), SeekOrigin.Begin);
                        loadedTexture tex;
                        tex.modified          = false;
                        tex.gpuCommandsOffset = (uint)(0x20 * (i + 1));
                        uint   textureNameOffset = input.ReadUInt32();
                        string textureName       = IOUtils.readString(input, textureNameOffset);
                        tex.length = input.ReadInt32();
                        tex.offset = input.ReadUInt32() + TextureSectionOffset;
                        tex.type   = (RenderBase.OTextureFormat)input.ReadUInt32();
                        ushort Width  = input.ReadUInt16();
                        ushort Height = input.ReadUInt16();
                        data.Seek(tex.offset, SeekOrigin.Begin);
                        byte[] buffer = new byte[tex.length];

                        input.Read(buffer, 0, buffer.Length);
                        Bitmap texture = TextureCodec.decode(
                            buffer,
                            Width,
                            Height,
                            tex.type);

                        tex.texture = new RenderBase.OTexture(texture, textureName);

                        tex.gpuCommandsWordCount = 0;

                        bch.mips[0].textures.Add(tex);
                    }
                }
            }

            updateTexturesList();
            return(true);
        }
Beispiel #4
0
        private bool open(string fileName)
        {
            using (FileStream data = new FileStream(fileName, FileMode.Open))
            {
                BinaryReader input = new BinaryReader(data);

                string magic = IOUtils.readString(input, 0);
                if (magic != "BCH")
                {
                    return(false);
                }
                currentFile = fileName;
                data.Seek(4, SeekOrigin.Current);
                byte   backwardCompatibility = input.ReadByte();
                byte   forwardCompatibility  = input.ReadByte();
                ushort version = input.ReadUInt16();

                uint mainHeaderOffset      = input.ReadUInt32();
                uint stringTableOffset     = input.ReadUInt32();
                uint gpuCommandsOffset     = input.ReadUInt32();
                uint dataOffset            = input.ReadUInt32();
                uint dataExtendedOffset    = backwardCompatibility > 0x20 ? input.ReadUInt32() : 0;
                uint relocationTableOffset = input.ReadUInt32();

                uint mainHeaderLength      = input.ReadUInt32();
                uint stringTableLength     = input.ReadUInt32();
                uint gpuCommandsLength     = input.ReadUInt32();
                uint dataLength            = input.ReadUInt32();
                uint dataExtendedLength    = backwardCompatibility > 0x20 ? input.ReadUInt32() : 0;
                uint relocationTableLength = input.ReadUInt32();

                data.Seek(mainHeaderOffset, SeekOrigin.Begin);
                uint modelsPointerTableOffset  = input.ReadUInt32() + mainHeaderOffset;
                uint modelsPointerTableEntries = input.ReadUInt32();

                data.Seek(mainHeaderOffset + 0x24, SeekOrigin.Begin);
                uint texturesPointerTableOffset  = input.ReadUInt32() + mainHeaderOffset;
                uint texturesPointerTableEntries = input.ReadUInt32();

                bch = new loadedBCH();

                //Textures
                for (int index = 0; index < texturesPointerTableEntries; index++)
                {
                    data.Seek(texturesPointerTableOffset + (index * 4), SeekOrigin.Begin);
                    data.Seek(input.ReadUInt32() + mainHeaderOffset, SeekOrigin.Begin);

                    loadedTexture tex;
                    tex.modified             = false;
                    tex.gpuCommandsOffset    = input.ReadUInt32() + gpuCommandsOffset;
                    tex.gpuCommandsWordCount = input.ReadUInt32();
                    data.Seek(0x14, SeekOrigin.Current);
                    uint   textureNameOffset = input.ReadUInt32();
                    string textureName       = IOUtils.readString(input, textureNameOffset + stringTableOffset);

                    data.Seek(tex.gpuCommandsOffset, SeekOrigin.Begin);
                    PICACommandReader textureCommands = new PICACommandReader(data, tex.gpuCommandsWordCount);

                    tex.offset = textureCommands.getTexUnit0Address() + dataOffset;
                    RenderBase.OTextureFormat fmt = textureCommands.getTexUnit0Format();
                    Size textureSize = textureCommands.getTexUnit0Size();
                    switch (fmt)
                    {
                    case RenderBase.OTextureFormat.rgba8: tex.length = (textureSize.Width * textureSize.Height) * 4; break;

                    case RenderBase.OTextureFormat.rgb8: tex.length = (textureSize.Width * textureSize.Height) * 3; break;

                    case RenderBase.OTextureFormat.rgba5551: tex.length = (textureSize.Width * textureSize.Height) * 2; break;

                    case RenderBase.OTextureFormat.rgb565: tex.length = (textureSize.Width * textureSize.Height) * 2; break;

                    case RenderBase.OTextureFormat.rgba4: tex.length = (textureSize.Width * textureSize.Height) * 2; break;

                    case RenderBase.OTextureFormat.la8: tex.length = (textureSize.Width * textureSize.Height) * 2; break;

                    case RenderBase.OTextureFormat.hilo8: tex.length = (textureSize.Width * textureSize.Height) * 2; break;

                    case RenderBase.OTextureFormat.l8: tex.length = textureSize.Width * textureSize.Height; break;

                    case RenderBase.OTextureFormat.a8: tex.length = textureSize.Width * textureSize.Height; break;

                    case RenderBase.OTextureFormat.la4: tex.length = textureSize.Width * textureSize.Height; break;

                    case RenderBase.OTextureFormat.l4: tex.length = (textureSize.Width * textureSize.Height) >> 1; break;

                    case RenderBase.OTextureFormat.a4: tex.length = (textureSize.Width * textureSize.Height) >> 1; break;

                    case RenderBase.OTextureFormat.etc1: tex.length = (textureSize.Width * textureSize.Height) >> 1; break;

                    case RenderBase.OTextureFormat.etc1a4: tex.length = textureSize.Width * textureSize.Height; break;

                    default: throw new Exception("OBCHTextureReplacer: Invalid texture format on BCH!");
                    }

                    while ((tex.length & 0x7f) > 0)
                    {
                        tex.length++;
                    }

                    data.Seek(tex.offset, SeekOrigin.Begin);
                    byte[] buffer = new byte[textureSize.Width * textureSize.Height * 4];
                    input.Read(buffer, 0, buffer.Length);
                    Bitmap texture = TextureCodec.decode(
                        buffer,
                        textureSize.Width,
                        textureSize.Height,
                        fmt);

                    tex.texture = new RenderBase.OTexture(texture, textureName);

                    bch.textures.Add(tex);
                }

                //Materials
                for (int mdlIndex = 0; mdlIndex < modelsPointerTableEntries; mdlIndex++)
                {
                    data.Seek(modelsPointerTableOffset + (mdlIndex * 4), SeekOrigin.Begin);
                    data.Seek(input.ReadUInt32() + mainHeaderOffset, SeekOrigin.Begin);
                    data.Seek(0x34, SeekOrigin.Current);

                    uint materialsTableOffset  = input.ReadUInt32() + mainHeaderOffset;
                    uint materialsTableEntries = input.ReadUInt32();

                    for (int index = 0; index < materialsTableEntries; index++)
                    {
                        if (backwardCompatibility < 0x21)
                        {
                            data.Seek(materialsTableOffset + (index * 0x58), SeekOrigin.Begin);
                        }
                        else
                        {
                            data.Seek(materialsTableOffset + (index * 0x2c), SeekOrigin.Begin);
                        }

                        loadedMaterial mat;

                        data.Seek(0x10, SeekOrigin.Current);
                        mat.gpuCommandsOffset    = input.ReadUInt32() + gpuCommandsOffset;
                        mat.gpuCommandsWordCount = input.ReadUInt32();

                        if (backwardCompatibility < 0x21)
                        {
                            data.Seek(0x30, SeekOrigin.Current);
                        }
                        else
                        {
                            data.Seek(4, SeekOrigin.Current);
                        }

                        uint texture0Offset = input.ReadUInt32() + stringTableOffset;
                        uint texture1Offset = input.ReadUInt32() + stringTableOffset;
                        uint texture2Offset = input.ReadUInt32() + stringTableOffset;

                        mat.texture0 = IOUtils.readString(input, texture0Offset);
                        mat.texture1 = IOUtils.readString(input, texture1Offset);
                        mat.texture2 = IOUtils.readString(input, texture2Offset);

                        bch.materials.Add(mat);
                    }
                }

                bch.mainHeaderOffset      = mainHeaderOffset;
                bch.gpuCommandsOffset     = gpuCommandsOffset;
                bch.dataOffset            = dataOffset;
                bch.relocationTableOffset = relocationTableOffset;
                bch.relocationTableLength = relocationTableLength;
            }

            updateTexturesList();
            return(true);
        }