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); }
public static string GetSongDataString(QbItemStruct item, uint[] keys, StringList strings) { QbItemBase data = GetQbItem(item, keys); if (data is QbItemString) { return((data as QbItemString).Strings[0]); } if (data is QbItemQbKey) { return(strings.FindItem((data as QbItemQbKey).Values[0]) ?? string.Empty); } return(string.Empty); }
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 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); }
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); }
public static SongData GetSongData(PlatformData platformdata, QbItemStruct item) { return(GetSongData(platformdata, item, new StringList())); }