예제 #1
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
            public FontList(ref BinaryStream s)
            {
                SectionHeader section = new SectionHeader(ref s);

                int startpos = (int)s.BaseStream.Position - 8;

                fontCount = s.ReadUInt16();

                s.Align(4); // Padding

                int basepos = (int)s.BaseStream.Position;

                fileNameOffsets = new uint[fontCount];
                fileNames       = new string[fontCount];

                for (int o = 0; o < fontCount; o++)
                {
                    fileNameOffsets[o] = s.ReadUInt32();

                    int offsetpos = (int)s.BaseStream.Position;

                    s.BaseStream.Position = basepos + fileNameOffsets[o];

                    fileNames[o] = s.ReadString(StringCoding.ZeroTerminated);

                    s.Align(4);

                    s.BaseStream.Position = offsetpos;
                }

                s.BaseStream.Position = startpos + section.size;
            }
예제 #2
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
            public void Write(ref BinaryStream s)
            {
                s.WriteByte((byte)originType);

                s.Align(4); // Padding

                s.WriteSingle(screenWidth);
                s.WriteSingle(screenHeight);
                s.WriteSingle(maxPartsWidth);
                s.WriteSingle(maxPartsHeight);

                s.WriteString(name, StringCoding.ZeroTerminated);

                s.Align(4);
            }
예제 #3
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
                    public void Write(ref BinaryStream s)
                    {
                        s.WriteByte((byte)combineRBG);
                        s.WriteByte((byte)combineAlpha);

                        s.Align(4); // Padding
                    }
예제 #4
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
            public MaterialList(ref BinaryStream s)
            {
                SectionHeader section = new SectionHeader(ref s);

                int startpos = (int)s.BaseStream.Position - 8;

                materialCount = s.ReadUInt16();

                s.Align(4); // Padding

                infoOffsets = new uint[materialCount];
                materials   = new Material[materialCount];

                for (int o = 0; o < materialCount; o++)
                {
                    infoOffsets[o] = s.ReadUInt32();

                    int offsetpos = (int)s.BaseStream.Position;

                    s.BaseStream.Position = startpos + infoOffsets[o];

                    materials[o] = new Material(ref s);

                    s.BaseStream.Position = offsetpos;
                }

                s.BaseStream.Position = startpos + section.size;
            }
예제 #5
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
                    public void Write(ref BinaryStream s)
                    {
                        s.WriteByte((byte)compareFunc);

                        s.Align(4); // Padding

                        s.WriteSingle(alphaRef);
                    }
예제 #6
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
            public TextBox(ref BinaryStream s) : base(ref s)
            {
                int startPos = (int)s.BaseStream.Position - 84;

                bufByteCount    = s.ReadUInt16();
                stringByteCount = s.ReadUInt16();

                materialIndex = s.ReadUInt16();
                fontIndex     = s.ReadUInt16();

                textPosition  = s.Read1Byte();
                textAlignment = s.Read1Byte();

                flags = s.ReadUInt16();

                italicsRatio = s.ReadSingle();

                textOffset = s.ReadUInt32();

                textColors = new Color[2];

                textColors[0] = ColorHelper.BytesToColor(s.ReadBytes(4)); // Color 1
                textColors[1] = ColorHelper.BytesToColor(s.ReadBytes(4)); // Color 2

                fontSize = new Vec2(s.ReadSingle(), s.ReadSingle());

                charSpace = s.ReadSingle();
                lineSpace = s.ReadSingle();

                textIDOffset = s.ReadUInt32();

                shadowOffset = new Vec2(s.ReadSingle(), s.ReadSingle());
                shadowScale  = new Vec2(s.ReadSingle(), s.ReadSingle());

                shadowColors = new Color[2];

                shadowColors[0] = ColorHelper.BytesToColor(s.ReadBytes(4)); // Color 1
                shadowColors[1] = ColorHelper.BytesToColor(s.ReadBytes(4)); // Color 2

                shadowItalicsRatio = s.ReadSingle();

                lineWidthOffsetOffset = s.ReadUInt32();

                perCharacterTransformOffset = s.ReadUInt32();

                text = Encoding.ASCII.GetString(s.ReadBytes(stringByteCount)).Replace("\0", "");

                if (textIDOffset != 0)
                {
                    s.BaseStream.Position = startPos + textIDOffset;
                    textID = (int)s.ReadUInt32();
                }

                s.Align(4); // Align everything

                // Do character transforms later
            }
