Author Topic: VB.net Inline Function Example (from AVCS Push to Talk Mode v2.0)  (Read 5228 times)

SemlerPDX

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 291
  • Upstanding Lunatic
    • My AVCS Homepage
This is the new Inline Function (in VB.net) for my Push to Talk "Get Key/Button" mode for VoiceAttack.  This is part of a larger voice command in my AVCS CORE profile, but this is the functional bit which gets all key/button baseline states, and then watches for a new key or button to be pressed.  It is an example of a threaded inline, which executes early in the voice command (and does not wait for it to complete) and pauses for a timeout loop that can be exited by voice command (cancel), timeout, or successful key/button press capture. (I will include an actual .vap once the commands surrounding this are fleshed out, currently an excellent proof of concept stage).

Someone had discussed recently on VA Discord a means to get a user input key for a Push to Talk mode button, and I figured I'd share this inline loop system with examples of many methods that would work to get a user keypress/button state in a loop.

If anyone has any questions, or would like help in applying similar keypress 'get' methods in another inline function (or even a C# Inline Function), feel free to ask and I'll help if I can.

Cheers!

(updated v3 on pastebin:  https://pastebin.com/eg19yc2e)

old v2 code:
Code: (VB.net) [Select]
' Push to Talk Button Inline-Function for VoiceAttack v2 -  Get/Set any Keyboard/Mouse/Joystick Button as a PTT Button
'  by SemlerPDX Jan2021
'  VETERANS-GAMING.COM


Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Public Class VAInline
  dim mouseButtons() as string = {
    "STATE_LEFTMOUSEBUTTON",
    "STATE_RIGHTMOUSEBUTTON",
    "STATE_MIDDLEMOUSEBUTTON",
    "STATE_FORWARDMOUSEBUTTON",
    "STATE_BACKMOUSEBUTTON"
  }
  dim gamepadTriggers() as string = {"LEFTTRIGGER","RIGHTTRIGGER"}
 
  dim buttonsAlwaysDownList as New List(Of String)
  dim buttonsAlwaysDown as boolean = False
  dim buttonDown as string = ""
  dim buttonCheck as string = ""
  dim buttonSet as boolean = False
  dim userReady as boolean = False
  dim counter as integer = 0
 
  dim debugging as boolean = False
 
 
  Private Function BuildAlwaysDownList()
    'Mouse Buttons Baseline State Loop
    if ((vaProxy.Utility.ParseTokens("{STATE_ANYMOUSEDOWN}")) <> "0")
      for m as integer = 0 to 4
        if ((vaProxy.Utility.ParseTokens("{"+ mouseButtons(m) +"}")) <> "0")
          buttonsAlwaysDownList.Add(mouseButtons(m))
          buttonsAlwaysDown = true
          if (debugging)
            VA.WriteToLog("MOUSE BUTTON ("+ mouseButtons(m) +") DISREGARED AS ALWAYS DOWN","red")
          end if
        end if
      next
    end if
   
    'Keyboard Key Baseline State Loop
    for k as integer = 1 to 254
      if ((vaProxy.Utility.ParseTokens("{STATE_ANYKEYDOWN}")) <> "0")
        if ((vaProxy.Utility.ParseTokens("{STATE_KEYSTATE:" + k.ToString() + "}")) = "1")
          buttonsAlwaysDownList.Add("STATE_KEYSTATE:" + k.ToString())
          buttonsAlwaysDown = true
          if (debugging)
            VA.WriteToLog("KEYBOARD KEY (virtual-key code " + k.ToString() + ") DISREGARED AS ALWAYS DOWN","red")
          end if
        end if
      end if
    next
   
    'Joystick Button Baseline State Loop
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1")
       
        'Joystick Buttons Baseline "Pressed" States
        if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ANYBUTTON}")) <> "0")
          for i as integer = 1 to 128
            if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString() + "}")) = "1")
              buttonsAlwaysDownList.Add("STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString())
              buttonsAlwaysDown = true
              if (debugging)
                VA.WriteToLog("JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " DISREGARED - POSSIBLE DUAL STAGE TRIGGER","red")
              end if
            end if
          next
        end if
       
        'Joystick as Gamepad Baseline Trigger States (with 20 of 255 as 'deadzone')
        if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ISGAMEPAD}")) <> "0")
          for t as integer = 0 to 1
            if (IsNumeric(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}")))
              if ((Convert.ToInt32(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}"))) > 20)
                buttonsAlwaysDownList.Add("STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t))
                buttonsAlwaysDown = true
                if (debugging)
                  VA.WriteToLog("Always Down " + gamepadTriggers(t),"yellow")
                end if
              end if
            end if
          next
        end if
       
      end if
    next
  End function
 
 
  Private Function GetReverseMouseButton(ByRef buttonSet as boolean)
    'Check Always Down Mouse Button for "Unpressed" state
    if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
      for each buttonAlwaysDown as string in buttonsAlwaysDownList
        if (buttonAlwaysDown.EndsWith("MOUSEBUTTON"))
          if ((vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")) = "0")
            buttonSet = true
            buttonDown = buttonCheck
            VA.SetBoolean("~avcs_ptt_reverse", true)
            if (debugging)
              VA.WriteToLog("(DST)- REVERSE MOUSE BUTTON (" + buttonDown + ") SET","green")
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  Private Function GetMouseButton(ByRef buttonSet as boolean)
    'Mouse Button Current States
    if ((vaProxy.Utility.ParseTokens("{STATE_ANYMOUSEDOWN}")) <> "0")
      for m as integer = 0 to 4
        if (buttonSet = false)
          if ((vaProxy.Utility.ParseTokens("{"+ mouseButtons(m) +"}")) <> "0")
            buttonCheck = mouseButtons(m)
            if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
              if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                buttonSet = true
                buttonDown = buttonCheck
                if (debugging)
                  VA.WriteToLog("(DST)- MOUSE BUTTON (" + mouseButtons(m) + ") SET","green")
                end if
              else
                if (debugging)
                  VA.WriteToLog("MOUSE BUTTON (" + mouseButtons(m) + ") DISREGARED - DISCOVERED ON LIST","red")
                end if
              end if
            else
              buttonSet = true
              buttonDown = buttonCheck
              if (debugging)
                VA.WriteToLog("MOUSE BUTTON (" + mouseButtons(m) + ") SET","green")
              end if
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  Private Function GetReverseKeyboardKey(ByRef buttonSet as boolean)
    'Check Always Down Keyboard Key for "Unpressed" state
    if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
      for each buttonAlwaysDown as string in buttonsAlwaysDownList
        if (buttonSet = false)
          if (buttonAlwaysDown.StartsWith("STATE_KEYSTATE"))
            if ((vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")) <> "1")
              buttonSet = true
              buttonDown = buttonAlwaysDown
              VA.SetBoolean("~avcs_ptt_reverse", true)
              if (debugging)
                VA.WriteToLog("(DST)- REVERSE KEYBOARD KEY (" + buttonAlwaysDown + ") SET","green")
              end if
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  Private Function GetKeyboardKey(ByRef buttonSet as boolean)
    'Keyboard Keys Current State Loop
    if ((vaProxy.Utility.ParseTokens("{STATE_ANYKEYDOWN}")) <> "0")
      for k as integer = 1 to 254
        if (buttonSet = false)
          if ((vaProxy.Utility.ParseTokens("{STATE_KEYSTATE:" + k.ToString() + "}")) = "1")
            buttonCheck = "STATE_KEYSTATE:" + k.ToString()
            if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
              if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                buttonSet = true
                buttonDown = buttonCheck
                if (debugging)
                  VA.WriteToLog("(DST)- KEYBOARD KEY (virtual-key code " + k.ToString() + ") SET","green")
                end if
              else
                if (debugging)
                  VA.WriteToLog("KEYBOARD KEY (virtual-key code " + k.ToString() + ") DISREGARED - DISCOVERED ON LIST","red")
                end if
              end if
            else
              buttonSet = true
              buttonDown = buttonCheck
              if (debugging)
                VA.WriteToLog("KEYBOARD KEY (virtual-key code " + k.ToString() + ") SET","green")
              end if
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  'Check Always Down Style Joystick Buttons for "Unpressed" state
  Private Function GetReverseJoystickbutton(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1")
        if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
          for each buttonAlwaysDown as string in buttonsAlwaysDownList
            if (buttonSet = false)
              if (buttonAlwaysDown.StartsWith("STATE_JOYSTICK" + d.ToString()))
                if ((vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")) = "0")
                  buttonSet = true
                  buttonDown = buttonCheck
                  VA.SetBoolean("~avcs_ptt_reverse", true)
                  if (debugging)
                    VA.WriteToLog("(DST)- REVERSE JOYSTICK " + d.ToString() + " BUTTON (" + buttonAlwaysDown + ") HAS BEEN SET","green")
                  end if
                end if
              end if
            end if
          next
        end if
      end if
    next
  End Function
 
 
  'Standard Button Current "Pressed" state
  Private Function GetJoystickButton(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1")
        if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ANYBUTTON}")) = "1")
          for i as integer = 1 to 128
            if (buttonSet = false)
              if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString() + "}")) = "1")
                buttonCheck = "STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString()
                if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
                  if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                    buttonSet = true
                    buttonDown = buttonCheck
                    if (debugging)
                      VA.WriteToLog("(DST)- JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " SET","green")
                    end if
                  else
                    if (debugging)
                      VA.WriteToLog("JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " DISREGARED - DISCOVERED ON LIST","red")
                    end if
                  end if
                else
                  buttonSet = true
                  buttonDown = buttonCheck
                  if (debugging)
                    VA.WriteToLog("JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " SET","green")
                  end if
                end if
              end if
            end if
          next
        end if
      end if
    next
  End Function
 
 
  'Check Always Down Triggers for "Unpressed" state
  Private Function GetReverseJoystickTrigger(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if (((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1") and ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ISGAMEPAD}")) = "1"))
        if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
          for each buttonAlwaysDown as string in buttonsAlwaysDownList
            if (buttonSet = false)
              if (buttonAlwaysDown.EndsWith("TRIGGER"))
                if (IsNumeric(vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")))
                  if ((Convert.ToInt32(vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}"))) < 20)
                    buttonSet = true
                    buttonDown = buttonCheck
                    VA.SetBoolean("~avcs_ptt_reverse", true)
                    if (debugging)
                      VA.WriteToLog("(DST)- REVERSE JOYSTICK GAMEPAD " + d.ToString() + " TRIGGER (" + buttonAlwaysDown + ") HAS BEEN SET","green")
                    end if
                  end if
                end if
              end if
            end if
          next
        end if
      end if
    next
  End Function
 
  'Check Triggers for "Pressed" state
  Private Function GetJoystickTrigger(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if (((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1") and ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ISGAMEPAD}")) = "1"))
        'Gamepad Triggers Current State (with 20 of 255 as 'deadzone')
        for t as integer = 0 to 1
          if (buttonSet = false)
            if (IsNumeric(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}")))
              if ((Convert.ToInt32(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}"))) > 20)
                buttonCheck = "STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t)
                if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
                  if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                    buttonSet = true
                    buttonDown = buttonCheck
                  else
                    if (debugging)
                      VA.WriteToLog("JOYSTICK GAMEPAD " + d.ToString() + gamepadTriggers(t) + " DISREGARED - DISCOVERED ON LIST","red")
                    end if
                  end if
                else
                  buttonSet = true
                  buttonDown = buttonCheck
                  if (debugging)
                    VA.WriteToLog("JOYSTICK GAMEPAD " + d.ToString() + gamepadTriggers(t) + " SET","green")
                  end if
                end if
              end if
            end if
          end if
        next
      end if
    next
  End Function
 
 
  Public Sub Main()
    if (debugging)
      VA.WriteToLog("inline begin....","yellow")
    end if
   
    'Get Button/Key Baseline States
    BuildAlwaysDownList()
    VA.WriteToLog("...Button baseline state has been established","gray")
   
   
    'Begin a pause loop to wait for timeout or Get User Input key/button ID
    VA.SetBoolean("~avcs_getting_input", true)
    while (not(userReady))
      Thread.CurrentThread.Sleep(1000)
      counter += 1
     
      'Check for Timeout or TTS User Prompt Instructions cue
      if ((VA.GetBoolean("~avcs_user_ready")) isNot nothing)
        userReady = VA.GetBoolean("~avcs_user_ready")
      end if
      if ((counter >= 120) or (userReady))
        if ((userReady) and ((VA.GetBoolean("~avcs_getting_input")) is nothing))
          if (debugging)
            VA.WriteToLog("cancelled - reason: command terminated by user or 'other'","red")
          end if
          Exit sub
        elseif ((userReady) and ((VA.GetBoolean("~avcs_getting_input")) isNot nothing))
          if (not(debugging))
            VA.ClearLog()
          end if
          VA.WriteToLog("   ( say anything to exit without saving )","blank")
          VA.WriteToLog("== PLEASE PRESS ANY KEY OR BUTTON NOW ==","green")
        else
          if (debugging)
            if (counter >= 120)
              VA.WriteToLog("cancelled - reason: command timed out... TTS or primary function error","red")
            else
              VA.WriteToLog("cancelled - reason: command terminated - default exit","red")
            end if
          end if
          VA.SetBoolean("~avcs_getting_input", false)
          Exit sub
        end if
      end if
    end while
   
   
    'Reset counter for Keypress/Button monitor
    counter = 0
    userReady = false
    VA.SetBoolean("~avcs_user_ready", false)
   
   
    'Begin a pause loop to wait for Joystick/Gamepad Input or spoken 'cancel/done' speech
    while (not(userReady))
      Thread.CurrentThread.Sleep(75)
      counter += 1
     
      if (buttonSet = false)
        GetReverseMouseButton(buttonSet)
        GetMouseButton(buttonSet)
        GetReverseKeyboardKey(buttonSet)
        GetKeyboardKey(buttonSet)
        GetReverseJoystickbutton(buttonSet)
        GetJoystickButton(buttonSet)
        GetReverseJoystickTrigger(buttonSet)
        GetJoystickTrigger(buttonSet)
      end if
     
      'Check for Input, Timeout or TTS User Prompt Instructions complete
      if ((VA.GetBoolean("~avcs_user_ready")) isNot nothing)
        userReady = VA.GetBoolean("~avcs_user_ready")
      end if
      if ((counter >= 200) or ((buttonSet) and (buttonDown <> "")) or (userReady))
        if ((buttonSet) and (buttonDown <> ""))
          VA.SetText("~avcs_button_choice", buttonDown)
          VA.SetBoolean("~avcs_getting_input", false)
          Exit While
        elseif (userReady)
          VA.WriteToLog("command cancelled - user input not detected","red")
          VA.SetBoolean("~avcs_getting_input", false)
          Exit sub
        elseif (counter >= 200)
          VA.SetBoolean("~avcs_getting_input", false)
          VA.WriteToLog("command timed out... user input not detected","red")
          Exit sub
        end if
      end if
    end while
   
    VA.WriteToLog("PTT Button Set to " + buttonDown, "green")
   
  End Sub

End Class
« Last Edit: February 04, 2022, 12:45:12 PM by SemlerPDX »

SemlerPDX

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 291
  • Upstanding Lunatic
    • My AVCS Homepage
UPDATED VB.net Inline Function Example (from AVCS Push to Talk Mode v3.0)
« Reply #1 on: October 24, 2021, 12:13:49 PM »
Updated inline function for AVCS CORE Push-To-Talk system.  In the previous version, I had not known that Joystick POV directional buttons where handled differently than buttons, etc., and had not included code to monitor for them.  I had also failed to include a check for 'already saved' PTT buttons, which allowed the same key/button/etc. to be set for multiple saved PTT buttons (1-6).

This inline runs in parallel with other VoiceAttack actions outside this inline function in the actual command containing them, to allow for user interaction while this inline is running - from button presses on request to 'save' a PTT button, or voice commands to exit such as "Cancel", or exiting on timeout for no user input.

This modification denies duplicate buttons, and also loops though each potential Joystick and each potential POV on them to check for a non-centered position state, and detect which direction is pressed (4-way only), saving a text variable of the Joystick # and POV # with a colon just before the actual direction pressed.

For example:  ExampleSavedPTTbutton#1 = Joystick1POV1:LEFT

Later, I can loop through any saved PTT buttons and split at the colon to check if that Joystick POV is not centered, and then check if it is matching the split(1) direction in the PTT button monitor (interruptible) infinite loop system.

On pastebin:  https://pastebin.com/eg19yc2e

Code: (VB.net) [Select]
' Push to Talk Button Inline-Function for VoiceAttack v3 -  Get/Set any Keyboard/Mouse/Joystick Button as a PTT Button
'  by SemlerPDX Jan2021/Oct2021
'  VETERANS-GAMING.COM


Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows.Forms


Public Class VAInline
  dim mouseButtons() as string = {
    "STATE_LEFTMOUSEBUTTON",
    "STATE_RIGHTMOUSEBUTTON",
    "STATE_MIDDLEMOUSEBUTTON",
    "STATE_FORWARDMOUSEBUTTON",
    "STATE_BACKMOUSEBUTTON"
  }
  dim gamepadTriggers() as string = {"LEFTTRIGGER","RIGHTTRIGGER"}
 
  dim buttonsAlreadySetList as New List(Of String)
  dim buttonsAlwaysDownList as New List(Of String)
  dim buttonsAlwaysDown as boolean = False
  dim buttonDown as string = ""
  dim buttonCheck as string = ""
  dim checkPOV as string = ""
  dim buttonSet as boolean = False
  dim userReady as boolean = False
  dim counter as integer = 0
 
  dim keyCheck as string = ""
  dim keyString as string = ""
  dim keyCode() as string
 
  dim kc as KeysConverter = new KeysConverter()
 
  dim activeProfile as string = "CORE"
 
  dim debugCheck as boolean
  dim debugCount as integer = 0
 
 
  Private Function SendDebugMessage(ByVal debugText as string, ByVal debugColor as integer)
    '1=Blue - 2=Green - 3=Yellow - 4=Red - 5=Purple - 6=Blank - 7=Orange - 8=Black - 9=Gray - 10=Pink
    if ((VA.GetText("AVCS_Debug_QMSG")) isNot nothing)
      debugCount = VA.GetInt("AVCS_Debug_QMSG")
    end if
    debugCount += 1
    VA.SetText("AVCS_Debug_TMSG_" + debugCount.ToString(), debugText)
    VA.SetInt("AVCS_Debug_WCLR_" + debugCount.ToString(), debugColor)
    VA.SetInt("AVCS_Debug_QMSG", debugCount)
    try
      vaProxy.Command.Execute("f_core_debug -log", true)
    catch
      VA.WriteToLog("AVCS ERROR: PTTGET02 - f_core_debug null - restart VoiceAttack or create bug report", "red")
    end try
    debugCount = 0
  end function
 
  Private Function BuildPTTkeysList()
    for keyIndex as integer = 1 to 6
      'Check for PTT buttons already set
      if ((VA.GetText("AVCS_" + activeProfile + "_PTTBUTTON_" + keyIndex.ToString())) isNot nothing)
        buttonCheck = VA.GetText("AVCS_" + activeProfile + "_PTTBUTTON_" + keyIndex.ToString())
        buttonsAlreadySetList.Add(buttonCheck)
      end if
    next
  end function
 
  Private Function BuildAlwaysDownList()
    'Mouse Buttons Baseline State Loop
    if ((vaProxy.Utility.ParseTokens("{STATE_ANYMOUSEDOWN}")) <> "0")
      for m as integer = 0 to 4
        if ((vaProxy.Utility.ParseTokens("{"+ mouseButtons(m) +"}")) <> "0")
          buttonsAlwaysDownList.Add(mouseButtons(m))
          buttonsAlwaysDown = true
          if (debugCheck)
            SendDebugMessage("MOUSE BUTTON ("+ mouseButtons(m) +") DISREGARED AS ALWAYS DOWN", 4)
          end if
        end if
      next
    end if
   
    'Keyboard Key Baseline State Loop
    for k as integer = 1 to 254
      if ((vaProxy.Utility.ParseTokens("{STATE_ANYKEYDOWN}")) <> "0")
        if ((vaProxy.Utility.ParseTokens("{STATE_KEYSTATE:" + k.ToString() + "}")) = "1")
          buttonsAlwaysDownList.Add("STATE_KEYSTATE:" + k.ToString())
          buttonsAlwaysDown = true
          if (debugCheck)
            SendDebugMessage("KEYBOARD KEY (virtual-key code " + k.ToString() + ") DISREGARED AS ALWAYS DOWN", 4)
          end if
        end if
      end if
    next
   
    'Joystick Button Baseline State Loop
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1")
       
        'Joystick Buttons Baseline "Pressed" States
        if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ANYBUTTON}")) <> "0")
          for i as integer = 1 to 128
            if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString() + "}")) = "1")
              buttonsAlwaysDownList.Add("STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString())
              buttonsAlwaysDown = true
              if (debugCheck)
                SendDebugMessage("JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " DISREGARED - POSSIBLE DUAL STAGE TRIGGER", 4)
              end if
            end if
          next
          'Joystick POV Buttons Baseline States (4-way only)
          if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POVENABLED}")) = "1")
            for i as integer = 1 to 4
              if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POV" + i.ToString() + "TYPE}")) = "4")
                'Loop though this Joystick POV 1-4
                if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POV" + i.ToString() + "}")) <> "CENTER")
                  checkPOV = vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POV" + i.ToString() + "}")
                  buttonsAlwaysDownList.Add("STATE_JOYSTICK" + d.ToString() + "POV" + i.ToString() + ":" + checkPOV)
                  buttonsAlwaysDown = true
                  if (debugCheck)
                    SendDebugMessage("JOYSTICK " + d.ToString() + " POV " + i.ToString() + ":" + checkPOV + " DISREGARED", 4)
                  end if
                end if
              end if
            next
          end if
         
        end if
       
        'Joystick as Gamepad Baseline Trigger States (with 20 of 255 as 'deadzone')
        if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ISGAMEPAD}")) <> "0")
          for t as integer = 0 to 1
            if (IsNumeric(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}")))
              if ((Convert.ToInt32(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}"))) > 20)
                buttonsAlwaysDownList.Add("STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t))
                buttonsAlwaysDown = true
                if (debugCheck)
                  SendDebugMessage("Always Down " + gamepadTriggers(t), 3)
                end if
              end if
            end if
          next
        end if
       
      end if
    next
  End function
 
 
  Private Function GetReverseMouseButton(ByRef buttonSet as boolean)
    'Check Always Down Mouse Button for "Unpressed" state
    if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
      for each buttonAlwaysDown as string in buttonsAlwaysDownList
        if (buttonAlwaysDown.EndsWith("MOUSEBUTTON"))
          if ((vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")) = "0")
            buttonSet = true
            buttonDown = buttonAlwaysDown 'changed from buttonCheck Sept2021
            VA.SetBoolean("~avcs_ptt_reverse", true)
            if (debugCheck)
              SendDebugMessage("(DST)- REVERSE MOUSE BUTTON (" + buttonDown + ") SET", 2)
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  Private Function GetMouseButton(ByRef buttonSet as boolean)
    'Mouse Button Current States
    if ((vaProxy.Utility.ParseTokens("{STATE_ANYMOUSEDOWN}")) <> "0")
      for m as integer = 0 to 4
        if (buttonSet = false)
          if ((vaProxy.Utility.ParseTokens("{"+ mouseButtons(m) +"}")) <> "0")
            buttonCheck = mouseButtons(m)
            if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
              if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                buttonSet = true
                buttonDown = buttonCheck
                if (debugCheck)
                  SendDebugMessage("(DST)- MOUSE BUTTON (" + mouseButtons(m) + ") SET", 2)
                end if
              else
                if (debugCheck)
                  SendDebugMessage("MOUSE BUTTON (" + mouseButtons(m) + ") DISREGARED - DISCOVERED ON LIST", 4)
                end if
              end if
            else
              buttonSet = true
              buttonDown = buttonCheck
              if (debugCheck)
                SendDebugMessage("MOUSE BUTTON (" + mouseButtons(m) + ") SET", 2)
              end if
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  Private Function GetReverseKeyboardKey(ByRef buttonSet as boolean)
    'Check Always Down Keyboard Key for "Unpressed" state
    if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
      for each buttonAlwaysDown as string in buttonsAlwaysDownList
        if (buttonSet = false)
          if (buttonAlwaysDown.StartsWith("STATE_KEYSTATE"))
            if ((vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")) <> "1")
              buttonSet = true
              buttonDown = buttonAlwaysDown
              VA.SetBoolean("~avcs_ptt_reverse", true)
              if (debugCheck)
                SendDebugMessage("(DST)- REVERSE KEYBOARD KEY (" + buttonAlwaysDown + ") SET", 2)
              end if
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  Private Function GetKeyboardKey(ByRef buttonSet as boolean)
    'Keyboard Keys Current State Loop
    if ((vaProxy.Utility.ParseTokens("{STATE_ANYKEYDOWN}")) <> "0")
      for k as integer = 1 to 254
        if (buttonSet = false)
          if ((vaProxy.Utility.ParseTokens("{STATE_KEYSTATE:" + k.ToString() + "}")) = "1")
            buttonCheck = "STATE_KEYSTATE:" + k.ToString()
            if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
              if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                buttonSet = true
                buttonDown = buttonCheck
                if (debugCheck)
                  SendDebugMessage("(DST)- KEYBOARD KEY (virtual-key code " + k.ToString() + ") SET", 2)
                end if
              else
                if (debugCheck)
                  SendDebugMessage("KEYBOARD KEY (virtual-key code " + k.ToString() + ") DISREGARED - DISCOVERED ON LIST", 4)
                end if
              end if
            else
              buttonSet = true
              buttonDown = buttonCheck
              if (debugCheck)
                SendDebugMessage("KEYBOARD KEY (virtual-key code " + k.ToString() + ") SET", 2)
              end if
            end if
          end if
        end if
      next
    end if
  End Function
 
 
  'Check Always Down Style Joystick Buttons for "Unpressed" state
  Private Function GetReverseJoystickbutton(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1")
        if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
          for each buttonAlwaysDown as string in buttonsAlwaysDownList
            if (buttonSet = false)
              if (buttonAlwaysDown.StartsWith("STATE_JOYSTICK" + d.ToString()))
                if ((vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")) = "0")
                  buttonSet = true
                  buttonDown = buttonAlwaysDown 'changed from buttonCheck Sept2021
                  VA.SetBoolean("~avcs_ptt_reverse", true)
                  if (debugCheck)
                    SendDebugMessage("(DST)- REVERSE JOYSTICK " + d.ToString() + " BUTTON (" + buttonAlwaysDown + ") HAS BEEN SET", 2)
                  end if
                end if
              end if
            end if
          next
        end if
      end if
    next
  End Function
 
 
  'Standard Button Current "Pressed" state
  Private Function GetJoystickButton(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1")
        if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ANYBUTTON}")) = "1")
          for i as integer = 1 to 128
            if (buttonSet = false)
              if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString() + "}")) = "1")
                buttonCheck = "STATE_JOYSTICK" + d.ToString() + "BUTTON:" + i.ToString()
                if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
                  if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                    buttonSet = true
                    buttonDown = buttonCheck
                    if (debugCheck)
                      SendDebugMessage("(DST)- JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " SET", 2)
                    end if
                  else
                    if (debugCheck)
                      SendDebugMessage("JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " DISREGARED - DISCOVERED ON LIST", 4)
                    end if
                  end if
                else
                  buttonSet = true
                  buttonDown = buttonCheck
                  if (debugCheck)
                    SendDebugMessage("JOYSTICK " + d.ToString() + " BUTTON " + i.ToString() + " SET", 2)
                  end if
                end if
              end if
            end if
          next
        end if
      end if
    next
  End Function
 
  'Check Always Down POV for "Unpressed" state
  Private Function GetReverseJoystickPOV(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POVENABLED}")) = "1")
        for i as integer = 1 to 4
          checkPOV = "STATE_JOYSTICK" + d.ToString() + "POV" + i.toString()
          if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
            if (buttonsAlwaysDownList.Contains(checkPOV))
              for each buttonAlwaysDown as string in buttonsAlwaysDownList
                if (buttonSet = false) and (buttonAlwaysDown.StartsWith(checkPOV))
                  if ((vaProxy.Utility.ParseTokens("{" + checkPOV + "}")) = "CENTER")
                    buttonSet = true
                    buttonDown = buttonAlwaysDown
                    VA.SetBoolean("~avcs_ptt_reverse", true)
                    if (debugCheck)
                      SendDebugMessage("(DST)- REVERSE JOYSTICK " + d.ToString() + " POV (" + buttonAlwaysDown + ") HAS BEEN SET", 2)
                    end if
                  end if
                end if
              next
            end if
          end if
        next
      end if
    next
  End Function
 
  'Check Joystick POV for "Pressed" state
  Private Function GetJoystickPOV(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POVENABLED}")) = "1")
        for i as integer = 1 to 4
          if (buttonSet = false)
            if ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POV" + i.toString() + "TYPE}")) = "4")
              checkPOV = vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "POV" + i.toString() + "}")
              if (checkPOV <> "CENTER")
                buttonCheck = "STATE_JOYSTICK" + d.ToString() + "POV" + i.toString() + ":" + checkPOV
                if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
                  if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                    buttonSet = true
                    buttonDown = buttonCheck
                    if (debugCheck)
                      SendDebugMessage("JOYSTICK " + d.ToString() + "POV" + i.ToString() + ":" + checkPOV + " SET", 2)
                    end if
                  else
                    if (debugCheck)
                      SendDebugMessage("JOYSTICK " + d.ToString() + "POV" + i.ToString() + ":" + checkPOV + " DISREGARED - DISCOVERED ON LIST", 4)
                    end if
                  end if
                else
                  buttonSet = true
                  buttonDown = buttonCheck
                  if (debugCheck)
                    SendDebugMessage("JOYSTICK " + d.ToString() + "POV" + i.ToString() + ":" + checkPOV + " SET", 2)
                  end if
                end if
              end if
            end if
          end if
        next
      end if
    next
  End Function
 
  '---------------------------------------------------------------------------
  '---------------------------------------------------------------------------
 
  'Check Always Down Triggers for "Unpressed" state
  Private Function GetReverseJoystickTrigger(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if (((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1") and ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ISGAMEPAD}")) = "1"))
        if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
          for each buttonAlwaysDown as string in buttonsAlwaysDownList
            if (buttonSet = false)
              if (buttonAlwaysDown.EndsWith("TRIGGER"))
                if (IsNumeric(vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}")))
                  if ((Convert.ToInt32(vaProxy.Utility.ParseTokens("{" + buttonAlwaysDown + "}"))) < 20)
                    buttonSet = true
                    buttonDown = buttonCheck
                    VA.SetBoolean("~avcs_ptt_reverse", true)
                    if (debugCheck)
                      SendDebugMessage("(DST)- REVERSE JOYSTICK GAMEPAD " + d.ToString() + " TRIGGER (" + buttonAlwaysDown + ") HAS BEEN SET", 2)
                    end if
                  end if
                end if
              end if
            end if
          next
        end if
      end if
    next
  End Function
 
  'Check Triggers for "Pressed" state
  Private Function GetJoystickTrigger(ByRef buttonSet as boolean)
    for d as integer = 1 to 4
      if (((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ENABLED}")) = "1") and ((vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + "ISGAMEPAD}")) = "1"))
        'Gamepad Triggers Current State (with 20 of 255 as 'deadzone')
        for t as integer = 0 to 1
          if (buttonSet = false)
            if (IsNumeric(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}")))
              if ((Convert.ToInt32(vaProxy.Utility.ParseTokens("{STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t) + "}"))) > 20)
                buttonCheck = "STATE_JOYSTICK" + d.ToString() + gamepadTriggers(t)
                if ((buttonsAlwaysDown) and (buttonsAlwaysDownList isNot nothing))
                  if (not(buttonsAlwaysDownList.Contains(buttonCheck)))
                    buttonSet = true
                    buttonDown = buttonCheck
                  else
                    if (debugCheck)
                      SendDebugMessage("JOYSTICK GAMEPAD " + d.ToString() + gamepadTriggers(t) + " DISREGARED - DISCOVERED ON LIST", 4)
                    end if
                  end if
                else
                  buttonSet = true
                  buttonDown = buttonCheck
                  if (debugCheck)
                    SendDebugMessage("JOYSTICK GAMEPAD " + d.ToString() + gamepadTriggers(t) + " SET", 2)
                  end if
                end if
              end if
            end if
          end if
        next
      end if
    next
  End Function
 
 
 
  Public Sub Main()
   
    if (VA.GetBoolean("AVCS_Debug_ON") IsNot nothing)
      debugCheck = VA.GetBoolean("AVCS_Debug_ON")
    end if
   
    if ((VA.GetText("AVCS_ACTIVE_PROFILE")) isNot nothing)
      activeProfile = VA.GetText("AVCS_ACTIVE_PROFILE")
    end if
   
    if (debugCheck)
      VA.ClearLog()
      SendDebugMessage("inline begin....", 3)
    end if
   
   
    'Get Button/Key Baseline States
    BuildPTTkeysList()
    BuildAlwaysDownList()
    VA.SetBoolean("~avcs_getting_input", true)
   
    if (debugCheck)
      SendDebugMessage("Always Down Array Complete", 3)
    end if
   
    'Begin a pause loop to wait for timeout or user input (key/button press or voice 'cancel' phrase)
    while (not(userReady))
      Thread.CurrentThread.Sleep(1000)
      counter += 1
     
      'Check for Timeout or TTS User Prompt Instructions complete
      if ((VA.GetBoolean("~avcs_user_ready")) isNot nothing)
        userReady = VA.GetBoolean("~avcs_user_ready")
      end if
      if ((counter >= 15) or (userReady))
        if (userReady)
          VA.WriteToLog("== PLEASE PRESS ANY KEY OR BUTTON NOW ==","green")
        else
          VA.WriteToLog("cancelled - command timed out... TTS or primary function error","red")
          if (debugCheck)
            SendDebugMessage("AVCS PTT SET cancelled - command timed out", 3)
          end if
          VA.SetBoolean("~avcs_getting_input", false)
          Exit sub
        end if
      end if
    end while
   
   
    'Reset counter for Keypress/Button monitor
    counter = 0
    userReady = false
    VA.SetBoolean("~avcs_user_ready", false)
   
   
    'Begin a pause loop to wait for Joystick/Gamepad Input or spoken 'cancel/done' speech
    while (not(userReady))
      Thread.CurrentThread.Sleep(75)
      counter += 1
     
      if (buttonSet = false)
        GetReverseMouseButton(buttonSet)
        GetMouseButton(buttonSet)
        GetReverseKeyboardKey(buttonSet)
        GetKeyboardKey(buttonSet)
        GetReverseJoystickbutton(buttonSet)
        GetJoystickButton(buttonSet)
        GetReverseJoystickPOV(buttonSet)
        GetJoystickPOV(buttonSet)
        GetReverseJoystickTrigger(buttonSet)
        GetJoystickTrigger(buttonSet)
      end if
     
      'Check for Input, Timeout or TTS User Prompt Instructions complete
      if ((VA.GetBoolean("~avcs_user_ready")) isNot nothing)
        userReady = VA.GetBoolean("~avcs_user_ready")
      end if
      if ((counter >= 200) or ((buttonSet) and (buttonDown <> "")) or (userReady))
        if ((buttonSet) and (buttonDown <> ""))
          if (buttonsAlreadySetList isNot nothing)
            if (buttonsAlreadySetList.Contains(buttonDown))
              VA.SetBoolean("~avcs_getting_input", false)
              VA.SetText("~avcs_button_choice", "alreadyset")
              if (debugCheck)
                SendDebugMessage("ERROR - Existing PTT button has already been set to " + buttonDown, 4)
              end if
              Exit While
            end if
          end if
          VA.SetBoolean("~avcs_getting_input", false)
          VA.SetText("~avcs_button_choice", buttonDown)
          if (debugCheck)
            SendDebugMessage("PTT button has been set " + buttonDown, 2)
          end if
          Exit While
        elseif (userReady)
          VA.SetBoolean("~avcs_getting_input", false)
          VA.WriteToLog("command cancelled - user input not detected","red")
          if (debugCheck)
            SendDebugMessage("AVCS PTT SET user input not detected", 4)
          end if
          Exit While
        elseif (counter >= 200)
          VA.SetBoolean("~avcs_getting_input", false)
          VA.WriteToLog("command timed out... user input not detected","red")
          if (debugCheck)
            SendDebugMessage("AVCS PTT SET command timed out", 4)
          end if
          Exit While
        end if
      end if
    end while
   
    if ((buttonSet) and (buttonDown <> ""))
      if (buttonDown.StartsWith("STATE_KEYSTATE:"))
        keyCode = buttonDown.Split(":")
        if (IsNumeric(keyCode(1)))
          try
            keyString = kc.ConvertToString(Convert.ToInt32(keyCode(1)))
            keyString = keyString.Replace("Oem","")
            VA.WriteToLog("PTT Button Set to " + buttonDown + " == " + keyString, "green")
          catch
            VA.WriteToLog("PTT Button Set to " + buttonDown, "green")
          end try
        end if
      else
        VA.WriteToLog("PTT Button Set to " + buttonDown, "green")
      end if
    end if
   
  End Sub

End Class
« Last Edit: February 04, 2022, 12:45:03 PM by SemlerPDX »

SemlerPDX

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 291
  • Upstanding Lunatic
    • My AVCS Homepage
...and here is the "interruptible infinite loop" Push To Talk Button Monitor v3 inline function from AVCS CORE that works with the above 'set/get' function and other VoiceAttack actions in the command(s).  It allows me to 'wake' listening programmatically if needed, or on saved button/key presses, or on voice command through use of a pre-saved 'computer name' command phrase.  The infinite loop can also be exited programmatically on change of booleans elsewhere, can be paused temporarily, or exited simply by executing it again (it detects and exits before a new instance started, and always exits if it detects PTT system offline as set by user):

On pastebin:  https://pastebin.com/jsa5WhC6

Code: (VB.net) [Select]
' Quick Command Creator Inline-Function for VoiceAttack v3 -  Monitor for PTT Button(s) press
'  by SemlerPDX Jan2021/Oct2021
'  VETERANS-GAMING.COM

Imports Microsoft.VisualBasic
Imports System
Imports System.Threading
Imports System.Threading.Tasks


Public Class VAInline
  dim checkKeyDown as string = ""
  dim checkPovDir() as string
  dim checkPOV as string = ""
 
  dim masterMode as boolean = false
  dim listenAwake as boolean = false
  dim listeningCanWake as boolean = false
  dim listeningAltered as boolean = false
  dim keyDown as boolean = false
  dim keyAlwaysDown as boolean = false
  dim keyMonitoring as boolean = true
  dim keyMonitorActive as boolean = true
  dim keyMonitorType as integer = 0
 
  dim listeningInterval as integer = 5500
  dim keyPollingInterval as integer = 100
 
  dim activeProfile as string = "CORE"
 
  dim debugCheck as boolean
  dim debugCount as integer = 0
 
 
  Private Function CheckPTTkeyDownState(ByRef keyDown as boolean)
    for keyIndex as integer = 1 to 6
      keyAlwaysDown = false
      'Check only if this PTT button has been set
      if ((VA.GetText("AVCS_" + activeProfile + "_PTTBUTTON_" + keyIndex.ToString())) isNot nothing)
        checkKeyDown = VA.GetText("AVCS_" + activeProfile + "_PTTBUTTON_" + keyIndex.ToString())
        'Check if this is a reverse-PTT (push-to-mute)
        if ((VA.GetText("AVCS_" + activeProfile + "_PTTREVERSE_" + keyIndex.ToString())) isNot nothing)
          if ((VA.GetText("AVCS_" + activeProfile + "_PTTREVERSE_" + keyIndex.ToString())) = "reverse")
            keyAlwaysDown = true
          end if
        end if
        'Attempt to check 'Trigger' type button state
        if (checkKeyDown.EndsWith("TRIGGER"))
          if (IsNumeric(vaProxy.Utility.ParseTokens("{" + checkKeyDown + "}")))
            if ((keyAlwaysDown) and (Convert.ToInt32(vaProxy.Utility.ParseTokens("{" + checkKeyDown + "}")) < 20))
              keyDown = true
            end if
            if ((not(keyAlwaysDown)) and (Convert.ToInt32(vaProxy.Utility.ParseTokens("{" + checkKeyDown + "}")) > 20))
              keyDown = true
            end if
          end if
        elseif (checkKeyDown.Contains("POV"))
          'Check PTT POV Directional state
          checkPovDir = checkKeyDown.Split(":")
          if ((keyAlwaysDown) and ((vaProxy.Utility.ParseTokens("{" + checkPovDir(0) + "}")) = "CENTER"))
            keyDown = true
          end if
          if ((not(keyAlwaysDown)) and (vaProxy.Utility.ParseTokens("{" + checkPovDir(0) + "}") <> "CENTER"))
            if (vaProxy.Utility.ParseTokens("{" + checkPovDir(0) + "}") = checkPovDir(1))
              keyDown = true
            end if
          end if
         
        else
          'Check PTT key/button state
          if ((keyAlwaysDown) and ((vaProxy.Utility.ParseTokens("{" + checkKeyDown + "}")) = "0"))
            keyDown = true
          end if
          if ((not(keyAlwaysDown)) and ((vaProxy.Utility.ParseTokens("{" + checkKeyDown + "}")) = "1"))
            keyDown = true
          end if
        end if
      end if
      'Stop checking if a button/key down state has been set for return
      if (keyDown)
        Exit For
      end if
    next
  end function
 
  Private Function PTTStartListening(ByVal keyMonitorType as integer)
    'Start Listening check with delay to eliminate false positives/negatives
    if (keyMonitorType > 0)
      Thread.CurrentThread.Sleep(150)
      if (not(vaProxy.State.GetListeningEnabled))
        vaProxy.State.SetListeningEnabled(true)
      end if
    end if
  end function
 
  Private Function PTTStopListening(ByVal keyMonitorType as integer)
    'Stop Listening check with delay to eliminate false positives/negatives
    if (keyMonitorType > 0)
      Thread.CurrentThread.Sleep(500)
      if (vaProxy.State.GetListeningEnabled)
        vaProxy.State.SetListeningEnabled(false)
      end if
    end if
  end function
 
  Private Function SendDebugMessage(ByVal debugText as string, ByVal debugColor as integer)
    if ((VA.GetText("AVCS_Debug_QMSG")) isNot nothing)
      debugCount = VA.GetInt("AVCS_Debug_QMSG")
    end if
    debugCount += 1
    VA.SetText("AVCS_Debug_TMSG_" + debugCount.ToString(), debugText)
    VA.SetInt("AVCS_Debug_WCLR_" + debugCount.ToString(), debugColor)
    VA.SetInt("AVCS_Debug_QMSG", debugCount)
    try
      vaProxy.Command.Execute("f_core_debug -log", true)
    catch
      VA.WriteToLog("AVCS ERROR: PTTMON01 - f_core_debug null - restart VoiceAttack or create bug report", "red")
    end try
    debugCount = 0
  end function
 
 
  Public Sub Main()
    if ((VA.GetText("AVCS_ACTIVE_PROFILE")) isNot nothing)
      activeProfile = VA.GetText("AVCS_ACTIVE_PROFILE")
    end if
   
    'Listening Wake - "Wait for spoken response" works when listening disabled; if that ever changes, set this bool to TRUE to enable hotfix below
    if ((VA.GetInt("AVCS_" + activeProfile + "_PTT_CANWAKE")) isNot nothing)
      listeningCanWake = VA.GetInt("AVCS_" + activeProfile + "_PTT_CANWAKE")
    end if
   
    if ((VA.GetInt("AVCS_" + activeProfile + "_PTT_MODE")) isNot nothing)
      keyMonitorType = VA.GetInt("AVCS_" + activeProfile + "_PTT_MODE")
    end if
   
    if ((VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening")) isNot nothing)
      listeningInterval = VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening")
    end if
   
    if ((VA.GetInt("AVCS_" + activeProfile + "_DevicePollingPTT")) isNot nothing)
      keyPollingInterval = VA.GetInt("AVCS_" + activeProfile + "_KeyPollingIntervalPTT")
    end if
   
    'Main Mode Check - call this command from any init, if running it will exit before re-entering, or not at all (if unset)
    if ((VA.GetBoolean("AVCS_" + activeProfile + "_RadioButtons_ON")) isNot nothing)
      masterMode = VA.GetBoolean("AVCS_" + activeProfile + "_RadioButtons_ON")
      if (masterMode)
        'Prepare Messages for AVCS Debug system to choose where to send them (event log/file/both)
        if ((vaProxy.ParseTokens("{BOOL:AVCS_Debug_ON:false}")) = true)
          debugCheck = true         
          SendDebugMessage("AVCS QCC PTT KeyMonitor Loop Entered",2)
        end if
       
        'Stagger Delay for any existing loop to exit before new loop instance starts
        Thread.CurrentThread.Sleep(600)
        VA.SetBoolean("AVCS_RadioButtons_ON", true)
        VA.SetBoolean("AVCS_PTT_MODE_ON", true)
       
        Thread.CurrentThread.Sleep(keyPollingInterval)
        PTTStopListening(keyMonitorType)
       
        'MAIN Monitor Loop
        while (keyMonitorActive)
          'Exit Check - allows staggered exit and 'only one instance' of this loop
          if ((vaProxy.ParseTokens("{BOOL:AVCS_RadioButtons_ON:false}")) = false)
            keyMonitorType = 1
            keyMonitorActive = false
            PTTStartListening(keyMonitorType)
            Exit While
          end if
         
          'Pausing Check - allows pausing the functionality of the main loop without exiting
          if ((vaProxy.ParseTokens("{BOOL:AVCS_PTT_MODE_ON:false}")) = true)
            keyMonitoring = true
          else
            keyMonitoring = false
          end if
         
          Thread.CurrentThread.Sleep(keyPollingInterval)
         
          if (keyMonitoring)
           
            'Keydown Check once per interval
            keyDown = false
            CheckPTTkeyDownState(keyDown)
           
            'Listening Wake function - if "Wait for spoken response" ever respects global listening, this this will be needed
            if (not(keyDown))
              if (listeningCanWake)
                if ((vaProxy.ParseTokens("{BOOL:AVCS_QCC_LISTENING:false}")) = true)
                  keyDown = true
                  VA.SetBoolean("AVCS_QCC_LISTENING", nothing)
                end if
              end if
            end if
           
            'Wake by Name Check once per interval
            if (not(keyDown))
              if ((vaProxy.ParseTokens("{BOOL:AVCS_QCC_AWAKE:false}")) = true)
                keyDown = true
                listenAwake = true
                VA.SetBoolean("AVCS_QCC_AWAKE", nothing)
              end if
            end if
           
            if (keyDown)
              VA.SetBoolean("AVCS_PTT_KeyDown", true)
              VA.SetBoolean("AVCS_" + activeProfile + "_PTT_KeyDown", true)
             
              PTTStartListening(keyMonitorType)
             
              if (debugCheck)
                SendDebugMessage("AVCS PTT KEY PRESS / WAKE DETECTED",2)
              end if
             
              'If Listen Wake Hotfix enabled, allow VAS Loop to increase default wait for response here
              if (listeningCanWake)
                if ((VA.GetDecimal("AVCS_VAS_TIMEOUT")) isNot nothing)
                  listeningInterval = 8500
                  listeningAltered = true
                end if
              end if
             
              'Secondary Loop - Wait until done / stop listening
              for i as integer = 0 to listeningInterval step 500
                Thread.CurrentThread.Sleep(500)
               
                if (i >= listeningInterval)
                  Exit For
                end if
               
                'Secondary Exit Check - get out if told to exit instance
                if ((vaProxy.ParseTokens("{BOOL:AVCS_RadioButtons_ON:false}")) = false)
                  keyMonitorType = 1
                  keyMonitorActive = false
                  PTTStartListening(keyMonitorType)
                  Exit While
                end if
               
                'Increase waiting time by resetting counter upon unrecognized speech or repeated Wake Name use
                if ((vaProxy.ParseTokens("{BOOL:AVCS_QCC_AWAKE:false}")) = true)
                  i = 0
                  listenAwake = true
                  VA.SetBoolean("AVCS_QCC_AWAKE", nothing)
                end if
               
                'If wait loop entered via keyDown state detection, allow immediate on/off of Global Listening based on key state
                if (not(listenAwake))
                  keyDown = false
                  CheckPTTkeyDownState(keyDown)
                  if (keyDown)
                    i = 0
                    PTTStartListening(keyMonitorType)
                  else
                    PTTStopListening(keyMonitorType)
                  end if
                end if
              next
             
              'Reset all function variables to begin loop again
              VA.SetBoolean("AVCS_PTT_KeyDown", false)
              VA.SetBoolean("AVCS_" + activeProfile + "_PTT_KeyDown", false)
             
              PTTStopListening(keyMonitorType)
             
              keyDown = false
              listenAwake = false
             
              if ((listeningCanWake) and (listeningAltered))
                listeningAltered = false
                listeningInterval = 5500
                if ((VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening")) isNot nothing)
                  listeningInterval = VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening")
                end if
              end if
             
              if (debugCheck)
                SendDebugMessage("AVCS PTT LISTENING INTERVAL COMPLETE",4)
              end if
            end if
           
          end if
         
        end while
       
        VA.SetBoolean("AVCS_PTT_KeyDown", false)
        VA.SetBoolean("AVCS_" + activeProfile + "_PTT_KeyDown", false)
       
        if (debugCheck)
          SendDebugMessage("AVCS QCC PTT KeyMonitor Loop ended",2)
        end if
      else
        'Cancel - when lauched but PTT mode is not enabled for this profile
        keyMonitorType = 1
        PTTStartListening(keyMonitorType)
      end if
    end if
   
  End Sub

End Class
(edit: dang, this forum code blocks uses very wide 'tabs' - changed to double-space in all three posts above to look better)
« Last Edit: February 04, 2022, 12:44:54 PM by SemlerPDX »