public void Convert(string inputPath, string outputPath, Bitmap bitmap, UVs[] sliceCoordinates)
        {
            string namespaceName = string.Format(NAMESPACE_FORMAT, Path.GetFileName(Path.GetFileNameWithoutExtension(inputPath)));

            StringBuilder sb   = new StringBuilder();
            Size          size = bitmap.Size;

            if (size.Width % TileConfig.c_TILEWIDTH != 0 || size.Height % TileConfig.c_TILEHEIGHT != 0)
            {
                throw new Exception("Size not compatible with GBA tiles. Width and height of pixels must be multiples of 8.");
            }

            Console.WriteLine("Processing colour palette");

            int xStart = 0;
            int yStart = 0;
            int width  = bitmap.Width;
            int height = bitmap.Height;

            Color[] preProcessedPalette = PaletteHelper.GeneratePaletteFromImage(bitmap, xStart, yStart, width, height);

            // Validate pallet length
            {
                if (preProcessedPalette.Length > 256)
                {
                    throw new Exception("Palette length out of range for the GBA");
                }

                // Todo, currently not supported
                if (preProcessedPalette.Length > 16)
                {
                    throw new Exception("Palette length out of range for 4bbp format");
                }
            }

            Compression.CompressionType compressionType = Compression.CompressionType.BitPacked;
            uint maxColours = MathX.IsPowerOf2((uint)preProcessedPalette.Length) ? (uint)preProcessedPalette.Length : MathX.NextPowerOf2((uint)preProcessedPalette.Length);
            uint destBpp    = (uint)MathX.IndexOfHighestSetBit(maxColours);

            if (!MathX.IsPowerOf2(destBpp))
            {
                destBpp = MathX.NextPowerOf2(destBpp);
            }

            Console.WriteLine(string.Format("Compression type = {0}", compressionType.ToString()));
            Console.WriteLine(string.Format("Destination Bit Depth = {0}", destBpp));

            List <int>           dataOffsets = new List <int>();
            List <StringBuilder> spriteData  = new List <StringBuilder>();

            dataOffsets.Add(0);
            int totalData = 0;

            // Collect data and add offsets
            {
                Console.WriteLine("Processing sprite data");

                for (int i = 0; i < sliceCoordinates.Length; ++i)
                {
                    StringBuilder dataSb = new StringBuilder();
                    UVs           slice = sliceCoordinates[i];
                    int           spriteWidth = slice.width, spriteHeight = slice.height;
                    int           dataCount = WriteSpriteData(dataSb, bitmap, preProcessedPalette, spriteWidth, spriteHeight, slice.x, slice.y, compressionType, destBpp);

                    spriteData.Add(dataSb);

                    // Add offsets
                    if (i < sliceCoordinates.Length - 1)
                    {
                        dataOffsets.Add(dataOffsets[i] + dataCount);
                    }

                    totalData += dataCount;
                }
            }

            sb.Append(MACRO_DEFINES);
            sb.Append(namespaceName);

            WriteHeader(sliceCoordinates, preProcessedPalette, totalData, compressionType, destBpp, sb);
            WritePalette(preProcessedPalette, sb);

            // Write width
            {
                sb.Append(VAR_WIDTHMAP);
                sb.Append(namespaceTabs + "{\n");
                sb.Append(namespaceTabs + TAB_CHAR);

                for (int i = 0; i < sliceCoordinates.Length; ++i)
                {
                    int spriteWidth = sliceCoordinates[i].width;
                    sb.AppendFormat("{0}, ", spriteWidth);
                    if ((i + 1) % c_arrayNewlineCount == 0)
                    {
                        sb.AppendFormat("\n" + namespaceTabs + TAB_CHAR);
                    }
                }

                sb.Append("\n");
                sb.Append(namespaceTabs + "};\n\n");
            }

            // Write height
            {
                sb.Append(VAR_HEIGHTMAP);
                sb.Append(namespaceTabs + "{\n");
                sb.Append(namespaceTabs + TAB_CHAR);

                for (int i = 0; i < sliceCoordinates.Length; ++i)
                {
                    int spriteHeight = sliceCoordinates[i].height;   // Todo
                    sb.AppendFormat("{0}, ", spriteHeight);
                    if ((i + 1) % c_arrayNewlineCount == 0)
                    {
                        sb.AppendFormat("\n" + namespaceTabs + TAB_CHAR);
                    }
                }

                sb.Append("\n");
                sb.Append(namespaceTabs + "};\n\n");
            }

            // Write offsets
            {
                const string tabs = namespaceTabs + TAB_CHAR;

                sb.Append(VAR_OFFSETS);
                sb.Append(namespaceTabs + "{\n" + tabs);
                for (int i = 0; i < dataOffsets.Count; i++)
                {
                    sb.AppendFormat("{0}, ", dataOffsets[i]);

                    if ((i + 1) % c_arrayNewlineCount == 0)
                    {
                        sb.AppendFormat("\n" + tabs);
                    }
                }

                sb.Append('\n' + namespaceTabs + "};\n\n");
            }

            // Write data
            {
                sb.Append(VAR_DATA);
                sb.Append(namespaceTabs + "{\n");

                foreach (StringBuilder dataSB in spriteData)
                {
                    sb.Append(dataSB.ToString());
                }

                sb.Append(namespaceTabs + "};\n\n");
            }

            sb.Append("}\n");

            Console.WriteLine("Sprite \"" + outputPath + "\" successfully converted");
            File.WriteAllText(outputPath, sb.ToString());
        }
