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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
public static int FromInt32(Endianness endianness, byte[] str, int offset) { switch (endianness) { case Endianness.LittleEndian: return(BitConv.FromInt32(str, offset)); case Endianness.BigEndian: return(BEBitConv.FromInt32(str, offset)); default: throw new ArgumentException("Endianness is invalid."); } }
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)); }
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)); }
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)); }
public static SceneryQuad Load(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length != 8) { throw new ArgumentException("Value must be 8 bytes long.", "data"); } int worda = BitConv.FromInt32(data, 0); int wordb = BitConv.FromInt32(data, 4); int vertexa = (worda >> 8) & 0xFFF; int vertexb = (worda >> 20) & 0xFFF; int vertexd = (wordb >> 8) & 0xFFF; int vertexc = (wordb >> 20) & 0xFFF; byte unknown2 = (byte)worda; byte unknown3 = (byte)wordb; return(new SceneryQuad(vertexa, vertexb, vertexc, vertexd, unknown2, unknown3)); }
public static OldSceneryPolygon Load(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length != 8) { throw new ArgumentException("Value must be 8 bytes long.", "data"); } int worda = BitConv.FromInt32(data, 0); int wordb = BitConv.FromInt32(data, 4); int vertexa = (worda >> 20) & 0xFFF; int vertexb = (wordb >> 8) & 0xFFF; int vertexc = (wordb >> 20) & 0xFFF; int unknown1 = (worda >> 8) & 0xFFF; byte unknown2 = (byte)(worda & 0xFF); byte unknown3 = (byte)(wordb & 0xFF); return(new OldSceneryPolygon(vertexa, vertexb, vertexc, unknown1, unknown2, unknown3)); }
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)); }
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)); }
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); }
protected override int LoadElement(byte[] data) { return(BitConv.FromInt32(data, 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)); }