Exemplo n.º 1
0
        internal void TakeBytes(MemChunk chunk, uint size)
        {
            if (chunk.FreeBytes < size)
            {
                throw new Exception("took too many bytes");
            }

            chunk.Address   += size;
            chunk.FreeBytes -= size;
        }
Exemplo n.º 2
0
        public static List <MemChunk> FindFreeMemoryInFontTexture(MemoryStream fontStream)
        {
            DuplicatableStream textureWiiStream = new DuplicatableByteArrayStream(fontStream.CopyToByteArray());

            HyoutaTools.Tales.Vesperia.FPS4.FPS4   textureWiiFps4 = new HyoutaTools.Tales.Vesperia.FPS4.FPS4(textureWiiStream);
            HyoutaTools.Tales.Vesperia.Texture.TXM textureWiiTxm  = new HyoutaTools.Tales.Vesperia.Texture.TXM(textureWiiFps4.GetChildByIndex(0).AsFile.DataStream);
            HyoutaTools.Tales.Vesperia.Texture.TXV textureWiiTxv  = new HyoutaTools.Tales.Vesperia.Texture.TXV(textureWiiTxm, textureWiiFps4.GetChildByIndex(1).AsFile.DataStream, false);
            Bitmap bitmapWii = textureWiiTxv.textures[2].GetBitmaps()[0];
            {
                for (int y = 0; y < bitmapWii.Height; ++y)
                {
                    for (int x = 0; x < bitmapWii.Width; ++x)
                    {
                        Color color;
                        switch (IdentifyPixel(x, y))
                        {
                        case TileIdentification.UsedTile:
                            color = Color.FromArgb(0, 255, 0);
                            break;

                        case TileIdentification.UnusedTile:
                            color = Color.FromArgb(0, 0, 255);
                            break;

                        default:
                            throw new Exception("???");
                        }
                        bitmapWii.SetPixel(x, y, color);
                    }
                }
            }

            var          pxit    = new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(bitmapWii.Width, bitmapWii.Height, 8, 8);
            MemoryStream stream  = new MemoryStream();
            byte         storage = 0;
            bool         even    = false;

            foreach (var px in pxit)
            {
                if (px.X < bitmapWii.Width && px.Y < bitmapWii.Height)
                {
                    Color col         = bitmapWii.GetPixel(px.X, px.Y);
                    bool  pixelUnused = col.B > 0;
                    var   colidx      = pixelUnused ? 0xF : 0x0;
                    if (!even)
                    {
                        storage = (byte)colidx;
                    }
                    else
                    {
                        storage = (byte)(storage << 4 | (byte)colidx);
                        stream.WriteByte(storage == 0xFF ? (byte)1 : (byte)0);
                    }
                    even = !even;
                }
            }

            List <MemChunk> chunks = new List <MemChunk>();
            uint            offset = textureWiiFps4.Files[1].Location.Value + textureWiiTxv.textures[2].TXM.TxvLocation;
            long            len    = stream.Length;
            long            startOfLastSafeBlock = -1;
            var             fontMapper           = new FontMapper(0xE0000000 - textureWiiFps4.Files[1].Location.Value);

            stream.Position = 0;
            for (long i = 0; i <= len; ++i)
            {
                bool safeToWriteTo = i == len ? false : stream.ReadUInt8() == 1;
                if (safeToWriteTo && startOfLastSafeBlock == -1)
                {
                    // start of block
                    startOfLastSafeBlock = i;
                }
                else if (!safeToWriteTo && startOfLastSafeBlock != -1)
                {
                    // end of block
                    long     start  = startOfLastSafeBlock;
                    long     length = i - startOfLastSafeBlock;
                    MemChunk mc     = new MemChunk();
                    mc.Address    = (uint)(start + offset);
                    mc.FreeBytes  = (uint)length;
                    mc.File       = fontStream;
                    mc.Mapper     = fontMapper;
                    mc.IsInternal = false;
                    chunks.Add(mc);
                    startOfLastSafeBlock = -1;
                }
            }

            return(chunks);
        }