/// <summary> /// Called for each beat of the piece /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Tick() { try { _stopwatch.Restart(); // waits for the beat to pass void wait() { Thread.Sleep(Math.Max((MS_PER_1_BPM / BPM) - (int)_stopwatch.ElapsedMilliseconds, 0)); _stopwatch.Reset(); } // check whether we should cancel if (_cancellationToken.IsCancellationRequested || !_playing || _currentActionIndex >= _currentFile.Actions.Count) { Stop(); return; } // check if we should skip this interval if (_wait > 0) { _wait--; wait(); return; } Type actionType = _currentFile.Actions[_currentActionIndex].GetType(); // get action type if (actionType == typeof(MusicLine)) { var keyboard = _inputSimulator.Keyboard; // get line from action MusicLine line = (MusicLine)(_currentFile.Actions[_currentActionIndex]); // iterate through every key in the key pairs for (int i = 0; i < line.Notes.Length; i++) { // find if any letters in the squence are uppercase bool upper = (line.Notes[i].Any(c => { return(char.IsUpper(c)); })); // press shift if the keys are uppercase if (upper) { keyboard.KeyDown(VirtualKeyCode.SHIFT); } // get array of virtual keycodes byte[] codes = line.Notes[i].Select(key => new KeyData { Value = VkKeyScan(key) }.Low).ToArray(); // press all keys down foreach (byte c in codes) { keyboard.KeyDown((VirtualKeyCode)c); keyboard.Sleep(2); } // wait keyboard.Sleep(KEY_DELAY); // pull all keys up foreach (byte c in codes) { keyboard.KeyUp((VirtualKeyCode)c); } // undo shift if (upper) { keyboard.KeyUp(VirtualKeyCode.SHIFT); } wait(); } } else if (actionType == typeof(DirectiveLine)) { var line = (DirectiveLine)_currentFile.Actions[_currentActionIndex]; switch (line.Type) { case DirectiveType.BPM: { checkArgCount(1); // get bpm number if (!int.TryParse(line.Arguments[0], out int bpm)) { throw new RuntimeErrorException($"Argument provided for bpm was not a valid integer number @ line {line.Line}"); } BPM = bpm; break; } case DirectiveType.WAIT: { checkArgCount(1); // get note count if (!int.TryParse(line.Arguments[0], out int count)) { throw new RuntimeErrorException($"Argument provided for wait was not a valid integer number @ line {line.Line}"); } _wait = count; break; } case DirectiveType.GOTO: { checkArgCount(2); // get and check args if (!_currentFile.Tags.ContainsKey(line.Arguments[0])) { throw new RuntimeErrorException($"Tag not found: {line.Arguments[0]} @ line {line.Line}"); } if (!int.TryParse(line.Arguments[1], out int count)) { throw new RuntimeErrorException($"Argument provided for goto count was not a valid integer number @ line {line.Line}"); } // check if goto directive has not been completed // because we can only have one directive per line, we track GOTOs by line number if (_gotoHistory.ContainsKey(line.Line) && _gotoHistory[line.Line] > count) { // create / update item for tracking if (!_gotoHistory.ContainsKey(line.Line)) { _gotoHistory.Add(line.Line, 1); } else { _gotoHistory[line.Line]++; } // move execution to the tag _currentActionIndex = _currentFile.Tags[line.Arguments[0]]; } break; } default: // ignore anything else break; } void checkArgCount(int argCount) { if (line.Arguments.Length < argCount) { throw new RuntimeErrorException($"Directive must have at least {argCount} argument(s) @ line {line.Line}"); } } } } catch (Exception ex) { Stop(); // send exceptions back via the callback _doneCallback(ex); return; } _currentActionIndex++; }
override public void Init(Profile profile, Form parent) { base.Init(profile, parent); InitializeComponent(); initColors(); _conf = new Configer(); //_processor = new MediaProcessor(_parent, _profile); //_processor.Processed += new Action(SetPlayIcon); _processors = new List <MediaProcessor>(); _musicLines = new List <MusicLine>(); for (int i = 0; i < Rows; i++) { BoomDataGrid.Rows.Add(); // init media processors VoiceMediaOutput voice = new VoiceMediaOutput(); voice.Init(this, new Configer()); List <MediaOutput> outs = new List <MediaOutput>(); outs.Add(voice); List <string> types = Profile.DefaultSpecfifcTypes.ToList(); types.AddRange(this.GetSpecificSoundTypes()); MediaProcessor proc = new MediaProcessor(profile, types.ToArray(), outs, _conf); TextBox tb = new TextBox(); tb.BorderStyle = BorderStyle.FixedSingle; tb.Parent = this; tb.Top = (i + 1) * 22 + 6; tb.Width = MusicComboBox.Width; tb.Left = MusicComboBox.Left; tb.Click += new EventHandler(tb_Click); tb.TextChanged += new EventHandler(tb_TextChanged); tb.DoubleClick += new EventHandler(tb_DoubleClick); tb.Tag = i; MusicLine ml = new MusicLine(tb, proc); _musicLines.Add(ml); _processors.Add(proc); } Label l = new Label(); l.Text = "Звуки Звуки Звуки Звуки Звуки"; l.Parent = this; l.Top = (Rows + 1) * 22 + 6; l.Left = MusicComboBox.Left + 10; l.Width = MusicComboBox.Width; l.BorderStyle = BorderStyle.None; l.BackColor = Color.FromArgb(255, 255, 192); BoomDataGrid.Height = Rows * 25 + 10; this.Height = Rows * 25 + 12; for (int i = 0; i < Columns; i++) { int n = BoomDataGrid.Columns.Count; DataGridViewTextBoxColumn C1 = new DataGridViewTextBoxColumn(); C1.Name = n.ToString(); //C1.State == n.ToString(); //C1.FlatStyle = FlatStyle.System; C1.ReadOnly = true; C1.CellTemplate.Style.BackColor = Color.White; C1.Width = 25; BoomDataGrid.Columns.Add(C1);//"Frame" + n.ToString(), n.ToString()); // BoomDataGrid.Columns[n].Width = 25; for (int j = 0; j < Rows; j++) { BoomDataGrid[i, j].Tag = 0; BoomDataGrid[i, j].Style.SelectionBackColor = Color.White; //(DataGridViewButton)BoomDataGrid[i, j].Clik } } //MusicComboBox.Items.AddRange(_profile.GetSpecificSoundsByType("музыка")); }