/// <summary> /// Write a key region. /// </summary> /// <param name="bw">The writer.</param> /// <param name="key">Key region.</param> public void WriteKeyRegion(BinaryDataWriter bw, IKeyRegion key, FileWriter FileWriter) { //Instrument is a new structure. FileWriter.StartStructure(bw); //Key region type reference. FileWriter.InitReference(bw, "VelType"); //Get the type of reference. switch (key.GetKeyRegionType()) { //Direct. case KeyRegionType.Direct: FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Direct, "VelType"); break; //Index. case KeyRegionType.Index: FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Index, "VelType"); break; //Range. case KeyRegionType.Range: FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Range, "VelType"); break; } //Key region is a new structure. FileWriter.StartStructure(bw); //Switch the type of reference. switch (key.GetKeyRegionType()) { //Direct. case KeyRegionType.Direct: //Direct. DirectKeyRegion d = (DirectKeyRegion)key; //Write velocity region reference. FileWriter.InitReference(bw, "VelRegion"); //Null region. if (d.VelocityRegion == null) { FileWriter.CloseNullReference(bw, "VelRegion"); } //Not null. else { //Close the reference. FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_VelocityRegion, "VelRegion"); //Write velocity region. WriteVelocityInfo(bw, d.VelocityRegion); } break; //Ranged. case KeyRegionType.Range: //Set range info. RangeKeyRegion ran = (RangeKeyRegion)key; //Write stuff. bw.Write((byte)ran.StartVelocity); bw.Write((byte)ran.EndVelocity); bw.Write((UInt16)0); //Init each reference. for (int j = 0; j < ran.VelocityCount; j++) { FileWriter.InitReference(bw, "RanKey" + j); } //Write each key region. for (int j = 0; j < ran.VelocityCount; j++) { //Null region. if (ran[j] == null) { FileWriter.CloseNullReference(bw, "RanKey" + j); } //Write key region. else { //Velocity region reference. FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_VelocityRegion, "RanKey" + j); //Write the velocity region. WriteVelocityInfo(bw, ran[j]); } } break; //Index. case KeyRegionType.Index: //Set index info. IndexKeyRegion ind = (IndexKeyRegion)key; //Write the table of indices. bw.Write((uint)ind.Count); for (int j = 0; j < ind.Count; j++) { bw.Write((byte)ind.Keys.ElementAt(j)); } //Write padding. FileWriter.Align(bw, 4); //Init each index reference. for (int j = 0; j < ind.Count; j++) { FileWriter.InitReference(bw, "IndKey" + j); } //Write each index. for (int j = 0; j < ind.Count; j++) { //Null index. if (ind.Values.ElementAt(j) == null) { FileWriter.CloseNullReference(bw, "IndKey" + j); } //Index exist. else { //Close reference. FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_VelocityRegion, "IndKey" + j); //Write the velocity region. WriteVelocityInfo(bw, ind.Values.ElementAt(j)); } } break; } //End the key region. FileWriter.EndStructure(); //End the key region structure. FileWriter.EndStructure(); }
/// <summary> /// Write the sound info. /// </summary> /// <param name="bw">The writer.</param> /// <param name="w">File writer.</param> /// <param name="a">The sound archive.</param> /// <param name="strings">Strings.</param> public void WriteSoundInfo(BinaryDataWriter bw, FileWriter w, SoundArchive a, List <string> strings) { //Keep track of position. long pos = bw.Position; //Write data. if (File != null) { bw.Write((uint)File.FileId); } else { bw.Write((uint)0xFFFFFFFF); } new Id(SoundTypes.Player, (uint)a.Players.IndexOf(Player)).Write(ref bw); bw.Write(Volume); bw.Write(RemoteFilter); bw.Write((ushort)0); w.InitReference(bw, "ToDetRef"); //3d info offset. long threeDeeInfoOffOff = bw.Position; //New flags. Dictionary <int, uint> f = new Dictionary <int, uint>(); //Write string data. if (a.CreateStrings && Name != null) { f.Add(0, (uint)strings.IndexOf(Name)); } //Other flags. f.Add(1, (uint)(((byte)PanCurve << 8) | (byte)PanMode)); f.Add(2, (uint)(((byte)PlayerActorId << 8) | (byte)PlayerPriority)); //Get 3d info offset offset. threeDeeInfoOffOff += (a.CreateStrings && Name != null ? 0x10 : 0xC); if (Sound3dInfo != null) { f.Add(8, 0); } //Front bypass. f.Add(17, (uint)(IsFrontBypass ? 1 : 0)); //User parameters. if (UserParamsEnabled[0]) { f.Add(31, UserParameter[0]); } if (UserParamsEnabled[1]) { f.Add(30, UserParameter[1]); } if (UserParamsEnabled[2]) { f.Add(29, UserParameter[2]); } if (UserParamsEnabled[3]) { f.Add(28, UserParameter[3]); } //Write the flags. new FlagParameters(f).Write(ref bw); //Write the 3d info. if (Sound3dInfo != null) { long newPos = bw.Position; bw.Position = threeDeeInfoOffOff; bw.Write((uint)(newPos - pos)); bw.Position = newPos; //Flags. uint tDFlags = 0; tDFlags += (uint)(Sound3dInfo.Volume ? 0b1 : 0); tDFlags += (uint)(Sound3dInfo.Priority ? 0b10 : 0); tDFlags += (uint)(Sound3dInfo.Pan ? 0b100 : 0); tDFlags += (uint)(Sound3dInfo.Span ? 0b1000 : 0); tDFlags += (uint)(Sound3dInfo.Filter ? 0b10000 : 0); bw.Write(tDFlags); //Other info. bw.Write(Sound3dInfo.AttenuationRate); bw.Write((byte)Sound3dInfo.AttenuationCurve); bw.Write(Sound3dInfo.DopplerFactor); bw.Write((ushort)0); bw.Write((uint)0); //For 'F' type. if (FileWriter.GetWriteModeChar(a.WriteMode) == 'F') { bw.Write((uint)(Sound3dInfo.UnknownFlag ? 1 : 0)); } } }
/// <summary> /// Write a bank file. /// </summary> /// <param name="writeMode">Write mode.</param> /// <param name="bw">The writer.</param> public void Write(WriteMode writeMode, BinaryDataWriter bw) { //Set the write mode. this.writeMode = writeMode; //Init the bank file. FileWriter FileWriter = new FileWriter(); FileWriter.InitFile(bw, writeMode, "BNK", 1, Version); //Init info block. FileWriter.InitBlock(bw, ReferenceTypes.BNK_Block_Info, "INFO"); //Init the reference to the wave id table. FileWriter.InitReference(bw, "WaveIdTableRef"); //Init the reference to the instrument reference table. FileWriter.InitReference(bw, "InstrumentReferenceTableRef"); //Write the instrument reference table. if (Instruments != null) { //Write the reference. FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "InstrumentReferenceTableRef"); //Reference table is a structure. FileWriter.StartStructure(bw); //Init the instrument reference table. FileWriter.InitReferenceTable(bw, Instruments.Count, "InstrumentReferenceTable"); //Write each instrument. for (int i = 0; i < Instruments.Count; i++) { //If instrument is null. if (Instruments[i] == null) { //Write the null reference. FileWriter.AddReferenceTableNullReferenceWithType(ReferenceTypes.BNK_Info_Null, "InstrumentReferenceTable"); } //Instrument is not null. else { //Add reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.BNK_Info_Instrument, "InstrumentReferenceTable"); //Instrument is a new structure. FileWriter.StartStructure(bw); //Instrument type reference. FileWriter.InitReference(bw, "InstType"); //Get the type of reference. switch (Instruments[i].GetInstrumentType()) { //Direct. case InstrumentType.Direct: FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Direct, "InstType"); break; //Index. case InstrumentType.Index: FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Index, "InstType"); break; //Range. case InstrumentType.Range: FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Range, "InstType"); break; } //Instrument is a new structure. FileWriter.StartStructure(bw); //Switch the type of reference. switch (Instruments[i].GetInstrumentType()) { //Direct. case InstrumentType.Direct: //Direct. DirectInstrument d = ((DirectInstrument)Instruments[i]); //Write key region reference. FileWriter.InitReference(bw, "KeyRegion"); //Null region. if (d.KeyRegion == null) { FileWriter.CloseNullReference(bw, "KeyRegion"); } //Not null. else { //Close the reference. FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_KeyRegion, "KeyRegion"); //Write key region. WriteKeyRegion(bw, d.KeyRegion, FileWriter); } break; //Ranged. case InstrumentType.Range: //Set range info. RangeInstrument ran = (RangeInstrument)Instruments[i]; //Write stuff. bw.Write((byte)ran.StartNote); bw.Write((byte)ran.EndNote); bw.Write((UInt16)0); //Init each reference. for (int j = 0; j < ran.NoteCount; j++) { FileWriter.InitReference(bw, "Ran" + j); } //Write each key region. for (int j = 0; j < ran.NoteCount; j++) { //Null region. if (ran[j] == null) { FileWriter.CloseNullReference(bw, "Ran" + j); } //Write key region. else { //Key region reference. FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_KeyRegion, "Ran" + j); //Write the key region. WriteKeyRegion(bw, ran[j], FileWriter); } } break; //Index. case InstrumentType.Index: //Set index data. IndexInstrument ind = (IndexInstrument)Instruments[i]; //Write the table of indices. bw.Write((uint)ind.Count); for (int j = 0; j < ind.Count; j++) { bw.Write((byte)ind.Keys.ElementAt(j)); } //Write padding. FileWriter.Align(bw, 4); //Init each index reference. for (int j = 0; j < ind.Count; j++) { FileWriter.InitReference(bw, "Ind" + j); } //Write each index. for (int j = 0; j < ind.Count; j++) { //Null index. if (ind.Values.ElementAt(j) == null) { FileWriter.CloseNullReference(bw, "Ind" + j); } //Index exist. else { //Close reference. FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_KeyRegion, "Ind" + j); //Write the key region. WriteKeyRegion(bw, ind.Values.ElementAt(j), FileWriter); } } break; } //End the instrument. FileWriter.EndStructure(); //End the instrument structure. FileWriter.EndStructure(); } } //Close the instrument reference table. FileWriter.CloseReferenceTable(bw, "InstrumentReferenceTable"); //End the instrument reference table structure. FileWriter.EndStructure(); } else { //Write null offset. FileWriter.CloseNullReference(bw, "InstrumentReferenceTableRef"); } //Write the wave id table. if (Waves != null) { //Write the reference. FileWriter.CloseReference(bw, ReferenceTypes.Tables, "WaveIdTableRef"); //Write the wave id table. bw.Write((uint)Waves.Count); for (int i = 0; i < Waves.Count; i++) { Id warId = new Id(SoundTypes.WaveArchive, (uint)Waves[i].WarIndex); warId.Write(ref bw); bw.Write((uint)Waves[i].WaveIndex); } } //Null wave ids. else { FileWriter.CloseNullReference(bw, "WaveIdTableRef"); } //Close the info block. FileWriter.CloseBlock(bw); //Close the bank file. FileWriter.CloseFile(bw); }
/// <summary> /// Write the file. /// </summary> /// <param name="writeMode">Write mode.</param> /// <param name="bw">The writer.</param> public void Write(WriteMode writeMode, BinaryDataWriter bw) { //Set write mode. this.writeMode = writeMode; //Init file. FileWriter FileWriter = new FileWriter(); FileWriter.InitFile(bw, writeMode, "WSD", 1, Version); //Init info block. FileWriter.InitBlock(bw, ReferenceTypes.WAR_Blocks, "INFO"); //Init wave id table reference. FileWriter.InitReference(bw, "ToWaveIdTableRef"); //Init wave sound data table reference. FileWriter.InitReference(bw, "ToWaveSoundDataRefTable"); //Close wave id reference table reference. if (Waves != null) { FileWriter.CloseReference(bw, ReferenceTypes.Tables, "ToWaveIdTableRef"); } else { FileWriter.CloseNullReference(bw, "ToWaveIdTableRef"); } //Write the table. if (Waves != null) { //Write count. bw.Write((uint)Waves.Count); //Write each id. for (int i = 0; i < Waves.Count; i++) { //Write id. Id id = new Id(SoundTypes.WaveArchive, (uint)Waves[i].WarIndex); id.Write(ref bw); bw.Write((uint)Waves[i].WaveIndex); } } //Close the wave sound table reference. if (DataItems != null) { FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "ToWaveSoundDataRefTable"); } else { FileWriter.CloseNullReference(bw, "ToWaveSoundDataRefTable"); } //Write the reference table. if (DataItems != null) { //Start structure. FileWriter.StartStructure(bw); //Init the table. FileWriter.InitReferenceTable(bw, DataItems.Count, "WaveSoundDataTable"); //Write each entry. for (int i = 0; i < DataItems.Count; i++) { //Entry is null. if (DataItems[i] == null) { FileWriter.AddReferenceTableNullReference("WaveSoundDataTable"); } //Valid entry. else { //Add the reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_ItemInfos, "WaveSoundDataTable"); //New structure. FileWriter.StartStructure(bw); //Init wave sound info reference. FileWriter.InitReference(bw, "WaveSoundInfoRef"); //Track info reference table reference. FileWriter.InitReference(bw, "TrackInfoRefTableRef"); //Note info reference table reference. FileWriter.InitReference(bw, "NoteInfoRefTableRef"); //Close wave sound info reference. FileWriter.CloseReference(bw, ReferenceTypes.WSF_WaveSoundInfo, "WaveSoundInfoRef"); //Write the wave sound info. Dictionary <int, uint> flags = new Dictionary <int, uint>(); //Flag list: /* * 0 - Pan info. 0x0000SSPP S-Span P-Pan. * 1 - Pitch, float. * 2 - Biquad and LPF info. 0x00VVTTLL L-LPF T-Biquad Type V-Biquad Value. * 8 - Offset to send value. * 9 - Offset to ADSHR curve offset. */ //Pan info. uint panInfo = 0; panInfo += (uint)(DataItems[i].SurroundPan << 8); panInfo += (uint)DataItems[i].Pan; flags.Add(0, panInfo); //Pitch. flags.Add(1, BitConverter.ToUInt32(BitConverter.GetBytes(DataItems[i].Pitch), 0)); //Biquad and LPF. if (DataItems[i].BiquadType != WaveSoundDataItem.EBiquadType.Unused) { uint bL = 0; bL += (uint)(DataItems[i].BiquadValue << 16); bL += (uint)((byte)DataItems[i].BiquadType << 8); bL += (uint)DataItems[i].LpfFrequency; flags.Add(2, bL); } //Offset to send value. flags.Add(8, (uint)(DataItems[i].BiquadType != WaveSoundDataItem.EBiquadType.Unused ? 0x18 : 0x14)); //Offset to ADSHR curve offset. flags.Add(9, (uint)(DataItems[i].BiquadType != WaveSoundDataItem.EBiquadType.Unused ? 0x20 : 0x1C)); //Write flag sound info. FlagParameters f = new FlagParameters(flags); f.Write(ref bw); //Send value for 3. if (writeMode == WriteMode.Cafe || writeMode == WriteMode.NX) { bw.Write(DataItems[i].SendValue[0]); bw.Write((byte)3); bw.Write(DataItems[i].SendValue[1]); bw.Write(DataItems[i].SendValue[2]); bw.Write(DataItems[i].SendValue[3]); bw.Write(new byte[3]); } //Send value for 2. else { bw.Write(DataItems[i].SendValue[0]); bw.Write((byte)2); bw.Write(DataItems[i].SendValue[1]); bw.Write(DataItems[i].SendValue[2]); bw.Write(new byte[4]); } //Write the ADSHR curve. bw.Write((UInt32)0); bw.Write((UInt32)8); bw.Write(DataItems[i].Attack); bw.Write(DataItems[i].Decay); bw.Write(DataItems[i].Sustain); bw.Write(DataItems[i].Hold); bw.Write(DataItems[i].Release); bw.Write(new byte[3]); //Close track info reference table reference. if (DataItems[i].NoteEvents == null) { FileWriter.CloseNullReference(bw, "TrackInfoRefTableRef"); } else { //Close it properly. FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "TrackInfoRefTableRef"); //New structure. FileWriter.StartStructure(bw); //Init the track info reference table. FileWriter.InitReferenceTable(bw, DataItems[i].NoteEvents.Count, "TrackInfoRefTable"); //Write each track. for (int j = 0; j < DataItems[i].NoteEvents.Count; j++) { //Add reference. (There is ambiguity between these note events, and the ones below. Should be fine? if (DataItems[i].NoteEvents[j] == null) { FileWriter.AddReferenceTableNullReference("TrackInfoRefTable"); } else { //Add reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_TrackInfo, "TrackInfoRefTable"); //Start structure. FileWriter.StartStructure(bw); //Reference to data. FileWriter.InitReference(bw, "TracksRef"); //Write the track reference table. FileWriter.CloseReference(bw, 0, "TracksRef"); //Start structure. FileWriter.StartStructure(bw); //Reference table. FileWriter.InitReferenceTable(bw, DataItems[i].NoteEvents[j].Count, "Tracks"); //Write each track. for (int k = 0; k < DataItems[i].NoteEvents[j].Count; k++) { //Write the info. if (DataItems[i].NoteEvents[j][k] == null) { FileWriter.AddReferenceTableNullReference("Tracks"); } else { //Proper reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_NoteEvent, "Tracks"); //Write data. bw.Write(DataItems[i].NoteEvents[j][k].Position); bw.Write(DataItems[i].NoteEvents[j][k].Length); bw.Write((uint)DataItems[i].NoteEvents[j][k].NoteIndex); bw.Write((uint)0); } } //Close reference table. FileWriter.CloseReferenceTable(bw, "Tracks"); //End structure. FileWriter.EndStructure(); //End structure. (Yes, again. There is that pointless reference from earlier.) FileWriter.EndStructure(); } } //Close the track info reference table. FileWriter.CloseReferenceTable(bw, "TrackInfoRefTable"); //End structure. FileWriter.EndStructure(); } //Close note info reference table reference. if (DataItems[i].Notes == null) { FileWriter.CloseNullReference(bw, "NoteInfoRefTableRef"); } else { //Close it properly. FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "NoteInfoRefTableRef"); //New structure. FileWriter.StartStructure(bw); //Init the note info reference table. FileWriter.InitReferenceTable(bw, DataItems[i].Notes.Count, "Notes"); for (int j = 0; j < DataItems[i].Notes.Count; j++) { //Add reference. if (DataItems[i].Notes[j] == null) { FileWriter.AddReferenceTableNullReference("Notes"); } else { //Add reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_NoteInfo, "Notes"); //Write data. TEMPORARY UNTIL DATA IS FOUND. bw.Write((uint)DataItems[i].Notes[j].WaveIndex); bw.Write((uint)0); } } //Close reference table. FileWriter.CloseReferenceTable(bw, "Notes"); //End structure. FileWriter.EndStructure(); } } } //Close the table. FileWriter.CloseReferenceTable(bw, "WaveSoundDataTable"); //End structure. FileWriter.EndStructure(); } //Close info block. FileWriter.CloseBlock(bw); //Close file. FileWriter.CloseFile(bw); }