示例#1
0
        private void save()
        {
            using (FileStream data = new FileStream(currentFile, FileMode.Open))
            {
                BinaryReader input  = new BinaryReader(data);
                BinaryWriter output = new BinaryWriter(data);

                for (int i = 0; i < bch.mips[mipSel].textures.Count; i++)
                {
                    loadedTexture tex = bch.mips[mipSel].textures[i];

                    if (tex.modified)
                    {
                        byte[] buffer = align(TextureCodec.encode(tex.texture.texture, tex.type));
                        int    diff   = buffer.Length - tex.length;
                        replaceData(data, tex.offset, returnSize(tex.type, tex.texture.texture.Width, tex.texture.texture.Height), buffer);

                        tex.modified = false;
                        updateTexture(i, tex);
                    }
                }
            }

            MessageBox.Show("Done!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
示例#2
0
        private void save()
        {
            using (FileStream data = new FileStream(currentFile, FileMode.Open))
            {
                BinaryReader input  = new BinaryReader(data);
                BinaryWriter output = new BinaryWriter(data);

                for (int i = 0; i < bch.textures.Count; i++)
                {
                    loadedTexture tex = bch.textures[i];

                    if (tex.modified)
                    {
                        byte[] buffer = align(TextureCodec.encode(tex.texture.texture, RenderBase.OTextureFormat.rgba8));
                        int    diff   = buffer.Length - tex.length;

                        replaceData(data, tex.offset, tex.length, buffer);

                        //Update offsets of next textures
                        tex.length   = buffer.Length;
                        tex.modified = false;
                        updateTexture(i, tex);
                        for (int j = i; j < bch.textures.Count; j++)
                        {
                            loadedTexture next = bch.textures[j];
                            next.offset = (uint)(next.offset + diff);
                            updateTexture(j, next);
                        }

                        //Update all addresses poiting after the replaced data
                        bch.relocationTableOffset = (uint)(bch.relocationTableOffset + diff);
                        for (int index = 0; index < bch.relocationTableLength; index += 4)
                        {
                            data.Seek(bch.relocationTableOffset + index, SeekOrigin.Begin);
                            uint value  = input.ReadUInt32();
                            uint offset = value & 0x1ffffff;
                            byte flags  = (byte)(value >> 25);

                            if ((flags & 0x20) > 0 || flags == 7 || flags == 0xc)
                            {
                                if ((flags & 0x20) > 0)
                                {
                                    data.Seek((offset * 4) + bch.gpuCommandsOffset, SeekOrigin.Begin);
                                }
                                else
                                {
                                    data.Seek((offset * 4) + bch.mainHeaderOffset, SeekOrigin.Begin);
                                }

                                uint address = input.ReadUInt32();
                                if (address + bch.dataOffset > tex.offset)
                                {
                                    address = (uint)(address + diff);
                                    data.Seek(-4, SeekOrigin.Current);
                                    output.Write(address);
                                }
                            }
                        }

                        uint newSize = (uint)((tex.texture.texture.Width << 16) | tex.texture.texture.Height);

                        //Update texture format
                        data.Seek(tex.gpuCommandsOffset, SeekOrigin.Begin);
                        for (int index = 0; index < tex.gpuCommandsWordCount * 3; index++)
                        {
                            uint command = input.ReadUInt32();

                            switch (command)
                            {
                            case 0xf008e:
                            case 0xf0096:
                            case 0xf009e:
                                replaceCommand(data, output, 0);     //Set texture format to 0 = RGBA8888
                                break;

                            case 0xf0082:
                            case 0xf0092:
                            case 0xf009a:
                                replaceCommand(data, output, newSize);     //Set new texture size
                                break;
                            }
                        }

                        //Update material texture format
                        foreach (loadedMaterial mat in bch.materials)
                        {
                            data.Seek(mat.gpuCommandsOffset, SeekOrigin.Begin);
                            for (int index = 0; index < mat.gpuCommandsWordCount; index++)
                            {
                                uint command = input.ReadUInt32();

                                switch (command)
                                {
                                case 0xf008e: if (mat.texture0 == tex.texture.name || mat.texture0 == "")
                                    {
                                        replaceCommand(data, output, 0);
                                    }
                                    break;

                                case 0xf0096: if (mat.texture1 == tex.texture.name || mat.texture1 == "")
                                    {
                                        replaceCommand(data, output, 0);
                                    }
                                    break;

                                case 0xf009e: if (mat.texture2 == tex.texture.name || mat.texture2 == "")
                                    {
                                        replaceCommand(data, output, 0);
                                    }
                                    break;
                                }
                            }
                        }

                        //Patch up BCH header for new offsets and lengths
                        data.Seek(4, SeekOrigin.Begin);
                        byte backwardCompatibility = input.ReadByte();
                        byte forwardCompatibility  = input.ReadByte();

                        //Update Data Extended and Relocation Table offsets
                        data.Seek(18, SeekOrigin.Current);
                        if (backwardCompatibility > 0x20)
                        {
                            updateAddress(data, input, output, diff);
                        }
                        updateAddress(data, input, output, diff);

                        //Update data length
                        data.Seek(12, SeekOrigin.Current);
                        updateAddress(data, input, output, diff);
                    }
                }
            }

            MessageBox.Show("Done!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }