Example #1
0
        public static VAB Join(VH vh, SampleLine[] vb)
        {
            if (vh == null)
            {
                throw new ArgumentNullException("vh");
            }
            if (vb == null)
            {
                throw new ArgumentNullException("vb");
            }
            if (vh.VBSize != vb.Length)
            {
                ErrorManager.SignalIgnorableError("VAB: VB size field mismatch");
            }
            SampleSet[] waves  = new SampleSet [vh.Waves.Count];
            int         offset = 0;

            for (int i = 0; i < vh.Waves.Count; i++)
            {
                int wavelength = vh.Waves[i];
                if (offset + wavelength > vb.Length)
                {
                    ErrorManager.SignalError("VAB: Wave ends out of bounds");
                }
                SampleLine[] wavelines = new SampleLine[wavelength];
                for (int j = 0; j < wavelength; j++)
                {
                    wavelines[j] = vb[offset + j];
                }
                offset  += wavelength;
                waves[i] = new SampleSet(wavelines);
            }
            return(new VAB(vh.IsOldVersion, vh.Volume, vh.Panning, vh.Attribute1, vh.Attribute2, vh.Programs, waves));
        }
Example #2
0
        public override Entry Load(byte[][] items, int eid)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }
            if (items.Length != 2)
            {
                ErrorManager.SignalError("WavebankEntry: Wrong number of items");
            }
            if (items[0].Length != 8)
            {
                ErrorManager.SignalError("WavebankEntry: First item length is wrong");
            }
            int id     = BitConv.FromInt32(items[0], 0);
            int length = BitConv.FromInt32(items[0], 4);

            if (id < 0 || id > 6)
            {
                ErrorManager.SignalIgnorableError("WavebankEntry: ID is invalid");
            }
            if (length != items[1].Length)
            {
                ErrorManager.SignalIgnorableError("WavebankEntry: Length field mismatch");
            }
            return(new WavebankEntry(id, SampleSet.Load(items[1]), eid));
        }
Example #3
0
        public static T4Item Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < 4)
            {
                ErrorManager.SignalError("T4Item: Data is too short");
            }
            short count    = BitConv.FromInt16(data, 0);
            short unknown1 = BitConv.FromInt16(data, 2);

            if (count < 0)
            {
                ErrorManager.SignalError("T4Item: Value count is negative");
            }
            if (data.Length < 4 + 2 * count)
            {
                ErrorManager.SignalError("T4Item: Data is too short");
            }
            short[] values = new short [count];
            for (int i = 0; i < count; i++)
            {
                values[i] = BitConv.FromInt16(data, 4 + i * 2);
            }
            return(new T4Item(unknown1, values));
        }
Example #4
0
        public override Entry Load(byte[][] items, int eid)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }
            if (items.Length != 2)
            {
                ErrorManager.SignalError("OldModelEntry: Wrong number of items");
            }
            int polygoncount = BitConv.FromInt32(items[0], 0);

            if (items[1].Length != polygoncount * 8)
            {
                ErrorManager.SignalError("OldModelEntry: Polygon count mismatch");
            }
            OldModelPolygon[] polygons = new OldModelPolygon [polygoncount];
            for (int i = 0; i < polygoncount; i++)
            {
                byte[] polygondata = new byte [8];
                Array.Copy(items[1], i * 8, polygondata, 0, polygondata.Length);
                polygons[i] = OldModelPolygon.Load(polygondata);
            }
            return(new OldModelEntry(items[0], polygons, eid));
        }
Example #5
0
        public static SEQ Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            // All SEP/SEQ stuff is big-endian, like MIDI
            if (data.Length < 15)
            {
                ErrorManager.SignalError("SEQ: Data is too short");
            }
            int magic   = BEBitConv.FromInt32(data, 0);
            int version = BEBitConv.FromInt32(data, 4);

            if (magic != Magic)
            {
                ErrorManager.SignalIgnorableError("SEQ: Magic number is wrong");
            }
            if (version != Version)
            {
                ErrorManager.SignalIgnorableError("SEQ: Version number is wrong");
            }
            short resolution = BEBitConv.FromInt16(data, 8);
            int   tempo      = MIDIConv.From3BE(data, 10);
            short rhythm     = BEBitConv.FromInt16(data, 13);

            byte[] scoredata = new byte [data.Length - 15];
            Array.Copy(data, 15, scoredata, 0, scoredata.Length);
            return(new SEQ(resolution, tempo, rhythm, scoredata));
        }
Example #6
0
 public override Entry Load(byte[][] items, int eid)
 {
     if (items.Length != 1)
     {
         ErrorManager.SignalError("DemoEntry: Wrong number of items");
     }
     return(new DemoEntry(items[0], eid));
 }
