예제 #1
0
        public virtual void Save(Stream fs)
        {
            var writer = new BinaryWriter(fs, Encoding.UTF8);

            writer.Write(Signature | (Version << 24));

            // Tiles
            int i, count = Tiles.Count; // Two generic ints we reuse

            writer.Write(count);

            for (i = 0; i < count; ++i)
            {
                Tiles[i].Write(writer);
            }

            // Blocks
            count = Blocks.Count;
            writer.Write(count);

            for (i = 0; i < count; ++i)
            {
                Blocks[i].Write(writer);
            }

            // Layers
            uint i2, i3;

            writer.Write(RowCount);
            writer.Write(ColumnCount);

            WriteLayer(background);
            WriteLayer(foreground);

            // Sub-Methods
            void WriteLayer(byte[,] layer)
            {
                // We're going to write a byte array called presentRows, with each bit
                // representing whether the corresponding layer is present in the file.
                long pos = fs.Position;
                byte presentRowsBitIndex = 0;

                i = 0;

                uint presentRowsLen = Bitwise.GetRequiredBytes(RowCount);
                var  presentRows    = new byte[presentRowsLen];

                writer.Write(presentRows);

                for (i2 = 0; i2 < RowCount; ++i2)
                {
                    // Do a very basic cutoff check to avoid writing tons of nulls
                    uint columnCount = 0;
                    for (i3 = 0; i3 < ColumnCount; ++i3)
                    {
                        if (layer[i2, i3] != 0)
                        {
                            columnCount = i3 + 1;
                        }
                    }

                    if (columnCount != 0)
                    {
                        // Set the appropriate bit stating this row is present
                        presentRows[i] |= (byte)(0x80 >> presentRowsBitIndex);

                        // Write the block indices that make up the column
                        writer.Write(columnCount);
                        for (i3 = 0; i3 < columnCount; ++i3)
                        {
                            writer.Write(layer[i2, i3]);
                        }
                    }

                    if (++presentRowsBitIndex > 7)
                    {
                        presentRowsBitIndex = 0;
                        ++i;
                    }
                }

                // Write presentRows
                long pos2 = fs.Position;

                fs.Position = pos;
                writer.Write(presentRows);
                fs.Position = pos2;
            }
        }
예제 #2
0
        public virtual void Load(Stream fs)
        {
            var  reader = new BinaryReader(fs, Encoding.UTF8);
            uint sig    = reader.ReadUInt32();
            byte ver    = (byte)((sig & 0xFF000000) >> 24);

            sig &= 0xFFFFFF;

            if (sig != Signature)
            {
                throw new InvalidDataException(
                          "The given file is not a valid SoniC# stage!");
            }

            if (ver > Version)
            {
                throw new NotImplementedException(
                          $"The given SoniC# stage is of an unsupported version (v{ver})!");
            }

            // Tiles
            int i, count; // Two generic ints we reuse

            count = reader.ReadInt32();
            Tiles.Clear();

            for (i = 0; i < count; ++i)
            {
                Tiles.Add(new Tile(i, TileMap, reader));
            }

            // Blocks
            count = reader.ReadInt32();
            Blocks.Clear();

            for (i = 0; i < count; ++i)
            {
                Blocks.Add(new Block(reader));
            }

            // Layers
            uint i2, i3;
            uint rowCount    = reader.ReadUInt32();
            uint columnCount = reader.ReadUInt32();

            if (rowCount != RowCount || columnCount != ColumnCount)
            {
                background = new byte[rowCount, columnCount];
                foreground = new byte[rowCount, columnCount];
            }

            ReadLayer(background);
            ReadLayer(foreground);

            // Sub-Methods
            void ReadLayer(byte[,] layer)
            {
                // Read the list of rows present in the file
                uint presentRowsLen      = Bitwise.GetRequiredBytes(rowCount);
                var  presentRows         = reader.ReadBytes((int)presentRowsLen);
                byte presentRowsBitIndex = 0;

                i = 0;

                // Read each row
                for (i2 = 0; i2 < rowCount; ++i2)
                {
                    // Read each column if the row it belongs to is present in the file
                    if ((presentRows[i] & (0x80 >> presentRowsBitIndex)) != 0)
                    {
                        columnCount = reader.ReadUInt32();
                        for (i3 = 0; i3 < columnCount; ++i3)
                        {
                            layer[i2, i3] = reader.ReadByte();
                        }
                    }

                    if (++presentRowsBitIndex > 7)
                    {
                        presentRowsBitIndex = 0;
                        ++i;
                    }
                }
            }
        }