예제 #7
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
                    public ProjectionTexGenParameters(ref BinaryStream s)
                    {
                        transX = s.ReadSingle();
                        transY = s.ReadSingle();
                        scaleX = s.ReadSingle();
                        scaleY = s.ReadSingle();

                        flag = s.Read1Byte();

                        s.Align(4); // Padding
                    }
예제 #8
0
        public static void AlignWithValue(this BinaryStream bs, int alignment, byte value, bool grow = false)
        {
            long basePos = bs.Position;
            long newPos  = bs.Align(alignment);

            bs.Position = basePos;
            for (long i = basePos; i < newPos; i++)
            {
                bs.WriteByte(value);
            }
        }
예제 #9
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
                    public void Write(ref BinaryStream s)
                    {
                        s.WriteByte((byte)genType);
                        s.WriteByte((byte)genSource);

                        s.Align(4); // Padding

                        s.WriteSingle(translate);
                        s.WriteSingle(scale);
                        s.WriteByte(flag);

                        s.Write(new byte[] { 0x00, 0x00, 0x00 }); // Reserved
                    }
        public static void AlignWithValue(this BinaryStream bs, int alignment, byte val)
        {
            long pos = bs.Position;

            bs.Align(alignment, true);
            long endPos = bs.Position;

            bs.Position = pos;
            for (int i = 0; i < endPos - pos; i++)
            {
                bs.WriteByte(val);
            }
        }
예제 #11
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
            public LayoutSettings(ref BinaryStream s)
            {
                SectionHeader section = new SectionHeader(ref s);

                s.Read1Byte();

                s.ReadBytes(3); // Padding

                screenWidth    = s.ReadSingle();
                screenHeight   = s.ReadSingle();
                maxPartsWidth  = s.ReadSingle();
                maxPartsHeight = s.ReadSingle();

                name = s.ReadString(StringCoding.ZeroTerminated);

                s.Align(4); // Padding
            }
예제 #12
0
        private List <dynamic> ReadArrayNode(BinaryStream _binaryStream, int length)
        {
            List <dynamic> array = new List <dynamic>(length);

            if (_fastLoad)
            {
                _alreadyReadNodes.Add((uint)_binaryStream.Position - 4, array);
            }

            // Read the element types of the array.
            byte[] nodeTypes = _binaryStream.ReadBytes(length);
            // Read the elements, which begin after a padding to the next 4 bytes.
            _binaryStream.Align(4);
            for (int i = 0; i < length; i++)
            {
                array.Add(ReadNode(_binaryStream, (ByamlNodeType)nodeTypes[i]));
            }

            return(array);
        }