Example #7
0
 internal override void LoadToField(object obj, FieldInfo field)
 {
     if (field.FieldType == typeof(T?))
     {
         if (rows.Count == 1)
         {
             if (rows[0].MetaValue == null)
             {
                 if (rows[0].Values.Count == 1)
                 {
                     field.SetValue(obj, rows[0].Values[0]);
                 }
                 else
                 {
                     ErrorManager.SignalError("EntityProperty: Property has more values than expected");
                 }
             }
             else
             {
                 ErrorManager.SignalError("EntityProperty: Property has an unexpected metavalue");
             }
         }
         else
         {
             ErrorManager.SignalError("EntityProperty: Property has more rows than expected");
         }
     }
     else if (field.FieldType == typeof(List <T>))
     {
         if (rows.Count == 1)
         {
             if (rows[0].MetaValue == null)
             {
                 List <T> list = new List <T>();
                 list.AddRange(rows[0].Values);
                 field.SetValue(obj, list);
             }
             else
             {
                 ErrorManager.SignalError("EntityProperty: Property has an unexpected metavalue");
             }
         }
         else
         {
             ErrorManager.SignalError("EntityProperty: Property has more rows than expected");
         }
     }
     else if (field.FieldType == GetType())
     {
         field.SetValue(obj, this);
     }
     else
     {
         base.LoadToField(obj, field);
     }
 }
Example #8
0
        public sealed override Chunk Load(int chunkid, byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length != Chunk.Length)
            {
                throw new ArgumentException("Data must be 65536 bytes long.");
            }
            int id         = BitConv.FromInt32(data, 4);
            int entrycount = BitConv.FromInt32(data, 8);
            int checksum   = BitConv.FromInt32(data, 12);
            int headersize = 20 + entrycount * 4;

            if (id != chunkid)
            {
                ErrorManager.SignalIgnorableError("EntryChunk: Chunk id is incorrect");
            }
            if (entrycount < 0)
            {
                ErrorManager.SignalError("EntryChunk: Entry count is negative");
            }
            if (checksum != Chunk.CalculateChecksum(data))
            {
                ErrorManager.SignalIgnorableError("Chunk: Checksum is wrong");
            }
            if (headersize > data.Length)
            {
                ErrorManager.SignalError("EntryChunk: Data is too short");
            }
            Entry[] entries = new Entry [entrycount];
            byte[]  entrydata;
            for (int i = 0; i < entrycount; i++)
            {
                int entrystart = BitConv.FromInt32(data, 16 + i * 4);
                int entryend   = BitConv.FromInt32(data, 20 + i * 4);
                if (entrystart < 0)
                {
                    ErrorManager.SignalError("EntryChunk: Entry begins out of bounds");
                }
                if (entryend < entrystart)
                {
                    ErrorManager.SignalError("EntryChunk: Entry ends before it begins");
                }
                if (entryend > data.Length)
                {
                    ErrorManager.SignalError("EntryChunk: Entry ends out of bounds");
                }
                int entrysize = entryend - entrystart;
                entrydata = new byte [entrysize];
                Array.Copy(data, entrystart, entrydata, 0, entrysize);
                entries[i] = Entry.Load(entrydata);
            }
            return(Load(entries));
        }
Example #9
0
 public override Entry Load(byte[][] items, int eid)
 {
     if (items == null)
     {
         throw new ArgumentNullException("items");
     }
     if (items.Length != 1)
     {
         ErrorManager.SignalError("SoundEntry: Wrong number of items");
     }
     return(new SoundEntry(SampleSet.Load(items[0]), eid));
 }
Example #10
0
 public Chunk Process(int chunkid)
 {
     if (loaders.ContainsKey(Type))
     {
         return(loaders[Type].Load(chunkid, data));
     }
     else
     {
         ErrorManager.SignalError("UnprocessedChunk: Unknown chunk type");
         return(null);
     }
 }
Example #11
0
        public static UnprocessedEntry Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < 16)
            {
                ErrorManager.SignalError("Entry: Data is too short");
            }
            int magic     = BitConv.FromInt32(data, 0);
            int eid       = BitConv.FromInt32(data, 4);
            int type      = BitConv.FromInt32(data, 8);
            int itemcount = BitConv.FromInt32(data, 12);

            if (magic != Magic)
            {
                ErrorManager.SignalIgnorableError("Entry: Magic number is wrong");
            }
            if (itemcount < 0)
            {
                ErrorManager.SignalError("Entry: Item count is negative");
            }
            if (data.Length < 20 + itemcount * 4)
            {
                ErrorManager.SignalError("Entry: Data is too short");
            }
            byte[][] items = new byte [itemcount][];
            byte[]   itemdata;
            for (int i = 0; i < itemcount; i++)
            {
                int itemstart = BitConv.FromInt32(data, 16 + i * 4);
                int itemend   = BitConv.FromInt32(data, 20 + i * 4);
                if (itemstart < 0)
                {
                    ErrorManager.SignalError("Entry: Item begins out of bounds");
                }
                if (itemend < itemstart)
                {
                    ErrorManager.SignalError("Entry: Item ends before it begins");
                }
                if (itemend > data.Length)
                {
                    ErrorManager.SignalError("Entry: Item ends out of bounds");
                }
                int itemsize = itemend - itemstart;
                itemdata = new byte [itemsize];
                Array.Copy(data, itemstart, itemdata, 0, itemsize);
                items[i] = itemdata;
            }
            return(new UnprocessedEntry(items, eid, type));
        }
