예제 #1
0
        private void mnuInsertItem_Click(object sender, EventArgs e)
        {
            int idx = lstItems.SelectedIndex;

            try
            {
                if (idx >= 0 && idx < lstItems.Items.Count)
                {
                    GenericQbItem qbi = QbFile.CreateGenericArrayItem(base.QbItem);
                    qbi.ConvertTo(_currentEditType);
                    _gItems.Insert(idx, qbi);

                    lstItems.Items.Insert(idx, qbi.Value);

                    enableItems();
                    lstItems.SelectedIndex = idx;
                    txtItem.SelectAll();
                    txtItem.Focus();
                }
            }
            catch (Exception ex)
            {
                base.ShowException("Simple Array Insert Item Error", ex);
            }
        }
예제 #2
0
        private static VoxelObject ChangeColor(string file, Dictionary <Color, Color> replaceColorsWith)
        {
            var voxelStream = GameContext.ContentLoader.ReadStream(file);

            voxelStream.Seek(0L, SeekOrigin.Begin);

            var voxels = QbFile.Read(voxelStream);

            voxelStream.Seek(0L, SeekOrigin.Begin);

            var sVoxels = VoxelLoader.LoadQb(voxelStream, file, Vector3I.Zero,
                                             new Vector3I(voxels.size.X, voxels.size.Y, voxels.size.Z));

            var colors = new List <Color>();

            Helpers.VectorLoop(Vector3I.Zero, sVoxels.Size, (x, y, z) => {
                try {
                    var color = sVoxels.Read(x, y, z);

                    foreach (var check in replaceColorsWith)
                    {
                        if (color == check.Key)
                        {
                            color = check.Value;

                            sVoxels.Write(x, y, z, check.Value);
                        }
                    }

                    colors.Add(color);
                } catch { }
            });

            return(sVoxels);
        }
예제 #3
0
        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));
            }
        }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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));
                }
            }
        }
예제 #6
0
        private void btnImport_Click(object sender, EventArgs e)
        {
            try
            {
                string fname = string.Empty; // string.Format("{0}_{1}.array.txt", base.QbItem.Root.Filename.Replace('\\', '#').Replace('/', '#').Replace('.', '#'), base.QbItem.ItemQbKey.Crc.ToString("X").PadLeft(8, '0'));

                if (AppState.LastArrayPath.Length == 0)
                {
                    fname = Path.Combine(AppState.LastArrayPath, fname);
                }

                fname = getBestFullFilename(fname);


                import.Filter          = string.Format("{0} (*.{0})|*.{0}|All files (*.*)|*.*", _fileExt);
                import.Title           = string.Format("Import {0} file", _fileExt);
                import.CheckFileExists = true;
                import.CheckPathExists = true;
                import.FileName        = fname;

                if (import.ShowDialog(this) != DialogResult.Cancel)
                {
                    fname = import.FileName;

                    using (FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read))
                    {
                        using (TextReader tr = new StreamReader(fs))
                        {
                            lstItems.Items.Clear();
                            _gItems.Clear();

                            string s;
                            while ((s = tr.ReadLine()) != null)
                            {
                                GenericQbItem qbi = QbFile.CreateGenericArrayItem(base.QbItem);
                                qbi.ConvertTo(_currentEditType);
                                _gItems.Add(qbi);
                                qbi.Value = s;

                                lstItems.Items.Add(qbi.Value);
                            }
                        }
                    }

                    if (lstItems.Items.Count > 1)
                    {
                        lstItems.SelectedIndex = 0;
                    }

                    btnUpdate_Click(this, e);
                }
            }
            catch (Exception ex)
            {
                base.ShowException("Script Import Error", ex);
            }
        }
예제 #7
0
        private void SimpleArrayEditor_Load(object sender, EventArgs e)
        {
            if (this.DesignMode)
            {
                return;
            }

            try
            {
                GenericQbItem gi;

                _gItems = QbFile.GetGenericItems(base.QbItem);

                if (_gItems.Count != 0)
                {
                    gi = _gItems[0];

                    try
                    {
                        lstItems.BeginUpdate();
                        foreach (GenericQbItem gqi in _gItems)
                        {
                            lstItems.Items.Add(gqi.Value);
                        }

                        lstItems.SelectedIndex = 0;
                    }
                    finally
                    {
                        lstItems.EndUpdate();
                    }
                }
                else
                {
                    gi = QbFile.CreateGenericArrayItem(base.QbItem);
                }

                _currentEditType = gi.CurrentEditType;
                btnConvert.Text  = GenericQbItem.GetTypeName(_currentEditType);

                lblItems.Text = gi.Name;

                mnuFloat.Click  += new EventHandler(mnu_Click);
                mnuInt.Click    += new EventHandler(mnu_Click);
                mnuUint.Click   += new EventHandler(mnu_Click);
                mnuHex.Click    += new EventHandler(mnu_Click);
                mnuString.Click += new EventHandler(mnu_Click);

                enableItems();
            }
            catch (Exception ex)
            {
                base.ShowException("Simple Array Load Item Error", ex);
            }
        }