예제 #13
0
        public static Tuple <int, byte[]> PackN(SarcData data, int _align = -1)
        {
            int align = _align >= 0 ? _align : (int)GuessAlignment(data.Files);

            MemoryStream o  = new MemoryStream();
            BinaryStream bs = new BinaryStream(o, ByteConverter.GetConverter(data.endianness), leaveOpen: false);

            bs.Write("SARC", StringCoding.Raw);
            bs.Write((UInt16)0x14);   // Chunk length
            bs.Write((UInt16)0xFEFF); // BOM
            bs.Write((UInt32)0x00);   //filesize update later
            bs.Write((UInt32)0x00);   //Beginning of data
            bs.Write((UInt16)0x100);
            bs.Write((UInt16)0x00);
            bs.Write("SFAT", StringCoding.Raw);
            bs.Write((UInt16)0xc);
            bs.Write((UInt16)data.Files.Keys.Count);
            bs.Write((UInt32)0x00000065);
            List <uint> offsetToUpdate = new List <uint>();

            //Sort files by hash
            string[] Keys = data.Files.Keys.OrderBy(x => data.HashOnly ? StringHashToUint(x) : NameHash(x)).ToArray();
            foreach (string k in Keys)
            {
                if (data.HashOnly)
                {
                    bs.Write(StringHashToUint(k));
                }
                else
                {
                    bs.Write(NameHash(k));
                }
                offsetToUpdate.Add((uint)bs.BaseStream.Position);
                bs.Write((UInt32)0);
                bs.Write((UInt32)0);
                bs.Write((UInt32)0);
            }
            bs.Write("SFNT", StringCoding.Raw);
            bs.Write((UInt16)0x8);
            bs.Write((UInt16)0);
            List <uint> StringOffsets = new List <uint>();

            foreach (string k in Keys)
            {
                StringOffsets.Add((uint)bs.BaseStream.Position);
                bs.Write(k, StringCoding.ZeroTerminated);
                bs.Align(4);
            }
            bs.Align(0x1000); //TODO: check if works in odyssey
            List <uint> FileOffsets = new List <uint>();

            foreach (string k in Keys)
            {
                bs.Align((int)GuessFileAlignment(data.Files[k]));
                FileOffsets.Add((uint)bs.BaseStream.Position);
                bs.Write(data.Files[k]);
            }
            for (int i = 0; i < offsetToUpdate.Count; i++)
            {
                bs.BaseStream.Position = offsetToUpdate[i];
                if (!data.HashOnly)
                {
                    bs.Write(0x01000000 | ((StringOffsets[i] - StringOffsets[0]) / 4));
                }
                else
                {
                    bs.Write((UInt32)0);
                }
                bs.Write((UInt32)(FileOffsets[i] - FileOffsets[0]));
                bs.Write((UInt32)(FileOffsets[i] + data.Files[Keys[i]].Length - FileOffsets[0]));
            }
            bs.BaseStream.Position = 0x08;
            bs.Write((uint)bs.BaseStream.Length);
            bs.Write((uint)FileOffsets[0]);

            return(new Tuple <int, byte[]>(align, o.ToArray()));
        }
예제 #14
0
        public void Save(string path)
        {
            using (var fs = new FileStream(path, FileMode.Create))
                using (var bs = new BinaryStream(fs, ByteConverter.Big))
                {
                    bs.WriteString(MAGIC, StringCoding.Raw);
                    bs.Position += 4;
                    bs.Position += 4; // Skip prefixes offset for now
                    bs.WriteInt32(NameTrees.Count);

                    bs.Position += NameTrees.Count * sizeof(uint);
                    bs.AlignWithValue(0x10, 0x5E);

                    long lastPos = bs.Position;
                    for (int i = 0; i < NameTrees.Count; i++)
                    {
                        var currentTree = NameTrees[i];
                        bs.Position = lastPos;
                        int baseTreePos = (int)bs.Position;
                        // For now skip everything and go to the string tables
                        bs.Position += 0x10;
                        bs.Position += 0x10 * currentTree.Entries.Count;

                        OptimizedStringTable opt = NameTrees[i].GetStringTable();
                        opt.SaveStream(bs);
                        bs.AlignWithValue(0x10, 0x5E);

                        lastPos = bs.Position;

                        // Write where the tree is located
                        bs.Position = 0x10 + (i * sizeof(uint));
                        bs.WriteInt32(baseTreePos);

                        // Write its data
                        bs.Position = baseTreePos;
                        bs.WriteInt32(100);
                        bs.WriteInt32(currentTree.Entries.Count);
                        bs.AlignWithValue(0x10, 0x5E);
                        for (int j = 0; j < currentTree.Entries.Count; j++)
                        {
                            var entry = currentTree.Entries[j];
                            bs.WriteUInt32(entry.SpecDBID);
                            bs.WriteUInt32(entry.AlphabeticalID);
                            bs.WriteInt32(opt.GetStringOffset(entry.FullName));
                            bs.WriteBytes(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF });
                        }
                    }

                    // Write the prefix tree
                    bs.Position = lastPos;
                    bs.WriteInt32(Prefixes.Count); // 4 byte header

                    // Skip entries
                    bs.Position += Prefixes.Count * sizeof(uint);
                    OptimizedStringTable prefixST = GetPrefixStringTable();
                    prefixST.SaveStream(bs);
                    bs.Align(0x10, true);

                    // String table
                    bs.Position = lastPos + 4;
                    foreach (var prefix in Prefixes)
                    {
                        bs.WriteInt32(prefixST.GetStringOffset(prefix.Name));
                    }

                    // Write prefix tree offset
                    bs.Position = 0x08;
                    bs.WriteInt32((int)lastPos);
                }
        }