Example #12
0
        public Entry Process(GameVersion gameversion)
        {
            Dictionary <int, EntryLoader> loaders = GetLoaders(gameversion);

            if (loaders.ContainsKey(type))
            {
                return(loaders[type].Load(((List <byte[]>)Items).ToArray(), EID));
            }
            else
            {
                ErrorManager.SignalError("UnprocessedEntry: Unknown entry type");
                return(null);
            }
        }
Example #13
0
 internal override void LoadToField(object obj, FieldInfo field)
 {
     if (field.FieldType == typeof(EntityID?))
     {
         if (Rows.Count == 1)
         {
             if (Rows[0].MetaValue == null)
             {
                 if (Rows[0].Values.Count == 1)
                 {
                     field.SetValue(obj, new EntityID(Rows[0].Values[0]));
                 }
                 else
                 {
                     ErrorManager.SignalError("EntityProperty: Property has more values than expected");
                 }
             }
             else
             {
                 ErrorManager.SignalError("EntityProperty: Property has an unexpected metavalue");
             }
         }
         else if (Rows.Count == 2)
         {
             if (Rows[0].MetaValue == null && Rows[1].MetaValue == null)
             {
                 if (Rows[0].Values.Count == 1 && Rows[1].Values.Count == 1)
                 {
                     field.SetValue(obj, new EntityID(Rows[0].Values[0], Rows[1].Values[0]));
                 }
                 else
                 {
                     ErrorManager.SignalError("EntityProperty: Property has more values than expected");
                 }
             }
             else
             {
                 ErrorManager.SignalError("EntityProperty: Property has an unexpected metavalue");
             }
         }
         else
         {
             ErrorManager.SignalError("EntityProperty: Property has more rows than expected");
         }
     }
     else
     {
         base.LoadToField(obj, field);
     }
 }
Example #14
0
 public override Entry Load(byte[][] items, int eid)
 {
     if (items.Length < 2)
     {
         ErrorManager.SignalError("EntityEntry: Wrong number of items");
     }
     byte[]   unknown1 = items[0];
     byte[]   unknown2 = items[1];
     Entity[] entities = new Entity [items.Length - 2];
     for (int i = 2; i < items.Length; i++)
     {
         entities[i - 2] = Entity.Load(items[i]);
     }
     return(new EntityEntry(unknown1, unknown2, entities, eid));
 }
Example #15
0
        public static NSD Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < 1312)
            {
                ErrorManager.SignalError("NSD: Data is too short");
            }
            int[] unknown1 = new int [256];
            for (int i = 0; i < 256; i++)
            {
                unknown1[i] = BitConv.FromInt32(data, i * 4);
            }
            int chunkcount = BitConv.FromInt32(data, 1024);
            int entrycount = BitConv.FromInt32(data, 1028);

            int[] unknown2 = new int [70];
            for (int i = 0; i < 70; i++)
            {
                unknown2[i] = BitConv.FromInt32(data, 1032 + i * 4);
            }
            if (chunkcount < 0)
            {
                ErrorManager.SignalError("NSD: Chunk count is negative");
            }
            if (entrycount < 0)
            {
                ErrorManager.SignalError("NSD: Entry count is negative");
            }
            if (data.Length < 1312 + 8 * entrycount)
            {
                ErrorManager.SignalError("NSD: Data is too short");
            }
            NSDLink[] index = new NSDLink [entrycount];
            for (int i = 0; i < entrycount; i++)
            {
                int chunkid = BitConv.FromInt32(data, 1312 + 8 * i);
                int entryid = BitConv.FromInt32(data, 1316 + 8 * i);
                index[i] = new NSDLink(chunkid, entryid);
            }
            int extralength = data.Length - (1312 + 8 * entrycount);

            byte[] extradata = new byte [extralength];
            Array.Copy(data, 1312 + 8 * entrycount, extradata, 0, extralength);
            return(new NSD(unknown1, chunkcount, unknown2, index, extradata));
        }
Example #16
0
 public override Entry Load(byte[][] items, int eid)
 {
     if (items == null)
     {
         throw new ArgumentNullException("items");
     }
     if (items.Length != 3 && items.Length != 5 && items.Length != 6)
     {
         ErrorManager.SignalError("T11Entry: Wrong number of items");
     }
     if (items[0].Length != 24)
     {
         ErrorManager.SignalError("T11Entry: First item length is wrong");
     }
     return(new T11Entry(items, eid));
 }
Example #17
0
        public static VHProgram Load(byte[] data, byte[] tonedata, bool isoldversion)
        {
            if (data.Length != 16)
            {
                throw new ArgumentException("Value must be 16 bytes long.", "data");
            }
            if (tonedata.Length != 32 * 16)
            {
                throw new ArgumentException("Value must be 512 bytes long.", "tonedata");
            }
            byte  tonecount = data[0];
            byte  volume    = data[1];
            byte  priority  = data[2];
            byte  mode      = data[3];
            byte  panning   = data[4];
            byte  reserved1 = data[5];
            short attribute = BitConv.FromInt16(data, 6);
            int   reserved2 = BitConv.FromInt32(data, 8);
            int   reserved3 = BitConv.FromInt32(data, 12);

            if (tonecount < 0 || tonecount > 16)
            {
                ErrorManager.SignalError("VHProgram: Tone count is wrong");
            }
            if (reserved1 != (isoldversion ? 0x00 : 0xFF))
            {
                ErrorManager.SignalIgnorableError("VHProgram: Reserved value 1 is wrong");
            }
            if (reserved2 != -1)
            {
                ErrorManager.SignalIgnorableError("VHProgram: Reserved value 2 is wrong");
            }
            if (reserved3 != -1)
            {
                ErrorManager.SignalIgnorableError("VHProgram: Reserved value 3 is wrong");
            }
            VHTone[] tones = new VHTone [tonecount];
            for (int i = 0; i < tonecount; i++)
            {
                byte[] thistonedata = new byte [32];
                Array.Copy(tonedata, i * 32, thistonedata, 0, 32);
                tones[i] = VHTone.Load(thistonedata);
            }
            return(new VHProgram(isoldversion, volume, priority, mode, panning, attribute, tones));
        }