예제 #8
0
        private void btnUpdateItems_Click(object sender, EventArgs e)
        {
            List <GenericQbItem> gis = new List <GenericQbItem>();
            GenericQbEditItem    ei;
            GenericQbItem        gi;

            //check that all the items are valid before saving

            try
            {
                //Check if QbKey is in the debug file, if not then add it to the user defined list
                base.AddQbKeyToUserDebugFile(base.QbItem.ItemQbKey);

                foreach (Control un in this.Controls)
                {
                    if ((ei = (un as GenericQbEditItem)) != null)
                    {
                        if (!ei.IsValid)
                        {
                            base.ShowError("Error", "QB cannot be updated while data is invalid.");
                            return;
                        }
                        gi = ei.GenericQbItem;

                        //if QbKey, check to see if it's in the debug file, if not then add it to the user defined list
                        if (gi.Type == typeof(QbKey))
                        {
                            AddQbKeyToUserDebugFile(gi.ToQbKey());
                        }

                        gis.Add(gi);
                    }
                }
            }
            catch (Exception ex)
            {
                base.ShowException("Failed to Get Item Values", ex);
                return;
            }

            try
            {
                QbFile.SetGenericItems(base.QbItem, gis);
            }
            catch (Exception ex)
            {
                base.ShowException("Edit Values Update Error", ex);
                return;
            }

            base.UpdateQbItem();
        }
예제 #9
0
        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());
        }
예제 #10
0
        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);
        }
예제 #11
0
        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]));
                }
            }
        }
예제 #12
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])));
                }
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        protected override Bitmap GetThumbnailImage(uint width)
        {
            var size      = (int)width;
            var voxelData = QbFile.Read(SelectedItemStream);

            if (voxelData == null)
            {
                return(null);
            }
            var bitmapBytes = Renderer.RenderBitmap((int)size, voxelData);

            // Convert Skia bytes to GDI Bitmap
            var format     = PixelFormat.Format32bppArgb;
            var bitmap     = new Bitmap(size, size, format);
            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, size, size), ImageLockMode.WriteOnly, format);

            Marshal.Copy(bitmapBytes, 0, bitmapData.Scan0, bitmapBytes.Length);
            bitmap.UnlockBits(bitmapData);
            return(bitmap);
        }
예제 #16
0
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                string qbKeyText;

                try
                {
                    QbFile.SetGenericItems(base.QbItem, _gItems);
                }
                catch (Exception ex)
                {
                    throw new ApplicationException(string.Format("Item conversion error: {0}", ex.Message));
                }
                base.UpdateQbItem();

                //Check if QbKey is in the debug file, if not then add it to the user defined list
                base.AddQbKeyToUserDebugFile(base.QbItem.ItemQbKey);

                if (base.QbItem.ItemQbKey != null)
                {
                    if ((qbKeyText = base.QbItem.Root.PakFormat.AddNonDebugQbKey(base.QbItem.ItemQbKey, base.QbItem.Root.Filename, base.QbItem.Root)).Length != 0)
                    {
                        base.ShowError("QB Key Error", string.Format("QB Key {0} as the same crc as item {1} from the debug file.", base.QbItem.ItemQbKey.Text, qbKeyText));
                    }
                }

                foreach (GenericQbItem gi in _gItems)
                {
                    //if QbKey, check to see if it's in the debug file, if not then add it to the user defined list
                    if (gi.Type == typeof(QbKey))
                    {
                        base.AddQbKeyToUserDebugFile(gi.ToQbKey());
                    }
                }
            }
            catch (Exception ex)
            {
                base.ShowException("Simple Array Update Error", ex);
            }
        }
예제 #17
0
        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])));
                }
            }
        }
