Jump to content

Dual Analog / Digital Throttle Control (Eg Logitech G13)


No replies to this topic

#1 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 03 September 2014 - 08:36 AM

I have recently been toying with using the thumbstick on my G13 for analog throttle while side-sniping and really loving it - in the Shawk 2K it really works well.

The idea is to use W+S normally (Or rather the G4 and G11 buttons on a G13), but when you need precise control for peeking around a corner, switch to using the analog thumbstick.
This works normally in MWO, but if you are say at full forwards speed because you are holding the thumbstick forwards, then hold W and release the thumbstick, you slow down briefly - a bit annoying when you are mid snipe and decide you need to bug out.

I have managed to fix this issue through AHK code by having both the W+S keys and the thumbstick control the same virtual joystick. At the moment my code is hard-wired to my joystick IDs etc, but if anyone else likes the idea, I could work my magic and provide one of my GUIfied apps so that others can use it.
If no-one else cares though, i won't bother.

For now, if anyone is geeky enough to know what to do with it, here is the source code:
You will need the vjoy library to run this - probably the simplest way to do this is to download the source for my UJR project (See sig) and drop this code into an AHK file in the same folder as ujr.ahk
; Init the PPJoy / vJoy library
#SingleInstance, force
#include VJoyLib\VJoy_lib.ahk
Process, Priority, , High
 
; User config section
config_joy_id := 5 ; The ID of the stick you wish to use - you will probably need to change this.
config_joy_axis := 2 ; The Axis number of your stick. For a G13, you will not need to change this
config_vjoy_id := 1 ; The vJoy stick number (Probably do not need to change)
config_joy_invert := 0 ; Whether to invert the axis or not
; End user config section
 
; Init stick vars for AHK
axis_list_ahk := Array("X","Y","Z","R","U","V")
 
; Init stick vars for vJoy
axis_list_vjoy := Array("X","Y","Z","RX","RY","RZ","SL0","SL1")
 
 
axis_1 := config_joy_id "Joy" axis_list_ahk[config_joy_axis]
 
axis_1_current := 0
axis_1_input := 0
up_held := 0
down_held := 0
axis_1_was_deflected := 0
 
 
LoadPackagedLibrary()
vjoy_id := 1      ; The current vjoy device the app is trying to use. Also serves as a "last item selected" for the vjoy id dropdown
vjoy_ready := 0      ; Whether the vjoy_id is connected and under the app's control
 
InitVJoy(vjoy_id)
if (!vjoy_ready){
  Gosub, AppQuit
}
 
Loop {
  axis_1_raw := GetKeyState(axis_1)
  axis_1_input := (axis_1_raw / 50) - 1
 
  if (abs(axis_1_input) < 0.1){
    axis_1_input := 0
  }
 
  if (up_held || down_held){
    ; keys being used
    if (up_held){
      mod := -1
    } else if (down_held){
      mod := 1
    } else {
      mod := 0
    }
    axis_1_current += (0.04 * mod)
  } else if (axis_1_input != 0) {
    ; joystick deflected
    axis_1_current := axis_1_input
  } else if(axis_1_was_deflected){
    ; nothing being pressed
    ; if joystick WAS deflected, but no longer is - throttle down to 0
    axis_1_current := 0
  }
 
  if (axis_1_current > 1){
    axis_1_current := 1
  } else if (axis_1_current < -1){
    axis_1_current := -1
  }
 
  axis_1_out := ((axis_1_current * 0.5) + 0.5) * 32767
  if (config_joy_invert){
    axis_1_out := 32767 - axis_1_out
  }
 
 
  ax := axis_list_vjoy[2]
  VJoy_SetAxis(axis_1_out, vjoy_id, HID_USAGE_%ax%)
 
  if (axis_1_input != 0){
    axis_1_was_deflected := 1
  } else {
    axis_1_was_deflected := 0
  }
 
  Sleep 5
}
 
#IfWinActive, ahk_class CryENGINE
  *~w::
    up_held := 1
    Return
 
  *~w up::
    up_held := 0
    Return
 
  *~s::
    down_held := 1
    return
 
  *~s up::
    down_held := 0
    return
 
  *~x::
    axis_1_current := 0
    return
#IfWinActive
 
OnExit, AppQuit
 
return
 
; Loads the vJoy DLL
LoadPackagedLibrary() {
    if (A_PtrSize < 8) {
        dllpath = VJoyLib\x86\vJoyInterface.dll
    } else {
        dllpath = VJoyLib\x64\vJoyInterface.dll
    }
    hDLL := DLLCall("LoadLibrary", "Str", dllpath)
    if (!hDLL) {
        MsgBox, [%A_ThisFunc%] LoadLibrary %dllpath% fail
    }
    return hDLL
} 
 
; Starts vJoy
InitVJoy(vjoy_id){
      global vjoy_ready
      
      if (VJoy_Ready(vjoy_id)){
         VJoy_RelinquishVJD(vjoy_id)
         VJoy_Close()
      }
      vjoy_status := DllCall("vJoyInterface\GetVJDStatus", "UInt", vjoy_id)
      if (vjoy_status == 2){
         msgbox err 2
      }  else if (vjoy_status >= 3){
         ; 3-4 not available
         msgbox err 3 or 4
      } else if (vjoy_status == 0){
         ; already owned by this app - should not come here as we want to release non used sticks
         msgbox already owned
      }
      if (vjoy_status <= 1){
         VJoy_Init(vjoy_id)
         
         ; Seem to need this to allow reconnecting to sticks (ie you selected id 1 then 2 then 1 again. Else control of stick does not resume
         VJoy_AcquireVJD(vjoy_id)
         VJoy_ResetVJD(vjoy_id)
         if (VJoy_Ready(vjoy_id)){
            vjoy_ready := 1
            return 1
         } else {
            msgbox Problem Connecting
            vjoy_ready := 0
         }
      } else {
         vjoy_ready := 0
      }
}
 
AppQuit:
   if (PPJ_Device != -1)
      VJoy_Close()
ExitApp


To use the code, edit the config values at the start, then run it.
In MWO, go to the CONTROLLER (not keyboard) bindings menu and double click the throttle axis binding, then hit the W key. This will move the virtual stick so that MWO will bind to it.

Edited by evilC, 11 September 2014 - 05:48 AM.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users