Exemplo n.º 1
0
        public override byte[] Save()
        {
            int length = 20 + Items.Count * 4;

            Aligner.Align(ref length, 4);
            foreach (byte[] item in Items)
            {
                length += item.Length;
                Aligner.Align(ref length, 4);
            }
            byte[] data = new byte [length];
            BitConv.ToInt32(data, 0, Magic);
            BitConv.ToInt32(data, 4, EID);
            BitConv.ToInt32(data, 8, Type);
            BitConv.ToInt32(data, 12, Items.Count);
            int offset = 20 + Items.Count * 4;

            Aligner.Align(ref offset, 4);
            BitConv.ToInt32(data, 16, offset);
            for (int i = 0; i < Items.Count; i++)
            {
                Items[i].CopyTo(data, offset);
                offset += Items[i].Length;
                Aligner.Align(ref offset, 4);
                BitConv.ToInt32(data, 20 + i * 4, offset);
            }
            return(data);
        }
Exemplo n.º 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));
        }
Exemplo n.º 3
0
        public static SceneryVertex Load(byte[] xydata, byte[] zdata)
        {
            if (xydata == null)
            {
                throw new ArgumentNullException("xydata");
            }
            if (zdata == null)
            {
                throw new ArgumentNullException("zdata");
            }
            if (xydata.Length != 4)
            {
                throw new ArgumentException("Value must be 4 bytes long.", "xydata");
            }
            if (zdata.Length != 2)
            {
                throw new ArgumentException("Value must be 2 bytes long.", "zdata");
            }
            int   xy       = BitConv.FromInt32(xydata, 0);
            short z        = BitConv.FromInt16(zdata, 0);
            short y        = (short)(xy >> 16);
            short x        = (short)xy;
            int   unknownx = x & 0xF;
            int   unknowny = y & 0xF;
            int   unknownz = z & 0xF;

            x >>= 4;
            y >>= 4;
            z >>= 4;
            return(new SceneryVertex(x, y, z, unknownx, unknowny, unknownz));
        }
Exemplo n.º 4
0
 public byte[] Save(int program)
 {
     byte[] data = new byte [32];
     data[0]  = priority;
     data[1]  = mode;
     data[2]  = volume;
     data[3]  = panning;
     data[4]  = centernote;
     data[5]  = pitchshift;
     data[6]  = minimumnote;
     data[7]  = maximumnote;
     data[8]  = vibratowidth;
     data[9]  = vibratotime;
     data[10] = portamentowidth;
     data[11] = portamentotime;
     data[12] = pitchbendminimum;
     data[13] = pitchbendmaximum;
     data[14] = 0xB1;
     data[15] = 0xB2;
     BitConv.ToInt16(data, 16, adsr1);
     BitConv.ToInt16(data, 18, adsr2);
     BitConv.ToInt16(data, 20, (short)program);
     BitConv.ToInt16(data, 22, wave);
     BitConv.ToInt16(data, 24, 0xC0);
     BitConv.ToInt16(data, 26, 0xC1);
     BitConv.ToInt16(data, 28, 0xC2);
     BitConv.ToInt16(data, 30, 0xC3);
     return(data);
 }
Exemplo n.º 5
0
        public static SceneryTriangle Load(byte[] adata, byte[] bdata)
        {
            if (adata == null)
            {
                throw new ArgumentNullException("adata");
            }
            if (bdata == null)
            {
                throw new ArgumentNullException("bdata");
            }
            if (adata.Length != 4)
            {
                throw new ArgumentException("Value must be 4 bytes long.", "adata");
            }
            if (bdata.Length != 2)
            {
                throw new ArgumentException("Value must be 2 bytes long.", "adata");
            }
            int   avalue   = BitConv.FromInt32(adata, 0);
            short bvalue   = BitConv.FromInt16(bdata, 0);
            int   vertexa  = (avalue >> 8) & 0xFFF;
            int   vertexb  = (avalue >> 20) & 0xFFF;
            int   vertexc  = (bvalue >> 4) & 0xFFF;
            byte  unknown1 = (byte)avalue;
            byte  unknown2 = (byte)(bvalue & 0xF);

            return(new SceneryTriangle(vertexa, vertexb, vertexc, unknown1, unknown2));
        }