예제 #18
0
        private void GenericQbItemEditor_Load(object sender, EventArgs e)
        {
            bool tooManyItems = false;
            int  spacing      = 22;
            int  top          = 20;
            int  tabIndex     = this.TabIndex;
            int  lblWidth     = 0;

            List <GenericQbItem> gis = QbFile.GetGenericItems(base.QbItem);

            if (gis.Count > 500)
            {
                tooManyItems           = true;
                this.AutoScrollMinSize = new Size(0, (top * 2) + (spacing * (1 + 1) + 10)); //+ 1 for button
            }
            else
            {
                this.AutoScrollMinSize = new Size(0, (top * 2) + (spacing * (gis.Count + 1) + 10)); //+ 1 for button
            }
            this.Tag = base.QbItem;                                                                 //store item for update

            bool hasEditable = false;

            try
            {
                int qbItemFound = 0;
                if (gis.Count > 0 && gis[gis.Count - 1].SourceProperty == "ItemQbKey") //nasty hack
                {
                    addEditItem(spacing, ref top, ref lblWidth, ref hasEditable, gis[gis.Count - 1]);
                    qbItemFound = 1;
                }

                if (!tooManyItems)
                {
                    for (int i = 0; i < gis.Count - qbItemFound; i++)
                    {
                        addEditItem(spacing, ref top, ref lblWidth, ref hasEditable, gis[i]);
                    }
                }
            }
            catch (Exception ex)
            {
                base.ShowException("Edit Item List Error", ex);
            }

            foreach (GenericQbEditItem et in this.Controls)
            {
                et.TextBoxLeft = lblWidth + 6;
            }

            try
            {
                if (this.Controls.Count != 0)
                {
                    Button btnUpdateItems = new Button();
                    btnUpdateItems.Text    = "&Update";
                    btnUpdateItems.Anchor  = AnchorStyles.Top | AnchorStyles.Right;
                    btnUpdateItems.Left    = (this.ClientSize.Width - btnUpdateItems.Width - 15);
                    btnUpdateItems.Top     = top + 10;
                    btnUpdateItems.Height  = 22;
                    btnUpdateItems.Enabled = hasEditable;
                    btnUpdateItems.Click  += new EventHandler(btnUpdateItems_Click);
                    this.Controls.Add(btnUpdateItems);
                }

                if (tooManyItems)
                {
                    base.ShowError("Too Many Items", string.Format("This item contains {0} items. It is likely that it should be edited by a dedicated application.", gis.Count.ToString()));
                }
            }
            catch (Exception ex)
            {
                base.ShowException("Update Button Error", ex);
            }
        }
예제 #19
0
        private bool DecodeChartVocals(SongData song, QbFile qbchart, StringList strings, Notes notes, NoteChart chart)
        {
            uint[] values = GetChartValues(notes, qbchart, QbKey.Create(0xE8E6ADCB), QbKey.Create(song.ID + "_song_vocals"), 4, 2, 1);
            for (int k = 0; k < values.Length; k += 3)
            {
                byte note = (byte)values[k + 2];
                if (note != 2)
                {
                    if (note > 84)
                    {
                        note -= 12;
                    }
                    chart.PartVocals.Gems.Add(new Midi.NoteEvent(chart.GetTicks(values[k]), 0, note, 100, chart.GetTicksDuration(values[k], values[k + 1])));
                }
            }

            List <Pair <NoteChart.Point, string> > vlyrics = new List <Pair <NoteChart.Point, string> >();

            if (notes != null)
            {
                byte[][] vdata = notes.Find(QbKey.Create(0x1DA27F4E)).Data;
                foreach (byte[] d in vdata)
                {
                    EndianReader reader = new EndianReader(new MemoryStream(d), Endianness.BigEndian);
                    uint         time   = reader.ReadUInt32();
                    string       lyric  = reader.ReadString();
                    vlyrics.Add(new Pair <NoteChart.Point, string>(
                                    new NoteChart.Point(chart.GetTicks(time)),
                                    lyric
                                    ));
                }
            }
            else
            {
                QbItemStructArray lyrics = (qbchart.FindItem(QbKey.Create(song.ID + "_lyrics"), false) as QbItemArray).Items[0] as QbItemStructArray;
                if (lyrics != null)
                {
                    foreach (QbItemBase item in lyrics.Items)
                    {
                        string lyric = strings.FindItem((item.Items[1] as QbItemQbKey).Values[0]);
                        vlyrics.Add(new Pair <NoteChart.Point, string>(
                                        new NoteChart.Point(chart.GetTicks((item.Items[0] as QbItemInteger).Values[0])),
                                        lyric
                                        ));
                    }
                }
            }

            Pair <NoteChart.Point, string> lastlyric = null;

            foreach (var item in vlyrics)
            {
                string lyric = item.Value;
                if (lyric.StartsWith("=") && lastlyric != null)
                {
                    if (lastlyric.Value.EndsWith("-"))
                    {
                        lastlyric.Value = lastlyric.Value.Substring(0, lastlyric.Value.Length - 1) + '=';
                    }
                    else
                    {
                        lastlyric.Value += "-";
                    }
                    lyric = lyric.Substring(1);
                }

                lastlyric = new Pair <NoteChart.Point, string>(
                    item.Key,
                    lyric
                    );
                chart.PartVocals.Lyrics.Add(lastlyric);
            }

            foreach (Midi.NoteEvent item in chart.PartVocals.Gems)
            {
                bool found = false;
                foreach (Pair <NoteChart.Point, string> lyric in chart.PartVocals.Lyrics)
                {
                    if (lyric.Key.Time == item.Time)
                    {
                        if (item.Note == 26)
                        {
                            lyric.Value += "#";
                            item.Note    = 36;
                        }
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    chart.PartVocals.Lyrics.Add(new Pair <NoteChart.Point, string>(new NoteChart.Point(item.Time), "+"));
                }
            }
__goddamnremovals:
            //Midi.NoteEvent lastnote = null;
            foreach (Pair <NoteChart.Point, string> lyric in chart.PartVocals.Lyrics)
            {
                bool found = false;
                foreach (Midi.NoteEvent item in chart.PartVocals.Gems)
                {
                    if (lyric.Key.Time == item.Time)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    /*
                     * ulong duration = chart.GetTicksDuration(chart.GetTime(lyric.Key.Time) / 1000, 30);
                     * if (lastnote != null && lastnote.Time + lastnote.Duration > lyric.Key.Time)
                     *      lastnote.Duration = lyric.Key.Time - lastnote.Time - 20;
                     * lastnote = new Midi.NoteEvent(lyric.Key.Time, 0, 36, 100, duration);
                     * chart.PartVocals.Gems.Add(lastnote);
                     * lyric.Value += "^";
                     */
                    chart.PartVocals.Lyrics.Remove(lyric);
                    goto __goddamnremovals;
                }
            }

            if (chart.PartVocals.Gems.Count == 0)
            {
                chart.PartVocals = null;
                return(false);
            }

            return(true);
        }
예제 #20
0
        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;
            }
        }