예제 #15
0
        protected void WriteContent(object rootReferenceKey)
        {
            using (_binaryStream)
            {
                // Write the header, specifying magic bytes, version and main node offsets.
                _binaryStream.Write(BYAML_MAGIC);
                _binaryStream.Write(_version);
                Offset nameArrayOffset   = _binaryStream.ReserveOffset();
                Offset stringArrayOffset = _binaryStream.ReserveOffset();
                Offset pathArrayOffset   = _supportPaths ? _binaryStream.ReserveOffset() : null;
                Offset rootOffset        = _binaryStream.ReserveOffset();

                // Write the main nodes.
                _binaryStream.Align(4);
                nameArrayOffset.Satisfy();
                WriteStringArrayNode(_binaryStream, _nameArray);
                if (_stringArray.Length == 0)
                {
                    stringArrayOffset.Satisfy(0);
                }
                else
                {
                    _binaryStream.Align(4);
                    stringArrayOffset.Satisfy();
                    WriteStringArrayNode(_binaryStream, _stringArray);
                }

                // Include a path array offset if requested.
                if (_supportPaths)
                {
                    if (_pathArray.Count == 0)
                    {
                        pathArrayOffset.Satisfy(0);
                    }
                    else
                    {
                        _binaryStream.Align(4);
                        pathArrayOffset.Satisfy();
                        WritePathArrayNode(_binaryStream, _pathArray);
                    }
                }

                _binaryStream.Align(4);

                //write value stack (Dictionary, Array, long, uint, double)
                uint valStackPos = (uint)_binaryStream.Position;

                //write all dictionaries
                foreach (KeyValuePair <object, ByamlDict> keyValuePair in _dictionaries)
                {
                    _binaryStream.Seek(valStackPos + keyValuePair.Value.offset, SeekOrigin.Begin);

                    if (keyValuePair.Key == rootReferenceKey)
                    {
                        rootOffset.Satisfy();
                    }

                    if (_byteOrder == Endian.Big)
                    {
                        _binaryStream.Write((uint)ByamlNodeType.Dictionary << 24 | (uint)keyValuePair.Value.entries.Length);
                    }
                    else
                    {
                        _binaryStream.Write((uint)ByamlNodeType.Dictionary | (uint)keyValuePair.Value.entries.Length << 8);
                    }

                    foreach ((string key, Entry entry) in keyValuePair.Value.entries)
                    {
                        if (_byteOrder == Endian.Big)
                        {
                            _binaryStream.Write(Array.IndexOf(_nameArray, key) << 8 | (byte)entry.type);
                        }
                        else
                        {
                            _binaryStream.Write(Array.IndexOf(_nameArray, key) | (byte)entry.type << 24);
                        }

                        WriteValue(entry);
                    }
                }

                //write all arrays
                foreach (KeyValuePair <object, ByamlArr> keyValuePair in _arrays)
                {
                    _binaryStream.Seek(valStackPos + keyValuePair.Value.offset, SeekOrigin.Begin);

                    if (keyValuePair.Key == rootReferenceKey)
                    {
                        rootOffset.Satisfy();
                    }

                    if (_byteOrder == Endian.Big)
                    {
                        _binaryStream.Write((uint)ByamlNodeType.Array << 24 | (uint)keyValuePair.Value.entries.Length);
                    }
                    else
                    {
                        _binaryStream.Write((uint)ByamlNodeType.Array | (uint)keyValuePair.Value.entries.Length << 8);
                    }


                    foreach (Entry entry in keyValuePair.Value.entries)
                    {
                        _binaryStream.Write((byte)entry.type);
                    }

                    _binaryStream.Align(4);

                    foreach (Entry entry in keyValuePair.Value.entries)
                    {
                        WriteValue(entry);
                    }
                }

                //write all 8 byte values
                foreach (var keyValuePair in _eightByteValues)
                {
                    _binaryStream.Seek(valStackPos + keyValuePair.Value, SeekOrigin.Begin);
                    _binaryStream.Write(keyValuePair.Key);
                }

                void WriteValue(Entry entry)
                {
                    // Only write the offset for the complex value contents, write simple values directly.
                    switch (entry.type)
                    {
                    case ByamlNodeType.StringIndex:
                        _binaryStream.Write((uint)Array.IndexOf(_stringArray, entry.value));
                        break;

                    case ByamlNodeType.PathIndex:
                        _binaryStream.Write(_pathArray.IndexOf(entry.value));
                        break;

                    case ByamlNodeType.Dictionary:
                        _binaryStream.Write(valStackPos + _dictionaries[(object)entry.value].offset);
                        break;

                    case ByamlNodeType.Array:
                        _binaryStream.Write(valStackPos + _arrays[(object)entry.value].offset);
                        break;

                    case ByamlNodeType.Boolean:
                        _binaryStream.Write(entry.value ? 1 : 0);
                        break;

                    case ByamlNodeType.Integer:
                    case ByamlNodeType.Float:
                    case ByamlNodeType.UInteger:
                        _binaryStream.Write(entry.value);
                        break;

                    case ByamlNodeType.Double:
                    case ByamlNodeType.ULong:
                    case ByamlNodeType.Long:
                        _binaryStream.Write(valStackPos + _eightByteValues[entry.value]);
                        return;

                    case ByamlNodeType.Null:
                        _binaryStream.Write(0);
                        break;
                    }
                }
            }
        }
