示例#1
0
        private static IEnumerable <Image <Rgba32> > ToTileset(sNFTR font, Rgba32[] palette, int charWidth, int charHeight,
                                                               int rowsPerTexture, int colsPerTexture, int zoom)
        {
            int numChars = font.plgc.tiles.Length;

            for (int processedChars = 0; processedChars < numChars;)
            {
                var image = new Image <Rgba32>(MAX_WIDTH, MAX_HEIGHT);
                image.Mutate(im => im.Fill(palette[palette.Length - 1]));

                // add charsPerTexture images here and return the image.
                for (int i = 0; i < rowsPerTexture; i++)
                {
                    for (int j = 0; j < colsPerTexture; j++)
                    {
                        int index = processedChars++;
                        if (index >= numChars)
                        {
                            break;
                        }

                        int x = j * charWidth;
                        // First row is empty.
                        int y = i * charHeight;
                        image.Mutate(im => im.DrawImage(GraphicsOptions.Default,
                                                        Get_Char(font, index, palette, zoom), new Point(x, y)));
                    }
                }
                yield return(image);
            }
        }
示例#2
0
        public static IEnumerable <Image <Rgba32> > ToTileset(sNFTR font, Rgba32[] palette)
        {
            int numChars = font.plgc.tiles.Length;

            // Get the image size
            int charWidth  = font.plgc.tile_width;
            int charHeight = font.plgc.tile_height;

            int numColumns = (int)Math.Floor((double)MAX_WIDTH / charWidth);
            int numRows    = (int)Math.Floor((double)MAX_HEIGHT / charHeight);

            int charsPerTexture = (int)Math.Floor((double)numChars / (numColumns * numRows));

            return(ToTileset(font, palette, charWidth, charHeight, numRows, numColumns, 1));
        }
示例#3
0
        public static IEnumerable <Image <Rgba32> > ToTileset(sNFTR font, Rgba32[] palette, IList <CharmapEntry> charmap, IList <char> charset)
        {
            int numChars = charset.Count;

            // Get the image size
            int charWidth  = font.plgc.tile_width;
            int charHeight = font.plgc.tile_height;

            int numColumns = (int)Math.Floor((double)MAX_WIDTH / charWidth);
            int numRows    = (int)Math.Floor((double)MAX_HEIGHT / charHeight);

            int charsPerTexture = (int)Math.Floor((double)numChars / (numColumns * numRows));

            for (int processedChars = 0; processedChars < numChars;)
            {
                var image = new Image <Rgba32>(MAX_WIDTH, MAX_HEIGHT);
                image.Mutate(im => im.Fill(palette[palette.Length - 1]));

                // add charsPerTexture images here and return the image.
                for (int i = 0; i < numRows; i++)
                {
                    for (int j = 0; j < numColumns; j++)
                    {
                        int x = j * charWidth;
                        // First row is empty.
                        int y = i * charHeight;
                        if (processedChars >= numChars)
                        {
                            break;
                        }
                        var charToDraw = charset[processedChars];
                        processedChars++;
                        int index = charmap.FirstOrDefault(c => c.Character == charToDraw)?.Index ?? 0;
                        image.Mutate(im => im.DrawImage(GraphicsOptions.Default,
                                                        Get_Char(font, index, palette, 1), new Point(x, y)));
                    }
                }
                yield return(image);
            }
        }