Example #18
0
        public static OldFrame Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length < 56)
            {
                ErrorManager.SignalError("OldFrame: Data is too short");
            }
            int vertexcount = BitConv.FromInt32(data, 0);

            if (vertexcount < 0 || vertexcount > Chunk.Length / 6)
            {
                ErrorManager.SignalError("OldFrame: Vertex count is invalid");
            }
            if (data.Length < 56 + vertexcount * 6 + 2)
            {
                ErrorManager.SignalError("OldFrame: Data is too short");
            }
            int modeleid = BitConv.FromInt32(data, 4);
            int xoffset  = BitConv.FromInt32(data, 8);
            int yoffset  = BitConv.FromInt32(data, 12);
            int zoffset  = BitConv.FromInt32(data, 16);
            int x1       = BitConv.FromInt32(data, 20);
            int y1       = BitConv.FromInt32(data, 24);
            int z1       = BitConv.FromInt32(data, 28);
            int x2       = BitConv.FromInt32(data, 32);
            int y2       = BitConv.FromInt32(data, 36);
            int z2       = BitConv.FromInt32(data, 40);
            int xglobal  = BitConv.FromInt32(data, 44);
            int yglobal  = BitConv.FromInt32(data, 48);
            int zglobal  = BitConv.FromInt32(data, 52);

            OldFrameVertex[] vertices = new OldFrameVertex [vertexcount];
            for (int i = 0; i < vertexcount; i++)
            {
                byte[] vertexdata = new byte [6];
                Array.Copy(data, 56 + i * 6, vertexdata, 0, vertexdata.Length);
                vertices[i] = OldFrameVertex.Load(vertexdata);
            }
            short unknown = BitConv.FromInt16(data, 56 + vertexcount * 6);

            return(new OldFrame(modeleid, xoffset, yoffset, zoffset, x1, y1, z1, x2, y2, z2, xglobal, yglobal, zglobal, vertices, unknown));
        }
Example #19
0
        public static SampleSet Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length % 16 != 0)
            {
                ErrorManager.SignalError("SampleSet: Length is invalid");
            }
            int samplelinecount = data.Length / 16;

            SampleLine[] samplelines = new SampleLine [samplelinecount];
            for (int i = 0; i < samplelinecount; i++)
            {
                byte[] linedata = new byte [16];
                Array.Copy(data, i * 16, linedata, 0, 16);
                samplelines[i] = SampleLine.Load(linedata);
            }
            return(new SampleSet(samplelines));
        }
Example #20
0
 public override Entry Load(byte[][] items, int eid)
 {
     if (items == null)
     {
         throw new ArgumentNullException("items");
     }
     if (items.Length != 3 && items.Length != 4)
     {
         ErrorManager.SignalError("OldSceneryEntry: Wrong number of items");
     }
     if (items[1].Length % 8 != 0)
     {
         ErrorManager.SignalError("OldSceneryEntry: Second item (polygons) length is invalid");
     }
     OldSceneryPolygon[] polygons = new OldSceneryPolygon [items[1].Length / 8];
     for (int i = 0; i < polygons.Length; i++)
     {
         byte[] polygondata = new byte [8];
         Array.Copy(items[1], i * 8, polygondata, 0, 8);
         polygons[i] = OldSceneryPolygon.Load(polygondata);
     }
     if (items[2].Length % 8 != 0)
     {
         ErrorManager.SignalError("OldSceneryEntry: Third item (vertices) length is invalid");
     }
     OldSceneryVertex[] vertices = new OldSceneryVertex [items[2].Length / 8];
     for (int i = 0; i < vertices.Length; i++)
     {
         byte[] vertexdata = new byte [8];
         Array.Copy(items[2], i * 8, vertexdata, 0, 8);
         vertices[i] = OldSceneryVertex.Load(vertexdata);
     }
     byte[] extradata = null;
     if (items.Length >= 4)
     {
         extradata = items[3];
     }
     return(new OldSceneryEntry(items[0], polygons, vertices, extradata, eid));
 }
