public void Initialize(int analog, int digital)
 {
     Log("Initialize inputs for " + analog + " analogs " + digital + " digitals", LogLevels.DEBUG);
     if (analog > MAXRAWAXIS)
     {
         analog = MAXRAWAXIS;
     }
     if (digital > MAXRAWINPUTS)
     {
         digital = MAXRAWINPUTS;
     }
     RawAxes.Clear();
     RawInputs.Clear();
     for (int i = 0; i < analog; i++)
     {
         var axis = new RawAxis();
         axis.RawAxisIndex = i;
         RawAxes.Add(axis);
     }
     for (int i = 0; i < digital; i++)
     {
         var rawinput = new RawInput();
         rawinput.RawInputIndex = i;
         RawInputs.Add(rawinput);
     }
     ClearAll();
 }
        public void PerformDeepInputAnalysis(RawInput input, bool newrawval, bool prevrawval)
        {
            var cs   = BFFManager.CurrentControlSet;
            var vJoy = SharedData.Manager.vJoy;
            // Bit corresponding to this input
            var rawbit = (UInt32)(1 << input.RawInputIndex);
            var rawdb  = input.Config;

            if (rawdb == null)
            {
                return;
            }
            // Check if we toggle the bit (or autofire mode)
            if (rawdb.IsToggle)
            {
                // Toggle only if we detect a false->true transition in raw value
                if (newrawval && (!prevrawval))
                {
                    // Toggle = xor on every vJoy buttons
                    if (vJoy != null)
                    {
                        vJoy.ToggleButtons(rawdb.MappedvJoyBtns);
                    }
                }
            }
            else if (rawdb.IsAutoFire)
            {
                // Autofire set, if false->true transition, then toggle autofire state
                if (newrawval && (!prevrawval))
                {
                    // Enable/disable autofire
                    autofire_mode_on ^= rawbit;
                }
                // No perform autofire toggle if autofire enabled
                if ((autofire_mode_on & rawbit) != 0)
                {
                    // Toggle = xor every n periods
                    ulong n = (ulong)(cs.vJoyButtonsDB.AutoFirePeriod_ms / BFFManager.GlobalRefreshPeriod_ms);
                    if ((SharedData.Manager.TickCount % n) == 0)
                    {
                        if (vJoy != null)
                        {
                            vJoy.ToggleButtons(rawdb.MappedvJoyBtns);
                        }
                    }
                }
            }
            else if (rawdb.IsSequencedvJoy)
            {
                // Sequenced vJoy buttons - every rising edge, will trigger a new vJoy
                // if false->true transition, then toggle vJoy and move index
                if (newrawval && (!prevrawval))
                {
                    // Clear previous button first
                    if (vJoy != null)
                    {
                        vJoy.Clear1Button(rawdb.MappedvJoyBtns[rawdb.SequenceCurrentToSet]);
                    }
                    // Move indexer
                    rawdb.SequenceCurrentToSet++;
                    if (rawdb.SequenceCurrentToSet >= rawdb.MappedvJoyBtns.Count)
                    {
                        rawdb.SequenceCurrentToSet = 0;
                    }
                    if (rawdb.MappedvJoyBtns.Count < 1)
                    {
                        return;
                    }
                    // Set only indexed one
                    if (vJoy != null)
                    {
                        vJoy.Set1Button(rawdb.MappedvJoyBtns[rawdb.SequenceCurrentToSet]);
                    }
                }
            }
            else if (rawdb.ShifterDecoder != ShifterDecoderMap.No)
            {
                // Part of HShifter decoder map, just save the values
                switch (rawdb.ShifterDecoder)
                {
                case ShifterDecoderMap.HShifterLeftRight:
                case ShifterDecoderMap.HShifterUp:
                case ShifterDecoderMap.HShifterDown:
                    // rawdb
                    _HShifterDecoderMap[(int)rawdb.ShifterDecoder - (int)ShifterDecoderMap.HShifterLeftRight] = rawdb;
                    // state of raw input
                    _HShifterPressedMap[(int)rawdb.ShifterDecoder - (int)ShifterDecoderMap.HShifterLeftRight] = newrawval;
                    break;

                case ShifterDecoderMap.SequencialUp:
                case ShifterDecoderMap.SequencialDown:
                    // rawdb
                    _UpDownShifterDecoderMap[(int)rawdb.ShifterDecoder - (int)ShifterDecoderMap.SequencialUp] = rawdb;
                    // state of raw input
                    _UpDownShifterPressedMap[(int)rawdb.ShifterDecoder - (int)ShifterDecoderMap.SequencialUp] = newrawval;
                    break;
                }
            }
            else
            {
                // Nothing specific : perform simple mask set or clear button
                if (newrawval)
                {
                    if (vJoy != null)
                    {
                        vJoy.SetButtons(rawdb.MappedvJoyBtns);
                    }
                }
                else
                {
                    if (vJoy != null)
                    {
                        vJoy.ClearButtons(rawdb.MappedvJoyBtns);
                    }
                }
            }
        }