示例#4
0
        public static sNFTR Read(Stream file)
        {
            sNFTR        font = new sNFTR();
            BinaryReader br   = new BinaryReader(file);

            // Read the standard header
            font.header.type       = br.ReadChars(4);
            font.header.endianess  = br.ReadUInt16();
            font.header.unknown    = br.ReadUInt16();
            font.header.file_size  = br.ReadUInt32();
            font.header.block_size = br.ReadUInt16();
            font.header.num_blocks = br.ReadUInt16();

            // Font INFo section
            font.fnif.type       = br.ReadChars(4);
            font.fnif.block_size = br.ReadUInt32();

            font.fnif.unknown1      = br.ReadByte();
            font.fnif.height        = br.ReadByte();
            font.fnif.nullCharIndex = br.ReadUInt16();
            font.fnif.unknown4      = br.ReadByte();
            font.fnif.width         = br.ReadByte();
            font.fnif.width_bis     = br.ReadByte();
            font.fnif.encoding      = br.ReadByte();

            font.fnif.offset_plgc = br.ReadUInt32();
            font.fnif.offset_hdwc = br.ReadUInt32();
            font.fnif.offset_pamc = br.ReadUInt32();

            if (font.fnif.block_size == 0x20)
            {
                font.fnif.height_font = br.ReadByte();
                font.fnif.widht_font  = br.ReadByte();
                font.fnif.bearing_y   = br.ReadByte();
                font.fnif.bearing_x   = br.ReadByte();
            }

            // Character Graphics LP
            br.BaseStream.Position = font.fnif.offset_plgc - 0x08;
            font.plgc.type         = br.ReadChars(4);
            font.plgc.block_size   = br.ReadUInt32();
            font.plgc.tile_width   = br.ReadByte();
            font.plgc.tile_height  = br.ReadByte();
            font.plgc.tile_length  = br.ReadUInt16();
            font.plgc.unknown      = br.ReadUInt16();
            font.plgc.depth        = br.ReadByte();
            font.plgc.rotateMode   = br.ReadByte();

            font.plgc.tiles = new Byte[(font.plgc.block_size - 0x10) / font.plgc.tile_length][];
            for (int i = 0; i < font.plgc.tiles.Length; i++)
            {
                font.plgc.tiles[i] = BytesToBits(br.ReadBytes(font.plgc.tile_length));
                if (font.plgc.rotateMode == 2)
                {
                    font.plgc.tiles[i] = Rotate270(font.plgc.tiles[i], font.plgc.tile_width, font.plgc.tile_height, font.plgc.depth);
                }
                else if (font.plgc.rotateMode == 1)
                {
                    font.plgc.tiles[i] = Rotate90(font.plgc.tiles[i], font.plgc.tile_width, font.plgc.tile_height, font.plgc.depth);
                }
                else if (font.plgc.rotateMode == 3)
                {
                    font.plgc.tiles[i] = Rotate180(font.plgc.tiles[i], font.plgc.tile_width, font.plgc.tile_height, font.plgc.depth);
                }
            }


            // Character Width DH
            br.BaseStream.Position = font.fnif.offset_hdwc - 0x08;
            font.hdwc.type         = br.ReadChars(4);
            font.hdwc.block_size   = br.ReadUInt32();
            font.hdwc.fist_code    = br.ReadUInt16();
            font.hdwc.last_code    = br.ReadUInt16();
            font.hdwc.unknown1     = br.ReadUInt32();

            font.hdwc.info = new List <sNFTR.HDWC.Info>();
            for (int i = 0; i < font.plgc.tiles.Length; i++)
            {
                sNFTR.HDWC.Info info = new sNFTR.HDWC.Info();
                info.pixel_start  = br.ReadSByte();
                info.pixel_width  = br.ReadByte();
                info.pixel_length = br.ReadByte();
                font.hdwc.info.Add(info);
            }

            // Character MAP
            br.BaseStream.Position = font.fnif.offset_pamc - 0x08;
            font.pamc = new List <sNFTR.PAMC>();
            uint nextOffset = 0x00;

            do
            {
                sNFTR.PAMC pamc = new sNFTR.PAMC();
                pamc.type         = br.ReadChars(4);
                pamc.block_size   = br.ReadUInt32();
                pamc.first_char   = br.ReadUInt16();
                pamc.last_char    = br.ReadUInt16();
                pamc.type_section = br.ReadUInt32();
                nextOffset        = br.ReadUInt32();
                pamc.next_section = nextOffset;

                switch (pamc.type_section)
                {
                case 0:
                    sNFTR.PAMC.Type0 type0 = new sNFTR.PAMC.Type0();
                    type0.fist_char_code = br.ReadUInt16();
                    pamc.info            = type0;
                    break;

                case 1:
                    sNFTR.PAMC.Type1 type1 = new sNFTR.PAMC.Type1();
                    type1.char_code = new ushort[pamc.last_char - pamc.first_char + 1];
                    for (int i = 0; i < type1.char_code.Length; i++)
                    {
                        type1.char_code[i] = br.ReadUInt16();
                    }

                    pamc.info = type1;
                    break;

                case 2:
                    sNFTR.PAMC.Type2 type2 = new sNFTR.PAMC.Type2();
                    type2.num_chars = br.ReadUInt16();
                    type2.charInfo  = new sNFTR.PAMC.Type2.CharInfo[type2.num_chars];

                    for (int i = 0; i < type2.num_chars; i++)
                    {
                        type2.charInfo[i].chars_code = br.ReadUInt16();
                        type2.charInfo[i].chars      = br.ReadUInt16();
                    }
                    pamc.info = type2;
                    break;
                }

                font.pamc.Add(pamc);
                br.BaseStream.Position = nextOffset - 0x08;
            } while (nextOffset != 0x00 && (nextOffset - 0x08) < br.BaseStream.Length);

            font.plgc.rotateMode = 0;

            br.Close();
            return(font);
        }
