/// <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++;
        }
Exemplo n.º 2
0
        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("музыка"));
        }