예제 #21
0
        public ChartFormat DecodeChart(FormatData data, ProgressIndicator progress, params Stream[] chartstreams)
        {
            progress.NewTask(5 + 12);

            PakFormat format = NeversoftMetadata.GetSongItemType(data.Song);
            SongData  song   = NeversoftMetadata.GetSongData(data.PlatformData, NeversoftMetadata.GetSongItem(data));

            List <Pak> chartpaks = new List <Pak>();

            foreach (Stream stream in chartstreams)
            {
                chartpaks.Add(new Pak(new EndianReader(stream, Endianness.BigEndian)));                 // TODO: Endianness based on format?
            }

            FileNode chartfile = null;

            foreach (Pak pak in chartpaks)
            {
                chartfile = pak.FindFile(song.ID + ".mid.qb.ngc") ?? chartfile;
                chartfile = pak.FindFile(song.ID + ".mid.qb") ?? chartfile;
            }
            if (chartfile == null)
            {
                foreach (Pak pak in chartpaks)
                {
                    chartfile = chartfile ?? pak.FindFileType(0xa7f505c4);
                }
            }
            QbFile qbchart = null;

            if (chartfile != null)
            {
                qbchart = new QbFile(chartfile.Data, format);
            }

            StringList strings = new StringList();

            foreach (Pak pak in chartpaks)
            {
                foreach (Pak.Node n in pak.Nodes)
                {
                    if (!n.Filename.HasValue())
                    {
                        strings.ParseFromStream(n.Data);
                    }
                }
            }

            QbFile   qbsections    = null;
            FileNode qbsectionfile = null;

            foreach (Pak pak in chartpaks)
            {
                qbsectionfile = pak.FindFile(song.ID + ".mid_text.qb.ngc") as FileNode ?? qbsectionfile;
                qbsectionfile = pak.FindFile(song.ID + ".mid_text.qb") as FileNode ?? qbsectionfile;
            }
            if (qbsectionfile != null)
            {
                qbsections = new QbFile(qbsectionfile.Data, format);
            }

            Notes    notes     = null;
            FileNode notesfile = null;

            foreach (Pak pak in chartpaks)
            {
                notesfile = notesfile ?? pak.FindFileType(0xa9d5bc8f);
                notesfile = pak.FindFile(song.ID + ".note.ngc") as FileNode ?? notesfile;
                notesfile = pak.FindFile(song.ID + ".note") as FileNode ?? notesfile;
            }
            if (notesfile == null)
            {
                foreach (Pak pak in chartpaks)
                {
                    notesfile = pak.FindFileType(0xa9d5bc8f) ?? notesfile;
                }
            }
            if (notesfile != null)
            {
                notesfile.Data.Position = 0;
                notes = Notes.Create(new EndianReader(notesfile.Data, Endianness.BigEndian));
            }

            NoteChart chart = new NoteChart();

            chart.PartGuitar = new NoteChart.Guitar(chart);
            chart.PartBass   = new NoteChart.Bass(chart);
            chart.PartDrums  = new NoteChart.Drums(chart);
            chart.PartVocals = new NoteChart.Vocals(chart);
            chart.Events     = new NoteChart.EventsTrack(chart);
            chart.Venue      = new NoteChart.VenueTrack(chart);
            chart.Beat       = new NoteChart.BeatTrack(chart);

            bool   gh4v2      = NeversoftMetadata.IsGuitarHero4(data.PlatformData.Game) && data.PlatformData.Game != Game.GuitarHeroWorldTour;
            string drumconfig = gh4v2 ? "drums3" : "drums2";

            chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Easy, drumconfig + "easy")));
            chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Medium, drumconfig)));
            chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Hard, drumconfig)));
            chart.PartDrums.Mixing.Add(new Pair <NoteChart.Point, Pair <NoteChart.Difficulty, string> >(new NoteChart.Point(0), new Pair <NoteChart.Difficulty, string>(NoteChart.Difficulty.Expert, drumconfig)));

            progress.Progress();

            DecodeChartFretbars(song, qbchart, notes, chart);

            progress.Progress();

            DecodeChartSections(song, qbchart, strings, qbsections, notes, chart);

            progress.Progress();

            for (NoteChart.TrackType track = NoteChart.TrackType.Guitar; track <= NoteChart.TrackType.Drums;)
            {
                for (NoteChart.Difficulty difficulty = NoteChart.Difficulty.Easy; difficulty <= NoteChart.Difficulty.Expert; difficulty++)
                {
                    DecodeChartNotes(song, qbchart, notes, chart, track, difficulty);
                    progress.Progress();
                }
                switch (track)
                {
                case NoteChart.TrackType.Guitar: track = NoteChart.TrackType.Bass; break;

                case NoteChart.TrackType.Bass: track = NoteChart.TrackType.Drums; break;

                case NoteChart.TrackType.Drums: track = NoteChart.TrackType.Events; break;
                }
            }

            // Automatic Drum Fills - 1-measure fills every 4 measures, if there's no overdrive overlap
            FillSections(chart, 1, 4, 3, chart.PartDrums.DrumFills, chart.PartDrums.Overdrive);

            progress.Progress();

            if (DecodeChartVocals(song, qbchart, strings, notes, chart))
            {
                DecodeChartVocalPhrases(song, qbchart, notes, chart);
            }

            ImportMap.ImportChart(data.Song, chart);

            progress.Progress();

            progress.EndTask();

            return(new ChartFormat(chart));
        }
