public void QbKeyNormalizeTest3() { // Forward slash is replaced with backslash var s = "a/b"; Assert.AreEqual("a\\b", QbKey.Normalize(s)); }
public DatWad(EndianReader dat, Stream wad) : this() { Nodes.Clear(); Wad = wad; uint num = dat.ReadUInt32(); // Number of nodes dat.ReadUInt32(); // Header size for (int i = 0; i < num; i++) { QbKey item = QbKey.Create(dat.ReadUInt32()); Node node = new Node() { Key = item, Offset = dat.ReadUInt32(), Size = dat.ReadUInt32(), Reserved = dat.ReadBytes(8) }; node.Data = new Substream(Wad, node.Offset, node.Size); Nodes.Add(node); } foreach (Node node in Nodes) { Wad.Seek((long)(node.Offset + 0x1A), SeekOrigin.Begin); node.Filename = Util.ReadCString(Wad, 30); } }
private static void DecodeChartFretbars(SongData song, QbFile qbchart, NoteChart chart) { QbItemInteger fretbars = (qbchart.FindItem(QbKey.Create(song.ID + "_fretbars"), false) as QbItemArray).Items[0] as QbItemInteger; ulong ticks = 0; uint previousfret = 0; uint previousMsPerBeat = 0; for (int k = 1; k < fretbars.Values.Length; k++) { uint fret = fretbars.Values[k]; uint msPerBeat = fret - previousfret; if (msPerBeat != previousMsPerBeat) { chart.BPM.Add(new Midi.TempoEvent(ticks, msPerBeat * 1000)); } previousfret = fret; previousMsPerBeat = msPerBeat; ticks += chart.Division.TicksPerBeat; } chart.Events.End = new NoteChart.Point(chart.GetTicks(fretbars.Values[fretbars.Values.Length - 1])); QbItemArray timesig = (qbchart.FindItem(QbKey.Create(song.ID + "_timesig"), false) as QbItemArray).Items[0] as QbItemArray; foreach (QbItemInteger sig in timesig.Items) { chart.Signature.Add(new Midi.TimeSignatureEvent(chart.GetTicks(sig.Values[0]), (byte)sig.Values[1], (byte)Math.Log(sig.Values[2], 2), 24, 8)); } }
public void QbKeyNormalizeTest1() { // Lowercase string with no / is unchanged var n = (int)TestContext.CurrentContext.Random.NextUInt(40); var s = TestContext.CurrentContext.Random.GetString(n, "abcdefghijklmnopqrstuvwxyz"); Assert.AreEqual(s, QbKey.Normalize(s)); }
public void QbKeyNormalizeTest2() { // Uppercase string with no / is made lowercase var n = (int)TestContext.CurrentContext.Random.NextUInt(40); var s = TestContext.CurrentContext.Random.GetString(n, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); Assert.AreEqual(s.ToLowerInvariant(), QbKey.Normalize(s)); }
public void QbKeyUIntTest() { var random = TestContext.CurrentContext.Random; uint x = random.NextUInt(); var qbKey = new QbKey(x); Assert.AreEqual(x, qbKey.Checksum); }
public void QbKeyStringTestNoNormalize() { string s = TestContext.CurrentContext.Random.GetString(); var latin1 = Encoding.GetEncoding("iso-8859-1"); var qbKey = new QbKey(s, false); var crc = new CRC32().ComputeHash(latin1.GetBytes(s)); Assert.AreEqual(~BitConverter.ToUInt32(crc, 0), qbKey.Checksum); }
private static void DecodeChartVenue(SongData song, QbFile qbchart, NoteChart chart) { QbItemArray cameraitems = qbchart.FindItem(QbKey.Create(song.ID + "_cameras_notes"), false) as QbItemArray; if (cameraitems != null && cameraitems.Items.Count > 0) { cameraitems = cameraitems.Items[0] as QbItemArray; } if (cameraitems != null) { Random random = new Random(); foreach (QbItemInteger camera in cameraitems.Items) { uint time = camera.Values[0]; NoteChart.Point point = new NoteChart.Point(chart.GetTicks(camera.Values[0])); if (random.Next() % 9 == 0) { chart.Venue.DirectedShots.Add(new Pair <NoteChart.Point, NoteChart.VenueTrack.DirectedCut>(point, NoteChart.VenueTrack.DirectedCut.None)); } else { chart.Venue.CameraShots.Add(new Pair <NoteChart.Point, NoteChart.VenueTrack.CameraShot>(point, new NoteChart.VenueTrack.CameraShot())); } } } QbItemArray crowditems = qbchart.FindItem(QbKey.Create(song.ID + "_crowd_notes"), false) as QbItemArray; if (crowditems != null && crowditems.Items.Count > 0) { crowditems = crowditems.Items[0] as QbItemArray; } if (crowditems != null) { foreach (QbItemInteger crowd in crowditems.Items) { NoteChart.Point point = new NoteChart.Point(chart.GetTicks(crowd.Values[0])); chart.Events.Crowd.Add(new Pair <NoteChart.Point, NoteChart.EventsTrack.CrowdType>(point, NoteChart.EventsTrack.CrowdType.None)); } } QbItemArray lightitems = qbchart.FindItem(QbKey.Create(song.ID + "_lightshow_notes"), false) as QbItemArray; if (lightitems != null && lightitems.Items.Count > 0) { lightitems = lightitems.Items[0] as QbItemArray; } if (lightitems != null) { foreach (QbItemInteger light in lightitems.Items) { NoteChart.Point point = new NoteChart.Point(chart.GetTicks(light.Values[0])); chart.Venue.Lighting.Add(new Pair <NoteChart.Point, NoteChart.VenueTrack.LightingType>(point, NoteChart.VenueTrack.LightingType.None)); } } }
public Entry Find(QbKey key) { foreach (Entry entry in Entries) { if (entry.Identifier == key) { return(entry); } } return(null); }
public static QbItemBase GetQbItem(QbItemStruct item, uint[] keys) { foreach (uint key in keys) { QbItemBase subitem = item.FindItem(QbKey.Create(key), false); if (subitem != null) { return(subitem); } } return(null); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); data.Game = Platform.DetermineGame(data); FileNode qbpak = dir.Navigate("pak/qb.pak.ngc") as FileNode; if (qbpak == null) { Exceptions.Error("Couldn't find qb.pak.ngc on Guitar Hero 3 Wii disc."); } try { Pak qb = new Pak(new EndianReader(qbpak.Data, Endianness.BigEndian)); FileNode songlistfile = qb.Root.Find("songlist.qb.ngc", SearchOption.AllDirectories) as FileNode; FileNode albumfile = dir.Navigate("pak/album_covers/album_covers.pak.ngc", false, true) as FileNode; QbFile songlist = new QbFile(songlistfile.Data, PakFormat); QbItemStruct list = songlist.FindItem(QbKey.Create(NeversoftMetadata.SonglistKeys[0]), true) as QbItemStruct; data.Session["rootdir"] = dir; data.Session["rootqb"] = qb; if (albumfile != null) { data.Session["albumpak"] = new Pak(new EndianReader(albumfile.Data, Endianness.BigEndian)); } var items = list.Items; progress.NewTask(items.Count); foreach (QbItemStruct item in items) { SongData song = NeversoftMetadata.GetSongData(data, item); try { AddSong(data, song, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } progress.Progress(); } progress.EndTask(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero 3 Wii disc."); } return(data); }
protected uint[][] GetJaggedChartValues(Notes notes, QbFile qbchart, QbKey notekey, QbKey qbkey, params int[] split) { Notes.Entry entry; List <uint[]> nums = new List <uint[]>(); if (notes == null) { QbItemArray data = qbchart.FindItem(qbkey, false) as QbItemArray; while (data.Items[0] is QbItemArray) { data = data.Items[0] as QbItemArray; } foreach (QbItemBase num in data.Items) { if (num is QbItemInteger) { nums.Add((num as QbItemInteger).Values); } else if (num is QbItemFloat) { nums.Add((num as QbItemFloat).Values.Cast <uint>().ToArray()); } } } else { entry = notes.Find(notekey); if (split.Length == 0) { split = new int[] { 4 } } ; for (int i = 0; i < entry.Data.Length; i++) { uint[] num = new uint[split.Length]; int pos = 0; for (int k = 0; k < split.Length; k++) { byte[] data = new byte[4]; Array.Copy(entry.Data[i], pos, data, 4 - split[k], split[k]); num[k] = BigEndianConverter.ToUInt32(data); pos += split[k]; } nums.Add(num); } } return(nums.ToArray()); }
protected void AddQbKeyToUserDebugFile(QbKey qbKey) { string qbKeyText = string.Empty; if (qbKey == null) { return; } if ((qbKeyText = _qbItemBase.Root.PakFormat.AddNonDebugQbKey(qbKey, _qbItemBase.Root.Filename, _qbItemBase.Root)).Length != 0) { this.ShowError("QB Key Error", string.Format("QB Key '{0}' has the same crc as item '{1}' from the debug file.{2}{2}The QbKey text '{0}' will not be saved to the User Debug file.", qbKey.Text, qbKeyText, Environment.NewLine)); } }
private static void DecodeChartMarkers(SongData song, QbFile qbsections, QbFile qbchart, NoteChart chart) { QbItemStructArray markers = (qbchart.FindItem(QbKey.Create(song.ID + "_markers"), false) as QbItemArray).Items[0] as QbItemStructArray; if (markers != null) { foreach (QbItemStruct mark in markers.Items) { QbItemString section = qbsections.FindItem((mark.Items[1] as QbItemQbKey).Values[0], false) as QbItemString; chart.Events.Sections.Add(new Pair <NoteChart.Point, string>(new NoteChart.Point(chart.GetTicks((mark.Items[0] as QbItemInteger).Values[0])), section.Strings[0])); } } }
private void DecodeChartVocalPhrases(SongData song, QbFile qbchart, Notes notes, NoteChart chart) { uint[] values = GetChartValues(notes, qbchart, QbKey.Create(0x032292A7), QbKey.Create(song.ID + "_vocals_phrases"), 4, 1); NoteChart.Note lastvnote = null; bool altvphrase = false; int odcounter = 1; ulong lastvtime = 0; for (int k = 0; k < values.Length; k += 2) { if (lastvnote != null) { lastvnote.Duration = chart.GetTicksDuration(lastvtime, values[k] - lastvtime) - 1; } lastvtime = values[k]; lastvnote = new NoteChart.Note(chart.GetTicks(lastvtime)); odcounter++; odcounter %= 4; if (odcounter == 0) { chart.PartVocals.Overdrive.Add(lastvnote); } if (altvphrase) { chart.PartVocals.Player2.Add(lastvnote); } else { chart.PartVocals.Player1.Add(lastvnote); } altvphrase = !altvphrase; } if (lastvnote != null) { lastvnote.Duration = chart.FindLastNote() - lastvnote.Time; } uint[][] jaggedvalues = GetJaggedChartValues(notes, qbchart, QbKey.Create("vocalstarpower"), QbKey.Create("vocalstarpower"), 4, 2); if (jaggedvalues != null) { foreach (uint[] star in jaggedvalues) { chart.PartVocals.Overdrive.Add(new NoteChart.Note(chart.GetTicks(star[0]), chart.GetTicksDuration(star[0], star[1]))); } } }
private static void DecodeChartDrums(SongData song, QbFile qbchart, NoteChart chart) { QbItemArray drumsitems = qbchart.FindItem(QbKey.Create(song.ID + "_drums_notes"), false) as QbItemArray; if (drumsitems != null) { drumsitems = drumsitems.Items[0] as QbItemArray; } if (drumsitems != null) { chart.PartDrums = new NoteChart.Drums(chart); Dictionary <uint, int> drumnotes = new Dictionary <uint, int>() // Garbage: 65, 70, 48, 64 { { 60, 0 }, { 40, 1 }, { 64, 1 }, { 55, 2 }, { 67, 2 }, { 53, 2 }, { 39, 3 }, { 38, 3 }, { 63, 3 }, { 62, 3 }, { 68, 4 }, { 56, 4 }, { 66, 4 }, { 54, 4 }, { 69, 4 }, { 57, 4 }, { 37, 4 }, { 61, 4 }, }; Dictionary <uint, NoteChart.Drums.Animation> drumanimnotes = new Dictionary <uint, NoteChart.Drums.Animation>() { }; foreach (QbItemInteger drums in drumsitems.Items) { NoteChart.Note note = new NoteChart.Note(chart.GetTicks(drums.Values[0]), (ulong)chart.Division.TicksPerBeat / 8); uint notenum = drums.Values[1]; if (drumnotes.ContainsKey(notenum)) { int notevalue = drumnotes[notenum]; chart.PartDrums.Gems[NoteChart.Difficulty.Expert][notevalue].Add(note); } if (drumanimnotes.ContainsKey(notenum)) { chart.PartDrums.Animations.Add(new Pair <NoteChart.Note, NoteChart.Drums.Animation>(note, drumanimnotes[notenum])); } } } ChartFormatGH5.FillSections(chart, 1, 8, 1, chart.PartDrums.Overdrive, null); ChartFormatGH5.FillSections(chart, 1, 4, 3, chart.PartDrums.DrumFills, null); }
public string FindItem(QbKey key) { foreach (KeyValuePair <QbKey, string> k in Items) { if (key.Crc == k.Key.Crc) { string value = k.Value; if (StripPrefix) { while (value.StartsWith(@"\L") || value.StartsWith(", ")) { value = value.Substring(2); } } return(value); } } return(null); }
public static QbItemStruct GetSongItem(FormatData formatdata) { SongData song = formatdata.Song; Stream datastream = formatdata.GetStream(Instance, "neversoftdata"); if (datastream == null || datastream.Length == 0) { SaveSongItem(formatdata); datastream = formatdata.GetStream(Instance, "neversoftdata"); } QbItemBase item = new QbFile(datastream, GetSongItemType(song)).FindItem(QbKey.Create(song.Data.GetValue <uint>("NeversoftSongItemKey")), true); formatdata.CloseStream(datastream); if (item is QbItemArray) { item.Items[0].ItemQbKey = item.ItemQbKey; item = item.Items[0]; } return(item as QbItemStruct); }
public static Entry Create(EndianReader stream) { Entry entry = new Entry(); uint entries; int sizeofentry; entry.Identifier = QbKey.Create(stream.ReadUInt32()); entries = stream.ReadUInt32(); entry.Type = QbKey.Create(stream.ReadUInt32()); sizeofentry = stream.ReadInt32(); entry.Data = new byte[entries][]; for (int i = 0; i < entries; i++) { entry.Data[i] = stream.ReadBytes(sizeofentry); } return(entry); }
private void DecodeChartSections(SongData song, QbFile qbchart, StringList strings, QbFile qbsections, Notes notes, NoteChart chart) { if (notes != null) { uint[] values = GetChartValues(notes, null, QbKey.Create(0x92511D84), null, 4, 4); for (int k = 0; k < values.Length; k += 2) { uint time = values[k]; string text = strings.FindItem(QbKey.Create(values[k + 1])); chart.Events.Sections.Add(new Pair <NoteChart.Point, string>(new NoteChart.Point(chart.GetTicks(time)), text)); } } else { QbItemStructArray markers = (qbchart.FindItem(QbKey.Create(song.ID + "_guitar_markers"), false) as QbItemArray).Items[0] as QbItemStructArray; foreach (QbItemStruct mark in markers.Items) { QbItemQbKey section = qbsections.FindItem((mark.Items[1] as QbItemQbKey).Values[0], false) as QbItemQbKey; chart.Events.Sections.Add(new Pair <NoteChart.Point, string>(new NoteChart.Point(chart.GetTicks((mark.Items[0] as QbItemInteger).Values[0])), strings.FindItem(section.Values[0]))); } } }
public void ParseFromStream(StreamReader reader, bool stripprefix = true) { try { while (!reader.EndOfStream) { char[] chars = new char[8]; if (reader.Read(chars, 0, 8) != 8) { break; } QbKey key = QbKey.Create(uint.Parse(new string(chars), System.Globalization.NumberStyles.HexNumber)); char c = '\0'; while (c != '"') { c = (char)reader.Read(); } c = (char)reader.Read(); string str = string.Empty; while (c != '"') { str += c; c = (char)reader.Read(); } Items.Add(new KeyValuePair <QbKey, string>(key, str)); reader.Read(chars, 0, 2); if (chars[0] != 0x0D || chars[1] != 0x0A) { break; } } } catch { } }
private void DecodeChartNotes(SongData song, QbFile qbchart, Notes notes, NoteChart chart, NoteChart.TrackType track, NoteChart.Difficulty difficulty) { bool expertplus = song.Data.GetValue <bool>("GH5ChartExpertPlus"); uint[] values; uint[][] jaggedvalues; QbKey basetrack = null; QbKey basetrackstar = null; QbKey basetrackfaceoff1 = null; QbKey basetrackfaceoff2 = null; QbKey basetracktapping = null; NoteChart.Instrument instrument = null; switch (track) { case NoteChart.TrackType.Guitar: instrument = chart.PartGuitar; if (notes != null) { basetrack = QbKey.Create("guitar" + difficulty.DifficultyToString().ToLower() + "instrument"); basetracktapping = QbKey.Create("guitar" + difficulty.DifficultyToString().ToLower() + "tapping"); basetrackstar = QbKey.Create("guitar" + difficulty.DifficultyToString().ToLower() + "starpower"); } else { basetrack = QbKey.Create(song.ID + "_song_" + difficulty.DifficultyToString().ToLower()); basetrackstar = QbKey.Create(song.ID + "_" + difficulty.DifficultyToString().ToLower() + "_star"); basetrackfaceoff1 = QbKey.Create(song.ID + "_faceoffp1"); basetrackfaceoff2 = QbKey.Create(song.ID + "_faceoffp2"); basetracktapping = QbKey.Create(song.ID + "_" + difficulty.DifficultyToString().ToLower() + "_tapping"); } break; case NoteChart.TrackType.Bass: instrument = chart.PartBass; if (notes != null) { basetrack = QbKey.Create("bass" + difficulty.DifficultyToString().ToLower() + "instrument"); basetracktapping = QbKey.Create("bass" + difficulty.DifficultyToString().ToLower() + "tapping"); basetrackstar = QbKey.Create("bass" + difficulty.DifficultyToString().ToLower() + "starpower"); } else { basetrack = QbKey.Create(song.ID + "_song_rhythm_" + difficulty.DifficultyToString().ToLower()); basetrackstar = QbKey.Create(song.ID + "_rhythm_" + difficulty.DifficultyToString().ToLower() + "_star"); basetrackfaceoff1 = QbKey.Create(song.ID + "_rhythm_faceoffp1"); basetrackfaceoff2 = QbKey.Create(song.ID + "_rhythm_faceoffp2"); // basetracktapping = song.ID + "_rhythm_" + difficulty.DifficultyToString().ToLower() + "_tapping"; } break; case NoteChart.TrackType.Drums: instrument = chart.PartDrums; if (notes != null) { basetrack = QbKey.Create("drums" + difficulty.DifficultyToString().ToLower() + "instrument"); basetrackstar = QbKey.Create("drums" + difficulty.DifficultyToString().ToLower() + "starpower"); } else { basetrack = QbKey.Create(song.ID + "_song_drum_" + difficulty.DifficultyToString().ToLower()); basetrackstar = QbKey.Create(song.ID + "_drum_" + difficulty.DifficultyToString().ToLower() + "_star"); basetrackfaceoff1 = QbKey.Create(song.ID + "_drum_faceoffp1"); basetrackfaceoff2 = QbKey.Create(song.ID + "_drum_faceoffp2"); // basetracktapping = song.ID + "_drum_" + difficulty.DifficultyToString().ToLower() + "_tapping"; } break; } if (difficulty == NoteChart.Difficulty.Expert) // GH has SP for each difficulty; RB2 has one OD for all { jaggedvalues = GetJaggedChartValues(notes, qbchart, basetrackstar, basetrackstar, 4, 2); foreach (uint[] star in jaggedvalues) { instrument.Overdrive.Add(new NoteChart.Note(chart.GetTicks(star[0]), chart.GetTicksDuration(star[0], star[1]))); } if (notes == null) { jaggedvalues = GetJaggedChartValues(notes, qbchart, basetrackfaceoff1, basetrackfaceoff1, 1); foreach (uint[] faceoff in jaggedvalues) { instrument.Player1.Add(new NoteChart.Note(chart.GetTicks(faceoff[0]), chart.GetTicksDuration(faceoff[0], faceoff[1]))); } jaggedvalues = GetJaggedChartValues(notes, qbchart, basetrackfaceoff2, basetrackfaceoff2, 2); foreach (uint[] faceoff in jaggedvalues) { instrument.Player2.Add(new NoteChart.Note(chart.GetTicks(faceoff[0]), chart.GetTicksDuration(faceoff[0], faceoff[1]))); } } } if (basetracktapping != null) { jaggedvalues = GetJaggedChartValues(notes, qbchart, basetracktapping, basetracktapping, 4, 4); foreach (uint[] tap in jaggedvalues) { if (instrument is NoteChart.IForcedHopo) { (instrument as NoteChart.IForcedHopo).ForceHammeron[difficulty].Add(new NoteChart.Note(chart.GetTicks(tap[0]), chart.GetTicksDuration(tap[0], tap[1]))); } } } int previouschordnum = 0; int previouschord = 0; NoteChart.Note previousnote = new NoteChart.Note(uint.MaxValue); int note32 = chart.Division.TicksPerBeat / 8; int note16 = chart.Division.TicksPerBeat / 4; values = GetChartValues(notes, qbchart, basetrack, basetrack, 4, 4); for (int k = 0; k < values.Length; k += 2) { uint fret = values[k + 1]; uint length = 0; if (notes != null) { length = fret >> 16; fret = fret & 0x0000FFFF; } else { length = fret & 0x0000FFFF; fret >>= 16; } if (notes != null) { fret = ((fret & 0xFF00) >> 8) | ((fret & 0x00FF) << 8); } NoteChart.Note note = new NoteChart.Note(chart.GetTicks(values[k]), chart.GetTicksDuration(values[k], length)); int chordnum = 0; int chord = 0; // Cut off sustains to a 32nd note before the next previousnote.Duration = (ulong)Math.Max(Math.Min((long)previousnote.Duration, (long)note.Time - (long)previousnote.Time - note16), note32); uint numfrets = 5; if (track == NoteChart.TrackType.Drums) { numfrets += 2; } int[] transform; if (notes == null) { transform = new int[] { 4, 1, 2, 3, 3, 0, -1 } } ; else { //transform = new int[] { 4, 1, 2, 3, -1, 0, 4 }; // -1 -> 4? transform = new int[] { 4, 1, 2, 3, 3, 0, 4 } }; // TODO: Verify charts for (int l = 0; l < numfrets; l++) { if (((fret >> l) & 0x01) != 0) { chordnum++; chord = l; if (track == NoteChart.TrackType.Drums) { chord = transform[l]; //if ((fret & 0x2000) != 0) // continue; //if (chord == 0 && ((fret & 0x2000) == 0) && !expertplus) // TODO: Verify expert+ // continue; } if (chord >= 0) { (instrument as NoteChart.IGems).Gems[difficulty][chord].Add(note); if (instrument is NoteChart.Drums) { ExpandDrumRoll(chart, difficulty, note, chord); } } } } if (chordnum == 0) // Bass open note, actually fret bit 6 { chordnum++; if (!(instrument is NoteChart.Drums)) { (instrument as NoteChart.IGems).Gems[difficulty][0].Add(note); } if (instrument is NoteChart.IForcedHopo) { (instrument as NoteChart.IForcedHopo).ForceHammeron[difficulty].Add(note); // Bass open notes become hopos, lulz } } else if (chordnum == 1 && chord != previouschord) { if (instrument is NoteChart.IForcedHopo) { if ((fret & 0x0040) != 0) { (instrument as NoteChart.IForcedHopo).ForceHammeron[difficulty].Add(note); } else { (instrument as NoteChart.IForcedHopo).ForceStrum[difficulty].Add(note); } } } previouschord = chord; previousnote = note; previouschordnum = chordnum; } }
public static SongData GetSongData(PlatformData platformdata, QbItemStruct item, StringList strings) { if (strings == null) { strings = new StringList(); } SongData data = new SongData(platformdata); data.ID = GetSongDataString(item, QbKeysID, strings); data.Name = GetSongDataString(item, QbKeysName, strings); data.Artist = GetSongDataString(item, QbKeysArtist, strings); data.Album = GetSongDataString(item, QbKeysAlbum, strings); if (strings.FindItem(QbKey.Create(QbKeysGenres[0].Key[0])) == null) { strings.Items.AddRange(QbKeysGenres.Select(g => new KeyValuePair <QbKey, string>(QbKey.Create(g.Key[0]), g.Value))); // TODO: Expand the Key array } data.Genre = GetSongDataString(item, QbKeysGenre, strings); QbItemInteger year = GetQbItem(item, QbKeysYear) as QbItemInteger; if (year != null) { data.Year = (int)year.Values[0]; } else { int yearnum; if (int.TryParse(GetSongDataString(item, QbKeysYear, strings).TrimStart(',', ' '), out yearnum)) // ", 2009" { data.Year = yearnum; } } QbItemInteger master = GetQbItem(item, QbKeysMaster) as QbItemInteger; if (master != null) { data.Master = master.Values[0] == 1; } QbItemInteger rank = GetQbItem(item, QbKeysDifficulty[Instrument.Ambient]) as QbItemInteger; if (rank != null) { data.Difficulty[Instrument.Ambient] = (int)rank.Values[0] * 60; } rank = GetQbItem(item, QbKeysDifficulty[Instrument.Drums]) as QbItemInteger; if (rank != null) { data.Difficulty[Instrument.Drums] = (int)rank.Values[0] * 50; } rank = GetQbItem(item, QbKeysDifficulty[Instrument.Vocals]) as QbItemInteger; if (rank != null) { data.Difficulty[Instrument.Vocals] = (int)rank.Values[0] * 45; } rank = GetQbItem(item, QbKeysDifficulty[Instrument.Bass]) as QbItemInteger; if (rank != null) { data.Difficulty[Instrument.Bass] = (int)rank.Values[0] * 55; } rank = GetQbItem(item, QbKeysDifficulty[Instrument.Guitar]) as QbItemInteger; if (rank != null) { data.Difficulty[Instrument.Guitar] = (int)rank.Values[0] * 60; } QbKey vocalmale = QbKey.Create(0xAA721F56); QbKey vocalfemale = QbKey.Create("female"); if (strings.FindItem(vocalmale) == null) { strings.Items.Add(new KeyValuePair <QbKey, string>(vocalmale, "male")); } if (strings.FindItem(vocalfemale) == null) { strings.Items.Add(new KeyValuePair <QbKey, string>(vocalfemale, "female")); } data.Vocalist = GetSongDataString(item, QbKeysVocalist, strings); if (!data.Vocalist.HasValue()) { data.Vocalist = "male"; } QbItemFloat hopo = GetQbItem(item, QbKeysHopo) as QbItemFloat; if (hopo != null) { data.HopoThreshold = (int)((float)NoteChart.DefaultTicksPerBeat / hopo.Values[0]); } // TODO: Better handling of QB items; this uses up a shitload of memory MemoryStream itemstream = new MemoryStream(); item.Root.Write(itemstream); data.Data.SetValue("NeversoftSongItem", itemstream.GetBuffer()); data.Data.SetValue("NeversoftSongType", (int)item.Root.PakFormat.PakFormatType); data.Data.SetValue("NeversoftSongItemKey", item.ItemQbKey.Crc); return(data); }
private void DecodeChartFretbars(SongData song, QbFile qbchart, Notes notes, NoteChart chart) { uint[] values = GetChartValues(notes, qbchart, Notes.KeyFretbars, QbKey.Create(song.ID + "_fretbars")); ulong ticks = 0; uint previousfret = 0; uint previousMsPerBeat = 0; for (int k = 1; k < values.Length; k++) { uint fret = values[k]; uint msPerBeat = fret - previousfret; if (msPerBeat != previousMsPerBeat) { chart.BPM.Add(new Midi.TempoEvent(ticks, msPerBeat * 1000)); } previousfret = fret; previousMsPerBeat = msPerBeat; ticks += chart.Division.TicksPerBeat; } chart.Events.End = new NoteChart.Point(chart.GetTicks(values[values.Length - 1])); uint[][] jaggedvalues = GetJaggedChartValues(notes, qbchart, Notes.KeyTimesignature, QbKey.Create(song.ID + "_timesig"), 4, 1, 1); foreach (uint[] sig in jaggedvalues) { chart.Signature.Add(new Midi.TimeSignatureEvent(chart.GetTicks(sig[0]), (byte)sig[1], (byte)Math.Log(sig[2], 2), 24, 8)); } }
public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress) { string albumname = null; switch (song.ID) { case "dontholdback": albumname = "TheSleepingQuestionsAndAnswers"; break; case "minuscelsius": albumname = "BackyardBabiesStockholmSyndrome"; break; case "thrufireandflames": albumname = "DragonforceInhumanRampage"; break; case "fcpremix": albumname = "FallofTroyDoppelganger"; break; case "avalancha": albumname = "HeroesDelSilencioAvalancha"; break; case "takethislife": albumname = "InFlamesComeClarity"; break; case "ruby": albumname = "KaiserChiefsYoursTrulyAngry_Mob"; break; case "mycurse": albumname = "KillswitchEngageAsDaylightDies"; break; case "closer": albumname = "LacunaCoilKarmaCode"; break; case "metalheavylady": albumname = "LionsLions"; break; case "mauvaisgarcon": albumname = "NaastAntichambre"; break; case "generationrock": albumname = "RevolverheldRevolverheld"; break; case "prayeroftherefugee": albumname = "RiseAgainstTheSuffererAndTheWitness"; break; case "cantbesaved": albumname = "SensesFailStillSearching"; break; case "shebangsadrum": albumname = "StoneRosesStoneRoses"; break; case "radiosong": albumname = "SuperbusPopnGum"; break; case "bellyofashark": albumname = "TheGallowsOrchestraofWoles"; break; case "gothatfar": albumname = "BretMichealsBandGoThatFar"; break; case "impulse": albumname = "endlesssporadic"; break; case "thewayitends": albumname = "prototype_continuum_cover"; break; case "nothingformehere": albumname = "Dope_PosterCover_edsel"; break; case "inlove": albumname = "store_song_ScoutsStSebastian"; break; } if (albumname != null) { if (data.Session.ContainsKey("albumpak")) { Pak albumpak = data.Session["albumpak"] as Pak; Pak.Node node = albumpak.Nodes.Find(n => n.FilenamePakKey == QbKey.Create(albumname).Crc); if (node != null) { song.AlbumArt = NgcImage.Create(new EndianReader(node.Data, Endianness.BigEndian)).Bitmap; } } } DirectoryNode dir = data.Session["rootdir"] as DirectoryNode; Pak qb = data.Session["rootqb"] as Pak; FileNode chartpak = dir.Navigate("songs/" + song.ID + ".pak.ngc", false, true) as FileNode; if (chartpak == null) { return(false); } chartpak.Data.Position = 0; Pak chartqb = new Pak(new EndianReader(chartpak.Data, Endianness.BigEndian)); FileNode sectionfile = chartqb.Root.Find(song.ID + ".mid_text.qb.ngc", SearchOption.AllDirectories, true) as FileNode; if (sectionfile == null) // GHA stores it elsewhere { sectionfile = qb.Root.Find(song.ID + ".mid_text.qb.ngc", SearchOption.AllDirectories, true) as FileNode; } if (sectionfile == null) // Last resort, check for it raw on the disc partition { sectionfile = dir.Find(song.ID + ".mid_text.qb.ngc", SearchOption.AllDirectories, true) as FileNode; } for (int coop = 0; coop < 2; coop++) { if (coop == 1) { song = new SongData(song); song.ID += "_coop"; song.Name += " [coop]"; } FormatData formatdata = new TemporaryFormatData(song, data); FileNode datfile = dir.Navigate("music/" + song.ID + ".dat.ngc", false, true) as FileNode; FileNode wadfile = dir.Navigate("music/" + song.ID + ".wad.ngc", false, true) as FileNode; if (datfile == null || wadfile == null) { continue; } AudioFormatGH3WiiFSB.Instance.Create(formatdata, datfile.Data, wadfile.Data); ChartFormatGH3.Instance.Create(formatdata, chartpak.Data, sectionfile.Data, coop == 1); data.AddSong(formatdata); } chartpak.Data.Close(); return(true); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); data.Game = Platform.DetermineGame(data); try { FileNode qbpak = dir.Navigate("pak/qb.pak.ngc") as FileNode; if (qbpak == null) { throw new FormatException("Couldn't find qb.pak on Guitar Hero Wii disc."); } FileNode qspak = dir.Navigate("pak/qs.pak.ngc") as FileNode; if (qspak == null) { throw new FormatException("Couldn't find qs.pak on Guitar Hero Wii disc."); } Pak qs = new Pak(new EndianReader(qspak.Data, Endianness.BigEndian)); StringList strings = new StringList(); foreach (Pak.Node node in qs.Nodes) { strings.ParseFromStream(node.Data); } Pak qb = new Pak(new EndianReader(qbpak.Data, Endianness.BigEndian)); FileNode songlistfile = qb.FindFile(@"scripts\guitar\songlist.qb.ngc"); if (songlistfile == null) { songlistfile = qb.FindFile(@"scripts\guitar\songlist.qb"); } if (songlistfile == null) { throw new FormatException("Couldn't find the songlist on the Guitar Hero Wii disc pak."); } QbFile songlist = new QbFile(songlistfile.Data, PakFormat); data.Session["rootdir"] = dir; List <QbKey> listkeys = new List <QbKey>(); foreach (uint songlistkey in NeversoftMetadata.SonglistKeys) { QbKey key = QbKey.Create(songlistkey); QbItemStruct list = songlist.FindItem(key, true) as QbItemStruct; if (list != null && list.Items.Count > 0) { listkeys.Add(key); } } progress.NewTask(listkeys.Count); List <string> songsadded = new List <string>(); foreach (QbKey songlistkey in listkeys) { QbItemStruct list = songlist.FindItem(songlistkey, true) as QbItemStruct; progress.NewTask(list.Items.Count); foreach (QbItemArray item in list.Items.OfType <QbItemArray>()) { item.Items[0].ItemQbKey = item.ItemQbKey; SongData song = NeversoftMetadata.GetSongData(data, item.Items[0] as QbItemStruct, strings); progress.Progress(); if (songsadded.Contains(song.ID)) { continue; } try { if (AddSong(data, song, progress)) { songsadded.Add(song.ID); } } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } } progress.EndTask(); progress.Progress(); } progress.EndTask(); qbpak.Data.Close(); qspak.Data.Close(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero Wii disc."); } return(data); }
public override PlatformData Create(string path, Game game, ProgressIndicator progress) { PlatformData data = new PlatformData(this, game); DirectoryNode dir = data.GetDirectoryStructure(path); FileNode binfile = dir.Navigate("001.bin") as FileNode; if (binfile == null) { Exceptions.Error("Unable to open Guitar Hero World Tour DLC because 001.bin is missing."); } data.Session["rootdir"] = dir; try { DlcBin bin = new DlcBin(binfile.Data); U8 u8 = new U8(bin.Data); FileNode listfile = u8.Root.Navigate("DLC1.pak.ngc") as FileNode; Pak qb = new Pak(new EndianReader(listfile.Data, Endianness.BigEndian)); FileNode songlistfile = qb.Root.Find("catalog_info.qb.ngc", SearchOption.AllDirectories) as FileNode; QbFile songlist = new QbFile(songlistfile.Data, PakFormat); StringList strings = new StringList(); foreach (Pak.Node node in qb.Nodes) { if (!node.Filename.HasValue()) { strings.ParseFromStream(node.Data); } } List <QbKey> listkeys = new List <QbKey>(); foreach (uint songlistkey in NeversoftMetadata.SonglistKeys) { QbKey key = QbKey.Create(songlistkey); QbItemStruct list = songlist.FindItem(key, true) as QbItemStruct; if (list != null && list.Items.Count > 0) { listkeys.Add(key); } } Stream str = new FileStream(@"C:\ghwt.xml", FileMode.Create); StreamWriter writer = new StreamWriter(str); progress.NewTask(listkeys.Count); foreach (QbKey songlistkey in listkeys) { QbItemStruct list = songlist.FindItem(songlistkey, true) as QbItemStruct; progress.NewTask(list.Items.Count); foreach (QbItemArray item in list.Items.OfType <QbItemArray>()) { item.Items[0].ItemQbKey = item.ItemQbKey; SongData song = NeversoftMetadata.GetSongData(data, item.Items[0] as QbItemStruct, strings); writer.WriteLine("\t<song id=\"" + song.ID + "\">"); writer.WriteLine("\t\t<pack>Guitar Hero World Tour DLC</pack>"); writer.WriteLine("\t\t<nameprefix>[GHWT DLC]</nameprefix>"); writer.WriteLine("\t\t<name>" + song.Name + "</name>"); writer.WriteLine("\t\t<artist>" + song.Artist + "</artist>"); writer.WriteLine("\t\t<album>" + song.Album + "</album>"); writer.WriteLine("\t\t<genre>" + song.Genre + "</genre>"); writer.WriteLine("\t\t<track>" + song.AlbumTrack.ToString() + "</track>"); writer.WriteLine("\t\t<difficulty instrument=\"band\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"guitar\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"bass\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"drum\" rank=\"1\" />"); writer.WriteLine("\t\t<difficulty instrument=\"vocals\" rank=\"1\" />"); writer.WriteLine("\t</song>"); try { AddSong(data, song, progress); } catch (Exception exception) { Exceptions.Warning(exception, "Unable to properly parse " + song.Name); } progress.Progress(); } progress.EndTask(); progress.Progress(); } progress.EndTask(); writer.Close(); binfile.Data.Close(); } catch (Exception exception) { Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero World Tour DLC list."); } return(data); }
public void QbKeyStringTest2() { var qbKey = new QbKey("test"); Assert.AreEqual(0x278081F3, qbKey.Checksum); }
public static AudioFormat GetAudioFormat(FormatData data) { SongData song = data.Song; AudioFormat audioformat = new AudioFormat(); QbItemStruct item = GetSongItem(data); if (item == null) { return(null); } float bandvolume = 0; float guitarvolume = 0; float bassvolume = 0; float drumvolume = 0; QbItemFloat subitem = item.FindItem(QbKey.Create(0xD8F335CF), false) as QbItemFloat; // GH3: band_playback_volume if (subitem != null) { bandvolume = (subitem as QbItemFloat).Values[0]; bassvolume = bandvolume; } subitem = item.FindItem(QbKey.Create(0xA449CAD3), false) as QbItemFloat; // GH3: guitar_playback_volume if (subitem != null) { guitarvolume = (subitem as QbItemFloat).Values[0]; } subitem = item.FindItem(QbKey.Create(0x46507438), false) as QbItemFloat; // GH4: overall_song_volume if (subitem != null) { bandvolume = (subitem as QbItemFloat).Values[0]; guitarvolume = bandvolume; bassvolume = bandvolume; drumvolume = bandvolume; } // GH4 engine games that came out after GHWT use a different drum audio scheme; the GH5 engine uses the same as GHWT bool gh4v2 = NeversoftMetadata.IsGuitarHero4(song.Game) && song.Game != Game.GuitarHeroWorldTour; // GHVH is the only BIK-based GH game with stereo bass bool ghvh = song.Game == Game.GuitarHeroVanHalen; if (gh4v2) { // Kick audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, -1, Instrument.Drums)); audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 1, Instrument.Drums)); // Snare audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, -1, Instrument.Drums)); audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 1, Instrument.Drums)); } else { // Kick audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 0, Instrument.Drums)); // Snare audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 0, Instrument.Drums)); } // Overhead audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, -1, Instrument.Drums)); audioformat.Mappings.Add(new AudioFormat.Mapping(drumvolume, 1, Instrument.Drums)); // Guitar audioformat.Mappings.Add(new AudioFormat.Mapping(guitarvolume, -1, Instrument.Guitar)); audioformat.Mappings.Add(new AudioFormat.Mapping(guitarvolume, 1, Instrument.Guitar)); // Bass audioformat.Mappings.Add(new AudioFormat.Mapping(bassvolume, ghvh ? -1 : 0, Instrument.Bass)); if (ghvh) { audioformat.Mappings.Add(new AudioFormat.Mapping(bassvolume, 1, Instrument.Bass)); } // Else / Vocals audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, -1, Instrument.Ambient)); audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, 1, Instrument.Ambient)); // Preview audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, -1, Instrument.Preview)); audioformat.Mappings.Add(new AudioFormat.Mapping(bandvolume, 1, Instrument.Preview)); return(audioformat); }
private static void DecodeChartNotes(FormatData data, SongData song, QbFile qbchart, NoteChart chart, NoteChart.TrackType track, NoteChart.Difficulty difficulty, bool coop) { string basetrack = string.Empty; string basetrackstar = string.Empty; string basetrackstarbattle = string.Empty; string basetrackfaceoff = string.Empty; NoteChart.Instrument instrument = null; switch (track) { case NoteChart.TrackType.Guitar: basetrack = song.ID + (coop ? "_song_guitarcoop_" : "_song_") + difficulty.DifficultyToString(); basetrackstar = song.ID + (coop ? "_guitarcoop_" : "_") + difficulty.DifficultyToString() + "_Star"; basetrackstarbattle = song.ID + (coop ? "_guitarcoop_" : "_") + difficulty.DifficultyToString() + "_StarBattleMode"; basetrackfaceoff = song.ID + "_FaceOffp"; instrument = chart.PartGuitar; break; case NoteChart.TrackType.Bass: basetrack = song.ID + (coop ? "_song_rhythmcoop_" : "_song_rhythm_") + difficulty.DifficultyToString(); basetrackstar = song.ID + (coop ? "_rhythmcoop_" : "_rhythm_") + difficulty.DifficultyToString() + "_Star"; basetrackstarbattle = song.ID + (coop ? "_rhythmcoop_" : "_rhythm_") + difficulty.DifficultyToString() + "_StarBattleMode"; basetrackfaceoff = song.ID + "_FaceOffP"; instrument = chart.PartBass; break; } if (instrument == null) { return; } if (difficulty == NoteChart.Difficulty.Expert) // GH3 has SP for each difficulty; RB2 has one OD for all { QbItemArray faceoff1 = (qbchart.FindItem(QbKey.Create(basetrackfaceoff + "1"), false) as QbItemArray).Items[0] as QbItemArray; if (faceoff1 != null) { foreach (QbItemInteger faceoff in faceoff1.Items) { NoteChart.Note fnote = new NoteChart.Note(chart.GetTicks(faceoff.Values[0]), chart.GetTicksDuration(faceoff.Values[0], faceoff.Values[1])); instrument.Player1.Add(fnote); } } QbItemArray faceoff2 = (qbchart.FindItem(QbKey.Create(basetrackfaceoff + "2"), false) as QbItemArray).Items[0] as QbItemArray; if (faceoff2 != null) { foreach (QbItemInteger faceoff in faceoff2.Items) { NoteChart.Note fnote = new NoteChart.Note(chart.GetTicks(faceoff.Values[0]), chart.GetTicksDuration(faceoff.Values[0], faceoff.Values[1])); instrument.Player2.Add(fnote); } } QbItemArray starpower = (qbchart.FindItem(QbKey.Create(basetrackstar), false) as QbItemArray).Items[0] as QbItemArray; if (starpower != null) { foreach (QbItemInteger star in starpower.Items) { instrument.Overdrive.Add(new NoteChart.Note(chart.GetTicks(star.Values[0]), chart.GetTicksDuration(star.Values[0], star.Values[1]))); } } if (instrument.Overdrive.Count == 0) { starpower = (qbchart.FindItem(QbKey.Create(basetrackstarbattle), false) as QbItemArray).Items[0] as QbItemArray; if (starpower != null) { foreach (QbItemInteger star in starpower.Items) { instrument.Overdrive.Add(new NoteChart.Note(chart.GetTicks(star.Values[0]), chart.GetTicksDuration(star.Values[0], star.Values[1]))); } } } } int previouschordnum = 0; int previouschord = 0; NoteChart.Note previousnote = new NoteChart.Note() { Time = uint.MaxValue, Duration = 0 }; QbItemInteger notes = (qbchart.FindItem(QbKey.Create(basetrack), false) as QbItemArray).Items[0] as QbItemInteger; if (notes == null) { if (track == NoteChart.TrackType.Guitar) { chart.PartGuitar = null; } else { chart.PartBass = null; } return; } int note32 = chart.Division.TicksPerBeat / 8; int note16 = chart.Division.TicksPerBeat / 4; for (int k = 0; k < notes.Values.Length; k += 3) { NoteChart.Note note = new NoteChart.Note(chart.GetTicks(notes.Values[k]), chart.GetTicksDuration(notes.Values[k], notes.Values[k + 1])); int chordnum = 0; int chord = 0; // Cut off sustains to a 32nd note before the next previousnote.Duration = (ulong)Math.Max(Math.Min((long)previousnote.Duration, (long)note.Time - (long)previousnote.Time - note16), note32); bool hopo = note.Time - previousnote.Time <= (ulong)data.Song.HopoThreshold; bool ishopo = hopo; hopo = hopo && previouschordnum == 1; uint fret = notes.Values[k + 2]; for (int l = 0; l < 6; l++) { if ((fret & 0x01) != 0) { if (l < 5) { chord = l; chordnum++; (instrument as NoteChart.IGems).Gems[difficulty][l].Add(note); } else // l == 5; hopo toggle bit { ishopo = !ishopo; } } fret >>= 1; } if (chordnum == 0) // Old TheGHOST bug, should be a green note { chordnum = 1; chord = 0; (instrument as NoteChart.IGems).Gems[difficulty][0].Add(note); } if (chord == previouschord) { ishopo = false; } if (ishopo != hopo && chordnum == 1) { if (ishopo) { (instrument as NoteChart.IForcedHopo).ForceHammeron[difficulty].Add(note); } else { (instrument as NoteChart.IForcedHopo).ForceStrum[difficulty].Add(note); } } previouschord = chord; previousnote = note; previouschordnum = chordnum; } }