/// <summary> /// Symb file to bytes. /// </summary> /// <param name="s"></param> /// <returns></returns> public static byte[] symbToBytes(NitroStructures.symbFile s) { //New reader. MemoryStream o = new MemoryStream(); BinaryWriter bw = new BinaryWriter(o); //Update offsets. s.fixOffsets(); //Write basic data. bw.Write(s.magic); bw.Write(s.fileSize); bw.Write(s.sseqOffset); bw.Write(s.seqArcOffset); bw.Write(s.bankOffset); bw.Write(s.waveOffset); bw.Write(s.playerOffset); bw.Write(s.groupOffset); bw.Write(s.player2Offset); bw.Write(s.strmOffset); bw.Write(s.reserved); //Write stuff. bw.Write(s.sseqRecord.count); for (int i = 0; i < s.sseqRecord.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.sseqStrings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.sseqRecord.offsets [i]); } } bw.Write(s.seqArcRecord.count); for (int i = 0; i < s.seqArcRecord.count; i++) { if (s.strings.seqArcStrings [i].isPlaceHolder) { bw.Write(0x00000000); bw.Write(0x00000000); } else { bw.Write(s.seqArcRecord.subNames [i].seqArcNameOffset); bw.Write(s.seqArcRecord.subNames [i].seqArcSubOffset); } } for (int i = 0; i < s.seqArcRecord.count; i++) { if (!s.strings.seqArcStrings [i].isPlaceHolder) { bw.Write(s.seqArcSubRecord [i].count); for (int j = 0; j < s.seqArcSubRecord [i].offsets.Length; j++) { if (s.strings.seqArcSubStrings [i] [j].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.seqArcSubRecord [i].offsets [j]); } } } } bw.Write(s.bankRecord.count); for (int i = 0; i < s.bankRecord.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.bankStrings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.bankRecord.offsets [i]); } } bw.Write(s.waveRecord.count); for (int i = 0; i < s.waveRecord.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.waveStrings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.waveRecord.offsets [i]); } } bw.Write(s.playerRecord.count); for (int i = 0; i < s.playerRecord.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.playerStrings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.playerRecord.offsets [i]); } } bw.Write(s.groupRecord.count); for (int i = 0; i < s.groupRecord.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.groupStrings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.groupRecord.offsets [i]); } } bw.Write(s.player2Record.count); for (int i = 0; i < s.player2Record.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.player2Strings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.player2Record.offsets [i]); } } bw.Write(s.strmRecord.count); for (int i = 0; i < s.strmRecord.count; i++) { //If placeholder write it, if not, write offset. if (s.strings.strmStrings [i].isPlaceHolder) { bw.Write(0x00000000); } else { bw.Write(s.strmRecord.offsets [i]); } } //Now time to write the strings. foreach (NitroStructures.symbStringEntry name in s.strings.sseqStrings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } //Seq arc. for (int i = 0; i < s.seqArcRecord.count; i++) { if (!s.strings.seqArcStrings [i].isPlaceHolder) { bw.Write(s.strings.seqArcStrings [i].name.ToCharArray()); bw.Write(s.strings.seqArcStrings [i].seperator); } for (int j = 0; j < s.strings.seqArcSubStrings[i].Length; j++) { if (!s.strings.seqArcSubStrings [i] [j].isPlaceHolder) { bw.Write(s.strings.seqArcSubStrings [i] [j].name.ToCharArray()); bw.Write(s.strings.seqArcSubStrings [i] [j].seperator); } } } //More. foreach (NitroStructures.symbStringEntry name in s.strings.bankStrings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } foreach (NitroStructures.symbStringEntry name in s.strings.waveStrings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } foreach (NitroStructures.symbStringEntry name in s.strings.playerStrings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } foreach (NitroStructures.symbStringEntry name in s.strings.groupStrings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } foreach (NitroStructures.symbStringEntry name in s.strings.player2Strings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } foreach (NitroStructures.symbStringEntry name in s.strings.strmStrings) { if (!name.isPlaceHolder) { bw.Write(name.name.ToCharArray()); bw.Write(name.seperator); } } //Return file. return(o.ToArray()); }
//Symb Tools #region symbTools /// <summary> /// Load an symb file. /// </summary> /// <param name="b"></param> /// <returns></returns> public static NitroStructures.symbFile loadSymbFile(byte[] b) { //New reader. MemoryStream src = new MemoryStream(b); BinaryDataReader br = new BinaryDataReader(src); //New File. NitroStructures.symbFile s = new NitroStructures.symbFile(); //Read lame stuff. s.magic = br.ReadChars(4); s.fileSize = br.ReadUInt32(); s.sseqOffset = br.ReadUInt32(); s.seqArcOffset = br.ReadUInt32(); s.bankOffset = br.ReadUInt32(); s.waveOffset = br.ReadUInt32(); s.playerOffset = br.ReadUInt32(); s.groupOffset = br.ReadUInt32(); s.player2Offset = br.ReadUInt32(); s.strmOffset = br.ReadUInt32(); s.reserved = br.ReadBytes(24); //Read records. br.Position = (int)s.sseqOffset; s.sseqRecord.count = br.ReadUInt32(); s.sseqRecord.offsets = br.ReadUInt32s((int)s.sseqRecord.count); br.Position = (int)s.seqArcOffset; s.seqArcRecord.count = br.ReadUInt32(); s.seqArcRecord.subNames = new NitroStructures.seqArcSubName[(int)s.seqArcRecord.count]; for (int i = 0; i < s.seqArcRecord.count; i++) { s.seqArcRecord.subNames[i].seqArcNameOffset = br.ReadUInt32(); s.seqArcRecord.subNames[i].seqArcSubOffset = br.ReadUInt32(); } //Get sub records. s.seqArcSubRecord = new NitroStructures.standardSymbName[(int)s.seqArcRecord.count]; for (int i = 0; i < s.seqArcRecord.count; i++) { //Set position to sub records. br.Position = s.seqArcRecord.subNames[i].seqArcSubOffset; //Read offsets. s.seqArcSubRecord[i].count = br.ReadUInt32(); s.seqArcSubRecord [i].offsets = br.ReadUInt32s((int)s.seqArcSubRecord[i].count); } br.Position = (int)s.bankOffset; s.bankRecord.count = br.ReadUInt32(); s.bankRecord.offsets = br.ReadUInt32s((int)s.bankRecord.count); br.Position = (int)s.waveOffset; s.waveRecord.count = br.ReadUInt32(); s.waveRecord.offsets = br.ReadUInt32s((int)s.waveRecord.count); br.Position = (int)s.playerOffset; s.playerRecord.count = br.ReadUInt32(); s.playerRecord.offsets = br.ReadUInt32s((int)s.playerRecord.count); br.Position = (int)s.groupOffset; s.groupRecord.count = br.ReadUInt32(); s.groupRecord.offsets = br.ReadUInt32s((int)s.groupRecord.count); br.Position = (int)s.player2Offset; s.player2Record.count = br.ReadUInt32(); s.player2Record.offsets = br.ReadUInt32s((int)s.player2Record.count); br.Position = (int)s.strmOffset; s.strmRecord.count = br.ReadUInt32(); s.strmRecord.offsets = br.ReadUInt32s((int)s.strmRecord.count); //Now time to get the strings. s.strings.sseqStrings = new NitroStructures.symbStringEntry[(int)s.sseqRecord.offsets.Length]; for (int i = 0; i < s.sseqRecord.offsets.Length; i++) { //Read strings. s.strings.sseqStrings[i].name = getStringFromOffset(br, s.sseqRecord.offsets[i]); s.strings.sseqStrings [i].seperator = (byte)0; s.strings.sseqStrings [i].isPlaceHolder = false; if (s.sseqRecord.offsets[i] == 0) { s.strings.sseqStrings [i].isPlaceHolder = true; } } //SeqArc s.strings.seqArcStrings = new NitroStructures.symbStringEntry[(int)s.seqArcRecord.count]; for (int i = 0; i < s.seqArcRecord.count; i++) { //Read strings. s.strings.seqArcStrings[i].name = getStringFromOffset(br, s.seqArcRecord.subNames[i].seqArcNameOffset); s.strings.seqArcStrings [i].seperator = (byte)0; s.strings.seqArcStrings [i].isPlaceHolder = false; if (s.seqArcRecord.subNames[i].seqArcNameOffset == 0) { s.strings.seqArcStrings [i].isPlaceHolder = true; } } //Subsections s.strings.seqArcSubStrings = new NitroStructures.symbStringEntry[(int)s.seqArcRecord.count][]; for (int i = 0; i < s.seqArcRecord.count; i++) { //Read strings. s.strings.seqArcSubStrings[i] = new NitroStructures.symbStringEntry[s.seqArcSubRecord[i].count]; for (int j = 0; j < s.seqArcSubRecord[i].count; j++) { s.strings.seqArcSubStrings[i][j].name = getStringFromOffset(br, s.seqArcSubRecord[i].offsets[j]); s.strings.seqArcSubStrings [i] [j].seperator = 0; s.strings.seqArcSubStrings [i][j].isPlaceHolder = false; if (s.seqArcSubRecord[i].offsets[j] == 0) { s.strings.seqArcSubStrings [i][j].isPlaceHolder = true; } } } //Bank s.strings.bankStrings = new NitroStructures.symbStringEntry[(int)s.bankRecord.offsets.Length]; for (int i = 0; i < s.bankRecord.offsets.Length; i++) { //Read strings. s.strings.bankStrings[i].name = getStringFromOffset(br, s.bankRecord.offsets[i]); s.strings.bankStrings [i].seperator = (byte)0; s.strings.bankStrings [i].isPlaceHolder = false; if (s.bankRecord.offsets[i] == 0) { s.strings.bankStrings [i].isPlaceHolder = true; } } //Wave s.strings.waveStrings = new NitroStructures.symbStringEntry[(int)s.waveRecord.offsets.Length]; for (int i = 0; i < s.waveRecord.offsets.Length; i++) { //Read strings. s.strings.waveStrings[i].name = getStringFromOffset(br, s.waveRecord.offsets[i]); s.strings.waveStrings [i].seperator = (byte)0; s.strings.waveStrings [i].isPlaceHolder = false; if (s.waveRecord.offsets[i] == 0) { s.strings.waveStrings [i].isPlaceHolder = true; } } //Player s.strings.playerStrings = new NitroStructures.symbStringEntry[(int)s.playerRecord.offsets.Length]; for (int i = 0; i < s.playerRecord.offsets.Length; i++) { //Read strings. s.strings.playerStrings[i].name = getStringFromOffset(br, s.playerRecord.offsets[i]); s.strings.playerStrings [i].seperator = (byte)0; s.strings.playerStrings [i].isPlaceHolder = false; if (s.playerRecord.offsets[i] == 0) { s.strings.playerStrings [i].isPlaceHolder = true; } } //Group s.strings.groupStrings = new NitroStructures.symbStringEntry[(int)s.groupRecord.offsets.Length]; for (int i = 0; i < s.groupRecord.offsets.Length; i++) { //Read strings. s.strings.groupStrings[i].name = getStringFromOffset(br, s.groupRecord.offsets[i]); s.strings.groupStrings [i].seperator = (byte)0; s.strings.groupStrings [i].isPlaceHolder = false; if (s.groupRecord.offsets[i] == 0) { s.strings.groupStrings [i].isPlaceHolder = true; } } //Player2 s.strings.player2Strings = new NitroStructures.symbStringEntry[(int)s.player2Record.offsets.Length]; for (int i = 0; i < s.player2Record.offsets.Length; i++) { //Read strings. s.strings.player2Strings[i].name = getStringFromOffset(br, s.player2Record.offsets[i]); s.strings.player2Strings [i].seperator = (byte)0; s.strings.player2Strings [i].isPlaceHolder = false; if (s.player2Record.offsets[i] == 0) { s.strings.player2Strings [i].isPlaceHolder = true; } } //Strm s.strings.strmStrings = new NitroStructures.symbStringEntry[(int)s.strmRecord.offsets.Length]; for (int i = 0; i < s.strmRecord.offsets.Length; i++) { //Read strings. s.strings.strmStrings[i].name = getStringFromOffset(br, s.strmRecord.offsets[i]); s.strings.strmStrings [i].seperator = (byte)0; s.strings.strmStrings [i].isPlaceHolder = false; if (s.strmRecord.offsets[i] == 0) { s.strings.strmStrings [i].isPlaceHolder = true; } } //Return file. return(s); }