예제 #1
0
        void CopyTexelsClut(BinaryReader br, BinaryWriter bw, TxmHeader pakTxm, TxmHeader textureTxm)
        {
            if (pakTxm.ClutPixelFormat != TxmPixelFormat.None)
            {
                throw new ArgumentException("Cannot operate on source TXM with CLUT.", nameof(pakTxm));
            }
            if (textureTxm.ClutPixelFormat == TxmPixelFormat.None)
            {
                return;
            }

            var destColumnParams = GsMemoryUtils.GetColumnParams(textureTxm.ClutPixelFormat);
            int copyLength       = textureTxm.GetClutByteSize();
            int baseBlockNumber  = textureTxm.ClutBufferBase - pakTxm.ImageBufferBase;
            int srcBase          = 0x10 + pakTxm.GetClutByteSize();
            var destBase         = 0x10;
            int bytesPerSrcLine  = pakTxm.GetImageByteSize() / pakTxm.ImageHeight;
            int bytesPerDestLine = textureTxm.GetClutByteSize() / textureTxm.ClutHeight;

            bw.Write(new byte[copyLength]);
            int numXBlocks = textureTxm.ClutWidth / destColumnParams.Width;

            if (numXBlocks == 0)
            {
                numXBlocks = 1;
            }
            int numYBlocks = textureTxm.ClutHeight / (destColumnParams.Height * GsMemoryUtils.COLUMNS_PER_BLOCK);

            if (numYBlocks == 0)
            {
                numYBlocks = 1;
            }
            int destBlock = 0;

            for (int blockY = 0; blockY < numYBlocks; ++blockY)
            {
                for (int blockX = 0; blockX < numXBlocks; ++blockX)
                {
                    int blockNumber = baseBlockNumber + GsMemoryUtils.CalcBlockNumber(textureTxm.ClutPixelFormat, blockX, blockY, 1);
                    br.BaseStream.Seek(srcBase + GsMemoryUtils.CalcBlockMemoryOffset(pakTxm.ImageSourcePixelFormat, blockNumber),
                                       SeekOrigin.Begin);
                    bw.BaseStream.Seek(destBase + GsMemoryUtils.CalcTxmImageOffset(destColumnParams, destBlock, textureTxm.ClutWidth),
                                       SeekOrigin.Begin);
                    for (int i = 0; i < GsMemoryUtils.COLUMNS_PER_BLOCK; ++i)
                    {
                        byte[] col = GsMemoryUtils.ReadColumn(br, pakTxm.ImageSourcePixelFormat, bytesPerSrcLine);
                        GsMemoryUtils.WriteColumn(bw, textureTxm.ClutPixelFormat, bytesPerDestLine, col);
                    }
                    ++destBlock;
                }
            }

            // Dump palette
            //bw.BaseStream.Seek(destBase, SeekOrigin.Begin);
            //BinaryReader palBr = new BinaryReader(bw.BaseStream);
            //using (var palette = TxmConversion.ConvertTxmRgba32(palBr, textureTxm.ClutWidth, textureTxm.ClutHeight))
            //{
            //    palette.SaveAsPng($"palette_{numWrittenTextures}.png");
            //}
        }
예제 #2
0
        void CopyTexels(BinaryReader br, BinaryWriter bw, TxmHeader pakTxm, TxmHeader textureTxm)
        {
            if (pakTxm.ClutPixelFormat != TxmPixelFormat.None)
            {
                throw new ArgumentException("Cannot operate on source TXM with CLUT.", nameof(pakTxm));
            }

            var destColumnParams = GsMemoryUtils.GetColumnParams(textureTxm.ImageSourcePixelFormat);
            int copyLength       = textureTxm.GetImageByteSize();
            int srcBase          = 0x10 + pakTxm.GetClutByteSize();
            int baseBlockNumber  = textureTxm.ImageBufferBase - pakTxm.ImageBufferBase;
            int destBase         = 0x10 + textureTxm.GetClutByteSize();
            int bytesPerSrcLine  = pakTxm.GetImageByteSize() / pakTxm.ImageHeight;
            int bytesPerDestLine = copyLength / textureTxm.ImageHeight;

            bw.Write(new byte[copyLength]);
            int numXBlocks = textureTxm.ImageWidth / destColumnParams.Width;

            if (numXBlocks == 0)
            {
                numXBlocks = 1;
            }
            int numYBlocks = textureTxm.ImageHeight / (destColumnParams.Height * GsMemoryUtils.COLUMNS_PER_BLOCK);

            if (numYBlocks == 0)
            {
                numYBlocks = 1;
            }
            int destBlock = 0;

            for (int blockY = 0; blockY < numYBlocks; ++blockY)
            {
                for (int blockX = 0; blockX < numXBlocks; ++blockX)
                {
                    int blockNumber = baseBlockNumber + GsMemoryUtils.CalcBlockNumber(textureTxm.ImageSourcePixelFormat, blockX, blockY, textureTxm.Misc);
                    br.BaseStream.Seek(srcBase + GsMemoryUtils.CalcBlockMemoryOffset(pakTxm.ImageSourcePixelFormat, blockNumber),
                                       SeekOrigin.Begin);
                    bw.BaseStream.Seek(destBase + GsMemoryUtils.CalcTxmImageOffset(destColumnParams, destBlock, textureTxm.ImageWidth),
                                       SeekOrigin.Begin);
                    for (int i = 0; i < GsMemoryUtils.COLUMNS_PER_BLOCK; ++i)
                    {
                        byte[] col = GsMemoryUtils.ReadColumn(br, pakTxm.ImageSourcePixelFormat, bytesPerSrcLine);
                        if (pakTxm.ImageSourcePixelFormat != textureTxm.ImageSourcePixelFormat)
                        {
                            col = PsmtMixer.MixColumn(col, pakTxm.ImageSourcePixelFormat, textureTxm.ImageSourcePixelFormat, i % 2 != 0);
                        }
                        GsMemoryUtils.WriteColumn(bw, textureTxm.ImageSourcePixelFormat, bytesPerDestLine, col);
                    }

                    ++destBlock;
                }
            }
        }