Exemplo n.º 6
0
        public RIFF ToDLSRegion()
        {
            RIFF rgn = new RIFF("rgn ");

            byte[] rgnh = new byte [12];
            BitConv.ToInt16(rgnh, 0, minimumnote);
            BitConv.ToInt16(rgnh, 2, maximumnote);
            BitConv.ToInt16(rgnh, 4, 0);
            BitConv.ToInt16(rgnh, 6, 127);
            BitConv.ToInt16(rgnh, 8, 0);
            BitConv.ToInt16(rgnh, 10, 0);
            rgn.Items.Add(new RIFFData("rgnh", rgnh));
            byte[] wsmp = new byte [20 /* 36 */];
            BitConv.ToInt32(wsmp, 0, 20);
            BitConv.ToInt16(wsmp, 4, centernote);
            BitConv.ToInt16(wsmp, 6, pitchshift);
            BitConv.ToInt32(wsmp, 8, volume - 64 << 16);
            BitConv.ToInt32(wsmp, 12, 0);
            BitConv.ToInt32(wsmp, 16, 0 /* 1 */);

            /*BitConv.ToInt32(wsmp,20,16);
             * BitConv.ToInt32(wsmp,24,0);
             * BitConv.ToInt32(wsmp,28,LOOPSTART);
             * BitConv.ToInt32(wsmp,28,LOOPLENGTH);*/
            rgn.Items.Add(new RIFFData("wsmp", wsmp));
            byte[] wlnk = new byte [12];
            BitConv.ToInt16(wlnk, 0, 0);
            BitConv.ToInt16(wlnk, 2, 0);
            BitConv.ToInt32(wlnk, 4, 3); // ???
            BitConv.ToInt32(wlnk, 8, wave - 1);
            rgn.Items.Add(new RIFFData("wlnk", wlnk));
            return(rgn);
        }
Exemplo n.º 7
0
        protected override EntitySetting LoadElement(byte[] data)
        {
            byte a = data[0];
            int  b = BitConv.FromInt24(data, 1);

            return(new EntitySetting(a, b));
        }
Exemplo n.º 8
0
        public override UnprocessedChunk Unprocess(int chunkid)
        {
            byte[] data = new byte [Length];
            BitConv.ToInt16(data, 0, Magic);
            BitConv.ToInt16(data, 2, Type);
            BitConv.ToInt32(data, 4, chunkid);
            BitConv.ToInt32(data, 8, entries.Count);
            // Checksum is here, but calculated later
            int offset = 20 + entries.Count * 4;

            for (int i = 0; i < entries.Count; i++)
            {
                UnprocessedEntry entry     = entries[i].Unprocess();
                byte[]           entrydata = entry.Save();
                offset += entry.HeaderLength;
                Aligner.Align(ref offset, Alignment);
                offset -= entry.HeaderLength;
                if (offset + entrydata.Length > Length)
                {
                    throw new PackingException();
                }
                BitConv.ToInt32(data, 16 + i * 4, offset);
                entrydata.CopyTo(data, offset);
                offset += entrydata.Length;
            }
            BitConv.ToInt32(data, 16 + entries.Count * 4, offset);
            int checksum = CalculateChecksum(data);

            BitConv.ToInt32(data, 12, checksum);
            return(new UnprocessedChunk(data));
        }
Exemplo n.º 9
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));
        }
Exemplo n.º 10
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));
        }
Exemplo n.º 11
0
        public byte[] SaveZ()
        {
            byte[] data  = new byte [2];
            int    zdata = (z << 4) | unknownz;

            BitConv.ToInt16(data, 0, (short)zdata);
            return(data);
        }
Exemplo n.º 12
0
        public byte[] SaveA()
        {
            byte[] data  = new byte [4];
            int    value = (vertexa << 8) | (vertexb << 20) | unknown1;

            BitConv.ToInt32(data, 0, value);
            return(data);
        }
Exemplo n.º 13
0
        protected override EntityPosition LoadElement(byte[] data)
        {
            short x = BitConv.FromInt16(data, 0);
            short y = BitConv.FromInt16(data, 2);
            short z = BitConv.FromInt16(data, 4);

            return(new EntityPosition(x, y, z));
        }
Exemplo n.º 14
0
        public byte[] SaveB()
        {
            byte[] data  = new byte [2];
            int    value = (vertexc << 4) | unknown2;

            BitConv.ToInt16(data, 0, (short)value);
            return(data);
        }
