예제 #1
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));
        }
예제 #2
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));
        }
예제 #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));
        }
예제 #4
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));
        }
예제 #5
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));
        }
예제 #6
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.");
            }
        }
예제 #7
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));
        }
예제 #8
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));
        }
예제 #9
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));
        }
예제 #10
0
        public static UnprocessedChunk Load(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (data.Length != Length)
            {
                throw new ArgumentException("Value must be 65536 bytes long.", "data");
            }
            short magic = BitConv.FromInt16(data, 0);

            if (magic != Magic)
            {
                ErrorManager.SignalIgnorableError("Chunk: Magic number is wrong");
            }
            return(new UnprocessedChunk(data));
        }
예제 #11
0
        public static OldSceneryVertex 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 x            = (short)(BitConv.FromInt16(data, 4) & 0xFFF8);
            short y            = (short)(BitConv.FromInt16(data, 6) & 0xFFF8);
            int   zhigh        = data[6] & 7;
            int   zmid         = (data[4] & 6) >> 1;
            int   zlow         = data[3];
            short z            = (short)(zhigh << 13 | zmid << 11 | zlow << 3);
            byte  red          = data[0];
            byte  green        = data[1];
            byte  blue         = data[2];
            bool  lightingflag = ((data[4] & 1) != 0);

            return(new OldSceneryVertex(x, y, z, red, green, blue, lightingflag));
        }
예제 #12
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));
        }
예제 #13
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);
        }
예제 #14
0
파일: Entity.cs 프로젝트: rjayhub/CrashEdit
        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));
        }
예제 #15
0
 protected override short LoadElement(byte[] data)
 {
     return(BitConv.FromInt16(data, 0));
 }
예제 #16
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));
        }