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)); } }
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)); } } }
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()); }
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); }
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(); }
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; } }