public Arrangement(Attributes2014 attr, string xmlSongFile) { var song = Song2014.LoadFromFile(xmlSongFile); this.SongFile = new SongFile(); this.SongFile.File = ""; this.SongXml = new SongXML(); this.SongXml.File = xmlSongFile; bool isBass = false; TuningDefinition tuning = null; switch ((ArrangementName)attr.ArrangementType) { case ArrangementName.Lead: case ArrangementName.Rhythm: case ArrangementName.Combo: this.ArrangementType = Sng.ArrangementType.Guitar; tuning = TuningDefinitionRepository.Instance().Select(song.Tuning, GameVersion.RS2014); break; case ArrangementName.Bass: this.ArrangementType = Sng.ArrangementType.Bass; tuning = TuningDefinitionRepository.Instance().SelectForBass(song.Tuning, GameVersion.RS2014); isBass = true; break; case ArrangementName.Vocals: this.ArrangementType = Sng.ArrangementType.Vocal; break; } if (tuning == null) { tuning = new TuningDefinition(); tuning.UIName = tuning.Name = tuning.NameFromStrings(song.Tuning, isBass); tuning.Custom = true; tuning.GameVersion = GameVersion.RS2014; tuning.Tuning = song.Tuning; TuningDefinitionRepository.Instance().Add(tuning, true); } this.Tuning = tuning.UIName; this.TuningStrings = tuning.Tuning; if (attr.CentOffset != null) this.TuningPitch = attr.CentOffset.Cents2Frequency(); this.ArrangementSort = attr.ArrangementSort; this.Name = (ArrangementName)Enum.Parse(typeof(ArrangementName), attr.ArrangementName); this.ScrollSpeed = Convert.ToInt32(attr.DynamicVisualDensity.Last() * 10); this.PluckedType = (PluckedType)attr.ArrangementProperties.BassPick; this.RouteMask = (RouteMask)attr.ArrangementProperties.RouteMask; this.BonusArr = attr.ArrangementProperties.BonusArr == 1; this.ToneBase = attr.Tone_Base; this.ToneMultiplayer = attr.Tone_Multiplayer; this.ToneA = attr.Tone_A; this.ToneB = attr.Tone_B; this.ToneC = attr.Tone_C; this.ToneD = attr.Tone_D; this.Id = Guid.Parse(attr.PersistentID); this.MasterId = attr.MasterID_RDV; }
private Arrangement(Attributes2014 attr, Sng2014File song, Guid id) { this.ArrangementSort = attr.ArrangementSort; this.Sng2014 = song; this.Name = (ArrangementName)Enum.Parse(typeof(ArrangementName), attr.ArrangementName); this.ScrollSpeed = 20; this.Id = id; this.MasterId = ArrangementType == Sng.ArrangementType.Vocal ? 1 : RandomGenerator.NextInt(); if (this.ArrangementType == ArrangementType.Vocal) { this.Tones = new List<Tone2014>(); } else { ParseTuning(this, attr); ParseTones(this, attr); } }
internal static SongTone2014[] Parse(Sng2014HSL.ToneSection toneSection, Attributes2014 attr = null) { var tones = new SongTone2014[toneSection.Count]; for (var i = 0; i < toneSection.Count; i++) { var tone = new SongTone2014(); tone.Id = toneSection.Tones[i].ToneId; tone.Time = toneSection.Tones[i].Time; if (attr != null) { // Get tone name switch (tone.Id) { case 0: tone.Name = attr.Tone_A; break; case 1: tone.Name = attr.Tone_B; break; case 2: tone.Name = attr.Tone_C; break; case 3: tone.Name = attr.Tone_D; break; default: tone.Name = "importedtone_" + tone.Id; break; } } else tone.Name = "importedtone_" + tone.Id; tones[i] = tone; } return tones; }
public Song2014(Sng2014HSL.Sng sngData, Attributes2014 attr = null) { Version = "7"; CrowdSpeed = "1"; if (attr != null) { // If manifest is passed, fill general song information Title = attr.SongName; Arrangement = ((ArrangementName)attr.ArrangementType).ToString(); Part = (short)attr.SongPartition; Offset = attr.SongOffset; CentOffset = Convert.ToString(attr.CentOffset); SongLength = (float)attr.SongLength; SongNameSort = attr.SongNameSort; AverageTempo = attr.SongAverageTempo; Tuning = attr.Tuning; Capo = Convert.ToByte(attr.CapoFret); ArtistName = attr.ArtistName; ArtistNameSort = attr.ArtistNameSort; AlbumName = attr.AlbumName; AlbumNameSort = attr.AlbumNameSort; AlbumYear = Convert.ToString(attr.SongYear) ?? ""; AlbumArt = attr.AlbumArt; ArrangementProperties = attr.ArrangementProperties; LastConversionDateTime = attr.LastConversionDateTime; ToneBase = attr.Tone_Base; ToneA = attr.Tone_A; ToneB = attr.Tone_B; ToneC = attr.Tone_C; ToneD = attr.Tone_D; } else { Part = sngData.Metadata.Part; SongLength = sngData.Metadata.SongLength; Tuning = new TuningStrings(sngData.Metadata.Tuning); Capo = (sngData.Metadata.CapoFretId >= 0) ? sngData.Metadata.CapoFretId : (byte)0; LastConversionDateTime = sngData.Metadata.LastConversionDateTime.ToNullTerminatedAscii(); } Tones = (attr != null) ? SongTone2014.Parse(sngData.Tones, attr) : SongTone2014.Parse(sngData.Tones); if (attr == null) { // Fix tones slots for fake tone names if manifest was not entered foreach (var tone in Tones) { if (tone.Name.EndsWith("_0")) ToneBase = tone.Name; if (tone.Name.EndsWith("_1")) { ToneA = ToneBase; ToneB = tone.Name; } if (tone.Name.EndsWith("_2")) ToneC = tone.Name; if (tone.Name.EndsWith("_3")) ToneD = tone.Name; } } //Sections can be obtained from manifest or sng file (manifest preferred) Sections = (attr != null) ? SongSection.Parse(attr.Sections) : SongSection.Parse(sngData.Sections); //Can be obtained from manifest or sng file (sng preferred) Phrases = SongPhrase.Parse(sngData.Phrases); PhraseIterations = SongPhraseIteration2014.Parse(sngData.PhraseIterations); //Can be obtained from manifest or sng file (combined preferred) ChordTemplates = SongChordTemplate2014.Parse(sngData.Chords); // Only SNG have all ChordTemplates, manifest have only chord templates with name if (attr != null) { SongChordTemplate2014.AddChordIds(ChordTemplates, attr.ChordTemplates); // Only manifest has chordIds } //Only in SNG Ebeats = SongEbeat.Parse(sngData.BPMs); StartBeat = sngData.BPMs.BPMs[0].Time; Events = SongEvent.Parse(sngData.Events); Levels = SongLevel2014.Parse(sngData); //Not used in RS2014 customs at this time. Need to check official files NewLinkedDiff = SongNewLinkedDiff.Parse(sngData.NLD); PhraseProperties = SongPhraseProperty.Parse(sngData.PhraseExtraInfo); LinkedDiffs = new SongLinkedDiff[0]; FretHandMuteTemplates = new SongFretHandMuteTemplate[0]; }
private static void GenerateRS2014SongPsarc(MemoryStream output, DLCPackageData info, Platform platform) { var dlcName = info.Name.ToLower(); { var packPsarc = new PSARC.PSARC(); // Stream objects Stream soundStream = null, soundPreviewStream = null, rsenumerableRootStream = null, rsenumerableSongStream = null; try { // ALBUM ART var ddsfiles = info.ArtFiles; if (ddsfiles == null) { string albumArtPath; if (File.Exists(info.AlbumArtPath)) { albumArtPath = info.AlbumArtPath; } else { using (var albumArtStream = new MemoryStream(Resources.albumart2014_256)) { albumArtPath = GeneralExtensions.GetTempFileName(".dds"); albumArtStream.WriteFile(albumArtPath); TMPFILES_ART.Add(albumArtPath); } } ddsfiles = new List<DDSConvertedFile>(); ddsfiles.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") }); ddsfiles.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") }); ddsfiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") }); // Convert to DDS ToDDS(ddsfiles); // Save for reuse info.ArtFiles = ddsfiles; } foreach (var dds in ddsfiles) packPsarc.AddEntry(String.Format("gfxassets/album_art/album_{0}_{1}.dds", dlcName, dds.sizeX), new FileStream(dds.destinationFile, FileMode.Open, FileAccess.Read, FileShare.Read)); //Lyrics Font Texture if (File.Exists(info.LyricsTex)) packPsarc.AddEntry(String.Format("assets/ui/lyrics/{0}/lyrics_{0}.dds", dlcName), new FileStream(info.LyricsTex, FileMode.Open, FileAccess.Read, FileShare.Read)); // AUDIO var audioFile = info.OggPath; if (File.Exists(audioFile)) if (platform.IsConsole != audioFile.GetAudioPlatform().IsConsole) soundStream = OggFile.ConvertAudioPlatform(audioFile); else soundStream = File.OpenRead(audioFile); else throw new InvalidOperationException(String.Format("Audio file '{0}' not found.", audioFile)); // AUDIO PREVIEW var previewAudioFile = info.OggPreviewPath; if (File.Exists(previewAudioFile)) if (platform.IsConsole != previewAudioFile.GetAudioPlatform().IsConsole) soundPreviewStream = OggFile.ConvertAudioPlatform(previewAudioFile); else soundPreviewStream = File.OpenRead(previewAudioFile); else soundPreviewStream = soundStream; // FLAT MODEL rsenumerableRootStream = new MemoryStream(Resources.rsenumerable_root); packPsarc.AddEntry("flatmodels/rs/rsenumerable_root.flat", rsenumerableRootStream); rsenumerableSongStream = new MemoryStream(Resources.rsenumerable_song); packPsarc.AddEntry("flatmodels/rs/rsenumerable_song.flat", rsenumerableSongStream); using (var toolkitVersionStream = new MemoryStream()) using (var appIdStream = new MemoryStream()) using (var packageListStream = new MemoryStream()) using (var soundbankStream = new MemoryStream()) using (var soundbankPreviewStream = new MemoryStream()) using (var aggregateGraphStream = new MemoryStream()) using (var manifestHeaderHSANStream = new MemoryStream()) using (var manifestHeaderHSONStreamList = new DisposableCollection<Stream>()) using (var manifestStreamList = new DisposableCollection<Stream>()) using (var arrangementStream = new DisposableCollection<Stream>()) using (var showlightStream = new MemoryStream()) using (var xblockStream = new MemoryStream()) { // TOOLKIT VERSION GenerateToolkitVersion(toolkitVersionStream, info.PackageVersion); packPsarc.AddEntry("toolkit.version", toolkitVersionStream); // APP ID if (!platform.IsConsole) { GenerateAppId(appIdStream, info.AppId, platform); packPsarc.AddEntry("appid.appid", appIdStream); } if (platform.platform == GamePlatform.XBox360) { var packageListWriter = new StreamWriter(packageListStream); packageListWriter.Write(dlcName); packageListWriter.Flush(); packageListStream.Seek(0, SeekOrigin.Begin); string packageList = "PackageList.txt"; packageListStream.WriteTmpFile(packageList, platform); } // SOUNDBANK var soundbankFileName = String.Format("song_{0}", dlcName); var audioFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name, soundStream, soundbankStream, info.Volume, platform); packPsarc.AddEntry(String.Format("audio/{0}/{1}.bnk", platform.GetPathName()[0].ToLower(), soundbankFileName), soundbankStream); packPsarc.AddEntry(String.Format("audio/{0}/{1}.wem", platform.GetPathName()[0].ToLower(), audioFileNameId), soundStream); // SOUNDBANK PREVIEW var soundbankPreviewFileName = String.Format("song_{0}_preview", dlcName); dynamic audioPreviewFileNameId; var previewVolume = (info.PreviewVolume != null) ? (float)info.PreviewVolume : info.Volume; if (!soundPreviewStream.Equals(soundStream)) audioPreviewFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name + "_Preview", soundPreviewStream, soundbankPreviewStream, previewVolume, platform, true); else audioPreviewFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name + "_Preview", soundPreviewStream, soundbankPreviewStream, info.Volume, platform, true, true); packPsarc.AddEntry(String.Format("audio/{0}/{1}.bnk", platform.GetPathName()[0].ToLower(), soundbankPreviewFileName), soundbankPreviewStream); if (!soundPreviewStream.Equals(soundStream)) packPsarc.AddEntry(String.Format("audio/{0}/{1}.wem", platform.GetPathName()[0].ToLower(), audioPreviewFileNameId), soundPreviewStream); // AGGREGATE GRAPH var aggregateGraphFileName = String.Format("{0}_aggregategraph.nt", dlcName); var aggregateGraph = new AggregateGraph2014(info, platform); aggregateGraph.Serialize(aggregateGraphStream); aggregateGraphStream.Flush(); aggregateGraphStream.Seek(0, SeekOrigin.Begin); packPsarc.AddEntry(aggregateGraphFileName, aggregateGraphStream); var manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform); var songPartition = new SongPartition(); var songPartitionCount = new SongPartition(); foreach (var arrangement in info.Arrangements) { var arrangementFileName = songPartition.GetArrangementFileName(arrangement.Name, arrangement.ArrangementType).ToLower(); // GAME SONG (SNG) UpdateToneDescriptors(info); GenerateSNG(arrangement, platform); var sngSongFile = File.OpenRead(arrangement.SongFile.File); arrangementStream.Add(sngSongFile); packPsarc.AddEntry(String.Format("songs/bin/{0}/{1}_{2}.sng", platform.GetPathName()[1].ToLower(), dlcName, arrangementFileName), sngSongFile); // XML SONG var xmlSongFile = File.OpenRead(arrangement.SongXml.File); arrangementStream.Add(xmlSongFile); packPsarc.AddEntry(String.Format("songs/arr/{0}_{1}.xml", dlcName, arrangementFileName), xmlSongFile); // MANIFEST var manifest = new Manifest2014<Attributes2014>(); var attribute = new Attributes2014(arrangementFileName, arrangement, info, platform); if (arrangement.ArrangementType != Sng.ArrangementType.Vocal) { attribute.SongPartition = songPartitionCount.GetSongPartition(arrangement.Name, arrangement.ArrangementType); if (attribute.SongPartition > 1) { // Make the second arrangement with the same arrangement type as ALTERNATE arrangement ingame attribute.Representative = 0; attribute.ArrangementProperties.Represent = 0; } } var attributeDictionary = new Dictionary<string, Attributes2014> { { "Attributes", attribute } }; manifest.Entries.Add(attribute.PersistentID, attributeDictionary); var manifestStream = new MemoryStream(); manifestStreamList.Add(manifestStream); manifest.Serialize(manifestStream); manifestStream.Seek(0, SeekOrigin.Begin); var jsonPathPC = "manifests/songs_dlc_{0}/{0}_{1}.json"; var jsonPathConsole = "manifests/songs_dlc/{0}_{1}.json"; packPsarc.AddEntry(String.Format((platform.IsConsole ? jsonPathConsole : jsonPathPC), dlcName, arrangementFileName), manifestStream); // MANIFEST HEADER var attributeHeaderDictionary = new Dictionary<string, AttributesHeader2014> { { "Attributes", new AttributesHeader2014(attribute) } }; if (platform.IsConsole) { // One for each arrangements (Xbox360/PS3) manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform); manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary); var manifestHeaderStream = new MemoryStream(); manifestHeaderHSONStreamList.Add(manifestHeaderStream); manifestHeader.Serialize(manifestHeaderStream); manifestStream.Seek(0, SeekOrigin.Begin); packPsarc.AddEntry(String.Format("manifests/songs_dlc/{0}_{1}.hson", dlcName, arrangementFileName), manifestHeaderStream); } else { // One for all arrangements (PC/Mac) manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary); } } if (!platform.IsConsole) { manifestHeader.Serialize(manifestHeaderHSANStream); manifestHeaderHSANStream.Seek(0, SeekOrigin.Begin); packPsarc.AddEntry(String.Format("manifests/songs_dlc_{0}/songs_dlc_{0}.hsan", dlcName), manifestHeaderHSANStream); } // SHOWLIGHT Showlights showlight = new Showlights(info); showlight.Serialize(showlightStream); if(showlightStream.CanRead) packPsarc.AddEntry(String.Format("songs/arr/{0}_showlights.xml", dlcName), showlightStream); // XBLOCK GameXblock<Entity2014> game = GameXblock<Entity2014>.Generate2014(info, platform); game.SerializeXml(xblockStream); xblockStream.Flush(); xblockStream.Seek(0, SeekOrigin.Begin); packPsarc.AddEntry(String.Format("gamexblocks/nsongs/{0}.xblock", dlcName), xblockStream); // WRITE PACKAGE packPsarc.Write(output, !platform.IsConsole); output.Flush(); output.Seek(0, SeekOrigin.Begin); output.WriteTmpFile(String.Format("{0}.psarc", dlcName), platform); } } catch (Exception ex) { throw ex; } finally { // Dispose all objects if (soundStream != null) soundStream.Dispose(); if (soundPreviewStream != null) soundPreviewStream.Dispose(); if (rsenumerableRootStream != null) rsenumerableRootStream.Dispose(); if (rsenumerableSongStream != null) rsenumerableSongStream.Dispose(); DeleteTmpFiles(TMPFILES_SNG); DeleteTmpFiles(TMPFILES_ART); } } }
private static void ParseTuning(Arrangement dest, Attributes2014 attr) { bool isBass = false; TuningDefinition tuning = null; switch (dest.Name) { case ArrangementName.Bass: tuning = TuningDefinitionRepository.Instance().SelectForBass(attr.Tuning, GameVersion.RS2014); isBass = true; break; case ArrangementName.Vocals: break; default: tuning = TuningDefinitionRepository.Instance().Select(attr.Tuning, GameVersion.RS2014); break; } if (tuning == null) { tuning = new TuningDefinition(); tuning.UIName = tuning.Name = TuningDefinition.NameFromStrings(attr.Tuning, isBass); tuning.Custom = true; tuning.GameVersion = GameVersion.RS2014; tuning.Tuning = attr.Tuning; TuningDefinitionRepository.Instance().Add(tuning, true); } dest.Tuning = tuning.UIName; dest.TuningStrings = tuning.Tuning; if (attr.CentOffset != null) dest.TuningPitch = attr.CentOffset.Cents2Frequency(); }
private static void ParseTones(Arrangement dest, Attributes2014 attr) { dest.ScrollSpeed = Convert.ToInt32(attr.DynamicVisualDensity.Last() * 10); dest.PluckedType = (PluckedType)attr.ArrangementProperties.BassPick; dest.RouteMask = (RouteMask)attr.ArrangementProperties.RouteMask; dest.BonusArr = attr.ArrangementProperties.BonusArr == 1; dest.ToneBase = attr.Tone_Base; dest.ToneMultiplayer = attr.Tone_Multiplayer; dest.ToneA = attr.Tone_A; dest.ToneB = attr.Tone_B; dest.ToneC = attr.Tone_C; dest.ToneD = attr.Tone_D; dest.Tones = attr.Tones.ToList(); }
public static Arrangement Read(Attributes2014 attr, Platform platform, Guid id, string filename, Stream data = null) { Arrangement result = null; using (var str = data ?? File.OpenRead(filename)) { switch (Path.GetExtension(filename)) { case ".xml": Sng2014File xml = null; if (((ArrangementName)attr.ArrangementType) == ArrangementName.Vocals) xml = Sng2014FileWriter.ReadVocals(data); else xml = Sng2014File.ConvertXML(str); result = new Arrangement(attr, xml, id); break; case ".sng": result = new Arrangement(attr, Sng2014File.ReadSng(str, platform), id); break; default: throw new Exception("Unknown file type: " + filename); } result._songFilename = filename; } return result; }
public AttributesHeader2014(Attributes2014 attributes) { foreach (PropertyInfo prop in attributes.GetType().GetProperties()) if (GetType().GetProperty(prop.Name) != null) GetType().GetProperty(prop.Name).SetValue(this, prop.GetValue(attributes, null), null); }