예제 #22
0
        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);
        }
예제 #23
0
        static void Main(string[] args)
        {
            Console.Title         = "FastGH3";
            Console.CursorVisible = false;
            Console.WindowWidth   = 41;
            Console.WindowHeight  = 19;
            Console.BufferWidth   = 41;
            Console.BufferHeight  = 19;
            parameters            = Environment.GetCommandLineArgs();
            if (args.Length == 0)
            {
                if (File.Exists(@"C:\Windows\fastgh3\CONFIGS\startupmsg"))
                {
                    if (File.ReadAllText(@"C:\Windows\fastgh3\CONFIGS\startupmsg").ToString() == "on")
                    {
                        Console.CursorVisible = false;
                        Console.WriteLine(@" 
 FastGH3 is an advanced mod of
 Guitar Hero 3 designed to be played
 as fast as possible. With this mod, you
 can play customs without any technical
 setup and even associate chart or mid
 files with the game so you can access
 your charts quickly.

 To access settings,
 use -settings in parameters.

 If you want to disable this welcome
 message, you can do so by using
 these parameters:
 -startupmsg off

 Press any key to load a chart.");
                        Console.ReadKey();
                    }
                }
                else
                {
                    Directory.CreateDirectory(@"C:\Windows\fastgh3\CONFIGS\");
                    File.WriteAllText(@"C:\Windows\fastgh3\CONFIGS\startupmsg", "on");
                }
                if (openchart.ShowDialog() == DialogResult.OK && args.Length == 0)
                {
                    Console.WriteLine("FASTGH3 by donnaken15");
                    Console.WriteLine("Checking file extension...");

                    if (!openchart.SafeFileName.Contains(".fsp") || !openchart.SafeFileName.Contains(".zip"))
                    {
                        if (openchart.SafeFileName.Contains(".chart") && !openchart.SafeFileName.Contains(".mid"))
                        {
                            Console.WriteLine("Detected chart file.");
                            currentchart = openchart.FileName;
                        }
                        else
                        {
                            Console.WriteLine("Detected midi file.");
                            Process.Start("mid2chart.exe", "-e " + openchart.FileName);
                            currentchart = openchart.FileName.Replace(openchart.SafeFileName, "") + openchart.SafeFileName.Replace(".chart", " (editable) .chart");
                        }
                        chart = File.ReadAllText(currentchart).Replace("}", "").Replace("{", "");
                        File.WriteAllText("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.chart", chart);
                        IniFile chartini = new IniFile();
                        chartini.Load("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.chart");
                        Console.WriteLine("Generating QB template.");
                        File.Delete("C:\\Windows\\fastgh3\\DATA\\SONGS\\song.qb");
                        File.Copy("C:\\Windows\\fastgh3\\DATA\\SONGS\\.qb", "C:\\Windows\\fastgh3\\DATA\\SONGS\\song.qb", true);
                        File.SetAttributes("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb", FileAttributes.Normal);
                        Console.WriteLine("Opening song pak.");
                        disallowGameStartup();
                        PakFormat pakformat = new PakFormat("C:\\Windows\\FastGH3\\DATA\\SONGS\\test_song.pak.xen", "", "", PakFormatType.PC);
                        PakEditor buildsong = new PakEditor(pakformat);
                        Console.WriteLine("Compiling chart.");
                        QbFile     songdata   = new QbFile("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb", pakformat);
                        QbItemBase array_easy = new QbItemArray(songdata);
                        array_easy.Create(QbItemType.SectionArray);
                        array_easy.ItemQbKey.Crc.Equals("BDA2A669");
                        QbItemInteger notes_easy = new QbItemInteger(songdata);
                        maxnotes = chartini.GetSection("EasySingle").Keys.Count;
                        File.WriteAllText("C:\\Windows\\FastGH3\\DATA\\SONGS\\maxarraysize", maxnotes.ToString());
                        notes_easy.Create(QbItemType.ArrayInteger);
                        notes_easy.Values[0] = 1;
                        foreach (IniSection.IniKey k in chartini.GetSection("EasySingle").Keys)
                        {
                            Console.WriteLine(k.GetValue().Replace("N ", "").EndsWith(" ") + " note @ " + k.GetName() + "");
                        }
                        Console.ReadKey();
                        songdata.AddItem(array_easy);
                        array_easy.AddItem(notes_easy);
                        songdata.AlignPointers();
                        songdata.Write("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb");
                        Console.WriteLine("Compiling pak.");
                        buildsong.ReplaceFile("6BE19E2F", "C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb");
                        Console.WriteLine("Encoding song.");
                        disallowGameStartup();
                        Console.WriteLine("Speeding up.");
                        Console.ReadKey();
                        Process gh3 = new Process();
                        gh3.StartInfo.FileName         = "C:\\Windows\\FastGH3\\gh3.exe";
                        gh3.StartInfo.WorkingDirectory = "C:\\Windows\\FastGH3\\";

                        /*gh3.Start();
                         * //*/
                    }
                    else
                    {
                        MessageBox.Show("TEST");
                    }
                }
            }
            //try
            //{
            if (parameters.Length >= 0)
            {
                if (parameters[1] == "-startupmsg" && args[2] == "off")
                {
                    File.WriteAllText(@"C:\Windows\fastgh3\CONFIGS\startupmsg", "off");
                }
                if (parameters[1] == "-startupmsg" && args[2] == "on")
                {
                    File.WriteAllText(@"C:\Windows\fastgh3\CONFIGS\startupmsg", "on");
                }
                if (parameters[1] == "-settings")
                {
                    Application.VisualStyleState = System.Windows.Forms.VisualStyles.VisualStyleState.NoneEnabled;
                    //Application.Run(new settings());
                    settings options = new settings();
                    options.ShowDialog();
                }
                if (File.Exists(parameters[1]))
                {
                    Console.WriteLine("FASTGH3 by donnaken15");
                    Console.WriteLine("Checking file extension...");
                    if (Path.GetFileName(parameters[1]).Contains(".chart") && !Path.GetFileName(parameters[1]).Contains(".mid"))
                    {
                        Console.WriteLine("Detected chart file.");
                        currentchart = parameters[1];
                    }
                    else
                    {
                        Console.WriteLine("Detected midi file.");
                        Process.Start("mid2chart.exe", "-e " + parameters[1]);
                        currentchart = parameters[1].Replace(Path.GetFileName(parameters[1]), "") + Path.GetFileName(parameters[1]).Replace(".chart", " (editable) .chart");
                    }
                    Console.WriteLine("Reading chart file.");
                    chart = File.ReadAllText(currentchart).Replace("}", "").Replace("{", "");
                    File.WriteAllText("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.chart", chart);
                    if (chart.Contains("= S "))
                    {
                        Process.Start("C:\\Windows\\FastGH3\\sed.exe", "sed - i '/ = S /d' C:\\Windows\\fastgh3\\DATA\\SONGS\\song.chart");
                        Process.Start("C:\\Windows\\FastGH3\\sed.exe", "sed - i '/ = TS /d' C:\\Windows\\fastgh3\\DATA\\SONGS\\song.chart");
                    }
                    IniFile chartini = new IniFile();
                    chartini.Load("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.chart");
                    chartiniexpert = chart.After("[ExpertSingle]").Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    File.WriteAllText("C:\\Windows\\FastGH3\\PLUGINS\\CODE\\notelimit\\notelimitfix.cpp", "#include \"noteLimitFix.h\"\n#include \"core\\Patcher.h\"\n#include <stdint.h>\n\nconst uint32_t MAX_NOTES " + chartini.GetSection("ExpertSingle").Keys.Count + ";//5DA666\nconst uint32_t GH3_MAX_PLAYERS = 2;\nvoid* const SIZEOP_NOTE_ALLOCATION = (void*)0x0041AA78;\nvoid* const ADDROP_SUSTAINARRAY_1 = (void*)0x0041EE33;\nvoid * const ADDROP_SUSTAINARRAY_2 = (void*)0x00423CD4;\nvoid * const ADDROP_SUSTAINARRAY_3 = (void*)0x00423D02;\nvoid * const ADDROP_FCARRAY = (void*)0x00423D14;\nvoid * const ADDROP_NOTEOFFSETARRAY = (void*)0x00423D22;\n\n\nstatic float* fixedSustainArray = nullptr;\nstatic float* fixedFcArray = nullptr;\nstatic uint32_t* fixedOffsetArray = nullptr;\n\n\nstatic GH3P::Patcher g_patcher = GH3P::Patcher(__FILE__);\n\n\nvoid FixNoteLimit()\n{\nif(fixedSustainArray == nullptr)\nfixedSustainArray = new float[MAX_NOTES * GH3_MAX_PLAYERS];\n\n\nif(fixedFcArray == nullptr)\nfixedFcArray = new float[MAX_NOTES * GH3_MAX_PLAYERS];\n\nif(fixedOffsetArray == nullptr)\nfixedOffsetArray = new uint32_t[MAX_NOTES * GH3_MAX_PLAYERS];\n\n\ng_patcher.WriteInt32(SIZEOP_NOTE_ALLOCATION, MAX_NOTES);\n\ng_patcher.WriteInt32(ADDROP_SUSTAINARRAY_1, reinterpret_cast<uint32_t>(fixedSustainArray));\ng_patcher.WriteInt32(ADDROP_SUSTAINARRAY_2, reinterpret_cast<uint32_t>(fixedSustainArray));\ng_patcher.WriteInt32(ADDROP_SUSTAINARRAY_3, reinterpret_cast<uint32_t>(fixedSustainArray));\ng_patcher.WriteInt32(ADDROP_FCARRAY, reinterpret_cast<uint32_t>(fixedFcArray));\ng_patcher.WriteInt32(ADDROP_NOTEOFFSETARRAY, reinterpret_cast<uint32_t>(fixedOffsetArray));\n}\n\n");
                    disallowGameStartup();
                    Console.WriteLine("Generating QB template.");
                    File.Delete("C:\\Windows\\fastgh3\\DATA\\SONGS\\song.qb");
                    File.Copy("C:\\Windows\\fastgh3\\DATA\\SONGS\\.qb", "C:\\Windows\\fastgh3\\DATA\\SONGS\\song.qb", true);
                    File.SetAttributes("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb", FileAttributes.Normal);
                    disallowGameStartup();
                    Console.WriteLine("Opening song pak.");
                    PakFormat pakformat = new PakFormat("C:\\Windows\\FastGH3\\DATA\\SONGS\\song_song.pak.xen", "", "", PakFormatType.PC);
                    PakEditor buildsong = new PakEditor(pakformat, false);
                    Console.WriteLine("Compiling chart.");
                    QbFile     songdata   = new QbFile("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb", pakformat);
                    QbItemBase array_easy = new QbItemArray(songdata);
                    array_easy.Create(QbItemType.SectionArray);
                    QbItemInteger notes_expert = new QbItemInteger(songdata);
                    File.WriteAllText("C:\\Windows\\FastGH3\\DATA\\SONGS\\maxarraysize", (3 * chartiniexpert.Length).ToString());
                    notes_expert.Create(QbItemType.ArrayInteger);
                    pushinteger = 0;
                    foreach (string note in chartiniexpert)
                    {
                        uint.TryParse(note.Before(" = N"), out notes_expert.Values[pushinteger]);
                        notes_expert.Values[pushinteger] *= Convert.ToUInt32(2.8125);
                        int.TryParse(note.After(" = N ").Before(" "), out notecolor);
                        uint.TryParse(note.After(" = N ") + notecolor + " ", out notes_expert.Values[pushinteger + 1]);
                        if (notes_expert.Values[pushinteger + 1] == 0)
                        {
                            notes_expert.Values[pushinteger + 1] = 1;
                        }
                        if (notecolor == 0)
                        {
                            try
                            {
                                if (notes_expert.Values[pushinteger - 1] == 2 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 3;
                                }
                                if (notes_expert.Values[pushinteger - 1] == 4 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 5;
                                }
                                if (notes_expert.Values[pushinteger - 1] == 8 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 9;
                                }
                                if (notes_expert.Values[pushinteger - 1] == 16 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 17;
                                }
                                if (notes_expert.Values[pushinteger - 3] != notes_expert.Values[pushinteger] && notes_expert.Values[pushinteger + 3] != notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 1;
                                }
                                if (notes_expert.Values[pushinteger + 5] == 2 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 3;
                                }
                                if (notes_expert.Values[pushinteger + 5] == 4 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 5;
                                }
                                if (notes_expert.Values[pushinteger + 5] == 8 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 9;
                                }
                                if (notes_expert.Values[pushinteger + 5] == 16 && notes_expert.Values[pushinteger - 3] == notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 17;
                                }
                                if (notes_expert.Values[pushinteger + 4] != notes_expert.Values[pushinteger] && notes_expert.Values[pushinteger + 3] != notes_expert.Values[pushinteger])
                                {
                                    notes_expert.Values[pushinteger + 2] = 1;
                                }
                            }
                            catch
                            {
                            }
                        }
                        if (notecolor == 1)
                        {
                            notes_expert.Values[pushinteger + 2] = 2;
                        }
                        if (notecolor == 2)
                        {
                            notes_expert.Values[pushinteger + 2] = 4;
                        }
                        if (notecolor == 3)
                        {
                            notes_expert.Values[pushinteger + 2] = 8;
                        }
                        if (notecolor == 4)
                        {
                            notes_expert.Values[pushinteger + 2] = 16;
                        }
                        Console.WriteLine(notes_expert.Values[pushinteger] + Environment.NewLine + notes_expert.Values[pushinteger + 1] + Environment.NewLine + notes_expert.Values[pushinteger + 2]);
                        pushinteger += 3;
                    }

                    /*foreach (IniSection s in chartini.Sections)
                     * {
                     *  foreach (IniSection.IniKey k in s.Keys)
                     *  {
                     *      if (s.Name == "ExpertSingle")
                     *      {
                     *          //Console.WriteLine("note @ " + k.GetName() + " that is " + k.GetValue().Substring(5) + " milliseconds long");
                     *          notes_expert.Values[pushinteger] = Convert.ToUInt32(k.Name);
                     *          notes_expert.Values[pushinteger + 1] = Convert.ToUInt32(k.Value.Substring(5)) + 1;
                     *          notes_expert.Values[pushinteger + 2] = 1;
                     *          pushinteger += 3;
                     *      }
                     *  }
                     * }*/
                    //Console.WriteLine(chartini.GetSection("ExpertSingle").Keys.Count+" notes in expert chart.");
                    Console.ReadKey();
                    songdata.AddItem(array_easy);
                    array_easy.AddItem(notes_expert);
                    songdata.AlignPointers();
                    songdata.Write("C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb");
                    Console.WriteLine("Compiling pak.");
                    buildsong.ReplaceFile("6BE19E2F", "C:\\Windows\\FastGH3\\DATA\\SONGS\\song.qb");
                    Console.WriteLine("Encoding song.");
                    disallowGameStartup();
                    Console.WriteLine("Speeding up.");
                    Process dxwnd = new Process();
                    dxwnd.StartInfo.FileName         = "C:\\Windows\\FastGH3\\WINDOWED\\dxwnd.exe";
                    dxwnd.StartInfo.WorkingDirectory = "C:\\Windows\\FastGH3\\WINDOWED\\";
                    dxwnd.StartInfo.WindowStyle      = ProcessWindowStyle.Minimized;
                    dxwnd.Start();
                    Process gh3 = new Process();
                    gh3.StartInfo.FileName         = "C:\\Windows\\FastGH3\\gh3.exe";
                    gh3.StartInfo.WorkingDirectory = "C:\\Windows\\FastGH3\\";

                    /*dxwnd.Start();
                     * gh3.Start();
                     * //*/
                }
            }

            GC.Collect();
        }
예제 #24
0
        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);
        }
