/// <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, "GRP", Version > new FileWriter.Version(1, 0, 0) ? 3 : 2, Version); //Info block. FileWriter.InitBlock(bw, ReferenceTypes.GRP_Block_Info, "INFO"); //Reference table to group items. FileWriter.InitReferenceTable(bw, SoundFiles.Count, "FileRefs"); //Write each sound thing. for (int i = 0; i < SoundFiles.Count; i++) { //Null. if (SoundFiles[i] == null) { FileWriter.AddReferenceTableNullReference("FileRefs"); } //Exists. else { //Add reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.GRP_Info_Item, "FileRefs"); //Write data. bw.Write((uint)SoundFiles[i].FileId); FileWriter.InitSizedReference(bw, "FileRef" + i); } } //Align. FileWriter.Align(bw, 0x20); //Close reference table. FileWriter.CloseReferenceTable(bw, "FileRefs"); //Close info block. FileWriter.CloseBlock(bw); //File block. FileWriter.InitBlock(bw, ReferenceTypes.GRP_Block_File, "FILE"); //Align to 0x20 bytes. FileWriter.Align(bw, 0x20); //Write each file and align. for (int i = 0; i < SoundFiles.Count; i++) { //Null. if (SoundFiles[i] == null) { FileWriter.CloseSizedNullReference(bw, "FileRef" + i); } //Not null. else { //If the file is embedded. if (SoundFiles[i].Embed) { //Keep track of position. long pos = bw.Position; //Write file. FileWriter.WriteFile(bw, SoundFiles[i].File, 0x20, writeMode); //Close reference. FileWriter.CloseSizedReference(bw, ReferenceTypes.General, (uint)(bw.Position - pos), "FileRef" + i); } //Don't write data. else { FileWriter.CloseSizedNullReference(bw, "FileRef" + i); } } } //Close file block. FileWriter.CloseBlock(bw); //Extra info exists if the version is greater than one. if (Version > new FileWriter.Version(1, 0, 0)) { //Extra info block. FileWriter.InitBlock(bw, ReferenceTypes.GRP_Block_Infx, "INFX"); //Ex table. FileWriter.InitReferenceTable(bw, ExtraInfo.Count, "Ex"); //Write each info entry. for (int i = 0; i < ExtraInfo.Count; i++) { //Null. if (ExtraInfo[i] == null) { FileWriter.AddReferenceTableNullReference("Ex"); } //Not null. else { //Add reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.GRP_Infx_Item, "Ex"); //Write the data. InfoExEntry e = ExtraInfo[i]; UInt32 flags = 0; switch (e.LoadFlags) { case InfoExEntry.ELoadFlags.All: flags = 0xFFFFFFFF; break; case InfoExEntry.ELoadFlags.Bank: flags = 0b100; break; case InfoExEntry.ELoadFlags.BankAndWarc: flags = 0b1100; break; case InfoExEntry.ELoadFlags.Seq: flags = 0b1; break; case InfoExEntry.ELoadFlags.SeqAndBank: flags = 0b101; break; case InfoExEntry.ELoadFlags.SeqAndWarc: flags = 0b1100; break; case InfoExEntry.ELoadFlags.Warc: flags = 0b1000; break; case InfoExEntry.ELoadFlags.Wsd: flags = 0b10; break; } //Get type. byte type = 0; switch (e.ItemType) { case InfoExEntry.EItemType.Bank: type = SoundTypes.Bank; break; case InfoExEntry.EItemType.Sound: type = SoundTypes.Sound; break; case InfoExEntry.EItemType.SequenceSetOrWaveData: type = SoundTypes.SoundGroup; break; case InfoExEntry.EItemType.WaveArchive: type = SoundTypes.WaveArchive; break; } //Item id. Id id = new Id(type, (uint)e.ItemIndex); id.Write(ref bw); //Write flags. bw.Write(flags); } } //Close Ex table. FileWriter.CloseReferenceTable(bw, "Ex"); //Close extra info block. FileWriter.CloseBlock(bw); } //Close file. FileWriter.CloseFile(bw); }
/// <summary> /// Get the file extension. /// </summary> /// <returns>The file extension.</returns> public string GetExtension() { return(("B" + FileWriter.GetWriteModeChar(writeMode) + "GRP").ToLower()); }
/// <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); }