/* Sets sound effect id for string at index */ public void SetSoundEffectID(int id, byte flag) { if (id < 0 || id >= StringFlags.Count) { return; } BMGFlags flg = StringFlags[id]; flg.SetFlag(4, flag); StringFlags[id] = flg; }
/* Reads BMG file */ private void Read() { Data.IsBigEndian = true; //Need these for later UInt16 numMes = 0; nSize = 0; infUnk1 = 0; infUnk2 = 0; UInt32[] strOffsets = null; BMGFlags[] strFlags = null; //Load disposable header information string magic = Data.ReadString(file, 8); if (magic != MAGIC) { throw new FileLoadException("Invalid file type."); } UInt32 size = Data.ReadUInt32(file); UInt32 sectioncount = Data.ReadUInt32(file); headUnknown = Data.ReadUInt32(file); file.Seek(12, SeekOrigin.Current); //Skip over null bytes //Clear tables StringTable.Clear(); StringFlags.Clear(); //Loop through sections bool inf1 = false; for (int i = 0; i < sectioncount; i++) { if (file.Position % 32 != 0) { file.Seek(((file.Position / 32) + 1) * 32, SeekOrigin.Begin); } string secmagic = Data.ReadString(file, 4); UInt32 secsize = Data.ReadUInt32(file); switch (secmagic) { case "INF1": //Read INF1 section if (inf1) { throw new FileLoadException("More than one index table in file."); } numMes = Data.ReadUInt16(file); nSize = Data.ReadUInt16(file); infUnk1 = Data.ReadUInt16(file); infUnk2 = Data.ReadUInt16(file); switch (nSize) { case 12: strOffsets = new UInt32[numMes]; strFlags = new BMGFlags[numMes]; for (int j = 0; j < numMes; j++) { strOffsets[j] = Data.ReadUInt32(file); strFlags[j] = new BMGFlags(file); } break; case 8: strOffsets = new UInt32[numMes]; strFlags = new BMGFlags[numMes]; for (int j = 0; j < numMes; j++) { strOffsets[j] = Data.ReadUInt32(file); List <byte> list = new List <byte>(); list.AddRange(BitConverter.GetBytes(Data.ReadUInt32(file))); list.AddRange(new byte[4]); strFlags[j] = new BMGFlags(list.ToArray()); } break; case 4: strOffsets = new UInt32[numMes]; strFlags = new BMGFlags[numMes]; for (int j = 0; j < numMes; j++) { strOffsets[j] = Data.ReadUInt32(file); strFlags[j] = new BMGFlags(new byte[8]); } break; default: throw new NotImplementedException("Unknown index table type."); } inf1 = true; break; case "DAT1": //Read DAT1 section if (!inf1) { throw new FileLoadException("String pool located too early in file."); } long datOffset = file.Position; for (int j = 0; j < numMes; j++) { //Read all strings and save string data string str = ""; file.Seek(datOffset + strOffsets[j], SeekOrigin.Begin); long end = 0; if (j == numMes - 1) { end = file.Length - datOffset; } else { end = strOffsets[j + 1]; } //Read string like this, because I still don't know SMS escape codes while (file.Position < datOffset + end - 1) { str += Data.ReadChar(file); } Data.ReadByte(file); //Clean up string if (j == numMes - 1) { while (str.Length > 0 && str[str.Length - 1] == '\0') { str = str.Substring(0, str.Length - 1); } } StringTable.Add(str); StringFlags.Add(strFlags[j]); } break; default: throw new NotImplementedException("Unknown BMG section."); } } }