예제 #25
0
        public override ChartFormat DecodeChart(FormatData data, ProgressIndicator progress)
        {
            if (!data.HasStream(this, ChartName) || !data.HasStream(this, SectionsName))
            {
                throw new FormatException();
            }

            progress.NewTask(6 + 8);

            Stream chartstream   = data.GetStream(this, ChartName);
            Stream sectionstream = data.GetStream(this, SectionsName);

            PakFormat format     = NeversoftMetadata.GetSongItemType(data.Song);
            SongData  song       = NeversoftMetadata.GetSongData(data.PlatformData, NeversoftMetadata.GetSongItem(data));
            Pak       chartpak   = new Pak(new EndianReader(chartstream, Endianness.BigEndian));     // TODO: Endianness based on format?
            FileNode  chartfile  = chartpak.Root.Find(song.ID + ".mid.qb.ngc", SearchOption.AllDirectories, true) as FileNode;
            QbFile    qbsections = new QbFile(sectionstream, format);
            QbFile    qbchart    = new QbFile(chartfile.Data, format);

            NoteChart chart = new NoteChart();

            chart.PartGuitar = new NoteChart.Guitar(chart);
            chart.PartBass   = new NoteChart.Bass(chart);
            chart.Events     = new NoteChart.EventsTrack(chart);
            chart.Venue      = new NoteChart.VenueTrack(chart);
            chart.Beat       = new NoteChart.BeatTrack(chart);

            progress.Progress();

            DecodeChartFretbars(song, qbchart, chart);

            progress.Progress();

            DecodeChartMarkers(song, qbsections, qbchart, chart);

            progress.Progress();

            for (NoteChart.TrackType track = NoteChart.TrackType.Guitar; track <= NoteChart.TrackType.Bass; track++)
            {
                for (NoteChart.Difficulty difficulty = NoteChart.Difficulty.Easy; difficulty <= NoteChart.Difficulty.Expert; difficulty++)
                {
                    DecodeChartNotes(data, song, qbchart, chart, track, difficulty, data.Song.Data.GetValue <bool>("GH3ChartCoop"));
                    progress.Progress();
                }
            }

            progress.Progress();

            DecodeChartDrums(song, qbchart, chart);

            progress.Progress();

            DecodeChartVenue(song, qbchart, chart);

            ImportMap.ImportChart(data.Song, chart);

            progress.Progress();

            data.CloseStream(chartstream);
            data.CloseStream(sectionstream);

            progress.EndTask();

            return(new ChartFormat(chart));
        }
예제 #26
0
        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;
            }
        }