Esempio n. 1
0
 private void writeString(String str)
 {
     baos.Write(str.ToByteArray());
     baos.Write(new byte[] { 0 }); //NULL
 }
        public static byte[] Compress(ByteArrayStream target)
        {
            var commands = new List <byte>();
            var data     = new List <byte>();
            var copyData = 0;

            while (!target.AtEnd)
            {
                var term       = target.GetBytes(0x11);
                var copyOutput = 0;
                var copyOffset = -1;

                while (term.Length >= 3)
                {
                    var(found, address) = target.FindLastInWindow(term, target.Address - 256, target.Address + term.Length - 1);

                    if (found)
                    {
                        copyOutput = term.Length - 2;
                        copyOffset = target.Address - address - 1;
                        break;
                    }

                    term = target.GetBytes(term.Length - 1);
                }

                if (copyOutput == 0)
                {
                    if (copyData == 0xf)
                    {
                        commands.Add((byte)copyData);
                        copyData = 1;
                    }
                    else
                    {
                        copyData++;
                    }
                    data.Add(target.Byte());
                }
                else
                {
                    commands.Add((byte)((copyOutput << 4) + copyData));
                    commands.Add((byte)copyOffset);
                    copyData        = 0;
                    target.Address += term.Length;
                }
            }

            // Add last copy data command
            if (copyData != 0)
            {
                commands.Add((byte)copyData);
            }

            // Add terminating command
            commands.Add(0);

            var output = new ByteArrayStream(commands.Count + data.Count + 2);

            var dataOffset = commands.Count;

            if (dataOffset > 0xffff)
            {
                throw new Exception($"{nameof(dataOffset)} cannot be larger than 0xffff. {nameof(commands)} is too large");
            }

            output.Word((ushort)dataOffset);
            output.Write(commands);
            output.Write(data);

            return(output.Buffer);
        }
Esempio n. 3
0
        public bool Save(string filename, PlayerData playerData)
        {
            ByteArrayStream stream = new ByteArrayStream();

            stream.WriteString("PTFF", 4);

            byte version = playerData.Version;

            stream.WriteByte(version);

            stream.WriteByte(0); // ??

            stream.WriteUShort(playerData.TickPerMinute);
            stream.WriteFloat(playerData.Tempo);

            UInt16 trackCount = playerData.Tracks.Count;

            stream.WriteUShort(trackCount);
            stream.writeUInt(playerData.HeaderEndTick);
            stream.WriteFloat(playerData.TrackDuration);

            ushort insCount = (ushort)(playerData.Instruments.Count - 1);

            stream.WriteUShort(insCount);

            for (int i = 0, l = playerData.Instruments.Count; i < l; i++)
            {
                InstrumentData ins = playerData.Instruments[i];
                if (ins != null && ins.InsNum != 0)
                {
                    if (version == 1)
                    {
                        stream.WriteUShort(ins.InsNum);
                        stream.WriteUShort(0);
                    }
                    else
                    {
                        stream.WriteByte((byte)ins.InsNum);
                        stream.WriteByte(0);
                    }

                    stream.WriteString(ins.Name, 0x40);
                }
            }

            int eventSize = version == 1 ? 0x10 : 0x0B;

            foreach (TrackData track in playerData.Tracks)
            {
                stream.writeUInt(EZTR);

                int eventsCount = track.Events.Count();
                int endTick     = 0;
                if (eventsCount > 0)
                {
                    endTick = track.Events.Max(evnt => evnt.Tick);
                }

                uint blockSize = (uint)(eventsCount * eventSize);

                stream.WriteString("", 0x02); // unknown

                stream.WriteString(track.TrackName, 0x40);

                stream.writeInt(endTick);
                stream.writeUInt(blockSize);

                if (version == 1)
                {
                    stream.WriteUShort(0); // Unknown
                }

                foreach (EventData evnt in track.Events)
                {
                    stream.writeInt(evnt.Tick);
                    stream.WriteByte((byte)evnt.EventType);

                    switch (evnt.EventType)
                    {
                    case EventType.Volume:
                    {
                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }

                        stream.WriteByte(evnt.Volume);
                        stream.WriteByte(0);

                        stream.WriteByte(0);
                        stream.WriteByte(0);

                        stream.WriteByte(0);
                        stream.WriteByte(0);

                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }
                    }
                    break;

                    case EventType.Note:
                    {
                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }

                        ushort insno = 0;

                        if (evnt.Instrument != null)
                        {
                            insno = evnt.Instrument.InsNum;
                        }

                        if (version == 1)
                        {
                            stream.WriteUShort(insno);
                        }
                        else
                        {
                            stream.WriteByte((byte)insno);
                        }

                        stream.WriteByte(evnt.Vel);
                        stream.WriteByte(evnt.Pan);

                        stream.WriteByte(evnt.Attribute);
                        stream.WriteUShort(evnt.Duration);

                        if (version == 1)
                        {
                            stream.WriteByte(0);
                        }
                    }
                    break;

                    case EventType.Tempo:

                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }

                        stream.Write(BitConverter.GetBytes(evnt.Tempo));

                        stream.WriteByte(0);
                        stream.WriteByte(0);

                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }

                        break;

                    case EventType.Beat:

                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }

                        stream.WriteUShort(evnt.Beat);

                        stream.WriteByte(0);
                        stream.WriteByte(0);

                        stream.WriteByte(0);
                        stream.WriteByte(0);

                        if (version == 1)
                        {
                            stream.WriteByte(0);
                            stream.WriteByte(0);
                        }

                        break;

                    default:
                    {
                    }
                    break;
                    }
                }
            }

            byte[] ptffData = stream.GetData();

            int sizeIn = ptffData.Count();

            if (m_settingsDialog.EncryptFile /*playerData.Encrypted*/)
            {
                ptffData = EncryptDataOnline(ptffData);
                if (ptffData == null || sizeIn != ptffData.Count())
                {
                    return(false);
                }
            }

            File.WriteAllBytes(filename, ptffData);

            return(true);
        }