Esempio n. 1
0
        private static Bitmap ConvertTileToBitmap(TileDescriptor tileDesc, byte[] tmem, ushort[][] palettes)
        {
            if (Math.Floor(tileDesc.sHi - tileDesc.sLo) != tileDesc.sHi - tileDesc.sLo)
            {
                throw new Exception();
            }
            if (Math.Floor(tileDesc.tHi - tileDesc.tLo) != tileDesc.tHi - tileDesc.tLo)
            {
                throw new Exception();
            }

            // Break into lines
            int startPtrBytes = tileDesc.tmemAddressInWords * 8;
            int width         = (int)(tileDesc.sHi - tileDesc.sLo + 1);
            int height        = (int)(tileDesc.tHi - tileDesc.tLo + 1);
            int bytesPerLine  = tileDesc.wordsPerLine * 8;

            byte[] data = tmem.Subsection(startPtrBytes, bytesPerLine * height);
            ushort[]? palette = tileDesc.palette == 0 ? null : palettes[tileDesc.palette - 1];

            return(Texels.ConvertToBitmap(data, tileDesc.format, tileDesc.bitSize, width, height, bytesPerLine, true, true, palette));
        }
Esempio n. 2
0
        public static void DumpFonts(byte[] romBytes, string outputDir)
        {
            Directory.CreateDirectory(outputDir + "Converted");
            string fullOutputPath = outputDir + "Converted/font/";

            Directory.CreateDirectory(fullOutputPath);

            // ok this is dumb i need to fix this
            Filesystem.Filesystem filesystem = new Filesystem.Filesystem(romBytes);

            foreach (Filesystem.Filesystem.File file in filesystem.AllFiles.Where(file => file.fileTypeFromFileHeader == "UVFT"))
            {
                // TODO
                string outputSubfolder = $"{fullOutputPath}[0x{file.formLocationInROM:x6}]/";
                Directory.CreateDirectory(outputSubfolder);

                List <byte[]> imageDatas       = file.SectionsOfType("IMAG");
                byte[]        charIndexToASCII = file.Section("STRG");
                byte[]        frmtSec          = file.Section("FRMT");
                if (frmtSec.Length != 8)
                {
                    throw new Exception();
                }
                Texels.ColorFormat colorFormat = (Texels.ColorFormat)frmtSec.ReadUInt32(0);
                Texels.BitSize     bitSize     = (Texels.BitSize)frmtSec.ReadUInt32(4);

                CharacterDescriptor[] characterDescriptors = file.Section("BITM")
                                                             .InGroupsOf(16)
                                                             .Select((charDescData, index) => new CharacterDescriptor(charDescData, index))
                                                             .ToArray();

                // First, save off the main images
                //for (int i = 0; i < imageDatas.Count; i++)
                //{
                //    byte[] imageData = imageDatas[i];
                //    IEnumerable<CharacterDescriptor> relevantChars = characterDescriptors.Where(c => c.sourceIMAGIndex == i);
                //    int texelsPerLine = relevantChars.First().sourceIMAGTexelsPerLine;
                //    if(relevantChars.Any(c => c.sourceIMAGTexelsPerLine != texelsPerLine))
                //    {
                //        throw new Exception("Inconsistent texels per line in BITM section!");
                //    }
                //    int imagHeightTexels = relevantChars.Max(c => c.heightTexels);
                //    int bytesPerLine = Texels.GetNumBytes(texelsPerLine, bitSize);

                //    Bitmap bitmap = Texels.ConvertToBitmap(imageData, colorFormat, bitSize, texelsPerLine, imagHeightTexels, bytesPerLine, false, false, null);
                //    bitmap.Save($"{outputSubfolder}{i+1}.png");
                //}

                // Now save each of the characters
                //string individualCharsDirectory = $"{outputSubfolder}Individual Characters/";
                //Directory.CreateDirectory(individualCharsDirectory);
                foreach (CharacterDescriptor charDesc in characterDescriptors)
                {
                    byte[] sourceIMAG = imageDatas[charDesc.sourceIMAGIndex];
                    byte[] texelData;
                    if (bitSize == Texels.BitSize._4)
                    {
                        texelData = GetByteArrayStartingFromFourBitIndex(sourceIMAG, charDesc.startTexel).ToArray();
                    }
                    else
                    {
                        texelData = sourceIMAG.Skip(Texels.GetNumBytes(charDesc.startTexel, bitSize)).ToArray();
                    }

                    int bytesPerLine = Texels.GetNumBytes(charDesc.sourceIMAGTexelsPerLine, bitSize);

                    Bitmap bitmap = Texels.ConvertToBitmap(texelData, colorFormat, bitSize, charDesc.widthTexels, charDesc.heightTexels, bytesPerLine, false, false, null);

                    string filename = $"{charDesc.indexInBITM:D2}";
                    char   ascii    = Convert.ToChar(charIndexToASCII[charDesc.indexInBITM]);
                    if (!Path.GetInvalidFileNameChars().Contains(ascii))
                    {
                        filename += $" ({ascii})";
                    }

                    bitmap.Save($"{outputSubfolder}{filename}.png");
                }
                Console.WriteLine($"Converted font at {file.formLocationInROM:x6}");
            }
        }
        public static void DumpBlits(byte[] romBytes, string outputDir)
        {
            Directory.CreateDirectory(outputDir + "Converted");
            string fullOutputPath = outputDir + "Converted/blit/";

            Directory.CreateDirectory(fullOutputPath);

            // ok this is dumb i need to fix this
            Filesystem.Filesystem filesystem = new Filesystem.Filesystem(romBytes);

            foreach (Filesystem.Filesystem.File file in filesystem.AllFiles.Where(file => file.fileTypeFromFileHeader == "UVBT"))
            {
                string outputFileName = $"[0x{file.formLocationInROM:x6}]";
                byte[] bytes          = file.Sections.Single().Item2;

                ColorFormat colorFormat   = (ColorFormat)bytes.ReadUInt16(0);
                BitSize     bitSize       = Texels.NumBitsToBitSize(bytes.ReadUInt16(2));
                ushort      width         = bytes.ReadUInt16(4);
                ushort      texelsPerLine = bytes.ReadUInt16(6);
                ushort      height        = bytes.ReadUInt16(8);
                ushort      tileWidth     = bytes.ReadUInt16(10);
                ushort      tileHeight    = bytes.ReadUInt16(12);

                byte[] colorData = bytes.Subsection(14, bytes.Length - 14);



                Console.WriteLine(bytes.Subsection(0, 14).PrettyPrint());
                Console.WriteLine($"{outputFileName} {bitSize}-bit {colorFormat}\t <{width} ({texelsPerLine}), {height}> [{tileWidth} {tileHeight}]");
                int bytesPerTile = (int)(tileWidth * tileHeight * Texels.BitSizeToNumBytesFloat(bitSize));

                Bitmap outBitmap   = new Bitmap(width, height);
                int    p           = 0;
                int    curTopLeftX = 0;
                int    curTopLeftY = 0;
                while (p < colorData.Length)
                {
                    if (curTopLeftY + tileHeight > height)
                    {
                        tileHeight   = (ushort)(height - curTopLeftY);
                        bytesPerTile = (int)(tileWidth * tileHeight * Texels.BitSizeToNumBytesFloat(bitSize));
                    }

                    byte[] tileColorData;
                    if (p + bytesPerTile >= colorData.Length)
                    {
                        tileColorData = new byte[bytesPerTile];
                        Array.Copy(colorData, p, tileColorData, 0, colorData.Length - p);
                    }
                    else
                    {
                        tileColorData = colorData.Subsection(p, bytesPerTile);
                    }
                    // TODO: why arent 32-bit textures deinterleaved?
                    Bitmap tile = Texels.ConvertToBitmap(tileColorData, colorFormat, bitSize, tileWidth, tileHeight, (int)(tileWidth * Texels.BitSizeToNumBytesFloat(bitSize)), false, bitSize != BitSize._32, null);
                    CopyToMainBitmap(tile, curTopLeftX, curTopLeftY, outBitmap);


                    p += bytesPerTile;

                    curTopLeftX += tileWidth;

                    if (curTopLeftX >= width)
                    {
                        curTopLeftX  = 0;
                        curTopLeftY += tileHeight;

                        if (curTopLeftY >= height)
                        {
                            break;
                        }
                    }
                }

                outBitmap.Save(fullOutputPath + outputFileName + ".png");
            }
        }