Exemplo n.º 15
0
        public byte[] Save()
        {
            byte[] data = new byte [2592 + 32 * 16 * programs.Count];
            BitConv.ToInt32(data, 0, Magic);
            BitConv.ToInt32(data, 4, isoldversion ? OldVersion : Version);
            BitConv.ToInt32(data, 8, 0);
            BitConv.ToInt32(data, 12, data.Length + vbsize * 16);
            BitConv.ToInt16(data, 16, -0x1112);
            int tonecount = 0;

            foreach (VHProgram program in programs.Values)
            {
                tonecount += program.Tones.Count;
            }
            BitConv.ToInt16(data, 18, (short)programs.Count);
            BitConv.ToInt16(data, 20, (short)tonecount);
            BitConv.ToInt16(data, 22, (short)waves.Count);
            data[24] = volume;
            data[25] = panning;
            data[26] = attribute1;
            data[27] = attribute2;
            BitConv.ToInt32(data, 28, -1);
            for (int i = 0; i < 128; i++)
            {
                if (programs.ContainsKey(i))
                {
                    programs[i].Save().CopyTo(data, 32 + 16 * i);
                }
                else
                {
                    new VHProgram(isoldversion).Save().CopyTo(data, 32 + 16 * i);
                }
            }
            int ii = 0;

            foreach (KeyValuePair <int, VHProgram> kvp in programs)
            {
                VHProgram program = kvp.Value;
                for (int j = 0; j < 16; j++)
                {
                    if (j < program.Tones.Count)
                    {
                        program.Tones[j].Save(kvp.Key).CopyTo(data, 2080 + 32 * 16 * ii + 32 * j);
                    }
                    else
                    {
                        new VHTone(isoldversion).Save(kvp.Key).CopyTo(data, 2080 + 32 * 16 * ii + 32 * j);
                    }
                }
                ii++;
            }
            for (int i = 0; i < waves.Count; i++)
            {
                BitConv.ToInt16(data, 2080 + 32 * 16 * programs.Count + 2 + i * 2, (short)(waves[i] * 2));
            }
            return(data);
        }
Exemplo n.º 16
0
 public byte[] Save()
 {
     byte[] data = new byte [8];
     BitConv.ToInt16(data, 0, vertexa);
     BitConv.ToInt16(data, 2, vertexb);
     BitConv.ToInt16(data, 4, vertexc);
     BitConv.ToInt16(data, 6, unknown);
     return(data);
 }
Exemplo n.º 17
0
        public static VHTone Load(byte[] data)
        {
            if (data.Length != 32)
            {
                throw new ArgumentException("Value must be 32 bytes long.", "data");
            }
            byte  priority         = data[0];
            byte  mode             = data[1];
            byte  volume           = data[2];
            byte  panning          = data[3];
            byte  centernote       = data[4];
            byte  pitchshift       = data[5];
            byte  minimumnote      = data[6];
            byte  maximumnote      = data[7];
            byte  vibratowidth     = data[8];
            byte  vibratotime      = data[9];
            byte  portamentowidth  = data[10];
            byte  portamentotime   = data[11];
            byte  pitchbendminimum = data[12];
            byte  pitchbendmaximum = data[13];
            byte  reserved1        = data[14];
            byte  reserved2        = data[15];
            short adsr1            = BitConv.FromInt16(data, 16);
            short adsr2            = BitConv.FromInt16(data, 18);
            // Unused 2 bytes here
            short wave      = BitConv.FromInt16(data, 22);
            short reserved3 = BitConv.FromInt16(data, 24);
            short reserved4 = BitConv.FromInt16(data, 26);
            short reserved5 = BitConv.FromInt16(data, 28);
            short reserved6 = BitConv.FromInt16(data, 30);

            if (reserved1 != 0xB1)
            {
                ErrorManager.SignalIgnorableError("VHTone: Reserved value 1 is wrong");
            }
            if (reserved2 != 0xB2)
            {
                ErrorManager.SignalIgnorableError("VHTone: Reserved value 2 is wrong");
            }
            if (reserved3 != 0xC0)
            {
                ErrorManager.SignalIgnorableError("VHTone: Reserved value 3 is wrong");
            }
            if (reserved4 != 0xC1)
            {
                ErrorManager.SignalIgnorableError("VHTone: Reserved value 4 is wrong");
            }
            if (reserved5 != 0xC2)
            {
                ErrorManager.SignalIgnorableError("VHTone: Reserved value 5 is wrong");
            }
            if (reserved6 != 0xC3)
            {
                ErrorManager.SignalIgnorableError("VHTone: Reserved value 6 is wrong");
            }
            return(new VHTone(priority, mode, volume, panning, centernote, pitchshift, minimumnote, maximumnote, vibratowidth, vibratotime, portamentowidth, portamentotime, pitchbendminimum, pitchbendmaximum, adsr1, adsr2, wave));
        }
Exemplo n.º 18
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));
        }