예제 #16
0
파일: BFLYT.cs 프로젝트: xnqdev/Lyzon
            public Window(ref BinaryStream s) : base(ref s)
            {
                int startPos = (int)s.BaseStream.Position - 84;

                inflation = new WindowInflation();

                inflation.left   = s.ReadUInt16();
                inflation.right  = s.ReadUInt16();
                inflation.top    = s.ReadUInt16();
                inflation.bottom = s.ReadUInt16();

                frameSize = new WindowFrameSize();

                frameSize.left   = s.ReadUInt16();
                frameSize.right  = s.ReadUInt16();
                frameSize.top    = s.ReadUInt16();
                frameSize.bottom = s.ReadUInt16();

                frameCount  = s.Read1Byte();
                windowFlags = s.Read1Byte();

                s.Align(4); // Padding

                contentOffset          = s.ReadUInt32();
                frameOffsetTableOffset = s.ReadUInt32();

                s.BaseStream.Position = startPos + contentOffset;

                content = new WindowContent();

                content.vertexColors = new Color[4];

                content.vertexColors[0] = ColorHelper.BytesToColor(s.ReadBytes(4)); // TL
                content.vertexColors[1] = ColorHelper.BytesToColor(s.ReadBytes(4)); // TR
                content.vertexColors[2] = ColorHelper.BytesToColor(s.ReadBytes(4)); // BL
                content.vertexColors[3] = ColorHelper.BytesToColor(s.ReadBytes(4)); // BR

                content.materialIndex = s.ReadUInt16();
                content.texCoordCount = s.Read1Byte();

                s.Align(4); // Padding

                content.texCoords = new TexCoord[content.texCoordCount];

                for (int i = 0; i < content.texCoordCount; i++)
                {
                    content.texCoords[i] = new TexCoord(
                        new Vec2(s.ReadSingle(), s.ReadSingle()), // TL
                        new Vec2(s.ReadSingle(), s.ReadSingle()), // TR
                        new Vec2(s.ReadSingle(), s.ReadSingle()), // BL
                        new Vec2(s.ReadSingle(), s.ReadSingle())  // BR
                        );
                }

                s.BaseStream.Position = startPos + frameOffsetTableOffset;

                frameOffsetTable = new uint[frameCount];

                for (int i = 0; i < frameCount; i++)
                {
                    frameOffsetTable[i] = s.ReadUInt32();
                }

                frames = new WindowFrame[frameCount];

                for (int i = 0; i < frameCount; i++)
                {
                    s.BaseStream.Position = startPos + frameOffsetTable[i];

                    WindowFrame frame = new WindowFrame();

                    frame.materialIndex = s.ReadUInt16();
                    frame.textureFlip   = s.Read1Byte();

                    s.Align(4); // Padding

                    frames[i] = frame;
                }
            }