示例#5
0
        public static XDocument ExportInfo(Dictionary <int, int> charTable, sNFTR font, int numChars)
        {
            var encoding = Encoding.UTF8;

            switch (font.fnif.encoding)
            {
            case 2:
                encoding = Encoding.GetEncoding(932);     //Shift-JIS
                break;

            case 0:
                encoding = Encoding.UTF8;
                break;

            case 3:
                encoding = Encoding.GetEncoding(1252);
                break;

            case 1:
                encoding = Encoding.Unicode;
                break;
            }

            XDocument doc = new XDocument();

            doc.Declaration = new XDeclaration("1.0", encoding.BodyName, null);



            XElement charMap         = new XElement("CharMap");
            XElement uvGen           = new XElement("UVGen");
            int      numColumns      = MAX_WIDTH / font.plgc.tile_width;
            int      numRows         = (int)Math.Floor((double)MAX_HEIGHT / font.plgc.tile_height);
            int      charsPerTexture = (int)Math.Floor((double)numChars / (numColumns * numRows));

            uvGen.Add(new XElement("ColumnsPerTexture", numColumns));
            uvGen.Add(new XElement("RowsPerTexture", numRows));
            uvGen.Add(new XElement("SpritesPerTexture", numColumns * numRows));
            uvGen.Add(new XElement("TileHeight", font.fnif.height));
            uvGen.Add(new XElement("TileWidth", font.fnif.width));
            charMap.Add(uvGen);

            var charCodeTuples = charTable.OrderBy(kvp => kvp.Value).ToList();

            foreach (var kvp in charCodeTuples)
            {
                var c = kvp.Key;

                string ch = "";

                byte[] codes = BitConverter.GetBytes(c).ToArray();
                ch = new String(Encoding.Unicode.GetChars(codes)).Replace("\0", "");

                int tileCode = kvp.Value;
                if (tileCode >= font.hdwc.info.Count)
                {
                    continue;
                }
                sNFTR.HDWC.Info info = font.hdwc.info[tileCode];

                XElement chx = new XElement("CharInfo");
                chx.SetAttributeValue("Char", ch);
                chx.SetAttributeValue("Code", c);
                chx.SetAttributeValue("Hex", c.ToString("x2"));
                chx.SetAttributeValue("Index", tileCode.ToString());
                chx.SetAttributeValue("Width", info.pixel_length.ToString());

                charMap.Add(chx);
            }
            // Export general info
            // FNIF data
            XElement xmlFnif = new XElement("FNIF");

            xmlFnif.Add(new XElement("Unknown1", font.fnif.unknown1));
            xmlFnif.Add(new XElement("Height", font.fnif.height));
            xmlFnif.Add(new XElement("NullCharIndex", font.fnif.nullCharIndex));
            xmlFnif.Add(new XElement("Unknown2", font.fnif.unknown4));
            xmlFnif.Add(new XElement("Width", font.fnif.width));
            xmlFnif.Add(new XElement("WidthBis", font.fnif.width_bis));
            xmlFnif.Add(new XElement("Encoding", encoding.BodyName));
            if (font.fnif.block_size == 0x20)
            {
                xmlFnif.Add(new XElement("GlyphHeight", font.fnif.height_font));
                xmlFnif.Add(new XElement("GlyphWidth", font.fnif.widht_font));
                xmlFnif.Add(new XElement("BearingY", font.fnif.bearing_y));
                xmlFnif.Add(new XElement("BearingX", font.fnif.bearing_x));
            }
            charMap.Add(xmlFnif);
            doc.Add(charMap);
            return(doc);
        }
示例#6
0
 public static Image <Rgba32> Get_Char(sNFTR font, int id, Rgba32[] palette, int zoom = 1)
 {
     return(Get_Char(font.plgc.tiles[id], font.plgc.depth, font.plgc.tile_width, font.plgc.tile_height, font.plgc.rotateMode, palette, zoom));
 }
示例#7
0
 public NFTRDumper(sNFTR font, Rgba32 background)
 {
     this.font    = font;
     this.palette = NFTR.CalculatePalette(font.plgc.depth, false, background);
     Fill_CharTile();
 }