/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mushroomButton_Click(object sender, EventArgs e) { var entries = _entry.Scripts; SEMScript[] newEntries = new SEMScript[((entries.Length - 1) * 3) + 1]; newEntries[0] = entries[0]; for (int i = 0; i < entries.Length - 1; i++) { var entry = entries[1 + i]; // normal entry newEntries[1 + i * 3] = entry; Console.WriteLine($"{1 + i} -> {1 + i * 3}"); // mushroom small -350 short small_pitch = -350; byte[] small_pitch_command = new byte[] { 0x0C, 0x00, (byte)((small_pitch >> 8) & 0xFF), (byte)((small_pitch) & 0xFF) }; var small = new SEMScript(); small.Name = entry.Name + "_small"; small.CommandData = new byte[entry.CommandData.Length + 4]; Array.Copy(entry.CommandData, 0, small.CommandData, 0, 8); Array.Copy(small_pitch_command, 0, small.CommandData, 8, 4); Array.Copy(entry.CommandData, 8, small.CommandData, 12, entry.CommandData.Length - 8); newEntries[1 + i * 3 + 1] = small; // mushroom big 450 short big_pitch = 450; byte[] big_pitch_command = new byte[] { 0x0C, 0x00, (byte)((big_pitch >> 8) & 0xFF), (byte)((big_pitch) & 0xFF) }; var big = new SEMScript(); big.Name = entry.Name + "_big"; big.CommandData = new byte[entry.CommandData.Length + 4]; Array.Copy(entry.CommandData, 0, big.CommandData, 0, 8); Array.Copy(big_pitch_command, 0, big.CommandData, 8, 4); Array.Copy(entry.CommandData, 8, big.CommandData, 12, entry.CommandData.Length - 8); newEntries[1 + i * 3 + 2] = big; } _entry.Scripts = newEntries; RefreshEntry(); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static List <SEMEntry> ReadSEMFile(string filePath, bool loadSoundBanks, MEX_Data mexData = null) { var Entries = new List <SEMEntry>(); Dictionary <int, SSM> indexToSSM = new Dictionary <int, SSM>(); if (loadSoundBanks) { foreach (var f in Directory.GetFiles(Path.GetDirectoryName(filePath))) { if (f.ToLower().EndsWith(".ssm")) { var ssm = new SSM(); ssm.Open(f); indexToSSM.Add(ssm.StartIndex, ssm); } } } //if (!loadSoundBanks) // return Entries; using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open))) { r.BigEndian = true; r.Seek(8); var entryCount = r.ReadInt32(); var offsetTableStart = r.Position + (entryCount + 1) * 4; for (uint i = 0; i < entryCount; i++) { SEMEntry e = new SEMEntry(); Entries.Add(e); r.Seek(0x0C + i * 4); var startIndex = r.ReadInt32(); var endIndex = r.ReadInt32(); var ssmStartIndex = int.MaxValue; for (uint j = 0; j < endIndex - startIndex; j++) { SEMScript s = new SEMScript(); r.Seek((uint)(offsetTableStart + startIndex * 4 + j * 4)); var dataOffsetStart = r.ReadUInt32(); var dataOffsetEnd = r.ReadUInt32(); if (dataOffsetEnd == 0) { dataOffsetEnd = (uint)r.Length; } r.Seek(dataOffsetStart); s.CommandData = r.ReadBytes((int)(dataOffsetEnd - dataOffsetStart)); e.AddScript(s); ssmStartIndex = Math.Min(ssmStartIndex, s.SoundCommandIndex); } if (loadSoundBanks && indexToSSM.ContainsKey(ssmStartIndex)) { e.SoundBank = indexToSSM[ssmStartIndex]; if (mexData != null) { var index = mexData.SSMTable.SSM_SSMFiles.Array.ToList().FindIndex(s => s.Value.Equals(e.SoundBank.Name)); if (index != -1) { e.SoundBank.GroupFlags = mexData.SSMTable.SSM_LookupTable[index].EntireFlag; e.SoundBank.Flag = mexData.SSMTable.SSM_BufferSizes[index].Flag; } } foreach (var v in e.Scripts) { v.SoundCommandIndex -= ssmStartIndex; } } } } return(Entries); }
/// <summary> /// /// </summary> /// <param name="pack"></param> /// <param name="fighter"></param> /// <param name="editor"></param> /// <returns>Dictionary to maps old sound id values to new values</returns> private void ImportSoundData(ZipFile pack, MEXFighterEntry fighter, string semFile) { Console.WriteLine($"Importing Sound Data..."); var root = Path.GetDirectoryName(MainForm.Instance.FilePath); // Load SEM File SemEntries = SEM.ReadSEMFile(semFile, true, editor._data); // narrator call----------------------------------------------- var narratorScript = @".SFXID : (id) .REVERB : 48 .PRIORITY : 15 .UNKNOWN06 : 229 .END : 0"; var narr = pack["Sound/narrator.dsp"]; var nameBank = SemEntries.Find(e => e.SoundBank?.Name == "nr_name.ssm"); if (narr != null && nameBank != null) { var narsound = new DSP(); narsound.FromFormat(GetBytes(narr), "dsp"); var index = nameBank.SoundBank.Sounds.Length; nameBank.SoundBank.AddSound(narsound); var script = new SEMScript(); SEM.CompileSEMScript(narratorScript.Replace("(id)", index.ToString()), out script.CommandData); var scriptIndex = nameBank.Scripts.Length; nameBank.AddScript(script); fighter.AnnouncerCall = scriptIndex + SemEntries.IndexOf(nameBank) * 10000; Console.WriteLine("Imported Announcer Call"); } // Create and import SSM----------------------------------------------- var semYAML = pack["Sound/sem.yaml"]; var ssmFile = pack["Sound/sound.ssm"]; if (semYAML != null) { using (MemoryStream zos = new MemoryStream()) { semYAML.Extract(zos); zos.Position = 0; using (StreamReader r = new StreamReader(zos)) { var semEntry = SEMEntry.Deserialize(r.ReadToEnd()); if (ssmFile != null) { var ssmName = fighter.NameText.ToLower() + ".ssm"; semEntry.SoundBank = new SSM(); using (MemoryStream ssmStream = new MemoryStream()) { ssmFile.Extract(ssmStream); ssmStream.Position = 0; semEntry.SoundBank.Open(ssmName, ssmStream); } var ssmFilePath = Path.Combine(root, "audio\\us\\" + ssmName); File.WriteAllBytes(ssmFilePath, GetBytes(ssmFile)); } fighter.SSMIndex = SemEntries.Count; SemEntries.Add(semEntry); } } } // Import Victory Theme var victory = pack["Sound/victory.hps"]; if (victory != null) { var ffname = $"ff_{fighter.NameText.ToLower()}.hps"; fighter.VictoryThemeID = editor.MusicControl.AddMusic(new HSD_String() { Value = ffname }); var fffilePath = Path.Combine(root, "audio\\" + ffname); File.WriteAllBytes(fffilePath, GetBytes(victory)); } }