예제 #17
0
        public void Save(string path)
        {
            using (var fs = new FileStream(path, FileMode.Create))
                using (var br = new BinaryStream(fs))
                {
                    br.WriteString(BGML.MAGIC, StringCoding.Raw);
                    br.Position += 4;
                    br.Position += 4; // Write File Size Later
                    br.Position += 4;
                    br.WriteInt32(Tracks.Count);
                    br.WriteInt32(0x30); // We know its always at 0x30.. so just write anyway
                    br.WriteInt32(Playlists.Count);
                    br.Position += 4;    // Offset write later

                    br.Position = 0x30;

                    // Step 1: Skip all way to the string table location so we can have proper string offsets

                    // - Move to the Playlist Tree for now
                    br.Position += 0x30 * Tracks.Count;

                    // - Go to the end of the Playlist Tree
                    br.Position += Playlists.Count * sizeof(uint);

                    // - Playlist Tree is aligned
                    br.Align(0x10, true);


                    int[] playlistDataOffsets = new int[Playlists.Count]; // Will be used later on to write the tree
                    // - Write Playlist Data along the way
                    for (int i = 0; i < Playlists.Count; i++)
                    {
                        playlistDataOffsets[i] = (int)br.Position;
                        br.Position           += 0x10; // We're skipping the first int which is the string offset
                        br.WriteInt32(Playlists[i].TrackIndexes.Count);
                        foreach (var index in Playlists[i].TrackIndexes)
                        {
                            br.WriteInt32(index);
                        }
                        br.Align(0x10, true);
                    }

                    // Step 2: We reached the string table location, write the string tables
                    OptimizedStringTable trackStringTable = SerializeTrackStringTable();
                    trackStringTable.SaveStream(br);

                    OptimizedStringTable playlistStringTable = SerializePlaylistStringTable();
                    playlistStringTable.SaveStream(br);

                    // Step 3: Populate the trees that reference the string tables
                    for (int i = 0; i < Tracks.Count; i++)
                    {
                        br.Position = 0x30 + (i * 0x30);
                        br.WriteInt32(trackStringTable.GetStringOffset(Tracks[i].Label));
                        br.WriteInt32((int)Tracks[i].Format);
                        br.WriteInt32(trackStringTable.GetStringOffset(Tracks[i].FileName));
                        br.Position += 8;
                        br.WriteInt32(trackStringTable.GetStringOffset(Tracks[i].TrackName));
                        br.WriteInt32(trackStringTable.GetStringOffset(Tracks[i].Artist));
                        br.WriteInt32(trackStringTable.GetStringOffset(Tracks[i].Genre));
                        br.Position += 0x10;
                    }

                    // Write the playlist data pointers
                    int playlistTreeOffset = (int)br.Position;
                    for (int i = 0; i < playlistDataOffsets.Length; i++)
                    {
                        br.WriteInt32(playlistDataOffsets[i]);
                    }
                    br.Align(0x10, true);

                    // Write Playlist Label offsets
                    for (int i = 0; i < Playlists.Count; i++)
                    {
                        br.Position = playlistDataOffsets[i]; // Using shortcut by using the precalculated offsets from earlier
                        br.WriteInt32(playlistStringTable.GetStringOffset(Playlists[i].Name));
                    }

                    // Finish up the header
                    br.Position = 0x08;
                    br.WriteInt32((int)br.Length); // File Size
                    br.Position = 0x1C;
                    br.WriteInt32(playlistTreeOffset);
                }
        }