Exemple #1
0
 static void PlatformDetection_DetectDirectoryNode(string path, DirectoryNode root, List <Pair <Engine, Game> > platforms)
 {
     if ((root.Find("data", SearchOption.AllDirectories, true) != null && root.Find("chart", SearchOption.AllDirectories, true) != null) || root.Find("songdata", SearchOption.AllDirectories, true) != null)
     {
         platforms.Add(new Pair <Engine, Game>(Instance, Game.Unknown));
     }
 }
Exemple #2
0
        public void DeletePath(string path)
        {
            var root = _rootDirectoryNode.Find(path);

            if (root != null)
            {
                foreach (var itemPath in root.GetAllChildrenPaths().ToList())
                {
                    DeleteFile(itemPath);
                }
            }
        }
        public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress)
        {
            FormatData formatdata = new TemporaryFormatData(song, data);

            DirectoryNode dir = data.Session["rootdirnode"] as DirectoryNode;

            string        path     = song.Data.GetValue <string>("FolderLocation");
            DirectoryNode songdir  = dir.Navigate("Common/" + path) as DirectoryNode;
            DirectoryNode audiodir = dir.Navigate("Wii/" + path) as DirectoryNode;

            string mode       = "SinglePlayer";
            string difficulty = "Medium";

            path = mode + "/" + difficulty;

            //audiodir = audiodir.Navigate(path) as DirectoryNode;

            List <FileNode> audiofiles = new List <FileNode>();

            audiofiles.Add(audiodir.Find("AudioTrack_Main.fsb", SearchOption.AllDirectories) as FileNode);
            audiofiles.Add(audiodir.Find("AudioTrack_Main_P1.fsb", SearchOption.AllDirectories) as FileNode);
            audiofiles.Add(audiodir.Find("AudioTrack_Main_P2.fsb", SearchOption.AllDirectories) as FileNode);
            audiofiles.RemoveAll(f => f == null);

            List <FileNode> chartfiles = new List <FileNode>();

            chartfiles.Add(audiodir.Find("Markup_Main_P1_0.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.Add(audiodir.Find("Markup_Main_P1_1.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.Add(audiodir.Find("Markup_Main_P1_2.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.Add(audiodir.Find("Markup_Main_P1_3.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.Add(audiodir.Find("Markup_Main_P1_4.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.Add(audiodir.Find("Markup_Main_P2.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.Add(audiodir.Find("Markup_Main_P1.fsgmub", SearchOption.AllDirectories) as FileNode);
            chartfiles.RemoveAll(f => f == null);

            if (audiofiles.Count == 0 && chartfiles.Count == 0)
            {
                return(false);
            }

            if (audiofiles.Count > 0)
            {
                AudioFormatMp3.Instance.CreateFromFSB(formatdata, audiofiles.Select(a => a.Data).ToArray(), FreeStyleGamesMetadata.GetAudioFormat(song));
            }

            if (chartfiles.Count > 0)
            {
                ChartFormatFsgMub.Instance.Create(formatdata, chartfiles.Select(c => c.Data).ToArray());
            }

            return(true);
        }
        public void ReturnNullOnNotFoundTest()
        {
            DirectoryNode root = new DirectoryNode("");

            Assert.IsNull(root.Find("D:\\Winfred"));

            TestPath("D:\\WinFred\\Project\\james-windows", root);
            TestPath("D:\\WinFred\\Project\\james-windows\\James.sln", root);
            TestPath("D:\\WinFred\\Project\\james-test\\James.sln", root);
            TestPath("D:\\WinFred\\Project\\james-test\\James.s.ln", root);

            Assert.IsNull(root.Find("D:\\Winfred2"));
        }
        public void ComparePathTest()
        {
            DirectoryNode root = new DirectoryNode("");

            root.Insert("D:\\WinFred\\Project\\james-windows");
            Assert.IsTrue(root.Find("D:\\WinFred\\Project\\james-windows").ComparePath("D:\\WinFred\\Project\\james-windows"));
        }
 static void PlatformDetection_DetectDirectoryNode(string path, DirectoryNode root, List <Pair <Engine, Game> > platforms)
 {
     root = FindFofFolder(root);
     if (root.Find("song.ini", System.IO.SearchOption.AllDirectories, true) != null)
     {
         platforms.Add(new Pair <Engine, Game>(Instance, Game.Unknown));
     }
 }
        public void BasicInsertAndFindTest()
        {
            DirectoryNode root = new DirectoryNode("");

            TestPath("D:\\WinFred\\Project\\james-windows", root);
            TestPath("D:\\WinFred\\Project\\james-windows\\James.sln", root);
            TestPath("D:\\WinFred\\Project\\james-test\\James.sln", root);
            TestPath("D:\\WinFred\\Project\\james-test\\James.s.ln", root);
            var result = root.Find("D:\\WinFred\\Project");

            Assert.IsTrue(result.Childrens.Count == 2);
        }
Exemple #8
0
        public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress)
        {
            DirectoryNode songdir = data.Session["songdir"] as DirectoryNode;

            SongsDTA dta = HarmonixMetadata.GetSongsDTA(song);

            if (dta == null)               // GH1's <addsong />
            {
                dta            = HarmonixMetadata.GetSongData(song);
                dta.Song.Cores = new List <int>()
                {
                    -1, -1, 1, 1
                };
                dta.Song.Vols = new List <float>()
                {
                    0, 0, 0, 0
                };
                dta.Song.Pans = new List <float>()
                {
                    -1, 1, -1, 1
                };
                dta.Song.Tracks.Find(t => t.Name == "guitar").Tracks.AddRange(new int[] { 2, 3 });
                HarmonixMetadata.SetSongsDTA(song, dta.ToDTB());
            }

            dta.Bank = "sfx/tambourine_bank.milo";

            DirectoryNode songnode = songdir.Navigate(song.ID) as DirectoryNode;

            FileNode chartfile = songnode.Find(song.ID + ".mid") as FileNode;

            if (chartfile == null)
            {
                return(false);
            }

            for (int coop = 0; coop < 2; coop++)
            {
                if (coop == 1)
                {
                    song       = new SongData(song);
                    song.ID   += "_coop";
                    song.Name += " [coop]";
                    if (dta.SongCoop != null)
                    {
                        dta.Song     = dta.SongCoop;
                        dta.SongCoop = null;
                    }
                    else
                    {
                        return(false);
                    }
                }
                HarmonixMetadata.SetSongsDTA(song, dta.ToDTB());
                FormatData formatdata = new TemporaryFormatData(song, data);

                FileNode songaudiofile = songnode.Find(song.ID + ".vgs") as FileNode;
                if (songaudiofile == null)
                {
                    songaudiofile = songnode.Find(song.ID + "_sp.vgs") as FileNode;
                }
                if (songaudiofile == null)
                {
                    return(false);
                }

                if (data.Game == Game.GuitarHero1)
                {
                    ChartFormatGH1.Instance.Create(formatdata, chartfile == null ? null : chartfile.Data);
                }
                else
                {
                    ChartFormatGH2.Instance.Create(formatdata, chartfile == null ? null : chartfile.Data, coop == 1);
                }

                AudioFormatVGS.Instance.Create(formatdata, songaudiofile.Data, null);

                data.AddSong(formatdata);
            }

            return(true);
        }
Exemple #9
0
        public override PlatformData Create(string path, Game game, ProgressIndicator progress)
        {
            if (File.Exists(path))
            {
                if (String.Compare(Path.GetExtension(path), ".ark", true) == 0 || String.Compare(Path.GetExtension(path), ".hdr", true) == 0)
                {
                    path = Path.GetDirectoryName(path);
                }
            }

            PlatformData data = new PlatformData(this, game);

            data.Game = Platform.DetermineGame(data);

            Ark ark = data.GetHarmonixArk(path);

            DirectoryNode songdir = ark.Root.Find("songs", true) as DirectoryNode;

            if (songdir == null)
            {
                Exceptions.Error("This is not a Guitar Hero PS2 disc; the songs dir is missing from the ark.");
            }

            FileNode songsdtbfile = ark.Root.Navigate("config/gen/songs.dtb", false, true) as FileNode;

            if (songsdtbfile == null)
            {
                Exceptions.Error("Couldn't find songs.dtb; this is not a Guitar Hero PS2 disc.");
            }

            data.Session["songdir"] = songdir;

            try {
                List <SongsDTA> dtas      = new List <SongsDTA>();
                Stream          dtbstream = new MemoryStream((int)songsdtbfile.Size);
                CryptedDtbStream.DecryptOld(dtbstream, new EndianReader(songsdtbfile.Data, Endianness.LittleEndian), (int)songsdtbfile.Size);
                dtbstream.Position = 0;
                DTB.NodeTree dtb = DTB.Create(new EndianReader(dtbstream, Endianness.LittleEndian));
                progress.NewTask(dtb.Nodes.Count);
                foreach (DTB.Node node in dtb.Nodes)
                {
                    DTB.NodeTree tree = node as DTB.NodeTree;
                    if (tree == null || tree.Nodes[0].Type != 0x00000005 || songdir.Find((tree.Nodes[0] as DTB.NodeString).Text) == null)
                    {
                        progress.Progress();
                        continue;
                    }

                    SongsDTA dta = SongsDTA.Create(tree);
                    if (dtas.FirstOrDefault(d => d.BaseName == dta.BaseName) != null)
                    {
                        progress.Progress();
                        continue;                         // Don't import songs twice
                    }
                    dtas.Add(dta);

                    SongData song = HarmonixMetadata.GetSongData(data, tree);
                    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 PS2 disc.");
            }

            return(data);
        }
        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);
        }
Exemple #11
0
        static void Main(string[] args)
        {
            string arkpath  = args[0];
            string songname = args[1];

            FileStream arkfile = new FileStream(arkpath, FileMode.Open, FileAccess.Read);

            Ark ark = new Ark(new EndianReader(arkfile, Endianness.LittleEndian));

            DirectoryNode songdir = ark.Root.Find("songs") as DirectoryNode;

            songdir = songdir.Find(songname) as DirectoryNode;

            Midi midi = Midi.Create(Mid.Create((songdir.Find(songname + "_g.mid") as FileNode).Data));

            Dictionary <InstrumentBank, Stream> banks = new Dictionary <InstrumentBank, Stream>();

            foreach (FileNode node in songdir.Files)
            {
                if (node.Name.EndsWith(".bnk"))
                {
                    InstrumentBank bank = InstrumentBank.Create(new EndianReader(node.Data, Endianness.LittleEndian));

                    FileNode nse = songdir.Find(Path.GetFileNameWithoutExtension(node.Name) + ".nse") as FileNode;

                    banks.Add(bank, nse.Data);
                }
            }

            int        tracknum = 0;
            FileStream outfile  = new FileStream(@"Z:\" + songname + "_" + midi.Tracks.Count.ToString() + ".raw", FileMode.Create, FileAccess.ReadWrite);
            //EndianReader writer = new EndianReader(outfile, Endianness.BigEndian);
            EndianReader writer = new EndianReader(new TemporaryStream(), Endianness.BigEndian);

            foreach (Midi.Track track in midi.Tracks)
            {
                List <Midi.Event> events = new List <Midi.Event>();
                events.AddRange(track.Banks.Cast <Midi.Event>());
                events.AddRange(track.Instruments.Cast <Midi.Event>());
                events.AddRange(track.Notes.Cast <Midi.Event>());

                InstrumentBank[]            bankids       = new InstrumentBank[0x10];
                InstrumentBank.Bank[]       subbankids    = new InstrumentBank.Bank[0x10];
                InstrumentBank.Instrument[] instrumentids = new InstrumentBank.Instrument[0x10];
                InstrumentBank.Sound[][]    soundids      = new InstrumentBank.Sound[0x10][];

                events.Sort(new SpecialEventComparer());

                foreach (Midi.ChannelEvent e in events.Cast <Midi.ChannelEvent>())
                {
                    Midi.BankEvent       banke       = e as Midi.BankEvent;
                    Midi.InstrumentEvent instrumente = e as Midi.InstrumentEvent;
                    Midi.NoteEvent       notee       = e as Midi.NoteEvent;

                    if (banke != null)
                    {
                        bankids[banke.Channel]    = banks.Select(b => b.Key).SingleOrDefault(b => b.Banks.SingleOrDefault(b2 => b2.ID == banke.Bank) != null);
                        subbankids[banke.Channel] = bankids[banke.Channel].Banks.SingleOrDefault(b => b.ID == banke.Bank);
                    }
                    else if (instrumente != null)
                    {
                        instrumentids[instrumente.Channel] = bankids[instrumente.Channel].Instruments.SingleOrDefault(i => i.ID == instrumente.Instrument);
                        int soundoffset = 0;
                        foreach (var instrument in bankids[instrumente.Channel].Instruments)
                        {
                            if (instrument == instrumentids[instrumente.Channel])
                            {
                                break;
                            }

                            soundoffset += instrument.Sounds;
                        }
                        soundids[instrumente.Channel] = bankids[instrumente.Channel].Sounds.Skip(soundoffset).Take(instrumentids[instrumente.Channel].Sounds).ToArray();
                    }
                    else
                    {
                        var bank = bankids[notee.Channel];
                        if (bank == null)
                        {
                            continue;
                        }

                        var instrument = instrumentids[notee.Channel];
                        if (instrument == null)
                        {
                            continue;                                                                 // Chart note, not audio-playable
                        }
                        var sound = soundids[notee.Channel].FirstOrDefault(s => s.ID0 == notee.Note); // Should be SingleOrDefault, but some duplicates use Sound.Unknown
                        if (sound == null)
                        {
                            continue;
                        }

                        ulong notetime = midi.GetTime(notee.Time);
                        long  sample   = (long)(notetime / 1000 * (uint)bank.Samples[sound.Sample].SampleRate / 1000);
                        long  duration = (long)((midi.GetTime(notee.Time + notee.Duration) - notetime) / 1000 * (uint)bank.Samples[sound.Sample].SampleRate / 1000);

                        short[] samples = bank.Decode(banks[bank], bank.Samples[sound.Sample]);

                        int volume = sound.Volume * notee.Velocity * instrument.Volume * subbankids[notee.Channel].Volume / 0x7F / 0x7F / 0x7F;
                        //int balance = ((int)sound.Balance - 0x40) * ((int)instrument.Balance - 0x40) / 0x40;
                        int balance = (int)sound.Balance - 0x40;
                        int lvolume = balance <= 0x00 ? 0x7F : 0x7F - balance * 2;
                        int rvolume = balance >= 0x00 ? 0x7F : 0x7F + balance * 2;

                        lvolume = lvolume * volume / 0x7F;
                        rvolume = rvolume * volume / 0x7F;

                        writer.Position = (sample * 2) * midi.Tracks.Count * 2 + tracknum * 2 * 2;
                        //writer.Position = (sample * 2) * midi.Tracks.Count + tracknum * 2;
                        duration = Math.Min(duration, samples.Length);
                        for (int i = 0; i < duration; i++)
                        {
                            //writer.Write(samples[i]);

                            if (lvolume > 1)
                            {
                                writer.Write((short)((int)samples[i] * lvolume / 0x7F));
                            }
                            else
                            {
                                writer.Position += 2;
                            }
                            if (rvolume > 1)
                            {
                                writer.Write((short)((int)samples[i] * rvolume / 0x7F));
                            }
                            else
                            {
                                writer.Position += 2;
                            }

                            writer.Position += 2 * (midi.Tracks.Count - 1) * 2;

                            //writer.Position += 2 * (midi.Tracks.Count - 1);
                        }
                    }
                }

                tracknum++;
                Console.WriteLine("Track: " + tracknum.ToString());
            }

            writer.Position = 0;
            Util.StreamCopy(outfile, writer.Base);

            outfile.Close();
            writer.Base.Close();

            arkfile.Close();
        }
Exemple #12
0
        public static Game DetermineGame(DirectoryNode root)
        {
            if (root.Find("SLES_541.32") != null || root.Find("SLUS_212.24") != null)
            {
                return(Game.GuitarHero1);
            }
            else if (root.Find("SLES_544.42") != null || root.Find("SLUS_214.47") != null)
            {
                return(Game.GuitarHero2);
            }
            else if (root.Find("SLES_548.59") != null || root.Find("SLUS_215.86") != null || root.Find("SLES_548.60") != null)
            {
                return(Game.GuitarHero80s);
            }

            FileNode rawksdnode = root.Find("disc_id") as FileNode;

            if (rawksdnode != null)
            {
                StreamReader reader = new StreamReader(rawksdnode.Data);
                string       name   = reader.ReadLine().Trim('\0');
                rawksdnode.Data.Close();
                switch (name)
                {
                case "RB1":
                    return(Game.RockBand);

                case "RB_TP1":
                    return(Game.RockBandTP1);

                case "RB_TP2":
                    return(Game.RockBandTP2);

                case "RB_ACDC":
                    return(Game.RockBandACDC);

                case "RB_CLASSIC":
                    return(Game.RockBandClassicTP);

                case "RB_COUNTRY":
                    return(Game.RockBandCountryTP);

                case "RB_METAL":
                    return(Game.RockBandMetalTP);

                case "LRB":
                    return(Game.LegoRockBand);

                case "RB2":
                    return(Game.RockBand2);

                case "TBRB":
                    return(Game.RockBandBeatles);

                case "GDRB":
                    return(Game.RockBandGreenDay);

                case "RB3":
                    return(Game.RockBand3);

                case "GH":
                case "GH1":
                    return(Game.GuitarHero1);

                case "GH2":
                    return(Game.GuitarHero2);

                case "GH80s":
                    return(Game.GuitarHero80s);

                case "GH3":
                    return(Game.GuitarHero3);

                case "GHA":
                    return(Game.GuitarHeroAerosmith);

                case "GHWT":
                    return(Game.GuitarHeroWorldTour);

                case "GHM":
                    return(Game.GuitarHeroMetallica);

                case "GHSH":
                    return(Game.GuitarHeroSmashHits);

                case "GHVH":
                    return(Game.GuitarHeroVanHalen);

                case "GH5":
                    return(Game.GuitarHero5);

                case "GH6":
                case "GHWOR":
                    return(Game.GuitarHero6);

                case "BH":
                    return(Game.BandHero);
                }
            }

            return(Game.Unknown);
        }
        public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress)
        {
            FormatData formatdata = new TemporaryFormatData(song, data);

            DirectoryNode songdir = data.Session["songdir"] as DirectoryNode;

            SongsDTA dta = HarmonixMetadata.GetSongsDTA(song);

            if (dta == null)               // LRB's <addsong />
            {
                dta            = HarmonixMetadata.GetSongData(song);
                dta.Song.Cores = new List <int>()
                {
                    -1, -1, -1, -1, -1, 1, 1, -1, -1
                };
                dta.Song.Vols = new List <float>()
                {
                    0, 0, 0, 0, 0, 0, 0, 0, 0
                };
                dta.Song.Pans = new List <float>()
                {
                    0, 0, -1, 1, 0, -1, 1, 0, 0
                };
                dta.Song.Tracks.Find(t => t.Name == "drum").Tracks.AddRange(new int[] { 0, 1, 2, 3 });
                dta.Song.Tracks.Find(t => t.Name == "bass").Tracks.AddRange(new int[] { 4 });
                dta.Song.Tracks.Find(t => t.Name == "guitar").Tracks.AddRange(new int[] { 5, 6 });
                dta.Song.Tracks.Find(t => t.Name == "vocals").Tracks.AddRange(new int[] { 7 });
                dta.Song.Name = "songs/" + song.ID + "/" + song.ID;
                HarmonixMetadata.SetSongsDTA(song, dta.ToDTB());
            }

            string dtaname = dta.Song.Name;

            if (dtaname.StartsWith("dlc"))
            {
                dtaname = dtaname.Split(new char[] { '/' }, 4)[3];
            }

            int    lastslash = dtaname.LastIndexOf('/');
            string basename  = dtaname.Substring(lastslash + 1);

            dtaname = dtaname.Substring(0, lastslash);
            DirectoryNode songnode = songdir.Navigate(dtaname) as DirectoryNode;

            if (songnode == null)
            {
                return(false);
            }

            FileNode    songaudiofile = songnode.Navigate(basename + ".bik", false, true) as FileNode;
            AudioFormat audio         = null;

            if (songaudiofile == null)
            {
                songaudiofile = songnode.Navigate(basename + ".mogg", false, true) as FileNode;
                if (songaudiofile == null)
                {
                    return(false);
                }
                if (HarmonixMetadata.IsRockBand1(data.Game))
                {
                    audio = HarmonixMetadata.GetAudioFormat(song);
                    audio.InitialOffset = 3000;
                }
                AudioFormatMogg.Instance.Create(formatdata, songaudiofile.Data, audio);
            }
            else
            {
                AudioFormatRB2Bink.Instance.Create(formatdata, songaudiofile.Data, null);
            }

            // TODO:	SongInfo
            // TODO:	Preview

            FileNode chartfile   = songnode.Find(basename + ".mid") as FileNode;
            FileNode panfile     = songnode.Find(basename + ".pan") as FileNode;
            FileNode weightsfile = songnode.Navigate("gen/" + basename + "_weights.bin") as FileNode;
            FileNode milofile    = songnode.Navigate("gen/" + basename + ".milo_wii") as FileNode;
            FileNode albumfile   = songnode.Navigate("gen/" + basename + "_keep.png_wii") as FileNode;

            if (chartfile == null)
            {
                return(false);
            }

            if (albumfile == null)
            {
                albumfile = songnode.Navigate("gen/" + basename + "_nomip_keep.bmp_wii") as FileNode;
            }

            if (albumfile != null)
            {
                song.AlbumArt = WiiImage.Create(new EndianReader(albumfile.Data, Endianness.LittleEndian)).Bitmap;
                albumfile.Data.Close();
            }

            ChartFormatRB.Instance.Create(formatdata, chartfile == null ? null : chartfile.Data, panfile == null ? null : panfile.Data, weightsfile == null ? null : weightsfile.Data, milofile == null ? null : milofile.Data, false, false, data.Game);

            data.AddSong(formatdata);

            return(true);
        }
        public override PlatformData Create(string path, Game game, ProgressIndicator progress)
        {
            PlatformData data = new PlatformData(this, game);

            Ark ark = data.GetHarmonixArk(path);

            data.Game = Platform.DetermineGame(data);

            if (data.Game == Game.RockBand2 || data.Game == Game.RockBandBeatles)
            {
                Exceptions.Error("Unable to parse song list from Rock Band Wii disc.");
            }

            data.Session["songdir"] = ark.Root;

            string[] songdirs = new string[] { "songs", "songs_regional/na", "songs_regional/eu" };
            progress.NewTask(songdirs.Length);
            foreach (string songdirname in songdirs)
            {
                DirectoryNode songdir = ark.Root.Navigate(songdirname) as DirectoryNode;
                if (songdir == null)
                {
                    continue;
                }

                FileNode songsdtbfile = songdir.Navigate("gen/songs.dtb") as FileNode;
                if (songsdtbfile == null)
                {
                    continue;
                }

                try {
                    List <SongsDTA> dtas = new List <SongsDTA>();
                    DTB.NodeTree    dtb  = DTB.Create(new EndianReader(new CryptedDtbStream(new EndianReader(songsdtbfile.Data, Endianness.LittleEndian)), Endianness.LittleEndian));
                    progress.NewTask(dtb.Nodes.Count);
                    foreach (DTB.Node node in dtb.Nodes)
                    {
                        DTB.NodeTree tree = node as DTB.NodeTree;
                        if (tree == null || tree.Nodes[0].Type != 0x00000005 || songdir.Find((tree.Nodes[0] as DTB.NodeString).Text) == null)
                        {
                            progress.Progress();
                            continue;
                        }

                        SongsDTA dta = SongsDTA.Create(tree);
                        if (dtas.Find(d => d.BaseName == dta.BaseName) != null)
                        {
                            progress.Progress();
                            continue;                             // Don't import songs twice
                        }

                        dtas.Add(dta);

                        try {
                            SongData song = HarmonixMetadata.GetSongData(data, tree);

                            AddSong(data, song, progress);
                        } catch (Exception exception) {
                            Exceptions.Warning(exception, "Could not import " + dta.Name + " from the Rock Band Wii disc.");
                        }

                        progress.Progress();
                    }
                } catch (Exception exception) {
                    Exceptions.Warning(exception, "Unable to parse song list from Rock Band Wii disc: " + songdirname);
                }
                progress.EndTask();
                progress.Progress();
            }

            progress.EndTask();

            return(data);
        }
		public override PlatformData Create(string path, Game game, ProgressIndicator progress)
		{
			PlatformData data = new PlatformData(this, game);

			DirectoryNode maindir = DirectoryNode.FromPath(path, data.Cache, FileAccess.Read);

			char[] regions = new char[] { 'E', 'P' };

			DirectoryNode dir = maindir.Navigate("private/wii/data", false, true) as DirectoryNode;
			if (dir == null)
				dir = maindir;

			for (char letter = 'A'; letter <= 'Z'; letter++) {
				foreach (char region in regions) {
					DirectoryNode subdir = dir.Find("SZ" + letter + region, true) as DirectoryNode;
					if (subdir == null)
						continue;

					foreach (FileNode file in subdir.Files) {
						if (String.Compare(Path.GetExtension(file.Name), ".bin", true) != 0)
							continue;

						try {
							file.Data.Position = 0;
							DlcBin bin = new DlcBin(file.Data);
							U8 u8;
							try {
								u8 = new U8(bin.Data);
							} catch (FormatException) {
								file.Data.Close();
								continue;
							}
							FileNode songsdta = u8.Root.Find("songs.dta", SearchOption.AllDirectories) as FileNode;
							if (songsdta == null) {
								file.Data.Close();
								continue;
							}

							DTB.NodeTree dtb = DTA.Create(songsdta.Data);
							SongsDTA dta = SongsDTA.Create(dtb);
							file.Data.Close();
							
							SongData song = HarmonixMetadata.GetSongData(data, dtb);

							string contentbin = dta.Song.Name.Substring(9, 3); // Example, "dlc/sZAE/023/content/songs/simpleman/simpleman"

							FileNode contentfile = subdir.Find(contentbin + ".bin", true) as FileNode;
							if (contentfile == null)
								continue;

							FormatData formatdata = new TemporaryFormatData(song, data);

							Create(formatdata, file.Data, contentfile.Data);
							
							data.AddSong(formatdata);

							contentfile.Data.Close();
						} catch (FormatException) { } // Not a DLC bin we care about
					}
				}
			}

			return data;
		}