Switch-Toolbox/Switch_FileFormatsMain/FileFormats/Audio/Archives/BARS.cs
KillzXGaming e531a779ed Small fixes and additions
Fixed mesh name exporting for assimp.
Fixed clearing models for bfres.
Fixed limit skin count setting.
Fixed material index breaking if a material is removed for bfres.
Update the vertex data properly if a model is imported as new.
Added AMTA editing for BARS.
Added audio player for BARS.
2019-06-07 16:31:13 -04:00

299 lines
9.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Switch_Toolbox.Library;
using Switch_Toolbox.Library.IO;
using Switch_Toolbox.Library.Forms;
using BarsLib;
using VGAudio.Formats;
using VGAudio;
using VGAudio.Containers.NintendoWare;
using VGAudio.Containers.Wave;
using NAudio.Wave;
namespace FirstPlugin
{
public class BARS : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Audio;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Sound Archive" };
public string[] Extension { get; set; } = new string[] { "*.bars" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(Stream stream)
{
using (var reader = new FileReader(stream, true))
{
return reader.CheckSignature(4, "BARS");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public override void OnClick(TreeView treeview)
{
STPropertyGrid editor = (STPropertyGrid)LibraryGUI.Instance.GetActiveContent(typeof(STPropertyGrid));
if (editor == null)
{
editor = new STPropertyGrid();
LibraryGUI.Instance.LoadEditor(editor);
}
var prop = new BarsProperty(bars);
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadProperty(prop, null);
}
public class BarsProperty
{
public int AudioCount { get; private set; }
public BarsProperty(BarsLib.BARS bars)
{
AudioCount = bars.AmtaList.Count;
}
}
public class AudioEntry : TreeNodeCustom
{
public AudioType Type;
public byte[] Data;
public AudioEntry()
{
ContextMenu = new ContextMenu();
MenuItem export = new MenuItem("Export");
ContextMenu.MenuItems.Add(export);
export.Click += Export;
MenuItem replace = new MenuItem("Replace");
ContextMenu.MenuItems.Add(replace);
replace.Click += Replace;
}
public void SetupMusic()
{
if (Type == AudioType.Bfwav)
{
ImageKey = "bfwav";
SelectedImageKey = "bfwav";
}
else if (Type == AudioType.Bfstp)
{
ImageKey = "bfstp";
SelectedImageKey = "bfstp";
}
else
{
ImageKey = "fileBlank";
SelectedImageKey = "fileBlank";
}
}
public AudioData GetAudioData()
{
BCFstmReader reader = new BCFstmReader();
return reader.Read(Data);
}
public byte[] BfwavToWav()
{
MemoryStream mem = new MemoryStream();
WaveWriter writer = new WaveWriter();
AudioData audioData = GetAudioData();
writer.WriteToStream(audioData, mem);
return mem.ToArray();
}
private void Export(object sender, EventArgs args)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = Text;
sfd.DefaultExt = Path.GetExtension(Text);
sfd.Filter = "All files(*.*)|*.*";
if (sfd.ShowDialog() == DialogResult.OK)
{
File.WriteAllBytes(sfd.FileName, Data);
}
}
private void Replace(object sender, EventArgs args)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.FileName = Text;
ofd.DefaultExt = Path.GetExtension(Text);
ofd.Filter = "All files(*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
Data = File.ReadAllBytes(ofd.FileName);
UpdateEditor();
}
}
public void UpdateEditor()
{
switch (Type)
{
case AudioType.Bfwav:
// ShowHexView();
ShowBfwavPlayer();
break;
default:
ShowHexView();
break;
}
}
private void ShowBfwavPlayer()
{
var audioFile = new VGAdudioFile();
audioFile.LoadAudio(new MemoryStream(Data), new BFWAV());
AudioPlayerPanel editor = (AudioPlayerPanel)LibraryGUI.Instance.GetActiveContent(typeof(AudioPlayerPanel));
if (editor == null)
{
editor = new AudioPlayerPanel();
LibraryGUI.Instance.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadFile(audioFile.audioData, new BFWAV(), true);
}
private void ShowHexView()
{
HexEditor editor = (HexEditor)LibraryGUI.Instance.GetActiveContent(typeof(HexEditor));
if (editor == null)
{
editor = new HexEditor();
LibraryGUI.Instance.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadData(Data);
}
public override void OnClick(TreeView treeview)
{
UpdateEditor();
}
}
private class MetaDataNodeWrapper : TreeNodeCustom
{
public MetaDataNodeWrapper(AMTA amta) { MetaFile = amta; }
public AMTA MetaFile { get; set; }
public override void OnClick(TreeView treeview)
{
STPropertyGrid editor = (STPropertyGrid)LibraryGUI.Instance.GetActiveContent(typeof(STPropertyGrid));
if (editor == null)
{
editor = new STPropertyGrid();
LibraryGUI.Instance.LoadEditor(editor);
}
editor.Text = Text;
editor.Dock = DockStyle.Fill;
editor.LoadProperty(MetaFile.Data, OnPropertyChanged);
}
private void OnPropertyChanged() { }
}
public BarsLib.BARS bars;
public void Load(Stream stream)
{
CanSave = true;
Text = FileName;
bars = new BarsLib.BARS(stream);
Nodes.Add("AMTA");
Nodes.Add("Audio");
for (int i = 0; i < bars.AmtaList.Count; i++)
{
var amtaWrapper = new MetaDataNodeWrapper(bars.AmtaList[i]);
string audioName = bars.AmtaList[i].Name;
amtaWrapper.Text = $"{audioName}.amta";
Nodes[0].Nodes.Add(amtaWrapper);
BARSAudioFile audio = bars.audioList[i];
AudioEntry node = new AudioEntry();
node.Type = audio.AudioType;
node.Data = audio.data;
node.SetupMusic();
if (audio.AudioType == AudioType.Bfwav)
node.Text = audioName + ".bfwav";
else if (audio.AudioType == AudioType.Bfstp)
node.Text = audioName + ".bfstp";
else
node.Text = audioName + ".UNKOWN";
Nodes[1].Nodes.Add(node);
}
ContextMenu = new ContextMenu();
MenuItem save = new MenuItem("Save");
ContextMenu.MenuItems.Add(save);
save.Click += Save;
}
public void Unload()
{
}
private void Save(object sender, EventArgs args)
{
List<IFileFormat> formats = new List<IFileFormat>();
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = Utils.GetAllFilters(formats);
sfd.FileName = FileName;
if (sfd.ShowDialog() == DialogResult.OK)
{
STFileSaver.SaveFileFormat(this, sfd.FileName);
}
}
public byte[] Save()
{
MemoryStream mem = new MemoryStream();
foreach (TreeNode node in Nodes[1].Nodes)
{
for (int i = 0; i < bars.AmtaList.Count; i++)
{
string audioName = bars.AmtaList[i].Name;
if (Path.GetFileNameWithoutExtension(node.Text) == audioName)
{
Console.WriteLine(audioName);
bars.audioList[i].data = ((AudioEntry)node).Data;
}
}
}
bars.Save(mem);
return mem.ToArray();
}
}
}