private static void OperationTex2Png() { string filename = ConsolePath("Full path to .tex file or partial path to txm/txv..?"); if (filename.IsEmpty()) { return; } if (Path.GetExtension(filename).ToLower() == ".txm" || Path.GetExtension(filename).ToLower() == ".txv") { filename = filename.Substring(0, filename.Length - 4); } DelayedStreamCache streams = new DelayedStreamCache(); Txm tex = OpenTex(filename, streams); string path = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileName(filename) + ".ext"); Directory.CreateDirectory(path); for (int i = 0; i < tex.Images.Count; i++) { string file = Path.Combine(path, tex.Images[i].Name); tex.Images[i].PrimaryBitmap.Save(file + ".png", ImageFormat.Png); if (tex.Images[i].SecondaryData != null) { tex.Images[i].SecondaryData.Position = 0; FileStream secondary = new FileStream(file + ".dat", FileMode.Create, FileAccess.Write); Util.StreamCopy(secondary, tex.Images[i].SecondaryData); secondary.Close(); } } streams.Dispose(); }
static void PlatformDetection_DetectDirectory(string path, PlatformList platforms) { if (DetectDirectoryNode != null) { DelayedStreamCache cache = new DelayedStreamCache(); DirectoryNode root = DirectoryNode.FromPath(path, cache, FileAccess.Read, FileShare.Read); DetectDirectoryNode(path, root, platforms); cache.Dispose(); } }
public PlatformData(Engine platform, Game game) { Cache = new DelayedStreamCache(); Session = new Dictionary <string, object>(); Data = new List <FormatData>(); ChangesetAdded = new List <FormatData>(); ChangesetRemoved = new List <FormatData>(); Mutex = new Mutex(); Platform = platform; Game = game; }
private static Txm OpenTex(string filename, DelayedStreamCache streams) { Txm tex; if (File.Exists(filename)) { Stream stream = new CachedReadStream(new FileStream(filename, FileMode.Open, FileAccess.Read)); tex = Tex.Create(stream); streams.AddStream(stream); } else { Stream txmstream = new CachedReadStream(new FileStream(filename + ".txm", FileMode.Open, FileAccess.Read)); Stream txvstream = new CachedReadStream(new FileStream(filename + ".txv", FileMode.Open, FileAccess.Read)); tex = new Txm(txmstream, txvstream); streams.AddStream(txmstream); streams.AddStream(txvstream); } return(tex); }
public void Dispose() { Mutex.WaitOne(); if (Cache != null) { Cache.Dispose(); Cache = null; } foreach (FormatData data in Data) { data.Dispose(); ChangesetRemoved.Add(data); } Data.Clear(); Mutex.ReleaseMutex(); }
public CPK(Stream data) { EndianReader reader = new EndianReader(data, Endianness.BigEndian); EndianReader lereader = new EndianReader(data, Endianness.LittleEndian); if (reader.ReadUInt32() != CpkMagic) { throw new FormatException(); } for (int i = 0; i < 3; i++) { reader.ReadUInt32(); // Little Endian: 0xFF; section size; 0x00; } Header = new UTF(data); if (Header.Rows.Count != 1) { throw new FormatException(); } UTF.Row mainrow = Header.Rows[0]; long tocoffset = (long)(mainrow.FindValue("TocOffset") as UTF.LongValue).Value; long etocoffset = (long)(mainrow.FindValue("EtocOffset") as UTF.LongValue).Value; long itocoffset = (long)(mainrow.FindValue("ItocOffset") as UTF.LongValue).Value; //long dpkitocoffset = (long)(mainrow.FindValue("DpkItoc") as UTF.IntValue).Value; long contentoffset = (long)(mainrow.FindValue("ContentOffset") as UTF.LongValue).Value; uint filecount = (mainrow.FindValue("Files") as UTF.IntValue).Value; UTF.ShortValue version = mainrow.FindValue("Version") as UTF.ShortValue; UTF.IntValue mode = mainrow.FindValue("Mode") as UTF.IntValue; if (version != null) { Version = version.Value; } if (mode != null) { Mode = mode.Value; } reader.Position = tocoffset; if (reader.ReadUInt32() != TocMagic) { throw new FormatException(); } for (int i = 0; i < 3; i++) { reader.ReadUInt32(); // Little Endian: 0xFF; size; 0x00; } ToC = new UTF(data); reader.Position = etocoffset; if (reader.ReadUInt32() != ETocMagic) { throw new FormatException(); } for (int i = 0; i < 3; i++) { reader.ReadUInt32(); // Little Endian: 0xFF; size; 0x00; } EToC = new UTF(data); reader.Position = itocoffset; if (reader.ReadUInt32() != ITocMagic) { throw new FormatException(); } for (int i = 0; i < 3; i++) { reader.ReadUInt32(); // Little Endian: 0xFF; size; 0x00; } IToC = new UTF(data); Cache = new DelayedStreamCache(); Root = new DirectoryNode(); foreach (var filerow in ToC.Rows) { UTF.StringValue dirnamevalue = filerow.FindValue("DirName") as UTF.StringValue; string dirname = string.Empty; if (dirnamevalue != null) { dirname = dirnamevalue.Value; } long offset = (long)(filerow.FindValue("FileOffset") as UTF.LongValue).Value; string filename = (filerow.FindValue("FileName") as UTF.StringValue).Value; uint packedsize = (filerow.FindValue("FileSize") as UTF.IntValue).Value; uint filesize = packedsize; if (Version == 7) // ToGf { offset += tocoffset; } else // Need to check ToG:Wii's version/mode { offset += contentoffset; } UTF.IntValue filesizevalue = filerow.FindValue("ExtractSize") as UTF.IntValue; if (filesizevalue != null) { filesize = filesizevalue.Value; } else // If we must, read the uncompressed size from the internal compressed file itself { data.Position = offset; EndianReader littlereader = new EndianReader(data, Endianness.LittleEndian); if (littlereader.ReadUInt64() == 0) { filesize = littlereader.ReadUInt32() + 0x100; } } DirectoryNode dir = Root.Navigate(dirname, true) as DirectoryNode; Stream substream = new Substream(data, offset, packedsize); try { if (filesize > packedsize) { //throw new Exception(); Stream compressed = substream; substream = new DelayedStream(delegate() { Stream ret = new TemporaryStream(); CpkCompression.Decompress(compressed, ret); ret.Position = 0; return(ret); }); Cache.AddStream(substream); } dir.AddChild(new FileNode(filename, filesize, substream)); } catch { dir.AddChild(new FileNode(filename, packedsize, substream)); } } // TODO: EToc: Groups // TODO: IToc: Attributes }
private static void OperationPackFPS4() { string dirname = ConsolePath("Full path to FPS4 file contents..?"); string filename; if (dirname.EndsWith(".ext")) { filename = dirname.Substring(0, dirname.Length - 4); } else { filename = ConsolePath("Full path to FPS4 archive..?"); } if (!File.Exists(filename)) { Console.WriteLine("FPS4 file does not exist."); return; } Stream stream = new CachedReadStream(new FileStream(filename, FileMode.Open, FileAccess.Read)); FPS4 fps = new FPS4(stream); DelayedStreamCache cache = new DelayedStreamCache(); string[] files = Directory.GetFiles(dirname, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) { string fname = Path.GetFileName(file); FPS4Base.Node node = fps.Base.Nodes.FirstOrDefault(n => n.Filename == fname); Stream data = new FileStream(file, FileMode.Open, FileAccess.Read); cache.AddStream(data); if (node == null) { continue; /* TODO: Only add when we want to * node = new FPS4Base.Node(0, (uint)data.Length, (uint)data.Length, fname, 0, 0, data); * fps.Base.Nodes.Insert((int)fps.Base.Files - 1, node); * fps.Base.Files++; */ } else { node.Data = data; } } fps.Base.Reorder(); Stream ostream = new FileStream(filename + ".new", FileMode.Create, FileAccess.Write); fps.Base.Save(ostream); ostream.Close(); stream.Close(); cache.Dispose(); }
private static void OperationPng2Tex() { string filename = ConsolePath("Full path to tex or txm/txv or png file..?"); if (filename.IsEmpty()) { return; } if (Path.GetExtension(filename).ToLower() == ".txm" || Path.GetExtension(filename).ToLower() == ".txv") { filename = filename.Substring(0, filename.Length - 4); } else if (Path.GetExtension(filename).ToLower() != ".tex") { filename = Path.GetDirectoryName(filename); if (filename.EndsWith(".ext")) { filename = filename.Substring(0, filename.Length - 4); } } DelayedStreamCache streams = new DelayedStreamCache(); Txm tex = OpenTex(filename, streams); Stream txmstream; Stream txvstream; if (File.Exists(filename)) { txmstream = new TemporaryStream(); txvstream = new TemporaryStream(); } else { txmstream = new FileStream(filename + ".txm.new", FileMode.Create); txvstream = new FileStream(filename + ".txv.new", FileMode.Create); } streams.AddStream(txmstream); streams.AddStream(txvstream); string[] files = Directory.GetFiles(filename + ".ext"); files = files.OrderBy(f => f).ToArray(); // Want to make sure the .dat files come before the pngs (hacky, but meh). foreach (string file in files) { string name = Path.GetFileName(file); string basename = Path.GetFileNameWithoutExtension(name); string extension = Path.GetExtension(name); Txm.Image image = tex.Images.FirstOrDefault(i => i.Name == basename); if (image == null) { if (extension != ".dat" && extension != ".png") { continue; } image = new Txm.Image(); image.Name = basename; image.PrimaryEncoding = PixelEncoding.GetEncoding <CI8>(); image.SecondaryData = new MemoryStream(); image.Unknown1 = 1; image.Unknown2 = 2 << 4; image.Unknown3 = 1; tex.Images.Add(image); } Stream stream = new FileStream(file, FileMode.Open); if (extension == ".dat") { image.SecondaryData = new MemoryStream((int)stream.Length); Util.StreamCopy(image.SecondaryData, stream); } else if (extension == ".png") { Bitmap bitmap = new Bitmap(stream); stream.Close(); stream = new MemoryStream(); if (image.SecondaryData is Substream || image.SecondaryData == null) { image.SecondaryData = new MemoryStream(); } image.SecondaryData.Position = 0; try { image.PrimaryEncoding.EncodeImage(stream, bitmap, image.SecondaryData, image.Unknown2 >> 4); } catch (NotImplementedException ex) { if (image.PrimaryEncoding.ID == 0xAAE4) { image.PrimaryEncoding = new ARGB(); image.Unknown1 = 5; image.Unknown2 = 0xa5; image.Unknown3 = 4; } else { image.PrimaryEncoding = PixelEncoding.GetEncoding <CI8>(); image.Unknown1 = 1; image.Unknown2 = 2 << 4; image.Unknown3 = 1; } try { image.PrimaryEncoding.EncodeImage(stream, bitmap, image.SecondaryData, image.Unknown2 >> 4); } catch { throw ex; } } image.Width = (uint)bitmap.Width; image.Height = (uint)bitmap.Height; image.PrimaryData = stream; } streams.AddStream(stream); } tex.Save(txmstream, txvstream); if (File.Exists(filename)) { Stream texstream = new FileStream(filename + ".new", FileMode.Create); streams.AddStream(texstream); FPS4Base fps = new FPS4Base(); fps.DataOffset = 0x60; fps.BlockSize = 0x0C; fps.Files = 3; fps.Flags = FPS4Base.NodeFlags.SectionSize | FPS4Base.NodeFlags.Filesize | FPS4Base.NodeFlags.Offset; fps.Type = new byte[] { 0x74, 0x78, 0x6D, 0x76 }; // "txmv" fps.TypeOffset = 0x40; uint txmlen = (uint)Util.RoundUp(txmstream.Length, 0x20); uint txvlen = (uint)Util.RoundUp(txvstream.Length, 0x20); fps.Nodes.Add(new FPS4Base.Node(0x60, txmlen, (uint)txmstream.Length, "", 0, 0, txmstream)); fps.Nodes.Add(new FPS4Base.Node(0x60 + txmlen, txvlen, (uint)txvstream.Length, "", 0, 0, txvstream)); fps.Nodes.Add(new FPS4Base.Node(0x60 + txmlen + txvlen, 0, 0, "", 0, 0, null)); fps.Save(texstream); } streams.Dispose(); }
private void ReplaceAudioButton_Click(object sender, EventArgs e) { OpenDialog.Multiselect = true; OpenDialog.Title = "Select audio files"; OpenDialog.Filter = "Common Audio Files|*.ogg;*.wav;*.flac;*.mp3;*.aiff;*.ac3|All Files|*"; if (OpenDialog.ShowDialog(this) == DialogResult.Cancel) { return; } bool allogg = true; using (DelayedStreamCache cache = new DelayedStreamCache()) { FormatData data = new TemporaryFormatData(); AudioFormat format = new AudioFormat(); List <string> names = new List <string>(); Stream[] streams = new Stream[OpenDialog.FileNames.Length]; for (int i = 0; i < streams.Length; i++) { string filename = OpenDialog.FileNames[i]; streams[i] = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); cache.AddStream(streams[i]); IDecoder decoder; if (new EndianReader(streams[i], Endianness.BigEndian).ReadUInt32() != OggMagic) { allogg = false; streams[i].Position = 0; decoder = new FFmpegDecoder(streams[i]); } else { decoder = new RawkAudio.Decoder(streams[i], RawkAudio.Decoder.AudioFormat.VorbisOgg); } for (int k = 0; k < decoder.Channels; k++) { names.Add(Path.GetFileName(filename) + " [Channel #" + (k + 1).ToString("0") + "]"); float balance = 0; if (decoder.Channels == 2) { balance = k == 0 ? -1 : 1; } format.Mappings.Add(new AudioFormat.Mapping(0, balance, Platform.InstrumentFromString(Path.GetFileNameWithoutExtension(filename)))); } decoder.Dispose(); streams[i].Position = 0; } if (AudioForm.Show(format, names.ToArray(), this) == DialogResult.Cancel) { return; } foreach (IFormat audioformat in Data.GetFormats(FormatType.Audio)) { foreach (string audiostream in Data.GetStreamNames(audioformat)) { Data.DeleteStream(audiostream); } } if (allogg) { AudioFormatOgg.Instance.Create(data, streams, format); } else { AudioFormatFFmpeg.Instance.Create(data, streams, format); } data.SaveTo(Data); } UpdateAudioSizes(); }
static void Main(string[] args) { string dir = string.Empty; if (args.Length == 2) { dir = args[1]; } else if (args.Length == 1) { dir = args[0] + ".ext"; } else { Console.WriteLine("Usage: wiidiscextractor /path/to/disc.iso /extract/path"); return; } Directory.CreateDirectory(dir); try { if (!Directory.Exists(args[0])) { throw new FormatException(); } DelayedStreamCache cache = new DelayedStreamCache(); DirectoryNode dirn = DirectoryNode.FromPath(args[0], cache, FileAccess.Read, FileShare.Read); DirectoryNode gen = dirn.Navigate("gen", false, true) as DirectoryNode; if (gen == null) // Just in case we're given the "wrong" directory that directly contains the ark { gen = dirn; } List <Pair <int, Stream> > arkfiles = new List <Pair <int, Stream> >(); Stream hdrfile = null; foreach (FileNode file in gen.Files) { if (file.Name.ToLower().EndsWith(".hdr")) { hdrfile = file.Data; } else if (file.Name.ToLower().EndsWith(".ark")) { Match match = Regex.Match(file.Name.ToLower(), @"_(\d+).ark"); if (match.Success) { arkfiles.Add(new Pair <int, Stream>(int.Parse(match.Groups[1].Value), file.Data)); } else { arkfiles.Add(new Pair <int, Stream>(0, file.Data)); } } } // FreQuency/Amplitude where the header is the ark if (hdrfile == null) { if (arkfiles.Count == 1) { hdrfile = arkfiles[0].Value; arkfiles.Clear(); } else { throw new FormatException(); } } Ark ark = new Ark(new EndianReader(hdrfile, Endianness.LittleEndian), arkfiles.OrderBy(f => f.Key).Select(f => f.Value).ToArray()); ark.Root.Extract(dir); cache.Dispose(); } catch (FormatException) { Stream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read); try { Iso9660 iso = new Iso9660(stream); iso.Root.Extract(dir); } catch (Exception) { try { stream.Position = 0; Disc disc = new Disc(stream); File.WriteAllText(Path.Combine(dir, "title"), disc.Title); foreach (var partition in disc.Partitions) { string path = Path.Combine(dir, "partition" + disc.Partitions.IndexOf(partition).ToString()); Directory.CreateDirectory(path); partition.Root.Root.Extract(Path.Combine(path, "data")); FileStream file = new FileStream(Path.Combine(path, "partition.tik"), FileMode.Create, FileAccess.Write); partition.Ticket.Save(file); file.Close(); file = new FileStream(Path.Combine(path, "partition.tmd"), FileMode.Create, FileAccess.Write); partition.TMD.Save(file); file.Close(); file = new FileStream(Path.Combine(path, "partition.certs"), FileMode.Create, FileAccess.Write); file.Write(partition.CertificateChain); file.Close(); } } catch { try { stream.Position = 0; DlcBin bin = new DlcBin(stream); U8 u8 = new U8(bin.Data); u8.Root.Extract(dir); } catch { try { stream.Position = 0; U8 u8 = new U8(stream); u8.Root.Extract(dir); } catch { stream.Position = 0; Rarc rarc = new Rarc(stream); rarc.Root.Extract(dir); } } } } stream.Close(); } }
public override void SaveSong(PlatformData data, FormatData formatdata, ProgressIndicator progress) { string path = data.Session["maindirpath"] as string; string otitle; ushort oindex; progress.NewTask(10); using (DelayedStreamCache cache = new DelayedStreamCache()) { progress.SetNextWeight(6); string audioextension = ".mogg"; Stream audio = null; Stream preview = null; AudioFormat audioformat = null; IList <IFormat> formats = formatdata.Formats; if (formats.Contains(AudioFormatRB2Mogg.Instance)) { audio = AudioFormatRB2Mogg.Instance.GetAudioStream(formatdata); preview = AudioFormatRB2Mogg.Instance.GetPreviewStream(formatdata); audioformat = AudioFormatRB2Mogg.Instance.DecodeAudioFormat(formatdata); } else if (formats.Contains(AudioFormatRB2Bink.Instance)) { audio = AudioFormatRB2Bink.Instance.GetAudioStream(formatdata); preview = AudioFormatRB2Bink.Instance.GetPreviewStream(formatdata, progress); if (!formatdata.HasStream(preview)) { cache.AddStream(preview); } audioformat = AudioFormatRB2Bink.Instance.DecodeAudioFormat(formatdata); audioextension = ".bik"; } else { throw new NotSupportedException(); } progress.Progress(6); ChartFormat chartformat = (formatdata.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(formatdata, progress); Stream album = null; Stream chart = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile); Stream pan = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.PanFile); Stream weights = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.WeightsFile); Stream milo = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.MiloFile); progress.SetNextWeight(2); if (chart != null && ChartFormatRB.Instance.NeedsFixing(formatdata)) { formatdata.CloseStream(chart); chart = null; } if (chart == null) { chart = new TemporaryStream(); cache.AddStream(chart); AdjustChart(formatdata.Song, audioformat, chartformat).ToMidi().ToMid().Save(chart); chart.Position = 0; } if (weights == null) { weights = new TemporaryStream(); cache.AddStream(weights); CreateWeights(weights, chartformat); weights.Position = 0; } if (pan == null) { pan = new TemporaryStream(); cache.AddStream(pan); CreatePan(pan, chartformat); pan.Position = 0; } if (milo == null) { milo = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.Milo3File); if (milo == null) { milo = new MemoryStream(Properties.Resources.rawksd_milo); } else { Stream milostream = new TemporaryStream(); cache.AddStream(milostream); Milo milofile = new Milo(new EndianReader(milo, Endianness.LittleEndian)); FaceFX fx = new FaceFX(new EndianReader(milofile.Data[0], Endianness.BigEndian)); TemporaryStream fxstream = new TemporaryStream(); fx.Save(new EndianReader(fxstream, Endianness.LittleEndian)); milofile.Data[0] = fxstream; milofile.Compressed = true; milofile.Save(new EndianReader(milostream, Endianness.LittleEndian)); fxstream.Close(); formatdata.CloseStream(milo); milo = milostream; milo.Position = 0; } } //if (album == null) // album = new MemoryStream(Properties.Resources.rawksd_albumart); progress.Progress(2); SongData song = new SongData(formatdata.Song); SongsDTA dta = GetSongsDTA(song, audioformat); if (album == null) { dta.AlbumArt = false; } else { dta.AlbumArt = true; } dta.Song.MidiFile = "dlc/content/songs/" + song.ID + "/" + song.ID + ".mid"; DTB.NodeTree dtb = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song)); MemoryStream songsdta = new MemoryStream(); cache.AddStream(songsdta); dtb.SaveDTA(songsdta); songsdta.Position = 0; U8 appdta = new U8(); DirectoryNode dir = new DirectoryNode("content"); appdta.Root.AddChild(dir); DirectoryNode songsdir = new DirectoryNode("songs"); dir.AddChild(songsdir); DirectoryNode songdir = new DirectoryNode(song.ID); songsdir.AddChild(songdir); songdir.AddChild(new FileNode(song.ID + "_prev.mogg", preview)); songdir.AddChild(new FileNode("songs.dta", songsdta)); DirectoryNode gendir; if (dta.AlbumArt.Value && album != null) { gendir = new DirectoryNode("gen"); songdir.AddChild(gendir); gendir.AddChild(new FileNode(song.ID + "_nomip_keep.bmp_wii", album)); } U8 appsong = new U8(); dir = new DirectoryNode("content"); appsong.Root.AddChild(dir); songsdir = new DirectoryNode("songs"); dir.AddChild(songsdir); songdir = new DirectoryNode(song.ID); songsdir.AddChild(songdir); songdir.AddChild(new FileNode(song.ID + audioextension, audio)); songdir.AddChild(new FileNode(song.ID + ".mid", chart)); songdir.AddChild(new FileNode(song.ID + ".pan", pan)); gendir = new DirectoryNode("gen"); songdir.AddChild(gendir); gendir.AddChild(new FileNode(song.ID + ".milo_wii", milo)); gendir.AddChild(new FileNode(song.ID + "_weights.bin", weights)); Stream memoryDta = new TemporaryStream(); cache.AddStream(memoryDta); appdta.Save(memoryDta); Stream memorySong = new TemporaryStream(); cache.AddStream(memorySong); appsong.Save(memorySong); formatdata.CloseStream(audio); formatdata.CloseStream(preview); formatdata.CloseStream(chart); formatdata.CloseStream(album); formatdata.CloseStream(pan); formatdata.CloseStream(weights); formatdata.CloseStream(milo); FindUnusedContent(data, formatdata.Song, out otitle, out oindex); TMD tmd = GenerateDummyTMD(otitle); dta.Song.Name = "dlc/" + otitle + "/" + Util.Pad(oindex.ToString(), 3) + "/content/songs/" + song.ID + "/" + song.ID; dtb = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song)); HarmonixMetadata.SetSongsDTA(song, dtb); string dirpath = Path.Combine(Path.Combine(path, "rawk"), "rb2"); if (!Directory.Exists(Path.Combine(dirpath, "customs"))) { Directory.CreateDirectory(Path.Combine(dirpath, "customs")); } Directory.CreateDirectory(Path.Combine(Path.Combine(dirpath, "customs"), song.ID)); FileStream savestream = new FileStream(Path.Combine(Path.Combine(Path.Combine(dirpath, "customs"), song.ID), "data"), FileMode.Create); dtb.Save(new EndianReader(savestream, Endianness.LittleEndian)); savestream.Close(); TmdContent contentDta = new TmdContent(); contentDta.ContentID = oindex; contentDta.Index = oindex; contentDta.Type = 0x4001; TmdContent contentSong = new TmdContent(); contentSong.ContentID = oindex + 1U; contentSong.Index = (ushort)(oindex + 1); contentSong.Type = 0x4001; memoryDta.Position = 0; contentDta.Hash = Util.SHA1Hash(memoryDta); contentDta.Size = memoryDta.Length; memorySong.Position = 0; contentSong.Hash = Util.SHA1Hash(memorySong); contentSong.Size = memorySong.Length; for (int i = 1; i <= oindex + 1; i++) { if (i == oindex) { tmd.Contents.Add(contentDta); } else if (i == oindex + 1) { tmd.Contents.Add(contentSong); } else { tmd.Contents.Add(new TmdContent() { Index = (ushort)i, ContentID = (uint)i, Size = 1, Type = 0x4001 }); } } tmd.Fakesign(); uint consoleid = GetConsoleID(path); progress.Progress(); dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), "sZAE"); TemporaryStream binstream; DlcBin bin; if (consoleid != 0 && !File.Exists(Path.Combine(dirpath, "000.bin"))) { Directory.CreateDirectory(dirpath); binstream = new TemporaryStream(); binstream.Write(Properties.Resources.rawksd_000bin, 0, Properties.Resources.rawksd_000bin.Length); binstream.Position = 8; new EndianReader(binstream, Endianness.BigEndian).Write(consoleid); binstream.ClosePersist(); File.Move(binstream.Name, Path.Combine(dirpath, "000.bin")); binstream.Close(); } dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), otitle); if (!Directory.Exists(dirpath)) { Directory.CreateDirectory(dirpath); } binstream = new TemporaryStream(); bin = new DlcBin(); bin.Bk.ConsoleID = consoleid; bin.TMD = tmd; bin.Content = tmd.Contents[oindex]; bin.Data = memoryDta; bin.Generate(); bin.Bk.ContentSize = bin.Bk.TotalSize = 0; bin.Bk.TitleID = 0x00010000535A4145UL; bin.Save(binstream); binstream.ClosePersist(); string dtabinpath = Path.Combine(dirpath, Util.Pad(oindex.ToString(), 3) + ".bin"); Util.Delete(dtabinpath); File.Move(binstream.Name, dtabinpath); binstream.Close(); binstream = new TemporaryStream(); bin = new DlcBin(); bin.Bk.ConsoleID = consoleid; bin.TMD = tmd; bin.Content = tmd.Contents[oindex + 1]; bin.Data = memorySong; bin.Generate(); bin.Bk.ContentSize = bin.Bk.TotalSize = 0; bin.Bk.TitleID = 0x00010000535A4145UL; bin.Save(binstream); binstream.ClosePersist(); string songbinpath = Path.Combine(dirpath, Util.Pad((oindex + 1).ToString(), 3) + ".bin"); Util.Delete(songbinpath); File.Move(binstream.Name, songbinpath); binstream.Close(); data.Mutex.WaitOne(); string mainbinpath = Path.Combine(dirpath, "000.bin"); if (!File.Exists(mainbinpath)) { binstream = new TemporaryStream(); bin = new DlcBin(); bin.Bk.ConsoleID = consoleid; bin.TMD = tmd; bin.Content = tmd.Contents[0]; bin.Data = new MemoryStream(Properties.Resources.rawksd_savebanner, false); bin.Generate(); bin.Bk.TitleID = 0x00010000535A4145UL; bin.Save(binstream); binstream.ClosePersist(); File.Move(binstream.Name, mainbinpath); binstream.Close(); } AddSongFromBins(data, song, dtabinpath, songbinpath, progress, true); SaveDTBCache(data); data.Mutex.ReleaseMutex(); cache.Dispose(); progress.Progress(); } progress.EndTask(); }
internal static void Export360(string path, FormatData original) { Program.Form.Progress.QueueTask(progress => { progress.NewTask("Exporting to 360 DLC file", 16); SongData song = original.Song; StfsArchive stfs = new StfsArchive(); stfs.Stfs.ContentType = StfsFile.ContentTypes.Marketplace; stfs.Stfs.TitleID = 0x45410829; for (int i = 0; i < stfs.Stfs.DisplayName.Length; i++) { stfs.Stfs.DisplayName[i] = song.Artist + " - " + song.Name; } for (int i = 0; i < stfs.Stfs.DisplayDescription.Length; i++) { stfs.Stfs.DisplayDescription[i] = "RawkSD DLC - http://rawksd.japaneatahand.com"; } stfs.Stfs.TitleName = "Rawk Band 2"; stfs.Stfs.Publisher = "RawkSD"; stfs.Stfs.TitleThumbnail = WiiImage.Create(new EndianReader(new MemoryStream(ConsoleHaxx.RawkSD.Properties.Resources.rawksd_albumart), Endianness.LittleEndian)).Bitmap; if (song.AlbumArt != null) { stfs.Stfs.Thumbnail = song.AlbumArt; } else { stfs.Stfs.Thumbnail = stfs.Stfs.TitleThumbnail; } StfsFile.SignedHeader header = new StfsFile.SignedHeader(StfsFile.FileTypes.LIVE); stfs.Stfs.Header = header; header.Licenses[0].ID = 0xFFFFFFFFFFFFFFFF; stfs.Stfs.MetadataVersion = 2; StfsFile.PackageDescriptor desc = new StfsFile.PackageDescriptor(); stfs.Stfs.Descriptor = desc; desc.StructSize = 0x24; desc.BlockSeparation = 1; desc.FileTableBlockCount = 0x100; // byte apparently stfs.Stfs.TransferFlags = 0xC0; FormatData data = original; Program.Form.TaskMutex.WaitOne(); bool local = data.PlatformData.Platform == PlatformLocalStorage.Instance; bool ownformat = false; if (!local && Configuration.MaxConcurrentTasks > 1) { data = new TemporaryFormatData(data.Song, data.PlatformData); original.SaveTo(data); ownformat = true; } Program.Form.TaskMutex.ReleaseMutex(); Stream songs = null; Stream audio = null; Stream chart = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile); Stream pan = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.PanFile); Stream weights = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.WeightsFile); Stream milo = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.MiloFile); milo = new MemoryStream(Properties.Resources.rbn_milo); // TODO: properly convert milo if (milo == null) { milo = new MemoryStream(ConsoleHaxx.RawkSD.Properties.Resources.rawksd_milo); } using (DelayedStreamCache cache = new DelayedStreamCache()) { AudioFormat audioformat = (data.GetFormat(FormatType.Audio) as IAudioFormat).DecodeAudio(data, progress); ushort[] masks = PlatformRB2WiiCustomDLC.RemixAudioTracks(data.Song, audioformat); progress.Progress(); // RBN Required DTA settings SongsDTA dta = PlatformRB2WiiCustomDLC.GetSongsDTA(song, audioformat, false); dta.AlbumArt = false; dta.Song.Name = "songs/" + song.ID + "/" + song.ID; dta.Song.MidiFile = "songs/" + song.ID + "/" + song.ID + ".mid"; dta.Rating = 4; dta.SubGenre = "subgenre_core"; dta.Format = 4; //dta.SongID = 0; dta.Origin = "rb2"; //dta.Ugc = 1; //dta.SongLength = 300000; dta.Context = 2000; dta.BasePoints = 0; if (!dta.TuningOffsetCents.HasValue) { dta.TuningOffsetCents = 0; } audio = new TemporaryStream(); cache.AddStream(audio); progress.Progress(); progress.SetNextWeight(10); long samples = audioformat.Decoder.Samples; CryptedMoggStream mogg = new CryptedMoggStream(audio); mogg.WriteHeader(); RawkAudio.Encoder encoder = new RawkAudio.Encoder(mogg, audioformat.Mappings.Count, audioformat.Decoder.SampleRate); progress.NewTask("Transcoding Audio", samples); JaggedShortArray buffer = new JaggedShortArray(encoder.Channels, audioformat.Decoder.AudioBuffer.Rank2); AudioFormat.ProcessOffset(audioformat.Decoder, encoder, audioformat.InitialOffset); while (samples > 0) { int read = audioformat.Decoder.Read((int)Math.Min(samples, audioformat.Decoder.AudioBuffer.Rank2)); if (read <= 0) { break; } audioformat.Decoder.AudioBuffer.DownmixTo(buffer, masks, read); encoder.Write(buffer, read); samples -= read; progress.Progress(read); } progress.EndTask(); progress.Progress(10); encoder.Dispose(); audioformat.Decoder.Dispose(); audio.Position = 0; dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Drums)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Bass)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Guitar)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Vocals)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Ambient)); for (int i = 0; i < dta.Song.Cores.Count; i++) { dta.Song.Cores[i] = -1; } songs = new TemporaryStream(); cache.AddStream(songs); dta.ToDTB().SaveDTA(songs); ChartFormat chartformat = (data.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(data, progress); if (chart != null && ChartFormatRB.Instance.NeedsFixing(data)) { data.CloseStream(chart); chart = null; } if (chart == null) { chart = new TemporaryStream(); cache.AddStream(chart); PlatformRB2WiiCustomDLC.AdjustChart(song, audioformat, chartformat).ToMidi().ToMid().Save(chart); chart.Position = 0; } if (weights == null) { weights = new TemporaryStream(); cache.AddStream(weights); PlatformRB2WiiCustomDLC.CreateWeights(weights, chartformat); weights.Position = 0; } if (pan == null) { pan = new TemporaryStream(); cache.AddStream(pan); PlatformRB2WiiCustomDLC.CreatePan(pan, chartformat); pan.Position = 0; } progress.Progress(3); DirectoryNode dir = new DirectoryNode("songs"); stfs.Root.AddChild(dir); dir.AddChild(new FileNode("songs.dta", songs)); DirectoryNode songdir = new DirectoryNode(song.ID); dir.AddChild(songdir); songdir.AddChild(new FileNode(song.ID + ".mogg", audio)); songdir.AddChild(new FileNode(song.ID + ".mid", chart)); DirectoryNode gendir = new DirectoryNode("gen"); songdir.AddChild(gendir); gendir.AddChild(new FileNode(song.ID + ".milo_xbox", milo)); gendir.AddChild(new FileNode(song.ID + "_weights.bin", weights)); Stream ostream = new FileStream(path, FileMode.Create); stfs.Save(ostream); ostream.Close(); data.CloseStream(audio); data.CloseStream(chart); data.CloseStream(pan); data.CloseStream(weights); data.CloseStream(milo); if (ownformat) { data.Dispose(); } progress.Progress(); progress.EndTask(); } }); }
public static void ExportRBN(string path, FormatData original) { Program.Form.Progress.QueueTask(progress => { progress.NewTask("Exporting to RBA file", 16); RBA rba = new RBA(); FormatData data = original; Program.Form.TaskMutex.WaitOne(); bool local = data.PlatformData.Platform == PlatformLocalStorage.Instance; bool ownformat = false; if (!local && Configuration.MaxConcurrentTasks > 1) { data = new TemporaryFormatData(data.Song, data.PlatformData); original.SaveTo(data); ownformat = true; } Program.Form.TaskMutex.ReleaseMutex(); using (DelayedStreamCache cache = new DelayedStreamCache()) { AudioFormat audioformat = (data.GetFormat(FormatType.Audio) as IAudioFormat).DecodeAudio(data, progress); ushort[] masks = PlatformRB2WiiCustomDLC.RemixAudioTracks(data.Song, audioformat); progress.Progress(); // RBN Required DTA settings SongsDTA dta = PlatformRB2WiiCustomDLC.GetSongsDTA(data.Song, audioformat, false); dta.AlbumArt = true; dta.BaseName = "song"; dta.Song.Name = "songs/" + dta.BaseName + "/" + dta.BaseName; dta.Song.MidiFile = "songs/" + dta.BaseName + "/" + dta.BaseName + ".mid"; dta.Rating = 4; dta.Genre = "rock"; dta.SubGenre = "subgenre_rock"; dta.Format = 4; dta.SongID = 0; dta.Origin = "rb2"; dta.Ugc = 1; dta.SongLength = 300000; dta.Preview[0] = 0; dta.Preview[1] = 30000; dta.Context = 2000; dta.BasePoints = 0; if (!dta.TuningOffsetCents.HasValue) { dta.TuningOffsetCents = 0; } rba.Audio = new TemporaryStream(); cache.AddStream(rba.Audio); progress.Progress(); progress.SetNextWeight(10); long samples = audioformat.Decoder.Samples; CryptedMoggStream mogg = new CryptedMoggStream(rba.Audio); mogg.WriteHeader(); RawkAudio.Encoder encoder = new RawkAudio.Encoder(mogg, audioformat.Mappings.Count, audioformat.Decoder.SampleRate); progress.NewTask("Transcoding Audio", samples); JaggedShortArray buffer = new JaggedShortArray(encoder.Channels, audioformat.Decoder.AudioBuffer.Rank2); AudioFormat.ProcessOffset(audioformat.Decoder, encoder, audioformat.InitialOffset); while (samples > 0) { int read = audioformat.Decoder.Read((int)Math.Min(samples, audioformat.Decoder.AudioBuffer.Rank2)); if (read <= 0) { break; } audioformat.Decoder.AudioBuffer.DownmixTo(buffer, masks, read); encoder.Write(buffer, read); samples -= read; progress.Progress(read); } progress.EndTask(); progress.Progress(10); encoder.Dispose(); audioformat.Decoder.Dispose(); rba.Audio.Position = 0; dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Drums)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Bass)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Guitar)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Vocals)); dta.Song.TracksCount.Add(audioformat.Mappings.Count(m => m.Instrument == Instrument.Ambient)); for (int i = 0; i < dta.Song.Cores.Count; i++) { dta.Song.Cores[i] = -1; } rba.Data = new TemporaryStream(); cache.AddStream(rba.Data); dta.Save(rba.Data); Stream stream = new MemoryStream(Properties.Resources.rbn_metadata); rba.Metadata = stream; stream = new MemoryStream(Properties.Resources.rbn_album); rba.AlbumArt = stream; stream = new MemoryStream(Properties.Resources.rbn_milo); rba.Milo = stream; stream = new MemoryStream(Properties.Resources.rbn_weights); rba.Weights = stream; if (data.Formats.Contains(ChartFormatRB.Instance) && !ChartFormatRB.Instance.NeedsFixing(data)) { rba.Chart = data.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile); } else { IChartFormat chartformat = data.GetFormat(FormatType.Chart) as IChartFormat; NoteChart chart = PlatformRB2WiiCustomDLC.AdjustChart(data.Song, audioformat, chartformat.DecodeChart(data, progress)); rba.Chart = new TemporaryStream(); cache.AddStream(rba.Chart); chart.ToMidi().ToMid().Save(rba.Chart); } progress.Progress(3); rba.Strings.Add(((char)0x02).ToString()); rba.Strings.Add(((char)0x22).ToString()); rba.Strings.Add((char)0x02 + "090923"); rba.Strings.Add("090923"); rba.Strings.Add(string.Empty); rba.Strings.Add(string.Empty); rba.Strings.Add((char)0x02 + "090923"); rba.Strings.Add("s/rawk/a"); Stream ostream = new FileStream(path, FileMode.Create); rba.Save(ostream); ostream.Close(); data.CloseStream(rba.Chart); if (ownformat) { data.Dispose(); } progress.Progress(); progress.EndTask(); } }); }