/// <summary> /// Converts RS1 Song Object to *.sng File /// </summary> /// <param name="rs1Song"></param> /// <param name="outputPath"></param> /// <returns>Path to binary *.sng file</returns> public string SongToSngFilePath(Song rs1Song, string outputPath) { string rs1XmlPath; using (var obj = new Rs1Converter()) rs1XmlPath = obj.SongToXml(rs1Song, outputPath, true); ArrangementType arrangementType; if (rs1Song.Arrangement.ToLower() == "bass") { arrangementType = ArrangementType.Bass; } else { arrangementType = ArrangementType.Guitar; } var sngFilePath = Path.ChangeExtension(rs1XmlPath, ".sng"); SngFileWriter.Write(rs1XmlPath, sngFilePath, arrangementType, new Platform(GamePlatform.Pc, GameVersion.None)); if (File.Exists(rs1XmlPath)) { File.Delete(rs1XmlPath); } return(sngFilePath); }
/// <summary> /// Converts RS1 Song Object to *.sng File /// </summary> /// <param name="rs1Song"></param> /// <param name="outputPath"></param> /// <returns>Path to binary *.sng file</returns> public string SongToSngFilePath(Song rs1Song, string outputPath) { string rs1XmlPath; using (var obj = new Rs1Converter()) rs1XmlPath = obj.SongToXml(rs1Song, outputPath, true); ArrangementType arrangementType; if (rs1Song.Arrangement.ToLower() == "bass") arrangementType = ArrangementType.Bass; else arrangementType = ArrangementType.Guitar; var sngFilePath = Path.ChangeExtension(rs1XmlPath, ".sng"); SngFileWriter.Write(rs1XmlPath, sngFilePath, arrangementType, new Platform(GamePlatform.Pc, GameVersion.None)); if (File.Exists(rs1XmlPath)) File.Delete(rs1XmlPath); return sngFilePath; }
public string SongFile2Song2014File(string songFilePath, bool overWrite) { Song2014 song2014; using (var obj = new Rs1Converter()) song2014 = obj.SongToSong2014(Song.LoadFromFile(songFilePath)); if (!overWrite) { var srcDir = Path.GetDirectoryName(songFilePath); var srcName = Path.GetFileNameWithoutExtension(songFilePath); var backupSrcPath = String.Format("{0}_{1}.xml", Path.Combine(srcDir, srcName), "RS1"); // backup original RS1 file File.Copy(songFilePath, backupSrcPath); } // write converted RS1 file using (FileStream stream = new FileStream(songFilePath, FileMode.Create)) song2014.Serialize(stream, true); return songFilePath; }
/// <summary> /// Song2014 to ASCII Tablature /// </summary> /// <param name="rs2014Song"></param> /// <param name="outputDir"></param> /// <param name="allDif"></param> public void Song2014ToAsciiTab(Song2014 rs2014Song, string outputDir, bool allDif) { if (rs2014Song == null || String.IsNullOrEmpty(outputDir)) { return; } // convert to Song Song rs1Song; using (var obj = new Rs2014Converter()) rs1Song = obj.Song2014ToSong(rs2014Song); Console.WriteLine("Converted Song2014 To Song"); if (false) // write Xml files for debugging { using (Rs2014Converter obj = new Rs2014Converter()) obj.Song2014ToXml(rs2014Song, outputDir); using (Rs1Converter obj = new Rs1Converter()) obj.SongToXml(rs1Song, outputDir); } // convert to SngFile string rs1SngFilePath; using (var obj = new Rs1Converter()) rs1SngFilePath = obj.SongToSngFilePath(rs1Song, outputDir); Console.WriteLine("Converted Song To SngFile"); // convert to AsciiTab using (var s2Tab = new Sng2Tab()) s2Tab.Convert(rs1SngFilePath, outputDir, allDif); Console.WriteLine("Converted SngFile To AsciiTab"); if (File.Exists(rs1SngFilePath)) { File.Delete(rs1SngFilePath); } }
private void convertButton_Click(object sender, EventArgs e) { IList<string> sourceFilePaths; allDif = difficultyAll.Checked; // Input file(s) using (var ofd = new OpenFileDialog()) { if (rbAsciiTab.Checked) ofd.Filter = "RS1 (*.dat, *.sng, *.xml) or RS2014 (*.psarc) files|*.dat;*.sng;*.xml;*.psarc"; else ofd.Filter = "RS2014 (*.psarc, *.xml) files|*.psarc;*.xml"; ofd.Title = "Select RS1 and/or RS2014 CDLC files to convert"; ofd.Multiselect = true; ofd.FileOk += OpenFileDialog_FileLimit; // Event handler if (ofd.ShowDialog() != DialogResult.OK) return; sourceFilePaths = ofd.FileNames; } using (var fbd = new FolderBrowserDialog()) { fbd.Description = "Select a folder for storing converted files."; fbd.ShowNewFolderButton = true; fbd.SelectedPath = outputDir; // fbd.SelectedPath = "D:\\Temp"; // for testing if (fbd.ShowDialog() != DialogResult.OK) return; outputDir = fbd.SelectedPath; } Cursor.Current = Cursors.WaitCursor; foreach (var inputFilePath in sourceFilePaths) { string fileExtension = Path.GetExtension(inputFilePath).ToLower(); switch (fileExtension) { case ".xml": if (rbGp5.Checked) { using (var obj = new Gp5Converter()) obj.XmlToGp5(inputFilePath, outputDir); } else { var fileName = Path.GetFileNameWithoutExtension(inputFilePath); var splitPoint = fileName.LastIndexOf('_'); var arrangement = fileName.Substring(splitPoint + 1); // skip any files for vocals and/or showlights if (arrangement.ToLower() == "vocals" || arrangement.ToLower() == "showlights") break; Song rs1Song; using (var obj = new Rs1Converter()) rs1Song = obj.XmlToSong(inputFilePath); string sngFilePath; using (var obj = new Rs1Converter()) sngFilePath = obj.SongToSngFilePath(rs1Song, Path.Combine(outputDir, Path.GetFileName(inputFilePath))); using (var obj = new Sng2Tab()) obj.Convert(sngFilePath, outputDir, allDif); if (File.Exists(sngFilePath)) File.Delete(sngFilePath); } break; case ".dat": using (var obj = new Sng2Tab()) obj.ExtractBeforeConvert(inputFilePath, outputDir, allDif); break; case ".sng": using (var obj = new Sng2Tab()) obj.Convert(inputFilePath, outputDir, allDif); break; case ".psarc": if (rbSongList.Checked) { using (var obj = new Rs2014Converter()) obj.PsarcSongList(inputFilePath, outputDir); break; } var fileInfo = new FileInfo(inputFilePath); // give user chance to abort big files if (fileInfo.Length / 1000 > 15000) { if (MessageBox.Show(string.Format("{0} file size is {1:N00} KB{2}It may take a long time to extract and convert that much data.{2}{2}Do you want to continue?", Path.GetFileName(inputFilePath), (fileInfo.Length / 1000), Environment.NewLine), MESSAGEBOX_CAPTION, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) return; } using (var obj = new Rs2014Converter()) songList = obj.PsarcSongList(inputFilePath); if (rbAsciiTab.Checked) { using (var form = new SongInfoForm()) { form.PopSongInfo(songList); do // waiting for user selection(s) form.ShowDialog(); while (form.SongListShort.Count == 0); this.Refresh(); if (form.SongListShort[0].Identifier == "User Aborted") break; Cursor.Current = Cursors.WaitCursor; foreach (var song in form.SongListShort) { Song2014 rs2014Song; using (var obj = new Rs2014Converter()) { rs2014Song = obj.PsarcToSong2014(inputFilePath, song.Identifier, song.Arrangement); obj.Song2014ToAsciiTab(rs2014Song, outputDir, allDif); } } } break; } // convert to *.gp5 file(s) optimized code for dll usage if (!allDif && songList.Count == 1) using (var obj = new Gp5Converter()) obj.PsarcToGp5(inputFilePath, outputDir); else if (!allDif && songList.Count > 1) { using (var form = new SongInfoForm()) { form.PopSongOnly(songList); // songs only (merge all arrangements into single GP file) // form.PopSongInfo(songList); // choose songs and arrangements do // waiting for user selection(s) form.ShowDialog(); while (form.SongListShort.Count == 0); this.Refresh(); if (form.SongListShort[0].Identifier == "User Aborted") break; Cursor.Current = Cursors.WaitCursor; using (var obj = new Gp5Converter()) obj.PsarcToGp5(inputFilePath, outputDir, form.SongListShort); } } // give user the option to select specific songs and arrangements else if (allDif) { using (var form = new SongInfoForm()) { form.PopSongInfo(songList); // choose songs and arrangements do // waiting for user selection(s) form.ShowDialog(); while (form.SongListShort.Count == 0); this.Refresh(); if (form.SongListShort[0].Identifier == "User Aborted") break; Cursor.Current = Cursors.WaitCursor; using (var obj = new Gp5Converter()) obj.PsarcToGp5(inputFilePath, outputDir, form.SongListShort, "gp5", true); } } break; } Refresh(); } Cursor.Current = Cursors.Default; if (MessageBox.Show("The conversion is complete.." + Environment.NewLine + "Would you like to open the folder?", MESSAGEBOX_CAPTION, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) Process.Start(outputDir); }
// Load RS1 CDLC into PackageCreator public static DLCPackageData RS1LoadFromFolder(string unpackedDir, Platform targetPlatform, bool convert) { var data = new DLCPackageData(); data.Arrangements = new List<Arrangement>(); data.TonesRS2014 = new List<Tone2014>(); data.Tones = new List<Tone>(); data.GameVersion = (convert ? GameVersion.RS2014 : GameVersion.RS2012); data.SignatureType = PackageMagic.CON; // set default volumes data.Volume = -6.5F; // default maybe too quite data.PreviewVolume = data.Volume; //Load song manifest var songsManifestJson = Directory.GetFiles(unpackedDir, "songs.manifest.json", SearchOption.AllDirectories); if (songsManifestJson.Length < 1) throw new DataException("No songs.manifest.json file found."); if (songsManifestJson.Length > 1) throw new DataException("More than one songs.manifest.json file found."); var attr = new List<Attributes>(); var songsManifest = Manifest.Manifest.LoadFromFile(songsManifestJson[0]).Entries.ToArray(); for (int smIndex = 0; smIndex < songsManifest.Count(); smIndex++) { var smData = songsManifest[smIndex].Value.ToArray()[0].Value; attr.Add(smData); } if (attr.FirstOrDefault() == null) throw new DataException("songs.manifest.json file did not parse correctly."); // Fill SongInfo data.SongInfo = new SongInfo(); data.SongInfo.SongDisplayName = attr.FirstOrDefault().SongName; data.SongInfo.SongDisplayNameSort = attr.FirstOrDefault().SongNameSort; data.SongInfo.Album = attr.FirstOrDefault().AlbumName; data.SongInfo.SongYear = (attr.FirstOrDefault().SongYear == 0 ? 2012 : attr.FirstOrDefault().SongYear); data.SongInfo.Artist = attr.FirstOrDefault().ArtistName; data.SongInfo.ArtistSort = attr.FirstOrDefault().ArtistNameSort; data.Name = attr.FirstOrDefault().SongKey; //Load tone manifest, even poorly formed tone_bass.manifest.json var toneManifestJson = Directory.GetFiles(unpackedDir, "*tone*.manifest.json", SearchOption.AllDirectories); if (toneManifestJson.Length < 1) throw new DataException("No tone.manifest.json file found."); // toolkit produces multiple tone.manifest.json files when packing RS1 CDLC files // rather than change toolkit behavior just merge manifest files for now if (toneManifestJson.Length > 1) { var mergeSettings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Union }; JObject toneObject1 = new JObject(); foreach (var tone in toneManifestJson) { JObject toneObject2 = JObject.Parse(File.ReadAllText(tone)); //(toneObject1.SelectToken("Entries") as JArray).Merge(toneObject2.SelectToken("Entries")); toneObject1.Merge(toneObject2, mergeSettings); } toneManifestJson = new string[1]; toneManifestJson[0] = Path.Combine(unpackedDir, "merged.tone.manifest.json"); string json = JsonConvert.SerializeObject(toneObject1, Formatting.Indented); File.WriteAllText(toneManifestJson[0], json); } var tones2014 = new List<Tone2014>(); var tones = new List<Tone>(); var toneManifest = Manifest.Tone.Manifest.LoadFromFile(toneManifestJson[0]); for (int tmIndex = 0; tmIndex < toneManifest.Entries.Count(); tmIndex++) { var tmData = toneManifest.Entries[tmIndex]; tones.Add(tmData); } data.Tones = tones; // Load AggregateGraph.nt var songDir = Path.Combine(unpackedDir, data.Name); if (targetPlatform.platform == GamePlatform.XBox360) songDir = Path.Combine(unpackedDir, "Root", data.Name); var aggFile = Directory.GetFiles(songDir, "*.nt", SearchOption.TopDirectoryOnly)[0]; var aggGraphData = AggregateGraph.AggregateGraph.ReadFromFile(aggFile); // Load Exports\Songs\*.xblock var xblockDir = Path.Combine(songDir, "Exports\\Songs"); var xblockFile = Directory.GetFiles(xblockDir, "*.xblock", SearchOption.TopDirectoryOnly)[0]; // xblockFile = "D:\\Temp\\Mapping\\songs.xblock"; var songsXblock = XblockX.LoadFromFile(xblockFile); // create project map for cross referencing arrangements with tones var projectMap = AggregateGraph.AggregateGraph.ProjectMap(aggGraphData, songsXblock, toneManifest); // Load xml arrangements var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories); if (xmlFiles.Length <= 0) throw new DataException("Can not find any XML arrangement files"); foreach (var xmlFile in xmlFiles) { if (xmlFile.ToLower().Contains("metadata")) // skip DeadFox file continue; // some poorly formed RS1 CDLC use just "vocal" if (xmlFile.ToLower().Contains("vocal")) { // Add Vocal Arrangement data.Arrangements.Add(new Arrangement { Name = ArrangementName.Vocals, ArrangementType = ArrangementType.Vocal, ScrollSpeed = 20, SongXml = new SongXML { File = xmlFile }, SongFile = new SongFile { File = "" }, CustomFont = false }); } else { var attr2014 = new Attributes2014(); var rsSong = new Song(); var rsSong2014 = new Song2014(); // optimized tone matching effort using project mapping algo var result = projectMap.First(m => String.Equals(Path.GetFileName(m.SongXmlPath), Path.GetFileName(xmlFile), StringComparison.CurrentCultureIgnoreCase)); if (result.Tones.Count != 1) throw new DataException("Invalid RS1 CDLC Tones Data"); var arrangement = attr.First(s => s.SongXml.ToLower().Contains(result.LLID)); var tone = tones.First(t => t.Key == result.Tones[0]); using (var obj1 = new Rs1Converter()) { rsSong = obj1.XmlToSong(xmlFile); data.SongInfo.AverageTempo = (int)obj1.AverageBPM(rsSong); } if (arrangement.Tuning == "E Standard") rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 }; else if (arrangement.Tuning == "DropD") rsSong.Tuning = new TuningStrings { String0 = -2, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 }; else if (arrangement.Tuning == "OpenG") rsSong.Tuning = new TuningStrings { String0 = -2, String1 = -2, String2 = 0, String3 = 0, String4 = 0, String5 = -2 }; else if (arrangement.Tuning == "EFlat") rsSong.Tuning = new TuningStrings { String0 = -1, String1 = -1, String2 = -1, String3 = -1, String4 = -1, String5 = -1 }; else // default to standard tuning { arrangement.Tuning = "E Standard"; rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 }; } // save/write the changes to xml file using (var obj1 = new Rs1Converter()) obj1.SongToXml(rsSong, xmlFile, true); if (convert) using (var obj1 = new Rs1Converter()) tones2014.Add(obj1.ToneToTone2014(tone, rsSong)); // load attr2014 with RS1 mapped values for use by Arrangement() attr2014.Tone_Base = tone.Name; attr2014.ArrangementName = arrangement.ArrangementName; attr2014.CentOffset = 0; attr2014.DynamicVisualDensity = new List<float>() { 2 }; attr2014.SongPartition = arrangement.SongPartition; attr2014.PersistentID = IdGenerator.Guid().ToString(); attr2014.MasterID_RDV = RandomGenerator.NextInt(); attr2014.ArrangementProperties = new SongArrangementProperties2014(); // processing order is important - CAREFUL // RouteMask None = 0, Lead = 1, Rhythm = 2, Any = 3, Bass = 4 // XML file names are usually meaningless to arrangement determination if (arrangement.ArrangementName.ToLower().Contains("lead") || rsSong.Arrangement.ToLower().Contains("lead")) { attr2014.ArrangementName = "Lead"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Lead; attr2014.ArrangementProperties.PathLead = 1; attr2014.ArrangementProperties.PathRhythm = 0; attr2014.ArrangementProperties.PathBass = 0; } else if (arrangement.ArrangementName.ToLower().Contains("rhythm") || rsSong.Arrangement.ToLower().Contains("rhythm")) // || rsSong.Arrangement.ToLower().Contains("guitar")) { attr2014.ArrangementName = "Rhythm"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Rhythm; attr2014.ArrangementProperties.PathLead = 0; attr2014.ArrangementProperties.PathRhythm = 1; attr2014.ArrangementProperties.PathBass = 0; } else if (arrangement.ArrangementName.ToLower().Contains("combo") || rsSong.Arrangement.ToLower().Contains("combo")) { attr2014.ArrangementName = "Combo"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = arrangement.EffectChainName.ToLower().Contains("lead") ? (int)RouteMask.Lead : (int)RouteMask.Rhythm; attr2014.ArrangementProperties.PathLead = arrangement.EffectChainName.ToLower().Contains("lead") ? 1 : 0; attr2014.ArrangementProperties.PathRhythm = arrangement.EffectChainName.ToLower().Contains("lead") ? 0 : 1; attr2014.ArrangementProperties.PathBass = 0; } else if (arrangement.ArrangementName.ToLower().Contains("bass") || rsSong.Arrangement.ToLower().Contains("bass")) { attr2014.ArrangementName = "Bass"; attr2014.ArrangementType = (int)ArrangementType.Bass; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Bass; attr2014.ArrangementProperties.PathLead = 0; attr2014.ArrangementProperties.PathRhythm = 0; attr2014.ArrangementProperties.PathBass = 1; } else { // default to Lead arrangment attr2014.ArrangementName = "Lead"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Lead; attr2014.ArrangementProperties.PathLead = 1; attr2014.ArrangementProperties.PathRhythm = 0; attr2014.ArrangementProperties.PathBass = 0; Console.WriteLine("RS1->RS2 CDLC Conversion defaulted to 'Lead' arrangment"); } if (convert) // RS1 -> RS2 magic { using (var obj1 = new Rs1Converter()) rsSong2014 = obj1.SongToSong2014(rsSong); // update ArrangementProperties rsSong2014.ArrangementProperties.RouteMask = attr2014.ArrangementProperties.RouteMask; rsSong2014.ArrangementProperties.PathLead = attr2014.ArrangementProperties.PathLead; rsSong2014.ArrangementProperties.PathRhythm = attr2014.ArrangementProperties.PathRhythm; rsSong2014.ArrangementProperties.PathBass = attr2014.ArrangementProperties.PathBass; rsSong2014.ArrangementProperties.StandardTuning = (arrangement.Tuning == "E Standard" ? 1 : 0); // <note time="58.366" linkNext="0" accent="0" bend="0" fret="7" hammerOn="0" harmonic="0" hopo="0" ignore="0" leftHand="-1" mute="0" palmMute="0" pluck="-1" pullOff="0" slap="-1" slideTo="-1" string="3" sustain="0.108" tremolo="0" harmonicPinch="0" pickDirection="0" rightHand="-1" slideUnpitchTo="-1" tap="0" vibrato="0" /> if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Bend != 0))) rsSong2014.ArrangementProperties.Bends = 1; if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Hopo != 0))) rsSong2014.ArrangementProperties.Hopo = 1; if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.SlideTo != -1))) rsSong2014.ArrangementProperties.Slides = 1; if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Sustain > 0))) rsSong2014.ArrangementProperties.Sustain = 1; // fixing times that are off var lastEbeatsTime = rsSong2014.Ebeats[rsSong2014.Ebeats.Length - 1].Time; var lastPhraseIterationsTime = rsSong2014.PhraseIterations[rsSong2014.PhraseIterations.Length - 1].Time; // tested ... not source of in game hangs // confirm last PhraseIterations time is less than last Ebeats time if (lastPhraseIterationsTime > lastEbeatsTime) { rsSong2014.PhraseIterations[rsSong2014.PhraseIterations.Length - 1].Time = lastEbeatsTime; rsSong2014.Sections[rsSong2014.Sections.Length - 1].StartTime = lastEbeatsTime; } // tested ... not source of in game hangs // confirm SongLength at least equals last Ebeats time if (rsSong2014.SongLength < lastEbeatsTime) rsSong2014.SongLength = lastEbeatsTime; using (var obj2 = new Rs2014Converter()) obj2.Song2014ToXml(rsSong2014, xmlFile, true); } // Adding Song Arrangement try { data.Arrangements.Add(new Arrangement(attr2014, xmlFile)); } catch (Exception ex) { // mainly for the benifit of convert2012 CLI users Console.WriteLine(@"This CDLC could not be auto converted." + Environment.NewLine + "You can still try manually adding the arrangements and assests." + Environment.NewLine + ex.Message); } } } if (convert) { // get rid of duplicate tone names tones2014 = tones2014.Where(p => p.Name != null) .GroupBy(p => p.Name).Select(g => g.First()).ToList(); data.TonesRS2014 = tones2014; } //Get Album Artwork DDS Files var artFiles = Directory.GetFiles(unpackedDir, "*.dds", SearchOption.AllDirectories); if (artFiles.Length < 1) throw new DataException("No Album Artwork file found."); if (artFiles.Length > 1) throw new DataException("More than one Album Artwork file found."); var targetArtFiles = new List<DDSConvertedFile>(); data.AlbumArtPath = artFiles[0]; targetArtFiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = artFiles[0], destinationFile = artFiles[0].CopyToTempFile(".dds") }); data.ArtFiles = targetArtFiles; //Audio files var targetAudioFiles = new List<string>(); var audioFiles = Directory.GetFiles(unpackedDir, "*.ogg", SearchOption.AllDirectories); if (audioFiles.Length < 1) throw new DataException("No Audio file found."); if (audioFiles.Length > 2) throw new DataException("Too many Audio files found."); int i; for (i = 0; i < audioFiles.Length; i++) { if (convert && audioFiles[i].Contains("_fixed.ogg")) // use it break; if (!convert && !audioFiles[i].Contains("_fixed.ogg")) break; } // FIXME: platform specific decode is broken var sourcePlatform = unpackedDir.GetPlatform(); if (targetPlatform.IsConsole != (sourcePlatform = audioFiles[i].GetAudioPlatform()).IsConsole) { var newFile = Path.Combine(Path.GetDirectoryName(audioFiles[i]), String.Format("{0}_cap.ogg", Path.GetFileNameWithoutExtension(audioFiles[i]))); OggFile.ConvertAudioPlatform(audioFiles[i], newFile); audioFiles[i] = newFile; } targetAudioFiles.Add(audioFiles[i]); if (!targetAudioFiles.Any()) throw new DataException("Audio file not found."); var a = new FileInfo(audioFiles[i]); data.OggPath = a.FullName; //AppID if (!sourcePlatform.IsConsole) { if (!convert) { var appidFile = Directory.GetFiles(unpackedDir, "*APP_ID*", SearchOption.AllDirectories); if (appidFile.Length > 0) data.AppId = File.ReadAllText(appidFile[0]); } else data.AppId = "248750"; } try {//TODO: validate that rs1 songs have no this file //Package version var versionFile = Directory.GetFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories); if (versionFile.Length > 0) data.PackageVersion = GeneralExtensions.ReadPackageVersion(versionFile[0]); else data.PackageVersion = "1"; } catch {} if (convert) data.Tones = null; return data; }
/// <summary> /// Song2014 to ASCII Tablature /// </summary> /// <param name="rs2014Song"></param> /// <param name="outputDir"></param> /// <param name="allDif"></param> public void Song2014ToAsciiTab(Song2014 rs2014Song, string outputDir, bool allDif) { if (rs2014Song == null || String.IsNullOrEmpty(outputDir)) return; // convert to Song Song rs1Song; using (var obj = new Rs2014Converter()) rs1Song = obj.Song2014ToSong(rs2014Song); Console.WriteLine("Converted Song2014 To Song"); //if (false) // write Xml files for debugging //{ // using (Rs2014Converter obj = new Rs2014Converter()) // obj.Song2014ToXml(rs2014Song, outputDir, true); // using (Rs1Converter obj = new Rs1Converter()) // obj.SongToXml(rs1Song, outputDir, true); //} // convert to SngFile string rs1SngFilePath; using (var obj = new Rs1Converter()) rs1SngFilePath = obj.SongToSngFilePath(rs1Song, outputDir); Console.WriteLine("Converted Song To SngFile"); // convert to AsciiTab using (var s2Tab = new Sng2Tab()) s2Tab.Convert(rs1SngFilePath, outputDir, allDif); Console.WriteLine("Converted SngFile To AsciiTab"); if (File.Exists(rs1SngFilePath)) File.Delete(rs1SngFilePath); }
public bool LoadXmlArrangement(string xmlFilePath) { if (isAlreadyAdded(xmlFilePath)) { MessageBox.Show(@"XML Arrangement: " + Path.GetFileName(xmlFilePath) + " " + Environment.NewLine + @"has already been added. Please choose a new file. ", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } try { bool isVocal = false; bool isShowlight = false; try { xmlSong = Song2014.LoadFromFile(xmlFilePath); Arrangement.XmlComments = Song2014.ReadXmlComments(xmlFilePath); } catch (Exception ex) { if (ex.InnerException.Message.ToLower().Contains("<vocals")) isVocal = true; else if (ex.InnerException.Message.ToLower().Contains("<showlights")) isShowlight = true; else { MessageBox.Show(@"Unable to get information from XML arrangement: " + Environment.NewLine + Path.GetFileName(xmlFilePath) + Environment.NewLine + @"It may not be a valid arrangment or " + Environment.NewLine + @"your version of the EOF may be out of date." + Environment.NewLine + ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } } // SETUP FIELDS if (isVocal) { arrangementTypeCombo.SelectedItem = ArrangementType.Vocal; _arrangement.ArrangementType = ArrangementType.Vocal; } else if (isShowlight) { arrangementTypeCombo.SelectedItem = ArrangementType.ShowLight; _arrangement.ArrangementType = ArrangementType.ShowLight; } else { var version = GameVersion.None; //Detect arrangement GameVersion if (xmlSong != null && xmlSong.Version != null) { var verAttrib = Convert.ToInt32(xmlSong.Version); if (verAttrib <= 6) version = GameVersion.RS2012; else if (verAttrib >= 7) version = GameVersion.RS2014; } else if (currentGameVersion == GameVersion.RS2012) { // add missing XML elements xmlSong.Version = "4"; xmlSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 }; xmlSong.ArrangementProperties = new SongArrangementProperties2014 { StandardTuning = 1 }; version = GameVersion.RS2012; } else if (currentGameVersion == GameVersion.None) { using (var obj = new Rs1Converter()) { xmlSong = null; xmlSong = obj.SongToSong2014(Song.LoadFromFile(XmlFilePath.Text)); } currentGameVersion = GameVersion.RS2014; } else MessageBox.Show("Your version of EOF may be out of date, please update.", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); // TODO: fix error checking logic for new types of conversion if (currentGameVersion != version && version != GameVersion.None) { Debug.WriteLine(String.Format("Please choose valid Rocksmith {0} arrangement file!", currentGameVersion)); //XmlFilePath.Text = ""; //return; } // SONG AND ARRANGEMENT INFO / ROUTE MASK BonusCheckBox.Checked = Equals(xmlSong.ArrangementProperties.BonusArr, 1); MetronomeCb.Checked = Equals(xmlSong.ArrangementProperties.Metronome, 2); if (!EditMode) { string arr = xmlSong.Arrangement.ToLowerInvariant(); if (arr.Contains("guitar") || arr.Contains("lead") || arr.Contains("rhythm") || arr.Contains("combo")) { arrangementTypeCombo.SelectedItem = ArrangementType.Guitar; if (arr.Contains("combo")) { arrangementNameCombo.SelectedItem = ArrangementName.Combo; if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead; } else if (arr.Contains("guitar_22") || arr.Contains("lead") || Equals(xmlSong.ArrangementProperties.PathLead, 1)) { arrangementNameCombo.SelectedItem = ArrangementName.Lead; if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead; } else if (arr.Contains("guitar") || arr.Contains("rhythm") || Equals(xmlSong.ArrangementProperties.PathRhythm, 1)) { arrangementNameCombo.SelectedItem = ArrangementName.Rhythm; if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Rhythm; } } else if (arr.Contains("bass")) { arrangementTypeCombo.SelectedItem = ArrangementType.Bass; //SetTuningCombo(xmlSong.Tuning, true); Picked.Checked = Equals(xmlSong.ArrangementProperties.BassPick, 1); if (currentGameVersion != GameVersion.RS2012) { RouteMask = RouteMask.Bass; //Low tuning fix for bass, If lowstring is B and bass fix not applied if (xmlSong.Tuning.String0 < -4 && this.frequencyTB.Text == "440") bassFix |= MessageBox.Show("Your tuning is too low, would you like to apply \"Low Tuning Fix?\"\n" + "Note, that this won't work if you re-save arangement in EOF.\n", "Low Tuning Fix Required!", MessageBoxButtons.YesNo) == DialogResult.Yes; } } } if (currentGameVersion != GameVersion.RS2012) { //Tones setup Arrangement.ToneBase = xmlSong.ToneBase; Arrangement.ToneA = xmlSong.ToneA; Arrangement.ToneB = xmlSong.ToneB; Arrangement.ToneC = xmlSong.ToneC; Arrangement.ToneD = xmlSong.ToneD; Arrangement.ToneMultiplayer = null; SetupTones(Arrangement); //Apply bass Fix, refactor me. if (bassFix) { bassFix = false; Arrangement.SongXml.File = XmlFilePath.Text; parentControl.ApplyBassFix(Arrangement); } } // Setup tuning var selectedType = new ArrangementType(); if (xmlSong.Arrangement.ToLower() == "bass") selectedType = ArrangementType.Bass; else selectedType = ArrangementType.Guitar; FillTuningCombo(selectedType, currentGameVersion); // find tuning in tuningComboBox list and make selection int foundTuning = -1; for (int tcbIndex = 0; tcbIndex < tuningComboBox.Items.Count; tcbIndex++) { tuningComboBox.SelectedIndex = tcbIndex; TuningDefinition tuning = (TuningDefinition)tuningComboBox.Items[tcbIndex]; if (tuning.Tuning == xmlSong.Tuning) { foundTuning = tcbIndex; break; } } if (foundTuning == -1 && selectedType != ArrangementType.Bass) ShowTuningForm(selectedType, new TuningDefinition { Tuning = xmlSong.Tuning, Custom = true, GameVersion = currentGameVersion }); else { if (selectedType == ArrangementType.Bass) { MessageBox.Show(@"Remember to set the correct tuning using Edit for" + Environment.NewLine + @"Bass Arrangement: " + Path.GetFileName(xmlFilePath), DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); tuningComboBox.SelectedIndex = 0; } else tuningComboBox.SelectedIndex = foundTuning; } tuningComboBox.Refresh(); Arrangement.Tuning = tuningComboBox.SelectedItem.ToString(); Arrangement.TuningStrings = xmlSong.Tuning; Arrangement.CapoFret = xmlSong.Capo; frequencyTB.Text = Arrangement.TuningPitch.ToString(); UpdateCentOffset(); // save converted RS1 to RS2014 Song2014 XML if (version == GameVersion.None) { var srcDir = Path.GetDirectoryName(XmlFilePath.Text); var srcName = Path.GetFileNameWithoutExtension(XmlFilePath.Text); var backupSrcPath = String.Format("{0}_{1}.xml", Path.Combine(srcDir, srcName), "RS1"); // backup original RS1 file File.Copy(XmlFilePath.Text, backupSrcPath); // write converted RS1 file using (FileStream stream = new FileStream(XmlFilePath.Text, FileMode.Create)) xmlSong.Serialize(stream, true); } } } catch (Exception ex) { MessageBox.Show(@"Unable to get information from XML arrangement: " + Environment.NewLine + Path.GetFileName(xmlFilePath) + Environment.NewLine + @"It may not be a valide arrangment or " + Environment.NewLine + @"your version of the EOF may be out of date." + Environment.NewLine + ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } return true; }
public bool LoadXmlArrangement(string xmlFilePath) { if (IsAlreadyAdded(xmlFilePath)) { MessageBox.Show(@"XML Arrangement: " + Path.GetFileName(xmlFilePath) + @" " + Environment.NewLine + @"has already been added. Please choose a new file. ", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } try { bool isVocal = false; bool isShowlight = false; try { xmlSong = Song2014.LoadFromFile(xmlFilePath); Arrangement.XmlComments = Song2014.ReadXmlComments(xmlFilePath); } catch (Exception ex) { if (ex.InnerException.Message.ToLower().Contains("<vocals")) isVocal = true; else if (ex.InnerException.Message.ToLower().Contains("<showlights")) isShowlight = true; else { MessageBox.Show(@"Unable to get information from XML arrangement: " + Environment.NewLine + Path.GetFileName(xmlFilePath) + Environment.NewLine + @"It may not be a valid arrangement or " + Environment.NewLine + @"your version of the EOF may be out of date." + Environment.NewLine + ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } } // SETUP FIELDS if (isVocal) { arrangementTypeCombo.SelectedItem = ArrangementType.Vocal; _arrangement.ArrangementType = ArrangementType.Vocal; } else if (isShowlight) { arrangementTypeCombo.SelectedItem = ArrangementType.ShowLight; _arrangement.ArrangementType = ArrangementType.ShowLight; } else { var version = GameVersion.None; //Detect arrangement GameVersion if (xmlSong != null && xmlSong.Version != null) { var verAttrib = Convert.ToInt32(xmlSong.Version); if (verAttrib <= 6) version = GameVersion.RS2012; else if (verAttrib >= 7) version = GameVersion.RS2014; } else switch (currentGameVersion) { case GameVersion.RS2012: // add missing XML elements xmlSong.Version = "4"; xmlSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 }; xmlSong.ArrangementProperties = new SongArrangementProperties2014 { StandardTuning = 1 }; version = GameVersion.RS2012; break; case GameVersion.None: using (var obj = new Rs1Converter()) { xmlSong = null; xmlSong = obj.SongToSong2014(Song.LoadFromFile(XmlFilePath.Text)); } currentGameVersion = GameVersion.RS2014; break; default: MessageBox.Show("Your version of EOF may be out of date, please update.", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); break; } // TODO: fix error checking logic for new types of conversion if (currentGameVersion != version && version != GameVersion.None) { Debug.WriteLine("Please choose valid Rocksmith {0} arrangement file!", currentGameVersion); //XmlFilePath.Text = ""; //return; } // SONG AND ARRANGEMENT INFO / ROUTE MASK BonusCheckBox.Checked = Equals(xmlSong.ArrangementProperties.BonusArr, 1); MetronomeCb.Checked = Equals(xmlSong.ArrangementProperties.Metronome, 2); Arrangement.ArrangementPropeties = xmlSong.ArrangementProperties; Arrangement.CapoFret = xmlSong.Capo; if (!EditMode) { string arr = xmlSong.Arrangement.ToLowerInvariant(); if (arr.Contains("guitar") || arr.Contains("lead") || arr.Contains("rhythm") || arr.Contains("combo")) { arrangementTypeCombo.SelectedItem = ArrangementType.Guitar; if (arr.Contains("combo")) { arrangementNameCombo.SelectedItem = ArrangementName.Combo; if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead; } else if (arr.Contains("guitar_22") || arr.Contains("lead") || Equals(xmlSong.ArrangementProperties.PathLead, 1)) { arrangementNameCombo.SelectedItem = ArrangementName.Lead; if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Lead; } else if (arr.Contains("guitar") || arr.Contains("rhythm") || Equals(xmlSong.ArrangementProperties.PathRhythm, 1)) { arrangementNameCombo.SelectedItem = ArrangementName.Rhythm; if (currentGameVersion != GameVersion.RS2012) RouteMask = RouteMask.Rhythm; } } else if (arr.Contains("bass")) { arrangementTypeCombo.SelectedItem = ArrangementType.Bass; Picked.Checked = Equals(xmlSong.ArrangementProperties.BassPick, 1); if (currentGameVersion != GameVersion.RS2012) { RouteMask = RouteMask.Bass; //Low tuning fix for bass, If lowest string is B and bass fix not applied TODO:applyonly when 'generate' if (xmlSong.Tuning.String0 < -4 && Arrangement.TuningPitch != 220) bassFix |= MessageBox.Show(@"The bass tuning may be too low. Apply Low Bass Tuning Fix?" + Environment.NewLine + @"Note: The fix will revert if bass arrangement is re-saved in EOF. ", @"Warning ... Low Bass Tuning", MessageBoxButtons.YesNo) == DialogResult.Yes; } } } if (currentGameVersion != GameVersion.RS2012) { //Tones setup //TODO: add parsing tones events Arrangement.ToneBase = xmlSong.ToneBase; Arrangement.ToneA = xmlSong.ToneA; Arrangement.ToneB = xmlSong.ToneB; Arrangement.ToneC = xmlSong.ToneC; Arrangement.ToneD = xmlSong.ToneD; Arrangement.ToneMultiplayer = null; SetupTones(Arrangement); // Fix Low Bass Tuning if (bassFix) { bassFix = false; Arrangement.SongXml.File = XmlFilePath.Text; if (Arrangement.TuningStrings == null) { // need to load tuning here from the xml arrangement Arrangement.TuningStrings = new TuningStrings(); Arrangement.TuningStrings = xmlSong.Tuning; } if (!TuningFrequency.ApplyBassFix(Arrangement)) MessageBox.Show("This bass arrangement is already at 220Hz pitch. ", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error); else { var commentsList = Arrangement.XmlComments.ToList(); commentsList.Add(new XComment("Low Bass Tuning Fixed")); Arrangement.XmlComments = commentsList; } xmlSong.Tuning = Arrangement.TuningStrings; } } // Setup tuning ArrangementType selectedType; if (xmlSong.Arrangement.ToLower() == "bass") selectedType = ArrangementType.Bass; else selectedType = ArrangementType.Guitar; FillTuningCombo(selectedType, currentGameVersion); // find tuning in tuningComboBox list and make selection int foundTuning = -1; for (int tcbIndex = 0; tcbIndex < tuningComboBox.Items.Count; tcbIndex++) { tuningComboBox.SelectedIndex = tcbIndex; TuningDefinition tuning = (TuningDefinition)tuningComboBox.Items[tcbIndex]; if (tuning.Tuning == xmlSong.Tuning) { foundTuning = tcbIndex; break; } } if (foundTuning == -1 && selectedType != ArrangementType.Bass) { tuningComboBox.SelectedIndex = 0; ShowTuningForm(selectedType, new TuningDefinition(xmlSong.Tuning, currentGameVersion)); //FIXME: Don't use this for QuickAdd call } // E Standard, Drop D, and Open E tuning are now the same for both guitar and bass if (foundTuning == -1 && selectedType == ArrangementType.Bass) { tuningComboBox.SelectedIndex = 0; MessageBox.Show("Toolkit was not able to automatically set tuning for" + Environment.NewLine + "Bass Arrangement: " + Path.GetFileName(xmlFilePath) + Environment.NewLine + "Use the tuning selector dropdown or Tuning Editor" + Environment.NewLine + "to customize bass tuning (as defined for six strings). ", DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); } tuningComboBox.Refresh(); Arrangement.Tuning = tuningComboBox.SelectedItem.ToString(); Arrangement.TuningStrings = xmlSong.Tuning; Arrangement.CapoFret = xmlSong.Capo; frequencyTB.Text = Arrangement.TuningPitch.ToString(CultureInfo.InvariantCulture); // bastard bass hack if (Arrangement.Tuning.ToLower().Contains("fixed")) frequencyTB.Text = "220"; //UpdateCentOffset();//bad way to update tuning info, IMO // save converted RS1 to RS2014 Song2014 XML if (version == GameVersion.None) { var srcDir = Path.GetDirectoryName(XmlFilePath.Text); var srcName = Path.GetFileNameWithoutExtension(XmlFilePath.Text); var backupSrcPath = String.Format("{0}_{1}.xml", Path.Combine(srcDir, srcName), "RS1"); // backup original RS1 file File.Copy(XmlFilePath.Text, backupSrcPath); // write converted RS1 file using (var stream = new FileStream(XmlFilePath.Text, FileMode.Create)) xmlSong.Serialize(stream, true); } } } catch (Exception ex) { MessageBox.Show(@"Unable to get information from XML arrangement: " + Environment.NewLine + Path.GetFileName(xmlFilePath) + Environment.NewLine + @"It may not be a valid arrangement or " + Environment.NewLine + @"your version of the EOF may be out of date." + Environment.NewLine + ex.Message, DLCPackageCreator.MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } return true; }