private bool gerDevVerHandler(Dictionary <string, object> devNodeDir)//获得设备版本 { int m_id = 0, s_id = 0; int next_m_id = 0, next_s_id = 0; if (devNodeDir != null) { m_id = (int)devNodeDir["m_id"]; s_id = (int)devNodeDir["s_id"]; if ((bool)devNodeDir["success"] == true) { devInfoTable[m_id, s_id] = devNodeDir; this.Invoke(new UpdateDevTreeView(updateDevTreeView), devInfoTable); } } for (int i = m_id; i < devDepTable.GetLength(0); i++) { for (int j = (i == m_id ? s_id + 1:0); j < devDepTable.GetLength(1); j++) { if (devDepTable[i, j] != null) { next_m_id = i; next_s_id = j; textBox1.AppendText("获取版本信息 m_id:" + next_m_id + " s_id:" + next_s_id + "\n"); return(this.canUpdateManager.GetDevVerCallback(next_m_id, next_s_id, gerDevVerHandler)); } } } TransitionState(WorkState.INIT);//没有下一个版本信息 XmlManager.SaveDevOnlineToXml(devInfoTable); return(false); }
private Bitmap CalculateFragmentStep() { int[] imageData = new int[_fragments.GetLength(0) * _fragments.GetLength(1)]; Vector4ToInt vec4ToInt = new Vector4ToInt(); for (int x = 0; x < _fragments.GetLength(0); x++) { for (int y = 0; y < _fragments.GetLength(1); y++) { if (_fragments[x, y] != null) { for (int i = 0; i < _fragments[x, y].Values.First().Count; i++) { bool closest = true; if (DepthEnabled) { for (int j = 0; j < _depths[x, y].Count; j++) { if (i != j) { if (_depths[x, y][i] > _depths[x, y][j]) { closest = false; } } } } if (closest) { foreach (var key in _fragments[x, y].Keys) { SetAttribute(_activeFragmentShader, key, _fragments[x, y][key][i]); } _activeFragmentShader.Main(); foreach (var outValue in _activeFragmentShader.GetOutValues()) { if (outValue.Key == FragmentShader.ColorName) { vec4ToInt.ColorValue = 0; vec4ToInt.valueA = (byte)Math.Min((int)(((Vector4)outValue.Value).A * 255), 255); vec4ToInt.valueR = (byte)Math.Min((int)(((Vector4)outValue.Value).R * 255), 255); vec4ToInt.valueG = (byte)Math.Min((int)(((Vector4)outValue.Value).G * 255), 255); vec4ToInt.valueB = (byte)Math.Min((int)(((Vector4)outValue.Value).B * 255), 255); imageData[x + y * Width] = vec4ToInt.ColorValue; } } } } } } } return(new Bitmap(Width, Height, Width, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Marshal.UnsafeAddrOfPinnedArrayElement(imageData, 0))); }
static void Check(Dictionary <int, string>[,] fff, string[] res, int[] ints, ref int count) { int W = fff.GetLength(0); for (int i = 0; i < ints.Length; i++) { if (res[i] != null) { continue; } for (int j = 0; j < W; j++) { for (int k = 0; k < W; k++) { string s; if (fff[j, k].TryGetValue(ints[i], out s)) { if (res[i] == null) { res[i] = s; count--; } else if (s.Length < res[i].Length || s.Length == res[i].Length && s.CompareTo(res[i]) < 0) { res[i] = s; } } } } } }
static void Go(Dictionary <int, string>[,] fff, string[] map, Triple triple, List <Triple> newList, int i1, int j1, int i2, int j2) { int W = fff.GetLength(0); if (i1 < 0 || i1 >= W || j1 < 0 || j1 >= W || i2 < 0 || i2 >= W || j2 < 0 || j2 >= W) { return; } int N = triple.C; char sign = map[i1][j1]; int d = map[i2][j2] - '0'; N += (sign == '+' ? 1 : -1) * d; string r = fff[triple.A, triple.B][triple.C]; r += sign.ToString() + map[i2][j2]; string old; if (!fff[i2, j2].TryGetValue(N, out old) || old.Length > r.Length || old.Length == r.Length && old.CompareTo(r) > 0) { fff[i2, j2][N] = r; newList.Add(new Triple(i2, j2, N)); } }
private void UpdateDevBtn_Click(object sender, EventArgs e) { treeView1.Nodes.Clear(); for (int i = 0; i < devInfoTable.GetLength(0); i++) { for (int j = 0; j < devInfoTable.GetLength(1); j++) { devInfoTable[i, j] = null; } } devDepTable = XmlManager.GetDevDevployFromXml(); if (gerDevVerHandler(null)) { TransitionState(WorkState.GET_SOFT_VERSION_LIST); } }
public static Dictionary <int, List <Rectangle> >[] read(this Dictionary <int, List <Rectangle> >[] ary, BinaryReader reader) { Dictionary <int, List <Rectangle> >[] result = new Dictionary <int, List <Rectangle> > [reader.ReadInt32()]; for (int i = 0; i < result.GetLength(0); i++) { result[i] = new Dictionary <int, List <Rectangle> >(); result[i].read(reader); } return(result); }
void updateDevTreeView(Dictionary <string, object>[,] devInfoTable) { treeView1.Nodes.Clear(); for (int i = 0; i < devInfoTable.GetLength(0); i++) { if (devInfoTable[i, 0] != null) { string devName = XmlManager.GetDevNameFromXml(i, 0); devName = devName == null ? "----" : devName; TreeNode mNode = treeView1.Nodes.Add((i << 4).ToString(), i.ToString() + " " + devName + " " + devInfoTable[i, 0]["app"] + " " + devInfoTable[i, 0]["ver"]); for (int j = 1; j < devInfoTable.GetLength(1); j++) { if (devInfoTable[i, j] != null) { devName = XmlManager.GetDevNameFromXml(i, j); devName = devName == null ? "----" : devName; mNode.Nodes.Add((i * 16 + j).ToString(), j.ToString() + " " + devName + " " + devInfoTable[i, j]["app"] + " " + devInfoTable[i, j]["ver"]); } } } } }
public static Dictionary <int, HashSet <Vector2> >[] read( this Dictionary <int, HashSet <Vector2> >[] array, BinaryReader reader) { var result = new Dictionary <int, HashSet <Vector2> > [reader.ReadInt32()]; for (int i = 0; i < result.GetLength(0); i++) { result[i] = new Dictionary <int, HashSet <Vector2> >(); result[i].read(reader); } return(result); }
/// <summary> /// Get the instance of card at the given location on the board /// </summary> /// <param name="x">X location of the desired card</param> /// <param name="y">Y location of the desired card</param> /// <returns>The card instance found at the provided location</returns> public Card this[int x, int y] { get { if (board is null) { return(null); } if (x < 0 || x >= board.GetLength(0)) { throw new ArgumentOutOfRangeException(nameof(x), x, "provided value cannot be less than zero, or greater than the last index of the array"); } if (y < 0 || y >= board.GetLength(1)) { throw new ArgumentOutOfRangeException(nameof(y), y, "provided value cannot be less than zero, or greater than the last index of the array"); } return(board[x, y]); } }
//Find collisions (where two words use the same grid position as two different characters) private static List<IntPoint> findCollisions(Dictionary<string, char>[,] collisionTable) { List<IntPoint> collisions = new List<IntPoint>(); for(int i = 0; i < collisionTable.GetLength(0); i++) //Cols { for(int j = 0; j < collisionTable.GetLength(1); j++) //Rows { Dictionary<string, char> words = collisionTable[i, j]; //If there is more than one word making use of this character, check that they are all using it as the same character if (words.Count > 1) { char? firstChar = null; foreach (char c in words.Values) { //If first iter, store char if (firstChar == null) { firstChar = c; } else //Otherwise this is a later iteration, check that the char this word is using this position as is the same as previous words { //If this word is using this charcter differently to how the first word used it, there's a collision if (c != firstChar) { collisions.Add(new IntPoint(i, j)); } } } } } } return collisions; }
//Generates a collision table (a lookup table for each cell in the wordsearch that shows each word using it and what character // that word uses it as) private static Dictionary<string, char>[,] generateCollisionTable(Dictionary<string, WordPosition> wordPositions, int cols, int rows) { //Build up a representation of the Wordsearch and what characters each word uses Dictionary<string, char>[,] collisionTable = new Dictionary<string, char>[cols, rows]; for(int i = 0; i < collisionTable.GetLength(0); i++) { for(int j = 0; j < collisionTable.GetLength(1); j++) { collisionTable[i, j] = new Dictionary<string, char>(); } } //Iterate over each word, populating the wordsearch foreach(KeyValuePair<string, WordPosition> kvp in wordPositions) { string word = kvp.Key; WordPosition position = kvp.Value; //Foreach character the word goes through int charIdx = 0; foreach(IntPoint charPosition in position.CharIndices) { //Store that this word goes through this character collisionTable[charPosition.X, charPosition.Y].Add(word, word[charIdx]); charIdx++; } } return collisionTable; }
public void step() { if (contradictive) { return; } steps++; interestingPoints = new HashSet <Point>(); void detectContradictions(Dictionary <int[, ], bool>[,] wave, out bool d, out Point maxNeg) { // Find the position with the most negentropy d = true; var ps = new List <Point>(); var maxscore = 0; var choiceIsValid = false; foreach (int x in Enumerable.Range(0, wave.GetLength(0))) { foreach (int y in Enumerable.Range(0, wave.GetLength(1))) { var numberOfFalses = 0; foreach (var possibility in wave[x, y]) { if (possibility.Value == false) { numberOfFalses += 1; } } var numberOfTrues = wave[x, y].Count() - numberOfFalses; if (numberOfTrues == 0) { contradictive = true; //Debug.Log("Encountered a contradiction at " + x.ToString() + ", " + y.ToString() + "!"); } if (numberOfTrues > 1) { if (!choiceIsValid || numberOfFalses > maxscore) { d = false; ps = new List <Point>(); ps.Add(new Point(x, y)); maxscore = numberOfFalses; choiceIsValid = true; } else if (numberOfFalses == maxscore) { ps.Add(new Point(x, y)); } } } } maxNeg = new Point(0, 0); if (choiceIsValid) { maxNeg = ps[Random.Range(0, ps.Count)]; } } Point toCollapse; bool done; detectContradictions(wave, out done, out toCollapse); offsetx = offsety = (int)Mathf.Floor(n / 2); if (!done) { // collapse a superposition //Debug.Log("collapsing wavefunction at " + toCollapse.x.ToString() + ", " + toCollapse.y.ToString()); var onesToMaybeKeep = (from entry in wave[toCollapse.x, toCollapse.y] where entry.Value select entry.Key).ToList(); var total = (from key in onesToMaybeKeep select patterns[key]).Sum(); var oneToKeep = Random.Range(0, total - 1); int i = 0; var patternToKeep = onesToMaybeKeep.ToList()[0]; foreach (var maybe in onesToMaybeKeep) { i += patterns[maybe]; if (i >= oneToKeep) { patternToKeep = maybe; break; } } foreach (var possibility in wave[toCollapse.x, toCollapse.y].Keys.ToArray()) { wave[toCollapse.x, toCollapse.y][possibility] = possibility == patternToKeep; } interestingPoints.UnionWith(generatePointsInSquare(toCollapse)); // propagate updates while (interestingPoints.Count() != 0) { foreach (Point p in interestingPoints.ToList()) { interestingPoints.Remove(p); if (p.x < 0 || p.y < 0 || p.x >= wave.GetLength(0) || p.y >= wave.GetLength(1)) { continue; } var truePossibilities = from entry in wave[p.x, p.y] where entry.Value select entry.Key; int c = truePossibilities.Count(); if (c < 2) { continue; } foreach (var possibility in truePossibilities.ToArray()) { bool possibilityValid = true; foreach (int yr in Enumerable.Range(0, n)) { foreach (int xr in Enumerable.Range(0, n)) { var posx = p.x + xr; var posy = p.y + yr; var color = possibility[xr, yr]; foreach (int xi in Enumerable.Range(0, n)) { foreach (int yi in Enumerable.Range(0, n)) { if ((posx - xi) >= 0 && (posy - yi) >= 0 && (posx - xi) < wave.GetLength(0) && (posy - yi) < wave.GetLength(1)) { bool foundOne = false; foreach (var possibility2 in wave[posx - xi, posy - yi]) { if (possibility2.Value && possibility2.Key[xi, yi] == color) { foundOne = true; break; } } if (!foundOne) { possibilityValid = false; } } } } } } if (!possibilityValid) { wave[p.x, p.y][possibility] = false; interestingPoints.UnionWith(generatePointsInSquare(p)); if ((from w in wave[p.x, p.y] where w.Value select w.Value).Count() == 0) { Debug.Log("Found a contradiction at " + p.x.ToString() + ", " + p.y.ToString() + "."); contradictive = true; squaresDrawn[p].GetComponent <SpriteRenderer>().color = Color.red; comeUpWithColors(); return; } } } } } } comeUpWithColors(); }
public static Project Load(string filename) { var project = new Project(); var envelopes = new Dictionary <int, Envelope> [Project.ExpansionCount, Envelope.Max]; var duties = new Dictionary <int, int> [Project.ExpansionCount]; var instruments = new Dictionary <int, Instrument>(); var dpcms = new Dictionary <int, DPCMSample>(); var columns = new int[5] { 1, 1, 1, 1, 1 }; var patternFxData = new Dictionary <Pattern, RowFxData[, ]>(); var noteLookup = new Dictionary <string, int> { ["A-"] = 9, ["A#"] = 10, ["B-"] = 11, ["C-"] = 0, ["C#"] = 1, ["D-"] = 2, ["D#"] = 3, ["E-"] = 4, ["F-"] = 5, ["F#"] = 6, ["G-"] = 7, ["G#"] = 8 }; for (int i = 0; i < envelopes.GetLength(0); i++) { for (int j = 0; j < envelopes.GetLength(1); j++) { envelopes[i, j] = new Dictionary <int, Envelope>(); } } for (int i = 0; i < duties.Length; i++) { duties[i] = new Dictionary <int, int>(); } DPCMSample currentDpcm = null; int dpcmWriteIdx = 0; Song song = null; string patternName = ""; var lines = File.ReadAllLines(filename); for (int i = 0; i < lines.Length; i++) { var line = lines[i].Trim(); if (line.StartsWith("TITLE")) { project.Name = line.Substring(5).Trim(' ', '"'); } else if (line.StartsWith("AUTHOR")) { project.Author = line.Substring(6).Trim(' ', '"'); } else if (line.StartsWith("COPYRIGHT")) { project.Copyright = line.Substring(9).Trim(' ', '"'); } else if (line.StartsWith("EXPANSION")) { var exp = int.Parse(line.Substring(9)); if (exp == 1) { project.SetExpansionAudio(Project.ExpansionVrc6); } } else if (line.StartsWith("MACRO")) { var expansion = line.Substring(5, 4) == "VRC6" ? Project.ExpansionVrc6 : Project.ExpansionNone; var halves = line.Substring(line.IndexOf(' ')).Split(':'); var param = halves[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var curve = halves[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var type = int.Parse(param[0]); var idx = int.Parse(param[1]); var loop = int.Parse(param[2]); var rel = int.Parse(param[3]); if (type < 3) { var env = new Envelope(); env.Length = curve.Length; // FamiTracker allows envelope with release with no loop. We dont allow that. if (type == Envelope.Volume && loop == -1 && rel != -1) { loop = rel; } env.Loop = loop; env.Release = type == Envelope.Volume && rel != -1 ? rel + 1 : -1; for (int j = 0; j < curve.Length; j++) { env.Values[j] = sbyte.Parse(curve[j]); } if (type == 2) { env.Relative = true; } envelopes[expansion, type][idx] = env; } else if (type == 4) { duties[expansion][idx] = int.Parse(curve[0]); } } else if (line.StartsWith("DPCMDEF")) { var param = SplitStringKeepQuotes(line.Substring(7)); var name = param[2]; var j = 2; while (!project.IsDPCMSampleNameUnique(name)) { name = param[2] + "-" + j++; } currentDpcm = project.CreateDPCMSample(name, new byte[int.Parse(param[1])]); dpcms[int.Parse(param[0])] = currentDpcm; dpcmWriteIdx = 0; } else if (line.StartsWith("DPCM")) { var param = line.Substring(6).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in param) { currentDpcm.Data[dpcmWriteIdx++] = Convert.ToByte(s, 16); } } else if (line.StartsWith("KEYDPCM")) { var param = line.Substring(7).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (param[0] == "0") { int octave = int.Parse(param[1]); int semitone = int.Parse(param[2]); int note = octave * 12 + semitone + 1; if (project.NoteSupportsDPCM(note)) { int dpcm = int.Parse(param[3]); int pitch = int.Parse(param[4]); int loop = int.Parse(param[5]); project.MapDPCMSample(note, dpcms[dpcm], pitch, loop != 0); } } } else if (line.StartsWith("INST2A03") || line.StartsWith("INSTVRC6")) { var expansion = line.Substring(4, 4) == "VRC6" ? Project.ExpansionVrc6 : Project.ExpansionNone; var param = SplitStringKeepQuotes(line.Substring(line.IndexOf(' '))); int idx = int.Parse(param[0]); int vol = int.Parse(param[1]); int arp = int.Parse(param[2]); int pit = int.Parse(param[3]); int dut = int.Parse(param[5]); var name = param[6]; var j = 2; if (!project.IsInstrumentNameUnique(name)) { name = param[6] + "-" + j++; } var expansionType = line.StartsWith("INSTVRC6") ? Project.ExpansionVrc6 : Project.ExpansionNone; var instrument = project.CreateInstrument(expansionType, name); if (vol >= 0) { instrument.Envelopes[0] = envelopes[expansion, 0][vol].Clone(); } if (arp >= 0) { instrument.Envelopes[1] = envelopes[expansion, 1][arp].Clone(); } if (pit >= 0) { instrument.Envelopes[2] = envelopes[expansion, 2][pit].Clone(); } if (dut >= 0) { instrument.DutyCycle = duties[expansionType][dut]; } instruments[idx] = instrument; } else if (line.StartsWith("TRACK")) { var param = SplitStringKeepQuotes(line.Substring(5)); song = project.CreateSong(param[3]); song.SetLength(0); song.SetPatternLength(int.Parse(param[0])); song.Speed = int.Parse(param[1]); song.Tempo = int.Parse(param[2]); columns = new int[song.Channels.Length]; } else if (line.StartsWith("COLUMNS")) { var param = line.Substring(7).Split(new[] { ' ', ':' }, StringSplitOptions.RemoveEmptyEntries); for (int j = 0; j < song.Channels.Length; j++) { columns[j] = int.Parse(param[j]); } } else if (line.StartsWith("ORDER")) { var orderIdx = Convert.ToInt32(line.Substring(6, 2), 16); var values = line.Substring(5).Split(':')[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var order = new int[song.Channels.Length]; for (int j = 0; j < song.Channels.Length; j++) { int patternIdx = Convert.ToInt32(values[j], 16); var name = values[j]; var pattern = song.Channels[j].GetPattern(name); if (pattern == null) { pattern = song.Channels[j].CreatePattern(name); } song.Channels[j].PatternInstances[orderIdx] = pattern; } song.SetLength(song.Length + 1); } else if (line.StartsWith("PATTERN")) { patternName = line.Substring(8); } else if (line.StartsWith("ROW")) { var channels = line.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); var rowIdx = Convert.ToInt32(channels[0].Substring(4, 2), 16); for (int j = 1; j <= song.Channels.Length; j++) { var noteData = channels[j].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var pattern = song.Channels[j - 1].GetPattern(patternName); if (pattern == null) { continue; } //var fxData = new RowFxData[song.PatternLength]; if (!patternFxData.ContainsKey(pattern)) { patternFxData[pattern] = new RowFxData[song.PatternLength, 4]; } // Note if (noteData[0] == "---") { pattern.Notes[rowIdx].Value = Note.NoteStop; } else if (noteData[0] == "===") { pattern.Notes[rowIdx].Value = Note.NoteRelease; } else if (noteData[0] != "...") { int famitoneNote; if (j == 4) { famitoneNote = (Convert.ToInt32(noteData[0].Substring(0, 1), 16) + 31) + 1; } else { int semitone = noteLookup[noteData[0].Substring(0, 2)]; int octave = noteData[0][2] - '0'; famitoneNote = octave * 12 + semitone + 1; } if (famitoneNote >= Note.MusicalNoteMin && famitoneNote <= Note.MusicalNoteMax) { pattern.Notes[rowIdx].Value = (byte)famitoneNote; pattern.Notes[rowIdx].Instrument = j == 5 ? null : instruments[Convert.ToInt32(noteData[1], 16)]; } else { // Note outside of range. } } // Volume if (noteData[2] != ".") { pattern.Notes[rowIdx].Volume = Convert.ToByte(noteData[2], 16); } // Read FX. for (int k = 0; k < columns[j - 1]; k++) { var fx = noteData[3 + k]; if (fx == "...") { continue; } var param = Convert.ToByte(fx.Substring(1), 16); var fxData = patternFxData[pattern]; fxData[rowIdx, k].fx = fx[0]; fxData[rowIdx, k].param = param; switch (fx[0]) { case 'B': // Jump pattern.Notes[rowIdx].Jump = param; break; case 'D': // Skip pattern.Notes[rowIdx].Skip = param; break; case 'F': // Tempo if (param <= 0x1f) // We only support speed change for now. { pattern.Notes[rowIdx].Speed = param; } break; case '4': // Vibrato pattern.Notes[rowIdx].VibratoDepth = (byte)(param & 0x0f); pattern.Notes[rowIdx].VibratoSpeed = (byte)VibratoSpeedImportLookup[param >> 4]; if (pattern.Notes[rowIdx].VibratoDepth == 0 || pattern.Notes[rowIdx].VibratoSpeed == 0) { pattern.Notes[rowIdx].Vibrato = 0; } break; } } } } } foreach (var s in project.Songs) { CreateSlideNotes(s, patternFxData); s.RemoveEmptyPatterns(); s.SetSensibleBarLength(); foreach (var c in s.Channels) { c.ColorizePatterns(); } } project.UpdateAllLastValidNotesAndVolume(); return(project); }
public Project Load(string filename) { var envelopes = new Dictionary <int, Envelope> [Project.ExpansionCount, Envelope.Count]; var instruments = new Dictionary <int, Instrument>(); var dpcms = new Dictionary <int, DPCMSample>(); var columns = new int[5] { 1, 1, 1, 1, 1 }; for (int i = 0; i < envelopes.GetLength(0); i++) { for (int j = 0; j < envelopes.GetLength(1); j++) { envelopes[i, j] = new Dictionary <int, Envelope>(); } } project = new Project(); project.TempoMode = Project.TempoFamiTracker; DPCMSample currentDpcm = null; int dpcmWriteIdx = 0; Song song = null; string patternName = ""; var lines = File.ReadAllLines(filename); for (int i = 0; i < lines.Length; i++) { var line = lines[i].Trim(); if (line.StartsWith("TITLE")) { project.Name = line.Substring(5).Trim(' ', '"'); } else if (line.StartsWith("AUTHOR")) { project.Author = line.Substring(6).Trim(' ', '"'); } else if (line.StartsWith("COPYRIGHT")) { project.Copyright = line.Substring(9).Trim(' ', '"'); } else if (line.StartsWith("EXPANSION")) { var exp = int.Parse(line.Substring(9)); var convertedExp = ConvertExpansionAudio(exp); if (convertedExp < 0) { return(null); } project.SetExpansionAudio(convertedExp); } else if (line.StartsWith("N163CHANNELS")) { var numExpChannels = int.Parse(line.Substring(12).Trim(' ', '"')); project.SetExpansionAudio(Project.ExpansionN163, numExpChannels); } else if (line.StartsWith("MACRO")) { var expansion = line.StartsWith("MACROVRC6") ? Project.ExpansionVrc6 : line.StartsWith("MACRON163") ? Project.ExpansionN163 : Project.ExpansionNone; var halves = line.Substring(line.IndexOf(' ')).Split(':'); var param = halves[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var curve = halves[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var type = int.Parse(param[0]); var idx = int.Parse(param[1]); var loop = int.Parse(param[2]); var rel = int.Parse(param[3]); var famistudioType = EnvelopeTypeLookup[type]; if (famistudioType < Envelope.Count) { var env = new Envelope(famistudioType); env.Length = curve.Length; // FamiTracker allows envelope with release with no loop. We dont allow that. if (env.CanRelease && loop == -1 && rel != -1) { loop = rel; } env.Loop = loop; env.Release = env.CanRelease && rel != -1 ? rel + 1 : -1; env.Relative = famistudioType == Envelope.Pitch; for (int j = 0; j < curve.Length; j++) { env.Values[j] = sbyte.Parse(curve[j]); } envelopes[expansion, famistudioType][idx] = env; } } else if (line.StartsWith("DPCMDEF")) { var param = SplitStringKeepQuotes(line.Substring(7)); currentDpcm = CreateUniquelyNamedSample(param[2], new byte[int.Parse(param[1])]); dpcms[int.Parse(param[0])] = currentDpcm; dpcmWriteIdx = 0; } else if (line.StartsWith("DPCM")) { if (currentDpcm != null) // Can happen if more than 16KB of samples { var param = line.Substring(6).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in param) { currentDpcm.Data[dpcmWriteIdx++] = Convert.ToByte(s, 16); } } } else if (line.StartsWith("KEYDPCM")) { var param = line.Substring(7).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (param[0] == "0") { int octave = int.Parse(param[1]); int semitone = int.Parse(param[2]); int note = octave * 12 + semitone + 1; if (project.NoteSupportsDPCM(note)) { int dpcm = int.Parse(param[3]); int pitch = int.Parse(param[4]); int loop = int.Parse(param[5]); project.MapDPCMSample(note, dpcms[dpcm], pitch, loop != 0); } } } else if (line.StartsWith("INST2A03") || line.StartsWith("INSTVRC6") || line.StartsWith("INSTN163")) { var expansion = line.StartsWith("INSTVRC6") ? Project.ExpansionVrc6 : line.StartsWith("INSTN163") ? Project.ExpansionN163 : Project.ExpansionNone; var param = SplitStringKeepQuotes(line.Substring(line.IndexOf(' '))); int idx = int.Parse(param[0]); int vol = int.Parse(param[1]); int arp = int.Parse(param[2]); int pit = int.Parse(param[3]); int dut = int.Parse(param[5]); var instrument = CreateUniquelyNamedInstrument(expansion, param[param.Length - 1]); if (expansion == Project.ExpansionN163) { instrument.N163WavePreset = Envelope.WavePresetCustom; instrument.N163WaveSize = byte.Parse(param[6]); instrument.N163WavePos = byte.Parse(param[7]); } if (vol >= 0 && instrument.IsEnvelopeActive(Envelope.Volume)) { instrument.Envelopes[Envelope.Volume] = envelopes[expansion, Envelope.Volume][vol].ShallowClone(); } if (arp >= 0 && instrument.IsEnvelopeActive(Envelope.Arpeggio)) { instrument.Envelopes[Envelope.Arpeggio] = envelopes[expansion, Envelope.Arpeggio][arp].ShallowClone(); } if (pit >= 0 && instrument.IsEnvelopeActive(Envelope.Pitch)) { instrument.Envelopes[Envelope.Pitch] = envelopes[expansion, Envelope.Pitch][pit].ShallowClone(); } if (dut >= 0 && instrument.IsEnvelopeActive(Envelope.DutyCycle)) { instrument.Envelopes[Envelope.DutyCycle] = envelopes[expansion, Envelope.DutyCycle][dut].ShallowClone(); } instruments[idx] = instrument; } else if (line.StartsWith("INSTVRC7")) { var param = SplitStringKeepQuotes(line.Substring(line.IndexOf(' '))); int idx = int.Parse(param[0]); var instrument = CreateUniquelyNamedInstrument(Project.ExpansionVrc7, param[param.Length - 1]); instrument.Vrc7Patch = byte.Parse(param[1]); if (instrument.Vrc7Patch == 0) { for (int j = 0; j < 8; j++) { instrument.Vrc7PatchRegs[j] = Convert.ToByte(param[2 + j], 16); } } instruments[idx] = instrument; } else if (line.StartsWith("INSTFDS")) { var param = SplitStringKeepQuotes(line.Substring(line.IndexOf(' '))); int idx = int.Parse(param[0]); int modEnable = int.Parse(param[1]); int modSpeed = int.Parse(param[2]); int modDepth = int.Parse(param[3]); int modDelay = int.Parse(param[4]); if (modEnable == 0) { modSpeed = 0; modDepth = 0; modDelay = 0; } instruments[idx] = CreateUniquelyNamedInstrument(Project.ExpansionFds, param[5]); instruments[idx].FdsModSpeed = (ushort)modSpeed; instruments[idx].FdsModDepth = (byte)modDepth; instruments[idx].FdsModDelay = (byte)modDelay; instruments[idx].FdsWavePreset = Envelope.WavePresetCustom; instruments[idx].FdsModPreset = Envelope.WavePresetCustom; } else if (line.StartsWith("FDSMACRO")) { var halves = line.Substring(line.IndexOf(' ')).Split(':'); var param = halves[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var curve = halves[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var inst = int.Parse(param[0]); var type = int.Parse(param[1]); var loop = int.Parse(param[2]); var rel = int.Parse(param[3]); var famistudioType = EnvelopeTypeLookup[type]; var env = instruments[inst].Envelopes[famistudioType]; env.Length = curve.Length; // FamiTracker allows envelope with release with no loop. We dont allow that. if (env.CanRelease && loop == -1 && rel != -1) { loop = rel; } env.Loop = loop; env.Release = env.CanRelease && rel != -1 ? rel + 1 : -1; env.Relative = famistudioType == Envelope.Pitch; for (int j = 0; j < curve.Length; j++) { env.Values[j] = sbyte.Parse(curve[j]); } } else if (line.StartsWith("FDSMOD") || line.StartsWith("FDSWAVE")) { var mod = line.StartsWith("FDSMOD"); var halves = line.Substring(line.IndexOf(' ')).Split(':'); var param = halves[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var curve = halves[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var inst = int.Parse(param[0]); var env = instruments[inst].Envelopes[mod ? Envelope.FdsModulation : Envelope.FdsWaveform]; for (int j = 0; j < curve.Length; j++) { env.Values[j] = sbyte.Parse(curve[j]); } if (mod) { env.ConvertFdsModulationToAbsolute(); } } else if (line.StartsWith("N163WAVE")) { var param = line.Substring(8).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var instIdx = int.Parse(param[0]); var waveIdx = int.Parse(param[1]); // TODO: We could create different instruments for each wave. if (waveIdx == 0) { var env = instruments[instIdx].Envelopes[Envelope.N163Waveform]; for (int j = 3; j < param.Length; j++) { env.Values[j - 3] = sbyte.Parse(param[j]); } } } else if (line.StartsWith("TRACK")) { var param = SplitStringKeepQuotes(line.Substring(5)); song = project.CreateSong(param[3]); song.SetLength(0); song.SetDefaultPatternLength(int.Parse(param[0])); song.FamitrackerSpeed = int.Parse(param[1]); song.FamitrackerTempo = int.Parse(param[2]); columns = new int[song.Channels.Length]; } else if (line.StartsWith("COLUMNS")) { var param = line.Substring(7).Split(new[] { ' ', ':' }, StringSplitOptions.RemoveEmptyEntries); for (int j = 0; j < song.Channels.Length; j++) { columns[j] = int.Parse(param[j]); } } else if (line.StartsWith("ORDER")) { var orderIdx = Convert.ToInt32(line.Substring(6, 2), 16); var values = line.Substring(5).Split(':')[1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var order = new int[song.Channels.Length]; for (int j = 0; j < song.Channels.Length; j++) { int patternIdx = Convert.ToInt32(values[j], 16); var name = values[j]; var pattern = song.Channels[j].GetPattern(name); if (pattern == null) { pattern = song.Channels[j].CreatePattern(name); } song.Channels[j].PatternInstances[orderIdx] = pattern; } song.SetLength(song.Length + 1); } else if (line.StartsWith("PATTERN")) { patternName = line.Substring(8); } else if (line.StartsWith("ROW")) { var channels = line.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); var n = Convert.ToInt32(channels[0].Substring(4, 2), 16); for (int j = 1; j <= song.Channels.Length; j++) { var noteData = channels[j].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var pattern = song.Channels[j - 1].GetPattern(patternName); if (pattern == null) { continue; } //var fxData = new RowFxData[song.PatternLength]; if (!patternFxData.ContainsKey(pattern)) { patternFxData[pattern] = new RowFxData[song.PatternLength, 4]; } // Note if (noteData[0] == "---") { pattern.GetOrCreateNoteAt(n).Value = Note.NoteStop; } else if (noteData[0] == "===") { pattern.GetOrCreateNoteAt(n).Value = Note.NoteRelease; } else if (noteData[0] != "...") { int famitoneNote; if (j == 4) { famitoneNote = (Convert.ToInt32(noteData[0].Substring(0, 1), 16) + 31) + 1; } else { int semitone = TextToNoteLookup[noteData[0].Substring(0, 2)]; int octave = noteData[0][2] - '0'; famitoneNote = octave * 12 + semitone + 1; } if (famitoneNote >= Note.MusicalNoteMin && famitoneNote <= Note.MusicalNoteMax) { var note = pattern.GetOrCreateNoteAt(n); note.Value = (byte)famitoneNote; note.Instrument = j == 5 ? null : instruments[Convert.ToInt32(noteData[1], 16)]; } else { // Note outside of range. } } // Volume if (noteData[2] != ".") { pattern.GetOrCreateNoteAt(n).Volume = Convert.ToByte(noteData[2], 16); } // Read FX. for (int k = 0; k < columns[j - 1]; k++) { var fxStr = noteData[3 + k]; if (fxStr == "...") { continue; } var fx = new RowFxData(); if (project.ExpansionAudio == Project.ExpansionFds && FdsTextToEffectLookup.TryGetValue(fxStr[0], out var fdsFx)) { fx.fx = (byte)fdsFx; } else { fx.fx = TextToEffectLookup[fxStr[0]]; } fx.param = Convert.ToByte(fxStr.Substring(1), 16); patternFxData[pattern][n, k] = fx; ApplySimpleEffects(fx, pattern, n, patternLengths); } } } } FinishImport(); return(project); }