Exemplo n.º 19
0
        public byte[] Save()
        {
            byte[] data  = new byte [8];
            int    worda = (vertexa << 8) | (vertexb << 20) | unknown2;
            int    wordb = (vertexd << 8) | (vertexc << 20) | unknown3;

            BitConv.ToInt32(data, 0, worda);
            BitConv.ToInt32(data, 4, wordb);
            return(data);
        }
Exemplo n.º 20
0
        public byte[] SaveXY()
        {
            byte[] data  = new byte [4];
            int    xdata = (x << 4) | unknownx;
            int    ydata = (y << 4) | unknowny;

            BitConv.ToInt16(data, 0, (short)xdata);
            BitConv.ToInt16(data, 2, (short)ydata);
            return(data);
        }
Exemplo n.º 21
0
 public override UnprocessedEntry Unprocess()
 {
     byte[] info = new byte [8];
     byte[] data = samples.Save();
     BitConv.ToInt32(info, 0, id);
     BitConv.ToInt32(info, 4, data.Length);
     byte[][] items = new byte [2][];
     items[0] = info;
     items[1] = data;
     return(new UnprocessedEntry(items, EID, Type));
 }
Exemplo n.º 22
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));
        }
Exemplo n.º 23
0
 public override UnprocessedEntry Unprocess()
 {
     byte[][] items = new byte [3][];
     items[0] = new byte [20];
     BitConv.ToInt32(items[0], 0, SEP.SEQs.Count);
     BitConv.ToInt32(items[0], 4, vb0eid);
     BitConv.ToInt32(items[0], 8, vb1eid);
     BitConv.ToInt32(items[0], 12, vb2eid);
     BitConv.ToInt32(items[0], 16, vb3eid);
     items[1] = vh.Save();
     items[2] = sep.Save();
     return(new UnprocessedEntry(items, EID, Type));
 }
Exemplo n.º 24
0
        public static short FromInt16(Endianness endianness, byte[] str, int offset)
        {
            switch (endianness)
            {
            case Endianness.LittleEndian:
                return(BitConv.FromInt16(str, offset));

            case Endianness.BigEndian:
                return(BEBitConv.FromInt16(str, offset));

            default:
                throw new ArgumentException("Endianness is invalid.");
            }
        }
Exemplo n.º 25
0
 public byte[] Save()
 {
     byte[] data = new byte [16];
     data[0] = (byte)tones.Count;
     data[1] = volume;
     data[2] = priority;
     data[3] = mode;
     data[4] = panning;
     data[5] = isoldversion ? (byte)0x00 : (byte)0xFF;
     BitConv.ToInt16(data, 6, attribute);
     BitConv.ToInt32(data, 8, -1);
     BitConv.ToInt32(data, 12, -1);
     return(data);
 }
Exemplo n.º 26
0
 public byte[] Save()
 {
     byte[] data = new byte [4 + values.Count * 2];
     if (values.Count > short.MaxValue)
     {
         throw new Exception();
     }
     BitConv.ToInt16(data, 0, (short)values.Count);
     BitConv.ToInt16(data, 2, unknown1);
     for (int i = 0; i < values.Count; i++)
     {
         BitConv.ToInt16(data, 4 + i * 2, values[i]);
     }
     return(data);
 }
Exemplo n.º 27
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));
        }
Exemplo n.º 28
0
        public byte[] Save()
        {
            int worda = 0;
            int wordb = 0;

            worda |= vertexa << 20;
            wordb |= vertexb << 8;
            wordb |= vertexc << 20;
            worda |= unknown1 << 8;
            worda |= unknown2;
            wordb |= unknown3;
            byte[] data = new byte [8];
            BitConv.ToInt32(data, 0, worda);
            BitConv.ToInt32(data, 4, wordb);
            return(data);
        }
Exemplo n.º 29
0
        public static void ToInt32(Endianness endianness, byte[] str, int offset, int value)
        {
            switch (endianness)
            {
            case Endianness.LittleEndian:
                BitConv.ToInt32(str, offset, value);
                break;

            case Endianness.BigEndian:
                BEBitConv.ToInt32(str, offset, value);
                break;

            default:
                throw new ArgumentException("Endianness is invalid.");
            }
        }
Exemplo n.º 30
0
        public static OldModelPolygon Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length != 8)
            {
                throw new ArgumentException("Value must be 8 bytes long.", "data");
            }
            short vertexa = BitConv.FromInt16(data, 0);
            short vertexb = BitConv.FromInt16(data, 2);
            short vertexc = BitConv.FromInt16(data, 4);
            short unknown = BitConv.FromInt16(data, 6);

            return(new OldModelPolygon(vertexa, vertexb, vertexc, unknown));
        }