Example #21
0
 internal override void LoadToField(object obj, FieldInfo field)
 {
     if (field.FieldType == typeof(string))
     {
         if (Rows.Count == 1)
         {
             if (Rows[0].MetaValue == null)
             {
                 byte[] bytestr = new byte [Rows[0].Values.Count];
                 for (int i = 0; i < bytestr.Length; i++)
                 {
                     bytestr[i] = Rows[0].Values[i];
                 }
                 string str = System.Text.Encoding.UTF8.GetString(bytestr);
                 if (str.EndsWith("\0"))
                 {
                     str = str.Remove(str.Length - 1);
                 }
                 else
                 {
                     ErrorManager.SignalIgnorableError("EntityProperty: String is not null-terminated");
                 }
                 field.SetValue(obj, str);
             }
             else
             {
                 ErrorManager.SignalError("EntityProperty: Property has an unexpected metavalue");
             }
         }
         else
         {
             ErrorManager.SignalError("EntityProperty: Property has more rows than expected");
         }
     }
     else
     {
         base.LoadToField(obj, field);
     }
 }
Example #22
0
        public override Entry Load(byte[][] items, int eid)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }
            if (items.Length != 3)
            {
                ErrorManager.SignalError("MusicEntry: Wrong number of items");
            }
            if (items[0].Length != 36)
            {
                ErrorManager.SignalError("MusicEntry: First item length is wrong");
            }
            int seqcount = BitConv.FromInt32(items[0], 0);
            int vheid    = BitConv.FromInt32(items[0], 4);
            int vb0eid   = BitConv.FromInt32(items[0], 8);
            int vb1eid   = BitConv.FromInt32(items[0], 12);
            int vb2eid   = BitConv.FromInt32(items[0], 16);
            int vb3eid   = BitConv.FromInt32(items[0], 20);
            int vb4eid   = BitConv.FromInt32(items[0], 24);
            int vb5eid   = BitConv.FromInt32(items[0], 28);
            int vb6eid   = BitConv.FromInt32(items[0], 32);
            VH  vh;

            if (items[1].Length != 0)
            {
                vh = VH.Load(items[1]);
            }
            else
            {
                vh = null;
            }
            SEP sep = SEP.Load(items[2], seqcount);

            return(new MusicEntry(vheid, vb0eid, vb1eid, vb2eid, vb3eid, vb4eid, vb5eid, vb6eid, vh, sep, eid));
        }
Example #23
0
        public static SEP Load(byte[] data, int seqcount)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (seqcount < 0)
            {
                throw new ArgumentOutOfRangeException("seqcount");
            }
            // All SEP/SEQ stuff is big-endian, like MIDI
            if (data.Length < 6)
            {
                ErrorManager.SignalError("SEP: Data is too short");
            }
            int   magic   = BEBitConv.FromInt32(data, 0);
            short version = BEBitConv.FromInt16(data, 4);

            if (magic != Magic)
            {
                ErrorManager.SignalIgnorableError("SEP: Magic number is wrong");
            }
            if (version != Version)
            {
                ErrorManager.SignalIgnorableError("SEP: Version number is wrong");
            }
            int offset = 6;

            SEQ[] seqs = new SEQ [seqcount];
            for (int i = 0; i < seqcount; i++)
            {
                if (data.Length < offset + 13)
                {
                    ErrorManager.SignalError("SEP: Data is too short");
                }
                short seqid      = BEBitConv.FromInt16(data, offset);
                short resolution = BEBitConv.FromInt16(data, offset + 2);
                // tempo is 3 (yes, three) bytes
                int   tempo  = MIDIConv.From3BE(data, offset + 4);
                short rhythm = BEBitConv.FromInt16(data, offset + 7);
                int   length = BEBitConv.FromInt32(data, offset + 9);
                if (seqid != i)
                {
                    ErrorManager.SignalIgnorableError("SEP: Track number is wrong");
                }
                if (length < 0)
                {
                    ErrorManager.SignalError("SEP: Track length is negative");
                }
                offset += 13;
                if (data.Length < offset + length)
                {
                    ErrorManager.SignalError("SEP: Data is too short");
                }
                byte[] seqdata = new byte [length];
                Array.Copy(data, offset, seqdata, 0, length);
                seqs[i] = new SEQ(resolution, tempo, rhythm, seqdata);
                offset += length;
            }
            return(new SEP(seqs));
        }