Exemple #2
0
        public void Convert(string inputPath, string outputPath, Bitmap bitmap, UVs[] sliceCoordinates)
        {
            CppWriter cppWriter = new CppWriter(Path.GetFileName(Path.GetFileNameWithoutExtension(inputPath)), outputPath);

            Size size = bitmap.Size;

            if (size.Width % TileConfig.TileWidth != 0 || size.Height % TileConfig.TileHeight != 0)
            {
                throw new Exception("Size not compatible with GBA tiles. Width and height of pixels must be multiples of 8.");
            }

            Console.WriteLine("Processing colour palette");

            int xStart = 0;
            int yStart = 0;
            int width  = bitmap.Width;
            int height = bitmap.Height;

            Color[] preProcessedPalette = PaletteHelper.GeneratePaletteFromImage(bitmap, xStart, yStart, width, height);

            // Validate pallet length
            {
                if (preProcessedPalette.Length > 256)
                {
                    throw new Exception("Palette length out of range for the GBA");
                }

                // Todo, currently not supported
                if (preProcessedPalette.Length > 16)
                {
                    throw new Exception("Palette length out of range for 4bbp format");
                }
            }

            Console.WriteLine(String.Format("Palette length: {0}", preProcessedPalette.Length));

            Compression.CompressionType compressionType = Compression.CompressionType.BitPacked;
            uint maxColours = MathX.IsPowerOf2((uint)preProcessedPalette.Length) ? (uint)preProcessedPalette.Length : MathX.NextPowerOf2((uint)preProcessedPalette.Length);
            uint destBpp    = (uint)MathX.IndexOfHighestSetBit(maxColours);

            if (!MathX.IsPowerOf2(destBpp))
            {
                destBpp = MathX.NextPowerOf2(destBpp);
            }

            Console.WriteLine(string.Format("Compression type = {0}", compressionType.ToString()));
            Console.WriteLine(string.Format("Destination Bit Depth = {0}", destBpp));

            List <int>            dataOffsets = new List <int>();
            List <List <UInt32> > spriteData  = new List <List <UInt32> >();

            dataOffsets.Add(0);
            int totalData = 0;

            // Collect data and add offsets
            {
                Console.WriteLine("Processing sprite data");

                for (int i = 0; i < sliceCoordinates.Length; ++i)
                {
                    StringBuilder dataSb = new StringBuilder();
                    UVs           slice = sliceCoordinates[i];
                    int           spriteWidth = slice.width, spriteHeight = slice.height;
                    List <UInt32> data = WriteSpriteData(bitmap, preProcessedPalette, spriteWidth, spriteHeight, slice.x, slice.y, compressionType, destBpp);

                    spriteData.Add(data);

                    // Add offsets
                    if (i < sliceCoordinates.Length - 1)
                    {
                        dataOffsets.Add(dataOffsets[i] + data.Count);
                    }

                    totalData += data.Count;
                }
            }

            WriteHeader(cppWriter, sliceCoordinates, preProcessedPalette, totalData, compressionType, destBpp);
            WritePalette(cppWriter, preProcessedPalette);

            // Write width
            {
                for (int i = 0; i < sliceCoordinates.Length; ++i)
                {
                    int spriteWidth = sliceCoordinates[i].width;
                    cppWriter.Write((byte)spriteWidth);
                }
            }

            // Write height
            {
                for (int i = 0; i < sliceCoordinates.Length; ++i)
                {
                    int spriteHeight = sliceCoordinates[i].height;
                    cppWriter.Write((byte)spriteHeight);
                }
            }

            // Write offsets
            {
                for (int i = 0; i < dataOffsets.Count; i++)
                {
                    cppWriter.Write((UInt32)dataOffsets[i]);
                }
            }

            // Write data
            {
                foreach (var dataList in spriteData)
                {
                    foreach (UInt32 data in dataList)
                    {
                        cppWriter.Write((UInt32)data);
                    }
                }
            }

            Console.WriteLine("Sprite \"" + outputPath + "\" successfully converted");

            cppWriter.Finalise();
        }