Example #24
0
        public sealed override EntityProperty Load(byte elementsize, short unknown, bool issparse, bool hasmetavalues, byte[] data)
        {
            if (elementsize != ElementSize)
            {
                ErrorManager.SignalError("EntityProperty: Element size is wrong");
            }
            if (unknown < 0)
            {
                ErrorManager.SignalError("EntityProperty: Unknown value is invalid");
            }
            List <EntityPropertyRow <T> > rows = new List <EntityPropertyRow <T> >();

            for (int i = 0; i < unknown; i++)
            {
                rows.Add(new EntityPropertyRow <T>());
            }
            int offset = 0;

            if (issparse)
            {
                if (offset + 2 * unknown > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                foreach (EntityPropertyRow <T> row in rows)
                {
                    int valuecount = (ushort)BitConv.FromInt16(data, offset);
                    offset += 2;
                    for (int i = 0; i < valuecount; i++)
                    {
                        row.Values.Add(new T());
                    }
                }
            }
            else
            {
                if (offset + 2 > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                int valuecount = (ushort)BitConv.FromInt16(data, offset);
                offset += 2;
                foreach (EntityPropertyRow <T> row in rows)
                {
                    for (int i = 0; i < valuecount; i++)
                    {
                        row.Values.Add(new T());
                    }
                }
            }
            if (hasmetavalues)
            {
                if (offset + 2 * unknown > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                foreach (EntityPropertyRow <T> row in rows)
                {
                    short metavalue = BitConv.FromInt16(data, offset);
                    offset       += 2;
                    row.MetaValue = metavalue;
                }
            }
            Aligner.Align(ref offset, 4);
            byte[] elementdata = new byte [elementsize];
            foreach (EntityPropertyRow <T> row in rows)
            {
                if (offset + row.Values.Count * elementsize > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                for (int i = 0; i < row.Values.Count; i++)
                {
                    Array.Copy(data, offset, elementdata, 0, elementsize);
                    offset       += elementsize;
                    row.Values[i] = LoadElement(elementdata);
                }
            }
            Aligner.Align(ref offset, 4);
            if (offset != data.Length)
            {
                ErrorManager.SignalIgnorableError("EntityProperty: More data than expected");
            }
            return(Load(rows));
        }
Example #25
0
        public static Entity Load(byte[] data)
        {
            if (data.Length < 16)
            {
                ErrorManager.SignalError("Entity: Data is too short");
            }
            int length        = BitConv.FromInt32(data, 0);
            int blank1        = BitConv.FromInt32(data, 4);
            int blank2        = BitConv.FromInt32(data, 8);
            int propertycount = BitConv.FromInt32(data, 12);

            if (length != data.Length)
            {
                ErrorManager.SignalIgnorableError("Entity: Length field mismatch");
            }
            if (blank1 != 0 || blank2 != 0)
            {
                ErrorManager.SignalIgnorableError("Entity: Blank value is wrong");
            }
            if (propertycount < 0 || propertycount > ushort.MaxValue)
            {
                ErrorManager.SignalError("Entity: Property count is invalid");
            }
            if (data.Length < 16 + propertycount * 8)
            {
                ErrorManager.SignalError("Entity: Data is too short");
            }
            Dictionary <short, EntityProperty> properties = new Dictionary <short, EntityProperty>();

            for (int i = 0; i < propertycount; i++)
            {
                short id          = BitConv.FromInt16(data, 16 + i * 8);
                int   offset      = (ushort)BitConv.FromInt16(data, 18 + i * 8) + 12;
                int   nextoffset  = (i == propertycount - 1) ? data.Length : ((ushort)BitConv.FromInt16(data, 26 + i * 8) + 12);
                byte  type        = data[20 + i * 8];
                byte  elementsize = data[21 + i * 8];
                short unknown     = BitConv.FromInt16(data, 22 + i * 8);
                if (offset > data.Length)
                {
                    ErrorManager.SignalError("Entity: Property begins out of bounds");
                }
                if (nextoffset < offset)
                {
                    ErrorManager.SignalError("Entity: Property ends before it begins");
                }
                if (nextoffset > data.Length)
                {
                    ErrorManager.SignalError("Entity: Property ends out of bounds");
                }
                if (properties.ContainsKey(id))
                {
                    ErrorManager.SignalIgnorableError("Entity: Duplicate property");
                }
                else
                {
                    byte[] propertydata = new byte [nextoffset - offset];
                    Array.Copy(data, offset, propertydata, 0, propertydata.Length);
                    EntityProperty property = EntityProperty.Load(type, elementsize, unknown, i == propertycount - 1, propertydata);
                    properties.Add(id, property);
                }
            }
            return(new Entity(properties));
        }
Example #26
0
 internal virtual void LoadToField(object obj, FieldInfo field)
 {
     ErrorManager.SignalError("EntityProperty: Type mismatch");
 }
Example #27
0
        public static NSF Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            int offset  = 0;
            int?firstid = null;
            List <UnprocessedChunk> prelude            = null;
            List <Chunk>            chunks             = new List <Chunk>();
            List <bool>             preludecompression = null;
            List <bool>             chunkcompression   = new List <bool>();

            while (offset < data.Length)
            {
                bool             compressed;
                byte[]           chunkdata = ReadChunk(data, ref offset, out compressed);
                UnprocessedChunk chunk     = Chunk.Load(chunkdata);
                if (firstid == null)
                {
                    firstid = chunk.ID;
                }
                else if (firstid == chunk.ID)
                {
                    if (prelude != null)
                    {
                        ErrorManager.SignalError("NSF: Double prelude");
                    }
                    prelude = new List <UnprocessedChunk>();
                    foreach (UnprocessedChunk unprocessedchunk in chunks)
                    {
                        prelude.Add(unprocessedchunk);
                    }
                    chunks.Clear();
                    preludecompression = chunkcompression;
                    chunkcompression   = new List <bool>();
                }
                chunkcompression.Add(compressed);
                if (prelude != null && chunks.Count < prelude.Count)
                {
                    for (int i = 0; i < Chunk.Length; i++)
                    {
                        if (prelude[chunks.Count].Data[i] != chunk.Data[i])
                        {
                            ErrorManager.SignalIgnorableError("NSF: Prelude data mismatch");
                            break;
                        }
                    }
                }
                chunks.Add(chunk);
            }
            if (prelude != null && chunks.Count < prelude.Count)
            {
                ErrorManager.SignalIgnorableError("NSF: Prelude is longer than actual data");
            }
            if (prelude != null)
            {
                ErrorManager.SignalIgnorableError("NSF: Prelude saving is not yet implemented");
            }
            foreach (bool compressed in chunkcompression)
            {
                if (compressed)
                {
                    ErrorManager.SignalIgnorableError("NSF: Non-prelude chunk was compressed");
                }
            }
            return(new NSF(chunks));
        }
Example #28
0
        public override Entry Load(byte[][] items, int eid)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }
            if (items.Length != 7)
            {
                ErrorManager.SignalError("SceneryEntry: Wrong number of items");
            }
            if (items[0].Length != 76)
            {
                ErrorManager.SignalError("SceneryEntry: First item length is wrong");
            }
            // TODO :: Get vertexcount from info
            int vertexcount = items[1].Length / 6;

            // TODO :: Check vertex list size
            SceneryVertex[] vertices = new SceneryVertex [vertexcount];
            for (int i = 0; i < vertexcount; i++)
            {
                byte[] xydata = new byte [4];
                byte[] zdata  = new byte [2];
                Array.Copy(items[1], (vertexcount - 1 - i) * 4, xydata, 0, xydata.Length);
                Array.Copy(items[1], vertexcount * 4 + i * 2, zdata, 0, zdata.Length);
                vertices[i] = SceneryVertex.Load(xydata, zdata);
            }
            // TODO :: Get trianglecount from info
            int trianglecount = items[2].Length / 6;

            // TODO :: Check triangle list size
            SceneryTriangle[] triangles = new SceneryTriangle [trianglecount];
            for (int i = 0; i < trianglecount; i++)
            {
                byte[] adata = new byte [4];
                byte[] bdata = new byte [2];
                Array.Copy(items[2], (trianglecount - 1 - i) * 4, adata, 0, adata.Length);
                Array.Copy(items[2], trianglecount * 4 + i * 2, bdata, 0, bdata.Length);
                triangles[i] = SceneryTriangle.Load(adata, bdata);
            }
            // TODO :: Get quadcount from info
            int quadcount = items[3].Length / 8;

            // TODO :: Check quad list size
            SceneryQuad[] quads = new SceneryQuad [quadcount];
            for (int i = 0; i < quadcount; i++)
            {
                byte[] quaddata = new byte [8];
                Array.Copy(items[3], i * 8, quaddata, 0, quaddata.Length);
                quads[i] = SceneryQuad.Load(quaddata);
            }
            // TODO :: Get colorcount from info
            int colorcount = items[5].Length / 4;

            // TODO :: Check color list size
            SceneryColor[] colors = new SceneryColor [colorcount];
            for (int i = 0; i < colorcount; i++)
            {
                byte red   = items[5][i * 4];
                byte green = items[5][i * 4 + 1];
                byte blue  = items[5][i * 4 + 2];
                byte extra = items[5][i * 4 + 3];
                colors[i] = new SceneryColor(red, green, blue, extra);
            }
            return(new SceneryEntry(items[0], vertices, triangles, quads, items[4], colors, items[6], eid));
        }
Example #29
0
        private static byte[] ReadChunk(byte[] data, ref int offset, out bool compressed)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (offset < 0 || offset > data.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (data.Length < offset + 2)
            {
                ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
            }
            byte[] result = new byte [Chunk.Length];
            short  magic  = BitConv.FromInt16(data, offset);

            if (magic == Chunk.Magic)
            {
                compressed = false;
                if (data.Length < offset + Chunk.Length)
                {
                    ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                }
                Array.Copy(data, offset, result, 0, Chunk.Length);
                offset += Chunk.Length;
            }
            else if (magic == Chunk.CompressedMagic)
            {
                compressed = true;
                int pos = 0;
                if (data.Length < offset + 12)
                {
                    ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                }
                short zero   = BitConv.FromInt16(data, offset + 2);
                int   length = BitConv.FromInt32(data, offset + 4);
                int   skip   = BitConv.FromInt32(data, offset + 8);
                if (zero != 0)
                {
                    ErrorManager.SignalIgnorableError("NSF.ReadChunk: Zero value is wrong");
                }
                if (length < 0 || length > Chunk.Length)
                {
                    ErrorManager.SignalError("NSF.ReadChunk: Length field is invalid");
                }
                if (skip < 0)
                {
                    ErrorManager.SignalError("NSF.ReadChunk: Skip value is negative");
                }
                offset += 12;
                while (pos < length)
                {
                    if (data.Length < offset + 1)
                    {
                        ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                    }
                    byte prefix = data[offset];
                    offset++;
                    if ((prefix & 0x80) != 0)
                    {
                        prefix &= 0x7F;
                        if (data.Length < offset + 1)
                        {
                            ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                        }
                        int seek = data[offset];
                        offset++;
                        int span = seek & 7;
                        seek >>= 3;
                        seek  |= prefix << 5;
                        if (span == 7)
                        {
                            span = 64;
                        }
                        else
                        {
                            span += 3;
                        }
                        if (pos - seek < 0)
                        {
                            ErrorManager.SignalError("NSF.ReadChunk: Repeat begins out of bounds");
                        }
                        if (pos + span > Chunk.Length)
                        {
                            ErrorManager.SignalError("NSF.ReadChunk: Repeat ends out of bounds");
                        }
                        // Do NOT use Array.Copy as
                        // overlap is possible i.e. span
                        // may be greater than seek
                        for (int i = 0; i < span; i++)
                        {
                            result[pos + i] = result[pos - seek + i];
                        }
                        pos += span;
                    }
                    else
                    {
                        if (data.Length < offset + prefix)
                        {
                            ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                        }
                        Array.Copy(data, offset, result, pos, prefix);
                        offset += prefix;
                        pos    += prefix;
                    }
                }
                if (data.Length < offset + skip)
                {
                    ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                }
                offset += skip;
                if (data.Length < offset + (Chunk.Length - length))
                {
                    ErrorManager.SignalError("NSF.ReadChunk: Data is too short");
                }
                Array.Copy(data, offset, result, pos, Chunk.Length - length);
                offset += (Chunk.Length - length);
            }
            else
            {
                compressed = false; // Fixes a stupid compile error
                ErrorManager.SignalError("NSF.ReadChunk: Unknown magic number");
            }
            return(result);
        }
Example #30
0
        public static VH Load(byte[] data)
        {
            if (data.Length < 2592)
            {
                ErrorManager.SignalError("VH: Data is too short");
            }
            int magic   = BitConv.FromInt32(data, 0);
            int version = BitConv.FromInt32(data, 4);

            if (magic != Magic)
            {
                ErrorManager.SignalIgnorableError("VH: Magic number is wrong");
            }
            bool isoldversion;

            if (version == Version)
            {
                isoldversion = false;
            }
            else if (version == OldVersion)
            {
                ErrorManager.SignalIgnorableError("VH: VABv6 (crash 1) is not fully supported");
                isoldversion = true;
            }
            else
            {
                ErrorManager.SignalIgnorableError("VH: Version number is wrong");
                isoldversion = true;
            }
            int   id           = BitConv.FromInt32(data, 8);
            int   size         = BitConv.FromInt32(data, 12);
            short reserved1    = BitConv.FromInt16(data, 16);
            short programcount = BitConv.FromInt16(data, 18);
            short tonecount    = BitConv.FromInt16(data, 20);
            short wavecount    = BitConv.FromInt16(data, 22);
            byte  volume       = data[24];
            byte  panning      = data[25];
            byte  attribute1   = data[26];
            byte  attribute2   = data[27];
            int   reserved2    = BitConv.FromInt32(data, 28);

            if (id != 0)
            {
                ErrorManager.SignalIgnorableError("VH: ID is wrong");
            }
            if (size < data.Length)
            {
                ErrorManager.SignalError("VH: Size field mismatch");
            }
            if ((size - data.Length) % 16 != 0)
            {
                ErrorManager.SignalError("VH: Size field is invalid");
            }
            int vbsize = (size - data.Length) / 16;

            if (reserved1 != -0x1112)
            {
                ErrorManager.SignalIgnorableError("VH: Reserved value 1 is wrong");
            }
            if (programcount < 0 || programcount > 128)
            {
                ErrorManager.SignalError("VH: Program count is invalid");
            }
            if (tonecount < 0 || tonecount > 2048)
            {
                ErrorManager.SignalError("VH: Tone count is invalid");
            }
            if (wavecount < 0 || wavecount > 254)
            {
                ErrorManager.SignalError("VH: Wave count is invalid");
            }
            if (reserved2 != -1)
            {
                ErrorManager.SignalIgnorableError("VH: Reserved value 2 is wrong");
            }
            if (data.Length < 2592 + 32 * 16 * programcount)
            {
                ErrorManager.SignalError("VH: Data is too short");
            }
            Dictionary <int, VHProgram> programs = new Dictionary <int, VHProgram>();

            for (int i = 0; i < 128; i++)
            {
                byte[] programdata = new byte [16];
                Array.Copy(data, 32 + 16 * i, programdata, 0, 16);
                if (programdata[0] == 0)
                {
                    continue;
                }
                if (programs.Count == programcount)
                {
                    ErrorManager.SignalError("VH: Program count field mismatch");
                }
                byte[] tonedata = new byte [32 * 16];
                Array.Copy(data, 32 + 16 * 128 + 32 * 16 * programs.Count, tonedata, 0, 32 * 16);
                programs.Add(i, VHProgram.Load(programdata, tonedata, isoldversion));
            }
            if (programs.Count != programcount)
            {
                ErrorManager.SignalError("VH: Program count field mismatch");
            }
            int[] waves = new int [wavecount];
            for (int i = 0; i < wavecount; i++)
            {
                int wave = BitConv.FromInt16(data, 32 + 16 * 128 + 32 * 16 * programcount + 2 + i * 2);
                if (wave % 2 != 0)
                {
                    ErrorManager.SignalError("VH: Wave size is invalid");
                }
                waves[i] = wave / 2;
            }
            return(new VH(isoldversion, vbsize, volume, panning, attribute1, attribute2, programs, waves));
        }